changeset 0:e0f8dcca02ed

Uploaded S-MART tool. A toolbox manages RNA-Seq and ChIP-Seq data.
author yufei-luo
date Thu, 17 Jan 2013 10:52:14 -0500
parents
children 30c5431d8ce4
files smart_toolShed/README.pdf smart_toolShed/SMART/Java/File.java smart_toolShed/SMART/Java/Files.java smart_toolShed/SMART/Java/FormatType.java smart_toolShed/SMART/Java/FormatsContainer.java smart_toolShed/SMART/Java/FormatsReader.java smart_toolShed/SMART/Java/Global.java smart_toolShed/SMART/Java/Installer/Old/PasswordAsker.java smart_toolShed/SMART/Java/Installer/Old/SmartInstaller.java smart_toolShed/SMART/Java/Installer/Old/SmartInstallerTask.java smart_toolShed/SMART/Java/Installer/PasswordAsker.java smart_toolShed/SMART/Java/Installer/SmartInstaller.jar smart_toolShed/SMART/Java/Installer/SmartInstaller.java smart_toolShed/SMART/Java/Installer/SmartInstallerTask.java smart_toolShed/SMART/Java/Installer/build.sh smart_toolShed/SMART/Java/Installer/manifest.txt smart_toolShed/SMART/Java/Installer/s-mart.zip smart_toolShed/SMART/Java/LICENSE.txt smart_toolShed/SMART/Java/Program.java smart_toolShed/SMART/Java/ProgramFileReader.java smart_toolShed/SMART/Java/ProgramLauncher.java smart_toolShed/SMART/Java/ProgramOption.java smart_toolShed/SMART/Java/Python/.gitignore smart_toolShed/SMART/Java/Python/CleanTranscriptFile.py smart_toolShed/SMART/Java/Python/ClusterizeByTags.py smart_toolShed/SMART/Java/Python/CollapseReads.py smart_toolShed/SMART/Java/Python/CombineTags.py smart_toolShed/SMART/Java/Python/CompareOverlapping.py smart_toolShed/SMART/Java/Python/CompareOverlappingSmallQuery.py smart_toolShed/SMART/Java/Python/CompareOverlappingSmallRef.py smart_toolShed/SMART/Java/Python/ComputeCoverage.py smart_toolShed/SMART/Java/Python/CountReadGCPercent.py smart_toolShed/SMART/Java/Python/FindOverlapsOptim.py smart_toolShed/SMART/Java/Python/GetDifferentialExpression.py smart_toolShed/SMART/Java/Python/GetDistribution.py smart_toolShed/SMART/Java/Python/GetFlanking.py smart_toolShed/SMART/Java/Python/GetRandomSubset.py smart_toolShed/SMART/Java/Python/GetReadDistribution.py smart_toolShed/SMART/Java/Python/GetReadSizes.py smart_toolShed/SMART/Java/Python/GetUpDownStream.py smart_toolShed/SMART/Java/Python/RestrictFromCoverage.py smart_toolShed/SMART/Java/Python/SelectByTag.py smart_toolShed/SMART/Java/Python/WrappGetDistribution.py smart_toolShed/SMART/Java/Python/WrappGetReadDistribution.py smart_toolShed/SMART/Java/Python/WrappPlotCoverage.py smart_toolShed/SMART/Java/Python/WrappPlotRepartition.py smart_toolShed/SMART/Java/Python/__init__.py smart_toolShed/SMART/Java/Python/__init__.pyc smart_toolShed/SMART/Java/Python/adaptorStripper.py smart_toolShed/SMART/Java/Python/changeGffFeatures.sh smart_toolShed/SMART/Java/Python/changeTagName.py smart_toolShed/SMART/Java/Python/cleanGff.py smart_toolShed/SMART/Java/Python/cleaning/CleanerChooser.py smart_toolShed/SMART/Java/Python/cleaning/DefaultCleaner.py smart_toolShed/SMART/Java/Python/cleaning/GffCleaner.py smart_toolShed/SMART/Java/Python/cleaning/GtfCleaner.py smart_toolShed/SMART/Java/Python/cleaning/TranscriptListCleaner.py smart_toolShed/SMART/Java/Python/cleaning/__init__.py smart_toolShed/SMART/Java/Python/clusterize.py smart_toolShed/SMART/Java/Python/clusterizeBySlidingWindows.py smart_toolShed/SMART/Java/Python/compareOverlapping.py smart_toolShed/SMART/Java/Python/convertTranscriptFile.py smart_toolShed/SMART/Java/Python/coordinatesToSequence.py smart_toolShed/SMART/Java/Python/fastqToFasta.py smart_toolShed/SMART/Java/Python/findTss.py smart_toolShed/SMART/Java/Python/fold.py smart_toolShed/SMART/Java/Python/getDifference.py smart_toolShed/SMART/Java/Python/getDistance.py smart_toolShed/SMART/Java/Python/getDistribution.py smart_toolShed/SMART/Java/Python/getElement.py smart_toolShed/SMART/Java/Python/getExons.py smart_toolShed/SMART/Java/Python/getInfoPerCoverage.py smart_toolShed/SMART/Java/Python/getIntrons.py smart_toolShed/SMART/Java/Python/getLetterDistribution.py smart_toolShed/SMART/Java/Python/getNb.py smart_toolShed/SMART/Java/Python/getRandomRegions.py smart_toolShed/SMART/Java/Python/getReadDistribution.py smart_toolShed/SMART/Java/Python/getSequence.py smart_toolShed/SMART/Java/Python/getSizes.py smart_toolShed/SMART/Java/Python/getWigData.py smart_toolShed/SMART/Java/Python/getWigDistance.py smart_toolShed/SMART/Java/Python/getWigProfile.py smart_toolShed/SMART/Java/Python/mapperAnalyzer.py smart_toolShed/SMART/Java/Python/mappingToCoordinates.py smart_toolShed/SMART/Java/Python/mergeSlidingWindowsClusters.py smart_toolShed/SMART/Java/Python/mergeTranscriptLists.py smart_toolShed/SMART/Java/Python/misc/MultipleRPlotter.py smart_toolShed/SMART/Java/Python/misc/Progress.py smart_toolShed/SMART/Java/Python/misc/Progress.pyc smart_toolShed/SMART/Java/Python/misc/RPlotter.py smart_toolShed/SMART/Java/Python/misc/UnlimitedProgress.py smart_toolShed/SMART/Java/Python/misc/UnlimitedProgress.pyc smart_toolShed/SMART/Java/Python/misc/Utils.py smart_toolShed/SMART/Java/Python/misc/Utils.pyc smart_toolShed/SMART/Java/Python/misc/__init__.py smart_toolShed/SMART/Java/Python/misc/__init__.pyc smart_toolShed/SMART/Java/Python/misc/test/Test_Utils.py smart_toolShed/SMART/Java/Python/misc/test/__init__.py smart_toolShed/SMART/Java/Python/modifyFasta.py smart_toolShed/SMART/Java/Python/modifyGenomicCoordinates.py smart_toolShed/SMART/Java/Python/modifySequenceList.py smart_toolShed/SMART/Java/Python/mySql/MySqlConnection.py smart_toolShed/SMART/Java/Python/mySql/MySqlExonTable.py smart_toolShed/SMART/Java/Python/mySql/MySqlExonTable.pyc smart_toolShed/SMART/Java/Python/mySql/MySqlQuery.py smart_toolShed/SMART/Java/Python/mySql/MySqlTable.py smart_toolShed/SMART/Java/Python/mySql/MySqlTable.pyc smart_toolShed/SMART/Java/Python/mySql/MySqlTranscriptTable.py smart_toolShed/SMART/Java/Python/mySql/MySqlTranscriptTable.pyc smart_toolShed/SMART/Java/Python/mySql/__init__.py smart_toolShed/SMART/Java/Python/mySql/__init__.pyc smart_toolShed/SMART/Java/Python/mySql/test/Test_MySqlTranscriptTable.py smart_toolShed/SMART/Java/Python/mySql/test/__init__.py smart_toolShed/SMART/Java/Python/ncList/ConvertToNCList.py smart_toolShed/SMART/Java/Python/ncList/FileSorter.py smart_toolShed/SMART/Java/Python/ncList/FindOverlapsWithOneInterval.py smart_toolShed/SMART/Java/Python/ncList/FindOverlapsWithSeveralIntervals.py smart_toolShed/SMART/Java/Python/ncList/FindOverlapsWithSeveralIntervalsBin.py smart_toolShed/SMART/Java/Python/ncList/FindOverlapsWithSeveralIntervalsIndex.py smart_toolShed/SMART/Java/Python/ncList/FindOverlaps_naif.py smart_toolShed/SMART/Java/Python/ncList/NCIndex.py smart_toolShed/SMART/Java/Python/ncList/NCIndex.pyc smart_toolShed/SMART/Java/Python/ncList/NCList.py smart_toolShed/SMART/Java/Python/ncList/NCList.pyc smart_toolShed/SMART/Java/Python/ncList/NCListCursor.py smart_toolShed/SMART/Java/Python/ncList/NCListCursor.pyc smart_toolShed/SMART/Java/Python/ncList/NCListFilePickle.py smart_toolShed/SMART/Java/Python/ncList/NCListFilePickle.pyc smart_toolShed/SMART/Java/Python/ncList/NCListHandler.py smart_toolShed/SMART/Java/Python/ncList/NCListMerger.py smart_toolShed/SMART/Java/Python/ncList/NCListParser.py smart_toolShed/SMART/Java/Python/ncList/__init__.py smart_toolShed/SMART/Java/Python/ncList/__init__.pyc smart_toolShed/SMART/Java/Python/ncList/test/MockFindOverlapsWithSeveralIntervals.py smart_toolShed/SMART/Java/Python/ncList/test/MockFindOverlaps_randomExample.py smart_toolShed/SMART/Java/Python/ncList/test/Test_F_FileSorter.py smart_toolShed/SMART/Java/Python/ncList/test/Test_F_FindOverlapsWithOneInterval.py smart_toolShed/SMART/Java/Python/ncList/test/Test_F_FindOverlapsWithSeveralIntervals.py smart_toolShed/SMART/Java/Python/ncList/test/Test_F_FindOverlaps_naif.py smart_toolShed/SMART/Java/Python/ncList/test/Test_F_FindOverlaps_randomExample.py smart_toolShed/SMART/Java/Python/ncList/test/Test_F_NCList.py smart_toolShed/SMART/Java/Python/ncList/test/Test_FindOverlapsWithOneInterval.py smart_toolShed/SMART/Java/Python/ncList/test/Test_FindOverlapsWithSeveralIntervals.py smart_toolShed/SMART/Java/Python/ncList/test/Test_FindOverlaps_randomExample.py smart_toolShed/SMART/Java/Python/ncList/test/Test_randExample.py smart_toolShed/SMART/Java/Python/ncList/test/__init__.py smart_toolShed/SMART/Java/Python/plot.py smart_toolShed/SMART/Java/Python/plotCoverage.py smart_toolShed/SMART/Java/Python/plotCsv.py smart_toolShed/SMART/Java/Python/plotGenomeCoverage.py smart_toolShed/SMART/Java/Python/plotRepartition.py smart_toolShed/SMART/Java/Python/plotTranscriptList.py smart_toolShed/SMART/Java/Python/qualToFastq.py smart_toolShed/SMART/Java/Python/removeAllTmpTables.py smart_toolShed/SMART/Java/Python/removeEmptySequences.py smart_toolShed/SMART/Java/Python/removeExonLines.sh smart_toolShed/SMART/Java/Python/repetGffConverter.py smart_toolShed/SMART/Java/Python/restrictFromNucleotides.py smart_toolShed/SMART/Java/Python/restrictFromSize.py smart_toolShed/SMART/Java/Python/restrictSequenceList.py smart_toolShed/SMART/Java/Python/restrictTranscriptList.py smart_toolShed/SMART/Java/Python/runRandomJobs.py smart_toolShed/SMART/Java/Python/selectByNbOccurrences.py smart_toolShed/SMART/Java/Python/sequenceListSplitter.py smart_toolShed/SMART/Java/Python/splitByTag.py smart_toolShed/SMART/Java/Python/splitMultiFasta.py smart_toolShed/SMART/Java/Python/structure/Bins.py smart_toolShed/SMART/Java/Python/structure/Bins.pyc smart_toolShed/SMART/Java/Python/structure/Interval.py smart_toolShed/SMART/Java/Python/structure/Interval.pyc smart_toolShed/SMART/Java/Python/structure/Mapping.py smart_toolShed/SMART/Java/Python/structure/Mapping.pyc smart_toolShed/SMART/Java/Python/structure/Sequence.py smart_toolShed/SMART/Java/Python/structure/Sequence.pyc smart_toolShed/SMART/Java/Python/structure/SequenceList.py smart_toolShed/SMART/Java/Python/structure/SequenceList.pyc smart_toolShed/SMART/Java/Python/structure/SubMapping.py smart_toolShed/SMART/Java/Python/structure/SubMapping.pyc smart_toolShed/SMART/Java/Python/structure/Transcript.py smart_toolShed/SMART/Java/Python/structure/Transcript.pyc smart_toolShed/SMART/Java/Python/structure/TranscriptContainer.py smart_toolShed/SMART/Java/Python/structure/TranscriptContainer.pyc smart_toolShed/SMART/Java/Python/structure/TranscriptList.py smart_toolShed/SMART/Java/Python/structure/TranscriptList.pyc smart_toolShed/SMART/Java/Python/structure/TranscriptListIterator.py smart_toolShed/SMART/Java/Python/structure/TranscriptListsComparator.py smart_toolShed/SMART/Java/Python/structure/__init__.py smart_toolShed/SMART/Java/Python/structure/__init__.pyc smart_toolShed/SMART/Java/Python/structure/test/Test_Interval.py smart_toolShed/SMART/Java/Python/structure/test/Test_Mapping.py smart_toolShed/SMART/Java/Python/structure/test/Test_Sequence.py smart_toolShed/SMART/Java/Python/structure/test/Test_SubMapping.py smart_toolShed/SMART/Java/Python/structure/test/Test_Transcript.py smart_toolShed/SMART/Java/Python/structure/test/Test_TranscriptListsComparator.py smart_toolShed/SMART/Java/Python/structure/test/__init__.py smart_toolShed/SMART/Java/Python/testInstall.py smart_toolShed/SMART/Java/Python/toolLauncher/RnaFoldLauncher.py smart_toolShed/SMART/Java/Python/toolLauncher/__init__.py smart_toolShed/SMART/Java/Python/trimAdaptor.py smart_toolShed/SMART/Java/Python/trimSequence.py smart_toolShed/SMART/Java/Python/trimSequences.py smart_toolShed/SMART/Java/Python/txtToFasta.py smart_toolShed/SMART/Java/Python/updateQual.py smart_toolShed/SMART/Java/Python/wigExploder.py smart_toolShed/SMART/Java/Python/wrongFastqToQual.py smart_toolShed/SMART/Java/PythonHelperReader.java smart_toolShed/SMART/Java/PythonProgramFinder.java smart_toolShed/SMART/Java/README.txt smart_toolShed/SMART/Java/Sav/File.java smart_toolShed/SMART/Java/Sav/Files.java smart_toolShed/SMART/Java/Sav/FormatType.java smart_toolShed/SMART/Java/Sav/FormatsContainer.java smart_toolShed/SMART/Java/Sav/FormatsReader.java smart_toolShed/SMART/Java/Sav/Global.java smart_toolShed/SMART/Java/Sav/Program.java smart_toolShed/SMART/Java/Sav/ProgramFileReader.java smart_toolShed/SMART/Java/Sav/ProgramLauncher.java smart_toolShed/SMART/Java/Sav/ProgramOption.java smart_toolShed/SMART/Java/Sav/PythonHelperReader.java smart_toolShed/SMART/Java/Sav/PythonProgramFinder.java smart_toolShed/SMART/Java/Sav/Smart.java smart_toolShed/SMART/Java/Smart.jar smart_toolShed/SMART/Java/Smart.java smart_toolShed/SMART/Java/SmartInstaller.jar smart_toolShed/SMART/Java/WindowsRegistry.java smart_toolShed/SMART/Java/__init__.py smart_toolShed/SMART/Java/__init__.pyc smart_toolShed/SMART/Java/doc.pdf smart_toolShed/SMART/Java/formats.txt smart_toolShed/SMART/Java/manifest.txt smart_toolShed/SMART/__init__.py smart_toolShed/SMART/galaxy/CleanTranscriptFile.xml smart_toolShed/SMART/galaxy/Clusterize.xml smart_toolShed/SMART/galaxy/CollapseReads.xml smart_toolShed/SMART/galaxy/CompareOverlappingSmallQuery.xml smart_toolShed/SMART/galaxy/CompareOverlappingSmallRef.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BedToCsv.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BedToGff2.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BedToGff3.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BedToSam.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BlastToCsv.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BlastToGff2.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BlastToGff3.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BlastToSam.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_FastqToFasta.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_Gff2ToCsv.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_Gff2ToGff3.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_Gff2ToSam.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_Gff3ToCsv.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_Gff3ToGff2.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_Gff3ToSam.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_Gff3ToWig.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_SamToCsv.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_SamToGff2.xml smart_toolShed/SMART/galaxy/ConvertTranscriptFile_SamToGff3.xml smart_toolShed/SMART/galaxy/CountReadGCPercent.xml smart_toolShed/SMART/galaxy/DiffExpAnal.xml smart_toolShed/SMART/galaxy/FindOverlaps_optim.xml smart_toolShed/SMART/galaxy/GetDifferentialExpression.xml smart_toolShed/SMART/galaxy/GetFlanking.xml smart_toolShed/SMART/galaxy/SelectByTag.xml smart_toolShed/SMART/galaxy/WrappGetLetterDistribution.py smart_toolShed/SMART/galaxy/WrappGetLetterDistribution.xml smart_toolShed/SMART/galaxy/__init__.py smart_toolShed/SMART/galaxy/changeGffFeatures.xml smart_toolShed/SMART/galaxy/changeTagName.xml smart_toolShed/SMART/galaxy/cleanGff.xml smart_toolShed/SMART/galaxy/clusterize.xml smart_toolShed/SMART/galaxy/clusterizeBySlidingWindows.xml smart_toolShed/SMART/galaxy/compareOverlapping.xml smart_toolShed/SMART/galaxy/computeCoverage.xml smart_toolShed/SMART/galaxy/coordinatesToSequence.xml smart_toolShed/SMART/galaxy/findTss.xml smart_toolShed/SMART/galaxy/getDifference.xml smart_toolShed/SMART/galaxy/getDistance.xml smart_toolShed/SMART/galaxy/getDistribution.xml smart_toolShed/SMART/galaxy/getExons.xml smart_toolShed/SMART/galaxy/getIntrons.xml smart_toolShed/SMART/galaxy/getNb.xml smart_toolShed/SMART/galaxy/getReadDistribution.xml smart_toolShed/SMART/galaxy/getSequence.xml smart_toolShed/SMART/galaxy/getSizes.xml smart_toolShed/SMART/galaxy/getWigData.xml smart_toolShed/SMART/galaxy/getWigDistance.xml smart_toolShed/SMART/galaxy/getWigProfile.xml smart_toolShed/SMART/galaxy/mapperAnalyzer.xml smart_toolShed/SMART/galaxy/mappingToCoordinates.xml smart_toolShed/SMART/galaxy/mergeSlidingWindowsClusters.xml smart_toolShed/SMART/galaxy/mergeTranscriptLists.xml smart_toolShed/SMART/galaxy/modifyFasta.xml smart_toolShed/SMART/galaxy/modifyGenomicCoordinates.xml smart_toolShed/SMART/galaxy/modifySequenceList.xml smart_toolShed/SMART/galaxy/plot.xml smart_toolShed/SMART/galaxy/plotCoverage.xml smart_toolShed/SMART/galaxy/plotGenomeCoverage.xml smart_toolShed/SMART/galaxy/plotRepartition.xml smart_toolShed/SMART/galaxy/plotTranscriptList.xml smart_toolShed/SMART/galaxy/qualToFastq.xml smart_toolShed/SMART/galaxy/removeExonLines.sh smart_toolShed/SMART/galaxy/removeExonLines.xml smart_toolShed/SMART/galaxy/restrictFromSize.xml smart_toolShed/SMART/galaxy/restrictSequenceList.xml smart_toolShed/SMART/galaxy/restrictTranscriptList.xml smart_toolShed/SMART/galaxy/test/CollapseReads.xml smart_toolShed/SMART/galaxy/test/Test_F_WrappGetLetterDistribution.py smart_toolShed/SMART/galaxy/test/__init__.py smart_toolShed/SMART/galaxy/testArgum.xml smart_toolShed/SMART/galaxy/testR.xml smart_toolShed/SMART/galaxy/trimAdaptor.xml smart_toolShed/SMART/galaxy/trimSequences.xml smart_toolShed/__init__.py smart_toolShed/commons/__init__.py smart_toolShed/commons/__init__.pyc smart_toolShed/commons/core/__init__.py smart_toolShed/commons/core/__init__.pyc smart_toolShed/commons/core/checker/AbstractChecker.py smart_toolShed/commons/core/checker/CheckerException.py smart_toolShed/commons/core/checker/CheckerUtils.py smart_toolShed/commons/core/checker/ConfigChecker.py smart_toolShed/commons/core/checker/ConfigException.py smart_toolShed/commons/core/checker/ConfigValue.py smart_toolShed/commons/core/checker/IChecker.py smart_toolShed/commons/core/checker/OldConfigChecker.py smart_toolShed/commons/core/checker/RepetException.py smart_toolShed/commons/core/checker/__init__.py smart_toolShed/commons/core/checker/test/TestSuite_Checker.py smart_toolShed/commons/core/checker/test/Test_CheckerUtils.py smart_toolShed/commons/core/checker/test/Test_ConfigChecker.py smart_toolShed/commons/core/checker/test/Test_ConfigValue.py smart_toolShed/commons/core/checker/test/Test_F_ConfigChecker.py smart_toolShed/commons/core/checker/test/Test_OldConfigChecker.py smart_toolShed/commons/core/checker/test/__init__.py smart_toolShed/commons/core/coord/Align.py smart_toolShed/commons/core/coord/Align.pyc smart_toolShed/commons/core/coord/AlignUtils.py smart_toolShed/commons/core/coord/ConvCoord.py smart_toolShed/commons/core/coord/Map.py smart_toolShed/commons/core/coord/Map.pyc smart_toolShed/commons/core/coord/MapUtils.py smart_toolShed/commons/core/coord/Match.py smart_toolShed/commons/core/coord/MatchUtils.py smart_toolShed/commons/core/coord/MergedRange.py smart_toolShed/commons/core/coord/Path.py smart_toolShed/commons/core/coord/PathUtils.py smart_toolShed/commons/core/coord/Range.py smart_toolShed/commons/core/coord/Range.pyc smart_toolShed/commons/core/coord/Set.py smart_toolShed/commons/core/coord/SetUtils.py smart_toolShed/commons/core/coord/SlidingWindow.py smart_toolShed/commons/core/coord/__init__.py smart_toolShed/commons/core/coord/__init__.pyc smart_toolShed/commons/core/coord/align2set.py smart_toolShed/commons/core/coord/test/TestSuite_coord.py smart_toolShed/commons/core/coord/test/Test_Align.py smart_toolShed/commons/core/coord/test/Test_AlignUtils.py smart_toolShed/commons/core/coord/test/Test_ConvCoord.py smart_toolShed/commons/core/coord/test/Test_F_ConvCoord.py smart_toolShed/commons/core/coord/test/Test_Map.py smart_toolShed/commons/core/coord/test/Test_MapUtils.py smart_toolShed/commons/core/coord/test/Test_Match.py smart_toolShed/commons/core/coord/test/Test_MatchUtils.py smart_toolShed/commons/core/coord/test/Test_MergedRange.py smart_toolShed/commons/core/coord/test/Test_Path.py smart_toolShed/commons/core/coord/test/Test_PathUtils.py smart_toolShed/commons/core/coord/test/Test_Range.py smart_toolShed/commons/core/coord/test/Test_Set.py smart_toolShed/commons/core/coord/test/Test_SetUtils.py smart_toolShed/commons/core/coord/test/Test_SlidingWindow.py smart_toolShed/commons/core/coord/test/__init__.py smart_toolShed/commons/core/launcher/JobScriptTemplate.py smart_toolShed/commons/core/launcher/JobScriptTemplateLight.py smart_toolShed/commons/core/launcher/JobScriptWithFilesCopyTemplate.py smart_toolShed/commons/core/launcher/Launcher.py smart_toolShed/commons/core/launcher/LauncherUtils.py smart_toolShed/commons/core/launcher/WriteScript.py smart_toolShed/commons/core/launcher/__init__.py smart_toolShed/commons/core/launcher/test/Test_Launcher.py smart_toolShed/commons/core/launcher/test/Test_LauncherUtils.py smart_toolShed/commons/core/launcher/test/Test_WriteScript.py smart_toolShed/commons/core/launcher/test/__init__.py smart_toolShed/commons/core/launcher/test/expFiles/expJobScriptSQLiteWithFilesCopyTemplate.py smart_toolShed/commons/core/launcher/test/expFiles/expJobScriptTemplate.py smart_toolShed/commons/core/launcher/test/expFiles/expJobScriptTemplateLight.py smart_toolShed/commons/core/launcher/test/expFiles/expJobScriptTemplate_cmdWith2Lines.py smart_toolShed/commons/core/launcher/test/expFiles/expJobScriptWithFilesCopyTemplate.py smart_toolShed/commons/core/parsing/AxtParser.py smart_toolShed/commons/core/parsing/AxtParser.pyc smart_toolShed/commons/core/parsing/BamParser.py smart_toolShed/commons/core/parsing/BamParser.pyc smart_toolShed/commons/core/parsing/BedParser.py smart_toolShed/commons/core/parsing/BedParser.pyc smart_toolShed/commons/core/parsing/BlastParser.py smart_toolShed/commons/core/parsing/BlastParser.pyc smart_toolShed/commons/core/parsing/BlatFileParser.py smart_toolShed/commons/core/parsing/BlatParser.py smart_toolShed/commons/core/parsing/BlatToGff.py smart_toolShed/commons/core/parsing/BlatToGffForBesPaired.py smart_toolShed/commons/core/parsing/BowtieParser.py smart_toolShed/commons/core/parsing/BowtieParser.pyc smart_toolShed/commons/core/parsing/CoordsParser.py smart_toolShed/commons/core/parsing/CoordsParser.pyc smart_toolShed/commons/core/parsing/CrossSsrAndBesMappedByBlatToGff.py smart_toolShed/commons/core/parsing/ElandParser.py smart_toolShed/commons/core/parsing/ElandParser.pyc smart_toolShed/commons/core/parsing/ExoParser.py smart_toolShed/commons/core/parsing/ExoParser.pyc smart_toolShed/commons/core/parsing/FastaParser.py smart_toolShed/commons/core/parsing/FastaParser.pyc smart_toolShed/commons/core/parsing/FastqParser.py smart_toolShed/commons/core/parsing/FastqParser.pyc smart_toolShed/commons/core/parsing/FindRep.py smart_toolShed/commons/core/parsing/GbParser.py smart_toolShed/commons/core/parsing/GffParser.py smart_toolShed/commons/core/parsing/GffParser.pyc smart_toolShed/commons/core/parsing/GtfParser.py smart_toolShed/commons/core/parsing/GtfParser.pyc smart_toolShed/commons/core/parsing/MapParser.py smart_toolShed/commons/core/parsing/MapParser.pyc smart_toolShed/commons/core/parsing/MapperParser.py smart_toolShed/commons/core/parsing/MapperParser.pyc smart_toolShed/commons/core/parsing/MaqParser.py smart_toolShed/commons/core/parsing/MaqParser.pyc smart_toolShed/commons/core/parsing/MrepsToSet.py smart_toolShed/commons/core/parsing/Multifasta2SNPFile.py smart_toolShed/commons/core/parsing/MummerParser.py smart_toolShed/commons/core/parsing/NCListParser.py smart_toolShed/commons/core/parsing/NCListParser.pyc smart_toolShed/commons/core/parsing/NucmerParser.py smart_toolShed/commons/core/parsing/PalsToAlign.py smart_toolShed/commons/core/parsing/ParserChooser.py smart_toolShed/commons/core/parsing/ParserChooser.pyc smart_toolShed/commons/core/parsing/PathNum2Id.py smart_toolShed/commons/core/parsing/PilerTAToGrouperMap.py smart_toolShed/commons/core/parsing/PklParser.py smart_toolShed/commons/core/parsing/PklParser.pyc smart_toolShed/commons/core/parsing/PslParser.py smart_toolShed/commons/core/parsing/PslParser.pyc smart_toolShed/commons/core/parsing/README_MultiFasta2SNPFile smart_toolShed/commons/core/parsing/RmapParser.py smart_toolShed/commons/core/parsing/RmapParser.pyc smart_toolShed/commons/core/parsing/SamParser.py smart_toolShed/commons/core/parsing/SamParser.pyc smart_toolShed/commons/core/parsing/SeqmapParser.py smart_toolShed/commons/core/parsing/SeqmapParser.pyc smart_toolShed/commons/core/parsing/SequenceListParser.py smart_toolShed/commons/core/parsing/SequenceListParser.pyc smart_toolShed/commons/core/parsing/ShrimpParser.py smart_toolShed/commons/core/parsing/ShrimpParser.pyc smart_toolShed/commons/core/parsing/Soap2Parser.py smart_toolShed/commons/core/parsing/Soap2Parser.pyc smart_toolShed/commons/core/parsing/SoapParser.py smart_toolShed/commons/core/parsing/SoapParser.pyc smart_toolShed/commons/core/parsing/SsrParser.py smart_toolShed/commons/core/parsing/TranscriptListParser.py smart_toolShed/commons/core/parsing/TranscriptListParser.pyc smart_toolShed/commons/core/parsing/VarscanFile.py smart_toolShed/commons/core/parsing/VarscanFileForGnpSNP.py smart_toolShed/commons/core/parsing/VarscanHit.py smart_toolShed/commons/core/parsing/VarscanHitForGnpSNP.py smart_toolShed/commons/core/parsing/VarscanHit_WithTag.py smart_toolShed/commons/core/parsing/VarscanHit_v2_2_8.py smart_toolShed/commons/core/parsing/VarscanHit_v2_2_8_WithTag.py smart_toolShed/commons/core/parsing/WigParser.py smart_toolShed/commons/core/parsing/__init__.py smart_toolShed/commons/core/parsing/__init__.pyc smart_toolShed/commons/core/parsing/multifastaParserLauncher.py smart_toolShed/commons/core/parsing/test/Test_BedParser.py smart_toolShed/commons/core/parsing/test/Test_BlatFileParser.py smart_toolShed/commons/core/parsing/test/Test_BlatParser.py smart_toolShed/commons/core/parsing/test/Test_BlatToGff.py smart_toolShed/commons/core/parsing/test/Test_BlatToGffForBesPaired.py smart_toolShed/commons/core/parsing/test/Test_BowtieParser.py smart_toolShed/commons/core/parsing/test/Test_CoordsParser.py smart_toolShed/commons/core/parsing/test/Test_CrossSsrAndBesMappedByBlatToGff.py smart_toolShed/commons/core/parsing/test/Test_F_BlatToGff.py smart_toolShed/commons/core/parsing/test/Test_F_BlatToGffForBesPaired.py smart_toolShed/commons/core/parsing/test/Test_F_CrossSsrAndBesMappedByBlatToGff.py smart_toolShed/commons/core/parsing/test/Test_FastaParser.py smart_toolShed/commons/core/parsing/test/Test_FindRep.py smart_toolShed/commons/core/parsing/test/Test_GffParser.py smart_toolShed/commons/core/parsing/test/Test_MapParser.py smart_toolShed/commons/core/parsing/test/Test_MrepsToSet.py smart_toolShed/commons/core/parsing/test/Test_Multifasta2SNPFile.py smart_toolShed/commons/core/parsing/test/Test_Multifasta2SNPFileWriter.py smart_toolShed/commons/core/parsing/test/Test_PalsToAlign.py smart_toolShed/commons/core/parsing/test/Test_PathNum2Id.py smart_toolShed/commons/core/parsing/test/Test_PslParser.py smart_toolShed/commons/core/parsing/test/Test_SsrParser.py smart_toolShed/commons/core/parsing/test/Test_VarscanFile.py smart_toolShed/commons/core/parsing/test/Test_VarscanFileForGnpSNP.py smart_toolShed/commons/core/parsing/test/Test_VarscanHit.py smart_toolShed/commons/core/parsing/test/Test_VarscanHitForGnpSNP.py smart_toolShed/commons/core/parsing/test/Test_VarscanHit_WithTag.py smart_toolShed/commons/core/parsing/test/Test_VarscanHit_v2_2_8.py smart_toolShed/commons/core/parsing/test/Test_VarscanHit_v2_2_8_WithTag.py smart_toolShed/commons/core/parsing/test/Test_WigParser.py smart_toolShed/commons/core/parsing/test/Test_pilerTAToGrouperMap.py smart_toolShed/commons/core/parsing/test/__init__.py smart_toolShed/commons/core/parsing/test/data/ExpPotDooblonsSubSNP.csv smart_toolShed/commons/core/parsing/test/data/Wig/chr1.wig smart_toolShed/commons/core/parsing/test/data/realExpBatchLine.csv smart_toolShed/commons/core/parsing/test/data/realExpIndividual.csv smart_toolShed/commons/core/parsing/test/data/realExpSequences.fsa smart_toolShed/commons/core/parsing/test/data/realExpSubSNP.csv smart_toolShed/commons/core/parsing/test/data/real_multifasta_input.fasta smart_toolShed/commons/core/parsing/test/data/test.wig smart_toolShed/commons/core/parsing/test/data/test1.wig smart_toolShed/commons/core/parsing/test/data/test2.wig smart_toolShed/commons/core/parsing/test/data/testBedParser1.bed smart_toolShed/commons/core/parsing/test/data/testCoordsParser.coords smart_toolShed/commons/core/parsing/test/data/testCoordsParser_showcoord.coords smart_toolShed/commons/core/parsing/test/data/testCoordsParser_showcoord_promer.coords smart_toolShed/commons/core/parsing/test/data/testGffParser1.gff3 smart_toolShed/commons/core/seq/AlignedBioseqDB.py smart_toolShed/commons/core/seq/Bioseq.py smart_toolShed/commons/core/seq/Bioseq.pyc smart_toolShed/commons/core/seq/BioseqDB.py smart_toolShed/commons/core/seq/BioseqUtils.py smart_toolShed/commons/core/seq/ClusterConsensusCollection.py smart_toolShed/commons/core/seq/FastaUtils.py smart_toolShed/commons/core/seq/__init__.py smart_toolShed/commons/core/seq/__init__.pyc smart_toolShed/commons/core/seq/test/TestClusterConsensusCollection.py smart_toolShed/commons/core/seq/test/TestSuite_seq.py smart_toolShed/commons/core/seq/test/Test_AlignedBioseqDB.py smart_toolShed/commons/core/seq/test/Test_Bioseq.py smart_toolShed/commons/core/seq/test/Test_BioseqDB.py smart_toolShed/commons/core/seq/test/Test_BioseqUtils.py smart_toolShed/commons/core/seq/test/Test_FastaUtils.py smart_toolShed/commons/core/seq/test/Utils_for_T_FastaUtils.py smart_toolShed/commons/core/seq/test/__init__.py smart_toolShed/commons/core/sql/DbFactory.py smart_toolShed/commons/core/sql/DbMySql.py smart_toolShed/commons/core/sql/DbSQLite.py smart_toolShed/commons/core/sql/ITableMapAdaptator.py smart_toolShed/commons/core/sql/ITableMatchAdaptator.py smart_toolShed/commons/core/sql/ITablePathAdaptator.py smart_toolShed/commons/core/sql/ITableSeqAdaptator.py smart_toolShed/commons/core/sql/ITableSetAdaptator.py smart_toolShed/commons/core/sql/Job.py smart_toolShed/commons/core/sql/JobAdaptator.py smart_toolShed/commons/core/sql/OldRepetDB.py smart_toolShed/commons/core/sql/RepetJob.py smart_toolShed/commons/core/sql/TableAdaptator.py smart_toolShed/commons/core/sql/TableBinPathAdaptator.py smart_toolShed/commons/core/sql/TableBinSetAdaptator.py smart_toolShed/commons/core/sql/TableJobAdaptator.py smart_toolShed/commons/core/sql/TableJobAdaptatorFactory.py smart_toolShed/commons/core/sql/TableMapAdaptator.py smart_toolShed/commons/core/sql/TableMatchAdaptator.py smart_toolShed/commons/core/sql/TablePathAdaptator.py smart_toolShed/commons/core/sql/TableSeqAdaptator.py smart_toolShed/commons/core/sql/TableSetAdaptator.py smart_toolShed/commons/core/sql/__init__.py smart_toolShed/commons/core/sql/test/TestSuite_sql.py smart_toolShed/commons/core/sql/test/Test_DbFactory.py smart_toolShed/commons/core/sql/test/Test_DbMySql.py smart_toolShed/commons/core/sql/test/Test_DbSQLite.py smart_toolShed/commons/core/sql/test/Test_F_JobAdaptator.py smart_toolShed/commons/core/sql/test/Test_F_TableJobAdaptator.py smart_toolShed/commons/core/sql/test/Test_Job.py smart_toolShed/commons/core/sql/test/Test_TableBinPathAdaptator.py smart_toolShed/commons/core/sql/test/Test_TableBinSetAdaptator.py smart_toolShed/commons/core/sql/test/Test_TableJobAdaptator.py smart_toolShed/commons/core/sql/test/Test_TableJobAdaptatorFactory.py smart_toolShed/commons/core/sql/test/Test_TableMapAdaptator.py smart_toolShed/commons/core/sql/test/Test_TableMatchAdaptator.py smart_toolShed/commons/core/sql/test/Test_TablePathAdaptator.py smart_toolShed/commons/core/sql/test/Test_TableSeqAdaptator.py smart_toolShed/commons/core/sql/test/Test_TableSetAdaptator.py smart_toolShed/commons/core/sql/test/Tst_F_RepetJob.py smart_toolShed/commons/core/sql/test/Tst_RepetJob.py smart_toolShed/commons/core/sql/test/__init__.py smart_toolShed/commons/core/stat/Stat.py smart_toolShed/commons/core/stat/__init__.py smart_toolShed/commons/core/stat/test/Test_F_Stat.py smart_toolShed/commons/core/stat/test/Test_Stat.py smart_toolShed/commons/core/stat/test/__init__.py smart_toolShed/commons/core/tree/Tree.py smart_toolShed/commons/core/tree/__init__.py smart_toolShed/commons/core/tree/test/Test_Tree.py smart_toolShed/commons/core/tree/test/__init__.py smart_toolShed/commons/core/tree/test/treeTestSuite.py smart_toolShed/commons/core/utils/FileUtils.py smart_toolShed/commons/core/utils/PipelineStepFTests.py smart_toolShed/commons/core/utils/RepetConfigParser.py smart_toolShed/commons/core/utils/RepetOptionParser.py smart_toolShed/commons/core/utils/__init__.py smart_toolShed/commons/core/utils/test/TestSuite_utils.py smart_toolShed/commons/core/utils/test/Test_FileUtils.py smart_toolShed/commons/core/utils/test/__init__.py smart_toolShed/commons/core/writer/BedWriter.py smart_toolShed/commons/core/writer/BedWriter.pyc smart_toolShed/commons/core/writer/CsvWriter.py smart_toolShed/commons/core/writer/CsvWriter.pyc smart_toolShed/commons/core/writer/EmblWriter.py smart_toolShed/commons/core/writer/EmblWriter.pyc smart_toolShed/commons/core/writer/FastaWriter.py smart_toolShed/commons/core/writer/FastaWriter.pyc smart_toolShed/commons/core/writer/FastqWriter.py smart_toolShed/commons/core/writer/FastqWriter.pyc smart_toolShed/commons/core/writer/GbWriter.py smart_toolShed/commons/core/writer/GbWriter.pyc smart_toolShed/commons/core/writer/Gff2Writer.py smart_toolShed/commons/core/writer/Gff2Writer.pyc smart_toolShed/commons/core/writer/Gff3Writer.py smart_toolShed/commons/core/writer/Gff3Writer.pyc smart_toolShed/commons/core/writer/GtfWriter.py smart_toolShed/commons/core/writer/GtfWriter.pyc smart_toolShed/commons/core/writer/MapWriter.py smart_toolShed/commons/core/writer/MapWriter.pyc smart_toolShed/commons/core/writer/MySqlTranscriptWriter.py smart_toolShed/commons/core/writer/MySqlTranscriptWriter.pyc smart_toolShed/commons/core/writer/SamWriter.py smart_toolShed/commons/core/writer/SamWriter.pyc smart_toolShed/commons/core/writer/SequenceListWriter.py smart_toolShed/commons/core/writer/SequenceListWriter.pyc smart_toolShed/commons/core/writer/TranscriptListWriter.py smart_toolShed/commons/core/writer/TranscriptListWriter.pyc smart_toolShed/commons/core/writer/TranscriptWriter.py smart_toolShed/commons/core/writer/TranscriptWriter.pyc smart_toolShed/commons/core/writer/UcscWriter.py smart_toolShed/commons/core/writer/UcscWriter.pyc smart_toolShed/commons/core/writer/WigWriter.py smart_toolShed/commons/core/writer/WigWriter.pyc smart_toolShed/commons/core/writer/WriterChooser.py smart_toolShed/commons/core/writer/WriterChooser.pyc smart_toolShed/commons/core/writer/__init__.py smart_toolShed/commons/core/writer/__init__.pyc smart_toolShed/commons/core/writer/test/Test_Gff3Writer.py smart_toolShed/commons/core/writer/test/Test_MapWriter.py smart_toolShed/commons/core/writer/test/__init__.py smart_toolShed/documentation.pdf
diffstat 596 files changed, 99522 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
Binary file smart_toolShed/README.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/File.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,55 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+public class File {
+  String name;
+  String formatType;
+  String format;
+
+
+  public File(String name, String type, String format) {
+    this.name       = name;
+    this.formatType = type;
+    this.format     = format;
+  }
+
+  public String getName() {
+    return this.name;
+  }
+
+  public String getFormatType() {
+    return this.formatType;
+  }
+
+  public String getFormat() {
+    return this.format;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Files.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,75 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+
+public class Files {
+  HashMap <String, File> files;  
+
+  public Files () {
+    files = new HashMap < String, File> ();
+  }
+
+  public void addFile(String fileName, String type, String format) {
+    this.addFile(new File(fileName, type, format));
+  }
+
+  public void addFile(File file) {
+    files.put(file.name, file);
+  }
+
+  public void clear() {
+    files.clear();
+  }
+
+  public String getType(String fileName) {
+    if (fileName == null) {
+      System.out.println("Error! Looking for format of empty file name!");
+    }
+    if (! files.containsKey(fileName)) {
+      System.out.println("Oops! Format type of file " + fileName + " is not found!");
+      return null;
+    }
+    return files.get(fileName).formatType;
+  }
+
+  public String getFormat(String fileName) {
+    if (fileName == null) {
+      System.out.println("Error! Looking for format of empty file name!");
+    }
+    if (! files.containsKey(fileName)) {
+      System.out.println("Oops! Format of file " + fileName + " is not found!");
+      return null;
+    }
+    return files.get(fileName).format;
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/FormatType.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,64 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+
+public class FormatType {
+  String type;
+  Vector < String > formats;
+
+  public FormatType (String type) {
+    this.type    = type;
+    this.formats = new Vector < String > ();
+  }
+
+  public String getType () {
+    return this.type;
+  }
+
+  public void addFormat (String format) {
+    formats.add(format);
+  }
+
+  public boolean containsFormat (String format) {
+    for (int i = 0; i < formats.size(); i++) {
+      if (((String) formats.get(i)).compareToIgnoreCase(format) == 0) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public Vector < String > getFormats () {
+    return formats;
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/FormatsContainer.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,90 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+
+public class FormatsContainer {
+
+  HashMap < String, FormatType > formatTypes;
+
+
+  public FormatsContainer() {
+    this.formatTypes = new HashMap < String, FormatType > ();
+  }
+
+
+  public void addFormat(String type, String format) {
+    FormatType formatType;
+    if (formatTypes.containsKey(type)) {
+      formatType = this.formatTypes.get(type);
+    }
+    else {
+      formatType = new FormatType(type);
+      this.formatTypes.put(type, formatType);
+    }
+    formatType.addFormat(format);
+  }
+
+
+  public Vector < String > getFormatTypes () {
+    Vector < String > v = new Vector < String > ();
+    v.addAll(this.formatTypes.keySet());
+    return v;
+  }
+
+
+  public FormatType getFormats (String type) {
+    if (! formatTypes.containsKey(type)) {
+      System.out.print("Format type " + type + " is unavailable. Got: ");
+      Iterator it = formatTypes.entrySet().iterator();
+      while (it.hasNext()) {
+        Map.Entry pairs = (Map.Entry) it.next();
+        System.out.print(pairs.getKey() + " ");
+      }
+      System.out.println();
+    }
+    return formatTypes.get(type);
+  }
+
+
+  public String getFormatType (String format) {
+    for (Iterator it = formatTypes.keySet().iterator(); it.hasNext(); ) {
+      Object type       =  it.next();
+      Object formatType = formatTypes.get(type);
+      if (((FormatType) formatType).containsFormat(format)) {
+        return (String) type;
+      }
+    }
+    return null;
+  }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/FormatsReader.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,83 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.io.File;
+import java.io.*;
+
+
+public class FormatsReader {
+
+  String fileName;
+  Vector < FormatType > formatTypes;
+  Vector < String > typeNames;
+
+
+  public FormatsReader(String fileName) {
+    this.fileName    = fileName;  
+    this.formatTypes = new Vector < FormatType > ();
+  }
+
+
+  public boolean read() {
+    File file = new File(this.fileName);
+
+    try {
+      BufferedReader reader = new BufferedReader(new FileReader(file));
+      String     line = null;
+      String[]   lineElements;
+      String[]   formats;
+      String     typeName;
+
+      while ((line = reader.readLine()) != null) {
+        if (line.length() > 0) {
+          lineElements = line.split(":");
+          typeName     = lineElements[0].trim();
+          formats      = lineElements[1].split(",");
+          for (int i = 0; i < formats.length; i++) {
+            Global.formats.addFormat(typeName, formats[i].trim());
+          }
+        }
+      }
+
+      reader.close();
+    }
+    catch (FileNotFoundException e) {
+      return false;
+    }
+    catch (IOException e) {
+      return false;
+    }
+
+    return true;
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Global.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,70 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.Vector;
+import java.util.HashMap;
+import javax.swing.DefaultListModel;
+import javax.swing.JButton;
+import javax.swing.JTextField;
+
+public class Global {
+
+  public static int logAreaSize = 100;
+
+  public static String smartConfFileName = "smart.conf";
+
+  public static String smartProgramsFileName = "programs.txt";
+
+  public static String smartFormatsFileName = "formats.txt";
+
+  public static String pythonPath = new String();
+
+  public static String pythonCommand = "python";
+
+  public static String mysqlCommand = "mysql";
+
+  public static String rCommand = "R";
+
+  public static Files files = new Files();
+
+  public static Vector < String > fileNames = new Vector < String >();
+
+  public static FormatsContainer formats = new FormatsContainer();
+
+  public static boolean programRunning = false;
+
+  public static HashMap < JButton, JTextField > otherFilesChooser = new HashMap < JButton, JTextField >();
+
+  public static HashMap < JButton, JTextField > otherDirectoriesChooser = new HashMap < JButton, JTextField >();
+
+  public static HashMap < JButton, JTextField > otherFileConcatenationChooser = new HashMap < JButton, JTextField >();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Installer/Old/PasswordAsker.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,87 @@
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import java.util.concurrent.CountDownLatch;
+
+public class PasswordAsker {
+
+  static String password;
+  static JFrame frame;
+  static CountDownLatch latch;
+
+
+  public PasswordAsker() {
+    password = null;
+    javax.swing.SwingUtilities.invokeLater(new Runnable() {
+      public void run() {
+        createAndShowGUI();
+      }
+    });
+    latch = new CountDownLatch(1);
+  }
+
+
+  private static void createAndShowGUI() {
+    //Create and set up the window.
+    frame = new JFrame("Password");
+    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+    frame.setContentPane(setMainPane());
+
+    //Display the window.
+    frame.pack();
+    frame.setVisible(true);
+  }
+
+
+  private static JPanel setMainPane() {
+    JPanel rootPanel = new JPanel(false);
+    rootPanel.setLayout(new GridLayout(0, 1));
+
+    JPanel infoPanel = new JPanel(false);
+    JLabel infoLabel = new JLabel("Please write here the password that you entered for the mySQL root account.\r\nNo information is stored nor sent. I promise.");
+    infoPanel.add(infoLabel);
+
+    JPanel passPanel = new JPanel(false);
+    passPanel.setLayout(new GridLayout(1, 0));
+    JLabel passLabel = new JLabel("password");
+    final JTextField passText = new JTextField(20);
+    passLabel.setLabelFor(passText);
+    passPanel.add(passLabel);
+    passPanel.add(passText);
+
+    JPanel  okPanel  = new JPanel(false);
+    JButton okButton = new JButton("OK");
+    okPanel.add(okButton);
+
+    okButton.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        password = passText.getText();
+        frame.setVisible(false);
+        frame.dispose();
+        latch.countDown();
+      }
+    });
+
+    rootPanel.add(infoPanel);
+    rootPanel.add(passPanel);
+    rootPanel.add(okPanel);
+
+    return rootPanel;
+  }
+
+
+  public boolean waitForPassword() {
+    try {
+      latch.await();
+    }
+    catch (InterruptedException e) {
+      return false;
+    }
+    return true;
+  }
+
+
+  public String getPassword() {
+    return password;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Installer/Old/SmartInstaller.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,167 @@
+import java.util.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.*;
+import javax.swing.*;
+import javax.swing.filechooser.*;
+import javax.swing.border.*;
+import javax.swing.SwingUtilities;
+import java.net.*;
+
+public class SmartInstaller extends JPanel implements ActionListener {
+  int       BUFFER = 1024;
+
+  JFrame    mainFrame;
+  JTextArea logArea;
+
+  // configuration chooser buttons
+  String       configurations[] = {"32 bits", "64 bits"};
+  JRadioButton configurationButtons[];
+
+  // program chooser buttons
+  String    programChoosers[] = {"R", "R Color Brewer Package", "R HMisc Package", "MySQL", "MySQL account", "Python 2.6", "Python DB", "S-MART"};
+  JCheckBox programChooserButtons[];
+
+  JButton   goButton;
+
+  // install directory
+  JButton    installDirectoryChooserButton;
+  JTextField installDirectoryChooserTextField;
+
+
+  public SmartInstaller() {
+    super();
+
+    Box box = Box.createVerticalBox();
+
+    // Header
+    JPanel       headerPanel = new JPanel(false);
+    JTextArea    headerArea  = new JTextArea("This is the S-MART installation tool.\r\nIt will download and install the needed softwares, as well as S-MART itself.\r\nYou can unselect the software that you already have installed.\r\nDuring the installation, accept all the default parameters.\r\nPlease remember the root password if you install MySQL!");
+    TitledBorder headerBorder = BorderFactory.createTitledBorder("Wellcome to the S-MART installer!");
+    headerArea.setEditable(false);
+    headerArea.setBackground(headerPanel.getBackground());
+    headerPanel.add(headerArea);
+    headerPanel.setBorder(headerBorder);
+
+
+    // Configuration
+    JPanel configurationPanel = new JPanel(false);
+    configurationPanel.setLayout(new GridLayout(1, 0));
+    configurationButtons = new JRadioButton[configurations.length];
+    ButtonGroup configurationGroup = new ButtonGroup();
+    for (int i = 0; i < configurations.length; i++) {
+      JRadioButton button = new JRadioButton(configurations[i]);
+      configurationPanel.add(button);
+      configurationButtons[i] = button;
+      configurationGroup.add(button);
+    }
+    configurationButtons[0].setSelected(true);
+    TitledBorder configurationBorder = BorderFactory.createTitledBorder("Configuration");
+    configurationPanel.setBorder(configurationBorder);
+
+
+    // Program chooser panel
+    JPanel programPanel = new JPanel(false);
+    programPanel.setLayout(new GridLayout(0, 1));
+
+    JLabel programLabel = new JLabel("Choose which programs to install:");
+    programPanel.add(programLabel);
+    programChooserButtons = new JCheckBox[programChoosers.length];
+    for (int i = 0; i < programChoosers.length; i++) {
+      JCheckBox button = new JCheckBox(programChoosers[i]);
+      button.setSelected(true);
+      programPanel.add(button);
+      programChooserButtons[i] = button;
+    }
+    TitledBorder programBorder = BorderFactory.createTitledBorder("Programs");
+    programPanel.setBorder(programBorder);
+
+    // Install directory chooser
+    JPanel installDirectoryChooserPanel = new JPanel(false);
+    installDirectoryChooserPanel.setLayout(new GridLayout(1, 0));
+    JLabel installDirectoryChooserLabel = new JLabel("Choose a directory to install S-MART: ");
+    installDirectoryChooserTextField = new JTextField();
+    installDirectoryChooserButton = new JButton("Open...");
+    installDirectoryChooserButton.addActionListener(this);
+
+    installDirectoryChooserPanel.add(installDirectoryChooserLabel);
+    installDirectoryChooserPanel.add(installDirectoryChooserTextField);
+    installDirectoryChooserPanel.add(installDirectoryChooserButton);
+    TitledBorder installDirectoryChooserBorder = BorderFactory.createTitledBorder("Installation directory");
+    installDirectoryChooserPanel.setBorder(installDirectoryChooserBorder);
+
+    // GO!
+    JPanel goPanel = new JPanel(false);
+    goButton = new JButton("GO!");
+    goButton.addActionListener(this);
+    goButton.setSelected(true);
+    goPanel.add(goButton);
+    TitledBorder goBorder = BorderFactory.createTitledBorder("Start install");
+    goPanel.setBorder(goBorder);
+
+    // Log
+    logArea = new JTextArea(10, 120);
+    logArea.setFont(new Font("Monospaced", logArea.getFont().getStyle(), logArea.getFont().getSize()));
+    JScrollPane logScroll  = new JScrollPane(logArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+    TitledBorder logBorder = BorderFactory.createTitledBorder("Log");
+    logScroll.setBorder(logBorder);
+
+    GridLayout horizontalLayout = new GridLayout(1, 0);
+
+    box.add(headerPanel);
+    box.add(configurationPanel);
+    box.add(programPanel);
+    box.add(installDirectoryChooserPanel);
+    box.add(goPanel);
+    box.add(logScroll);
+
+    add(box);
+  }
+
+
+  public void actionPerformed(ActionEvent e) {
+
+    // Install directories chooser
+    if (e.getSource() == goButton) {
+      boolean[] selectedPrograms = new boolean[programChoosers.length];
+      for (int i = 0; i < programChoosers.length; i++) {
+        selectedPrograms[i] = programChooserButtons[i].isSelected();
+      }
+      SmartInstallerTask task = new SmartInstallerTask(logArea, selectedPrograms, installDirectoryChooserTextField.getText(), (configurationButtons[0].isSelected())? 0: 1);
+      task.execute();
+    }
+    // Install directories chooser
+    else if (e.getSource() == installDirectoryChooserButton) {
+      JFileChooser chooser = new JFileChooser();
+      chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        installDirectoryChooserTextField.setText(chooser.getSelectedFile().getPath());
+      }
+    }
+  }
+
+  private static void createAndShowGUI() {
+    // Create and set up the window.
+    JFrame mainFrame = new JFrame("S-Mart Installer");
+    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+    //Create and set up the content pane.
+    JComponent newContentPane = new SmartInstaller();
+    newContentPane.setOpaque(true);
+    mainFrame.setContentPane(newContentPane);
+
+    // Display the window.
+    mainFrame.pack();
+    mainFrame.setVisible(true);
+  }
+
+
+  public static void main(String[] args) {
+    javax.swing.SwingUtilities.invokeLater(new Runnable() {
+      public void run() {
+        createAndShowGUI();
+      }
+    });
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Installer/Old/SmartInstallerTask.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,455 @@
+import java.util.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.*;
+import javax.swing.*;
+import javax.swing.filechooser.*;
+import javax.swing.border.*;
+import javax.swing.SwingUtilities;
+import java.net.*;
+import java.util.Stack;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+public class SmartInstallerTask extends SwingWorker<Boolean, String> {
+
+  int BUFFER = 1024;
+
+  int       architecture         = 0;
+  String    installDirectoryName = null;
+  JTextArea logArea              = null;
+  boolean[] selectedPrograms     = null;
+
+  // program chooser buttons
+  String    programChoosers[] = {"R", "R Color Brewer Package", "R HMisc Package", "MySQL", "MySQL account", "Python 2.6", "Python DB", "S-MART"};
+
+  // Web addresses for the tools
+  String packageAddresses[][] = {
+    {"http://cran.cict.fr/bin/windows/base/R-2.11.0-win32.exe", "http://cran.cict.fr/bin/windows64/base/R-2.11.0-win64.exe"},
+    {"", ""},
+    {"", ""},
+    {"http://mirrors.ircam.fr/pub/mysql/Downloads/MySQL-5.1/mysql-essential-5.1.47-win32.msi", "http://mirrors.ircam.fr/pub/mysql/Downloads/MySQL-5.1/mysql-essential-5.1.47-winx64.msi"},
+    {"", ""},
+    {"http://www.python.org/ftp/python/2.6.5/python-2.6.5.msi", "http://www.python.org/ftp/python/2.6.5/python-2.6.5.amd64.msi"},
+    {"http://www.technicalbard.com/files/MySQL-python-1.2.2.win32-py2.6.exe", "http://www.technicalbard.com/files/MySQL-python-1.2.2.win32-py2.6.exe"},
+    {"http://urgi.versailles.inra.fr/download/s-mart/s-mart.zip", "http://urgi.versailles.inra.fr/download/s-mart/s-mart.zip"}
+  };
+
+  // Packages to install
+  String rPackages[] = {"RColorBrewer", "Hmisc"};
+
+  // Script lines
+  String scriptLines[][] = {
+    {"\"<INSTALLDIR>\\R-2.11.0-win32.exe\"", "\"<INSTALLDIR>\\R-2.11.0-win64.exe\""},
+    {"\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installRColorBrewer.R\"", "\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installRColorBrewer.R\""},
+    {"\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installHmisc.R\"", "\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installHmisc.R\""},
+    {"msiexec /i \"<INSTALLDIR>\\mysql-essential-5.1.47-win32.msi\"", "msiexec /i \"<INSTALLDIR>\\mysql-essential-5.1.47-winx64.msi\""},
+    {"", ""},
+    {"msiexec /i \"<INSTALLDIR>\\python-2.6.5.msi\"", "msiexec /i \"<INSTALLDIR>\\python-2.6.5.amd64.msi\""},
+    {"<INSTALLDIR>\\MySQL-python-1.2.2.win32-py2.6.exe", "<INSTALLDIR>\\MySQL-python-1.2.2.win32-py2.6.exe"},
+    {"", ""}
+  };
+
+  // Files to uncompress
+  String compressedFiles[][] = {
+    {"", ""},
+    {"", ""},
+    {"", ""},
+    {"", ""},
+    {"", ""},
+    {"", ""},
+    {"", ""},
+    {"<INSTALLDIR>\\s-mart.zip", "<INSTALLDIR>\\s-mart.zip"}
+  };
+
+
+  public SmartInstallerTask(JTextArea ta, boolean[] b, String s, int a) {
+    logArea              = ta;
+    selectedPrograms     = b;
+    installDirectoryName = s;
+    architecture         = a;
+  }
+
+
+  @Override
+  public Boolean doInBackground() {
+    boolean installOk;
+    publish("Starting install\n");
+    writeFiles();
+    for (int i = 0; i < selectedPrograms.length; i++) {
+      if (selectedPrograms[i]) {
+        if (! install(i)) {
+          return Boolean.FALSE;
+        }
+      }
+    }
+    removeFiles();
+    setEnvironmentVariables();
+    publish("Ending install\n");
+    return Boolean.TRUE;
+  }
+
+
+  @Override
+  protected void process(List<String> chunks) {
+    for (String chunk: chunks) {
+      logArea.append(chunk);
+    }
+  }
+
+
+  private boolean launch(String command) {
+    return realLaunch(new ProcessBuilder(command), command);
+  }
+
+  private boolean launch(String[] command) {
+    return realLaunch(new ProcessBuilder(command), Arrays.toString(command));
+  }
+
+  private boolean realLaunch(ProcessBuilder pb, String command) {
+    BufferedReader outputReader;
+    pb                          = pb.redirectErrorStream(true);
+    Process        process      = null;
+    publish("      Starting command '" + command + "'\n");
+    try {
+      process = pb.start();
+      BufferedInputStream outputStream = new BufferedInputStream(process.getInputStream());
+      InputStream is        = process.getInputStream();
+      InputStreamReader isr = new InputStreamReader(is);
+      outputReader          = new BufferedReader(isr);
+    }
+    catch (Exception exception) {
+      publish("      !Process cannot be started (command is '" + command + "')!\n");
+      exception.printStackTrace();
+      return false;
+    }
+    if (outputReader == null) {
+      publish("      !Problem in the output of the command!\n");
+      return false;
+    }
+    else {
+      publish("      Output is:\n");
+      try {
+        publish("        ---\n");
+        String line;
+        while ((line = outputReader.readLine()) != null) {
+          publish("        " + line + "\r\n");
+        }
+        publish("        ---\n");
+      }
+      catch (IOException e) {
+        publish("      !Cannot get the output of the command!\n");
+        return false;
+      }
+    }
+    int exitValue = process.exitValue();
+    if (exitValue != 0) {
+      publish("      !Problem during the execution of the command '" + command + "'!\n");
+      return false;
+    }
+    publish("      Ending command '" + command + "'\n");
+    return true;
+  }
+
+
+  private File lookForFile(String fileName, String[] putativePlaces) {
+    publish("      Looking for file " + fileName + "\n");
+    for (String place: putativePlaces) {
+      File file = new File(place, fileName);
+      publish("      Look at " + file.getAbsolutePath() + "\n");
+      if (file.exists()) {
+        publish("      Found it in expected place " + file.getAbsolutePath() + "\n");
+        return file;
+      }
+    }
+    Stack<File> files = new Stack<File>();
+    files.push(new File("\\"));
+    while (! files.empty()) {
+      File file = files.pop();
+      for (File childFile: file.listFiles()) {
+        if (childFile.isDirectory()) {
+          files.push(childFile);
+        }
+        else {
+          if (fileName.compareToIgnoreCase(childFile.getName()) == 0) {
+            publish("      Found it in unexpected place " + childFile.getAbsolutePath() + "\n");
+            return childFile;
+          }
+        }
+      }
+    }
+    publish("      !Cannot file file '" + fileName + "'!\n");
+    return null;
+  }
+
+
+  private boolean writeFile(String fileName, String content) {
+    try {
+      FileWriter     fw = new FileWriter(fileName);
+      BufferedWriter bw = new BufferedWriter(fw);
+      bw.write(content);
+      bw.close();
+      fw.close();
+    }
+    catch (Exception e) {
+      publish("      !Cannot write file '" + fileName + "'!\n");
+      return false;
+    }
+    return true;
+  }
+
+
+  private boolean removeFile(String fileName) {
+    File file = new File(fileName);
+    if (file.exists()) {
+      if (! file.delete()) {
+        publish("      !Cannot delete file '" + file.getAbsolutePath() + "'!\n");
+        return false;
+      }
+    }
+    return true;
+  }
+
+
+  private boolean writeFiles() {
+    for (String rPackage: rPackages) {
+      String fileName = installDirectoryName + File.separator + "install" + rPackage + ".R";
+      String content  = "install.packages(\"" + rPackage + "\", repos = \"http://cran.cict.fr\", dependencies = TRUE)\n";
+      if (! writeFile(fileName, content)) {
+        publish("    !Cannot write file for R package '" + rPackage + "'!\n");
+        return false;
+      }
+    }
+    String fileName = installDirectoryName + File.separator + "createUser.sql";
+    String content  = "CREATE USER 'smart'@'localhost';\nGRANT ALL PRIVILEGES ON *.* TO 'smart'@'localhost' WITH GRANT OPTION;\nCREATE DATABASE smart;\nGRANT ALL ON smart.* TO 'smart'@'localhost';\n";
+    if (! writeFile(fileName, content)) {
+      publish("    !Cannot write mySQL configuration file!\n");
+      return false;
+    }
+    return true;
+  }
+
+  private boolean removeFiles() {
+    for (String rPackage: rPackages) {
+      File file = new File(installDirectoryName + File.separator + "install" + rPackage + ".R");
+      if (! file.delete()) {
+        publish("!Cannot delete R install file for " + rPackage + "!\n");
+        return false;
+      }
+    }
+    File file = new File(installDirectoryName + File.separator + "createUser.sql");
+    if (! file.delete()) {
+      publish("!Cannot delete mySQL configuration file!\n");
+      return false;
+    }
+    return true;
+  }
+
+  private boolean install(int element) {
+    publish("  Starting install of " + programChoosers[element] + "\n");
+    downloadPackage(element);
+    executeInstall(element);
+    uncompressPackage(element);
+    removePackage(element);
+    postProcess(element);
+    publish("  Ending install of " + programChoosers[element] + "\n");
+    return true;
+  }
+
+
+  private String getLocalName(String remoteName) {
+    String localName = installDirectoryName + File.separator + (new File(remoteName)).getName();
+    int    position  = localName.indexOf("?");
+    if (position >= 0) {
+      localName = localName.substring(0, position);
+    }
+    return localName;
+  }
+
+
+  private boolean downloadPackage(int element) {
+    String fileName  = packageAddresses[element][architecture];
+    if (! "".equals(fileName)) {
+      publish("    Starting download of " + programChoosers[element] + "\n");
+      try {
+        BufferedInputStream  bis = new BufferedInputStream(new URL(fileName).openStream());
+        FileOutputStream     fos = new FileOutputStream(getLocalName(fileName));
+        BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER);
+        byte[] data = new byte[BUFFER];
+        int x       = 0;
+        while((x = bis.read(data, 0, BUFFER)) >= 0) {
+          bos.write(data, 0, x);
+        }
+        bos.close();
+        fos.close();
+        bis.close();
+      }
+      catch (IOException e) {
+        publish("    !Cannot download file '" + fileName + "'!\n");
+        return false;
+      }
+      publish("    Ending download of " + programChoosers[element] + "\n");
+    }
+    return true;
+  }
+
+
+  private String replaceSubstring(String line) {
+    if (line.contains("<INSTALLDIR>")) {
+      String protectedDirectory = installDirectoryName.replaceAll("\\\\", "\\\\\\\\");
+      line = line.replaceAll("<INSTALLDIR>", protectedDirectory);
+    }
+    if (line.contains("<RFILE>")) {
+      String   userName = System.getenv().get("USERNAME");
+      String[] possibleRDirectories = {"C:\\Program Files\\R-2.11.0", "C:\\Documents and Settings\\" + userName + "\\Mes documents\\R\\R-2.11.0\\bin", "C:\\Documents and Settings\\" + userName + "\\My documents\\R\\R-2.11.0\\bin"};
+      String rDirectory = lookForFile("'.exe", possibleRDirectories).getAbsolutePath();
+      rDirectory = rDirectory.replaceAll("\\\\", "\\\\\\\\");
+      line = line.replaceAll("<RFILE>", rDirectory);
+    }
+    if (line.contains("<MYSQLFILE>")) {
+      String   userName = System.getenv().get("USERNAME");
+      String[] possibleRDirectories = {"C:\\Program Files\\MySQL\\MySQL Server 5.1\\bin", "C:\\Documents and Settings\\" + userName + "\\Mes documents\\MySQL\\MySQL Server 5.1\\bin", "C:\\Documents and Settings\\" + userName + "\\My documents\\MySQL\\MySQL Server 5.1\\bin"};
+      String rDirectory = lookForFile("mysql.exe", possibleRDirectories).getAbsolutePath();
+      rDirectory = rDirectory.replaceAll("\\\\", "\\\\\\\\");
+      line = line.replaceAll("<MYSQLFILE>", rDirectory);
+    }
+    return line;
+  }
+
+
+  private boolean executeInstall(int element) {
+    String commands           = scriptLines[element][architecture];
+    if (! "".equals(commands)) {
+      for (String command: commands.split(";")) {
+        command = replaceSubstring(command);
+        publish("    Starting command '" + command + "'\n");
+        Process process = null;
+        try {
+          process = Runtime.getRuntime().exec(command);
+        }
+        catch (IOException e) {
+          publish("    !Cannot execute command '" + command + "'!\n");
+          return false;
+        }
+        try {
+          process.waitFor();
+        }
+        catch (InterruptedException e) {
+          publish("    !Cannot wait for the end of the command '" + command + "'!\n");
+          return false;
+        }
+        int exitValue = process.exitValue();
+        if (exitValue != 0) {
+          publish("    !Problem during the execution of the command '" + command + "'!\n");
+          return false;
+        }
+        publish("    Ending command '" + command + "'\n");
+      }
+    }
+    return true;
+  }
+
+
+  private boolean uncompressPackage(int element) {
+    String file = compressedFiles[element][architecture];
+    if (! "".equals(file)) {
+      file = replaceSubstring(file);
+      publish("    Starting uncompressing file '" + file + "'\n");
+      try {
+        FileInputStream     fis = new FileInputStream(file);
+        BufferedInputStream bis = new BufferedInputStream(fis);
+        ZipInputStream      zis = new ZipInputStream(bis);
+        ZipEntry            entry;
+        while ((entry = zis.getNextEntry()) != null) {
+          if (! entry.isDirectory()) {
+            File newFile = new File(installDirectoryName + File.separator + entry.getName());
+            // create parent directories
+            File upDirectory = newFile.getParentFile();
+            while (upDirectory != null){
+              if (! upDirectory.exists()) {
+                upDirectory.mkdir();
+                publish("      Creating directory '" + upDirectory.getAbsolutePath() + "'\n");
+              }
+              upDirectory = upDirectory.getParentFile();
+            }
+            // write the files to the disk
+            publish("      Extracting '" + entry.getName() + "' to '" + newFile.getAbsolutePath() + "'\n");
+            int  count;
+            byte data[] = new byte[BUFFER];
+            FileOutputStream     fos = new FileOutputStream(newFile);
+            BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER);
+            while ((count = zis.read(data, 0, BUFFER)) != -1){
+              bos.write(data, 0, count);
+            }
+            bos.flush();
+            bos.close();
+            fos.close();
+          }
+        }
+        zis.close();
+        bis.close();
+        fis.close();
+      }
+      catch(FileNotFoundException e) {
+        publish("    !Cannot find file '" + file + "'!\n");
+        return false;
+      }
+      catch(Exception e){
+        publish("    !Cannot uncompress file '" + file + "'!\n");
+        return false;
+      }
+      publish("    Ending uncompressing file '" + file + "'\n");
+    }
+    return true;
+  }
+
+
+  private boolean removePackage(int element) {
+    String packageName = packageAddresses[element][architecture];
+    if ("".equals(packageName)) {
+      return true;
+    }
+    String fileName = getLocalName(packageAddresses[element][architecture]);
+    return removeFile(fileName);
+  }
+
+
+  private boolean postProcess(int element) {
+    switch (element) {
+      case 4:
+        // Create mySQL user
+        PasswordAsker pa = new PasswordAsker();
+        if (! pa.waitForPassword()) {
+          publish("Problem in the password asker!\n");
+          return false;
+        }
+        String command = "\"<MYSQLFILE>\" --user=root --password=" + pa.getPassword() + " -e \"source <INSTALLDIR>\\createUser.sql\"";
+        command        = replaceSubstring(command);
+        if (! launch(command)) {
+          publish("    !Cannot create SQL accounts!\n");
+          return false;
+        }
+        return true;
+      case 7:
+        // Move S-MART files to parent directory
+        File installDirectory = new File(installDirectoryName + File.separator + "S-Mart");
+        for (File file: installDirectory.listFiles()) {
+          File destinationFile = new File(file.getParentFile().getParentFile(), file.getName());
+          if (! file.renameTo(destinationFile)) {
+            publish("     !Cannot move '" + file.getAbsolutePath() + "' to '" + destinationFile.getAbsolutePath() + "'!\n");
+          }
+        }
+        if (! installDirectory.delete()) {
+          publish("     !Cannot remove installation S-MART directory '" + installDirectory.getAbsolutePath() + "'!\n");
+        }
+    }
+    return true;
+  }
+
+
+  private boolean setEnvironmentVariables() {
+    String[] command = {"REG", "ADD", "HKCU\\Environment", "/v", "PYTHONPATH", "/t", "REG_SZ", "/d", "\"" + installDirectoryName + "\\Python\"", "/f"};
+    return launch(command);
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Installer/PasswordAsker.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,87 @@
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import java.util.concurrent.CountDownLatch;
+
+public class PasswordAsker {
+
+  static String password;
+  static JFrame frame;
+  static CountDownLatch latch;
+
+
+  public PasswordAsker() {
+    password = null;
+    javax.swing.SwingUtilities.invokeLater(new Runnable() {
+      public void run() {
+        createAndShowGUI();
+      }
+    });
+    latch = new CountDownLatch(1);
+  }
+
+
+  private static void createAndShowGUI() {
+    //Create and set up the window.
+    frame = new JFrame("Password");
+    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+    frame.setContentPane(setMainPane());
+
+    //Display the window.
+    frame.pack();
+    frame.setVisible(true);
+  }
+
+
+  private static JPanel setMainPane() {
+    JPanel rootPanel = new JPanel(false);
+    rootPanel.setLayout(new GridLayout(0, 1));
+
+    JPanel infoPanel = new JPanel(false);
+    JLabel infoLabel = new JLabel("Please write here the password that you entered for the mySQL root account.\r\nNo information is stored nor sent. I promise.");
+    infoPanel.add(infoLabel);
+
+    JPanel passPanel = new JPanel(false);
+    passPanel.setLayout(new GridLayout(1, 0));
+    JLabel passLabel = new JLabel("password");
+    final JTextField passText = new JTextField(20);
+    passLabel.setLabelFor(passText);
+    passPanel.add(passLabel);
+    passPanel.add(passText);
+
+    JPanel  okPanel  = new JPanel(false);
+    JButton okButton = new JButton("OK");
+    okPanel.add(okButton);
+
+    okButton.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        password = passText.getText();
+        frame.setVisible(false);
+        frame.dispose();
+        latch.countDown();
+      }
+    });
+
+    rootPanel.add(infoPanel);
+    rootPanel.add(passPanel);
+    rootPanel.add(okPanel);
+
+    return rootPanel;
+  }
+
+
+  public boolean waitForPassword() {
+    try {
+      latch.await();
+    }
+    catch (InterruptedException e) {
+      return false;
+    }
+    return true;
+  }
+
+
+  public String getPassword() {
+    return password;
+  }
+}
Binary file smart_toolShed/SMART/Java/Installer/SmartInstaller.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Installer/SmartInstaller.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,167 @@
+import java.util.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.*;
+import javax.swing.*;
+import javax.swing.filechooser.*;
+import javax.swing.border.*;
+import javax.swing.SwingUtilities;
+import java.net.*;
+
+public class SmartInstaller extends JPanel implements ActionListener {
+  int       BUFFER = 1024;
+
+  JFrame    mainFrame;
+  JTextArea logArea;
+
+  // configuration chooser buttons
+  String       configurations[] = {"32 bits", "64 bits"};
+  JRadioButton configurationButtons[];
+
+  // program chooser buttons
+  String    programChoosers[] = {"R", "R Color Brewer Package", "R HMisc Package", "Python 2.6", "S-MART"};
+  JCheckBox programChooserButtons[];
+
+  JButton   goButton;
+
+  // install directory
+  JButton    installDirectoryChooserButton;
+  JTextField installDirectoryChooserTextField;
+
+
+  public SmartInstaller() {
+    super();
+
+    Box box = Box.createVerticalBox();
+
+    // Header
+    JPanel       headerPanel = new JPanel(false);
+    JTextArea    headerArea  = new JTextArea("This is the S-MART installation tool.\r\nIt will download and install the needed softwares, as well as S-MART itself.\r\nYou can unselect the software that you already have installed.\r\nDuring the installation, accept all the default parameters.");
+    TitledBorder headerBorder = BorderFactory.createTitledBorder("Welcome to the S-MART installer!");
+    headerArea.setEditable(false);
+    headerArea.setBackground(headerPanel.getBackground());
+    headerPanel.add(headerArea);
+    headerPanel.setBorder(headerBorder);
+
+
+    // Configuration
+    JPanel configurationPanel = new JPanel(false);
+    configurationPanel.setLayout(new GridLayout(1, 0));
+    configurationButtons = new JRadioButton[configurations.length];
+    ButtonGroup configurationGroup = new ButtonGroup();
+    for (int i = 0; i < configurations.length; i++) {
+      JRadioButton button = new JRadioButton(configurations[i]);
+      configurationPanel.add(button);
+      configurationButtons[i] = button;
+      configurationGroup.add(button);
+    }
+    configurationButtons[0].setSelected(true);
+    TitledBorder configurationBorder = BorderFactory.createTitledBorder("Configuration");
+    configurationPanel.setBorder(configurationBorder);
+
+
+    // Program chooser panel
+    JPanel programPanel = new JPanel(false);
+    programPanel.setLayout(new GridLayout(0, 1));
+
+    JLabel programLabel = new JLabel("Choose which programs to install:");
+    programPanel.add(programLabel);
+    programChooserButtons = new JCheckBox[programChoosers.length];
+    for (int i = 0; i < programChoosers.length; i++) {
+      JCheckBox button = new JCheckBox(programChoosers[i]);
+      button.setSelected(true);
+      programPanel.add(button);
+      programChooserButtons[i] = button;
+    }
+    TitledBorder programBorder = BorderFactory.createTitledBorder("Programs");
+    programPanel.setBorder(programBorder);
+
+    // Install directory chooser
+    JPanel installDirectoryChooserPanel = new JPanel(false);
+    installDirectoryChooserPanel.setLayout(new GridLayout(1, 0));
+    JLabel installDirectoryChooserLabel = new JLabel("Choose a directory to install S-MART: ");
+    installDirectoryChooserTextField = new JTextField();
+    installDirectoryChooserButton = new JButton("Open...");
+    installDirectoryChooserButton.addActionListener(this);
+
+    installDirectoryChooserPanel.add(installDirectoryChooserLabel);
+    installDirectoryChooserPanel.add(installDirectoryChooserTextField);
+    installDirectoryChooserPanel.add(installDirectoryChooserButton);
+    TitledBorder installDirectoryChooserBorder = BorderFactory.createTitledBorder("Installation directory");
+    installDirectoryChooserPanel.setBorder(installDirectoryChooserBorder);
+
+    // GO!
+    JPanel goPanel = new JPanel(false);
+    goButton = new JButton("GO!");
+    goButton.addActionListener(this);
+    goButton.setSelected(true);
+    goPanel.add(goButton);
+    TitledBorder goBorder = BorderFactory.createTitledBorder("Start install");
+    goPanel.setBorder(goBorder);
+
+    // Log
+    logArea = new JTextArea(10, 120);
+    logArea.setFont(new Font("Monospaced", logArea.getFont().getStyle(), logArea.getFont().getSize()));
+    JScrollPane logScroll  = new JScrollPane(logArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+    TitledBorder logBorder = BorderFactory.createTitledBorder("Log");
+    logScroll.setBorder(logBorder);
+
+    GridLayout horizontalLayout = new GridLayout(1, 0);
+
+    box.add(headerPanel);
+    box.add(configurationPanel);
+    box.add(programPanel);
+    box.add(installDirectoryChooserPanel);
+    box.add(goPanel);
+    box.add(logScroll);
+
+    add(box);
+  }
+
+
+  public void actionPerformed(ActionEvent e) {
+
+    // Install directories chooser
+    if (e.getSource() == goButton) {
+      boolean[] selectedPrograms = new boolean[programChoosers.length];
+      for (int i = 0; i < programChoosers.length; i++) {
+        selectedPrograms[i] = programChooserButtons[i].isSelected();
+      }
+      SmartInstallerTask task = new SmartInstallerTask(logArea, selectedPrograms, installDirectoryChooserTextField.getText(), (configurationButtons[0].isSelected())? 0: 1);
+      task.execute();
+    }
+    // Install directories chooser
+    else if (e.getSource() == installDirectoryChooserButton) {
+      JFileChooser chooser = new JFileChooser();
+      chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        installDirectoryChooserTextField.setText(chooser.getSelectedFile().getPath());
+      }
+    }
+  }
+
+  private static void createAndShowGUI() {
+    // Create and set up the window.
+    JFrame mainFrame = new JFrame("S-Mart Installer");
+    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+    //Create and set up the content pane.
+    JComponent newContentPane = new SmartInstaller();
+    newContentPane.setOpaque(true);
+    mainFrame.setContentPane(newContentPane);
+
+    // Display the window.
+    mainFrame.pack();
+    mainFrame.setVisible(true);
+  }
+
+
+  public static void main(String[] args) {
+    javax.swing.SwingUtilities.invokeLater(new Runnable() {
+      public void run() {
+        createAndShowGUI();
+      }
+    });
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Installer/SmartInstallerTask.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,419 @@
+import java.util.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.*;
+import javax.swing.*;
+import javax.swing.filechooser.*;
+import javax.swing.border.*;
+import javax.swing.SwingUtilities;
+import java.net.*;
+import java.util.Stack;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+public class SmartInstallerTask extends SwingWorker<Boolean, String> {
+
+  int BUFFER = 1024;
+
+  int       architecture         = 0;
+  String    installDirectoryName = null;
+  JTextArea logArea              = null;
+  boolean[] selectedPrograms     = null;
+
+  // program chooser buttons
+  String    programChoosers[] = {"R", "R Color Brewer Package", "R HMisc Package", "Python 2.6", "S-MART"};
+
+  // Web addresses for the tools
+  String packageAddresses[][] = {
+    {"http://cran.cict.fr/bin/windows/base/R-2.11.0-win32.exe", "http://cran.cict.fr/bin/windows64/base/R-2.11.0-win64.exe"},
+    {"", ""},
+    {"", ""},
+    {"http://www.python.org/ftp/python/2.6.5/python-2.6.5.msi", "http://www.python.org/ftp/python/2.6.5/python-2.6.5.amd64.msi"},
+    {"http://urgi.versailles.inra.fr/content/download/1929/17848/file/s-mart-1.0.15.zip", "http://urgi.versailles.inra.fr/content/download/1929/17848/file/s-mart-1.0.15.zip"}
+  };
+
+  // Packages to install
+  String rPackages[] = {"RColorBrewer", "Hmisc"};
+
+  // Script lines
+  String scriptLines[][] = {
+    {"\"<INSTALLDIR>\\R-2.11.0-win32.exe\"", "\"<INSTALLDIR>\\R-2.11.0-win64.exe\""},
+    {"\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installRColorBrewer.R\"", "\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installRColorBrewer.R\""},
+    {"\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installHmisc.R\"", "\"<RFILE>\" CMD BATCH \"<INSTALLDIR>\\installHmisc.R\""},
+    {"msiexec /i \"<INSTALLDIR>\\python-2.6.5.msi\"", "msiexec /i \"<INSTALLDIR>\\python-2.6.5.amd64.msi\""},
+    {"", ""}
+  };
+
+  // Files to uncompress
+  String compressedFiles[][] = {
+    {"", ""},
+    {"", ""},
+    {"", ""},
+    {"", ""},
+    {"<INSTALLDIR>\\s-mart-1.0.15.zip", "<INSTALLDIR>\\s-mart-1.0.15.zip"}
+  };
+
+
+  public SmartInstallerTask(JTextArea ta, boolean[] b, String s, int a) {
+    logArea              = ta;
+    selectedPrograms     = b;
+    installDirectoryName = s;
+    architecture         = a;
+  }
+
+
+  @Override
+  public Boolean doInBackground() {
+    boolean installOk;
+    publish("Starting install\n");
+    writeFiles();
+    for (int i = 0; i < selectedPrograms.length; i++) {
+      if (selectedPrograms[i]) {
+        if (! install(i)) {
+          return Boolean.FALSE;
+        }
+      }
+    }
+    removeFiles();
+    setEnvironmentVariables();
+    publish("Ending install\n");
+    return Boolean.TRUE;
+  }
+
+
+  @Override
+  protected void process(List<String> chunks) {
+    for (String chunk: chunks) {
+      logArea.append(chunk);
+    }
+  }
+
+
+  private boolean launch(String command) {
+    return realLaunch(new ProcessBuilder(command), command);
+  }
+
+  private boolean launch(String[] command) {
+    return realLaunch(new ProcessBuilder(command), Arrays.toString(command));
+  }
+
+  private boolean realLaunch(ProcessBuilder pb, String command) {
+    BufferedReader outputReader;
+    pb                          = pb.redirectErrorStream(true);
+    Process        process      = null;
+    publish("      Starting command '" + command + "'\n");
+    try {
+      process = pb.start();
+      BufferedInputStream outputStream = new BufferedInputStream(process.getInputStream());
+      InputStream is        = process.getInputStream();
+      InputStreamReader isr = new InputStreamReader(is);
+      outputReader          = new BufferedReader(isr);
+    }
+    catch (Exception exception) {
+      publish("      !Process cannot be started (command is '" + command + "')!\n");
+      exception.printStackTrace();
+      return false;
+    }
+    if (outputReader == null) {
+      publish("      !Problem in the output of the command!\n");
+      return false;
+    }
+    else {
+      publish("      Output is:\n");
+      try {
+        publish("        ---\n");
+        String line;
+        while ((line = outputReader.readLine()) != null) {
+          publish("        " + line + "\r\n");
+        }
+        publish("        ---\n");
+      }
+      catch (IOException e) {
+        publish("      !Cannot get the output of the command!\n");
+        return false;
+      }
+    }
+    int exitValue = process.exitValue();
+    if (exitValue != 0) {
+      publish("      !Problem during the execution of the command '" + command + "'!\n");
+      return false;
+    }
+    publish("      Ending command '" + command + "'\n");
+    return true;
+  }
+
+
+  private File lookForFile(String fileName, String[] putativePlaces) {
+    publish("      Looking for file " + fileName + "\n");
+    for (String place: putativePlaces) {
+      File file = new File(place, fileName);
+      publish("      Look at " + file.getAbsolutePath() + "\n");
+      if (file.exists()) {
+        publish("      Found it in expected place " + file.getAbsolutePath() + "\n");
+        return file;
+      }
+    }
+    Stack<File> files = new Stack<File>();
+    files.push(new File("\\"));
+    while (! files.empty()) {
+      File file = files.pop();
+      for (File childFile: file.listFiles()) {
+        if (childFile.isDirectory()) {
+          files.push(childFile);
+        }
+        else {
+          if (fileName.compareToIgnoreCase(childFile.getName()) == 0) {
+            publish("      Found it in unexpected place " + childFile.getAbsolutePath() + "\n");
+            return childFile;
+          }
+        }
+      }
+    }
+    publish("      !Cannot file file '" + fileName + "'!\n");
+    return null;
+  }
+
+
+  private boolean writeFile(String fileName, String content) {
+    try {
+      FileWriter     fw = new FileWriter(fileName);
+      BufferedWriter bw = new BufferedWriter(fw);
+      bw.write(content);
+      bw.close();
+      fw.close();
+    }
+    catch (Exception e) {
+      publish("      !Cannot write file '" + fileName + "'!\n");
+      return false;
+    }
+    return true;
+  }
+
+
+  private boolean removeFile(String fileName) {
+    File file = new File(fileName);
+    if (file.exists()) {
+      if (! file.delete()) {
+        publish("      !Cannot delete file '" + file.getAbsolutePath() + "'!\n");
+        return false;
+      }
+    }
+    return true;
+  }
+
+
+  private boolean writeFiles() {
+    for (String rPackage: rPackages) {
+      String fileName = installDirectoryName + File.separator + "install" + rPackage + ".R";
+      String content  = "install.packages(\"" + rPackage + "\", repos = \"http://cran.cict.fr\", dependencies = TRUE)\n";
+      if (! writeFile(fileName, content)) {
+        publish("    !Cannot write file for R package '" + rPackage + "'!\n");
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private boolean removeFiles() {
+    for (String rPackage: rPackages) {
+      File file = new File(installDirectoryName + File.separator + "install" + rPackage + ".R");
+      if (! file.delete()) {
+        publish("!Cannot delete R install file for " + rPackage + "!\n");
+        return false;
+      }
+    }
+    File file = new File(installDirectoryName + File.separator + "createUser.sql");
+    if (! file.delete()) {
+      publish("!Cannot delete mySQL configuration file!\n");
+      return false;
+    }
+    return true;
+  }
+
+  private boolean install(int element) {
+    publish("  Starting install of " + programChoosers[element] + "\n");
+    downloadPackage(element);
+    executeInstall(element);
+    uncompressPackage(element);
+    removePackage(element);
+    postProcess(element);
+    publish("  Ending install of " + programChoosers[element] + "\n");
+    return true;
+  }
+
+
+  private String getLocalName(String remoteName) {
+    String localName = installDirectoryName + File.separator + (new File(remoteName)).getName();
+    int    position  = localName.indexOf("?");
+    if (position >= 0) {
+      localName = localName.substring(0, position);
+    }
+    return localName;
+  }
+
+
+  private boolean downloadPackage(int element) {
+    String fileName  = packageAddresses[element][architecture];
+    if (! "".equals(fileName)) {
+      publish("    Starting download of " + programChoosers[element] + "\n");
+      try {
+        BufferedInputStream  bis = new BufferedInputStream(new URL(fileName).openStream());
+        FileOutputStream     fos = new FileOutputStream(getLocalName(fileName));
+        BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER);
+        byte[] data = new byte[BUFFER];
+        int x       = 0;
+        while((x = bis.read(data, 0, BUFFER)) >= 0) {
+          bos.write(data, 0, x);
+        }
+        bos.close();
+        fos.close();
+        bis.close();
+      }
+      catch (IOException e) {
+        publish("    !Cannot download file '" + fileName + "'!\n");
+        return false;
+      }
+      publish("    Ending download of " + programChoosers[element] + "\n");
+    }
+    return true;
+  }
+
+
+  private String replaceSubstring(String line) {
+    if (line.contains("<INSTALLDIR>")) {
+      String protectedDirectory = installDirectoryName.replaceAll("\\\\", "\\\\\\\\");
+      line = line.replaceAll("<INSTALLDIR>", protectedDirectory);
+    }
+    if (line.contains("<RFILE>")) {
+      String   userName = System.getenv().get("USERNAME");
+      String[] possibleRDirectories = {"C:\\Program Files\\R-2.11.0", "C:\\Documents and Settings\\" + userName + "\\Mes documents\\R\\R-2.11.0\\bin", "C:\\Documents and Settings\\" + userName + "\\My documents\\R\\R-2.11.0\\bin"};
+      String rDirectory = lookForFile("'.exe", possibleRDirectories).getAbsolutePath();
+      rDirectory = rDirectory.replaceAll("\\\\", "\\\\\\\\");
+      line = line.replaceAll("<RFILE>", rDirectory);
+    }
+    return line;
+  }
+
+
+  private boolean executeInstall(int element) {
+    String commands           = scriptLines[element][architecture];
+    if (! "".equals(commands)) {
+      for (String command: commands.split(";")) {
+        command = replaceSubstring(command);
+        publish("    Starting command '" + command + "'\n");
+        Process process = null;
+        try {
+          process = Runtime.getRuntime().exec(command);
+        }
+        catch (IOException e) {
+          publish("    !Cannot execute command '" + command + "'!\n");
+          return false;
+        }
+        try {
+          process.waitFor();
+        }
+        catch (InterruptedException e) {
+          publish("    !Cannot wait for the end of the command '" + command + "'!\n");
+          return false;
+        }
+        int exitValue = process.exitValue();
+        if (exitValue != 0) {
+          publish("    !Problem during the execution of the command '" + command + "'!\n");
+          return false;
+        }
+        publish("    Ending command '" + command + "'\n");
+      }
+    }
+    return true;
+  }
+
+
+  private boolean uncompressPackage(int element) {
+    String file = compressedFiles[element][architecture];
+    if (! "".equals(file)) {
+      file = replaceSubstring(file);
+      publish("    Starting uncompressing file '" + file + "'\n");
+      try {
+        FileInputStream     fis = new FileInputStream(file);
+        BufferedInputStream bis = new BufferedInputStream(fis);
+        ZipInputStream      zis = new ZipInputStream(bis);
+        ZipEntry            entry;
+        while ((entry = zis.getNextEntry()) != null) {
+          if (! entry.isDirectory()) {
+            File newFile = new File(installDirectoryName + File.separator + entry.getName());
+            // create parent directories
+            File upDirectory = newFile.getParentFile();
+            while (upDirectory != null){
+              if (! upDirectory.exists()) {
+                upDirectory.mkdir();
+                publish("      Creating directory '" + upDirectory.getAbsolutePath() + "'\n");
+              }
+              upDirectory = upDirectory.getParentFile();
+            }
+            // write the files to the disk
+            publish("      Extracting '" + entry.getName() + "' to '" + newFile.getAbsolutePath() + "'\n");
+            int  count;
+            byte data[] = new byte[BUFFER];
+            FileOutputStream     fos = new FileOutputStream(newFile);
+            BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER);
+            while ((count = zis.read(data, 0, BUFFER)) != -1){
+              bos.write(data, 0, count);
+            }
+            bos.flush();
+            bos.close();
+            fos.close();
+          }
+        }
+        zis.close();
+        bis.close();
+        fis.close();
+      }
+      catch(FileNotFoundException e) {
+        publish("    !Cannot find file '" + file + "'!\n");
+        return false;
+      }
+      catch(Exception e){
+        publish("    !Cannot uncompress file '" + file + "'!\n");
+        return false;
+      }
+      publish("    Ending uncompressing file '" + file + "'\n");
+    }
+    return true;
+  }
+
+
+  private boolean removePackage(int element) {
+    String packageName = packageAddresses[element][architecture];
+    if ("".equals(packageName)) {
+      return true;
+    }
+    String fileName = getLocalName(packageAddresses[element][architecture]);
+    return removeFile(fileName);
+  }
+
+
+  private boolean postProcess(int element) {
+    switch (element) {
+      case 4:
+        // Move S-MART files to parent directory
+        File installDirectory = new File(installDirectoryName + File.separator + "S-Mart");
+        for (File file: installDirectory.listFiles()) {
+          File destinationFile = new File(file.getParentFile().getParentFile(), file.getName());
+          if (! file.renameTo(destinationFile)) {
+            publish("     !Cannot move '" + file.getAbsolutePath() + "' to '" + destinationFile.getAbsolutePath() + "'!\n");
+          }
+        }
+        if (! installDirectory.delete()) {
+          publish("     !Cannot remove installation S-MART directory '" + installDirectory.getAbsolutePath() + "'!\n");
+        }
+    }
+    return true;
+  }
+
+
+  private boolean setEnvironmentVariables() {
+    String[] command = {"REG", "ADD", "HKCU\\Environment", "/v", "PYTHONPATH", "/t", "REG_SZ", "/d", "\"" + installDirectoryName + "\\Python\"", "/f"};
+    return launch(command);
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Installer/build.sh	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,5 @@
+#! /bin/sh
+
+rm -rf SmartInstaller.jar
+javac *.java
+jar cvfm SmartInstaller.jar manifest.txt *.class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Installer/manifest.txt	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Created-By: Matthias Zytnicki
+Main-Class: SmartInstaller
Binary file smart_toolShed/SMART/Java/Installer/s-mart.zip has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/LICENSE.txt	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,506 @@
+
+CeCILL FREE SOFTWARE LICENSE AGREEMENT
+
+
+    Notice
+
+This Agreement is a Free Software license agreement that is the result
+of discussions between its authors in order to ensure compliance with
+the two main principles guiding its drafting:
+
+    * firstly, compliance with the principles governing the distribution
+      of Free Software: access to source code, broad rights granted to
+      users,
+    * secondly, the election of a governing law, French law, with which
+      it is conformant, both as regards the law of torts and
+      intellectual property law, and the protection that it offers to
+      both authors and holders of the economic rights over software.
+
+The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre])
+license are:
+
+Commissariat à l'Energie Atomique - CEA, a public scientific, technical
+and industrial research establishment, having its principal place of
+business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France.
+
+Centre National de la Recherche Scientifique - CNRS, a public scientific
+and technological establishment, having its principal place of business
+at 3 rue Michel-Ange, 75794 Paris cedex 16, France.
+
+Institut National de Recherche en Informatique et en Automatique -
+INRIA, a public scientific and technological establishment, having its
+principal place of business at Domaine de Voluceau, Rocquencourt, BP
+105, 78153 Le Chesnay cedex, France.
+
+
+    Preamble
+
+The purpose of this Free Software license agreement is to grant users
+the right to modify and redistribute the software governed by this
+license within the framework of an open source distribution model.
+
+The exercising of these rights is conditional upon certain obligations
+for users so as to preserve this status for all subsequent redistributions.
+
+In consideration of access to the source code and the rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty and the software's author, the holder of the
+economic rights, and the successive licensors only have limited liability.
+
+In this respect, the risks associated with loading, using, modifying
+and/or developing or reproducing the software by the user are brought to
+the user's attention, given its Free Software status, which may make it
+complicated to use, with the result that its use is reserved for
+developers and experienced professionals having in-depth computer
+knowledge. Users are therefore encouraged to load and test the
+suitability of the software as regards their requirements in conditions
+enabling the security of their systems and/or data to be ensured and,
+more generally, to use and operate it in the same conditions of
+security. This Agreement may be freely reproduced and published,
+provided it is not altered, and that no provisions are either added or
+removed herefrom.
+
+This Agreement may apply to any or all software for which the holder of
+the economic rights decides to submit the use thereof to its provisions.
+
+
+    Article 1 - DEFINITIONS
+
+For the purpose of this Agreement, when the following expressions
+commence with a capital letter, they shall have the following meaning:
+
+Agreement: means this license agreement, and its possible subsequent
+versions and annexes.
+
+Software: means the software in its Object Code and/or Source Code form
+and, where applicable, its documentation, "as is" when the Licensee
+accepts the Agreement.
+
+Initial Software: means the Software in its Source Code and possibly its
+Object Code form and, where applicable, its documentation, "as is" when
+it is first distributed under the terms and conditions of the Agreement.
+
+Modified Software: means the Software modified by at least one
+Contribution.
+
+Source Code: means all the Software's instructions and program lines to
+which access is required so as to modify the Software.
+
+Object Code: means the binary files originating from the compilation of
+the Source Code.
+
+Holder: means the holder(s) of the economic rights over the Initial
+Software.
+
+Licensee: means the Software user(s) having accepted the Agreement.
+
+Contributor: means a Licensee having made at least one Contribution.
+
+Licensor: means the Holder, or any other individual or legal entity, who
+distributes the Software under the Agreement.
+
+Contribution: means any or all modifications, corrections, translations,
+adaptations and/or new functions integrated into the Software by any or
+all Contributors, as well as any or all Internal Modules.
+
+Module: means a set of sources files including their documentation that
+enables supplementary functions or services in addition to those offered
+by the Software.
+
+External Module: means any or all Modules, not derived from the
+Software, so that this Module and the Software run in separate address
+spaces, with one calling the other when they are run.
+
+Internal Module: means any or all Module, connected to the Software so
+that they both execute in the same address space.
+
+GNU GPL: means the GNU General Public License version 2 or any
+subsequent version, as published by the Free Software Foundation Inc.
+
+Parties: mean both the Licensee and the Licensor.
+
+These expressions may be used both in singular and plural form.
+
+
+    Article 2 - PURPOSE
+
+The purpose of the Agreement is the grant by the Licensor to the
+Licensee of a non-exclusive, transferable and worldwide license for the
+Software as set forth in Article 5 hereinafter for the whole term of the
+protection granted by the rights over said Software. 
+
+
+    Article 3 - ACCEPTANCE
+
+3.1 The Licensee shall be deemed as having accepted the terms and
+conditions of this Agreement upon the occurrence of the first of the
+following events:
+
+    * (i) loading the Software by any or all means, notably, by
+      downloading from a remote server, or by loading from a physical
+      medium;
+    * (ii) the first time the Licensee exercises any of the rights
+      granted hereunder.
+
+3.2 One copy of the Agreement, containing a notice relating to the
+characteristics of the Software, to the limited warranty, and to the
+fact that its use is restricted to experienced users has been provided
+to the Licensee prior to its acceptance as set forth in Article 3.1
+hereinabove, and the Licensee hereby acknowledges that it has read and
+understood it.
+
+
+    Article 4 - EFFECTIVE DATE AND TERM
+
+
+      4.1 EFFECTIVE DATE
+
+The Agreement shall become effective on the date when it is accepted by
+the Licensee as set forth in Article 3.1.
+
+
+      4.2 TERM
+
+The Agreement shall remain in force for the entire legal term of
+protection of the economic rights over the Software.
+
+
+    Article 5 - SCOPE OF RIGHTS GRANTED
+
+The Licensor hereby grants to the Licensee, who accepts, the following
+rights over the Software for any or all use, and for the term of the
+Agreement, on the basis of the terms and conditions set forth hereinafter.
+
+Besides, if the Licensor owns or comes to own one or more patents
+protecting all or part of the functions of the Software or of its
+components, the Licensor undertakes not to enforce the rights granted by
+these patents against successive Licensees using, exploiting or
+modifying the Software. If these patents are transferred, the Licensor
+undertakes to have the transferees subscribe to the obligations set
+forth in this paragraph.
+
+
+      5.1 RIGHT OF USE
+
+The Licensee is authorized to use the Software, without any limitation
+as to its fields of application, with it being hereinafter specified
+that this comprises:
+
+   1. permanent or temporary reproduction of all or part of the Software
+      by any or all means and in any or all form.
+
+   2. loading, displaying, running, or storing the Software on any or
+      all medium.
+
+   3. entitlement to observe, study or test its operation so as to
+      determine the ideas and principles behind any or all constituent
+      elements of said Software. This shall apply when the Licensee
+      carries out any or all loading, displaying, running, transmission
+      or storage operation as regards the Software, that it is entitled
+      to carry out hereunder.
+
+
+      5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS
+
+The right to make Contributions includes the right to translate, adapt,
+arrange, or make any or all modifications to the Software, and the right
+to reproduce the resulting software.
+
+The Licensee is authorized to make any or all Contributions to the
+Software provided that it includes an explicit notice that it is the
+author of said Contribution and indicates the date of the creation thereof.
+
+
+      5.3 RIGHT OF DISTRIBUTION
+
+In particular, the right of distribution includes the right to publish,
+transmit and communicate the Software to the general public on any or
+all medium, and by any or all means, and the right to market, either in
+consideration of a fee, or free of charge, one or more copies of the
+Software by any means.
+
+The Licensee is further authorized to distribute copies of the modified
+or unmodified Software to third parties according to the terms and
+conditions set forth hereinafter.
+
+
+        5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION
+
+The Licensee is authorized to distribute true copies of the Software in
+Source Code or Object Code form, provided that said distribution
+complies with all the provisions of the Agreement and is accompanied by:
+
+   1. a copy of the Agreement,
+
+   2. a notice relating to the limitation of both the Licensor's
+      warranty and liability as set forth in Articles 8 and 9,
+
+and that, in the event that only the Object Code of the Software is
+redistributed, the Licensee allows future Licensees unhindered access to
+the full Source Code of the Software by indicating how to access it, it
+being understood that the additional cost of acquiring the Source Code
+shall not exceed the cost of transferring the data.
+
+
+        5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE
+
+When the Licensee makes a Contribution to the Software, the terms and
+conditions for the distribution of the resulting Modified Software
+become subject to all the provisions of this Agreement.
+
+The Licensee is authorized to distribute the Modified Software, in
+source code or object code form, provided that said distribution
+complies with all the provisions of the Agreement and is accompanied by:
+
+   1. a copy of the Agreement,
+
+   2. a notice relating to the limitation of both the Licensor's
+      warranty and liability as set forth in Articles 8 and 9,
+
+and that, in the event that only the object code of the Modified
+Software is redistributed, the Licensee allows future Licensees
+unhindered access to the full source code of the Modified Software by
+indicating how to access it, it being understood that the additional
+cost of acquiring the source code shall not exceed the cost of
+transferring the data.
+
+
+        5.3.3 DISTRIBUTION OF EXTERNAL MODULES
+
+When the Licensee has developed an External Module, the terms and
+conditions of this Agreement do not apply to said External Module, that
+may be distributed under a separate license agreement.
+
+
+        5.3.4 COMPATIBILITY WITH THE GNU GPL
+
+The Licensee can include a code that is subject to the provisions of one
+of the versions of the GNU GPL in the Modified or unmodified Software,
+and distribute that entire code under the terms of the same version of
+the GNU GPL.
+
+The Licensee can include the Modified or unmodified Software in a code
+that is subject to the provisions of one of the versions of the GNU GPL,
+and distribute that entire code under the terms of the same version of
+the GNU GPL.
+
+
+    Article 6 - INTELLECTUAL PROPERTY
+
+
+      6.1 OVER THE INITIAL SOFTWARE
+
+The Holder owns the economic rights over the Initial Software. Any or
+all use of the Initial Software is subject to compliance with the terms
+and conditions under which the Holder has elected to distribute its work
+and no one shall be entitled to modify the terms and conditions for the
+distribution of said Initial Software.
+
+The Holder undertakes that the Initial Software will remain ruled at
+least by this Agreement, for the duration set forth in Article 4.2.
+
+
+      6.2 OVER THE CONTRIBUTIONS
+
+The Licensee who develops a Contribution is the owner of the
+intellectual property rights over this Contribution as defined by
+applicable law.
+
+
+      6.3 OVER THE EXTERNAL MODULES
+
+The Licensee who develops an External Module is the owner of the
+intellectual property rights over this External Module as defined by
+applicable law and is free to choose the type of agreement that shall
+govern its distribution.
+
+
+      6.4 JOINT PROVISIONS
+
+The Licensee expressly undertakes:
+
+   1. not to remove, or modify, in any manner, the intellectual property
+      notices attached to the Software;
+
+   2. to reproduce said notices, in an identical manner, in the copies
+      of the Software modified or not.
+
+The Licensee undertakes not to directly or indirectly infringe the
+intellectual property rights of the Holder and/or Contributors on the
+Software and to take, where applicable, vis-à-vis its staff, any and all
+measures required to ensure respect of said intellectual property rights
+of the Holder and/or Contributors.
+
+
+    Article 7 - RELATED SERVICES
+
+7.1 Under no circumstances shall the Agreement oblige the Licensor to
+provide technical assistance or maintenance services for the Software.
+
+However, the Licensor is entitled to offer this type of services. The
+terms and conditions of such technical assistance, and/or such
+maintenance, shall be set forth in a separate instrument. Only the
+Licensor offering said maintenance and/or technical assistance services
+shall incur liability therefor.
+
+7.2 Similarly, any Licensor is entitled to offer to its licensees, under
+its sole responsibility, a warranty, that shall only be binding upon
+itself, for the redistribution of the Software and/or the Modified
+Software, under terms and conditions that it is free to decide. Said
+warranty, and the financial terms and conditions of its application,
+shall be subject of a separate instrument executed between the Licensor
+and the Licensee.
+
+
+    Article 8 - LIABILITY
+
+8.1 Subject to the provisions of Article 8.2, the Licensee shall be
+entitled to claim compensation for any direct loss it may have suffered
+from the Software as a result of a fault on the part of the relevant
+Licensor, subject to providing evidence thereof.
+
+8.2 The Licensor's liability is limited to the commitments made under
+this Agreement and shall not be incurred as a result of in particular:
+(i) loss due the Licensee's total or partial failure to fulfill its
+obligations, (ii) direct or consequential loss that is suffered by the
+Licensee due to the use or performance of the Software, and (iii) more
+generally, any consequential loss. In particular the Parties expressly
+agree that any or all pecuniary or business loss (i.e. loss of data,
+loss of profits, operating loss, loss of customers or orders,
+opportunity cost, any disturbance to business activities) or any or all
+legal proceedings instituted against the Licensee by a third party,
+shall constitute consequential loss and shall not provide entitlement to
+any or all compensation from the Licensor.
+
+
+    Article 9 - WARRANTY
+
+9.1 The Licensee acknowledges that the scientific and technical
+state-of-the-art when the Software was distributed did not enable all
+possible uses to be tested and verified, nor for the presence of
+possible defects to be detected. In this respect, the Licensee's
+attention has been drawn to the risks associated with loading, using,
+modifying and/or developing and reproducing the Software which are
+reserved for experienced users.
+
+The Licensee shall be responsible for verifying, by any or all means,
+the suitability of the product for its requirements, its good working
+order, and for ensuring that it shall not cause damage to either persons
+or properties.
+
+9.2 The Licensor hereby represents, in good faith, that it is entitled
+to grant all the rights over the Software (including in particular the
+rights set forth in Article 5).
+
+9.3 The Licensee acknowledges that the Software is supplied "as is" by
+the Licensor without any other express or tacit warranty, other than
+that provided for in Article 9.2 and, in particular, without any warranty 
+as to its commercial value, its secured, safe, innovative or relevant
+nature.
+
+Specifically, the Licensor does not warrant that the Software is free
+from any error, that it will operate without interruption, that it will
+be compatible with the Licensee's own equipment and software
+configuration, nor that it will meet the Licensee's requirements.
+
+9.4 The Licensor does not either expressly or tacitly warrant that the
+Software does not infringe any third party intellectual property right
+relating to a patent, software or any other property right. Therefore,
+the Licensor disclaims any and all liability towards the Licensee
+arising out of any or all proceedings for infringement that may be
+instituted in respect of the use, modification and redistribution of the
+Software. Nevertheless, should such proceedings be instituted against
+the Licensee, the Licensor shall provide it with technical and legal
+assistance for its defense. Such technical and legal assistance shall be
+decided on a case-by-case basis between the relevant Licensor and the
+Licensee pursuant to a memorandum of understanding. The Licensor
+disclaims any and all liability as regards the Licensee's use of the
+name of the Software. No warranty is given as regards the existence of
+prior rights over the name of the Software or as regards the existence
+of a trademark.
+
+
+    Article 10 - TERMINATION
+
+10.1 In the event of a breach by the Licensee of its obligations
+hereunder, the Licensor may automatically terminate this Agreement
+thirty (30) days after notice has been sent to the Licensee and has
+remained ineffective.
+
+10.2 A Licensee whose Agreement is terminated shall no longer be
+authorized to use, modify or distribute the Software. However, any
+licenses that it may have granted prior to termination of the Agreement
+shall remain valid subject to their having been granted in compliance
+with the terms and conditions hereof.
+
+
+    Article 11 - MISCELLANEOUS
+
+
+      11.1 EXCUSABLE EVENTS
+
+Neither Party shall be liable for any or all delay, or failure to
+perform the Agreement, that may be attributable to an event of force
+majeure, an act of God or an outside cause, such as defective
+functioning or interruptions of the electricity or telecommunications
+networks, network paralysis following a virus attack, intervention by
+government authorities, natural disasters, water damage, earthquakes,
+fire, explosions, strikes and labor unrest, war, etc.
+
+11.2 Any failure by either Party, on one or more occasions, to invoke
+one or more of the provisions hereof, shall under no circumstances be
+interpreted as being a waiver by the interested Party of its right to
+invoke said provision(s) subsequently.
+
+11.3 The Agreement cancels and replaces any or all previous agreements,
+whether written or oral, between the Parties and having the same
+purpose, and constitutes the entirety of the agreement between said
+Parties concerning said purpose. No supplement or modification to the
+terms and conditions hereof shall be effective as between the Parties
+unless it is made in writing and signed by their duly authorized
+representatives.
+
+11.4 In the event that one or more of the provisions hereof were to
+conflict with a current or future applicable act or legislative text,
+said act or legislative text shall prevail, and the Parties shall make
+the necessary amendments so as to comply with said act or legislative
+text. All other provisions shall remain effective. Similarly, invalidity
+of a provision of the Agreement, for any reason whatsoever, shall not
+cause the Agreement as a whole to be invalid.
+
+
+      11.5 LANGUAGE
+
+The Agreement is drafted in both French and English and both versions
+are deemed authentic.
+
+
+    Article 12 - NEW VERSIONS OF THE AGREEMENT
+
+12.1 Any person is authorized to duplicate and distribute copies of this
+Agreement.
+
+12.2 So as to ensure coherence, the wording of this Agreement is
+protected and may only be modified by the authors of the License, who
+reserve the right to periodically publish updates or new versions of the
+Agreement, each with a separate number. These subsequent versions may
+address new issues encountered by Free Software.
+
+12.3 Any Software distributed under a given version of the Agreement may
+only be subsequently distributed under the same version of the Agreement
+or a subsequent version, subject to the provisions of Article 5.3.4.
+
+
+    Article 13 - GOVERNING LAW AND JURISDICTION
+
+13.1 The Agreement is governed by French law. The Parties agree to
+endeavor to seek an amicable solution to any disagreements or disputes
+that may arise during the performance of the Agreement.
+
+13.2 Failing an amicable solution within two (2) months as from their
+occurrence, and unless emergency proceedings are necessary, the
+disagreements or disputes shall be referred to the Paris Courts having
+jurisdiction, by the more diligent Party.
+
+
+Version 2.0 dated 2006-09-05.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Program.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,175 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.awt.*;
+import javax.swing.*;
+
+
+public class Program {
+  String                 shortName;
+  String                 name;
+  String                 section;
+  String                 description;
+  Vector <ProgramOption> options;
+  JPanel                 panel;
+  JButton                button;
+
+
+  public Program() {
+    this.shortName = null;  
+    this.name      = null;  
+    this.options   = new Vector <ProgramOption> ();  
+  }
+
+
+  public void setShortName(String shortName) {
+    this.shortName = shortName;
+  }
+
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+
+  public void setSection(String section) {
+    this.section = section;
+  }
+
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
+
+  public void addOption(ProgramOption option) {
+    options.add(option);
+  }
+
+
+  public String getShortName() {
+    return this.shortName;
+  }
+
+
+  public String getName() {
+    return this.name;
+  }
+
+
+  public String getSection() {
+    return this.section;
+  }
+
+  public String getDescription() {
+    return this.description;
+  }
+
+
+  public String checkValues() {
+    for (int i = 0; i < options.size(); i++) {
+      String comment = options.get(i).checkValue();
+      if (comment != null) {
+        return comment;
+      }
+    }
+    return null;
+  }
+
+
+  public LinkedList<String> getCommand() {
+    LinkedList<String> parameterList = new LinkedList<String>();
+    parameterList.add(Global.pythonCommand);
+    parameterList.add("Python" + java.io.File.separator + this.shortName);
+    for (int i = 0; i < options.size(); i++) {
+      ProgramOption option = options.get(i);
+      parameterList.addAll(option.getCommand());
+    }
+    return parameterList;
+  }
+
+
+  public JPanel getPanel() {
+    if (this.panel != null) {
+      return this.panel;
+    }
+    
+    this.panel = new JPanel(false);
+    this.panel.setLayout(new FlowLayout());
+    Box box = Box.createVerticalBox();
+
+    JPanel descriptionPanel = new JPanel(false);
+    JLabel descriptionLabel = new JLabel(this.description);
+    descriptionPanel.add(descriptionLabel);
+    box.add(descriptionPanel);
+
+    for (int i = 0; i < options.size(); i++) {
+      ProgramOption option = options.get(i);
+      JPanel        panel  = option.getPanel();
+      if (panel == null) {
+        System.out.println("Problem with Python program '" + this.shortName + "'.");
+        return null;
+      }
+      box.add(option.getPanel());
+    }
+
+    JPanel buttonPanel = new JPanel(false);
+    this.button = new JButton("GO!");
+
+    buttonPanel.add(button);
+
+    box.add(buttonPanel);
+
+    this.panel.add(box);
+
+    return this.panel;
+  }
+
+
+  public JButton getButton() {
+    if (this.button == null) {
+      this.getPanel();
+    }
+    return this.button;
+  }
+
+  
+  public Vector < File > getOutputFiles() {
+    Vector < File > files = new Vector < File > ();
+    for (int i = 0; i < options.size(); i++) {
+      ProgramOption option = options.get(i);
+      if (! option.isInput()) {
+        files.add(option.getOutputFile());
+      }
+    }
+    return files;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/ProgramFileReader.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,174 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.io.File;
+import java.io.*;
+
+
+public class ProgramFileReader {
+  String fileName;
+  Vector <Program> programs;
+
+
+  public ProgramFileReader(String fileName) {
+    this.fileName = fileName;  
+    this.programs = new Vector <Program> ();
+  }
+
+
+  public boolean read() {
+//  File    file    = new File(this.fileName);
+//  Program program = null;
+//  int     step    = 0;
+//  TreeMap <String, ProgramOption> options = new TreeMap <String, ProgramOption> ();
+
+//  try {
+//    BufferedReader reader = new BufferedReader(new FileReader(file));
+//    String line    = null;
+//    String section = null;
+
+//    while ((line = reader.readLine()) != null) {
+
+//      line = line.trim();
+
+//      if (line.length() == 0) {
+//        if (program != null) {
+//          programs.add(program);
+//        }
+//        program = null;
+//        step = 0;
+//        continue;
+//      }
+
+//      if ((line.charAt(0) == '[') && (line.charAt(line.length() - 1) == ']')) {
+//        section = line.substring(1, line.length() - 1).trim();
+//        continue;
+//      }
+//      switch (step) {
+//        case 0:
+//        program = new Program();
+//          program.setName(line);
+//          if (section == null) {
+//            System.out.println("Error! Section of program '" + line + "' is not set!");
+//          }
+//          program.setSection(section);
+//          step = 1;
+//          break;
+//        case 1:
+//          program.setShortName(line);
+//          step = 2;
+//          break;
+//        case 2:
+//          ProgramOption option = new ProgramOption();
+
+//          String[] elements    = line.split(":");
+//          boolean  input       = elements[0].trim().equalsIgnoreCase("input")? true: false;
+//          String[] subElements = elements[1].split(";");
+//          String   identifier = subElements[0].trim();
+
+//          option.setInput(input);
+
+//          if (input) {
+
+//            if (subElements.length < 4) {
+//              System.out.println("Line '" + line + "' is weird...");
+//            }
+
+//            String   type       = subElements[1].trim();
+//            String   comment    = subElements[2].trim();
+//            boolean  compulsory = subElements[3].trim().equalsIgnoreCase("0")? false: true;
+
+//            option.setIdentifier(identifier);
+//            option.setType(type);
+//            option.setComment(comment);
+//            option.setCompulsory(compulsory);
+
+//            if ("file".compareToIgnoreCase(type) == 0) {
+//              if (subElements.length < 5) {
+//                System.out.println("Line '" + line + "' is weird...");
+//              }
+
+//              String formatIdentifier = subElements[4].trim();
+//              option.setFormatIdentifier(formatIdentifier);
+//            }
+//            else if ("choice".compareToIgnoreCase(type) == 0) {
+//              if (subElements.length < 5) {
+//                System.out.println("Line '" + line + "' is weird...");
+//              }
+
+//              String[] choices = subElements[4].trim().split(",");
+//              for (int i = 0; i < choices.length; i++) {
+//                choices[i] = choices[i].trim();
+//              }
+//              option.setChoices(choices);
+//            }
+//            options.put(identifier, option);
+//          }
+//          else {
+//            String format = subElements[1].trim();
+
+//            option.setFormat(format);
+//            option.setAssociatedOption(options.get(identifier));
+//          }
+
+//          program.addOption(option);
+
+//          break;
+//        default:
+//          return false;
+//      }
+//    }
+
+//    reader.close();
+//  }
+//  catch (FileNotFoundException e) {
+//    return false;
+//  }
+//  catch (IOException e) {
+//    return false;
+//  }
+
+//  if (program != null) {
+//    programs.add(program);
+//  }
+
+    return true;
+  }
+
+  public int getNbPrograms() {
+    return programs.size();
+  }
+
+  public Program getProgram(int i) {
+    return programs.get(i);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/ProgramLauncher.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,209 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.io.*;
+import javax.swing.SwingUtilities;
+import javax.swing.*;
+import java.util.concurrent.CountDownLatch;
+
+public class ProgramLauncher extends SwingWorker<Boolean, String>  {
+
+  String[]     command;
+  JTextArea    logArea;
+  JLabel       messageField;
+  JProgressBar progressBar;
+  JLabel       etaField;
+  int          exitValue;
+  CountDownLatch latch;
+
+  
+
+  public ProgramLauncher (LinkedList <String> c, JTextArea la, JLabel mf, JProgressBar pb, JLabel ef) {
+    command       = new String[c.size()];
+    logArea       = la;
+    messageField  = mf;
+    progressBar   = pb;
+    etaField      = ef;
+    exitValue     = -1;
+    c.toArray(command);
+    latch = new CountDownLatch(1);
+  }
+
+
+  public ProgramLauncher (String[] c, JTextArea la, JLabel mf, JProgressBar pb, JLabel ef) {
+    command       = c;
+    logArea       = la;
+    messageField  = mf;
+    progressBar   = pb;
+    etaField      = ef;
+    exitValue     = -1;
+    latch = new CountDownLatch(1);
+  }
+
+
+  @Override
+  public Boolean doInBackground() {
+    ProcessBuilder pb           = new ProcessBuilder(command);
+    Process process             = null;
+    BufferedReader outputReader = null;
+    pb                          = pb.redirectErrorStream(true);
+    Map<String, String> env     = pb.environment();
+    env.put("PYTHONPATH", System.getProperty("user.dir"));
+    env.put("SMARTPATH", System.getProperty("user.dir") + java.io.File.separator + "SMART" + java.io.File.separator + "Java" + java.io.File.separator + "Python");
+    env.put("SMARTMYSQLPATH", Global.mysqlCommand);
+    env.put("SMARTRPATH", Global.rCommand);
+    String commandJoined = Arrays.toString(command);
+
+    try {
+      publish("=== Starting command '" + commandJoined.trim() + "' ===\n");
+      process = pb.start();
+
+      BufferedInputStream outputStream = new BufferedInputStream(process.getInputStream());
+      InputStream is                   = process.getInputStream();
+      InputStreamReader isr            = new InputStreamReader(is);
+      outputReader                     = new BufferedReader(isr);
+    }
+    catch (Exception exception) {
+      publish("!Process cannot be started (command is '" + commandJoined + "')!\n");
+      exception.printStackTrace();
+      latch.countDown();
+      return Boolean.FALSE;
+    }
+    if (outputReader == null) {
+      publish("!Problem in the output of the command!\n");
+      latch.countDown();
+      return Boolean.FALSE;
+    }
+    else {
+      try {
+        String line;
+        while ((line = outputReader.readLine()) != null) {
+          publish(line + "\n");
+        }
+      }
+      catch (IOException e) {
+        e.printStackTrace();
+        publish("!Cannot get the output of the command!\n");
+        latch.countDown();
+        return Boolean.FALSE;
+      }
+    }
+    try {
+      process.waitFor();
+    }
+    catch (InterruptedException e) {
+      e.printStackTrace();
+      publish("!Cannot wait for the end of the command!\n");
+      latch.countDown();
+      return Boolean.FALSE;
+    }
+    try {
+      exitValue = process.exitValue();
+    }
+    catch (IllegalThreadStateException e) {
+      e.printStackTrace();
+      publish("!Cannot get the exit value of the command!\n");
+      latch.countDown();
+      return Boolean.FALSE;
+    }
+    if (exitValue != 0) {
+      publish("!Problem during the execution of the command '" + commandJoined + "'!\n");
+      latch.countDown();
+      return Boolean.FALSE;
+    }
+    publish("=== Ending command '" + commandJoined.trim() + "' ===\n");
+    latch.countDown();
+    return Boolean.TRUE;
+  }
+
+
+  @Override
+  protected void process(List<String> chunks) {
+    String message = "";
+    String text    = logArea.getText();
+    for (String chunk: chunks) {
+      text += chunk;
+    }
+    for (String lineSeparatedByCarriageReturn: text.split("\n")) {
+      for (String line: lineSeparatedByCarriageReturn.split("\r")) {
+        boolean progressLine = false;
+        if (line.matches(".*\\[=*\\s*\\]\\s*\\d*/\\d*\\s*")) {
+          String[] ratioElements = line.split("\\]")[1].trim().split("/");
+          int      current       = Integer.parseInt(ratioElements[0].trim());
+          int      aim           = Integer.parseInt(ratioElements[1].trim());
+          messageField.setText(line.split("\\[")[0].trim());
+          progressBar.setValue(current * 100 / aim);
+          etaField.setText("");
+          progressLine = true;
+        }
+        else if (line.matches(".*\\[=*\\s*\\]\\s*\\d*/\\d*\\s*ETA:\\s*.*")) {
+          String[] ratioElements = line.split("\\]")[1].split("E")[0].trim().split("/");
+          int      current       = Integer.parseInt(ratioElements[0].trim());
+          int      aim           = Integer.parseInt(ratioElements[1].trim());
+          String   eta           = line.split("ETA:")[1].trim();
+          messageField.setText(line.split("\\[")[0].trim());
+          progressBar.setValue(current * 100 / aim);
+          etaField.setText("ETA: " + eta);
+          progressLine = true;
+        }
+        else if (line.matches(".*\\[=*\\s*\\]\\s*\\d*\\s*completed in.*")) {
+          String nbElements = line.split("\\]")[1].split("completed")[0].trim();
+          String timeSpent  = line.split("completed in")[1].trim();
+          message          += line.split("\\[")[0].trim() + ": " + nbElements + " elements completed in " + timeSpent + "\n";
+          messageField.setText(line.split("\\[")[0].trim());
+          progressLine = true;
+        }
+        if (! progressLine) {
+          message += line + "\n";
+        }
+      }
+    }
+    String lines[]     = message.split("\n");
+    String toBeWritten = "";
+    for (int i = Math.max(0, lines.length - Global.logAreaSize); i < lines.length; i++) {
+      toBeWritten += lines[i] + "\n";
+    }
+    logArea.setText(toBeWritten);
+  }
+
+  public int getExitValue() {
+    try {
+      latch.await();
+    }
+    catch (InterruptedException e) {
+      logArea.append("Cannot wait for the end of the process!\n");
+      e.printStackTrace();
+      return -1;
+    }
+    return exitValue;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/ProgramOption.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,358 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.*;
+import javax.swing.*;
+import javax.swing.filechooser.*;
+import javax.swing.border.*;
+import javax.swing.SwingUtilities;
+
+
+public class ProgramOption {
+  boolean       input;
+  String        identifier;
+  String        type;
+  String        comment;
+  boolean       compulsory;
+  String[]      format;
+  String        formatIdentifier;
+  ProgramOption associatedOption;
+  String        defaultValue;
+  String[]      choices;
+  JComponent    component;
+  JPanel        panel;
+
+
+  public ProgramOption() {
+    this.input            = true;
+    this.identifier       = null;
+    this.type             = null;
+    this.comment          = null;
+    this.compulsory       = false;
+    this.format           = null;
+    this.formatIdentifier = null;
+    this.associatedOption = null;
+    this.defaultValue     = "";
+    this.choices          = null;
+    this.component        = null;
+    this.panel            = null;
+  }
+
+
+  public void setInput(boolean input) {
+    this.input = input;
+  }
+
+
+  public void setIdentifier(String identifier) {
+    this.identifier = identifier;
+  }
+
+
+  public void setType(String type) {
+    this.type = type;
+  }
+
+
+  public void setComment(String comment) {
+    this.comment = comment;
+  }
+
+
+  public void setCompulsory(boolean compulsory) {
+    this.compulsory = compulsory;
+  }
+
+
+  public void setFormat(String[] format) {
+    this.format = format;
+  }
+
+
+  public void setFormat(String format) {
+    this.format    = new String[1];
+    this.format[0] = format;
+  }
+
+
+  public void setFormatIdentifier(String formatIdentifier) {
+    this.formatIdentifier = formatIdentifier;
+  }
+
+
+  public void setAssociatedOption(ProgramOption option) {
+    this.associatedOption = option;
+  }
+
+
+  public void setChoices(String[] choices) {
+    this.choices = new String[choices.length+1];
+    this.choices[0] = "---";
+    for (int i = 0; i < choices.length; i++) {
+      this.choices[i+1] = choices[i];
+    }
+  }
+
+
+  public void setDefault(String defaultValue) {
+    this.defaultValue = defaultValue;
+  }
+
+
+  public boolean isInput() {
+    return this.input;
+  }
+
+
+  public boolean checkSettings() {
+    if (this.identifier == null) {
+      return false;
+    }
+    if (this.type == null) {
+      return false;
+    }
+    if (this.comment == null) {
+      return false;
+    }
+    if (this.comment == null) {
+      return false;
+    }
+    if (("choice".compareToIgnoreCase(this.type) == 0) && (this.choices == null)) {
+      return false;
+    }
+    return true;
+  }
+
+
+  public JPanel getPanel() {
+    if (this.panel != null) {
+      return this.panel;
+    }
+    String comment = this.comment;
+    if (this.compulsory) {
+      comment += " [*]";
+    }
+
+    GridLayout horizontalLayout = new GridLayout(1, 0);
+    this.panel = new JPanel(false);
+    this.panel.setLayout(horizontalLayout);
+    JLabel label = new JLabel(comment);
+
+    if (this.type == null) {
+      System.out.println("Error! Option '" + this.identifier + "' is not set!");
+    }
+
+    if (("int".compareToIgnoreCase(this.type) == 0) || ("float".compareToIgnoreCase(this.type) == 0) || ("string".compareToIgnoreCase(this.type) == 0) || (("file".compareToIgnoreCase(this.type) == 0) && (!this.input))) {
+      this.component = new JTextField();
+      if (this.defaultValue != null) {
+        ((JTextField) this.component).setText(this.defaultValue);
+      }
+      label.setLabelFor(this.component);
+      this.panel.add(label);
+      this.panel.add(this.component);
+    }
+    else if ("file".compareToIgnoreCase(this.type) == 0) {
+      this.component = new JComboBox(Global.fileNames);
+      label.setLabelFor(this.component);
+      this.panel.add(label);
+      this.panel.add(this.component);
+    }
+    else if ("boolean".compareToIgnoreCase(this.type) == 0) {
+      this.component = new JCheckBox();
+      if ((this.defaultValue != null) && (this.defaultValue.compareToIgnoreCase("true") == 0)) {
+        ((JCheckBox) this.component).setSelected(true);
+      }
+      label.setLabelFor(this.component);
+      this.panel.add(label);
+      this.panel.add(this.component);
+    }
+    else if ("format".compareToIgnoreCase(this.type) == 0) {
+      Vector < String > formats = new Vector < String > ();
+      for (String format: this.format) {
+        if (Global.formats.getFormats(format) == null) {
+          System.out.println("Do not know how to handle format '" + format + "'.");
+        }
+        formats.addAll(Global.formats.getFormats(format).getFormats());
+      }
+      this.component = new JComboBox(formats);
+      label.setLabelFor(this.component);
+      this.panel.add(label);
+      this.panel.add(this.component);
+    }
+    else if ("files".compareToIgnoreCase(this.type) == 0) {
+      JButton button = new JButton("file...");
+      this.component = new JTextField();
+      label.setLabelFor(this.component);
+      this.panel.add(label);
+      this.panel.add(this.component);
+      this.panel.add(button);
+      Global.otherFileConcatenationChooser.put(button, (JTextField) this.component);
+    }
+    else if ("directory".compareToIgnoreCase(this.type) == 0) {
+      JButton button = new JButton("directory...");
+      this.component = new JTextField();
+      label.setLabelFor(this.component);
+      this.panel.add(label);
+      JPanel rightPanel = new JPanel(false);
+      rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.LINE_AXIS));
+      rightPanel.add(this.component);
+      rightPanel.add(button);
+      this.panel.add(rightPanel);
+      Global.otherDirectoriesChooser.put(button, (JTextField) this.component);
+    }
+    else if ("choice".compareToIgnoreCase(this.type) == 0) {
+      this.component = new JComboBox(this.choices);
+      label.setLabelFor(this.component);
+      this.panel.add(label);
+      this.panel.add(this.component);
+    }
+    else {
+      System.out.println("Do not know how to read type " + this.type);
+    }
+
+    return this.panel;
+  }
+
+
+  public JComponent getComponent() {
+    if (component == null) {
+      this.getPanel();
+    }
+    return this.component;
+  }
+
+
+  private String getValue() {
+    if (("int".equals(this.type)) || ("float".equals(this.type)) || ("string".equals(this.type)) || (("file".equals(this.type)) && (! this.input)) || ("directory".equals(this.type)) || ("files".equals(this.type)))  {
+      String s = ((JTextField) this.component).getText();
+      if ("None".equals(s)) {
+        return "";
+      }
+      return s;
+    }
+    if ("file".equals(this.type)) {
+      return (String) ((JComboBox) this.component).getSelectedItem();
+    }
+    if ("boolean".equals(this.type)) {
+      return ((JCheckBox) this.component).isSelected()? "true": "false";
+    }
+    if ("format".equals(this.type)) {
+      return (String) ((JComboBox) this.component).getSelectedItem();
+    }
+    if ("choice".equals(this.type)) {
+      String s = (String) ((JComboBox) this.component).getSelectedItem();
+      if ("---".equals(s)) {
+        return "";
+      }
+      return s;
+    }
+    System.out.println("Do not know how to get value of '" + this.type + "' (" + this.identifier + ").");
+    return null;
+  }
+
+
+  public String checkValue() {
+    String value = this.getValue();
+    if ((this.compulsory) && ((value == null) || ("".equals(value)))) {
+      return "Option '" + this.comment + "' has no value... Please specify it.\n";
+    }
+    if ("int".equals(this.type)) {
+      if ((value != null) && (! "".equals(value)) && (! "None".equals(value))) {
+        try {
+          int i = Integer.parseInt(value);
+        }
+        catch (NumberFormatException e) {
+          return "Option '" + this.comment + "' should be an integer... Please correct it.\n";
+        }
+      }
+    }
+    else if ("float".equals(this.type)) {
+      if ((value != null) && (! "".equals(value))) {
+        try {
+          float i = Float.parseFloat(value);
+        }
+        catch (NumberFormatException e) {
+          return "Option '" + this.comment + "' should be a float... Please correct it.\n";
+        }
+      }
+    }
+    return null;
+  }
+
+
+  public LinkedList <String> getCommand() {
+    LinkedList <String> list = new LinkedList <String> ();
+
+    if (("int".equals(this.type)) || ("float".equals(this.type)) || ("string".equals(this.type)) || (("file".equals(this.type)) && (! this.input)) || ("format".equals(this.type)) || ("directory".equals(this.type)) || ("files".equals(this.type)) || ("choice".equals(this.type))) {
+      String value = this.getValue();
+      if (value.length() == 0) {
+        return list;
+      }
+      list.add(this.identifier);
+      list.add(value);
+      return list;
+    }
+    if ("file".equals(this.type)) {
+      String fileName = (String) ((JComboBox) this.component).getSelectedItem();
+      if (fileName == null) {
+        return list;
+      }
+      list.add(this.identifier);
+      list.add(this.getValue());
+      return list;
+    }
+    if (("boolean".equals(this.type)) || ("bool".equals(this.type))) {
+      if ("true".equals(this.getValue())) {
+        list.add(this.identifier);
+      }
+      return list;
+    }
+    System.out.println("Cannot get type of option " + this.type + " (" + this.identifier + "): " + this.getValue());
+    return null;
+  }
+
+
+  public File getOutputFile() {
+    if (this.input) return null;
+    String format = "";
+    if (this.format != null) {
+      format = this.format[0];
+    }
+    if (this.associatedOption != null) {
+      format = this.associatedOption.getValue();
+    }
+    return new File(this.getValue(), Global.formats.getFormatType(format), format);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/.gitignore	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,1 @@
+/CleanTranscriptFile.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/CleanTranscriptFile.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,74 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2011
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from optparse import OptionParser
+from SMART.Java.Python.cleaning.CleanerChooser import CleanerChooser
+
+
+class CleanTranscriptFile(object):
+
+	def __init__(self, verbosity):
+		self.verbosity = verbosity
+		self.chooser   = CleanerChooser(self.verbosity)
+
+	def setInputFile(self, fileName, format):
+		self.chooser.findFormat(format)
+		self.cleaner = self.chooser.getCleaner()
+		self.cleaner.setInputFileName(fileName)
+
+	def setOutputFile(self, fileName):
+		self.cleaner.setOutputFileName(fileName)
+
+	def setAcceptedTypes(self, types):
+		if types != None:
+			self.cleaner.setAcceptedTypes(types)
+
+	def run(self):
+		self.cleaner.clean()
+
+
+if __name__ == "__main__":
+
+	description = "Clean Transcript File v1.0.1: Clean a transcript file so that it is useable for S-MART. [Category: Other]"
+
+	parser = OptionParser(description = description)
+	parser.add_option("-i", "--input",       dest="inputFileName",  action="store",                     type="string", help="query input file [compulsory] [format: file in transcript format given by -f]")
+	parser.add_option("-f", "--format",      dest="format",         action="store",                     type="string", help="format of previous file [compulsory] [format: transcript file format]")
+	parser.add_option("-t", "--types",       dest="acceptedTypes",  action="store",      default=None,  type="string", help="name of the types you want to keep in GFF/GTF (list separated by commas) [format: string] [default: None]")
+	parser.add_option("-o", "--output",      dest="outputFileName", action="store",                     type="string", help="output file [format: output file in GFF3 format]")
+	parser.add_option("-v", "--verbosity",   dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [format: int]")
+	(options, args) = parser.parse_args()
+
+	ctf = CleanTranscriptFile(options.verbosity)
+	ctf.setInputFile(options.inputFileName, options.format)
+	ctf.setOutputFile(options.outputFileName)
+	ctf.setAcceptedTypes(None if options.acceptedTypes == None else options.acceptedTypes.split(","))
+	ctf.run()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ClusterizeByTags.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,157 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2011
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import random
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.mySql.MySqlConnection import MySqlConnection
+from commons.core.writer.MySqlTranscriptWriter import MySqlTranscriptWriter
+
+
+OPERATIONS = ("diff", "div")
+BOOLTOSTRANDS = {True: [0], False: [-1, 1]}
+
+class ClusterizeByTags(object):
+
+    def __init__(self, verbosity):
+        self.verbosity   = verbosity
+        self.connection  = MySqlConnection(self.verbosity-1)
+        self.defautValue = None
+        self.maxDistance = None
+        self.oneStrand   = False
+
+    def setInputFile(self, fileName, format):
+        chooser = ParserChooser(self.verbosity)
+        chooser.findFormat(format)
+        parser = chooser.getParser(fileName)
+        writer = MySqlTranscriptWriter(self.connection, None, self.verbosity)
+        writer.addTranscriptList(parser)
+        writer.write()
+        self.transcriptTables = writer.getTables()
+
+    def setOutputFile(self, fileName):
+        self.writer = TranscriptWriter(fileName, "gff3", self.verbosity)
+
+    def setTag(self, tagName, defaultValue):
+        self.tagName      = tagName
+        self.defaultValue = defaultValue
+
+    def setThreshold(self, threshold):
+        self.threshold = threshold
+
+    def setOperation(self, operation):
+        self.operation = operation
+        if self.operation not in OPERATIONS:
+            raise Exception("Operation '%s' unsupported: choose among %s" % (self.operation, ", ".join(OPERATIONS)))
+
+    def setMaxDistance(self, distance):
+        self.maxDistance = distance
+
+    def setOneStrand(self, oneStrand):
+        self.oneStrand = oneStrand
+
+    def run(self):
+        for chromosome in sorted(self.transcriptTables.keys()):
+            progress = Progress(self.transcriptTables[chromosome].getNbElements(), "Analyzing %s" % (chromosome), self.verbosity)
+            for strand in BOOLTOSTRANDS[self.oneStrand]:
+                previousValue      = None
+                previousTrend      = None
+                previousTranscript = None
+                sumValue           = 0
+                command = "SELECT * FROM %s" % (self.transcriptTables[chromosome].getName())
+                if not self.oneStrand:
+                    command += " WHERE direction = %d" % (strand)
+                command += " ORDER BY start, end"
+                for index, transcript in self.transcriptTables[chromosome].selectTranscripts(command):
+                    if self.tagName in transcript.getTagNames():
+                        value = transcript.getTagValue(self.tagName)
+                    else:
+                        value = self.defaultValue
+                    if previousValue == None:
+                        trend = None
+                    else:
+                        if self.operation == "diff":
+                            trend = value - previousValue
+                        else:
+                            trend = value / previousValue
+                    if previousTranscript == None:
+                        sumValue = value
+                    elif (previousTrend == None or abs(trend - previousTrend) <= self.threshold) and (self.maxDistance == None or previousTranscript.getDistance(transcript) <= self.maxDistance) and (previousTranscript.getDirection() == transcript.getDirection() or not self.oneStrand):
+                        if previousTranscript.getDirection() != transcript.getDirection():
+                            transcript.reverse()
+                        previousTranscript.merge(transcript)
+                        transcript = previousTranscript
+                        sumValue += value
+                        previousTrend = trend
+                    else:
+                        previousTranscript.setTagValue(self.tagName, sumValue)
+                        self.writer.addTranscript(previousTranscript)
+                        sumValue = value
+                        previousTrend = None
+                    previousValue      = value
+                    previousTranscript = transcript
+                    progress.inc()
+                if previousTranscript != None:
+                    previousTranscript.setTagValue(self.tagName, sumValue)
+                    self.writer.addTranscript(previousTranscript)
+            progress.done()
+        self.writer.close()
+
+
+if __name__ == "__main__":
+    
+    description = "Clusterize By Tags v1.0.1: Clusterize a set of element using their tag values. [Category: Merge]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",       dest="inputFileName",  action="store",                     type="string", help="query input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",      dest="format",         action="store",                     type="string", help="format of previous file [compulsory] [format: transcript file format]")
+    parser.add_option("-t", "--tag",         dest="tagName",        action="store",                     type="string", help="name of the tag [format: string] [compulsory]")
+    parser.add_option("-e", "--default",     dest="defaultValue",   action="store",      default=None,  type="int",    help="default value for the tag [format: string]")
+    parser.add_option("-r", "--threshold",   dest="threshold",      action="store",                     type="int",    help="threshold between two consecutive tags [format: int] [compulsory]")
+    parser.add_option("-p", "--operation",   dest="operation",      action="store",                     type="string", help="operation to apply between 2 different clusters to compare them [format: choice (diff, div)] [compulsory]")
+    parser.add_option("-d", "--distance",    dest="maxDistance",    action="store",      default=None,  type="int",    help="maximum distance for 2 clusters to be merged [format: int] [default: None]")
+    parser.add_option("-1", "--oneStrand",   dest="oneStrand",      action="store_true", default=False,                help="also cluster the elements which are on different strands [format: bool] [default: False]")
+    parser.add_option("-o", "--output",      dest="outputFileName", action="store",                     type="string", help="output file [format: output file in GFF3 format]")
+    parser.add_option("-v", "--verbosity",   dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    cbt = ClusterizeByTags(options.verbosity)
+    cbt.setInputFile(options.inputFileName, options.format)
+    cbt.setOutputFile(options.outputFileName)
+    cbt.setTag(option.tagName, option.defaultValue)
+    cbt.setThreshold(option.threshold)
+    cbt.setOperation(option.operation)
+    cbt.setMaxDistance(operation.maxDistance)
+    cbt.setOneStrand(operation.oneStrand)
+    cbt.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/CollapseReads.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,174 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os
+from optparse import OptionParser, OptionGroup
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.ncList.NCListFilePickle import NCListFileUnpickle
+from SMART.Java.Python.ncList.FileSorter import FileSorter
+from SMART.Java.Python.misc.Progress import Progress
+
+
+class CollapseReads(object):
+    """
+    Merge two reads if they have exactly the same genomic coordinates
+    """
+
+    def __init__(self, verbosity = 0):
+        self.verbosity         = verbosity
+        self.inputReader       = None
+        self.outputWriter      = None
+        self.strands           = True
+        self.nbRead            = 0
+        self.nbWritten         = 0
+        self.nbMerges          = 0
+        self.splittedFileNames = {}
+
+    def __del__(self):
+        for fileName in self.splittedFileNames.values():
+            os.remove(fileName)
+            
+    def close(self):
+        self.outputWriter.close()
+        
+    def setInputFile(self, fileName, format):
+        parserChooser = ParserChooser(self.verbosity)
+        parserChooser.findFormat(format, "transcript")
+        self.parser = parserChooser.getParser(fileName)
+        self.sortedFileName = "%s_sorted.pkl" % (os.path.splitext(fileName)[0])
+
+    def setOutputFile(self, fileName):
+        self.outputWriter = Gff3Writer(fileName, self.verbosity)
+
+    def getNbElements(self):
+        return self.parser.getNbTranscripts()
+
+    def _sortFile(self):
+        fs = FileSorter(self.parser, self.verbosity-4)
+        fs.perChromosome(True)
+        fs.setOutputFileName(self.sortedFileName)
+        fs.sort()
+        self.splittedFileNames       = fs.getOutputFileNames()
+        self.nbElementsPerChromosome = fs.getNbElementsPerChromosome()
+        self.nbRead                  = fs.getNbElements()
+        
+    def _iterate(self, chromosome):
+        progress    = Progress(self.nbElementsPerChromosome[chromosome], "Checking chromosome %s" % (chromosome), self.verbosity)
+        transcripts = []
+        parser      = NCListFileUnpickle(self.splittedFileNames[chromosome], self.verbosity)
+        for newTranscript in parser.getIterator():
+            newTranscripts = []
+            for oldTranscript in transcripts:
+                if self._checkOverlap(newTranscript, oldTranscript):
+                    self._merge(newTranscript, oldTranscript)
+                elif self._checkPassed(newTranscript, oldTranscript):
+                    self._write(oldTranscript)
+                else:
+                    newTranscripts.append(oldTranscript)
+            newTranscripts.append(newTranscript)
+            transcripts = newTranscripts
+            progress.inc()
+        for transcript in transcripts:
+            self._write(transcript)
+        progress.done()
+
+    def _merge(self, transcript1, transcript2):
+        self.nbMerges += 1
+        transcript2.setDirection(transcript1.getDirection())
+        transcript1.merge(transcript2)
+
+    def _write(self, transcript):
+        self.nbWritten += 1
+        self.outputWriter.addTranscript(transcript)
+
+    def _checkOverlap(self, transcript1, transcript2):
+        if transcript1.getStart() != transcript2.getStart() or transcript1.getEnd() != transcript2.getEnd():
+            return False
+        return (not self.strands or transcript1.getDirection() == transcript2.getDirection())
+
+    def _checkPassed(self, transcript1, transcript2):
+        return (transcript2.getStart() < transcript1.getStart())
+
+    def collapseChromosome(self, chromosome):
+        progress            = Progress(table.getNbElements(), "Analysing chromosome %s" % (chromosome), self.verbosity)
+        command             = "SELECT * FROM %s ORDER BY start ASC, end DESC" % (table.name)
+        transcriptStart     = None
+        transcriptEnd       = None
+        transcriptDirection = None
+        currentTranscript   = None
+        if self.strands:
+            command += ", direction"
+        for index, transcript in table.selectTranscripts(command, True):
+            self.nbRead += 1
+            if not self.strands:
+                transcript.setDirection("+")
+            if transcriptStart != transcript.getStart() or transcriptEnd != transcript.getEnd() or transcriptDirection != transcript.getDirection():
+                self.writeTranscript(currentTranscript)
+                transcriptStart     = transcript.getStart()
+                transcriptEnd       = transcript.getEnd()
+                transcriptDirection = transcript.getDirection()
+                currentTranscript   = transcript
+            else:
+                currentTranscript.setTagValue("nbElements", (currentTranscript.getTagValue("nbElements") + 1) if "nbElements" in currentTranscript.getTagNames() else 1)
+            progress.inc()
+        self.writeTranscript(currentTranscript)
+        progress.done()
+
+    def collapse(self):
+        self._sortFile()
+        for chromosome in sorted(self.nbElementsPerChromosome.keys()):
+            self._iterate(chromosome)
+        self.outputWriter.close()
+        if self.verbosity > 1:
+            print "# reads read: %d" % (self.nbRead)
+            print "# reads written: %d (%.2f%%)" % (self.nbWritten, float(self.nbWritten) / self.nbRead * 100)
+            print "# reads merges: %d" % (self.nbMerges)
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Collapse Reads v1.0.3: Merge two reads if they have exactly the same genomic coordinates. [Category: Merge]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",                     type="string", help="input file [compulsory] [format: file in mapping format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",         action="store",                     type="string", help="format of the file [compulsory] [format: mapping file format]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",                     type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-s", "--strands",   dest="strands",        action="store_true", default=False,                help="merge elements on 2 different strands [format: bool] [default: false]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [default: 1] [format: int]")
+    (options, args) = parser.parse_args()
+
+    collapser = CollapseReads(options.verbosity)
+    collapser.setInputFile(options.inputFileName, options.format)
+    collapser.setOutputFile(options.outputFileName)
+    collapser.strands = not options.strands
+    collapser.collapse()
+    collapser.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/CombineTags.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,115 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2011
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os
+import random
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.misc.Progress import Progress
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.Gff3Writer import Gff3Writer
+
+OPERATIONS = ("plus", "minus", "times", "div")
+
+class CombineTags(object):
+
+    def __init__(self, verbosity = 0):
+        self.verbosity       = verbosity
+
+    def setInputFile(self, fileName, format):
+        self.inputFileName = fileName
+        parserChooser = ParserChooser(self.verbosity)
+        parserChooser.findFormat(format, "transcript")
+        self.parser = parserChooser.getParser(fileName)
+
+    def setOutputFile(self, fileName):
+        self.outputWriter = Gff3Writer(fileName, self.verbosity)
+
+    def setTags(self, tag1, tag2, outputTag, defaultValue = None):
+        self.tag1         = tag1
+        self.tag2         = tag2
+        self.outputTag    = outputTag
+        self.defaultValue = defaultValue
+
+    def setOperation(self, operation):
+        self.operation = operation
+        if self.operation not in OPERATIONS:
+            raise Exception("Do no handle operation %s, only: %s" % (self.operation, ", ".join(OPERATIONS)))
+
+    def run(self):
+        progress = Progress(self.parser.getNbTranscripts(), "Printing transcripts %s" % (self.inputFileName), self.verbosity)
+        for transcript in self.parser.getIterator():
+            tag1 = transcript.getTagValue(self.tag1)
+            tag2 = transcript.getTagValue(self.tag2)
+            if tag1 == None or tag2 == None:
+                if self.defaultValue == None:
+                    raise Exception("Transcript %s misses one of the tags %s and %s, and has no default value !" % (transcript, self.tag1, self.tag2))
+                newTag = self.defaultValue
+            else:
+                tag1, tag2 = float(tag1), float(tag2)
+                if self.operation == "plus":
+                    newTag = tag1 + tag2
+                elif self.operation == "minus":
+                    newTag = tag1 - tag2
+                elif self.operation == "times":
+                    newTag = tag1 * tag2
+                elif self.operation == "div":
+                    newTag = tag1 / tag2
+            transcript.setTagValue(self.outputTag, newTag)
+            self.outputWriter.addTranscript(transcript)
+            progress.inc()
+        progress.done()
+        self.parser.close()
+        self.outputWriter.close()
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Change Tag Name v1.0.1: Change the name of tag of a list of transcripts. [Category: Data Modification]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",       dest="inputFileName",  action="store",               type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--inputFormat", dest="inputFormat",    action="store",               type="string", help="format of the input file [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",      dest="outputFileName", action="store",               type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-t", "--tag1",        dest="tag1",           action="store",               type="string", help="name of the first tag [compulsory] [format: string]")
+    parser.add_option("-T", "--tag2",        dest="tag2",           action="store",               type="string", help="name of the second tag [compulsory] [format: string]")
+    parser.add_option("-d", "--default",     dest="defaultValue",   action="store", default=None, type="string", help="default value when one of the tag is absent [compulsory] [format: float]")
+    parser.add_option("-n", "--new",         dest="newTag",         action="store",               type="string", help="name of the new tag [compulsory] [format: string]")
+    parser.add_option("-p", "--operation",   dest="operation",      action="store",               type="string", help="operation combining the tags [compulsory] [format: choice (plus, minus, times, div)]")
+    parser.add_option("-v", "--verbosity",   dest="verbosity",      action="store", default=1,    type="int",    help="trace level [format: int] [default: 1]")
+    (options, args) = parser.parse_args()
+
+    combiner = CombineTags(options.verbosity)
+    combiner.setInputFile(options.inputFileName, options.inputFormat)
+    combiner.setOutputFile("%s.gff3" % (options.outputFileName))
+    combiner.setTags(options.tag1, options.tag2, options.newTag, options.defaultValue)
+    combiner.setOperation(options.operation)
+    combiner.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/CompareOverlapping.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,491 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os, struct, time, random
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.ncList.NCList import NCList
+from SMART.Java.Python.ncList.NCListCursor import NCListCursor
+from SMART.Java.Python.ncList.NCListFilePickle import NCListFilePickle, NCListFileUnpickle
+from SMART.Java.Python.ncList.NCListHandler import NCListHandler
+from SMART.Java.Python.ncList.ConvertToNCList import ConvertToNCList
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+from SMART.Java.Python.misc import Utils
+try:
+	import cPickle as pickle
+except:
+	import pickle
+
+REFERENCE = 0
+QUERY = 1
+TYPES = (REFERENCE, QUERY)
+TYPETOSTRING = {0: "reference", 1: "query"}
+
+class CompareOverlapping(object):
+
+	def __init__(self, verbosity = 1):
+		self._outputFileName		   = "outputOverlaps.gff3"
+		self._iWriter				   = None
+		self._nbOverlappingQueries	   = 0
+		self._nbOverlaps			   = 0
+		self._nbLines				   = {REFERENCE: 0, QUERY: 0}
+		self._verbosity				   = verbosity
+		self._ncLists				   = {}
+		self._cursors				   = {}
+		self._splittedFileNames		   = {}
+		self._nbElements			   = {}
+		self._nbElementsPerChromosome  = {}
+		self._inputFileNames		   = {REFERENCE: None,  QUERY: None}
+		self._inputFileFormats		   = {REFERENCE: None,  QUERY: None}
+		self._starts				   = {REFERENCE: None, QUERY: None}
+		self._ends					   = {REFERENCE: None, QUERY: None}
+		self._fivePrimes			   = {REFERENCE: None, QUERY: None}
+		self._threePrimes			   = {REFERENCE: None, QUERY: None}
+		self._ncListHandlers		   = {REFERENCE: None,  QUERY: None}
+		self._convertedFileNames	   = {REFERENCE: False, QUERY: False}
+		self._sorted                   = False
+		self._index                    = False
+		self._introns				   = False
+		self._antisense				   = False
+		self._colinear				   = False
+		self._invert				   = False
+		self._distance				   = 0
+		self._minOverlap			   = 1
+		self._pcOverlap				   = None
+		self._included				   = False
+		self._including				   = False
+		self._outputNotOverlapping	   = False
+		self._tmpRefFileName		   = None
+		self._currentQueryTranscript   = None
+		self._currentOrQueryTranscript = None
+		self._currentExQueryTranscript = None
+		self._randInt				   = random.randint(0, 100000)
+		
+	def __del__(self):
+		for fileName in [self._tmpRefFileName] + self._convertedFileNames.values():
+			if fileName != None and os.path.exists(fileName):
+				os.remove(fileName)
+
+	def close(self):
+		self._iWriter.close()
+		
+	def setInput(self, fileName, format, type):
+		chooser = ParserChooser(self._verbosity)
+		chooser.findFormat(format)
+		self._inputFileNames[type]   = fileName
+		self._inputFileFormats[type] = format
+		
+	def setOutput(self, outputFileName):
+		if outputFileName != '':
+			self._outputFileName = outputFileName
+		self._iWriter = Gff3Writer(self._outputFileName)
+
+	def setSorted(self, sorted):
+		self._sorted = sorted
+
+	def setIndex(self, index):
+		self._index = index
+
+	def restrictToStart(self, distance, type):
+		self._starts[type] = distance
+		
+	def restrictToEnd(self, distance, type):
+		self._ends[type] = distance
+		
+	def extendFivePrime(self, distance, type):
+		self._fivePrimes[type] = distance
+		
+	def extendThreePrime(self, distance, type):
+		self._threePrimes[type] = distance
+
+	def acceptIntrons(self, boolean):
+		self._introns = boolean
+
+	def getAntisenseOnly(self, boolean):
+		self._antisense = boolean
+		
+	def getColinearOnly(self, boolean):
+		self._colinear = boolean
+
+	def getInvert(self, boolean):
+		self._invert = boolean
+
+	def setMaxDistance(self, distance):
+		self._distance = distance
+
+	def setMinOverlap(self, overlap):
+		self._minOverlap = overlap
+
+	def setPcOverlap(self, overlap):
+		self._pcOverlap = overlap
+
+	def setIncludedOnly(self, boolean):
+		self._included = boolean
+		
+	def setIncludingOnly(self, boolean):
+		self._including = boolean
+
+	def includeNotOverlapping(self, boolean):
+		self._outputNotOverlapping = boolean
+		
+	def transformTranscript(self, transcript, type):
+		if self._starts[type] != None:
+			transcript.restrictStart(self._starts[type])
+		if self._ends[type] != None:
+			transcript.restrictEnd(self._ends[type])
+		if self._fivePrimes[type] != None:
+			transcript.extendStart(self._fivePrimes[type])
+		if self._threePrimes[type] != None:
+			transcript.extendEnd(self._threePrimes[type])
+		if self._introns:
+			transcript.exons = []
+		if type == REFERENCE and self._distance > 0:
+			transcript.extendExons(self._distance)
+		return transcript
+
+	def extendQueryTranscript(self, transcript):
+		self._currentExQueryTranscript = Transcript()
+		self._currentExQueryTranscript.copy(transcript)
+		if self._fivePrimes[QUERY] != None:
+			self._currentExQueryTranscript.extendStart(self._fivePrimes[QUERY])
+		if self._threePrimes[QUERY] != None:
+			self._currentExQueryTranscript.extendEnd(self._threePrimes[QUERY])
+		transcript.exons = []
+
+	def createTmpRefFile(self):
+		self._tmpRefFileName = "tmp_ref_%d.pkl" % (self._randInt)
+		if "SMARTTMPPATH" in os.environ:
+			self._tmpRefFileName = os.path.join(os.environ["SMARTTMPPATH"], self._tmpRefFileName)
+		chooser = ParserChooser(self._verbosity)
+		chooser.findFormat(self._inputFileFormats[REFERENCE])
+		parser = chooser.getParser(self._inputFileNames[REFERENCE])
+		writer = NCListFilePickle(self._tmpRefFileName, self._verbosity)
+		for transcript in parser.getIterator():
+			transcript = self.transformTranscript(transcript, REFERENCE)
+			writer.addTranscript(transcript)
+		writer.close()
+		self._inputFileNames[REFERENCE]   = self._tmpRefFileName
+		self._inputFileFormats[REFERENCE] = "pkl"
+
+	def createNCLists(self):
+		self._ncLists = dict([type, {}] for type in TYPES)
+		self._indices = dict([type, {}] for type in TYPES)
+		self._cursors = dict([type, {}] for type in TYPES)
+		for type in TYPES:
+			if self._verbosity > 2:
+				print "Creating %s NC-list..." % (TYPETOSTRING[type])
+			self._convertedFileNames[type] = "%s_%d_%d.ncl" % (self._inputFileNames[type], self._randInt, type)
+			ncLists = ConvertToNCList(self._verbosity)
+			ncLists.setInputFileName(self._inputFileNames[type], self._inputFileFormats[type])
+			ncLists.setOutputFileName(self._convertedFileNames[type])
+			ncLists.setSorted(self._sorted)
+			if type == REFERENCE and self._index:
+				ncLists.setIndex(True)
+			ncLists.run()
+			self._ncListHandlers[type] = NCListHandler(self._verbosity)
+			self._ncListHandlers[type].setFileName(self._convertedFileNames[type])
+			self._ncListHandlers[type].loadData()
+			self._nbLines[type]					= self._ncListHandlers[type].getNbElements()
+			self._nbElementsPerChromosome[type] = self._ncListHandlers[type].getNbElementsPerChromosome()
+			self._ncLists[type]					= self._ncListHandlers[type].getNCLists()
+			for chromosome, ncList in self._ncLists[type].iteritems():
+				self._cursors[type][chromosome] = NCListCursor(None, ncList, 0, self._verbosity)
+				if type == REFERENCE and self._index:
+					self._indices[REFERENCE][chromosome] = ncList.getIndex()
+			if self._verbosity > 2:
+				print "	...done"
+
+	def compare(self):
+		nbSkips, nbMoves   = 0, 0
+		previousChromosome = None
+		done			   = False
+		refNCList		   = None
+		queryNCList		   = None
+		startTime		   = time.time()
+		progress		   = Progress(len(self._ncLists[QUERY].keys()), "Checking overlap", self._verbosity)
+		for chromosome, queryNCList in self._ncLists[QUERY].iteritems():
+			queryParser = self._ncListHandlers[QUERY].getParser(chromosome)
+			queryNCList = self._ncLists[QUERY][chromosome]
+			queryCursor = self._cursors[QUERY][chromosome]
+			if chromosome != previousChromosome:
+				skipChromosome		= False
+				previousChromosome  = chromosome
+				if chromosome not in self._ncLists[REFERENCE]:
+					if self._outputNotOverlapping:
+						while not queryCursor.isOut():
+							self._currentQueryTranscript = queryCursor.getTranscript()
+							self._writeIntervalInNewGFF3({})
+							if queryCursor.hasChildren():
+								queryCursor.moveDown()
+							else:
+								queryCursor.moveNext()
+					progress.inc()
+					continue
+				refNCList = self._ncLists[REFERENCE][chromosome]
+				refCursor = self._cursors[REFERENCE][chromosome]
+			while True:
+				self._currentOrQueryTranscript = queryCursor.getTranscript()
+				self._currentQueryTranscript = Transcript()
+				self._currentQueryTranscript.copy(self._currentOrQueryTranscript)
+				self._currentQueryTranscript = self.transformTranscript(self._currentQueryTranscript, QUERY)
+				self.extendQueryTranscript(self._currentOrQueryTranscript)
+				newRefLaddr = self.checkIndex(refCursor)
+				if newRefLaddr != None:
+					nbMoves += 1
+					refCursor.setLIndex(newRefLaddr)
+					done = False
+				refCursor, done, unmatched = self.findOverlapIter(refCursor, done)
+				if refCursor.isOut():
+					if not self._invert and not self._outputNotOverlapping:
+						break
+				if (unmatched and not self._invert and not self._outputNotOverlapping) or not queryCursor.hasChildren():
+					queryCursor.moveNext()
+					nbSkips += 1
+				else:
+					queryCursor.moveDown()
+				if queryCursor.isOut():
+					break
+			progress.inc()
+		progress.done()
+		endTime = time.time()
+		self._timeSpent = endTime - startTime
+		if self._verbosity >= 10:
+			print "# skips:   %d" % (nbSkips)
+			print "# moves:   %d" % (nbMoves)
+
+	def findOverlapIter(self, cursor, done):
+		chromosome = self._currentQueryTranscript.getChromosome()
+		matched	= False
+		if chromosome not in self._ncLists[REFERENCE]:
+			return None, False, True
+		ncList = self._ncLists[REFERENCE][chromosome]
+		overlappingNames = {}
+		nextDone = False
+		firstOverlapLAddr = NCListCursor(cursor)
+		firstOverlapLAddr.setLIndex(-1)
+		if cursor.isOut():
+			self._writeIntervalInNewGFF3(overlappingNames)
+			return firstOverlapLAddr, False, True
+		parentCursor = NCListCursor(cursor)
+		parentCursor.moveUp()
+		firstParentAfter = False
+		while not parentCursor.isOut(): 
+			if self.isOverlapping(parentCursor) == 0:
+				matched = True
+				if self._checkOverlap(parentCursor.getTranscript()):
+					overlappingNames.update(self._extractID(parentCursor.getTranscript()))
+				if firstOverlapLAddr.isOut():
+					firstOverlapLAddr.copy(parentCursor)
+					nextDone = True 
+			elif self.isOverlapping(parentCursor) == 1:
+				firstParentAfter = NCListCursor(parentCursor)
+			parentCursor.moveUp()
+		if firstParentAfter:
+			written = self._writeIntervalInNewGFF3(overlappingNames)
+			return firstParentAfter, False, not written if self._invert else not matched
+		#This loop finds the overlaps with currentRefLAddr.#
+		while True:
+			parentCursor = NCListCursor(cursor)
+			parentCursor.moveUp()
+			#In case: Query is on the right of the RefInterval and does not overlap.
+			overlap = self.isOverlapping(cursor)
+			if overlap == -1:
+				cursor.moveNext()
+			#In case: Query overlaps with RefInterval.	
+			elif overlap == 0:
+				matched = True
+				if self._checkOverlap(cursor.getTranscript()):
+					overlappingNames.update(self._extractID(cursor.getTranscript()))
+				if firstOverlapLAddr.compare(parentCursor):
+					firstOverlapLAddr.copy(cursor)
+					nextDone = True
+				if done:
+					cursor.moveNext()
+				else:
+					if not cursor.hasChildren():
+						cursor.moveNext()
+						if cursor.isOut():
+							break
+					else:
+						cursor.moveDown()
+			#In case: Query is on the left of the RefInterval and does not overlap.		
+			else:
+				if firstOverlapLAddr.isOut() or firstOverlapLAddr.compare(parentCursor):
+					firstOverlapLAddr.copy(cursor)
+					nextDone = False # new
+				break
+			
+			done = False
+			if cursor.isOut():
+				break
+		written = self._writeIntervalInNewGFF3(overlappingNames)
+		return firstOverlapLAddr, nextDone, not written if self._invert else not matched
+	
+	def isOverlapping(self, refTranscript):
+		if (self._currentExQueryTranscript.getStart() <= refTranscript.getEnd() and self._currentExQueryTranscript.getEnd() >= refTranscript.getStart()):
+			return 0   
+		if self._currentExQueryTranscript.getEnd() < refTranscript.getStart():
+			return 1
+		return -1
+
+	def checkIndex(self, cursor):
+		if not self._index:
+			return None
+		if cursor.isOut():
+			return None
+		chromosome = self._currentExQueryTranscript.getChromosome()
+		nextLIndex = self._indices[REFERENCE][chromosome].getIndex(self._currentExQueryTranscript)
+		if nextLIndex == None:
+			return None
+		ncList		 = self._ncLists[REFERENCE][chromosome]
+		nextGffAddress = ncList.getRefGffAddr(nextLIndex)
+		thisGffAddress = cursor.getGffAddress()
+		if nextGffAddress > thisGffAddress:
+			return nextLIndex
+		return None
+		
+	def _writeIntervalInNewGFF3(self, names):
+		nbOverlaps = 0
+		for cpt in names.values():
+			nbOverlaps += cpt
+		self._nbOverlappingQueries += 1		      if Utils.xor(names, self._invert) else 0
+		self._nbOverlaps		   += nbOverlaps  if Utils.xor(names, self._invert) else 0
+		if names:
+			self._currentQueryTranscript.setTagValue("overlapWith", ",".join(names))
+			self._currentQueryTranscript.setTagValue("nbOverlaps", nbOverlaps)
+			if self._invert:
+				return False
+		else:
+			if self._outputNotOverlapping:
+				self._currentQueryTranscript.setTagValue("nbOverlaps", 0)
+			elif not self._invert:
+				return False
+		self._iWriter.addTranscript(self._currentQueryTranscript)
+		self._iWriter.write()
+		return True
+		
+	def _extractID(self, transcript):
+		id		 = transcript.getTagValue("ID")		      if "ID"		  in transcript.getTagNames() else transcript.getUniqueName()
+		nbElements = transcript.getTagValue("nbElements") if "nbElements" in transcript.getTagNames() else 1
+		return {id: float(nbElements)}
+
+	def _checkOverlap(self, refTranscript):
+		if self._currentQueryTranscript.getDistance(refTranscript) > self._distance:
+			return False
+		minOverlap = self._minOverlap
+		if self._pcOverlap != None:
+			minOverlap = max(self._minOverlap, self._currentQueryTranscript.getSize() / 100.0 * self._pcOverlap)
+		if not self._currentQueryTranscript.overlapWith(refTranscript, minOverlap):
+			return False
+		if self._antisense and self._currentQueryTranscript.getDirection() == refTranscript.getDirection():
+			return False
+		if self._colinear and self._currentQueryTranscript.getDirection() != refTranscript.getDirection():
+			return False
+		if self._included and not refTranscript.include(self._currentQueryTranscript):
+			return False
+		if self._including and not self._currentQueryTranscript.include(refTranscript):
+			return False
+		if self._introns:
+			return True
+		return self._currentQueryTranscript.overlapWithExon(refTranscript, minOverlap)
+		
+	def run(self):
+		self.createTmpRefFile()
+		self.createNCLists()
+		self.compare()
+		self.close()
+		if self._verbosity > 0:
+			print "# queries: %d" % (self._nbLines[QUERY])
+			print "# refs:	  %d" % (self._nbLines[REFERENCE])
+			print "# written: %d (%d overlaps)" % (self._nbOverlappingQueries, self._nbOverlaps)
+			print "time: 	  %ds" % (self._timeSpent)
+
+
+if __name__ == "__main__":
+	description = "Compare Overlapping v1.0.4: Get the data which overlap with a reference set. [Category: Data Comparison]"
+
+	parser = OptionParser(description = description)
+	parser.add_option("-i", "--input1",		      dest="inputFileName1", action="store",					 type="string", help="input file 1 [compulsory] [format: file in transcript format given by -f]")
+	parser.add_option("-f", "--format1",		  dest="format1",		 action="store",					 type="string", help="format of file 1 [compulsory] [format: transcript file format]")
+	parser.add_option("-j", "--input2",		      dest="inputFileName2", action="store",					 type="string", help="input file 2 [compulsory] [format: file in transcript format given by -g]")
+	parser.add_option("-g", "--format2",		  dest="format2",		 action="store",					 type="string", help="format of file 2 [compulsory] [format: transcript file format]")
+	parser.add_option("-o", "--output",		      dest="output",		 action="store",	  default=None,  type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+	parser.add_option("-D", "--index",	          dest="index",	         action="store_true", default=False,	            help="add an index to the reference file (faster but more memory) [format: boolean] [default: False]")
+	parser.add_option("-r", "--sorted",	          dest="sorted",	     action="store_true", default=False,	            help="input files are already sorted [format: boolean] [default: False]")
+	parser.add_option("-S", "--start1",		      dest="start1",		 action="store",	  default=None,  type="int",	help="only consider the n first nucleotides of the transcripts in file 1 (do not use it with -U) [format: int]")
+	parser.add_option("-s", "--start2",		      dest="start2",		 action="store",	  default=None,  type="int",	help="only consider the n first nucleotides of the transcripts in file 2 (do not use it with -u) [format: int]")
+	parser.add_option("-U", "--end1",			  dest="end1",		     action="store",	  default=None,  type="int",	help="only consider the n last nucleotides of the transcripts in file 1 (do not use it with -S) [format: int]")
+	parser.add_option("-u", "--end2",			  dest="end2",		     action="store",	  default=None,  type="int",	help="only consider the n last nucleotides of the transcripts in file 2 (do not use it with -s) [format: int]")
+	parser.add_option("-t", "--intron",		      dest="introns",		 action="store_true", default=False,				help="also report introns [format: bool] [default: false]")
+	parser.add_option("-E", "--5primeExtension1", dest="fivePrime1",	 action="store",	  default=None,  type="int",	help="extension towards 5' in file 1 [format: int]")
+	parser.add_option("-e", "--5primeExtension2", dest="fivePrime2",	 action="store",	  default=None,  type="int",	help="extension towards 5' in file 2 [format: int]")
+	parser.add_option("-N", "--3primeExtension1", dest="threePrime1",	 action="store",	  default=None,  type="int",	help="extension towards 3' in file 1 [format: int]")
+	parser.add_option("-n", "--3primeExtension2", dest="threePrime2",	 action="store",	  default=None,  type="int",	help="extension towards 3' in file 2 [format: int]")
+	parser.add_option("-c", "--colinear",		  dest="colinear",		 action="store_true", default=False,				help="colinear only [format: bool] [default: false]")
+	parser.add_option("-a", "--antisense",		  dest="antisense",		 action="store_true", default=False,				help="antisense only [format: bool] [default: false]")
+	parser.add_option("-d", "--distance",		  dest="distance",	     action="store",	  default=0,	 type="int",	help="accept some distance between query and reference [format: int]")
+	parser.add_option("-k", "--included",		  dest="included",	     action="store_true", default=False,				help="keep only elements from file 1 which are included in an element of file 2 [format: bool] [default: false]")
+	parser.add_option("-K", "--including",		  dest="including",	     action="store_true", default=False,				help="keep only elements from file 2 which are included in an element of file 1 [format: bool] [default: false]")
+	parser.add_option("-m", "--minOverlap",		  dest="minOverlap",	 action="store",	  default=1,	 type="int",	help="minimum number of nucleotides overlapping to declare an overlap [format: int] [default: 1]")
+	parser.add_option("-p", "--pcOverlap",		  dest="pcOverlap",	     action="store",	  default=None,  type="int",	help="minimum percentage of nucleotides to overlap to declare an overlap [format: int]")
+	parser.add_option("-O", "--notOverlapping",   dest="notOverlapping", action="store_true", default=False,				help="also output not overlapping data [format: bool] [default: false]")
+	parser.add_option("-x", "--exclude",		  dest="exclude",		 action="store_true", default=False,				help="invert the match [format: bool] [default: false]")
+	parser.add_option("-v", "--verbosity",		  dest="verbosity",		 action="store",	  default=1,	 type="int",	help="trace level [format: int]")
+	(options, args) = parser.parse_args()
+
+	co = CompareOverlapping(options.verbosity)
+	co.setInput(options.inputFileName1, options.format1, QUERY)
+	co.setInput(options.inputFileName2, options.format2, REFERENCE)
+	co.setOutput(options.output)
+	co.setSorted(options.sorted)
+	co.setIndex(options.index)
+	co.restrictToStart(options.start1, QUERY)
+	co.restrictToStart(options.start2, REFERENCE)
+	co.restrictToEnd(options.end1, QUERY)
+	co.restrictToEnd(options.end2, REFERENCE)
+	co.extendFivePrime(options.fivePrime1, QUERY)
+	co.extendFivePrime(options.fivePrime2, REFERENCE)
+	co.extendThreePrime(options.threePrime1, QUERY)
+	co.extendThreePrime(options.threePrime2, REFERENCE)
+	co.acceptIntrons(options.introns)
+	co.getAntisenseOnly(options.antisense)
+	co.getColinearOnly(options.colinear)
+	co.getInvert(options.exclude)
+	co.setMaxDistance(options.distance)
+	co.setMinOverlap(options.minOverlap)
+	co.setPcOverlap(options.pcOverlap)
+	co.setIncludedOnly(options.included)
+	co.setIncludingOnly(options.including)
+	co.includeNotOverlapping(options.notOverlapping)
+	co.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/CompareOverlappingSmallQuery.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,226 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2011
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Mapping import Mapping
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+
+MINBIN = 3
+MAXBIN = 7
+REFERENCE = 0
+QUERY = 1
+
+def getBin(start, end):
+	for i in range(MINBIN, MAXBIN + 1):
+		binLevel = 10 ** i
+		if int(start / binLevel) == int(end / binLevel):
+			return int(i * 10 ** (MAXBIN + 1) + int(start / binLevel))
+	return int((MAXBIN + 1) * 10 ** (MAXBIN + 1))
+
+def getOverlappingBins(start, end):
+	array	= []
+	bigBin = int((MAXBIN + 1) * 10 ** (MAXBIN + 1))
+	for i in range(MINBIN, MAXBIN + 1):
+		binLevel = 10 ** i
+		array.append((int(i * 10 ** (MAXBIN + 1) + int(start / binLevel)), int(i * 10 ** (MAXBIN + 1) + int(end / binLevel))))
+	array.append((bigBin, bigBin))
+	return array
+
+
+class CompareOverlappingSmallQuery(object):
+
+	def __init__(self, verbosity):
+		self.verbosity      = verbosity
+		self.tableNames     = {}
+		self.nbQueries      = 0
+		self.nbRefs	        = 0
+		self.nbWritten      = 0
+		self.nbOverlaps     = 0
+		self.distance       = None
+		self.invert         = False
+		self.antisense      = False
+		self.collinear      = False
+		self.bins	        = {}
+		self.overlaps       = {}
+		self.notOverlapping = False
+
+	def setReferenceFile(self, fileName, format):
+		chooser = ParserChooser(self.verbosity)
+		chooser.findFormat(format)
+		self.refParser = chooser.getParser(fileName)
+
+	def setQueryFile(self, fileName, format):
+		chooser = ParserChooser(self.verbosity)
+		chooser.findFormat(format)
+		self.queryParser = chooser.getParser(fileName)
+
+	def setOutputFile(self, fileName):
+		self.writer = TranscriptWriter(fileName, "gff3", self.verbosity)
+
+	def setDistance(self, distance):
+		self.distance = distance
+
+	def setInvert(self, boolean):
+		self.invert = boolean
+
+	def setCollinear(self, boolean):
+		self.collinear = boolean
+
+	def setAntisense(self, boolean):
+		self.antisense = boolean
+
+	def includeNotOverlapping(self, boolean):
+		self.notOverlapping = boolean
+
+	def loadQuery(self):
+		progress = UnlimitedProgress(10000, "Reading queries", self.verbosity)
+		for transcript in self.queryParser.getIterator():
+			if transcript.__class__.__name__ == "Mapping":
+				transcript = transcript.getTranscript()
+			chromosome = transcript.getChromosome()
+			bin		   = getBin(transcript.getStart(), transcript.getEnd())
+			if chromosome not in self.bins:
+				self.bins[chromosome] = {}
+			if bin not in self.bins[chromosome]:
+				self.bins[chromosome][bin] = []
+			self.bins[chromosome][bin].append(transcript)
+			if self.notOverlapping or self.invert:
+				self.overlaps[transcript] = {}
+			self.nbQueries += 1
+			progress.inc()
+		progress.done()
+
+	def _compareTwoTranscripts(self, queryTranscript, refTranscript):
+		if not queryTranscript.overlapWithExon(refTranscript):
+			return False
+		if self.collinear and queryTranscript.getDirection() != refTranscript.getDirection():
+			return False
+		if self.antisense and queryTranscript.getDirection() == refTranscript.getDirection():
+			return False
+		return True
+
+	def _alterTranscript(self, transcript, type):
+		if type == REFERENCE:
+			if self.distance != None:
+				transcript.extendExons(self.distance)
+		return transcript
+
+	def _compareTranscript(self, refTranscript):
+		refChromosome = refTranscript.getChromosome()
+		if refChromosome not in self.bins:
+			return []
+		refStart = refTranscript.getStart()
+		refEnd   = refTranscript.getEnd()
+		bins	 = getOverlappingBins(refStart, refEnd)
+		for binRange in bins:
+			for bin in range(binRange[0], binRange[1]+1):
+				if bin not in self.bins[refChromosome]:
+					continue
+				for queryTranscript in self.bins[refChromosome][bin]:
+					if self._compareTwoTranscripts(queryTranscript, refTranscript):
+						if queryTranscript not in self.overlaps:
+							self.overlaps[queryTranscript] = {}
+						nbElements = int(float(refTranscript.getTagValue("nbElements"))) if "nbElements" in refTranscript.getTagNames() else 1
+						self.overlaps[queryTranscript][refTranscript.getName()] = int(float(refTranscript.getTagValue("nbElements"))) if "nbElements" in refTranscript.getTagNames() else 1
+						self.nbOverlaps += nbElements
+
+	def _updateTranscript(self, queryTranscript):
+		overlaps = self.overlaps[queryTranscript]
+		queryTranscript.setTagValue("nbOverlaps", sum(overlaps.values()))
+		if overlaps:
+			queryTranscript.setTagValue("overlapsWith", "--".join(overlaps.keys())[:100])
+		return queryTranscript
+
+	def compare(self):
+		progress = UnlimitedProgress(10000, "Comparing references", self.verbosity)
+		for refTranscript in self.refParser.getIterator():
+			if refTranscript.__class__.__name__ == "Mapping":
+				refTranscript = refTranscript.getTranscript()
+			refTranscript = self._alterTranscript(refTranscript, REFERENCE)
+			self._compareTranscript(refTranscript)
+			self.nbRefs += 1
+			progress.inc()
+		progress.done()
+
+	def printResults(self):
+		for transcript in self.overlaps:
+			if not self.invert or not self.overlaps[transcript]:
+				if not self.invert:
+					transcript = self._updateTranscript(transcript)
+				self.writer.addTranscript(transcript)
+				self.nbWritten += 1
+		self.writer.close()
+
+	def displayResults(self):
+		print "# queries:  %d" % (self.nbQueries)
+		print "# refs:     %d" % (self.nbRefs)
+		print "# written:  %d (%d overlaps)" % (self.nbWritten, self.nbOverlaps)
+
+	def run(self):
+		self.loadQuery()
+		self.compare()
+		self.printResults()
+		self.displayResults()
+
+if __name__ == "__main__":
+	
+	description = "Compare Overlapping Small Query v1.0.1: Provide the queries that overlap with a reference, when the query is small. [Category: Data Comparison]"
+
+	parser = OptionParser(description = description)
+	parser.add_option("-i", "--input1",	        dest="inputFileName1", action="store",			          type="string", help="query input file [compulsory] [format: file in transcript format given by -f]")
+	parser.add_option("-f", "--format1",        dest="format1",		  action="store",			          type="string", help="format of previous file [compulsory] [format: transcript file format]")
+	parser.add_option("-j", "--input2",	        dest="inputFileName2", action="store",			          type="string", help="reference input file [compulsory] [format: file in transcript format given by -g]")
+	parser.add_option("-g", "--format2",        dest="format2",		  action="store",			          type="string", help="format of previous file [compulsory] [format: transcript file format]")
+	parser.add_option("-o", "--output",	        dest="outputFileName", action="store",			          type="string", help="output file [format: output file in GFF3 format]")
+	parser.add_option("-O", "--notOverlapping", dest="notOverlapping", action="store_true", default=False,				 help="also output not overlapping data [format: bool] [default: false]")
+	parser.add_option("-d", "--distance",		dest="distance",	   action="store",	    default=0,	  type="int",	 help="accept some distance between query and reference [format: int]")
+	parser.add_option("-c", "--collinear",		dest="collinear",	   action="store_true", default=False,			 	 help="provide collinear features [format: bool] [default: false]")
+	parser.add_option("-a", "--antisense",		dest="antisense",	   action="store_true", default=False,			 	 help="provide antisense features [format: bool] [default: false]")
+	parser.add_option("-x", "--exclude",		dest="exclude",		   action="store_true", default=False,			 	 help="invert the match [format: bool] [default: false]")
+	parser.add_option("-v", "--verbosity",      dest="verbosity",	   action="store",      default=1,    type="int",	 help="trace level [format: int]")
+	(options, args) = parser.parse_args()
+
+	cosq = CompareOverlappingSmallQuery(options.verbosity)
+	cosq.setQueryFile(options.inputFileName1, options.format1)
+	cosq.setReferenceFile(options.inputFileName2, options.format2)
+	cosq.setOutputFile(options.outputFileName)
+	cosq.includeNotOverlapping(options.notOverlapping)
+	cosq.setDistance(options.distance)
+	cosq.setCollinear(options.collinear)
+	cosq.setAntisense(options.antisense)
+	cosq.setInvert(options.exclude)
+	cosq.run()
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/CompareOverlappingSmallRef.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,217 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2011
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Mapping import Mapping
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+
+MINBIN = 3
+MAXBIN = 7
+REFERENCE = 0
+QUERY = 1
+
+def getBin(start, end):
+	for i in range(MINBIN, MAXBIN + 1):
+		binLevel = 10 ** i
+		if int(start / binLevel) == int(end / binLevel):
+			return int(i * 10 ** (MAXBIN + 1) + int(start / binLevel))
+	return int((MAXBIN + 1) * 10 ** (MAXBIN + 1))
+
+def getOverlappingBins(start, end):
+	array	= []
+	bigBin = int((MAXBIN + 1) * 10 ** (MAXBIN + 1))
+	for i in range(MINBIN, MAXBIN + 1):
+		binLevel = 10 ** i
+		array.append((int(i * 10 ** (MAXBIN + 1) + int(start / binLevel)), int(i * 10 ** (MAXBIN + 1) + int(end / binLevel))))
+	array.append((bigBin, bigBin))
+	return array
+
+
+class CompareOverlappingSmallRef(object):
+
+	def __init__(self, verbosity):
+		self.verbosity      = verbosity
+		self.tableNames     = {}
+		self.nbQueries      = 0
+		self.nbRefs	        = 0
+		self.nbWritten      = 0
+		self.nbOverlaps     = 0
+		self.invert         = False
+		self.antisense      = False
+		self.collinear      = False
+		self.distance       = None
+		self.bins	        = {}
+		self.notOverlapping = False
+
+	def setReferenceFile(self, fileName, format):
+		chooser = ParserChooser(self.verbosity)
+		chooser.findFormat(format)
+		self.refParser = chooser.getParser(fileName)
+
+	def setQueryFile(self, fileName, format):
+		chooser = ParserChooser(self.verbosity)
+		chooser.findFormat(format)
+		self.queryParser = chooser.getParser(fileName)
+
+	def setOutputFile(self, fileName):
+		self.writer = TranscriptWriter(fileName, "gff3", self.verbosity)
+
+	def setDistance(self, distance):
+		self.distance = distance
+
+	def setCollinear(self, boolean):
+		self.collinear = boolean
+
+	def setAntisense(self, boolean):
+		self.antisense = boolean
+
+	def setInvert(self, boolean):
+		self.invert = boolean
+
+	def includeNotOverlapping(self, boolean):
+		self.notOverlapping = boolean
+
+	def loadRef(self):
+		progress = UnlimitedProgress(10000, "Reading references", self.verbosity)
+		for transcript in self.refParser.getIterator():
+			if transcript.__class__.__name__ == "Mapping":
+				transcript = transcript.getTranscript()
+			transcript = self._alterTranscript(transcript, REFERENCE)
+			chromosome = transcript.getChromosome()
+			bin		   = getBin(transcript.getStart(), transcript.getEnd())
+			if chromosome not in self.bins:
+				self.bins[chromosome] = {}
+			if bin not in self.bins[chromosome]:
+				self.bins[chromosome][bin] = []
+			self.bins[chromosome][bin].append(transcript)
+			self.nbRefs += 1
+			progress.inc()
+		progress.done()
+
+	def _alterTranscript(self, transcript, type):
+		if type == REFERENCE:
+			if self.distance != None:
+				transcript.extendExons(self.distance)
+		return transcript
+
+	def _compareTwoTranscripts(self, queryTranscript, refTranscript):
+		if not queryTranscript.overlapWithExon(refTranscript):
+			return False
+		if self.collinear and queryTranscript.getDirection() != refTranscript.getDirection():
+			return False
+		if self.antisense and queryTranscript.getDirection() == refTranscript.getDirection():
+			return False
+		return True
+
+	def _compareTranscript(self, queryTranscript):
+		queryChromosome = queryTranscript.getChromosome()
+		if queryChromosome not in self.bins:
+			return []
+		queryStart = queryTranscript.getStart()
+		queryEnd   = queryTranscript.getEnd()
+		bins	   = getOverlappingBins(queryStart, queryEnd)
+		overlaps   = {}
+		for binRange in bins:
+			for bin in range(binRange[0], binRange[1]+1):
+				if bin not in self.bins[queryChromosome]:
+					continue
+				for refTranscript in self.bins[queryChromosome][bin]:
+					if self._compareTwoTranscripts(queryTranscript, refTranscript):
+						nbElements = int(float(refTranscript.getTagValue("nbElements"))) if "nbElements" in refTranscript.getTagNames() else 1
+						overlaps[refTranscript.getName()] = int(float(refTranscript.getTagValue("nbElements"))) if "nbElements" in refTranscript.getTagNames() else 1
+						self.nbOverlaps += nbElements
+		return overlaps
+
+	def _updateTranscript(self, queryTranscript, overlaps):
+		queryTranscript.setTagValue("nbOverlaps", sum(overlaps.values()))
+		if overlaps:
+			queryTranscript.setTagValue("overlapsWith", "--".join(overlaps.keys())[:100])
+		return queryTranscript
+
+	def compare(self):
+		progress = UnlimitedProgress(10000, "Comparing queries", self.verbosity)
+		for queryTranscript in self.queryParser.getIterator():
+			if queryTranscript.__class__.__name__ == "Mapping":
+				queryTranscript = queryTranscript.getTranscript()
+			progress.inc()
+			self.nbQueries += 1
+			overlaps = self._compareTranscript(queryTranscript)
+			if self.notOverlapping or (overlaps and not self.invert) or (not overlaps and self.invert):
+				if not self.invert:
+					queryTranscript = self._updateTranscript(queryTranscript, overlaps)
+				self.writer.addTranscript(queryTranscript)
+				self.nbWritten += 1
+		progress.done()
+		self.writer.close()
+
+	def displayResults(self):
+		print "# queries:  %d" % (self.nbQueries)
+		print "# refs:     %d" % (self.nbRefs)
+		print "# written:  %d (%d overlaps)" % (self.nbWritten, self.nbOverlaps)
+
+	def run(self):
+		self.loadRef()
+		self.compare()
+		self.displayResults()
+
+if __name__ == "__main__":
+	
+	description = "Compare Overlapping Small Reference v1.0.1: Provide the queries that overlap with a reference, when the reference is small. [Category: Data Comparison]"
+
+	parser = OptionParser(description = description)
+	parser.add_option("-i", "--input1",	        dest="inputFileName1", action="store",			          type="string", help="query input file [compulsory] [format: file in transcript format given by -f]")
+	parser.add_option("-f", "--format1",        dest="format1",		  action="store",			          type="string", help="format of previous file [compulsory] [format: transcript file format]")
+	parser.add_option("-j", "--input2",	        dest="inputFileName2", action="store",			          type="string", help="reference input file [compulsory] [format: file in transcript format given by -g]")
+	parser.add_option("-g", "--format2",        dest="format2",		  action="store",			          type="string", help="format of previous file [compulsory] [format: transcript file format]")
+	parser.add_option("-o", "--output",	        dest="outputFileName", action="store",			          type="string", help="output file [format: output file in GFF3 format]")
+	parser.add_option("-O", "--notOverlapping", dest="notOverlapping", action="store_true", default=False,				help="also output not overlapping data [format: bool] [default: false]")
+	parser.add_option("-d", "--distance",		dest="distance",	   action="store",	    default=0,	  type="int",	 help="accept some distance between query and reference [format: int]")
+	parser.add_option("-c", "--collinear",		dest="collinear",	   action="store_true", default=False,			 	 help="provide collinear features [format: bool] [default: false]")
+	parser.add_option("-a", "--antisense",		dest="antisense",	   action="store_true", default=False,			 	 help="provide antisense features [format: bool] [default: false]")
+	parser.add_option("-x", "--exclude",		dest="exclude",		   action="store_true", default=False,			 	 help="invert the match [format: bool] [default: false]")
+	parser.add_option("-v", "--verbosity",      dest="verbosity",	  action="store",       default=1,    type="int",	help="trace level [format: int]")
+	(options, args) = parser.parse_args()
+
+	cosr = CompareOverlappingSmallRef(options.verbosity)
+	cosr.setQueryFile(options.inputFileName1, options.format1)
+	cosr.setReferenceFile(options.inputFileName2, options.format2)
+	cosr.setOutputFile(options.outputFileName)
+	cosr.includeNotOverlapping(options.notOverlapping)
+	cosr.setDistance(options.distance)
+	cosr.setAntisense(options.antisense)
+	cosr.setInvert(options.exclude)
+	cosr.setInvert(options.exclude)
+	cosr.run()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ComputeCoverage.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,142 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2011
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os, random
+from optparse import OptionParser, OptionGroup
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.misc.Progress import Progress
+from commons.core.writer.Gff3Writer import Gff3Writer
+
+
+class CoverageComputer(object):
+
+	def __init__(self, verbosity = 0):
+		self.verbosity	     = verbosity
+		self.queryReader	 = None
+		self.referenceReader = None
+		self.outputWriter	 = None
+		self.introns		 = False
+		self.nbNucleotides   = 0
+		self.nbCovered	     = 0
+
+	def setInputQueryFile(self, fileName, format):
+		self.queryReader = TranscriptContainer(fileName, format, self.verbosity-1)
+
+	def setInputReferenceFile(self, fileName, format):
+		self.referenceReader = TranscriptContainer(fileName, format, self.verbosity-1)
+
+	def includeIntrons(self, boolean):
+		self.introns = boolean
+
+	def setOutputFileName(self, fileName, title="S-MART", feature="transcript", featurePart="exon"):
+		self.outputWriter = Gff3Writer(fileName, self.verbosity-1)
+		self.outputWriter.setTitle(title)
+		self.outputWriter.setFeature(feature)
+		self.outputWriter.setFeaturePart(featurePart)
+
+	def readReference(self):
+		self.coveredRegions = {}
+		progress = Progress(self.referenceReader.getNbTranscripts(), "Reading reference file", self.verbosity-1)
+		for transcript in self.referenceReader.getIterator():
+			chromosome = transcript.getChromosome()
+			if chromosome not in self.coveredRegions:
+				self.coveredRegions[chromosome] = {}
+			if self.introns:
+				transcript.removeExons()
+			for exon in transcript.getExons():
+				for position in range(exon.getStart(), exon.getEnd()+1):
+					self.coveredRegions[chromosome][position] = 1
+			progress.inc()
+		progress.done()
+
+	def readQuery(self):
+		progress = Progress(self.queryReader.getNbTranscripts(), "Reading query file", self.verbosity-1)
+		for transcript in self.queryReader.getIterator():
+			progress.inc()
+			chromosome = transcript.getChromosome()
+			if chromosome not in self.coveredRegions:
+				continue
+			if self.introns:
+				transcript.removeExons()
+			for exon in transcript.getExons():
+				for position in range(exon.getStart(), exon.getEnd()+1):
+					self.nbNucleotides += 1
+					self.nbCovered     += self.coveredRegions[chromosome].get(position, 0)
+		progress.done()
+
+	def write(self):
+		progress = Progress(self.queryReader.getNbTranscripts(), "Writing output file", self.verbosity-1)
+		for transcript in self.queryReader.getIterator():
+			chromosome = transcript.getChromosome()
+			if self.introns:
+				transcript.removeExons()
+			size	 = transcript.getSize()
+			coverage = 0
+			for exon in transcript.getExons():
+				for position in range(exon.getStart(), exon.getEnd()+1):
+					coverage += self.coveredRegions[chromosome].get(position, 0)
+			transcript.setTagValue("coverage", 0 if size == 0 else float(coverage) / size * 100)
+			self.outputWriter.addTranscript(transcript)
+			progress.inc()
+		progress.done()
+
+	def sumUp(self):
+		print "%d nucleotides in query, %d (%.f%%) covered" % (self.nbNucleotides, self.nbCovered, 0 if self.nbNucleotides == 0 else float(self.nbCovered) / self.nbNucleotides * 100)
+
+	def run(self):
+		self.readReference()
+		self.readQuery()
+		if self.outputWriter != None:
+			self.write()
+		self.sumUp()
+
+
+if __name__ == "__main__":
+	
+	# parse command line
+	description = "Compute Coverage v1.0.1: Compute the coverage of a set with respect to another set. [Category: Personal]"
+
+	parser = OptionParser(description = description)
+	parser.add_option("-i", "--input1",	   dest="inputFileName1", action="store",                     type="string", help="input query file [compulsory] [format: file in transcript format given by -f]")
+	parser.add_option("-f", "--format1",   dest="format1",        action="store",                     type="string", help="format of the first file [compulsory] [format: transcript file format]")
+	parser.add_option("-j", "--input2",	   dest="inputFileName2", action="store",                     type="string", help="input reference file [compulsory] [format: file in transcript format given by -f]")
+	parser.add_option("-g", "--format2",   dest="format2",        action="store",                     type="string", help="format of the second file [compulsory] [format: transcript file format]")
+	parser.add_option("-t", "--introns",   dest="introns",        action="store_true", default=False,                help="also include introns [format: boolean] [default: false]")
+	parser.add_option("-o", "--output",	   dest="outputFileName", action="store",	   default=None,  type="string", help="output file [format: output file in GFF3 format]")
+	parser.add_option("-v", "--verbosity", dest="verbosity",	  action="store",                     type="int",    help="trace level [default: 1] [format: int]")
+	(options, args) = parser.parse_args()
+
+	computer = CoverageComputer(options.verbosity)
+	computer.setInputQueryFile(options.inputFileName1, options.format1)
+	computer.setInputReferenceFile(options.inputFileName2, options.format2)
+	computer.includeIntrons(options.introns)
+	computer.setOutputFileName(options.outputFileName)
+	computer.run()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/CountReadGCPercent.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import FastaParser
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.misc.Progress import Progress
+from commons.core.utils.RepetOptionParser import RepetOptionParser
+from Gnome_tools.CountGCPercentBySlidingWindow import CountGCPercentBySlidingWindow
+
+
+class CountReadGCPercent(object):
+    
+    def __init__(self):
+        self.referenceReader = None
+        self.gffReader = None
+        self.outputWriter = None
+        self.verbose = 0
+        
+    def setInputReferenceFile(self, fileName):
+        self.referenceReader = fileName
+ 
+    def setInputGffFile(self, fileName):
+        self.gffReader = TranscriptContainer(fileName, 'gff3', self.verbose)
+        
+    def setOutputFileName(self, fileName):
+        self.outputWriter = Gff3Writer(fileName, self.verbose)
+
+    def readGffAnnotation(self):
+        self.coveredRegions = {}
+        progress = Progress(self.gffReader.getNbTranscripts(), "Reading gff3 annotation file", self.verbose)
+        for transcript in self.gffReader.getIterator():
+            chromosome = transcript.getChromosome()
+            if chromosome not in self.coveredRegions:
+                self.coveredRegions[chromosome] = {}
+            for exon in transcript.getExons():
+                for position in range(exon.getStart(), exon.getEnd()+1):
+                    self.coveredRegions[chromosome][position] = 1
+            progress.inc()
+        progress.done()
+        
+    def write(self):
+        iParser = FastaParser(self.referenceReader)
+        iParser.setTags()
+        iGetGCPercentBySW = CountGCPercentBySlidingWindow()
+        progress = Progress(self.gffReader.getNbTranscripts(), "Writing output file", self.verbose)
+        for transcript in self.gffReader.getIterator():
+            chromosome = transcript.getChromosome()
+            GCpercent = 0
+            nPercent = 0
+            for exon in transcript.getExons():
+                    for sequenceName in iParser.getTags().keys():
+                        if sequenceName != chromosome:
+                            continue
+                        else:
+                            subSequence = iParser.getSubSequence(sequenceName, exon.getStart() , exon.getEnd(), 1)
+                            GCpercent, nPercent = iGetGCPercentBySW.getGCPercentAccordingToNAndNPercent(subSequence)
+                            print "GCpercent = %f, nPercent = %f" % (GCpercent, nPercent)
+            transcript.setTagValue("GCpercent", GCpercent)
+            transcript.setTagValue("NPercent", nPercent)
+            self.outputWriter.addTranscript(transcript)
+            progress.inc()
+        progress.done()
+ 
+    def run(self):
+        self.readGffAnnotation()
+        if self.outputWriter != None:
+            self.write()
+            
+if __name__ == "__main__":
+        description = "Count GC percent for each read against a genome."
+        usage = "CountReadGCPercent.py -i <fasta file> -j <gff3 file> -o <output gff3 file> -v <verbose> -h]"
+        examples = "\nExample: \n"
+        examples += "\t$ python CountReadGCPercent.py -i file.fasta -j annotation.gff -o output.gff3"
+        examples += "\n\n"
+        parser = RepetOptionParser(description = description, usage = usage, version = "v1.0", epilog = examples)
+        parser.add_option( '-i', '--inputGenome', dest='fastaFile', help='fasta file [compulsory]', default= None )
+        parser.add_option( '-j', '--inputAnnotation', dest='gffFile', help='gff3 file [compulsory]', default= None)
+        parser.add_option( '-o', '--output', dest='outputFile', help='output gff3 file [compulsory]', default= None )
+        parser.add_option( '-v', '--verbose', dest='verbose', help='verbosity level (default=0/1)',type="int", default= 0 )
+        (options, args) = parser.parse_args()
+    
+        readGCPercent = CountReadGCPercent()
+        readGCPercent.setInputReferenceFile(options.fastaFile)
+        readGCPercent.setInputGffFile(options.gffFile)
+        readGCPercent.setOutputFileName(options.outputFile)
+        readGCPercent.run()
+        
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/FindOverlapsOptim.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,343 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2012
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+import os, struct, time, shutil
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.ncList.NCList import NCList
+from SMART.Java.Python.ncList.ConvertToNCList import ConvertToNCList
+from SMART.Java.Python.ncList.NCListParser import NCListParser
+from SMART.Java.Python.ncList.NCListCursor import NCListCursor
+from SMART.Java.Python.ncList.NCListFilePickle import NCListFilePickle, NCListFileUnpickle
+from SMART.Java.Python.ncList.NCListHandler import NCListHandler
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+try:
+   import cPickle as pickle
+except:
+   import pickle
+
+REFERENCE = 0
+QUERY = 1
+TYPES = (REFERENCE, QUERY)
+TYPETOSTRING = {0: "reference", 1: "query"}
+
+class FindOverlapsOptim(object):
+	
+	def __init__(self, verbosity = 1):
+		self._parsers				  = {}
+		self._sortedFileNames		  = {}
+		self._outputFileName		  = "outputOverlaps.gff3"
+		self._iWriter				  = None
+		self._inputFileNames		  = {REFERENCE: None,  QUERY: None}
+		self._convertedFileNames      = {REFERENCE: False, QUERY: False}
+		self._inputFileFormats		  = {REFERENCE: None,  QUERY: None}
+		self._converted			      = {REFERENCE: False, QUERY: False}
+		self._ncListHandlers          = {REFERENCE: None,  QUERY: None}
+		self._splittedFileNames	      = {REFERENCE: {},	QUERY: {}}
+		self._nbOverlappingQueries	  = 0
+		self._nbOverlaps			  = 0
+		self._nbLines				  = {REFERENCE: 0, QUERY: 0}
+		self._sorted                  = False
+		self._index                   = False
+		self._verbosity			      = verbosity
+		self._ncLists				  = {}
+		self._cursors				  = {}
+		self._nbElementsPerChromosome = {}
+		self._tmpDirectories		  = {REFERENCE: False, QUERY: False}
+		
+	def close(self):
+		self._iWriter.close()
+		for fileName in (self._sortedFileNames.values()):
+			if os.path.exists(fileName):
+				os.remove(fileName)
+		for fileName in self._convertedFileNames.values():
+			if fileName:
+				os.remove(fileName)
+		
+	def setRefFileName(self, fileName, format):
+		self.setFileName(fileName, format, REFERENCE)
+		
+	def setQueryFileName(self, fileName, format):
+		self.setFileName(fileName, format, QUERY)
+
+	def setFileName(self, fileName, format, type):
+		self._inputFileNames[type] = fileName
+		self._inputFileFormats[type] = format
+		if format.lower() != "nclist":
+			self._converted[type] = True
+		
+	def setOutputFileName(self, outputFileName):
+		self._outputFileName = outputFileName
+		self._iWriter = Gff3Writer(self._outputFileName)
+	
+	def setSorted(self, sorted):
+		self._sorted = sorted
+
+	def setIndex(self, index):
+		self._index = index
+
+	def createNCLists(self):
+		startTime = time.time()
+		if self._verbosity > 1:
+			print "Building database"
+		self._ncLists = dict([type, {}] for type in TYPES)
+		self._indices = dict([type, {}] for type in TYPES)
+		self._cursors = dict([type, {}] for type in TYPES)
+		for type in TYPES:
+			self._ncListHandlers[type] = NCListHandler(self._verbosity-3)
+			if self._converted[type]:
+				self._convertedFileNames[type] = "%s_%d.ncl" % (os.path.splitext(self._inputFileNames[type])[0], type)
+				ncLists = ConvertToNCList(self._verbosity-3)
+				ncLists.setInputFileName(self._inputFileNames[type], self._inputFileFormats[type])
+				ncLists.setSorted(self._sorted)
+				ncLists.setOutputFileName(self._convertedFileNames[type])
+				if type == REFERENCE and self._index:
+					ncLists.setIndex(True)
+				ncLists.run()
+				self._ncListHandlers[type].setFileName(self._convertedFileNames[type])
+			else:
+				self._ncListHandlers[type].setFileName(self._inputFileNames[type])
+			self._ncListHandlers[type].loadData()
+			self._nbLines[type]				    = self._ncListHandlers[type].getNbElements()
+			self._nbElementsPerChromosome[type] = self._ncListHandlers[type].getNbElementsPerChromosome()
+			self._ncLists[type]				    = self._ncListHandlers[type].getNCLists()
+			for chromosome, ncList in self._ncLists[type].iteritems():
+				self._cursors[type][chromosome] = NCListCursor(None, ncList, 0, self._verbosity)
+				if type == REFERENCE and self._index:
+					self._indices[REFERENCE][chromosome] = ncList.getIndex()
+		endTime = time.time()
+		if self._verbosity > 1:
+			print "done (%.2gs)" % (endTime - startTime)
+
+	def compare(self):
+		nbSkips, nbMoves   = 0, 0
+		previousChromosome = None
+		done			   = False
+		startTime		   = time.time()
+		progress		   = Progress(len(self._ncLists[QUERY].keys()), "Checking overlap", self._verbosity)
+		#print "query:", self._ncLists[QUERY].keys()
+		#print "reference:", self._ncLists[REFERENCE].keys()
+		for chromosome, queryNCList in self._ncLists[QUERY].iteritems():
+			queryParser = self._ncListHandlers[QUERY].getParser(chromosome)
+			queryCursor = self._cursors[QUERY][chromosome]
+			if chromosome != previousChromosome:
+				skipChromosome	  = False
+				previousChromosome  = chromosome
+				if chromosome not in self._ncLists[REFERENCE]:
+					#print "out ", chromosome
+					continue
+				refNCList = self._ncLists[REFERENCE][chromosome]
+				refCursor = self._cursors[REFERENCE][chromosome]
+			#print "starting", chromosome
+			while True:
+				queryTranscript = queryCursor.getTranscript()
+				newRefLaddr = self.checkIndex(queryTranscript, refCursor)
+				#print "query is", queryTranscript
+				if newRefLaddr != None:
+					nbMoves += 1
+					refCursor.setLIndex(newRefLaddr)
+					#print "skipping to", refCursor
+					done = False
+				refCursor, done, unmatched = self.findOverlapIter(queryTranscript, refCursor, done)
+				#print "completed with", refCursor, done, unmatched
+				if refCursor.isOut():
+					#print "exiting 1", chromosome
+					break
+				if unmatched or not queryCursor.hasChildren():
+					queryCursor.moveNext()
+					#print "moving next to", queryCursor
+					nbSkips += 1
+				else:
+					queryCursor.moveDown()
+					#print "moving down to", queryCursor
+				if queryCursor.isOut():
+					#print "exiting 2", chromosome
+					break
+			progress.inc()
+		progress.done()
+		endTime = time.time()
+		self._timeSpent = endTime - startTime
+		if self._verbosity >= 10:
+			print "# skips:   %d" % (nbSkips)
+			print "# moves:   %d" % (nbMoves)
+
+	def findOverlapIter(self, queryTranscript, cursor, done):
+		chromosome = queryTranscript.getChromosome()
+		if chromosome not in self._ncLists[REFERENCE]:
+			return False, None
+		ncList = self._ncLists[REFERENCE][chromosome]
+		overlappingNames = {}
+		nextDone = False
+		firstOverlapLAddr = NCListCursor(cursor)
+		firstOverlapLAddr.setLIndex(-1)
+		if cursor.isOut():
+			return firstOverlapLAddr, False
+		parentCursor = NCListCursor(cursor)
+		parentCursor.moveUp()
+		firstParentAfter = False
+		#print "query transcript 1", queryTranscript
+		#print "cursor 1", cursor
+		#print "parent 1", parentCursor
+		while not parentCursor.isOut(): 
+			if self.isOverlapping(queryTranscript, parentCursor) == 0:
+				#print "overlap parent choice 0"
+				overlappingNames.update(self._extractID(parentCursor.getTranscript()))
+				if firstOverlapLAddr.isOut():
+					#print "overlap parent 2"
+					firstOverlapLAddr.copy(parentCursor)
+					nextDone = True # new
+			elif self.isOverlapping(queryTranscript, parentCursor) == 1:
+				#print "overlap parent choice 1"
+				firstParentAfter = NCListCursor(parentCursor)
+			parentCursor.moveUp()
+			#print "parent 2", parentCursor
+		if firstParentAfter:
+			#print "exit parent", firstParentAfter, overlappingNames
+			self._writeIntervalInNewGFF3(queryTranscript, overlappingNames)
+			return firstParentAfter, False, not overlappingNames
+		#This loop finds the overlaps with currentRefLAddr.#
+		while True:
+			#print "ref cursor now is", cursor
+			parentCursor = NCListCursor(cursor)
+			parentCursor.moveUp()
+			#In case: Query is on the right of the RefInterval and does not overlap.
+			overlap = self.isOverlapping(queryTranscript, cursor)
+			if overlap == -1:
+				cursor.moveNext()
+			#In case: Query overlaps with RefInterval.	
+			elif overlap == 0:
+				#print "choice 2"
+				overlappingNames.update(self._extractID(cursor.getTranscript()))
+				if firstOverlapLAddr.compare(parentCursor):
+					firstOverlapLAddr.copy(cursor)
+					nextDone = True # new
+				if done:
+					cursor.moveNext()
+				else:
+					if not cursor.hasChildren():
+						cursor.moveNext()
+						if cursor.isOut():
+							#print "break 1"
+							break
+					else:
+						cursor.moveDown()
+			#In case: Query is on the left of the RefInterval and does not overlap.		
+			else:
+				#print "choice 3"
+				if firstOverlapLAddr.isOut() or firstOverlapLAddr.compare(parentCursor):
+					#print "changing nfo 2"
+					firstOverlapLAddr.copy(cursor)
+					nextDone = False # new
+				#print "break 2"
+				break
+			
+			done = False
+			if cursor.isOut():
+				#print "break 3"
+				break
+		self._writeIntervalInNewGFF3(queryTranscript, overlappingNames)
+		return firstOverlapLAddr, nextDone, not overlappingNames
+	
+	def isOverlapping(self, queryTranscript, refTranscript):
+		if (queryTranscript.getStart() <= refTranscript.getEnd() and queryTranscript.getEnd() >= refTranscript.getStart()):
+			return 0   
+		if queryTranscript.getEnd() < refTranscript.getStart():
+			return 1
+		return -1
+
+	def checkIndex(self, transcript, cursor):
+		if not self._index:
+			return None
+		chromosome = transcript.getChromosome()
+		nextLIndex = self._indices[REFERENCE][chromosome].getIndex(transcript)
+		if nextLIndex == None:
+			return None
+		ncList		 = self._ncLists[REFERENCE][chromosome]
+		nextGffAddress = ncList.getRefGffAddr(nextLIndex)
+		thisGffAddress = cursor.getGffAddress()
+		if nextGffAddress > thisGffAddress:
+			return nextLIndex
+		return None
+		
+	def _writeIntervalInNewGFF3(self, transcript, names):
+		nbOverlaps = 0
+		for cpt in names.values():
+			nbOverlaps += cpt
+		if not names:
+			return
+		transcript.setTagValue("overlapsWith", "--".join(sorted(names.keys())))
+		transcript.setTagValue("nbOverlaps", nbOverlaps)
+		self._iWriter.addTranscript(transcript)
+		self._iWriter.write()
+		self._nbOverlappingQueries += 1
+		self._nbOverlaps		   += nbOverlaps
+		
+	def _extractID(self, transcript):
+		nbElements = float(transcript.getTagValue("nbElements")) if "nbElements" in transcript.getTagNames() else 1
+		id		   = transcript.getTagValue("ID")				 if "ID"		 in transcript.getTagNames() else transcript.getUniqueName()
+		return {id: nbElements}
+		
+	def run(self):
+		self.createNCLists()
+		self.compare()
+		self.close()
+		if self._verbosity > 0:
+			print "# queries: %d" % (self._nbLines[QUERY])
+			print "# refs:    %d" % (self._nbLines[REFERENCE])
+			print "# written: %d (%d overlaps)" % (self._nbOverlappingQueries, self._nbOverlaps)
+			print "time:      %.2gs" % (self._timeSpent)
+
+
+if __name__ == "__main__":
+	description = "Find Overlaps Optim v1.0.0: Finds overlaps with several query intervals. [Category: Data Comparison]"
+
+	parser = OptionParser(description = description)
+	parser.add_option("-i", "--query",	     dest="inputQueryFileName", action="store",			            type="string", help="query input file [compulsory] [format: file in transcript or other format given by -f]")
+	parser.add_option("-f", "--queryFormat", dest="queryFormat",		action="store",			            type="string", help="format of previous file (possibly in NCL format) [compulsory] [format: transcript or other file format]")
+	parser.add_option("-j", "--ref",		 dest="inputRefFileName",   action="store",			            type="string", help="reference input file [compulsory] [format: file in transcript or other format given by -g]")
+	parser.add_option("-g", "--refFormat",   dest="refFormat",		    action="store",			            type="string", help="format of previous file (possibly in NCL format) [compulsory] [format: transcript or other file format]")
+	parser.add_option("-o", "--output",	     dest="outputFileName",	    action="store",			            type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+	parser.add_option("-d", "--index",	     dest="index",	            action="store_true", default=False,	               help="add an index to the reference file (faster but more memory) [format: boolean] [default: False]")
+	parser.add_option("-s", "--sorted",	     dest="sorted",	            action="store_true", default=False,	               help="input files are already sorted [format: boolean] [default: False]")
+	parser.add_option("-v", "--verbosity",   dest="verbosity",		    action="store",      default=1,     type="int",	   help="Trace level [format: int] [default: 1]")
+	(options, args) = parser.parse_args()
+	
+	iFOO = FindOverlapsOptim(options.verbosity)
+	iFOO.setRefFileName(options.inputRefFileName, options.refFormat)
+	iFOO.setQueryFileName(options.inputQueryFileName, options.queryFormat)
+	iFOO.setOutputFileName(options.outputFileName)
+	iFOO.setIndex(options.index)
+	iFOO.setSorted(options.sorted)
+	iFOO.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/GetDifferentialExpression.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,441 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Get the differential expression between 2 conditions (2 files), on regions defined by a third file"""
+
+import os, re
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from SMART.Java.Python.misc import Utils
+from SMART.Java.Python.mySql.MySqlConnection import MySqlConnection
+from SMART.Java.Python.structure.Transcript import Transcript
+
+class GetDifferentialExpression(object):
+    
+    def __init__(self, verbosity = 1):
+        self.verbosity              = verbosity
+        self.mySqlConnection        = MySqlConnection(verbosity)
+        self.inputs                 = (0, 1)
+        self.transcriptContainers   = [None, None]
+        self.transcriptContainerRef = None
+        self.outputFileName         = None
+        self.writer                 = None
+        self.tables                 = [None, None]
+        self.nbElements             = [0, 0]
+
+        self.regionsToValues = {}
+        self.regionsToNames  = {}
+        self.valuesToPvalues = {}
+
+        self.oriented                      = True
+        self.simpleNormalization           = False
+        self.simpleNormalizationParameters = None
+        self.adjustedNormalization         = False
+        self.fixedSizeFactor               = None
+        self.normalizationSize             = None
+        self.normalizationFactors          = [1, 1]
+        self.fdr                           = None 
+        self.fdrPvalue                     = None 
+
+        self.plot    = False
+        self.plotter = None
+        self.plotterName = None
+        self.points  = {}
+
+
+    def setInputFile(self, i, fileName, fileFormat):
+        self.transcriptContainers[i] = TranscriptContainer(fileName, fileFormat, self.verbosity)
+        self.transcriptContainers[i].mySqlConnection = self.mySqlConnection
+
+
+    def setReferenceFile(self, fileName, fileFormat):
+        self.transcriptContainerRef = TranscriptContainer(fileName, fileFormat, self.verbosity)
+        self.transcriptContainerRef.mySqlConnection = self.mySqlConnection
+
+
+    def setOutputFile(self, fileName):
+        self.outputFileName = fileName
+        self.writer         = Gff3Writer(fileName, self.verbosity)
+
+    
+    def setOriented(self, boolean):
+        self.oriented = boolean
+
+
+    def setSimpleNormalization(self, boolean):
+        self.simpleNormalization = boolean
+
+
+    def setSimpleNormalizationParameters(self, parameters):
+        if parameters != None:
+            self.simpleNormalization = True
+            self.simpleNormalizationParameters = [0, 0]
+            for i, splittedParameter in enumerate(parameters.split(",")):
+                self.simpleNormalizationParameters[i] = int(splittedParameter)
+
+
+    def setAdjustedNormalization(self, boolean):
+        self.adjustedNormalization = boolean
+
+
+    def setFixedSizeNormalization(self, value):
+        self.fixedSizeFactor = value
+
+
+    def setFdr(self, fdr):
+        self.fdr = fdr
+
+
+    def setPlot(self, boolean):
+        self.plot = boolean
+
+
+    def setPlotterName(self, plotterName):
+        self.plotterName = plotterName
+
+    def setPlotter(self):
+        self.plot    = True
+        self.plotter = RPlotter(self.plotterName, self.verbosity)
+        self.plotter.setPoints(True)
+        self.plotter.setLog("xy")
+        self.points = {}
+
+
+    def readInput(self, i):
+        self.transcriptContainers[i].storeIntoDatabase()
+        self.tables[i] = self.transcriptContainers[i].getTables()
+        progress       = Progress(len(self.tables[i].keys()), "Adding indices", self.verbosity)
+        for chromosome in self.tables[i]:
+            if self.oriented:
+                self.tables[i][chromosome].createIndex("iStartEndDir_%s_%d" % (chromosome, i), ("start", "end", "direction"))
+            else:
+                self.tables[i][chromosome].createIndex("iStartEnd_%s_%d" % (chromosome, i), ("start", "end"))
+            progress.inc()
+        progress.done()
+    
+        progress = Progress(self.transcriptContainers[i].getNbTranscripts(), "Reading sample %d" % (i +1), self.verbosity)
+        for chromosome in self.tables[i]:
+            for transcript in self.tables[i][chromosome].getIterator():
+                self.nbElements[i] += 1 if "nbElements" not in transcript.getTagNames() else transcript.getTagValue("nbElements")
+                progress.inc()
+        progress.done()
+        if self.verbosity > 0:
+            print "%d elements in sample %d" % (self.nbElements[i], i+1)
+
+
+    def computeSimpleNormalizationFactors(self):
+        nbElements = self.nbElements
+        if self.simpleNormalizationParameters != None:
+            print "Using provided normalization parameters: %s" % (", ".join([str(parameter) for parameter in self.simpleNormalizationParameters]))
+            nbElements = self.simpleNormalizationParameters
+        avgNbElements = int(float(sum(nbElements)) / len(nbElements))
+        for i in self.inputs:
+            self.normalizationFactors[i] = float(avgNbElements) / nbElements[i]
+            self.nbElements[i]          *= self.normalizationFactors[i]
+        if self.verbosity > 1:
+            print "Normalizing to average # reads: %d" % (avgNbElements)
+            if self.simpleNormalizationParameters != None:
+                print "# reads: %s" % (", ".join([str(nbElement) for nbElement in self.nbElements]))
+
+    def __del__(self):
+        self.mySqlConnection.deleteDatabase()
+
+    def regionToString(self, transcript):
+        return "%s:%d-%d(%s)" % (transcript.getChromosome(), transcript.getStart(), transcript.getEnd(), "+" if transcript.getDirection() == 1 else "-")
+
+    def stringToRegion(self, region):
+        m = re.search(r"^(\S+):(\d+)-(\d+)\((\S)\)$", region)
+        if m == None:
+            raise Exception("Internal format error: cannot parse region '%s'" % (region))
+        transcript = Transcript()
+        transcript.setChromosome(m.group(1))
+        transcript.setStart(int(m.group(2)))
+        transcript.setEnd(int(m.group(3)))
+        transcript.setDirection(m.group(4))
+        return transcript
+
+    def computeMinimumSize(self):
+        self.normalizationSize = 1000000000
+        progress = Progress(self.transcriptContainerRef.getNbTranscripts(), "Getting minimum reference size", self.verbosity)
+        for transcriptRef in self.transcriptContainerRef.getIterator():
+            self.normalizationSize = min(self.normalizationSize, transcriptRef.getEnd() - transcriptRef.getStart())
+            progress.inc()
+        progress.done()
+        if self.verbosity > 1:
+            print "Minimum reference size: %d" % (self.normalizationSize+1)
+
+    def useFixedSizeNormalization(self, start, end, starts):
+        currentNb = 0
+        sum       = 0
+        if not starts:
+            return 0
+        for i in range(start - self.normalizationSize, end + 1 + self.normalizationSize):
+            if i not in starts:
+                starts[i] = 0
+        for i, s in starts.iteritems():
+            if i < start:
+                starts[start] += s
+                starts[i]      = 0
+        for i in range(start - self.normalizationSize, end + 1):
+            currentNb += starts[i+self.normalizationSize] - starts[i]
+            sum       += currentNb
+        return (float(sum) / self.normalizationSize) * (self.fixedSizeFactor / (end - start + 1))
+
+    def retrieveCounts(self, transcriptRef, i):
+        if transcriptRef.getChromosome() not in self.tables[i]:
+            return (0, 0)
+        cumulatedCount           = 0
+        cumulatedNormalizedCount = 0
+        for exon in transcriptRef.getExons():
+            count   = 0
+            starts  = {}
+            command = "SELECT start, tags FROM '%s' WHERE start >= %d AND end <= %d" % (self.tables[i][exon.getChromosome()].getName(), exon.getStart(), exon.getEnd())
+            if self.oriented:
+                command += " AND direction = %d" % (exon.getDirection())
+            query = self.mySqlConnection.executeQuery(command)
+            for line in query.getIterator():
+                nb   = 1
+                tags = line[1].split(";")
+                for tag in tags:
+                    key, value = tag.split("=")
+                    if key == "nbElements":
+                        nb = int(float(value))
+                count += nb
+                starts[int(line[0])] = nb
+            normalizedCount = count if self.fixedSizeFactor == None else self.useFixedSizeNormalization(exon.getStart(), exon.getEnd(), starts)
+            cumulatedCount           += count
+            cumulatedNormalizedCount += normalizedCount
+        return (cumulatedCount, cumulatedNormalizedCount)
+
+    def getAllCounts(self):
+        progress = Progress(self.transcriptContainerRef.getNbTranscripts(), "Getting counts", self.verbosity)
+        for cpt, transcriptRef in enumerate(self.transcriptContainerRef.getIterator()):
+            if "ID" in transcriptRef.getTagNames():
+                self.regionsToNames[self.regionToString(transcriptRef)] = transcriptRef.getTagValue("ID")
+            elif transcriptRef.getName() != None:
+                self.regionsToNames[self.regionToString(transcriptRef)] = transcriptRef.getName()
+            else:
+                self.regionsToNames[self.regionToString(transcriptRef)] = "region_%d" % (cpt)
+            values           = [None, None]
+            normalizedValues = [None, None]
+            for i in self.inputs:
+                values[i], normalizedValues[i] = self.retrieveCounts(transcriptRef, i)
+                normalizedValues[i]            = int(self.normalizationFactors[i] * normalizedValues[i])
+            if sum(values) != 0:
+                self.regionsToValues[self.regionToString(transcriptRef)] = (normalizedValues[0], normalizedValues[1], values[0], values[1])
+            progress.inc()
+        progress.done()
+
+    def computeAdjustedNormalizationFactors(self):
+        nbElements = len(self.regionsToValues.keys())
+        avgValues  = []
+        progress   = Progress(nbElements, "Normalization step 1", self.verbosity)
+        for values in self.regionsToValues.values():
+            correctedValues = [values[i] * self.normalizationFactors[i] for i in self.inputs]
+            avgValues.append(float(sum(correctedValues)) / len(correctedValues))
+            progress.inc()
+        progress.done()
+
+        sortedAvgValues = sorted(avgValues)
+        minAvgValues    = sortedAvgValues[nbElements / 4]
+        maxAvgValues    = sortedAvgValues[nbElements * 3 / 4]
+        sums            = [0, 0]
+        progress        = Progress(nbElements, "Normalization step 2", self.verbosity)
+        for values in self.regionsToValues.values():
+            correctedValues = [values[i] * self.normalizationFactors[i] for i in self.inputs]
+            avgValue        = float(sum(correctedValues)) / len(correctedValues)
+            if minAvgValues <= avgValue and avgValue <= maxAvgValues:
+                for i in self.inputs:
+                    sums[i] += values[i]
+            progress.inc()
+        progress.done()
+
+        avgSums = float(sum(sums)) / len(sums)
+        for i in self.inputs:
+            if self.verbosity > 1:
+                print "Normalizing sample %d: %s to" % ((i+1), self.nbElements[i]),
+            self.normalizationFactors[i] *= float(avgSums) / sums[i]
+            self.nbElements[i]           *= self.normalizationFactors[i]
+            if self.verbosity > 1:
+                print "%s" % (int(self.nbElements[i]))
+                
+    def getMinimumReferenceSize(self):
+        self.normalizationSize = 1000000000
+        progress               = Progress(self.transcriptContainerRef.getNbTranscripts(), "Reference element sizes", self.verbosity)
+        for transcriptRef in self.transcriptContainerRef.getIterator():
+            self.normalizationSize = min(self.normalizationSize, transcriptRef.getEnd() - transcriptRef.getStart() + 1)
+            progress.inc()
+        progress.done()
+        if self.verbosity > 1:
+            print "Minimum reference size: %d" % (self.normalizationSize)
+
+    def computePvalues(self):
+        normalizedValues = set()
+        progress         = Progress(len(self.regionsToValues.keys()), "Normalizing counts", self.verbosity)
+        for region in self.regionsToValues:
+            values                       = self.regionsToValues[region]
+            normalizedValues0            = int(round(values[0] * self.normalizationFactors[0]))
+            normalizedValues1            = int(round(values[1] * self.normalizationFactors[1]))
+            self.regionsToValues[region] = (normalizedValues0, normalizedValues1, self.regionsToValues[region][2], self.regionsToValues[region][3])
+            normalizedValues.add((normalizedValues0, normalizedValues1, self.nbElements[0] - normalizedValues0, self.nbElements[1] - normalizedValues1, self.regionsToValues[region][2], self.regionsToValues[region][3]))
+            progress.inc()
+        progress.done()
+
+        if self.verbosity > 1:
+            print "Computing p-values..."
+        self.valuesToPvalues = Utils.fisherExactPValueBulk(list(normalizedValues))
+        if self.verbosity > 1:
+            print "... done"
+
+    def setTagValues(self, transcript, values, pValue):
+        for tag in transcript.getTagNames():
+            transcript.deleteTag(tag)
+        transcript.removeExons()
+        transcript.setTagValue("pValue", str(pValue))
+        transcript.setTagValue("nbReadsCond1", str(values[0]))
+        transcript.setTagValue("nbReadsCond2", str(values[1]))
+        transcript.setTagValue("nbUnnormalizedReadsCond1", str(values[2]))
+        transcript.setTagValue("nbUnnormalizedReadsCond2", str(values[3]))
+        if (values[0] == values[1]) or (self.fdr != None and pValue > self.fdrPvalue):
+            transcript.setTagValue("regulation", "equal")
+        elif values[0] < values[1]:
+            transcript.setTagValue("regulation", "up")
+        else:
+            transcript.setTagValue("regulation", "down")
+        return transcript
+
+    def computeFdr(self):
+        pValues   = []
+        nbRegions = len(self.regionsToValues.keys())
+        progress  = Progress(nbRegions, "Computing FDR", self.verbosity)
+        for values in self.regionsToValues.values():
+            pValues.append(self.valuesToPvalues[values[0:2]])
+            progress.inc()
+        progress.done()
+        
+        for i, pValue in enumerate(reversed(sorted(pValues))):
+            if pValue <= self.fdr * (nbRegions - 1 - i) / nbRegions:
+                self.fdrPvalue = pValue
+                if self.verbosity > 1:
+                    print "FDR: %f, k: %i, m: %d" % (pValue, nbRegions - 1 - i, nbRegions)
+                return
+
+    def writeDifferentialExpression(self):
+        if self.plot:
+            self.setPlotter()
+
+        cpt = 1
+        progress = Progress(len(self.regionsToValues.keys()), "Writing output", self.verbosity)
+        for region, values in self.regionsToValues.iteritems():
+            transcript = self.stringToRegion(region)
+            pValue     = self.valuesToPvalues[values[0:2]]
+            transcript.setName(self.regionsToNames[region])
+            transcript = self.setTagValues(transcript, values, pValue)
+            self.writer.addTranscript(transcript)
+            cpt += 1
+
+            if self.plot:
+                self.points[region] = (values[0], values[1])
+        progress.done()
+        self.writer.write()
+        self.writer.close()
+
+        if self.plot:
+            self.plotter.addLine(self.points)
+            self.plotter.plot()
+
+    def getDifferentialExpression(self):
+        for i in self.inputs:
+            self.readInput(i)
+
+        if self.simpleNormalization:
+            self.computeSimpleNormalizationFactors()
+        if self.fixedSizeFactor != None:
+            self.computeMinimumSize()
+
+        self.getAllCounts()
+
+        if self.adjustedNormalization:
+            self.computeAdjustedNormalizationFactors()
+
+        self.computePvalues()
+
+        if self.fdr != None:
+            self.computeFdr()
+            
+        self.writeDifferentialExpression()
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Get Differential Expression v1.0.1: Get the differential expression between 2 conditions using Fisher's exact test, on regions defined by a third file. [Category: Data Comparison]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input1",           dest="inputFileName1",    action="store",                     type="string", help="input file 1 [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format1",          dest="format1",           action="store",                     type="string", help="format of file 1 [compulsory] [format: transcript file format]")
+    parser.add_option("-j", "--input2",           dest="inputFileName2",    action="store",                     type="string", help="input file 2 [compulsory] [format: file in transcript format given by -g]")
+    parser.add_option("-g", "--format2",          dest="format2",           action="store",                     type="string", help="format of file 2 [compulsory] [format: transcript file format]")
+    parser.add_option("-k", "--reference",        dest="referenceFileName", action="store",                     type="string", help="reference file [compulsory] [format: file in transcript format given by -l]")
+    parser.add_option("-l", "--referenceFormat",  dest="referenceFormat",   action="store",                     type="string", help="format of reference file [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",           dest="outputFileName",    action="store",                     type="string", help="output file [format: output file in gff3 format]")
+    parser.add_option("-n", "--notOriented",      dest="notOriented",       action="store_true", default=False,                help="if the reads are not oriented [default: False] [format: bool]")
+    parser.add_option("-s", "--simple",           dest="simple",            action="store_true", default=False,                help="normalize using the number of reads in each condition [format: bool]")
+    parser.add_option("-S", "--simpleParameters", dest="simpleParameters",  action="store",      default=None,  type="string", help="provide the number of reads [format: bool]")
+    parser.add_option("-a", "--adjusted",         dest="adjusted",          action="store_true", default=False,                help="normalize using the number of reads of 'mean' regions [format: bool]")
+    parser.add_option("-x", "--fixedSizeFactor",  dest="fixedSizeFactor",   action="store",      default=None,  type="int",    help="give the magnification factor for the normalization using fixed size sliding windows in reference regions (leave empty for no such normalization) [format: int]")
+    parser.add_option("-d", "--fdr",              dest="fdr",               action="store",      default=None,  type="float",  help="use FDR [format: float]")
+    parser.add_option("-p", "--plot",             dest="plotName",          action="store",      default=None,  type="string", help="plot cloud plot [format: output file in PNG format]")
+    parser.add_option("-v", "--verbosity",        dest="verbosity",         action="store",      default=1,     type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+
+        
+    differentialExpression = GetDifferentialExpression(options.verbosity)
+    differentialExpression.setInputFile(0, options.inputFileName1, options.format1)
+    differentialExpression.setInputFile(1, options.inputFileName2, options.format2)
+    differentialExpression.setReferenceFile(options.referenceFileName, options.referenceFormat)
+    differentialExpression.setOutputFile(options.outputFileName)
+    if options.plotName != None :
+        differentialExpression.setPlotterName(options.plotName)
+        differentialExpression.setPlotter()
+    differentialExpression.setOriented(not options.notOriented)
+    differentialExpression.setSimpleNormalization(options.simple)
+    differentialExpression.setSimpleNormalizationParameters(options.simpleParameters)
+    differentialExpression.setAdjustedNormalization(options.adjusted)
+    differentialExpression.setFixedSizeNormalization(options.fixedSizeFactor)
+    differentialExpression.setFdr(options.fdr)
+    differentialExpression.getDifferentialExpression()
+    differentialExpression.mySqlConnection.deleteDatabase()
+    
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/GetDistribution.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,362 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2012
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.parsing.FastaParser import FastaParser
+from SMART.Java.Python.structure.Transcript import Transcript
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from SMART.Java.Python.misc.MultipleRPlotter import MultipleRPlotter
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+from SMART.Java.Python.misc.Progress import Progress
+
+TWOSTRANDS = {True: [1, -1], False: [0]}
+STRANDTOSTR = {1: "(+)", -1: "(-)", 0: ""}
+
+class GetDistribution(object):
+
+	def __init__(self, verbosity):
+		self.verbosity     = verbosity
+		self.sizes         = None
+		self.twoStrands    = False
+		self.start         = 1
+		self.names         = ["nbElements"]
+		self.average       = False
+		self.nbValues      = {}
+		self.height        = 300
+		self.width         = 600
+		self.colors        = None
+		self.gffFileName   = None
+		self.csvFileName   = None
+		self.yMin          = None
+		self.yMax          = None
+		self.chromosome    = None
+		self.merge         = False
+		self.nbTranscripts = None
+
+	def setInputFile(self, fileName, format):
+		chooser = ParserChooser(self.verbosity)
+		chooser.findFormat(format)
+		self.parser = chooser.getParser(fileName)
+
+	def setReferenceFile(self, fileName):
+		if fileName == None:
+			return
+		fastaParser = FastaParser(fileName, self.verbosity)
+		self.chromosomes = fastaParser.getRegions()
+		self.sizes       = dict([region, fastaParser.getSizeOfRegion(region)] for region in self.chromosomes)
+		self.maxSize     = max(self.sizes.values())
+
+	def setRegion(self, chromosome, start, end):
+		if chromosome == None:
+			return
+		self.maxSize     = options.end
+		self.sizes       = {chromosome: end}
+		self.chromosomes = [chromosome]
+		self.chromosome  = chromosome
+		self.start       = start
+		self.end         = end
+
+	def setOutputFile(self, fileName):
+		self.outputFileName = fileName
+
+	def setNbBins(self, nbBins):
+		self.nbBins = nbBins
+
+	def set2Strands(self, twoStrands):
+		self.twoStrands = twoStrands
+
+	def setNames(self, names):
+		self.names = names
+
+	def setAverage(self, average):
+		self.average = average
+
+	def setNormalization(self, normalization):
+		self.normalization = normalization
+	
+	def setImageSize(self, height, width):
+		self.height = height
+		self.width  = width
+
+	def setYLimits(self, yMin, yMax):
+		self.yMin = yMin
+		self.yMax = yMax
+
+	def setColors(self, colors):
+		self.colors = colors
+
+	def writeGff(self, fileName):
+		self.gffFileName = fileName
+
+	def writeCsv(self, fileName):
+		self.csvFileName = fileName
+
+	def mergePlots(self, merge):
+		self.merge = merge
+
+	def _estimateSizes(self):
+		progress = UnlimitedProgress(10000, "Reading input for chromosome size estimate", self.verbosity)
+		self.sizes = {}
+		for self.nbTranscripts, transcript in enumerate(self.parser.getIterator()):
+			chromosome = transcript.getChromosome()
+			start      = transcript.getStart()
+			self.sizes[chromosome] = max(start, self.sizes.get(chromosome, 0))
+			progress.inc()
+		progress.done()
+
+	def _computeSliceSize(self):
+		if self.nbBins == 0:
+			return
+		tmp1           = int(max(self.sizes.values()) / float(self.nbBins))
+		tmp2           = 10 ** (len("%d" % (tmp1))-2)
+		self.sliceSize = max(1, int((tmp1 / tmp2) * tmp2))
+		if self.verbosity > 0:
+			print "choosing bin size of %d" % (self.sliceSize)
+
+	def _initBins(self):
+		self.bins = {}
+		for chromosome in self.sizes:
+			self.bins[chromosome] = {}
+			for name in self.names:
+				self.bins[chromosome][name] = {}
+				for strand in TWOSTRANDS[self.twoStrands]:
+					if self.nbBins == 0:
+						self.bins[chromosome][name][strand] = {}
+					else:
+						self.bins[chromosome][name][strand] = dict([(i * self.sliceSize + 1, 0.0) for i in range(self.start / self.sliceSize, self.sizes[chromosome] / self.sliceSize + 1)])
+
+	def _populateBins(self):
+		if self.nbTranscripts == None:
+			progress = UnlimitedProgress(10000, "Counting data", self.verbosity)
+		else:
+			progress = Progress(self.nbTranscripts, "Counting data", self.verbosity)
+		for transcript in self.parser.getIterator():
+			if transcript.__class__.__name__ == "Mapping":
+				transcript = transcript.getTranscript()
+			progress.inc()
+			chromosome = transcript.getChromosome()
+			start      = transcript.getStart()
+			if self.chromosome and (chromosome != self.chromosome or start < self.start or start > self.end):
+				continue
+			strand = transcript.getDirection() if self.twoStrands else 0
+			if self.nbBins != 0:
+				bin = (start / self.sliceSize) * self.sliceSize + 1
+			else:
+				bin = start
+			for name in self.names:
+				value = float(transcript.tags.get(name, 1))
+				self.bins[chromosome][name][strand][bin] = self.bins[chromosome][name][strand].get(bin, 0) + value
+				self.nbValues[name] = self.nbValues.get(name, 0) + value
+		progress.done()
+
+	def _normalize(self):
+		average = float(sum(self.nbValues)) / len(self.nbValues.keys())
+		factors = dict([name, float(average) / self.nbValues[name]] for name in self.nbValues)
+		for chromosome in self.bins:
+			for name in self.bins[chromosome]:
+				for strand in self.bins[chromosome][name]:
+					for bin in self.bins[chromosome][name][strand]:
+						self.bins[chromosome][name][strand][bin] *= factors[name]
+
+	def _computeAverage(self):
+		for chromosome in self.bins:
+			for name in self.bins[chromosome]:
+				for strand in self.bins[chromosome][name]:
+					for bin in self.bins[chromosome][name][strand]:
+						self.bins[chromosome][name][strand][bin] = float(self.bins[chromosome][name][strand][bin]) / self.sliceSize
+
+	def _getPlotter(self, chromosome):
+		plot = RPlotter("%s_%s.png" % (os.path.splitext(self.outputFileName)[0], chromosome), self.verbosity)
+		plot.setImageSize(self.width, self.height)
+		if self.sizes[chromosome] <= 1000:
+			unit  = "nt."
+			ratio = 1.0
+		elif self.sizes[chromosome] <= 1000000:
+			unit  = "kb"
+			ratio = 1000.0
+		else:
+			unit  = "Mb"
+			ratio = 1000000.0
+		if self.yMin != None:
+			plot.setMinimumY(self.yMin)
+		if self.yMax != None:
+			plot.setMaximumY(self.yMax)
+		plot.setXLabel("Position on %s (in %s)" % (chromosome.replace("_", " "), unit))
+		plot.setLegend(True)
+		for i, name in enumerate(self.bins[chromosome]):
+			for strand in self.bins[chromosome][name]:
+				fullName = "%s %s" % (name.replace("_", " ")[:6], STRANDTOSTR[strand])
+				factor = 1 if strand == 0 else strand
+				correctedLine = dict([(key / ratio, value * factor) for key, value in self.bins[chromosome][name][strand].iteritems()])
+				plot.addLine(correctedLine, fullName, self.colors[i] if self.colors else None)
+		return plot
+
+	def _plot(self):
+		if self.merge:
+			multiplePlot = MultipleRPlotter(self.outputFileName, self.verbosity)
+			multiplePlot.setImageSize(self.width, self.height * len(self.bins.keys()))
+		progress = Progress(len(self.bins.keys()), "Plotting", options.verbosity)
+		for chromosome in sorted(self.bins.keys()):
+			plot = self._getPlotter(chromosome)
+			if self.merge:
+				multiplePlot.addPlot(plot)
+			else:
+				plot.plot()
+			progress.inc()
+		if self.merge:
+			multiplePlot.plot()
+		progress.done()
+
+	def _writeCsv(self):
+		if self.verbosity > 1:
+			print "Writing CSV file..."
+		csvHandle = open(self.csvFileName, "w")
+		csvHandle.write("chromosome;tag;strand")
+		if self.nbBins != 0:
+			xValues = range(self.start / self.sliceSize, max(self.sizes.values()) / self.sliceSize + 1)
+			for value in xValues:
+				csvHandle.write(";%d-%d" % (value * self.sliceSize + 1, (value+1) * self.sliceSize))
+			csvHandle.write("\n")
+		else:
+			xValues = []
+			for chromosome in self.bins:
+				for name in self.bins[chromosome]:
+					for strand in self.bins[chromosome][name]:
+						for bin in self.bins[chromosome][name][strand]:
+							xValues.extend(self.bins[chromosome][name][strand].keys())
+			xValues = sorted(list(set(xValues)))
+			for value in xValues:
+				csvHandle.write(";%d" % (value))
+			csvHandle.write("\n")
+		for chromosome in self.bins:
+			csvHandle.write("%s" % (chromosome))
+			for name in self.bins[chromosome]:
+				csvHandle.write(";%s" % (name))
+				for strand in self.bins[chromosome][name]:
+					csvHandle.write(";%s" % (STRANDTOSTR[strand]))
+					for bin in xValues:
+						csvHandle.write(";%.2f" % (self.bins[chromosome][name][strand].get(bin, 0)))
+					csvHandle.write("\n")
+				csvHandle.write(";")
+			csvHandle.write(";")
+		csvHandle.close()
+		if self.verbosity > 1:
+			print "...done"
+		
+	def _writeGff(self):
+		if self.verbosity > 1:
+			print "Writing GFF file..."
+		writer = Gff3Writer(self.gffFileName, self.verbosity)
+		cpt    = 1
+		for chromosome in self.bins:
+			for name in self.bins[chromosome]:
+				for strand in self.bins[chromosome][name]:
+					for bin in self.bins[chromosome][name][strand]:
+						transcript = Transcript()
+						transcript.setChromosome(chromosome)
+						transcript.setStart(bin)
+						if self.nbBins > 0:
+							transcript.setEnd(bin + self.sliceSize)
+						else:
+							transcript.setEnd(start)
+						transcript.setDirection(1 if strand == 0 else strand)
+						transcript.setTagValue("ID", "region%d" % (cpt))
+						cpt += 1
+		writer.write()
+		if self.verbosity > 1:
+			print "...done"
+
+	def run(self):
+		if self.sizes == None:
+			self._estimateSizes()
+		self._computeSliceSize()
+		self._initBins()
+		self._populateBins()
+		if self.normalization:
+			self._normalize()
+		if self.average:
+			self._computeAverage()
+		self._plot()
+		if self.csvFileName != None:
+			self._writeCsv()
+		if self.gffFileName != None:
+			self._writeGff()
+
+
+if __name__ == "__main__":
+
+	description = "Get Distribution v1.0.2: Get the distribution of the genomic coordinates on a genome. [Category: Visualization]"
+
+	parser = OptionParser(description = description)
+	parser.add_option("-i", "--input",       dest="inputFileName",     action="store",                            type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+	parser.add_option("-f", "--format",      dest="format",            action="store",                            type="string", help="format of the input file [compulsory] [format: transcript file format]")
+	parser.add_option("-o", "--output",      dest="outputFileName",    action="store",                            type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+	parser.add_option("-r", "--reference",   dest="referenceFileName", action="store",      default=None,         type="string", help="file containing the genome [format: file in FASTA format]")
+	parser.add_option("-b", "--nbBins",      dest="nbBins",            action="store",      default=1000,         type="int",    help="number of bins [default: 1000] [format: int]")
+	parser.add_option("-2", "--bothStrands", dest="bothStrands",       action="store_true", default=False,                       help="plot one curve per strand [format: bool] [default: false]")
+	parser.add_option("-c", "--chromosome",  dest="chromosome",        action="store",      default=None,         type="string", help="plot only a chromosome [format: string]")
+	parser.add_option("-s", "--start",       dest="start",             action="store",      default=None,         type="int",    help="start from a given region [format: int]")
+	parser.add_option("-e", "--end",         dest="end",               action="store",      default=None,         type="int",    help="end from a given region [format: int]")
+	parser.add_option("-y", "--yMin",        dest="yMin",              action="store",      default=None,         type="int",    help="minimum value on the y-axis to plot [format: int]")
+	parser.add_option("-Y", "--yMax",        dest="yMax",              action="store",      default=None,         type="int",    help="maximum value on the y-axis to plot [format: int]")
+	parser.add_option("-x", "--csv",         dest="csv",               action="store",      default=None,                        help="write a .csv file [format: output file in CSV format] [default: None]")
+	parser.add_option("-g", "--gff",         dest="gff",               action="store",      default=None,                        help="also write GFF3 file [format: output file in GFF format] [default: None]")
+	parser.add_option("-H", "--height",      dest="height",            action="store",      default=300,          type="int",    help="height of the graphics [format: int] [default: 300]")
+	parser.add_option("-W", "--width",       dest="width",             action="store",      default=600,          type="int",    help="width of the graphics [format: int] [default: 1000]")
+	parser.add_option("-a", "--average",     dest="average",           action="store_true", default=False,                       help="plot average (instead of sum) [default: false] [format: boolean]")
+	parser.add_option("-n", "--names",       dest="names",             action="store",      default="nbElements", type="string", help="name for the tags (separated by commas and no space) [default: None] [format: string]")
+	parser.add_option("-l", "--color",       dest="colors",            action="store",      default=None,         type="string", help="color of the lines (separated by commas and no space) [format: string]")
+	parser.add_option("-z", "--normalize",   dest="normalize",         action="store_true", default=False,                       help="normalize data (when panels are different) [format: bool] [default: false]")
+	parser.add_option("-m", "--merge",       dest="mergePlots",        action="store_true", default=False,                       help="merge all plots in one figure [format: bool] [default: false]")
+	parser.add_option("-v", "--verbosity",   dest="verbosity",         action="store",      default=1,            type="int",    help="trace level [default: 1] [format: int]")
+	(options, args) = parser.parse_args()
+
+	gt = GetDistribution(options.verbosity)
+	gt.setInputFile(options.inputFileName, options.format)
+	gt.setOutputFile(options.outputFileName)
+	gt.setReferenceFile(options.referenceFileName)
+	gt.setNbBins(int(options.nbBins))
+	gt.set2Strands(options.bothStrands)
+	gt.setRegion(options.chromosome, options.start, options.end)
+	gt.setNormalization(options.normalize)
+	gt.setAverage(options.average)
+	gt.setYLimits(options.yMin, options.yMax)
+	gt.writeCsv(options.csv)
+	gt.writeGff(options.gff)
+	gt.setImageSize(options.height, options.width)
+	gt.setNames(options.names.split(","))
+	gt.setColors(None if options.colors == None else options.colors.split(","))
+	gt.setNormalization(options.normalize)
+	gt.mergePlots(options.mergePlots)
+	gt.run()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/GetFlanking.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,231 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2011
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.misc.Progress import Progress
+
+QUERY        = 0
+REFERENCE    = 1
+INPUTS       = (QUERY, REFERENCE)
+STRANDS      = (-1, 1)
+TAG_DISTANCE = "distance_"
+TAG_SENSE    = "_sense"
+TAG_REGION   = "_region"
+TAGS_REGION  = {-1: "_upstream", 0: "", 1: "_downstream"}
+TAGS_RREGION = {-1: "upstream", 0: "overlapping", 1: "downstream"}
+TAGS_SENSE   = {-1: "antisense", 0: "", 1: "colinear"}
+STRANDSTOSTR = {-1: "(-)", 0: "", 1: "(+)"}
+
+
+def getOrderKey(transcript, direction):
+    if direction == 1:
+        return transcript.getEnd()
+    return - transcript.getStart()
+
+def isInGoodRegion(transcriptRef, transcriptQuery, direction):
+    if direction == 1:
+        return transcriptQuery.getEnd() > transcriptRef.getEnd()
+    return transcriptQuery.getStart() < transcriptRef.getStart()
+
+
+class GetFlanking(object):
+
+    def __init__(self, verbosity):
+        self.verbosity   = verbosity
+        self.transcripts = dict([id, {}] for id in INPUTS)
+        self.directions  = []
+        self.noOverlap   = False
+        self.colinear    = False
+        self.antisense   = False
+        self.distance    = None
+        self.minDistance = None
+        self.maxDistance = None
+        self.tagName     = "flanking"
+
+    def setInputFile(self, fileName, format, id):
+        chooser = ParserChooser(self.verbosity)
+        chooser.findFormat(format)
+        parser = chooser.getParser(fileName)
+        for transcript in parser.getIterator():
+            chromosome = transcript.getChromosome()
+            if chromosome not in self.transcripts[id]:
+                self.transcripts[id][chromosome] = []
+            self.transcripts[id][chromosome].append(transcript)
+
+    def setOutputFile(self, fileName):
+        self.writer = TranscriptWriter(fileName, "gff3", self.verbosity)
+
+    def addUpstreamDirection(self, upstream):
+        if upstream:
+            self.directions.append(-1)
+
+    def addDownstreamDirection(self, downstream):
+        if downstream:
+            self.directions.append(1)
+
+    def setColinear(self, colinear):
+        self.colinear = colinear
+
+    def setAntisense(self, antisense):
+        self.antisense = antisense
+
+    def setNoOverlap(self, noOverlap):
+        self.noOverlap = noOverlap
+
+    def setMinDistance(self, distance):
+        self.minDistance = distance
+
+    def setMaxDistance(self, distance):
+        self.maxDistance = distance
+
+    def setNewTagName(self, tagName):
+        self.tagName = tagName
+
+    def match(self, transcriptRef, transcriptQuery, direction):
+        if self.noOverlap and transcriptRef.overlapWith(transcriptQuery):
+            return False
+        if self.colinear and transcriptRef.getDirection() != transcriptQuery.getDirection():
+            return False
+        if self.antisense and transcriptRef.getDirection() == transcriptQuery.getDirection():
+            return False
+        if self.minDistance != None or self.maxDistance != None:
+            distance = transcriptRef.getDistance(transcriptQuery)
+            if self.minDistance != None and distance < self.minDistance:
+                return False
+            if self.maxDistance != None and distance > self.maxDistance:
+                return False
+        return True
+
+    def getFlanking(self, direction):
+        for chromosome in sorted(self.transcripts[REFERENCE].keys()):
+            if chromosome not in self.transcripts[QUERY]:
+                continue
+            sortedTranscripts = dict([id, {}] for id in INPUTS)
+            for id in INPUTS:
+                sortedTranscripts[id] = sorted(self.transcripts[id][chromosome], key = lambda t: getOrderKey(t, direction))
+            refIndex    = 0
+            currentRefs = []
+            outputs     = set()
+            progress    = Progress(len(sortedTranscripts[QUERY]), "Reading chr %s %s" % (chromosome, STRANDSTOSTR[direction]), self.verbosity)
+            for query in sortedTranscripts[QUERY]:
+                while refIndex < len(sortedTranscripts[REFERENCE]) and isInGoodRegion(sortedTranscripts[REFERENCE][refIndex], query, direction):
+                    currentRefs.append(sortedTranscripts[REFERENCE][refIndex])
+                    refIndex += 1
+                nextCurrentRefs = []
+                for currentRef in currentRefs:
+                    if self.match(currentRef, query, direction):
+                        if currentRef not in self.flankings:
+                            self.flankings[currentRef] = {}
+                        self.flankings[currentRef][direction * currentRef.getDirection()] = query
+                    else:
+                        nextCurrentRefs.append(currentRef)
+                currentRefs = nextCurrentRefs
+                progress.inc()
+            progress.done()
+
+    def setTags(self, query, reference, direction):
+        refName = reference.getTagValue("ID")
+        if refName == None:
+            refName = reference.getName()
+        if refName == None:
+            refName = reference.__str__()
+        query.setTagValue("%s%s" % (self.tagName, TAGS_REGION[direction]), refName)
+        query.setTagValue("%s_%s%s" % (TAG_DISTANCE, self.tagName, TAGS_REGION[direction]), query.getDistance(reference))
+        if direction == 0:
+            query.setTagValue("%s_%s" % (TAG_SENSE, self.tagName), TAGS_SENSE[query.getDirection() * reference.getDirection()])
+            query.setTagValue("%s_%s" % (TAG_REGION, self.tagName), TAGS_RREGION[cmp(query.getRelativeDistance(reference), 0)])
+        for tag in reference.getTagNames():
+            if tag not in ("quality", "feature"):
+                query.setTagValue("%s%s_%s" % (self.tagName, TAGS_REGION[direction], tag), reference.getTagValue(tag))
+        return query
+
+    def write(self):
+        outputs   = set()
+        progress  = Progress(len(self.flankings.keys()), "Printing data", self.verbosity)
+        for transcriptRef in self.flankings.keys():
+            if self.directions:
+                for direction in self.directions:
+                    if direction in self.flankings[transcriptRef]:
+                        query = self.flankings[transcriptRef][direction]
+                        outputs.add(self.setTags(query, transcriptRef, direction))
+            else:
+                if self.flankings[transcriptRef]:
+                    query = sorted(self.flankings[transcriptRef].values(), key = lambda query: query.getDistance(transcriptRef))[0]
+                    outputs.add(self.setTags(query, transcriptRef, 0))
+            progress.inc()
+        for transcript in sorted(list(outputs), key = lambda flanking: (flanking.getChromosome(), flanking.getStart(), flanking.getEnd())):
+            self.writer.addTranscript(transcript)
+        self.writer.close()
+        progress.done()
+
+    def run(self):
+        self.flankings = {}
+        for direction in STRANDS:
+            self.getFlanking(direction)
+        self.write()
+
+if __name__ == "__main__":
+    
+    description = "Get Flanking v1.0.1: Get the flanking regions of a set of reference. [Category: Data Selection]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input1",      dest="inputFileName1", action="store",                          type="string", help="query input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format1",     dest="format1",        action="store",                          type="string", help="format of previous file [compulsory] [format: transcript file format]")
+    parser.add_option("-j", "--input2",      dest="inputFileName2", action="store",                          type="string", help="reference input file [compulsory] [format: file in transcript format given by -g]")
+    parser.add_option("-g", "--format2",     dest="format2",        action="store",                          type="string", help="format of previous file [compulsory] [format: transcript file format]")
+    parser.add_option("-5", "--upstream",    dest="upstream",       action="store_true", default=False,                     help="output upstream elements [format: boolean] [default: False]")
+    parser.add_option("-3", "--downstream",  dest="downstream",     action="store_true", default=False,                     help="output downstream elements [format: boolean] [default: False]")
+    parser.add_option("-c", "--colinear",    dest="colinear",       action="store_true", default=False,                     help="find first colinear element [format: boolean] [default: False]")
+    parser.add_option("-a", "--antisense",   dest="antisense",      action="store_true", default=False,                     help="find first anti-sense element [format: boolean] [default: False]")
+    parser.add_option("-e", "--noOverlap",   dest="noOverlap",      action="store_true", default=False,                     help="do not consider elements which are overlapping reference elements [format: boolean] [default: False]")
+    parser.add_option("-d", "--minDistance", dest="minDistance",    action="store",      default=None,       type="int",    help="minimum distance between 2 elements [format: int]")
+    parser.add_option("-D", "--maxDistance", dest="maxDistance",    action="store",      default=None,       type="int",    help="maximum distance between 2 elements [format: int]")
+    parser.add_option("-t", "--tag",         dest="tagName",        action="store",      default="flanking", type="string", help="name of the new tag [format: string] [default: flanking]")
+    parser.add_option("-o", "--output",      dest="outputFileName", action="store",                          type="string", help="output file [format: output file in GFF3 format]")
+    parser.add_option("-v", "--verbosity",   dest="verbosity",      action="store",      default=1,          type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    gf = GetFlanking(options.verbosity)
+    gf.setInputFile(options.inputFileName1, options.format1, QUERY)
+    gf.setInputFile(options.inputFileName2, options.format2, REFERENCE)
+    gf.setOutputFile(options.outputFileName)
+    gf.addUpstreamDirection(options.upstream)
+    gf.addDownstreamDirection(options.downstream)
+    gf.setColinear(options.colinear)
+    gf.setAntisense(options.antisense)
+    gf.setNoOverlap(options.noOverlap)
+    gf.setMinDistance(options.minDistance)
+    gf.setMaxDistance(options.maxDistance)
+    gf.setNewTagName(options.tagName)
+    gf.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/GetRandomSubset.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,96 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2011
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import random
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.misc.Progress import Progress
+
+class GetRandomSubset(object):
+
+    def __init__(self, verbosity):
+        self.verbosity = verbosity
+
+    def setInputFile(self, fileName, format):
+        chooser = ParserChooser(self.verbosity)
+        chooser.findFormat(format)
+        self.parser = chooser.getParser(fileName)
+
+    def setNumber(self, number, percent):
+        if number != None:
+            self.number = number
+        elif percent != None:
+            self.number = int(float(percent) / 100 * self.parser.getNbTranscripts())
+        else:
+            raise Exception("Error! Number of elements to output is not given!")
+
+    def setOutputFile(self, fileName):
+        self.writer = TranscriptWriter(fileName, "gff3", self.verbosity)
+
+    def chooseElements(self):
+        self.randomIndices = random.sample(range(self.parser.getNbTranscripts()), self.number)
+        
+    def run(self):
+        self.chooseElements()
+        progress  = Progress(self.parser.getNbTranscripts(), "Reading input file", self.verbosity)
+        nbWritten = 0
+        for cpt1, transcript in enumerate(self.parser.getIterator()):
+            if cpt1 in self.randomIndices:
+                self.writer.addTranscript(transcript)
+                nbWritten += 1
+            progress.inc()
+        self.writer.write()
+        self.writer.close()
+        progress.done()
+        if self.verbosity > 1:
+            print "%d transcripts read" % (self.parser.getNbTranscripts())
+            print "%d transcripts written" % (nbWritten)
+
+
+if __name__ == "__main__":
+    
+    description = "Get Random Subset v1.0.1: Get a random sub-set of a list of genomic coordinates. [Category: Personal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",               type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",         action="store",               type="string", help="format of file [compulsory] [format: transcript file format]")
+    parser.add_option("-n", "--number",    dest="number",         action="store", default=None, type="string", help="number of elements to output [format: int]")
+    parser.add_option("-p", "--percent",   dest="percent",        action="store", default=None, type="string", help="percentage of elements to output (between 0 and 100) [format: int]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",               type="string", help="output file [format: output file in GFF3 format]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store", default=1,    type="int", help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    grs = GetRandomSubset(options.verbosity)
+    grs.setInputFile(options.inputFileName, options.format)
+    grs.setNumber(options.number, options.percent)
+    grs.setOutputFile(options.outputFileName)
+    grs.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/GetReadDistribution.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,283 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import random, os, glob, subprocess
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.parsing.GffParser import GffParser
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc import Utils
+from commons.core.LoggerFactory import LoggerFactory
+from commons.core.utils.RepetOptionParser import RepetOptionParser
+
+LOG_DEPTH      = "smart"
+DEFAULT_REGION = "_all_"
+MULTIPLE_STR   = {1: "", 1000: " (in kpb)", 1000000: " (in Gbp)"}
+
+class GetReadDistribution(object):
+
+	def __init__(self, verbosity = 0):
+		self.xLab         = ""
+		self.yLab         = "# reads"
+		self.verbosity    = verbosity
+		self.number       = random.randint(0, 100000)
+		self.log          = LoggerFactory.createLogger("%s.%s" % (LOG_DEPTH, self.__class__.__name__), self.verbosity)
+		self.parsers      = {}
+		self.distribution = {}
+		self.factors      = {}
+		self.regions      = None
+		self.tmpDatName   = None
+		self.tmpRName     = None
+		self.quorum       = 1
+		self.width        = 800
+		self.height       = 300
+
+	def setNames(self, names):
+		self.names = names
+
+	def setInputFiles(self, fileNames, format):
+		chooser = ParserChooser(self.verbosity)
+		chooser.findFormat(format)
+		for cpt, fileName in enumerate(fileNames):
+			self.parsers[self.names[cpt]] = chooser.getParser(fileName)
+
+	def setOutputFileName(self, fileName):
+		self.outputFileName = fileName
+
+	def setLabs(self, xLab, yLab):
+		self.xLab = xLab
+		self.yLab = yLab
+
+	def setBinSize(self, binSize):
+		self.binSize = binSize
+
+	def setColors(self, colors):
+		self.colors = colors
+
+	def setFactors(self, factors):
+		self.factors = dict(zip(self.names, factors))
+
+	def setMultiple(self, boolean):
+		self.multiple = boolean
+	
+	def setImageSize(self, width, height):
+		if width != None:
+			self.width = width
+		if height != None:
+			self.height = height
+
+	def setQuorum(self, quorum):
+		self.quorum = quorum
+
+	def setRegionsFile(self, fileName):
+		if fileName != None:
+			self._loadRegions(fileName)
+
+	def _checkOptions(self):
+		if not self.parsers:
+			self.logAndRaise("ERROR: Missing input file names")
+
+	def _logAndRaise(self, errorMsg):
+		self.log.error(errorMsg)
+		raise Exception(errorMsg)
+
+	def _loadRegions(self, fileName):
+		self.regions = {}
+		parser       = GffParser(fileName, self.verbosity)
+		for transcript in parser.getIterator():
+			chromosome = transcript.getChromosome()
+			start      = transcript.getStart()
+			end        = transcript.getEnd()
+			name       = transcript.getName()
+			if chromosome not in self.regions:
+				self.regions[chromosome] = {}
+			if start not in self.regions[chromosome]:
+				self.regions[chromosome][start] = {}
+			if end not in self.regions[chromosome][start]:
+				self.regions[chromosome][start][end] = []
+			self.regions[chromosome][start][end].append(name)
+
+	def _getRegions(self, transcript):
+		if self.regions == None:
+			return [DEFAULT_REGION]
+		chromosome = transcript.getChromosome()
+		start      = transcript.getStart()
+		end        = transcript.getEnd()
+		if chromosome not in self.regions:
+			return []
+		names = []
+		for loadedStart in sorted(self.regions[chromosome].keys()):
+			if loadedStart > end:
+				return names
+			for loadedEnd in reversed(sorted(self.regions[chromosome][loadedStart].keys())):
+				if loadedEnd < start:
+					break
+				names.extend(self.regions[chromosome][loadedStart][loadedEnd])
+		return names
+
+	def _parse(self, name):
+		progress = UnlimitedProgress(10000, "Reading file '%s'" % (name), self.verbosity)
+		for transcript in self.parsers[name].getIterator():
+			if transcript.__class__.__name__ == "Mapping":
+				transcript = transcript.getTranscript()
+			regions = self._getRegions(transcript)
+			for region in regions:
+				if region not in self.distribution:
+					self.distribution[region] = {}
+				if name not in self.distribution[region]:
+					self.distribution[region][name] = {}
+				chromosome  = transcript.getChromosome()
+				nbElements  = float(transcript.getTagValue("nbElements")) if "nbElements" in transcript.getTagNames() else 1
+				nbElements *= self.factors.get(name, 1)
+				if chromosome not in self.distribution[region][name]:
+					self.distribution[region][name][chromosome] = {}
+				previousBin = None
+				for exon in transcript.getExons():
+					for pos in range(exon.getStart(), exon.getEnd()+1):
+						bin = pos / self.binSize
+						if bin != previousBin:
+							self.distribution[region][name][chromosome][bin] = self.distribution[region][name][chromosome].get(bin, 0) + nbElements
+							previousBin = bin
+			progress.inc()
+		progress.done()
+
+	def _checkQuorum(self, region):
+		if self.quorum == None:
+			return True
+		return max([max([max(self.distribution[region][name][chromosome].values()) for chromosome in self.distribution[region][name]]) for name in self.distribution[region]]) >= self.quorum
+
+	def _writeData(self, region):
+		self.tmpDatName = "tmpFile%d.dat" % (self.number)
+		handle          = open(self.tmpDatName, "w")
+		handle.write("Chr\tPos\tCount\tSample\n")
+		for name in self.distribution[region]:
+			for chromosome in sorted(self.distribution[region][name].keys()):
+				for pos in sorted(self.distribution[region][name][chromosome].keys()):
+					handle.write("%s\t%d\t%d\t\"%s\"\n" % (chromosome, pos * self.binSize, self.distribution[region][name][chromosome].get(pos, 0), name))
+		handle.close()
+
+	def _findMultiple(self, region):
+		if not self.multiple:
+			return 1
+		maxPosition = max([self.distribution[region][name][chromosome].keys() for name in self.distribution[region] for chromosome in self.distribution[region][name]])
+		if maxPosition > 2000000:
+			return 1000000
+		elif maxPosition > 2000:
+			return 1000
+		return 1
+
+	def _writeScript(self, region):
+		self.tmpRName = "tmpFile%d.R" % (self.number)
+		fileName      = self.outputFileName if region == DEFAULT_REGION else "%s_%s.png" % (os.path.splitext(self.outputFileName)[0], region)
+		colors        = "scale_fill_brewer(palette=\"Set1\") + scale_color_brewer(palette=\"Set1\")" if self.colors == None else "scale_fill_manual(values = c(%s)) + scale_color_manual(values = c(%s))" % (", ".join(["\"%s\"" % (color) for color in self.colors]), ", ".join(["\"%s\"" % (color) for color in self.colors]))
+		title         = "" if region == DEFAULT_REGION else " of %s" % (region)
+		facet         = "Sample ~ Chr" if region == DEFAULT_REGION else "Sample ~ ."
+		handle        = open(self.tmpRName, "w")
+		multiple      = self._findMultiple(region)
+		handle.write("library(ggplot2)\n")
+		handle.write("data <- read.table(\"%s\", header = T)\n" % (self.tmpDatName))
+		handle.write("data$Sample <- factor(data$Sample, levels=c(%s))\n" % (", ".join(["\"%s\"" % (name) for name in self.names])))
+		handle.write("png(\"%s\", width = %d, height = %d)\n" % (fileName, self.width, self.height))
+		handle.write("ggplot(data, aes(x = Pos/%d, y = Count, fill = Sample, color = Sample)) + opts(title = \"Distribution%s\") + geom_bar(stat = \"identity\") + facet_grid(%s, space=\"free\") + xlab(\"%s%s\") + ylab(\"%s\") + %s + opts(legend.position = \"none\", panel.grid.major = theme_blank(), panel.grid.minor = theme_blank(), panel.background = theme_blank())\n" % (multiple, title, facet, self.xLab, MULTIPLE_STR[multiple], self.yLab, colors))
+		handle.write("dev.off()\n")
+
+	def _runR(self):
+		rCommand = "R"
+		if "SMARTRPATH" in os.environ:
+			rCommand = os.environ["SMARTRPATH"]
+		command = "\"%s\" CMD BATCH %s" % (rCommand, self.tmpRName)
+		status = subprocess.call(command, shell=True)
+		if status != 0:
+			raise Exception("Problem with the execution of script file %s, status is: %s" % (self.tmpRName, status))
+
+	def _plot(self):
+		progress = Progress(len(self.distribution), "Plotting data", self.verbosity)
+		for region in self.distribution:
+			if not self._checkQuorum(region):
+				self.log.info("Not displaying '%s' for it contains insufficient data." % (region))
+			else:
+				self._writeData(region)
+				self._writeScript(region)
+				self._runR()
+			progress.inc()
+		progress.done()
+
+	def _cleanFiles(self):
+		for fileName in (self.tmpDatName, self.tmpRName):
+			if fileName != None and os.path.exists(fileName):
+				os.remove(fileName)
+				for otherFileName in glob.glob("%s*" % (fileName)):
+					os.remove(otherFileName)
+
+	def run(self):
+		LoggerFactory.setLevel(self.log, self.verbosity)
+		self._checkOptions()
+		self.log.info("START Get Read Distribution")
+		for name in self.names:
+			self._parse(name)
+		self._plot()
+		self._cleanFiles()
+		self.log.info("END Get Read Distribution")
+
+
+if __name__ == "__main__":
+	description = "Usage: GetReadDistribution.py [options]\n\nGet Read Distribution v1.0.1: Get the distribution of a set of reads. [Category: Personal]\n"
+	epilog = ""
+	parser = RepetOptionParser(description = description, epilog = epilog)
+	parser.add_option("-i", "--input",     dest="inputFileNames",  action="store",      default=None,      type="string", help="input files, separated by commas [compulsory] [format: string]")
+	parser.add_option("-f", "--format",    dest="format",          action="store",      default=None,      type="string", help="format of the input [compulsory] [format: transcript or sequence file format]")
+	parser.add_option("-n", "--names",     dest="names",           action="store",      default=None,      type="string", help="name of the input data, separated by commas [compulsory] [format: string]")
+	parser.add_option("-o", "--output",    dest="outputFileName",  action="store",      default=None,      type="string", help="output file [format: output file in PNG format]")
+	parser.add_option("-s", "--binSize",   dest="binSize",         action="store",      default=10000,     type="int",    help="bin size [format: int] [default: 10000]")
+	parser.add_option("-l", "--xLabel",    dest="xLab",            action="store",      default="",        type="string", help="x-axis label name [format: string]")
+	parser.add_option("-L", "--yLabel",    dest="yLab",            action="store",      default="# reads", type="string", help="y-axis label name [format: string] [default: Reads]")
+	parser.add_option("-c", "--colors",    dest="colors",          action="store",      default=None,      type="string", help="colors of the bars, separated by commas  [format: string]")
+	parser.add_option("-a", "--factors",   dest="factors",         action="store",      default=None,      type="string", help="normalization factors, separated by commas  [format: string]")
+	parser.add_option("-r", "--regions",   dest="regionsFileName", action="store",      default=None,      type="string", help="regions to plot [format: transcript file in GFF format]")
+	parser.add_option("-m", "--multiple",  dest="multiple",        action="store_true", default=False,                    help="print position using multiples (k, G) [format: boolean] [default: False]")
+	parser.add_option("-q", "--quorum",    dest="quorum",          action="store",      default=1,         type="int",    help="minimum number of intervals to plot a region [format: int] [default: 1]")
+	parser.add_option("-z", "--width",     dest="width",           action="store",      default=800,       type="int",    help="width of the image [format: int] [default: 800]")
+	parser.add_option("-Z", "--height",    dest="height",          action="store",      default=300,       type="int",    help="height of the image [format: int] [default: 300]")
+	parser.add_option("-v", "--verbosity", dest="verbosity",       action="store",      default=1,         type="int",    help="trace level [format: int]")
+	options = parser.parse_args()[0]
+	iGetReadDistribution = GetReadDistribution(options.verbosity)
+	iGetReadDistribution.setNames(options.names.split(","))
+	iGetReadDistribution.setInputFiles(options.inputFileNames.split(","), options.format)
+	iGetReadDistribution.setOutputFileName(options.outputFileName)
+	iGetReadDistribution.setLabs(options.xLab, options.yLab)
+	iGetReadDistribution.setBinSize(options.binSize)
+	iGetReadDistribution.setColors(None if options.colors == None else options.colors.split(","))
+	iGetReadDistribution.setFactors(None if options.factors == None else map(float, options.factors.split(",")))
+	iGetReadDistribution.setRegionsFile(options.regionsFileName)
+	iGetReadDistribution.setMultiple(options.multiple)
+	iGetReadDistribution.setQuorum(options.quorum)
+	iGetReadDistribution.setImageSize(options.width, options.height)
+	iGetReadDistribution.run()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/GetReadSizes.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,255 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import random, os, glob, subprocess
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.parsing.GffParser import GffParser
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc import Utils
+from commons.core.LoggerFactory import LoggerFactory
+from commons.core.utils.RepetOptionParser import RepetOptionParser
+
+LOG_DEPTH      = "smart"
+DEFAULT_REGION = "_all_"
+
+class GetReadSizes(object):
+
+	def __init__(self, verbosity = 0):
+		self.xLab       = "Size"
+		self.yLab       = "# reads"
+		self.verbosity  = verbosity
+		self.number     = random.randint(0, 100000)
+		self.log        = LoggerFactory.createLogger("%s.%s" % (LOG_DEPTH, self.__class__.__name__), self.verbosity)
+		self.parsers      = {}
+		self.sizes      = {}
+		self.factors    = {}
+		self.regions    = None
+		self.tmpDatName = None
+		self.tmpRName   = None
+		self.width      = 800
+		self.height     = 300
+
+	def setNames(self, names):
+		self.names = names
+
+	def setInputFiles(self, fileNames, format):
+		chooser = ParserChooser(self.verbosity)
+		chooser.findFormat(format)
+		for cpt, fileName in enumerate(fileNames):
+			self.parsers[self.names[cpt]] = chooser.getParser(fileName)
+
+	def setOutputFileName(self, fileName):
+		self.outputFileName = fileName
+
+	def setLabs(self, xLab, yLab):
+		self.xLab = xLab
+		self.yLab = yLab
+
+	def setSizes(self, minSize, maxSize):
+		self.minSize = minSize
+		self.maxSize = maxSize
+
+	def setColors(self, colors):
+		self.colors = colors
+
+	def setFactors(self, factors):
+		self.factors = dict(zip(self.names, factors))
+
+	def setRegionsFile(self, fileName):
+		if fileName != None:
+			self._loadRegions(fileName)
+
+	def setImageSize(self, width, height):
+		if width != None:
+			self.width = width
+		if height != None:
+			self.height = height
+
+	def _checkOptions(self):
+		if not self.parsers:
+			self.logAndRaise("ERROR: Missing input file names")
+
+	def _logAndRaise(self, errorMsg):
+		self.log.error(errorMsg)
+		raise Exception(errorMsg)
+
+	def _loadRegions(self, fileName):
+		self.regions = {}
+		parser       = GffParser(fileName, self.verbosity)
+		for transcript in parser.getIterator():
+			chromosome = transcript.getChromosome()
+			start      = transcript.getStart()
+			end        = transcript.getEnd()
+			name       = transcript.getName()
+			if chromosome not in self.regions:
+				self.regions[chromosome] = {}
+			if start not in self.regions[chromosome]:
+				self.regions[chromosome][start] = {}
+			if end not in self.regions[chromosome][start]:
+				self.regions[chromosome][start][end] = []
+			self.regions[chromosome][start][end].append(name)
+
+	def _getRegions(self, transcript):
+		if self.regions == None:
+			return [DEFAULT_REGION]
+		chromosome = transcript.getChromosome()
+		start      = transcript.getStart()
+		end        = transcript.getEnd()
+		if chromosome not in self.regions:
+			return []
+		names = []
+		for loadedStart in sorted(self.regions[chromosome].keys()):
+			if loadedStart > end:
+				return names
+			for loadedEnd in reversed(sorted(self.regions[chromosome][loadedStart].keys())):
+				if loadedEnd < start:
+					break
+				names.extend(self.regions[chromosome][loadedStart][loadedEnd])
+		return names
+
+	def _parse(self, name):
+		progress = UnlimitedProgress(10000, "Reading file '%s'" % (name), self.verbosity)
+		for transcript in self.parsers[name].getIterator():
+			if transcript.__class__.__name__ == "Mapping":
+				transcript = transcript.getTranscript()
+			regions = self._getRegions(transcript)
+			for region in regions:
+				if region not in self.sizes:
+					self.sizes[region] = {}
+				if name not in self.sizes[region]:
+					self.sizes[region][name] = {}
+				size = transcript.getSize()
+				if (self.minSize == None or size >= self.minSize) and (self.maxSize == None or size <= self.maxSize):
+					nbElements                     = float(transcript.getTagValue("nbElements")) if "nbElements" in transcript.getTagNames() else 1
+					nbElements                    *= self.factors.get(name, 1)
+					self.sizes[region][name][size] = self.sizes[region][name].get(size, 0) + nbElements
+			progress.inc()
+		progress.done()
+		if self.minSize == None:
+			self.minSize = min([min(self.sizes[region][name].keys()) for name in self.names for region in region])
+		if self.maxSize == None:
+			self.maxSize = max([max(self.sizes[region][name].keys()) for name in self.names for region in region])
+
+	def _checkQuorum(self, region):
+		return (max([sum(self.sizes[region][name].values()) for name in self.sizes[region]]) > 0)
+
+	def _writeData(self, region):
+		self.tmpDatName = "tmpFile%d.dat" % (self.number)
+		handle          = open(self.tmpDatName, "w")
+		handle.write("Size\tCount\tSample\n")
+		for name in self.sizes[region]:
+			for size in sorted(self.sizes[region][name].keys()):
+				handle.write("%d\t%d\t\"%s\"\n" % (size, self.sizes[region][name].get(size, 0), name))
+		handle.close()
+
+	def _writeScript(self, region):
+		self.tmpRName = "tmpFile%d.R" % (self.number)
+		fileName      = self.outputFileName if region == DEFAULT_REGION else "%s_%s.png" % (os.path.splitext(self.outputFileName)[0], region)
+		colors        = "scale_fill_brewer(palette=\"Set1\")" if self.colors == None else "scale_fill_manual(values = c(%s))" % (", ".join(["\"%s\"" % (color) for color in self.colors]))
+		title         = "" if region == DEFAULT_REGION else " of %s" % (region)
+		handle        = open(self.tmpRName, "w")
+		handle.write("library(ggplot2)\n")
+		handle.write("data <- read.table(\"%s\", header = T)\n" % (self.tmpDatName))
+		handle.write("data$Sample <- factor(data$Sample, levels=c(%s))\n" % (", ".join(["\"%s\"" % (name) for name in self.names])))
+		handle.write("data$Size <- factor(data$Size, levels=c(%s))\n" % (", ".join(["%d" % (size) for size in range(self.minSize, self.maxSize+1)])))
+		handle.write("png(\"%s\", width = %d, height = %d)\n" % (fileName, self.width, self.height))
+		handle.write("ggplot(data, aes(x = Size, y = Count, fill = Size)) + opts(title = \"Size distribution%s\") + geom_bar(stat = \"identity\") + facet_grid(. ~ Sample, space=\"free_x\") + xlab(\"%s\") + ylab(\"%s\") + %s + opts(legend.position = \"none\", panel.grid.major = theme_blank(), panel.grid.minor = theme_blank(), panel.background = theme_blank())\n" % (title, self.xLab, self.yLab, colors))
+		handle.write("dev.off()\n")
+
+	def _runR(self):
+		rCommand = "R"
+		if "SMARTRPATH" in os.environ:
+			rCommand = os.environ["SMARTRPATH"]
+		command = "\"%s\" CMD BATCH %s" % (rCommand, self.tmpRName)
+		status = subprocess.call(command, shell=True)
+		if status != 0:
+			raise Exception("Problem with the execution of script file %s, status is: %s" % (self.tmpRName, status))
+
+	def _plot(self):
+		progress = Progress(len(self.sizes), "Plotting data", self.verbosity)
+		for region in self.sizes:
+			if not self._checkQuorum(region):
+				self.log.info("Not displaying '%s' for it contains no data." % (region))
+			else:
+				self._writeData(region)
+				self._writeScript(region)
+				self._runR()
+			progress.inc()
+		progress.done()
+
+	def _cleanFiles(self):
+		for fileName in (self.tmpDatName, self.tmpRName):
+			if fileName != None and os.path.exists(fileName):
+				os.remove(fileName)
+				for otherFileName in glob.glob("%s*" % (fileName)):
+					os.remove(otherFileName)
+
+	def run(self):
+		LoggerFactory.setLevel(self.log, self.verbosity)
+		self._checkOptions()
+		self.log.info("START Get Read Sizes")
+		for name in self.names:
+			self._parse(name)
+		self._plot()
+		self._cleanFiles()
+		self.log.info("END Get Read Sizes")
+
+
+if __name__ == "__main__":
+	description = "Usage: GetReadSizes.py [options]\n\nGet Read Sizes v1.0.1: Get the sizes of a set of reads. [Category: Personal]\n"
+	epilog = ""
+	parser = RepetOptionParser(description = description, epilog = epilog)
+	parser.add_option("-i", "--input",     dest="inputFileNames",  action="store",      default=None,     type="string", help="input files, separated by commas [compulsory] [format: string]")
+	parser.add_option("-f", "--format",    dest="format",          action="store",      default=None,     type="string", help="format of the input [compulsory] [format: transcript or sequence file format]")
+	parser.add_option("-n", "--names",     dest="names",           action="store",      default=None,     type="string", help="name of the input data, separated by commas [compulsory] [format: string]")
+	parser.add_option("-o", "--output",    dest="outputFileName",  action="store",      default=None,      type="string", help="output file [format: output file in PNG format]")
+	parser.add_option("-s", "--minSize",   dest="minSize",         action="store",      default=None,      type="int",    help="minimum size [format: int]")
+	parser.add_option("-S", "--maxSize",   dest="maxSize",         action="store",      default=None,      type="int",    help="maximum size [format: int]")
+	parser.add_option("-l", "--xLabel",    dest="xLab",            action="store",      default="Size",    type="string", help="x-axis label name [format: string] [default: Size]")
+	parser.add_option("-L", "--yLabel",    dest="yLab",            action="store",      default="# reads", type="string", help="y-axis label name [format: string] [default: Reads]")
+	parser.add_option("-c", "--colors",    dest="colors",          action="store",      default=None,      type="string", help="colors of the bars, separated by commas  [format: string]")
+	parser.add_option("-a", "--factors",   dest="factors",         action="store",      default=None,      type="string", help="normalization factors, separated by commas  [format: string]")
+	parser.add_option("-r", "--regions",   dest="regionsFileName", action="store",      default=None,      type="string", help="regions to plot [format: transcript file in GFF format]")
+	parser.add_option("-z", "--width",     dest="width",           action="store",      default=800,       type="int",    help="width of the image [format: int] [default: 800]")
+	parser.add_option("-Z", "--height",    dest="height",          action="store",      default=300,       type="int",    help="height of the image [format: int] [default: 300]")
+	parser.add_option("-v", "--verbosity", dest="verbosity",       action="store",      default=1,         type="int",    help="trace level [format: int]")
+	options = parser.parse_args()[0]
+	iGetReadSizes = GetReadSizes(options.verbosity)
+	iGetReadSizes.setNames(options.names.split(","))
+	iGetReadSizes.setInputFiles(options.inputFileNames.split(","), options.format)
+	iGetReadSizes.setOutputFileName(options.outputFileName)
+	iGetReadSizes.setLabs(options.xLab, options.yLab)
+	iGetReadSizes.setSizes(options.minSize, options.maxSize)
+	iGetReadSizes.setColors(None if options.colors == None else options.colors.split(","))
+	iGetReadSizes.setFactors(None if options.factors == None else map(float, options.factors.split(",")))
+	iGetReadSizes.setRegionsFile(options.regionsFileName)
+	iGetReadSizes.setImageSize(options.width, options.height)
+	iGetReadSizes.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/GetUpDownStream.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,152 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2012
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os
+from optparse import OptionParser, OptionGroup
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.ncList.NCListFilePickle import NCListFileUnpickle
+from SMART.Java.Python.ncList.FileSorter import FileSorter
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc import Utils
+
+
+class GetUpDownStream(object):
+
+    def __init__(self, verbosity = 0):
+        self.verbosity         = verbosity
+        self.inputReader       = None
+        self.outputWriter      = None
+        self.nbRead            = 0
+        self.nbWritten         = 0
+        self.nbMerges          = 0
+        self.splittedFileNames = {}
+
+    def __del__(self):
+        for fileName in self.splittedFileNames.values():
+            os.remove(fileName)
+            
+    def setInputFile(self, fileName, format):
+        parserChooser = ParserChooser(self.verbosity)
+        parserChooser.findFormat(format, "transcript")
+        self.parser = parserChooser.getParser(fileName)
+        self.sortedFileName = "%s_sorted.pkl" % (os.path.splitext(fileName)[0])
+
+    def setOutputFile(self, fileName):
+        self.outputWriter = Gff3Writer(fileName, self.verbosity)
+
+    def setDistances(self, up, down):
+        self.upDistance   = up
+        self.downDistance = down
+
+    def _sortFile(self):
+        fs = FileSorter(self.parser, self.verbosity-4)
+        fs.perChromosome(True)
+        fs.setOutputFileName(self.sortedFileName)
+        fs.sort()
+        self.splittedFileNames       = fs.getOutputFileNames()
+        self.nbElementsPerChromosome = fs.getNbElementsPerChromosome()
+        self.nbRead                  = fs.getNbElements()
+
+    def _write(self, start, end, reference, after):
+        if start > end:
+            return
+        transcript = Transcript()
+        transcript.setChromosome(reference.getChromosome())
+        transcript.setStart(start)
+        transcript.setEnd(end)
+        transcript.setDirection("+")
+        transcript.setName("%s_%s" % ("up" if Utils.xor(reference.getDirection() == 1, after) else "down", reference.getName()))
+        self.outputWriter.addTranscript(transcript)
+        
+    def _getFlanking(self, chromosome):
+        progress    = Progress(self.nbElementsPerChromosome[chromosome], "Analyzing chromosome %s" % (chromosome), self.verbosity)
+        parser      = NCListFileUnpickle(self.splittedFileNames[chromosome], self.verbosity)
+        previous    = None
+        for transcript in parser.getIterator():
+            progress.inc()
+            transcript.removeExons()
+            if previous == None:
+                distance = self.upDistance if transcript.getDirection() == 1 else self.downDistance
+                start    = max(1, transcript.getStart() - distance)
+                self._write(start, transcript.getStart()-1, transcript, False)
+                previous = transcript
+                continue
+            if previous.include(transcript):
+                continue
+            if transcript.overlapWith(previous):
+                previous = transcript
+                continue
+            distancePrevious = self.downDistance if previous.getDirection()   == 1 else self.upDistance
+            distanceCurrent  = self.upDistance   if transcript.getDirection() == 1 else self.downDistance
+            distance = transcript.getDistance(previous)
+            if distancePrevious + distanceCurrent == 0:
+                previous = transcript
+                continue
+            if distance >= distancePrevious + distanceCurrent:
+                endPrevious  = previous.getEnd() + distancePrevious
+                startCurrent = transcript.getStart() - distanceCurrent
+            else:
+                middle       = previous.getEnd() + int((distance-1) * float(distancePrevious) / (distancePrevious + distanceCurrent))
+                endPrevious  = middle
+                startCurrent = middle+1
+            self._write(previous.getEnd() + 1, endPrevious, previous, True)
+            self._write(startCurrent, transcript.getStart() - 1, transcript, False)
+            previous = transcript
+        distance = self.downDistance if previous.getDirection() == 1 else self.upDistance
+        self._write(previous.getEnd() + 1, previous.getEnd() + distance, previous, True)
+        progress.done()
+
+    def run(self):
+        self._sortFile()
+        for chromosome in sorted(self.nbElementsPerChromosome.keys()):
+            self._getFlanking(chromosome)
+        self.outputWriter.close()
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Get Up and Down Stream v1.0.0: Get the flanking regions of an annotation. [Category: Data Modification]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",                     type="string", help="input file [compulsory] [format: file in mapping format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",         action="store",                     type="string", help="format of the file [compulsory] [format: mapping file format]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",                     type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-u", "--up",        dest="up",             action="store",      default=0,     type="int",    help="the upstream distance  [format: int]")
+    parser.add_option("-d", "--down",      dest="down",           action="store",      default=0,     type="int",    help="the downstream distance  [format: int]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [default: 1] [format: int]")
+    (options, args) = parser.parse_args()
+
+    guds = GetUpDownStream(options.verbosity)
+    guds.setInputFile(options.inputFileName, options.format)
+    guds.setOutputFile(options.outputFileName)
+    guds.setDistances(options.up, options.down)
+    guds.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/RestrictFromCoverage.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,224 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2012
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os, struct, time, random
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.ncList.NCList import NCList
+from SMART.Java.Python.ncList.NCListCursor import NCListCursor
+from SMART.Java.Python.ncList.NCListFilePickle import NCListFilePickle, NCListFileUnpickle
+from SMART.Java.Python.ncList.FileSorter import FileSorter
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+from SMART.Java.Python.misc import Utils
+try:
+    import cPickle as pickle
+except:
+    import pickle
+
+REFERENCE = 0
+QUERY = 1
+TYPES = (REFERENCE, QUERY)
+TYPETOSTRING = {0: "reference", 1: "query"}
+
+class RestrictFromCoverage(object):
+
+    def __init__(self, verbosity = 1):
+        self._verbosity               = verbosity
+        self._randomNumber            = random.randint(0, 100000)
+        self._nbWritten               = 0
+        self._nbLines                 = dict([type, 0]  for type in TYPES)
+        self._splittedFileNames       = dict([type, {}] for type in TYPES)
+        self._nbElementsPerChromosome = dict([type, {}] for type in TYPES)
+        self._nbElements              = dict([type, 0]  for type in TYPES)
+        
+    def __del__(self):
+        pass
+
+    def _close(self):
+        self._writer.close()
+        
+    def setInputFileName(self, fileName, format, type):
+        chooser = ParserChooser(self._verbosity)
+        chooser.findFormat(format)
+        parser = chooser.getParser(fileName)
+        sortedFileName = "%s_%d_%d_sorted.pkl" % (os.path.splitext(fileName)[0], self._randomNumber, type)
+        if self._verbosity > 2:
+            print "Preparing %s file..." % (TYPETOSTRING[type])
+        startTime = time.time()
+        fs = FileSorter(parser, self._verbosity-1)
+        fs.perChromosome(True)
+        fs.setOutputFileName(sortedFileName)
+        fs.sort()
+        self._nbLines[type]                 = fs.getNbElements()
+        self._splittedFileNames[type]       = fs.getOutputFileNames()
+        self._nbElementsPerChromosome[type] = fs.getNbElementsPerChromosome()
+        self._nbElements[type]              = fs.getNbElements()
+        endTime = time.time()
+        if self._verbosity > 2:
+            print "    ...done (%ds)" % (endTime - startTime)
+            
+    def setOutputFileName(self, outputFileName):
+        self._writer = Gff3Writer(outputFileName)
+
+    def setPercent(self, minPercent, maxPercent):
+        self._minPercent = minPercent
+        self._maxPercent = maxPercent
+
+    def setNbNucleotides(self, minNb, maxNb):
+        self._minNucleotides = minNb
+        self._maxNucleotides = maxNb
+
+    def setOverlap(self, minOverlap, maxOverlap):
+        self._minOverlap = minOverlap
+        self._maxOverlap = maxOverlap
+
+    def setStrands(self, boolean):
+        self._twoStrands = boolean
+
+    def _compareChromosome(self, chromosome):
+        firstOverlap = 0
+        parser1      = NCListFileUnpickle(self._splittedFileNames[QUERY][chromosome],     self._verbosity)
+        parser2      = NCListFileUnpickle(self._splittedFileNames[REFERENCE][chromosome], self._verbosity)
+        progress     = Progress(self._nbElementsPerChromosome[QUERY][chromosome], "Analyzing %s" % (chromosome), self._verbosity)
+        for transcript1 in parser1.getIterator():
+            firstOverlap = self._compareList(transcript1, parser2)
+            parser2.setInitAddress(firstOverlap)
+            progress.inc()
+        progress.done()
+
+    def _compareList(self, transcript1, parser2):
+        values = []
+        for exon in transcript1.getExons():
+            values.append([0.0] * exon.getSize())
+        firstOverlap = None
+        for transcript2 in parser2.getIterator():
+            address       = parser2.getCurrentTranscriptAddress()
+            nbElements    = float(transcript2.getTagValue("nbElements"))    if "nbElements"    in transcript2.getTagNames() else 1.0
+            nbOccurrences = float(transcript2.getTagValue("nbOccurrences")) if "nbOccurrences" in transcript2.getTagNames() else 1.0
+            nbElements   /= nbOccurrences
+            if transcript2.getStart() > transcript1.getEnd():
+                if firstOverlap == None:
+                    firstOverlap = address
+                if self._checkValues(values):
+                    self._printTranscript(transcript1)
+                return firstOverlap
+            elif transcript1.overlapWith(transcript2):
+                if firstOverlap == None:
+                    firstOverlap = address
+                values = self._compareTranscript(transcript1, transcript2, values, nbElements)
+        if self._checkValues(values):
+            self._printTranscript(transcript1)
+            return firstOverlap
+    
+    def _compareTranscript(self, transcript1, transcript2, values, nbElements):
+        if not transcript1.overlapWith(transcript2) or ((self._twoStrands) and transcript1.getDirection() != transcript2.getDirection()):
+            return values
+        for id1, exon1 in enumerate(transcript1.getExons()):
+            for exon2 in transcript2.getExons():
+                values[id1] = map(sum, zip(values[id1], self._compareExon(exon1, exon2, nbElements)))
+        return values
+        
+    def _compareExon(self, exon1, exon2, nbElements):
+        array = [0.0] * exon1.getSize()
+        if not exon1.overlapWith(exon2) or ((self._twoStrands) and exon1.getDirection() != exon2.getDirection()):
+            return array
+        for pos in range(max(exon1.getStart(), exon2.getStart()) - exon1.getStart(), min(exon1.getEnd(), exon2.getEnd()) - exon1.getStart()+1):
+            array[pos] += nbElements
+        return array
+
+    def _filter(self, value):
+        if self._minOverlap and self._maxOverlap:
+            return self._minOverlap <= value <= self._maxOverlap
+        if self._minOverlap:
+            return self._minOverlap <= value
+        if self._maxOverlap:
+            return value <= self._maxOverlap
+        return True
+
+    def _checkValues(self, values):
+        nbValues    = sum(map(len, values))
+        nbPosValues = sum(map(len, [filter(self._filter, valuePart) for valuePart in values]))
+        ratio       = float(nbPosValues) / nbValues * 100
+        if self._minNucleotides and nbPosValues < self._minNucleotides:
+            return False
+        if self._maxNucleotides and nbPosValues > self._maxNucleotides:
+            return False
+        if self._minPercent and ratio < self._minPercent:
+            return False
+        if self._maxPercent and ratio > self._maxPercent:
+            return False
+        return True
+
+    def _printTranscript(self, transcript):
+        self._writer.addTranscript(transcript)
+        self._nbWritten += 1
+
+    def run(self):
+        for chromosome in sorted(self._splittedFileNames[QUERY].keys()):
+            self._compareChromosome(chromosome)
+        self._close()
+        if self._verbosity > 0:
+            print "# queries: %d" % (self._nbElements[QUERY])
+            print "# refs:    %d" % (self._nbElements[REFERENCE])
+            print "# written: %d (%d%%)" % (self._nbWritten, 0 if self._nbElements[QUERY] == 0 else round(float(self._nbWritten) / self._nbElements[QUERY] * 100))
+        
+
+if __name__ == "__main__":
+    description = "Restrict From Coverage v1.0.0: Select the elements from the first set which have a given coverage. [Category: Data Comparison]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input1",           dest="inputFileName1", action="store",                     type="string", help="input file 1 [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format1",          dest="format1",        action="store",                     type="string", help="format of file 1 [compulsory] [format: transcript file format]")
+    parser.add_option("-j", "--input2",           dest="inputFileName2", action="store",                     type="string", help="input file 2 [compulsory] [format: file in transcript format given by -g]")
+    parser.add_option("-g", "--format2",          dest="format2",        action="store",                     type="string", help="format of file 2 [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",           dest="output",         action="store",      default=None,  type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-n", "--minNucleotides",   dest="minNucleotides", action="store",      default=None,  type="int",    help="minimum number of nucleotides overlapping to declare an overlap [format: int]")
+    parser.add_option("-N", "--maxNucleotides",   dest="maxNucleotides", action="store",      default=None,  type="int",    help="maximum number of nucleotides overlapping to declare an overlap [format: int]")
+    parser.add_option("-p", "--minPercent",       dest="minPercent",     action="store",      default=None,  type="int",    help="minimum percentage of nucleotides overlapping to declare an overlap [format: int]")
+    parser.add_option("-P", "--maxPercent",       dest="maxPercent",     action="store",      default=None,  type="int",    help="maximum percentage of nucleotides overlapping to declare an overlap [format: int]")
+    parser.add_option("-e", "--minOverlap",       dest="minOverlap",     action="store",      default=None,  type="int",    help="minimum number of elements from 2nd file to declare an overlap [format: int]")
+    parser.add_option("-E", "--maxOverlap",       dest="maxOverlap",     action="store",      default=None,  type="int",    help="maximum number of elements from 2nd file to declare an overlap [format: int]")
+    parser.add_option("-s", "--strands",          dest="strands",        action="store_true", default=False,                help="consider the two strands separately [format: bool] [default: false]")
+    parser.add_option("-v", "--verbosity",        dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    rfc = RestrictFromCoverage(options.verbosity)
+    rfc.setInputFileName(options.inputFileName1, options.format1, QUERY)
+    rfc.setInputFileName(options.inputFileName2, options.format2, REFERENCE)
+    rfc.setOutputFileName(options.output)
+    rfc.setNbNucleotides(options.minNucleotides, options.maxNucleotides)
+    rfc.setPercent(options.minPercent, options.maxPercent)
+    rfc.setOverlap(options.minOverlap, options.maxOverlap)
+    rfc.setStrands(options.strands)
+    rfc.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/SelectByTag.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,148 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Select the transcript such that a tag value is not less than a given threshold"""
+import os
+import sys
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from commons.core.writer import MySqlTranscriptWriter
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.RPlotter import RPlotter
+
+class SelectByTag(object):
+    
+    def __init__(self, verbosity = 1):
+        self.input     = None
+        self.format    = None
+        self.tag       = None
+        self.value     = None
+        self.min       = None
+        self.max       = None
+        self.default   = None
+        self.output    = None
+        self.mysql     = None
+        self.verbosity = verbosity
+
+        self.parser      = None
+        self.writer      = None
+        self.mysqlWriter = None
+        self.nbElements  = None
+        self.nbWritten   = 0
+
+    
+    def setParser(self):
+        self.parser     = TranscriptContainer(self.input, self.format, self.verbosity)
+        self.nbElements = self.parser.getNbTranscripts()
+
+
+    def setWriter(self):
+        self.writer = Gff3Writer(self.output, self.verbosity)
+        if self.mysql:
+            self.mysqlWriter = MySqlTranscriptWriter(self.output, self.verbosity)
+
+
+    def isAccepted(self, transcript):
+        value = transcript.getTagValue(self.tag)
+        if value == None:
+            if self.default != None:
+                value = self.default
+            else:
+                raise Exception("Error! Transcript %s no tag called '%s'" % (transcript, self.tag))
+        if self.value != None:
+            if self.value == str(value):
+                return True
+            return self.value.isdigit() and value == float(self.value)
+        value = float(value)
+        return (self.min == None or self.min <= value) and (self.max == None or self.max >= value)
+
+
+    def readInputFile(self):
+        progress = Progress(self.parser.getNbTranscripts(), "Writing transcripts", self.verbosity)
+        for transcript in self.parser.getIterator():
+            if self.isAccepted(transcript):
+                self.writer.addTranscript(transcript)
+                if self.mysql:
+                    self.mysqlWriter.addTranscript(transcript)
+                self.nbWritten += 1
+            progress.inc()
+        progress.done()
+
+
+    def writeFile(self):
+        self.writer.write()
+        if self.mysql:
+            self.mysqlWriter.write()
+
+    
+    def run(self):
+        self.setParser()
+        self.setWriter()
+        self.readInputFile()
+        self.writeFile()
+        if self.verbosity > 0:
+            print "%d input" % (self.nbElements)
+            if self.nbElements != 0:
+                print "%d output (%.2f%%)" % (self.nbWritten, float(self.nbWritten) / self.nbElements * 100)
+
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Select by Tag v1.0.2: Keep the genomic coordinates such that a the value of a given tag is between two limits. [Category: Data Selection]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input", dest="inputFileName", action="store", type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format", dest="format", action="store", type="string", help="format of the input [compulsory] [format: transcript file format]")
+    parser.add_option("-g", "--tag", dest="tag", action="store", default=None, type="string", help="the tag [compulsory] [format: string]")     
+    parser.add_option("-a", "--value", dest="value", action="store", default=None, type="string", help="the value to be found [format: string]")     
+    parser.add_option("-m", "--min", dest="min", action="store", default=None, type="float", help="the minimum threshold [format: float]")     
+    parser.add_option("-M", "--max", dest="max", action="store", default=None, type="float", help="the maximum threshold [format: float]")     
+    parser.add_option("-d", "--default", dest="default", action="store", default=None, type="float", help="value if tag is not present [format: float]")     
+    parser.add_option("-o", "--output", dest="outputFileName", action="store", type="string", help="output file [format: output file in GFF3 format]")
+    parser.add_option("-y", "--mysql", dest="mysql", action="store_true", default=False, help="write output into MySQL tables [format: boolean] [default: False]")
+    parser.add_option("-v", "--verbosity", dest="verbosity", action="store", default=1, type="int", help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    selectByTag         = SelectByTag(options.verbosity)
+    selectByTag.input   = options.inputFileName
+    selectByTag.format  = options.format
+    selectByTag.tag     = options.tag
+    selectByTag.value   = options.value
+    selectByTag.min     = options.min
+    selectByTag.max     = options.max
+    selectByTag.default = options.default
+    selectByTag.output  = options.outputFileName
+    selectByTag.mysql   = options.mysql
+    selectByTag.run()
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/WrappGetDistribution.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,96 @@
+#! /usr/bin/env python
+from optparse import OptionParser
+import tarfile
+import os
+import re
+import shutil
+import subprocess
+
+SMART_PATH = "%s/SMART" % os.environ["REPET_PATH"]
+
+def toTar(tarFileName, directory):
+    fileName = os.path.splitext(tarFileName)[0]
+    fileNameBaseName = os.path.basename(fileName)
+    tfile = tarfile.open(fileName + ".tmp.tar", "w")
+    list = os.listdir(directory)
+    for file in list:
+        if re.search(str(fileNameBaseName), file):
+            tfile.add(file)
+    os.system("mv %s %s" % (fileName + ".tmp.tar", options.outTarFileName))
+    tfile.close()
+    
+
+if __name__ == "__main__":
+    
+    magnifyingFactor = 1000
+    
+    # parse command line
+    description = "Get Distribution v1.0.1: Get the distribution of the genomic coordinates on a genome. [Category: Visualization]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",       dest="inputFileName",     action="store",                     type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",      dest="format",            action="store",                     type="string", help="format of the input file [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",      dest="outTarFileName",    action="store",                     type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-r", "--reference",   dest="referenceFileName", action="store",      default=None,  type="string", help="file containing the genome [compulsory] [format: file in FASTA format]")
+    parser.add_option("-n", "--nbBins",      dest="nbBins",            action="store",      default=1000,  type="int",    help="number of bins [default: 1000] [format: int]")
+    parser.add_option("-2", "--bothStrands", dest="bothStrands",       action="store_true", default=False,                help="plot one curve per strand [format: bool] [default: false]")
+    parser.add_option("-w", "--raw",         dest="raw",               action="store_true", default=False,                help="plot raw number of occurrences instead of density [format: bool] [default: false]")
+    parser.add_option("-x", "--csv",         dest="csv",               action="store_true", default=False,                help="write a .csv file [format: bool]")
+    parser.add_option("-c", "--chromosome",  dest="chromosome",        action="store",      default=None,  type="string", help="plot only a chromosome [format: string]")
+    parser.add_option("-s", "--start",       dest="start",             action="store",      default=None,  type="int",    help="start from a given region [format: int]")
+    parser.add_option("-e", "--end",         dest="end",               action="store",      default=None,  type="int",    help="end from a given region [format: int]")
+    parser.add_option("-y", "--yMin",        dest="yMin",              action="store",      default=None,  type="int",    help="minimum value on the y-axis to plot [format: int]")
+    parser.add_option("-Y", "--yMax",        dest="yMax",              action="store",      default=None,  type="int",    help="maximum value on the y-axis to plot [format: int]")
+    parser.add_option("-g", "--gff",         dest="gff",               action="store_true", default=False,                help="also write GFF3 file [format: bool] [default: false]")
+    parser.add_option("-H", "--height",      dest="height",            action="store",      default=None,  type="int",    help="height of the graphics [format: int] [default: 300]")
+    parser.add_option("-W", "--width",       dest="width",             action="store",      default=None,  type="int",    help="width of the graphics [format: int] [default: 1000]")
+    parser.add_option("-v", "--verbosity",   dest="verbosity",         action="store",      default=1,     type="int",    help="trace level [default: 1] [format: int]")
+    parser.add_option("-l", "--log",         dest="log",               action="store_true", default=False,                help="write a log file [format: bool]")
+    (options, args) = parser.parse_args()
+
+
+    absPath = os.getcwd()
+    print "the current path is :", absPath
+    directory = "/tmp/wrappGetDistribution"
+    print "the dir path is :", directory
+    if not os.path.exists(directory):
+        os.makedirs(directory)
+    os.chdir(directory)
+    if options.inputFileName != None and options.format != None and options.outTarFileName != None:
+        outputFileName = os.path.splitext(os.path.basename(options.outTarFileName))[0]
+        cmd = "python %s/Java/Python/getDistribution.py -i %s -f %s -o %s -D %s" % (SMART_PATH, options.inputFileName, options.format, outputFileName, directory)
+    if options.referenceFileName != None :
+        cmd += " -r %s" % options.referenceFileName
+    if options.nbBins != None :
+        cmd += " -n %s" % options.nbBins
+    if options.chromosome :
+        cmd += " -c %s" % options.chromosome 
+    if options.start != None :
+        cmd += " -s %s" % options.start
+    if options.end != None :
+        cmd += " -e %s" % options.end
+    if options.yMin != None :
+        cmd += " -y %s" % options.yMin
+    if options.yMax != None :
+        cmd += " -Y %s" % options.yMax
+    if options.height != None :
+        cmd += " -H %s" % options.height
+    if options.width != None :
+        cmd += " -W %s" % options.width
+    if options.bothStrands :
+        cmd += " -2" 
+    if options.raw :
+        cmd += " -w" 
+    if options.csv :
+        cmd += " -x" 
+    if options.gff :
+        cmd += " -g"
+    if options.log :
+        cmd += " -l" 
+    print "cmd is: ", cmd    
+    status = subprocess.call(cmd, shell=True)
+    if status != 0:
+            raise Exception("Problem with the execution of command!")
+    toTar(options.outTarFileName, directory)
+    shutil.rmtree(directory)
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/WrappGetReadDistribution.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,58 @@
+#! /usr/bin/env python
+from optparse import OptionParser
+import tarfile
+import os
+import re
+import shutil
+import subprocess
+
+SMART_PATH = "%s/SMART" % os.environ["REPET_PATH"]
+
+def toTar(tarFileName, directory):
+    fileName = os.path.splitext(tarFileName)[0]
+    fileNameBaseName = os.path.basename(fileName)
+    tfile = tarfile.open(fileName + ".tmp.tar", "w")
+    list = os.listdir(directory)
+    for file in list:
+        if re.search(str(fileNameBaseName), file):
+            tfile.add(file)
+    os.system("mv %s %s" % (fileName + ".tmp.tar", options.outTarFileName))
+    tfile.close()
+    
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Get Read Distribution v1.0.1: Plot the number of identical reads and give the most represented. [Category: Visualization]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",               type="string", help="input file sequence [compulsory] [format: file in sequence format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",         action="store",               type="string", help="format of the file [compulsory] [format: sequence file format]")
+    parser.add_option("-n", "--number",    dest="number",         action="store", default=None, type="int",    help="keep the best n    [format: int]")
+    parser.add_option("-p", "--percent",   dest="percent",        action="store", default=None, type="float",  help="keep the best n\% [format: float]")
+    parser.add_option("-o", "--output",    dest="outTarFileName", action="store",               type="string", help="output file [compulsory] [format: zip]")
+
+    (options, args) = parser.parse_args()
+
+
+    absPath = os.getcwd()
+    print "the current path is :", absPath
+    directory = "/tmp/wrappGetReadDistribution"
+    print "the dir path is :", directory
+    if not os.path.exists(directory):
+        os.makedirs(directory)
+    os.chdir(directory)
+    if options.inputFileName != None and options.format != None and options.outTarFileName != None:
+        outputFileName = os.path.splitext(os.path.basename(options.outTarFileName))[0]
+        cmd = "python %s/Java/Python/getReadDistribution.py -i %s -f %s -o %s -D %s" % (SMART_PATH, options.inputFileName, options.format, outputFileName, directory)
+    if options.number != None :
+        cmd += " -n %s" % options.number
+    if options.percent != None :
+        cmd += " -p %s" % options.percent
+    print "cmd is: ", cmd    
+    status = subprocess.call(cmd, shell=True)
+    if status != 0:
+            raise Exception("Problem with the execution of command!")
+    toTar(options.outTarFileName, directory)
+    shutil.rmtree(directory)
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/WrappPlotCoverage.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,89 @@
+#! /usr/bin/env python
+from optparse import OptionParser
+import tarfile
+import os
+import re
+import shutil
+import subprocess
+
+SMART_PATH = "%s/SMART" % os.environ["REPET_PATH"]
+
+def toTar(tarFileName, directory):
+    fileName = os.path.splitext(tarFileName)[0]
+    fileNameBaseName = os.path.basename(fileName)
+    tfile = tarfile.open(fileName + ".tmp.tar", "w")
+    list = os.listdir(directory)
+    for file in list:
+        if re.search(str(fileNameBaseName), file):
+            tfile.add(file)
+    os.system("mv %s %s" % (fileName + ".tmp.tar", options.outTarFileName))
+    tfile.close()
+
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Plot Coverage v1.0.1: Plot the coverage of the first data with respect to the second one. [Category: Visualization]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input1",       dest="inputFileName1", action="store",                       type="string", help="input file 1 [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--inputFormat1", dest="inputFormat1",   action="store",                       type="string", help="format of input file 1 [compulsory] [format: transcript file format]")
+    parser.add_option("-j", "--input2",       dest="inputFileName2", action="store",                       type="string", help="input file 2 [compulsory] [format: file in transcript format given by -g]")
+    parser.add_option("-g", "--inputFormat2", dest="inputFormat2",   action="store",                       type="string", help="format of input file 2 [compulsory] [format: transcript file format]")
+    parser.add_option("-q", "--sequence",     dest="inputSequence",  action="store",      default=None,    type="string", help="input sequence file [format: file in FASTA format] [default: None]")
+    parser.add_option("-o", "--output",       dest="outTarFileName", action="store",                       type="string", help="output file [compulsory] [format: output file in zip format]")
+    parser.add_option("-w", "--width",        dest="width",          action="store",      default=1500,    type="int",    help="width of the plots (in px) [format: int] [default: 1500]")
+    parser.add_option("-e", "--height",       dest="height",         action="store",      default=1000,    type="int",    help="height of the plots (in px) [format: int] [default: 1000]")
+    parser.add_option("-t", "--title",        dest="title",          action="store",      default="",      type="string", help="title of the plots [format: string]")
+    parser.add_option("-x", "--xlab",         dest="xLabel",         action="store",      default="",      type="string", help="label on the x-axis [format: string]")
+    parser.add_option("-y", "--ylab",         dest="yLabel",         action="store",      default="",      type="string", help="label on the y-axis [format: string]")
+    parser.add_option("-p", "--plusColor",    dest="plusColor",      action="store",      default="red",   type="string", help="color for the elements on the plus strand [format: string] [default: red]")
+    parser.add_option("-m", "--minusColor",   dest="minusColor",     action="store",      default="blue",  type="string", help="color for the elements on the minus strand [format: string] [default: blue]")
+    parser.add_option("-s", "--sumColor",     dest="sumColor",       action="store",      default="black", type="string", help="color for 2 strands coverage line [format: string] [default: black]")
+    parser.add_option("-l", "--lineColor",    dest="lineColor",      action="store",      default="black", type="string", help="color for the lines [format: string] [default: black]")
+    parser.add_option("-1", "--merge",        dest="merge",          action="store_true", default=False,                  help="merge the 2 plots in 1 [format: boolean] [default: false]")
+    parser.add_option("-v", "--verbosity",    dest="verbosity",      action="store",      default=1,       type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    absPath = os.getcwd()
+    directory = "/tmp/wrappPlotCov"
+    if not os.path.exists(directory):
+        os.makedirs(directory)
+    os.chdir(directory)
+    if options.inputFileName1 != None and options.inputFormat1 != None and options.inputFileName2 != None and options.inputFormat2 != None and options.outTarFileName != None:
+        outputFileName = os.path.splitext(os.path.basename(options.outTarFileName))[0]
+        print 'outputfile is :', outputFileName
+        cmd = "python %s/Java/Python/plotCoverage.py -i %s -f %s -j %s -g %s -o %s -D %s" % (SMART_PATH, options.inputFileName1, options.inputFormat1, options.inputFileName2, options.inputFormat2, outputFileName, directory)
+    if options.inputSequence!= None:
+        cmd += " -q %s" % options.inputSequence
+    if options.width != None:
+        cmd += " -w %s" % options.width
+    if options.height != None:
+        cmd += " -e %s" % options.height
+    if options.title != None:
+        cmd += " -t %s" % options.title
+    if options.xLabel != None:
+        cmd += " -x %s" % options.xLabel
+    if options.yLabel != None:
+        cmd += " -y %s" % options.yLabel
+    if options.plusColor != None:
+        cmd += " -p %s" % options.plusColor
+    if options.minusColor != None:
+        cmd += " -m %s" % options.minusColor
+    if options.sumColor != None:
+        cmd += " -s %s" % options.sumColor
+    if options.lineColor != None:
+        cmd += " -l %s" % options.lineColor
+    if options.merge:
+        cmd += " -1"
+    status = subprocess.call(cmd, shell=True)
+    if status != 0:
+            raise Exception("Problem with the execution of command!")
+    toTar(options.outTarFileName, directory)
+    shutil.rmtree(directory)
+
+ 
+
+
+        
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/WrappPlotRepartition.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,71 @@
+#! /usr/bin/env python
+from optparse import OptionParser
+import tarfile
+import os
+import re
+import shutil
+import subprocess
+
+SMART_PATH = "%sSMART" % os.environ["REPET_PATH"]
+
+def toTar(tarFileName, directory):
+    fileName = os.path.splitext(tarFileName)[0]
+    fileNameBaseName = os.path.basename(fileName)
+    tfile = tarfile.open(fileName + ".tmp.tar", "w")
+    list = os.listdir(directory)
+    for file in list:
+        if re.search(str(fileNameBaseName), file):
+            tfile.add(file)
+    os.system("mv %s %s" % (fileName + ".tmp.tar", options.outTarFileName))
+    tfile.close()
+    
+
+if __name__ == "__main__":
+    
+    magnifyingFactor = 1000
+    
+    # parse command line
+    description = "Plot the repartition of different data on a whole genome. (This tool uses 1 input file only, the different values being stored in the tags.    See documentation to know more about it.) [Category: Visualization]"
+
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",dest="inputFileName",action="store",type="string",help="input file name [compulsory] [format: file in GFF3 format]")
+    parser.add_option("-n", "--names",dest="names", action="store", type="string", help="name for the tags (separated by commas and no space) [compulsory] [format: string]")
+    parser.add_option("-o", "--output",dest="outTarFileName",action="store",type="string", help="output file [compulsory] [format: output file tar format]")
+    parser.add_option("-c", "--color",dest="colors",action="store",default=None,type="string", help="color of the lines (separated by commas and no space) [format: string]")
+    parser.add_option("-f", "--format",dest="format",action="store",default="png",type="string", help="format of the output file [format: string] [default: png]")
+    parser.add_option("-r", "--normalize",dest="normalize",action="store_true", default=False,help="normalize data (when panels are different) [format: bool] [default: false]")
+    parser.add_option("-l", "--log",dest="log",action="store",default="",type="string", help="use log on x- or y-axis (write 'x', 'y' or 'xy') [format: string]")
+    parser.add_option("-v", "--verbosity",dest="verbosity",action="store",default=1,type="int",help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+
+    absPath = os.getcwd()
+    print "the current path is :", absPath
+    directory = "/tmp/wrappPlotRepartition"
+    print "the dir path is :", directory
+    if not os.path.exists(directory):
+        os.makedirs(directory)
+    os.chdir(directory)
+    if options.inputFileName != None and options.format != None and options.outTarFileName != None:
+        outputFileName = os.path.splitext(os.path.basename(options.outTarFileName))[0]
+        cmd = "python %s/Java/Python/plotRepartition.py -i %s -o %s -D %s" % (SMART_PATH, options.inputFileName, outputFileName, directory)
+    if options.names != None :
+        cmd += " -n %s" % options.names
+    else: print "You must choose tag names !"
+    if options.colors != None :
+        cmd += " -c %s" % options.colors
+    if options.format != None:
+        cmd += " -f %s" % options.format
+    if options.normalize :
+        cmd += " -r " 
+    if options.log != "" :
+        cmd += " -l %s" % options.log
+    
+    print "cmd is: ", cmd    
+    status = subprocess.call(cmd, shell=True)
+    if status != 0:
+            raise Exception("Problem with the execution of command!")
+    toTar(options.outTarFileName, directory)
+    shutil.rmtree(directory)
+    
Binary file smart_toolShed/SMART/Java/Python/__init__.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/adaptorStripper.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,115 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Remove adaptors"""
+
+import os
+from optparse import OptionParser
+from SMART.Java.Python.structure.Sequence import Sequence
+from SMART.Java.Python.structure.SequenceList import SequenceList
+from commons.core.parsing.FastaParser import FastaParser
+from commons.core.writer.FastaWriter import FastaWriter
+from SMART.Java.Python.misc.Progress import Progress
+
+
+def distance (string1, string2):
+    if len(string1) != len(string2):
+        return None
+    distance = 0
+    for i in range(0, len(string1)):
+        if string1[i] != string2[i]:
+            distance += 1
+    return distance
+
+
+
+if __name__ == "__main__":
+    nbRemaining = 0
+    
+    # parse command line
+    description = "Adaptor Stripper v1.0.1: Remove the adaptor of a list of reads. [Category: Personnal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",         dest="inputFileName",      action="store",                     type="string", help="input file [compulsory] [format: file in FASTA format]")
+    parser.add_option("-o", "--output",        dest="outputFileName",     action="store",                     type="string", help="output file [compulsory] [format: output file in FASTA format]")
+    parser.add_option("-5", "--5primeAdaptor", dest="fivePrimeAdaptor",   action="store",                     type="string", help="five prime adaptor [format: string]")
+    parser.add_option("-3", "--3primeAdaptor", dest="threePrimeAdaptor",  action="store",                     type="string", help="three prime adaptor [format: string]")
+    parser.add_option("-d", "--5primeDist",    dest="fivePrimeDistance",  action="store",      default=3,     type="int",    help="five prime distance [format: int] [default: 3]")
+    parser.add_option("-e", "--3primeDist",    dest="threePrimeDistance", action="store",      default=3,     type="int",    help="three prime distance [format: int [default: 3]]")
+    parser.add_option("-m", "--3primeSize",    dest="threePrimeSize",     action="store",      default=10,    type="int",    help="three prime size [format: int] [default: 10]")
+    parser.add_option("-v", "--verbosity",     dest="verbosity",          action="store",      default=1,     type="int",    help="trace level [format: int] [default: 1]")
+    parser.add_option("-l", "--log",           dest="log",                action="store_true", default=False,                help="write a log file [format: bool] [default: false]")
+    (options, args) = parser.parse_args()
+
+    if options.log:
+        logHandle = open(options.outputFileName + ".log", "w")
+
+
+    writer         = FastaWriter(options.outputFileName + ".fas", options.verbosity)
+    sequenceParser = FastaParser(options.inputFileName, options.verbosity)
+    nbSequences    = sequenceParser.getNbSequences()
+
+    # treat sequences
+    progress = Progress(sequenceParser.getNbSequences(), "Analyzing " + options.inputFileName, options.verbosity)
+    for sequence in sequenceParser.getIterator():
+        fivePrimeAdaptor  = sequence.getSequence()[0:len(options.fivePrimeAdaptor)]
+        threePrimeAdaptor = sequence.getSequence()[len(sequence.sequence)-len(options.threePrimeAdaptor):]
+
+        # check 5' adaptor
+        fivePrimeDistance = distance(fivePrimeAdaptor, options.fivePrimeAdaptor)
+        # check 3' adaptor
+        threePrimeDistance = len(threePrimeAdaptor)
+        for i in range(options.threePrimeSize, len(threePrimeAdaptor)+1):
+            threePrimeDistance = min(threePrimeDistance, distance(threePrimeAdaptor[-i:], options.threePrimeAdaptor[:i]))
+
+        # sort candidates
+        if fivePrimeDistance > options.fivePrimeDistance:
+            if options.log:
+                logHandle.write("Sequence %s does not start with the right adaptor (%s != %s)\n" % (sequence.getSequence(), fivePrimeAdaptor, options.fivePrimeAdaptor))
+        elif threePrimeDistance > options.threePrimeDistance:
+            if options.log:
+                logHandle.write("Sequence %s does not end with the right adaptor (%s != %s)\n" % (sequence.getSequence(), threePrimeAdaptor, options.threePrimeAdaptor))
+        else:
+            nbRemaining += 1
+            sequence.setSequence(sequence.getSequence()[len(options.fivePrimeAdaptor):len(sequence.getSequence())-len(options.threePrimeAdaptor)])
+            writer.addSequence(sequence)
+
+        progress.inc()
+
+    progress.done()
+
+    if options.log:
+        logHandle.close()
+
+    writer.write()
+
+    print "kept %i over %i (%.f%%)" % (nbRemaining, nbSequences, float(nbRemaining) / nbSequences * 100)
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/changeGffFeatures.sh	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,2 @@
+#!/bin/bash
+sed "s/\t$2\t/\t$3\t/g" $1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/changeTagName.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,90 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Change the name of a tag
+"""
+
+import os
+import random
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.misc.Progress import Progress
+from commons.core.writer.MySqlTranscriptWriter import MySqlTranscriptWriter
+from commons.core.writer.Gff3Writer import Gff3Writer
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Change Tag Name v1.0.1: Change the name of tag of a list of transcripts. [Category: Data Modification]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",       dest="inputFileName",  action="store",                      type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--inputFormat", dest="inputFormat",    action="store",                      type="string", help="format of the input file [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",      dest="outputFileName", action="store",                      type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-t", "--tag",         dest="tag",            action="store",                      type="string", help="name of the tag to change [compulsory] [format: string]")
+    parser.add_option("-n", "--name",        dest="name",           action="store",                      type="string", help="new name for the tag [compulsory] [format: string]")
+    parser.add_option("-y", "--mysql",       dest="mysql",          action="store_true", default=False,                 help="mySQL output [format: bool] [default: false]")    
+    parser.add_option("-v", "--verbosity",   dest="verbosity",      action="store",      default=1,      type="int",    help="trace level [format: int] [default: 1]")
+    parser.add_option("-l", "--log",         dest="log",            action="store_true", default=False,                 help="write a log file [format: bool] [default: false]")
+    (options, args) = parser.parse_args()
+
+    if options.log:
+        logHandle = open("%s.log" % options.outputFileName, "w")
+
+    # create parser and writer(s)
+    parser      = TranscriptContainer(options.inputFileName, options.inputFormat, options.verbosity)
+    tmpFileName = "tmpTranscriptFile%d.gff3" % (random.randint(0, 100000))
+    writer      = Gff3Writer(tmpFileName, options.verbosity)
+    if options.mysql:
+        mysqlWriter = MySqlTranscriptWriter(options.outputFileName, options.verbosity)
+    outputData = {}
+        
+    # process transcripts
+    progress = Progress(parser.getNbTranscripts(), "Printing transcripts %s" % (options.inputFileName), options.verbosity)
+    for transcript in parser.getIterator():
+        if options.tag in transcript.tags:
+            value = transcript.tags[options.tag]
+            del transcript.tags[options.tag]
+            transcript.tags[options.name] = value
+        writer.addTranscript(transcript)
+        if options.mysql:
+            mysqlWriter.addTranscript(transcript)
+        progress.inc()
+    progress.done()
+    parser.transcriptListParser.close()
+
+    writer.write()
+
+    if options.mysql:
+        mysqlWriter.write()
+
+    os.rename(tmpFileName, options.outputFileName)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/cleanGff.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,195 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Clean a GFF file (as given by NCBI or TAIR) and outputs a GFF3 file.
+"""
+
+import os
+import re
+from optparse import OptionParser
+from commons.core.parsing.GffParser import *
+from SMART.Java.Python.misc.RPlotter import *
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+
+count = {}
+
+class ParsedLine(object):
+    def __init__(self, line, cpt):
+        self.line = line
+        self.cpt  = cpt
+        self.parse()
+
+    def parse(self):
+        self.line = self.line.strip()
+        self.splittedLine = self.line.split(None, 8)
+        if len(self.splittedLine) < 9:
+            raise Exception("Line '%s' has less than 9 fields.  Exiting..." % (self.line))
+        self.type = self.splittedLine[2]
+        self.parseOptions()
+        self.getId()
+        self.getParents()
+
+    def parseOptions(self):
+        self.parsedOptions = {}
+        for option in self.splittedLine[8].split(";"):
+            option = option.strip()
+            if option == "": continue
+            posSpace = option.find(" ")
+            posEqual = option.find("=")
+            if posEqual != -1 and (posEqual < posSpace or posSpace == -1):
+                key, value = option.split("=", 1)
+            elif posSpace != -1:
+                key, value = option.split(None, 1)
+            else:
+                key   = "ID"
+                value = option
+            self.parsedOptions[key.strip()] = value.strip(" \"")
+
+    def getId(self):
+        for key in self.parsedOptions:
+            if key.lower() == "id":
+                self.id = self.parsedOptions[key]
+                return
+        if "Parent" in self.parsedOptions:
+            parent = self.parsedOptions["Parent"].split(",")[0]
+            if parent not in count:
+                count[parent] = {}
+            if self.type not in count[parent]:
+                count[parent][self.type] = 0
+            count[parent][self.type] += 1
+            self.id = "%s-%s-%d" % (parent, self.type, count[parent][self.type])
+        else:
+            self.id = "smart%d" % (self.cpt)
+        self.parsedOptions["ID"] = self.id
+
+    def getParents(self):
+        for key in self.parsedOptions:
+            if key.lower() in ("parent", "derives_from"):
+                self.parents = self.parsedOptions[key].split(",")
+                return
+        self.parents = None
+
+    def removeParent(self):
+        for key in self.parsedOptions.keys():
+            if key.lower() in ("parent", "derives_from"):
+                del self.parsedOptions[key]
+
+    def export(self):
+        self.splittedLine[8] = ";".join(["%s=%s" % (key, value) for key, value in self.parsedOptions.iteritems()])
+        return "%s\n" % ("\t".join(self.splittedLine))
+
+
+class CleanGff(object):
+
+    def __init__(self, verbosity = 1):
+        self.verbosity = verbosity
+        self.lines         = {}
+        self.acceptedTypes = []
+        self.parents       = []
+        self.children      = {}
+
+    def setInputFileName(self, name):
+        self.inputFile = open(name)
+        
+    def setOutputFileName(self, name):
+        self.outputFile = open(name, "w")
+
+    def setAcceptedTypes(self, types):
+        self.acceptedTypes = types
+
+    def parse(self):
+        progress = UnlimitedProgress(100000, "Reading input file", self.verbosity)
+        for cpt, line in enumerate(self.inputFile):
+            if not line or line[0] == "#": continue
+            if line[0] == ">": break
+            parsedLine = ParsedLine(line, cpt)
+            if parsedLine.type in self.acceptedTypes:
+                self.lines[parsedLine.id] = parsedLine
+            progress.inc()
+        progress.done()
+
+    def sort(self):
+        progress = Progress(len(self.lines.keys()), "Sorting file", self.verbosity)
+        for line in self.lines.values():
+            parentFound = False
+            if line.parents:
+                for parent in line.parents:
+                    if parent in self.lines:
+                        parentFound = True
+                        if parent in self.children:
+                            self.children[parent].append(line)
+                        else:
+                            self.children[parent] = [line]
+            if not parentFound:
+                line.removeParent()
+                self.parents.append(line)
+            progress.inc()
+        progress.done()
+
+    def write(self):
+        progress = Progress(len(self.parents), "Writing output file", self.verbosity)
+        for line in self.parents:
+            self.writeLine(line)
+            progress.inc()
+        self.outputFile.close()
+        progress.done()
+
+    def writeLine(self, line):
+        self.outputFile.write(line.export())
+        if line.id in self.children:
+            for child in self.children[line.id]:
+                self.writeLine(child)
+
+    def run(self):
+        self.parse()
+        self.sort()
+        self.write()
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Clean GFF v1.0.3: Clean a GFF file (as given by NCBI) and outputs a GFF3 file. [Category: Other]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",                      type="string", help="input file name [compulsory] [format: file in GFF format]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",                      type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-t", "--types",     dest="types",          action="store", default="mRNA,exon", type="string", help="list of comma-separated types that you want to keep [format: string] [default: mRNA,exon]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store", default=1,           type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    cleanGff = CleanGff(options.verbosity)
+    cleanGff.setInputFileName(options.inputFileName)
+    cleanGff.setOutputFileName(options.outputFileName)
+    cleanGff.setAcceptedTypes(options.types.split(","))
+    cleanGff.run()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/cleaning/CleanerChooser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,80 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+from SMART.Java.Python.cleaning.TranscriptListCleaner import TranscriptListCleaner
+from SMART.Java.Python.cleaning.GffCleaner import GffCleaner
+from SMART.Java.Python.cleaning.GtfCleaner import GtfCleaner
+from SMART.Java.Python.cleaning.DefaultCleaner import DefaultCleaner
+
+#Attention!! Do not delete the imports!! They are used to know the type of file format!!!
+
+class CleanerChooser(object):
+	"""
+	A class that finds the correct cleaner
+	@ivar format: the format
+	@type format: string
+	@ivar cleaner: the parser
+	@type cleaner: object
+	@ivar cleanerClass: the class of the parser
+	@type cleanerClass: class
+	@ivar verbosity: verbosity
+	@type verbosity: int		
+	"""
+
+	def __init__(self, verbosity = 0):
+		"""
+		Constructor
+		@param verbosity: verbosity
+		@type verbosity: int
+		"""
+		self.verbosity = verbosity
+	
+
+	def findFormat(self, format):
+		"""
+		Find the correct parser
+		@ivar format: the format
+		@type format: string
+		@return: a cleaner
+		"""
+		for cleanerClass in TranscriptListCleaner.__subclasses__():
+			if cleanerClass != None:
+				if cleanerClass.getFileFormats() != None and format in cleanerClass.getFileFormats():
+					self.cleanerClass = cleanerClass
+					return
+		self.cleanerClass = DefaultCleaner
+
+
+	def getCleaner(self):
+		"""
+		Get the parser previously found
+		@return: the parser
+		"""
+		return self.cleanerClass(self.verbosity)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/cleaning/DefaultCleaner.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,45 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Default cleaner. Does nothing but copying.
+"""
+from SMART.Java.Python.cleaning.TranscriptListCleaner import TranscriptListCleaner
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+
+
+class DefaultCleaner(TranscriptListCleaner):
+
+	def __init__(self, verbosity = 1):
+		super(DefaultCleaner, self).__init__(verbosity)
+
+	def _clean(self):
+		self.outputHandle.write(self.inputHandle.read())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/cleaning/GffCleaner.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,168 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Clean a GFF file (as given by NCBI or TAIR) and outputs a GFF3 file.
+"""
+
+from SMART.Java.Python.cleaning.TranscriptListCleaner import TranscriptListCleaner
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+
+count = {}
+
+class ParsedLine(object):
+	def __init__(self, line, cpt):
+		self.line = line
+		self.cpt  = cpt
+		self.parse()
+
+	def parse(self):
+		self.line = self.line.strip()
+		self.splittedLine = self.line.split(None, 8)
+		if len(self.splittedLine) < 9:
+			raise Exception("Line '%s' has less than 9 fields.  Exiting..." % (self.line))
+		self.type = self.splittedLine[2]
+		self.parseOptions()
+		self.getId()
+		self.getParents()
+
+	def parseOptions(self):
+		self.parsedOptions = {}
+		for option in self.splittedLine[8].split(";"):
+			option = option.strip()
+			if option == "": continue
+			posSpace = option.find(" ")
+			posEqual = option.find("=")
+			if posEqual != -1 and (posEqual < posSpace or posSpace == -1):
+				key, value = option.split("=", 1)
+			elif posSpace != -1:
+				key, value = option.split(None, 1)
+			else:
+				key   = "ID"
+				value = option
+			self.parsedOptions[key.strip()] = value.strip(" \"")
+
+	def getId(self):
+		for key in self.parsedOptions:
+			if key.lower() == "id":
+				self.id = self.parsedOptions[key]
+				return
+		if "Parent" in self.parsedOptions:
+			parent = self.parsedOptions["Parent"].split(",")[0]
+			if parent not in count:
+				count[parent] = {}
+			if self.type not in count[parent]:
+				count[parent][self.type] = 0
+			count[parent][self.type] += 1
+			self.id = "%s-%s-%d" % (parent, self.type, count[parent][self.type])
+		else:
+			self.id = "smart%d" % (self.cpt)
+		self.parsedOptions["ID"] = self.id
+
+	def getParents(self):
+		for key in self.parsedOptions:
+			if key.lower() in ("parent", "derives_from"):
+				self.parents = self.parsedOptions[key].split(",")
+				return
+		self.parents = None
+
+	def removeParent(self):
+		for key in self.parsedOptions.keys():
+			if key.lower() in ("parent", "derives_from"):
+				del self.parsedOptions[key]
+
+	def export(self):
+		self.splittedLine[8] = ";".join(["%s=%s" % (key, value) for key, value in self.parsedOptions.iteritems()])
+		return "%s\n" % ("\t".join(self.splittedLine))
+
+
+class GffCleaner(TranscriptListCleaner):
+
+	def __init__(self, verbosity = 1):
+		super(GffCleaner, self).__init__(verbosity)
+		self.lines		 = {}
+		self.acceptedTypes = ["mRNA", "transcript", "exon"]
+		self.parents	   = []
+		self.children	  = {}
+
+	def getFileFormats():
+		return ["gff", "gff2", "gff3"]
+	getFileFormats = staticmethod(getFileFormats)
+
+	def setAcceptedTypes(self, types):
+		self.acceptedTypes = types
+
+	def parse(self):
+		progress = UnlimitedProgress(100000, "Reading input file", self.verbosity)
+		for cpt, line in enumerate(self.inputHandle):
+			if not line or line[0] == "#": continue
+			if line[0] == ">": break
+			parsedLine = ParsedLine(line, cpt)
+			if self.acceptedTypes == None or parsedLine.type in self.acceptedTypes:
+				self.lines[parsedLine.id] = parsedLine
+			progress.inc()
+		progress.done()
+
+	def sort(self):
+		progress = Progress(len(self.lines.keys()), "Sorting file", self.verbosity)
+		for line in self.lines.values():
+			parentFound = False
+			if line.parents:
+				for parent in line.parents:
+					if parent in self.lines:
+						parentFound = True
+						if parent in self.children:
+							self.children[parent].append(line)
+						else:
+							self.children[parent] = [line]
+			if not parentFound:
+				line.removeParent()
+				self.parents.append(line)
+			progress.inc()
+		progress.done()
+
+	def write(self):
+		progress = Progress(len(self.parents), "Writing output file", self.verbosity)
+		for line in self.parents:
+			self.writeLine(line)
+			progress.inc()
+		progress.done()
+
+	def writeLine(self, line):
+		self.outputHandle.write(line.export())
+		if line.id in self.children:
+			for child in self.children[line.id]:
+				self.writeLine(child)
+
+	def _clean(self):
+		self.parse()
+		self.sort()
+		self.write()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/cleaning/GtfCleaner.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,121 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Clean a GTF file
+"""
+
+import shlex
+from SMART.Java.Python.cleaning.TranscriptListCleaner import TranscriptListCleaner
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+
+count = {}
+
+class ParsedLine(object):
+	def __init__(self, line, cpt):
+		self.line = line
+		self.cpt  = cpt
+		self.parse()
+
+	def parse(self):
+		self.line = self.line.strip()
+		self.splittedLine = self.line.split(None, 8)
+		if len(self.splittedLine) < 9:
+			raise Exception("Line '%s' has less than 9 fields.  Exiting..." % (self.line))
+		self.type = self.splittedLine[2]
+		self.parseOptions()
+
+	def parseOptions(self):
+		self.parsedOptions = {}
+		key   = None
+		value = ""
+		for option in shlex.split(self.splittedLine[8]):
+			option = option.strip()
+			if option == "": continue
+			if key == None:
+				key = option
+			else:
+				endValue = False
+				if option[-1] == ";":
+					endValue = True
+					option.rstrip(";")
+				value = "%s \"%s\"" % (value, option)
+				if endValue:
+					self.parsedOptions[key] = value
+					if key == "transcript_id":
+						self.transcriptId = value
+					key   = None
+					value = ""
+
+	def export(self):
+		return "%s\n" % (self.line)
+
+
+class GtfCleaner(TranscriptListCleaner):
+
+	def __init__(self, verbosity = 1):
+		super(GtfCleaner, self).__init__(verbosity)
+		self.acceptedTypes = ["exon"]
+		self.parents	   = {}
+
+	def getFileFormats():
+		return ["gtf"]
+	getFileFormats = staticmethod(getFileFormats)
+
+	def setAcceptedTypes(self, types):
+		self.acceptedTypes = types
+
+	def parse(self):
+		progress = UnlimitedProgress(100000, "Reading input file", self.verbosity)
+		for cpt, line in enumerate(self.inputHandle):
+			if not line or line[0] == "#": continue
+			parsedLine = ParsedLine(line, cpt)
+			if self.acceptedTypes == None or parsedLine.type in self.acceptedTypes:
+				transcriptId = parsedLine.transcriptId
+				if transcriptId not in self.parents:
+					self.parents[parsedLine.transcriptId] = [parsedLine]
+				else:
+					self.parents[parsedLine.transcriptId].append(parsedLine)
+			progress.inc()
+		progress.done()
+
+	def write(self):
+		progress = Progress(len(self.parents.keys()), "Writing output file", self.verbosity)
+		for parent in sorted(self.parents.keys()):
+			for line in self.parents[parent]:
+				self.outputHandle.write(line.export())
+			progress.inc()
+		progress.done()
+
+	def _clean(self):
+		self.parse()
+		self.write()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/cleaning/TranscriptListCleaner.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,63 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+from SMART.Java.Python.structure.TranscriptList import TranscriptList
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+
+class TranscriptListCleaner(object):
+	"""A (quite generic) class that cleans a file containing transcripts"""
+
+	def __init__(self, verbosity = 0):
+		self.verbosity = verbosity
+
+	def setInputFileName(self, fileName):
+		try:
+			self.inputHandle = open(fileName)
+		except IOError:
+			raise Exception("Error! Transcript file '%s' does not exist! Exiting..." % (self.fileName))
+
+	def setOutputFileName(self, fileName):
+		try:
+			self.outputHandle = open(fileName, "w")
+		except IOError:
+			raise Exception("Error! Transcript file '%s' does not exist! Exiting..." % (self.fileName))
+
+	def getFileFormats():
+		pass
+	getFileFormats = staticmethod(getFileFormats)
+
+	def close(self):
+		self.inputHandle.close()
+		self.outputHandle.close()
+
+	def clean(self):
+		self._clean()
+		self.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/clusterize.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,165 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from commons.core.writer.WriterChooser import WriterChooser
+"""Clusterize a set of transcripts"""
+
+import os
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.ncList.NCListFilePickle import NCListFileUnpickle
+from SMART.Java.Python.ncList.FileSorter import FileSorter
+from SMART.Java.Python.misc.Progress import Progress
+
+class Clusterize(object):
+        
+    def __init__(self, verbosity):
+        self.normalize         = False
+        self.presorted         = False
+        self.distance          = 1
+        self.colinear          = False
+        self.nbWritten         = 0
+        self.nbMerges          = 0
+        self.verbosity         = verbosity
+        self.splittedFileNames = {}
+
+    def __del__(self):
+        for fileName in self.splittedFileNames.values():
+            os.remove(fileName)
+
+    def setInputFile(self, fileName, format):
+        parserChooser = ParserChooser(self.verbosity)
+        parserChooser.findFormat(format)
+        self.parser = parserChooser.getParser(fileName)
+        self.sortedFileName = "%s_sorted.pkl" % (os.path.splitext(fileName)[0])
+
+    def setOutputFileName(self, fileName, format="gff3", title="S-MART", feature="transcript", featurePart="exon"):
+        writerChooser = WriterChooser()
+        writerChooser.findFormat(format)
+        self.writer = writerChooser.getWriter(fileName)
+        self.writer.setTitle(title)
+        self.writer.setFeature(feature)
+        self.writer.setFeaturePart(featurePart)
+
+    def setDistance(self, distance):
+        self.distance = distance
+
+    def setColinear(self, colinear):
+        self.colinear = colinear
+
+    def setNormalize(self, normalize):
+        self.normalize = normalize
+        
+    def setPresorted(self, presorted):
+        self.presorted = presorted
+
+    def _sortFile(self):
+        fs = FileSorter(self.parser, self.verbosity-4)
+        fs.perChromosome(True)
+        fs.setPresorted(self.presorted)
+        fs.setOutputFileName(self.sortedFileName)
+        fs.sort()
+        self.splittedFileNames       = fs.getOutputFileNames()
+        self.nbElementsPerChromosome = fs.getNbElementsPerChromosome()
+        self.nbElements              = fs.getNbElements()
+        
+    def _iterate(self, chromosome):
+        progress    = Progress(self.nbElementsPerChromosome[chromosome], "Checking chromosome %s" % (chromosome), self.verbosity)
+        transcripts = []
+        parser      = NCListFileUnpickle(self.splittedFileNames[chromosome], self.verbosity)
+        for newTranscript in parser.getIterator():
+            newTranscripts = []
+            for oldTranscript in transcripts:
+                if self._checkOverlap(newTranscript, oldTranscript):
+                    self._merge(newTranscript, oldTranscript)
+                elif self._checkPassed(newTranscript, oldTranscript):
+                    self._write(oldTranscript)
+                else:
+                    newTranscripts.append(oldTranscript)
+            newTranscripts.append(newTranscript)
+            transcripts = newTranscripts
+            progress.inc()
+        for transcript in transcripts:
+            self._write(transcript)
+        progress.done()
+
+    def _merge(self, transcript1, transcript2):
+        self.nbMerges += 1
+        transcript2.setDirection(transcript1.getDirection())
+        transcript1.merge(transcript2)
+
+    def _write(self, transcript):
+        self.nbWritten += 1
+        self.writer.addTranscript(transcript)
+
+    def _checkOverlap(self, transcript1, transcript2):
+        if self.colinear and transcript1.getDirection() != transcript2.getDirection():
+            return False
+        if transcript1.getDistance(transcript2) > self.distance:
+            return False
+        return True
+
+    def _checkPassed(self, transcript1, transcript2):
+        return (transcript1.getDistance(transcript2) > self.distance)
+
+    def run(self):
+        self._sortFile()
+        for chromosome in sorted(self.splittedFileNames.keys()):
+            self._iterate(chromosome)
+        self.writer.close()
+        if self.verbosity > 0:
+            print "# input:   %d" % (self.nbElements)
+            print "# written: %d (%d%% overlaps)" % (self.nbWritten, 0 if (self.nbElements == 0) else ((float(self.nbWritten) / self.nbElements) * 100))
+            print "# merges:  %d" % (self.nbMerges)
+        
+
+if __name__ == "__main__":
+    description = "Clusterize v1.0.3: clusterize the data which overlap. [Category: Merge]"
+    
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",                     type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",         action="store",                     type="string", help="format of file [format: transcript file format]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",                     type="string", help="output file [compulsory] [format: output file in transcript format given by -u]")
+    parser.add_option("-u", "--outputFormat", dest="outputFormat", action="store",     default="gff",             type="string", help="output file format [format: transcript file format]")
+    parser.add_option("-c", "--colinear",  dest="colinear",       action="store_true", default=False,                help="merge colinear transcripts only [format: bool] [default: false]")
+    parser.add_option("-d", "--distance",  dest="distance",       action="store",      default=0,     type="int",    help="max. distance between two transcripts to be merged [format: int] [default: 0]")
+    parser.add_option("-n", "--normalize", dest="normalize",      action="store_true", default=False,                help="normalize the number of reads per cluster by the number of mappings per read [format: bool] [default: false]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [format: int] [default: 1]")
+    (options, args) = parser.parse_args()
+        
+    c = Clusterize(options.verbosity)
+    c.setInputFile(options.inputFileName, options.format)
+    c.setOutputFileName(options.outputFileName, options.outputFormat)
+    c.setColinear(options.colinear)
+    c.setDistance(options.distance)
+    c.setNormalize(options.normalize)
+    c.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/clusterizeBySlidingWindows.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,344 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+from commons.core.writer.WriterChooser import WriterChooser
+"""
+Cluster the data into regions (defined by size and overlap with next region) and keep only highest peaks.
+"""
+
+import os, os.path
+from optparse import OptionParser
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from SMART.Java.Python.misc.Progress import Progress
+from commons.core.writer.Gff3Writer import Gff3Writer
+
+class ClusterizeBySlidingWindows(object):
+
+    def __init__(self, verbosity = 0):
+        self.verbosity = verbosity
+        self.strands   = (0, )
+        self.normalize = False
+        self.plot      = None
+        self.excel     = None
+        self.outputFileName = ''
+        self.defaultValue = None
+
+    def __del__(self):
+        pass
+
+    def setInputFile(self, fileName, format):
+        self.parser = TranscriptContainer(fileName, format, self.verbosity)
+
+    def setOutputFileName(self, fileName, format="gff", title="S-MART", feature="transcript", featurePart="exon"):
+        writerChooser = WriterChooser(self.verbosity)
+        writerChooser.findFormat(format)
+        self.writer = writerChooser.getWriter(fileName)
+        self.writer.setTitle(title)
+        self.writer.setFeature(feature)
+        self.writer.setFeaturePart(featurePart)
+#        self.outputFileName = fileName
+#        self.outputFormat = format
+
+    def setWindowSize(self, size):
+        self.size = size
+
+    def setWindowOverlap(self, overlap):
+        self.overlap = overlap
+
+    def setTag(self, tag):
+        self.tag = tag
+
+    def setOperation(self, operation):
+        self.operation = operation
+
+    def setBothStrands(self, bothStrands):
+        if bothStrands:
+            self.strands = (-1, 1)
+
+    def setNormalize(self, normalize):
+        self.normalize = normalize
+
+    def setPlot(self, plot):
+        self.plot = plot
+
+    def setExcel(self, excel):
+        self.excel = excel
+
+    def setOutputTag(self, tag):
+        self.outputTagName = tag
+        
+    def setDefaultValue(self, defaultValue):
+        self.defaultValue = defaultValue
+
+    def checkOptions(self):
+#        if self.operation != None:
+#            raise Exception("Trying to combine the values without specifying tag! Aborting...")
+        if self.operation != None and self.operation not in ("sum", "avg", "med", "min", "max"):
+            raise Exception("Do not understand tag '%s'! Aborting..." % (self.operation))
+
+    def getChromosomeSizes(self):
+        self.sizes = {}
+        progress = Progress(self.parser.getNbTranscripts(), "Getting sizes in genome", self.verbosity)
+        for transcript in self.parser.getIterator():
+            self.sizes[transcript.getChromosome()] = max(transcript.getStart(), self.sizes.get(transcript.getChromosome(), 0))
+            progress.inc()
+        progress.done()
+
+    def getBinsFromPos(self, pos):
+        bin = (pos - 1) / (self.size - self.overlap)
+        if bin >= 1 and pos <= bin * (self.size - self.overlap) + self.overlap:
+            return (bin - 1, bin)
+        return (bin, )
+
+    def getPosFromBin(self, bin):
+        return (bin * (self.size - self.overlap) + 1, bin * (self.size - self.overlap) + self.size)
+
+    def initializeBins(self):
+        self.binsPerStrand        = {}
+        self.sumsPerStrand        = {}
+        self.valuesPerStrand      = {}
+        self.toBePlottedPerStrand = {}
+        for strand in self.strands:
+            self.binsPerStrand[strand]        = {}
+            self.sumsPerStrand[strand]        = {}
+            self.valuesPerStrand[strand]      = {}
+            self.toBePlottedPerStrand[strand] = {}
+            for chromosome in self.sizes:
+                binRange = range(self.getBinsFromPos(self.sizes[chromosome])[-1] + 1)
+                self.binsPerStrand[strand][chromosome]        = dict([[i, 0]   for i in binRange])
+                self.sumsPerStrand[strand][chromosome]        = dict([[i, 0.0] for i in binRange])
+                self.valuesPerStrand[strand][chromosome]      = dict([[i, []]  for i in binRange])
+                self.toBePlottedPerStrand[strand][chromosome] = dict([[i, 0] for i in binRange])
+
+    def getNbElements(self, transcript):
+        nbOccurrences = 1 if "nbOccurrences" not in transcript.getTagNames() else transcript.getTagValue("nbOccurrences")
+        nbElements    = 1 if "nbElements"    not in transcript.getTagNames() else transcript.getTagValue("nbElements")
+        nbOccurrences = float(nbOccurrences)
+        nbElements = float(nbElements)
+        nbElements /= float(nbOccurrences)
+        return nbElements
+
+    def setBins(self):
+        progress = Progress(self.parser.getNbTranscripts(), "Setting bins", self.verbosity)
+        for transcript in self.parser.getIterator():
+            nbElements = self.getNbElements(transcript)
+            strand     = transcript.getDirection() if len(self.strands) == 2 else 0
+            for bin in self.getBinsFromPos(transcript.getStart()):
+                self.binsPerStrand[strand][transcript.getChromosome()][bin] += nbElements
+                if self.tag != None:
+                    if self.tag not in transcript.getTagNames():
+                        if self.defaultValue is None:
+                            raise Exception("Tag %s undefined in transcript %s" % (self.tag, transcript))
+                        value = self.defaultValue
+                    else:
+                        value = float(transcript.getTagValue(self.tag))
+                    self.sumsPerStrand[strand][transcript.getChromosome()][bin] += value
+                    self.valuesPerStrand[strand][transcript.getChromosome()][bin].append(value)
+            progress.inc()
+        progress.done()
+
+    def aggregateData(self):
+        if self.operation == "sum":
+            self.computeSumData()
+        elif self.operation == "avg":
+            self.computeAvgData()
+        elif self.operation == "med":
+            self.computeMedData()
+        elif self.operation == "min":
+            self.computeMinData()
+        elif self.operation == "max":
+            self.computeMaxData()
+        elif self.operation == "GCpercent":
+            self.computeGCPercent()
+        else:
+            self.toBePlottedPerStrand = self.binsPerStrand
+
+    def computeSumData(self):
+        self.toBePlottedPerStrand = self.sumsPerStrand
+
+    def computeAvgData(self):
+        for strand in self.strands:
+            for chromosome in self.binsPerStrand[strand]:
+                for bin in self.binsPerStrand[strand][chromosome]:
+                    if self.binsPerStrand[strand][chromosome][bin] != 0:
+                        self.toBePlottedPerStrand[strand][chromosome][bin] = float(self.sumsPerStrand[strand][chromosome][bin]) / self.binsPerStrand[strand][chromosome][bin]
+
+    def computeMedData(self):
+        for strand in self.strands:
+            for chromosome in self.binsPerStrand[strand]:
+                for bin in self.binsPerStrand[strand][chromosome]:
+                    if self.valuesPerStrand[strand][chromosome][bin]:
+                        self.valuesPerStrand[strand][chromosome][bin].sort()
+                        size = len(self.valuesPerStrand[strand][chromosome][bin])
+                        if size % 2 == 1:
+                            self.toBePlottedPerStrand[strand][chromosome][bin] = self.valuesPerStrand[strand][chromosome][bin][(size - 1) / 2]
+                        else:
+                            self.toBePlottedPerStrand[strand][chromosome][bin] = (self.valuesPerStrand[strand][chromosome][bin][size / 2 - 1] + self.valuesPerStrand[strand][chromosome][bin][size / 2]) / 2.0
+
+    def computeMinData(self):
+        for strand in self.strands:
+            for chromosome in self.binsPerStrand[strand]:
+                for bin in self.binsPerStrand[strand][chromosome]:
+                    if self.valuesPerStrand[strand][chromosome][bin]:
+                        self.toBePlottedPerStrand[strand][chromosome][bin] = min(self.valuesPerStrand[strand][chromosome][bin])
+
+    def computeMaxData(self):
+        for strand in self.strands:
+            for chromosome in self.binsPerStrand[strand]:
+                for bin in self.binsPerStrand[strand][chromosome]:
+                    if self.valuesPerStrand[strand][chromosome][bin]:
+                        self.toBePlottedPerStrand[strand][chromosome][bin] = max(self.valuesPerStrand[strand][chromosome][bin])
+                        
+    def computeGCPercent(self):
+        for strand in self.strands:
+            for chromosome in self.binsPerStrand[strand]:
+                for bin in self.binsPerStrand[strand][chromosome]:
+                    if self.valuesPerStrand[strand][chromosome][bin]:
+                        subSequence = self.valuesPerStrand[strand][chromosome][bin]
+                        NPercent = 100 * (subSequence.countNt("N") / float(subSequence.getSize()))
+                        if NPercent >= 50:
+                            currentGCpercent = "NA"
+                        else:
+                            currentGCpercent = subSequence.getGCpercentageInSequenceWithoutCountNInLength()
+                        
+                        self.toBePlottedPerStrand[strand][chromosome][bin] = currentGCpercent
+        #TODO: see if a map method could be used for the various "compute" methods 
+        #return currentGCpercent, NPercent
+        
+    def plotData(self):
+        if self.plot != None:
+            for strand in self.strands:
+                adjunct = ""
+                if strand != 0:
+                    adjunct = "Strand%d" % (strand)
+                for chromosome in self.toBePlottedPerStrand[strand]:
+                    if len(self.toBePlottedPerStrand[strand][chromosome].keys()) > 0:
+                        plotter = RPlotter(self.plot, self.verbosity)
+                        plotter.setFill(0)
+                        plotter.addLine(self.toBePlottedPerStrand[strand][chromosome], chromosome)
+                        plotter.plot()
+
+    def writeExcel(self):
+        if self.excel != None:
+            excelFile = open(self.excel, "w")
+            for strand in self.strands:
+                maxBin = max([max(self.toBePlottedPerStrand[strand][chromosome].keys()) for chromosome in self.binsPerStrand[strand]])
+                for bin in range(0, maxBin + 1):
+                    excelFile.write(",%d-%d" % self.getPosFromBin(bin))
+                excelFile.write("\n")
+                for chromosome in self.toBePlottedPerStrand[strand]:
+                    excelFile.write("%s" % (chromosome))
+                    for bin in self.toBePlottedPerStrand[strand][chromosome]:
+                        excelFile.write(",%f" % (self.toBePlottedPerStrand[strand][chromosome][bin]))
+                    excelFile.write("\n")
+            excelFile.close()
+
+    def printRegions(self):
+        cpt           = 1
+        tagOp         = "nb"
+        tagName       = "Elements"
+        outputTagName = "nbElements"
+        if self.operation != None:
+            tagOp = self.operation.lower()
+        if self.tag != None:
+            tagName = self.tag.title()
+        if self.outputTagName != None:
+            outputTagName = self.outputTagName
+            
+     
+        #writer = Gff3Writer(self.outputFileName, self.verbosity)
+        
+        for strand in self.strands:
+            for chromosome in self.toBePlottedPerStrand[strand]:
+                for bin in self.toBePlottedPerStrand[strand][chromosome]:
+                    transcript = Transcript()
+                    transcript.setName("region%d" % cpt)
+                    transcript.setChromosome(chromosome)
+                    transcript.setStart(self.getPosFromBin(bin)[0])
+                    transcript.setEnd(self.getPosFromBin(bin)[1])
+                    transcript.setDirection(1 if strand == 0 else strand)
+                    transcript.setTagValue(outputTagName, self.binsPerStrand[strand][chromosome][bin])
+                    transcript.setTagValue("%s%s" % (tagOp, tagName), str(self.toBePlottedPerStrand[strand][chromosome][bin]))
+                    self.writer.addTranscript(transcript)
+                    cpt += 1
+        self.writer.close()
+
+    def run(self):
+        self.checkOptions()
+        self.getChromosomeSizes()
+        self.initializeBins()
+        self.setBins()
+        self.aggregateData()
+        if self.excel:
+            self.writeExcel()
+        if self.plot:
+            self.plotData()
+        self.printRegions()
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Clusterize by Sliding Windows v1.0.1: Produces a GFF3 file that clusters a list of transcripts using a sliding window. [Category: Sliding Windows]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",       dest="inputFileName",  action="store",                     type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--inputFormat", dest="inputFormat",    action="store",                     type="string", help="format of the input file [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",      dest="outputFileName", action="store",                     type="string", help="output file [compulsory] [format: output file in transcript format given by -u]")
+    parser.add_option("-u", "--outputFormat", dest="outputFormat",  action="store",     default="gff",  type="string", help="format of the output file [format: transcript file format]")
+    parser.add_option("-s", "--size",        dest="size",           action="store",                     type="int",    help="size of the regions [compulsory] [format: int]")
+    parser.add_option("-e", "--overlap",     dest="overlap",        action="store",                     type="int",    help="overlap between two consecutive regions [compulsory] [format: int]")
+    parser.add_option("-m", "--normalize",   dest="normalize",      action="store_true", default=False,                help="normalize the number of reads per cluster by the number of mappings per read [format: bool] [default: false]")
+    parser.add_option("-g", "--tag",         dest="tag",            action="store",      default=None,  type="string", help="use a given tag as input (instead of summing number of features) [format: string]")    
+    parser.add_option("-r", "--operation",   dest="operation",      action="store",      default=None,  type="string", help="combine tag value with given operation [format: choice (sum, avg, med, min, max)]")
+    parser.add_option("-d", "--defaultValue",dest="defaultValue",   action="store",                     type="float",    help="default value for input tag [format: float]")
+    parser.add_option("-w", "--write",       dest="writeTag",       action="store",      default=None,  type="string", help="print the result in the given tag (default usually is 'nbElements') [format: string]")    
+    parser.add_option("-2", "--strands",     dest="strands",        action="store_true", default=False,                help="consider the two strands separately [format: bool] [default: false]")
+    parser.add_option("-p", "--plot",        dest="plot",           action="store",      default=None,  type="string", help="plot regions to the given file [format: output file in PNG format]")
+    parser.add_option("-x", "--excel",       dest="excel",          action="store",      default=None,  type="string", help="write an Excel file to the given file [format: output file in Excel format]")
+    parser.add_option("-v", "--verbosity",   dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [format: int] [default: 1]")
+    (options, args) = parser.parse_args()
+
+    cbsw = ClusterizeBySlidingWindows(options.verbosity)
+    cbsw.setInputFile(options.inputFileName, options.inputFormat)
+    cbsw.setOutputFileName(options.outputFileName, options.outputFormat)
+    cbsw.setWindowSize(options.size)
+    cbsw.setWindowOverlap(options.overlap)
+    cbsw.setTag(options.tag)
+    cbsw.setDefaultValue(options.defaultValue)
+    cbsw.setOperation(options.operation)
+    cbsw.setOutputTag(options.writeTag)
+    cbsw.setBothStrands(options.strands)
+    cbsw.setPlot(options.plot)
+    cbsw.setExcel(options.excel)
+    cbsw.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/compareOverlapping.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,126 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Compare overlap of two transcript lists"""
+import sys
+import os
+from optparse import OptionParser
+from SMART.Java.Python.misc import Utils
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.structure.TranscriptListsComparator import TranscriptListsComparator
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from commons.core.writer.Gff3Writer import Gff3Writer
+
+class CompareOverlapping(object):
+
+    def __init__(self):
+        self._options = None
+
+
+    def setAttributesFromCmdLine(self):
+        description = "Compare Overlapping v1.0.3: Get the data which overlap with a reference set. [Category: Data Comparison]"
+
+        parser = OptionParser(description = description)
+        parser.add_option("-i", "--input1",           dest="inputFileName1", action="store",                     type="string", help="input file 1 [compulsory] [format: file in transcript format given by -f]")
+        parser.add_option("-f", "--format1",          dest="format1",        action="store",                     type="string", help="format of file 1 [compulsory] [format: transcript file format]")
+        parser.add_option("-j", "--input2",           dest="inputFileName2", action="store",                     type="string", help="input file 2 [compulsory] [format: file in transcript format given by -g]")
+        parser.add_option("-g", "--format2",          dest="format2",        action="store",                     type="string", help="format of file 2 [compulsory] [format: transcript file format]")
+        parser.add_option("-o", "--output",           dest="output",         action="store",      default=None,  type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+        parser.add_option("-S", "--start1",           dest="start1",         action="store",      default=None,  type="int",    help="only consider the n first nucleotides of the transcripts in file 1 (do not use it with -U) [format: int]")
+        parser.add_option("-s", "--start2",           dest="start2",         action="store",      default=None,  type="int",    help="only consider the n first nucleotides of the transcripts in file 2 (do not use it with -u) [format: int]")
+        parser.add_option("-U", "--end1",             dest="end1",           action="store",      default=None,  type="int",    help="only consider the n last nucleotides of the transcripts in file 1 (do not use it with -S) [format: int]")
+        parser.add_option("-u", "--end2",             dest="end2",           action="store",      default=None,  type="int",    help="only consider the n last nucleotides of the transcripts in file 2 (do not use it with -s) [format: int]")
+        parser.add_option("-t", "--intron",           dest="introns",        action="store_true", default=False,                help="also report introns [format: bool] [default: false]")
+        parser.add_option("-E", "--5primeExtension1", dest="fivePrime1",     action="store",      default=None,  type="int",    help="extension towards 5' in file 1 [format: int]")
+        parser.add_option("-e", "--5primeExtension2", dest="fivePrime2",     action="store",      default=None,  type="int",    help="extension towards 5' in file 2 [format: int]")
+        parser.add_option("-N", "--3primeExtension1", dest="threePrime1",    action="store",      default=None,  type="int",    help="extension towards 3' in file 1 [format: int]")
+        parser.add_option("-n", "--3primeExtension2", dest="threePrime2",    action="store",      default=None,  type="int",    help="extension towards 3' in file 2 [format: int]")
+        parser.add_option("-c", "--colinear",         dest="colinear",       action="store_true", default=False,                help="colinear only [format: bool] [default: false]")
+        parser.add_option("-a", "--antisense",        dest="antisense",      action="store_true", default=False,                help="antisense only [format: bool] [default: false]")
+        parser.add_option("-d", "--distance",         dest="distance",       action="store",      default=None,  type="int",    help="accept some distance between query and reference [format: int]")
+        parser.add_option("-k", "--included",         dest="included",       action="store_true", default=False,                help="keep only elements from file 1 which are included in an element of file 2 [format: bool] [default: false]")
+        parser.add_option("-K", "--including",        dest="including",      action="store_true", default=False,                help="keep only elements from file 2 which are included in an element of file 1 [format: bool] [default: false]")
+        parser.add_option("-m", "--minOverlap",       dest="minOverlap",     action="store",      default=1,     type="int",    help="minimum number of nucleotides overlapping to declare an overlap [format: int] [default: 1]")
+        parser.add_option("-p", "--pcOverlap",        dest="pcOverlap",      action="store",      default=None,  type="int",    help="minimum percentage of nucleotides to overlap to declare an overlap [format: int]")
+        parser.add_option("-O", "--notOverlapping",   dest="notOverlapping", action="store_true", default=False,                help="also output not overlapping data [format: bool] [default: false]")
+        parser.add_option("-x", "--exclude",          dest="exclude",        action="store_true", default=False,                help="invert the match [format: bool] [default: false]")
+        parser.add_option("-v", "--verbosity",        dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [format: int]")
+        parser.add_option("-l", "--log",              dest="log",            action="store_true", default=False,                help="write a log file [format: bool] [default: false]")
+        (self._options, args) = parser.parse_args()
+
+
+    def run(self):             
+        logHandle = None
+        if self._options.log:
+            logHandle = open(self._options.output, "w")
+
+        transcriptContainer1 = TranscriptContainer(self._options.inputFileName1, self._options.format1, self._options.verbosity)
+        transcriptContainer2 = TranscriptContainer(self._options.inputFileName2, self._options.format2, self._options.verbosity)
+        writer               = TranscriptWriter(self._options.output, "gff3", self._options.verbosity)
+
+        transcriptListComparator = TranscriptListsComparator(logHandle, self._options.verbosity)
+        transcriptListComparator.restrictToStart(transcriptListComparator.QUERY, self._options.start1)
+        transcriptListComparator.restrictToStart(transcriptListComparator.REFERENCE, self._options.start2)
+        transcriptListComparator.restrictToEnd(transcriptListComparator.QUERY, self._options.end1)
+        transcriptListComparator.restrictToEnd(transcriptListComparator.REFERENCE, self._options.end2)
+        transcriptListComparator.extendFivePrime(transcriptListComparator.QUERY, self._options.fivePrime1)
+        transcriptListComparator.extendFivePrime(transcriptListComparator.REFERENCE, self._options.fivePrime2)
+        transcriptListComparator.extendThreePrime(transcriptListComparator.QUERY, self._options.threePrime1)
+        transcriptListComparator.extendThreePrime(transcriptListComparator.REFERENCE, self._options.threePrime2)
+        transcriptListComparator.acceptIntrons(transcriptListComparator.QUERY, self._options.introns)
+        transcriptListComparator.acceptIntrons(transcriptListComparator.REFERENCE, self._options.introns)
+        transcriptListComparator.getAntisenseOnly(self._options.antisense)
+        transcriptListComparator.getColinearOnly(self._options.colinear)
+        transcriptListComparator.getInvert(self._options.exclude)
+        transcriptListComparator.setMaxDistance(self._options.distance)
+        transcriptListComparator.setMinOverlap(self._options.minOverlap)
+        transcriptListComparator.setPcOverlap(self._options.pcOverlap)
+        transcriptListComparator.setIncludedOnly(self._options.included)
+        transcriptListComparator.setIncludingOnly(self._options.including)
+        transcriptListComparator.includeNotOverlapping(self._options.notOverlapping)
+        transcriptListComparator.computeOdds(True)
+        transcriptListComparator.setInputTranscriptContainer(transcriptListComparator.QUERY, transcriptContainer1)
+        transcriptListComparator.setInputTranscriptContainer(transcriptListComparator.REFERENCE, transcriptContainer2)
+        transcriptListComparator.setOutputWriter(writer)
+        transcriptListComparator.compareTranscriptList()
+
+        if self._options.log:
+            logHandle.close()
+
+        if not self._options.exclude:
+            odds = transcriptListComparator.getOdds()
+            if self._options.verbosity > 0 and odds:
+                print "min/avg/med/max transcripts: %d/%.2f/%.1f/%d" % Utils.getMinAvgMedMax(odds)
+                
+if __name__ == "__main__":
+    icompareOverlapping = CompareOverlapping()
+    icompareOverlapping.setAttributesFromCmdLine()
+    icompareOverlapping.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/convertTranscriptFile.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,115 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Read a transcript file and convert it to another format
+"""
+
+import os, re
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.misc.Progress import Progress
+
+
+class ConvertTranscriptFile(object):
+    def __init__(self,inputFileName="", inputFormat ="", outputFileName="", outputFormat="", name="", sequenceFileName=None, strands=False, galaxy=False, feature=None, featurePart=None, verbosity=1):
+        self.inputFileName = inputFileName
+        self.inputFormat = inputFormat
+        self.outputFileName = outputFileName
+        self.outputFormat = outputFormat
+        self.name = name
+        self.sequenceFileName = sequenceFileName
+        self.strands = strands
+        self.galaxy = galaxy
+
+        self.feature=feature
+        self.featurePart=featurePart
+        
+        self.verbosity = verbosity
+         
+    def setAttributesFromCmdLine(self):
+        description = "Convert Transcript File v1.0.3: Convert a file from a format to another. [Category: Conversion]"
+        parser = OptionParser(description = description)
+        parser.add_option("-i", "--input",        dest="inputFileName",    action="store",                       type="string", help="input file [compulsory] [format: file in format given by -f]")
+        parser.add_option("-f", "--inputFormat",  dest="inputFormat",      action="store",                       type="string", help="format of the input file [compulsory] [format: transcript or mapping file format]")
+        parser.add_option("-o", "--output",       dest="outputFileName",   action="store",                       type="string", help="output file [compulsory] [format: output file in format given by -g]")
+        parser.add_option("-g", "--outputFormat", dest="outputFormat",     action="store",                       type="string", help="format of the output file [compulsory] [format: transcript file format]")
+        parser.add_option("-n", "--name",         dest="name",             action="store",      default="SMART", type="string", help="name for the transcripts [format: string] [default: SMART]")
+        parser.add_option("-s", "--sequences",    dest="sequenceFileName", action="store",      default=None,    type="string", help="give the corresponding Multi-Fasta file (useful for EMBL format) [format: string]")
+        parser.add_option("-t", "--strands",      dest="strands",          action="store_true", default=False,                  help="consider the 2 strands as different (only useful for writing WIG files) [format: bool] [default: False]")
+        parser.add_option("-v", "--verbosity",    dest="verbosity",        action="store",      default=1,       type="int",    help="trace level [format: int] [default: 1]")
+        parser.add_option("-G", "--galaxy",       dest="galaxy",           action="store_true", default=False,                  help="used for galaxy [format: bool] [default: False]")
+        (options, args) = parser.parse_args()
+        self._setAttributesFromOptions(options)
+
+    def _setAttributesFromOptions(self, options):
+        self.inputFileName = options.inputFileName
+        self.inputFormat = options.inputFormat
+        self.outputFileName = options.outputFileName
+        self.outputFormat = options.outputFormat
+        self.name = options.name  
+        self.sequenceFileName = options.sequenceFileName
+        self.strands = options.strands
+        self.galaxy =  options.galaxy
+        self.verbosity = options.verbosity
+
+    def run(self):
+        # create parser
+        parser = TranscriptContainer(self.inputFileName, self.inputFormat, self.verbosity)
+        # create writer
+        writer = TranscriptWriter(self.outputFileName, self.outputFormat, self.verbosity)
+        # connect parser and writer
+        writer.setContainer(parser)
+            
+        if self.name != None:
+            writer.setTitle(self.name)
+        if self.feature != None:
+            writer.setFeature(self.feature)
+        if self.featurePart != None:
+            writer.setFeaturePart(self.featurePart)
+        if self.sequenceFileName != None:
+            writer.addSequenceFile(self.sequenceFileName)
+            
+        nbItems = 0
+        if self.verbosity > 0:
+            nbItems = parser.getNbItems()
+            print "%i items found" % (nbItems)
+    
+        if self.strands:
+            writer.setStrands(True)
+        # convert
+        writer.write()
+        writer.close()
+
+if __name__ == "__main__":
+    iConvertTranscriptFile = ConvertTranscriptFile()
+    iConvertTranscriptFile.setAttributesFromCmdLine()
+    iConvertTranscriptFile.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/coordinatesToSequence.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,64 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Convert a list of coordinates to sequences"""
+
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import FastaParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from commons.core.writer.FastaWriter import FastaWriter
+from SMART.Java.Python.misc.Progress import Progress
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Coordinates to Sequences v1.0.2: Extract the sequences from a list of coordinates. [Category: Conversion]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input", dest="inputFileName", action="store", type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format", dest="format", action="store", type="string", help="format of file [compulsory] [format: transcript file format]")
+    parser.add_option("-s", "--sequences", dest="sequences", action="store",  type="string", help="file that contains the sequences [compulsory] [format: file in FASTA format]")
+    parser.add_option("-o", "--output", dest="outputFileName", action="store",  default=None, type="string", help="output file (FASTA format) [format: output file in FASTA format]")
+    parser.add_option("-v", "--verbosity", dest="verbosity", action="store", default=1, type="int", help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    # create parser
+    parser = TranscriptContainer(options.inputFileName, options.format, options.verbosity) 
+
+    sequenceParser = FastaParser(options.sequences, options.verbosity)
+
+    writer = FastaWriter(options.outputFileName, options.verbosity)
+    progress = Progress(parser.getNbTranscripts(), "Reading %s" % (options.inputFileName), options.verbosity)
+    for transcript in parser.getIterator():
+        sequence = transcript.extractSequence(sequenceParser)
+        writer.addSequence(sequence)
+        progress.inc()
+    progress.done()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/fastqToFasta.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,96 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Convert a FASTQ file to a FASTA file"""
+
+import os
+import sys
+from optparse import OptionParser
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from SMART.Java.Python.misc.Progress import Progress
+from math import *
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "FastQ to FastA v1.0.1: Convert a FastQ file into a FastA file. [Category: Personnal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input", dest="inputFileName", action="store", type="string", help="input file [compulsory] [format: file in FASTQ format]")
+    parser.add_option("-o", "--output", dest="outputFileName", action="store", type="string", help="output file [compulsory] [format: output file in FASTA format]")
+    parser.add_option("-v", "--verbosity", dest="verbosity", action="store", default=1, type="int", help="trace level [default: 1] [format: int]")
+    (options, args) = parser.parse_args()
+
+    inputFile = open(options.inputFileName)
+    outputFastaFile = open(options.outputFileName, "w")
+    
+    inSequenceName = False
+    inQualityName = False
+    inSequence = False
+    inQuality = True
+    sequenceName = None
+    lineNumber = 1
+    
+    for line in inputFile:
+
+        if inSequenceName:
+            inSequence = True
+            inSequenceName = False
+        elif inQualityName:
+            inQuality = True
+            inQualityName = False
+        elif inSequence:
+            inQualityName = True
+            inSequence = False
+        elif inQuality:
+            inSequenceName = True
+            inQuality = False
+        else:
+            sys.exit("Error! Do not in which section I am (line is %d)" % (lineNumber))
+
+        line = line.strip()
+        if inSequenceName:
+            if line[0] != "@":
+                sys.exit("Error! Sequence name '%s' does not start with '@' (line is %d)" % (line, lineNumber))
+            sequenceName = line[1:]
+            outputFastaFile.write(">%s\n" % (sequenceName))
+        elif inQualityName:
+            if line[0] != "+":
+                sys.exit("Error! Quality name '%s' does not start with '+' (line is %d)" % (line, lineNumber))
+            if len(line) > 1 and sequenceName != line[1:]:
+                sys.exit("Names in sequence and qual are different (%s, %s) (line is %d)" % (sequenceName, line[1:], lineNumber))
+        elif inSequence:
+            outputFastaFile.write("%s\n" % (line))
+        elif inQuality:
+            pass
+        lineNumber += 1
+    
+    inputFile.close()
+    outputFastaFile.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/findTss.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,77 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Find TSS from short reads"""
+import os
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptListsComparator import TranscriptListsComparator
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from commons.core.writer.Gff3Writer import Gff3Writer
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Find TSS v1.0.1: Find the transcription start site of a list of transcripts. [Category: Merge]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName", action="store",                     type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",        action="store",                     type="string", help="format of file [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",    dest="output",        action="store",      default=None,  type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-n", "--normalize", dest="normalize",     action="store_true", default=False,                help="normalize the number of reads per cluster by the number of mappings per read [format: bool] [default: false]")
+    parser.add_option("-d", "--distance",  dest="distance",      action="store",      default=10,    type="int",    help="distance between two reads to mark the same TSS [format: int] [default: 10]")
+    parser.add_option("-e", "--colinear",  dest="colinear",      action="store_true", default=False,                help="group by strand [format: bool] [default: false]")
+    parser.add_option("-c", "--csv",       dest="csv",           action="store",      default=None,  type="string", help="output a CSV file in the given path [format: output file in Excel format]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",     action="store",      default=1,     type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    transcriptContainer = TranscriptContainer(options.inputFileName, options.format, options.verbosity)        
+    transcriptListComparator = TranscriptListsComparator(None, options.verbosity)
+    transcriptListComparator.restrictToStart(transcriptListComparator.QUERY, 1)
+    transcriptListComparator.setMaxDistance(options.distance)
+    transcriptListComparator.aggregate(True)
+    transcriptListComparator.computeOdds(True)
+    transcriptListComparator.getColinearOnly(options.colinear)
+    transcriptListComparator.setNormalization(options.normalize)
+    transcriptListComparator.setInputTranscriptContainer(transcriptListComparator.QUERY, transcriptContainer)
+    transcriptListComparator.setOutputWriter(Gff3Writer(options.output, options.verbosity))
+    transcriptListComparator.compareTranscriptListSelfMerge()
+
+    if options.csv != None:
+        csvResults = transcriptListComparator.getOddsPerTranscript()
+        csvFile    = open(options.csv, "w")
+        csvFile.write("Number,Transcript\n")
+        for number in sorted(list(set(csvResults.values()))):
+            csvFile.write("%d," % (number))
+            for name in csvResults:
+                if csvResults[name] == number:
+                    csvFile.write("%s " % (name))
+            csvFile.write("\n")
+        csvFile.close()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/fold.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,95 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Read a mapping file (many formats supported) and select some of them
+Mappings should be sorted by read names
+"""
+
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.toolLauncher.RnaFoldLauncher import RnaFoldLauncher
+from commons.core.writer.Gff3Writer import Gff3Writer
+
+
+class Fold(object):
+    """
+    Fold a series of transcripts
+    """
+
+    def __init__(self, verbosity = 0):
+        self.verbosity       = verbosity
+        self.rnaFoldLauncher = RnaFoldLauncher(verbosity)
+        self.gff3Writer      = None
+
+
+    def setInputFileName(self, fileName, format):
+        transcriptContainer = TranscriptContainer(fileName, format, options.verbosity)
+        self.rnaFoldLauncher.setTranscriptList(transcriptContainer)
+
+    
+    def setOutputFileName(self, fileName):
+        self.gff3Writer = Gff3Writer("%s.gff3" % (fileName), self.verbosity)
+
+
+    def setGenomeFileName(self, fileName):
+        self.rnaFoldLauncher.setGenomeFile(fileName)
+
+
+    def setExtensions(self, fivePrime, threePrime):
+        self.rnaFoldLauncher.setExtensions(fivePrime, threePrime)
+
+
+    def start(self):
+        self.gff3Writer.addTranscriptList(self.rnaFoldLauncher.getResults())
+
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Fold v1.0.1: Fold a list of transcript and give the energy. [Category: Personal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",      dest="inputFileName",  action="store",            type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",     dest="format",         action="store",            type="string", help="format of file [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",     dest="outputFileName", action="store",            type="string", help="output file [format: output file in GFF3 format]")
+    parser.add_option("-g", "--genome",     dest="genomeFileName", action="store",            type="string", help="genome file name [format: file in FASTA format]")
+    parser.add_option("-5", "--fivePrime",  dest="fivePrime",      action="store",            type="int",    help="extend towards the 5' end [format: int]")
+    parser.add_option("-3", "--threePrime", dest="threePrime",     action="store",            type="int",    help="extend towards the 3' end [format: int]")
+    parser.add_option("-v", "--verbosity",  dest="verbosity",      action="store", default=1, type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    folder = Fold(options.verbosity)
+    folder.setInputFileName(options.inputFileName, options.format)
+    folder.setOutputFileName(options.outputFileName)
+    folder.setExtensions(options.fivePrime, options.threePrime)
+    folder.setGenomeFileName(options.genomeFileName)
+    folder.start()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getDifference.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,155 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Restrict a transcript list with some parameters (regions)"""
+
+from optparse import OptionParser
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.structure.TranscriptListsComparator import TranscriptListsComparator
+from commons.core.writer.Gff3Writer import Gff3Writer
+from commons.core.parsing.FastaParser import FastaParser
+from SMART.Java.Python.misc.Progress import Progress
+
+class DifferenceGetter(object):
+
+    def __init__(self, verbosity):
+        self.verbosity        = verbosity
+        self.annotationParser = None
+        self.referenceParser  = None
+        self.sequenceParser   = None
+        self.transcriptCount  = 1
+        self.split            = False
+
+    def createTranscript(self, chromosome, start, end):
+        transcript = Transcript()
+        transcript.setChromosome(chromosome)
+        transcript.setDirection("+")
+        transcript.setStart(start)
+        transcript.setEnd(end)
+        transcript.setName("region_%d" % self.transcriptCount)
+        transcript.setTagValue("ID", "region_%d" % self.transcriptCount)
+        self.transcriptCount += 1
+        return transcript
+
+    def setSplit(self, split):
+        self.split = split
+
+    def setAnnotationFile(self, fileName, format):
+        if fileName != None:
+            self.annotationParser = TranscriptContainer(fileName, format, self.verbosity)
+
+    def setReferenceFile(self, fileName, format):
+        if fileName != None:
+            self.referenceParser = TranscriptContainer(fileName, format, self.verbosity)
+
+    def setSequenceFile(self, fileName):
+        if fileName != None:
+            self.sequenceParser = FastaParser(fileName, self.verbosity)
+
+    def setOutputFile(self, fileName):
+        self.writer = Gff3Writer(fileName, self.verbosity)
+
+    def initialize(self):
+        self.presence = {}
+        for chromosome in self.sequenceParser.getRegions():
+            self.presence[chromosome] = [[1, self.sequenceParser.getSizeOfRegion(chromosome)]]
+
+    def readTranscripts(self):
+        nbTranscripts = self.annotationParser.getNbTranscripts()
+        progress      = Progress(nbTranscripts, "Parsing annotation file" , self.verbosity)
+        for transcript in self.annotationParser.getIterator():
+            chromosome   = transcript.getChromosome()
+            toBeDeleted  = []
+            toBeAppended = []
+            for i, element in enumerate(self.presence[chromosome]):
+                start, end = element
+                if start <= transcript.getEnd() and transcript.getStart() <= end:
+                    toBeDeleted.append(i)
+                    if start < transcript.getStart():
+                        toBeAppended.append([start, transcript.getStart() - 1])
+                    if end > transcript.getEnd():
+                        toBeAppended.append([transcript.getEnd() + 1, end])
+            for i in reversed(toBeDeleted):
+                del self.presence[chromosome][i]
+            self.presence[chromosome].extend(toBeAppended)
+            progress.inc()
+        progress.done()
+
+    def writeOutput(self):
+        for chromosome in self.presence:
+            for element in self.presence[chromosome]:
+                start, end = element
+                self.writer.addTranscript(self.createTranscript(chromosome, start, end))
+        self.writer.write()
+
+    def compareToSequence(self):
+        self.initialize()
+        self.readTranscripts()
+        self.writeOutput()
+
+    def compareToAnnotation(self):
+        transcriptListComparator = TranscriptListsComparator(None, self.verbosity)
+        transcriptListComparator.setSplitDifference(self.split)
+        transcriptListComparator.setInputTranscriptContainer(transcriptListComparator.QUERY, self.annotationParser)
+        transcriptListComparator.setInputTranscriptContainer(transcriptListComparator.REFERENCE, self.referenceParser)
+        transcriptListComparator.setOutputWriter(self.writer)
+        transcriptListComparator.getDifferenceTranscriptList()
+
+    def run(self):
+        if self.referenceParser != None:
+            self.compareToAnnotation()
+        else:
+            self.compareToSequence()
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Get Difference v1.0.1: Get all the regions of the genome, except the one given or get all the elements from the first set which does not ovelap with the second set (at the nucleotide level). [Category: Data Comparison]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input1",    dest="inputFileName1",   action="store",                     type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format1",   dest="format1",          action="store",                     type="string", help="format [compulsory] [format: transcript file format]")
+    parser.add_option("-j", "--input2",    dest="inputFileName2",   action="store",      default=None,  type="string", help="reference file [format: file in transcript format given by -g]")
+    parser.add_option("-g", "--format2",   dest="format2",          action="store",      default=None,  type="string", help="format of the reference file [format: transcript file format]")
+    parser.add_option("-s", "--sequence",  dest="sequenceFileName", action="store",      default=None,  type="string", help="sequence file [format: file in FASTA format]")
+    parser.add_option("-p", "--split",     dest="split",            action="store_true", default=False,                help="when comparing to a set of genomic coordinates, do not join [format: boolean] [default: False")
+    parser.add_option("-o", "--output",    dest="outputFileName",   action="store",                     type="string", help="output file [format: output file in GFF3 format]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",        action="store",      default=1,     type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    getter = DifferenceGetter(options.verbosity)
+    getter.setSplit(options.split)
+    getter.setAnnotationFile(options.inputFileName1, options.format1)
+    getter.setSequenceFile(options.sequenceFileName)
+    getter.setReferenceFile(options.inputFileName2, options.format2)
+    getter.setOutputFile(options.outputFileName)
+    getter.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getDistance.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,241 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Get the distance between the transcripts of two lists"""
+
+import os
+import sys
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptListsComparator import TranscriptListsComparator
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from commons.core.writer.Gff3Writer import Gff3Writer
+
+class GetDistance(object):
+
+    def __init__(self, verbosity = 0):
+        self.verbosity      = verbosity
+        self.writer         = None
+        self.spearman       = False
+        self.tlc            = TranscriptListsComparator(None, self.verbosity)
+        self.strands        = (0, )
+        self.buckets        = None
+        self.title          = ""
+        self.xMin           = None
+        self.xMax           = None
+        self.proportion     = False
+        self.outputFileName = None
+        self.keep           = False
+
+    def __del__(self):
+        pass
+
+    def setQueryFile(self, fileName, format):
+        self.transcriptContainer1 = TranscriptContainer(fileName, format, self.verbosity)
+        
+    def setReferenceFile(self, fileName, format):
+        self.transcriptContainer2 = TranscriptContainer(fileName, format, self.verbosity)
+
+    def setOutputFile(self, fileName):
+        self.outputFileName = fileName
+        
+    def setOutputTranscriptFile(self, fileName):
+        if fileName != None:
+            self.writer = Gff3Writer(fileName, self.verbosity)
+        
+    def restrictQueryToStart(self, number):
+        self.tlc.restrictToStart(self.tlc.QUERY, number)
+
+    def restrictReferenceToStart(self, number):
+        self.tlc.restrictToStart(self.tlc.REFERENCE, number)
+
+    def restrictQueryToEnd(self, number):
+        self.tlc.restrictToEnd(self.tlc.QUERY, number)
+
+    def restrictReferenceToEnd(self, number):
+        self.tlc.restrictToEnd(self.tlc.REFERENCE, number)
+
+    def setAbsolute(self, boolean):
+        self.tlc.setAbsolute(boolean)
+
+    def setProportion(self, boolean):
+        self.proportion = boolean
+
+    def setColinear(self, boolean):
+        self.tlc.getColinearOnly(boolean)
+
+    def setAntisense(self, boolean):
+        self.tlc.getAntisenseOnly(boolean)
+
+    def setDistances(self, minDistance, maxDistance):
+        self.tlc.setMinDistance(minDistance)
+        self.tlc.setMaxDistance(maxDistance)
+
+    def setStrands(self, boolean):
+        self.tlc.setStrandedDistance(boolean)
+        if boolean:
+            self.strands = (-1, 1)
+
+    def setUpstream(self, number):
+        self.tlc.setUpstream(self.tlc.REFERENCE, number)
+
+    def setDownstream(self, number):
+        self.tlc.setDownstream(self.tlc.REFERENCE, number)
+
+    def setBuckets(self, number):
+        self.buckets = number
+
+    def setTitle(self, title):
+        self.title = title
+
+    def setXValues(self, xMin, xMax):
+        self.xMin, self.xMax = xMin, xMax
+
+    def keepTmpValues(self, boolean):
+        self.keep = boolean
+
+    def getSpearman(self, boolean):
+        self.spearman = True
+
+    def compare(self):
+        self.tlc.setInputTranscriptContainer(self.tlc.QUERY, self.transcriptContainer1)
+        self.tlc.setInputTranscriptContainer(self.tlc.REFERENCE, self.transcriptContainer2)
+        self.tlc.setOutputWriter(self.writer)
+        self.distances = self.tlc.compareTranscriptListDistance()
+
+    def checkEmptyDistances(self):
+        return (sum([len(self.distances[strand].keys()) for strand in self.strands]) == 0)
+
+    def setPlotterMinusStrand(self):
+        if -1 in self.strands:
+            for x, y in self.distances[-1].iteritems():
+                self.distances[-1][x] = -y
+
+    def setPlotterProportion(self):
+        if not self.proportion:
+            return
+        self.nbElements = sum([abs(sum(self.distances[strand].values())) for strand in self.strands])
+        for strand in self.strands:
+            self.distances[strand] = dict([(distance, float(nb) / self.nbElements * 100) for distance, nb in self.distances[strand].iteritems()])
+
+    def setPlotter(self):
+        self.plotter = RPlotter(self.outputFileName, self.verbosity, self.keep)
+        if self.buckets != None:
+            self.plotter.setBarplot(True)
+        self.plotter.setFill(0)
+        self.plotter.setXLabel("distance")
+        self.plotter.setYLabel("# elements")
+        if self.proportion:
+            self.plotter.setYLabel("%% elements (%d in toto)" % (self.nbElements))
+        self.plotter.setBuckets(self.buckets)
+        self.plotter.setMinimumX(self.xMin)
+        self.plotter.setMaximumX(self.xMax)
+        self.plotter.setTitle(self.title)
+
+    def plot(self):
+        if len(self.strands) == 1:
+            self.distances = {0: self.distances}
+        if self.checkEmptyDistances():
+            print "No output."
+            sys.exit()
+        self.setPlotterMinusStrand()
+        self.setPlotterProportion()
+        if self.outputFileName == None:
+            return
+        self.setPlotter()
+        for strand in self.strands:
+            self.plotter.addLine(self.distances[strand])
+        self.plotter.plot()
+
+    def printSpearman(self):
+        if self.spearman:
+            print "Spearman's rho: %.5f" % (self.plotter.getSpearmanRho())
+
+    def run(self):
+        self.compare()
+        self.plot()
+        self.printSpearman()
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Get Distance v1.0.3: Compute the distance of a set of transcript with respect to a reference set. [Category: Visualization]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input1",          dest="inputFileName1",  action="store",                    type="string", help="input file 1 [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format1",         dest="format1",         action="store",                    type="string", help="format of file 1 [compulsory] [format: transcript file format]")
+    parser.add_option("-j", "--input2",          dest="inputFileName2",  action="store",                    type="string", help="input file 2 [compulsory] [format: file in transcript format given by -g]")
+    parser.add_option("-g", "--format2",         dest="format2",         action="store",                    type="string", help="format of file 2 [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",          dest="outputFileName",  action="store",                    type="string", help="plot output file [format: output file in PNG format]")
+    parser.add_option("-O", "--outputDistances", dest="outputDistances", action="store",      default=None, type="string", help="output file containing the distance for each element of the query [format: output file in GFF3 format] [default: None]")
+    parser.add_option("-c", "--colinear",        dest="colinear",        action="store_true", default=False,               help="only consider features on the same strand [format: bool] [default: false]")
+    parser.add_option("-a", "--antisense",       dest="antisense",       action="store_true", default=False,               help="only consider features on the opposite strand [format: bool] [default: false]")
+    parser.add_option("-b", "--absolute",        dest="absolute",        action="store_true", default=False,               help="give the absolute value of the distance [format: bool] [default: false]")
+    parser.add_option("-p", "--proportion",      dest="proportion",      action="store_true", default=False,               help="give the proportion on the y-axis instead of the number of distances [format: bool] [default: false]")
+    parser.add_option("-s", "--start1",          dest="start1",          action="store",      default=None, type="int",    help="only consider the n first 5' nucleotides for list 1 [format: int]")
+    parser.add_option("-S", "--start2",          dest="start2",          action="store",      default=None, type="int",    help="only consider the n first 5' nucleotides for list 2 [format: int]")
+    parser.add_option("-e", "--end1",            dest="end1",            action="store",      default=None, type="int",    help="only consider the n last 3' nucleotides for list 1 [format: int]")
+    parser.add_option("-E", "--end2",            dest="end2",            action="store",      default=None, type="int",    help="only consider the n last 3' nucleotides for list 2 [format: int]")
+    parser.add_option("-m", "--minDistance",     dest="minDistance",     action="store",      default=None, type="int",    help="minimum distance considered between two transcripts [format: int] [default: None]")
+    parser.add_option("-M", "--maxDistance",     dest="maxDistance",     action="store",      default=1000, type="int",    help="maximum distance considered between two transcripts [format: int] [default: 1000]")
+    parser.add_option("-5", "--fivePrime",       dest="fivePrime",       action="store_true", default=False,               help="consider the elements from list 1 which are upstream of elements of list 2 [format: bool] [default: False]")
+    parser.add_option("-3", "--threePrime",      dest="threePrime",      action="store_true", default=False,               help="consider the elements from list 1 which are downstream of elements of list 2 [format: bool] [default: False]")
+    parser.add_option("-u", "--buckets",         dest="buckets",         action="store",      default=None, type="int",    help="plot histogram instead of line plot with given interval size [format: int] [default: None]")
+    parser.add_option("-2", "--2strands",        dest="twoStrands",      action="store_true", default=False,               help="plot the distributions of each strand separately [format: bool] [default: False]")
+    parser.add_option("-r", "--spearman",        dest="spearman",        action="store_true", default=False,               help="compute Spearman rho [format: bool] [default: False]")
+    parser.add_option("-x", "--xMin",            dest="xMin",            action="store",      default=None, type="int",    help="minimum value on the x-axis to plot [format: int] [default: None]")
+    parser.add_option("-X", "--xMax",            dest="xMax",            action="store",      default=None, type="int",    help="maximum value on the x-axis to plot [format: int] [default: None]")
+    parser.add_option("-t", "--title",           dest="title",           action="store",      default=None, type="string", help="title for the graph [format: int] [default: None]")
+    parser.add_option("-v", "--verbosity",       dest="verbosity",       action="store",      default=1,    type="int",    help="trace level [format: int]")
+    parser.add_option("-k", "--keep",            dest="keep",            action="store_true", default=False,               help="keep temporary files [format: bool]")
+    (options, args) = parser.parse_args()
+
+    gd = GetDistance(options.verbosity)
+    gd.setQueryFile(options.inputFileName1, options.format1)
+    gd.setReferenceFile(options.inputFileName2, options.format2)
+    gd.setOutputFile(options.outputFileName)
+    gd.setOutputTranscriptFile(options.outputDistances)
+    gd.setColinear(options.colinear)
+    gd.setAntisense(options.antisense)
+    gd.setAbsolute(options.absolute)
+    gd.setProportion(options.proportion)
+    gd.restrictQueryToStart(options.start1)
+    gd.restrictReferenceToStart(options.start2)
+    gd.restrictQueryToEnd(options.end1)
+    gd.restrictReferenceToEnd(options.end2)
+    gd.setDistances(options.minDistance, options.maxDistance)
+    gd.setUpstream(options.fivePrime)
+    gd.setDownstream(options.threePrime)
+    gd.setStrands(options.twoStrands)
+    gd.setBuckets(options.buckets)
+    gd.setTitle(options.title)
+    gd.setXValues(options.xMin, options.xMax)
+    gd.keepTmpValues(options.keep)
+    gd.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getDistribution.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,291 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Get the repartition of some elements in a chromosomes"""
+
+import os
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.structure.Transcript import Transcript
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from SMART.Java.Python.misc.Progress import Progress
+from math import *
+
+def divideKeyDict(dictionary, ratio):
+    return dict([(key / ratio, dictionary[key]) for key in dictionary])
+
+
+def setTranscript(chromosome, direction, start, end, name, value):
+    transcript = Transcript()
+    transcript.setChromosome(chromosome)
+    transcript.setDirection(direction)
+    transcript.setStart(start)
+    transcript.setEnd(end)
+    transcript.setName(name)
+    transcript.setTagValue("nbElements", value)
+    return transcript
+
+
+
+if __name__ == "__main__":
+    
+    magnifyingFactor = 1000
+    
+    # parse command line
+    description = "Get Distribution v1.0.1: Get the distribution of the genomic coordinates on a genome. [Category: Visualization]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",       dest="inputFileName",     action="store",                           type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",      dest="format",            action="store",                           type="string", help="format of the input file [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",      dest="outputFileName",    action="store",                           type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-r", "--reference",   dest="referenceFileName", action="store",      default=None,        type="string", help="file containing the genome [compulsory] [format: file in FASTA format]")
+    parser.add_option("-n", "--nbBins",      dest="nbBins",            action="store",      default=1000,        type="int",    help="number of bins [default: 1000] [format: int]")
+    parser.add_option("-2", "--bothStrands", dest="bothStrands",       action="store_true", default=False,                      help="plot one curve per strand [format: bool] [default: false]")
+    parser.add_option("-w", "--raw",         dest="raw",               action="store_true", default=False,                      help="plot raw number of occurrences instead of density [format: bool] [default: false]")
+    parser.add_option("-x", "--csv",         dest="csv",               action="store_true", default=False,                      help="write a .csv file [format: bool]")
+    parser.add_option("-c", "--chromosome",  dest="chromosome",        action="store",      default=None,        type="string", help="plot only a chromosome [format: string]")
+    parser.add_option("-s", "--start",       dest="start",             action="store",      default=None,        type="int",    help="start from a given region [format: int]")
+    parser.add_option("-e", "--end",         dest="end",               action="store",      default=None,        type="int",    help="end from a given region [format: int]")
+    parser.add_option("-y", "--yMin",        dest="yMin",              action="store",      default=None,        type="int",    help="minimum value on the y-axis to plot [format: int]")
+    parser.add_option("-Y", "--yMax",        dest="yMax",              action="store",      default=None,        type="int",    help="maximum value on the y-axis to plot [format: int]")
+    parser.add_option("-g", "--gff",         dest="gff",               action="store_true", default=False,                      help="also write GFF3 file [format: bool] [default: false]")
+    parser.add_option("-H", "--height",      dest="height",            action="store",      default=None,        type="int",    help="height of the graphics [format: int] [default: 300]")
+    parser.add_option("-W", "--width",       dest="width",             action="store",      default=None,        type="int",    help="width of the graphics [format: int] [default: 1000]")
+    parser.add_option("-v", "--verbosity",   dest="verbosity",         action="store",      default=1,           type="int",    help="trace level [default: 1] [format: int]")
+    parser.add_option("-l", "--log",         dest="log",               action="store_true", default=False,                      help="write a log file [format: bool]")
+    parser.add_option("-D", "--directory",   dest="working_Dir",       action="store",      default=os.getcwd(), type="string", help="the directory to store the results [format: directory]")
+    (options, args) = parser.parse_args()
+
+    sizes = {}
+    if options.referenceFileName != None:
+        # get the sizes of the chromosomes
+        referenceHandle = open(options.referenceFileName)
+        name            = None
+        size            = 0
+        maxSize         = 0
+        for line in referenceHandle:
+            line = line.strip()
+            if line == "": continue
+            if line[0] == ">":
+                if name != None:
+                    if options.verbosity > 10:
+                        print name
+                    sizes[name] = size
+                    maxSize     = max(maxSize, size)
+                    size        = 0
+                name = line[1:]
+            else:
+                size += len(line)
+        sizes[name] = size
+        maxSize     = max(maxSize, size)
+        if options.verbosity > 1:
+            print "done"
+        start = 0
+        end   = maxSize
+    else:
+        if options.chromosome == None or options.start == None or options.end == None:
+            raise Exception("Missing chromosome or start and end positions, or reference file")
+        maxSize                   = options.end
+        sizes[options.chromosome] = options.end
+        start                     = options.start
+        end                       = options.end
+
+    
+    tmp1      = int(maxSize / float(options.nbBins))
+    tmp2      = 10 ** (len("%d" % (tmp1))-2)
+    sliceSize = int((tmp1 / tmp2) * tmp2)
+    
+    bins      = dict()
+    binsPlus  = dict()
+    binsMinus = dict()
+    for chromosome in sizes:
+        bins[chromosome]      = dict([(i * sliceSize + 1, 0) for i in range(start / sliceSize, sizes[chromosome] / sliceSize + 1)])
+        binsPlus[chromosome]  = dict([(i * sliceSize + 1, 0) for i in range(start / sliceSize, sizes[chromosome] / sliceSize + 1)])
+        binsMinus[chromosome] = dict([(i * sliceSize + 1, 0) for i in range(start / sliceSize, sizes[chromosome] / sliceSize + 1)])
+
+    parser   = TranscriptContainer(options.inputFileName, options.format, options.verbosity)
+    progress = Progress(parser.getNbTranscripts(), "Parsing %s" % (options.inputFileName), options.verbosity)
+    maxSlice = 0
+    # count the number of reads
+    for transcript in parser.getIterator():
+        if options.chromosome == None or (transcript.getChromosome() == options.chromosome and transcript.getStart() >= start and transcript.getStart() <= end):
+            if transcript.getDirection() == 1:
+                binsPlus[transcript.getChromosome()][(transcript.getStart() / sliceSize) * sliceSize + 1] += 1
+            else:
+                binsMinus[transcript.getChromosome()][(transcript.getStart() / sliceSize) * sliceSize + 1] += 1
+            bins[transcript.getChromosome()][(transcript.getStart() / sliceSize) * sliceSize + 1] += 1
+            maxSlice = max(maxSlice, transcript.getStart() / sliceSize)
+        progress.inc()
+    progress.done()
+
+    # compute densities
+    densityPlus = dict()
+    for chromosome in bins:
+        densityPlus[chromosome] = dict([(bin, 0) for bin in binsPlus[chromosome]])
+        for bin in binsPlus[chromosome]:
+            densityPlus[chromosome][bin] = float(binsPlus[chromosome][bin]) / sliceSize * magnifyingFactor
+        # correct densities for first and last bins
+        if start % sliceSize != 0:
+            densityPlus[chromosome][(start / sliceSize) * sliceSize + 1] = float(binsPlus[chromosome][(start / sliceSize) * sliceSize + 1]) / (sliceSize - (start % sliceSize)) * magnifyingFactor
+        if sizes[chromosome] % sliceSize != 0:
+            densityPlus[chromosome][(sizes[chromosome] / sliceSize) * sliceSize + 1] = float(binsPlus[chromosome][(sizes[chromosome] / sliceSize) * sliceSize + 1]) / (sizes[chromosome] % sliceSize) * magnifyingFactor
+    densityMinus = dict()
+    for chromosome in binsMinus:
+        densityMinus[chromosome] = dict([(bin, 0) for bin in binsMinus[chromosome]])
+        for bin in binsMinus[chromosome]:
+            densityMinus[chromosome][bin] = float(binsMinus[chromosome][bin]) / sliceSize * magnifyingFactor
+        # correct densities for first and last bins
+        if start % sliceSize != 0:
+            densityMinus[chromosome][(start / sliceSize) * sliceSize + 1] = float(binsMinus[chromosome][(start / sliceSize) * sliceSize + 1]) / (sliceSize - (start % sliceSize)) * magnifyingFactor
+        if sizes[chromosome] % sliceSize != 0:
+            densityMinus[chromosome][(sizes[chromosome] / sliceSize) * sliceSize + 1] = float(binsMinus[chromosome][(sizes[chromosome] / sliceSize) * sliceSize + 1]) / (sizes[chromosome] % sliceSize) * magnifyingFactor
+    density = dict()
+    for chromosome in bins:
+        density[chromosome] = dict([(bin, 0) for bin in bins[chromosome]])
+        for bin in bins[chromosome]:
+            density[chromosome][bin] = densityPlus[chromosome][bin] + densityMinus[chromosome][bin]
+
+    for chromosome in densityMinus:
+        for bin in densityMinus[chromosome]:
+            densityMinus[chromosome][bin] *= -1
+        for bin in binsMinus[chromosome]:
+            binsMinus[chromosome][bin] *= -1
+
+    for chromosome in density:
+        maxX = max(bins[chromosome].keys())
+        if maxX <= 1000:
+            unit  = "nt."
+            ratio = 1.0
+        elif maxX <= 1000000:
+            unit  = "kb"
+            ratio = 1000.0
+        else:
+            unit  = "Mb"
+            ratio = 1000000.0
+        outputFileName = "%s_%s" % (options.outputFileName, chromosome)
+        if options.start != None and options.end != None:
+            outputFileName += ":%d-%d" % (options.start, options.end)
+        outputFileName += ".png"
+        plotter = RPlotter(outputFileName, options.verbosity)
+        plotter.setXLabel("Position on %s (in %s)" % (chromosome.replace("_", " "), unit))
+        plotter.setYLabel("# reads")
+        if options.bothStrands:
+            plotter.setImageSize(1000, 300)
+        else:
+            plotter.setImageSize(1000, 200)
+        if options.height != None:
+            plotter.setHeight(options.height)
+        if options.width != None:
+            plotter.setWidth(options.width)
+        if options.yMax != None:
+            plotter.setMinimumY(options.yMin)
+        if options.yMax != None:
+            plotter.setMaximumY(options.yMax)
+        if options.bothStrands :
+            if options.raw:
+                plotter.addLine(divideKeyDict(binsPlus[chromosome], ratio))
+            else:
+                plotter.addLine(divideKeyDict(densityPlus[chromosome], ratio))
+            if options.raw:
+                plotter.addLine(divideKeyDict(binsMinus[chromosome], ratio))
+            else:
+                plotter.addLine(divideKeyDict(densityMinus[chromosome], ratio))
+        else:
+            if options.raw:
+                plotter.addLine(divideKeyDict(bins[chromosome], ratio))
+            else:
+                plotter.addLine(divideKeyDict(density[chromosome], ratio))
+        plotter.plot()
+        
+    if options.csv:
+        outputFileName = "%s" % (options.outputFileName)
+        if options.chromosome != None:
+            outputFileName += "_%s" % (options.chromosome)
+        if options.start != None and options.end != None:
+            outputFileName += ":%d-%d" % (options.start, options.end)
+        outputFileName += ".csv"
+        csvHandle = open(outputFileName, "w")
+        for slice in range(start / sliceSize, maxSlice + 1):
+            csvHandle.write(";%d-%d" % (slice * sliceSize + 1, (slice+1) * sliceSize))
+        csvHandle.write("\n")
+        if options.bothStrands:
+            for chromosome in densityPlus:
+                if len(densityPlus[chromosome]) > 0:
+                    csvHandle.write("%s [+]" % (chromosome))
+                    for slice in sorted(densityPlus[chromosome].keys()):
+                        csvHandle.write(";%.2f" % (densityPlus[chromosome][slice]))
+                    csvHandle.write("\n")            
+                if len(densityMinus[chromosome]) > 0:
+                    csvHandle.write("%s [-]" % (chromosome))
+                    for slice in sorted(densityPlus[chromosome].keys()):
+                        csvHandle.write(";%.2f" % (-densityMinus[chromosome][slice]))
+                    csvHandle.write("\n")            
+        else:
+            for chromosome in density:
+                if len(density[chromosome]) > 0:
+                    csvHandle.write(chromosome)
+                    for slice in sorted(density[chromosome].keys()):
+                        csvHandle.write(";%.2f" % (density[chromosome][slice]))
+                    csvHandle.write("\n")
+        csvHandle.close()
+             
+    if options.gff:
+        chromosome = "" if options.chromosome == None                         else options.chromosome.capitalize()
+        start      = "" if options.start      == None                         else "%d" % (options.start)
+        end        = "" if options.end        == None                         else "%d" % (options.end)
+        link1      = "" if options.start      == None and options.end == None else ":"
+        link2      = "" if options.start      == None and options.end == None else "-"
+        writer     = Gff3Writer("%s%s%s%s%s.gff3" % (options.outputFileName, link1, start, link2, end), options.verbosity)
+        cpt = 1
+        if options.raw:
+            valuesPlus  = binsPlus
+            valuesMinus = binsMinus
+            values      = bins
+        else:
+            valuesPlus  = densityPlus
+            valuesMinus = densityMinus
+            values      = density
+        if options.bothStrands:
+            for chromosome in values:
+                for slice in valuesPlus[chromosome]:
+                    writer.addTranscript(setTranscript(chromosome, 1, slice, slice + sliceSize, "region%d" % (cpt), valuesPlus[chromosome][slice]))
+                    cpt += 1
+                for slice in valuesMinus[chromosome]:
+                    writer.addTranscript(setTranscript(chromosome, -1, slice, slice + sliceSize, "region%d" % (cpt), - valuesMinus[chromosome][slice]))
+                    cpt += 1
+        else:
+            for chromosome in values:
+                for slice in values[chromosome]:
+                    writer.addTranscript(setTranscript(chromosome, 1, slice, slice + sliceSize, "region%d" % (cpt), values[chromosome][slice]))
+                    cpt += 1
+        writer.write()
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getElement.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,106 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Get the first element (exon / intron) from a list of transcripts"""
+
+import os
+from optparse import OptionParser
+from commons.core.writer.Gff3Writer import *
+from SMART.Java.Python.structure.TranscriptContainer import *
+from SMART.Java.Python.misc.Progress import *
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Get Element v1.0.1: Get the first element (exon / intron) from a list of transcripts. [Category: Personnal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",         dest="inputFileName",    action="store",                                                type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",        dest="format",                 action="store",                                                type="string", help="format of file [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",        dest="outputFileName", action="store",                                                type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-y", "--mysql",         dest="mysql",                    action="store_true", default=False,                                     help="mySQL output [format: bool] [default: false]")
+    parser.add_option("-t", "--type",            dest="type",                     action="store",                                                type="string", help="type of the element    [format: choice (exon, intron)]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",            action="store",            default=1,                type="int",        help="trace level [format: int]")
+    parser.add_option("-l", "--log",             dest="log",                        action="store_true", default=False,                                     help="write a log file [format: bool] [default: false]")
+    (options, args) = parser.parse_args()
+
+    parser        = TranscriptContainer(options.inputFileName, options.format, options.verbosity)
+    writer        = Gff3Writer(options.outputFileName, options.verbosity)
+    sqlWriter = MySqlTranscriptWriter(options.outputFileName, options.verbosity)
+    
+    nbLines = parser.getNbTranscripts()
+    print "%i lines found" % (nbLines)
+
+    # treat transcripts
+    nbWritten = 0
+    nbUsed        = 0
+    progress    = Progress(nbLines, "Analyzing transcripts of " + options.inputFileName, options.verbosity)
+    for transcript in parser.getIterator():
+
+        outTranscript = Transcript()
+        outTranscript.setName(transcript.getName())
+        outTranscript.setDirection(transcript.getDirection())
+        outTranscript.setChromosome(transcript.getChromosome())
+        
+        if options.type == "exon":
+            if len(transcript.getExons()) > 1:
+                transcript.sortExons()
+                outTranscript.setStart(transcript.getExons()[0].getStart())
+                outTranscript.setEnd(transcript.getExons()[0].getEnd())
+                writer.addTranscript(outTranscript)
+                if options.mysql:
+                    sqlWriter.addTranscript(transcript)
+                nbWritten += 1
+                nbUsed        += 1
+        elif options.type == "intron":
+            used = False
+            for intron in transcript.getIntrons():
+                used = True
+                thisTranscript = Transcript()
+                thisTranscript.copy(outTranscript)
+                thisTranscript.setStart(intron.getStart())
+                thisTranscript.setEnd(intron.getEnd())
+                writer.addTranscript(thisTranscript)
+                if options.mysql:
+                    sqlWriter.addTranscript(transcript)
+                nbWritten += 1
+            if used:
+                nbUsed += 1
+        else:
+            sys.exit("Cannot understan type %s" % (options.type))
+        progress.inc()
+    progress.done()
+
+    if options.mysql:
+        sqlWriter.write()
+
+    print "nb sequences used: %d" % (nbUsed)
+    print "nb elements used: %d" % (nbWritten)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getExons.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,128 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.misc.Progress import Progress
+
+zeroBaseToOneBaseConvertor = (lambda x: x - 1 if x > 0 else x)
+
+class GetExons(object):
+
+    def __init__(self, verbosity):
+        self.verbosity = verbosity
+        self.selection = False
+
+    def setInputFile(self, fileName, format):
+        chooser = ParserChooser(self.verbosity)
+        chooser.findFormat(format)
+        self.parser = chooser.getParser(fileName)
+
+    def setSelection(self, selection):
+        if selection == None:
+            return
+        self.selection = True
+        self.selectionItems = []
+        self.selectionIntervals = []
+        for part in selection.split(","):
+            try:
+                splittedPart = map(int, part.split(".."))
+            except Exception:
+                raise Exception("Elements '" + splittedPart + "' of selection '" + selection + "' do no seem to be integers!")
+            if len(splittedPart) == 1:
+                self.selectionItems.append(splittedPart[0])
+            elif len(splittedPart) == 2:
+                self.selectionIntervals.append((splittedPart[0], splittedPart[1]))
+            else:
+                raise Exception("Cannot parse elements '" + splittedPart + "' of selection '" + selection + "'!")
+
+    def getSelectionExonIndices(self, nbExons):
+        if not self.selection:
+            return range(nbExons)
+        indices = []
+        for item in self.selectionItems:
+            indices.append(range(nbExons)[zeroBaseToOneBaseConvertor(item)])
+        for start, end in self.selectionIntervals:
+            start, end = map(zeroBaseToOneBaseConvertor, (start, end))
+            if end > 0:
+                end += 1
+            indices.extend(range(nbExons)[start:end])
+        return indices
+
+    def setOutputFile(self, fileName):
+        self.writer = TranscriptWriter(fileName, "gff3", self.verbosity)
+        
+    def run(self):
+        progress = Progress(self.parser.getNbTranscripts(), "Reading input file", self.verbosity)
+        nbExons = 0
+        for cpt1, transcript in enumerate(self.parser.getIterator()):
+            selectedExons = self.getSelectionExonIndices(transcript.getNbExons())
+            transcript.sortExons()
+            for cpt2, exon in enumerate(transcript.getExons()):
+                if cpt2 not in selectedExons:
+                    continue
+                exonTranscript = Transcript()
+                exonTranscript.copy(exon)
+                if "Parent" in exonTranscript.tags:
+                    del exonTranscript.tags["Parent"]
+                exonTranscript.tags["feature"] = "transcript"
+                if "ID" not in exonTranscript.tags or exonTranscript.tags["ID"] == "unnamed transcript":
+                    exonTranscript.tags["ID"] = "exon_%d-%d" % (cpt1+1, cpt2+1)
+                if exonTranscript.getName() == "unnamed transcript":
+                    exonTranscript.setName("exon_%d-%d" % (cpt1+1, cpt2+1))
+                self.writer.addTranscript(exonTranscript)
+                nbExons += 1
+            progress.inc()
+        self.writer.write()
+        self.writer.close()
+        progress.done()
+        if self.verbosity > 1:
+            print "%d transcripts read" % (self.parser.getNbTranscripts())
+            print "%d exons written" % (nbExons)
+
+if __name__ == "__main__":
+    
+    description = "Get Exons v1.0.1: Get the exons of a set of transcripts. [Category: Data Modification]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",               type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",         action="store",               type="string", help="format of file [compulsory] [format: transcript file format]")
+    parser.add_option("-s", "--select",    dest="select",         action="store", default=None, type="string", help="select some of the exons (like '1,2,5..-3,-1') [format: string]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",               type="string", help="output file [format: output file in GFF3 format]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store", default=1,    type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    ge = GetExons(options.verbosity)
+    ge.setInputFile(options.inputFileName, options.format)
+    ge.setSelection(options.select)
+    ge.setOutputFile(options.outputFileName)
+    ge.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getInfoPerCoverage.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,167 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Compare overlap of a transcript list and list of read, and get some info depending on the coverage"""
+
+import os
+from optparse import OptionParser
+from commons.core.parsing.SequenceListParser import *
+from commons.core.writer.Gff3Writer import *
+from SMART.Java.Python.mySql.MySqlConnection import *
+from SMART.Java.Python.structure.TranscriptListsComparator import *
+from SMART.Java.Python.misc.RPlotter import *
+from SMART.Java.Python.misc.Progress import *
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Get Info per Coverage v1.0.1: Get a list of information clustered by the density of the coverage on a genome. [Category: Personnal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input1",                     dest="inputFileName1", action="store",                                         type="string", help="input file 1 [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format1",                    dest="format1",                action="store",                                         type="string", help="format of file 1 [compulsory] [format: transcript file format]")
+    parser.add_option("-j", "--input2",                     dest="inputFileName2", action="store",                                         type="string", help="input file 2 [compulsory] [format: file in transcript format given by -g]")
+    parser.add_option("-g", "--format2",                    dest="format2",                action="store",                                         type="string", help="format of file 2 [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",                     dest="output",                 action="store",            default=None,    type="string", help="output file [compulsory] [format: output file in TXT format]")
+    parser.add_option("-v", "--verbosity",                dest="verbosity",            action="store",            default=1,         type="int",        help="trace level [format: int]")
+    parser.add_option("-l", "--log",                            dest="log",                        action="store",            default=None,    type="string", help="write a log file [format: bool] [default: false]")
+    (options, args) = parser.parse_args()
+
+    logHandle = None
+    if options.log != None:
+        logHandle = open(options.log, "w")
+        
+    transcriptContainer1 = TranscriptContainer(options.inputFileName1, options.format1, options.verbosity)
+    transcriptContainer2 = TranscriptContainer(options.inputFileName2, options.format2, options.verbosity)
+    
+    transcriptListComparator = TranscriptListsComparator(logHandle, options.verbosity)
+    transcriptListComparator.restrictToStart(transcriptListComparator.REFERENCE, 10)
+    transcriptListComparator.getColinearOnly(True)
+    transcriptListComparator.computeOddsPerTranscript(True)
+    transcriptListComparator.setInputTranscriptContainer(transcriptListComparator.QUERY, transcriptContainer1)
+    transcriptListComparator.setInputTranscriptContainer(transcriptListComparator.REFERENCE, transcriptContainer2)
+    transcriptListComparator.compareTranscriptList()
+    transcriptTables = transcriptListComparator.getOutputTables()
+    
+    sizesWithIntrons                     = {}
+    sizesWithoutIntrons                = {}
+    nbExons                                        = {}
+    averageSizesWithIntrons        = {}
+    averageSizesWithoutIntrons = {}
+    averageNbExons                         = {}
+    sumSizesWithIntrons                = {}
+    sumSizesWithoutIntrons         = {}
+    sumSizesNbExons                        = {}
+    coverages                                    = transcriptListComparator.getOddsPerTranscript()
+
+    progress = Progress(transcriptContainer2.getNbTranscripts(), "Reading transcript file again", options.verbosity)
+    for transcript in transcriptContainer2.getIterator():
+        if transcript.name in coverages:
+            if transcript.getSizeWithIntrons() not in averageSizesWithIntrons:
+                averageSizesWithIntrons[transcript.getSizeWithIntrons()] = coverages[transcript.name]
+            else:
+                averageSizesWithIntrons[transcript.getSizeWithIntrons()] += coverages[transcript.name]
+            if transcript.getSizeWithIntrons() not in sumSizesWithIntrons:
+                sumSizesWithIntrons[transcript.getSizeWithIntrons()] = 1
+            else:
+                sumSizesWithIntrons[transcript.getSizeWithIntrons()] += 1
+            if transcript.getSize() not in averageSizesWithoutIntrons:
+                averageSizesWithoutIntrons[transcript.getSize()] = coverages[transcript.name]
+            else:
+                averageSizesWithoutIntrons[transcript.getSize()] += coverages[transcript.name]
+            if transcript.getSize() not in sumSizesWithoutIntrons:
+                sumSizesWithoutIntrons[transcript.getSize()] = 1
+            else:
+                sumSizesWithoutIntrons[transcript.getSize()] += 1
+            if transcript.getNbExons() not in averageNbExons:
+                averageNbExons[transcript.getNbExons()] = coverages[transcript.name]
+            else:
+                averageNbExons[transcript.getNbExons()] += coverages[transcript.name]
+            if transcript.getNbExons() not in sumSizesNbExons:
+                sumSizesNbExons[transcript.getNbExons()] = 1
+            else:
+                sumSizesNbExons[transcript.getNbExons()] += 1
+            sizesWithIntrons[transcript.name]        = (transcript.getSizeWithIntrons(), coverages[transcript.name])
+            sizesWithoutIntrons[transcript.name] = (transcript.getSize(), coverages[transcript.name])
+            nbExons[transcript.name]                         = (transcript.getNbExons(), coverages[transcript.name])
+        progress.inc()
+    progress.done()
+        
+    plotterSizeWithIntrons = RPlotter("%sWithIntrons.png" % (options.output), options.verbosity)
+    plotterSizeWithIntrons.setPoints(True)
+    plotterSizeWithIntrons.setMaximumX(10000)
+    plotterSizeWithIntrons.setMaximumY(1000)    
+    plotterSizeWithIntrons.setLog("y")
+    plotterSizeWithIntrons.addLine(sizesWithIntrons)
+    plotterSizeWithIntrons.plot()
+    
+    plotterSizeWithoutIntrons = RPlotter("%sWithoutIntrons.png" % (options.output), options.verbosity)
+    plotterSizeWithoutIntrons.setPoints(True)
+    plotterSizeWithoutIntrons.setMaximumX(10000)    
+    plotterSizeWithoutIntrons.setMaximumY(1000)
+    plotterSizeWithoutIntrons.setLog("y")
+    plotterSizeWithoutIntrons.addLine(sizesWithoutIntrons)
+    plotterSizeWithoutIntrons.plot()
+    
+    plotterNbExons = RPlotter("%sNbExons.png" % (options.output), options.verbosity)
+    plotterNbExons.setPoints(True)
+    plotterNbExons.addLine(nbExons)
+    plotterNbExons.plot()
+    
+    for element in averageSizesWithIntrons:
+        averageSizesWithIntrons[element] = int(float(averageSizesWithIntrons[element]) / sumSizesWithIntrons[element])
+    plotterAverageSizeWithIntrons = RPlotter("%sAverageWithIntrons.png" % (options.output), options.verbosity)
+    plotterAverageSizeWithIntrons.setMaximumX(10000)
+    plotterAverageSizeWithIntrons.setMaximumY(1000)    
+    plotterAverageSizeWithIntrons.setLog("y")
+    plotterAverageSizeWithIntrons.addLine(averageSizesWithIntrons)
+    plotterAverageSizeWithIntrons.plot()
+    print "min/avg/med/max sizes with introns: %d/%.2f/%.1f/%d" % Utils.getMinAvgMedMax(averageSizesWithIntrons)
+
+    for element in averageSizesWithoutIntrons:
+        averageSizesWithoutIntrons[element] = int(float(averageSizesWithoutIntrons[element]) / sumSizesWithoutIntrons[element])
+    plotterAverageSizeWithoutIntrons = RPlotter("%sAverageWithoutIntrons.png" % (options.output), options.verbosity)
+    plotterAverageSizeWithoutIntrons.setMaximumX(10000)
+    plotterAverageSizeWithoutIntrons.setMaximumY(1000)    
+    plotterAverageSizeWithoutIntrons.setLog("y")
+    plotterAverageSizeWithoutIntrons.addLine(averageSizesWithoutIntrons)
+    plotterAverageSizeWithoutIntrons.plot()
+    print "min/avg/med/max sizes without introns: %d/%.2f/%.1f/%d" % Utils.getMinAvgMedMax(averageSizesWithoutIntrons)
+
+    for element in averageNbExons:
+        averageNbExons[element] = int(float(averageNbExons[element]) / sumSizesNbExons[element])
+    plotterAverageNbExons = RPlotter("%sAverageNbExons.png" % (options.output), options.verbosity)
+    plotterAverageNbExons.addLine(averageNbExons)
+    plotterAverageNbExons.plot()
+    print "min/avg/med/max # exons: %d/%.2f/%.1f/%d" % Utils.getMinAvgMedMax(averageNbExons)
+
+    if options.log:
+        logHandle.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getIntrons.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,89 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.misc.Progress import Progress
+
+class GetIntrons(object):
+
+    def __init__(self, verbosity):
+        self.verbosity = verbosity
+
+    def setInputFile(self, fileName, format):
+        chooser = ParserChooser(self.verbosity)
+        chooser.findFormat(format)
+        self.parser = chooser.getParser(fileName)
+
+    def setOutputFile(self, fileName):
+        self.writer = TranscriptWriter(fileName, "gff3", self.verbosity)
+        
+    def run(self):
+        progress  = Progress(self.parser.getNbTranscripts(), "Reading input file", self.verbosity)
+        nbIntrons = 0
+        for cpt1, transcript in enumerate(self.parser.getIterator()):
+            for cpt2, intron in enumerate(transcript.getIntrons()):
+                intronTranscript = Transcript()
+                intronTranscript.copy(intron)
+                if "Parent" in intronTranscript.tags:
+                    del intronTranscript.tags["Parent"]
+                intronTranscript.tags["feature"] = "transcript"
+                if "ID" not in intronTranscript.tags or intronTranscript.tags["ID"] == "unnamed transcript":
+                    intronTranscript.tags["ID"] = "intron_%d-%d" % (cpt1+1, cpt2+1)
+                if intronTranscript.getName() == "unnamed transcript":
+                    intronTranscript.setName("intron_%d-%d" % (cpt1+1, cpt2+1))
+                self.writer.addTranscript(intronTranscript)
+                nbIntrons += 1
+            progress.inc()
+        self.writer.write()
+        self.writer.close()
+        progress.done()
+        if self.verbosity > 1:
+            print "%d transcripts read" % (self.parser.getNbTranscripts())
+            print "%d introns written" % (nbIntrons)
+
+
+if __name__ == "__main__":
+    
+    description = "Get Introns v1.0.1: Get the introns of a set of transcripts. [Category: Data Modification]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",             type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",         action="store",             type="string", help="format of file [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",             type="string", help="output file [format: output file in GFF3 format]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store",  default=1, type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    gi = GetIntrons(options.verbosity)
+    gi.setInputFile(options.inputFileName, options.format)
+    gi.setOutputFile(options.outputFileName)
+    gi.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getLetterDistribution.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,153 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Get the size distribution of a Fasta / BED file"""
+
+import os
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import *
+from SMART.Java.Python.misc.Progress import *
+from SMART.Java.Python.misc.RPlotter import *
+from commons.core.parsing.ParserChooser import ParserChooser
+
+
+def writeCVSfile(outHandler):
+    for pos in range(len(letters)):
+        posTrue = pos +1
+        outHandler.write( "%s;" % (posTrue))
+        for letter in lettersRate:
+            if positionRate[letter].has_key(pos):
+                outHandler.write("%s=%.2f%s;" %(letter, positionRate[letter][pos], "%"))
+            else:
+                outHandler.write("%s=0%s;" % (letter, "%"))
+        outHandler.write("\n")
+
+if __name__ == "__main__":
+
+    # parse command line
+    description = "Get Letter Distribution v1.0.1: Compute the distribution of nucleotides of a set of genomic coordinates. [Category: Visualization]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",                     type="string", help="input file to be analyzed [compulsory] [format: file in sequence format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",         action="store",                     type="string", help="format of file [format: sequence file format]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",                     type="string", help="output file [compulsory] [format: output file in PNG format]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [format: int]")
+    parser.add_option("-c", "--csv",       dest="csv",            action="store_true", default=False,                help="write a .csv file [format: bool] [default: false]")
+    parser.add_option("-l", "--log",       dest="log",            action="store_true", default=False,                help="write a log file [format: bool] [default: false]")
+    (options, args) = parser.parse_args()
+
+    chooser = ParserChooser()
+    chooser.findFormat(options.format)    
+    parser      = chooser.getParser(options.inputFileName)
+    nbSequences = parser.getNbSequences()
+    print "%i sequences read" % (nbSequences)
+
+    # treat items
+    progress       = Progress(nbSequences, "Analyzing sequences of " + options.inputFileName, options.verbosity)
+    nbLettersTotal = 0
+    nbLetters      = {}
+    lettersRate    = {}
+    nbPositions    = {}
+    positionCount  = {}
+    positionRate   = {}
+    nbPositionRate = {}
+    for sequence in parser.getIterator():
+        letters            = sequence.getSequence()
+        thisNbLettersTotal = sequence.getSize()
+        nbLettersTotal    += thisNbLettersTotal
+        thisNbLetters      = {}
+        
+        for pos in range(len(letters)):
+            letter = letters[pos]
+            if letter not in thisNbLetters:
+                thisNbLetters[letter] = 1
+            else:
+                thisNbLetters[letter] += 1
+            if pos+1 not in nbPositions:
+                nbPositions[pos+1] = 1
+            else:
+                nbPositions[pos+1] += 1
+            if letter not in positionCount:
+                positionCount[letter] = {}
+            if pos+1 not in positionCount[letter]:
+                positionCount[letter][pos+1] = 1
+            else:
+                positionCount[letter][pos+1] += 1
+
+        for letter in thisNbLetters:
+            if letter not in nbLetters:
+                nbLetters[letter] = thisNbLetters[letter]
+            else:
+                nbLetters[letter] += thisNbLetters[letter]
+            if letter not in lettersRate:
+                lettersRate[letter] = {}
+            rate = int(float(thisNbLetters[letter]) / thisNbLettersTotal * 100)
+            if rate not in lettersRate[letter]:
+                lettersRate[letter][rate] = 1
+            else:
+                lettersRate[letter][rate] += 1
+        progress.inc()
+    progress.done()
+    
+    for letter in positionCount:
+        positionRate[letter] = {}
+        for pos in positionCount[letter]:
+            positionRate[letter][pos] = positionCount[letter][pos] / float(nbPositions[pos]) * 100
+    for pos in nbPositions:
+        nbPositionRate[pos] = nbPositions[pos] / float(nbPositions[1]) * 100
+
+    # plot content distributions
+    plotter = RPlotter("%s.png" % (options.outputFileName), options.verbosity, True)
+    plotter.setFill(0)
+    plotter.setLegend(True)
+    for letter in lettersRate:
+        plotter.addLine(lettersRate[letter], letter)
+    plotter.plot()
+    
+    # plot distribution per position
+    plotter = RPlotter("%sPerNt.png" % (options.outputFileName), options.verbosity, True)
+    plotter.setFill(0)
+    plotter.setLegend(True)
+    plotter.setXLabel("Position on the read")
+    plotter.setYLabel("Percentage")
+    for letter in positionRate:
+        plotter.addLine(positionRate[letter], letter)
+    plotter.addLine(nbPositionRate, "#")
+    plotter.plot()
+
+    if options.csv:
+        outHandler = open("%s.csv" % (options.outputFileName), "w")
+        writeCVSfile(outHandler)
+        outHandler.close() 
+ 
+    print "%d sequences" % (nbSequences)
+    print "%d letters" % (nbLettersTotal)
+    for letter in nbLetters:
+        print "%s: %d (%.2f%%)" % (letter, nbLetters[letter], float(nbLetters[letter]) / nbLettersTotal * 100)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getNb.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,99 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Get the repartition of some elements (# exons per transcripts, # of repetitions of a mapping or # of transcripts in a cluster)"""
+
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc import Utils
+from math import *
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Get Nb v1.0.1: Get the distribution of exons per transcripts, or mapping per read, or transcript per cluster. [Category: Visualization]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",                     type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",         action="store",                     type="string", help="format of the input file [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",                     type="string", help="output file [compulsory] [format: output file in png format]")
+    parser.add_option("-q", "--query",     dest="query",          action="store",                     type="string", help="query  [compulsory] (# exons, # transcripts) [format: choice (exon, transcript, cluster)]")    
+    parser.add_option("-b", "--barplot",   dest="barplot",        action="store_true", default=False,                help="use barplot representation [format: bool] [default: false]")
+    parser.add_option("-x", "--xMax",      dest="xMax",           action="store",      default=None,  type="int",    help="maximum value on the x-axis to plot [format: int]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [default: 1] [format: int]")
+    parser.add_option("-l", "--log",       dest="log",            action="store_true", default=False,                help="write a log file [format: bool] [default: false]")
+    (options, args) = parser.parse_args()
+
+    if options.query != "exon" and options.query != "transcript" and options.query != "cluster":
+        raise Exception("Do not understand query %s" % (options.query))
+
+    exonDistribution       = {}
+    transcriptDistribution = {}
+    clusterDistribution    = {}
+    
+    transcriptContainer = TranscriptContainer(options.inputFileName, options.format, options.verbosity)
+        
+    progress = Progress(transcriptContainer.getNbTranscripts(), "Parsing %s" % (options.inputFileName), options.verbosity)
+    # count the number of reads
+    for element in transcriptContainer.getIterator():
+        if options.query == "exon":
+            nbExons = element.getNbExons()
+            exonDistribution[nbExons] = exonDistribution.get(nbExons, 0) + 1
+        elif options.query == "transcript":
+            name = element.getName()
+            transcriptDistribution[name] = transcriptDistribution.get(name, 0) + 1
+        elif options.query == "cluster":
+            nbElements = 1 if "nbElements" not in element.getTagNames() else element.getTagValue("nbElements")
+            clusterDistribution[nbElements] = clusterDistribution.get(nbElements, 0) + 1
+        progress.inc()
+    progress.done()
+    
+    if options.query == "exon":
+        distribution = exonDistribution
+    elif options.query == "transcript":
+        distribution = {}
+        for name in transcriptDistribution:
+            distribution[transcriptDistribution[name]] = distribution.get(transcriptDistribution[name], 0) + 1
+    elif options.query == "cluster":
+        distribution = clusterDistribution
+    
+    outputFileName = options.outputFileName
+    plotter = RPlotter(outputFileName, options.verbosity)
+    plotter.setImageSize(1000, 300)
+    plotter.setFill(0)
+    plotter.setMaximumX(options.xMax)
+    plotter.setBarplot(options.barplot)
+    plotter.addLine(distribution)
+    plotter.plot()
+             
+    print "min/avg/med/max: %d/%.2f/%.1f/%d" % (Utils.getMinAvgMedMax(distribution))
+            
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getRandomRegions.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,267 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Find random regions in a genome"""
+
+import random, math
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import *
+from commons.core.writer.Gff3Writer import *
+from commons.core.writer.MySqlTranscriptWriter import *
+from SMART.Java.Python.misc.Progress import *
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+
+repetitions = 100
+
+
+class RandomRegionsGenerator(object):
+
+    def __init__(self, verbosity):
+        self.verbosity      = verbosity
+        self.strands        = False
+        self.distribution   = "uniform"
+        self.transcripts    = None
+        self.sequenceParser = None
+        random.seed()
+
+
+    def setInput(self, fileName):
+        self.sequenceParser = FastaParser(fileName, self.verbosity)
+
+
+    def setGenomeSize(self, size):
+        self.genomeSize = size
+
+
+    def setChromosomeName(self, name):
+        self.chromosomeName = name
+
+
+    def setAnnotation(self, fileName, format):
+        parser           = TranscriptContainer(fileName, format, self.verbosity)
+        self.transcripts = []
+        for transcript in parser.getIterator():
+            self.transcripts.append(transcript)
+        self.setNumber(len(self.transcripts))
+        self.setSize(0)
+
+
+    def setOutputFile(self, fileName):
+        self.outputFileName = fileName
+
+
+    def setSize(self, size):
+        self.minSize = size
+        self.maxSize = size
+
+
+    def setMinSize(self, size):
+        self.minSize = size
+
+
+    def setMaxSize(self, size):
+        self.maxSize = size
+
+
+    def setNumber(self, number):
+        self.number = number
+
+
+    def setStrands(self, strands):
+        self.strands = strands
+
+
+    def setMaxDistribution(self, maxElements):
+        if maxElements == None:
+            return
+        self.maxElements = maxElements
+        self.distribution = "gaussian"
+
+
+    def setDeviationDistribution(self, deviation):
+        if deviation == None:
+            return
+        self.deviation = deviation
+        self.distribution = "gaussian"
+
+
+    def getSizes(self):
+        if self.sequenceParser == None:
+            self.chromosomes    = [self.chromosomeName]
+            self.sizes          = {self.chromosomeName: self.genomeSize}
+            self.cumulatedSize  = self.genomeSize
+            self.cumulatedSizes = {self.chromosomeName: self.genomeSize}
+            return
+        self.chromosomes    = self.sequenceParser.getRegions()
+        self.sizes          = {}
+        self.cumulatedSize  = 0
+        self.cumulatedSizes = {}
+        for chromosome in self.chromosomes:
+            self.sizes[chromosome]          = self.sequenceParser.getSizeOfRegion(chromosome)
+            self.cumulatedSize             += self.sizes[chromosome]
+            self.cumulatedSizes[chromosome] = self.cumulatedSize
+
+
+    def findPosition(self, size = None):
+        if size == None:
+            size = random.randint(self.minSize, self.maxSize)
+        integer = random.randint(0, self.cumulatedSize)
+        for chromosome in self.chromosomes:
+            if self.cumulatedSizes[chromosome] > integer:
+                break
+        start = random.randint(1, self.sizes[chromosome] - size)
+        return (chromosome, start, size)
+
+
+    def createTranscript(self, chromosome, start, size, strand, cpt):
+        transcript = Transcript()
+        transcript.setChromosome(chromosome)
+        transcript.setStart(start)
+        transcript.setEnd(start + size-1)
+        transcript.setDirection(strand)
+        transcript.setName("rand_%d" % (cpt))
+        return transcript
+
+
+    def moveTranscript(self, chromosome, start, transcript):
+        while transcript.getEnd() + start - transcript.getStart() > self.cumulatedSizes[chromosome]:
+            chromosome, start, size = self.findPosition(transcript.getEnd() - transcript.getStart())
+        transcript.setChromosome(chromosome)
+        oldStart, oldEnd = transcript.getStart(), transcript.getEnd()
+        if transcript.getNbExons() > 1:
+            for exon in transcript.getNbExons():
+                oldExonStart, oldExonEnd = exon.getStart(), exon.getEnd()
+                exon.setStart(oldExonStart + start - oldStart)
+                exon.setEnd(oldExonEnd + start - oldStart)
+        transcript.setStart(start)
+        transcript.setEnd(oldEnd + start - oldStart)
+        return [transcript]
+
+
+    def createUniformCluster(self, chromosome, start, size, strand, cpt):
+        transcript = self.createTranscript(chromosome, start, size, strand, cpt)
+        return [transcript]
+
+
+    def findNbTranscripts(self, cpt):
+        return min(int(round(math.exp(random.random() * math.log(self.maxElements)))), self.number - cpt + 1)
+
+
+    def getDev(self):
+        deviation = 0.0
+        for j in range(repetitions):
+            deviation += random.randint(-self.deviation, self.deviation)
+        deviation /= repetitions
+        deviation  = int(round(deviation))
+        return deviation
+
+
+    def createGaussianCluster(self, chromosome, start, size, strand, cpt):
+        transcripts   = []
+        nbTranscripts = self.findNbTranscripts(cpt)
+        for i in range(nbTranscripts):
+            transcript = self.createTranscript(chromosome, start + self.getDev(), size + self.getDev(), strand, cpt + i)
+            transcripts.append(transcript)
+        return transcripts
+
+
+    def writeRegions(self):
+        writer     = Gff3Writer(self.outputFileName, self.verbosity)
+        outputFile = open(self.outputFileName, "w")
+        progress   = Progress(self.number, "Writing to %s" % (self.outputFileName), self.verbosity)
+        i          = 0
+        while i < self.number:
+            chromosome, start, size = self.findPosition()
+            strand                  = random.choice([-1, 1]) if self.strands else 1
+            if self.transcripts != None:
+                transcripts = self.moveTranscript(chromosome, start, self.transcripts[i])
+            elif self.distribution == "uniform":
+                transcripts = self.createUniformCluster(chromosome, start, size, strand, i+1)
+            else:
+                transcripts = self.createGaussianCluster(chromosome, start, size, strand, i+1)
+            for transcript in transcripts:
+                writer.addTranscript(transcript)
+                i += 1
+                progress.inc()
+        progress.done()
+        outputFile.close()
+        writer.write()
+        writer.close()
+
+
+    def run(self):
+        self.getSizes()
+        self.writeRegions()
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Get Random Regions v1.0.2: Get some random coordinates on a genome. May use uniform or gaussian distribution (in gaussion distribution, # of element per cluster follows a power law). [Category: Other]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-r", "--reference",     dest="reference",      action="store",      default=None,  type="string", help="file that contains the sequences [format: file in FASTA format]")
+    parser.add_option("-S", "--referenceSize", dest="referenceSize",  action="store",      default=None,  type="int",    help="size of the chromosome (when no reference is given) [format: int]")
+    parser.add_option("-c", "--chromosome",    dest="chromosome",     action="store",      default=None,  type="string", help="name of the chromosome (when no reference is given) [format: string]")
+    parser.add_option("-o", "--output",        dest="outputFileName", action="store",                     type="string", help="output file [compulsory] [format: output file in FASTA format]")
+    parser.add_option("-i", "--input",         dest="inputFileName",  action="store",      default=None,  type="string", help="optional file containing regions to shuffle [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",        dest="format",         action="store",      default=None,  type="string", help="format of the previous file [format: transcript file format]")
+    parser.add_option("-s", "--size",          dest="size",           action="store",      default=None,  type="int",    help="size of the regions (if no region set is provided) [format: int]")
+    parser.add_option("-z", "--minSize",       dest="minSize",        action="store",      default=None,  type="int",    help="minimum size of the regions (if no region set nor a fixed size are provided) [format: int]")
+    parser.add_option("-Z", "--maxSize",       dest="maxSize",        action="store",      default=None,  type="int",    help="maximum size of the regions (if no region set nor a fixed size are provided) [format: int]")
+    parser.add_option("-n", "--number",        dest="number",         action="store",      default=None,  type="int",    help="number of regions (if no region set is provided) [format: int]")
+    parser.add_option("-t", "--strands",       dest="strands",        action="store_true", default=False,                help="use both strands (if no region set is provided) [format: boolean]")
+    parser.add_option("-m", "--max",           dest="max",            action="store",      default=None,  type="int",    help="max. # reads in a cluster (for Gaussian dist.) [format: int]")
+    parser.add_option("-d", "--deviation",     dest="deviation",      action="store",      default=None,  type="int",    help="deviation around the center of the cluster (for Gaussian dist.) [format: int]")
+    parser.add_option("-v", "--verbosity",     dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    rrg = RandomRegionsGenerator(options.verbosity)
+    if options.reference == None:
+        rrg.setGenomeSize(options.referenceSize)
+        rrg.setChromosomeName(options.chromosome)
+    else:
+        rrg.setInput(options.reference)
+    rrg.setOutputFile(options.outputFileName)
+    if options.inputFileName == None:
+        if options.size != None:
+            rrg.setSize(options.size)
+        else:
+            rrg.setMinSize(options.minSize)
+            rrg.setMaxSize(options.maxSize)
+        rrg.setNumber(options.number)
+        rrg.setStrands(options.strands)
+    else:
+        rrg.setAnnotation(options.inputFileName, options.format)
+    rrg.setMaxDistribution(options.max)
+    rrg.setDeviationDistribution(options.deviation)
+    rrg.run()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getReadDistribution.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,129 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Plot the data from the data files
+"""
+import os
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import FastaParser
+from commons.core.parsing.FastqParser import FastqParser
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc import Utils
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Get Read Distribution v1.0.1: Plot the number of identical reads and give the most represented. [Category: Visualization]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",               type="string", help="input file sequence [compulsory] [format: file in sequence format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",         action="store",               type="string", help="format of the file [compulsory] [format: sequence file format]")
+    parser.add_option("-n", "--number",    dest="number",         action="store", default=None, type="int",    help="keep the best n    [format: int]")
+    parser.add_option("-p", "--percent",   dest="percent",        action="store", default=None, type="float",  help="keep the best n\% [format: float]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",               type="string", help="output file [compulsory] [format: output files in PNG format and txt format]")
+    parser.add_option("-x", "--xMax",      dest="xMax",           action="store", default=None, type="int",    help="maximum value on the x-axis to plot [format: int]")
+    parser.add_option("-D", "--directory", dest="working_Dir",    action="store", default=os.getcwd(), type="string", help="the directory to store the results [format: directory]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store", default=1,    type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    if options.working_Dir[-1] != '/':
+        options.outputFileName = options.working_Dir + '/' + options.outputFileName
+        
+    if options.format == "fasta":
+        parser = FastaParser(options.inputFileName, options.verbosity)
+    elif options.format == "fastq":
+        parser = FastqParser(options.inputFileName, options.verbosity)
+    else:
+        raise Exception("Do not understand '%s' file format." % (options.format))
+
+    progress  = Progress(parser.getNbSequences(), "Reading %s" % (options.inputFileName), options.verbosity)
+    sequences = {}
+    for sequence in parser.getIterator():
+        sequence = sequence.sequence
+        if sequence not in sequences:
+            sequences[sequence] = 1
+        else:
+            sequences[sequence] += 1
+        progress.inc()
+    progress.done()
+
+    values = sequences.values()
+    values.sort()
+    if options.percent != None:
+        threshold = values[int(float(options.percent) / 100 * len(values))]
+    elif options.number != None:
+        threshold = values[-options.number]
+    else:
+        threshold = 0
+
+    # sort by value
+    progress     = Progress(parser.getNbSequences(), "Sorting values", options.verbosity)
+    sortedValues = dict([(value, []) for value in sequences.values()])
+    for sequence, value in sequences.iteritems():
+        sortedValues[value].append(sequence)
+        progress.inc()
+    progress.done()
+
+    outputFileName = "%s.txt" % (options.outputFileName)
+    handle         = open(outputFileName, "w")
+    progress       = Progress(parser.getNbSequences(), "Writing into %s" % (outputFileName), options.verbosity)
+    for value in reversed(sorted(sortedValues.keys())):
+        if value >= threshold:
+            for sequence in sortedValues[value]:
+                handle.write("%s\t%d\n" % (sequence, value))
+        progress.inc()
+    progress.done()
+    handle.close()
+
+    line     = {}
+    progress = Progress(len(values), "Preparing plot", options.verbosity)
+    for value in values:
+        if value not in line:
+            line[value] = 1
+        else:
+            line[value] += 1
+        progress.inc()
+    progress.done()
+
+    plot = RPlotter("%s.png" % (options.outputFileName), options.verbosity)
+    plot.setFill(0)
+    plot.setMaximumX(options.xMax)
+    plot.setXLabel("# occurrences")
+    plot.setYLabel("# reads")
+    plot.addLine(line)
+    plot.plot()
+
+    if options.verbosity > 0:
+        print "%d/%.2f/%.1f/%d occurrences" % (Utils.getMinAvgMedMax(line))
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getSequence.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,60 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Get a given sequence in a multi-Fasta file"""
+import sys
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import FastaParser
+from SMART.Java.Python.misc.Progress import Progress
+from commons.core.writer.FastaWriter import FastaWriter
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Get Sequence v1.0.1: Get a single sequence in a FASTA file. [Category: Data Selection]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input", dest="inputFileName",action="store",type="string", help="multi-FASTA file [compulsory] [format: file in FASTA format]")
+    parser.add_option("-n", "--name",dest="name",action="store",type="string", help="name of the sequence [compulsory] [format: string]")
+    parser.add_option("-o", "--output",dest="outputFileName",action="store",type="string", help="output sequence file (FASTA) [compulsory] [format: file in FASTA format]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",action="store",default=1,type="int",help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    # read Fasta file
+    sequenceListParser = FastaParser(options.inputFileName, options.verbosity)
+    for sequence in sequenceListParser.getIterator():
+        name = sequence.name.split(" ")[0]
+        if name == options.name:
+            writer = FastaWriter(options.outputFileName, options.verbosity)
+            writer.addSequence(sequence)
+            print sequence.printFasta(),
+            sys.exit(0)
+    writer.close()
+    print "No sequence found"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getSizes.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,238 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os, sys
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import FastaParser
+from commons.core.parsing.FastqParser import FastqParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from commons.core.parsing.GffParser import GffParser
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from SMART.Java.Python.misc import Utils
+
+from commons.core.LoggerFactory import LoggerFactory
+from commons.core.utils.RepetOptionParser import RepetOptionParser
+
+LOG_DEPTH = "smart"
+
+class GetSizes(object):
+    
+    def __init__(self, inFileName = None, inFormat=None, outFileName = None, query=None,xMax=None, xMin=None, csv=False, verbosity = 0):
+        self.inFileName = inFileName
+        self.inFormat= inFormat
+        self.outFileName = outFileName
+        self.query = query
+        self.xMax = xMax
+        self.xMin = xMin
+        self.xLab = "Size"
+        self.yLab = "# reads"
+        self.barplot = False
+        self.csv = csv
+        self._verbosity = verbosity
+        self.parser = None
+        self._log = LoggerFactory.createLogger("%s.%s" % (LOG_DEPTH, self.__class__.__name__), self._verbosity)
+        
+    def setAttributesFromCmdLine(self):
+        description = "Usage: getSizes.py [options]\n\nGet Sizes v1.0.2: Get the sizes of a set of genomic coordinates. [Category: Visualization]\n"
+        epilog = ""
+        parser = RepetOptionParser(description = description, epilog = epilog)
+        parser.add_option("-i", "--input",     dest="inputFileName",  action="store",      default=None,      type="string", help="input file [compulsory] [format: file in transcript or sequence format given by -f]")
+        parser.add_option("-f", "--format",    dest="format",         action="store",      default=None,      type="string", help="format of the input [compulsory] [format: transcript or sequence file format]")
+        parser.add_option("-q", "--query",     dest="query",          action="store",      default=None,      type="string", help="type to mesure [default: size] [format: choice (size, intron size, exon size, 1st exon size)]")     
+        parser.add_option("-o", "--output",    dest="outputFileName", action="store",      default=None,      type="string", help="output file [format: output file in PNG format]")
+        parser.add_option("-x", "--xMax",      dest="xMax",           action="store",      default=None,      type="int",    help="maximum value on the x-axis to plot [format: int]")
+        parser.add_option("-X", "--xMin",      dest="xMin",           action="store",      default=None,      type="int",    help="minimum value on the x-axis to plot [format: int]")
+        parser.add_option("-v", "--verbosity", dest="verbosity",      action="store",      default=1,         type="int",    help="trace level [format: int]")
+        parser.add_option("-c", "--csv",       dest="csv",            action="store",                         type="string", help="write a .csv file [format: bool] [default: false]")
+        parser.add_option("-a", "--xLabel",    dest="xLab",           action="store",      default="Size",    type="string", help="x absis label name [format: string] [default: Size]")
+        parser.add_option("-b", "--yLabel",    dest="yLab",           action="store",      default="# reads", type="string", help="y absis label name [format: string] [default: Reads]")
+        parser.add_option("-B", "--barplot",   dest="barplot",        action="store_true", default=False,                    help="use barplot representation [format: bool] [default: false]")  
+        options = parser.parse_args()[0]
+        self._setAttributesFromOptions(options)
+        
+    def _setAttributesFromOptions(self, options):
+        self.setInFileName(options.inputFileName)
+        self.setInFormat(options.format)
+        self.setQuery(options.query)
+        self.setOutFileName(options.outputFileName)
+        self.setXMax(options.xMax)
+        self.setXMin(options.xMin)
+        self.setxLab(options.xLab)
+        self.setyLab(options.yLab)
+        self.setBarplot(options.barplot)
+        self.setVerbosity(options.verbosity)
+        
+    def setInFileName(self, inputFileName):
+        self.inFileName = inputFileName
+        
+    def setInFormat(self, inFormat):
+        self.inFormat = inFormat
+    
+    def setQuery(self, query):
+        self.query = query
+        
+    def setOutFileName(self, outFileName):
+        self.outFileName = outFileName
+    
+    def setXMax(self, xMax):
+        self.xMax = xMax
+        
+    def setXMin(self, xMin):
+        self.xMin = xMin
+    
+    def setxLab(self, xLab):
+        self.xLab = xLab
+        
+    def setyLab(self, yLab):
+        self.yLab = yLab
+        
+    def setBarplot(self, barplot):
+        self.barplot = barplot
+        
+    def setCsv(self, csv):
+        self.csv = csv
+        
+    def setVerbosity(self, verbosity):
+        self._verbosity = verbosity
+        
+    def _checkOptions(self):
+        if self.inFileName == None:
+            self._logAndRaise("ERROR: Missing input file name")
+        if self.inFormat == "fasta":
+            self.parser = FastaParser(self.inFileName, self._verbosity)
+        elif self.inFormat == "fastq":
+            self.parser = FastqParser(self.inFileName, self._verbosity)
+        else:
+            self.parser = TranscriptContainer(self.inFileName, self.inFormat, self._verbosity)
+            
+    def _logAndRaise(self, errorMsg):
+        self._log.error(errorMsg)
+        raise Exception(errorMsg)
+                    
+    def run(self):
+        LoggerFactory.setLevel(self._log, self._verbosity)
+        self._checkOptions()
+        self._log.info("START getsizes")
+        self._log.debug("Input file name: %s" % self.inFileName)
+
+        nbItems = self.parser.getNbItems()
+        self._log.info( "%i items found" % (nbItems))
+        
+        # treat items
+        progress   = Progress(nbItems, "Analyzing sequences of %s" % (self.inFileName), self._verbosity)
+        sizes      = {}
+        names      = {}
+        minimum    = 1000000000000
+        maximum    = 0
+        sum        = 0
+        number     = 0
+        nbSubItems = 0
+        for item in self.parser.getIterator():
+            items = []
+            if self.query == "exon":
+                items = item.getExons()
+            elif self.query == "exon1":
+                if len(item.getExons()) > 1:
+                    item.sortExons()
+                    items = [item.getExons()[0]]
+            elif self.query == "intron":
+                items = item.getIntrons()
+            else:
+                items = [item, ]
+    
+            for thisItem in items:
+                try:
+                    nbElements = int(float(thisItem.getTagValue("nbElements")))
+                    if nbElements == None:
+                        nbElements = 1
+                except:
+                    nbElements = 1
+                size    = thisItem.getSize()
+                minimum = min(minimum, size)
+                maximum = max(maximum, size)
+                name    = thisItem.name.split()[0]
+                
+                if size not in sizes:
+                    sizes[size] = nbElements
+                    if self.csv:
+                        names[size] = [name, ]
+                else:
+                    sizes[size] += nbElements
+                    if self.csv:
+                        names[size].append(name)
+                sum        += size
+                nbSubItems += nbElements
+            number += 1
+            progress.inc()
+        progress.done()
+
+        if self.outFileName != None:
+            plotter = RPlotter(self.outFileName, self._verbosity)
+            plotter.setFill(0)
+            plotter.setMinimumX(self.xMin)
+            plotter.setMaximumX(self.xMax)
+            plotter.setXLabel(self.xLab)
+            plotter.setYLabel(self.yLab)
+            plotter.setBarplot(self.barplot)
+            plotter.addLine(sizes)
+            plotter.plot()
+            
+        if nbSubItems == 0:
+            self._logAndRaise("No item found")
+            
+        if self.csv:
+            csvHandle = open(self.csv, "w")
+            for size in range(min(sizes.keys()), max(sizes.keys())+1):
+                if size not in sizes:
+                    csvHandle.write("%d,0,\n" % (size))
+                else:
+                    csvHandle.write("%d,%d,%s\n" % (size, sizes[size], ";".join(names[size])))
+            csvHandle.close()
+        
+        self.items = number      
+        self.subItems = nbSubItems
+        self.nucleotides = sum
+        self.minAvgMedMax = Utils.getMinAvgMedMax(sizes)
+                  
+        print "%d items" % (number)
+        print "%d sub-items" % (nbSubItems)
+        print "%d nucleotides" % (sum)
+        print "min/avg/med/max transcripts: %d/%.2f/%.1f/%d" % Utils.getMinAvgMedMax(sizes)
+
+        self._log.info("END getsizes")
+
+
+if __name__ == "__main__":
+    iGetSizes = GetSizes()
+    iGetSizes.setAttributesFromCmdLine()
+    iGetSizes.run()
+    
+#TODO: add two more options!!!!!!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getWigData.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,67 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from commons.core.parsing.WigParser import WigParser
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.misc.Progress import Progress
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Get WIG Data v1.0.1: Compute the average data for some genomic coordinates using WIG files (thus covering a large proportion of the genome) and update a tag. [Category: WIG Tools]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",       dest="inputFileName",  action="store",                     type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--inputFormat", dest="inputFormat",    action="store",                     type="string", help="format of the input file [compulsory] [format: transcript file format]")
+    parser.add_option("-w", "--wig",         dest="wig",            action="store",                     type="string", help="wig file name [compulsory] [format: file in WIG format]")    
+    parser.add_option("-t", "--tag",         dest="tag",            action="store",                     type="string", help="choose a tag name to write the wig information to output file [compulsory] [format: file in WIG format]")    
+    parser.add_option("-o", "--output",      dest="outputFileName", action="store",                     type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-s", "--strands",     dest="strands",        action="store_true", default=False,                help="consider both strands separately [format: boolean] [default: False]")    
+    parser.add_option("-v", "--verbosity",   dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    # create parsers and writers
+    transcriptParser = TranscriptContainer(options.inputFileName, options.inputFormat, options.verbosity)
+    wigParser        = WigParser(options.wig)
+    writer           = Gff3Writer(options.outputFileName, options.verbosity)
+    wigParser.setStrands(options.strands)
+    
+    progress = Progress(transcriptParser.getNbTranscripts(), "Parsing %s" % (options.inputFileName), options.verbosity)
+    for transcript in transcriptParser.getIterator():
+        values = transcript.extractWigData(wigParser)
+        if options.strands:
+            values = values[transcript.getDirection()]
+        transcript.setTagValue(options.tag, str(float(sum(values)) / len(values)))
+        writer.addTranscript(transcript)
+        progress.inc()
+    progress.done()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getWigDistance.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,105 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Cluster the data into regions (defined by size and overlap with next region) and keep only highest peaks.
+"""
+
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from commons.core.parsing.WigParser import WigParser
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.RPlotter import RPlotter
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Get WIG Data v1.0.2: Compute the average data around some genomic coordinates using WIG files (thus covering a large proportion of the genome). [Category: WIG Tools]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",       dest="inputFileName",  action="store",                     type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--inputFormat", dest="inputFormat",    action="store",                     type="string", help="format of the input file [compulsory] [format: transcript file format]")
+    parser.add_option("-w", "--wig",         dest="wig",            action="store",                     type="string", help="wig file name [compulsory] [format: file in WIG format]")    
+    parser.add_option("-d", "--distance",    dest="distance",       action="store",      default=1000,  type="int",    help="distance around position [compulsory] [format: int] [default: 1000]")    
+    parser.add_option("-s", "--strands",     dest="strands",        action="store_true", default=False,                help="consider both strands separately [format: boolean] [default: False]")    
+    parser.add_option("-o", "--output",      dest="outputFileName", action="store",                     type="string", help="output file [compulsory] [format: output file in PNG format]")
+    parser.add_option("-a", "--default",     dest="defaultValue",   action="store",      default=0.0,   type="float",  help="default value (when value is NA) [default: 0.0] [format: float]")
+    parser.add_option("-l", "--log",         dest="log",            action="store_true", default=False,                help="use log scale for y-axis [format: boolean] [default: False]")
+    parser.add_option("-k", "--keep",        dest="keep",           action="store_true", default=False,                help="keep temporary files [format: boolean] [default: False]")
+    parser.add_option("-v", "--verbosity",   dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    # create parsers and writers
+    transcriptParser = TranscriptContainer(options.inputFileName, options.inputFormat, options.verbosity)
+    wigParser        = WigParser(options.wig)
+    wigParser.setStrands(options.strands)
+    wigParser.setDefaultValue(options.defaultValue)
+    
+    # allocate data
+    strands = (1, -1) if options.strands else (1, )
+    values    = {}
+    for strand in strands:
+        values[strand] = dict([(i, 0.0) for i in range(-options.distance, options.distance+1)])
+
+    # read transcripts
+    progress = Progress(transcriptParser.getNbTranscripts(), "Parsing %s" % (options.inputFileName), options.verbosity)
+    for transcript in transcriptParser.getIterator():
+        transcript.removeExons()
+        transcript.restrictStart(2)
+        transcript.extendStart(options.distance)
+        transcript.extendEnd(options.distance-1)
+        theseValues = transcript.extractWigData(wigParser)
+        if len(strands) == 1:
+            theseValues = {1: theseValues}
+        for strand in strands:
+            if len(theseValues[strand]) < 2 * options.distance + 1:
+                theseValues[strand] = [options.defaultValue] * (2 * options.distance + 1 - len(theseValues[strand])) + theseValues[strand]
+            if len(theseValues[strand]) != 2 * options.distance + 1:
+				raise Exception("Got something wrong with the size of the WIG data concerning %s: %d found instead of %d" % (transcript, len(theseValues[strand]), 2 * options.distance + 1))
+            for i in range(-options.distance, options.distance+1):
+                values[strand][i] += theseValues[strand][i + options.distance]
+        progress.inc()
+    progress.done()
+
+    for strand in strands:
+        for i in range(-options.distance, options.distance+1):
+            values[strand][i] /= transcriptParser.getNbTranscripts() * strand
+
+    # draw plot
+    plotter = RPlotter(options.outputFileName, options.verbosity, options.keep)
+    plotter.setXLabel("Distance")
+    plotter.setYLabel("WigValue")
+    for strand in strands:
+        plotter.addLine(values[strand])
+    if options.log:
+        plotter.setLog("y")
+    plotter.plot()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/getWigProfile.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,160 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Cluster the data into regions (defined by size and overlap with next region) and keep only highest peaks.
+"""
+
+import math
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from commons.core.parsing.WigParser import WigParser
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.RPlotter import RPlotter
+
+class GetWigProfile(object):
+
+	def __init__(self, verbosity):
+		self.verbosity	= verbosity
+		self.values		 = {}
+		self.defaultValue = 0.0
+
+	def _iToJ(self, i, size):
+		return min(self.nbPoints+1, int(math.floor(float(i - self.distance) / (size) * (self.nbPoints))))
+
+	def readTranscripts(self):
+		self.strandNames = (1, -1) if self.strands else (1, )
+		self.values		= dict([(strand, dict([(i, 0.0) for i in range(self.nbPoints + 2 * self.distance)])) for strand in self.strandNames])
+		transcriptParser = TranscriptContainer(self.inputFileName, self.inputFormat, self.verbosity)
+		wigParser		= WigParser(self.wig)
+		nbValues		 = dict([(strand, dict([(i, 0.0) for i in range(self.nbPoints + 2 * self.distance)])) for strand in self.strandNames])
+		wigParser.setStrands(self.strands)
+		wigParser.setDefaultValue(self.defaultValue)
+
+		progress = Progress(transcriptParser.getNbTranscripts(), "Parsing %s" % (self.inputFileName), self.verbosity)
+		for transcript in transcriptParser.getIterator():
+			transcriptSize = transcript.getSize()
+			expectedSize   = transcriptSize + 2 * self.distance
+			transcript.extendStart(self.distance)
+			transcript.extendEnd(self.distance)
+			theseValues = transcript.extractWigData(wigParser)
+
+			if len(self.strandNames) == 1:
+				theseValues = {1: theseValues}
+			for strand in self.strandNames:
+				if len(theseValues[strand]) < expectedSize:
+					theseValues[strand] = [self.defaultValue] * (expectedSize - len(theseValues[strand])) + theseValues[strand]
+				if len(theseValues[strand]) != expectedSize:
+					raise Exception("Got something wrong with the size of the WIG data concerning %s [%s]: %d found instead of %d" % (transcript, ",".join(["%d-%d" % (exon.getStart(), exon.getEnd()) for exon in transcript.getExons()]), len(theseValues[strand]), expectedSize))
+				fivePValues = theseValues[strand][: self.distance]
+				nbValues         = [0.0] * (self.nbPoints)
+				transcriptValues = [0.0] * (self.nbPoints)
+				for i in range(self.distance, len(theseValues[strand]) - self.distance):
+					startJ = self._iToJ(i, transcriptSize)
+					endJ   = max(startJ+1, self._iToJ(i+1, transcriptSize))
+					for j in range(startJ, endJ):
+						transcriptValues[j]	+= theseValues[strand][i]
+						nbValues[j] += 1
+				threePValues = theseValues[strand][-self.distance: ]
+				values = fivePValues + [self.defaultValue if nbValue == 0 else transcriptValue / nbValue for transcriptValue, nbValue in zip(transcriptValues, nbValues)] + threePValues
+				for i, value in enumerate(values):
+					self.values[strand][i] += value
+			progress.inc()
+		progress.done()
+
+		for strand in self.strandNames:
+			if strand == 0:
+				strand = 1
+			for i in range(self.nbPoints + 2 * self.distance):
+				self.values[strand][i] /= transcriptParser.getNbTranscripts() * strand
+
+
+	def smoothen(self):
+		if self.smoothenForce == None:
+			return
+		for strand in self.strandNames:
+			averageValues = {}
+			for center in range(self.distance, self.distance + self.nbPoints):
+				sum		= 0.0
+				nbValues = 0.0
+				for i in range(center - self.smoothenForce + 1, center + self.smoothenForce):
+					if i > self.distance and i < self.distance + self.nbPoints:
+						nbValues += 1
+						sum		+= self.values[strand][i]
+				averageValues[center] = sum / nbValues
+			for position in range(self.distance, self.distance + self.nbPoints):
+				self.values[strand][position] = averageValues[position]
+		
+
+	def plot(self):
+		plotter = RPlotter(self.outputFileName, self.verbosity)
+		for strand in self.strandNames:
+			plotter.addLine(self.values[strand])
+		if self.log:
+			plotter.setLog("y")
+		plotter.setAxisLabel("x", {0: -self.distance, self.distance: "start", self.distance+self.nbPoints-1: "end", 2*self.distance+self.nbPoints-1: self.distance})
+		plotter.plot()
+
+
+
+if __name__ == "__main__":
+	
+	# parse command line
+	description = "Get WIG Profile v1.0.1: Compute the average profile of some genomic coordinates using WIG files (thus covering a large proportion of the genome). [Category: WIG Tools]"
+
+	parser = OptionParser(description = description)
+	parser.add_option("-i", "--input",			 dest="inputFileName",	action="store",											type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+	parser.add_option("-f", "--inputFormat", dest="inputFormat",		action="store",											type="string", help="format of the input file [compulsory] [format: transcript file format]")
+	parser.add_option("-w", "--wig",				 dest="wig",						action="store",											type="string", help="wig file name [compulsory] [format: file in WIG format]")	
+	parser.add_option("-p", "--nbPoints",		 dest="nbPoints",				action="store",			 default=1000,	type="int",		 help="number of points on the x-axis [compulsory] [format: int] [default: 1000]")	
+	parser.add_option("-d", "--distance",		 dest="distance",				action="store",			 default=0,			type="int",		 help="distance around genomic coordinates [compulsory] [format: int] [default: 0]")	
+	parser.add_option("-s", "--strands",		 dest="strands",				action="store_true", default=False,								 help="consider both strands separately [format: boolean] [default: False]")	
+	parser.add_option("-m", "--smoothen",		 dest="smoothen",				action="store",			 default=None,	type="int",		 help="smoothen the curve [format: int] [default: None]")	
+	parser.add_option("-a", "--default",		 dest="defaultValue",	 action="store",			 default=0.0,	 type="float",	help="default value (when value is NA) [default: 0.0] [format: float]")
+	parser.add_option("-o", "--output",			 dest="outputFileName", action="store",											type="string", help="output file [compulsory] [format: output file in PNG format]")
+	parser.add_option("-l", "--log",				 dest="log",						action="store_true", default=False,								 help="use log scale for y-axis	[format: boolean] [default: False]")
+	parser.add_option("-v", "--verbosity",	 dest="verbosity",			action="store",			 default=1,			type="int",		 help="trace level [format: int]")
+	(options, args) = parser.parse_args()
+
+	wigProfile								= GetWigProfile(options.verbosity)
+	wigProfile.strands			 	= options.strands
+	wigProfile.inputFileName	= options.inputFileName
+	wigProfile.inputFormat		= options.inputFormat
+	wigProfile.wig						= options.wig
+	wigProfile.nbPoints				= options.nbPoints
+	wigProfile.distance				= options.distance
+	wigProfile.smoothenForce	= options.smoothen
+	wigProfile.defaultValue	  = options.defaultValue
+	wigProfile.outputFileName = options.outputFileName
+	wigProfile.log						= options.log
+
+	wigProfile.readTranscripts()
+	wigProfile.smoothen()
+	wigProfile.plot()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/mapperAnalyzer.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,486 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Read a mapping file (many formats supported) and select some of them
+Mappings should be sorted by read names
+"""
+import os, random, shelve
+from optparse import OptionParser, OptionGroup
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.parsing.FastaParser import FastaParser
+from commons.core.parsing.FastqParser import FastqParser
+from commons.core.parsing.GffParser import GffParser
+from commons.core.writer.BedWriter import BedWriter
+from commons.core.writer.UcscWriter import UcscWriter
+from commons.core.writer.GbWriter import GbWriter
+from commons.core.writer.Gff2Writer import Gff2Writer
+from commons.core.writer.Gff3Writer import Gff3Writer
+from commons.core.writer.FastaWriter import FastaWriter
+from commons.core.writer.FastqWriter import FastqWriter
+from commons.core.writer.MySqlTranscriptWriter import MySqlTranscriptWriter
+from SMART.Java.Python.mySql.MySqlConnection import MySqlConnection
+from SMART.Java.Python.mySql.MySqlTable import MySqlTable
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+
+
+distanceExons = 20
+exonSize      = 20
+
+
+class MapperAnalyzer(object):
+    """
+    Analyse the output of a parser
+    """
+
+    def __init__(self, verbosity = 0):
+        self.verbosity                = verbosity
+        self.mySqlConnection          = MySqlConnection(verbosity)
+        self.tooShort                 = 0
+        self.tooManyMismatches        = 0
+        self.tooManyGaps              = 0
+        self.tooShortExons            = 0
+        self.tooManyMappings          = 0
+        self.nbMappings               = 0
+        self.nbSequences              = 0
+        self.nbAlreadyMapped          = 0
+        self.nbAlreadyMappedSequences = 0
+        self.nbWrittenMappings        = 0
+        self.nbWrittenSequences       = 0
+        self.parser                   = None
+        self.logHandle                = None
+        self.randomNumber             = random.randint(0, 100000)
+        self.gff3Writer               = None
+        self.alreadyMappedReader      = None
+        self.unmatchedWriter          = None
+        self.sequenceListParser       = None
+        self.sequences                = None
+        self.alreadyMapped            = None
+        self.mappedNamesTable         = None
+        self.minSize                  = None
+        self.minId                    = None
+        self.maxMismatches            = None 
+        self.maxGaps                  = None 
+        self.maxMappings              = None 
+        self.merge                    = False
+        self.checkExons               = False
+        self.suffix                   = None
+        self.tmpDirectory             = "%s%s" % (os.environ["SMARTMPPATH"], os.sep) if "SMARTMPPATH" in os.environ else ""
+
+
+    def __del__(self):
+        if self.sequences != None:
+            self.sequences.close()
+        if self.alreadyMapped != None:
+            self.alreadyMapped.close()
+        if self.mappedNamesTable != None:
+            self.mappedNamesTable.remove()
+        if self.gff3Writer != None:
+            self.gff3Writer.close()
+
+        if self.logHandle != None:
+            self.logHandle.close()
+        
+
+    def setMappingFile(self, fileName, format):
+        parserChooser = ParserChooser(self.verbosity)
+        parserChooser.findFormat(format, "mapping")
+        self.parser = parserChooser.getParser(fileName)
+
+
+    def setSequenceFile(self, fileName, format):
+        if format == "fasta":
+            self.sequenceListParser = FastaParser(fileName, self.verbosity)
+        elif format == "fastq":
+            self.sequenceListParser = FastqParser(fileName, self.verbosity)
+        else:
+            raise Exception("Do not understand sequence format %s" % (format))
+
+    
+    def setOutputFile(self, fileName, title):
+        self.gff3Writer = Gff3Writer(fileName, self.verbosity)
+        self.gff3Writer.setTitle(title)
+
+    
+    def setAlreadyMatched(self, fileName):
+        self.alreadyMappedReader = GffParser(fileName, self.verbosity)
+
+
+    def setRemainingFile(self, fileName, format):
+        if format == "fasta":
+            self.unmatchedWriter = FastaWriter("%s_unmatched.fasta" % (fileName), self.verbosity)
+        elif format == "fastq":
+            self.unmatchedWriter = FastqWriter("%s_unmatched.fastq" % (fileName), self.verbosity)
+        else:
+            raise Exception("Do not understand %s format." % (format))
+        self.mappedNamesTable = MySqlTable(self.mySqlConnection, "mappedNames_%d" % (self.randomNumber), self.verbosity)
+        self.mappedNamesTable.create(["name"], {"name": "char"}, {"name": 50})
+        self.mappedNamesTable.createIndex("iNameMapped", ["name", ], True)
+
+
+    def setLog(self, fileName):
+        self.logHandle = open(fileName, "w")
+
+
+    def setMinSize(self, size):
+        self.minSize = size
+
+
+    def setMinId(self, id):
+        self.minId = id
+
+
+    def setMaxMismatches(self, mismatches):
+        self.maxMismatches = mismatches
+
+
+    def setMaxGaps(self, gaps):
+        self.maxGaps = gaps
+
+
+    def setMaxMappings(self, mappings):
+        self.maxMappings = mappings
+
+
+    def mergeExons(self, b):
+        self.merge = b
+
+
+    def acceptShortExons(self, b):
+        self.checkExons = not b
+
+
+    def countMappings(self):
+        self.nbMappings = self.parser.getNbMappings()
+        if self.verbosity > 0:
+            print "%i matches found" % (self.nbMappings)
+
+
+    def storeAlreadyMapped(self):
+        self.alreadyMapped            = shelve.open("%stmpAlreadyMapped_%d" % (self.tmpDirectory, self.randomNumber))
+        progress                      = Progress(self.alreadyMappedReader.getNbTranscripts(), "Reading already mapped reads", self.verbosity)
+        self.nbAlreadyMappedSequences = 0
+        for transcript in self.alreadyMappedReader.getIterator():
+            if not self.alreadyMapped.has_key(transcript.getName()):
+                self.alreadyMapped[transcript.getName()] = 1
+                self.nbAlreadyMappedSequences           += 1
+            progress.inc()
+        progress.done()
+        self.nbAlreadyMapped = self.alreadyMappedReader.getNbTranscripts()
+
+
+    def storeSequences(self):
+        self.sequences = shelve.open("%stmpSequences_%d" % (self.tmpDirectory, self.randomNumber))
+        progress       = Progress(self.sequenceListParser.getNbSequences(), "Reading sequences", self.verbosity)
+        for sequence in self.sequenceListParser.getIterator():
+            self.sequences[sequence.getName().split(" ")[0]] = len(sequence.getSequence())
+            self.nbSequences += 1
+            progress.inc()
+        progress.done()
+        if self.verbosity > 0:
+            print "%i sequences read" % (self.nbSequences)
+
+
+    def checkOrder(self):
+        names        = shelve.open("%stmpNames_%d" % (self.tmpDirectory, self.randomNumber))
+        previousName = None
+        progress = Progress(self.nbMappings, "Checking mapping file", self.verbosity)
+        for mapping in self.parser.getIterator():
+            name = mapping.queryInterval.getName()
+            if name != previousName and previousName != None:
+                if names.has_key(previousName):
+                    raise Exception("Error! Input mapping file is not ordered! (Name '%s' occurs at least twice)" % (previousName))
+                names[previousName] = 1
+                previousName        = name
+            progress.inc()
+        progress.done()
+        names.close()
+
+
+    def checkPreviouslyMapped(self, name):
+        if self.alreadyMappedReader == None:
+            return False
+        return self.alreadyMapped.has_key(name)
+
+
+    def findOriginalSize(self, name):
+        alternate    = "%s/1" % (name)
+        if (self.suffix == None) or (not self.suffix):
+            if self.sequences.has_key(name):
+                self.suffix = False
+                return self.sequences[name]
+            if self.suffix == None:
+                self.suffix = True
+            else:
+                raise Exception("Cannot find name %n" % (name))
+        if (self.suffix):
+            if self.sequences.has_key(alternate):
+                return self.sequences[alternate]        
+        raise Exception("Cannot find name %s" % (name))
+        
+
+    def checkErrors(self, mapping):
+        accepted = True
+        # short size
+        if self.minSize != None and mapping.size * 100 < self.minSize * mapping.queryInterval.size:
+            self.tooShort += 1
+            accepted    = False
+            if self.logHandle != None:
+                self.logHandle.write("size of mapping %s is too short (%i instead of %i)\n" % (str(mapping), mapping.queryInterval.size, mapping.size))
+        # low identity
+        if self.minId != None and mapping.getTagValue("identity") < self.minId:
+            self.tooManyMismatches += 1
+            accepted                = False
+            if self.logHandle != None:
+                self.logHandle.write("mapping %s has a low identity rate\n" % (str(mapping)))
+        # too many mismatches
+        if self.maxMismatches != None and mapping.getTagValue("nbMismatches") > self.maxMismatches:
+            self.tooManyMismatches += 1
+            accepted                = False
+            if self.logHandle != None:
+                self.logHandle.write("mapping %s has more mismatches than %i\n" % (str(mapping), self.maxMismatches))
+        # too many gaps
+        if self.maxGaps != None and mapping.getTagValue("nbGaps") > self.maxGaps:
+            self.tooManyGaps += 1
+            accepted         = False
+            if self.logHandle != None:
+                self.logHandle.write("mapping %s has more gaps than %i\n" % (str(mapping), self.maxGaps))
+        # short exons
+        if self.checkExons and len(mapping.subMappings) > 1 and min([subMapping.targetInterval.getSize() for subMapping in mapping.subMappings]) < exonSize:
+            self.tooShortExons += 1
+            accepted            = False
+            if self.logHandle != None:
+                self.logHandle.write("sequence %s maps as too short exons\n" % (mapping))
+        return accepted
+
+    
+    def checkNbMappings(self, mappings):
+        nbOccurrences = 0
+        for mapping in mappings:
+            nbOccurrences += 1 if "nbOccurrences" not in mapping.getTagNames() else mapping.getTagValue("nbOccurrences")
+        if (self.maxMappings != None and nbOccurrences > self.maxMappings):
+            self.tooManyMappings += 1
+            if self.logHandle != None:
+                self.logHandle.write("sequence %s maps %i times\n" % (mappings[0].queryInterval.getName(), nbOccurrences))
+            return False
+        return (nbOccurrences > 0)
+
+
+    def sortMappings(self, mappings):
+        nbOccurrences = 0
+        for mapping in mappings:
+            nbOccurrences += 1 if "nbOccurrences" not in mapping.getTagNames() else mapping.getTagValue("nbOccurrences")
+
+        orderedMappings = sorted(mappings, key = lambda mapping: mapping.getErrorScore())
+        cpt             = 1
+        rank            = 1
+        previousMapping = None
+        previousScore   = None
+        wasLastTie      = False
+        rankedMappings  = []
+        bestRegion      = "%s:%d-%d" % (orderedMappings[0].targetInterval.getChromosome(), orderedMappings[0].targetInterval.getStart(), orderedMappings[0].targetInterval.getEnd())
+        for mapping in orderedMappings:
+            mapping.setNbOccurrences(nbOccurrences)
+            mapping.setOccurrence(cpt)
+
+            score = mapping.getErrorScore()
+            if previousScore != None and previousScore == score:
+                if "Rank" in previousMapping.getTagNames():
+                    if not wasLastTie:
+                        previousMapping.setRank("%sTie" % (rank))
+                    mapping.setRank("%sTie" % (rank))
+                    wasLastTie = True
+            else:
+                rank = cpt
+                mapping.setRank(rank)
+                wasLastTie = False
+            if cpt != 1:
+                mapping.setBestRegion(bestRegion)
+
+            rankedMappings.append(mapping)
+            previousMapping = mapping
+            previousScore   = score
+            cpt            += 1
+        return rankedMappings
+
+
+    def processMappings(self, mappings):
+        if not mappings:
+            return
+        selectedMappings = []
+        name             = mappings[0].queryInterval.getName()
+        size             = self.findOriginalSize(name)
+        for mapping in mappings:
+            if self.merge:
+                mapping.mergeExons(distanceExons)
+            mapping.queryInterval.size = size
+            if self.checkErrors(mapping):
+                selectedMappings.append(mapping)
+
+        if self.checkNbMappings(selectedMappings):
+            if self.unmatchedWriter != None:
+                query = self.mySqlConnection.executeQuery("INSERT INTO %s (name) VALUES ('%s')" % (self.mappedNamesTable.name, name if not self.suffix else "%s/1" % (name)))
+            self.nbWrittenSequences += 1
+            mappings = self.sortMappings(selectedMappings)
+            for mapping in mappings:
+                self.nbWrittenMappings += 1
+                self.gff3Writer.addTranscript(mapping.getTranscript())
+
+
+    def readMappings(self):
+        previousQueryName = None
+        mappings          = []
+        self.parser.reset()
+        progress = Progress(self.nbMappings, "Reading mappings", self.verbosity)
+        for mapping in self.parser.getIterator():
+            queryName = mapping.queryInterval.getName().split(" ")[0]
+            if self.checkPreviouslyMapped(queryName):
+                if self.logHandle != None:
+                    self.logHandle.write("Mapping %s has already been mapped.\n" % (queryName))
+            else:
+                if previousQueryName == queryName:
+                    mappings.append(mapping)
+                else:
+                    if previousQueryName != None:
+                        self.processMappings(mappings)
+                    previousQueryName = queryName
+                    mappings          = [mapping, ]
+            progress.inc()
+        self.processMappings(mappings)
+        self.gff3Writer.write()
+        self.gff3Writer.close()
+        progress.done()
+        
+
+    def writeUnmatched(self):
+        progress = Progress(self.nbSequences, "Reading unmatched sequences", self.verbosity)
+        for sequence in self.sequenceListParser.getIterator():
+            name = sequence.getName().split(" ")[0]
+            query = self.mySqlConnection.executeQuery("SELECT * FROM %s WHERE name = '%s' LIMIT 1" % (self.mappedNamesTable.name, name))
+            if query.isEmpty():
+                self.unmatchedWriter.addSequence(sequence)
+            progress.inc()
+        progress.done() 
+
+
+    def analyze(self):
+        self.countMappings()
+        self.checkOrder()
+        self.storeSequences()
+        if self.alreadyMappedReader != None:
+            self.storeAlreadyMapped()
+        self.readMappings()
+        if self.unmatchedWriter != None:
+            self.writeUnmatched()
+
+
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Mapper Analyzer v1.0.1: Read the output of an aligner, print statistics and possibly translate into BED or GBrowse formats. [Category: Conversion]"
+
+    parser = OptionParser(description = description)
+    compGroup = OptionGroup(parser, "Compulsory options")
+    filtGroup = OptionGroup(parser, "Filtering options")
+    tranGroup = OptionGroup(parser, "Transformation options")
+    outpGroup = OptionGroup(parser, "Output options")
+    otheGroup = OptionGroup(parser, "Other options")
+    compGroup.add_option("-i", "--input",            dest="inputFileName",     action="store",                        type="string", help="input file (output of the tool) [compulsory] [format: file in mapping format given by -f]")
+    compGroup.add_option("-f", "--format",           dest="format",            action="store",      default="seqmap", type="string", help="format of the file [compulsory] [format: mapping file format]")
+    compGroup.add_option("-q", "--sequences",        dest="sequencesFileName", action="store",                        type="string", help="file of the sequences [compulsory] [format: file in sequence format given by -k]")
+    compGroup.add_option("-k", "--seqFormat",        dest="sequenceFormat",    action="store",      default="fasta",  type="string", help="format of the sequences: fasta or fastq [default: fasta] [format: sequence file format]")
+    compGroup.add_option("-o", "--output",           dest="outputFileName",    action="store",                        type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    filtGroup.add_option("-n", "--number",           dest="number",            action="store",      default=None,     type="int",    help="max. number of occurrences of a sequence [format: int]")
+    filtGroup.add_option("-s", "--size",             dest="size",              action="store",      default=None,     type="int",    help="minimum pourcentage of size [format: int]")
+    filtGroup.add_option("-d", "--identity",         dest="identity",          action="store",      default=None,     type="int",    help="minimum pourcentage of identity [format: int]")
+    filtGroup.add_option("-m", "--mismatch",         dest="mismatch",          action="store",      default=None,     type="int",    help="maximum number of mismatches [format: int]")
+    filtGroup.add_option("-p", "--gap",              dest="gap",               action="store",      default=None,     type="int",    help="maximum number of gaps [format: int]")
+    tranGroup.add_option("-e", "--mergeExons",       dest="mergeExons",        action="store_true", default=False,                   help="merge exons when introns are short [format: bool] [default: false]")
+    tranGroup.add_option("-x", "--removeExons",      dest="removeExons",       action="store_true", default=False,                   help="remove transcripts when exons are short [format: bool] [default: false]")
+    outpGroup.add_option("-t", "--title",            dest="title",             action="store",      default="SMART",  type="string", help="title of the UCSC track [format: string] [default: SMART]")
+    outpGroup.add_option("-r", "--remaining",        dest="remaining",         action="store_true", default=False,                   help="print the unmatched sequences [format: bool] [default: false]")
+    otheGroup.add_option("-a", "--append",           dest="appendFileName",    action="store",      default=None,     type="string", help="append to GFF3 file [format: file in GFF3 format]")    
+    otheGroup.add_option("-v", "--verbosity",        dest="verbosity",         action="store",      default=1,        type="int",    help="trace level [default: 1] [format: int]")
+    otheGroup.add_option("-l", "--log",              dest="log",               action="store_true", default=False,                   help="write a log file [format: bool] [default: false]")
+    parser.add_option_group(compGroup)
+    parser.add_option_group(filtGroup)
+    parser.add_option_group(tranGroup)
+    parser.add_option_group(outpGroup)
+    parser.add_option_group(otheGroup)
+    (options, args) = parser.parse_args()
+
+    
+    analyzer = MapperAnalyzer(options.verbosity)
+    analyzer.setMappingFile(options.inputFileName, options.format)
+    analyzer.setSequenceFile(options.sequencesFileName, options.sequenceFormat)
+    analyzer.setOutputFile(options.outputFileName, options.title)
+    if options.appendFileName != None:
+        analyzer.setAlreadyMatched(options.appendFileName)
+    if options.remaining:
+        analyzer.setRemainingFile(options.outputFileName, options.sequenceFormat)
+    if options.number != None:
+        analyzer.setMaxMappings(options.number)
+    if options.size != None:
+        analyzer.setMinSize(options.size)
+    if options.identity != None:
+        analyzer.setMinId(options.identity)
+    if options.mismatch != None:
+        analyzer.setMaxMismatches(options.mismatch)
+    if options.gap != None:
+        analyzer.setMaxGaps(options.gap)
+    if options.mergeExons:
+        analyzer.mergeExons(True)
+    if options.removeExons:
+        analyzer.acceptShortExons(False)
+    if options.log:
+        analyzer.setLog("%s.log" % (options.outputFileName))
+    analyzer.analyze()
+    
+    if options.verbosity > 0:
+        print "kept %i sequences over %s (%f%%)" % (analyzer.nbWrittenSequences, analyzer.nbSequences, float(analyzer.nbWrittenSequences) / analyzer.nbSequences * 100)
+        if options.appendFileName != None:
+            print "kept %i sequences over %s (%f%%) including already mapped sequences" % (analyzer.nbWrittenSequences + analyzer.nbAlreadyMappedSequences, analyzer.nbSequences, float(analyzer.nbWrittenSequences + analyzer.nbAlreadyMappedSequences) / analyzer.nbSequences * 100)
+        print "kept %i mappings over %i (%f%%)" % (analyzer.nbWrittenMappings, analyzer.nbMappings, float(analyzer.nbWrittenMappings) / analyzer.nbMappings * 100)
+        if options.appendFileName != None:
+            print "kept %i mappings over %i (%f%%) including already mapped" % (analyzer.nbWrittenMappings + analyzer.nbAlreadyMapped, analyzer.nbMappings, float(analyzer.nbWrittenMappings + analyzer.nbAlreadyMapped) / analyzer.nbMappings * 100)
+        print "removed %i too short mappings (%f%%)" % (analyzer.tooShort, float(analyzer.tooShort) / analyzer.nbMappings * 100)
+        print "removed %i mappings with too many mismatches (%f%%)" % (analyzer.tooManyMismatches, float(analyzer.tooManyMismatches) / analyzer.nbMappings * 100)
+        print "removed %i mappings with too many gaps (%f%%)" % (analyzer.tooManyGaps, float(analyzer.tooManyGaps) / analyzer.nbMappings * 100)
+        print "removed %i mappings with too short exons (%f%%)" % (analyzer.tooShortExons, float(analyzer.tooShortExons) / analyzer.nbMappings * 100)
+        print "removed %i sequences with too many hits (%f%%)" % (analyzer.tooManyMappings, float(analyzer.tooManyMappings) / analyzer.nbSequences * 100)
+        print "%i sequences have no mapping (%f%%)" % (analyzer.nbSequences - analyzer.nbWrittenSequences, float(analyzer.nbSequences - analyzer.nbWrittenSequences) / analyzer.nbSequences * 100)
+        if options.appendFileName != None:
+            print "%i sequences have no mapping (%f%%) excluding already mapped sequences" % (analyzer.nbSequences - analyzer.nbWrittenSequences - analyzer.nbAlreadyMappedSequences, float(analyzer.nbSequences - analyzer.nbWrittenSequences - analyzer.nbAlreadyMappedSequences) / analyzer.nbSequences * 100)
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/mappingToCoordinates.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,91 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+
+"""Convert files with some mapping format to coordinates format"""
+
+import os
+from optparse import OptionParser
+from commons.core.parsing.PslParser import PslParser
+from commons.core.parsing.AxtParser import AxtParser
+from commons.core.writer.Gff3Writer import Gff3Writer
+from commons.core.writer.MySqlTranscriptWriter import MySqlTranscriptWriter
+from SMART.Java.Python.structure.TranscriptListsComparator import TranscriptListsComparator
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.misc.Progress import Progress
+
+
+class MappingToCoordinates(object):
+    def __init__(self,verbosity=1, inputFileName=None, format = None, output=None,galaxy = False, title="S-MART"):
+        self.verbosity = verbosity
+        self.inputFileName = inputFileName
+        self.format = format
+        self.output = output
+        self.galaxy = galaxy
+        self.title = title
+    
+    def setAttributesFromCmdLine(self):
+        description = "Mapping To Coordinates v1.0.1: Convert a set of mappings (given by a mapping tool) to a set of transcripts. [Category: Conversion]"
+        parser = OptionParser(description = description)
+        parser.add_option("-i", "--input",     dest="inputFileName", action="store",                     type="string", help="input file [compulsory] [format: file in mapping format given by -f]")
+        parser.add_option("-f", "--format",    dest="format",        action="store",                     type="string", help="format of file [compulsory] [format: mapping file format]")
+        parser.add_option("-o", "--output",    dest="output",        action="store",      default=None,  type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+        parser.add_option("-v", "--verbosity", dest="verbosity",     action="store",      default=1,     type="int",    help="trace level [format: int]")
+        parser.add_option("-G", "--galaxy",    dest="galaxy",        action="store_true", default=False,                help="used for galaxy [format: bool] [default: False]")    
+        (options, args) = parser.parse_args()
+    
+        self.verbosity = options.verbosity
+        self.inputFileName = options.inputFileName
+        self.format = options.format
+        self.output = options.output
+        self.galaxy = options.galaxy
+
+    def run(self):  
+        if self.verbosity > 0:
+            print "Reading input file..."
+        parser = TranscriptContainer(self.inputFileName, self.format, self.verbosity)
+        if self.verbosity > 0:
+            print "... done"
+        writer = Gff3Writer(self.output, self.verbosity, self.title)
+            
+        progress = Progress(parser.getNbTranscripts(), "Reading %s" % (self.inputFileName), self.verbosity)
+        for transcript in parser.getIterator():
+            writer.addTranscript(transcript)
+            progress.inc()
+        progress.done()
+        
+        if self.galaxy:
+            os.rename("%s.gff3" % (self.output), self.output) 
+            
+if __name__ == '__main__':
+    launcher = MappingToCoordinates()
+    launcher.setAttributesFromCmdLine()
+    launcher.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/mergeSlidingWindowsClusters.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,144 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Merge sliding windows of two different clusterings
+"""
+
+import sys
+import re
+import os
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.structure.Transcript import Transcript
+
+class MergeSlidingWindowsClusters(object):
+    """
+    Merge the ouptput of several sets of sliding windows
+    """
+
+    def __init__(self, verbosity = 0):
+        self.verbosity     = verbosity
+        self.inputs        = []
+        self.outputData    = {}
+        self.nbData        = 0
+        self.nbWrittenData = 0
+        self.chromosomes   = []
+        self.writer        = None
+
+    def __del__(self):
+        if self.writer != None:
+            self.writer.close()
+
+    def addInput(self, fileName, fileFormat):
+        self.inputs.append(TranscriptContainer(fileName, fileFormat, self.verbosity))
+        self.chromosomes = list(set(self.chromosomes).union(set(self.inputs[-1].getChromosomes())))
+
+    def setOutput(self, fileName):
+        self.writer = Gff3Writer(fileName, self.verbosity)
+
+    def readInput(self, i, chromosome):
+        progress = Progress(self.inputs[i].getNbTranscripts(), "Reading file #%d -- chromosome %s" % (i+1, chromosome), self.verbosity)
+        for transcript in self.inputs[i].getIterator():
+            progress.inc()
+            if chromosome != transcript.getChromosome(): continue
+            start     = transcript.getStart()
+            end       = transcript.getEnd()
+            direction = transcript.getDirection()
+            tags      = transcript.tags
+            if chromosome not in self.outputData:
+                self.outputData[chromosome] = {}
+            if direction not in self.outputData[chromosome]:
+                self.outputData[chromosome][direction] = {}
+            if start not in self.outputData[chromosome][direction]:
+                self.outputData[chromosome][direction][start] = {}
+            if end in self.outputData[chromosome][direction][start]:
+                ends = self.outputData[chromosome][direction][start].keys()
+                if ends[0] != end:
+                    sys.exit("Error! Two regions starting at %d end are not consistent (%d and %d) in %s on strand %d" % (start, end, ends[0], chromosome, direction))
+                self.outputData[chromosome][direction][start][end].update(tags)
+            else:
+                self.outputData[chromosome][direction][start][end] = tags
+                self.nbData += 1
+        progress.done()
+
+
+    def writeOutput(self, chromosome):
+        progress = Progress(self.nbData - self.nbWrittenData, "Writing output for chromosome %s" % (chromosome), self.verbosity)
+        for direction in self.outputData[chromosome]:
+            for start in self.outputData[chromosome][direction]:
+                for end in self.outputData[chromosome][direction][start]:
+                    transcript = Transcript()
+                    transcript.setChromosome(chromosome)
+                    transcript.setStart(start)
+                    transcript.setEnd(end)
+                    transcript.setDirection(direction)
+                    transcript.tags = self.outputData[chromosome][direction][start][end]
+                    transcript.setName("region_%d" % (self.nbWrittenData + 1))
+                    tags = transcript.getTagNames()
+                    for tag in tags:
+                        if tag.startswith("Name_") or tag.startswith("ID_"):
+                            del transcript.tags[tag]
+                    self.nbWrittenData += 1
+                    self.writer.addTranscript(transcript)
+                    progress.inc()
+        self.writer.write()
+        progress.done()
+        self.outputData = {}
+
+    def merge(self):
+        for chromosome in self.chromosomes:
+            for i, input in enumerate(self.inputs):
+                self.readInput(i, chromosome)
+            self.writeOutput(chromosome)
+        self.writer.close()
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Merge Sliding Windows Clusters v1.0.2: Merge two files containing the results of a sliding windows clustering. [Category: Sliding Windows]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input1",       dest="inputFileName1", action="store",                     type="string", help="input file 1 [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--inputFormat1", dest="inputFormat1",   action="store",                     type="string", help="format of the input file 1 [compulsory] [format: transcript file format]")
+    parser.add_option("-j", "--input2",       dest="inputFileName2", action="store",                     type="string", help="input file 2 [compulsory] [format: file in transcript format given by -g]")
+    parser.add_option("-g", "--inputFormat2", dest="inputFormat2",   action="store",                     type="string", help="format of the input file 2 [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",       dest="outputFileName", action="store",                     type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-v", "--verbosity",    dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    merger = MergeSlidingWindowsClusters(options.verbosity)
+    merger.addInput(options.inputFileName1, options.inputFormat1)
+    merger.addInput(options.inputFileName2, options.inputFormat2)
+    merger.setOutput(options.outputFileName)
+    merger.merge()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/mergeTranscriptLists.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,174 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Merge elements of two transcript lists with some condition"""
+
+import os, random, shutil, glob
+from optparse import OptionParser
+from commons.core.parsing.SequenceListParser import SequenceListParser
+from commons.core.parsing.BedParser import BedParser
+from commons.core.parsing.GffParser import GffParser
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.structure.TranscriptListsComparator import TranscriptListsComparator
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from SMART.Java.Python.misc.Progress import Progress
+
+
+
+class MergeLists(object):
+
+    def __init__(self, verbosity):
+        self.verbosity     = verbosity
+        self.seed          = random.randint(0, 100000)
+        self.aggregation   = False
+        self.normalization = False
+        self.distance      = False
+        self.antisense     = False
+        self.colinear      = False
+        self.fileNames     = {}
+        self.formats       = {}
+        self.tmpFileNames  = []
+        self.logHandle     = None
+
+#    def __del__(self):
+#        for fileNameRoot in self.tmpFileNames:
+#            for fileName in glob.glob("%s*" % (fileNameRoot)):
+#                os.remove(fileName)
+#        if self.logHandle != None:
+#            self.logHandle.close()
+#            self.logHandle = None
+
+    def setLogFileName(self, fileName):
+        self.logHandle = open(fileName, "w")
+
+    def setInputFileName(self, fileName, format, id):
+        self.fileNames[id] = fileName
+        self.formats[id]   = format
+
+    def setOutputFileName(self, fileName):
+        self.outputFileName = fileName
+
+    def setAggregate(self, aggregation):
+        self.aggregation = aggregation
+
+    def setNormalization(self, normalization):
+        self.normalization = normalization
+
+    def setDistance(self, distance):
+        self.distance = distance
+
+    def setAntisense(self, antisense):
+        self.antisense = antisense
+
+    def setColinear(self, colinear):
+        self.colinear = colinear
+
+    def createTmpFileName(self, root):
+        fileName = "tmp_%s_%d.gff3" % (root, self.seed)
+        self.tmpFileNames.append(fileName)
+        return fileName
+
+    def selfMerge(self, fileName, format, outputFileName):
+        transcriptListComparator = TranscriptListsComparator(self.logHandle, self.verbosity)
+        transcriptListComparator.getColinearOnly(True)
+        transcriptListComparator.setNormalization(self.normalization)
+        transcriptContainer = TranscriptContainer(fileName, format, self.verbosity)
+        writer              = TranscriptWriter(outputFileName, "gff3", self.verbosity)
+        transcriptListComparator.setInputTranscriptContainer(transcriptListComparator.QUERY, transcriptContainer)
+        transcriptListComparator.setOutputWriter(writer)
+        transcriptListComparator.compareTranscriptListSelfMerge()
+
+    def keepOverlapping(self, fileNames, formats, outputFileName):
+        transcriptListComparator = TranscriptListsComparator(self.logHandle, self.verbosity)
+        transcriptListComparator.getAntisenseOnly(self.antisense)
+        transcriptListComparator.getColinearOnly(self.colinear)
+        for i in (0, 1):
+            transcriptContainer = TranscriptContainer(fileNames[i], formats[i], self.verbosity)
+            transcriptListComparator.setInputTranscriptContainer(i, transcriptContainer)
+        transcriptListComparator.aggregate(self.aggregation)
+        transcriptListComparator.setNormalization(self.normalization)
+        transcriptListComparator.setMaxDistance(self.distance)
+        writer = TranscriptWriter(outputFileName, "gff3", self.verbosity)
+        transcriptListComparator.setOutputWriter(writer)
+        transcriptListComparator.compareTranscriptList()
+
+    def mergeFiles(self, fileName1, fileName2, outputFileName):
+        outputFile = open(outputFileName, "w")
+        shutil.copyfileobj(open(fileName1, "r"), outputFile)
+        shutil.copyfileobj(open(fileName2, "r"), outputFile)
+        outputFile.close()
+
+    def run(self):
+        selectedFileQuery = self.createTmpFileName("query")
+        self.keepOverlapping({0: self.fileNames[0], 1: self.fileNames[0]}, {0: "gff3", 1: "gff3"}, selectedFileQuery)
+        mergeFileTarget = self.createTmpFileName("target")
+        self.selfMerge(self.fileNames[1], self.formats[1], mergeFileTarget)
+        if not self.aggregation:
+            overlapFile = self.createTmpFileName("overlap")
+            self.keepOverlapping({0: mergeFileTarget, 1: selectedFileQuery}, {0: "gff3", 1: "gff3"}, overlapFile)
+            mergeFileTarget = overlapFile
+        mergeFileMerged = self.createTmpFileName("merged")
+        self.mergeFiles(mergeFileTarget, selectedFileQuery, mergeFileMerged)
+        self.selfMerge(mergeFileMerged, "gff3", self.outputFileName)
+
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Merge Lists v1.0.3: Merge the elements of two lists of genomic coordinates. [Category: Merge]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input1",    dest="inputFileName1", action="store",                       type="string", help="input file 1 [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format1",   dest="format1",        action="store",                       type="string", help="format of file 1 [compulsory] [format: transcript file format]")
+    parser.add_option("-j", "--input2",    dest="inputFileName2", action="store",      default=None,    type="string", help="input file 2 [compulsory] [format: file in transcript format given by -g]")
+    parser.add_option("-g", "--format2",   dest="format2",        action="store",      default=None,    type="string", help="format of file 2 [compulsory] [format: file in transcript format]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",      default=None,    type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-k", "--all",       dest="all",            action="store_true", default=False,                  help="print all the transcripts, not only those overlapping [format: bool] [default: false]")
+    parser.add_option("-d", "--distance",  dest="distance",       action="store",      default=0,       type="int",    help="max. distance between two transcripts [format: int] [default: 0]")
+    parser.add_option("-a", "--antisense", dest="antisense",      action="store_true", default=False,                  help="antisense only [format: bool] [default: false]")
+    parser.add_option("-c", "--colinear",  dest="colinear",       action="store_true", default=False,                  help="colinear only [format: bool] [default: false]")
+    parser.add_option("-n", "--normalize", dest="normalize",      action="store_true", default=False,                  help="normalize the number of reads per cluster by the number of mappings per read [format: bool] [default: false]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store",      default=1,       type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+#    ml = MergeLists(logHandle, options.verbosity)
+    
+    ml = MergeLists(0)
+    ml.setInputFileName(options.inputFileName1, options.format1, 0)
+    ml.setInputFileName(options.inputFileName2, options.format2, 1)
+    ml.setOutputFileName(options.outputFileName)
+    ml.setAntisense(options.antisense)
+    ml.setColinear(options.colinear)
+    ml.setAggregate(options.all)
+    ml.setNormalization(options.normalize)
+    ml.setDistance(options.distance)
+    ml.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/misc/MultipleRPlotter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,160 @@
+#
+# Copyright INRA-URGI 2009-2012
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+import os
+import subprocess
+import random
+import math
+from SMART.Java.Python.misc.RPlotter import RPlotter
+
+NBCOLORS = 9
+
+"""
+Plot multiple curves with RPlotter
+"""
+
+class MultipleRPlotter(object):
+	"""
+	Plot some curves
+	@ivar fileName: name of the file
+	@type fileName: string
+	@ivar height: height of the file
+	@type height: int
+	@ivar width: width of the file
+	@type width: int
+	@ivar plots: plots to be included
+	@type plots: list of L{RPlotter{RPlotter}}
+	@ivar keep: keep script lines
+	@type keep: boolean
+	@ivar format: format of the file
+	@type format: string
+	"""
+
+	def __init__(self, fileName, verbosity = 0, keep = False):
+		"""
+		Constructor
+		@param fileName: name of the file to produce
+		@type  fileName: string
+		@param verbosity: verbosity
+		@type  verbosity: int
+		@param keep: keep temporary files
+		@type  keep: boolean
+		"""
+		self.fileName = fileName
+		self.verbosity = verbosity
+		self.keep = keep
+		self.format	= "png"
+		self.width = 1000
+		self.height	= 500
+		self.plots = []
+		self.scriptFileName = "tmpScript-%d.R" % (os.getpid())
+	
+	def __del__(self):
+		"""
+		Destructor
+		Remove script files
+		"""
+		if not self.keep:
+			if os.path.exists(self.scriptFileName):
+				os.remove(self.scriptFileName)
+			outputFileName = "%sout" % (self.scriptFileName)
+			if os.path.exists(outputFileName):
+				os.remove(outputFileName)
+
+	def setFormat(self, format):
+		"""
+		Set the format of the picture
+		@param format: the format
+		@type format: string
+		"""
+		if format not in ("png", "pdf", "jpeg", "bmp", "tiff"):
+			raise Exception("Format '%s' is not supported by RPlotter" % (format))
+		self.format = format
+
+
+	def setWidth(self, width):
+		"""
+		Set the dimensions of the image produced
+		@param width: width of the image
+		@type width: int
+		"""
+		self.width = width
+		
+		
+	def setHeight(self, height):
+		"""
+		Set the dimensions of the image produced
+		@param height: heigth of the image
+		@type height: int
+		"""
+		self.height = height
+		
+		
+	def setImageSize(self, width, height):
+		"""
+		Set the dimensions of the image produced
+		@param width: width of the image
+		@type width: int
+		@param height: heigth of the image
+		@type height: int
+		"""
+		self.width = width
+		self.height = height
+		
+	def addPlot(self, plot):
+		"""
+		Add a plot
+		@param plots: plot to be included
+		@type  plots: L{RPlotter{RPlotter}}
+		"""
+		self.plots.append(plot)
+
+	def plot(self):
+		"""
+		Plot the figures
+		"""
+		scriptHandle = open(self.scriptFileName, "w")
+		scriptHandle.write("library(RColorBrewer)\n")
+		scriptHandle.write("colorPanel = brewer.pal(n=%d, name=\"Set1\")\n" % (NBCOLORS))
+		scriptHandle.write("%s(%s = \"%s\", width = %d, height = %d, bg = \"white\")\n" % (self.format, "filename" if self.format != "pdf" else "file", self.fileName, self.width, self.height))
+		scriptHandle.write("par(mfrow=c(%d, 1))\n" % (len(self.plots)))
+		for plot in self.plots:
+			scriptHandle.write(plot.getScript())
+		scriptHandle.write("dev.off()\n")
+		scriptHandle.close()
+		rCommand = "R"
+		if "SMARTRPATH" in os.environ:
+			rCommand = os.environ["SMARTRPATH"]
+		command = "\"%s\" CMD BATCH %s" % (rCommand, self.scriptFileName)
+		status = subprocess.call(command, shell=True)
+		if status != 0:
+			self.keep = True
+			raise Exception("Problem with the execution of script file %s, status is: %s" % (self.scriptFileName, status))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/misc/Progress.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,93 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+import time
+
+class Progress(object):
+    """Show the progress of a process"""
+
+    def __init__(self, aim, message = "Progress", verbosity = 0):
+        self.aim            = aim
+        self.progress       = 0
+        self.message        = message
+        self.length         = -1
+        self.verbosity      = verbosity
+        self.maxMessageSize = 50
+        self.barSize        = 80
+        self.startTime      = time.time()
+        self.elapsed        = 0
+        if len(self.message) > self.maxMessageSize:
+            self.message = self.message[0:self.maxMessageSize-3] + "..."
+        self.show()
+
+
+    def inc(self):
+        self.progress += 1
+        self.show()
+        
+        
+    def getPrintableElapsedTime(self, time):
+        timeHou = int(time) / 3600
+        timeMin = int(time) / 60 - 60 * timeHou
+        timeSec = int(time) % 60
+        if timeHou > 0:
+            return "%3dh %2dm" % (timeHou, timeMin)
+        if timeMin > 0:
+            return "%2dm %2ds" % (timeMin, timeSec)
+        return "%2ds   " % (timeSec)
+
+
+    def show(self):
+        if self.verbosity <= 0:
+            return
+        if self.aim == 0:
+            return
+        messageSize = len(self.message)
+        length = int(self.progress / float(self.aim) * self.barSize)
+        elapsed = int(time.time() - self.startTime)
+        if (length > self.length) or (elapsed > self.elapsed + 10):
+            self.length = length
+            self.elapsed = elapsed            
+            string = "%s%s[%s%s] %d/%d" % (self.message, " " * max(0, self.maxMessageSize - messageSize), "=" * self.length, " " * (self.barSize - self.length), self.progress, self.aim)
+            if elapsed > 5:
+                done = float(self.progress) / self.aim
+                total = elapsed / done
+                remaining = total - elapsed
+                string += " ETA: %s " % (self.getPrintableElapsedTime(remaining))
+            string += "\r"
+            sys.stdout.write(string)
+            sys.stdout.flush()
+
+
+    def done(self):
+        if self.verbosity > 0:
+            messageSize = len(self.message)
+            elapsed = time.time() - self.startTime
+            print "%s%s[%s] %d completed in %s " % (self.message, " " * max(0, self.maxMessageSize - messageSize), "=" * self.barSize, self.aim, self.getPrintableElapsedTime(elapsed))
Binary file smart_toolShed/SMART/Java/Python/misc/Progress.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/misc/RPlotter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,820 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+import os
+import subprocess
+import random
+import math
+
+minPositiveValue = 10e-6
+
+"""
+Plot simple curves in R
+"""
+
+class RPlotter(object):
+    """
+    Plot some curves
+    @ivar nbColors: number of different colors
+    @type nbColors: int
+    @ivar fileName: name of the file
+    @type fileName: string
+    @ivar lines: lines to be plotted
+    @type lines: array of dict
+    @ivar names: name of the lines
+    @type names: array of strings
+    @ivar colors: color of the lines
+    @type colors: array of strings
+    @ivar types: type of the lines (plain or dashed)
+    @type types: array of strings
+    @ivar format: format of the picture
+    @type format: string
+    @ivar lineWidth: width of the line in a xy-plot
+    @type lineWidth: int
+    @ivar xMin: minimum value taken on the x-axis
+    @type xMin: int
+    @ivar xMax: maximum value taken on the x-axis
+    @type xMax: int
+    @ivar yMin: minimum value taken on the y-axis
+    @type yMin: int
+    @ivar yMax: maximum value taken on the y-axis
+    @type yMax: int
+    @ivar minimumX: minimum value allowed on the x-axis
+    @type minimumX: int
+    @ivar maximumX: maximum value allowed on the x-axis
+    @type maximumX: int
+    @ivar minimumY: minimum value allowed on the y-axis
+    @type minimumY: int
+    @ivar maximumY: maximum value allowed on the y-axis
+    @type maximumY: int
+    @ivar leftMargin:  add some margin in the left part of the plot
+    @type leftMargin:  float
+    @ivar rightMargin: add some margin in the right part of the plot
+    @type rightMargin: float
+    @ivar downMargin:  add some margin at the top of the plot
+    @type downMargin:  float
+    @ivar upMargin:    add some margin at the bottom of the plot
+    @type upMargin:    float
+    @ivar logX: use log scale on the x-axis
+    @type logX: boolean
+    @ivar logY: use log scale on the y-axis
+    @type logY: boolean
+    @ivar logZ: use log scale on the z-axis (the color)
+    @type logZ: boolean
+    @ival fill: if a value is not given, fill it with given value
+    @type fill: int
+    @ival bucket: cluster the data into buckets of given size
+    @type bucket: int
+    @ival seed: a random number
+    @type seed: int
+    @ival regression: plot a linear regression
+    @type regression: boolean
+    @ival legend: set the legend
+    @type legend: boolean
+    @ival legendBySide: set the legend outside of the plot
+    @type legendBySde: boolean
+    @ival xLabel: label for the x-axis
+    @type xLabel: string
+    @ival yLabel: label for the y-axis
+    @type yLabel: string
+    @ival title: title of the plot
+    @type title: string
+    @ival barplot: use a barplot representation instead
+    @type barplot: boolean
+    @ival points: use a point cloud instead
+    @type points: boolean
+    @ival heatPoints: use a colored point cloud instead
+    @type heatPoints: boolean
+    @ival axesLabels: change the names of the axes
+    @type axesLabels: vector of 2 int to string dict
+    @ival rotateAxesLabels: rotate the axes labels
+    @type rotateAxesLabels: dict of 2 boolean
+    @ival verbosity: verbosity of the class
+    @type verbosity: int
+    @ival keep: keep temporary files
+    @type keep: boolean
+    """
+
+    def __init__(self, fileName, verbosity = 0, keep = False):
+        """
+        Constructor
+        @param fileName: name of the file to produce
+        @type    fileName: string
+        @param verbosity: verbosity
+        @type    verbosity: int
+        @param keep: keep temporary files
+        @type keep: boolean
+        """
+        self.nbColors = 9
+        self.fileName = fileName
+        self.verbosity = verbosity
+        self.keep = keep
+        self.format = "png"
+        self.fill = None
+        self.bucket = None
+        self.lines = []
+        self.names = []
+        self.colors = []
+        self.types = []
+        self.lineWidth = 1
+        self.xMin = None
+        self.xMax = None
+        self.yMin = None
+        self.yMax = None
+        self.seed = random.randint(0, 10000)
+        self.minimumX = None
+        self.maximumX = None
+        self.minimumY = None
+        self.maximumY = None
+        self.leftMargin   = 0
+        self.rightMargin  = 0
+        self.topMargin    = 0
+        self.bottomMargin = 0
+        self.logX = False
+        self.logY = False
+        self.logZ = False
+        self.regression = False
+        self.width = 1000
+        self.height = 500
+        self.legend = False
+        self.legendBySide = False
+        self.xLabel = ""
+        self.yLabel = ""
+        self.title = None
+        self.points = False
+        self.heatPoints = False
+        self.barplot = False
+        self.axesLabels = {1: None, 2: None}
+        self.rotateAxesLabels = {1: False, 2: False}
+        self.linesToAddBox = ""
+    
+    def __del__(self):
+        """
+        Destructor
+        Remove tmp files
+        """
+        if not self.keep:
+            scriptFileName = "tmpScript-%d.R" % (self.seed)
+            if os.path.exists(scriptFileName):
+                os.remove(scriptFileName)
+            outputFileName = "%sout" % (scriptFileName)
+            if os.path.exists(outputFileName):
+                os.remove(outputFileName)
+            nbLines = len(self.lines) + (1 if self.heatPoints else 0)
+            for i in range(nbLines):
+                if os.path.exists("tmpData-%d-%d.dat" % (self.seed, i)):
+                    os.remove("tmpData-%d-%d.dat" % (self.seed, i))
+
+        
+    def setMinimumX(self, xMin):
+        """
+        Set the minimum value on the x-axis
+        @param xMin:minimum value on the x-axis
+        @type xMin: int
+        """
+        self.minimumX = xMin
+
+        
+    def setMaximumX(self, xMax):
+        """
+        Set the maximum value on the x-axis
+        @param xMax: maximum value on the x-axis
+        @type xMax: int
+        """
+        self.maximumX = xMax
+        
+    
+    def setMinimumY(self, yMin):
+        """
+        Set the minimum value on the y-axis
+        @param yMin: minimum value on the y-axis
+        @type yMin: int
+        """
+        self.minimumY = yMin
+
+        
+    def setMaximumY(self, yMax):
+        """
+        Set the maximum value on the y-axis
+        @param yMax: maximum value on the y-axis
+        @type xmax: int
+        """
+        self.maximumY = yMax
+        
+    
+    def setFill(self, fill):
+        """
+        Fill empty data with given value
+        @param fill: the value to fill with
+        @type fill: int
+        """
+        self.fill = fill
+
+
+    def setBuckets(self, bucket):
+        """
+        Cluster the data into buckets of given size
+        @param bucket: the size of the buckets
+        @type bucket: int
+        """
+        self.bucket = bucket
+
+
+    def setRegression(self, regression):
+        """
+        Plot a linear regression line
+        @param regression: whether to plot the regression
+        @type  regression: bool
+        """
+        self.regression = regression
+
+
+    def setFormat(self, format):
+        """
+        Set the format of the picture
+        @param format: the format
+        @type format: string
+        """
+        if format not in ("png", "pdf", "jpeg", "bmp", "tiff"):
+            raise Exception("Format '%s' is not supported by RPlotter" % (format))
+        self.format = format
+
+
+    def setWidth(self, width):
+        """
+        Set the dimensions of the image produced
+        @param width: width of the image
+        @type width: int
+        """
+        self.width = width
+        
+        
+    def setHeight(self, height):
+        """
+        Set the dimensions of the image produced
+        @param height: heigth of the image
+        @type height: int
+        """
+        self.height = height
+        
+        
+    def setImageSize(self, width, height):
+        """
+        Set the dimensions of the image produced
+        @param width: width of the image
+        @type width: int
+        @param height: heigth of the image
+        @type height: int
+        """
+        self.setWidth(width)
+        self.setHeight(height)
+        
+        
+    def setLegend(self, legend, bySide = False):
+        """
+        Print a legend or not
+        @param legend: print a legend
+        @type  legend: boolean
+        @param bySide: put the legend outside of the plot
+        @type  bySide: boolean
+        """
+        self.legend       = legend
+        self.legendBySide = bySide
+
+
+    def setXLabel(self, label):
+        """
+        Print a label for the x-axis
+        @param label: the label
+        @type label: string
+        """
+        self.xLabel = label
+        if self.xLabel != None:
+            self.xLabel = self.xLabel.replace("_", " ")
+
+
+    def setYLabel(self, label):
+        """
+        Print a label for the y-axis
+        @param label: the label
+        @type label: string
+        """
+        self.yLabel = label
+        if self.yLabel != None:
+            self.yLabel = self.yLabel.replace("_", " ")
+
+
+    def addLeftMargin(self, margin):
+        """
+        Increase the size of the space on the left part of the graph
+        @param margin: the space added
+        @type  margin: float
+        """
+        self.leftMargin = margin
+
+
+    def addRightMargin(self, margin):
+        """
+        Increase the size of the space on the right part of the graph
+        @param margin: the space added
+        @type  margin: float
+        """
+        self.rightMargin = margin
+
+
+    def addTopMargin(self, margin):
+        """
+        Increase the size of the space at the top of the graph
+        TopMargin is a percentage if 0 < TopMargin < 1.
+        TopMargin is a value if TopMargin >= 1.
+        @param margin: the space added
+        @type  margin: float
+        """
+        self.topMargin = margin
+
+
+    def addBottomMargin(self, margin):
+        """
+        Increase the size of the space at the bottom of the graph
+        @param margin: the space added
+        @type  margin: float
+        """
+        self.bottomMargin = margin
+
+
+    def getNewYMaxWithTopMargin(self):
+        """
+        Return new xMin coordinate with left margin
+        @param xMin: coordinate
+        @type  xMin: float
+        """
+        yMax = self.yMax
+        if 0 < self.topMargin and self.topMargin < 1:
+            topMargin = self.topMargin * self.yMax
+            yMax = self.yMax + topMargin
+        elif self.topMargin >= 1:
+            yMax = self.yMax + self.topMargin
+        return yMax
+
+
+    def setTitle(self, title):
+        """
+        Print a title for graph
+        @param title: a title
+        @type title: string
+        """
+        self.title = title
+        if self.title != None:
+            self.title = self.title.replace("_", " ")
+
+
+    def setAxisLabel(self, i, labels):
+        """
+        Change x- or y-labels
+        @param i: x for x-label, y for y-label
+        @type  i: string
+        @param labels: new labels
+        @type  labels: int to string dict
+        """
+        i = i.lower()
+        if i not in ("x", "y"):
+            raise Exception("Label name '" + i + "' should by 'x' or 'y' while changing axis labels.")
+        self.axesLabels[{"x": 1, "y": 2}[i]] = labels
+
+
+    def rotateAxisLabel(self, i, b = True):
+        """
+        Rotate x- or y-labels
+        @param i: x for x-label, y for y-label
+        @type  i: string
+        @param b: whether the labels should be rotated
+        @type  b: boolean
+        """
+        i = i.lower()
+        if i not in ("x", "y"):
+            raise Exception("Label name '" + i + "' should by 'x' or 'y' while rotating axis labels.")
+        self.rotateAxesLabels[{"x": 1, "y": 2}[i]] = b
+
+    def setLineWidth(self, width):
+        """
+        Set the line width in a xy-plot
+        @param width: the new line width
+        @type  width: int
+        """
+        self.lineWidth = width
+
+    def setLog(self, log):
+        """
+        Use log-scale for axes
+        @param log: use log scale
+        @type log: boolean
+        """
+        self.logX = ("x" in log)
+        self.logY = ("y" in log)
+        self.logZ = ("z" in log)
+        
+
+    def setBarplot(self, barplot):
+        """
+        Use barplot representation instead
+        @param barplot: barplot representation
+        @type barplot: boolean
+        """
+        self.barplot = barplot
+        
+
+    def setPoints(self, points):
+        """
+        Use points cloud representation instead
+        @param points: points cloud representation
+        @type points: boolean
+        """
+        self.points = points
+        
+
+    def setHeatPoints(self, heatPoints):
+        """
+        Use points cloud representation with color representing another variable instead
+        @param points: colored points cloud representation
+        @type points: boolean
+        """
+        self.heatPoints = heatPoints
+
+
+    def addBox(self, lXCoordList, minY, maxY):
+        for lXCoord in lXCoordList:
+            self.linesToAddBox += "rect(%s,%s,%s,%s,density=50, col='grey',border='transparent')\n" % (lXCoord[0], minY, lXCoord[1], maxY)
+    
+    def addLine(self, line, name = "", color = None):
+        """
+        Add a line 
+        @param line: a line to plot
+        @type line: dict
+        """
+        # prepare data
+        plot = []
+        if self.points or self.heatPoints:
+            values = line.values()
+        elif self.fill == None:
+            values = sorted(line.keys())
+        else:
+            values = range(min(line.keys()), max(line.keys()) + 1)
+            
+        for element in values:
+            if self.points or self.heatPoints:
+                x = element[0]
+                y = element[1]
+            else:
+                x = element
+                if x not in line:
+                    y = self.fill
+                else:
+                    y = line[x]
+                
+            if self.minimumX != None and x < self.minimumX:
+                continue
+            if self.maximumX != None and x > self.maximumX:
+                continue
+            
+            if x == None:
+                raise Exception("Problem! x is None. Aborting...")
+            if y == None:
+                raise Exception("Problem! y is None. Aborting...")
+            if x == 0 and self.logX:
+                x = minPositiveValue
+            if y == 0 and self.logY:
+                y = minPositiveValue
+            if self.xMin == None:
+                if not self.logX or x != 0:
+                    self.xMin = x
+            else:
+                if not self.logX or x != 0:
+                    self.xMin = min(self.xMin, x)
+            if self.xMax == None:
+                self.xMax = x
+            else:
+                self.xMax = max(self.xMax, x)
+            if self.yMin == None:
+                if not self.logY or y != 0:
+                    self.yMin = y
+            else:
+                if not self.logY or y != 0:
+                    if y != "NA":
+                        self.yMin = min(self.yMin, y)
+            if self.yMax == None:
+                self.yMax = y
+            else:
+                if y != "NA":
+                    self.yMax = max(self.yMax, y)
+
+            plot.append((x, y))
+
+        # cluster the data into buckets
+        if self.bucket != None:
+            buckets = dict([((int(value) / int(self.bucket)) * self.bucket, 0) for value in xrange(min(line.keys()), max(line.keys())+1)])
+            for distance, nb in line.iteritems():
+                buckets[(int(distance) / int(self.bucket)) * self.bucket] += nb
+            self.yMax = max(buckets.values())
+            plot = []
+            for x, y in buckets.iteritems():
+                plot.append((x, y))
+
+        # write file
+        dataFileName = "tmpData-%d-%d.dat" % (self.seed, len(self.lines))
+        dataHandle = open(dataFileName, "w")
+        if not self.heatPoints:
+            plot.sort()
+        for (x, y) in plot:
+            if y != "NA":
+                dataHandle.write("%f\t%f\n" % (x, y))
+            else:
+                dataHandle.write("%f\t%s\n" % (x, y))
+        dataHandle.close()
+
+        self.lines.append(line)
+        self.names.append(name)
+
+        if color == None:
+            colorNumber = len(self.colors) % (self.nbColors - 1) + 1
+            type = "solid"
+            if len(self.colors) >= self.nbColors:
+                type = "dashed"
+            color = "colorPanel[%d]" % (colorNumber)
+        else:
+            color = "\"%s\"" % (color)
+            type = "solid"
+        self.colors.append(color)
+        self.types.append(type)
+
+
+    def addHeatLine(self, line, name = "", color = None):
+        """
+        Add the heat line 
+        @param line: the line which gives the color of the points
+        @type    line: dict
+        """
+        if not self.heatPoints:
+            raise Exception("Error! Trying to add a heat point whereas not mentioned to earlier! Aborting.")
+            
+        dataFileName = "tmpData-%d-%d.dat" % (self.seed, len(self.lines))
+        dataHandle = open(dataFileName, "w")
+    
+        minimumHeat = min(line.values())
+        maximumHeat = max(line.values())
+        minLogValue = 0.00001
+        log = self.logZ
+        
+        if log:
+            if minimumHeat == 0:
+                for element in line:
+                    line[element] += minLogValue
+                minimumHeat += minLogValue
+                maximumHeat += minLogValue
+            minimumHeat = math.log10(minimumHeat)
+            maximumHeat = math.log10(maximumHeat)
+        
+        coeff = 255.0 / (maximumHeat - minimumHeat)
+
+        for element in line:
+            value = line[element]
+            if log:
+                value = math.log10(max(minLogValue, value))
+            dataHandle.write("\"#%02X%02X00\"\n" % (int((value - minimumHeat) * coeff), 255 - int((value - minimumHeat) * coeff)))
+
+        dataHandle.close()
+        self.names.append(name)
+        if color == None:
+            colorNumber = len(self.colors) % (self.nbColors - 1) + 1
+            type = "solid"
+            if len(self.colors) >= self.nbColors:
+                type = "dashed"
+            color = "colorPanel[%d]" % (colorNumber)
+        else:
+            color = "\"%s\"" % (color)
+            type = "solid"
+        self.colors.append(color)
+        self.types.append(type)
+
+
+    def getScript(self):
+        """
+        Write (unfinished) R script
+        """
+        script = ""
+
+        xMin = self.xMin - self.leftMargin
+        if self.minimumX != None:
+            xMin = max(xMin, self.minimumX)
+        xMax = self.xMax + self.rightMargin
+        if self.maximumX != None:
+            xMax = min(xMax, self.maximumX)
+        yMin = self.yMin - self.bottomMargin
+        if self.minimumY != None:
+            yMin = self.minimumY
+        yMax = self.getNewYMaxWithTopMargin()
+        if self.maximumY != None:
+            yMax = self.maximumY
+
+        log = ""
+        if self.logX:
+            log += "x"
+        if self.logY:
+            log += "y"
+        if log != "":
+            log = ", log=\"%s\"" % (log)
+
+        title = ""
+        if self.title != None:
+            title = ", main = \"%s\"" % (self.title)
+
+        if self.legend and self.legendBySide:
+            script += "layout(matrix(c(1,2), 1, 2), widths=c(5,1))\n"
+
+        if self.rotateAxesLabels[2]:
+            script += "par(mar=c(5,12,4,2))\n"
+        else:
+            script += "par(mar=c(5,5,4,2))\n"
+
+        addAxes = True
+
+        if self.barplot:
+            script += "data = scan(\"tmpData-%d-0.dat\", list(x = -666, y = -666))\n" % (self.seed)
+            if len(self.lines) == 1:
+                script += "barplot(data$y, name = data$x, xlab=\"%s\", ylab=\"%s\", ylim = c(%f, %f), cex.axis = 2, cex.names = 2, cex.lab = 2%s%s)\n" % (self.xLabel, self.yLabel, yMin, yMax, title, log)
+                addAxes = False
+            else:
+                script += "data1 = scan(\"tmpData-%d-1.dat\", list(x = -666, y = -666))\n" % (self.seed)
+                script += "barplot(rbind(data$y, data1$y), name = data$x, xlab=\"%s\", ylab=\"%s\", cex.axis = 2, cex.names = 2, cex.lab = 2%s, beside = TRUE, space=c(-1,0), axes = FALSE%s)\n" % (self.xLabel, self.yLabel, title, log)
+        elif self.points:
+            script += "data = scan(\"tmpData-%d-0.dat\", list(x = -666, y = -666))\n" % (self.seed)
+            script += "plot(data$x, data$y, xlab=\"%s\", ylab=\"%s\", cex.axis = 2, cex.lab = 2, axes = FALSE%s%s)\n" % (self.xLabel, self.yLabel, title, log)
+            if self.regression:
+                x = "log10(data$x)" if self.logX else "data$x"
+                y = "log10(data$y)" if self.logY else "data$y"
+                script += "abline(lm(%s ~ %s))\n" % (y, x)
+        elif self.heatPoints:
+            if len(self.lines) != 1:
+                raise Exception("Error! Bad number of input data! Aborting...")
+            script += "data = scan(\"tmpData-%d-0.dat\", list(x = -666, y = -666))\n" % (self.seed)
+            script += "heatData = scan(\"tmpData-%d-1.dat\", list(x = \"\"))\n" % (self.seed)
+            script += "plot(data$x, data$y, col=heatData$x, xlab=\"%s\", ylab=\"%s\", cex.axis = 2, cex.lab = 2, axes = FALSE%s%s)\n" % (self.xLabel, self.yLabel, title, log)
+            if self.regression:
+                x = "log10(data$x)" if self.logX else "data$x"
+                y = "log10(data$y)" if self.logY else "data$y"
+                script += "abline(lm(%s ~ %s))\n" % (y, x)
+        else:
+            script += "plot(x = NA, y = NA, panel.first = grid(lwd = 1.0), xlab=\"%s\", ylab=\"%s\", xlim = c(%f, %f), ylim = c(%f, %f), cex.axis = 2, cex.lab = 2, axes = FALSE%s%s)\n" % (self.xLabel, self.yLabel, xMin, xMax, yMin, yMax, title, log)
+            for i in range(0, len(self.lines)):
+                script += "data = scan(\"tmpData-%d-%d.dat\", list(x = -666.666, y = -666.666))\n" % (self.seed, i)
+                script += "lines(x = data$x, y = data$y, col = %s, lty = \"%s\", lwd = %d)\n" % (self.colors[i], self.types[i], self.lineWidth)
+                
+            script += self.linesToAddBox
+                
+        if addAxes:
+            for i in self.axesLabels:
+                rotation = ", las = 2" if self.rotateAxesLabels[i] else ""
+                if self.axesLabels[i] == None:
+                    script += "axis(%d, cex.axis = 2, cex.lab = 2%s)\n" % (i, rotation)
+                else:
+                    oldKeys = ", ".join(["%d" % (key) for key in sorted(self.axesLabels[i].keys())])
+                    newKeys = ", ".join(["\"%s\"" % (self.axesLabels[i][key]) for key in sorted(self.axesLabels[i].keys())])
+                    script += "axis(%d, at=c(%s), lab=c(%s), cex.axis = 2, cex.lab = 2%s)\n" % (i, oldKeys, newKeys, rotation)
+        script += "box()\n"
+
+        if self.legend:
+            if self.legendBySide:
+                script += "plot.new()\n"
+                script += "par(mar=c(0,0,0,0))\n"
+                script += "plot.window(c(0,1), c(0,1))\n"
+            script += "legends   = c(%s)\n" % ", ".join(["\"%s\"" % name  for name  in self.names])
+            script += "colors    = c(%s)\n" % ", ".join(["%s" %     color for color in self.colors])
+            script += "lineTypes = c(%s)\n" % ", ".join(["\"%s\"" % type  for type  in self.types])
+            if self.legendBySide:
+                script += "legend(0, 1, legend = legends, xjust = 0, yjust = 1, col = colors, lty = lineTypes, lwd = %d, cex = 1.5, ncol = 1, bg = \"white\")\n" % (self.lineWidth)
+            else:
+                script += "legend(\"topright\", legend = legends, xjust = 0, yjust = 1, col = colors, lty = lineTypes, lwd = %d, cex = 1.5, ncol = 1, bg = \"white\")\n" % (self.lineWidth)
+
+        return script
+            
+
+
+    def plot(self):
+        """
+        Plot the lines
+        """
+        scriptFileName = "tmpScript-%d.R" % (self.seed)
+        scriptHandle = open(scriptFileName, "w")
+        scriptHandle.write("library(RColorBrewer)\n")
+        scriptHandle.write("colorPanel = brewer.pal(n=%d, name=\"Set1\")\n" % (self.nbColors))
+        scriptHandle.write("%s(%s = \"%s\", width = %d, height = %d, bg = \"white\")\n" % (self.format, "filename" if self.format != "pdf" else "file", self.fileName, self.width, self.height))
+        scriptHandle.write(self.getScript())
+        scriptHandle.write("dev.off()\n")
+        scriptHandle.close()
+        rCommand = "R"
+        if "SMARTRPATH" in os.environ:
+            rCommand = os.environ["SMARTRPATH"]
+        command = "\"%s\" CMD BATCH %s" % (rCommand, scriptFileName)
+        status = subprocess.call(command, shell=True)
+
+        if status != 0:
+            self.keep = True
+            raise Exception("Problem with the execution of script file %s, status is: %s" % (scriptFileName, status))
+            
+
+    def getCorrelationData(self):
+        if not self.regression:
+            return ""
+        scriptFileName = "tmpScript-%d.R" % (self.seed)
+        rScript = open(scriptFileName, "w")
+        rScript.write("data = scan(\"tmpData-%d-0.dat\", list(x = -0.000000, y = -0.000000))\n" % (self.seed))
+        x = "log10(data$x)" if self.logX else "data$x"
+        y = "log10(data$y)" if self.logY else "data$y"
+        rScript.write("summary(lm(%s ~ %s))\n" % (y, x))
+        rScript.close()
+        rCommand = "R"
+        if "SMARTRPATH" in os.environ:
+            rCommand = os.environ["SMARTRPATH"]
+        command = "\"%s\" CMD BATCH %s" % (rCommand, scriptFileName)
+        status = subprocess.call(command, shell=True)
+        if status != 0:
+            self.keep = True
+            raise Exception("Problem with the execution of script file %s computing the correlation, status is: %s" % (scriptFileName, status))
+        outputRFile = open("%sout" % (scriptFileName))
+        output      = ""
+        start       = False
+        end         = False
+        for line in outputRFile:
+            if start and "> " in line:
+                end = True
+            if start and not end:
+                output += line
+            if "summary" in line:
+                start = True
+        return output
+
+
+    def getSpearmanRho(self):
+        """
+        Get the Spearman rho correlation using R
+        """
+        return None
+        if not self.points and not self.barplot and not self.heatPoints:
+            raise Exception("Cannot compute Spearman rho correlation whereas not in 'points' or 'bar' mode.")
+        
+        scriptFileName = "tmpScript-%d.R" % (self.seed)
+        rScript = open(scriptFileName, "w")
+        rScript.write("library(Hmisc)\n")
+        rScript.write("data = scan(\"tmpData-%d-0.dat\", list(x = -0.000000, y = -0.000000))\n" % (self.seed))
+        rScript.write("spearman(data$x, data$y)\n")
+        rScript.close()
+
+        rCommand = "R"
+        if "SMARTRPATH" in os.environ:
+            rCommand = os.environ["SMARTRPATH"]
+        command = "\"%s\" CMD BATCH %s" % (rCommand, scriptFileName)
+        status = subprocess.call(command, shell=True)
+
+        if status != 0:
+            self.keep = True
+            raise Exception("Problem with the execution of script file %s, status is: %s" % (scriptFileName, status))
+
+        outputRFile = open("%sout" % (scriptFileName))
+        nextLine = False
+        for line in outputRFile:
+            line = line.strip()
+            if nextLine:
+                if line == "NA":
+                    return None
+                return float(line)
+                nextLine = False
+            if line == "rho":
+                nextLine = True
+
+        return None
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/misc/UnlimitedProgress.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,81 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+import time
+
+class UnlimitedProgress(object):
+    """Show the progress of a process when no upper bound is known"""
+
+    def __init__(self, step = 1000, message = "Progress", verbosity = 0):
+        self.step           = step
+        self.progress       = 0
+        self.message        = message
+        self.verbosity      = verbosity
+        self.maxMessageSize = 50
+        self.startTime      = time.time()
+        self.elapsed        = 0
+        if len(self.message) > self.maxMessageSize:
+            self.message = self.message[0:self.maxMessageSize-3] + "..."
+        self.show()
+
+
+    def inc(self):
+        self.progress += 1
+        self.show()
+        
+        
+    def getPrintableElapsedTime(self, time):
+        timeHou = int(time) / 3600
+        timeMin = int(time) / 60 - 60 * timeHou
+        timeSec = int(time) % 60
+        if timeHou > 0:
+            return "%3dh %2dm" % (timeHou, timeMin)
+        if timeMin > 0:
+            return "%2dm %2ds" % (timeMin, timeSec)
+        return "%2ds" % (timeSec)
+
+
+    def show(self):
+        if self.verbosity <= 0:
+            return
+        elapsed = int(time.time() - self.startTime)
+        if (self.progress % self.step == 0) or (elapsed > self.elapsed + 10):
+            self.elapsed = elapsed            
+            string = "%s %d -- time spent: %s\r" % (self.message, self.progress, self.getPrintableElapsedTime(elapsed))
+            sys.stdout.write(string)
+            sys.stdout.flush()
+
+
+    def done(self):
+        if self.verbosity > 0:
+            elapsed = time.time() - self.startTime
+            string = "%s %d -- time spent: %s\r" % (self.message, self.progress, self.getPrintableElapsedTime(elapsed))
+            print string
+
Binary file smart_toolShed/SMART/Java/Python/misc/UnlimitedProgress.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/misc/Utils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,271 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Some useful functions"""
+
+import sys, os
+import random
+import subprocess
+
+
+def writeFile(fileName, content):
+    """
+    Write the content of a file
+    """
+    handle = open(fileName, "w")
+    handle.write(content)
+    handle.close()
+
+def sumOfLists(list1, list2):
+    """
+    Element by element sum
+    """
+    if len(list1) != len(list2):
+        sys.exit("Cannot sum list whose sizes are different!")
+    return [list1[i] + list2[i] for i in range(len(list1))]
+
+
+def protectBackslashes(string):
+    """
+    Protect the backslashes in a path by adding another backslash
+    """
+    return string.replace("\\", "\\\\")
+    
+
+def getHammingDistance(string1, string2):
+    """
+    Compute Hamming distance between two strings
+    """
+    if len(string1) != len(string2):
+        raise Exception("Error, size of %s and %s differ" % (string1, string2))
+    return sum(ch1 != ch2 for ch1, ch2 in zip(string1, string2))
+
+
+def getLevenshteinDistance(string1, string2):
+    """
+    Compute Levenshtein distance between two strings
+    """
+    if len(string1) < len(string2):
+        return getLevenshteinDistance(string2, string1)
+    if not string1:
+        return len(string2)
+    previousRow = xrange(len(string2) + 1)
+    for i, c1 in enumerate(string1):
+        currentRow = [i + 1]
+        for j, c2 in enumerate(string2):
+            insertions    = previousRow[j + 1] + 1
+            deletions     = currentRow[j] + 1
+            substitutions = previousRow[j] + (c1 != c2)
+            currentRow.append(min(insertions, deletions, substitutions))
+        previousRow = currentRow
+    return previousRow[-1]
+
+
+def getMinAvgMedMax(values):
+    """
+    Get some stats about a dict
+    @param values: a distribution (the value being the number of occurrences of the key)
+    @type values: dict int to int
+    @return: a tuple
+    """
+    minValues = min(values.keys())
+    maxValues = max(values.keys())
+    sumValues = sum([value * values[value] for value in values])
+    nbValues = sum(values.values())
+    allValues = []
+    for key in values:
+        for i in range(values[key]):
+            allValues.append(key)
+    sortedValues = sorted(allValues)
+    sorted(values.values())
+    if (nbValues % 2 == 0):
+        medValues = (sortedValues[nbValues / 2 - 1] + sortedValues[nbValues / 2]) / 2.0
+    else:
+        medValues = sortedValues[(nbValues + 1) / 2 - 1]
+    return (minValues, float(sumValues) / nbValues, medValues, maxValues)
+
+
+def xor(value1, value2):
+    """
+    Logical xor
+    @param value1: a value
+    @type value1: anything
+    @param value2: a value
+    @type value2: anything
+    """
+    return bool(value1) != bool(value2)
+
+
+def diff(fileName1, fileName2):
+    """
+    Compare two files
+    @param fileName1: a file name
+    @type fileName1: string
+    @param fileName2: another file name
+    @type fileName2: string
+    @return: None if the files are the same, a string otherwise
+    """
+    handle1 = open(fileName1)
+    lines1 = handle1.readlines()
+    handle2 = open(fileName2)
+    lines2 = handle2.readlines()
+    if len(lines1) != len(lines2):
+        print "Sizes of files differ (%d != %d)" % (len(lines1), len(lines2))
+        return False
+    for i in xrange(len(lines1)):
+        if lines1[i] != lines2[i]:
+            print "Line %d differ ('%s' != '%s')" % (i, lines1[i].strip(), lines2[i].strip())
+            return False
+    return True
+
+
+def binomialCoefficient(a, b):
+    """
+    Compute cumulated product from a to b
+    @param a: a value
+    @type    a: int
+    @param b: a value
+    @type    b: int
+    """
+    if a > b / 2:
+        a = b-a
+    p = 1.0
+    for i in range(b-a+1, b+1):
+        p *= i
+    q = 1.0
+    for i in range(1, a+1):
+        q *= i
+    return p / q
+
+
+memory = {}
+
+# def fisherExactPValue(a, b, c, d):
+#     """
+#     P-value of Fisher exact test for 2x2 contingency table
+#     """
+#     if (a, b, c, d) in memory:
+#         return memory[(a, b, c, d)]
+
+#     n = a + b + c + d
+#     i1 = binomialCoefficient(a, a+b)
+#     i2 = binomialCoefficient(c, a+c)
+#     i3 = binomialCoefficient(c+d, n)
+#     pValue = i1 * i2 / i3
+
+#     memory[(a, b, c, d)] = pValue
+
+#     return pValue
+    
+
+def fisherExactPValue(a, b, c, d):
+    if (a, b, c, d) in memory:
+        return memory[(a, b, c, d)]
+
+    scriptFileName = "tmpScript-%d.R" % (random.randint(0, 10000))
+    rScript = open(scriptFileName, "w")
+    rScript.write("data = matrix(c(%d, %d, %d, %d), nr=2)\n" % (a, b, c, d))
+    rScript.write("fisher.test(data)\n")
+    #rScript.write("chisq.test(data)\n")
+    rScript.close()
+
+    rCommand = "R"
+    if "SMARTRPATH" in os.environ:
+        rCommand = os.environ["SMARTRPATH"]
+    command = "\"%s\" CMD BATCH %s" % (rCommand, scriptFileName)
+    status = subprocess.call(command, shell=True)
+
+    if status != 0:
+        sys.exit("Problem with the execution of script file %s, status is: %s" % (scriptFileName, status))
+
+    outputRFileName = "%sout" % (scriptFileName)
+    outputRFile = open(outputRFileName)
+    pValue = None
+    pValueTag = "p-value "
+    for line in outputRFile:
+        line = line.strip()
+        if line == "": continue
+        for splittedLine in line.split(","):
+            splittedLine = splittedLine.strip()
+            if splittedLine.startswith(pValueTag):
+                pValue = float(splittedLine.split()[-1])
+                break
+
+    if pValue == None:
+        sys.exit("Problem with the cannot find p-value! File %s, values are: %d, %d, %d, %d" % (scriptFileName, a, b, c, d))
+
+    os.remove(scriptFileName)
+    os.remove(outputRFileName)
+
+    memory[(a, b, c, d)] = pValue
+
+    return pValue
+
+
+def fisherExactPValueBulk(list):
+
+    scriptFileName = "tmpScript-%d.R" % (random.randint(0, 10000))
+    rScript = open(scriptFileName, "w")
+    for element in list:
+        rScript.write("fisher.test(matrix(c(%d, %d, %d, %d), nr=2))$p.value\n" % (int(element[0]), int(element[1]), int(element[2]), int(element[3])))
+    rScript.close()
+
+    rCommand = "R"
+    if "SMARTRPATH" in os.environ:
+        rCommand = os.environ["SMARTRPATH"]
+    command = "\"%s\" CMD BATCH %s" % (rCommand, scriptFileName)
+    status = subprocess.call(command, shell=True)
+
+    if status != 0:
+        sys.exit("Problem with the execution of script file %s, status is: %s" % (scriptFileName, status))
+
+    outputRFileName = "%sout" % (scriptFileName)
+    outputRFile = open(outputRFileName)
+    pValue = None
+    pValueTag = "[1] "
+    results = {}
+    cpt = 0
+    for line in outputRFile:
+        line = line.strip()
+        if line == "": continue
+        if line.startswith(pValueTag):
+            pValue = float(line.split()[-1])
+            results[list[cpt][0:2]] = pValue
+            cpt += 1
+
+    if pValue == None:
+        sys.exit("Problem with the cannot find p-value!")
+    if cpt != len(list):
+        sys.exit("Error in the number of p-values computed by R in file '%s'!" % (scriptFileName))
+
+    os.remove(scriptFileName)
+    os.remove(outputRFileName)
+
+    return results
+
Binary file smart_toolShed/SMART/Java/Python/misc/Utils.pyc has changed
Binary file smart_toolShed/SMART/Java/Python/misc/__init__.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/misc/test/Test_Utils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,13 @@
+import unittest
+from SMART.Java.Python.misc import Utils
+
+
+class Test_Utils(unittest.TestCase):
+
+    def testFisherExactPValue(self):
+        self.assertAlmostEqual(Utils.fisherExactPValue(3, 1, 1, 3), 0.4857142857142842, 3)
+
+
+if __name__ == '__main__':
+    unittest.main()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/modifyFasta.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,62 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Modify the content of a FASTA file"""
+
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import FastaParser
+from commons.core.writer.FastaWriter import FastaWriter
+from SMART.Java.Python.misc.Progress import Progress
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Modify Sequence List v1.0.1: Extend or shring a list of sequences. [Category: Data Modification]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",                     dest="inputFileName",    action="store",                                         type="string", help="input file [compulsory] [format: file in FASTA format]")
+    parser.add_option("-o", "--output",                    dest="outputFileName", action="store",            default=None,    type="string", help="output file [compulsory] [format: output file in FASTA format]")
+    parser.add_option("-s", "--start",                     dest="start",                    action="store",            default=None,    type="int",        help="keep first nucleotides [format: int]")
+    parser.add_option("-e", "--end",                         dest="end",                        action="store",            default=None,    type="int",        help="keep last nucleotides [format: int]")
+    parser.add_option("-v", "--verbosity",             dest="verbosity",            action="store",            default=1,         type="int",        help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    parser     = FastaParser(options.inputFileName, options.verbosity)
+    writer     = FastaWriter(options.outputFileName, options.verbosity)
+    progress = Progress(parser.getNbSequences(), "Reading file %s" % (options.inputFileName), options.verbosity)
+    for sequence in parser.getIterator():
+        if options.start != None:
+            sequence.shrinkToFirstNucleotides(options.start)
+        if options.end != None:
+            sequence.shrinkToLastNucleotides(options.end)
+        writer.addSequence(sequence)
+        progress.inc()
+    progress.done()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/modifyGenomicCoordinates.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,80 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Modify the genomic coordinates of a file"""
+
+from optparse import OptionParser
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.misc.Progress import Progress
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Modify Genomic Coordinates v1.0.1: Extend or shrink a list of genomic coordinates. [Category: Data Modification]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",      dest="inputFileName",  action="store",               type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",     dest="format",         action="store",               type="string", help="format of the input [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",     dest="outputFileName", action="store",               type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-s", "--start",      dest="start",          action="store", default=None, type="int",    help="restrict to the start of the transcript [format: int]")
+    parser.add_option("-e", "--end",        dest="end",            action="store", default=None, type="int",    help="restrict to the end of the transcript [format: int]")
+    parser.add_option("-5", "--fivePrime",  dest="fivePrime",      action="store", default=None, type="int",    help="extend to the 5' direction [format: int]")
+    parser.add_option("-3", "--threePrime", dest="threePrime",     action="store", default=None, type="int",    help="extend to the 3' direction [format: int]")
+    parser.add_option("-v", "--verbosity",  dest="verbosity",      action="store", default=1,    type="int",    help="trace level [format: int]")
+
+    (options, args) = parser.parse_args()
+
+    parser = TranscriptContainer(options.inputFileName, options.format, options.verbosity)
+        
+    writer = TranscriptWriter(options.outputFileName, "gff3", options.verbosity)
+
+    nbItems = 0
+    nbItems = parser.getNbItems()
+    print "%i items found" % (nbItems)
+
+    progress = Progress(nbItems, "Analyzing sequences of " + options.inputFileName, options.verbosity)
+    for transcript in parser.getIterator():
+        if options.start != None:
+            transcript.restrictStart(options.start)
+        if options.end != None:
+            transcript.restrictEnd(options.end)
+        if options.fivePrime != None:
+            transcript.extendStart(options.fivePrime)
+        if options.threePrime != None:
+            transcript.extendEnd(options.threePrime)
+
+        writer.addTranscript(transcript)
+
+        progress.inc()
+    progress.done()
+
+    writer.write()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/modifySequenceList.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,72 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Modify the content of a FASTA file"""
+import sys
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import FastaParser
+from commons.core.parsing.FastqParser import FastqParser
+from commons.core.writer.FastaWriter import FastaWriter
+from commons.core.writer.FastqWriter import FastqWriter
+from SMART.Java.Python.misc.Progress import Progress
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Modify Sequence List v1.0.1: Extend or shring a list of sequences. [Category: Data Modification]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input", dest="inputFileName",action="store", type="string", help="input file [compulsory] [format: file in format given by -f]")
+    parser.add_option("-o", "--output", dest="outputFileName", action="store",default=None,    type="string", help="output file [compulsory] [format: output file in format given by -f]")
+    parser.add_option("-f", "--format", dest="format",action="store",type="string", help="format of the file [compulsory] [format: sequence file format]")
+    parser.add_option("-s", "--start", dest="start", action="store", default=None,type="int",help="keep first nucleotides [format: int]")
+    parser.add_option("-e", "--end",  dest="end", action="store",default=None,type="int",help="keep last nucleotides [format: int]")
+    parser.add_option("-v", "--verbosity",dest="verbosity",action="store",default=1,type="int",help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    if options.format == "fasta":
+        parser = FastaParser(options.inputFileName, options.verbosity)
+        writer = FastaWriter(options.outputFileName, options.verbosity)
+    elif options.format == "fastq":
+        parser = FastqParser(options.inputFileName, options.verbosity)
+        writer = FastqWriter(options.outputFileName, options.verbosity)
+    else:
+        sys.exit("Do not understand '%s' file format." % (options.format))
+
+    progress = Progress(parser.getNbSequences(), "Reading file %s" % (options.inputFileName), options.verbosity)
+    for sequence in parser.getIterator():
+        if options.start != None:
+            sequence.shrinkToFirstNucleotides(options.start)
+        if options.end != None:
+            sequence.shrinkToLastNucleotides(options.end)
+        writer.addSequence(sequence)
+        progress.inc()
+    progress.done()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/mySql/MySqlConnection.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,109 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+#! /usr/bin/env python
+import os
+import random
+import sqlite3
+from SMART.Java.Python.mySql.MySqlQuery import MySqlQuery
+
+
+class MySqlConnection(object):
+    """Connection to a database"""
+
+    def __init__(self, verbosity = 0):
+        self.verbosity = verbosity
+        self.databaseName = "%s%ssmartdb%d" % (os.environ.get("SMARTTMPPATH", "."), os.sep, random.randint(0, 100000))
+        self.connection = sqlite3.connect(self.databaseName)
+        self.executeQuery("PRAGMA journal_mode = OFF")
+        self.executeQuery("PRAGMA synchronous = 0")
+        self.executeQuery("PRAGMA locking_mode = EXCLUSIVE")
+        self.executeQuery("PRAGMA count_change = OFF")
+        self.executeQuery("PRAGMA temp_store = 2")
+
+    def __del__(self):
+        self.connection.close()
+
+
+    def createDatabase(self):
+        pass
+
+
+    def deleteDatabase(self):
+        if os.path.exists(self.databaseName):
+            os.remove(self.databaseName)
+
+
+    def executeQuery(self, command, insertion = False):
+        cursor = self.connection.cursor()
+        query = MySqlQuery(cursor, self.verbosity)
+        try:
+            result = query.execute(command, insertion)
+            self.connection.commit()
+        except:
+            result = query.execute(command, insertion)
+            self.connection.commit()
+        if insertion:
+            return result
+        else:
+            return query
+
+
+    def executeManyQueries(self, commands):
+        cursor = self.connection.cursor()
+        query = MySqlQuery(cursor, self.verbosity)
+        try:
+            for cpt, command in enumerate(commands):
+                query.execute(command)
+            self.connection.commit()
+        except:
+            for cpt, command in enumerate(commands):
+                query.execute(command)
+            self.connection.commit()
+
+
+    def executeManyQueriesIterator(self, table):
+        cursor = self.connection.cursor()
+        query = MySqlQuery(cursor, self.verbosity)
+        try:
+            for command in table.getIterator():
+                query.execute(command)
+            self.connection.commit()
+        except:
+            for command in table.getIterator():
+                query.execute(command)
+            self.connection.commit()
+
+
+    def executeFormattedQuery(self, command, *parameters):
+        cursor = self.connection.cursor()
+        query = MySqlQuery(cursor, self.verbosity)
+        query.executeFormat(command, parameters)
+        self.connection.commit()
+        return query
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/mySql/MySqlExonTable.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,97 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import random
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.mySql.MySqlTable import MySqlTable
+
+
+class MySqlExonTable(MySqlTable):
+    """A table of exon in a mySQL database"""
+
+    def __init__(self, connection, name = None, chromosome = None, verbosity = 0):
+        if chromosome == None:
+            chromosome = ""
+        else:
+            chromosome = "_%s" % chromosome
+        if name == None:
+            name = "TmpTable_%d" % (random.randint(0, 100000))
+        name = "%s%s_exons" % (name, chromosome)
+        super(MySqlExonTable, self).__init__(connection, name, verbosity)
+
+
+    def createExonTable(self):
+        variables = Interval.getSqlVariables()
+        variables.append("transcriptId")
+        types = Interval.getSqlTypes()
+        types["transcriptId"] = "int"
+        sizes = Interval.getSqlSizes()
+        sizes["transcriptId"] = 11
+        self.create(variables, types, sizes)
+
+
+    def rename(self, name):
+        super(MySqlExonTable, self).rename("%s_exons" % name)
+    
+        
+    def addExon(self, exon, transcriptId):
+        values = exon.getSqlValues()
+        values["transcriptId"] = transcriptId
+        id = self.addLine(values)
+        exon.id = id
+
+
+    def retrieveExonsFromTranscriptId(self, transcriptId):
+        if not self.created:
+            return []
+        query = self.mySqlConnection.executeQuery("SELECT * FROM %s WHERE transcriptId = %d" % (self.name, transcriptId))
+        exons = []
+        for exonLine in query.getIterator():
+            exon = Interval()
+            exon.setSqlValues(exonLine)
+            exons.append(exon)
+        return exons
+            
+
+    def retrieveExonsFromBulkTranscriptIds(self, transcriptIds):
+        if not transcriptIds:
+            return {}
+        if not self.created:
+            return {}
+        exons = dict([(transcriptId, []) for transcriptId in transcriptIds])
+        query = self.mySqlConnection.executeQuery("SELECT * FROM %s WHERE transcriptId IN (%s)" % (self.name, ", ".join(["%s" % (transcriptId) for transcriptId in transcriptIds])))
+        for exonLine in query.getIterator():
+            exon = Interval()
+            exon.setSqlValues(exonLine)
+            exons[exonLine[-1]].append(exon)
+        return exons
+            
+
+    def removeFromTranscriptId(self, transcriptId):
+        self.mySqlConnection.executeQuery("DELETE FROM %s WHERE transcriptId = %d" % (self.name, transcriptId))
Binary file smart_toolShed/SMART/Java/Python/mySql/MySqlExonTable.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/mySql/MySqlQuery.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,94 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+class MySqlQuery(object):
+    """Query to a database"""
+
+    def __init__(self, cursor, verbosity = 0):
+        self.verbosity = verbosity
+        self.cursor = cursor
+        self.insertedId = None
+
+
+    def __del__(self):
+        self.cursor.close()
+        
+        
+    def execute(self, query, insertion = False):
+        if self.verbosity > 99:
+            print "Querying %s" % (query)
+        try:
+            results = self.cursor.execute(query)
+        except Exception:
+            raise Exception("Error! Command \"%s\" failed!" % (query))
+        if insertion:
+            return self.cursor.lastrowid
+        return results
+
+
+    def executeFormat(self, query, parameters):
+        if self.verbosity > 99:
+            print "Querying %s |" % (query),
+            for parameter in parameters:
+                print parameter,
+            print
+        results = self.cursor.execute(query, parameters)
+        return results
+
+
+    def getLine(self):
+        return self.cursor.fetchone()
+
+
+    def getLines(self, lines = None):
+        if lines == None:
+            return self.cursor.fetchall()
+        return self.cursor.fetchmany(lines)
+
+
+    def isEmpty(self):
+        self.getLines()
+        return self.cursor.rowcount == None or self.cursor.rowcount == 0
+    
+
+    def getInsertedId(self):
+        return self.insertedId
+
+
+    def getIterator(self):
+        line = self.getLine()
+        while line != None:
+            yield line
+            line = self.getLine()
+         
+
+    def show(self):
+        for line in self.getIterator():
+            print line
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/mySql/MySqlTable.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,334 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+
+class MySqlTable(object):
+    """
+    Store a table of a mySQL database, used for transcripts or exons
+    Record a a name and a type (int, float, double) for each column
+    @ivar name:            name of the table
+    @type name:            string
+    @ivar variables:       name of the columns
+    @type variables:       list of string
+    @ivar types:           type of the columns
+    @type types:           dict of string
+    @ivar mySqlConnection: connection to a database
+    @type mySqlConnection: class L{MySqlConnection<MySqlConnection>}
+    @ivar nbLines:         number of rows
+    @type nbLines:         int
+    @ivar verbosity:       verbosity
+    @type verbosity:       int
+    """
+
+    def __init__(self, connection, name, verbosity = 0):
+        """
+        Constructor
+        Possibly retrieve column names and types if table exists
+        @param mySqlConnection: connection to a databas
+        @type  mySqlConnection: class L{MySqlConnection<MySqlConnection>}
+        @param name:            name of the table
+        @type  name:            string
+        @param verbosity:       verbosity
+        @type  verbosity:       int
+        """
+        self.name      = name
+        self.variables = []
+        self.types     = {}
+        self.sizes     = {}
+        self.nbLines   = None
+        self.verbosity = verbosity
+        self.mySqlConnection = connection
+        queryTables = self.mySqlConnection.executeQuery("SELECT name FROM sqlite_master WHERE type LIKE 'table' AND name LIKE '%s'" % (self.name))
+        self.created = not queryTables.isEmpty()
+        if self.created:
+            queryFields = self.mySqlConnection.executeQuery("PRAGMA table_info('%s')" % (name))
+            for field in queryFields.getIterator():
+                if field[1] != "id":
+                    self.variables.append(field[1])
+                    self.types[field[1]] = field[2]
+                    self.sizes[field[1]] = field[3]
+                    
+                    
+    def getName(self):
+        return self.name
+
+
+    def create(self, variables, types, sizes):
+        """
+        Create a table using give column names and types
+        @param variables: names of the columns
+        @type  variables: list of string
+        @param types:     types of the columns
+        @type  types:     dict of string
+        @param sizes:     sizes of the types
+        @type  sizes:     dict of int
+        """
+        self.variables = variables
+        self.types = types
+        self.sizes = sizes
+        if self.created:
+            self.remove()
+        query = "CREATE TABLE '%s' (id INTEGER PRIMARY KEY" % (self.name)
+        for variable in variables:
+            query = "%s, %s %s(%d)" % (query, variable, types[variable], sizes[variable])
+        query += ")"
+        self.mySqlConnection.executeQuery(query)
+        self.created = True
+
+
+    def insertMany(self, lines):
+        """
+        Insert many lines
+        @param lines: the list of values
+        @type  lines: list of lists
+        """
+        commands = []
+        for values in lines:
+            commands.append("INSERT INTO '%s' (%s) VALUES (%s)" % (self.name, ", ".join(self.variables), ", ".join([MySqlTable.formatSql(values[variable], self.types[variable], self.sizes[variable]) for variable in self.variables])))
+        self.mySqlConnection.executeManyQueries(commands)
+        
+        
+    def rename(self, name):
+        """
+        Rename the table
+        @param name: the new name
+        @type  name: string
+        """
+        self.mySqlConnection.executeQuery("RENAME TABLE '%s' TO '%s'" % (self.name, name))
+        self.name = name
+        
+    
+    def copy(self, table):
+        """
+        Copy the given table this one
+        @param table: the table to be copied
+        @type  table: class L{MySqlTable<MySqlTable>}
+        """
+        variables = []
+        types = {}
+        sizes = {}
+        fields = self.mySqlConnection.executeQuery("PRAGMA table_info(%s)" % (table.name))
+        for field in fields.getIterator():
+            if field[1] != "id":
+                variables.append(field[1])
+                m = re.search(r"(\w+)\((\d+)\)", field[2])
+                if m == None:
+                    raise Exception("\nFormat %s in table %s is strange." % (field[2], table.name))
+                types[field[1]] = m.group(1)
+                sizes[field[1]] = int(m.group(2))
+        self.create(variables, types, sizes)
+        self.mySqlConnection.executeQuery("INSERT INTO '%s' SELECT * FROM %s" % (self.name, table.name))
+        
+
+    def add(self, table):
+        """
+        Add the content of a table to this one
+        @param table: the table to be added
+        @type  table: class L{MySqlTable<MySqlTable>}
+        """
+        self.mySqlConnection.executeQuery("INSERT INTO '%s' SELECT * FROM %s" % (self.name, table.name))
+        self.created = True
+        
+        
+    def exists(self):
+        """
+        Check if the table exists in mySQL
+        @return: true if it exits
+        """
+        return self.created
+    
+
+    def remove(self):
+        """
+        Remove this table
+        """
+        if self.exists():
+            query = "DROP TABLE IF EXISTS '%s'" % (self.name)
+            self.mySqlConnection.executeQuery(query)
+        self.created = False
+        
+        
+    def clear(self):
+        """
+        Clear the content of this table
+        """
+        self.mySqlConnection.executeQuery("DELETE FROM '%s'" % (self.name))
+        
+        
+    def getNbElements(self):
+        """
+        Count the number of rows in the table
+        """
+        command = "SELECT COUNT(id) FROM '%s'" % (self.name)
+        query = self.mySqlConnection.executeQuery(command)
+        return int(query.getLine()[0])
+
+
+    def formatSql(self, value, type, size):
+        """
+        Format a value using MySQL encapsulation
+        """
+        if type.find("int") != -1:
+            return "%d" % value
+        if type.find("float") != -1:
+            return "%.10f" % value
+        if type.find("double") != -1:
+            return "%.20f" % value
+        if type.find("varchar") != -1:
+            if len(value) > size:
+                return "'%s'" % value[0:size]
+            return "'%s'" % value
+        raise Exception("Do not understand type %s" % (type))
+    formatSql = classmethod(formatSql)
+
+
+    def addLine(self, values):
+        """
+        Add a row to this table
+        @param values: the values of the row
+        @type  values: dict
+        @return:       the id of the added row
+        """
+        sqlValues = []
+        for variable in self.variables:
+            sqlValues.append(self.formatSql(values[variable], self.types[variable], self.sizes[variable]))
+        command = "INSERT INTO '%s' (%s) VALUES (%s)" % (self.name, ", ".join(self.variables), ", ".join(sqlValues))
+        id = self.mySqlConnection.executeQuery(command, True)
+        return id
+    
+    
+    def retrieveFromId(self, id):
+        """
+        Retrieve a row from its id
+        @param id: the id of the row
+        @type  id: int
+        @return:   the row
+        """
+        query = self.mySqlConnection.executeQuery("SELECT * FROM '%s' WHERE id = %d" % (self.name, id))
+        result = query.getLine()
+        if result == None:
+            raise Exception("Error! Id %d is not in the table %s!" % (id, self.name))
+        return result
+
+
+    def retrieveBulkFromId(self, ids):
+        """
+        Retrieve a row from its id
+        @param id: the ids of the row
+        @type  id: list of int
+        @return:   the row
+        """
+        if not ids:
+            return []
+        MAXSIZE = 1000
+        results = []
+        for batch in range(len(ids) / MAXSIZE + 1):
+            theseIds = ids[batch * MAXSIZE : (batch+1) * MAXSIZE]
+            if theseIds:
+                query = self.mySqlConnection.executeQuery("SELECT * FROM '%s' WHERE id IN (%s)" % (self.name, ", ".join(["%d" % (id) for id in theseIds])))
+                lines = query.getLines()
+                if len(lines) != len(theseIds):
+                    raise Exception("Error! Some Ids of (%s) is are missing in the table '%s' (got %d instead of %d)!" % (", ".join(["%d" % (id) for id in theseIds]), self.name, len(lines)), len(theseIds))
+                results.extend(lines)
+        return results
+
+
+    def removeFromId(self, id):
+        """
+        Remove a row from its id
+        @param id: the id of the row
+        @type  id: int
+        """
+        self.mySqlConnection.executeQuery("DELETE FROM '%s' WHERE id = %d" % (self.name, id))
+    
+    
+    def getIterator(self):
+        """
+        Iterate on the content of table
+        @return: iterator to the rows of the table
+        """
+        if not self.created:
+            return
+        MAXSIZE = 1000
+        query = self.mySqlConnection.executeQuery("SELECT count(id) FROM '%s'" % (self.name))
+        nbRows = int(query.getLine()[0])
+        for chunk in range((nbRows / MAXSIZE) + 1):
+            query = self.mySqlConnection.executeQuery("SELECT * FROM '%s' LIMIT %d, %d" % (self.name, chunk * MAXSIZE, MAXSIZE))
+            for line in query.getIterator():
+                yield line
+
+
+    def createIndex(self, indexName, values, unique = False, fullText = False):
+        """
+        Add an index on the table
+        @param indexName: name of the index
+        @type  indexName: string
+        @param values:    values to be indexed
+        @type  values:    string
+        @param unique:    if the index is unique
+        @type  unique:    boolean
+        @param fullText:  whether full text should be indexed
+        @type  fullText:  boolean
+        """
+        self.mySqlConnection.executeQuery("CREATE %s%sINDEX '%s' ON '%s' (%s)" % ("UNIQUE " if unique else "", "FULLTEXT " if fullText else "", indexName, self.name, ", ".join(values)))
+
+
+    def setDefaultTagValue(self, field, name, value):
+        """
+        Add a tag value
+        @param name:  name of the tag
+        @type  name:  string
+        @param value: value of the tag
+        @type  value: string or int
+        """
+        newData = {}
+        for line in MySqlTable.getIterator(self):
+            id = line[0]
+            tags = line[field]
+            if tags == '':
+                newTag = "%s=%s" % (name, value)
+            else:
+                newTag = "%s;%s=%s" % (tags, name, value)
+            if name not in [tag.split("=")[0] for tag in tags.split(";")]:
+                newData[id] = newTag
+        for id, tag in newData.iteritems():
+            query = self.mySqlConnection.executeQuery("UPDATE '%s' SET tags = '%s' WHERE id = %i" % (self.name, tag, id))
+
+
+
+    def show(self):
+        """
+        Drop the content of the current table
+        """
+        query = self.mySqlConnection.executeQuery("SELECT * FROM '%s'" % (self.name))
+        print query.getLines()
+
+
Binary file smart_toolShed/SMART/Java/Python/mySql/MySqlTable.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/mySql/MySqlTranscriptTable.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,149 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import random
+import sys
+from SMART.Java.Python.structure.TranscriptList import TranscriptList
+from SMART.Java.Python.mySql.MySqlExonTable import MySqlExonTable
+from SMART.Java.Python.mySql.MySqlTable import MySqlTable
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.misc.Progress import Progress
+
+class MySqlTranscriptTable(MySqlTable):
+    """A table of transcripts in a mySQL database"""
+
+    def __init__(self, connection, name = None, chromosome = None, verbosity = 0):
+        if chromosome == None:
+            chromosome = ""
+        else:
+            chromosome = "_%s" % chromosome
+        if name == None:
+            name = "TmpTable_%d" % (random.randint(0, 100000))
+        name = "%s%s" % (name, chromosome)
+        super(MySqlTranscriptTable, self).__init__(connection, "%s_transcripts" % name, verbosity)
+
+
+    def createTranscriptTable(self):
+        self.create(Transcript.getSqlVariables(), Transcript.getSqlTypes(), Transcript.getSqlSizes())
+
+
+    def rename(self, name):
+        super(MySqlTranscriptTable, self).rename("%s_transcripts" % name)
+
+
+    def remove(self):
+        super(MySqlTranscriptTable, self).remove()
+        
+        
+    def clear(self):
+        super(MySqlTranscriptTable, self).clear()
+
+        
+    def copy(self, transcriptTable):
+        self.remove()
+        super(MySqlTranscriptTable, self).copy(transcriptTable)
+
+
+    def add(self, transcriptTable):
+        super(MySqlTranscriptTable, self).add(transcriptTable)
+
+
+    def addTranscript(self, transcript):
+        id = self.addLine(transcript.getSqlValues())
+        transcript.id = id
+            
+            
+    def addTranscriptList(self, transcriptList):
+        progress = Progress(transcriptList.getNbTranscript(), "Storing list to %s" % (self.name), self.verbosity)
+        for transcript in transcriptList.getIterator():
+            self.addTranscript(transcript)
+            progress.inc()
+        progress.done()
+
+            
+    def removeTranscript(self, transcript):
+        self.removeFromId(transcript.id)
+            
+            
+    def retrieveTranscriptFromId(self, id):
+        transcript = Transcript()
+        transcript.setSqlValues(self.retrieveFromId(id))
+        return transcript
+    
+    
+    def retrieveBulkTranscriptFromId(self, ids):
+        if not ids:
+            return []
+        transcripts = self.retrieveBulkFromId(ids)
+        idsToTranscripts = {}
+        for values in transcripts:
+            transcript = Transcript()
+            transcript.setSqlValues(values)
+            idsToTranscripts[values[0]] = transcript
+        return idsToTranscripts.values()
+    
+    
+    def selectTranscripts(self, command, simple = False):
+        MAXSIZE = 100000
+        found   = True
+        cpt     = 0
+        while found:
+            found = False
+            if simple:
+                thisCommand = command
+            else:
+                thisCommand = "%s LIMIT %d OFFSET %d" % (command, MAXSIZE, MAXSIZE * cpt)
+            query = self.mySqlConnection.executeQuery(thisCommand)
+            for line in query.getIterator():
+                found      = True
+                id         = int(line[0])
+                transcript = Transcript()
+                transcript.setSqlValues(line)
+                yield (id, transcript)
+            cpt += 1
+            if simple:
+                return
+
+    
+    def getIterator(self):
+        for id, transcript in self.selectTranscripts("SELECT * FROM '%s'" % (self.name)):
+            yield transcript
+
+
+    def retrieveTranscriptList(self):
+        transcriptList = TranscriptList()
+        for transcriptLine in self.getLines():
+            transcript = Transcript()
+            transcript.setSqlValues(transcriptLine)
+            transcriptList.addTranscript(transcript)
+        return transcriptList
+            
+
+    def setDefaultTagValue(self, name, value):
+        super(MySqlTranscriptTable, self).setDefaultTagValue(Transcript.getSqlVariables().index("tags")+1, name, value)
Binary file smart_toolShed/SMART/Java/Python/mySql/MySqlTranscriptTable.pyc has changed
Binary file smart_toolShed/SMART/Java/Python/mySql/__init__.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/mySql/test/Test_MySqlTranscriptTable.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,158 @@
+from commons.core.writer.MySqlTranscriptWriter import MySqlTranscriptWriter
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.mySql.MySqlConnection import MySqlConnection
+from SMART.Java.Python.mySql.MySqlTranscriptTable import MySqlTranscriptTable
+import unittest
+
+
+class Test_MySqlTranscriptTable(unittest.TestCase):
+  
+    def test_getRange(self):
+        transcript = Transcript()
+        transcript.setName("test1.1")
+        transcript.setChromosome("arm_X")
+        transcript.setStart(1000)
+        transcript.setEnd(4000)
+        transcript.setSize(2000)
+        transcript.setDirection("+")
+        
+        exon1 = Interval()
+        exon1.setName("test1.1")
+        exon1.setChromosome("arm_X")
+        exon1.setStart(1000)
+        exon1.setEnd(2000)
+        exon1.setSize(1000)
+        
+        exon2 = Interval()
+        exon2.setName("test1.1")
+        exon2.setChromosome("arm_X")
+        exon2.setStart(3000)
+        exon2.setEnd(4000)
+        exon2.setSize(1000)
+        
+        transcript.addExon(exon1)
+        transcript.addExon(exon2)
+        
+        connection = MySqlConnection()
+        writer = MySqlTranscriptWriter(connection, "testMySqlTranscriptTableGetRange")
+        writer.addTranscript(transcript)
+        writer.write()
+        
+        transcriptContainer = TranscriptContainer("testMySqlTranscriptTableGetRange", "sql")
+        transcriptContainer.mySqlConnection = connection
+        self.assertEqual(transcriptContainer.getNbTranscripts(), 1)
+        for transcript in transcriptContainer.getIterator():
+            self.assertEqual(transcript.getName(), "test1.1")
+            self.assertEqual(transcript.getChromosome(), "arm_X")
+            self.assertEqual(transcript.getStart(), 1000)
+            self.assertEqual(transcript.getEnd(), 4000)
+            self.assertEqual(transcript.getSize(), 2002)
+            self.assertEqual(transcript.getNbExons(), 2)
+            exons = transcript.getExons()
+            self.assertEqual(exons[0].getStart(), 1000)
+            self.assertEqual(exons[0].getEnd(), 2000)
+            self.assertEqual(exons[1].getStart(), 3000)
+            self.assertEqual(exons[1].getEnd(), 4000)
+    
+    
+    def test_setDefaultTagValue(self):
+        transcript1 = Transcript()
+        transcript1.setName("test1.1")
+        transcript1.setChromosome("arm_X")
+        transcript1.setStart(1000)
+        transcript1.setEnd(2000)
+        transcript1.setDirection("+")
+        
+        exon1 = Interval()
+        exon1.setName("test1.1")
+        exon1.setChromosome("arm_X")
+        exon1.setStart(1000)
+        exon1.setEnd(2000)
+        
+        transcript1.addExon(exon1)
+        
+        transcript2 = Transcript()
+        transcript2.setName("test2.1")
+        transcript2.setChromosome("arm_X")
+        transcript2.setStart(1000)
+        transcript2.setEnd(2000)
+        transcript2.setDirection("+")
+        transcript2.setTagValue("nbOccurrences", "2")
+        
+        exon2 = Interval()
+        exon2.setName("test2.1")
+        exon2.setChromosome("arm_X")
+        exon2.setStart(1000)
+        exon2.setEnd(2000)
+        
+        transcript2.addExon(exon2)
+        
+        transcript3 = Transcript()
+        transcript3.setName("test3.1")
+        transcript3.setChromosome("arm_X")
+        transcript3.setStart(1000)
+        transcript3.setEnd(2000)
+        transcript3.setDirection("+")
+        transcript3.setTagValue("occurrences", "2")
+        
+        exon3 = Interval()
+        exon3.setName("test3.1")
+        exon3.setChromosome("arm_X")
+        exon3.setStart(1000)
+        exon3.setEnd(2000)
+        
+        transcript3.addExon(exon3)
+        
+        connection = MySqlConnection()
+        table      = MySqlTranscriptTable(connection, "testMySqlTranscriptTableSetDefaultTagValue")
+        table.createTranscriptTable()
+        table.addTranscript(transcript1)
+        table.addTranscript(transcript2)
+        table.addTranscript(transcript3)
+        table.setDefaultTagValue("occurrence", "1")
+        
+        cpt = 0
+        for transcript in table.getIterator():
+            cpt += 1
+            self.assert_(cpt != 4)
+            if cpt == 1:
+                self.assertEqual(transcript.name, "test1.1")
+                self.assertEqual(transcript.getChromosome(), "arm_X")
+                self.assertEqual(transcript.getStart(), 1000)
+                self.assertEqual(transcript.getEnd(), 2000)
+                self.assertEqual(transcript.getSize(), 1001)
+                self.assertEqual(transcript.getNbExons(), 1)
+                exons = transcript.getExons()
+                self.assertEqual(exons[0].getStart(), 1000)
+                self.assertEqual(exons[0].getEnd(), 2000)
+                self.assertEqual(transcript.getTagValue("occurrence"), 1)
+            elif cpt == 2:
+                self.assertEqual(transcript.name, "test2.1")
+                self.assertEqual(transcript.getChromosome(), "arm_X")
+                self.assertEqual(transcript.getStart(), 1000)
+                self.assertEqual(transcript.getEnd(), 2000)
+                self.assertEqual(transcript.getSize(), 1001)
+                self.assertEqual(transcript.getNbExons(), 1)
+                exons = transcript.getExons()
+                self.assertEqual(exons[0].getStart(), 1000)
+                self.assertEqual(exons[0].getEnd(), 2000)
+                self.assertEqual(transcript.getTagValue("nbOccurrences"), 2)
+                self.assertEqual(transcript.getTagValue("occurrence"), 1)
+            elif cpt == 2:
+                self.assertEqual(transcript.name, "test3.1")
+                self.assertEqual(transcript.getChromosome(), "arm_X")
+                self.assertEqual(transcript.getStart(), 1000)
+                self.assertEqual(transcript.getEnd(), 2000)
+                self.assertEqual(transcript.getSize(), 1001)
+                self.assertEqual(transcript.getNbExons(), 1)
+                exons = transcript.getExons()
+                self.assertEqual(exons[0].getStart(), 1000)
+                self.assertEqual(exons[0].getEnd(), 2000)
+                self.assertEqual(transcript.getTagValue("occurrence"), 2)
+      
+        table.remove()
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/ConvertToNCList.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,172 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2012
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+import random, os, time, shutil
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.ncList.NCList import NCList
+from SMART.Java.Python.ncList.NCListCursor import NCListCursor
+from SMART.Java.Python.ncList.NCListFilePickle import NCListFilePickle, NCListFileUnpickle
+from SMART.Java.Python.ncList.FileSorter import FileSorter
+from SMART.Java.Python.ncList.NCListMerger import NCListMerger
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+try:
+   import cPickle as pickle
+except:
+   import pickle
+
+class ConvertToNCList(object):
+	
+	def __init__(self, verbosity = 1):
+		self._parsers				  = {}
+		self._sortedFileNames		  = {}
+		self._inputFileName		      = None
+		self._outputFileName		  = None
+		self._index				      = False
+		self._ncLists				  = {}
+		self._splittedFileNames	      = {}
+		self._nbElements			  = 0
+		self._nbElementsPerChromosome = {}
+		self._randomNumber			  = random.randint(0, 10000)
+		self._sorted                  = False
+		self._verbosity			      = verbosity
+		
+	def setInputFileName(self, fileName, format):
+		self._inputFileName = fileName
+		chooser = ParserChooser(self._verbosity)
+		chooser.findFormat(format)
+		self._parser = chooser.getParser(fileName)
+		
+	def setOutputFileName(self, fileName):
+		self._outputFileName = fileName
+		fileNameNoExtension  = os.path.splitext(fileName)[0]
+		baseName			 = "%s_%d" % (fileNameNoExtension, self._randomNumber)
+		self._directory	     = "%s_files" % (baseName)
+		if not os.path.exists(self._directory):
+			os.makedirs(self._directory)
+		self._sortedFileNames = os.path.join(self._directory, baseName)
+
+	def setIndex(self, boolean):
+		self._index = boolean
+
+	def setSorted(self, boolean):
+		self._sorted = boolean
+
+	def sortFile(self):
+		if self._verbosity > 2:
+			print "%s file %s..." % ("Rewriting" if self._sorted else "Sorting", self._inputFileName)
+		startTime = time.time()
+		fs = FileSorter(self._parser, self._verbosity-4)
+		fs.setPresorted(self._sorted)
+		fs.perChromosome(True)
+		fs.setOutputFileName(self._sortedFileNames)
+		fs.sort()
+		self._splittedFileNames	      = fs.getOutputFileNames()
+		self._nbElementsPerChromosome = fs.getNbElementsPerChromosome()
+		self._nbElements			  = fs.getNbElements()
+		endTime = time.time()
+		if self._verbosity > 2:
+			print "	...done (%ds)" % (endTime - startTime)
+			
+	def createNCLists(self):
+		self._ncLists = {}
+		if self._verbosity > 2:
+			print "Creating NC-list for %s..." % (self._inputFileName)
+		startTime = time.time()
+		for chromosome, fileName in self._splittedFileNames.iteritems():
+			if self._verbosity > 3:
+				print "  chromosome %s" % (chromosome)
+			ncList = NCList(self._verbosity)
+			if self._index:
+				ncList.createIndex(True)
+			ncList.setChromosome(chromosome)
+			ncList.setFileName(fileName)
+			ncList.setNbElements(self._nbElementsPerChromosome[chromosome])
+			ncList.buildLists()
+			self._ncLists[chromosome] = ncList
+		endTime = time.time()
+		if self._verbosity > 2:
+			print "	...done (%ds)" % (endTime - startTime)
+
+	def writeOutputFile(self):
+		merger = NCListMerger(self._verbosity)
+		merger.setFileName(self._outputFileName)
+		merger.addIndex(self._index)
+		merger.setNCLists(self._ncLists)
+		merger.merge()
+
+	def cleanFiles(self):
+		shutil.rmtree(self._directory)
+
+	def run(self):
+		self.sortFile()
+		self.createNCLists()
+		self.writeOutputFile()
+		self.cleanFiles()
+
+	def getSortedFileNames(self):
+		return self._splittedFileNames
+
+	def getNbElements(self):
+		return self._nbElements
+
+	def getNbElementsPerChromosome(self):
+		return self._nbElementsPerChromosome
+
+	def getNCLists(self):
+		return self._ncLists
+
+	def getTmpDirectory(self):
+		return self._directory
+
+
+if __name__ == "__main__":
+	description = "Convert To NC-List v1.0.0: Convert a mapping or transcript file into a NC-List. [Category: NC-List]"
+
+	parser = OptionParser(description = description)
+	parser.add_option("-i", "--input",	   dest="inputFileName",  action="store",					  type="string",  help="Query input file [compulsory] [format: file in transcript format given by -f]")
+	parser.add_option("-f", "--format",	   dest="format",		  action="store",					  type="string",  help="format of previous file [compulsory] [format: transcript file format]")
+	parser.add_option("-d", "--index",	   dest="index",		  action="store_true", default=False,				  help="create an index [default: false] [format: boolean]")
+	parser.add_option("-o", "--output",	   dest="outputFileName", action="store",					  type="string",  help="Output file [compulsory] [format: output file in NCList format]")
+	parser.add_option("-s", "--sorted",	   dest="sorted",	      action="store_true", default=False,	              help="input file is already sorted [format: boolean] [default: False]")
+	parser.add_option("-v", "--verbosity", dest="verbosity",	  action="store",	   default=1,	  type="int",	  help="Trace level [format: int] [default: 1]")
+	(options, args) = parser.parse_args()
+	
+	ctncl = ConvertToNCList(options.verbosity)
+	ctncl.setInputFileName(options.inputFileName, options.format)
+	ctncl.setOutputFileName(options.outputFileName)
+	ctncl.setIndex(options.index)
+	ctncl.setSorted(options.sorted)
+	ctncl.run()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/FileSorter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,210 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+try:
+	import cPickle as pickle
+except:
+	import pickle
+import random, os
+from heapq import heapify, heappop, heappush
+from itertools import islice, cycle
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+
+BUFFER_SIZE = 100 * 1024
+
+class FileSorter(object):
+
+	def __init__(self, parser, verbosity = 1):
+		self._parser				  = parser
+		self._verbosity			      = verbosity
+		self._chunks				  = {}
+		self._nbElements			  = 0
+		self._nbElementsPerChromosome = {}
+		self._perChromosome		      = False
+		self._isPreSorted             = False
+		self._outputFileNames		  = {}
+		self._prefix				  = "tmpFile_%d" % (random.randint(0, 100000))
+		self._chromosome			  = None
+		if "SMARTTMPPATH" in os.environ:
+			self._prefix = os.path.join(os.environ["SMARTTMPPATH"], self._prefix)
+
+	def selectChromosome(self, chromosome):
+		self._chromosome = chromosome
+
+	def perChromosome(self, boolean):
+		self._perChromosome = boolean
+
+	def setOutputFileName(self, fileName):
+		self._outputFileName = fileName
+		if self._perChromosome:
+			self._outputFileName = os.path.splitext(self._outputFileName)[0]
+			
+	def setPresorted(self, presorted):
+		self._isPreSorted = presorted
+		
+	def sort(self):
+		if not self._isPreSorted:
+			self._batchSort()
+		else:
+			self._presorted()
+	
+	def _presorted(self):
+		progress = UnlimitedProgress(1000, "Writing files %s" % (self._parser.fileName), self._verbosity)
+		curChromosome = None
+		outputHandle  = None
+		
+		if not self._perChromosome:
+			outputHandle = open(self._outputFileName, "wb")
+		for transcript in self._parser.getIterator():
+			progress.inc()
+			if transcript.__class__.__name__ == "Mapping":
+				transcript = transcript.getTranscript()
+			chromosome = transcript.getChromosome()
+			if self._chromosome != None and chromosome != self._chromosome:
+				continue
+			self._nbElements += 1
+			self._nbElementsPerChromosome[chromosome] = self._nbElementsPerChromosome.get(chromosome, 0) + 1
+			if self._perChromosome:
+				if chromosome != curChromosome:
+					if outputHandle != None:
+						outputHandle.close()
+					self._outputFileNames[chromosome] = "%s_%s.pkl" % (self._outputFileName, chromosome)
+					outputHandle  = open(self._outputFileNames[chromosome], "wb")
+					curChromosome = chromosome
+			outputHandle.writelines("%s" % pickle.dumps(transcript))  
+		if outputHandle != None:
+			outputHandle.close()
+		progress.done() 
+
+	def getNbElements(self):
+		return self._nbElements
+
+	def getNbElementsPerChromosome(self):
+		return self._nbElementsPerChromosome
+
+	def _printSorted(self, chromosome, chunk):
+		chunk.sort(key = lambda transcript: (transcript.getStart(), -transcript.getEnd()))
+		outputChunk = open("%s_%s_%06i.tmp" % (self._prefix, chromosome, len(self._chunks[chromosome])), "wb", 32000)
+		self._chunks[chromosome].append(outputChunk)
+		for transcript in chunk:
+			outputChunk.write(pickle.dumps(transcript, -1))
+		outputChunk.close()
+		
+	def _merge(self, chunks):
+		values = []
+		for chunk in chunks:
+			chunk = open(chunk.name, "rb")
+			try:
+				transcript = pickle.load(chunk)
+				start	   = transcript.getStart()
+				end		   = -transcript.getEnd()
+			except EOFError:
+				try:
+					chunk.close()
+					chunks.remove(chunk)
+					os.remove(chunk.name)
+				except:
+					pass
+			else:
+				heappush(values, (start, end, transcript, chunk))
+		while values:
+			start, end, transcript, chunk = heappop(values)
+			yield transcript
+			try:
+				transcript = pickle.load(chunk)
+				start	   = transcript.getStart()
+				end		   = -transcript.getEnd()
+			except EOFError:
+				try:
+					chunk.close()
+					chunks.remove(chunk)
+					os.remove(chunk.name)
+				except:
+					pass
+			else:
+				heappush(values, (start, end, transcript, chunk))
+		
+	def _batchSort(self):
+		currentChunks = {}
+		counts		  = {}
+		try:
+			progress = UnlimitedProgress(1000, "Sorting file %s" % (self._parser.fileName), self._verbosity)
+			for transcript in self._parser.getIterator():
+				progress.inc()
+				if transcript.__class__.__name__ == "Mapping":
+					transcript = transcript.getTranscript()
+				chromosome = transcript.getChromosome()
+				if self._chromosome != None and chromosome != self._chromosome:
+					continue
+				if chromosome not in self._chunks:
+					self._chunks[chromosome]  = []
+					currentChunks[chromosome] = []
+					counts[chromosome]		= 0
+				currentChunks[chromosome].append(transcript)
+				counts[chromosome] += 1
+				if counts[chromosome] == BUFFER_SIZE:
+					self._printSorted(chromosome, currentChunks[chromosome])
+					currentChunks[chromosome] = []
+					counts[chromosome]		  = 0
+				self._nbElements += 1
+				self._nbElementsPerChromosome[chromosome] = self._nbElementsPerChromosome.get(chromosome, 0) + 1
+			for chromosome in self._chunks:
+				if counts[chromosome] > 0:
+					self._printSorted(chromosome, currentChunks[chromosome])
+			progress.done()
+			if not self._perChromosome:
+				outputHandle = open(self._outputFileName, "wb")
+			progress = Progress(len(self._chunks), "Writing sorted file %s" % (self._parser.fileName), self._verbosity)
+			for chromosome in self._chunks:
+				if self._perChromosome:
+					self._outputFileNames[chromosome] = "%s_%s.pkl" % (self._outputFileName, chromosome)
+					outputHandle = open(self._outputFileNames[chromosome], "wb")
+				for sequence in self._merge(self._chunks[chromosome]):
+					pickle.dump(sequence, outputHandle, -1)
+				if self._perChromosome:
+					outputHandle.close()
+				progress.inc()
+			if not self._perChromosome:
+				outputHandle.close()
+			progress.done()
+		finally:
+			for chunks in self._chunks.values():
+				for chunk in chunks:
+					try:
+						chunk.close()
+						os.remove(chunk.name)
+					except Exception:
+						pass
+
+	def getOutputFileNames(self):
+		return self._outputFileNames
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/FindOverlapsWithOneInterval.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,197 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+import struct
+import math
+import os
+from optparse import OptionParser
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.ncList.NCList import NCList
+from SMART.Java.Python.ncList.FileSorter import FileSorter
+from commons.core.parsing.ParserChooser import ParserChooser
+from SMART.Java.Python.ncList.NCListCursor import NCListCursor
+from SMART.Java.Python.structure.Transcript import Transcript
+
+LONGSIZE = struct.calcsize('l')
+
+class FindOverlapsWithOneInterval(object):
+	
+	def __init__(self, verbosity):
+		self._sortedFileName   = None
+		self._verbosity		= verbosity
+		self._overlappingNames = []
+		self._nbOverlaps	   = 0
+		self._nbWritten		= 0
+		
+	def __del__(self):
+		if self._sortedFileName and os.path.exists(self._sortedFileName):
+			os.remove(self._sortedFileName)
+	
+	def close(self):
+		self._iWriter.close()
+		
+	def setOutputFileName(self, fileName):
+		self._iWriter = Gff3Writer(fileName)
+		
+	def setFileName(self, fileName, format):
+		chooser = ParserChooser(self._verbosity)
+		chooser.findFormat(format)
+		self._parser		 = chooser.getParser(fileName)
+		self._sortedFileName = "%s_sorted.pkl" % (os.path.splitext(fileName)[0])
+		
+	def setInterval(self, chromosome, start, end):
+		self._chromosome = chromosome
+		self._start	  = start
+		self._end		= end
+		self._transcript = Transcript()
+		self._transcript.setChromosome(chromosome)
+		self._transcript.setStart(start)
+		self._transcript.setEnd(end)
+		self._transcript.setDirection("+")
+		
+	def setTranscript(self, transcript):
+		if transcript.__class__.__name__ == "Mapping":
+			transcript = transcript.getTranscript()
+		self._chromosome = transcript.getChromosome()
+		self._start	  = transcript.getStart()
+		self._end		= transcript.getEnd()
+		self._transcript = transcript
+
+	def prepareIntermediateFiles(self):
+		fs = FileSorter(self._parser, self._verbosity-4)
+		fs.selectChromosome(self._chromosome)
+		fs.perChromosome(False)
+		fs.setOutputFileName(self._sortedFileName)
+		fs.sort()
+		self._nbTotalLines = fs.getNbElements()
+		self._nbLines	  = fs.getNbElementsPerChromosome()[self._chromosome]
+			
+	def createNCList(self):
+		if self._verbosity > 2:
+			print "Creating NC-list..."
+		ncList = NCList(self._verbosity)
+		ncList.createIndex(True)
+		ncList.setChromosome(self._chromosome)
+		ncList.setFileName(self._sortedFileName)
+		ncList.setNbElements(self._nbTotalLines)
+		ncList.buildLists()
+		self.setNCList(ncList, ncList.getIndex())
+		if self._verbosity > 2:
+			print "	...done (%ds)" % (endTime - startTime)
+
+	def setNCList(self, ncList, index):
+		self._ncList = ncList
+		self._indix  = index
+
+	def binarySearch(self, cursor, startL, endL):
+		if startL > endL:
+			return None
+		middleL = (startL + endL) / 2
+		cursor.moveSibling(middleL)
+		overlap = self.isOverlapping(cursor)
+		if overlap == 0:
+			if middleL == startL:
+				return cursor
+			else:
+				return self.binarySearch(cursor, startL, middleL)
+		if overlap == -1:
+			return self.binarySearch(cursor, middleL + 1, endL)
+		return self.binarySearch(cursor, startL, middleL - 1)
+
+	def compare(self, cursor = None):
+		self._ncList.openFiles()
+		if cursor == None:
+			dump   = True
+			cursor = NCListCursor(None, self._ncList, 0, self._verbosity)
+		cursor._getSiblingData()
+		cursor = self.binarySearch(cursor, cursor._firstSiblingLIndex, cursor._lastSiblingLIndex)
+		if cursor == None:
+			return
+		while not cursor.isOut() and self.isOverlapping(cursor) == 0:
+			self.write(cursor)
+			newCursor = NCListCursor(cursor)
+			if newCursor.hasChildren():
+				newCursor.moveDown()
+				self.compare(newCursor)
+			if cursor.isLast():
+				return
+			cursor.moveRight()
+				
+	def isOverlapping(self, cursor):
+		if self._end < cursor.getStart():
+			return 1
+		if self._start > cursor.getEnd():
+			return -1
+		return 0
+
+	def write(self, cursor):
+		self._nbOverlaps += 1
+		refTranscript = cursor.getTranscript()
+		self._overlappingNames.append(refTranscript.getName())
+
+	def dumpWriter(self):
+		if (not self._overlappingNames) or self._transcript == None:
+			return
+		self._transcript.setTagValue("nbOverlaps", len(self._overlappingNames))
+		self._transcript.setTagValue("overlapsWith", "--".join(self._overlappingNames))
+		self._iWriter.addTranscript(self._transcript)
+		self._nbWritten	   += 1
+		self._overlappingNames = []
+
+	def run(self):
+		self.prepareIntermediateFiles()
+		self.createNCList()
+		self.compare()
+		self.dumpWriter()
+		self.close()
+		if self._verbosity > 0:
+			print "# refs:	%d" % (self._nbLines)
+			print "# written: %d (%d overlaps)" % (self._nbOverlappingQueries, self._nbOverlaps)
+
+	
+if __name__ == "__main__":
+	description = "FindOverlapsWithOneInterval: Finds overlaps with one query interval."
+
+	parser = OptionParser(description = description)
+	parser.add_option("-i", "--input",	   dest="inputFileName",	  action="store",			type="string",  help="Input file [compulsory] [format: file in transcript format given by -f]")
+	parser.add_option("-f", "--format",	  dest="format",			 action="store",			type="string",  help="Format of previous file [compulsory] [format: transcript file format]")
+	parser.add_option("-s", "--start",	   dest="start",			  action="store",			type="int",	 help="The start of the query interval [compulsory] [format: int]")
+	parser.add_option("-e", "--end",		 dest="end",				action="store",			type="int",	 help="The end of the query interval [compulsory] [format: int]")
+	parser.add_option("-c", "--chromosome",  dest="chromosome",		 action="store",			type="string",  help="Chromosome of the query interval [compulsory] [format: string]")
+	parser.add_option("-o", "--output",	  dest="outputFileName",	 action="store",			type="string",  help="Output file [compulsory] [format: output file in GFF3 format]")
+	parser.add_option("-v", "--verbosity",   dest="verbosity",		  action="store", default=1, type="int",	 help="Trace level [format: int] [default: 1]")
+	(options, args) = parser.parse_args()
+	
+	iFOWOI = FindOverlapsWithOneInterval(options.verbosity)
+	iFOWOI.setFileName(options.inputFileName, options.format)
+	iFOWOI.setInterval(options.chromosome, options.start, options.end)
+	iFOWOI.setOutputFileName(options.outputFileName)
+	iFOWOI.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/FindOverlapsWithSeveralIntervals.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,182 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+import os, struct, time
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.ncList.NCList import NCList
+from SMART.Java.Python.ncList.NCListCursor import NCListCursor
+from SMART.Java.Python.ncList.NCListFilePickle import NCListFilePickle, NCListFileUnpickle
+from SMART.Java.Python.ncList.FileSorter import FileSorter
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+from SMART.Java.Python.ncList.NCListCursor import NCListCursor
+from SMART.Java.Python.ncList.FindOverlapsWithOneInterval import FindOverlapsWithOneInterval
+
+REFERENCE = 0
+QUERY = 1
+TYPETOSTRING = {0: "reference", 1: "query"}
+
+class FindOverlapsWithSeveralIntervals(object):
+    
+    def __init__(self, verbosity = 1):
+        self._parsers            = {}
+        self._outputFileName     = "outputOverlaps.gff3"
+        self._iWriter            = None
+        self._nbLines            = {REFERENCE: 0, QUERY: 0}
+        self._verbosity          = verbosity
+        self._ncLists            = {}
+        self._sortedRefFileNames = None
+        self._transQueryFileName = None
+        self._cursors            = {}
+        self._iFowoi             = FindOverlapsWithOneInterval(self._verbosity)
+        
+    def __del__(self):
+        self.close()
+        for fileName in (self._sortedRefFileNames, self._transQueryFileName):
+            if os.path.exists(fileName):
+                os.remove(fileName)
+    
+    def close(self):
+        self._iFowoi.close()
+        
+    def setRefFileName(self, fileName, format):
+        self.setFileName(fileName, format, REFERENCE)
+        self._sortedRefFileNames = "%s_ref_sorted.pkl" % (os.path.splitext(fileName)[0])
+        
+    def setQueryFileName(self, fileName, format):
+        self.setFileName(fileName, format, QUERY)
+        self._transQueryFileName = "%s_query_trans.pkl" % (os.path.splitext(fileName)[0])
+
+    def setFileName(self, fileName, format, type):
+        chooser = ParserChooser(self._verbosity)
+        chooser.findFormat(format)
+        self._parsers[type]   = chooser.getParser(fileName)
+        
+    def setOutputFileName(self, outputFileName):
+        self._iFowoi.setOutputFileName(outputFileName)
+
+    def _sortRefFile(self):
+        fs = FileSorter(self._parsers[REFERENCE], self._verbosity-4)
+        fs.perChromosome(True)
+        fs.setOutputFileName(self._sortedRefFileNames)
+        fs.sort()
+        self._nbLines[REFERENCE]      = fs.getNbElements()
+        self._nbRefLinesPerChromosome = fs.getNbElementsPerChromosome()
+        self._splittedFileNames       = fs.getOutputFileNames()
+
+    def _translateQueryFile(self):
+        pickler = NCListFilePickle(self._transQueryFileName, self._verbosity)
+        progress = UnlimitedProgress(1000, "Translating query data", self._verbosity-4)
+        cpt      = 0
+        for queryTranscript in self._parsers[QUERY].getIterator():
+            pickler.addTranscript(queryTranscript)
+            progress.inc()
+            cpt += 1
+        progress.done()
+        self._nbLines[QUERY] = cpt
+        self._parsers[QUERY] = NCListFileUnpickle(self._transQueryFileName, self._verbosity)
+            
+    def prepareIntermediateFiles(self):
+        self._sortRefFile()
+        self._translateQueryFile()
+
+    def createNCLists(self):
+        self._ncLists = {}
+        self._indices = {}
+        self._cursors = {}
+        for chromosome, fileName in self._splittedFileNames.iteritems():
+            if self._verbosity > 3:
+                print "  chromosome %s" % (chromosome)
+            ncList = NCList(self._verbosity)
+            ncList.createIndex(True)
+            ncList.setChromosome(chromosome)
+            ncList.setFileName(fileName)
+            ncList.setNbElements(self._nbRefLinesPerChromosome[chromosome])
+            ncList.buildLists()
+            self._ncLists[chromosome] = ncList
+            cursor = NCListCursor(None, ncList, 0, self._verbosity)
+            self._cursors[chromosome] = cursor
+            self._indices[chromosome] = ncList.getIndex()
+        endTime = time.time()
+
+    def compare(self):
+        progress = Progress(self._nbLines[QUERY], "Comparing data", self._verbosity-3)
+        startTime = time.time()
+        for cpt, queryTranscript in enumerate(self._parsers[QUERY].getIterator()):
+            chromosome = queryTranscript.getChromosome()
+            if chromosome not in self._ncLists:
+                continue
+            self._iFowoi.setNCList(self._ncLists[chromosome], self._indices[chromosome])
+            self._iFowoi.setTranscript(queryTranscript)
+            self._iFowoi.compare()
+            self._iFowoi.dumpWriter()
+            progress.inc()
+        progress.done()
+        endTime = time.time()
+        self._timeSpent = endTime - startTime
+
+    def run(self):
+        startTime = time.time()
+        if self._verbosity > 2:
+            print "Creating NC-list..."
+        self.prepareIntermediateFiles()
+        self.createNCLists()
+        endTime = time.time()
+        if self._verbosity > 2:
+            print "    ...done (%.2gs)" % (endTime - startTime)
+        self.compare()
+        self.close()
+        if self._verbosity > 0:
+            print "# queries: %d" % (self._nbLines[QUERY])
+            print "# refs:    %d" % (self._nbLines[REFERENCE])
+            print "# written: %d (%d overlaps)" % (self._iFowoi._nbWritten, self._iFowoi._nbOverlaps)
+            print "time:      %.2gs" % (self._timeSpent)
+
+
+if __name__ == "__main__":
+    description = "FindOverlaps With Several Intervals v1.0.0: Finds overlaps with several query intervals. [Category: Data comparison]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--query",       dest="inputQueryFileName", action="store",            type="string",  help="Query input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--queryFormat", dest="queryFormat",        action="store",            type="string",  help="format of previous file [compulsory] [format: transcript file format]")
+    parser.add_option("-j", "--ref",         dest="inputRefFileName",   action="store",            type="string",  help="Reference input file [compulsory] [format: file in transcript format given by -g]")
+    parser.add_option("-g", "--refFormat",   dest="refFormat",          action="store",            type="string",  help="format of previous file [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",      dest="outputFileName",     action="store",            type="string",  help="Output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-v", "--verbosity",   dest="verbosity",          action="store", default=1, type="int",     help="Trace level [format: int] [default: 1]")
+    (options, args) = parser.parse_args()
+    
+    iFWSI = FindOverlapsWithSeveralIntervals(options.verbosity)
+    iFWSI.setRefFileName(options.inputRefFileName, options.refFormat)
+    iFWSI.setQueryFileName(options.inputQueryFileName, options.queryFormat)
+    iFWSI.setOutputFileName(options.outputFileName)
+    iFWSI.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/FindOverlapsWithSeveralIntervalsBin.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,204 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2011
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import random, os, os.path, time, sqlite3
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Mapping import Mapping
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+try:
+   import cPickle as pickle
+except:
+   import pickle
+
+MINBIN = 3
+MAXBIN = 7
+
+
+def getBin(start, end):
+	for i in range(MINBIN, MAXBIN + 1):
+		binLevel = 10 ** i
+		if int(start / binLevel) == int(end / binLevel):
+			return int(i * 10 ** (MAXBIN + 1) + int(start / binLevel))
+	return int((MAXBIN + 1) * 10 ** (MAXBIN + 1))
+
+def getOverlappingBins(start, end):
+	array	= []
+	bigBin = int((MAXBIN + 1) * 10 ** (MAXBIN + 1))
+	for i in range(MINBIN, MAXBIN + 1):
+		binLevel = 10 ** i
+		array.append((int(i * 10 ** (MAXBIN + 1) + int(start / binLevel)), int(i * 10 ** (MAXBIN + 1) + int(end / binLevel))))
+	array.append((bigBin, bigBin))
+	return array
+
+
+class FindOverlapsWithSeveralIntervalsBin(object):
+
+	def __init__(self, verbosity):
+		self.verbosity	= verbosity
+		self.randomNumber = random.randint(0, 10000)
+		self.dbName	   = "smartdb%d" % (self.randomNumber)
+		if "SMARTTMPPATH" in os.environ:
+			self.dbName = os.join(os.environ["SMARTTMPPATH"], self.dbName)
+		self.connection = sqlite3.connect(self.dbName)
+		self.tableNames = {}
+		self.nbQueries  = 0
+		self.nbRefs	 = 0
+		self.nbWritten  = 0
+		self.nbOverlaps = 0
+		cursor = self.connection.cursor()
+		cursor.execute("PRAGMA journal_mode = OFF")
+		cursor.execute("PRAGMA synchronous = 0")
+		cursor.execute("PRAGMA locking_mode = EXCLUSIVE")
+		cursor.execute("PRAGMA count_change = OFF")
+		cursor.execute("PRAGMA temp_store = 2")
+
+	def __del__(self):
+		cursor = self.connection.cursor()
+		for tableName in self.tableNames.values():
+			cursor.execute("DROP TABLE IF EXISTS %s" % (tableName))
+		if os.path.exists(self.dbName):
+			os.remove(self.dbName)
+		
+	def createTable(self, chromosome):
+		cursor = self.connection.cursor()
+		tableName = "tmpTable_%s_%d" % (chromosome.replace("-", "_"), self.randomNumber)
+		cursor.execute("CREATE TABLE %s (start INT, end INT, transcript BLOB, bin INT)" % (tableName))
+		cursor.execute("CREATE INDEX index_%s ON %s (bin)" % (tableName, tableName))
+		self.tableNames[chromosome] = tableName
+
+	def setReferenceFile(self, fileName, format):
+		chooser = ParserChooser(self.verbosity)
+		chooser.findFormat(format)
+		parser = chooser.getParser(fileName)
+		startTime = time.time()
+		if self.verbosity > 2:
+			print "Storing into table"
+		for transcript in parser.getIterator():
+			if transcript.__class__.__name__ == "Mapping":
+				transcript = transcript.getTranscript()
+			transcriptString = pickle.dumps(transcript)
+			chromosome = transcript.getChromosome()
+			if chromosome not in self.tableNames:
+				self.createTable(chromosome)
+			start	  = transcript.getStart()
+			end		= transcript.getEnd()
+			bin		= getBin(start, end)
+			cursor	 = self.connection.cursor()
+			cursor.execute("INSERT INTO %s (start, end, transcript, bin) VALUES (?, ?, ?, ?)" % (self.tableNames[chromosome]), (start, end, sqlite3.Binary(transcriptString), bin))
+			self.nbRefs += 1
+		self.connection.commit()
+		endTime = time.time()
+		if self.verbosity > 2:
+			print "	...done (%.2gs)" % (endTime - startTime)
+
+	def setQueryFile(self, fileName, format):
+		chooser = ParserChooser(self.verbosity)
+		chooser.findFormat(format)
+		self.queryParser = chooser.getParser(fileName)
+		self.nbQueries = self.queryParser.getNbItems()
+
+	def setOutputFile(self, fileName):
+		self.writer = TranscriptWriter(fileName, "gff3", self.verbosity)
+
+	def compare(self):
+		progress = Progress(self.nbQueries, "Reading queries", self.verbosity)
+		startTime = time.time()
+		for queryTranscript in self.queryParser.getIterator():
+			if queryTranscript.__class__.__name__ == "Mapping":
+				queryTranscript = queryTranscript.getTranscript()
+			progress.inc()
+			queryChromosome = queryTranscript.getChromosome()
+			if queryChromosome not in self.tableNames:
+				continue
+			queryStart = queryTranscript.getStart()
+			queryEnd   = queryTranscript.getEnd()
+			bins	   = getOverlappingBins(queryStart, queryEnd)
+			commands   = []
+			for bin in bins:
+				command = "SELECT * FROM %s WHERE bin " % (self.tableNames[queryChromosome])
+				if bin[0] == bin[1]:
+					command += "= %d" % (bin[0])
+				else:
+					command += "BETWEEN %d AND %d" % (bin[0], bin[1])
+				commands.append(command)
+			command = " UNION ".join(commands)
+			cursor  = self.connection.cursor()
+			cursor.execute(command)
+			overlap = False
+			line	= cursor.fetchone()
+			while line:
+				refStart, refEnd, refTranscriptString, refBin = line
+				if refStart <= queryEnd and refEnd >= queryStart:
+					refTranscript = pickle.loads(str(refTranscriptString))
+					if refTranscript.overlapWith(queryTranscript):
+						overlap = True
+						self.nbOverlaps += 1
+				line = cursor.fetchone()
+			if overlap:
+				self.writer.addTranscript(queryTranscript)
+				self.nbWritten += 1
+		progress.done()
+		endTime = time.time()
+		self.timeSpent = endTime - startTime
+
+	def displayResults(self):
+		print "# queries:  %d" % (self.nbQueries)
+		print "# refs:	   %d" % (self.nbRefs)
+		print "# written:  %d (%d overlaps)" % (self.nbWritten, self.nbOverlaps)
+		print "time:	   %.2gs" % (self.timeSpent)
+
+	def run(self):
+		self.compare()
+		self.displayResults()
+
+if __name__ == "__main__":
+	
+	description = "Find Overlaps With Several Intervals Using Bin v1.0.1: Use MySQL binning to compare intervals. [Category: Personal]"
+
+	parser = OptionParser(description = description)
+	parser.add_option("-i", "--input1",	  dest="inputFileName1", action="store",			type="string", help="query input file [compulsory] [format: file in transcript format given by -f]")
+	parser.add_option("-f", "--format1",	 dest="format1",		action="store",			type="string", help="format of previous file [compulsory] [format: transcript file format]")
+	parser.add_option("-j", "--input2",	  dest="inputFileName2", action="store",			type="string", help="reference input file [compulsory] [format: file in transcript format given by -g]")
+	parser.add_option("-g", "--format2",	 dest="format2",		action="store",			type="string", help="format of previous file [compulsory] [format: transcript file format]")
+	parser.add_option("-o", "--output",	  dest="outputFileName", action="store",			type="string", help="output file [format: output file in GFF3 format]")
+	parser.add_option("-v", "--verbosity",   dest="verbosity",	  action="store", default=1, type="int",	help="trace level [format: int]")
+	(options, args) = parser.parse_args()
+
+	fowsib = FindOverlapsWithSeveralIntervalsBin(options.verbosity)
+	fowsib.setQueryFile(options.inputFileName1, options.format1)
+	fowsib.setReferenceFile(options.inputFileName2, options.format2)
+	fowsib.setOutputFile(options.outputFileName)
+	fowsib.run()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/FindOverlapsWithSeveralIntervalsIndex.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,137 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2011
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import random, os, time, MySQLdb
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+
+
+class FindOverlapsWithSeveralIntervalsIndex(object):
+
+    def __init__(self, verbosity):
+        self.verbosity = verbosity
+        randomNumber   = random.randint(0, 10000)
+        self.dbName    = "smartdb"
+        if "SMARTTMPPATH" in os.environ:
+            self.dbName = os.join(os.environ["SMARTTMPPATH"], self.dbName)
+        self.db         = MySQLdb.connect(db = self.dbName)
+        self.tableName  = "table_%s" % (randomNumber)
+        self.nbQueries  = 0
+        self.nbRefs     = 0
+        self.nbOverlaps = 0
+
+    def __del__(self):
+        cursor = self.db.cursor()
+        cursor.execute("DROP TABLE IF EXISTS %s" % (self.tableName))
+        
+
+    def setReferenceFile(self, fileName, format):
+        cursor = self.db.cursor()
+        cursor.execute("CREATE TABLE %s (start INT, end INT)" % (self.tableName))
+        cursor.execute("CREATE INDEX index_%s ON %s (start, end)" % (self.tableName, self.tableName))
+        chooser = ParserChooser(self.verbosity)
+        chooser.findFormat(format)
+        parser = chooser.getParser(fileName)
+        progress = UnlimitedProgress(1000, "Reading references", self.verbosity)
+        for transcript in parser.getIterator():
+            start      = transcript.getStart()
+            end        = transcript.getEnd()
+            cursor     = self.db.cursor()
+            cursor.execute("INSERT INTO %s (start, end) VALUES (%d, %d)" % (self.tableName, start, end))
+            self.nbRefs += 1
+            progress.inc()
+        self.db.commit()
+        progress.done()
+
+    def setQueryFile(self, fileName, format):
+        chooser = ParserChooser(self.verbosity)
+        chooser.findFormat(format)
+        self.queryParser = chooser.getParser(fileName)
+        self.nbQueries = self.queryParser.getNbTranscripts()
+
+    def setOutputFile(self, fileName):
+        self.writer = TranscriptWriter(fileName, "gff3", self.verbosity)
+
+    def compare(self):
+        progress = Progress(self.nbQueries, "Reading queries", self.verbosity)
+        startTime = time.time()
+        for queryTranscript in self.queryParser.getIterator():
+            queryStart = queryTranscript.getStart()
+            queryEnd   = queryTranscript.getEnd()
+            command    = "SELECT 1 FROM %s WHERE start <= %d and end >= %d" % (self.tableName, queryEnd, queryStart)
+            cursor     = self.db.cursor()
+            cursor.execute(command)
+            overlap = False
+            line = cursor.fetchone()
+            while line:
+                overlap = True
+                line    = cursor.fetchone()
+            if overlap:
+                self.writer.addTranscript(queryTranscript)
+                self.nbOverlaps += 1
+            progress.inc()
+        progress.done()
+        endTime = time.time()
+        self.timeSpent = endTime - startTime
+
+    def displayResults(self):
+        print "# queries:  %d" % (self.nbQueries)
+        print "# refs:     %d" % (self.nbRefs)
+        print "# overlaps: %d" % (self.nbOverlaps)
+        print "time:       %.2gs" % (self.timeSpent)
+
+    def run(self):
+        self.compare()
+        self.displayResults()
+
+if __name__ == "__main__":
+    
+    description = "Find Overlaps With Several Intervals Using Indices v1.0.1: Use MySQL to compare intervals. [Category: Personal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input1",      dest="inputFileName1", action="store",            type="string", help="query input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format1",     dest="format1",        action="store",            type="string", help="format of previous file [compulsory] [format: transcript file format]")
+    parser.add_option("-j", "--input2",      dest="inputFileName2", action="store",            type="string", help="reference input file [compulsory] [format: file in transcript format given by -g]")
+    parser.add_option("-g", "--format2",     dest="format2",        action="store",            type="string", help="format of previous file [compulsory] [format: transcript file format]")
+    parser.add_option("-o", "--output",      dest="outputFileName", action="store",            type="string", help="output file [format: output file in GFF3 format]")
+    parser.add_option("-v", "--verbosity",   dest="verbosity",      action="store", default=1, type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    fowsii = FindOverlapsWithSeveralIntervalsIndex(options.verbosity)
+    fowsii.setQueryFile(options.inputFileName1, options.format1)
+    fowsii.setReferenceFile(options.inputFileName2, options.format2)
+    fowsii.setOutputFile(options.outputFileName)
+    fowsii.run()
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/FindOverlaps_naif.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,85 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+import os
+import struct
+from optparse import OptionParser
+from commons.core.parsing.GffParser import GffParser
+from commons.core.writer.Gff3Writer import Gff3Writer
+
+LONGSIZE = struct.calcsize('l')
+
+class FindOverlaps_naif(object):
+    
+    def __init__(self, inputRefGff3FileName, inputQueryGff3FileName):
+        self._inputRefGff3FileName = inputRefGff3FileName
+        self._inputQueryGff3FileName = inputQueryGff3FileName
+                
+    def close(self):
+        self._iGff3Writer.close()
+    
+    def setGff3FileName(self, fileName):
+        self._inputRefGff3FileName = fileName
+        
+    def setQueryGff3FileName(self, fileName):
+        self._inputQueryGff3FileName = fileName
+    
+    def setOutputGff3FileName(self, outputGff3FileName):
+        if outputGff3FileName != '':
+            self._outputGff3FileName = outputGff3FileName
+        self._iGff3Writer = Gff3Writer(self._outputGff3FileName)
+                
+    def run(self):
+        queryParser = GffParser(self._inputQueryGff3FileName, 0)
+        for queryTranscript in queryParser.getIterator():
+            ids       = []
+            refParser = GffParser(self._inputRefGff3FileName, 0)
+            for refTranscript in refParser.getIterator():
+                if queryTranscript.overlapWith(refTranscript):
+                    ids.append(refTranscript.getTagValue('ID'))
+            if ids:
+                queryTranscript.setTagValue("nbOverlaps", len(ids))
+                queryTranscript.setTagValue("overlapsWith", "--".join(ids))
+                self._iGff3Writer.addTranscript(queryTranscript)
+    
+if __name__ == "__main__":
+    description = "FindOverlapsWithSeveralInterval: Finds overlaps with several query intervals."
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--inputRef", dest="inputRefGff3FileName", action="store", type="string", help="Reference input file [compulsory] [format: file in gff3 format]")
+    parser.add_option("-j", "--inputQuery", dest="inputQueryGff3FileName", action="store", type="string", help="Query input file [compulsory] [format: file in gff3 format]")
+    parser.add_option("-o", "--output", dest="outputGff3FileName", action="store", type="string", help="output file [compulsory] [format: output file in gff3 format]")
+    (options, args) = parser.parse_args()
+    
+    iFON = FindOverlaps_naif(options.inputRefGff3FileName, options.inputQueryGff3FileName)
+    iFON.setOutputGff3FileName(options.outputGff3FileName)
+    iFON.run()
+    iFON.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/NCIndex.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,55 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+from SMART.Java.Python.structure.Transcript import Transcript
+
+class NCIndex(object):
+
+    def __init__(self, verbosity):
+        self._verbosity = verbosity
+        self._step      = 10000
+        self._indices   = []
+
+    def setStep(self, step):
+        self._step = step
+
+    def addTranscript(self, end, index):
+        binStart = len(self._indices)
+        binEnd   = int(end / self._step)
+        for bin in range(binStart, binEnd+1):
+            self._indices.append(index)
+
+    def getIndex(self, transcript):
+        bin = int(transcript.getStart() / self._step)
+        if bin >= len(self._indices):
+            return self._indices[-1]
+        return self._indices[bin]
+
Binary file smart_toolShed/SMART/Java/Python/ncList/NCIndex.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/NCList.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,337 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os, os.path
+import struct
+import shelve
+import sys
+from SMART.Java.Python.ncList.NCListFilePickle import NCListFilePickle, NCListFileUnpickle
+from SMART.Java.Python.ncList.NCIndex import NCIndex
+from SMART.Java.Python.misc.Progress import Progress
+
+LONG_SIZE = struct.calcsize('l')
+
+H = 0
+L = 1
+T = 2
+G = 3
+
+H_CELL_SIZE = 2
+L_CELL_SIZE = 5
+T_CELL_SIZE = 6
+
+START   = 0
+END	 = 1
+ADDRESS = 2
+LIST	= 3
+PARENT  = 4
+NEW	 = 5
+LENGTH  = 1
+
+def pack(input):
+	return struct.pack("l", long(input))
+def unpack(input):
+	return struct.unpack("l", input)[0]
+
+
+class NCList(object):
+
+	def __init__(self, verbosity):
+		self._verbosity		         = verbosity
+		self._subPos			     = 0
+		self._parentPos		         = 0
+		self._nbLines			     = 0
+		self._nbLists			     = 0
+		self._chromosome		     = None
+		self._transcriptFileName     = None
+		self._lHandle			     = None
+		self._hHandle			     = None
+		self._tHandle			     = None
+		self._parser			     = None
+		self._sizeDict		         = {H: H_CELL_SIZE, L: L_CELL_SIZE, T: T_CELL_SIZE}
+		self._offsets			     = {H: 0, L: 0, G: 0}
+		self._fileNameDict	         = {}
+		self._handleDict		     = {}
+		self._createIndex		     = False
+		self._missingValues	         = dict([table, {}] for table in self._sizeDict)
+		self._missingValues[T][LIST] = -1
+		self._missingValues[L][LIST] =  0
+		self._missingValues[T][NEW]  = -1
+
+	def __del__(self):
+		for handle in (self._lHandle, self._hHandle):
+			if handle != None:
+				handle.close()
+
+	def createIndex(self, boolean):
+		self._createIndex = boolean
+
+	def setChromosome(self, chromosome):
+		self._chromosome = chromosome
+
+	def setFileName(self, fileName):
+		self._transcriptFileName = fileName
+		self._parser = NCListFileUnpickle(fileName, self._verbosity)
+		self._setFileNames(fileName)
+
+	def setNbElements(self, nbElements):
+		self._nbLines = nbElements
+
+	def setOffset(self, fileType, offset):
+		self._offsets[fileType] = offset
+
+	def _setFileNames(self, fileName):
+		if self._chromosome != None and fileName != None:
+			coreName = os.path.splitext(fileName)[0]
+			if "SMARTTMPPATH" in os.environ:
+				coreName = os.path.join(os.environ["SMARTTMPPATH"], coreName)
+			self._hFileName = "%s_H.bin" % (coreName)
+			self._lFileName = "%s_L.bin" % (coreName)
+			self._tFileName = "%s_T.bin" % (coreName)
+			self._fileNameDict = {H: self._hFileName, L: self._lFileName, T: self._tFileName}
+
+	def getSizeFirstList(self):
+		return self._sizeFirstList
+		
+	def _writeSubListIntoH(self, SubListAddr, SubListLength):
+		self._hHandle.write(pack(SubListAddr))
+		self._hHandle.write(pack(SubListLength))
+		self._subPos += H_CELL_SIZE
+			
+	def _writeParentIntoL(self, readAddr, subListAddr, parentAddr, start, end): 
+		self._lHandle.write(pack(start))
+		self._lHandle.write(pack(end))
+		self._lHandle.write(pack(readAddr))
+		self._lHandle.write(pack(subListAddr)) 
+		self._lHandle.write(pack(parentAddr))
+		self._parentPos += L_CELL_SIZE
+
+	def getLLineElements(self, subListLAddr): 
+		if subListLAddr == -1 or subListLAddr == None:
+			#print "reading bad from L", subListLAddr
+			return -1, -1, -1, -1, -1
+		else:
+			self._lHandle.seek(subListLAddr * L_CELL_SIZE * LONG_SIZE + self._offsets[L])
+			start = self._lHandle.read(LONG_SIZE)	 
+			if len(start) < LONG_SIZE:
+				#print "reading very bad from L", subListLAddr
+				return -1, -1, -1, -1, -1
+			start		= unpack(start)
+			end		  = unpack(self._lHandle.read(LONG_SIZE))
+			gff3Addr	 = unpack(self._lHandle.read(LONG_SIZE))
+			subListHAddr = unpack(self._lHandle.read(LONG_SIZE))
+			parentLAddr  = unpack(self._lHandle.read(LONG_SIZE))
+			#print "reading from L", subListLAddr, "-->", gff3Addr, subListHAddr, parentLAddr, start, end
+			return gff3Addr, subListHAddr, parentLAddr, start, end
+
+	def getHLineElements(self, subListHAddr):
+		self._hHandle.seek(subListHAddr * H_CELL_SIZE * LONG_SIZE + self._offsets[H])
+		subListStartBin = self._hHandle.read(LONG_SIZE)
+		if len(subListStartBin) < 8 :
+			#print "reading bad from H"
+			return -1, -1
+		subListStart		 = unpack(subListStartBin)
+		subListElementsNb	= unpack(self._hHandle.read(LONG_SIZE))
+		#print "reading from H", subListHAddr, "-->", subListStart, subListElementsNb
+		return subListStart, subListElementsNb
+
+	def getRefGffAddr(self, currentRefLAddr):
+		RefGff3Addr, subListHAddr, parentLAddr, start, end = self.getLLineElements(currentRefLAddr)
+		return RefGff3Addr
+	
+	def getIntervalFromAdress(self, address):
+		self._parser.gotoAddress(int(address) + self._offsets[G])
+		iTranscrit = self._parser.getNextTranscript()
+		return iTranscrit
+
+	def removeFiles(self):
+		return
+
+	def buildLists(self):
+		if self._createIndex:
+			self._index = NCIndex(self._verbosity)
+		self._createTables()
+		self._labelLists()
+		self._computeSubStart()
+		self._computeAbsPosition()
+		self._cleanFiles()
+
+	def _createTables(self):
+		self._initLists()
+		self._createTable(H, self._nbLists)
+		self._createTable(T, self._nbLines)
+		self._createTable(L, self._nbLines)
+		self._fillTables()
+
+	def _initLists(self):
+		previousTranscript = None
+		self._nbLists	  = 1
+		progress = Progress(self._nbLines, "Initializing lists", self._verbosity-5)
+		for transcript in self._parser.getIterator():
+			if self._isIncluded(transcript, previousTranscript):
+				self._nbLists += 1
+			previousTranscript = transcript
+			progress.inc()
+		progress.done()
+
+	def _isIncluded(self, transcript1, transcript2):
+		return transcript1 != None and transcript2 != None and transcript1.getStart() >= transcript2.getStart() and transcript1.getEnd() <= transcript2.getEnd()
+
+	def _createTable(self, name, size):
+		handle = open(self._fileNameDict[name], "w+b")
+		progress = Progress(self._sizeDict[name] * size, "Initializing table %d" % (name), self._verbosity-5)
+		for i in xrange(self._sizeDict[name] * size):
+			handle.write(pack(-1))
+			progress.inc()
+		progress.done()
+		self._handleDict[name] = handle
+
+	def _fillTables(self):
+		progress = Progress(self._nbLines, "Filling table T", self._verbosity-5)
+		for i, transcript in enumerate(self._parser.getIterator()):
+			self._writeValue(T, i, START,   transcript.getStart())
+			self._writeValue(T, i, END,	 transcript.getEnd())
+			self._writeValue(T, i, ADDRESS, self._parser.getCurrentTranscriptAddress())
+			self._writeValue(T, i, PARENT,  -1)
+			self._writeValue(T, i, LIST,	-1)
+			progress.inc()
+		progress.done()
+		progress = Progress(self._nbLists, "Filling table H", self._verbosity-5)
+		for i in xrange(self._nbLists):
+			self._writeValue(H, i, LENGTH, 0)
+			progress.inc()
+		progress.done()
+
+	def _labelLists(self):
+		progress = Progress(self._nbLines, "Getting table structure", self._verbosity-5)
+		nextL = 0
+		for i in xrange(self._nbLines):
+			p	 = i - 1
+			start = self._readValue(T, i, START)
+			end   = self._readValue(T, i, END)
+			while p != -1 and (start < self._readValue(T, p, START) or end > self._readValue(T, p, END)):
+				p = self._readValue(T, p, PARENT)
+			thisL = self._readValue(T, p, LIST)
+			if thisL == -1:
+				#print "entering"
+				thisL  = nextL
+				nextL += 1
+				length = 0
+				self._writeValue(T, p, LIST, thisL)
+			else:
+				length = self._readValue(H, thisL, LENGTH)
+			self._writeValue(T, i,	 PARENT, p)
+			self._writeValue(H, thisL, LENGTH, length + 1)
+			progress.inc()
+		progress.done()
+
+	def _computeSubStart(self):
+		progress = Progress(self._nbLines, "Getting table sub-lists", self._verbosity-5)
+		total = 0
+		for i in xrange(self._nbLists):
+			self._writeValue(H, i, START, total)
+			total += self._readValue(H, i, LENGTH)
+			self._writeValue(H, i, LENGTH, 0)
+			progress.inc()
+		progress.done()
+
+	def _computeAbsPosition(self):
+		progress = Progress(self._nbLines, "Writing table", self._verbosity-5)
+		self._sizeFirstList = 0
+		for i in xrange(self._nbLines):
+			s  = self._readValue(T, i,  START)
+			e  = self._readValue(T, i,  END)
+			a  = self._readValue(T, i,  ADDRESS)
+			pt = self._readValue(T, i,  PARENT)
+			h  = self._readValue(T, pt, LIST)
+			pl = self._readValue(T, pt, NEW)
+			nb = self._readValue(H, h,  LENGTH)
+			l  = self._readValue(H, h,  START) + nb
+			self._writeValue(T, i, NEW,	 l)
+			self._writeValue(L, l, START,   s)
+			self._writeValue(L, l, END,	 e)
+			self._writeValue(L, l, ADDRESS, a)
+			self._writeValue(L, l, LIST,	-1)
+			self._writeValue(L, l, PARENT,  pl)
+			self._writeValue(H, h, LENGTH,  nb+1)
+			if nb == 0:
+				#print "adding it"
+				self._writeValue(L, pl, LIST, h)
+			if pl == -1:
+				self._sizeFirstList += 1
+				if self._createIndex:
+					self._index.addTranscript(e, l)
+			progress.inc()
+		progress.done()
+
+	def closeFiles(self):
+		for handle in self._handleDict.values():
+			handle.close()
+		del self._handleDict
+		self._lHandle = None
+		self._hHandle = None
+		self._tHandle = None
+		self._parser = None
+
+	def openFiles(self):
+		self._lHandle = open(self._fileNameDict[L], "rb")
+		self._hHandle = open(self._fileNameDict[H], "rb")
+		self._handleDict = {H: self._hHandle, L: self._lHandle}
+		self._parser  = NCListFileUnpickle(self._transcriptFileName, self._verbosity)
+
+	def _cleanFiles(self):
+		self.closeFiles()
+		os.remove(self._fileNameDict[T])
+
+	def _getPosition(self, table, line, key):
+		handle = self._handleDict[table]
+		handle.seek(self._sizeDict[table] * line * LONG_SIZE + key * LONG_SIZE)
+		return handle
+
+	def _writeValue(self, table, line, key, value):
+		#print "writing", table, line, key, "<-", value
+		if line == -1:
+			self._missingValues[table][key] = value
+			return
+		handle = self._getPosition(table, line, key)
+		handle.write(pack(value))
+
+	def _readValue(self, table, line, key):
+		#print "reading", table, line, key, "->",
+		if line == -1:
+			#print self._missingValues[table][key]
+			return self._missingValues[table][key]
+		handle = self._getPosition(table, line, key)
+		r = unpack(handle.read(LONG_SIZE))
+		#print r
+		return r
+
+	def getIndex(self):
+		return self._index
Binary file smart_toolShed/SMART/Java/Python/ncList/NCList.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/NCListCursor.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,325 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os, os.path, struct
+from commons.core.parsing.GffParser import GffParser
+from SMART.Java.Python.misc.Progress import Progress
+
+
+class Data(object):
+    def __init__(self, hIndex, transcript, firstChildLIndex, lastChildLIndex, start, end):
+        self.hIndex           = hIndex
+        self.transcript       = transcript
+        self.firstChildLIndex = firstChildLIndex
+        self.lastChildLIndex  = lastChildLIndex
+        self.start            = start
+        self.end              = end
+
+class NCListCursor(object):
+
+    def __init__(self, cursor = None, ncList = None, lIndex = 0, verbosity = 0):
+        self._verbosity = verbosity
+        self._mainListData = []
+        if cursor:
+            self.copy(cursor)
+        else:
+            self._ncList = ncList
+            self.setLIndex(lIndex)
+
+    def setLIndex(self, lIndex):
+        self._lIndex             = lIndex
+        self._start              = None
+        self._end                = None
+        self._hIndex             = None
+        self._gffIndex           = None
+        self._parentGffIndex     = None
+        self._parentLIndex       = None
+        self._parentHIndex       = None
+        self._parentStart        = None
+        self._parentEnd          = None
+        self._transcript         = None
+        self._firstSiblingLIndex = None
+        self._lastSiblingLIndex  = None
+        self._firstChildLIndex   = None
+        self._lastChildLIndex    = None
+        self._mainListIndex      = lIndex if lIndex < self._ncList.getSizeFirstList() else None
+
+    def precompute(self):
+        self._mainListIndex = 0
+        progress = Progress(self._ncList.getSizeFirstList(), "Precomputing data", self._verbosity)
+        for i in range(self._ncList.getSizeFirstList()):
+            gffIndex, hIndex, parentLIndex, start, end = self._ncList.getLLineElements(i)
+            transcript = self._ncList.getIntervalFromAdress(gffIndex)
+            firstChildLIndex, nbChildren = self._ncList.getHLineElements(hIndex)
+            lastChildLIndex = -1 if firstChildLIndex == -1 else firstChildLIndex + nbChildren-1
+            self._mainListData.append(Data(hIndex, transcript, firstChildLIndex, lastChildLIndex, start, end))
+            progress.inc()
+        progress.done()
+
+    def _updateFromMainListData(self):
+        if not self._mainListData or self._lIndex >= self._ncList.getSizeFirstList():
+            #print "OUT"
+            return False
+        if self._mainListIndex >= self._ncList.getSizeFirstList():
+            self._hIndex = -1
+        data = self._mainListData[self._mainListIndex]
+        self._hIndex           = data.hIndex
+        self._transcript       = data.transcript
+        self._firstChildLIndex = data.firstChildLIndex
+        self._lastChildLIndex  = data.lastChildLIndex
+        self._start            = data.start
+        self._end              = data.end
+        return True
+
+    def getLIndex(self):
+        return self._lIndex
+
+    def _getCurrentData(self):
+        self._gffIndex, self._hIndex, self._parentLIndex, self._start, self._end = self._ncList.getLLineElements(self._lIndex)
+        #print "-->", self._lIndex, "-->", self._gffIndex, self._hIndex, self._parentLIndex, self._start, self._end
+        if self._end == -1:
+            raise Exception("Error")
+
+    def _getParentData(self):
+        if self._parentLIndex == None:
+            self._getCurrentData()
+        self._parentGffIndex, self._parentHIndex, greatParentLIndex, self._parentStart, self._parentEnd = self._ncList.getLLineElements(self._parentLIndex)
+
+    def _getTranscript(self):
+        if self._gffIndex == None:
+            self._getCurrentData()
+        self._transcript = self._ncList.getIntervalFromAdress(self._gffIndex)
+
+    def _getSiblingData(self):
+        if self._parentHIndex == None:
+            self._getParentData()
+        if self._parentHIndex == -1:
+            self._firstSiblingLIndex = 0
+            self._lastSiblingLIndex  = self._ncList.getSizeFirstList() - 1
+        else:
+            self._firstSiblingLIndex, nbSiblings = self._ncList.getHLineElements(self._parentHIndex)
+            self._lastSiblingLIndex = -1 if self._firstSiblingLIndex == -1 else self._firstSiblingLIndex + nbSiblings-1
+
+    def _getChildrenData(self):
+        if self._hIndex == None:
+            self._getCurrentData()
+        self._firstChildLIndex, nbChildren = self._ncList.getHLineElements(self._hIndex)
+        self._lastChildLIndex = -1 if self._firstChildLIndex == -1 else self._firstChildLIndex + nbChildren-1
+
+    def getGffAddress(self):
+        if self._gffIndex == None:
+            self._getCurrentData()
+        return self._gffIndex
+
+    def getStart(self):
+        if self._start == None:
+            self._getCurrentData()
+        return self._start
+
+    def getEnd(self):
+        if self._end == None:
+            self._getCurrentData()
+        return self._end
+
+    def compare(self, cursor):
+        return (self._lIndex == cursor._lIndex)
+
+    def getTranscript(self):
+        if self.isOut():
+            return None
+        if self._transcript == None:
+            self._getTranscript()
+        return self._transcript
+        
+    def isFirst(self):
+        #print "is last: ", self._lIndex, self._ncList.getSizeFirstList(), self._lastSiblingLIndex
+        if self._lIndex < self._ncList.getSizeFirstList() - 1:
+            return (self._lIndex == 0)
+        if self._firstSiblingLIndex == None:
+            self._getSiblingData()
+        return (self._lIndex == self._firstSiblingLIndex)
+        
+    def isLast(self):
+        #print "is last: ", self._lIndex, self._ncList.getSizeFirstList(), self._lastSiblingLIndex
+        if self._lIndex < self._ncList.getSizeFirstList() - 1:
+            return (self._lIndex == self._ncList.getSizeFirstList() - 1)
+        if self._lastSiblingLIndex == None:
+            self._getSiblingData()
+        return (self._lIndex == self._lastSiblingLIndex)
+        
+    def moveUp(self):
+        if self._parentLIndex == None:
+            self._getCurrentData()
+        self._lIndex = self._parentLIndex
+        self._updateFromMainListData()
+        self._hIndex             = self._parentHIndex
+        self._gffIndex           = self._parentGffIndex
+        self._parentLIndex       = None
+        self._parentHIndex       = None
+        self._parentGffIndex     = None
+        self._transcript         = None
+        self._firstSiblingLIndex = None
+        self._lastSiblingLIndex  = None
+        self._firstChildLIndex   = self._firstChildLIndex
+        self._lastChildLIndex    = self._lastChildLIndex
+        self._start              = self._parentStart
+        self._end                = self._parentEnd
+        self._parentStart        = None
+        self._parentEnd          = None
+        
+    def moveRight(self):
+        if self.isOut():
+            return
+        #print "IN1", self
+        if self._lIndex < self._ncList.getSizeFirstList() - 1 and self._mainListIndex != None:
+            self._mainListIndex += 1
+            self._updateFromMainListData()
+        #print "IN2", self
+        self._lIndex          += 1
+        self._hIndex           = None
+        self._start            = None
+        self._end              = None
+        self._transcript       = None
+        self._gffIndex         = None
+        self._firstChildLIndex = None
+        self._lastChildLIndex  = None
+        #print "IN3", self
+        
+    def moveNext(self):
+        while not self.isOut() and self.isLast():
+            if self.isTop():
+                self._lIndex = -1
+                return
+            self.moveUp()
+        #print "F1", self
+        self.moveRight()
+        #print "F2", self
+    
+    def moveMiddleSibling(self):
+        if self._lIndex < self._ncList.getSizeFirstList() - 1:
+            self._mainListIndex = (self._ncList.getSizeFirstList() - 1) / 2
+            self._updateFromMainListData()
+        if self._lastSiblingLIndex == None:
+            self._getSiblingData()
+        self._lIndex           = (self._lastSiblingLIndex + self._firstSiblingLIndex) / 2
+        self._hIndex           = None
+        self._start            = None
+        self._end              = None
+        self._gffIndex         = None
+        self._transcript       = None
+        self._firstChildLIndex = None
+        self._lastChildLIndex  = None
+
+    def moveSibling(self, lIndex):
+        if self._lIndex < self._ncList.getSizeFirstList() - 1:
+            self._mainListIndex = lIndex
+            self._updateFromMainListData()
+        self._lIndex           = lIndex
+        self._hIndex           = None
+        self._start            = None
+        self._end              = None
+        self._gffIndex         = None
+        self._transcript       = None
+        self._firstChildLIndex = None
+        self._lastChildLIndex  = None
+
+    def moveLastSibling(self):
+        if self._lIndex < self._ncList.getSizeFirstList() - 1:
+            self._mainListIndex = self._ncList.getSizeFirstList() - 1
+            self._updateFromMainListData()
+        if self._lastSiblingLIndex == None:
+            self._getSiblingData()
+        self._lIndex           = self._lastSiblingLIndex
+        self._hIndex           = None
+        self._start            = None
+        self._end              = None
+        self._gffIndex         = None
+        self._transcript       = None
+        self._firstChildLIndex = None
+        self._lastChildLIndex  = None
+
+    def moveDown(self):
+        if self._firstChildLIndex == None:
+            self._getChildrenData()
+        self._parentLIndex      = self._lIndex
+        self._parentHIndex      = self._hIndex
+        self._parentGffIndex    = self._gffIndex
+        self._lIndex            = self._firstChildLIndex
+        self._lastSiblingLIndex = self._lastChildLIndex
+        self._hIndex            = None
+        self._gffIndex          = None
+        self._transcript        = None
+        self._firstChildLIndex  = None
+        self._lastChildLIndex   = None
+        self._parentStart       = self._start
+        self._parentEnd         = self._end
+        self._start             = None
+        self._end               = None
+
+    def isOut(self):
+        return (self._lIndex == -1)
+
+    def isTop(self):
+        if self._parentLIndex == None:
+            self._getCurrentData()
+        return (self._parentLIndex == -1)
+
+    def hasChildren(self):
+        if self._hIndex == None:
+            self._getCurrentData()
+        if self._hIndex == -1:
+            return False
+        if self._firstChildLIndex == None:
+            self._getChildrenData()
+        return (self._firstChildLIndex != -1)
+
+    def copy(self, cursor):
+        self._ncList             = cursor._ncList
+        self._lIndex             = cursor._lIndex
+        self._hIndex             = cursor._hIndex
+        self._gffIndex           = cursor._gffIndex
+        self._parentLIndex       = cursor._parentLIndex
+        self._parentHIndex       = cursor._parentHIndex
+        self._parentGffIndex     = cursor._parentGffIndex
+        self._transcript         = cursor._transcript
+        self._firstSiblingLIndex = cursor._firstSiblingLIndex
+        self._lastSiblingLIndex  = cursor._lastSiblingLIndex
+        self._firstChildLIndex   = cursor._firstChildLIndex
+        self._lastChildLIndex    = cursor._lastChildLIndex
+        self._mainListData       = cursor._mainListData
+        self._mainListIndex      = cursor._mainListIndex
+        self._verbosity          = cursor._verbosity
+        self._parentStart        = cursor._parentStart
+        self._parentEnd          = cursor._parentEnd
+        self._start              = cursor._start
+        self._end                = cursor._end
+
+    def __str__(self):
+        return "NC-list: %s, Lindex: %s, Hindex: %s, GFFindex: %s, start: %s, end: %s, parent Lindex: %s, parent Hindex: %s, parent GFFindex: %s, transcript: %s, last sibling: %s" % (self._ncList, self._lIndex, self._hIndex, self._gffIndex, self._start, self._end, self._parentLIndex, self._parentHIndex, self._parentGffIndex, self._transcript, self._lastSiblingLIndex)
Binary file smart_toolShed/SMART/Java/Python/ncList/NCListCursor.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/NCListFilePickle.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,123 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+try:
+	 import cPickle as pickle
+except:
+	 import pickle
+from SMART.Java.Python.structure.Transcript import Transcript
+
+
+class NCListFilePickle(object):
+	
+	def __init__(self, fileName, verbosity = 1):
+		self.fileName  = fileName
+		self.handle	= open(fileName, "wb")
+		self.verbosity = verbosity
+
+	def __del__(self):
+		if self.handle != None:
+			self.handle.close()
+	
+	def addTranscript(self, transcript):
+		pickle.dump(transcript, self.handle, -1)
+
+	def write(self):
+		pass
+
+	def close(self):
+		self.__del__()
+
+
+class NCListFileUnpickle(object):
+		
+	def __init__(self, fileName, verbosity = 1):
+		self.handle		   = open(fileName, "rb")
+		self.verbosity	   = verbosity
+		self.initAddress   = 0
+		self.address	   = self.initAddress
+		self.nbTranscripts = None
+		self.fileName	   = fileName
+		self.over		   = False
+		self.chromosome    = None
+
+	def __del__(self):
+		if self.handle != None:
+			self.handle.close()
+
+	def reset(self):
+		self.handle.seek(0)
+		self.initAddress = 0
+
+	def setChromosome(self, chromosome):
+		self.chromosome = chromosome
+	
+	def getNbTranscripts(self):
+		if self.nbTranscripts != None:
+			return self._nbTranscripts
+		self.nbTranscripts = 0
+		for transcript in self.getIterator():
+			self_nbTranscripts += 1
+		return self.nbTranscripts
+
+	def gotoAddress(self, address):
+		self.handle.seek(address)
+		self.address = address
+
+	def getNextTranscript(self):
+		self.address = self.handle.tell()
+		try:
+			transcript = pickle.load(self.handle)
+			if self.chromosome != None and transcript.getChromosome() != self.chromosome:
+				self.over = True
+				return False
+			return transcript
+		except EOFError:
+			self.over = True
+			return False
+
+	def getIterator(self):
+		self.gotoAddress(self.initAddress)
+		while True:
+			transcript = self.getNextTranscript()
+			if not transcript:
+				self.over = True
+				return
+			yield transcript
+
+	def setInitAddress(self, address):
+		self.initAddress = address
+
+	def getCurrentTranscriptAddress(self):
+		return self.address
+
+	def isOver(self):
+		return self.over
Binary file smart_toolShed/SMART/Java/Python/ncList/NCListFilePickle.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/NCListHandler.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,125 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+import struct
+try:
+	import cPickle as pickle
+except:
+	import pickle
+from SMART.Java.Python.ncList.NCList import NCList
+from SMART.Java.Python.ncList.NCIndex import NCIndex
+from SMART.Java.Python.ncList.NCListFilePickle import NCListFileUnpickle
+
+LONG_SIZE = struct.calcsize('l')
+
+INFO_PER_NCLIST = 5
+H_FILE		    = 0
+L_FILE		    = 1
+G_FILE		    = 2
+FIRST_LIST_SIZE = 3
+INDEX		    = 4
+
+H = 0
+L = 1
+T = 2
+G = 3
+
+def pack(input):
+	return struct.pack("l", long(input))
+def unpack(input):
+	return struct.unpack("l", input)[0]
+
+
+class NCListHandler(object):
+
+	def __init__(self, verbosity):
+		self._verbosity = verbosity
+		self._index	    = False
+
+	def setFileName(self, fileName):
+		self._fileName = fileName
+		self._handle   = open(fileName, "rb")
+
+	def loadData(self):
+		self._chromosomes = pickle.load(self._handle)
+		self._nbElements = 0
+		self._nbElementsPerChromosome = {}
+		self._ncLists = {}
+		for chromosome in self._chromosomes:
+			self._nbElementsPerChromosome[chromosome] = unpack(self._handle.read(LONG_SIZE))
+			self._nbElements += self._nbElementsPerChromosome[chromosome]
+		self._headerPos = self._handle.tell()
+		for i, chromosome in enumerate(self._chromosomes):
+			ncList = NCList(self._verbosity)
+			ncList._hHandle = self._handle
+			ncList._lHandle = self._handle
+			ncList._parser  = NCListFileUnpickle(self._fileName)
+			self._handle.seek(self._headerPos + i * INFO_PER_NCLIST * LONG_SIZE + H_FILE * LONG_SIZE)
+			ncList.setOffset(H, unpack(self._handle.read(LONG_SIZE)))
+			self._handle.seek(self._headerPos + i * INFO_PER_NCLIST * LONG_SIZE + L_FILE * LONG_SIZE)
+			ncList.setOffset(L, unpack(self._handle.read(LONG_SIZE)))
+			self._handle.seek(self._headerPos + i * INFO_PER_NCLIST * LONG_SIZE + G_FILE * LONG_SIZE)
+			ncList.setOffset(G, unpack(self._handle.read(LONG_SIZE)))
+			self._handle.seek(self._headerPos + i * INFO_PER_NCLIST * LONG_SIZE + FIRST_LIST_SIZE * LONG_SIZE)
+			ncList._sizeFirstList = unpack(self._handle.read(LONG_SIZE))
+			self._handle.seek(self._headerPos + i * INFO_PER_NCLIST * LONG_SIZE + INDEX * LONG_SIZE)
+			indices = unpack(self._handle.read(LONG_SIZE))
+			if indices != -1:
+				self._handle.seek(indices)
+				data = pickle.load(self._handle)
+				index = NCIndex(self._verbosity)
+				index._indices = data
+				ncList._index = index
+			self._ncLists[chromosome] = ncList
+
+	def getChromosomes(self):
+		return self._chromosomes
+
+	def getNbElements(self):
+		return self._nbElements
+
+	def getNbElementsPerChromosome(self):
+		return self._nbElementsPerChromosome
+
+	def getNCLists(self):
+		return self._ncLists
+
+	def getParser(self, chromosome = None):
+		parser = NCListFileUnpickle(self._fileName)
+		if chromosome == None:
+			parser.setInitAddress(unpack(self._handle, self._headerPos + G_FILE * LONG_SIZE))
+			return parser
+		i = self._chromosomes.index(chromosome)
+		self._handle.seek(self._headerPos + i * INFO_PER_NCLIST * LONG_SIZE + G_FILE * LONG_SIZE)
+		pos = unpack(self._handle.read(LONG_SIZE))
+		parser.setInitAddress(pos)
+		parser.setChromosome(chromosome)
+		return parser
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/NCListMerger.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,126 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+import struct, os, shutil
+try:
+	import cPickle as pickle
+except:
+	import pickle
+
+LONG_SIZE = struct.calcsize('l')
+
+INFO_PER_NCLIST = 5
+H_FILE		    = 0
+L_FILE		    = 1
+G_FILE		    = 2
+FIRST_LIST_SIZE = 3
+INDEX		    = 4
+
+def pack(input):
+	return struct.pack("l", long(input))
+def unpack(input):
+	return struct.unpack("l", input)[0]
+
+
+class NCListMerger(object):
+
+	def __init__(self, verbosity):
+		self._verbosity = verbosity
+		self._index	 = False
+
+	def setFileName(self, fileName):
+		self._handle = open(fileName, "wb")
+
+	def setNCLists(self, ncLists):
+		self._ncLists = ncLists
+		self._chromosomes = sorted(self._ncLists.keys())
+
+	def addIndex(self, boolean):
+		self._index = boolean
+
+	def merge(self):
+		self._writeHeader()
+		self._addNCLists()
+		self._handle.close()
+		self._removeInputFiles()
+
+	def _writeHeader(self):
+		pickle.dump(self._chromosomes, self._handle, -1)
+		for chromosome in self._chromosomes:
+			self._handle.write(pack(self._ncLists[chromosome]._nbLines))
+		self._headerPos = self._handle.tell()
+		for chromosome in self._chromosomes:
+			for i in range(INFO_PER_NCLIST):
+				self._handle.write(pack(-1))
+
+	def _addInHeader(self, i, info, value = None):
+		currentPos = self._handle.tell()
+		if value == None:
+			value = currentPos
+		self._handle.seek(self._headerPos + i * INFO_PER_NCLIST * LONG_SIZE + info * LONG_SIZE)
+		self._handle.write(pack(value))
+		self._handle.seek(currentPos)
+
+	def _addNCLists(self):
+		self._inputFileNames = []
+		for i, chromosome in enumerate(self._chromosomes):
+			ncList = self._ncLists[chromosome]
+			self._addInHeader(i, H_FILE)
+			hFile = open(ncList._hFileName)
+			shutil.copyfileobj(hFile, self._handle)
+			hFile.close()
+			self._inputFileNames.append(ncList._hFileName)
+		for i, chromosome in enumerate(self._chromosomes):
+			ncList = self._ncLists[chromosome]
+			self._addInHeader(i, L_FILE)
+			lFile = open(ncList._lFileName)
+			shutil.copyfileobj(lFile, self._handle)
+			lFile.close()
+			self._inputFileNames.append(ncList._lFileName)
+		for i, chromosome in enumerate(self._chromosomes):
+			ncList = self._ncLists[chromosome]
+			self._addInHeader(i, FIRST_LIST_SIZE, ncList.getSizeFirstList())
+		if self._index:
+			for i, chromosome in enumerate(self._chromosomes):
+				ncList = self._ncLists[chromosome]
+				self._addInHeader(i, INDEX)
+				pickle.dump(ncList.getIndex()._indices, self._handle, -1)
+		for i, chromosome in enumerate(self._chromosomes):
+			ncList = self._ncLists[chromosome]
+			self._addInHeader(i, G_FILE)
+			tFile = open(ncList._transcriptFileName)
+			shutil.copyfileobj(tFile, self._handle)
+			tFile.close()
+			self._inputFileNames.append(ncList._transcriptFileName)
+
+	def _removeInputFiles(self):
+		for fileName in self._inputFileNames:
+			os.remove(fileName)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/NCListParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,74 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2012
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+import random, os, time
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.ncList.NCList import NCList
+from SMART.Java.Python.ncList.NCListCursor import NCListCursor
+try:
+   import cPickle as pickle
+except:
+   import pickle
+
+class NCListParser(object):
+    
+    def __init__(self, fileName, verbosity = 1):
+        self._fileName                = fileName
+        self._ncLists                 = {}
+        self._sortedFileNames         = {}
+        self._nbElements              = 0
+        self._nbElementsPerChromosome = {}
+        self._verbosity               = verbosity
+        
+    def parse(self):
+        handle                        = open(self._fileName)
+        self._sortedFileNames         = pickle.load(handle)
+        self._nbElements              = pickle.load(handle)
+        self._nbElementsPerChromosome = pickle.load(handle)
+        self._ncLists                 = pickle.load(handle)
+        for ncList in self._ncLists.values():
+            ncList._reopenFiles()
+        handle.close()
+
+    def getSortedFileNames(self):
+        return self._sortedFileNames
+
+    def getNbElements(self):
+        return self._nbElements
+
+    def getNbElementsPerChromosome(self):
+        return self._nbElementsPerChromosome
+
+    def getNCLists(self):
+        return self._ncLists
Binary file smart_toolShed/SMART/Java/Python/ncList/__init__.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/test/MockFindOverlapsWithSeveralIntervals.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,197 @@
+from SMART.Java.Python.misc import Utils
+
+class MockFindOverlapsWithOneInterval (object) :
+  def write(self, inFileName):
+    Utils.writeFile(inFileName, "chr1\ttest\ttest1.1\t0\t1000\t.\t+\t.\tID=test1.1;Name=test1.1\n")
+
+class MockFindOverlapsWithServeralIntervals_case1 (object) :
+	def write(self,inFileName):
+		f = open(inFileName, "w")
+		f.write("chr1\ttest\ttest1.1\t0\t1000\t1001\t+\t.\tID=test1.1;Name=test1.1\n")
+		f.write("chr1\ttest\ttest1.2\t50\t350\t301\t+\t.\tID=test1.2;Name=test1.2\n")
+		f.write("chr1\ttest\ttest1.3\t100\t600\t501\t+\t.\tID=test1.3;Name=test1.3\n")
+		f.write("chr1\ttest\ttest1.4\t200\t450\t251\t+\t.\tID=test1.4;Name=test1.4\n")
+		f.write("chr1\ttest\ttest1.5\t700\t950\t251\t+\t.\tID=test1.5;Name=test1.5\n")
+		f.write("chr1\ttest\ttest1.6\t800\t900\t101\t+\t.\tID=test1.6;Name=test1.6\n")
+		f.write("chr1\ttest\ttest1.7\t1200\t1300\t101\t+\t.\tID=test1.7;Name=test1.7\n")
+		f.close()
+
+class MockFindOverlapsWithServeralIntervals_case2 (object) :
+	def write(self,inFileName):
+		f = open(inFileName,'w')
+		f.write("chr1\ttest\ttest2.1\t0\t500\t501\t+\t.\tID=test2.1;Name=test2.1\n")
+		f.write("chr1\ttest\ttest2.2\t50\t450\t401\t+\t.\tID=test2.2;Name=test2.2\n")
+		f.write("chr1\ttest\ttest2.3\t100\t400\t301\t+\t.\tID=test2.3;Name=test2.3\n")
+		f.write("chr1\ttest\ttest2.4\t100\t200\t101\t+\t.\tID=test2.4;Name=test2.4\n")
+		f.write("chr1\ttest\ttest2.5\t900\t1200\t301\t+\t.\tID=test2.5;Name=test2.5\n")
+		f.close()
+
+class MockFindOverlapsWithServeralIntervals_case3 (object) :
+	def write(self,inFileName):
+		f = open(inFileName,'w')
+		f.write("chr1\ttest\ttest3.1\t0\t500\t501\t+\t.\tID=test3.1;Name=test3.1\n")
+		f.write("chr1\ttest\ttest3.2\t50\t450\t401\t+\t.\tID=test3.2;Name=test3.2\n")
+		f.write("chr1\ttest\ttest3.3\t100\t400\t301\t+\t.\tID=test3.3;Name=test3.3\n")
+		f.write("chr1\ttest\ttest3.4\t100\t200\t101\t+\t.\tID=test3.4;Name=test3.4\n")
+		f.write("chr1\ttest\ttest3.5\t300\t400\t101\t+\t.\tID=test3.5;Name=test3.5\n")
+		f.write("chr1\ttest\ttest3.6\t800\t1000\t201\t+\t.\tID=test3.6;Name=test3.6\n")
+		f.close()
+		
+class MockFindOverlapsWithServeralIntervals_case4_5 (object) :
+	def write(self,inFileName):
+		f = open(inFileName,'w')
+		f.write("chr1\ttest\ttest4.1\t0\t1000\t1001\t+\t.\tID=test4.1;Name=test4.1\n")
+		f.write("chr1\ttest\ttest4.2\t200\t800\t601\t+\t.\tID=test4.2;Name=test4.2\n")
+		f.write("chr1\ttest\ttest4.3\t400\t600\t201\t+\t.\tID=test4.3;Name=test4.3\n")
+		f.close()	
+		
+class MockFindOverlapsWithServeralIntervals_case6_7 (object) :
+	def write(self,inFileName):
+		f = open(inFileName,'w')
+		f.write("chr1\ttest\ttest6.1\t0\t1000\t1001\t+\t.\tID=test6.1;Name=test6.1\n")
+		f.write("chr1\ttest\ttest6.2\t100\t300\t201\t+\t.\tID=test6.2;Name=test6.2\n")
+		f.write("chr1\ttest\ttest6.3\t400\t500\t101\t+\t.\tID=test6.3;Name=test6.3\n")
+		f.write("chr1\ttest\ttest6.4\t510\t520\t11\t+\t.\tID=test6.4;Name=test6.4\n")
+		f.write("chr1\ttest\ttest6.5\t850\t950\t001\t+\t.\tID=test6.5;Name=test6.5\n")
+		f.close()	
+		
+class MockFindOverlapsWithServeralIntervals_case8 (object) :
+	def write(self,inFileName):
+		f = open(inFileName,'w')
+		f.write("chr1\ttest\ttest8.1\t0\t1000\t1001\t+\t.\tID=test8.1;Name=test8.1\n")
+		f.write("chr1\ttest\ttest8.2\t100\t200\t101\t+\t.\tID=test8.2;Name=test8.2\n")
+		f.write("chr1\ttest\ttest8.3\t300\t400\t101\t+\t.\tID=test8.3;Name=test8.3\n")
+		f.close()		
+
+class MockFindOverlapsWithServeralIntervals_case9 (object) :
+	def write(self,inFileName):
+		f = open(inFileName,'w')
+		f.write("chr1\ttest\ttest9.1\t0\t1000\t1001\t+\t.\tID=test9.1;Name=test9.1\n")
+		f.write("chr1\ttest\ttest9.2\t600\t700\t101\t+\t.\tID=test9.2;Name=test9.2\n")
+		f.write("chr1\ttest\ttest9.3\t800\t1200\t401\t+\t.\tID=test9.3;Name=test9.3\n")
+		f.close()
+
+class MockFindOverlapsWithServeralIntervals_case10 (object) :
+	def write(self,inFileName):
+		f = open(inFileName,'w')
+		f.write("chr1\ttest\ttest10.1\t0\t1000\t1001\t+\t.\tID=test10.1;Name=test10.1\n")
+		f.write("chr1\ttest\ttest10.2\t100\t200\t101\t+\t.\tID=test10.2;Name=test10.2\n")
+		f.write("chr1\ttest\ttest10.3\t300\t400\t101\t+\t.\tID=test10.3;Name=test10.3\n")
+		f.write("chr1\ttest\ttest10.4\t500\t600\t101\t+\t.\tID=test10.4;Name=test10.4\n")
+		f.write("chr1\ttest\ttest10.5\t1200\t1300\t101\t+\t.\tID=test10.5;Name=test10.5\n")
+		f.write("chr1\ttest\ttest10.6\t1400\t1500\t101\t+\t.\tID=test10.6;Name=test10.6\n")
+		f.close()
+
+class MockFindOverlapsWithServeralIntervals_case11 (object) :
+	def write(self,inFileName):
+		f = open(inFileName,'w')
+		f.write("chr1\ttest\ttest11.1\t0\t500\t501\t+\t.\tID=test11.1;Name=test11.1\n")
+		f.write("chr1\ttest\ttest11.2\t100\t200\t101\t+\t.\tID=test11.2;Name=test11.2\n")
+		f.write("chr1\ttest\ttest11.3\t300\t400\t101\t+\t.\tID=test11.3;Name=test11.3\n")
+		f.write("chr1\ttest\ttest11.4\t700\t900\t201\t+\t.\tID=test11.4;Name=test11.4\n")
+		f.write("chr1\ttest\ttest11.5\t710\t720\t11\t+\t.\tID=test11.5;Name=test11.5\n")
+		f.write("chr1\ttest\ttest11.6\t740\t750\t11\t+\t.\tID=test11.6;Name=test11.6\n")
+		f.close()
+		
+class MockFindOverlapsWithServeralIntervals_case12 (object) :
+	def write(self,inFileName):
+		f = open(inFileName,'w')
+		f.write("chr1\ttest\ttest12.1\t0\t1400\t.\t+\t.\tID=test12.1;Name=test12.1\n")
+		f.write("chr1\ttest\ttest12.2\t300\t500\t.\t+\t.\tID=test12.2;Name=test12.2\n")
+		f.write("chr1\ttest\ttest12.3\t300\t500\t.\t+\t.\tID=test12.3;Name=test12.3\n")
+		f.write("chr1\ttest\ttest12.4\t800\t1100\t.\t+\t.\tID=test12.4;Name=test12.4\n")
+		f.write("chr1\ttest\ttest12.5\t1200\t1300\t.\t+\t.\tID=test12.5;Name=test12.5\n")
+		f.close()
+		
+class MockFindOverlapsWithServeralIntervals_query_case1 (object):
+	def write(self, fileName):
+		f = open(fileName, 'w')
+		f.write("chr1\tquery\tquery1.1\t25\t150\t126\t+\t.\tID=query_1;Name=query1.1\n")
+		f.write("chr1\tquery\tquery1.2\t70\t850\t781\t+\t.\tID=query_2;Name=query1.2\n")
+		f.write("chr1\tquery\tquery1.3\t550\t850\t201\t+\t.\tID=query_3;Name=query1.3\n")
+		f.write("chr1\tquery\tquery1.4\t925\t1025\t101\t+\t.\tID=query_4;Name=query1.4\n")
+		f.write("chr1\tquery\tquery1.5\t1201\t1210\t10\t+\t.\tID=query_5;Name=query1.5\n")
+		f.write("chr1\tquery\tquery1.6\t1500\t1600\t101\t+\t.\tID=query_6;Name=query1.6\n")
+		f.close()
+		
+class MockFindOverlapsWithServeralIntervals_query_case2 (object):
+	def write(self, fileName):
+		f = open(fileName, 'w')
+		f.write("chr1\tquery\tquery2.1\t150\t300\t151\t+\t.\tID=query_1;Name=query2.1\n")
+		f.write("chr1\tquery\tquery2.2\t300\t450\t151\t+\t.\tID=query_2;Name=query2.2\n")
+		f.write("chr1\tquery\tquery2.3\t480\t800\t321\t+\t.\tID=query_3;Name=query2.3\n")
+		f.write("chr1\tquery\tquery2.4\t560\t800\t241\t+\t.\tID=query_4;Name=query2.4\n")
+		f.write("chr1\tquery\tquery2.5\t850\t1000\t151\t+\t.\tID=query_5;Name=query2.5\n")
+		f.close()
+		
+class MockFindOverlapsWithServeralIntervals_query_case3 (object):
+	def write(self, fileName):
+		f = open(fileName, 'w')
+		f.write("chr1\tquery\tquery3.1\t150\t250\t101\t+\t.\tID=query_1;Name=query3.1\n")
+		f.write("chr1\tquery\tquery3.2\t380\t400\t21\t+\t.\tID=query_2;Name=query3.2\n")
+		f.write("chr1\tquery\tquery3.3\t480\t520\t41\t+\t.\tID=query_3;Name=query3.3\n")
+		f.write("chr1\tquery\tquery3.4\t510\t700\t191\t+\t.\tID=query_4;Name=query3.4\n")
+		f.write("chr1\tquery\tquery3.5\t900\t950\t41\t+\t.\tID=query_5;Name=query3.5\n")
+		f.close()	
+		
+class MockFindOverlapsWithServeralIntervals_query_case4 (object):
+	def write(self, fileName):
+		f = open(fileName, 'w')
+		f.write("chr1\tquery\tquery4.1\t400\t500\t101\t+\t.\tID=query_1;Name=query4.1\n")
+		f.write("chr1\tquery\tquery4.2\t450\t600\t151\t+\t.\tID=query_2;Name=query4.2\n")
+		f.write("chr1\tquery\tquery4.3\t700\t800\t101\t+\t.\tID=query_3;Name=query4.3\n")
+		f.close()	
+		
+class MockFindOverlapsWithServeralIntervals_query_case5 (object):
+	def write(self, fileName):
+		f = open(fileName, 'w')
+		f.write("chr1\tquery\tquery5.1\t850\t950\t101\t+\t.\tID=query_1;Name=query5.1\n")
+		f.close()				
+		
+class MockFindOverlapsWithServeralIntervals_query_case6 (object):
+	def write(self, fileName):
+		f = open(fileName, 'w')
+		f.write("chr1\tquery\tquery6.1\t200\t300\t101\t+\t.\tID=query_1;Name=query6.1\n")
+		f.write("chr1\tquery\tquery6.2\t800\t900\t101\t+\t.\tID=query_2;Name=query6.2\n")
+		f.close()		
+		
+class MockFindOverlapsWithServeralIntervals_query_case7 (object):
+	def write(self, fileName):
+		f = open(fileName, 'w')
+		f.write("chr1\tquery\tquery6.1\t530\t550\t21\t+\t.\tID=query_1;Name=query6.1\n")
+		f.write("chr1\tquery\tquery6.2\t600\t700\t101\t+\t.\tID=query_2;Name=query6.2\n")
+		f.write("chr1\tquery\tquery6.3\t650\t900\t251\t+\t.\tID=query_3;Name=query6.3\n")
+		f.close()		
+		
+class MockFindOverlapsWithServeralIntervals_query_case8 (object):
+	def write(self, fileName):
+		f = open(fileName, 'w')
+		f.write("chr1\tquery\tquery7.1\t500\t600\t101\t+\t.\tID=query_1;Name=query7.1\n")
+		f.write("chr1\tquery\tquery7.2\t700\t800\t101\t+\t.\tID=query_2;Name=query7.2\n")
+		f.write("chr1\tquery\tquery7.3\t900\t1100\t201\t+\t.\tID=query_3;Name=query7.3\n")
+		f.write("chr1\tquery\tquery7.4\t1200\t1300\t101\t+\t.\tID=query_4;Name=query7.4\n")
+		f.close()		
+		
+class MockFindOverlapsWithServeralIntervals_query_case9 (object):
+	def write(self, fileName):
+		f = open(fileName, 'w')
+		f.write("chr1\tquery\tquery8.1\t400\t400\t101\t+\t.\tID=query_1;Name=query8.1\n")
+		f.write("chr1\tquery\tquery8.2\t550\t650\t101\t+\t.\tID=query_2;Name=query8.2\n")
+		f.close()		
+		
+class MockFindOverlapsWithServeralIntervals_query_case10 (object):
+	def write(self, fileName):
+		f = open(fileName, 'w')
+		f.write("chr1\tquery\tquery10.1\t700\t800\t101\t+\t.\tID=query_1;Name=query10.1\n")
+		f.write("chr1\tquery\tquery10.2\t900\t1000\t101\t+\t.\tID=query_2;Name=query10.2\n")
+		f.write("chr1\tquery\tquery10.3\t1100\t1300\t201\t+\t.\tID=query_3;Name=query10.3\n")
+		f.close()			
+		
+class MockFindOverlapsWithServeralIntervals_query_case11 (object):
+	def write(self, fileName):
+		f = open(fileName, 'w')
+		f.write("chr1\tquery\tquery11.1\t420\t480\t61\t+\t.\tID=query_1;Name=query11.1\n")
+		f.write("chr1\tquery\tquery11.2\t450\t715\t266\t+\t.\tID=query_2;Name=query11.2\n")
+		f.close()		
+		
+				
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/test/MockFindOverlaps_randomExample.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,118 @@
+import os
+import random
+from SMART.Java.Python.getRandomRegions import RandomRegionsGenerator
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.structure.Transcript import Transcript
+from commons.core.parsing.GffParser import GffParser
+
+class MockFindOverlaps_randomExample(object):
+
+    def __init__(self, fileName, ID, numberOfReads, chromSize):	
+        self._fileName = fileName
+        self._ID = ID
+        self._numberOfReads = numberOfReads
+        self._chromSize = chromSize
+		
+    def write(self):
+        iMFO_RE = MockFindOverlaps_randomExample_NonOrder(self._fileName, self._ID, self._numberOfReads, self._chromSize)
+        iMFO_RE.write()
+        cmd = 'sort -f -n -k4 -k5.4rn -o %s %s'%(self._fileName, self._fileName)
+        os.system(cmd)
+		
+class MockFindOverlaps_randomExample_NonOrder(object):
+
+	def __init__(self, fileName, ID, numberOfReads, chromSize):	
+		self._fileName = fileName
+		self._ID = ID
+		self._numberOfReads = numberOfReads
+		self._chromSize = chromSize
+		
+	def write(self):
+		iRRG = RandomRegionsGenerator(2)
+		iRRG.setMinSize(36)
+		iRRG.setMaxSize(100)
+		iRRG.setGenomeSize(self._chromSize)
+		iRRG.setChromosomeName("chr1")
+		iRRG.setStrands(False)
+		iRRG.setNumber(self._numberOfReads)
+		iRRG.setOutputFile(self._fileName)
+		iRRG.run()
+		
+
+class MockFindOverlaps_randomExample_MOverlaps(object):
+	
+	def __init__(self, refFileName, queryFileName, overlapNumber, numberOfReads, chromSize):
+		self._refFileName = refFileName
+		self._queryFileName = queryFileName
+		self._overlapNumber = overlapNumber
+		self._numberOfReads = numberOfReads
+		self._chromSize = chromSize
+		
+	def createRandomExample(self):
+		id = 'reference'
+		iRSS = MockFindOverlaps_randomExample(self._refFileName, id, self._numberOfReads, self._chromSize)
+		iRSS.write()
+		self.queryWriter = TranscriptWriter(self._queryFileName , 'gff3')
+		totalOverlap = 0
+		while totalOverlap != self._overlapNumber:
+			totalOverlap = 0
+			i = 0
+			while i < 10:
+				query = self.createRandomTranscript(i, id)
+				overlapNumber = self.getOverlapNumber(query, self._refFileName, totalOverlap)
+				while overlapNumber > self._overlapNumber:
+					query = self.createRandomTranscript(i, id)
+					overlapNumber = self.getOverlapNumber(query, self._refFileName, totalOverlap)
+				totalOverlap = overlapNumber
+				i += 1
+				self.queryWriter.addTranscript(query)
+		self.queryWriter.write()
+		self.queryWriter.close()
+#		os.rename("%s.gff3" % (self._queryFileName), self._queryFileName)
+		
+		cmd = 'sort -f -n -k4 -k5.4rn -o %s %s'%(self._refFileName, self._refFileName)
+		os.system(cmd)
+		cmd = 'sort -f -n -k4 -k5.4rn -o %s %s'%(self._queryFileName, self._queryFileName)
+		os.system(cmd)			
+		
+	def createRandomTranscript(self, cpt, id):
+		iRRG = RandomRegionsGenerator(2)
+		strand = '+'
+		chromosome = 'chr1'
+		size = random.randint(36, 100)
+		iRRG.setSize(size)
+		start = random.randint(0, 1000-size)
+		transcript = iRRG.createTranscript(chromosome, start, size, strand, cpt)	
+		IDdetail = '%s_%d'%(id,cpt)
+		transcript.setTagValue('ID', IDdetail)
+		transcript.setName(IDdetail)		 
+		return transcript
+	
+	def isOverlap(self, query, ref):
+		if (query.getStart() <= ref.getEnd() and query.getEnd() >= ref.getStart()):
+			return True 
+		else:
+			return False	
+		
+	def getIntervalFromAdress(self, fileName, address):
+		iParser = GffParser(fileName)
+		iParser.gotoAddress(int(address))
+		iTranscrit = iParser.getNextTranscript()
+		iParser.close()
+		return iTranscrit
+	
+	def getOverlapNumber(self, query, refFileName, totalOverlap):
+		count = totalOverlap
+		fRef = open(refFileName, 'r')
+		address = fRef.tell()
+		line = fRef.readline()
+		while line != '':
+			ref = self.getIntervalFromAdress(refFileName, address)
+			if self.isOverlap(query, ref):
+				count += 1
+			address = fRef.tell()
+			line = fRef.readline()					
+		fRef.close()
+		return count
+	
+		
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/test/Test_F_FileSorter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,84 @@
+import os
+import unittest
+import struct
+from SMART.Java.Python.misc import Utils
+from SMART.Java.Python.ncList.FileSorter import FileSorter
+from SMART.Java.Python.structure.Transcript import Transcript
+from commons.core.writer.Gff3Writer import Gff3Writer
+from commons.core.parsing.GffParser import GffParser
+from SMART.Java.Python.ncList.NCListFilePickle import NCListFileUnpickle
+
+
+class Test_F_FileSorter(unittest.TestCase):
+
+    def setUp(self):
+        self._inputGff3FileName = 'inputFile.gff3'
+        self._outputFileName    = 'outputFile.pkl'
+        
+    def tearDown(self):
+        return
+        for fileName in (self._inputGff3FileName, self._sortedFileName, self._expHFileName, self._expLFileName, self._obsHFileName, self._obsLFileName, self._addressFileName):
+            if os.path.exists(fileName):
+                os.remove(fileName)
+        
+    def test_unique(self):
+        transcript = self._createTranscript("chr1", 100, 200, "test1.1")
+        parser     = self._writeAndSortAndParse([transcript])
+        self.assertEquals(parser.getNbTranscripts(), 1)
+        for transcript in parser.getIterator():
+            self._checkTranscript(transcript, "chr1", 100, 200, "test1.1")
+            
+    def test_simple(self):
+        transcript1 = self._createTranscript("chr1", 300, 400, "test1.1")
+        transcript2 = self._createTranscript("chr1", 100, 200, "test1.2")
+        parser = self._writeAndSortAndParse([transcript1, transcript2])
+        self.assertEquals(parser.getNbTranscripts(), 2)
+        for cpt, transcript in enumerate(parser.getIterator()):
+            if cpt == 0:
+                self._checkTranscript(transcript, "chr1", 100, 200, "test1.2")
+            else:
+                self._checkTranscript(transcript, "chr1", 300, 400, "test1.1")
+
+    def test_same_start(self):
+        transcript1 = self._createTranscript("chr1", 100, 200, "test1.1")
+        transcript2 = self._createTranscript("chr1", 100, 300, "test1.2")
+        parser = self._writeAndSortAndParse([transcript1, transcript2])
+        self.assertEquals(parser.getNbTranscripts(), 2)
+        for cpt, transcript in enumerate(parser.getIterator()):
+            if cpt == 0:
+                self._checkTranscript(transcript, "chr1", 100, 300, "test1.2")
+            else:
+                self._checkTranscript(transcript, "chr1", 100, 200, "test1.1")
+
+    def _writeAndSortAndParse(self, transcripts):
+        writer = Gff3Writer(self._inputGff3FileName, 0)
+        for transcript in transcripts:
+            writer.addTranscript(transcript)
+        writer.close()
+        parser = GffParser(self._inputGff3FileName, 0)
+        fs = FileSorter(parser, 0)
+        fs.setOutputFileName(self._outputFileName)
+        fs.sort()
+        parser = NCListFileUnpickle(self._outputFileName, 0)
+        return parser
+
+    def _createTranscript(self, chromosome, start, end, name):
+        transcript = Transcript()
+        transcript.setChromosome(chromosome)
+        transcript.setStart(start)
+        transcript.setEnd(end)
+        transcript.setDirection("+")
+        transcript.setName(name)
+        return transcript
+
+    def _checkTranscript(self, transcript, chromosome, start, end, name):
+        self.assertEquals(transcript.getChromosome(), chromosome)
+        self.assertEquals(transcript.getStart(),      start)
+        self.assertEquals(transcript.getEnd(),        end)
+        self.assertEquals(transcript.getDirection(),  1)
+        self.assertEquals(transcript.getName(),       name)
+        
+            
+if __name__ == "__main__":
+    unittest.main()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/test/Test_F_FindOverlapsWithOneInterval.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,121 @@
+import unittest
+import struct
+import os
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.ncList.FindOverlapsWithOneInterval import FindOverlapsWithOneInterval
+from SMART.Java.Python.misc import Utils
+
+class Test_F_FindOverlapsWithOneInterval(unittest.TestCase):
+
+    def setUp(self):
+        self._inputGff3FileName = 'sortedFile.gff3'
+        self._writeGFF3File(self._inputGff3FileName)
+        self._obsFileName = "overlap.gff3"
+        self._expFileName = "expFile.gff3"
+        self._iFOWOI = FindOverlapsWithOneInterval(0)
+        self._iFOWOI.setFileName(self._inputGff3FileName, "gff3")
+        self._iFOWOI.setOutputFileName(self._obsFileName)
+        
+    def tearDown(self):
+        os.remove(self._inputGff3FileName)
+        os.remove(self._obsFileName)
+        os.remove(self._expFileName)
+        
+    def test_run_general(self):
+        self._iFOWOI.setInterval("chr1", 500, 850)
+        self._iFOWOI.run()
+        self._writeExpGFF3File_general(self._expFileName)
+        self.assertTrue(Utils.diff(self._expFileName, self._obsFileName))
+        
+#   def test_run_general_asScript(self):
+#       cmd = 'python ../FindOverlapsWithOneInterval.py -i %s -f gff3 -o %s -c chr1 -s 500 -e 850 -v 0' % (self._inputGff3FileName, self._obsFileName)
+#       os.system(cmd)
+#       self._writeExpGFF3File_general(self._expFileName)
+#       self.assertTrue(Utils.diff(self._expFileName, self._obsFileName))
+#       
+#   def test_run_one_overlap(self):
+#       self._iFOWOI.setInterval("chr1", 1250, 1450)
+#       self._iFOWOI.run()
+#       self._writeExpGFF3File_one_overlap(self._expFileName)
+#       self.assertTrue(Utils.diff(self._expFileName, self._obsFileName))
+#       
+#   def test_run_one_overlap_asScript(self):
+#       cmd = 'python ../FindOverlapsWithOneInterval.py -i %s -f gff3 -o %s -c chr1 -s 1250 -e 1450 -v 0' % (self._inputGff3FileName, self._obsFileName)
+#       os.system(cmd)
+#       self._writeExpGFF3File_one_overlap(self._expFileName) 
+#       self.assertTrue(Utils.diff(self._expFileName, self._obsFileName))       
+#       
+#   def test_run_all_overlap(self):
+#       self._iFOWOI.setInterval("chr1", 300, 1250)
+#       self._iFOWOI.run()
+#       self._writeExpGff3File_all_overlap(self._expFileName)
+#       self.assertTrue(Utils.diff(self._expFileName, self._obsFileName))
+#       
+#   def test_run_all_overlap_asScript(self):
+#       cmd = 'python ../FindOverlapsWithOneInterval.py -i %s -f gff3 -o %s -c chr1 -s 300 -e 1250 -v 0' % (self._inputGff3FileName, self._obsFileName)
+#       os.system(cmd)        
+#       self._writeExpGff3File_all_overlap(self._expFileName)
+#       self.assertTrue(Utils.diff(self._expFileName, self._obsFileName))
+#               
+#   def test_run_no_overlap_right(self):
+#       self._iFOWOI.setInterval("chr1", 1400, 1500)
+#       self._iFOWOI.run()
+#       f = open(self._expFileName, "w")
+#       f.close()
+#       self.assertTrue(Utils.diff(self._expFileName, self._obsFileName))
+#       
+#   def test_run_no_overlap_right_asScript(self):
+#       cmd = 'python ../FindOverlapsWithOneInterval.py -i %s -f gff3 -o %s -c chr1 -s 1400 -e 1500 -v 0' % (self._inputGff3FileName, self._obsFileName)
+#       os.system(cmd)           
+#       f = open(self._expFileName, "w")
+#       f.close()
+#       self.assertTrue(Utils.diff(self._expFileName, self._obsFileName))
+#               
+#   def test_run_no_overlap_left(self):
+#       self._iFOWOI.setInterval("chr1", 0, 8)
+#       self._iFOWOI.run()
+#       f = open(self._expFileName, "w")
+#       f.close()
+#       self.assertTrue(Utils.diff(self._expFileName, self._obsFileName))
+#       
+#   def test_run_no_overlap_left_asScript(self):
+#       cmd = 'python ../FindOverlapsWithOneInterval.py -i %s -f gff3 -o %s -c chr1 -s 0 -e 8 -v 0' % (self._inputGff3FileName, self._obsFileName)
+#       os.system(cmd)  
+#       f = open(self._expFileName, "w")
+#       f.close()
+#       self.assertTrue(Utils.diff(self._expFileName, self._obsFileName))                
+
+    def _writeExpGff3File_all_overlap(self, fileName):  
+        f = open(fileName, 'w')
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tID=test2.1;Name=test2.1\n")
+        f.write("chr1\tS-MART\ttest2.2\t50\t350\t301\t+\t.\tID=test2.2;Name=test2.2\n")
+        f.write("chr1\tS-MART\ttest2.3\t100\t600\t501\t+\t.\tID=test2.3;Name=test2.3\n")
+        f.write("chr1\tS-MART\ttest2.4\t200\t450\t251\t+\t.\tID=test2.4;Name=test2.4\n")
+        f.write("chr1\tS-MART\ttest2.5\t700\t950\t251\t+\t.\tID=test2.5;Name=test2.5\n")
+        f.write("chr1\tS-MART\ttest2.6\t800\t900\t101\t+\t.\tID=test2.6;Name=test2.6\n")
+        f.write("chr1\tS-MART\ttest2.7\t1200\t1300\t101\t+\t.\tID=test2.7;Name=test2.7\n")
+        f.close()
+        
+    def _writeExpGFF3File_one_overlap(self, fileName):
+        f = open(fileName, "w")
+        f.write("chr1\tS-MART\ttest2.7\t1200\t1300\t101\t+\t.\tID=test2.7;Name=test2.7\n")
+        f.close()    
+        
+    def _writeExpGFF3File_general(self, fileName):
+        f = open(fileName, "w")
+        f.write("chr1\tS-MART\ttranscript\t500\t850\t.\t+\t.\tnbOverlaps=4;overlapsWith=test2.1--test2.3--test2.5--test2.6\n")
+        f.close()
+        
+    def _writeGFF3File(self, fileName):
+        f = open(fileName, "w")
+        f.write("chr1\ttest\ttest2.1\t9\t1000\t1001\t+\t.\tID=test2.1;Name=test2.1\n")
+        f.write("chr1\ttest\ttest2.2\t50\t350\t301\t+\t.\tID=test2.2;Name=test2.2\n")
+        f.write("chr1\ttest\ttest2.3\t100\t600\t501\t+\t.\tID=test2.3;Name=test2.3\n")
+        f.write("chr1\ttest\ttest2.4\t200\t450\t251\t+\t.\tID=test2.4;Name=test2.4\n")
+        f.write("chr1\ttest\ttest2.5\t700\t950\t251\t+\t.\tID=test2.5;Name=test2.5\n")
+        f.write("chr1\ttest\ttest2.6\t800\t900\t101\t+\t.\tID=test2.6;Name=test2.6\n")
+        f.write("chr1\ttest\ttest2.7\t1200\t1300\t101\t+\t.\tID=test2.7;Name=test2.7\n")
+        f.close()
+
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/test/Test_F_FindOverlapsWithSeveralIntervals.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,173 @@
+import unittest
+import os, os.path
+from SMART.Java.Python.ncList.FindOverlapsWithSeveralIntervals import FindOverlapsWithSeveralIntervals
+from SMART.Java.Python.misc import Utils
+
+class Test_F_FindOverlapsWithSeveralIntervals(unittest.TestCase):
+
+    def setUp(self):
+        self._inputRefGff3FileName   = 'sorted_Ref.gff3'
+        self._inputQueryGff3FileName = 'sorted_Query.gff3'
+        self._outputGff3FileName     = 'output.gff3'
+        self._expOutputFileName      = 'expOutGff3.gff3'
+        self._writeQueryGff3File(self._inputQueryGff3FileName)
+        self._writeGFF3File(self._inputRefGff3FileName)
+        self._iFOWSI = FindOverlapsWithSeveralIntervals(0)
+        self._iFOWSI.setRefFileName(self._inputRefGff3FileName, "gff3")
+        self._iFOWSI.setQueryFileName(self._inputQueryGff3FileName, "gff3")
+        self._iFOWSI.setOutputFileName(self._outputGff3FileName)
+        self._iFOWSI.prepareIntermediateFiles()
+        self._iFOWSI.createNCLists()
+        
+    def tearDown(self):
+        for fileName in (self._inputRefGff3FileName, self._inputQueryGff3FileName, self._outputGff3FileName, self._expOutputFileName):
+            if os.path.exists(fileName):
+                os.remove(fileName)
+        
+    def test_run_general(self):
+        self._writeQueryGff3File(self._inputQueryGff3FileName)
+        self._writeGFF3File(self._inputRefGff3FileName)
+        self._iFOWSI = FindOverlapsWithSeveralIntervals(0)
+        self._iFOWSI.setRefFileName(self._inputRefGff3FileName, "gff3")
+        self._iFOWSI.setQueryFileName(self._inputQueryGff3FileName, "gff3")
+        self._iFOWSI.setOutputFileName(self._outputGff3FileName)
+        self._iFOWSI.prepareIntermediateFiles()
+        self._iFOWSI.createNCLists()
+        self._iFOWSI.compare()
+        self._iFOWSI.close()
+        self._writeExpOutFile_general(self._expOutputFileName)
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))  
+        
+    def test_run_general_asScript(self):
+        cmd = 'python ../FindOverlapsWithSeveralIntervals.py -i %s -f gff3 -j %s -g gff3 -o %s -v 0' % (self._inputQueryGff3FileName, self._inputRefGff3FileName, self._outputGff3FileName)      
+        os.system(cmd)
+        self._writeExpOutFile_general(self._expOutputFileName)
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))         
+
+      
+    def test_run_overlap_special_case(self):
+        inputQueryGff3FileName = 'query2.gff3'
+        self._writeQueryGff3File2(inputQueryGff3FileName)
+        self._iFOWSI = FindOverlapsWithSeveralIntervals(0)
+        self._iFOWSI.setRefFileName(self._inputRefGff3FileName, "gff3")
+        self._iFOWSI.setQueryFileName(inputQueryGff3FileName, "gff3")
+        self._iFOWSI.setOutputFileName(self._outputGff3FileName)
+        self._iFOWSI.prepareIntermediateFiles()
+        self._iFOWSI.createNCLists()
+        self._iFOWSI.compare()
+        self._iFOWSI.close()
+        self._writeExpOutFile_special_case(self._expOutputFileName)        
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))   
+        os.remove(inputQueryGff3FileName) 
+        
+    def test_run_overlap_special_case_asScript(self):
+        inputQueryGff3FileName = 'query2.gff3'
+        self._writeQueryGff3File2(inputQueryGff3FileName)
+        cmd = 'python ../FindOverlapsWithSeveralIntervals.py -i %s -f gff3 -j %s -g gff3 -o %s -v 0' % (inputQueryGff3FileName, self._inputRefGff3FileName, self._outputGff3FileName)      
+        os.system(cmd) 
+        self._writeExpOutFile_special_case(self._expOutputFileName)        
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))         
+        os.remove(inputQueryGff3FileName) 
+                
+    def _writeExpOutFile_special_case(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1	S-MART	test2	1250	1300	781	+	.	nbOverlaps=1;overlapsWith=test2.7;ID=query_2;Name=test1.2\n")
+        f.close() 
+        
+    def _writeExpOutFile_general(self, fileName):
+        f = open(fileName, 'w')
+        f.write("""chr1	S-MART	test1.1	25	150	126	+	.	nbOverlaps=3;overlapsWith=test2.1--test2.2--test2.3;ID=query_1;Name=test1.1
+chr1	S-MART	test1.2	70	850	781	+	.	nbOverlaps=6;overlapsWith=test2.1--test2.2--test2.3--test2.4--test2.5--test2.6;ID=query_2;Name=test1.2
+chr1	S-MART	test1.3	550	850	201	+	.	nbOverlaps=4;overlapsWith=test2.1--test2.3--test2.5--test2.6;ID=query_3;Name=test1.3
+chr1	S-MART	test1.4	925	1025	101	+	.	nbOverlaps=2;overlapsWith=test2.1--test2.5;ID=query_4;Name=test1.4
+chr1	S-MART	test1.5	1201	1210	10	+	.	nbOverlaps=1;overlapsWith=test2.7;ID=query_5;Name=test1.5
+""")
+        f.close() 
+
+    def _writeExpOutFile_cas_1(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tName=test2.1;OverlapWith=query_3;score=1001;feature=test2.1;ID=test2.1\n")
+        f.write("chr1\tS-MART\ttest2.3\t100\t600\t501\t+\t.\tName=test2.3;OverlapWith=query_3;score=501;feature=test2.3;ID=test2.3\n")
+        f.write("chr1\tS-MART\ttest2.5\t700\t950\t251\t+\t.\tName=test2.5;OverlapWith=query_3;score=251;feature=test2.5;ID=test2.5\n")
+        f.write("chr1\tS-MART\ttest2.6\t800\t900\t101\t+\t.\tName=test2.6;OverlapWith=query_3;score=101;feature=test2.6;ID=test2.6\n")
+        f.close()         
+
+    def _writeExpOutFile_cas_2(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tName=test2.1;OverlapWith=query_2;score=1001;feature=test2.1;ID=test2.1\n")
+        f.write("chr1\tS-MART\ttest2.2\t50\t350\t301\t+\t.\tName=test2.2;OverlapWith=query_2;score=301;feature=test2.2;ID=test2.2\n")
+        f.write("chr1\tS-MART\ttest2.3\t100\t600\t501\t+\t.\tName=test2.3;OverlapWith=query_2;score=501;feature=test2.3;ID=test2.3\n")
+        f.write("chr1\tS-MART\ttest2.4\t200\t450\t251\t+\t.\tName=test2.4;OverlapWith=query_2;score=251;feature=test2.4;ID=test2.4\n")
+        f.write("chr1\tS-MART\ttest2.5\t700\t950\t251\t+\t.\tName=test2.5;OverlapWith=query_2;score=251;feature=test2.5;ID=test2.5\n")
+        f.write("chr1\tS-MART\ttest2.6\t800\t900\t101\t+\t.\tName=test2.6;OverlapWith=query_2;score=101;feature=test2.6;ID=test2.6\n")
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tName=test2.1;OverlapWith=query_3;score=1001;feature=test2.1;ID=test2.1\n")
+        f.write("chr1\tS-MART\ttest2.3\t100\t600\t501\t+\t.\tName=test2.3;OverlapWith=query_3;score=501;feature=test2.3;ID=test2.3\n")
+        f.write("chr1\tS-MART\ttest2.5\t700\t950\t251\t+\t.\tName=test2.5;OverlapWith=query_3;score=251;feature=test2.5;ID=test2.5\n")
+        f.write("chr1\tS-MART\ttest2.6\t800\t900\t101\t+\t.\tName=test2.6;OverlapWith=query_3;score=101;feature=test2.6;ID=test2.6\n")
+        f.close() 
+
+    def _writeExpOutFile_all_overlap(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tName=test2.1;OverlapWith=query_2;score=1001;feature=test2.1;ID=test2.1\n")
+        f.write("chr1\tS-MART\ttest2.2\t50\t350\t301\t+\t.\tName=test2.2;OverlapWith=query_2;score=301;feature=test2.2;ID=test2.2\n")
+        f.write("chr1\tS-MART\ttest2.3\t100\t600\t501\t+\t.\tName=test2.3;OverlapWith=query_2;score=501;feature=test2.3;ID=test2.3\n")
+        f.write("chr1\tS-MART\ttest2.4\t200\t450\t251\t+\t.\tName=test2.4;OverlapWith=query_2;score=251;feature=test2.4;ID=test2.4\n")
+        f.write("chr1\tS-MART\ttest2.5\t700\t950\t251\t+\t.\tName=test2.5;OverlapWith=query_2;score=251;feature=test2.5;ID=test2.5\n")
+        f.write("chr1\tS-MART\ttest2.6\t800\t900\t101\t+\t.\tName=test2.6;OverlapWith=query_2;score=101;feature=test2.6;ID=test2.6\n")
+        f.close()           
+
+    def _writeExpOutFile_overlap_to_children(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tName=test2.1;OverlapWith=query_3;score=1001;feature=test2.1;ID=test2.1\n") 
+        f.write("chr1\tS-MART\ttest2.3\t100\t600\t501\t+\t.\tName=test2.3;OverlapWith=query_3;score=501;feature=test2.3;ID=test2.3\n") 
+        f.write("chr1\tS-MART\ttest2.5\t700\t950\t251\t+\t.\tName=test2.5;OverlapWith=query_3;score=251;feature=test2.5;ID=test2.5\n") 
+        f.write("chr1\tS-MART\ttest2.6\t800\t900\t101\t+\t.\tName=test2.6;OverlapWith=query_3;score=101;feature=test2.6;ID=test2.6\n") 
+        f.close()         
+
+    def _writeExpOutFile_not_overlap_to_children(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tName=test2.1;OverlapWith=query_1;score=1001;feature=test2.1;ID=test2.1\n")
+        f.write("chr1\tS-MART\ttest2.2\t50\t350\t301\t+\t.\tName=test2.2;OverlapWith=query_1;score=301;feature=test2.2;ID=test2.2\n")
+        f.write("chr1\tS-MART\ttest2.3\t100\t600\t501\t+\t.\tName=test2.3;OverlapWith=query_1;score=501;feature=test2.3;ID=test2.3\n")
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tName=test2.1;OverlapWith=query_4;score=1001;feature=test2.1;ID=test2.1\n")
+        f.write("chr1\tS-MART\ttest2.5\t700\t950\t251\t+\t.\tName=test2.5;OverlapWith=query_4;score=251;feature=test2.5;ID=test2.5\n")
+        f.close()        
+
+    def _writeExpOutFile_no_overlap_right(self, fileName):
+        f = open(fileName, 'w')
+        f.close()                 
+
+    def _writeExpOutFile_one_overlap(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tS-MART\ttest2.7\t1200\t1300\t101\t+\t.\tName=test2.7;OverlapWith=query_5;score=101;feature=test2.7;ID=test2.7\n")
+        f.close()        
+        
+    def _writeQueryGff3File2(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest1\t1100\t1150\t126\t+\t.\tID=query_1;Name=test1.1\n")
+        f.write("chr1\tquery\ttest2\t1250\t1300\t781\t+\t.\tID=query_2;Name=test1.2\n")
+        f.close()
+        
+    def _writeQueryGff3File(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest1.1\t25\t150\t126\t+\t.\tID=query_1;Name=test1.1\n")
+        f.write("chr1\tquery\ttest1.2\t70\t850\t781\t+\t.\tID=query_2;Name=test1.2\n")
+        f.write("chr1\tquery\ttest1.3\t550\t850\t201\t+\t.\tID=query_3;Name=test1.3\n")
+        f.write("chr1\tquery\ttest1.4\t925\t1025\t101\t+\t.\tID=query_4;Name=test1.4\n")
+        f.write("chr1\tquery\ttest1.5\t1201\t1210\t10\t+\t.\tID=query_5;Name=test1.5\n")
+        f.write("chr1\tquery\ttest1.6\t1500\t1600\t101\t+\t.\tID=query_6;Name=test1.6\n")
+        f.close()
+        
+    def _writeGFF3File(self, fileName):
+        f = open(fileName, "w")
+        f.write("chr1\ttest\ttest2.1\t9\t1000\t1001\t+\t.\tID=test2.1;Name=test2.1\n")
+        f.write("chr1\ttest\ttest2.2\t50\t350\t301\t+\t.\tID=test2.2;Name=test2.2\n")
+        f.write("chr1\ttest\ttest2.3\t100\t600\t501\t+\t.\tID=test2.3;Name=test2.3\n")
+        f.write("chr1\ttest\ttest2.4\t200\t450\t251\t+\t.\tID=test2.4;Name=test2.4\n")
+        f.write("chr1\ttest\ttest2.5\t700\t950\t251\t+\t.\tID=test2.5;Name=test2.5\n")
+        f.write("chr1\ttest\ttest2.6\t800\t900\t101\t+\t.\tID=test2.6;Name=test2.6\n")
+        f.write("chr1\ttest\ttest2.7\t1200\t1300\t101\t+\t.\tID=test2.7;Name=test2.7\n")
+        f.close()
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/test/Test_F_FindOverlaps_naif.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,455 @@
+import unittest
+import os
+from commons.core.utils.FileUtils import FileUtils
+from SMART.Java.Python.misc import Utils
+from SMART.Java.Python.ncList.FindOverlaps_naif import FindOverlaps_naif
+from SMART.Java.Python.ncList.test.MockFindOverlapsWithSeveralIntervals import *
+
+class Test_F_FindOverlaps_naif(unittest.TestCase):
+
+    def setUp(self):
+        self._inputRefGff3FileName = 'ref.gff3'
+        self._writeGFF3File(self._inputRefGff3FileName)
+        self._inputQueryGff3FileName = 'query.gff3'
+        self._writeQueryGff3File(self._inputQueryGff3FileName)
+        self._outputGff3FileName = 'output.gff3'
+        self._expOutputFileName = 'expOutGff3.gff3'
+        self._iFON = FindOverlaps_naif(self._inputRefGff3FileName, self._inputQueryGff3FileName)
+        self._iFON.setOutputGff3FileName(self._outputGff3FileName)
+        
+    def tearDown(self):
+        os.remove(self._inputRefGff3FileName)
+        os.remove(self._inputQueryGff3FileName)
+        os.remove(self._outputGff3FileName)
+        os.remove(self._expOutputFileName)
+        
+    def test_run_general(self):
+        self._iFON.run()
+        self._iFON.close()
+        self._writeExpOutFile_general(self._expOutputFileName)
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))  
+        
+    def test_run_general_asScript(self):
+        cmd = 'python ../FindOverlaps_naif.py -i %s -j %s -o %s' % (self._inputRefGff3FileName, self._inputQueryGff3FileName, self._outputGff3FileName)      
+        os.system(cmd)
+        self._writeExpOutFile_general(self._expOutputFileName)
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))         
+
+    def test_run_overlap_special_case(self):
+        inputQueryGff3FileName = 'query2.gff3'
+        self._writeQueryGff3File2(inputQueryGff3FileName)
+        iFON = FindOverlaps_naif(self._inputRefGff3FileName, inputQueryGff3FileName)
+        iFON.setOutputGff3FileName(self._outputGff3FileName)
+        iFON.run()
+        iFON.close()
+        self._writeExpOutFile_special_case(self._expOutputFileName)        
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))   
+        os.remove(inputQueryGff3FileName) 
+        
+    def test_run_overlap_special_case_asScript(self):
+        inputQueryGff3FileName = 'query2.gff3'
+        self._writeQueryGff3File2(inputQueryGff3FileName)
+        cmd = 'python ../FindOverlaps_naif.py -i %s -j %s -o %s' % (self._inputRefGff3FileName, inputQueryGff3FileName, self._outputGff3FileName)      
+        os.system(cmd) 
+        self._writeExpOutFile_special_case(self._expOutputFileName)        
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))         
+        os.remove(inputQueryGff3FileName) 
+        
+    def test_case_2(self):
+        inputRefGff3FileName = 'ref_case2.gff3'
+        iMock = MockFindOverlapsWithServeralIntervals_case2()
+        iMock.write(inputRefGff3FileName)
+        inputQueryGff3FileName = 'query_case2.gff3'
+        self._writeQueryGff3File_case2(inputQueryGff3FileName)  
+        iFON = FindOverlaps_naif(inputRefGff3FileName, inputQueryGff3FileName)
+        iFON.setOutputGff3FileName(self._outputGff3FileName)
+        iFON.run()
+        iFON.close()
+        self._writeExpOutFile_case2(self._expOutputFileName)        
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))   
+        os.remove(inputQueryGff3FileName) 
+        os.remove(inputRefGff3FileName) 
+        
+    def test_case_3(self):
+        inputRefGff3FileName = 'ref_case3.gff3'
+        iMock = MockFindOverlapsWithServeralIntervals_case3()
+        iMock.write(inputRefGff3FileName)
+        inputQueryGff3FileName = 'query_case3.gff3'
+        self._writeQueryGff3File_case3(inputQueryGff3FileName)  
+        iFON = FindOverlaps_naif(inputRefGff3FileName, inputQueryGff3FileName)
+        iFON.setOutputGff3FileName(self._outputGff3FileName)
+        iFON.run()
+        iFON.close()
+        self._writeExpOutFile_case3(self._expOutputFileName)        
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))   
+        os.remove(inputQueryGff3FileName)
+        os.remove(inputRefGff3FileName)    
+       
+    def test_case_4(self):
+        inputRefGff3FileName = 'ref_case4.gff3'
+        iMock = MockFindOverlapsWithServeralIntervals_case4_5()
+        iMock.write(inputRefGff3FileName)
+        inputQueryGff3FileName = 'query_case4.gff3'
+        self._writeQueryGff3File_case4(inputQueryGff3FileName)  
+        iFON = FindOverlaps_naif(inputRefGff3FileName, inputQueryGff3FileName)
+        iFON.setOutputGff3FileName(self._outputGff3FileName)
+        iFON.run()
+        iFON.close()
+        self._writeExpOutFile_case4(self._expOutputFileName)        
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))   
+        os.remove(inputQueryGff3FileName) 
+        os.remove(inputRefGff3FileName)   
+       
+    def test_case_5(self):
+        inputRefGff3FileName = 'ref_case5.gff3'
+        iMock = MockFindOverlapsWithServeralIntervals_case4_5()
+        iMock.write(inputRefGff3FileName)
+        inputQueryGff3FileName = 'query_case5.gff3'
+        self._writeQueryGff3File_case5(inputQueryGff3FileName)  
+        iFON = FindOverlaps_naif(inputRefGff3FileName, inputQueryGff3FileName)
+        iFON.setOutputGff3FileName(self._outputGff3FileName)
+        iFON.run()
+        iFON.close()
+        self._writeExpOutFile_case5(self._expOutputFileName)        
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))   
+        os.remove(inputQueryGff3FileName) 
+        os.remove(inputRefGff3FileName)   
+       
+    def test_case_6(self):
+        inputRefGff3FileName = 'ref_case6.gff3'
+        iMock = MockFindOverlapsWithServeralIntervals_case6_7()
+        iMock.write(inputRefGff3FileName)
+        inputQueryGff3FileName = 'query_case6.gff3'
+        self._writeQueryGff3File_case6(inputQueryGff3FileName)  
+        iFON = FindOverlaps_naif(inputRefGff3FileName, inputQueryGff3FileName)
+        iFON.setOutputGff3FileName(self._outputGff3FileName)
+        iFON.run()
+        iFON.close()
+        self._writeExpOutFile_case6(self._expOutputFileName)        
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))   
+        os.remove(inputQueryGff3FileName)
+        os.remove(inputRefGff3FileName)   
+       
+    def test_case_7(self):
+        inputRefGff3FileName = 'ref_case7.gff3'
+        iMock = MockFindOverlapsWithServeralIntervals_case6_7()
+        iMock.write(inputRefGff3FileName)
+        inputQueryGff3FileName = 'query_case7.gff3'
+        self._writeQueryGff3File_case7(inputQueryGff3FileName)  
+        iFON = FindOverlaps_naif(inputRefGff3FileName, inputQueryGff3FileName)
+        iFON.setOutputGff3FileName(self._outputGff3FileName)
+        iFON.run()
+        iFON.close()
+        self._writeExpOutFile_case7(self._expOutputFileName)        
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))   
+        os.remove(inputQueryGff3FileName)
+        os.remove(inputRefGff3FileName)
+       
+    def test_case_8(self):
+        inputRefGff3FileName = 'ref_case8.gff3'
+        iMock = MockFindOverlapsWithServeralIntervals_case8()
+        iMock.write(inputRefGff3FileName)
+        inputQueryGff3FileName = 'query_case8.gff3'
+        self._writeQueryGff3File_case8(inputQueryGff3FileName)  
+        iFON = FindOverlaps_naif(inputRefGff3FileName, inputQueryGff3FileName)
+        iFON.setOutputGff3FileName(self._outputGff3FileName)
+        iFON.run()
+        iFON.close()
+        self._writeExpOutFile_case8(self._expOutputFileName)        
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))   
+        os.remove(inputQueryGff3FileName)
+        os.remove(inputRefGff3FileName)
+       
+    def test_case_9(self):
+        inputRefGff3FileName = 'ref_case9.gff3'
+        iMock = MockFindOverlapsWithServeralIntervals_case9()
+        iMock.write(inputRefGff3FileName)
+        inputQueryGff3FileName = 'query_case9.gff3'
+        self._writeQueryGff3File_case9(inputQueryGff3FileName)  
+        iFON = FindOverlaps_naif(inputRefGff3FileName, inputQueryGff3FileName)
+        iFON.setOutputGff3FileName(self._outputGff3FileName)
+        iFON.run()
+        iFON.close()
+        self._writeExpOutFile_case9(self._expOutputFileName)        
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))   
+        os.remove(inputQueryGff3FileName)
+        os.remove(inputRefGff3FileName)
+       
+    def test_case_10(self):
+        inputRefGff3FileName = 'ref_case10.gff3'
+        iMock = MockFindOverlapsWithServeralIntervals_case10()
+        iMock.write(inputRefGff3FileName)
+        inputQueryGff3FileName = 'query_case10.gff3'
+        self._writeQueryGff3File_case10(inputQueryGff3FileName)  
+        iFON = FindOverlaps_naif(inputRefGff3FileName, inputQueryGff3FileName)
+        iFON.setOutputGff3FileName(self._outputGff3FileName)
+        iFON.run()
+        iFON.close()
+        self._writeExpOutFile_case10(self._expOutputFileName)        
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))   
+        os.remove(inputQueryGff3FileName)
+        os.remove(inputRefGff3FileName)
+       
+    def test_case_11(self):
+        inputRefGff3FileName = 'ref_case11.gff3'
+        iMock = MockFindOverlapsWithServeralIntervals_case11()
+        iMock.write(inputRefGff3FileName)
+        inputQueryGff3FileName = 'query_case11.gff3'
+        self._writeQueryGff3File_case11(inputQueryGff3FileName)  
+        iFON = FindOverlaps_naif(inputRefGff3FileName, inputQueryGff3FileName)
+        iFON.setOutputGff3FileName(self._outputGff3FileName)
+        iFON.run()
+        iFON.close()
+        self._writeExpOutFile_case11(self._expOutputFileName)        
+        self.assertTrue(Utils.diff(self._expOutputFileName, self._outputGff3FileName))   
+        os.remove(inputQueryGff3FileName)
+        os.remove(inputRefGff3FileName)
+               
+    def _writeExpOutFile_special_case(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1	S-MART	test2	1250	1300	781	+	.	nbOverlaps=1;overlapsWith=test2.7;ID=query_2;Name=test1.2\n")
+        f.close() 
+        
+    def _writeExpOutFile_general(self, fileName):
+        f = open(fileName, 'w')
+        f.write("""chr1	S-MART	test1.1	25	150	126	+	.	nbOverlaps=3;overlapsWith=test2.1--test2.2--test2.3;ID=query_1;Name=test1.1
+chr1	S-MART	test1.2	70	850	781	+	.	nbOverlaps=6;overlapsWith=test2.1--test2.2--test2.3--test2.4--test2.5--test2.6;ID=query_2;Name=test1.2
+chr1	S-MART	test1.3	550	850	201	+	.	nbOverlaps=4;overlapsWith=test2.1--test2.3--test2.5--test2.6;ID=query_3;Name=test1.3
+chr1	S-MART	test1.4	925	1025	101	+	.	nbOverlaps=2;overlapsWith=test2.1--test2.5;ID=query_4;Name=test1.4
+chr1	S-MART	test1.5	1201	1210	10	+	.	nbOverlaps=1;overlapsWith=test2.7;ID=query_5;Name=test1.5
+""")
+        f.close() 
+
+    def _writeExpOutFile_cas_1(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tOverlapWith=query_3;ID=test2.1;Name=test2.1\n")
+        f.write("chr1\tS-MART\ttest2.3\t100\t600\t501\t+\t.\tOverlapWith=query_3;ID=test2.3;Name=test2.3\n")
+        f.write("chr1\tS-MART\ttest2.5\t700\t950\t251\t+\t.\tOverlapWith=query_3;ID=test2.5;Name=test2.5\n")
+        f.write("chr1\tS-MART\ttest2.6\t800\t900\t101\t+\t.\tOverlapWith=query_3;ID=test2.6;Name=test2.6\n")
+        f.close()         
+
+    def _writeExpOutFile_cas_2(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tOverlapWith=query_2;Name=test2.1\n")
+        f.write("chr1\tS-MART\ttest2.2\t50\t350\t301\t+\t.\tOverlapWith=query_2;Name=test2.2\n")
+        f.write("chr1\tS-MART\ttest2.3\t100\t600\t501\t+\t.\tOverlapWith=query_2;Name=test2.3\n")
+        f.write("chr1\tS-MART\ttest2.4\t200\t450\t251\t+\t.\tOverlapWith=query_2;Name=test2.4\n")
+        f.write("chr1\tS-MART\ttest2.5\t700\t950\t251\t+\t.\tOverlapWith=query_2;Name=test2.5\n")
+        f.write("chr1\tS-MART\ttest2.6\t800\t900\t101\t+\t.\tOverlapWith=query_2;Name=test2.6\n")
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tOverlapWith=query_3;Name=test2.1\n")
+        f.write("chr1\tS-MART\ttest2.3\t100\t600\t501\t+\t.\tOverlapWith=query_3;Name=test2.3\n")
+        f.write("chr1\tS-MART\ttest2.5\t700\t950\t251\t+\t.\tOverlapWith=query_3;Name=test2.5\n")
+        f.write("chr1\tS-MART\ttest2.6\t800\t900\t101\t+\t.\tOverlapWith=query_3;Name=test2.6\n")
+        f.close() 
+
+    def _writeExpOutFile_all_overlap(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tOverlapWith=query_2;ID=test2.1;Name=test2.1\n")
+        f.write("chr1\tS-MART\ttest2.2\t50\t350\t301\t+\t.\tOverlapWith=query_2;D=test2.2;Name=test2.2\n")
+        f.write("chr1\tS-MART\ttest2.3\t100\t600\t501\t+\t.\tOverlapWith=query_2;ID=test2.3;Name=test2.3\n")
+        f.write("chr1\tS-MART\ttest2.4\t200\t450\t251\t+\t.\tOverlapWith=query_2;ID=test2.4;Name=test2.4\n")
+        f.write("chr1\tS-MART\ttest2.5\t700\t950\t251\t+\t.\tOverlapWith=query_2;ID=test2.5;Name=test2.5\n")
+        f.write("chr1\tS-MART\ttest2.6\t800\t900\t101\t+\t.\tOverlapWith=query_2;ID=test2.6;Name=test2.6\n")
+        f.close()           
+
+    def _writeExpOutFile_overlap_to_children(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tOverlapWith=query_3;ID=test2.1;Name=test2.1\n") 
+        f.write("chr1\tS-MART\ttest2.3\t100\t600\t501\t+\t.\tOverlapWith=query_3;ID=test2.3;Name=test2.3\n") 
+        f.write("chr1\tS-MART\ttest2.5\t700\t950\t251\t+\t.\tOverlapWith=query_3;ID=test2.5;Name=test2.5\n") 
+        f.write("chr1\tS-MART\ttest2.6\t800\t900\t101\t+\t.\tOverlapWith=query_3;ID=test2.6;Name=test2.6\n") 
+        f.close()         
+
+    def _writeExpOutFile_not_overlap_to_children(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tOverlapWith=query_1;ID=test2.1;Name=test2.1\n")
+        f.write("chr1\tS-MART\ttest2.2\t50\t350\t301\t+\t.\tOverlapWith=query_1;ID=test2.2;Name=test2.2\n")
+        f.write("chr1\tS-MART\ttest2.3\t100\t600\t501\t+\t.\tOverlapWith=query_1;ID=test2.3;Name=test2.3\n")
+        f.write("chr1\tS-MART\ttest2.1\t9\t1000\t1001\t+\t.\tOverlapWith=query_4;ID=test2.1;Name=test2.1\n")
+        f.write("chr1\tS-MART\ttest2.5\t700\t950\t251\t+\t.\tOverlapWith=query_4;ID=test2.5;Name=test2.5\n")
+        f.close()        
+
+    def _writeExpOutFile_no_overlap_right(self, fileName):
+        f = open(fileName, 'w')
+        f.close()                 
+
+    def _writeExpOutFile_one_overlap(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tS-MART\ttest2.7\t1200\t1300\t101\t+\t.\tOverlapWith=query_5;ID=test2.7;Name=test2.7\n")
+        f.close()                  
+
+    def _writeExpOutFile_case2(self, fileName):
+        f = open(fileName, 'w')
+        f.write("""chr1	S-MART	test2.1	150	300	151	+	.	nbOverlaps=4;overlapsWith=test2.1--test2.2--test2.3--test2.4;ID=query_1;Name=test2.1
+chr1	S-MART	test2.2	300	450	781	+	.	nbOverlaps=3;overlapsWith=test2.1--test2.2--test2.3;ID=query_2;Name=test2.2
+chr1	S-MART	test2.3	480	800	321	+	.	nbOverlaps=1;overlapsWith=test2.1;ID=query_3;Name=test2.3
+chr1	S-MART	test2.5	850	1000	151	+	.	nbOverlaps=1;overlapsWith=test2.5;ID=query_5;Name=test2.5
+""")
+        f.close()        
+
+    def _writeExpOutFile_case3(self, fileName):
+        f = open(fileName, 'w')
+        f.write("""chr1	S-MART	test3.1	150	250	101	+	.	nbOverlaps=4;overlapsWith=test3.1--test3.2--test3.3--test3.4;ID=query_1;Name=test3.1
+chr1	S-MART	test3.2	380	400	21	+	.	nbOverlaps=4;overlapsWith=test3.1--test3.2--test3.3--test3.5;ID=query_2;Name=test3.2
+chr1	S-MART	test3.3	480	520	41	+	.	nbOverlaps=1;overlapsWith=test3.1;ID=query_3;Name=test3.3
+chr1	S-MART	test3.5	900	950	51	+	.	nbOverlaps=1;overlapsWith=test3.6;ID=query_5;Name=test3.5
+""")
+        f.close()       
+
+    def _writeExpOutFile_case4(self, fileName):
+        f = open(fileName, 'w')
+        f.write("""chr1	S-MART	test4.1	400	500	101	+	.	nbOverlaps=3;overlapsWith=test4.1--test4.2--test4.3;ID=query_1;Name=test4.1
+chr1	S-MART	test4.2	450	600	151	+	.	nbOverlaps=3;overlapsWith=test4.1--test4.2--test4.3;ID=query_2;Name=test4.2
+chr1	S-MART	test4.3	700	800	101	+	.	nbOverlaps=2;overlapsWith=test4.1--test4.2;ID=query_3;Name=test4.3
+""")
+        f.close()      
+
+    def _writeExpOutFile_case5(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1	S-MART	test5.1	850	950	101	+	.	nbOverlaps=1;overlapsWith=test4.1;ID=query_1;Name=test5.1\n")
+        f.close()      
+
+    def _writeExpOutFile_case6(self, fileName):
+        f = open(fileName, 'w')
+        f.write("""chr1	S-MART	test6.1	200	300	101	+	.	nbOverlaps=2;overlapsWith=test6.1--test6.2;ID=query_1;Name=test6.1
+chr1	S-MART	test6.2	800	900	101	+	.	nbOverlaps=2;overlapsWith=test6.1--test6.5;ID=query_2;Name=test6.2
+""")
+        f.close() 
+
+    def _writeExpOutFile_case7(self, fileName):
+        f = open(fileName, 'w')
+        f.write("""chr1	S-MART	test7.1	530	550	21	+	.	nbOverlaps=1;overlapsWith=test6.1;ID=query_1;Name=test7.1
+chr1	S-MART	test7.2	600	700	101	+	.	nbOverlaps=1;overlapsWith=test6.1;ID=query_2;Name=test7.2
+chr1	S-MART	test7.3	650	900	251	+	.	nbOverlaps=2;overlapsWith=test6.1--test6.5;ID=query_3;Name=test7.3
+""")
+        f.close() 
+
+    def _writeExpOutFile_case8(self, fileName):
+        f = open(fileName, 'w')
+        f.write("""chr1	S-MART	test8.1	500	600	101	+	.	nbOverlaps=1;overlapsWith=test8.1;ID=query_1;Name=test8.1
+chr1	S-MART	test8.2	700	800	101	+	.	nbOverlaps=1;overlapsWith=test8.1;ID=query_2;Name=test8.2
+chr1	S-MART	test8.3	900	1100	201	+	.	nbOverlaps=1;overlapsWith=test8.1;ID=query_3;Name=test8.3
+""")
+        f.close() 
+
+    def _writeExpOutFile_case9(self, fileName):
+        f = open(fileName, 'w')
+        f.write("""chr1	S-MART	test9.1	400	500	101	+	.	nbOverlaps=1;overlapsWith=test9.1;ID=query_1;Name=test9.1
+chr1	S-MART	test9.2	550	650	101	+	.	nbOverlaps=2;overlapsWith=test9.1--test9.2;ID=query_2;Name=test9.2
+""")
+        f.close() 
+
+    def _writeExpOutFile_case10(self, fileName):
+        f = open(fileName, 'w')
+        f.write("""chr1	S-MART	test10.1	700	800	101	+	.	nbOverlaps=1;overlapsWith=test10.1;ID=query_1;Name=test10.1
+chr1	S-MART	test10.2	900	1000	101	+	.	nbOverlaps=1;overlapsWith=test10.1;ID=query_2;Name=test10.2
+chr1	S-MART	test10.3	1100	1300	201	+	.	nbOverlaps=1;overlapsWith=test10.5;ID=query_3;Name=test10.3
+""")
+        f.close()
+
+    def _writeExpOutFile_case11(self, fileName):
+        f = open(fileName, 'w')
+        f.write("""chr1	S-MART	test11.1	420	480	61	+	.	nbOverlaps=1;overlapsWith=test11.1;ID=query_1;Name=test11.1
+chr1	S-MART	test11.2	450	715	266	+	.	nbOverlaps=3;overlapsWith=test11.1--test11.4--test11.5;ID=query_2;Name=test11.2
+""")
+        f.close()
+        
+    def _writeQueryGff3File2(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest1\t1100\t1150\t126\t+\t.\tID=query_1;Name=test1.1\n")
+        f.write("chr1\tquery\ttest2\t1250\t1300\t781\t+\t.\tID=query_2;Name=test1.2\n")
+        f.close()
+        
+    def _writeQueryGff3File(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest1.1\t25\t150\t126\t+\t.\tID=query_1;Name=test1.1\n")
+        f.write("chr1\tquery\ttest1.2\t70\t850\t781\t+\t.\tID=query_2;Name=test1.2\n")
+        f.write("chr1\tquery\ttest1.3\t550\t850\t201\t+\t.\tID=query_3;Name=test1.3\n")
+        f.write("chr1\tquery\ttest1.4\t925\t1025\t101\t+\t.\tID=query_4;Name=test1.4\n")
+        f.write("chr1\tquery\ttest1.5\t1201\t1210\t10\t+\t.\tID=query_5;Name=test1.5\n")
+        f.write("chr1\tquery\ttest1.6\t1500\t1600\t101\t+\t.\tID=query_6;Name=test1.6\n")
+        f.close()
+        
+    def _writeQueryGff3File_case2(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest2.1\t150\t300\t151\t+\t.\tID=query_1;Name=test2.1\n")
+        f.write("chr1\tquery\ttest2.2\t300\t450\t781\t+\t.\tID=query_2;Name=test2.2\n")
+        f.write("chr1\tquery\ttest2.3\t480\t800\t321\t+\t.\tID=query_3;Name=test2.3\n")
+        f.write("chr1\tquery\ttest2.4\t560\t800\t241\t+\t.\tID=query_4;Name=test2.4\n")
+        f.write("chr1\tquery\ttest2.5\t850\t1000\t151\t+\t.\tID=query_5;Name=test2.5\n")
+        f.close()
+        
+    def _writeQueryGff3File_case3(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest3.1\t150\t250\t101\t+\t.\tID=query_1;Name=test3.1\n")
+        f.write("chr1\tquery\ttest3.2\t380\t400\t21\t+\t.\tID=query_2;Name=test3.2\n")
+        f.write("chr1\tquery\ttest3.3\t480\t520\t41\t+\t.\tID=query_3;Name=test3.3\n")
+        f.write("chr1\tquery\ttest3.4\t510\t700\t191\t+\t.\tID=query_4;Name=test3.4\n")
+        f.write("chr1\tquery\ttest3.5\t900\t950\t51\t+\t.\tID=query_5;Name=test3.5\n")
+        f.close()
+        
+    def _writeQueryGff3File_case4(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest4.1\t400\t500\t101\t+\t.\tID=query_1;Name=test4.1\n")
+        f.write("chr1\tquery\ttest4.2\t450\t600\t151\t+\t.\tID=query_2;Name=test4.2\n")
+        f.write("chr1\tquery\ttest4.3\t700\t800\t101\t+\t.\tID=query_3;Name=test4.3\n")
+        f.close()
+        
+    def _writeQueryGff3File_case5(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest5.1\t850\t950\t101\t+\t.\tID=query_1;Name=test5.1\n")
+        f.close()
+        
+    def _writeQueryGff3File_case6(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest6.1\t200\t300\t101\t+\t.\tID=query_1;Name=test6.1\n")
+        f.write("chr1\tquery\ttest6.2\t800\t900\t101\t+\t.\tID=query_2;Name=test6.2\n")
+        f.close()
+        
+    def _writeQueryGff3File_case7(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest7.1\t530\t550\t21\t+\t.\tID=query_1;Name=test7.1\n")
+        f.write("chr1\tquery\ttest7.2\t600\t700\t101\t+\t.\tID=query_2;Name=test7.2\n")
+        f.write("chr1\tquery\ttest7.3\t650\t900\t251\t+\t.\tID=query_3;Name=test7.3\n")
+        f.close()
+        
+    def _writeQueryGff3File_case8(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest8.1\t500\t600\t101\t+\t.\tID=query_1;Name=test8.1\n")
+        f.write("chr1\tquery\ttest8.2\t700\t800\t101\t+\t.\tID=query_2;Name=test8.2\n")
+        f.write("chr1\tquery\ttest8.3\t900\t1100\t201\t+\t.\tID=query_3;Name=test8.3\n")
+        f.write("chr1\tquery\ttest8.4\t1200\t1300\t101\t+\t.\tID=query_4;Name=test8.4\n")
+        f.close()
+        
+    def _writeQueryGff3File_case9(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest9.1\t400\t500\t101\t+\t.\tID=query_1;Name=test9.1\n")
+        f.write("chr1\tquery\ttest9.2\t550\t650\t101\t+\t.\tID=query_2;Name=test9.2\n")
+        f.close()
+        
+    def _writeQueryGff3File_case10(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest10.1\t700\t800\t101\t+\t.\tID=query_1;Name=test10.1\n")
+        f.write("chr1\tquery\ttest10.2\t900\t1000\t101\t+\t.\tID=query_2;Name=test10.2\n")
+        f.write("chr1\tquery\ttest10.3\t1100\t1300\t201\t+\t.\tID=query_3;Name=test10.3\n")
+        f.close()
+        
+    def _writeQueryGff3File_case11(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest11.1\t420\t480\t61\t+\t.\tID=query_1;Name=test11.1\n")
+        f.write("chr1\tquery\ttest11.2\t450\t715\t266\t+\t.\tID=query_2;Name=test11.2\n")
+        f.close()
+        
+    def _writeGFF3File(self, fileName):
+        f = open(fileName, "w")
+        f.write("chr1\ttest\ttest2.1\t9\t1000\t1001\t+\t.\tID=test2.1;Name=test2.1\n")
+        f.write("chr1\ttest\ttest2.2\t50\t350\t301\t+\t.\tID=test2.2;Name=test2.2\n")
+        f.write("chr1\ttest\ttest2.3\t100\t600\t501\t+\t.\tID=test2.3;Name=test2.3\n")
+        f.write("chr1\ttest\ttest2.4\t200\t450\t251\t+\t.\tID=test2.4;Name=test2.4\n")
+        f.write("chr1\ttest\ttest2.5\t700\t950\t251\t+\t.\tID=test2.5;Name=test2.5\n")
+        f.write("chr1\ttest\ttest2.6\t800\t900\t101\t+\t.\tID=test2.6;Name=test2.6\n")
+        f.write("chr1\ttest\ttest2.7\t1200\t1300\t101\t+\t.\tID=test2.7;Name=test2.7\n")
+        f.close()
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/test/Test_F_FindOverlaps_randomExample.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,48 @@
+import unittest
+import os
+import time
+from commons.core.utils.FileUtils import FileUtils
+from SMART.Java.Python.ncList.test.MockFindOverlaps_randomExample import MockFindOverlaps_randomExample_NonOrder
+from SMART.Java.Python.ncList.FindOverlaps_naif import FindOverlaps_naif
+from SMART.Java.Python.FindOverlapsOptim import FindOverlapsOptim
+
+class Test_F_FindOverlaps_randomExample(unittest.TestCase):
+
+    def setUp(self):
+        self._output_optim = 'output_optim.gff3'
+
+    def test_FindOverlaps_NonOrder(self):
+        inputRefGff3FileName = 'refMOverlaps.gff3'
+        inputQueryGff3FileName = 'queryMOverlaps.gff3'
+        outputDataName = 'timeResult.dat'  
+        fTime = open(outputDataName, 'w')  
+        fTime.write('NbRef\tNbQuery\tNbOverlap\ttime\n')   
+        numberOfRefReads = 10
+        chromSize = 100000
+        numberOfQReads = 10
+        print 'ref size = %d,  query size = %d' %(numberOfRefReads, numberOfQReads)
+        iMFOR_ref = MockFindOverlaps_randomExample_NonOrder(inputRefGff3FileName, 'ref', numberOfRefReads, chromSize)
+        iMFOR_ref.write()
+        iMFOR_query = MockFindOverlaps_randomExample_NonOrder(inputQueryGff3FileName,'q', numberOfQReads, chromSize)
+        iMFOR_query.write()
+        iFOO = FindOverlapsOptim(0)
+        iFOO.setRefFileName(inputRefGff3FileName, "gff3")
+        iFOO.setQueryFileName(inputQueryGff3FileName, "gff3")
+        iFOO.setOutputFileName(self._output_optim)
+        startTime_optim = time.time()
+        iFOO.run()
+        iFOO.close()  
+        nbOverlap = iFOO._nbOverlaps
+        endTime_optim = time.time()    
+        totalTime_optim = endTime_optim - startTime_optim
+        print 'we take %s second.' % (totalTime_optim)
+        fTime.write('%d\t%d\t%d\t%.2f\n'%(numberOfRefReads, numberOfQReads, nbOverlap, totalTime_optim))
+        fTime.close()
+        os.remove(inputQueryGff3FileName)
+        os.remove(inputRefGff3FileName)
+        os.remove(self._output_optim)  
+        os.remove(outputDataName)      
+        
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/test/Test_F_NCList.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,302 @@
+import os
+import unittest
+import struct
+from SMART.Java.Python.ncList.NCList import NCList
+from SMART.Java.Python.misc import Utils
+from commons.core.utils.FileUtils import FileUtils
+from SMART.Java.Python.ncList.test.MockFindOverlapsWithSeveralIntervals import *
+from commons.core.parsing.GffParser import GffParser
+from SMART.Java.Python.ncList.FileSorter import FileSorter
+
+class Test_F_NCList(unittest.TestCase):
+
+    def setUp(self):
+        self._inputGff3FileName = 'sortedFile.gff3'
+        self._sortedFileName    = 'sortedFile.pkl'
+        self._expHFileName      = 'expH.bin'
+        self._expLFileName      = 'expL.bin'
+        self._obsHFileName      = 'H.bin'
+        self._obsLFileName      = 'L.bin'
+        self._addressFileName   = 'address.txt'
+        self._writeGFF3File(self._inputGff3FileName)
+        self._ncList = NCList(0)
+        self._ncList.setChromosome("chr1")
+        
+    def tearDown(self):
+        return
+        for fileName in (self._inputGff3FileName, self._sortedFileName, self._expHFileName, self._expLFileName, self._obsHFileName, self._obsLFileName, self._addressFileName):
+            if os.path.exists(fileName):
+                os.remove(fileName)
+        
+    def _sortAndBuild(self):
+        parser = GffParser(self._inputGff3FileName)
+        fs = FileSorter(parser, 0)
+        fs.setOutputFileName(self._sortedFileName)
+        fs.sort()
+        self._ncList.setFileName(self._sortedFileName)
+        self._ncList.setNbElements(parser.getNbTranscripts())
+        self._ncList.buildLists()
+
+    def test_run_with_one_elementSubList(self):
+        iMock = MockFindOverlapsWithOneInterval()
+        iMock.write(self._inputGff3FileName)
+        self._sortAndBuild()
+        self._writeExpHFile_one_elementSubList()
+        self._writeExpLFile_one_elementSubList()
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expHFileName, self._ncList._hFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expLFileName, self._ncList._lFileName))    
+        
+    def test_case1(self):
+        iMock = MockFindOverlapsWithServeralIntervals_case1()
+        iMock.write(self._inputGff3FileName)
+        self._sortAndBuild()
+        self._writeExpHFileCase1()
+        self._writeExpLFileCase1()
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expHFileName, self._ncList._hFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expLFileName, self._ncList._lFileName))    
+        
+    def test_case2(self):
+        iMock = MockFindOverlapsWithServeralIntervals_case2()
+        iMock.write(self._inputGff3FileName)
+        self._sortAndBuild()
+        self._writeExpHFileCase2()
+        self._writeExpLFileCase2()
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expHFileName, self._ncList._hFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expLFileName, self._ncList._lFileName))    
+        
+    def test_case3(self):
+        iMock = MockFindOverlapsWithServeralIntervals_case3()
+        iMock.write(self._inputGff3FileName)
+        self._sortAndBuild()
+        self._writeExpHFileCase3()
+        self._writeExpLFileCase3()
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expHFileName, self._ncList._hFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expLFileName, self._ncList._lFileName))    
+    
+    def test_case4_5(self):
+        iMock = MockFindOverlapsWithServeralIntervals_case4_5()
+        iMock.write(self._inputGff3FileName)
+        self._sortAndBuild()
+        self._writeExpHFileCase4_5()
+        self._writeExpLFileCase4_5()
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expHFileName, self._ncList._hFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expLFileName, self._ncList._lFileName))    
+
+    def test_case6_7(self):
+        iMock = MockFindOverlapsWithServeralIntervals_case6_7()
+        iMock.write(self._inputGff3FileName)
+        self._sortAndBuild()
+        self._writeExpHFileCase6_7()
+        self._writeExpLFileCase6_7()
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expHFileName, self._ncList._hFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expLFileName, self._ncList._lFileName))    
+
+    def test_case8(self):
+        iMock = MockFindOverlapsWithServeralIntervals_case8()
+        iMock.write(self._inputGff3FileName)
+        self._sortAndBuild()
+        self._writeExpHFileCase8()
+        self._writeExpLFileCase8()
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expHFileName, self._ncList._hFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expLFileName, self._ncList._lFileName))    
+        
+    def test_case9(self):
+        iMock = MockFindOverlapsWithServeralIntervals_case9()
+        iMock.write(self._inputGff3FileName)
+        self._sortAndBuild()
+        self._writeExpHFileCase9()
+        self._writeExpLFileCase9()
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expHFileName, self._ncList._hFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expLFileName, self._ncList._lFileName))    
+ 
+    def test_case10(self):
+        iMock = MockFindOverlapsWithServeralIntervals_case10()
+        iMock.write(self._inputGff3FileName)
+        self._sortAndBuild()
+        self._writeExpHFileCase10()
+        self._writeExpLFileCase10()
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expHFileName, self._ncList._hFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expLFileName, self._ncList._lFileName))    
+ 
+    def test_case11(self):
+        iMock = MockFindOverlapsWithServeralIntervals_case11()
+        iMock.write(self._inputGff3FileName)
+        self._sortAndBuild()
+        self._writeExpHFileCase11()
+        self._writeExpLFileCase11()
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expHFileName, self._ncList._hFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expLFileName, self._ncList._lFileName))    
+               
+    def test_case12(self):
+        iMock = MockFindOverlapsWithServeralIntervals_case12()
+        iMock.write(self._inputGff3FileName)
+        self._sortAndBuild()
+        self._writeExpHFileCase12()
+        self._writeExpLFileCase12()
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expHFileName, self._ncList._hFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expLFileName, self._ncList._lFileName))    
+
+    def _writeGFF3File(self, fileName):
+        f = open(fileName, "w")
+        f.write("chr1\ttest\ttest2.1\t9\t1000\t1001\t+\t.\tID=test2.1;Name=test2.1\n")
+        f.write("chr1\ttest\ttest2.2\t50\t350\t301\t+\t.\tID=test2.2;Name=test2.2\n")
+        f.write("chr1\ttest\ttest2.3\t100\t600\t501\t+\t.\tID=test2.3;Name=test2.3\n")
+        f.write("chr1\ttest\ttest2.4\t200\t450\t251\t+\t.\tID=test2.4;Name=test2.4\n")
+        f.write("chr1\ttest\ttest2.5\t700\t950\t251\t+\t.\tID=test2.5;Name=test2.5\n")
+        f.write("chr1\ttest\ttest2.6\t800\t900\t101\t+\t.\tID=test2.6;Name=test2.6\n")
+        f.write("chr1\ttest\ttest2.7\t1200\t1300\t101\t+\t.\tID=test2.7;Name=test2.7\n")
+        f.close()
+    
+    def _writeBinFile(self, fileName, elements):
+        handle = open(fileName, "wb")
+        for element in elements:
+            handle.write(struct.pack('l', element))
+        handle.close()
+                     
+    def _writeExpHFile(self, HFileName):
+        list = [0, 2, 48, 3, -1, -1, -1, -1, 120, 1, 144, 1, -1, -1, -1, -1]
+        H = open(HFileName, 'wb')
+        
+        for item in list:
+            item = struct.pack('l', item)
+            H.write(item)
+        H.close()
+        
+    def _writeExpHFile_with_empty_SubParentDict(self, HFileName):
+        list = [0, 1, -1, -1]
+        H = open(HFileName, 'wb')
+        
+        for item in list:
+            item = struct.pack('l', item)
+            H.write(item)
+        H.close()
+        
+    def _writeExpHFile_one_elementSubList(self):
+        elements = [0, 1]
+        self._writeBinFile(self._expHFileName, elements)
+     
+    def _writeExpHFileCase1(self):
+        elements = [0, 2, 2, 3, 5, 1, 6, 1]
+        self._writeBinFile(self._expHFileName, elements)
+                     
+    def _writeExpHFileCase2(self):
+        elements = [0, 2, 2, 1, 3, 1, 4, 1]
+        self._writeBinFile(self._expHFileName, elements)
+                     
+    def _writeExpHFileCase3(self):
+        elements = [0, 2, 2, 1, 3, 1, 4, 2]
+        self._writeBinFile(self._expHFileName, elements)
+                     
+    def _writeExpHFileCase4_5(self):
+        elements = [0, 1, 1, 1, 2, 1]
+        self._writeBinFile(self._expHFileName, elements)
+                                              
+    def _writeExpHFileCase6_7(self):
+        elements = [0, 1, 1, 4]
+        self._writeBinFile(self._expHFileName, elements)
+              
+    def _writeExpHFileCase8(self):
+        elements = [0, 1, 1, 2]
+        self._writeBinFile(self._expHFileName, elements)
+              
+    def _writeExpHFileCase9(self):
+        elements = [0, 2, 2, 1]
+        self._writeBinFile(self._expHFileName, elements)
+              
+    def _writeExpHFileCase10(self):
+        elements = [0, 3, 3, 3]
+        self._writeBinFile(self._expHFileName, elements)
+              
+    def _writeExpHFileCase11(self):
+        elements = [0, 2, 2, 2, 4, 2]
+        self._writeBinFile(self._expHFileName, elements)
+        
+    def _writeExpHFileCase12(self):
+        elements = [0, 1, 1, 3, 4, 1]
+        self._writeBinFile(self._expHFileName, elements)
+        
+    def _writeExpLFile_one_elementSubList(self):
+        elements = [0, 1000, 0, -1, -1]
+        self._writeBinFile(self._expLFileName, elements)
+
+    def _writeExpLFileCase1(self):
+        elements = [   0, 1000,    0,  1, -1, \
+                    1200, 1300, 2345, -1, -1, \
+                      50,  350,  391, -1,  0, \
+                     100,  600,  781,  2,  0, \
+                     700,  950, 1563,  3,  0, \
+                     200,  450, 1172, -1,  3, \
+                     800,  900, 1954, -1,  4]
+        self._writeBinFile(self._expLFileName, elements)
+        
+    def _writeExpLFileCase2(self):
+        elements = [   0,  500,    0,  1, -1, \
+                     900, 1200, 1561, -1, -1, \
+                      50,  450,  389,  2,  0, \
+                     100,  400,  779,  3,  2, \
+                     100,  200, 1170, -1,  3]
+        self._writeBinFile(self._expLFileName, elements)
+        
+    def _writeExpLFileCase3(self):
+        elements = [   0,  500,    0,  1, -1, \
+                     800, 1000, 1952, -1, -1, \
+                      50,  450,  389,  2,  0, \
+                     100,  400,  779,  3,  2, \
+                     100,  200, 1170, -1,  3, \
+                     300,  400, 1561, -1,  3]
+        self._writeBinFile(self._expLFileName, elements)
+             
+    def _writeExpLFileCase4_5(self):
+        elements = [   0, 1000,    0,  1, -1, \
+                     200,  800,  391,  2,  0, \
+                     400,  600,  782, -1,  1]
+        self._writeBinFile(self._expLFileName, elements)
+                           
+    def _writeExpLFileCase6_7(self):
+        elements = [   0, 1000,    0,  1, -1, \
+                     100,  300,  391, -1,  0, \
+                     400,  500,  782, -1,  0, \
+                     510,  520, 1173, -1,  0, \
+                     850,  950, 1563, -1,  0]
+        self._writeBinFile(self._expLFileName, elements)
+        
+    def _writeExpLFileCase8(self):
+        elements = [   0, 1000,    0,  1, -1, \
+                     100,  200,  391, -1,  0, \
+                     300,  400,  782, -1,  0]
+        self._writeBinFile(self._expLFileName, elements)
+        
+    def _writeExpLFileCase9(self):
+        elements = [   0, 1000,    0,  1, -1, \
+                     800, 1200,  782, -1, -1, \
+                     600,  700,  391, -1,  0]
+        self._writeBinFile(self._expLFileName, elements)
+        
+    def _writeExpLFileCase10(self):
+        elements = [   0, 1000,    0,  1, -1, \
+                    1200, 1300, 1576, -1, -1, \
+                    1400, 1500, 1972, -1, -1, \
+                     100,  200,  394, -1,  0, \
+                     300,  400,  788, -1,  0, \
+                     500,  600, 1182, -1,  0]
+        self._writeBinFile(self._expLFileName, elements)
+        
+    def _writeExpLFileCase11(self):
+        elements = [   0,  500,    0,  1, -1, \
+                     700,  900, 1180,  2, -1, \
+                     100,  200,  392, -1,  0, \
+                     300,  400,  786, -1,  0, \
+                     710,  720, 1574, -1,  1, \
+                     740,  750, 1967, -1,  1]
+        self._writeBinFile(self._expLFileName, elements)
+              
+    def _writeExpLFileCase12(self):
+        elements = [   0, 1400,    0,  1, -1, \
+                     300,  500,  368,  2,  0, \
+                     800, 1100, 1106, -1,  0, \
+                    1200, 1300, 1476, -1,  0, \
+                     300,  500,  737, -1,  1]
+        self._writeBinFile(self._expLFileName, elements)
+              
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/test/Test_FindOverlapsWithOneInterval.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,81 @@
+import unittest
+import struct
+import os
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.ncList.FindOverlapsWithOneInterval import FindOverlapsWithOneInterval
+from SMART.Java.Python.ncList.NCListCursor import NCListCursor
+
+class Test_FindOverlapsWithOneInterval(unittest.TestCase):
+
+    def setUp(self):
+        self._inputGff3FileName = 'sortedFile.gff3'
+        self._writeGFF3File(self._inputGff3FileName)
+        self._obsFileName = "overlap.gff3"
+        self._iFOWOI = FindOverlapsWithOneInterval(0)
+        self._iFOWOI.setFileName(self._inputGff3FileName, "gff3")
+        self._iFOWOI._chromosome = "chr1"
+        self._iFOWOI.prepareIntermediateFiles()
+        self._iFOWOI.createNCList()
+        self._ncList = self._iFOWOI._ncList
+        self._iFOWOI.setOutputFileName(self._obsFileName)
+        
+    def tearDown(self):
+        return
+        self._iFOWOI.close()
+        for file in (self._inputGff3FileName, self._obsFileName):
+            if os.path.exists(file):
+                os.remove(file)
+        
+    def test_binarySearch_first_element_overlap(self):
+        self._iFOWOI.setInterval("chr1", 500, 850)
+        obsReadPosition = self._iFOWOI.binarySearch(NCListCursor(None, self._ncList, 0, 0), 0, 6)
+        expReadPosition = 0
+        self._iFOWOI.dumpWriter()
+        self._iFOWOI.close()
+        self.assertEquals(expReadPosition, obsReadPosition._lIndex)
+        
+    def test_binarySearch_second_element_overlap(self):
+        self._iFOWOI.setInterval("chr1", 500, 850)
+        obsReadPosition = self._iFOWOI.binarySearch(NCListCursor(None, self._ncList, 2, 0), 2, 6)
+        expReadPosition = 3
+        self._iFOWOI.dumpWriter()
+        self._iFOWOI.close()
+        self.assertEquals(expReadPosition, obsReadPosition._lIndex)
+        
+    def test_binarySearch_empty_subList(self):
+        self._iFOWOI.setInterval("chr1", 500, 850)
+        obsReadPosition = self._iFOWOI.binarySearch(NCListCursor(None, self._ncList, 5, 0), 5, 5)
+        expReadPosition = None
+        self._iFOWOI.dumpWriter()
+        self._iFOWOI.close()
+        self.assertEquals(expReadPosition, obsReadPosition)
+        
+    def test_binarySearch_no_overlap_right(self):
+        self._iFOWOI.setInterval("chr1", 1400, 1500)
+        obsReadPosition = self._iFOWOI.binarySearch(NCListCursor(None, self._ncList, 0, 0), 0, 6)
+        expReadPosition = None
+        self._iFOWOI.dumpWriter()
+        self._iFOWOI.close()
+        self.assertEquals(expReadPosition, obsReadPosition)
+        
+    def test_binarySearch_no_overlap_left(self):
+        self._iFOWOI.setInterval("chr1", 0, 45)       
+        obsReadPosition = self._iFOWOI.binarySearch(NCListCursor(None, self._ncList, 2, 0), 2, 6)
+        expReadPosition = None
+        self._iFOWOI.dumpWriter()
+        self._iFOWOI.close()
+        self.assertEquals(expReadPosition, obsReadPosition)
+
+    def _writeGFF3File(self, fileName):
+        f = open(fileName, "w")
+        f.write("chr1\ttest\ttest2.1\t9\t1000\t1001\t+\t.\tID=test2.1;Name=test2.1\n")
+        f.write("chr1\ttest\ttest2.2\t50\t350\t301\t+\t.\tID=test2.2;Name=test2.2\n")
+        f.write("chr1\ttest\ttest2.3\t100\t600\t501\t+\t.\tID=test2.3;Name=test2.3\n")
+        f.write("chr1\ttest\ttest2.4\t200\t450\t251\t+\t.\tID=test2.4;Name=test2.4\n")
+        f.write("chr1\ttest\ttest2.5\t700\t950\t251\t+\t.\tID=test2.5;Name=test2.5\n")
+        f.write("chr1\ttest\ttest2.6\t800\t900\t101\t+\t.\tID=test2.6;Name=test2.6\n")
+        f.write("chr1\ttest\ttest2.7\t1200\t1300\t101\t+\t.\tID=test2.7;Name=test2.7\n")
+        f.close()
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/test/Test_FindOverlapsWithSeveralIntervals.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,160 @@
+import unittest
+import os
+from SMART.Java.Python.ncList.FindOverlapsWithSeveralIntervals import FindOverlapsWithSeveralIntervals
+
+class Test_FindOverlapsWithSeveralIntervals(unittest.TestCase):
+
+    def setUp(self):
+        self._inputRefGff3FileName = 'sortedFile.gff3'
+        self._writeGFF3File(self._inputRefGff3FileName)
+        self._inputQueryGff3FileName = 'sorted_Query.gff3'
+        self._writeQueryGff3File(self._inputQueryGff3FileName)
+        self._outputGff3FileName = 'overlaps.gff3'
+        self._iFOWSI = FindOverlapsWithSeveralIntervals(self._inputRefGff3FileName, self._inputQueryGff3FileName)
+        self._iFOWSI.setOutputGff3FileName(self._outputGff3FileName)
+        
+    def tearDown(self):
+        os.remove(self._inputRefGff3FileName)
+        os.remove(self._inputQueryGff3FileName)
+        os.remove(self._outputGff3FileName)
+        self._iFOWSI.deletIntermediateFiles()
+    
+    def test_isOverlapping_true(self):
+        queryGff3Addr = 116
+        RefGff3Addr = 231
+        obs = self._iFOWSI.isOverlapping(queryGff3Addr, RefGff3Addr)
+        exp = 0
+        self.assertEquals(exp, obs)
+        
+    def test_isOverlapping_false_left(self):
+        queryGff3Addr = 116
+        RefGff3Addr = 58
+        obs = self._iFOWSI.isOverlapping(queryGff3Addr, RefGff3Addr)
+        exp = -1
+        self.assertEquals(exp, obs)
+    
+    def test_isOverlapping_false_right(self):
+        queryGff3Addr = 116
+        RefGff3Addr = 347
+        obs = self._iFOWSI.isOverlapping(queryGff3Addr, RefGff3Addr)
+        exp = 1
+        self.assertEquals(exp, obs) 
+           
+    def test_getHisFirstChild(self):
+        firstRefLAddr = 0
+        obsFirstChildLAddr = self._iFOWSI.getHisFirstChild(firstRefLAddr)
+        expFirstChildLAddr = 48
+        self.assertEquals(expFirstChildLAddr, obsFirstChildLAddr) 
+    
+    def test_isLastElement_true(self):
+        refLAddr = 96
+        obsBool = self._iFOWSI.isLastElement(refLAddr)
+        expBool = True
+        self.assertEquals(expBool, obsBool)
+    
+    def test_isLastElement_false(self):
+        refLAddr = 72
+        obsBool = self._iFOWSI.isLastElement(refLAddr)
+        expBool = False
+        self.assertEquals(expBool, obsBool)  
+        
+    def test_isLastElement_highestLevel_true(self):
+        refLAddr = 24
+        obsBool = self._iFOWSI.isLastElement(refLAddr)
+        expBool = True
+        self.assertEquals(expBool, obsBool)
+    
+    def test_isLastElement_highestLevel_false(self):
+        refLAddr = 0
+        obsBool = self._iFOWSI.isLastElement(refLAddr)
+        expBool = False
+        self.assertEquals(expBool, obsBool)           
+
+    def test_findOverlapIter(self):
+        queryGff3Addr = 175
+        firstRefLAddr = 0 
+        obsFirstOverlapLAddr = self._iFOWSI.findOverlapIter(queryGff3Addr, firstRefLAddr)
+        expFirstOverlapLAddr = 0
+        self.assertEquals(expFirstOverlapLAddr, obsFirstOverlapLAddr)
+        
+    def test_not_findOverlapIter(self):
+        queryGff3Addr = 295
+        firstRefLAddr = 24 
+        obsFirstOverlapLAddr = self._iFOWSI.findOverlapIter(queryGff3Addr, firstRefLAddr)
+        expFirstOverlapLAddr = None
+        self.assertEquals(expFirstOverlapLAddr, obsFirstOverlapLAddr)   
+        
+    def test_findOverlapIter_not_the_first_RefOverlap(self):
+        queryGff3Addr = 235
+        firstRefLAddr = 0 
+        obsFirstOverlapLAddr = self._iFOWSI.findOverlapIter(queryGff3Addr, firstRefLAddr)
+        expFirstOverlapLAddr = 24
+        self.assertEquals(expFirstOverlapLAddr, obsFirstOverlapLAddr)  
+        
+    def test_changeToNewSubEndLAddr(self):
+        firstChildLAddr = 48
+        subEndLAddr = 48
+        expSubEndLAddr = 120
+        obsSubEndLAddr = self._iFOWSI.changeToNewSubEndLAddr(firstChildLAddr, subEndLAddr)
+        self.assertEquals(expSubEndLAddr, obsSubEndLAddr) 
+        
+    def test_defineSubEndLaddr(self):
+        parentLAddr = -1
+        expSubEndLAddr = 48
+        obsSubEndLAddr = self._iFOWSI.defineSubEndLaddr(parentLAddr)
+        self.assertEquals(expSubEndLAddr, obsSubEndLAddr)
+        
+    def test_getNextRefIntervalInCaseNotOverLap(self):
+        firstRefLAddr = 96
+        expRefLAddr = 24
+        obsRefLAddr = self._iFOWSI.getNextRefIntervalInCaseNotOverLap(firstRefLAddr)
+        self.assertEquals(expRefLAddr, obsRefLAddr)
+        
+    def test_getNextRefIntervalInCaseOverLap(self):
+        firstChildLAddr = -1
+        firstRefLAddr = 120
+        subEndLAddr = 144
+        expRefLAddr, expSubEndLAddr = (96, 144)
+        obsRefLAddr, obsSubEndLAddr = self._iFOWSI.getNextRefIntervalInCaseOverLap(firstChildLAddr, firstRefLAddr, subEndLAddr)
+        self.assertEquals((expRefLAddr, expSubEndLAddr), (obsRefLAddr, obsSubEndLAddr))        
+
+    def test_not_findOverlapIter_between2RefIntervals(self):
+        inputQueryGff3FileName = 'query2.gff3'
+        self._writeQueryGff3File2(inputQueryGff3FileName)
+        self._iFOWSI.setQueryGff3FileName(inputQueryGff3FileName)
+        queryGff3Addr = 0
+        firstRefLAddr = 0
+        obsFirstOverlapLAddr = self._iFOWSI.findOverlapIter(queryGff3Addr, firstRefLAddr)
+        expFirstOverlapLAddr = 24
+        self.assertEquals(expFirstOverlapLAddr, obsFirstOverlapLAddr) 
+        os.remove(inputQueryGff3FileName) 
+
+    def _writeQueryGff3File2(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest1\t1100\t1150\t126\t+\t.\tID=test1.1;Name=test1.1\n")
+        f.write("chr1\tquery\ttest2\t1250\t1300\t781\t+\t.\tID=test1.2;Name=test1.2\n")
+        f.close()  
+        
+    def _writeQueryGff3File(self, fileName):
+        f = open(fileName, 'w')
+        f.write("chr1\tquery\ttest1.1\t25\t150\t126\t+\t.\tID=test1.1;Name=test1.1\n")
+        f.write("chr1\tquery\ttest1.2\t70\t850\t781\t+\t.\tID=test1.2;Name=test1.2\n")
+        f.write("chr1\tquery\ttest1.3\t550\t850\t201\t+\t.\tID=test1.3;Name=test1.3\n")
+        f.write("chr1\tquery\ttest1.4\t925\t1025\t101\t+\t.\tID=test1.4;Name=test1.4\n")
+        f.write("chr1\tquery\ttest1.5\t1201\t1210\t10\t+\t.\tID=test1.5;Name=test1.5\n")
+        f.write("chr1\tquery\ttest1.6\t1500\t1600\t101\t+\t.\tID=test1.6;Name=test1.6\n")
+        f.close()
+        
+    def _writeGFF3File(self, fileName):
+        f = open(fileName, "w")
+        f.write("chr1\ttest\ttest2.1\t9\t1000\t1001\t+\t.\tID=test2.1;Name=test2.1\n")
+        f.write("chr1\ttest\ttest2.2\t50\t350\t301\t+\t.\tID=test2.2;Name=test2.2\n")
+        f.write("chr1\ttest\ttest2.3\t100\t600\t501\t+\t.\tID=test2.3;Name=test2.3\n")
+        f.write("chr1\ttest\ttest2.4\t200\t450\t251\t+\t.\tID=test2.4;Name=test2.4\n")
+        f.write("chr1\ttest\ttest2.5\t700\t950\t251\t+\t.\tID=test2.5;Name=test2.5\n")
+        f.write("chr1\ttest\ttest2.6\t800\t900\t101\t+\t.\tID=test2.6;Name=test2.6\n")
+        f.write("chr1\ttest\ttest2.7\t1200\t1300\t101\t+\t.\tID=test2.7;Name=test2.7\n")
+        f.close()
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/test/Test_FindOverlaps_randomExample.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,99 @@
+import unittest
+import os
+import time
+from SMART.Java.Python.misc import Utils
+from SMART.Java.Python.ncList.test.MockFindOverlaps_randomExample import *
+from SMART.Java.Python.ncList.FindOverlaps_naif import FindOverlaps_naif
+from SMART.Java.Python.FindOverlapsOptim import FindOverlapsOptim
+
+class Test_FindOverlaps_randomExample(unittest.TestCase):
+
+    def setUp(self):
+        self._output_naif = 'output_naif.gff3'
+        self._outputOptim = 'outputOptim.gff3'
+
+        
+    def tearDown(self):
+        return
+        os.remove(self._output_naif)
+        os.remove(self._outputOptim)
+        
+    def test_run_smallSize(self):
+        inputRefGff3FileName = 'ref_small.gff3'
+        numberOfReads = 10
+        chromSize = 1000
+        iMFO_rand = MockFindOverlaps_randomExample(inputRefGff3FileName, 'reference', numberOfReads, chromSize)
+        iMFO_rand.write()
+
+        inputQueryGff3FileName = 'query_small.gff3'
+        iMFO_rand = MockFindOverlaps_randomExample(inputQueryGff3FileName,'query', 10, 1000)
+        iMFO_rand.write()
+        
+        iFON = FindOverlaps_naif(inputRefGff3FileName, inputQueryGff3FileName)
+        iFON.setOutputGff3FileName(self._output_naif)
+        iFOO = FindOverlapsOptim(0)
+        iFOO.setRefFileName(inputRefGff3FileName, "gff3")
+        iFOO.setQueryFileName(inputQueryGff3FileName, "gff3")
+        iFOO.setOutputFileName(self._outputOptim)
+        iFOO.prepareIntermediateFiles()
+        iFOO.createNCLists()
+        
+        startTime_naif = time.time()
+        iFON.run()
+        iFON.close()
+        endTime_naif = time.time()
+        totalTime_naif = endTime_naif - startTime_naif
+        print 'for naive algo, we take %e second' % (totalTime_naif)
+        
+        startTimeOptim = time.time()
+        iFOO.compare()
+        endTimeOptim = time.time()
+        totalTimeOptim = endTimeOptim - startTimeOptim
+        print 'for optim algo, we take %e second' % (totalTimeOptim)
+        iFOO.close()
+        
+        self.assertTrue(Utils.diff(self._output_naif, self._outputOptim)) 
+        
+        os.remove(inputRefGff3FileName)
+        os.remove(inputQueryGff3FileName)
+      
+
+    def test_creatRandomExampleWithMOverlaps_smallSize(self):
+        inputRefGff3FileName = 'refMOverlaps_small.gff3'
+        inputQueryGff3FileName = 'queryMOverlaps_small.gff3'       
+        numberOfReads = 10
+        chromSize = 1000 
+        iRMSS = MockFindOverlaps_randomExample_MOverlaps(inputRefGff3FileName, inputQueryGff3FileName, 7, numberOfReads, chromSize)
+        iRMSS.createRandomExample()
+  
+  
+        iFON = FindOverlaps_naif(inputRefGff3FileName, inputQueryGff3FileName)
+        iFON.setOutputGff3FileName(self._output_naif)
+        iFOO = FindOverlapsOptim(0)
+        iFOO.setRefFileName(inputRefGff3FileName, "gff3")
+        iFOO.setQueryFileName(inputQueryGff3FileName, "gff3")
+        iFOO.setOutputFileName(self._outputOptim)
+        iFOO.prepareIntermediateFiles()
+        iFOO.createNCLists()
+        
+        startTime_naif = time.time()
+        iFON.run()
+        endTime_naif = time.time()
+        totalTime_naif = endTime_naif - startTime_naif
+        print 'for naive algo, we take %e second' % (totalTime_naif)
+        iFON.close()
+        
+        startTimeOptim = time.time()
+        iFOO.compare()
+        endTimeOptim = time.time()
+        totalTimeOptim = endTimeOptim - startTimeOptim
+        print 'for optim algo, we take %e second' % (totalTimeOptim)
+        iFOO.close()        
+        
+        self.assertTrue(Utils.diff(self._output_naif, self._outputOptim)) 
+        
+        os.remove(inputRefGff3FileName)
+        os.remove(inputQueryGff3FileName)        
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/ncList/test/Test_randExample.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,51 @@
+import unittest
+import time
+from SMART.Java.Python.ncList.test.MockFindOverlaps_randomExample import *
+from SMART.Java.Python.FindOverlapsOptim import FindOverlapsOptim
+
+class Test_F_FindOverlaps_randomExample(unittest.TestCase):
+
+    def setUp(self):
+        self._output_optim = 'output_optim.gff3'
+        
+    def test_creatRandomExampleWithMOverlaps(self):
+        inputRefGff3FileName = 'refMOverlaps.gff3'
+        inputQueryGff3FileName = 'queryMOverlaps.gff3'
+        outputDataName = 'timeResult.dat'  
+        fTime = open(outputDataName, 'w')  
+        fTime.write('NbRef\tNbQuery\tNbOverlap\ttime\n')   
+        numberOfRefReads = 1000
+        chromSize = 100000
+        while numberOfRefReads <= 1000:
+            numberOfQReads = 1000
+            while numberOfQReads <= 1000:
+                print 'ref size = %d,  query size = %d' %(numberOfRefReads, numberOfQReads)
+                iMFOR_ref = MockFindOverlaps_randomExample(inputRefGff3FileName, 'ref', numberOfRefReads, chromSize)
+                iMFOR_ref.write()
+                iMFOR_query = MockFindOverlaps_randomExample(inputQueryGff3FileName,'q', numberOfQReads, chromSize)
+                iMFOR_query.write()
+                iFOO = FindOverlapsOptim(0)
+                iFOO.setRefFileName(inputRefGff3FileName, "gff3")
+                iFOO.setQueryFileName(inputQueryGff3FileName, "gff3")
+                iFOO.setOutputFileName(self._output_optim)
+                iFOO.prepareIntermediateFiles()
+                iFOO.createNCLists()
+                
+                startTime_optim = time.time()
+                iFOO.compare()
+                endTime_optim = time.time()
+                totalTime_optim = endTime_optim - startTime_optim
+                print 'we took %s second.' % (totalTime_optim)
+                nbOverlap = iFOO._nbOverlaps
+                iFOO.close()  
+                fTime.write('%d\t%d\t%d\t%.2f\n' % (numberOfRefReads, numberOfQReads, nbOverlap, totalTime_optim))
+                numberOfQReads *= 10
+            numberOfRefReads *= 10
+        fTime.close()
+        os.remove(inputQueryGff3FileName)
+        os.remove(inputRefGff3FileName)
+        os.remove(self._output_optim)
+        
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/plot.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,223 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+"""
+Plot the data from the data files
+"""
+
+import os, re, math
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from SMART.Java.Python.misc.Progress import Progress
+from commons.core.utils.FileUtils import FileUtils
+
+class Plot(object):
+
+    def __init__(self, verbosity):
+        self.verbosity = verbosity
+        self.keep      = False
+
+    def keepTmpFiles(self, boolean):
+        self.keep = boolean
+
+    def setShape(self, shape):
+        self.shape = shape
+
+    def setInputFileName(self, fileName, format):
+        self.parser = TranscriptContainer(fileName, format, self.verbosity)
+
+    def setXData(self, tag, default):
+        self.x        = tag
+        self.xDefault = default
+
+    def setYData(self, tag, default):
+        self.y        = tag
+        self.yDefault = default
+
+    def setZData(self, tag, default):
+        self.z        = tag
+        self.zDefault = default
+
+    def setNbBars(self, nbBars):
+        self.nbBars = nbBars
+
+    def setOutputFileName(self, fileName):
+        self.outputFileName = fileName
+
+    def setRegression(self, regression):
+        self.regression = regression
+
+    def setLog(self, log):
+        self.log = log
+
+    def createPlotter(self):
+        self.plotter = RPlotter(self.outputFileName, self.verbosity, self.keep)
+        if self.shape == "barplot":
+            self.plotter.setBarplot(True)
+        elif self.shape == "line":
+            pass
+        elif self.shape == "points":
+            self.plotter.setPoints(True)
+        elif self.shape == "heatPoints":
+            self.plotter.setHeatPoints(True)
+        else:
+            raise Exception("Do not understand shape '%s'\n" % (self.shape))
+            
+        self.plotter.setLog(self.log)
+        self.plotter.setRegression(self.regression)
+
+    def getValues(self, transcript):
+        x = transcript.getTagValue(self.x)
+        y = None
+        z = None
+        if self.y != None:
+            y = transcript.getTagValue(self.y)
+        if self.z != None:
+            z = transcript.getTagValue(self.z)
+        if x == None:
+            if self.xDefault != None:
+                x = self.xDefault
+            else:
+                raise Exception("Error! Transcript %s do not have the x-tag %s\n" % (transcript, self.x))
+        if self.y != None:
+            if y == None:
+                if self.yDefault != None:
+                    y = self.yDefault
+                else:
+                    raise Exception("Error! Transcript %s do not have the y-tag %s\n" % (transcript, self.y))
+        if self.z != None:
+            if z == None:
+                if self.zDefault != None:
+                    z = self.zDefault
+                else:
+                    raise Exception("Error! Transcript %s do not have the z-tag %s\n" % (transcript, self.z))
+        x = float(x)
+        if self.y != None:
+            y = float(y)
+        if self.z != None:
+            z = float(z)
+        return (x, y, z)
+
+    def correctPointsToBarplot(self, line):
+        minValue = int(math.floor(min(line.keys())))
+        maxValue = int(math.ceil(max(line.keys())))
+        step     = (maxValue - minValue) / self.nbBars
+        values   = dict([i * step + minValue, 0] for i in range(0, self.nbBars))
+        top      = (self.nbBars - 1) * step + minValue
+        for key, value in line.iteritems():
+            newKey = min(top, int(math.floor((key - minValue) / float(maxValue - minValue) * self.nbBars)) * step + minValue)
+            values[newKey] += value
+        return values
+
+    def parseFile(self):
+        line     = {}
+        heatLine = {}
+
+        cpt = 1
+        for transcript in self.parser.getIterator():
+            x, y, z = self.getValues(transcript)
+            name = transcript.name
+            if name == "unnamed transcript":
+                name = "transcript %d" % (cpt)
+                cpt += 1
+            if self.shape in ("points", "heatPoints"):
+                line[name] = (x, y)
+            if self.shape == "heatPoints":
+                heatLine[name] = z
+            if self.shape == "line":
+                line[x] = y
+            if self.shape == "barplot":
+                line[x] = line.get(x, 0) + 1
+        if self.shape == "barplot":
+            line = self.correctPointsToBarplot(line)
+        self.plotter.setXLabel(self.x)
+        if self.y != None:
+            self.plotter.setYLabel(self.y)
+        else:
+            self.plotter.setYLabel("Count")
+        self.plotter.addLine(line)
+        if self.shape == "heatPoints":
+            self.plotter.addHeatLine(heatLine)
+        self.plotter.plot()
+
+    def close(self):
+        if self.regression:
+            print self.plotter.getCorrelationData()
+        if self.shape == "points":
+            rho = self.plotter.getSpearmanRho()
+            if rho == None:
+                print "Cannot compute Spearman rho."
+            else:
+                print "Spearman rho: %f" % (rho)    
+
+    def run(self):
+        self.createPlotter()
+        self.parseFile() 
+        self.close()
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Plot v1.0.2: Plot some information from a list of transcripts. [Category: Visualization]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",      dest="inputFileName",  action="store",                      type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",     dest="format",         action="store",                      type="string", help="format of the input [compulsory] [format: transcript file format]")
+    parser.add_option("-x", "--x",          dest="x",              action="store",                      type="string", help="tag for the x value [format: string]")
+    parser.add_option("-y", "--y",          dest="y",              action="store",                      type="string", help="tag for the y value [format: string]")
+    parser.add_option("-z", "--z",          dest="z",              action="store",      default=None,   type="string", help="tag for the z value [format: string]")
+    parser.add_option("-X", "--xDefault",   dest="xDefault",       action="store",      default=None,   type="float",  help="value for x when tag is not present [format: float]")
+    parser.add_option("-Y", "--yDefault",   dest="yDefault",       action="store",      default=None,   type="float",  help="value for y when tag is not present [format: float]")
+    parser.add_option("-Z", "--zDefault",   dest="zDefault",       action="store",      default=None,   type="float",  help="value for z when tag is not present [format: float]")
+    parser.add_option("-o", "--output",     dest="outputFileName", action="store",                      type="string", help="output file names [format: output file in PNG format]")
+    parser.add_option("-s", "--shape",      dest="shape",          action="store", default="barplot",   type="string", help="shape of the plot [format: choice (barplot, line, points, heatPoints)]")
+    parser.add_option("-n", "--nbBars",     dest="nbBars",         action="store",      default=2,                type="int",    help="number of bars in barplot [format: int]")
+    parser.add_option("-k", "--keep",       dest="keep",           action="store_true", default=False,                 help="keep temporary files [format: bool]")
+    parser.add_option("-r", "--regression", dest="regression",     action="store_true", default=False,                 help="plot regression line (in 'points' format) [format: bool]")
+    parser.add_option("-l", "--log",        dest="log",            action="store",      default="y",     type="string", help="use log on x- or y-axis (write 'x', 'y' or 'xy') [format: string]")
+    parser.add_option("-v", "--verbosity",  dest="verbosity",      action="store",      default=1,      type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    plot = Plot(options.verbosity)
+    plot.setInputFileName(options.inputFileName, options.format)
+    plot.setOutputFileName(options.outputFileName)
+    plot.setXData(options.x, options.xDefault)
+    plot.setYData(options.y, options.yDefault)
+    plot.setZData(options.z, options.zDefault)
+    plot.setShape(options.shape)
+    plot.setNbBars(options.nbBars)
+    plot.setRegression(options.regression)
+    plot.setLog(options.log)
+    plot.keepTmpFiles(options.keep)
+    plot.run()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/plotCoverage.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,473 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os, subprocess, glob, random
+from optparse import OptionParser
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from SMART.Java.Python.misc.Progress import Progress
+from commons.core.parsing.FastaParser import FastaParser
+
+strands = [-1, 1]
+colors  = {-1: "blue", 1: "red", 0: "black"}
+colorLine = "black"
+
+def parseTargetField(field):
+    strand             = "+"
+    splittedFieldSpace = field.split()
+    splittedFieldPlus  = field.split("+", 4)
+    if len(splittedFieldSpace) == 3:
+        id, start, end = splittedFieldSpace
+    elif len(splittedFieldSpace) == 4:
+        id, start, end, strand = splittedFieldSpace
+    elif len(splittedFieldPlus) == 3:
+        id, start, end = splittedFieldPlus
+    elif len(splittedFieldPlus) == 4:
+        id, start, end, strand = splittedFieldPlus
+    else:
+        raise Exception("Cannot parse Target field '%s'." % (field))
+    return (id, int(start), int(end), strand)
+
+
+class SimpleTranscript(object):
+    def __init__(self, transcript1, transcript2, color = None):
+        self.start  = max(0, transcript1.getStart() - transcript2.getStart())
+        self.end    = min(transcript2.getEnd() - transcript2.getStart(), transcript1.getEnd() - transcript2.getStart())
+        self.strand = transcript1.getDirection() * transcript2.getDirection()
+        self.exons  = []
+        for exon in transcript1.getExons():
+            if exon.getEnd() >= transcript2.getStart() and exon.getStart() <= transcript2.getEnd():
+                start = max(0, exon.getStart() - transcript2.getStart())
+                end   = min(transcript2.getEnd() - transcript2.getStart(), exon.getEnd() - transcript2.getStart())
+                self.addExon(start, end, self.strand, color)
+
+    def addExon(self, start, end, strand, color):
+        exon = SimpleExon(start, end, strand, color)
+        self.exons.append(exon)
+
+    def getRScript(self, yOffset, height):
+        rString     = ""
+        previousEnd = None
+        for exon in sorted(self.exons, key=lambda exon: exon.start):
+            if previousEnd != None:
+                rString += "segments(%.1f, %.1f, %.1f, %.1f, col = \"%s\")\n" % (previousEnd, yOffset + height / 4.0, exon.start, yOffset + height / 4.0, colorLine)
+            rString    += exon.getRScript(yOffset, height)
+            previousEnd = exon.end
+        return rString
+
+
+class SimpleExon(object):
+    def __init__(self, start, end, strand, color = None):
+        self.start  = start
+        self.end    = end
+        self.strand = strand
+        self.color  = color
+        
+    def getRScript(self, yOffset, height):
+        color = self.color if self.color != None else colors[self.strand]
+        return "rect(%.1f, %.1f, %.1f, %.1f, col=\"%s\", border = \"%s\")\n" % (self.start, yOffset, self.end, yOffset + height / 2.0, color, colorLine)
+
+
+class Plotter(object):
+    
+    def __init__(self, seed, index, verbosity):
+        self.seed        = seed
+        self.index       = index
+        self.verbosity   = verbosity
+        self.maxCoverage = 0
+        self.maxOverlap  = 0
+        self.log         = ""
+        self.merge       = False
+        self.width       = 1500
+        self.heigth      = 1000
+        self.xLabel      = ""
+        self.yLabel      = ""
+        self.title       = None
+        self.absPath     = os.getcwd()
+        self.coverageDataFileName    = "tmpFile_%d_%s.dat" % (seed, index)
+        self.coverageScript          = ""
+        self.overlapScript           = ""
+        self.outputFileName          = None
+
+    def setOutputFileName(self, fileName):
+        self.outputFileName = fileName
+
+    def setTranscript(self, transcript):
+        self.transcript = transcript
+        self.name       = transcript.getName()
+        self.size       = transcript.getEnd() - transcript.getStart() + 1
+        if self.title == None:
+            self.title = self.name
+        else:
+            self.title += " " + self.name
+
+    def setTitle(self, title):
+        self.title = title + " " + self.name
+
+    def setPlotSize(self, width, height):
+        self.width  = width
+        self.height = height
+
+    def setLabels(self, xLabel, yLabel):
+        self.xLabel = xLabel
+        self.yLabel = yLabel
+
+    def setMerge(self, merge):
+        self.merge = merge
+
+    def setCoverageData(self, coverage):
+        outputCoveragePerStrand = dict([strand, 0] for strand in strands)
+        outputCoverage          = 0
+        dataFile = open(os.path.abspath(self.coverageDataFileName), "w")
+        for position in range(self.size+1):
+            sumValue = 0
+            found    = False
+            dataFile.write("%d\t" % (position))
+            for strand in strands:
+                value     = coverage[strand].get(position, 0)
+                sumValue += value
+                dataFile.write("%d\t" % (value))
+                if value > 0:
+                    found = True
+                    outputCoveragePerStrand[strand] += 1
+            self.maxCoverage = max(self.maxCoverage, sumValue)
+            dataFile.write("%d\n" % (sumValue))
+            if found:
+                outputCoverage += 1
+        dataFile.close()
+        self.log += "%s (%d nt):\n - both strands: %d (%.0f%%)\n - (+) strand: %d (%.0f%%)\n - (-) strand: %d (%.0f%%)\n" % (self.name, self.size, outputCoverage, float(outputCoverage) / self.size * 100, outputCoveragePerStrand[1], float(outputCoveragePerStrand[1]) / self.size * 100, outputCoveragePerStrand[-1], float(outputCoveragePerStrand[-1]) / self.size * 100) 
+        self.coverageScript += "data = scan(\"%s\", list(pos = -666, minus = -666, plus = -666, sumValue = -666), sep=\"\t\")\n" % (os.path.abspath(self.coverageDataFileName))
+        self.coverageScript += "lines(x = data$pos, y = data$minus,    col = \"%s\")\n" % (colors[-1])
+        self.coverageScript += "lines(x = data$pos, y = data$plus,     col = \"%s\")\n" % (colors[1])
+        self.coverageScript += "lines(x = data$pos, y = data$sumValue, col = \"%s\")\n" % (colors[0])
+
+    def setOverlapData(self, overlap):
+        height              = 1
+        self.maxOverlap     = (len(overlap) + 1) * height
+        thisElement         = SimpleTranscript(self.transcript, self.transcript, "black")
+        self.overlapScript += thisElement.getRScript(0, height)
+        for cpt, transcript in enumerate(sorted(overlap, cmp=lambda c1, c2: c1.start - c2.start if c1.start != c2.start else c1.end - c2.end)):
+            self.overlapScript += transcript.getRScript((cpt + 1) * height, height)
+
+    def getFirstLine(self, suffix = None):
+        return "png(file = \"%s_%s%s.png\", width = %d, height = %d, bg = \"white\")\n" % (self.outputFileName, self.name, "" if suffix == None or self.merge else "_%s" % (suffix), self.width, self.height)
+
+    def getLastLine(self):
+        return "dev.off()\n"
+
+    def startR(self, fileName, script):
+        scriptFile = open(fileName, "w")
+        scriptFile.write(script)
+        scriptFile.close()
+        command = "R CMD BATCH %s" % (fileName)
+        status  = subprocess.call(command, shell=True)
+        if status != 0:
+            raise Exception("Problem with the execution of script file %s, status is: %s" % (fileName, status))
+
+    def plot(self):
+        print "outputfileName is written in :", self.outputFileName
+        if self.merge:
+            fileName = "%s_%d_%s.R" % (self.outputFileName, self.seed, self.index)
+            plotLine = "plot(x = NA, y = NA, xlab=\"%s\", ylab=\"%s\", panel.first = grid(lwd = 1.0), xlim = c(0, %d), ylim = c(0, %d), cex.axis = 2, cex.lab = 2, cex.main=2, main = \"%s\")\n" % (self.xLabel, self.yLabel, self.size, max(self.maxCoverage, self.maxOverlap), self.title)
+            script   = self.getFirstLine() + plotLine + self.overlapScript + self.coverageScript + self.getLastLine()
+            self.startR(fileName, script)
+        else:
+            fileName = "%s_%d_%s_overlap.R" % (self.outputFileName, self.seed, self.index)
+            print "overlap file is written in :", fileName
+            plotLine = "plot(x = NA, y = NA, xlab=\"%s\", ylab=\"%s\", panel.first = grid(lwd = 1.0), xlim = c(0, %d), ylim = c(0, %d), cex.axis = 2, cex.lab = 2, cex.main=2, main = \"%s\")\n" % (self.xLabel, self.yLabel, self.size, self.maxOverlap, self.title)
+            script   = self.getFirstLine("overlap") + plotLine + self.overlapScript + self.getLastLine()
+            self.startR(fileName, script)
+            fileName = "%s_%d_%s_coverage.R" % (self.outputFileName, self.seed, self.index)
+            plotLine = "plot(x = NA, y = NA, xlab=\"%s\", ylab=\"%s\", panel.first = grid(lwd = 1.0), xlim = c(0, %d), ylim = c(0, %d), cex.axis = 2, cex.lab = 2, cex.main=2, main = \"%s\")\n" % (self.xLabel, self.yLabel, self.size, self.maxCoverage, self.title)
+            script   = self.getFirstLine("coverage") + plotLine + self.coverageScript + self.getLastLine()
+            self.startR(fileName, script)
+
+
+class PlotParser(object):
+
+    def __init__(self, verbosity):
+        self.verbosity      = verbosity
+        self.parsers        = [None, None]
+        self.sequenceParser = None
+        self.seed           = random.randint(0, 10000)
+        self.title          = ""
+        self.merge          = False
+
+    def __del__(self):
+        for fileName in glob.glob("tmpFile_%d*.dat" % (self.seed)):
+            os.remove(fileName)
+        for fileName in glob.glob("%s*.R" % (os.path.abspath(self.outputFileName))):
+            os.remove(fileName)
+        for fileName in glob.glob("%s*.Rout" % (os.path.abspath(self.outputFileName))):
+            os.remove(fileName)
+
+    def addInput(self, inputNb, fileName, fileFormat):
+        if fileName == None:
+            return
+        self.parsers[inputNb] = TranscriptContainer(fileName, fileFormat, self.verbosity)
+        if inputNb == 0:
+            self.parsers[1] = self.parsers[0]
+
+    def addSequence(self, fileName):
+        if fileName == None:
+            return
+        self.sequenceParser = FastaParser(fileName, self.verbosity)
+
+    def setOutput(self, fileName):
+        self.outputFileName = fileName
+
+    def setPlotSize(self, width, height):
+        self.width  = width
+        self.height = height
+
+    def setLabels(self, xLabel, yLabel):
+        self.xLabel = xLabel
+        self.yLabel = yLabel
+
+    def setTitle(self, title):
+        self.title = title
+
+    def setMerge(self, merge):
+        self.merge = merge
+
+    def initializeDataFromSequences(self):
+        self.sizes    = {}
+        self.coverage = {}
+        self.overlap  = {}
+        for region in self.sequenceParser.getRegions():
+            self.sizes[region]    = self.sequenceParser.getSizeOfRegion(region)
+            self.coverage[region] = {}
+            self.overlap[region]  = []
+            for strand in strands:
+                self.coverage[region][strand] = {}
+                self.coverage[region][strand][1] = 0
+                self.coverage[region][strand][self.sizes[region]] = 0
+
+
+    def initializeDataFromTranscripts(self):
+        self.coverage = dict([i, None] for i in range(self.parsers[1].getNbTranscripts()))
+        self.overlap  = dict([i, None] for i in range(self.parsers[1].getNbTranscripts()))
+        self.sizes    = dict([i, 0]    for i in range(self.parsers[1].getNbTranscripts()))
+        self.parsers[0].findData()
+        progress = Progress(self.parsers[1].getNbTranscripts(), "Reading regions", self.verbosity)
+        for cpt, transcript in enumerate(self.parsers[1].getIterator()):
+            self.coverage[cpt] = {}
+            self.overlap[cpt]  = []
+            for strand in strands:
+                self.coverage[cpt][strand] = {}
+                self.coverage[cpt][strand][0] = 0
+                self.coverage[cpt][strand][transcript.getEnd() - transcript.getStart()] = 0
+            for exon in transcript.getExons():
+                self.sizes[cpt] += exon.getSize()
+            progress.inc()
+        progress.done()
+
+    def initialize(self):
+        if self.sequenceParser == None:
+            self.initializeDataFromTranscripts()
+        else:
+            self.initializeDataFromSequences()
+
+    def computeCoverage(self, transcript1, transcript2, id):
+        strand = transcript1.getDirection() * transcript2.getDirection()
+        for exon1 in transcript1.getExons():
+            for exon2 in transcript2.getExons():
+                if exon1.overlapWith(exon2):
+                    for position in range(max(exon1.getStart(), exon2.getStart()), min(exon1.getEnd(), exon2.getEnd()) + 1):
+                        relativePosition = position - transcript2.getStart() + 1
+                        self.coverage[id][strand][relativePosition] = self.coverage[id][strand].get(relativePosition, 0) + 1
+
+    def computeOverlap(self, transcript1, transcript2, id):
+        simpleTranscript = SimpleTranscript(transcript1, transcript2)
+        self.overlap[id].append(simpleTranscript)
+        
+    def compute2TranscriptFiles(self):
+        progress = Progress(self.parsers[1].getNbTranscripts(), "Comparing regions", self.verbosity)
+        for cpt2, transcript2 in enumerate(self.parsers[1].getIterator()):
+            for transcript1 in self.parsers[0].getIterator():
+                if transcript1.overlapWithExon(transcript2):
+                    self.computeCoverage(transcript1, transcript2, cpt2)
+                    self.computeOverlap(transcript1, transcript2, cpt2)
+            progress.inc()
+        progress.done()
+
+    def extractReferenceQuery(self, inputTranscript):
+        if "Target" not in inputTranscript.getTagNames():
+            raise Exception("Cannot extract Target field in line '%s'." % (inputTranscript))
+        id, start, end, strand = parseTargetField(inputTranscript.getTagValue("Target"))
+        if id not in self.sizes:
+            raise Exception("Target id '%s' of transcript '%s' does not correspond to anything in FASTA file." % (id, inputTranscript))
+        referenceTranscript = Transcript()
+        referenceTranscript.setChromosome(id)
+        referenceTranscript.setName(id)
+        referenceTranscript.setDirection("+")
+        referenceTranscript.setEnd(self.sizes[id])
+        referenceTranscript.setStart(1)
+        queryTranscript = Transcript()
+        queryTranscript.setChromosome(id)
+        queryTranscript.setName(id)
+        queryTranscript.setStart(start)
+        queryTranscript.setEnd(end)
+        queryTranscript.setDirection(strand)
+        if inputTranscript.getNbExons() > 1:
+            factor = float(end - start) / (inputTranscript.getEnd() - inputTranscript.getStart())
+            for exon in inputTranscript.getExons():
+                newExon = Interval()
+                newExon.setChromosome(id)
+                newExon.setDirection(strand)
+                if "Target" in inputTranscript.getTagNames():
+                    id, start, end, strand = parseTargetField(exon.getTagValue("Target"))
+                    newExon.setStart(start)
+                    newExon.setEnd(end)
+                else:
+                    newExon.setStart(int(round((exon.getStart() - inputTranscript.getStart()) * factor)) + start)
+                    newExon.setEnd(  int(round((exon.getEnd() -   inputTranscript.getStart()) * factor)) + start)
+                queryTranscript.addExon(newExon)
+        return (referenceTranscript, queryTranscript)
+
+    def compute1TranscriptFiles(self):
+        progress = Progress(self.parsers[1].getNbTranscripts(), "Comparing regions", self.verbosity)
+        for transcript in self.parsers[1].getIterator():
+            referenceTranscript, queryTranscript = self.extractReferenceQuery(transcript)
+            self.computeCoverage(queryTranscript, referenceTranscript, referenceTranscript.getName())
+            self.computeOverlap(queryTranscript, referenceTranscript, referenceTranscript.getName())
+            progress.inc()
+        progress.done()
+
+    def compute(self):
+        if self.sequenceParser == None:
+            self.compute2TranscriptFiles()
+        else:
+            self.compute1TranscriptFiles()
+
+    def plotTranscript(self, index, transcript):
+        plotter = Plotter(self.seed, index, self.verbosity)
+        plotter.setOutputFileName(self.outputFileName)
+        plotter.setTranscript(transcript)
+        plotter.setTitle(self.title)
+        plotter.setLabels(self.xLabel, self.yLabel)
+        plotter.setPlotSize(self.width, self.height)
+        plotter.setCoverageData(self.coverage[index])
+        plotter.setOverlapData(self.overlap[index])
+        plotter.setMerge(self.merge)
+        plotter.plot()
+        output = plotter.log
+        return output
+        
+    def plot1TranscriptFile(self):
+        self.outputCoverage          = {}
+        self.outputCoveragePerStrand = {}
+        output   = ""
+        progress = Progress(len(self.sequenceParser.getRegions()), "Plotting regions", self.verbosity)
+        for cpt2, region in enumerate(self.sequenceParser.getRegions()):
+            transcript = Transcript()
+            transcript.setName(region)
+            transcript.setDirection("+")
+            transcript.setEnd(self.sizes[region])
+            transcript.setStart(1)
+            output += self.plotTranscript(region, transcript)
+            progress.inc()
+        progress.done()
+        if self.verbosity > 0:
+            print output
+
+    def plot2TranscriptFiles(self):
+        self.outputCoverage          = [0] * self.parsers[1].getNbTranscripts()
+        self.outputCoveragePerStrand = [None] * self.parsers[1].getNbTranscripts()
+        for cpt in range(self.parsers[1].getNbTranscripts()):
+            self.outputCoveragePerStrand[cpt] = dict([strand, 0] for strand in strands)
+        progress = Progress(self.parsers[1].getNbTranscripts(), "Plotting regions", self.verbosity)
+        output = ""
+        for cpt2, transcript2 in enumerate(self.parsers[1].getIterator()):
+            output += self.plotTranscript(cpt2, transcript2)
+            progress.inc()
+        progress.done()
+        if self.verbosity > 0:
+            print output
+
+    def plot(self):
+        if self.sequenceParser == None:
+            self.plot2TranscriptFiles()
+        else:
+            self.plot1TranscriptFile()
+
+    def start(self):
+        self.initialize()
+        self.compute()
+        self.plot()
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Plot Coverage v1.0.1: Plot the coverage of the first data with respect to the second one. [Category: Visualization]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input1",       dest="inputFileName1", action="store",                       type="string", help="input file 1 [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--inputFormat1", dest="inputFormat1",   action="store",                       type="string", help="format of input file 1 [compulsory] [format: transcript file format]")
+    parser.add_option("-j", "--input2",       dest="inputFileName2", action="store",                       type="string", help="input file 2 [compulsory] [format: file in transcript format given by -g]")
+    parser.add_option("-g", "--inputFormat2", dest="inputFormat2",   action="store",                       type="string", help="format of input file 2 [compulsory] [format: transcript file format]")
+    parser.add_option("-q", "--sequence",     dest="inputSequence",  action="store",      default=None,    type="string", help="input sequence file [format: file in FASTA format] [default: None]")
+    parser.add_option("-o", "--output",       dest="outputFileName", action="store",                       type="string", help="output file [compulsory] [format: output file in PNG format]")
+    parser.add_option("-w", "--width",        dest="width",          action="store",      default=1500,    type="int",    help="width of the plots (in px) [format: int] [default: 1500]")
+    parser.add_option("-e", "--height",       dest="height",         action="store",      default=1000,    type="int",    help="height of the plots (in px) [format: int] [default: 1000]")
+    parser.add_option("-t", "--title",        dest="title",          action="store",      default="",      type="string", help="title of the plots [format: string]")
+    parser.add_option("-x", "--xlab",         dest="xLabel",         action="store",      default="",      type="string", help="label on the x-axis [format: string]")
+    parser.add_option("-y", "--ylab",         dest="yLabel",         action="store",      default="",      type="string", help="label on the y-axis [format: string]")
+    parser.add_option("-p", "--plusColor",    dest="plusColor",      action="store",      default="red",   type="string", help="color for the elements on the plus strand [format: string] [default: red]")
+    parser.add_option("-m", "--minusColor",   dest="minusColor",     action="store",      default="blue",  type="string", help="color for the elements on the minus strand [format: string] [default: blue]")
+    parser.add_option("-s", "--sumColor",     dest="sumColor",       action="store",      default="black", type="string", help="color for 2 strands coverage line [format: string] [default: black]")
+    parser.add_option("-l", "--lineColor",    dest="lineColor",      action="store",      default="black", type="string", help="color for the lines [format: string] [default: black]")
+    parser.add_option("-1", "--merge",        dest="merge",          action="store_true", default=False,                  help="merge the 2 plots in 1 [format: boolean] [default: false]")
+    parser.add_option("-D", "--directory",    dest="working_Dir",    action="store",      default=os.getcwd(), type="string", help="the directory to store the results [format: directory]")
+    parser.add_option("-v", "--verbosity",    dest="verbosity",      action="store",      default=1,       type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    colors[1]  = options.plusColor
+    colors[-1] = options.minusColor
+    colors[0]  = options.sumColor
+    colorLine  = options.lineColor
+
+    pp = PlotParser(options.verbosity)
+    pp.addInput(0, options.inputFileName1, options.inputFormat1)
+    pp.addInput(1, options.inputFileName2, options.inputFormat2)
+    pp.addSequence(options.inputSequence)
+    if options.working_Dir[-1] != '/':
+        path = options.working_Dir + '/'
+    pp.setOutput(path + options.outputFileName)
+    pp.setPlotSize(options.width, options.height)
+    pp.setLabels(options.xLabel, options.yLabel)
+    pp.setTitle(options.title)
+    pp.setMerge(options.merge)
+    pp.start()
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/plotCsv.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,146 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Plot the data from the data files
+"""
+
+import os
+import re
+from optparse import OptionParser
+from SMART.Java.Python.misc.RPlotter import *
+from SMART.Java.Python.misc.Progress import *
+
+
+def mergeData(line1, line2):
+    if line1.keys() != line2.keys():
+        sys.exit("Error! Input files do not correspond to each other! Aborting...")
+    mergedData = {}
+    for key in line1:
+        mergedData[key] = (line1[key], line2[key])
+    return mergedData
+
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Plot CSV v1.0.1: Plot the content of a CSV file. [Category: Personnal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileNames", action="store",             type="string", help="input file [compulsory] [format: file in CSV format]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",             type="string", help="output file [compulsory] [format: output file in PNG format]")
+    parser.add_option("-s", "--shape",     dest="shape",          action="store",             type="string", help="shape of the plot [format: choice (line, bar, points, heatPoints)]")
+    parser.add_option("-l", "--log",       dest="log",            action="store", default="", type="string", help="use log on x- or y-axis (write 'x', 'y' or 'xy') [format: string] [default: ]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store", default=1,  type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    plotter = RPlotter(options.outputFileName, options.verbosity)
+    if options.shape == "bar":
+        plotter.setBarplot(True)
+    elif options.shape == "points":
+        plotter.setPoints(True)
+    elif options.shape == "heatPoints":
+        plotter.setHeatPoints(True)
+        
+    plotter.setLog(options.log)
+    
+    lines            = []
+    nbsColumns = []
+    for inputFileName in options.inputFileNames.split(","):
+        inputFile = open(inputFileName)
+        line            = {}
+        nbColumns = None
+        
+        for point in inputFile:
+            point = point.strip()
+            
+            m = re.search(r"^\s*(\S+)\s+(\d+\.?\d*)\s+(\d+\.?\d*)\s*$", point)
+            if m != None:
+                line[m.group(1)] = (float(m.group(2)), float(m.group(3)))
+                if nbColumns == None:
+                    nbColumns = 3
+                    nbsColumns.append(nbColumns)
+                elif nbColumns != 3:
+                    sys.exit("Number of columns changed around line '%s' of file '%s'! Aborting..." % (point, inputFileName))
+            else:
+                m = re.search(r"^\s*(\d+\.?\d*)\s+(\d+\.?\d*)\s*$", point)
+                if m != None:
+                    line[float(m.group(1))] = float(m.group(2))
+                    if nbColumns == None:
+                        nbColumns = 2
+                        nbsColumns.append(nbColumns)
+                    if nbColumns != 2:
+                        sys.exit("Number of columns changed around line '%s' of file '%s'! Aborting..." % (point, inputFileName))
+                else:
+                    m = re.search(r"^\s*(\S+)\s+(\d+\.?\d*)\s*$", point)
+                    if m != None:
+                        line[m.group(1)] = float(m.group(2))
+                        if nbColumns == None:
+                            nbColumns = 1
+                            nbsColumns.append(nbColumns)
+                        if nbColumns != 1:
+                            sys.exit("Number of columns changed around line '%s' of file '%s'! Aborting..." % (point, inputFileName))
+                    else:
+                        sys.exit("Do not understand line '%s' of file '%s'! Aborting..." % (point, inputFileName))
+
+        lines.append(line)
+                    
+    if len(lines) != len(nbsColumns):
+        sys.exit("Something is wrong in the input files! Aborting...")
+
+    if options.shape == "bar":
+        if len(lines) != 1:
+            sys.exit("Error! Bar plot should have exactly one input file! Aborting...")
+        if nbsColumns[0] != 2:
+            sys.exit("Error! Bar plot input file should have exactly two columns! Aborting...")
+        plotter.addLine(lines[0])
+    elif options.shape == "points":
+        if len(lines) != 2:
+            sys.exit("Error! Points cloud should have exactly two input file! Aborting...")
+        if nbsColumns[0] != 2 or nbsColumns[1] != 2:
+            sys.exit("Error! Points cloud plot input file should have exactly two columns! Aborting...")
+        plotter.addLine(mergedData(lines[0], lines[1]))
+    elif options.shape == "heatPoints":
+        if len(lines) != 3:
+            sys.exit("Error! Heat points cloud should have exactly three input file! Aborting...")
+        plotter.addLine(mergeData(lines[0], lines[1]))
+        plotter.addHeatLine(lines[2])
+    elif options.shape == "line":
+        for i in range(0, len(lines)):
+            if (nbsColumns[i] != 2):
+                sys.exit("Error! Curve plot input file should have exactly two columns! Aborting...")
+            plotter.addLine(lines[i])
+    else:
+        sys.exit("Do not understand shape '%s'" % (options.shape))
+
+
+    plotter.plot()
+                
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/plotGenomeCoverage.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,132 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import FastaParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from SMART.Java.Python.misc.Utils import *
+
+
+class GetGenomeCoverage(object):
+
+    def __init__(self, verbosity = 1):
+        self.verbosity       = verbosity
+        self.inputContainer  = None
+        self.referenceParser = None
+        self.outputFileName  = None
+        self.genomeSize      = None
+        self.coverage        = {}
+        self.distribution    = {}
+
+
+    def setInputFile(self, fileName, format):
+        self.inputContainer = TranscriptContainer(fileName, format, self.verbosity)
+
+
+    def setOutputFile(self, fileName):
+        self.outputFileName = fileName
+
+
+    def setReference(self, fileName):
+        self.referenceParser = FastaParser(fileName, self.verbosity)
+
+
+    def getReferenceSizes(self):
+        self.genomeSize = 0
+        for chromosome in self.referenceParser.getRegions():
+            self.genomeSize += self.referenceParser.getSizeOfRegion(chromosome)
+    
+
+    def getCoverage(self):
+        progress = Progress(self.inputContainer.getNbTranscripts(), "Reading reads", self.verbosity)
+        for transcript in self.inputContainer.getIterator():
+            chromosome = transcript.getChromosome()
+            if chromosome not in self.coverage:
+                self.coverage[chromosome] = {}
+            for exon in transcript.getExons():
+                for pos in range(exon.getStart(), exon.getEnd() + 1):
+                    if pos not in self.coverage[chromosome]:
+                        self.coverage[chromosome][pos] = 1
+                    else:
+                        self.coverage[chromosome][pos] += 1
+            progress.inc()
+        progress.done()
+
+    
+    def getDistribution(self):
+        nbNucleotides = sum([len(self.coverage[chromosome].keys()) for chromosome in self.coverage])
+        progress      = Progress(nbNucleotides, "Building distribution", self.verbosity)
+        for chromosome in self.coverage:
+            for num in self.coverage[chromosome].values():
+                if num not in self.distribution:
+                    self.distribution[num] = 1
+                else:
+                    self.distribution[num] += 1
+                progress.inc()
+        progress.done()
+        self.distribution[0] = self.genomeSize - nbNucleotides
+                
+
+    def plotDistribution(self):
+        plotter = RPlotter(self.outputFileName, self.verbosity)
+        plotter.setFill(0)
+        plotter.addLine(self.distribution)
+        plotter.plot()
+        print "min/avg/med/max reads per base: %d/%.2f/%.1f/%d" % getMinAvgMedMax(self.distribution)
+
+
+    def run(self):
+        self.getReferenceSizes()
+        self.getCoverage()
+        self.getDistribution()
+        self.plotDistribution()
+        
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Plot Genome Coverage v1.0.1: Get the coverage of a genome. [Category: Personal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",               type="string", help="reads file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",         action="store",               type="string", help="format of file [compulsory] [format: transcript file format]")
+    parser.add_option("-r", "--reference", dest="reference",      action="store",               type="string", help="sequences file [compulsory] [format: file in FASTA format]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",               type="string", help="output file [compulsory] [format: output file in PNG format]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store", default=1,    type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    getGenomeCoverage = GetGenomeCoverage(options.verbosity)
+    getGenomeCoverage.setInputFile(options.inputFileName, options.format)
+    getGenomeCoverage.setOutputFile(options.outputFileName)
+    getGenomeCoverage.setReference(options.reference)
+    getGenomeCoverage.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/plotRepartition.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,128 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Plot the data from the data files
+"""
+import os
+from optparse import OptionParser
+from commons.core.parsing.GffParser import GffParser
+from SMART.Java.Python.misc.RPlotter import RPlotter
+from SMART.Java.Python.misc.Progress import Progress
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Plot Repartition v1.0.1: Plot the repartition of different data on a whole genome. (This tool uses 1 input file only, the different values being stored in the tags.    See documentation to know more about it.) [Category: Visualization]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",                           type="string", help="input file name [compulsory] [format: file in GFF3 format]")
+    parser.add_option("-n", "--names",     dest="names",          action="store",      default=None,        type="string", help="name for the tags (separated by commas and no space) [default: None] [format: string]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",                           type="string", help="output file [compulsory] [format: output file in PNG format]")
+    parser.add_option("-c", "--color",     dest="colors",         action="store",      default=None,        type="string", help="color of the lines (separated by commas and no space) [format: string]")
+    parser.add_option("-f", "--format",    dest="format",         action="store",      default="png",       type="string", help="format of the output file [format: string] [default: png]")
+    parser.add_option("-r", "--normalize", dest="normalize",      action="store_true", default=False,                      help="normalize data (when panels are different) [format: bool] [default: false]")
+    parser.add_option("-l", "--log",       dest="log",            action="store",      default="",          type="string", help="use log on x- or y-axis (write 'x', 'y' or 'xy') [format: string]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store",      default=1,           type="int",    help="trace level [format: int]")
+    parser.add_option("-D", "--directory", dest="working_Dir",    action="store",      default=os.getcwd(), type="string", help="the directory to store the results [format: directory]")
+    (options, args) = parser.parse_args()
+
+    strands        = [1, -1]
+    strandToString = {1: "+", -1: "-"}
+    names          = [None] if options.names == None else options.names.split(",")
+    maxs           = {}
+    nbElements     = [0 for name in names]
+    lines          = [{} for i in range(len(names))]
+    if options.colors == None:
+        colors = [None for i in range(len(names))]
+    else:
+        colors = options.colors.split(",")
+
+    parser = GffParser(options.inputFileName, options.verbosity)
+    progress = Progress(parser.getNbTranscripts(), "Reading %s" % (options.inputFileName), options.verbosity)
+    for transcript in parser.getIterator():
+        chromosome = transcript.getChromosome()
+        direction  = transcript.getDirection()
+        start      = transcript.getStart()
+        for i, name in enumerate(names):
+            if chromosome not in lines[i]:
+                lines[i][chromosome] = dict([(strand, {}) for strand in strands])
+            if chromosome not in maxs:
+                maxs[chromosome] = transcript.getStart()
+            else:
+                maxs[chromosome] = max(maxs[chromosome], start)
+            if start not in lines[i][chromosome][direction]:
+                lines[i][chromosome][direction][start] = 0
+            thisNbElements                          = float(transcript.getTagValue(name)) if name != None and name in transcript.getTagNames() else 1
+            lines[i][chromosome][direction][start] += thisNbElements * direction
+            nbElements[i]                          += thisNbElements
+        progress.inc()
+    progress.done()
+
+    if options.normalize:
+        if options.verbosity >= 10:
+            print "Normalizing..."
+        for i, linesPerCondition in enumerate(lines):
+            for linesPerChromosome in linesPerCondition.values():
+                for line in linesPerChromosome.values():
+                    for key, value in line.iteritems():
+                        line[key] = value / float(nbElements[i]) * max(nbElements)
+    if options.verbosity >= 10:
+        print "... done."
+
+    progress = Progress(len(maxs.keys()), "Plotting", options.verbosity)
+    for chromosome in maxs:
+        plot = RPlotter("%s%s.%s" % (options.outputFileName, chromosome.capitalize(), options.format), options.verbosity)
+        plot.setLog(options.log)
+        plot.setImageSize(2000, 500)
+        plot.setFormat(options.format)
+        if maxs[chromosome] <= 1000:
+            unit    = "nt."
+            ratio = 1.0
+        elif maxs[chromosome] <= 1000000:
+            unit    = "kb"
+            ratio = 1000.0
+        else:
+            unit    = "Mb"
+            ratio = 1000000.0
+        plot.setXLabel("Position on %s (in %s)" % (chromosome.replace("_", " "), unit))
+        plot.setYLabel("# reads")
+        plot.setLegend(True)
+        for i, name in enumerate(names):
+            for strand in strands:
+                correctedLine = dict([(key / ratio, value) for key, value in lines[i][chromosome][strand].iteritems()])
+                if name != None:
+                    name = "%s (%s)" % (name.replace("_", " "), strandToString[strand])
+                plot.addLine(correctedLine, None, colors[i])
+        plot.plot()
+        progress.inc()
+    progress.done()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/plotTranscriptList.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,255 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Plot the data from the data files
+"""
+import sys
+import math
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.misc.RPlotter import RPlotter
+
+
+class PlotTranscriptList(object):
+
+    def __init__(self, verbosity = 0):
+        self.inputFileName    = None
+        self.format                 = None
+        self.x                            = None
+        self.y                            = None
+        self.z                            = None
+        self.xDefault             = None
+        self.yDefault             = None
+        self.zDefault             = None
+        self.xLabel                 = None
+        self.yLabel                 = None
+        self.shape                    = None
+        self.bucket                 = None
+        self.keep                     = None
+        self.log                        = None
+        self.verbosity            = None
+
+
+    def setPlotter(self, outputFileName, keep, log, xLabel, yLabel):
+        self.plotter = RPlotter(outputFileName, self.verbosity, keep)
+        if self.shape != "barplot":
+            self.plotter.setLog(log)
+        self.plotter.setXLabel(xLabel)
+        self.plotter.setYLabel(yLabel)
+
+
+    def setShape(self, shape):
+        if self.shape == "line":
+            pass
+        elif shape == "barplot":
+            self.plotter.setBarplot(True)
+        elif shape == "points":
+            self.plotter.setPoints(True)
+        elif shape == "heatPoints":
+            self.plotter.setHeatPoints(True)
+        else:
+            sys.exit("Do not understand shape '%s'" % (shape))
+
+
+    def setInput(self, inputFileName, format):
+        self.parser = TranscriptContainer(inputFileName, format, self.verbosity)
+
+
+    def getValues(self, transcript):
+        x, y, z = None, None, None
+        x = transcript.getTagValue(self.x)
+        if self.y != None:
+            y = transcript.getTagValue(self.y)
+        if self.z != None:
+            z = transcript.getTagValue(self.z)
+        if x == None:
+            if self.xDefault != None:
+                x = self.xDefault
+            else:
+                sys.exit("Error! Transcript %s do not have the x-tag %s" % (transcript, self.x))
+        if y == None and self.shape != "line" and self.shape != "barplot":
+            if self.yDefault != None:
+                y = self.yDefault
+            else:
+                sys.exit("Error! Transcript %s do not have the y-tag %s" % (transcript, self.y))
+        if self.z != None:
+            if z == None:
+                if self.zDefault != None:
+                    z = self.zDefault
+                else:
+                    sys.exit("Error! Transcript %s do not have the z-tag %s" % (transcript, self.z))
+        x = float(x)
+        if self.y != None:
+            y = float(y)
+        if self.z != None:
+            z = float(z)
+        return (x, y, z)
+
+
+    def readFile(self):
+        cpt            = 1
+        line         = {}
+        heatLine = {}
+        for transcript in self.parser.getIterator():
+            x, y, z = self.getValues(transcript)
+
+            name = transcript.name
+            if name == "unnamed transcript":
+                name = "transcript %d" % (cpt)
+                cpt += 1
+            if self.shape == "points":
+                line[name] = (x, y)
+            elif self.shape == "heatPoints":
+                line[name] = (x, y)
+                heatLine[name] = z
+            elif self.shape == "line" or self.shape == "barplot":
+                if x not in line:
+                    line[x] = 1
+                else:
+                    line[x] += 1
+            else:
+                sys.exit("Do not understand shape '%s'" % (self.shape))
+        return line, heatLine
+
+
+    def putLineInBuckets(self, line):
+        tmpLine = line
+        line        = {}
+        for key, value in tmpLine.iteritems():
+            line[int(key / float(self.bucket)) * self.bucket] = value
+        return line
+
+
+    def clusterInBarplot(self, line):
+        nbZeros        = 0
+        minValue     = min(line.keys())
+        maxValue     = max(line.keys())
+        if self.log != "":
+            if minValue == 0:
+                minValue = 1000000000
+                for value in line:
+                    if value < minValue:
+                        if value == 0:
+                            nbZeros += 1
+                        else:
+                            minValue = value
+            minValue = math.log(minValue)
+            maxValue = math.log(maxValue)
+        bucketSize = (maxValue - minValue) / self.bucket
+        tmpLine        = line
+        line             = {}
+        for i in range(int(self.bucket) + 1):
+            line[i * bucketSize + minValue] = 0
+        for key, value in tmpLine.iteritems():
+            if self.log != "" and key != 0:
+                key = math.log(key)
+            bucketKey = int((key - minValue) / bucketSize) * bucketSize + minValue
+            if self.log == "" or key != 0:
+                line[bucketKey] += value
+#     if self.log != "":
+#         tmpLine = line
+#         line        = {}
+#         for key, value in tmpLine.iteritems():
+#             line[math.exp(key)] = value
+        print "%d zeros have been removed" % (nbZeros)
+        return line
+
+
+    def getSpearmanRho(self):
+        rho = self.plotter.getSpearmanRho()
+        if rho == None:
+            print "Cannot compute Spearman rho."
+        else:
+            print "Spearman rho: %f" % (rho)
+
+
+    def run(self):
+        line, heatLine = self.readFile()
+
+        if self.shape == "line" and self.bucket != None:
+            line = self.putLineInBuckets(line)
+        if self.shape == "barplot":
+            line = self.clusterInBarplot(line)
+
+        if self.shape == "points" or self.shape == "barplot" or self.shape == "line":
+            self.plotter.addLine(line)
+        elif self.shape == "heatPoints":
+            self.plotter.addLine(line)
+            self.plotter.addHeatLine(heatLine)
+        else:
+            sys.exit("Do not understand shape '%s'" % (self.shape))
+
+        self.plotter.plot()
+
+        if self.shape == "points" or self.shape == "heatPoints":
+            self.getSpearmanRho()
+
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Plot v1.0.2: Plot some information from a list of transcripts. [Category: Visualization]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",dest="inputFileName", action="store", type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",dest="format", action="store",type="string", help="format of the input [compulsory] [format: transcript file format]")
+    parser.add_option("-x", "--x",dest="x",action="store", type="string", help="tag for the x value [format: string]")
+    parser.add_option("-y", "--y",dest="y",action="store", type="string", help="tag for the y value [format: string]")
+    parser.add_option("-z", "--z",dest="z", action="store", default=None,type="string", help="tag for the z value [format: string]")
+    parser.add_option("-X", "--xDefault",dest="xDefault",action="store", default=None,type="float",help="value for x when tag is not present [format: float]")
+    parser.add_option("-Y", "--yDefault",dest="yDefault",action="store",default=None,type="float",help="value for y when tag is not present [format: float]")
+    parser.add_option("-Z", "--zDefault",dest="zDefault", action="store",default=None,type="float",help="value for z when tag is not present [format: float]")
+    parser.add_option("-n", "--xLabel",dest="xLabel",action="store",default="",type="string", help="label on the x-axis [format: string] [default: ]")
+    parser.add_option("-m", "--yLabel",dest="yLabel",action="store",default="", type="string", help="label on the y-axis [format: string] [default: ]")
+    parser.add_option("-o", "--output",dest="outputFileName",action="store",type="string", help="output file names [format: output file in PNG format]")
+    parser.add_option("-s", "--shape",dest="shape",action="store", type="string", help="shape of the plot [format: choice (barplot, line, points, heatPoints)]")
+    parser.add_option("-b", "--bucket",dest="bucket",action="store",default=None,type="float",help="bucket size (for the line plot) [format: int] [default: 1]")
+    parser.add_option("-k", "--keep",dest="keep",action="store_true", default=False, help="keep temporary files [format: bool]")
+    parser.add_option("-l", "--log",dest="log",action="store",default="",type="string", help="use log on x- or y-axis (write 'x', 'y' or 'xy') [format: string] [default: ]")
+    parser.add_option("-v", "--verbosity",dest="verbosity",action="store",default=1, type="int",help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    plotTranscriptList = PlotTranscriptList(options.verbosity)
+    plotTranscriptList.x                = options.x
+    plotTranscriptList.y                = options.y
+    plotTranscriptList.z                = options.z
+    plotTranscriptList.xDefault = options.xDefault
+    plotTranscriptList.yDefault = options.yDefault
+    plotTranscriptList.zDefault = options.zDefault
+    plotTranscriptList.shape        = options.shape
+    plotTranscriptList.bucket     = options.bucket
+    plotTranscriptList.log            = options.log
+    plotTranscriptList.setPlotter(options.outputFileName, options.keep, options.log, options.xLabel, options.yLabel)
+    plotTranscriptList.setShape(options.shape)
+    plotTranscriptList.setInput(options.inputFileName, options.format)
+    plotTranscriptList.run()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/qualToFastq.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,87 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+from optparse import OptionParser
+from commons.core.parsing.SequenceListParser import SequenceListParser
+from SMART.Java.Python.misc.Progress import Progress
+
+"""
+Transform qual and fasta files to a single fastq file
+"""
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Qual To FastQ v1.0.2: Convert a file in FASTA/Qual format to FastQ format. [Category: Conversion]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-f", "--fasta",     dest="fastaFileName",  action="store",               type="string", help="input fasta file [compulsory] [format: file in FASTA format]")
+    parser.add_option("-q", "--qual",      dest="qualFileName",   action="store",               type="string", help="input qual file [compulsory] [format: file in TXT format]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store", default=None, type="string", help="output file [compulsory] [format: output file in FASTQ format]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store", default=1,    type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+    
+    fastaFile = open(options.fastaFileName)
+    qualFile  = open(options.qualFileName)
+    fastqFile = open(options.outputFileName, "w")
+    
+    fastaLine = fastaFile.readline().strip()
+    qualLine  = qualFile.readline().strip()
+    header    = None
+    cpt       = 0
+    while fastaLine:
+        if not qualLine:
+            raise Exception("Qual file is shorter!")
+        if fastaLine[0] == ">":
+            header = fastaLine[1:]
+            if qualLine[0] != ">":
+                raise Exception("Discrepencies around %s!" % (header))
+            fastqFile.write("@%s\n" % (header))
+        else:
+            if qualLine[0] == ">":
+                raise Exception("Discrepencies around %s!" % (qualLine[1:]))
+            intQualities = qualLine.split()
+            if len(intQualities) != len(fastaLine):
+                raise Exception("Sizes of read and quality diverge in %s!" % (header))
+            chrQualities = [chr(min(int(quality), 93) + 33) for quality in intQualities]
+            fastqFile.write("%s\n+\n%s\n" % (fastaLine, "".join(chrQualities)))
+        fastaLine = fastaFile.readline().strip()
+        qualLine  = qualFile.readline().strip()
+        if cpt % 1000 == 0 and options.verbosity > 1:
+            sys.stdout.write("%d lines read\r" % (cpt))
+            sys.stdout.flush()
+        cpt += 1
+    if options.verbosity > 0:
+        print "%d lines read" % (cpt)
+        
+    if qualLine:
+        raise Exception("Qual file is longer!")
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/removeAllTmpTables.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,64 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Remove all tmp tables in the MySQL database"""
+
+import os
+import glob
+from optparse import OptionParser
+from SMART.Java.Python.mySql.MySqlConnection import *
+
+
+if __name__ == "__main__":
+    
+    description = "Remove Tables v1.0.2: Remove tables in the local MySQL database. [Category: Other]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-t", "--tmp",     dest="tmp",     action="store_true",    default=False, help="Remove temporary tables only [format: bool] [default: false]")
+    parser.add_option("-f", "--files", dest="files", action="store_false", default=True,    help="Do not remove temporary files [format: bool] [default: true]")
+    (options, args) = parser.parse_args()
+    
+    print "Removing temporary databases:"
+    if options.files:
+        for tmpFile in glob.glob("smartdb*"):
+            print "    removing %s" % (tmpFile)
+            os.unlink(tmpFile)
+    print "Removing temporary files:"
+    if options.files:
+        for tmpFile in glob.glob("tmp*.dat"):
+            print "    removing %s" % (tmpFile)
+            os.unlink(tmpFile)
+        for tmpFile in glob.glob("tmp*.R"):
+            print "    removing %s" % (tmpFile)
+            os.unlink(tmpFile)
+        for tmpFile in glob.glob("tmp*.Rout"):
+            print "    removing %s" % (tmpFile)
+            os.unlink(tmpFile)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/removeEmptySequences.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,135 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Remove empty sequences from a FASTA or FASTQ file
+"""
+
+import os, random
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import *
+from commons.core.parsing.FastqParser import *
+from commons.core.writer.FastaWriter import *
+from commons.core.writer.FastqWriter import *
+from SMART.Java.Python.misc.Progress import *
+
+
+class EmptySequenceRemover(object):
+
+    def __init__(self, verbosity = 1):
+        self.verbosity            = verbosity
+        self.inputFileName    = None
+        self.parser                 = None
+        self.format                 = None
+        self.writer                 = None
+        self.forbiddenNames = {}
+        self.removedNames     = {}
+
+
+    def setInputFileName(self, fileName, format):
+        self.inputFileName = fileName
+        self.format                = format
+        if options.format == "fasta":
+            self.parser = FastaParser(self.inputFileName, self.verbosity)
+        elif options.format == "fastq":
+            self.parser = FastqParser(self.inputFileName, self.verbosity)
+        else:
+            sys.exit("Do not understand '%s' file format." % (self.format))
+
+
+    def setOutputFileName(self, fileName):
+        if options.format == "fasta":
+            self.writer = FastaWriter("%s.mfa" % (fileName), self.verbosity)
+        elif options.format == "fastq":
+            self.writer = FastqWriter("%s.mfq" % (fileName), self.verbosity)
+
+
+    def parse(self):
+        progress = Progress(self.parser.getNbSequences(), "Reading sequences in %s" % (options.inputFileName), options.verbosity)
+        for sequence in self.parser.getIterator():
+            name = sequence.name.split("/")[0]
+            if name not in self.forbiddenNames:
+                if sequence.sequence == "":
+                    self.removedNames[name] = 1
+                else:
+                    self.writer.addSequence(sequence)
+            progress.inc()
+        progress.done()
+        self.writer.write()
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Remove Empty Sequences v1.0.2: Remove all the empty sequences in a list. [Category: Personal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",         dest="inputFileName",     action="store",                                         type="string", help="input file [compulsory] [format: file in sequence format given by -f]")
+    parser.add_option("-f", "--format",        dest="format",                    action="store",                                         type="string", help="format of the input file [compulsory] [format: sequence file format]")
+    parser.add_option("-j", "--input2",        dest="inputFileName2",    action="store",                                         type="string", help="input file 2 (in case of pair end reads) [format: file in sequence format given by -f] [default: None]")
+    parser.add_option("-o", "--output",        dest="outputFileName",    action="store",            default=None,    type="string", help="output file [compulsory] [format: output file in format given by -f]")
+    parser.add_option("-p", "--output2",     dest="outputFileName2", action="store",            default=None,    type="string", help="output file 2 (in case of pair end reads) [format: output file in sequence format given by -f] [default: None]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",             action="store",            default=1,         type="int",        help="trace level [format: int] [default: 1]")
+    parser.add_option("-l", "--log",             dest="log",                         action="store_true", default=False,                                help="write a log file [format: bool] [default: false]")
+    (options, args) = parser.parse_args()
+
+    if options.log:
+        logHandle = open("%s.log" % options.outputFileName, "w")
+    
+    remover = EmptySequenceRemover(options.verbosity)
+    remover.setInputFileName(options.inputFileName, options.format)
+    remover.setOutputFileName(options.outputFileName)
+    remover.parse()
+    removedNames = remover.removedNames
+    if options.log:
+        for name in removedNames:
+            logHandle.write("Removed '%s' in %s\n" % (name, options.inputFileName))
+    nbSequences = remover.parser.getNbSequences()
+
+    newRemovedNames = {}
+    if options.inputFileName2 != None:
+        remover = EmptySequenceRemover(options.verbosity)
+        remover.setInputFileName(options.inputFileName2, options.format)
+        remover.setOutputFileName(options.outputFileName2)
+        remover.forbiddenNames = removedNames
+        remover.parse()
+        newRemovedNames = remover.removedNames
+        if options.log:
+            for name in newRemovedNames:
+                logHandle.write("Removed '%s' in %s\n" % (name, options.inputFileName2))
+
+        remover = EmptySequenceRemover(options.verbosity)
+        remover.setInputFileName(options.inputFileName, options.format)
+        remover.setOutputFileName(options.outputFileName)
+        remover.forbiddenNames = newRemovedNames
+        remover.parse()
+
+    nbRemoved = len(removedNames.keys()) + len(newRemovedNames.keys())
+    print "%d over %d sequences are empty (%.2f%%)." % (nbRemoved, nbSequences, float(nbRemoved) / nbSequences * 100)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/removeExonLines.sh	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,2 @@
+#!/bin/bash
+sed '/exon/d' $1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/repetGffConverter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,71 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Convert a GFF with REPET format to BED format"""
+
+import os
+from optparse import OptionParser
+from commons.core.parsing.GffParser import *
+from commons.core.writer.BedWriter import *
+from SMART.Java.Python.misc.Progress import *
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Repet GFF Convert v1.0.1: Convert REPET-flavored GFF to normal GFF. [Category: Personnal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",                        dest="inputFileName",    action="store",                                         type="string", help="input file [compulsory] [format: file in GFF3 format]")
+    parser.add_option("-o", "--output",                     dest="outputFileName", action="store",                                         type="string", help="output file [compulsory] [format: output file in GFF3 format]")
+    parser.add_option("-v", "--verbosity",                dest="verbosity",            action="store",            default=1,         type="int",        help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    parser            = GffParser(options.inputFileName, options.verbosity)
+    transcripts = dict()
+    progress        = Progress(parser.getNbTranscripts(), "Analyzing file %s" % (options.inputFileName), options.verbosity)
+    for transcript in parser.getIterator():
+        if transcript.feature.endswith("range"):
+            transcripts[transcript.name] = transcript
+        elif transcript.feature.endswith("hsp"):
+            if transcript.name in transcripts:
+                transcripts[transcript.name].addExon(transcript)
+            else:
+                sys.exit("Transcript %s is not defined\n" % (transcript.name))
+        else:
+            sys.exit("Do not understand feature %s" % (transcript.feature))
+        progress.inc()
+    progress.done()
+        
+    writer = BedWriter(options.outputFileName, options.verbosity)
+    for name in transcripts:
+        writer.addTranscript(transcripts[name])
+        
+    print "%d transcripts out of %d written (%.2f%%)" % (len(transcripts.keys()), parser.getNbTranscripts(), float(len(transcripts.keys())) / parser.getNbTranscripts() * 100)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/restrictFromNucleotides.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,78 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Remove all dirty sequences"""
+
+import os
+import sys
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import *
+from commons.core.writer.FastaWriter import *
+from commons.core.parsing.FastqParser import *
+from commons.core.writer.FastqWriter import *
+from SMART.Java.Python.misc.Progress import *
+from SMART.Java.Python.misc.RPlotter import *
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Restrict from nucleotide v1.0.1: Remove the sequences with ambiguous nucleotides. [Category: Personal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",         dest="inputFileName",    action="store",                                                type="string", help="input file [compulsory] [format: file in sequence format given by -f]")
+    parser.add_option("-f", "--format",        dest="inputFileName",    action="store",            default="fasta",    type="string", help="format of the input and output files [compulsory] [format: sequence file format]")
+    parser.add_option("-o", "--output",        dest="outputFileName", action="store",                                                type="string", help="output file [compulsory] [format: output file in sequence format given by -f]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",            action="store",            default=1,                type="int",        help="trace level [format: int]")
+    parser.add_option("-l", "--log",             dest="log",                        action="store_true", default=False,                                     help="write a log file [format: bool] [default: false]")
+    (options, args) = parser.parse_args()
+
+    # treat items
+    if options.format == "fasta":
+        parser     = FastaParser(options.inputFileName, options.verbosity)
+        writer     = FastaWriter(options.outputFileName, options.verbosity)
+    elif options.format == "fastq":
+        parser     = FastqParser(options.inputFileName, options.verbosity)
+        writer     = FastqWriter(options.outputFileName, options.verbosity)
+    else:
+        sys.exit("Do not understand '%s' format." % (options.format))
+    nbSequences = parser.getNbSequences()
+    print "sequences: %d" % (nbSequences)
+    
+    progress = Progress(nbSequences, "Analyzing sequences of %s" % (options.inputFileName), options.verbosity)
+    nbKept     = 0
+    for sequence in parser.getIterator():
+        if not sequence.containsAmbiguousNucleotides():
+            writer.addSequence(sequence)
+            nbKept += 1
+        progress.inc()
+    progress.done()
+
+    print "%d items, %d kept (%.2f%%)" % (nbSequences, nbKept, float(nbKept) / nbSequences * 100)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/restrictFromSize.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,94 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Get the size distribution of a Fasta / BED file"""
+
+import os
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import *
+from commons.core.parsing.FastqParser import *
+from SMART.Java.Python.structure.TranscriptContainer import *
+from commons.core.writer.TranscriptWriter import *
+from commons.core.writer.FastaWriter import *
+from commons.core.writer.FastqWriter import *
+from SMART.Java.Python.misc.Progress import *
+from SMART.Java.Python.misc.RPlotter import *
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Restrict from Size v1.0.1: Select the elements of a list of sequences or transcripts with a given size. [Category: Data Selection]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",                     type="string", help="input file [compulsory] [format: file in transcript or sequence format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",         action="store",                     type="string", help="format of the input [compulsory] [format: sequence or transcript file format]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",                     type="string", help="output file [compulsory] [format: output file in transcript or sequence format given by -f]")
+    parser.add_option("-m", "--minSize",   dest="minSize",        action="store",      default=None,  type="int",    help="minimum size [format: int]")
+    parser.add_option("-M", "--maxSize",   dest="maxSize",        action="store",      default=None,  type="int",    help="maximum size [format: int]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [format: int]")
+    parser.add_option("-l", "--log",       dest="log",            action="store_true", default=False,                help="write a log file [format: bool] [default: false]")
+    (options, args) = parser.parse_args()
+
+    if options.format == "fasta":
+        parser = FastaParser(options.inputFileName, options.verbosity)
+        writer = FastaWriter(options.outputFileName, options.verbosity)
+    elif options.format == "fastq":
+        parser = FastqParser(options.inputFileName, options.verbosity)
+        writer = FastqWriter(options.outputFileName, options.verbosity)
+    else:
+        parser = TranscriptContainer(options.inputFileName, options.format, options.verbosity)
+        writer = TranscriptWriter(options.outputFileName, options.format, options.verbosity)
+
+
+    # treat items
+    nbItems  = parser.getNbItems()
+    progress = Progress(nbItems, "Analyzing sequences of %s" % (options.inputFileName), options.verbosity)
+    nbKept   = 0
+    nbRead   = 0
+    nbClKept = 0
+    nbClRead = 0
+    for item in parser.getIterator():
+        size      = item.getSize()
+        nb        = 1 if options.format in ("fasta", "fastq") or "nbElements" not in item.getTagNames() else float(item.getTagValue("nbElements"))
+        nbRead   += nb
+        nbClRead += 1
+        if (options.minSize == None or options.minSize <= size) and (options.maxSize == None or options.maxSize >= size):
+            writer.addElement(item)
+            nbKept   += nb
+            nbClKept += 1
+        progress.inc()
+    progress.done()
+    
+    writer.write()
+
+    print "%d items,    %d kept (%.2f%%)" % (nbRead, nbKept, 0 if nbItems == 0 else float(nbKept) / nbItems * 100)
+    if nbKept != nbClKept or nbRead != nbClRead:
+        print "%d clusters, %d kept (%.2f%%)" % (nbClRead, nbClKept, 0 if nbClRead == 0 else float(nbClKept) / nbClRead * 100)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/restrictSequenceList.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,113 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Restrict a sequence list with some names"""
+
+from optparse import OptionParser
+from commons.core.parsing.ParserChooser import ParserChooser
+from commons.core.writer.WriterChooser import WriterChooser
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc import Utils
+
+class RestrictSequenceList(object):
+
+    def __init__(self, verbosity):
+        self.verbosity = verbosity
+        self.exclude   = False
+
+    def setInputFileName(self, fileName, format):
+        chooser = ParserChooser(self.verbosity)
+        chooser.findFormat(format)
+        self.parser = chooser.getParser(fileName)
+
+    def setExclusion(self, boolean):
+        self.exclude = boolean
+
+    def setOutputFileName(self, fileName, format):
+        chooser = WriterChooser(self.verbosity)
+        chooser.findFormat(format)
+        self.writer = chooser.getWriter(fileName)
+
+    def setNamesFileName(self, fileName):
+        self.namesFileName = fileName
+
+    def _readNames(self):
+        self.names = []
+        handle = open(self.namesFileName)
+        for name in handle:
+            self.names.append(name.strip())
+        handle.close()
+
+    def _write(self):
+        nbElements = self.parser.getNbItems()
+        progress   = Progress(nbElements, "Parsing input file", self.verbosity)
+        nbRead     = 0
+        nbWritten  = 0
+        for element in self.parser.getIterator():
+            name    = element.getName()
+            nbRead += 1
+            if Utils.xor(name in self.names, self.exclude):
+                self.writer.addElement(element)
+                nbWritten += 1
+            if name in self.names:
+                self.names.remove(name)
+            progress.inc()
+        progress.done()
+        if self.verbosity > 0:
+            print "%d read" % (nbRead)
+            print "%d written (%d%%)" % (nbWritten, 0 if nbRead == 0 else round(float(nbWritten) / nbRead * 100))
+    
+    def run(self):
+        self._readNames()
+        self._write()
+        if self.names:
+            print "Some names are not present in the file: %s" % ", ".join(self.names)
+        
+
+
+if __name__ == "__main__":
+    
+    description = "Restrict Sequence List v1.0.1: Keep the elements of a list of sequences whose name is mentionned in a given file. [Category: Data Selection]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFile",  action="store",                       type="string", help="input file [compulsory] [format: file in sequence format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",     action="store",      default="fasta", type="string", help="format of the input and output files [compulsory] [format: sequence file format] [default: fasta]")
+    parser.add_option("-n", "--name",      dest="names",      action="store",                       type="string", help="names of the transcripts [compulsory] [format: file in TXT format]")
+    parser.add_option("-o", "--output",    dest="outputFile", action="store",                       type="string", help="output file [format: output file in sequence format given by -f]")
+    parser.add_option("-x", "--exclude",   dest="exclude",    action="store_true", default=False,                  help="output all those whose name is NOT on the list [format: boolean]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",  action="store",      default=1,       type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    rsl = RestrictSequenceList(options.verbosity)
+    rsl.setInputFileName(options.inputFile, options.format)
+    rsl.setOutputFileName(options.outputFile, options.format)
+    rsl.setNamesFileName(options.names)
+    rsl.setExclusion(options.exclude)
+    rsl.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/restrictTranscriptList.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,85 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Restrict a transcript list with some parameters (regions)"""
+
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from commons.core.writer.TranscriptWriter import TranscriptWriter
+from SMART.Java.Python.misc.Progress import Progress
+
+STRAND2DIRECTION = {"+": 1, "-": -1, None: None}
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Restrict Transcript List v1.0.2: Keep the coordinates which are located in a given position. [Category: Data Selection]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",      dest="inputFileName",  action="store",                             type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",     dest="format",         action="store",                             type="string", help="format [compulsory] [format: transcript file format]")
+    parser.add_option("-c", "--chromosome", dest="chromosome",     action="store",            default=None,    type="string", help="chromosome [format: string]")
+    parser.add_option("-s", "--start",      dest="start",          action="store",            default=None,    type="int",    help="start [format: int]")
+    parser.add_option("-e", "--end",        dest="end",            action="store",            default=None,    type="int",    help="end [format: int]")
+    parser.add_option("-t", "--strand",     dest="strand",         action="store",            default=None,    type="string", help="strand (+ or -) [format: string]")
+    parser.add_option("-o", "--output",     dest="outputFileName", action="store",                             type="string", help="output file [format: output file in GFF3 format]")
+    parser.add_option("-v", "--verbosity",  dest="verbosity",      action="store",            default=1,       type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    parser = TranscriptContainer(options.inputFileName, options.format, options.verbosity)
+    writer = TranscriptWriter(options.outputFileName, options.format, options.verbosity)
+
+    direction = STRAND2DIRECTION[options.strand]
+        
+    nbTranscripts = parser.getNbTranscripts()
+    progress      = Progress(nbTranscripts, "Parsing file %s" % (options.inputFileName), options.verbosity)
+    
+    nbTotal = 0
+    nbKept    = 0
+    for transcript in parser.getIterator():
+        progress.inc()
+        nbTotal += 1
+        if options.chromosome != None and options.chromosome != transcript.getChromosome():
+            continue
+        if options.start != None and options.start > transcript.getEnd():
+            continue
+        if options.end != None and options.end < transcript.getStart():
+            continue
+        if options.end != None and options.end < transcript.getStart():
+            continue
+        if direction != None and direction != transcript.getDirection():
+            continue
+        nbKept += 1
+        writer.addTranscript(transcript)
+    progress.done()
+    
+    writer.write()
+        
+    print "%d out of %d are kept (%f%%)" % (nbKept, nbTotal, (float(nbKept) / nbTotal * 100))        
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/runRandomJobs.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,46 @@
+import unittest
+import os
+import time
+from optparse import OptionParser
+from SMART.Java.Python.ncList.test.MockFindOverlaps_randomExample import MockFindOverlaps_randomExample
+from SMART.Java.Python.FindOverlapsOptim import FindOverlapsOptim
+
+if __name__ == '__main__':
+    description = "runRandomJobs: create random ref/query files (with size given), and run the jobs on cluster with help of runJobs.sh"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--inputRef", dest="inputRefGff3FileName", action="store", type="string", help="Reference input file [compulsory] [format: file in gff3 format]")
+    parser.add_option("-j", "--inputQuery", dest="inputQueryGff3FileName", action="store", type="string", help="Query input file [compulsory] [format: file in gff3 format]")
+    parser.add_option("-m", "--inputRefSize", dest="numberOfRefReads", action="store", type="int", help="The number of Reference")
+    parser.add_option("-n", "--inputQuerySize", dest="numberOfQReads", action="store", type="int", help="The number of Query")
+    parser.add_option("-o", "--output", dest="outputGff3FileName", action="store", type="string", help="output file [compulsory] [format: output file in gff3 format]")
+    (options, args) = parser.parse_args()
+    
+    outputDataName = 'timeResult.dat' 
+    fTime = open(outputDataName, 'w')  
+    fTime.write('NbRef\tNbQuery\tNbOverlap\ttime\n')   
+    chromSize = 100000
+    print 'ref size = %d,  query size = %d' %(options.numberOfRefReads, options.numberOfQReads)
+    iMFOR_ref = MockFindOverlaps_randomExample(options.inputRefGff3FileName, 'ref', options.numberOfRefReads, chromSize)
+    iMFOR_ref.write()
+    cmd_ref = 'sort -f -n -k4 -k5.4rn -o %s %s' % (options.inputRefGff3FileName, options.inputRefGff3FileName)
+    os.system(cmd_ref)
+    iMFOR_query = MockFindOverlaps_randomExample(options.inputQueryGff3FileName,'q', options.numberOfQReads, chromSize)
+    iMFOR_query.write()
+    cmd_query = 'sort -f -n -k4 -k5.4rn -o %s %s' % (options.inputQueryGff3FileName, options.inputQueryGff3FileName)
+    os.system(cmd_query)
+    iFOO = FindOverlaps_optim(options.inputRefGff3FileName, options.inputQueryGff3FileName)
+    iFOO.setOutputGff3FileName(options.outputGff3FileName)
+    
+    startTime_optim = time.time()
+    iFOO.run()
+    iFOO.close()  
+    nbOverlap = iFOO.getNbOverlap() 
+    endTime_optim = time.time()    
+    cmd = 'sort -f -n -k4 -k5.4rn -k9.5 -t ";" -o %s %s' % (options.outputGff3FileName, options.outputGff3FileName)
+    os.system(cmd)
+    totalTime_optim = endTime_optim - startTime_optim
+    print 'we take %s second.' % (totalTime_optim)
+    fTime.write('%d\t%d\t%d\t%.2f\n'%(options.numberOfRefReads, options.numberOfQReads, nbOverlap, totalTime_optim))
+    iFOO.deletIntermediateFiles()
+    fTime.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/selectByNbOccurrences.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,89 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Select the transcript that have not more that a given number of occurrences"""
+
+import os
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import *
+from commons.core.writer.Gff3Writer import *
+from SMART.Java.Python.misc.Progress import *
+from SMART.Java.Python.misc.RPlotter import *
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Select by # of Occurrences v1.0.1: Keep the reads which have mapped less than a given number of times. [Category: Personnal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",             dest="inputFileName",    action="store",                                                type="string", help="input file [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",            dest="format",                 action="store",                                                type="string", help="format of the input [compulsory] [format: transcript file format]")
+    parser.add_option("-n", "--occurrences", dest="occurrences",        action="store",            default=1,                type="int",        help="maximum number of occurrences allowed [format: int] [default: 1]")     
+    parser.add_option("-o", "--output",            dest="outputFileName", action="store",                                                type="string", help="output file [format: output file in GFF3 format]")
+    parser.add_option("-y", "--mysql",             dest="mysql",                    action="store_true", default=False,                                     help="mySQL output [format: bool] [default: false]")
+    parser.add_option("-v", "--verbosity",     dest="verbosity",            action="store",            default=1,                type="int",        help="trace level [format: int] [default: 1]")
+    parser.add_option("-l", "--log",                 dest="log",                        action="store_true", default=False,                                     help="write a log file [format: bool] [default: false]")
+    (options, args) = parser.parse_args()
+
+    parser = TranscriptContainer(options.inputFileName, options.format, options.verbosity)
+
+    # get occurrences of the transcripts
+    names        = dict()
+    progress = Progress(parser.getNbTranscripts(), "Reading names of %s" % (options.inputFileName), options.verbosity)
+    for transcript in parser.getIterator():
+        name = transcript.name
+        if name not in names:
+            names[name] = 1
+        else:
+            names[name] += 1
+        progress.inc()
+    progress.done()
+
+    # write output file
+    nbWritten = 0
+    writer        = Gff3Writer(options.outputFileName, options.verbosity)
+    if options.mysql:
+        mysqlWriter = MySqlTranscriptWriter(options.outputFileName, options.verbosity)
+    progress    = Progress(parser.getNbTranscripts(), "Writing transcripts", options.verbosity)
+    for transcript in parser.getIterator():
+        name = transcript.name
+        if names[name] <= options.occurrences:
+            nbWritten += 1
+            writer.addTranscript(transcript)
+            if options.mysql:
+                mysqlWriter.addTranscript(transcript)
+        progress.inc()
+    progress.done()
+                                                     
+    if options.mysql:
+        mysqlWriter.write()
+    print "%d input" % (parser.getNbTranscripts())
+    print "%d output (%.2f%%)" % (nbWritten, float(nbWritten) / parser.getNbTranscripts() * 100)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/sequenceListSplitter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,73 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Split a FASTA file into several shorter ones"""
+
+from optparse import OptionParser
+from commons.core.parsing.SequenceListParser import *
+from commons.core.writer.FastaWriter import *
+from SMART.Java.Python.misc.Progress import *
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Sequence List Splitter v1.0.1: Split a list of big sequences into small chunks. [Category: Personnal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",   action="store",                         type="string", help="input file [compulsory] [format: file in FASTA format]")
+    parser.add_option("-o", "--output",    dest="outputFileNames", action="store",                         type="string", help="output files [compulsory] [format: output file in FASTA format]")
+    parser.add_option("-n", "--number",    dest="number",          action="store",      default=10,        type="int",    help="number of splits [compulsory] [format: int] [default: 10]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",       action="store",      default=1,         type="int",    help="trace level [format: int]")
+    parser.add_option("-l", "--log",       dest="log",             action="store_true", default=False,                    help="write a log file [format: bool] [default: false]")
+    (options, args) = parser.parse_args()
+
+    if options.log:
+        logHandle = open(options.outputFileNames + ".log", "w")
+
+    # split file
+    sequenceListParser = SequenceListParser(options.inputFileName, options.verbosity)
+    nbSequences                = sequenceListParser.getNbSequences()
+    nbSequencesByFile    = math.ceil(nbSequences / options.number)
+
+    # write into files
+    currentFileNumber = 1
+    writer            = FastaWriter("%s%i.fasta" % (options.outputFileNames, currentFileNumber), options.verbosity)
+    nbSequencesHere   = 0
+    progress          = Progress(nbSequences, "Writing files", options.verbosity)
+    for sequence in sequenceListParser.getIterator():
+        writer.addSequence(sequence)
+        nbSequencesHere += 1
+        if nbSequencesHere == nbSequencesByFile:
+            currentFileNumber += 1
+            writer             = FastaWriter("%s%i.fasta" % (options.outputFileNames, currentFileNumber), options.verbosity)
+            nbSequencesHere    = 0
+        progress.inc()
+    progress.done()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/splitByTag.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,68 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Read a file and split it into several, depending on a tag"""
+
+import os
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import *
+from commons.core.writer.Gff3Writer import *
+from SMART.Java.Python.misc.Progress import *
+from SMART.Java.Python.misc import Utils
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Split By Tag v1.0.1: Read a file and split it into several, depending on a tag. [Category: Personnal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",                     dest="inputFileName",         action="store",                                        type="string", help="input file 1 [compulsory] [format: file in transcript format given by -f]")
+    parser.add_option("-f", "--format",                    dest="format",                        action="store",                                        type="string", help="format of file 1 [compulsory] [format: transcript file format]")
+    parser.add_option("-t", "--tag",                         dest="tag",                             action="store",                                        type="string", help="tag on which the split is made [compulsory] [format: string]")
+    parser.add_option("-o", "--output",                    dest="outputFileName",        action="store",                                        type="string", help="output file [format: output file in CSV format]")
+    parser.add_option("-v", "--verbosity",             dest="verbosity",                 action="store",            default=1,        type="int",        help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    transcriptContainer = TranscriptContainer(options.inputFileName, options.format, options.verbosity)
+    writers                         = dict()
+
+    progress = Progress(transcriptContainer.getNbTranscripts(), "Reading file %s" % (options.inputFileName), options.verbosity)
+    for transcript in transcriptContainer.getIterator():
+        value = transcript.getTagValue(options.tag)
+        if value == None:
+            value = "noTag"
+        value = str(value).replace(" ", "_").title()
+        if value not in writers:
+            writers[value] = Gff3Writer("%s.gff3" % (os.path.join(options.outputFileName, value)))
+        writers[value].addTranscript(transcript)
+
+        progress.inc()
+    progress.done()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/splitMultiFasta.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,64 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Split a Multi-Fasta file to several Fasta files"""
+
+import os
+from optparse import OptionParser
+from SMART.Java.Python.structure.TranscriptContainer import *
+from commons.core.writer.Gff3Writer import *
+from SMART.Java.Python.misc.Progress import *
+from SMART.Java.Python.misc import Utils
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Split Multi-Fasta v1.0.1: Split a Multi-Fasta file to several Fasta files. [Category: Personnal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",                     dest="inputFileName",         action="store",                                        type="string", help="input file 1 [compulsory] [format: file in FASTA format]")
+    parser.add_option("-o", "--output",                    dest="outputFileName",        action="store",                                        type="string", help="output file [format: output file in FASTA format]")
+    (options, args) = parser.parse_args()
+
+    inputHandle    = open(options.inputFileName)
+    outputHandle = None
+    
+    for line in inputHandle:
+        line = line.strip()
+        if line[0] == ">":
+            if outputHandle != None:
+                outputHandle.close()
+            name = line[1:].split(" ")[0]
+            outputHandle = open("%s%s.fasta" % (options.outputFileName, name), "w")
+        outputHandle.write("%s\n" % (line))
+            
+    inputHandle.close()
+    outputHandle.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/Bins.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,77 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Some functions about bins
+"""
+
+def getMinBin():
+    return 3
+
+
+def getMaxBin():
+    return 7
+
+
+def getBin(start, end):
+    for i in range(getMinBin(), getMaxBin() + 1):
+        binLevel = 10 ** i
+        if int(start / binLevel) == int(end / binLevel):
+            return int(i * 10 ** (getMaxBin() + 1) + int(start / binLevel))
+    return int((getMaxBin() + 1) * 10 ** (getMaxBin() + 1))
+
+
+def getOverlappingBins(start, end):
+    array  = []
+    bigBin = int((getMaxBin() + 1) * 10 ** (getMaxBin() + 1))
+    for i in range(getMinBin(), getMaxBin() + 1):
+        binLevel = 10 ** i
+        array.append((int(i * 10 ** (getMaxBin() + 1) + int(start / binLevel)), int(i * 10 ** (getMaxBin() + 1) + int(end / binLevel))))
+    array.append((bigBin, bigBin))
+    return array
+
+
+def getIterator(maxValue = None):
+    if maxValue == None:
+        maxValue = 10 ** (getMaxBin() + getMinBin()) - 1
+    for i in range(getMinBin(), getMaxBin() + 1):
+        binLevel = 10 ** i
+        binBit   = i * 10 ** (getMaxBin() + 1)
+        for j in range(0, maxValue / binLevel+1):
+            yield binBit + j
+    yield int((getMaxBin() + 1) * 10 ** (getMaxBin() + 1))
+
+
+def getNbBins(maxValue = None):
+    if maxValue == None:
+        maxValue = 10 ** (getMaxBin() + getMinBin()) - 1
+    nbBins = 0
+    for i in range(getMinBin(), getMaxBin() + 1):
+        nbBins += maxValue / 10 ** i
+    return nbBins + 1
Binary file smart_toolShed/SMART/Java/Python/structure/Bins.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/Interval.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,707 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+from SMART.Java.Python.structure.Bins import *
+from commons.core.coord.Range import Range
+
+class Interval(Range):
+    """
+    Store a genomic interval
+    @ivar name:          name of the interval [optional]
+    @type name:          string
+    @ivar id:            id of the interval [optional]
+    @type id:            int
+    @ivar bin:           bin in which the interval should be if stored in a database [computed]
+    @type bin:           int 
+    @ival tags:          information about the transcript [optional]
+    @type tags:          dict
+    @ivar verbosity:     verbosity
+    @type verbosity:     int [default: 0]
+    """
+
+    def __init__(self, interval = None, verbosity = 0):
+        """
+        Constructor
+        @param interval:    interval to be copied
+        @type    interval:    class L{Interval<Interval>}
+        @param verbosity: verbosity
+        @type    verbosity: int
+        """
+        Range.__init__(self)
+        self.name          = None
+        self.id            = None
+        self.bin           = None
+        self.verbosity     = verbosity
+        self.tags          = {}
+        if interval != None:
+            self.copy(interval)
+
+    #!!!! Warning: two methods getStart() and getEnd() give the information maximum and minimum in interval.!!!!#
+    #In case strand = "+", start < end; strand = "-", start > end        
+    def getStart(self):
+        if self.start == -1:
+            return -1
+        if self.end == -1:
+            return self.start
+        return self.getMin()
+
+    
+    def getEnd(self):
+        if self.end == -1:
+            return -1
+        if self.start == -1:
+            return self.end
+        return self.getMax()
+
+
+    def getChromosome(self):
+        return self.getSeqname()
+
+
+    def getDirection(self):
+        return 1 if self.getStrand() == "+" else -1
+
+
+    def getName(self):
+        return self.name
+
+
+    def isSet(self):
+        """
+        Check if the interval is set
+        """
+        return self.getStart() == None and self.getEnd() == None
+
+
+    def copy(self, interval):
+        """
+        Copy method
+        @param interval: interval to be copied
+        @type    interval: class L{Interval<Interval>}
+        """
+        self.setStart(interval.getStart())
+        self.setEnd(interval.getEnd())
+        self.setChromosome(interval.getChromosome())
+        self.setDirection(interval.getDirection())
+        self.name      = interval.name     
+        self.id        = interval.id
+        self.bin       = interval.bin
+        self.tags      = {}
+        for tag in interval.tags:
+            self.tags[tag] = interval.tags[tag]
+        self.verbosity     = interval.verbosity
+
+
+    def setName(self, name):
+        """
+        Set the name
+        @param name: name of the interval
+        @type    name: string
+        """
+        if len(name) > 100:
+            name = name[:100]
+        self.name = name
+
+
+    def setChromosome(self, chromosome=""):
+        """
+        Set the chromosome
+        @param chromosome: chromosome on which the interval is
+        @type    chromosome: string
+        """
+        if not chromosome:
+            self.seqname = None
+        else:
+            self.seqname = chromosome.replace(".", "_").replace("|", "_")
+
+
+    def setStart(self, start):
+        """
+        Set the start point
+        Possibly reset bin
+        @param start: start point of the interval
+        @type    start: int
+        """
+        self.bin  = None
+        direction = self.getDirection()
+        if self.start == -1:
+            self.start = start
+        elif self.end == -1:
+            self.end = start
+        else:
+            if direction == 1:
+                self.start = start
+            else:
+                self.end = start
+        if direction == 1:
+            self.start, self.end = min(self.start, self.end), max(self.start, self.end)
+        else:
+            self.start, self.end = max(self.start, self.end), min(self.start, self.end)
+
+
+    def setEnd(self, end):
+        """
+        Set the end point
+        Possibly reset bin
+        @param end: end point of the interval of the interval
+        @type    end: int
+        """
+        self.bin  = None
+        direction = self.getDirection()
+        if self.end == -1:
+            self.end = end
+        elif self.start == -1:
+            self.start = end
+        else:
+            if direction == 1:
+                self.end = end
+            else:
+                self.start = end
+        if direction == 1:
+            self.start, self.end = min(self.start, self.end), max(self.start, self.end)
+        else:
+            self.start, self.end = max(self.start, self.end), min(self.start, self.end)
+
+
+    def setSize(self, size):
+        """
+        Possibly modify the end point
+        @param size: size of the transcript
+        @type    size: int
+        """
+        if self.end == None and self.start != None:
+            self.setEnd(self.start + self.getSize() - 1)
+        elif self.start == None and self.end != None:
+            self.setStart(self.end - self.getSize() + 1)
+
+
+    def getSize(self):
+        """
+        Get the size
+        """
+        return self.getEnd() - self.getStart() + 1
+
+
+    def _setDirection(self, direction):
+        """
+        Set the direction of the interval (connection to Range)
+        @param direction: direction of the transcript (+ / -)
+        @type  direction: int (1 or -1)
+        """
+        if direction * self.getDirection() < 0:
+            self.reverse()
+
+
+    def setDirection(self, direction):
+        """
+        Set the direction of the interval
+        Possibly parse different formats
+        @param direction: direction of the transcript (+ / -)
+        @type    direction: int or string
+        """
+        if type(direction).__name__ == 'int':
+            self._setDirection(direction / abs(direction))
+        elif type(direction).__name__ == 'str':
+            if direction == "+":
+                self._setDirection(1)
+            elif direction == "-":
+                self._setDirection(-1)
+            elif direction == "1" or direction == "-1":
+                self._setDirection(int(direction))
+            elif direction.lower() == "plus":
+                self._setDirection(1)
+            elif direction.lower() == "minus":
+                self._setDirection(-1)
+            else:
+                raise Exception("Cannot understand direction %s" % (direction))
+        else:
+            raise Exception("Cannot understand direction %s" % (direction))
+
+
+    def extendStart(self, size):
+        """
+        Extend the interval by the 5' end
+        @param size: the size to be exended
+        @type    size: int
+        """
+        if self.getDirection() == 1:
+            self.setStart(max(0, self.getStart() - size))
+        else:
+            self.setEnd(self.getEnd() + size)
+        self.bin  = None
+        
+        
+    def extendEnd(self, size):
+        """
+        Extend the interval by the 3' end
+        @param size: the size to be exended
+        @type    size: int
+        """
+        if self.getDirection() == 1:
+            self.setEnd(self.getEnd() + size)
+        else:
+            self.setStart(max(0, self.getStart() - size))
+        self.bin  = None
+        
+        
+    def restrictStart(self, size = 1):
+        """
+        Restrict the interval by some nucleotides, start from its start position
+        Remove the exons
+        @param size: the size to be restricted to
+        @type    size: int
+        """
+        if self.getDirection() == 1:
+            self.setEnd(min(self.getEnd(), self.getStart() + size - 1))
+        else:
+            self.setStart(max(self.getStart(), self.getEnd() - size + 1))
+        self.bin  = None
+        
+        
+    def restrictEnd(self, size = 1):
+        """
+        Restrict the interval by some nucleotides, end from its end position
+        Remove the exons
+        @param size: the size to be restricted to
+        @type    size: int
+        """
+        if self.getDirection() == 1:
+            self.setStart(max(self.getStart(), self.getEnd() - size + 1))
+        else:
+            self.setEnd(min(self.getEnd(), self.getStart() + size - 1))
+        self.bin  = None
+
+            
+    
+    def setTagValue(self, name, value):
+        """
+        Set a tag
+        @param name:    name of the tag
+        @type    name:    string
+        @param value: value of the tag
+        @type    value: int or string
+        """
+        self.tags[name] = value
+    
+    
+    def getTagNames(self):
+        """
+        Get all the names of the tags
+        """
+        return self.tags.keys()
+
+
+    def getTagValue(self, tag):
+        """
+        Get the value of a tag
+        @param tag: name of a tag
+        @type    tag: string
+        """
+        if tag not in self.tags:
+            return None
+        return self.tags[tag]
+
+
+    def getTagValues(self, tagSep = "; ", fieldSep = " ", surrounder = ""):
+        """
+        Get the formatted tag values
+        @param tagSep:     separator between tags
+        @type  tagSep:     string
+        @param fieldSep:   separator between tag name and tag value
+        @type  fieldSep:   string
+        @param surrounder: string which optionally surround values
+        @type  surrounder: string
+        """
+        tags = []
+        for name in self.tags:
+            value = self.tags[name]
+            if value == None:
+                continue
+            if isinstance(value, basestring):
+                tags.append("%s%s%s%s%s" % (name, fieldSep, surrounder, self.tags[name], surrounder))
+            elif type(value) is int:
+                tags.append("%s%s%s%i%s" % (name, fieldSep, surrounder, self.tags[name], surrounder))
+            elif type(value) is float:
+                tags.append("%s%s%s%f%s" % (name, fieldSep, surrounder, self.tags[name], surrounder))
+            else:
+                raise Exception("Do not know how to print '" + value + "'.")
+        if self.getName() != None:
+            tags.append("%s%s%s%s%s" % ("Name", fieldSep, surrounder, self.getName(), surrounder))
+        return tagSep.join(tags)
+
+    
+    def setTagValues(self, tags, tagSep = "; ", fieldSep = " "):
+        """
+        Set the tag values using given string
+        @param tags:     the tags, concatenated
+        @type  tags:     string
+        @param tagSep:   separator between tags
+        @type  tagSep:   string
+        @param fieldSep: separator between tag name and tag value
+        @type  fieldSep: string
+        """
+        if tags == "":
+            self.tags = {}
+            return
+        for splittedTag in tags.split(tagSep):
+            if fieldSep not in splittedTag:
+                raise Exception("Weird field '%s' in tags '%s'" % (splittedTag, tags))
+            tag, value = splittedTag.split(fieldSep, 1)
+            if tag == "Name":
+                self.setName(value)
+                continue
+            try:
+                intValue       = int(value)
+                self.tags[tag] = intValue
+            except ValueError:
+                try:
+                    floatValue     = float(value)
+                    self.tags[tag] = floatValue
+                except ValueError:
+                    self.tags[tag] = value
+
+
+    def deleteTag(self, tag):
+        """
+        Remove a tag
+        @param tag: the tag to be removed
+        @type    tag: string
+        """
+        if tag in self.tags:
+            del self.tags[tag]
+
+    
+    def setNbOccurrences(self, nbOccurrences):
+        """
+        Set the number of occurrences of the interval
+        @param nbOccurrences: number of occurrences of the interval
+        @type    nbOccurrences: int
+        """
+        self.setTagValue("nbOccurrences", nbOccurrences)
+    
+        
+    def setOccurrence(self, occurrence):
+        """
+        Set the occurrence of this interval
+        @param occurrence: an occurrence for this transcript
+        @type    occurrence: int
+        """
+        self.setTagValue("occurrence", occurrence)
+    
+    def __eq__(self, interval):
+        """
+        Whether two intervals are equal (start and end at same position)
+        @param interval: object to be compared to
+        @type    interval: class L{Interval<Interval>}
+        """
+        if not interval:
+            return False
+        return self.getChromosome() == interval.getChromosome() and self.getStart() == interval.getStart() and self.getEnd() == interval.getEnd() and self.getDirection() == interval.getDirection()
+
+
+    def overlapWith(self, interval, nbNucleotides = 1):
+        """
+        Whether two intervals overlap
+        @param interval:        object to be compared to
+        @type    interval:        class L{Interval<Interval>}
+        @param nbNucleotides: minimum number of nucleotides to declare and overlap
+        @type    nbNucleotides: int
+        """    
+        if self.getChromosome() != interval.getChromosome():
+            return False
+        return (min(self.getEnd(), interval.getEnd()) - max(self.getStart(), interval.getStart()) + 1 >= nbNucleotides)
+
+    def isIncludeIn(self, interval):
+        return interval.include(self)
+
+
+    def include(self, interval):
+        """
+        Whether this interval includes the other one
+        @param interval:      object to be compared to
+        @type  interval:      class L{Interval<Interval>}
+        """    
+        if self.getChromosome() != interval.getChromosome():
+            return False
+        return ((self.getStart() <= interval.getStart()) and (self.getEnd() >= interval.getEnd()))
+    
+    
+    def getDifference(self, interval, sameStrand = False):
+        """
+        Get the difference between this cluster and another one
+        @param interval:   object to be compared to
+        @type  interval:   class L{Interval<Interval>}
+        @param sameStrand: do the comparison iff the intervals are on the same strand
+        @type  sameStrand: boolean
+        @return:           a (possibly empty) list of intervals
+        """    
+        newInterval = Interval()
+        newInterval.copy(self)
+        if self.getChromosome() != interval.getChromosome():
+            return [newInterval]
+        if not self.overlapWith(interval):
+            return [newInterval]
+        if sameStrand and self.getDirection() != interval.getDirection():
+            return [newInterval]
+        intervals = []
+        if self.getStart() < interval.getStart():
+            newInterval = Interval()
+            newInterval.copy(self)
+            newInterval.setEnd(min(self.getEnd(), interval.getStart() - 1))
+            intervals.append(newInterval)
+        if self.getEnd() > interval.getEnd():
+            newInterval = Interval()
+            newInterval.copy(self)
+            newInterval.setStart(max(self.getStart(), interval.getEnd() + 1))
+            intervals.append(newInterval)
+        return intervals
+    
+    
+    def getIntersection(self, interval):
+        """
+        Get the intersection between this interval and another one
+        @param interval: object to be compared to
+        @type  interval: class L{Interval<Interval>}
+        @return:         an other interval
+        """    
+        if not self.overlapWith(interval):
+            return None
+        newInterval = Interval()
+        newInterval.setChromosome(self.getChromosome())
+        newInterval.setDirection(self.getDirection())
+        newInterval.setName("%s_intersect_%s" % (self.getName(), interval.getName()))
+        newInterval.setStart(max(self.getStart(), interval.getStart()))
+        newInterval.setEnd(min(self.getEnd(), interval.getEnd()))
+        return newInterval
+    
+    
+    def getDistance(self, interval):
+        """
+        Get the distance between two intervals (a non-negative value)
+        @param interval: another interval
+        @type    interval: class L{Interval<Interval>}
+        """    
+        if self.overlapWith(interval):
+            return 0
+        if self.getChromosome() != interval.getChromosome():
+            raise Exception("Cannot get the distance between %s and %s" % (str(self), str(interval)))
+        return min(abs(self.getStart() - interval.getEnd()), abs(self.getEnd() - interval.getStart()))
+
+
+    def getRelativeDistance(self, interval):
+        """
+        Get the distance between two intervals (negative if first interval is before)
+        @param interval: another interval
+        @type    interval: class L{Interval<Interval>}
+        """    
+        if self.overlapWith(interval):
+            return 0
+        if self.getChromosome() != interval.getChromosome():
+            raise Exception("Cannot get the distance between %s and %s" % (str(self), str(interval)))
+        if self.getEnd() < interval.getStart():
+            distance = interval.getStart() - self.getEnd()
+        else:
+            distance = interval.getEnd() - self.getStart()
+        distance *= self.getDirection()
+        return distance
+
+
+    def merge(self, interval, normalization = False):
+        """
+        Merge two intervals
+        @param interval:        another interval
+        @type    interval:        class L{Interval<Interval>}
+        @param normalization: whether the sum of the merge should be normalized wrt the number of mappings of each elements
+        @type    normalization: boolean
+        """
+        if self.getChromosome() != interval.getChromosome():
+            raise Exception("Cannot merge '%s' and '%s' for they are on different chromosomes." % (str(self), str(interval)))
+        direction = None
+        if self.getStart() == self.getEnd():
+            direction = interval.getDirection()
+        elif interval.getStart() == interval.getEnd():
+            direction = self.getDirection()
+        elif self.getDirection() != interval.getDirection():
+            raise Exception("Cannot merge '%s' and '%s' for they are on different strands." % (str(self), str(interval)))
+        self.setStart(min(self.getStart(), interval.getStart()))
+        self.setEnd(max(self.getEnd(), interval.getEnd()))
+        if direction != None:
+            self.setDirection(direction)
+        nbElements = 0.0
+        for element in (self, interval):
+            for tagName in ("nbElements", "nbOccurrences"):
+                if tagName not in element.getTagNames():
+                    element.setTagValue(tagName, 1)
+            nbElements += float(element.getTagValue("nbElements")) / float(element.getTagValue("nbOccurrences")) if normalization else float(element.getTagValue("nbElements"))
+        self.setTagValue("nbElements", nbElements)
+        self.bin = None
+        for tagName in ("identity", "nbOccurrences", "occurrence", "nbMismatches", "nbGaps", "rank", "evalue", "bestRegion"):
+            if tagName in self.getTagNames():
+                del self.tags[tagName]
+
+
+    def getBin(self):
+        """
+        Get the bin of the interval
+        Computed on the fly
+        """
+        if self.bin == None:
+            self.bin = getBin(self.getStart(), self.getEnd())
+        return self.bin
+
+
+    def getBins(self):
+        """
+        Get all the bin this interval could fall into
+        """
+        return getOverlappingBins(self.getStart(), self.getEnd())
+
+
+    def getSqlVariables(cls):
+        """
+        Get the properties of the object that should be saved in a database
+        """
+        variables = ["name", "chromosome", "start", "end", "direction", "tags", "bin"]
+        return variables
+    getSqlVariables = classmethod(getSqlVariables)
+
+
+    def setSqlValues(self, array):
+        """
+        Set the values of the properties of this object as given by a results line of a SQL query
+        """
+        self.id         = array[0]
+        self.name       = array[1].strip("'")
+        self.setChromosome(array[2].strip("'"))
+        self.setStart(array[3])
+        self.setEnd(array[4])
+        self.setDirection(array[5])
+        self.setTagValues(array[6].strip("'"), ";", "=")
+        self.bin        = array[7]
+
+
+    def getSqlValues(self):
+        """
+        Get the values of the properties that should be saved in a database
+        """
+        values = dict()
+        values["name"]       = self.name
+        values["chromosome"] = self.getChromosome()
+        values["start"]      = self.getStart()
+        values["end"]        = self.getEnd()
+        values["direction"]  = self.getDirection()
+        values["tags"]       = self.getTagValues(";", "=")
+        values["bin"]        = self.getBin()
+        return values
+
+
+    def getSqlTypes(cls):
+        """
+        Get the values of the properties that should be saved in a database
+        """
+        types = dict()
+        types["name"]       = "varchar"
+        types["chromosome"] = "varchar"
+        types["start"]      = "int"
+        types["end"]        = "int"
+        types["direction"]  = "tinyint"
+        types["tags"]       = "varchar"
+        types["bin"]        = "int"
+        return types
+    getSqlTypes = classmethod(getSqlTypes)
+    
+
+    def getSqlSizes(cls):
+        """
+        Get the sizes of the properties that should be saved in a database
+        """
+        sizes = dict()
+        sizes["name"]       = 255
+        sizes["chromosome"] = 255
+        sizes["start"]      = 11
+        sizes["end"]        = 11
+        sizes["direction"]  = 4
+        sizes["tags"]       = 1023
+        sizes["bin"]        = 11
+        return sizes
+    getSqlSizes = classmethod(getSqlSizes)
+    
+
+    def printCoordinates(self):
+        """
+        Print start and end positions (depending on the direction of the interval)
+        """
+        if self.getDirection() == 1:
+            return "%d-%d" % (self.getStart(), self.getEnd())
+        else:
+            return "%d-%d" % (self.getEnd(), self.getStart())
+
+    
+    def extractSequence(self, parser):
+        """
+        Get the sequence corresponding to this interval
+        @param parser: a parser to a FASTA file
+        @type    parser: class L{SequenceListParser<SequenceListParser>}
+        @return        : a instance of L{Sequence<Sequence>}
+        """
+        return parser.getSubSequence(self.getChromosome(), self.getStart(), self.getEnd(), self.getDirection(), self.name)
+    
+    
+    def extractWigData(self, parser):
+        """
+        Get the data retrieved from a wig file
+        @param parser: a parser class to a WIG file
+        @type    parser: class L{WigParser<WigParser>}
+        """
+        data = parser.getRange(self.getChromosome(), self.getStart(), self.getEnd())
+        if self.getDirection() == -1:
+            if parser.strands:
+                newData = {}
+                for strand in data:
+                    data[strand].reverse()
+                    newData[-strand] = data[strand]
+                data = newData
+            else:
+                data.reverse()
+        return data
+
+
+    def __str__(self):
+        """
+        Output a simple representation of this interval
+        """
+        direction = "+"
+        if self.getDirection() == -1:
+            direction = "-"
+        string = "%s:%d-%d (%s)" % (self.getChromosome(), self.getStart(), self.getEnd(), direction)
+        if self.name != "":
+            string = "(%s) %s" % (self.name, string)
+        return string
+
Binary file smart_toolShed/SMART/Java/Python/structure/Interval.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/Mapping.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,255 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from SMART.Java.Python.structure.SubMapping import SubMapping
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Interval import Interval
+
+class Mapping(object):
+    """A class that represents a mapping"""
+
+    def __init__(self):
+        self.targetInterval = None
+        self.queryInterval  = None
+        self.subMappings    = []
+        self.size           = None
+        self.transcript     = None
+        self.tags           = {}
+
+
+    def copy(self, mapping):
+        for subMapping in mapping.subMappings:
+            newSubMapping = SubMapping(subMapping)
+            self.addSubMapping(newSubMapping)
+        self.targetInterval = Interval(mapping.targetInterval)
+        self.queryInterval  = Interval(mapping.queryInterval)
+        self.size           = mapping.size
+        self.tags           = {}
+        for tag in mapping.tags:
+            self.tags[tag] = mapping[tag]
+        self.transcript.copy(mapping.transcript)
+
+
+    def setTargetInterval(self, interval):
+        self.targetInterval = Interval(interval)
+        if self.queryInterval != None:
+            self.setDirection(self.targetInterval.getDirection() * self.queryInterval.getDirection())
+
+
+    def setQueryInterval(self, interval):
+        self.queryInterval = Interval(interval)
+        if self.targetInterval != None:
+            self.setDirection(self.targetInterval.getDirection() * self.queryInterval.getDirection())
+
+
+    def getQueryInterval(self):
+        return self.queryInterval
+
+
+    def addSubMapping(self, subMapping):
+        subMappingCopy = SubMapping(subMapping)
+        self.subMappings.append(subMappingCopy)
+
+        if self.targetInterval:
+            self.targetInterval.setStart(min(self.targetInterval.getStart(), subMapping.targetInterval.getStart()))
+            self.targetInterval.setEnd(max(self.targetInterval.getEnd(),     subMapping.targetInterval.getEnd()))
+        else:
+            self.setTargetInterval(subMapping.targetInterval)
+        if self.queryInterval:
+            self.queryInterval.setStart(min(self.queryInterval.getStart(), subMapping.queryInterval.getStart()))
+            self.queryInterval.setEnd(max(self.queryInterval.getEnd(),     subMapping.queryInterval.getEnd()))
+        else:
+            self.setQueryInterval(subMapping.queryInterval)
+
+        if self.getDirection() != 0:
+            subMapping.setDirection(self.getDirection())
+        if self.size == None:
+            self.size = 0
+        if "identity" in subMapping.getTagNames() and "identity" not in self.getTagNames():
+            self.setTagValue("identity", subMapping.getTagValue("identity"))
+        elif "identity" in subMapping.getTagNames() and subMapping.size != None:
+            self.setTagValue("identity", (self.getTagValue("identity") * self.size + subMapping.getTagValue("identity") * subMapping.size) / (self.size + subMapping.size))
+        if subMapping.size != None:
+            self.size += subMapping.size
+        if "nbMismatches" in subMapping.getTagNames() and "nbMismatches" not in self.getTagNames():
+            self.setTagValue("nbMismatches", subMapping.getTagValue("nbMismatches"))
+        elif "nbMismatches" in subMapping.getTagNames():
+            self.setTagValue("nbMismatches", self.getTagValue("nbMismatches") + subMapping.getTagValue("nbMismatches"))
+        if "nbGaps" in subMapping.getTagNames() and "nbGaps" not in self.getTagNames():
+            self.setTagValue("nbGaps", subMapping.getTagValue("nbGaps"))
+        elif "nbGaps" in subMapping.getTagNames():
+            self.setTagValue("nbGaps", self.getTagValue("nbGaps") + subMapping.getTagValue("nbGaps"))
+
+
+    def setDirection(self, direction):
+        for subMapping in self.subMappings:
+            subMapping.setDirection(direction)
+
+
+    def getDirection(self):
+        if not self.subMappings:
+            raise Exception("Error! Mapping '%s' has no submapping" % (self))
+        return self.subMappings[0].getDirection()
+
+
+    def setSize(self, size):
+        self.size = size
+        if "identity" in self.getTagNames():
+            self.setTagValue("nbMismatches", self.size - round(self.size * self.getTagValue("identity") / 100.0))
+
+
+    def setTagValue(self, name, value):
+        self.tags[name] = value
+        self.transcript = None
+
+
+    def getTagValue(self, name):
+        return self.tags[name]
+
+    
+    def getTagNames(self):
+        return self.tags.keys()
+
+
+    def setIdentity(self, identity):
+        self.setTagValue("identity", identity)
+        if self.size != None and "nbMismatches" not in self.getTagNames():
+            nbMismatches = 0 if self.size == 0 else self.size - round(self.size * self.getTagValue("identity") / 100.0)
+            self.setTagValue("nbMismatches", nbMismatches)
+
+
+    def setNbOccurrences(self, nbOccurrences):
+        self.setTagValue("nbOccurrences", nbOccurrences)
+
+
+    def setNbMismatches(self, nbMismatches):
+        self.setTagValue("nbMismatches", nbMismatches)
+        if self.size != None and "identity" not in self.getTagNames():
+            identity = 100 if self.size == 0 else (self.size - self.getTagValue("nbMismatches")) / float(self.size) * 100
+            self.setTagValue("identity", identity)
+
+
+    def setNbGaps(self, nbGaps):
+        self.setTagValue("nbGaps", nbGaps)
+        
+        
+    def setRank(self, rank):
+        self.setTagValue("rank", rank)
+        
+
+    def setEvalue(self, evalue):
+        self.setTagValue("evalue", evalue)
+        
+
+    def setOccurrence(self, occurrence):
+        self.setTagValue("occurrence", occurrence)
+        
+        
+    def setBestRegion(self, bestRegion):
+        self.setTagValue("bestRegion", bestRegion)
+
+
+    def mergeExons(self, distance):
+        previousSubMapping = None
+        subMappings        = []
+        for subMapping in self.subMappings:
+            if previousSubMapping == None:
+                subMappings.append(subMapping)
+                previousSubMapping = subMapping
+            else:
+                targetDistance = subMapping.targetInterval.getDistance(previousSubMapping.targetInterval)
+                queryDistance  = subMapping.queryInterval.getDistance(previousSubMapping.queryInterval)
+                if targetDistance <= distance:
+                    self.setTagValue("nbGaps", self.getTagValue("nbGaps") + queryDistance)
+                    previousSubMapping.merge(subMapping)
+                else:
+                    subMappings.append(subMapping)
+                    previousSubMapping = subMapping
+        self.subMappings = subMappings
+        
+        
+    def getTranscript(self):
+        """
+        Extract a transcript from this mapping
+        @return: a transcript
+        """
+        if self.transcript != None:
+            return self.transcript
+        self.transcript = Transcript()
+        self.transcript.copy(self.targetInterval)
+        self.transcript.setDirection(self.getDirection())
+        self.transcript.setName(self.queryInterval.getName())
+        self.transcript.removeExons()
+        if len(self.subMappings) > 1:
+            for subMapping in self.subMappings:
+                self.transcript.addExon(subMapping.targetInterval)
+        cpt = 1
+        for exon in self.transcript.exons:
+            exon.setDirection(self.transcript.getDirection())
+            exon.setName("%s-exon%d" % (self.transcript.getName(), cpt))
+            exon.setChromosome(self.transcript.getChromosome())
+            cpt += 1
+        self.transcript.setDirection(self.getDirection())
+        self.transcript.sortExons()
+        for tag in self.tags:
+            if "bestRegion" not in self.getTagNames():
+                self.transcript.setTagValue("bestRegion", "(self)")
+            self.transcript.setTagValue(tag, self.getTagValue(tag))
+        return self.transcript
+    
+
+    def getChromosome(self):
+        if not self.subMappings:
+            raise Exception("Error! Mapping '%s' has no submapping" % (self))
+        return self.subMappings[0].targetInterval.getChromosome()
+
+
+    
+    def getErrorScore(self):
+        return self.getTagValue("nbGaps") * 3 + self.getTagValue("nbMismatches") + (len(self.subMappings) - 1) * 0.1
+            
+
+    def printGBrowseReference(self):
+        return self.getTranscript().printGBrowseReference()
+
+
+    def printGBrowseLine(self):
+        return self.getTranscript().printGBrowseLine()
+
+
+    def printGBrowse(self):
+        return self.getTranscript().printGBrowse()
+
+
+    def printBed(self):
+        return self.getTranscript().printBed()
+
+
+    def __str__(self):
+        return "%s     ----     %s" % (str(self.getTranscript()), ", ". join([str(submapping) for submapping in self.subMappings]))
Binary file smart_toolShed/SMART/Java/Python/structure/Mapping.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/Sequence.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,184 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+import re
+from commons.core.seq.Bioseq import Bioseq
+
+reverseComplementString = {
+    "A": "T",
+    "C": "G",
+    "G": "C",
+    "T": "A",
+    "U": "A",
+    "M": "K",
+    "R": "Y",
+    "W": "W",
+    "S": "S",
+    "Y": "R",
+    "K": "M",
+    "V": "B",
+    "H": "D",
+    "D": "H",
+    "B": "V",
+    "N": "N",
+    "a": "t",
+    "c": "g",
+    "g": "c",
+    "t": "a",
+    "u": "a",
+    "m": "k",
+    "r": "y",
+    "w": "w",
+    "s": "s",
+    "y": "r",
+    "k": "m",
+    "v": "b",
+    "h": "d",
+    "d": "h",
+    "b": "v",
+    "n": "n"
+}
+
+class Sequence(Bioseq):
+    """A class that codes for a sequence"""
+
+    def __init__(self, name = "", sequence = ""):
+        super(Sequence, self).__init__(name, sequence)
+        self.name            = self.header        
+        self.quality         = None
+        self.chunkedSequence = None
+        self.chunkedQuality  = None
+        self.integerQuality  = False
+
+    def setName(self, name=""):
+        super(Sequence, self).setHeader(name)
+            
+    def getName(self):
+        return self.getHeader()
+    
+    def setSequence(self, seq=""):
+        super(Sequence, self).setSequence(seq)
+
+    def setQuality(self, quality):
+        if quality == None:
+            self.quality = None
+            return
+        if " " in quality:
+            self.quality        = quality.split()
+            self.integerQuality = True
+        else:
+            self.quality = list(quality)
+        
+    def getQuality(self):
+        if self.quality == None:
+            return None
+        if self.integerQuality:
+            return " ".join(self.quality)
+        return "".join(self.quality)
+    
+    def getSize(self):
+        return len(self.getSequence())
+
+
+    def copy(self, sequence):
+        self.setName(sequence.getName())
+        self.setSequence(sequence.getSequence())
+        self.setQuality(sequence.getQuality())
+        self.chunkedSequence = None
+        self.chunkedQuality  = None
+
+
+    def chunkSequence(self):
+        self.chunkedSequence = []
+        for i in range (0, self.getSize() / 60 + 1):
+            self.chunkedSequence.append(self.getSequence()[i * 60 : min(self.getSize(), (i+1) * 60)])
+        if self.quality != None:
+            self.chunkedQuality = []
+            for i in range (0, self.getSize() / 60 + 1):
+                self.chunkedQuality.append(self.quality[i * 60 : min(self.getSize(), (i+1) * 60)])
+
+    def concatenate(self, seq):
+        sequence  = self.getSequence()
+        sequence += seq.getSequence()
+        self.setSequence(sequence)
+        if self.quality != None:
+            sep = " " if self.integerQuality else ""
+            self.setQuality(self.getQuality() + sep + seq.getQuality())
+        self.chunkedSequence = None
+        self.chunkedQuality  = None
+        
+
+    def printFasta(self):
+        if self.chunkedSequence == None:
+            self.chunkSequence()
+        return ">%s\n%s\n" % (self.getHeader(), "\n".join(self.chunkedSequence))
+
+
+    def printFastq(self):
+        if self.chunkedSequence == None:
+            self.chunkSequence()
+        return "@%s\n%s\n+%s\n%s\n" % (self.getHeader(), self.getSequence(), self.getHeader(), self.getQuality())
+
+
+    def reverseComplement(self):
+        seq = ""
+        self.chunkedSequence = None
+        self.chunkedQuality  = None
+        for i in range(0, self.getSize()):
+            char = self.getSequence()[i:i+1]
+            if char not in reverseComplementString:
+                sys.exit("Cannot understand character %s from string %s" % (char, self.getSequence()))
+            seq = "%s%s" % (reverseComplementString[char], seq)
+        self.setSequence(seq)
+        if self.quality != None:
+            self.quality = self.quality[::-1]
+        
+        
+    def containsAmbiguousNucleotides(self):
+        m = re.search("[^ACGTUacgtu]", self.getSequence())
+        if m != None:
+            return True
+        return False
+    
+    
+    def shrinkToFirstNucleotides(self, nbNucleotides):
+        self.chunkedSequence = None
+        self.chunkedQuality  = None
+        self.setSequence(self.getSequence()[0:nbNucleotides])
+        if self.quality != None:
+            self.quality = self.quality[0:nbNucleotides]
+    
+    
+    def shrinkToLastNucleotides(self, nbNucleotides):
+        self.chunkedSequence = None
+        self.chunkedQuality  = None
+        self.setSequence(self.getSequence()[-nbNucleotides:])
+        if self.quality != None:
+            self.quality = self.quality[-nbNucleotides:]
Binary file smart_toolShed/SMART/Java/Python/structure/Sequence.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/SequenceList.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,72 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import math
+
+class SequenceList(object):
+    """A class that codes for a list of sequences"""
+
+    def __init__(self, verbosity = 0):
+        self.sequences = []
+        self.verbosity = verbosity
+
+
+    def nbSequences(self):
+        return len(self.sequences)
+
+
+    def getSequence(self, index):
+        return self.sequences[index]
+        
+
+    def addSequence(self, sequence):
+        self.sequences.append(sequence)
+        
+
+    def split(self, number):
+        sequenceLists = []
+        size          = math.ceil(self.nbSequences() / number)
+
+        sequenceList = SequenceList()
+        for i in range(0, self.nbSequences()):
+            sequenceList.addSequence(self.getSequence(i))
+            if (sequenceList.nbSequences() == size):
+                sequenceLists.append(sequenceList)
+                sequenceList = SequenceList()
+        if (sequenceList.nbSequences() != 0):
+            sequenceLists.append(sequenceList)
+        return sequenceLists
+
+
+    def printFasta(self):
+        string = ""
+        for sequence in self.sequences:
+            string += sequence.printFasta()
+        return string
+
Binary file smart_toolShed/SMART/Java/Python/structure/SequenceList.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/SubMapping.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,258 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from SMART.Java.Python.structure.Interval import Interval
+from commons.core.coord.Align import Align
+
+class SubMapping(Align):
+    """
+    A class that represents a part of a mapping, more precisely, a pair (target interval, query interval) that match together
+    @ivar targetInterval: the target interval
+    @type targetInterval: class L{Interval<Interval>}
+    @ivar queryInterval:  the query interval
+    @type queryInterval:  class L{Interval<Interval>}
+    @ivar size:           size of this sub-mapping
+    @type size:           int
+    @ivar tags:           various information
+    @type tags:           dict
+    """
+
+    def __init__(self, subMapping = None):
+        """
+        Constructor
+        @param subMapping: a sub-mapping to be copied
+        @type  subMapping: class L{SubMapping<SubMapping>}
+        """
+        self.targetInterval = Interval()
+        self.queryInterval  = Interval()
+        Align.__init__(self, self.queryInterval, self.targetInterval)
+        self.size = None
+        self.tags = {}
+        if subMapping != None:
+            self.copy(subMapping)
+    
+    def __eq__(self, o):
+        if o == None:
+            return False
+        areAlignAttributesEquals = Align.__eq__(self, o)
+        return areAlignAttributesEquals and (self.targetInterval == o.targetInterval) and (self.queryInterval == o.queryInterval) and self.size == o.getSize() and self.tags == o.getTags()
+    
+    def getSuperAdress(self):
+        return hex(id(super(Align, self)))
+    
+#    def setRangesAlignToRangesInterval(self):
+#        self.range_query = super(Range, self.queryInterval)
+#        self.range_subject = super(Range, self.targetInterval)
+        
+    def copy(self, subMapping):
+        """
+        Copy method
+        @param subMapping: a sub-mapping to be copied
+        @type    subMapping: class L{SubMapping<SubMapping>}
+        """
+        self.setQueryName(subMapping.getQueryName())
+        self.setQueryStart(subMapping.getQueryStart())
+        self.setQueryEnd(subMapping.getQueryEnd())
+        self.setSubjectName(subMapping.getSubjectName())
+        self.setSubjectStart(subMapping.getSubjectStart())
+        self.setSubjectEnd(subMapping.getSubjectEnd())
+        self.e_value = subMapping.getEvalue()
+        self.score = subMapping.getScore()
+        self.identity = subMapping.getIdentity()
+        
+        self.targetInterval.copy(subMapping.targetInterval)
+        self.queryInterval.copy(subMapping.queryInterval)
+        self.size = subMapping.size
+        for tag in subMapping.tags:
+            self.tags[tag] = subMapping.tags[tag]
+
+
+    def setTargetInterval(self, interval):
+        """
+        Set target interval
+        @param targetInterval: the target interval of the sub-mapping
+        @type    targetInterval: class L{Interval<Interval>}
+        """
+        self.targetInterval.copy(interval)
+
+
+    def setQueryInterval(self, interval):
+        """
+        Set query interval
+        @param queryInterval: the query interval of the sub-mapping
+        @type    queryInterval: class L{Interval<Interval>}
+        """
+        self.queryInterval.copy(interval)
+
+
+    def setSize(self, size):
+        """
+        Set the size of the sub-mapping
+        Possibly also target and query interval sizes, as well as number of mismatches
+        @param size: the size of the sub-mapping
+        @type    size: int
+        """
+        self.size = size
+        if "identity" in self.getTagNames():
+            self.setTagValue("nbMismatches", self.size - round(self.size * self.getTagValue("identity") / 100.0))
+
+
+    def getDirection(self):
+        """
+        Get the direction of the alignment
+        """
+        return self.targetInterval.getDirection()
+
+
+    def setDirection(self, direction):
+        """
+        Set the direction of the alignment
+        @param direction: the directio of the alignment
+        type   direction: int or string
+        """
+        return self.targetInterval.setDirection(direction)
+
+
+    def setTagValue(self, name, value):
+        """
+        Set the value of a tag
+        @param name:    name of the tag
+        @type    name:    string
+        @param value: value of the tag
+        @type    value: string or int
+        """
+        self.tags[name] = value
+
+
+    def getTagValue(self, name):
+        """
+        Get the value of a tag
+        @param name:    name of the tag
+        @type    name:    string
+        @return:            value of the tag
+        """
+        return self.tags[name]
+
+    
+    def getTagNames(self):
+        """
+        Get all the names of the tags
+        @return: the names of the tags
+        """
+        return self.tags.keys()
+
+    def getTargetInterval(self):
+        return self.targetInterval
+    
+    def getQueryInterval(self):
+        return self.queryInterval
+    
+    def getSize(self):
+        return self.size
+    
+    def getTags(self):
+        return self.tags
+
+    def setIdentity(self, identity):
+        """
+        Set the percentage of identity of the sub-mapping
+        Possibly also set number of mismatches
+        @param identity: the percentage of identity of the sub-mapping
+        @type  identity: float
+        """
+        self.identity = identity
+        self.setTagValue("identity", identity)
+        if self.size != None and "nbMismatches" not in self.getTagNames():
+            self.setTagValue("nbMismatches", self.size - round(self.size * self.getTagValue("identity") / 100.0))
+
+
+    def setNbMismatches(self, nbMismatches):
+        """
+        Set the number of mismatches of the sub-mapping
+        Possibly also set percentage of identity
+        @param nbMismatches: the number of mismatches of the sub-mapping
+        @type    nbMismatches: int
+        """
+        self.nbMismatches = nbMismatches
+        if self.size != None and "identity" not in self.getTagNames():
+            self.setTagValue("identity", (self.size - self.getTagValue("nbMismatches")) / float(self.size) * 100)
+
+
+    def setNbGaps(self, nbGaps):
+        """
+        Set the number of gaps of the sub-mapping
+        @param nbGaps: the number of gaps of the sub-mapping
+        @type    nbGaps: int
+        """
+        self.setTagValue("nbGaps", nbGaps)
+        
+        
+    def merge(self, subMapping):
+        """
+        Merge two subMappings
+        @param subMapping: another sub-mapping
+        @type    subMapping: class L{SubMapping<SubMapping>}
+        """
+        self.targetInterval.merge(subMapping.targetInterval)
+        self.queryInterval.merge(subMapping.queryInterval)
+
+
+    def printCoordinates(self):
+        """
+        Print the coordinates of the sub-mapping (considering the direction)
+        @return: a string
+        """
+        if self.getDirection() == 1:
+            return "%d-%d" % (self.targetInterval.getStart(), self.targetInterval.getEnd())
+        else:
+            return "%d-%d" % (self.targetInterval.getEnd(), self.targetInterval.getStart())
+
+
+    def __str__(self):
+        """
+        Return a representation of this object
+        @return: a string
+        """
+
+        if "match" in self.getTagNames() and not self.getTagValue("match"):
+            return "%s ---" % self.queryName
+
+        direction = "+"
+        if self.getDirection() == -1:
+            direction = "-"
+        string = "%s:%d-%d -- %s:%d-%d    (%s)" % (self.targetInterval.getChromosome(), self.targetInterval.getStart(), self.targetInterval.getEnd(), self.queryInterval.name, self.queryInterval.getStart(), self.queryInterval.getEnd(), direction)
+        if "nbMismatches" in self.getTagNames():
+            string += "(%i mm)" % (self.getTagValue("nbMismatches"))
+        if "identity" in self.getTagNames():
+            string += "(id: %i%%)" % (self.getTagValue("identity"))
+        if self.targetInterval.getSize() != None and self.queryInterval.getSize() != None and self.size != None:
+            string += "(sizes: %d, %d -> %d)" % (self.targetInterval.getSize(), self.queryInterval.getSize(), self.size)
+        return string
+
+
Binary file smart_toolShed/SMART/Java/Python/structure/SubMapping.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/Transcript.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,851 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.structure.Sequence import Sequence
+
+
+class Transcript(Interval):
+	"""
+	A class that models an transcript, considered as a specialized interval (the bounds of the transcript) that contains exons (also represented as intervals)
+	@ivar exons: a list of exons (intervals)
+	@type exons: list of L{Interval{Interval}}
+	"""
+
+	def __init__(self, transcript = None, verbosity = 0):
+		"""
+		Constructor
+		@param transcript: transcript to be copied
+		@type  transcript: class L{Transcript<Transcript>}
+		@param verbosity:  verbosity
+		@type  verbosity:  int
+		"""
+		super(Transcript, self).__init__(None, verbosity)
+		self.exons   = []
+		self.introns = None
+		if transcript != None:
+			self.copy(transcript)
+
+
+	def copy(self, transcript):
+		"""
+		Copy method
+		@param transcript: transcript to be copied
+		@type	transcript: class L{Transcript<Transcript>} or L{Interval<Interval>}
+		"""
+		super(Transcript, self).copy(transcript)
+		if transcript.__class__.__name__ == "Transcript":
+			exons = transcript.getExons()
+			if len(exons) > 1:
+				for exon in exons:
+					exonCopy = Interval(exon)
+					self.addExon(exonCopy)
+
+
+	def setDirection(self, direction):
+		"""
+		Set the direction of the interval
+		Possibly parse different formats
+		Impact all exons
+		@param direction: direction of the transcript (+ / -)
+		@type	direction: int or string
+		"""
+		super(Transcript, self).setDirection(direction)
+		for exon in self.exons:
+			exon.setDirection(direction)
+			
+
+	def setChromosome(self, chromosome):
+		"""
+		Set the chromosome
+		@param chromosome: chromosome on which the transcript is
+		@type  chromosome: string
+		"""
+		super(Transcript, self).setChromosome(chromosome)
+		for exon in self.exons:
+			exon.setChromosome(chromosome)
+
+	
+	def addExon(self, exon):
+		"""
+		Add an exon to the list of exons
+		@param exon: a new exon
+		@type  exon: class L{Interval<Interval>}
+		"""
+		if not self.exons and not exon.overlapWith(self):
+			firstExon = Interval()
+			firstExon.setStart(self.getStart())
+			firstExon.setEnd(self.getEnd())
+			firstExon.setDirection(self.getDirection())
+			firstExon.setChromosome(self.getChromosome())
+			self.exons.append(firstExon)
+		newExon = Interval(exon)
+		newExon.setDirection(self.getDirection())
+		self.exons.append(newExon)
+		if newExon.getStart() < self.getStart():
+			self.setStart(newExon.getStart())
+		if newExon.getEnd() > self.getEnd():
+			self.setEnd(newExon.getEnd())
+
+
+	def setStart(self, start):
+		"""
+		Set the new start, move the first exon accordingly (if exists)
+		@param start: the new start
+		@type  start: int
+		"""
+		super(Transcript, self).setStart(start)
+		if self.exons:
+			self.sortExonsIncreasing()
+			self.exons[0].setStart(start)
+
+
+	def setEnd(self, end):
+		"""
+		Set the new end, move the last exon accordingly (if exists)
+		@param end: the new end
+		@type  end: int
+		"""
+		super(Transcript, self).setEnd(end)
+		if self.exons:
+			self.sortExonsIncreasing()
+			self.exons[-1].setEnd(end)
+
+
+	def reverse(self):
+		"""
+		Reverse the strand of the transcript
+		"""
+		super(Transcript, self).reverse()
+		for exon in self.exons:
+			exon.reverse()
+
+		
+	def getUniqueName(self):
+		"""
+		Try to give a unique name by possibly adding occurrence
+		"""
+		if "nbOccurrences" in self.tags and "occurrence" in self.tags and self.tags["nbOccurrences"] != 1:
+			return "%s-%d" % (self.name, self.tags["occurrence"])
+		return self.name
+
+
+	def getNbExons(self):
+		"""
+		Get the number of exons
+		"""
+		return max(1, len(self.exons))
+
+
+	def getExon(self, i):
+		"""
+		Get a specific exon
+		@param i: the rank of the exon
+		@type  i: int
+		"""
+		if len(self.exons) == 0:
+			if i != 0:
+				raise Exception("Cannot get exon #%i while there is no exon in the transcript" % (i))
+			return self
+		return self.exons[i]
+
+
+	def getExons(self):
+		"""
+		Get all the exons
+		"""
+		if len(self.exons) == 0:
+			return [Interval(self)]
+		return self.exons
+
+
+	def getIntrons(self):
+		"""
+		Get all the introns
+		Compute introns on the fly
+		"""
+		if self.introns != None:
+			return self.introns
+		self.sortExons()
+		self.introns = []
+		exonStart = self.getExon(0)
+		for cpt, exonEnd in enumerate(self.exons[1:]):
+			intron = Interval()
+			intron.setName("%s_intron%d" % (self.getName(), cpt+1))
+			intron.setChromosome(self.getChromosome())
+			intron.setDirection(self.getDirection())
+			if self.getDirection() == 1:
+				intron.setEnd(exonEnd.getStart() - 1)
+				intron.setStart(exonStart.getEnd() + 1)
+			else:
+				intron.setStart(exonEnd.getEnd() + 1)
+				intron.setEnd(exonStart.getStart() - 1)
+			intron.setDirection(self.getDirection())
+			if intron.getSize() > 0:
+				self.introns.append(intron)
+			exonStart = exonEnd
+			intron.setSize(intron.getEnd() - intron.getStart() + 1)
+		return self.introns
+	
+	
+	def getSize(self):
+		"""
+		Get the size of the transcript (i.e. the number of nucleotides)
+		Compute size on the fly
+		"""
+		if len(self.exons) == 0:
+			return self.getSizeWithIntrons()
+		size = 0
+		for exon in self.exons:
+			size += exon.getSize()
+		return size
+
+
+	def getSizeWithIntrons(self):
+		"""
+		Get the size of the interval (i.e. distance from start to end)
+		"""
+		return super(Transcript, self).getSize()
+
+
+	def overlapWithExon(self, transcript, nbNucleotides = 1):
+		"""
+		Check if the exons of this transcript overlap with the exons of another transcript
+		@param transcript:		transcript to be compared to
+		@type	transcript:		class L{Transcript<Transcript>}
+		@param nbNucleotides: minimum number of nucleotides to declare and overlap
+		@type	nbNucleotides: int
+		"""
+		if not self.overlapWith(transcript, nbNucleotides):
+			return False
+		for thisExon in self.getExons():
+			for thatExon in transcript.getExons():
+				if thisExon.overlapWith(thatExon, nbNucleotides):
+					return True
+		return False
+	
+	
+	def include(self, transcript):
+		"""
+		Whether this transcript includes the other one
+		@param transcript: object to be compared to
+		@type  transcript: class L{Transcript<Transcript>}
+		"""	
+		if not super(Transcript, self).include(transcript):
+			return False
+		for thatExon in transcript.getExons():
+			for thisExon in self.getExons():
+				if thisExon.include(thatExon):
+					break
+			else:
+				return False
+		return True
+	
+	
+	def merge(self, transcript, normalization = False):
+		"""
+		Merge with another transcript
+		Merge exons if they overlap, otherwise add exons
+		@param transcript:		transcript to be merged to
+		@type	transcript:		class L{Transcript<Transcript>}
+		@param normalization: whether the sum of the merge should be normalized wrt the number of mappings of each elements
+		@type	normalization: boolean
+		"""
+		if self.getChromosome() != transcript.getChromosome() or self.getDirection() != transcript.getDirection():
+			raise Exception("Cannot merge '%s' with '%s'!" % (self, transcript))
+
+		theseExons = self.getExons()
+		thoseExons = transcript.getExons()
+
+		for thatExon in thoseExons:
+			toBeRemoved = []
+			for thisIndex, thisExon in enumerate(theseExons):
+				if thisExon.overlapWith(thatExon):
+					thatExon.merge(thisExon)
+					toBeRemoved.append(thisIndex)
+			theseExons.append(thatExon)
+			for thisIndex in reversed(toBeRemoved):
+				del theseExons[thisIndex]
+		self.removeExons()
+		self.setStart(min(self.getStart(), transcript.getStart()))
+		self.setEnd(max(self.getEnd(), transcript.getEnd()))
+		if len(theseExons) > 1:
+			for thisExon in theseExons:
+				self.addExon(thisExon)
+			
+		self.setName("%s--%s" % (self.getUniqueName(), transcript.getUniqueName()))
+		super(Transcript, self).merge(transcript, normalization)
+
+
+	def getDifference(self, transcript, sameStrand = False):
+		"""
+		Get the difference between this cluster and another one
+		@param transcript: object to be compared to
+		@type  transcript: class L{Transcript<Transcript>}
+		@param sameStrand: do the comparison iff the transcripts are on the same strand
+		@type  sameStrand: boolean
+		@return:		   a transcript
+		"""	
+		newTranscript = Transcript()
+		newTranscript.copy(self)
+		if self.getChromosome() != transcript.getChromosome():
+			return newTranscript
+		if not self.overlapWith(transcript):
+			return newTranscript
+		if sameStrand and self.getDirection() != transcript.getDirection():
+			return newTranscript
+		newTranscript.removeExons()
+		if transcript.getEnd() > newTranscript.getStart():
+			newTranscript.setStart(transcript.getEnd() + 1)
+		if transcript.getStart() < newTranscript.getEnd():
+			newTranscript.setEnd(transcript.getStart() + 1)
+		theseExons = []
+		for exon in self.getExons():
+			exonCopy = Interval()
+			exonCopy.copy(exon) 
+			theseExons.append(exonCopy)
+		for thatExon in transcript.getExons():
+			newExons = []
+			for thisExon in theseExons:
+				newExons.extend(thisExon.getDifference(thatExon))
+			theseExons = newExons
+		if not theseExons:
+			return None
+		newStart, newEnd = theseExons[0].getStart(), theseExons[0].getEnd()
+		for thisExon in theseExons[1:]:
+			newStart = min(newStart, thisExon.getStart())
+			newEnd   = max(newEnd,   thisExon.getEnd())
+		newTranscript.setEnd(newEnd)
+		newTranscript.setStart(newStart)
+		newTranscript.exons = theseExons
+		return newTranscript
+			
+	
+	def getSqlVariables(cls):
+		"""
+		Get the properties of the object that should be saved in a database
+		"""
+		variables = Interval.getSqlVariables()
+		variables.append("exons")
+		return variables
+	getSqlVariables = classmethod(getSqlVariables)
+
+
+	def setSqlValues(self, array):
+		"""
+		Set the values of the properties of this object as given by a results line of a SQL query
+		@param array: the values to be copied
+		@type	array: a list
+		"""
+		super(Transcript, self).setSqlValues(array)
+		mergedExons = array[8]
+		if not mergedExons:
+			return
+		for exonCount, splittedExon in enumerate(mergedExons.split(",")):
+			start, end = splittedExon.split("-")
+			exon = Interval()
+			exon.setChromosome(self.getChromosome())
+			exon.setDirection(self.getDirection())
+			exon.setName("%s_exon%d" % (self.getName(), exonCount+1))
+			exon.setStart(int(start))
+			exon.setEnd(int(end))
+			self.addExon(exon)
+
+
+	def getSqlValues(self):
+		"""
+		Get the values of the properties that should be saved in a database
+		"""
+		values = super(Transcript, self).getSqlValues()
+		values["size"] = self.getSize()
+		if self.getNbExons() == 1:
+			values["exons"] = ""
+		else:
+			values["exons"] = ",".join(["%d-%d" % (exon.getStart(), exon.getEnd()) for exon in self.getExons()])
+		return values
+
+
+	def getSqlTypes(cls):
+		"""
+		Get the types of the properties that should be saved in a database
+		"""
+		types		  = Interval.getSqlTypes()
+		types["exons"] = "varchar"
+		return types
+	getSqlTypes = classmethod(getSqlTypes)
+
+	
+	def getSqlSizes(cls):
+		"""
+		Get the sizes of the properties that should be saved in a database
+		"""
+		sizes		  = Interval.getSqlSizes()
+		sizes["exons"] = 10000
+		return sizes
+	getSqlSizes = classmethod(getSqlSizes)
+	
+		
+	def sortExons(self):
+		"""
+		Sort the exons
+		Increasing order if transcript is on strand "+", decreasing otherwise
+		"""
+		self.sortExonsIncreasing()
+		if self.getDirection() == -1:
+			exons = self.getExons()
+			exons.reverse()
+			self.exons = exons
+		
+		
+	def sortExonsIncreasing(self):
+		"""
+		Sort the exons
+		Increasing order
+		"""
+		exons = self.getExons()
+		sortedExons = []
+		while len(exons) > 0:
+			minExon = exons[0]
+			for index in range(1, len(exons)):
+				if minExon.getStart() > exons[index].getStart():
+					minExon = exons[index]
+			sortedExons.append(minExon)
+			exons.remove(minExon)
+		self.exons = sortedExons
+		
+		
+	def extendStart(self, size):
+		"""
+		Extend the transcript by the 5' end
+		@param size: the size to be extended
+		@type	size: int
+		"""
+		if len(self.exons) != 0:
+			self.sortExons()
+			if self.getDirection() == 1:
+				self.exons[0].setStart(max(0, self.exons[0].getStart() - size))
+			else:
+				self.exons[0].setEnd(self.exons[0].getEnd() + size)
+		super(Transcript, self).extendStart(size)
+		self.bin  = None
+		
+		
+	def extendEnd(self, size):
+		"""
+		Extend the transcript by the 3' end
+		@param size: the size to be extended
+		@type	size: int
+		"""
+		if len(self.exons) != 0:
+			self.sortExons()
+			if self.getDirection() == 1:
+				self.exons[-1].setEnd(self.exons[-1].getEnd() + size)
+			else:
+				self.exons[-1].setStart(max(0, self.exons[-1].getStart() - size))
+		super(Transcript, self).extendEnd(size)
+		self.bin  = None
+		
+		
+	def extendExons(self, size):
+		"""
+		Extend all the exons
+		@param size: the size to be extended
+		@type	size: int
+		"""
+		if len(self.exons) != 0:
+			self.sortExons()
+			exons = []
+			previousExon = None
+			for exon in self.exons:
+				exon.extendStart(size)
+				exon.extendEnd(size)
+				exon.setDirection(self.getDirection())
+				if previousExon != None and previousExon.overlapWith(exon):
+					previousExon.merge(exon)
+				else:
+					if previousExon != None:
+						exons.append(previousExon)
+					previousExon = exon
+			exons.append(previousExon)
+			self.exons = exons
+		super(Transcript, self).extendStart(size)
+		super(Transcript, self).extendEnd(size)
+		self.bin  = None
+		
+		
+	def restrictStart(self, size = 1):
+		"""
+		Restrict the transcript by some nucleotides, start from its start position
+		Remove the exons
+		@param size: the size to be restricted to
+		@type  size: int
+		"""
+		newExons = []
+		if self.getDirection() == 1:
+			for exon in self.exons:
+				if exon.getStart() <= self.getStart() + size - 1:
+					if exon.getEnd() > self.getStart() + size - 1:
+						exon.setEnd(self.getStart() + size - 1)
+					newExons.append(exon)
+		else:
+			for exon in self.exons:
+				if exon.getEnd() >= self.getEnd() - size + 1:
+					if exon.getStart() < self.getEnd() - size + 1:
+						exon.setStart(self.getEnd() - size + 1)
+					newExons.append(exon)
+		super(Transcript, self).restrictStart(size)
+		self.exons = newExons
+		
+		
+	def restrictEnd(self, size = 1):
+		"""
+		Restrict the transcript by some nucleotides, end from its end position
+		Remove the exons
+		@param size: the size to be restricted to
+		@type  size: int
+		"""
+		newExons = []
+		if self.getDirection() == 1:
+			for exon in self.exons:
+				if exon.getEnd() >= self.getEnd() - size + 1:
+					if exon.getStart() < self.getEnd() - size + 1:
+						exon.setStart(self.getEnd() - size + 1)
+					newExons.append(exon)
+		else:
+			for exon in self.exons:
+				if exon.getEnd() >= self.getEnd() - size + 1:
+					if exon.getStart() < self.getEnd() - size + 1:
+						exon.setEnd(self.getEnd() - size + 1)
+					newExons.append(exon)
+		super(Transcript, self).restrictEnd(size)
+		self.exons = newExons
+		
+		
+	def removeExons(self):
+		"""
+		Remove the exons and transforms the current transcript into a mere interval
+		"""
+		self.exons = []
+		self.bin   = None
+
+
+	def printGtf(self, title):
+		"""
+		Export this transcript using GTF2.2 format
+		@param title: the title of the transcripts
+		@type title: string
+		@return:	 a string
+		"""
+		transcriptId = self.getUniqueName()
+		geneId	   = "%s_gene" % (transcriptId)
+		direction	= "+"
+		if self.getDirection() == -1:
+			direction = "-"
+		self.sortExonsIncreasing()
+		string = ""
+		for i, exon in enumerate(self.getExons()):
+			exonCopy = Interval()
+			exonCopy.copy(exon)
+			if "ID" in exonCopy.getTagValues():
+				del exonCopy.tags["ID"]
+			feature = "exon"
+			if "feature" in exonCopy.getTagNames():
+				feature = exonCopy.getTagValue("feature")
+				del exonCopy.tags["feature"]
+			score = "."
+			if "score" in exonCopy.getTagNames():
+				score = "%d" % (int(exonCopy.getTagValue("score")))
+				del exonCopy.tags["score"]
+			if "Parent" in exonCopy.getTagNames():
+				del exonCopy.tags["Parent"]
+			exonCopy.setName("%s_part%d" % (self.getName(), i+1))
+			comment = exonCopy.getTagValues("; ", " ", "\"")
+			string += "%s\t%s\t%s\t%d\t%d\t%s\t%s\t.\ttranscript_id \"%s\"; gene_id \"%s\"; %s\n" % (exonCopy.getChromosome(), title, feature, exonCopy.getStart(), exonCopy.getEnd(), score, direction, transcriptId, geneId, comment)
+		return string
+
+
+	def printGff2(self, title):
+		"""
+		Export this transcript using GFF2 format
+		@param title: the title of the transcripts
+		@type  title: string
+		@return: a string
+		"""
+		direction = "+"
+		if self.getDirection() == -1:
+			direction = "-"
+		self.sortExonsIncreasing()
+		comment = self.getTagValues()
+		if comment != None:
+			comment = ";%s" % (comment)
+		score = "."
+		if "score" in self.getTagNames():
+			score = "%d" % (int(self.getTagValue("score")))
+		feature = "transcript"
+		if "feature" in self.getTagNames():
+			feature = self.getTagValue("feature")
+		string = "%s\t%s\t%s\t%d\t%d\t%s\t%s\t.\tGENE %s%s\n" % (self.getChromosome(), title, feature, self.getStart(), self.getEnd(), score, direction, self.name, comment)
+		for exon in self.getExons():
+			if "score" in exon.getTagNames():
+				score = "%d" % (int(self.getTagValue("score")))
+			string += "%s\t%s\t_exon\t%d\t%d\t%s\t%s\t.\tGENE %s\n" % (self.getChromosome(), title, exon.getStart(), exon.getEnd(), score, direction, self.name)
+		return string
+	
+
+	def printGff3(self, title):
+		"""
+		Export this transcript using GFF3 format
+		@param title: the title of the transcripts
+		@type title: string
+		@return: a string
+		"""
+		direction = "+"
+		if self.getDirection() == -1:
+			direction = "-"
+		self.sortExonsIncreasing()
+		if "ID" not in self.getTagValues():
+			self.setTagValue("ID", self.getUniqueName())
+		feature = "transcript"
+		tags = self.tags
+		if "feature" in self.getTagNames():
+			feature = self.getTagValue("feature")
+			del self.tags["feature"]
+		score = "."
+		if "score" in self.getTagNames():
+			score = "%d" % (int(self.getTagValue("score")))
+			del self.tags["score"]
+		comment = self.getTagValues(";", "=")
+		string = "%s\t%s\t%s\t%d\t%d\t%s\t%s\t.\t%s\n" % (self.getChromosome(), title, feature, self.getStart(), self.getEnd(), score, direction, comment)
+		if len(self.exons) > 1:
+			for i, exon in enumerate(self.getExons()):
+				if "score" in exon.getTagNames():
+					score = "%d" % (int(exon.getTagValue("score")))
+				string += "%s\t%s\texon\t%d\t%d\t%s\t%s\t.\tID=%s-exon%d;Name=%s-exon%d;Parent=%s\n" % (self.getChromosome(), title, exon.getStart(), exon.getEnd(), score, direction, self.getTagValue("ID"), i+1, self.name, i+1, self.getTagValue("ID"))
+		self.tags = tags
+		return string
+
+
+	def printEmbl(self):
+		"""
+		Export this transcript using EMBL format
+		@return: a string
+		"""
+		if len(self.exons) <= 1:
+			position = "%d..%d" % (self.getStart(), self.getEnd())
+		else:
+			positions = []
+			for exon in self.getExons():
+				positions.append("%d..%d" % (self.getStart(), self.getEnd()))
+			position = ",".join(positions)
+			position = "join(%s)" % (position)
+		if self.getDirection() == -1:
+			position = "complement(%s)" % (position)
+		feature = "misc_feature"
+		if "feature" in self.getTagNames():
+			if not self.getTagValue("feature").startswith("S-MART"):
+				feature = self.getTagValue("feature")
+		string = "FT %s %s\n" % (feature, position)
+		if "Name" in self.getTagNames():
+			string += "FT /label=\"%s\"\n" % (self.getTagValue("Name"))
+		return string
+
+
+	def printBed(self):
+		"""
+		Export this transcript using BED format
+		@return: a string
+		"""
+		name = self.name
+		if "nbOccurrences" in self.getTagNames() and self.getTagValue("nbOccurrences") != 1 and self.getTagValue("occurrences"):
+			name = "%s-%d" % (name, self.getTagValue("occurrence"))
+		comment = self.getTagValues(";", "=")
+		sizes   = []
+		starts  = []
+		direction = "+"
+		if self.getDirection() == -1:
+			direction = "-"
+		self.sortExonsIncreasing()
+		for exon in self.getExons():
+			sizes.append("%d" % (exon.getSize()))
+			starts.append("%d" % (exon.getStart() - self.getStart()))
+		return "%s\t%d\t%d\t%s\t1000\t%s\t%d\t%d\t0\t%d\t%s,\t%s,\n" % (self.getChromosome(), self.getStart(), self.getEnd()+1, name, direction, self.getStart(), self.getEnd()+1, self.getNbExons(), ",".join(sizes), ",".join(starts))
+
+
+	def printSam(self):
+		"""
+		Export this transcript using SAM format
+		@return: a string
+		"""
+		name			= self.name
+		flag			= 0 if self.getDirection() == 1 else 0x10
+		chromosome	  = self.getChromosome()
+		genomeStart	 = self.getStart()
+		quality		 = 255
+		mate			= "*"
+		mateGenomeStart = 0
+		gapSize		 = 0
+		sequence		= "*"
+		qualityString   = "*"
+		tags			= "NM:i:0"
+
+		lastExonEnd = None
+		self.sortExonsIncreasing()
+		exon  = self.getExons()[0]
+		cigar = "%dM" % (self.getExons()[0].getSize())
+		lastExonEnd = exon.getEnd()
+		for i, exon in enumerate(self.getExons()):
+			if i == 0:
+				continue
+			cigar += "%dN" % (exon.getStart() - lastExonEnd - 1)
+			cigar += "%dM" % (exon.getSize())
+
+		return "%s\t%d\t%s\t%d\t%d\t%s\t%s\t%d\t%d\t%s\t%s\t%s\n" % (name, flag, chromosome, genomeStart, quality, cigar, mate, mateGenomeStart, gapSize, sequence, qualityString, tags)
+
+
+	def printUcsc(self):
+		"""
+		Export this transcript using UCSC BED format
+		@return: a string
+		"""
+		if self.getChromosome().find("Het") != -1:
+			return ""
+		name	  = self.name
+		comment   = self.getTagValues(";", "")
+		sizes	 = []
+		starts	= []
+		direction = "+"
+		if self.getDirection() == -1:
+			direction = "-"
+		self.sortExonsIncreasing()
+		for exon in self.getExons():
+			sizes.append("%d" % (exon.getSize()))
+			starts.append("%d" % (exon.getStart() - self.getStart()))
+		return "%s\t%d\t%d\t%s\t1000\t%s\t%d\t%d\t0\t%d\t%s,\t%s,\n" % (self.getChromosome().replace("arm_", "chr"), self.getStart(), self.getEnd()+1, name, direction, self.getStart(), self.getEnd()+1, self.getNbExons(), ",".join(sizes), ",".join(starts))
+
+
+	def printGBrowseReference(self):
+		"""
+		Export this transcript using GBrowse format (1st line only)
+		@return: a string
+		"""
+		return "reference = %s\n" % (self.getChromosome())
+
+
+	def printGBrowseLine(self):
+		"""
+		Export this transcript using GBrowse format (2nd line only)
+		@return: a string
+		"""
+		self.sortExons()
+		coordinates = []
+		for exon in self.getExons():
+			coordinates.append(exon.printCoordinates())
+		coordinatesString = ",".join(coordinates)
+		comment = self.getTagValues(";", "=")
+		if comment:
+			comment = "\t\"%s\"" % (comment)
+		return "User_data\t%s\t%s%s\n" % (self.name, coordinatesString, comment)
+
+	
+	def printGBrowse(self):
+		"""
+		Export this transcript using GBrowse format
+		@return: a string
+		"""
+		return "%s%s" % (self.printGBrowseReference(), self.printGBrowseLine())
+
+
+	def printCsv(self):
+		"""
+		Export this transcript using CSV format
+		@return: a string
+		"""
+		self.sortExons()
+		string = "%s,%d,%d,\"%s\"," % (self.getChromosome(), self.getStart(), self.getEnd(), "+" if self.getDirection() == 1 else "-")
+		if len(self.getExons()) == 1:
+			string += "None"
+		else:
+			for exon in self.getExons():
+				string += "%d-%d " % (exon.getStart(), exon.getEnd())
+		for tag in sorted(self.tags.keys()):
+			string += ",%s=%s" % (tag, str(self.tags[tag]))
+		string += "\n"
+		return string
+
+
+	def extractSequence(self, parser):
+		"""
+		Get the sequence corresponding to this transcript
+		@param parser: a parser to a FASTA file
+		@type  parser: class L{SequenceListParser<SequenceListParser>}
+		@return:	   an instance of L{Sequence<Sequence>}
+		"""
+		self.sortExons()
+		name = self.name
+		if "ID" in self.getTagNames() and self.getTagValue("ID") != self.name:
+			name += ":%s" % (self.getTagValue("ID"))
+		sequence = Sequence(name)
+		for exon in self.getExons():
+			sequence.concatenate(exon.extractSequence(parser))
+		return sequence
+	
+	
+	def extractWigData(self, parser):
+		"""
+		Get some wig data corresponding to this transcript
+		@param parser: a parser to a wig file
+		@type  parser: class L{WigParser<WigParser>}
+		@return: a sequence of float
+		"""
+		self.sortExons()
+		if parser.strands:
+			strands = (-1, 1)
+			values  = dict([(strand, []) for strand in strands])
+			for exon in self.getExons():
+				theseValues = exon.extractWigData(parser)
+				if self.getDirection() == -1:
+					for strand in strands:
+						theseValues[strand].reverse()
+				for strand in strands:
+					values[strand].extend(theseValues[strand])
+			if self.getDirection() == -1:
+				for strand in strands:
+					values[strand].reverse()
+			return values
+		else:
+			values = []
+			for exon in self.getExons():
+				theseValues = exon.extractWigData(parser)
+				#if self.getDirection() == -1:
+				#	theseValues.reverse()
+				values.extend(theseValues)
+			#if self.getDirection() == -1:
+			#	values.reverse()
+			return values
Binary file smart_toolShed/SMART/Java/Python/structure/Transcript.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/TranscriptContainer.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,236 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from commons.core.parsing.ParserChooser import ParserChooser
+from SMART.Java.Python.mySql.MySqlTranscriptTable import MySqlTranscriptTable
+from commons.core.writer.MySqlTranscriptWriter import MySqlTranscriptWriter
+
+class TranscriptContainer(object):
+    """
+    An interface class that contains a list of transcripts, handle different formats
+    @ivar container: container of the data
+    @type container: string 
+    @ivar format: format of the data
+    @type format: string        
+    @ivar transcriptListParser: possibly contains a parser to a list of transcripts
+    @type transcriptListParser: L{TranscriptListParser<TranscriptListParser>} or None
+    @ivar mappingListParser: possibly contains a parser to a list of mappings
+    @type mappingListParser: L{MapperParser<MapperParser>} or None
+    @ivar transcriptTables: possibly contains the mySQL tables
+    @type transcriptTables: dict of L{MySqlTranscriptTable<MySqlTranscriptTable>} or None
+    @ivar mySqlConnection: connection to a MySQL database
+    @type mySqlConnection: class L{MySqlConnection<MySqlConnection>}
+    @ivar type: type of the data (transcripts, mappings or mySQL)
+    @type type: string
+    @ivar verbosity: verbosity
+    @type verbosity: int        
+    """
+
+    def __init__(self, container, format, verbosity = 0):
+        """
+        Constructor
+        @param container: container of the data
+        @type container: string
+        @param format: format of the data
+        @type format: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        self.container            = container
+        self.format               = format
+        self.verbosity            = verbosity
+        self.transcriptListParser = None
+        self.mappingListParser    = None
+        self.transcriptTables     = {}
+        self.mySqlConnection      = None
+        self.foundData            = False
+        self.nbTranscripts        = None
+        self.nbNucleotides        = None
+        self.chromosomes          = None
+        self.type                 = None
+        if self.container == None:
+            sys.exit("Error! Container input file name is empty!")
+        if self.format == None:
+            sys.exit("Error! Container input format is empty!")
+        
+        
+    def findData(self):
+        """
+        Load data
+        """
+        if self.format == None:
+            sys.exit("Error! Format is not specified!")
+        if self.format == "sql":
+            self.transcriptTables = {}
+            self.chromosomes      = []
+            self.nbTranscripts    = 0
+            self.nbNucleotides    = 0
+            self.type             = "sql"
+            query                 = self.mySqlConnection.executeQuery("SELECT name FROM sqlite_master WHERE type LIKE 'table' AND name LIKE '%s_%%_transcripts'" % (self.container))
+            for line in query.getIterator():
+                tableName = line[0]
+                m = re.search(r"^(\S*)_transcripts$", tableName[len(self.container)+1:])
+                if m == None:
+                    sys.exit("Table '%s' has a strange name" % (tableName))
+                chromosome = m.group(1)
+                self.transcriptTables[chromosome] = MySqlTranscriptTable(self.mySqlConnection, self.container, chromosome, self.verbosity)
+                self.chromosomes.append(chromosome)
+                for transcript in self.transcriptTables[chromosome].getIterator():
+                    self.nbTranscripts += 1
+                    self.nbNucleotides += transcript.getSize()
+        if self.type == None:
+            parserChooser = ParserChooser(self.verbosity)
+            parserChooser.findFormat(self.format)
+            self.type = parserChooser.getType()
+            if self.type == "transcript":
+                self.transcriptListParser = parserChooser.getParser(self.container)
+            elif self.type == "mapping":
+                self.mappingListParser = parserChooser.getParser(self.container)
+            else:
+                sys.exit("Error! Cannot handle format '%s'!" % (self.format))
+        if self.type == None:
+            sys.exit("Error! Cannot handle format '%s'!" % (self.format))
+
+        if self.transcriptListParser != None:
+            if self.type == "transcript":
+                self.nbTranscripts = self.transcriptListParser.getNbTranscripts()
+                self.nbNucleotides = self.transcriptListParser.getNbNucleotides()
+                self.chromosomes   = self.transcriptListParser.getChromosomes()
+        if self.mappingListParser != None:
+            if self.type == "mapping":
+                self.nbTranscripts = self.mappingListParser.getNbMappings()
+                self.nbNucleotides = self.mappingListParser.getNbNucleotides()
+                self.chromosomes   = self.mappingListParser.getChromosomes()
+
+        self.foundData = True
+
+
+    def getNbTranscripts(self):
+        """
+        Get the number of transcripts
+        @return: the number of transcripts
+        """
+        if not self.foundData:
+            self.findData()
+        return self.nbTranscripts
+    
+    
+    def getNbItems(self):
+        """
+        Same as getNbTranscripts
+        """
+        return self.getNbTranscripts()
+
+
+    def getNbNucleotides(self):
+        """
+        Get the number of nucleotides
+        @return: the number of nucleotides
+        """
+        if not self.foundData:
+            self.findData()
+        return self.nbNucleotides
+
+
+    def getChromosomes(self):
+        """
+        Get the chromosomes
+        @return: the chromosomes
+        """
+        if not self.foundData:
+            self.findData()
+        return self.chromosomes
+    
+
+    def getIterator(self):
+        """
+        An iterator
+        @return: an iterator to a list of transcripts
+        """
+        if not self.foundData:
+            self.findData()
+        if self.type == "sql":
+            for chromosome in self.transcriptTables:
+                for transcript in self.transcriptTables[chromosome].getIterator():
+                    yield transcript
+            return
+        if self.type == "transcript":
+            for transcript in self.transcriptListParser.getIterator():
+                yield transcript
+            return
+        if self.type == "mapping":
+            for mapping in self.mappingListParser.getIterator():
+                yield mapping.getTranscript()
+            return
+        sys.exit("Error! No valid transcript container given!")
+        
+        
+    def storeIntoDatabase(self, name = None):
+        """
+        Store the current transcript / mapping list into database
+        """
+        if not self.foundData:
+            self.findData()
+
+        if (self.transcriptListParser == None and self.mappingListParser == None) or len(self.transcriptTables.keys()) != 0:
+            return
+        
+        mySqlTranscriptWriter = MySqlTranscriptWriter(self.mySqlConnection, name, self.verbosity)
+        mySqlTranscriptWriter.addTranscriptList(self.transcriptListParser if self.transcriptListParser else self.mappingListParser)
+        mySqlTranscriptWriter.write()
+        self.transcriptTables = mySqlTranscriptWriter.getTables()
+        self.type = "sql"
+            
+            
+    def getTables(self):
+        """
+        Accessor to the mySQL tables
+        @return: the mySQL tables
+        """
+        return self.transcriptTables
+        
+
+    def setDefaultTagValue(self, name, value):
+        """
+        Set the given tag to the value for all transcripts
+        @param name: name of the tag
+        @type name: string
+        @param value: value of the tag
+        @type value: string
+        """
+        if self.type == "sql":
+            for chromosome in self.transcriptTables:
+                self.transcriptTables[chromosome].setDefaultTagValue(name, value)
+        elif self.type == "transcript":
+            self.transcriptListParser.setDefaultTagValue(name, value)
+        elif self.type == "mapping":
+            self.mappingListParser.setDefaultTagValue(name, value)
+
Binary file smart_toolShed/SMART/Java/Python/structure/TranscriptContainer.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/TranscriptList.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,172 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.mySql.MySqlTable import MySqlTable
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.misc.Progress import Progress
+
+
+class TranscriptList(object):
+    """A class that codes for a list of transcript"""
+
+    def __init__(self, verbosity = 0):
+        self.transcripts = dict()
+        self.longestTranscript = 0
+        self.verbosity = verbosity
+
+
+    def getTranscript(self, chromosome, index):
+        return self.transcripts[chromosome][index]
+        
+
+    def getChromosomes(self):
+        return self.transcripts.keys()
+
+
+    def getTranscriptsOnChromosome(self, chromosome):
+        if chromosome not in self.transcripts:
+            return []
+        return self.transcripts[chromosome]
+
+
+    def addTranscript(self, transcript):
+        if transcript.getChromosome() in self.transcripts:
+            self.transcripts[transcript.getChromosome()].append(transcript)
+        else:
+            self.transcripts[transcript.getChromosome()] = [transcript]
+        self.longestTranscript = max(self.longestTranscript, transcript.getEnd() - transcript.getStart())
+        
+
+    def removeTranscript(self, chromosome, i):
+        del self.transcripts[chromosome][i]
+
+
+    def removeAll(self):
+        self.transcripts = {}
+
+
+    def getNbTranscripts(self):
+        nbTranscripts = 0
+        for chromosome in self.transcripts:
+            nbTranscripts += len(self.transcripts[chromosome])
+        return nbTranscripts
+
+
+    def getSize(self):
+        size = 0
+        for chromosome in self.transcripts:
+            for transcript in self.transcripts[chromosome]:
+                size += transcript.getSize()
+        return size
+
+
+    def sort(self):
+        for chromosome in self.transcripts:
+            self.transcripts[chromosome].sort(lambda x, y: x.getStart() - y.getStart())
+
+
+    def removeOverlapWith(self, transcriptList):
+        transcriptList.sort()
+        for chromosome in self.transcripts:
+            progress = Progress(len(self.transcripts[chromosome]), "Handling chromosome %s" % (chromosome), self.verbosity)
+            for thisTranscriptId in range(len(self.transcripts[chromosome])):
+                progress.inc()
+                for thatTranscriptId in range(len(transcriptList.transcripts[chromosome])):
+                    if self.transcripts[chromosome][thisTranscriptId].overlapWith(transcriptList.transcripts[chromosome][thatTranscriptId]):
+                        self.transcripts[chromosome][thisTranscriptId] = None
+                        break
+                    if self.transcripts[chromosome][thisTranscriptId].getEnd() > transcriptList.transcripts[chromosome][thatTranscriptId]:
+                        break
+            self.transcripts[chromosome] = [transcript for transcript in self.transcripts[chromosome] if transcript != None]
+        progress.done()
+
+
+    def removeOverlapWithExon(self, transcriptList):
+        transcriptList.sort()
+        for chromosome in self.transcripts:
+            progress = Progress(len(self.transcripts[chromosome]), "Handling chromosome %s" % (chromosome), self.verbosity)
+            for thisTranscriptId in range(len(self.transcripts[chromosome])):
+                progress.inc()
+                for thatTranscriptId in range(len(transcriptList.transcripts[chromosome])):
+                    if self.transcripts[chromosome][thisTranscriptId].overlapWithExon(transcriptList.transcripts[chromosome][thatTranscriptId]):
+                        self.transcripts[chromosome][thisTranscriptId] = None
+                        break
+                    if self.transcripts[chromosome][thisTranscriptId].getEnd() > transcriptList.transcripts[chromosome][thatTranscriptId]:
+                        break
+            self.transcripts[chromosome] = [transcript for transcript in self.transcripts[chromosome] if transcript != None]
+        progress.done()
+
+
+    def setDefaultTagValue(self, name, value):
+        for transcript in self.getIterator():
+            transcript.setTag(name, value)
+
+
+    def storeDatabase(self, mySqlConnection):
+        transcriptsTable = MySqlTable("TmpTranscriptsTable", mySqlConnection)
+        transcriptsTable.create(Transcript.getSqlVariables(), Transcript.getSqlTypes())
+        intervalsVariables = Interval.getSqlVariables()
+        intervalsVariables.append("idTranscript")
+        intervalsTypes = Interval.getSqlTypes()
+        intervalsTypes["idTranscript"] = "int"
+        intervalsTable = MySqlTable("TmpIntervalsTable", mySqlConnection)
+        intervalsTable.create(intervalsVariables, intervalsTypes)
+        for chromosome in self.transcripts:
+            for transcript in self.transcripts[chromosome]:
+                idTranscript = transcriptsTable.addLine(transcript.getSqlValues())
+                for exon in transcript.getExons():
+                    intervalValues = exon.getSqlValues()
+                    intervalValues["idTranscript"] = idTranscript
+                    intervalsTable.addLine(intervalValues)
+                    
+    
+    def getIterator(self):
+        chromosomes = self.transcripts.keys()
+        currentChromosome = 0
+        currentTranscript = 0
+        while True:
+            if currentChromosome >= len(chromosomes):
+                return
+            elif currentTranscript >= len(self.transcripts[chromosomes[currentChromosome]]):
+                currentTranscript    = 0
+                currentChromosome += 1
+            elif self.transcripts[chromosomes[currentChromosome]][currentTranscript] == None:
+                currentTranscript += 1
+            else:
+                yield self.transcripts[chromosomes[currentChromosome]][currentTranscript]
+                currentTranscript += 1
+
+
+    def __str__(self):
+        string = ""
+        for transcript in self.getIterator():
+            string += str(transcript)
+        return string
+
Binary file smart_toolShed/SMART/Java/Python/structure/TranscriptList.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/TranscriptListIterator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,58 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+class TranscriptListIterator(object):
+    """A class that iterates on a list of transcript"""
+
+    def __init__(self, transcriptList, verbosity = 0):
+        self.transcriptList = transcriptList
+        self.verbosity = verbosity
+        self.chromosomes = self.transcriptList.transcripts.keys()
+        self.currentChromosome = 0
+        self.currentTranscript = -1
+
+
+    def __iter__(self):
+        return self
+    
+    
+    def next(self):
+        self.currentTranscript += 1
+        while True:
+            if self.currentChromosome >= len(self.transcriptList.transcripts):
+                raise StopIteration
+            elif self.currentTranscript >= len(self.transcriptList.transcripts[self.chromosomes[self.currentChromosome]]):
+                self.currentTranscript = 0
+                self.currentChromosome += 1
+            elif self.transcriptList.transcripts[self.chromosomes[self.currentChromosome]][self.currentTranscript] == None:
+                self.currentTranscript += 1
+            else:
+                return self.transcriptList.transcripts[self.chromosomes[self.currentChromosome]][self.currentTranscript]
+            
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/TranscriptListsComparator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,1198 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+import random
+from SMART.Java.Python.misc import Utils
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.TranscriptList import TranscriptList
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from SMART.Java.Python.mySql.MySqlConnection import MySqlConnection
+from SMART.Java.Python.mySql.MySqlTranscriptTable import MySqlTranscriptTable
+from SMART.Java.Python.misc.Progress import Progress
+from commons.core.writer.MySqlTranscriptWriter import MySqlTranscriptWriter
+
+
+
+class TranscriptListsComparator(object):
+    """
+    Compare two transcript lists, using a database for one of the list
+    Uses one TranscriptContainer for query data, 
+             one TranscriptContainer exported to MySqlTranscriptTable for reference data, 
+             one MySqlTranscriptTable for transformed reference data
+    @ivar inputTranscriptContainers: parsers to the list of query transcripts
+    @type inputTranscriptContainers: list of 2 L{TranscriptContainer<TranscriptContainer>}
+    @ivar writer:                    transcript list writer
+    @type writer:                    class L{TranscriptListWriter<TranscriptListWriter>}
+    @ivar mySqlConnection:           connection to a MySQL database (to compute the ovelapping efficiently)
+    @type mySqlConnection:           class L{MySqlConnection<MySqlConnection>}
+    @ivar introns:                   compare transcripts or exons only
+    @type introns:                   list of 2 boolean
+    @ivar starts:                    restrict the query transcripts to first nucleotides
+    @type starts:                    list of 2 int or None
+    @ivar fivePrimes:                extend a list of transcripts by their 5' end
+    @type fivePrimes:                list of 2 int or None
+    @ivar threePrimes:               extend a list of transcripts by their 3' end
+    @type threePrimes:               list of 2 int or None
+    @ivar minDistance:               min distance between two transcripts [default: 0]
+    @type minDistance:               int
+    @ivar maxDistance:               max distance between two transcripts [default: 0]
+    @type maxDistance:               int
+    @ivar minOverlap:                minimum number of overlapping nucleotides to declare an overlap
+    @type minOverlap:                int
+    @ivar pcOverlap:                 percentage of overlapping nucleotides to declare an overlap
+    @type pcOverlap:                 int
+    @ivar upstreams:                 consider distances with elements which are upstream of the transcripts
+    @type upstreams:                 boolean
+    @ivar downstreams:               consider distances with elements which are downstream of the transcripts
+    @type downstreams:               boolean
+    @ivar colinear:                  whether transcripts should overlap in the same direction
+    @type colinear:                  boolean
+    @ivar antisense:                 whether transcripts should overlap in the opposite direction
+    @type antisense:                 boolean
+    @ivar outputDistance:            output distance between query and reference instead of query transcript
+    @type outputDistance:            boolean
+    @ivar absolute:                  do not consider the strand while computing distance
+    @type absolute:                  boolean
+    @ivar strandedDistance:          return a line per strand while computing distances
+    @type strandedDistance:          boolean
+    @ivar QUERY:                     constant specifying the query objects
+    @type QUERY:                     int
+    @ivar REFERENCE:                 constant specifying the reference objects
+    @type REFERENCE:                 int
+    @ivar INPUTTYPES:                set of input types of data (query or reference) objects
+    @type INPUTTYPES:                list of 2 int
+    @ivar typeToString:              string representation of the previous types
+    @type typeToString:              dict
+    @ivar tableNames:                name of the transcript tables
+    @type tableNames:                dict of strings
+    @ivar nbTranscripts:             number of transcript in the query/reference set
+    @type nbTranscripts:             list of 2 int or None
+    @ivar nbNucleotides:             number of nucleotides in the query/reference set
+    @type nbNucleotides:             list of 2 int or None
+    @ivar transcriptsToBeStored:     transcripts that will be stored into database
+    @type transcriptsToBeStored:     dict of class L{TranscriptList<TranscriptList>}
+    @ivar multiple:                  in merge mode, aggregate multiple transcripts
+    @type multiple:                  boolean
+    @ivar normalization:             normalize each element by the number of mappings of this element
+    @type normalization:             boolean
+    @ivar invert:                    invert the current comparison
+    @type invert:                    boolean
+    @ivar splitDifference:           split into intervals when computing difference
+    @type splitDifference:           boolean
+    @ivar odds:                      whether odds about the comparison should be computed
+    @type odds:                      boolean
+    @ivar overlapResults:            count the number of overlaps
+    @type overlapResults:            dictionary
+    @ivar oddResults:                compute the number of times each transcript overlaps (or is merged with) another one
+    @type oddResults:                dictionary
+    @ivar outputContainer:           container of the output transcripts
+    @type outputContainer:           class L{TranscriptContainer<TranscriptContainer>}
+    @ivar logHandle:                 log handle
+    @type logHandle:                 file
+    @ivar verbosity:                 verbosity
+    @type verbosity:                 int    
+    """
+    
+    def __init__(self, logHandle = None, verbosity = 0):
+        """
+        Constructor
+        @param transcriptListParser2: parser to the list of reference transcripts
+        @type  transcriptListParser2: class L{TranscriptListParser<TranscriptListParser>}
+        @param logHandle:             log handle
+        @type  logHandle:             file
+        @param verbosity:             verbosity
+        @type  verbosity:             int
+        """
+        self.QUERY                     = 0
+        self.REFERENCE                 = 1
+        self.WORKING                   = 2
+        self.INPUTTYPES                = (self.QUERY, self.REFERENCE)
+        self.INPUTWORKINGTYPES         = (self.QUERY, self.REFERENCE, self.WORKING)
+        self.typeToString              = {self.QUERY: "Query", self.REFERENCE: "Reference", self.WORKING: "Working"}
+
+        self.logHandle                 = logHandle
+        self.verbosity                 = verbosity
+        self.mySqlConnection           = MySqlConnection(self.verbosity-1)
+        self.inputTranscriptContainers = [None, None]
+        self.tableNames                = ["tmpQueryTable_%d" % (random.randint(0, 100000)), "tmpReferenceTable_%d" % (random.randint(0, 100000)), "tmpOutputTable_%d" % (random.randint(0, 100000)), "tmpWorkingTable_%d" % (random.randint(0, 100000))]
+        self.mySqlTranscriptWriters    = [MySqlTranscriptWriter(self.mySqlConnection, name, verbosity-1) for name in self.tableNames]
+        self.writer                    = None
+        self.introns                   = [False, False]
+        self.starts                    = [None, None]
+        self.ends                      = [None, None]
+        self.fivePrimes                = [None, None]
+        self.threePrimes               = [None, None]
+        self.minDistance               = None
+        self.maxDistance               = 0
+        self.minOverlap                = 1
+        self.pcOverlap                 = None
+        self.colinear                  = False
+        self.antisense                 = False
+        self.downstreams               = [False, False]
+        self.upstreams                 = [False, False]
+        self.outputDistance            = False
+        self.absolute                  = False
+        self.strandedDistance          = False
+        self.nbTranscripts             = [None, None]
+        self.nbNucleotides             = [None, None]
+        self.normalization             = False
+        self.included                  = False
+        self.including                 = False
+        self.invert                    = False
+        self.notOverlapping            = False
+        self.splitDifference           = False
+        self.multiple                  = False
+        self.odds                      = False
+        self.overlapResults            = None
+        self.oddResults                = None
+        self.outputContainer           = None
+        self.transcriptsToBeStored     = dict([(type, TranscriptList()) for type in self.INPUTWORKINGTYPES])
+        self.nbPrinted                 = 0
+
+        self.mySqlConnection.createDatabase()
+
+        
+    def __del__(self):
+        """
+        Destructor
+        Remove all temporary tables
+        """
+        for type in self.INPUTWORKINGTYPES:
+            self.mySqlTranscriptWriters[type].removeTables()
+        self.mySqlConnection.deleteDatabase()
+        
+    def acceptIntrons(self, type, bool):
+        """
+        Compare transcripts or exons only
+        @param type: whether use query/reference data
+        @type  type: int
+        @param bool: include introns or not
+        @type  bool: boolean
+        """
+        self.introns[type] = bool
+
+        
+    def restrictToStart(self, type, size):
+        """
+        Restrict a list of transcripts to first nucleotides
+        @param type: whether use query/reference data
+        @type  type: int
+        @param size: the size of the transcript to be considered
+        @type  size: int
+        """
+        self.starts[type]  = size
+        self.introns[type] = False
+        
+        
+    def restrictToEnd(self, type, size):
+        """
+        Restrict a list of transcripts to first nucleotides
+        @param type: whether use query/reference data
+        @type  type: int
+        @param size: the size of the transcript to be considered
+        @type  size: int
+        """
+        self.ends[type]    = size
+        self.introns[type] = False
+        
+        
+    def extendFivePrime(self, type, size):
+        """
+        Extend a list of transcripts by their 5' end
+        @param type: whether use query/reference data
+        @type  type: int
+        @param size: size of the extension
+        @type  size: int
+        """
+        self.fivePrimes[type] = size
+        
+
+    def extendThreePrime(self, type, size):
+        """
+        Extend the list of query transcripts by their 3' end
+        @param type: whether use query/reference data
+        @type  type: int
+        @param size: size of the extension
+        @type  size: int
+        """
+        self.threePrimes[type] = size
+        
+        
+    def setMinDistance(self, distance):
+        """
+        Set the min distance between two transcripts
+        @param distance: distance
+        @type  distance: int
+        """
+        self.minDistance = distance
+
+
+    def setMaxDistance(self, distance):
+        """
+        Set the max distance between two transcripts
+        @param distance: distance
+        @type  distance: int
+        """
+        self.maxDistance = distance
+        
+
+    def setMinOverlap(self, overlap):
+        """
+        Set the minimum number of nucleotides to declare an overlap
+        @param overlap: minimum number of nucleotides
+        @type  overlap: int
+        """
+        self.minOverlap = overlap
+        
+
+    def setPcOverlap(self, overlap):
+        """
+        Set the percentage of nucleotides to declare an overlap
+        @param overlap: percentage of nucleotides
+        @type  overlap: int
+        """
+        self.pcOverlap = overlap
+        
+
+    def setUpstream(self, type, boolean):
+        """
+        Consider transcripts which are upstream of some transcripts
+        @param type:        whether use query/reference data
+        @type  type:        int
+        @param boolean: consider only these transcripts or not
+        @type  boolean: boolean
+        """
+        self.upstreams[type] = boolean
+
+
+    def setDownstream(self, type, boolean):
+        """
+        Consider transcripts which are downstream of some transcripts
+        @param type:        whether use query/reference data
+        @type  type:        int
+        @param boolean: consider only these transcripts or not
+        @type  boolean: boolean
+        """
+        self.downstreams[type] = boolean
+
+
+    def setOutputDistance(self, boolean):
+        """
+        Output distance between query and reference instead of query transcript
+        @param boolean: whether distance should be output
+        @type  boolean: boolean
+        """
+        self.outputDistance = boolean
+        
+
+    def setAbsolute(self, boolean):
+        """
+        Do not consider strand when computing distance (thus, having only non-negative values)
+        @param boolean: whether we should consider strands
+        @type  boolean: boolean
+        """
+        self.absolute = boolean
+        
+
+    def setStrandedDistance(self, boolean):
+        """
+        Return two distance distributions, one per strand
+        @param boolean: whether we should return 2 distance distance
+        @type  boolean: boolean
+        """
+        self.strandedDistance = boolean
+        
+
+    def getColinearOnly(self, boolean):
+        """
+        Only consider transcripts that overlap in the same direction
+        @param boolean: whether transcripts should overlap in the same direction
+        @type  boolean: boolean
+        """
+        self.colinear = boolean
+        
+                
+    def getAntisenseOnly(self, boolean):
+        """
+        Only consider transcripts that overlap in the opposite direction
+        @param boolean: whether transcripts should overlap in the opposite direction
+        @type  boolean: boolean
+        """
+        self.antisense = boolean
+        
+        
+    def setIncludedOnly(self, boolean):
+        """
+        Keep the elements from first set which are included in the second set
+        @param boolean: whether to keep included elements only
+        @type  boolean: boolean
+        """
+        self.included = boolean
+
+
+    def setIncludingOnly(self, boolean):
+        """
+        Keep the elements from second set which are included in the first set
+        @param boolean: whether to keep included elements only
+        @type  boolean: boolean
+        """
+        self.including = boolean
+
+
+    def setNormalization(self, boolean):
+        """
+        Normalize the elements by the number of mappings in the genome
+        @param boolean: whether normalize
+        @type  boolean: boolean
+        """
+        self.normalization = boolean
+
+
+    def getInvert(self, boolean):
+        """
+        Only consider transcripts that do not overlap
+        @param boolean: whether invert the selection
+        @type  boolean: boolean
+        """
+        self.invert = boolean
+        
+        
+    def includeNotOverlapping(self, boolean):
+        """
+        Also output the elements which do not overlap
+        @param boolean: whether output the elements which do not overlap
+        @type  boolean: boolean
+        """
+        self.notOverlapping = boolean
+        
+        
+    def setSplitDifference(self, boolean):
+        """
+        Split into intervals when computing difference
+        @param boolean: whether to split
+        @type  boolean: boolean
+        """
+        self.splitDifference = boolean
+
+
+    def aggregate(self, boolean):
+        """
+        In merge mode, aggregate multiple transcripts
+        @param boolean: aggregate multiple transcripts
+        @type  boolean: boolean
+        """
+        self.multiple = boolean
+    
+
+    def getTables(self, type):
+        """
+        Get the SQL tables
+        @param type: type of the table (query, reference, etc.)
+        @type  type: int
+        """
+        return self.mySqlTranscriptWriters[type].getTables()
+    
+
+    def computeOdds(self, boolean):
+        """
+        Compute odds
+        @param boolean: whether odds should be computed
+        @type  boolean: boolean
+        """
+        self.odds = boolean
+        if self.odds:
+            self.overlapResults = dict()
+        
+        
+    def computeOddsPerTranscript(self, boolean):
+        """
+        Compute odds for each transcript
+        @param boolean: whether odds for each transcript should be computed
+        @type  boolean: boolean
+        """
+        self.odds = boolean
+        if self.odds:
+            self.overlapResults = dict()
+        
+        
+    def removeTables(self):
+        """
+        Remove the temporary MySQL tables
+        """
+        for type in self.INPUTWORKINGTYPES:
+            for chromosome in self.getTables(type):
+                self.getTables(type)[chromosome].remove()
+
+
+    def clearTables(self):
+        """
+        Empty the content of the databases
+        """
+        for type in self.INPUTWORKINGTYPES:
+            if self.transcriptListParsers[type] != None:
+                for chromosome in self.getTables(type):
+                    self.getTables(type)[chromosome].clear()
+
+
+    def extendTranscript(self, type, transcript):
+        """
+        Extend a transcript corresponding to the parameters of the class
+        @param transcript: a transcript
+        @type  transcript: class L{Transcript<Transcript>}
+        @return: the possibly extended transcript
+        """
+        extendedTranscript = Transcript()
+        extendedTranscript.copy(transcript)
+        if self.starts[type] != None:
+            extendedTranscript.restrictStart(self.starts[type])
+        if self.ends[type] != None:
+            extendedTranscript.restrictEnd(self.ends[type])
+        if self.fivePrimes[type] != None:
+            extendedTranscript.extendStart(self.fivePrimes[type])
+        if self.threePrimes[type] != None:
+            extendedTranscript.extendEnd(self.threePrimes[type])
+        return extendedTranscript
+
+
+    def storeTranscript(self, type, transcript, now = True):
+        """
+        Add a transcript to a MySQL database, or postpone the store
+        @param type:       whether use query/reference table
+        @type  type:       int
+        @param transcript: a transcript
+        @type  transcript: class L{Transcript<Transcript>}
+        @param now:        whether transcript should be stored now (or stored can be postponed)
+        @type  now:        bool
+        """
+        self.mySqlTranscriptWriters[type].addTranscript(transcript)
+        if type == self.REFERENCE:
+            self.mySqlTranscriptWriters[self.WORKING].addTranscript(transcript)
+        if now:
+            self.mySqlTranscriptWriters[type].write()
+            if type == self.REFERENCE:
+                self.mySqlTranscriptWriters[self.WORKING].write()
+
+
+    def writeTranscript(self, transcript):
+        """
+        Write a transcript in the output file
+        @param transcript: a transcript
+        @type  transcript: class L{Transcript<Transcript>}
+        """
+        if self.writer != None:
+            self.writer.addTranscript(transcript)
+            self.nbPrinted += 1
+
+
+    def flushData(self, type = None):
+        """
+        Store the remaining transcripts
+        @param type: whether use query/reference table (None for all)
+        @type  type: int or None
+        """
+        if type == None:
+            types = self.INPUTWORKINGTYPES
+        else:
+            types = [type]
+        for type in types:
+            self.mySqlTranscriptWriters[type].write()
+        if self.writer != None:
+            self.writer.write()
+        
+        
+    def unstoreTranscript(self, type, transcript):
+        """
+        Remove a transcript from a MySQL database
+        @param type:       whether use query/reference table
+        @type  type:       int
+        @param transcript: a transcript
+        @type  transcript: class L{Transcript<Transcript>}
+        """
+        self.getTables(type)[transcript.getChromosome()].removeTranscript(transcript)
+        if type == self.REFERENCE:
+            self.getTables(self.WORKING)[transcript.getChromosome()].removeTranscript(transcript)
+
+
+    def addIndexes(self, tables):
+        """
+        Add useful indexes to the tables
+        @param tables: which tables should be indexed
+        @type  tables: list of int
+        """
+        for type in tables:
+            for chromosome in self.getTables(type):
+                self.getTables(type)[chromosome].createIndex("iStart_transcript_%s_%d_%d" % (chromosome, type, random.randint(0, 100000)), ["start"])
+                self.getTables(type)[chromosome].exonsTable.createIndex("iTranscriptId_exon_%s_%d_%d" % (chromosome, type, random.randint(0, 100000)), ["transcriptId"])
+
+
+    def storeTranscriptList(self, type, transcriptListParser, extension):
+        """
+        Store a transcript list into database
+        @param type:      whether use query/reference parser
+        @type  type:      int
+        @param parser:    a parser of transcript list
+        @type  parser:    class L{TranscriptContainer<TranscriptContainer>}
+        @param extension: extend (or not) the transcripts
+        @type  extension: boolean
+        """
+        progress = Progress(transcriptListParser.getNbTranscripts(), "Writing transcripts for %s" % ("query" if type == self.QUERY else "reference"), self.verbosity-1)
+        for transcript in transcriptListParser.getIterator():
+            if extension:
+                transcript = self.extendTranscript(type, transcript)
+            self.mySqlTranscriptWriters[type].addTranscript(transcript)
+            progress.inc()
+        self.mySqlTranscriptWriters[type].write()
+        progress.done()
+        if type == self.REFERENCE:
+            for chromosome in self.getTables(self.REFERENCE):
+                self.getTables(self.WORKING)[chromosome] = MySqlTranscriptTable(self.mySqlConnection, self.tableNames[self.WORKING], chromosome, self.verbosity-1)
+                self.getTables(self.WORKING)[chromosome].copy(self.getTables(self.REFERENCE)[chromosome])
+        
+    
+    def setInputTranscriptContainer(self, type, inputTranscriptContainer):
+        """
+        Set an input transcript list container
+        @param type:                     whether use query/reference parser
+        @type  type:                     int
+        @param inputTranscriptContainer: a container
+        @type  inputTranscriptContainer: class L{TranscriptContainer<TranscriptContainer>}
+        """
+        self.inputTranscriptContainers[type] = inputTranscriptContainer
+        self.nbTranscripts[type]             = self.inputTranscriptContainers[type].getNbTranscripts()
+        self.nbNucleotides[type]             = self.inputTranscriptContainers[type].getNbNucleotides()
+
+
+    def setOutputWriter(self, writer):
+        """
+        Set an output transcript list writer
+        @param writer: a writer
+        @type  writer: class L{TranscriptListWriter<TranscriptListWriter>}
+        """
+        self.writer = writer
+
+
+    def compareTranscript(self, transcript1, transcript2, includeDistance = False):
+        """
+        Compare two transcripts, using user defined parameters
+        @param transcript1:     a transcript from the query set (already extended)
+        @type  transcript1:     class L{Transcript<Transcript>}
+        @param transcript2:     a transcript from the reference set (already extended)
+        @type  transcript2:     class L{Transcript<Transcript>}
+        @param includeDistance: take into account the distance too
+        @type  includeDistance: boolean
+        @return:                true, if they overlap
+        """
+        extendedTranscript1 = Transcript()
+        extendedTranscript1.copy(transcript1)
+        if includeDistance:
+            if self.maxDistance > 0:
+                extendedTranscript1.extendStart(self.maxDistance)
+                extendedTranscript1.extendEnd(self.maxDistance)
+
+        minOverlap = self.minOverlap
+        if self.pcOverlap != None:
+            minOverlap = max(minOverlap, transcript1.getSize() / 100.0 * self.pcOverlap)
+        if not extendedTranscript1.overlapWith(transcript2, self.minOverlap):
+            return False
+        if (self.downstreams[self.QUERY]       and transcript2.getStart() > extendedTranscript1.getStart()) or \
+             (self.upstreams[self.QUERY]       and transcript2.getEnd()   < extendedTranscript1.getEnd())   or \
+             (self.downstreams[self.REFERENCE] and extendedTranscript1.getStart() > transcript2.getStart()) or \
+             (self.upstreams[self.REFERENCE]   and extendedTranscript1.getEnd()   < transcript2.getEnd()):
+            return False
+        if (self.antisense and extendedTranscript1.getDirection() == transcript2.getDirection()) or (self.colinear and extendedTranscript1.getDirection() != transcript2.getDirection()):
+            return False
+        if self.included and not transcript2.include(extendedTranscript1):
+            return False
+        if self.including and not extendedTranscript1.include(transcript2):
+            return False
+        if self.introns[self.REFERENCE] and self.introns[self.QUERY]:
+            if self.logHandle != None:
+                self.logHandle.write("%s overlaps with intron of %s\n" % (str(extendedTranscript1), str(transcript2)))
+            return True
+        if (not self.introns[self.REFERENCE]) and (not self.introns[self.QUERY]) and extendedTranscript1.overlapWithExon(transcript2, minOverlap):
+            if self.logHandle != None:
+                self.logHandle.write("%s overlaps with exon of %s\n" % (str(extendedTranscript1), str(transcript2)))
+            return True
+        return False
+
+
+    def compareTranscriptToList(self, transcript1):
+        """
+        Compare a transcript to the reference list of transcripts
+        (Do not extend the transcripts, except for the distance)
+        @param transcript1: a transcript (from the query set)
+        @type  transcript1: class L{Transcript<Transcript>}
+        @return:            the reference transcripts overlapping
+        """
+        # no transcript in the reference table
+        if transcript1.getChromosome() not in self.getTables(self.WORKING):
+            return
+
+        # retrieve the the transcripts that may overlap in the working tables
+        clauses = []
+        extendedTranscript1 = Transcript()
+        extendedTranscript1.copy(transcript1)
+        if self.maxDistance > 0:
+            extendedTranscript1.extendStart(self.maxDistance)
+        if self.maxDistance > 0:
+            extendedTranscript1.extendEnd(self.maxDistance)
+        command = "SELECT * FROM %s WHERE (" % (self.getTables(self.WORKING)[transcript1.getChromosome()].getName())
+        for binPair in extendedTranscript1.getBins():
+            clause = "bin "
+            if binPair[0] == binPair[1]:
+                clause += "= %i" % (binPair[0])
+            else:
+                clause += "BETWEEN %i AND %i" % (binPair[0], binPair[1])
+            clauses.append(clause)
+        command += " OR ".join(clauses)
+        command += ") AND start <= %d AND end >= %d" % (extendedTranscript1.getEnd(), extendedTranscript1.getStart())
+
+        for index2, transcript2 in self.getTables(self.REFERENCE)[transcript1.getChromosome()].selectTranscripts(command):
+            if self.compareTranscript(extendedTranscript1, transcript2):
+                yield transcript2
+
+    
+    def compareTranscriptList(self):
+        """
+        Compare a list of transcript to the reference one
+        @return: the transcripts that overlap with the reference set
+        """
+        distance      = 0
+        nbClustersIn  = 0
+        nbClustersOut = 0
+        if self.maxDistance != None:
+            distance = self.maxDistance
+
+        self.addIndexes([self.QUERY, self.REFERENCE])
+
+        # export the container into tables
+        self.storeTranscriptList(self.QUERY, self.inputTranscriptContainers[self.QUERY], True)
+        self.storeTranscriptList(self.REFERENCE, self.inputTranscriptContainers[self.REFERENCE], True)
+
+        # looping
+        for chromosome1 in sorted(self.getTables(self.QUERY).keys()):
+            # get range of transcripts
+            command = "SELECT MIN(start), MAX(end), COUNT(id) FROM %s" % (self.getTables(self.QUERY)[chromosome1].getName())
+            query     = self.mySqlConnection.executeQuery(command)
+            result    = query.getLine()
+            first     = result[0]
+            last      = result[1]
+            nb        = result[2]
+
+            transcripts1 = []
+            toBeRemoved1 = []
+            transcripts2 = []
+            toBeRemoved2 = []
+            overlapsWith = []
+            nbOverlaps   = []
+            nbChunks     = max(1, nb / 100)
+            chunkSize    = (last - first) / nbChunks
+            progress     = Progress(nbChunks + 1, "Analyzing chromosome %s" % (chromosome1), self.verbosity-1)
+            for chunk in range(nbChunks + 1):
+
+                # load transcripts
+                start   = first + chunk * chunkSize
+                end     = start + chunkSize - 1
+                command = "SELECT * FROM %s WHERE start BETWEEN %d AND %d" % (self.getTables(self.QUERY)[chromosome1].getName(), start, end-1)
+                for index1, transcript1 in self.getTables(self.QUERY)[chromosome1].selectTranscripts(command):
+                    transcripts1.append(transcript1)
+                    overlapsWith.append([])
+                    nbOverlaps.append(0)
+                    nbClustersIn += 1 if "nbElements" not in transcript1.getTagNames() else transcript1.getTagValue("nbElements")
+                command = "DELETE FROM %s WHERE start < %d" % (self.getTables(self.QUERY)[chromosome1].getName(), end)
+                self.mySqlConnection.executeQuery(command)
+                if chromosome1 in self.getTables(self.REFERENCE):
+                    command = "SELECT * FROM %s WHERE start BETWEEN %d AND %d" % (self.getTables(self.REFERENCE)[chromosome1].getName(), start-distance, end+distance-1)
+                    if chunk == 0:
+                        command = "SELECT * FROM %s WHERE start < %d" % (self.getTables(self.REFERENCE)[chromosome1].getName(), end + distance)
+                    for index2, transcript2 in self.getTables(self.REFERENCE)[chromosome1].selectTranscripts(command):
+                        transcripts2.append(transcript2)
+                    command = "DELETE FROM %s WHERE start < %d" % (self.getTables(self.REFERENCE)[chromosome1].getName(), end + distance)
+                    self.mySqlConnection.executeQuery(command)
+
+                # compare sets
+                for index1, transcript1 in enumerate(transcripts1):
+                    overlappingNames = []
+                    nbElements1      = 1 if "nbElements" not in transcript1.getTagNames() else transcript1.getTagValue("nbElements")
+                    for transcript2 in transcripts2:
+                        if self.compareTranscript(transcript1, transcript2, True):
+                            id2 = transcript2.getTagValue("ID") if "ID" in transcript2.getTagNames() else transcript2.getName()
+                            if id2 not in overlapsWith[index1]:
+                                overlapsWith[index1].append(id2)
+                                nbOverlaps[index1] += 1 if "nbElements" not in transcript2.getTagNames() else transcript2.getTagValue("nbElements")
+                                if self.odds:
+                                    if transcript2.getName() not in self.overlapResults:
+                                        self.overlapResults[transcript2.getName()] = 0
+                                    self.overlapResults[transcript2.getName()] += nbElements1
+
+                    # check if query transcript extends bounds of the chunk
+                    if transcript1.getEnd() < end:
+                        if Utils.xor(overlapsWith[index1], self.invert) or self.notOverlapping:
+                            if overlapsWith[index1]:
+                                transcript1.setTagValue("overlapWith", ",".join(overlapsWith[index1])[:100])
+                                transcript1.setTagValue("nbOverlaps", "%d" % (nbOverlaps[index1]))
+                            elif self.notOverlapping:
+                                transcript1.setTagValue("nbOverlaps", "0")
+                            self.writeTranscript(transcript1)
+                            nbClustersOut += nbElements1
+                        toBeRemoved1.append(index1)
+
+                # update list of query transcripts
+                for index1 in reversed(toBeRemoved1):
+                    del transcripts1[index1]
+                    del overlapsWith[index1]
+                    del nbOverlaps[index1]
+                toBeRemoved1 = []
+
+                # check if the reference transcripts extends bounds of the chunk
+                for index2, transcript2 in enumerate(transcripts2):
+                    if transcript2.getEnd() + distance < end:
+                        toBeRemoved2.append(index2)
+                for index2 in reversed(toBeRemoved2):
+                    del transcripts2[index2]
+                toBeRemoved2 = []
+
+                progress.inc()
+
+            for index1, transcript1 in enumerate(transcripts1):
+                if Utils.xor(overlapsWith[index1], self.invert) or self.notOverlapping:
+                    if overlapsWith[index1]:
+                        transcript1.setTagValue("overlapWith", ",".join(overlapsWith[index1])[:100])
+                        transcript1.setTagValue("nbOverlaps", "%d" % (nbOverlaps[index1]))
+                    elif self.notOverlapping:
+                        transcript1.setTagValue("nbOverlaps", "0")
+                    self.writeTranscript(transcript1)
+                    nbClustersOut += 1 if "nbElements" not in transcript1.getTagNames() else transcript1.getTagValue("nbElements")
+            progress.done()
+            self.getTables(self.QUERY)[chromosome1].remove()
+            if chromosome1 in self.getTables(self.REFERENCE):
+                self.getTables(self.REFERENCE)[chromosome1].remove()
+                self.getTables(self.WORKING)[chromosome1].remove()
+
+        self.flushData()
+        if self.writer != None:
+            self.writer.close()
+            self.writer = None
+
+        if self.verbosity > 0:
+            print "reference: %d elements" % (self.nbTranscripts[self.REFERENCE])
+            print "query:     %d elements, %d clustered" % (self.nbTranscripts[self.QUERY], nbClustersIn)
+            if self.nbTranscripts[self.QUERY] != 0:
+                print "output:    %d elements (%.2f%%)"% (self.nbPrinted, self.nbPrinted / float(self.nbTranscripts[self.QUERY]) * 100), 
+                if nbClustersOut != 0:
+                    print ", %d clustered (%.2f%%)" % (nbClustersOut, float(nbClustersOut) / nbClustersIn * 100)
+
+
+    def compareTranscriptListDistance(self):
+        """
+        Compare a list of transcript to the reference one
+        @return: the distance distributions in a hash
+        """
+        nbDistances  = 0
+        distances    = {}
+        absDistances = {}
+        strandedDistances = dict([(strand, {}) for strand in (1, -1)])
+        
+        # export the container into tables
+        self.storeTranscriptList(self.QUERY, self.inputTranscriptContainers[self.QUERY], True)
+        self.storeTranscriptList(self.REFERENCE, self.inputTranscriptContainers[self.REFERENCE], True)
+        
+        progress = Progress(self.nbTranscripts[self.QUERY], "Analyzing chromosomes", self.verbosity-1)
+        for transcript1 in self.inputTranscriptContainers[self.QUERY].getIterator():
+            # get the distance
+            transcript1    = self.extendTranscript(self.QUERY, transcript1)
+            distance       = self.maxDistance + 1
+            strand         = None
+            closestElement = "None"
+            for transcript2 in self.compareTranscriptToList(transcript1):
+                thisStrand = transcript1.getDirection() * transcript2.getDirection()
+                if self.antisense or (not self.colinear and transcript1.getDirection() != transcript2.getDirection()):
+                    transcript2.reverse()
+                if self.absolute:
+                    transcript2.setDirection(transcript1.getDirection())
+                if transcript2.getDirection() == transcript1.getDirection():
+                    if self.starts[self.REFERENCE] != None:
+                        transcript2.restrictStart(self.starts[self.REFERENCE])
+                    if self.ends[self.REFERENCE] != None:
+                        transcript2.restrictEnd(self.ends[self.REFERENCE])
+                    thisDistance = transcript1.getRelativeDistance(transcript2)
+                    if (self.absolute):
+                        thisDistance = abs(thisDistance)
+                    if abs(thisDistance) < abs(distance):
+                        distance       = thisDistance
+                        strand         = thisStrand
+                        closestElement = transcript2.getTagValue("ID") if "ID" in transcript2.getTagNames() else transcript2.getName()
+            if (distance <= self.maxDistance) and (self.minDistance == None or distance >= self.minDistance):
+                nbDistances                        += 1
+                distances[distance]                 = distances.get(distance, 0) + 1
+                absDistance                         = abs(distance)
+                absDistances[absDistance]           = absDistances.get(absDistance, 0) + 1
+                strandedDistances[strand][distance] = strandedDistances[strand].get(distance, 0)
+                if distance not in strandedDistances[-strand]:
+                    strandedDistances[-strand][distance] = 0
+
+            # write transcript
+            if distance == self.maxDistance + 1:
+                distance = "None"
+            tmpTranscript = Transcript()
+            tmpTranscript.copy(transcript1)
+            tmpTranscript.setTagValue("distance", distance)
+            tmpTranscript.setTagValue("closestElement", closestElement)
+            self.writeTranscript(tmpTranscript)
+
+            progress.inc()
+        progress.done()
+
+        self.flushData()
+
+        if self.verbosity > 0:
+            print "reference: %d sequences" % (self.nbTranscripts[self.REFERENCE])
+            print "query:     %d sequences" % (self.nbTranscripts[self.QUERY])
+            if nbDistances == 0:
+                print "Nothing matches"
+            else:
+                print "min/avg/med/max transcripts: %d/%.2f/%.1f/%d" % Utils.getMinAvgMedMax(absDistances)
+                print "for %d distances (%.2f%%)" % (nbDistances, float(nbDistances) / self.nbTranscripts[self.QUERY] * 100)
+
+        if self.strandedDistance:
+            return strandedDistances
+        return distances
+
+
+    def compareTranscriptListMerge(self):
+        """
+        Merge the query list of transcript with itself
+        @return: the merged transcripts in a transcript list database
+        """
+        nbMerges  = 0
+
+        for type in (self.QUERY, self.REFERENCE):
+            self.storeTranscriptList(type, self.inputTranscriptContainers[type], True)
+        self.flushData()
+
+        # Loop on the chromosomes
+        for chromosome in sorted(self.getTables(self.QUERY).keys()):
+            if chromosome not in self.getTables(self.REFERENCE):
+                continue
+
+            # Get the size of the chromosome
+            maxEnd   = 0
+            nbChunks = 0
+            for type in (self.QUERY, self.REFERENCE):
+                command  = "SELECT MAX(end) from %s" % (self.getTables(type)[chromosome].getName())
+                query    = self.mySqlConnection.executeQuery(command)
+                maxEnd   = max(maxEnd, int(query.getLine()[0]))
+                nbChunks = max(nbChunks, self.getTables(type)[chromosome].getNbElements())
+
+            mergedTranscripts = {}
+            transcripts = {self.QUERY: [], self.REFERENCE: []}
+            progress    = Progress(nbChunks, "Analyzing %s" % (chromosome), self.verbosity-1)
+            for i in range(nbChunks):
+                rangeStart = int(i * (float(maxEnd) / nbChunks)) + 1
+                rangeEnd   = int((i+1) * (float(maxEnd) / nbChunks))
+
+                # Get all transcripts in query and reference from chunk
+                for type in (self.QUERY, self.REFERENCE):
+                    correction = 0 if self.QUERY else self.maxDistance
+                    command = "SELECT * FROM %s WHERE start <= %d" % (self.getTables(type)[chromosome].getName(), rangeEnd + correction)
+                    for index, transcript in self.getTables(type)[chromosome].selectTranscripts(command):
+                        transcripts[type].append(transcript)
+
+                # Merge elements between the two samples
+                for iQuery, queryTranscript in enumerate(transcripts[self.QUERY]):
+                    for iReference, referenceTranscript in enumerate(transcripts[self.REFERENCE]):
+                        if referenceTranscript == None: continue
+                        if self.compareTranscript(queryTranscript, referenceTranscript, True):
+                            if queryTranscript.getDirection() != referenceTranscript.getDirection():
+                                referenceTranscript.setDirection(queryTranscript.getDirection())
+                            queryTranscript.merge(referenceTranscript, self.normalization)
+                            nbMerges += 1
+                            transcripts[self.REFERENCE][iReference] = None
+                            if not self.multiple:
+                                mergedTranscripts[iQuery] = 0
+
+                # Remove transcripts from database
+                for type in (self.QUERY, self.REFERENCE):
+                    correction = 0 if self.QUERY else self.maxDistance
+                    command    = "DELETE FROM %s WHERE start <= %d" % (self.getTables(type)[chromosome].getName(), rangeEnd - correction)
+                    query      = self.mySqlConnection.executeQuery(command)
+
+                # Just in case, self-merge the elements in the query (beware of mergedTranscripts!)
+                if (self.multiple):
+                    for iQuery1, queryTranscript1 in enumerate(transcripts[self.QUERY]):
+                        if queryTranscript1 == None: continue
+                        for iQuery2, queryTranscript2 in enumerate(transcripts[self.QUERY]):
+                            if iQuery2 <= iQuery1 or queryTranscript2 == None: continue
+                            minOverlap = self.minOverlap
+                            if self.pcOverlap != None:
+                                minOverlap = max(minOverlap, queryTranscript1.getSize() / 100.0 * self.pcOverlap)
+                            if queryTranscript2.overlapWith(queryTranscript1, minOverlap) and (queryTranscript1.getDirection() == queryTranscript2.getDirection() or not self.colinear):
+                                if queryTranscript1.getDirection() != queryTranscript2.getDirection():
+                                    queryTranscript2.setDirection(queryTranscript1.getDirection())
+                                queryTranscript1.merge(queryTranscript2, self.normalization)
+                                transcripts[self.QUERY][iQuery2] = None
+                                nbMerges += 1
+                                if not self.multiple:
+                                    mergedTranscripts[iQuery1] = 0
+
+                # Update the sets of transcripts and write into database (also update mergedTranscripts)
+                newTranscripts = {self.QUERY: [], self.REFERENCE: []}
+                newMergedTranscripts = {}
+                for type in (self.QUERY, self.REFERENCE):
+                    for i, transcript in enumerate(transcripts[type]):
+                        if transcript == None: continue
+                        correction = 0 if self.QUERY else self.maxDistance
+                        if transcript.getEnd() < rangeEnd - correction:
+                            if self.multiple or ((type == self.QUERY) and (i in mergedTranscripts)):
+                                self.writeTranscript(transcripts[type][i])
+                        else:
+                            if type == self.QUERY and i in mergedTranscripts:
+                                newMergedTranscripts[len(newTranscripts[type])] = 0
+                            newTranscripts[type].append(transcript)
+                transcripts = newTranscripts
+                mergedTranscripts = newMergedTranscripts
+
+                progress.inc()
+            progress.done()
+
+            for type in (self.QUERY, self.REFERENCE):
+                for i, transcript in enumerate(transcripts[type]):
+                    if transcripts == None: continue
+                    if self.multiple or ((type == self.QUERY) and (i in mergedTranscripts)):
+                        self.writeTranscript(transcripts[type][i])
+
+        # Manage chromosomes with no corresponding data
+        if self.multiple:
+            for type in self.INPUTTYPES:
+                for chromosome in self.getTables(type):
+                    if chromosome in self.getTables(1 - type):
+                        continue
+                    for transcript in self.getTables(self.OUTPUT)[chromosome].getIterator():
+                        self.writeTranscript(transcript)
+
+        self.flushData()
+        if self.writer != None:
+            self.writer.close()
+            self.writer = None
+
+        if self.verbosity > 0:
+            print "query:    %d sequences" % (self.nbTranscripts[self.QUERY])
+            print "# merges: %d" % (nbMerges)
+            print "# printed %d (%.2f%%)" % (self.nbPrinted, self.nbPrinted / float(self.nbTranscripts[self.QUERY]) * 100)
+
+
+    def compareTranscriptListSelfMerge(self):
+        """
+        Merge the query list of transcript with itself
+        @return: the merged transcripts in a transcript list database
+        """
+        nbMerges  = 0
+        distance  = self.maxDistance if self.maxDistance != None else 0
+
+        self.addIndexes([self.QUERY])
+        self.storeTranscriptList(self.QUERY, self.inputTranscriptContainers[self.QUERY], True)
+        self.flushData()
+
+        # looping
+        for chromosome1 in sorted(self.getTables(self.QUERY).keys()):
+            transcripts2 = []
+
+            # get range of transcripts
+            progress = Progress(self.getTables(self.QUERY)[chromosome1].getNbElements(), "Analyzing chromosome %s" % (chromosome1), self.verbosity-1)
+            command  = "SELECT * FROM %s ORDER BY start" % (self.getTables(self.QUERY)[chromosome1].getName())
+            for index1, transcript1 in self.getTables(self.QUERY)[chromosome1].selectTranscripts(command):
+
+                # compare sets
+                toBeRemoved = set()
+                toBePrinted = set()
+                for index2, transcript2 in enumerate(transcripts2):
+
+                    if self.compareTranscript(transcript1, transcript2, True):
+                        if transcript1.getDirection() != transcript2.getDirection():
+                            transcript2.setDirection(transcript1.getDirection())
+                        transcript1.merge(transcript2, self.normalization)
+                        toBeRemoved.add(index2)
+                        nbMerges += 1
+                    elif transcript2.getEnd() + distance < transcript1.getStart():
+                        toBePrinted.add(index2)
+                transcripts2.append(transcript1)
+
+                for index2 in sorted(toBePrinted):
+                    self.writeTranscript(transcripts2[index2])
+                transcripts2 = [transcripts2[index2] for index2 in range(len(transcripts2)) if index2 not in (toBeRemoved | toBePrinted)]
+
+            for transcript2 in transcripts2:
+                self.writeTranscript(transcript2)
+            progress.done()
+            self.getTables(self.QUERY)[chromosome1].remove()
+
+        self.flushData()
+        if self.writer != None:
+            self.writer.close()
+            self.writer = None
+
+        if self.verbosity > 0:
+            print "query:    %d sequences" % (self.nbTranscripts[self.QUERY])
+            print "# merges: %d" % (nbMerges)
+            print "# printed %d (%.2f%%)" % (self.nbPrinted, self.nbPrinted / float(self.nbTranscripts[self.QUERY]) * 100)
+
+
+    def getDifferenceTranscriptList(self):
+        """
+        Get the elements of the first list which do not overlap the second list (at the nucleotide level)
+        @return: the transcripts that overlap with the reference set
+        """
+        distance = 0 if self.maxDistance == None else self.maxDistance
+
+        self.addIndexes([self.QUERY, self.REFERENCE])
+
+        # export the container into tables
+        self.storeTranscriptList(self.QUERY, self.inputTranscriptContainers[self.QUERY], True)
+        self.storeTranscriptList(self.REFERENCE, self.inputTranscriptContainers[self.REFERENCE], True)
+
+        # looping
+        for chromosome1 in sorted(self.getTables(self.QUERY).keys()):
+            # get range of transcripts
+            command = "SELECT MIN(start), MAX(end), COUNT(id) FROM %s" % (self.getTables(self.QUERY)[chromosome1].getName())
+            query   = self.mySqlConnection.executeQuery(command)
+            result  = query.getLine()
+            first   = result[0]
+            last    = result[1]
+            nb      = result[2]
+
+            transcripts1 = []
+            transcripts2 = []
+            nbChunks     = max(1, nb / 100)
+            chunkSize    = (last - first) / nbChunks
+            progress     = Progress(nbChunks + 1, "Analyzing chromosome %s" % (chromosome1), self.verbosity-1)
+            for chunk in range(nbChunks + 1):
+
+                # load transcripts
+                start   = first + chunk * chunkSize
+                end     = start + chunkSize - 1
+                command = "SELECT * FROM %s WHERE start BETWEEN %d AND %d" % (self.getTables(self.QUERY)[chromosome1].getName(), start, end-1)
+                for index1, transcript1 in self.getTables(self.QUERY)[chromosome1].selectTranscripts(command):
+                    transcripts1.append(transcript1)
+                command = "DELETE FROM %s WHERE start < %d" % (self.getTables(self.QUERY)[chromosome1].getName(), end)
+                self.mySqlConnection.executeQuery(command)
+                if chromosome1 in self.getTables(self.REFERENCE):
+                    command = "SELECT * FROM %s WHERE start BETWEEN %d AND %d" % (self.getTables(self.REFERENCE)[chromosome1].getName(), start-distance, end+distance-1)
+                    if chunk == 0:
+                        command = "SELECT * FROM %s WHERE start < %d" % (self.getTables(self.REFERENCE)[chromosome1].getName(), end + distance)
+                    for index2, transcript2 in self.getTables(self.REFERENCE)[chromosome1].selectTranscripts(command):
+                        transcripts2.append(transcript2)
+                    command = "DELETE FROM %s WHERE start < %d" % (self.getTables(self.REFERENCE)[chromosome1].getName(), end + distance)
+                    self.mySqlConnection.executeQuery(command)
+
+                # compare sets
+                toBeRemoved1 = []
+                for index1, transcript1 in enumerate(transcripts1):
+                    newTranscript1 = Transcript()
+                    newTranscript1.copy(transcript1)
+                    for transcript2 in transcripts2:
+                        newTranscript1 = newTranscript1.getDifference(transcript2)
+                        if newTranscript1 == None:
+                            toBeRemoved1.append(index1)
+                            break
+                    transcripts1[index1] = newTranscript1
+
+                    # check if query transcript extends bounds of the chunk
+                    if newTranscript1 != None and newTranscript1.getEnd() < end:
+                        if self.splitDifference:
+                            for exon in newTranscript1.getExons():
+                                transcript = Transcript()
+                                transcript.copy(exon)
+                                self.writeTranscript(transcript)
+                        else:
+                            self.writeTranscript(newTranscript1)
+                        toBeRemoved1.append(index1)
+
+                # update list of query transcripts
+                for index1 in reversed(toBeRemoved1):
+                    del transcripts1[index1]
+
+                # check if the reference transcripts extends bounds of the chunk
+                toBeRemoved2 = []
+                for index2, transcript2 in enumerate(transcripts2):
+                    if transcript2.getEnd() + distance < end:
+                        toBeRemoved2.append(index2)
+                for index2 in reversed(toBeRemoved2):
+                    del transcripts2[index2]
+
+                progress.inc()
+
+            for transcript1 in transcripts1:
+                if self.splitDifference:
+                    for exon in transcript1.getExons():
+                        transcript = Transcript()
+                        transcript.copy(exon)
+                        self.writeTranscript(transcript)
+                else:
+                    self.writeTranscript(transcript1)
+            progress.done()
+            self.getTables(self.QUERY)[chromosome1].remove()
+            if chromosome1 in self.getTables(self.REFERENCE):
+                self.getTables(self.REFERENCE)[chromosome1].remove()
+                self.getTables(self.WORKING)[chromosome1].remove()
+
+        self.flushData()
+        if self.writer != None:
+            self.writer.close()
+            self.writer = None
+
+        if self.verbosity > 0:
+            print "query:     %d elements" % (self.nbTranscripts[self.QUERY])
+            print "reference: %d elements" % (self.nbTranscripts[self.REFERENCE])
+            print "# printed: %d (%.2f%%)" % (self.nbPrinted, self.nbPrinted / float(self.nbTranscripts[self.QUERY]) * 100)
+
+
+    def getOddsPerTranscript(self):
+        """
+        Return overlap results
+        @return a dict of data
+        """
+        if not self.odds:
+            raise Exception("Did not compute odds!")
+        return self.overlapResults
+
+
+    def getOdds(self):
+        """
+        Return odds about the overlap
+        @return a dict of data
+        """
+        if not self.odds:
+            raise Exception("Did not compute odds!")
+        if self.oddResults != None:
+            return self.oddResults
+        self.oddResults = {}
+        for name, value in self.overlapResults.iteritems():
+            self.oddResults[value] = self.oddResults.get(value, 0) + 1
+        return self.oddResults
Binary file smart_toolShed/SMART/Java/Python/structure/__init__.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/test/Test_Interval.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,369 @@
+import unittest
+from SMART.Java.Python.structure.Interval import Interval
+
+class Test_Interval(unittest.TestCase):
+
+    def setUp(self):
+        self.iInterval = Interval()
+        self.iInterval1 = Interval()
+        self.iInterval2 = Interval()
+        
+    def test__init__(self):
+        self.iInterval.setChromosome("chromosome")
+        self.iInterval.setName("sequence")
+        self.iInterval.setStart(0)
+        self.iInterval.setEnd(123)
+        obsStart = self.iInterval.getStart()
+        obsEnd = self.iInterval.getEnd()
+        expStart = 0
+        expEnd = 123
+        
+        self.assertEqual(expStart, obsStart)
+        self.assertEqual(expEnd, obsEnd)
+
+    def test_copy(self):
+        self.iInterval1.setName("interval1")
+        self.iInterval1.setChromosome("chr1")
+        self.iInterval1.setStart(100)
+        self.iInterval1.setEnd(300)
+        self.iInterval1.setDirection("+")
+
+        self.iInterval2.copy(self.iInterval1)
+        self.assertEqual(self.iInterval2.getName(), "interval1")
+        self.assertEqual(self.iInterval2.getChromosome(), "chr1")
+        self.assertEqual(self.iInterval2.getStart(), 100)
+        self.assertEqual(self.iInterval2.getEnd(), 300)
+        self.assertEqual(self.iInterval2.getDirection(), 1)
+
+        self.iInterval1.setStart(200)
+        self.assertEqual(self.iInterval2.getStart(), 100)
+        
+    def test_getDirection(self):
+        self.iInterval1.setName("interval1")
+        self.iInterval1.setChromosome("chr1")
+        self.iInterval1.setStart(100)
+        self.iInterval1.setEnd(300)
+        self.iInterval1.setDirection("+")
+        expDirect = 1
+        self.assertEquals(expDirect,self.iInterval1.getDirection())
+
+    #!!!! Warning: two methods getStart() and getEnd() give the information maximum and minimum in interval.!!!!#
+    #In case strand = "+", start < end; strand = "-", start > end   
+    def test_setStartEnd(self):
+        self.iInterval1 = Interval()
+        self.iInterval1.setName("interval1")
+        self.iInterval1.setChromosome("chr1")
+        self.iInterval1.setStart(100)
+        self.iInterval1.setEnd(300)
+        self.iInterval1.setDirection("+")
+        
+        self.assertEqual(self.iInterval1.getName(), "interval1")
+        self.assertEqual(self.iInterval1.getChromosome(), "chr1")
+        self.assertEqual(self.iInterval1.getStart(),100)
+        self.assertEqual(self.iInterval1.getEnd(), 300)
+        self.assertEqual(self.iInterval1.getDirection(), 1)
+
+        self.iInterval1.setStart(200)
+        self.assertEqual(self.iInterval1.getStart(), 200)
+        self.assertEqual(self.iInterval1.getEnd(), 300)
+
+        self.iInterval1.setEnd(300)
+        self.iInterval1.setStart(100)
+        self.assertEqual(self.iInterval1.getStart(), 100)
+        self.assertEqual(self.iInterval1.getEnd(), 300)
+
+        self.iInterval1.setEnd(1200)
+        self.iInterval1.setStart(1000)
+        self.assertEqual(self.iInterval1.getStart(), 1000)
+        self.assertEqual(self.iInterval1.getEnd(), 1200)
+
+        self.iInterval1.reverse()
+        self.assertEqual(self.iInterval1.getDirection(), -1)
+        self.assertEqual(self.iInterval1.getStart(), 1000)
+        self.assertEqual(self.iInterval1.getEnd(), 1200)
+
+        self.iInterval1.setStart(1100)
+        self.assertEqual(self.iInterval1.getStart(), 1100)
+        self.assertEqual(self.iInterval1.getEnd(), 1200)
+
+        self.iInterval1.setEnd(2200)
+        self.iInterval1.setStart(2000)
+        self.assertEqual(self.iInterval1.getStart(), 2000)
+        self.assertEqual(self.iInterval1.getEnd(), 2200)
+
+        self.iInterval1.setStart(1000)
+        self.iInterval1.setEnd(1200)
+        self.assertEqual(self.iInterval1.getStart(), 1000)
+        self.assertEqual(self.iInterval1.getEnd(), 1200)
+
+    def test_reverse(self):
+        self.iInterval1 = Interval()
+        self.iInterval1.setName("interval1")
+        self.iInterval1.setChromosome("chr1")
+        self.iInterval1.setStart(100)
+        self.iInterval1.setEnd(200)
+        self.iInterval1.setDirection("+")
+        self.iInterval1.reverse()
+        self.assertEqual(self.iInterval1.getStart(), 100)
+        self.assertEqual(self.iInterval1.getEnd(), 200)
+        self.assertEqual(self.iInterval1.getDirection(), -1)
+
+    def test_overlapWith(self):
+        self.iInterval1 = Interval()
+        self.iInterval1.setName("interval1")
+        self.iInterval1.setChromosome("chr1")
+        self.iInterval1.setStart(100)
+        self.iInterval1.setEnd(200)
+        self.iInterval1.setDirection("+")
+        
+        self.iInterval2 = Interval()
+        self.iInterval2.copy(self.iInterval1)
+        self.iInterval2.setName("interval2")
+
+        self.assertTrue(self.iInterval1.overlapWith(self.iInterval2))
+
+        self.iInterval2.setChromosome("chr2")
+        try:
+            self.iInterval1.overlapWith(self.iInterval2)
+            self.fail()
+        except Exception:
+            pass
+
+        self.iInterval2.setChromosome("chr1")
+        self.iInterval2.setEnd(400)
+        self.iInterval2.setStart(300)
+        self.assertFalse(self.iInterval1.overlapWith(self.iInterval2))
+        
+        self.iInterval2.setStart(200)
+        self.assertTrue(self.iInterval1.overlapWith(self.iInterval2))
+
+    def test_isIncludeIn(self):
+        self.iInterval1 = Interval()
+        self.iInterval1.setName("interval1")
+        self.iInterval1.setChromosome("chr1")
+        self.iInterval1.setStart(100)
+        self.iInterval1.setEnd(200)
+        self.iInterval1.setDirection("+")
+        
+        self.iInterval2 = Interval()
+        self.iInterval2.setName("interval2")
+        self.iInterval2.setChromosome("chr1")
+        self.iInterval2.setStart(80)
+        self.iInterval2.setEnd(280)
+        self.iInterval2.setDirection("+")        
+        self.assertTrue(self.iInterval1.isIncludeIn(self.iInterval2))
+        
+    def test_getDistance(self):
+        self.iInterval1 = Interval()
+        self.iInterval1.setName("interval1")
+        self.iInterval1.setChromosome("chr1")
+        self.iInterval1.setStart(100)
+        self.iInterval1.setEnd(200)
+        self.iInterval1.setDirection("+")
+        
+        self.iInterval2 = Interval()
+        self.iInterval2.copy(self.iInterval1)
+        self.iInterval2.setName("interval2")
+
+        self.assertEqual(self.iInterval1.getDistance(self.iInterval2), 0)
+        self.assertEqual(self.iInterval2.getDistance(self.iInterval1), 0)
+
+        self.iInterval2.setChromosome("chr2")
+        try:
+            self.iInterval1.getDistance(self.iInterval2)
+            self.fail()
+        except Exception:
+            pass
+
+        self.iInterval2.setChromosome("chr1")
+        self.iInterval2.setEnd(400)
+        self.iInterval2.setStart(300)
+        self.assertEqual(self.iInterval1.getDistance(self.iInterval2), 100)
+        self.assertEqual(self.iInterval2.getDistance(self.iInterval1), 100)
+        
+    def test_getRelativeDistance(self):
+        self.iInterval1 = Interval()
+        self.iInterval1.setName("interval1")
+        self.iInterval1.setChromosome("chr1")
+        self.iInterval1.setStart(100)
+        self.iInterval1.setEnd(200)
+        self.iInterval1.setDirection("+")
+        
+        self.iInterval2 = Interval()
+        self.iInterval2.copy(self.iInterval1)
+        self.iInterval2.setName("interval2")
+
+        self.assertEqual(self.iInterval1.getDistance(self.iInterval2), 0)
+        self.assertEqual(self.iInterval2.getDistance(self.iInterval1), 0)
+
+        self.iInterval2.setChromosome("chr2")
+        try:
+            self.iInterval1.getDistance(self.iInterval2)
+            self.fail()
+        except Exception:
+            pass
+
+        self.iInterval2.setChromosome("chr1")
+        self.iInterval2.setEnd(400)
+        self.iInterval2.setStart(300)
+        self.assertEqual(self.iInterval1.getRelativeDistance(self.iInterval2), 100)
+        self.assertEqual(self.iInterval2.getRelativeDistance(self.iInterval1), -100)
+        
+    def test_merge(self):
+        self.iInterval1 = Interval()
+        self.iInterval1.setName("interval1")
+        self.iInterval1.setChromosome("chr1")
+        self.iInterval1.setStart(100)
+        self.iInterval1.setEnd(200)
+        self.iInterval1.setDirection("+")
+        
+        self.iInterval2 = Interval()
+        self.iInterval2.copy(self.iInterval1)
+        self.iInterval2.setName("interval2")
+        self.iInterval2.merge(self.iInterval1)
+
+        self.assertEqual(self.iInterval1, self.iInterval2)
+
+        self.iInterval2.setChromosome("chr2")
+        expMessage = "Cannot merge '%s' and '%s' for they are on different chromosomes." % (str(self.iInterval2), str(self.iInterval1))
+        isExceptionRaised = False
+        try:
+            self.iInterval2.merge(self.iInterval1)
+        except Exception, e:
+            isExceptionRaised = True
+        obsMessage = str(e)
+
+        self.assertTrue(isExceptionRaised)
+        self.assertEquals(expMessage, obsMessage)
+        #Warning! Both two intervals should be on the same chromosome and direction.  
+        self.iInterval2.setChromosome("chr1")
+        self.iInterval2.setStart(300)
+        self.iInterval2.setEnd(400)
+        self.iInterval2.merge(self.iInterval1)
+        self.assertEqual(self.iInterval2.getStart(), 100)
+        self.assertEqual(self.iInterval2.getEnd(), 400)
+        self.assertEqual(self.iInterval2.getChromosome(), "chr1")
+
+    def test_include(self):
+        iInterval1 = Interval()
+        iInterval1.setName("interval1")
+        iInterval1.setChromosome("chr1")
+        iInterval1.setStart(100)
+        iInterval1.setEnd(200)
+        iInterval1.setDirection("+")
+        
+        iInterval2 = Interval()
+        iInterval2.copy(iInterval1)
+        iInterval2.setName("interval2")
+        self.assertTrue(iInterval1.include(iInterval2))
+        self.assertTrue(iInterval2.include(iInterval1))
+
+        iInterval2.setChromosome("chr2")
+        self.assertFalse(iInterval1.include(iInterval2))
+        self.assertFalse(iInterval2.include(iInterval1))
+
+        iInterval2.setChromosome("chr1")
+        iInterval1.setStart(1)
+        self.assertTrue(iInterval1.include(iInterval2))
+        self.assertFalse(iInterval2.include(iInterval1))
+        
+        iInterval1.setStart(100)
+        iInterval1.setEnd(300)
+        self.assertTrue(iInterval1.include(iInterval2))
+        self.assertFalse(iInterval2.include(iInterval1))
+        
+
+    def test_getDifference(self):
+        iInterval1 = Interval()
+        iInterval1.setName("interval1")
+        iInterval1.setChromosome("chr1")
+        iInterval1.setStart(100)
+        iInterval1.setEnd(400)
+        iInterval1.setDirection("+")
+        
+        iInterval2 = Interval()
+        iInterval2.copy(iInterval1)
+        iInterval2.setName("interval2")
+        self.assertEqual(iInterval1.getDifference(iInterval2), [])
+        self.assertEqual(iInterval2.getDifference(iInterval1), [])
+
+        iInterval2.setChromosome("chr2")
+        results = iInterval1.getDifference(iInterval2)
+        self.assertEqual(len(results), 1)
+        resultInterval = results[0]
+        self.assertEqual(resultInterval.getStart(),      iInterval1.getStart())
+        self.assertEqual(resultInterval.getEnd(),        iInterval1.getEnd())
+        self.assertEqual(resultInterval.getDirection(),  iInterval1.getDirection())
+        self.assertEqual(resultInterval.getChromosome(), iInterval1.getChromosome())
+
+        iInterval2.setChromosome("chr1")
+        iInterval2.setEnd(300)
+        results = iInterval1.getDifference(iInterval2)
+        self.assertEqual(len(results), 1)
+        resultInterval = results[0]
+        self.assertEqual(resultInterval.getStart(),      301)
+        self.assertEqual(resultInterval.getEnd(),        iInterval1.getEnd())
+        self.assertEqual(resultInterval.getDirection(),  iInterval1.getDirection())
+        self.assertEqual(resultInterval.getChromosome(), iInterval1.getChromosome())
+        
+        iInterval2.setDirection("-")
+        results = iInterval1.getDifference(iInterval2, True)
+        self.assertEqual(len(results), 1)
+        resultInterval = results[0]
+        self.assertEqual(resultInterval.getStart(),      iInterval1.getStart())
+        self.assertEqual(resultInterval.getEnd(),        iInterval1.getEnd())
+        self.assertEqual(resultInterval.getDirection(),  iInterval1.getDirection())
+        self.assertEqual(resultInterval.getChromosome(), iInterval1.getChromosome())
+        
+        iInterval2.setDirection("+")
+        iInterval2.setStart(200)
+        results = iInterval1.getDifference(iInterval2)
+        self.assertEqual(len(results), 2)
+        resultInterval1, resultInterval2 = results
+        self.assertEqual(resultInterval1.getStart(),      iInterval1.getStart())
+        self.assertEqual(resultInterval1.getEnd(),        199)
+        self.assertEqual(resultInterval1.getDirection(),  iInterval1.getDirection())
+        self.assertEqual(resultInterval1.getChromosome(), iInterval1.getChromosome())
+        self.assertEqual(resultInterval2.getStart(),      301)
+        self.assertEqual(resultInterval2.getEnd(),        iInterval1.getEnd())
+        self.assertEqual(resultInterval2.getDirection(),  iInterval1.getDirection())
+        self.assertEqual(resultInterval2.getChromosome(), iInterval1.getChromosome())
+
+        iInterval2.setEnd(2000)
+        iInterval2.setStart(1000)
+        results = iInterval1.getDifference(iInterval2)
+        self.assertEqual(len(results), 1)
+        resultInterval = results[0]
+        self.assertEqual(resultInterval.getStart(),      iInterval1.getStart())
+        self.assertEqual(resultInterval.getEnd(),        iInterval1.getEnd())
+        self.assertEqual(resultInterval.getDirection(),  iInterval1.getDirection())
+        self.assertEqual(resultInterval.getChromosome(), iInterval1.getChromosome())
+ 
+    def test_mergeWithDifferentStrand(self):
+        self.iInterval1 = Interval()
+        self.iInterval1.setName("interval1")
+        self.iInterval1.setChromosome("chr1")
+        self.iInterval1.setStart(100)
+        self.iInterval1.setEnd(200)
+        self.iInterval1.setDirection("+")
+   
+        self.iInterval2 = Interval()
+        self.iInterval2.setName("interval2")
+        self.iInterval2.setChromosome("chr1")
+        self.iInterval2.setStart(300)
+        self.iInterval2.setEnd(400)
+        self.iInterval2.setDirection("-")
+
+        expMessage = "Cannot merge '%s' and '%s' for they are on different strands." % (str(self.iInterval2), str(self.iInterval1))
+        isExceptionRaised = False
+        try:
+            self.iInterval2.merge(self.iInterval1)
+        except Exception, e:
+            isExceptionRaised = True
+        obsMessage = str(e)
+
+        self.assertTrue(isExceptionRaised)
+        self.assertEquals(expMessage, obsMessage)
+
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/test/Test_Mapping.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,59 @@
+import unittest
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.structure.SubMapping import SubMapping
+from SMART.Java.Python.structure.Mapping import Mapping
+
+class Test_Mapping(unittest.TestCase):
+
+    def test__getTranscript(self):
+        queryInterval1 = Interval()
+        queryInterval1.setName("read1_1")
+        queryInterval1.setStart(1)
+        queryInterval1.setEnd(10)
+        queryInterval1.setDirection(1)
+
+        targetInterval1 = Interval()
+        targetInterval1.setChromosome("chr1")
+        targetInterval1.setStart(100)
+        targetInterval1.setEnd(110)
+        targetInterval1.setDirection(1)
+
+        subMapping1 = SubMapping()
+        subMapping1.setQueryInterval(queryInterval1)
+        subMapping1.setTargetInterval(targetInterval1)
+
+        queryInterval2 = Interval()
+        queryInterval2.setName("read1_2")
+        queryInterval2.setStart(11)
+        queryInterval2.setEnd(20)
+        queryInterval2.setDirection(1)
+
+        targetInterval2 = Interval()
+        targetInterval2.setChromosome("chr1")
+        targetInterval2.setStart(200)
+        targetInterval2.setEnd(210)
+        targetInterval2.setDirection(1)
+
+        subMapping2 = SubMapping()
+        subMapping2.setQueryInterval(queryInterval2)
+        subMapping2.setTargetInterval(targetInterval2)
+
+        mapping = Mapping()
+        mapping.addSubMapping(subMapping1)
+        mapping.addSubMapping(subMapping2)
+
+        transcript = mapping.getTranscript()
+        self.assertEqual(transcript.getStart(),      100)
+        self.assertEqual(transcript.getEnd(),        210)
+        self.assertEqual(transcript.getChromosome(), "chr1")
+        exons = transcript.getExons()
+        self.assertEqual(len(exons), 2)
+        exon1, exon2 = exons
+        self.assertEqual(exon1.getStart(), 100)
+        self.assertEqual(exon1.getEnd(),   110)
+        self.assertEqual(exon2.getStart(), 200)
+        self.assertEqual(exon2.getEnd(),   210)
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/test/Test_Sequence.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,90 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+from SMART.Java.Python.structure.Sequence import Sequence
+
+
+class Test_Sequence(unittest.TestCase):
+    
+    def setUp(self):
+        self._bs = Sequence()
+        self._bs1 = Sequence()
+    
+    def test_getSize(self):
+        self._bs.setName("sequence1")
+        self._bs.setSequence("AGCGGACGATGCAGCATGCGAATGACGATA")
+        obsSize = self._bs.getSize()
+        expSize = 30
+        self.assertEquals( expSize, obsSize )   
+    
+    def test_concatenate(self):
+        self._bs.setName("sequence")
+        self._bs.setSequence("GATGTGCAGACTTTTCACGCAGGACTACATCACTGT")
+        self._bs.setQuality("WWWVVVWPWWWVWWWWVVVVKVPWWVVWVWUUQUTQ")
+        self._bs1.setName("sequence1")
+        self._bs1.setSequence("GGAAACATATGCACATAAACGTTGAAATCATGCTTA")
+        self._bs1.setQuality("WWWWWWWWWWWWWWWWWVWWVWWVWWWWWWUUUUUU")
+        self._bs.concatenate(self._bs1)
+        expSeq = "GATGTGCAGACTTTTCACGCAGGACTACATCACTGTGGAAACATATGCACATAAACGTTGAAATCATGCTTA"
+        expQal = "WWWVVVWPWWWVWWWWVVVVKVPWWVVWVWUUQUTQWWWWWWWWWWWWWWWWWVWWVWWVWWWWWWUUUUUU"
+        self.assertEquals(expSeq, self._bs.getSequence())
+        self.assertEquals(expQal, self._bs.getQuality())
+
+    def test_reverseComplement(self):
+        self._bs.setName("seq1")
+        self._bs.setSequence("TACGGC")
+        exp = "GCCGTA"
+        self._bs.reverseComplement()
+        obs = self._bs.getSequence()
+        self.assertEquals(exp, obs)
+
+    def test_containsAmbiguousNucleotides(self):
+        self._bs.setName("seq1")
+        self._bs.setSequence("WCGTUacgtu")
+        self.assertTrue (self._bs.containsAmbiguousNucleotides())
+
+    def test_shrinkToFirstNucleotides(self):
+        self._bs.setName("seq1")
+        self._bs.setSequence("WCGTUacgtu")
+        self._bs.shrinkToFirstNucleotides(3)
+        expSeq = "WCG"
+        self.assertEquals(expSeq, self._bs.getSequence())
+        
+    def test_shrinkToLastNucleotides(self):
+        self._bs.setName("seq1")
+        self._bs.setSequence("WCGTUacgtu")
+        self._bs.shrinkToLastNucleotides(5)
+        expSeq = "acgtu"
+        self.assertEquals(expSeq, self._bs.getSequence())
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/test/Test_SubMapping.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,292 @@
+import unittest
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.structure.SubMapping import SubMapping
+
+class Test_SubMapping(unittest.TestCase):
+
+    def test__init__(self):
+        expEvalue = 0.00
+        expScore = 0
+        expIdentity = 0.00
+        expTargetInterval = Interval()
+        expQueryInterval = Interval()
+        expQueryRange = expQueryInterval
+        expSubjectRange = expTargetInterval
+        expSize = None
+        expTags = {}
+        
+        iSubMapping = SubMapping()
+        obsQueryRange = iSubMapping.getQueryAsRange()
+        obsSubjectRange = iSubMapping.getSubjectAsRange()
+        obsEvalue = iSubMapping.getEvalue()
+        obsScore = iSubMapping.getScore()
+        obsIdentity = iSubMapping.getIdentity()
+        obsTargetInterval = iSubMapping.getTargetInterval()
+        obsQueryInterval = iSubMapping.getQueryInterval()
+        obsSize = iSubMapping.getSize()
+        obsTags = iSubMapping.getTags()
+        
+        self.assertEquals(expEvalue, obsEvalue)
+        self.assertEquals(expIdentity, obsIdentity)
+        self.assertEquals(expQueryInterval, obsQueryInterval)
+        self.assertEquals(expQueryRange, obsQueryRange)
+        self.assertEquals(expScore, obsScore)
+        self.assertEquals(expSize, obsSize)
+        self.assertEquals(expSubjectRange, obsSubjectRange)
+        self.assertEquals(expTags, obsTags)
+        self.assertEquals(expTargetInterval, obsTargetInterval)
+        
+    def test__init__change_values_by_Interval(self):
+        iSubMapping = SubMapping()
+        
+        expSeqName = ""
+        
+        obsRangeSubject = iSubMapping.range_subject.getSeqname()
+        obsRangeQuery = iSubMapping.range_query.getSeqname()
+        obsIntervalTarget = iSubMapping.getTargetInterval().getChromosome()
+        obsIntervalQuery = iSubMapping.getQueryInterval().getChromosome()
+        
+        self.assertEquals(expSeqName, obsRangeSubject)
+        self.assertEquals(expSeqName, obsRangeQuery)
+        self.assertEquals(expSeqName, obsIntervalTarget)
+        self.assertEquals(expSeqName, obsIntervalQuery)
+        
+        iSubMapping.getTargetInterval().setChromosome("intervalTarget")
+        iSubMapping.getQueryInterval().setChromosome("intervalQuery")
+        
+        expTargetSeqName = "intervalTarget"
+        expQuerySeqName = "intervalQuery"
+        
+        obsRangeSubject = iSubMapping.range_subject.getSeqname()
+        obsRangeQuery = iSubMapping.range_query.getSeqname()
+        obsIntervalTarget = iSubMapping.getTargetInterval().getChromosome()
+        obsIntervalQuery = iSubMapping.getQueryInterval().getChromosome()
+        
+        self.assertEquals(expTargetSeqName, obsRangeSubject)
+        self.assertEquals(expQuerySeqName, obsRangeQuery)
+        self.assertEquals(expTargetSeqName, obsIntervalTarget)
+        self.assertEquals(expQuerySeqName, obsIntervalQuery)
+        
+    def test__init__change_values_by_Align(self):
+        iSubMapping = SubMapping()
+        
+        expSeqName = ""
+        
+        obsRangeSubject = iSubMapping.range_subject.getSeqname()
+        obsRangeQuery = iSubMapping.range_query.getSeqname()
+        obsIntervalTarget = iSubMapping.getTargetInterval().getChromosome()
+        obsIntervalQuery = iSubMapping.getQueryInterval().getChromosome()
+        
+        self.assertEquals(expSeqName, obsRangeSubject)
+        self.assertEquals(expSeqName, obsRangeQuery)
+        self.assertEquals(expSeqName, obsIntervalTarget)
+        self.assertEquals(expSeqName, obsIntervalQuery)
+        
+        iSubMapping.range_subject.setSeqName("intervalTarget")
+        iSubMapping.range_query.setSeqName("intervalQuery")
+        
+        expTargetSeqName = "intervalTarget"
+        expQuerySeqName = "intervalQuery"
+        
+        obsRangeSubject = iSubMapping.range_subject.getSeqname()
+        obsRangeQuery = iSubMapping.range_query.getSeqname()
+        obsIntervalTarget = iSubMapping.getTargetInterval().getChromosome()
+        obsIntervalQuery = iSubMapping.getQueryInterval().getChromosome()
+        
+        self.assertEquals(expTargetSeqName, obsRangeSubject)
+        self.assertEquals(expQuerySeqName, obsRangeQuery)
+        self.assertEquals(expTargetSeqName, obsIntervalTarget)
+        self.assertEquals(expQuerySeqName, obsIntervalQuery)
+  
+    def test__eq__(self):
+        iSubMapping1 = SubMapping()
+        iSubMapping1.setQueryName("Query")
+        iSubMapping1.setQueryStart(50)
+        iSubMapping1.setQueryEnd(150)
+        iSubMapping1.setSubjectName("Subject")
+        iSubMapping1.setSubjectStart(100)
+        iSubMapping1.setSubjectEnd(200)
+        iSubMapping1.e_value = 1e-20
+        iSubMapping1.score = 30
+        iSubMapping1.identity = 90.2         
+        iInterval1 = Interval()
+        iInterval1.setChromosome("chromosome1")
+        iInterval1.setStart(0)
+        iInterval1.setEnd(100)
+        iInterval1.setDirection("+")
+        iInterval2 = Interval()
+        iInterval2.setChromosome("chromosome2")
+        iInterval2.setStart(200)
+        iInterval2.setEnd(300)
+        iInterval2.setDirection("+")
+        iSubMapping1.setTargetInterval(iInterval1)
+        iSubMapping1.setQueryInterval(iInterval2)
+        iSubMapping1.setTagValue("name", 50)
+        iSubMapping1.setSize(100)
+        
+        iSubMapping2 = SubMapping()
+        iSubMapping2.setQueryName("Query")
+        iSubMapping2.setQueryStart(50)
+        iSubMapping2.setQueryEnd(150)
+        iSubMapping2.setSubjectName("Subject")
+        iSubMapping2.setSubjectStart(100)
+        iSubMapping2.setSubjectEnd(200)
+        iSubMapping2.e_value = 1e-20
+        iSubMapping2.score = 30
+        iSubMapping2.identity = 90.2 
+        iSubMapping2.setTargetInterval(iInterval1)
+        iSubMapping2.setQueryInterval(iInterval2)
+        iSubMapping2.setTagValue("name", 50)
+        iSubMapping2.setSize(100)
+        self.assertEqual(iSubMapping1, iSubMapping2)
+        
+        
+    def test__eq__withInitialValue(self):
+        iSubMapping1 = SubMapping()
+        iInterval1 = Interval()
+        iInterval2 = Interval()
+        iSubMapping1.setTargetInterval(iInterval1)
+        iSubMapping1.setQueryInterval(iInterval2)
+        iSubMapping1.setTagValue("name", 50)
+        iSubMapping1.setSize(100)
+        
+        iSubMapping2 = SubMapping()
+        iSubMapping2.setTargetInterval(iInterval1)
+        iSubMapping2.setQueryInterval(iInterval2)
+        iSubMapping2.setTagValue("name", 50)
+        iSubMapping2.setSize(100)
+        self.assertEqual(iSubMapping1, iSubMapping2)       
+              
+              
+    def test__init__with_copy(self):
+        iTestSubMapping = SubMapping()
+        iTestSubMapping.setQueryName("Query")
+        iTestSubMapping.setQueryStart(50)
+        iTestSubMapping.setQueryEnd(150)
+        iTestSubMapping.setSubjectName("Subject")
+        iTestSubMapping.setSubjectStart(100)
+        iTestSubMapping.setSubjectEnd(200)
+        iTestSubMapping.e_value = 1e-20
+        iTestSubMapping.score = 30
+        iTestSubMapping.identity = 90.2 
+        
+        iIntervalTarget = Interval()
+        iIntervalTarget.setChromosome("chromosomeTarget")
+        iIntervalTarget.setName("sequenceTarget")
+        iIntervalTarget.setStart(0)
+        iIntervalTarget.setEnd(123)
+        iIntervalTarget.setDirection("+")
+        iIntervalQuery = Interval()
+        iIntervalQuery.setChromosome("chromosomeQuery")
+        iIntervalQuery.setName("sequenceQuery")
+        iIntervalQuery.setStart(200)
+        iIntervalQuery.setEnd(323)
+        iIntervalQuery.setDirection("+")    
+        
+        iTestSubMapping.setQueryInterval(iIntervalTarget)
+        iTestSubMapping.setTargetInterval(iIntervalQuery)
+        iTestSubMapping.setTagValue("identity", 50)
+        iTestSubMapping.setSize(10)
+        
+        iSubMappingWithCopy = SubMapping(iTestSubMapping)
+        self.assertEquals(iSubMappingWithCopy, iTestSubMapping)        
+
+      
+    def test_copy(self):
+        iSubMapping = SubMapping()
+        iSubMapping.setQueryName("Query")
+        iSubMapping.setQueryStart(50)
+        iSubMapping.setQueryEnd(150)
+        iSubMapping.setSubjectName("Subject")
+        iSubMapping.setSubjectStart(100)
+        iSubMapping.setSubjectEnd(200)
+        iSubMapping.e_value = 1e-20
+        iSubMapping.score = 30
+        iSubMapping.identity = 90.2 
+               
+        iInterval1 = Interval()
+        iInterval1.setChromosome("chromosome1")
+        iInterval1.setName("sequence1")
+        iInterval1.setStart(0)
+        iInterval1.setEnd(123)
+        iInterval1.setDirection("+")
+        iInterval2 = Interval()
+        iInterval2.setChromosome("chromosome2")
+        iInterval2.setName("sequence2")
+        iInterval2.setStart(200)
+        iInterval2.setEnd(300)     
+        iInterval2.setDirection("+")           
+        iSubMapping.setQueryInterval(iInterval1)
+        iSubMapping.setTargetInterval(iInterval2)
+        iSubMapping.setTagValue("identity", 50)
+        iSubMapping.setSize(10)
+
+        iSubMappingCopy = SubMapping()
+        iSubMappingCopy.copy(iSubMapping)
+        self.assertEqual(iSubMappingCopy, iSubMapping)
+        
+        
+    def test_setTags(self):
+        iSubMapping = SubMapping()
+        iSubMapping.getQueryInterval().setSize(50)
+        iSubMapping.getTargetInterval().setSize(2)
+        iSubMapping.setTagValue("identity", 50)
+        iSubMapping.setSize(10)
+        
+        expQueryIntervalSize = 50
+        expTargetIntervalSize = 2
+        expTags = {"identity" : 50,
+                   "nbMismatches" : 5}
+        
+        obsTags = iSubMapping.getTags()
+        self.assertEquals(expTags, obsTags)
+        
+        
+    def test_setIdentity(self):
+        iSubMapping = SubMapping()        
+        iSubMapping.setIdentity(10)
+        expIdentity = 10
+        expTags = {"identity": 10}
+        
+        obsIdentity = iSubMapping.getIdentity()
+        obsTags = iSubMapping.getTags()
+        
+        self.assertEquals(expIdentity,obsIdentity)
+        self.assertEquals(expTags,obsTags)
+        
+        
+    def test_setIdentity_with_size(self):
+        iSubMapping = SubMapping()        
+        iSubMapping.setSize(10)
+        iSubMapping.setIdentity(50)
+        
+        expIdentity = 50
+        expTags = {"identity" : 50,
+                   "nbMismatches" : 5}
+        
+        obsIdentity = iSubMapping.getIdentity()
+        obsTags = iSubMapping.getTags()
+        
+        self.assertEquals(expIdentity,obsIdentity)
+        self.assertEquals(expTags,obsTags)
+        
+        
+    def test_setIdentity_with_sizeAndMismatchTag(self):
+        iSubMapping = SubMapping()        
+        iSubMapping.setSize(10)
+        iSubMapping.setTagValue("nbMismatches", 8)
+        iSubMapping.setIdentity(50)
+        
+        expIdentity = 50
+        expTags = {"identity" : 50,
+                   "nbMismatches" : 8}
+        
+        obsIdentity = iSubMapping.getIdentity()
+        obsTags = iSubMapping.getTags()
+        
+        self.assertEquals(expIdentity,obsIdentity)
+        self.assertEquals(expTags,obsTags)
+        
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/test/Test_Transcript.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,351 @@
+import unittest
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.structure.Transcript import Transcript
+
+class Test_Transcript(unittest.TestCase):
+  
+    def test_getSize(self):
+        transcript1 = Transcript()
+        transcript1.setDirection("+")
+        transcript1.setStart(2000)
+        transcript1.setEnd(3000)
+        transcript1.setChromosome("arm_X")
+    
+        self.assertEqual(transcript1.getSize(), 1001)
+      
+        transcript2 = Transcript()
+        transcript2.copy(transcript1)
+        self.assertEqual(transcript1.getSize(), 1001)
+    
+        transcript3 = Transcript()
+        transcript3.setDirection("+")
+        transcript3.setChromosome("arm_X")
+    
+        exon1 = Interval()
+        exon1.setDirection("+")
+        exon1.setChromosome("arm_X")
+        exon1.setStart(100)
+        exon1.setEnd(200)
+        transcript3.addExon(exon1)
+    
+        exon2 = Interval()
+        exon2.setDirection("+")
+        exon2.setChromosome("arm_X")
+        exon2.setStart(300)
+        exon2.setEnd(400)
+        transcript3.addExon(exon2)
+    
+        self.assertEqual(transcript3.getSize(), 203)
+
+
+    def test_overlapWithExons(self):
+        exon1_1 = Interval()
+        exon1_1.setChromosome("chr1")
+        exon1_1.setStart(100)
+        exon1_1.setEnd(200)
+        exon1_1.setDirection("+")
+
+        exon1_2 = Interval()
+        exon1_2.setChromosome("chr1")
+        exon1_2.setStart(500)
+        exon1_2.setEnd(600)
+        exon1_2.setDirection("+")
+
+        transcript1 = Transcript()
+        transcript1.setChromosome("chr1")
+        transcript1.setStart(100)
+        transcript1.setEnd(600)
+        transcript1.setDirection("+")
+        transcript1.addExon(exon1_1)
+        transcript1.addExon(exon1_2)
+
+        exon2_1 = Interval()
+        exon2_1.copy(exon1_1)
+
+        transcript2 = Transcript()
+        transcript2.setChromosome("chr1")
+        transcript2.setStart(100)
+        transcript2.setEnd(200)
+        transcript2.setDirection("+")
+        transcript2.addExon(exon2_1)
+    
+        self.assertTrue(transcript1.overlapWithExon(transcript2))
+
+        transcript2.reverse()
+        try:
+            self.assertFalse(transcript1.overlapWithExon(transcript2))
+        except Exception:
+            pass
+      
+        transcript2.reverse()
+        transcript2.setChromosome("chr2")
+        self.assertFalse(transcript1.overlapWithExon(transcript2))
+
+        exon3_1 = Interval()
+        exon3_1.copy(exon1_1)
+        exon3_1.setEnd(400)
+        exon3_1.setStart(300)
+
+        transcript3 = Transcript()
+        transcript3.setChromosome("chr1")
+        transcript3.setStart(300)
+        transcript3.setEnd(400)
+        transcript3.setDirection("+")
+        transcript3.addExon(exon3_1)
+        self.assertFalse(transcript1.overlapWithExon(transcript3))
+
+
+    def test_merge(self):
+        exon1_1 = Interval()
+        exon1_1.setChromosome("chr1")
+        exon1_1.setStart(100)
+        exon1_1.setEnd(200)
+        exon1_1.setDirection("+")
+
+        exon1_2 = Interval()
+        exon1_2.setChromosome("chr1")
+        exon1_2.setStart(500)
+        exon1_2.setEnd(600)
+        exon1_2.setDirection("+")
+
+        transcript1 = Transcript()
+        transcript1.setChromosome("chr1")
+        transcript1.setEnd(600)
+        transcript1.setStart(100)
+        transcript1.setDirection("+")
+        transcript1.addExon(exon1_1)
+        transcript1.addExon(exon1_2)
+
+        exon2_1 = Interval()
+        exon2_1.copy(exon1_1)
+
+        transcript2 = Transcript()
+        transcript2.setChromosome("chr1")
+        transcript2.setEnd(200)
+        transcript2.setStart(100)
+        transcript2.setDirection("+")
+        transcript2.addExon(exon2_1)
+    
+        transcript1.merge(transcript2)
+        transcript1.sortExonsIncreasing()
+        exons = transcript1.getExons()
+        self.assertEqual(len(exons), 2)
+        exon1, exon2 = exons
+        self.assertEqual(exon1.getStart(), 100)
+        self.assertEqual(exon1.getEnd(),   200)
+        self.assertEqual(exon2.getStart(), 500)
+        self.assertEqual(exon2.getEnd(),   600)
+
+        transcript2.setChromosome("chr2")
+        try:
+            transcript1.merge(transcript2)
+            self.fail()
+        except Exception:
+            pass
+      
+        exon3_1 = Interval()
+        exon3_1.copy(exon1_1)
+        exon3_1.setEnd(650)
+        exon3_1.setStart(550)
+
+        transcript3 = Transcript()
+        transcript3.setChromosome("chr1")
+        transcript3.setEnd(650)
+        transcript3.setStart(550)
+        transcript3.setDirection("+")
+        transcript3.addExon(exon3_1)
+
+        transcript1.merge(transcript3)
+        self.assertEqual(transcript1.getStart(), 100)
+        self.assertEqual(transcript1.getEnd(),   650)
+        exons = transcript1.getExons()
+        self.assertEqual(len(exons), 2)
+        exon1, exon2 = exons
+        self.assertEqual(exon1.getStart(), 100)
+        self.assertEqual(exon1.getEnd(),   200)
+        self.assertEqual(exon2.getStart(), 500)
+        self.assertEqual(exon2.getEnd(),   650)
+
+        exon4_1 = Interval()
+        exon4_1.copy(exon1_1)
+        exon4_1.setEnd(400)
+        exon4_1.setStart(300)
+
+        transcript4 = Transcript()
+        transcript4.setChromosome("chr1")
+        transcript4.setStart(300)
+        transcript4.setEnd(400)
+        transcript4.setDirection("+")
+        transcript4.addExon(exon4_1)
+
+        transcript1.merge(transcript4)
+        self.assertEqual(transcript1.getStart(), 100)
+        self.assertEqual(transcript1.getEnd(),   650)
+        transcript1.sortExonsIncreasing()
+        exons = transcript1.getExons()
+        self.assertEqual(len(exons), 3)
+        exon1, exon2, exon3 = exons
+        self.assertEqual(exon1.getStart(), 100)
+        self.assertEqual(exon1.getEnd(),   200)
+        self.assertEqual(exon2.getStart(), 300)
+        self.assertEqual(exon2.getEnd(),   400)
+        self.assertEqual(exon3.getStart(), 500)
+        self.assertEqual(exon3.getEnd(),   650)
+
+
+    def test_extendStart(self):
+        transcript1 = Transcript()
+        transcript1.setStart(2000)
+        transcript1.setEnd(3000)
+        transcript1.setDirection("+")
+        transcript1.setChromosome("arm_X")
+      
+        transcript2 = Transcript()
+        transcript2.copy(transcript1)
+        transcript2.setDirection("-")
+    
+        transcript1.extendStart(1000)
+        transcript2.extendStart(1000)
+
+    
+        self.assertEqual(transcript1.getDirection(),  1)
+        self.assertEqual(transcript1.getStart(),      1000)
+        self.assertEqual(transcript1.getEnd(),        3000)
+        self.assertEqual(transcript1.getChromosome(), "arm_X")
+    
+        self.assertEqual(transcript2.getDirection(),  -1)
+        self.assertEqual(transcript2.getStart(),      2000)
+        self.assertEqual(transcript2.getEnd(),        4000)
+        self.assertEqual(transcript2.getChromosome(), "arm_X")
+
+
+    def test_restrictStart(self):
+        exon1_1 = Interval()
+        exon1_1.setChromosome("chr1")
+        exon1_1.setStart(100)
+        exon1_1.setEnd(200)
+        exon1_1.setDirection("+")
+
+        exon1_2 = Interval()
+        exon1_2.setChromosome("chr1")
+        exon1_2.setStart(300)
+        exon1_2.setEnd(500)
+        exon1_2.setDirection("+")
+
+        transcript1 = Transcript()
+        transcript1.setChromosome("chr1")
+        transcript1.setStart(100)
+        transcript1.setEnd(500)
+        transcript1.setDirection("+")
+        transcript1.addExon(exon1_1)
+        transcript1.addExon(exon1_2)
+
+        transcript1.restrictStart(301)
+        exons = transcript1.getExons()
+        self.assertEqual(len(exons), 2)
+        exon1, exon2 = exons
+        self.assertEqual(exon1.getStart(), 100)
+        self.assertEqual(exon1.getEnd(),   200)
+        self.assertEqual(exon2.getStart(), 300)
+        self.assertEqual(exon2.getEnd(),   400)
+
+
+    def test__include(self):
+        iTranscript1 = Transcript()
+        iTranscript1.setName("transcript1")
+        iTranscript1.setChromosome("chr1")
+        iTranscript1.setStart(100)
+        iTranscript1.setEnd(200)
+        iTranscript1.setDirection("+")
+        
+        iTranscript2 = Transcript()
+        iTranscript2.copy(iTranscript1)
+        iTranscript2.setName("transcript2")
+        self.assertTrue(iTranscript1.include(iTranscript2))
+        self.assertTrue(iTranscript2.include(iTranscript1))
+
+        iTranscript2.setChromosome("chr2")
+        self.assertFalse(iTranscript1.include(iTranscript2))
+        self.assertFalse(iTranscript2.include(iTranscript1))
+
+        iTranscript2.setChromosome("chr1")
+        exon = Interval()
+        exon.setChromosome("chr1")
+        exon.setDirection("+")
+        exon.setStart(300)
+        exon.setEnd(400)
+        iTranscript1.addExon(exon)
+        self.assertTrue(iTranscript1.include(iTranscript2))
+        self.assertFalse(iTranscript2.include(iTranscript1))
+        
+        exon = Interval()
+        exon.setChromosome("chr1")
+        exon.setDirection("+")
+        exon.setStart(500)
+        exon.setEnd(600)
+        iTranscript2.addExon(exon)
+        self.assertFalse(iTranscript1.include(iTranscript2))
+        self.assertFalse(iTranscript2.include(iTranscript1))
+        
+
+    def test__getDifference(self):
+        iTranscript1 = Transcript()
+        iTranscript1.setName("transcript1")
+        iTranscript1.setChromosome("chr1")
+        iTranscript1.setStart(100)
+        iTranscript1.setEnd(400)
+        iTranscript1.setDirection("+")
+        
+        iTranscript2 = Transcript()
+        iTranscript2.setName("transcript1")
+        iTranscript2.setChromosome("chr1")
+        iTranscript2.setStart(200)
+        iTranscript2.setEnd(400)
+        iTranscript2.setDirection("+")
+
+        newTranscript = iTranscript1.getDifference(iTranscript2)
+        self.assertTrue(newTranscript.getStart(), 100)
+        self.assertTrue(newTranscript.getEnd(),   199)
+        exons = newTranscript.getExons()
+        self.assertTrue(len(exons), 1)
+        exon1 = exons[0]
+        self.assertTrue(exon1.getStart(), 100)
+        self.assertTrue(exon1.getEnd(),   199)
+
+        iTranscript2 = Transcript()
+        iTranscript2.setName("transcript1")
+        iTranscript2.setChromosome("chr1")
+        iTranscript2.setStart(100)
+        iTranscript2.setEnd(200)
+        iTranscript2.setDirection("+")
+
+        newTranscript = iTranscript1.getDifference(iTranscript2)
+        self.assertTrue(newTranscript.getStart(), 201)
+        self.assertTrue(newTranscript.getEnd(),   400)
+        exons = newTranscript.getExons()
+        self.assertTrue(len(exons), 1)
+        exon1 = exons[0]
+        self.assertTrue(exon1.getStart(), 201)
+        self.assertTrue(exon1.getEnd(),   400)
+
+        iTranscript2 = Transcript()
+        iTranscript2.setName("transcript1")
+        iTranscript2.setChromosome("chr1")
+        iTranscript2.setStart(200)
+        iTranscript2.setEnd(300)
+        iTranscript2.setDirection("+")
+
+        newTranscript = iTranscript1.getDifference(iTranscript2)
+        self.assertTrue(newTranscript.getStart(), 100)
+        self.assertTrue(newTranscript.getEnd(),   400)
+        exons = newTranscript.getExons()
+        self.assertTrue(len(exons), 2)
+        exon1, exon2 = exons
+        self.assertTrue(exon1.getStart(), 100)
+        self.assertTrue(exon1.getEnd(),   199)
+        self.assertTrue(exon2.getStart(), 301)
+        self.assertTrue(exon2.getEnd(),   400)
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/structure/test/Test_TranscriptListsComparator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,262 @@
+import os
+import unittest
+from SMART.Java.Python.structure.TranscriptListsComparator import TranscriptListsComparator
+from SMART.Java.Python.structure.TranscriptContainer import TranscriptContainer
+from commons.core.writer.Gff3Writer import Gff3Writer
+from commons.core.parsing.GffParser import GffParser
+from commons.core.utils.FileUtils import FileUtils
+
+SMART_PATH = os.environ["REPET_PATH"] + "/SMART"
+
+class Test_TranscriptListsComparator(unittest.TestCase):
+    
+
+    def test_compareTranscriptList(self):
+        container1 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptList1.bed" % SMART_PATH, "bed", 0)
+        container2 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptList2.bed" % SMART_PATH, "bed", 0)
+        outputContainer = "output.gff3"
+        comparator = TranscriptListsComparator(None, 0)
+        comparator.computeOdds(True)
+        comparator.setInputTranscriptContainer(comparator.QUERY, container1)
+        comparator.setInputTranscriptContainer(comparator.REFERENCE, container2)
+        comparator.setOutputWriter(Gff3Writer(outputContainer, 0))
+        comparator.compareTranscriptList()
+        parser = GffParser("output.gff3", 0)
+        self.assertEqual(parser.getNbTranscripts(), 2)
+        cpt = 0
+        for transcript in parser.getIterator():
+            if cpt == 0:
+                self.assertEqual(transcript.getChromosome(), "arm_X")
+                self.assertEqual(transcript.getStart(), 1000)
+                self.assertEqual(transcript.getEnd(), 1999)
+                self.assertEqual(transcript.getDirection(), 1)
+            elif cpt == 1:
+                self.assertEqual(transcript.getChromosome(), "arm_X")
+                self.assertEqual(transcript.getStart(), 1000)
+                self.assertEqual(transcript.getEnd(), 1999)
+                self.assertEqual(transcript.getDirection(), -1)
+            cpt += 1
+
+
+    def test_compareTranscriptListDistanceSimple(self):
+        container1 = TranscriptContainer("%s/Java/Python/TestFiles/testCompareTranscriptListDistanceSimple1.gff3" % SMART_PATH, "gff", 0)
+        container2 = TranscriptContainer("%s/Java/Python/TestFiles/testCompareTranscriptListDistanceSimple2.gff3" % SMART_PATH, "gff", 0)
+
+        comparator = TranscriptListsComparator(None, 0)
+        comparator.computeOdds(True)
+        comparator.setMaxDistance(1000)
+        comparator.setInputTranscriptContainer(comparator.QUERY, container1)
+        comparator.setInputTranscriptContainer(comparator.REFERENCE, container2)
+        distances = comparator.compareTranscriptListDistance()
+
+        self.assertEqual(distances, {0: 1})
+
+        comparator = TranscriptListsComparator(None, 0)
+        comparator.computeOdds(True)
+        comparator.setMaxDistance(1000)
+        comparator.setInputTranscriptContainer(comparator.QUERY, container2)
+        comparator.setInputTranscriptContainer(comparator.REFERENCE, container1)
+        distances = comparator.compareTranscriptListDistance()
+
+        self.assertEqual(distances, {0: 1, -1000: 1})
+
+
+    def test_compareTranscriptListDistanceAntisense(self):
+        container1 = TranscriptContainer("%s/Java/Python/TestFiles/testCompareTranscriptListDistanceAntisense1.gff3" % SMART_PATH, "gff", 0)
+        container2 = TranscriptContainer("%s/Java/Python/TestFiles/testCompareTranscriptListDistanceAntisense2.gff3" % SMART_PATH, "gff", 0)
+
+        comparator = TranscriptListsComparator(None, 0)
+        comparator.computeOdds(True)
+        comparator.setMaxDistance(10000)
+        comparator.getAntisenseOnly(True)
+        comparator.setInputTranscriptContainer(comparator.QUERY, container1)
+        comparator.setInputTranscriptContainer(comparator.REFERENCE, container2)
+        distances = comparator.compareTranscriptListDistance()
+
+        self.assertEqual(distances, {1000: 1})
+
+
+
+    def test_compareTranscriptListMergeSimple(self):
+        container1 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptListMergeSimple1.bed" % SMART_PATH, "bed", 0)
+        container2 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptListMergeSimple2.bed" % SMART_PATH, "bed", 0)
+        outputContainer = 'output.gff3'
+        comparator = TranscriptListsComparator(None, 0)
+        comparator.computeOdds(True)
+        comparator.setInputTranscriptContainer(comparator.QUERY, container1)
+        comparator.setInputTranscriptContainer(comparator.REFERENCE, container2)
+        comparator.setOutputWriter(Gff3Writer(outputContainer, 0))
+        comparator.compareTranscriptListMerge()
+
+        parser = GffParser(outputContainer, 0)
+        self.assertEqual(parser.getNbTranscripts(), 1)
+        for transcript in parser.getIterator():
+            self.assertEqual(transcript.getChromosome(), "arm_X")
+            self.assertEqual(transcript.getStart(), 1000)
+            self.assertEqual(transcript.getEnd(), 3999)
+            self.assertEqual(transcript.getDirection(), 1)
+            self.assertEqual(transcript.getSize(), 3000)
+
+    def test_compareTranscriptListMergeSenseAntiSenseAway(self):
+        container1 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptListMergeSenseAntiSenseAway1.bed" % SMART_PATH, "bed", 0)
+        container2 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptListMergeSenseAntiSenseAway2.bed" % SMART_PATH, "bed", 0)
+        outputContainer = 'output.gff3'
+        comparator = TranscriptListsComparator(None, 0)
+        comparator.restrictToStart(comparator.QUERY, 2)
+        comparator.restrictToStart(comparator.REFERENCE, 2)
+        comparator.extendFivePrime(comparator.REFERENCE, 150)
+        comparator.getAntisenseOnly(True)
+        comparator.computeOdds(True)
+        comparator.setInputTranscriptContainer(comparator.QUERY, container1)
+        comparator.setInputTranscriptContainer(comparator.REFERENCE, container2)
+        comparator.setOutputWriter(Gff3Writer(outputContainer, 0))
+        comparator.compareTranscriptListMerge()
+
+        parser = GffParser(outputContainer, 0)
+        self.assertEqual(parser.getNbTranscripts(), 1)
+        for transcript in parser.getIterator():
+            self.assertEqual(transcript.getChromosome(), "arm_X")
+            self.assertEqual(transcript.getStart(), 10000048)
+            self.assertEqual(transcript.getEnd(), 10000199)
+            self.assertEqual(transcript.getSize(), 152)
+            self.assertEqual(transcript.getNbExons(), 1)
+
+
+    def test_compareTranscriptListMergeAggregation(self):
+        container1 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptListMergeAggregation1.bed" % SMART_PATH, "bed", 0)
+        container2 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptListMergeAggregation2.bed" % SMART_PATH, "bed", 0)
+        outputContainer = 'output.gff3'
+        comparator = TranscriptListsComparator(None, 0)
+        comparator.getColinearOnly(True)
+        comparator.computeOdds(True)
+        comparator.setInputTranscriptContainer(comparator.QUERY, container1)
+        comparator.setInputTranscriptContainer(comparator.REFERENCE, container2)
+        comparator.aggregate(True)
+        comparator.setOutputWriter(Gff3Writer(outputContainer, 0))
+        comparator.compareTranscriptListMerge()
+
+        parser = GffParser(outputContainer, 0)
+        self.assertEqual(parser.getNbTranscripts(), 1)
+        for transcript in parser.getIterator():
+            self.assertEqual(transcript.getChromosome(), "arm_X")
+            self.assertEqual(transcript.getStart(), 10000000)
+            self.assertEqual(transcript.getEnd(), 10000199)
+            self.assertEqual(transcript.getSize(), 200)
+            self.assertEqual(transcript.getNbExons(), 1)
+
+
+    def test_compareTranscriptListSelfMerge(self):
+        container1 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptListSelfMerge1.gff3" % SMART_PATH, "gff", 0)
+
+        comparator = TranscriptListsComparator(None, 0)
+        comparator.computeOdds(True)
+        comparator.setInputTranscriptContainer(comparator.QUERY, container1)
+        comparator.setOutputWriter(Gff3Writer("output.gff3", 0))
+        comparator.compareTranscriptListSelfMerge()
+
+        parser = GffParser("output.gff3", 0)
+        self.assertEqual(parser.getNbTranscripts(), 1)
+        for transcript in parser.getIterator():
+            self.assertEqual(transcript.getChromosome(), "arm_X")
+            self.assertEqual(transcript.getStart(), 1000)
+            self.assertEqual(transcript.getEnd(), 2000)
+            self.assertEqual(transcript.getDirection(), 1)
+            self.assertEqual(transcript.getNbExons(), 1)
+            self.assertEqual(transcript.getSize(), 1001)
+            self.assertEqual(float(transcript.getTagValue("nbElements")), 3)
+
+
+    def test_compareTranscriptListSelfMergeSense(self):
+        container1 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptListSelfMerge1.gff3" % SMART_PATH, "gff", 0)
+
+        comparator = TranscriptListsComparator(None, 0)
+        comparator.getColinearOnly(True)
+        comparator.computeOdds(True)
+        comparator.setInputTranscriptContainer(comparator.QUERY, container1)
+        comparator.setOutputWriter(Gff3Writer("output.gff3", 0))
+        comparator.compareTranscriptListSelfMerge()
+
+        parser = GffParser("%s/SMART/Java/Python/structure/test/output.gff3" % os.environ["REPET_PATH"], 0) 
+        self.assertEqual(parser.getNbTranscripts(), 1)
+        for transcript in parser.getIterator():
+            self.assertEqual(transcript.getChromosome(), "arm_X")
+            self.assertEqual(transcript.getStart(), 1000)
+            self.assertEqual(transcript.getEnd(), 2000)
+            self.assertEqual(transcript.getDirection(), 1)
+            self.assertEqual(transcript.getNbExons(), 1)
+            self.assertEqual(transcript.getSize(), 1001)
+
+    def test_compareTranscriptListSelfMergeDifferentClusters(self):
+        container1 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptListSelfMergeDifferentClusters1.bed" % SMART_PATH, "bed", 0)
+        comparator = TranscriptListsComparator(None, 0)
+        comparator.setInputTranscriptContainer(comparator.QUERY, container1)
+        comparator.setOutputWriter(Gff3Writer("output.gff3", 0))
+        comparator.compareTranscriptListSelfMerge()
+
+        parser = GffParser("output.gff3", 0)
+        self.assertEquals(parser.getNbTranscripts(), 1)
+        for transcript in parser.getIterator():
+            self.assertEqual(transcript.getChromosome(), "arm_X")
+            self.assertEqual(transcript.getStart(), 100)
+            self.assertEqual(transcript.getEnd(), 100099)
+            self.assertEqual(transcript.getDirection(), 1)
+            self.assertEqual(transcript.getNbExons(), 1)
+            self.assertEqual(transcript.getSize(), 100000)
+
+
+    def test_compareTranscriptListgetDifferenceTranscriptList(self):
+        container1 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptListGetDifference1.gff3" % SMART_PATH, "gff", 0)
+        container2 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptListGetDifference2.gff3" % SMART_PATH, "gff", 0)
+
+        comparator = TranscriptListsComparator(None, 0)
+        comparator.setInputTranscriptContainer(comparator.QUERY, container1)
+        comparator.setInputTranscriptContainer(comparator.REFERENCE, container2)
+        comparator.setOutputWriter(Gff3Writer("output.gff3", 0))
+        comparator.getDifferenceTranscriptList()
+
+        parser = GffParser("output.gff3", 0)
+        self.assertEqual(parser.getNbTranscripts(), 1)
+        for transcript in parser.getIterator():
+            self.assertEqual(transcript.getChromosome(), "arm_X")
+            self.assertEqual(transcript.getStart(), 1000)
+            self.assertEqual(transcript.getEnd(), 4000)
+            self.assertEqual(transcript.getDirection(), 1)
+            self.assertEqual(transcript.getNbExons(), 2)
+            exon1, exon2 = transcript.getExons()
+            self.assertEqual(exon1.getStart(), 1000)
+            self.assertEqual(exon1.getEnd(), 1999)
+            self.assertEqual(exon2.getStart(), 3001)
+            self.assertEqual(exon2.getEnd(), 4000)
+
+
+
+    def test_compareTranscriptListgetDifferenceTranscriptListSplit(self):
+        container1 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptListGetDifference1.gff3" % SMART_PATH, "gff", 0)
+        container2 = TranscriptContainer("%s/Java/Python/TestFiles/testTranscriptListsComparatorCompareTranscriptListGetDifference2.gff3" % SMART_PATH, "gff", 0)
+
+        comparator = TranscriptListsComparator(None, 0)
+        comparator.setInputTranscriptContainer(comparator.QUERY, container1)
+        comparator.setInputTranscriptContainer(comparator.REFERENCE, container2)
+        comparator.setSplitDifference(True)
+        comparator.setOutputWriter(Gff3Writer("output.gff3", 0))
+        comparator.getDifferenceTranscriptList()
+
+        parser = GffParser("output.gff3", 0)
+        self.assertEqual(parser.getNbTranscripts(), 2)
+        for id, transcript in enumerate(parser.getIterator()):
+            if id == 0:
+                self.assertEqual(transcript.getChromosome(), "arm_X")
+                self.assertEqual(transcript.getStart(), 1000)
+                self.assertEqual(transcript.getEnd(), 1999)
+                self.assertEqual(transcript.getDirection(), 1)
+                self.assertEqual(transcript.getNbExons(), 1)
+            else:
+                self.assertEqual(transcript.getChromosome(), "arm_X")
+                self.assertEqual(transcript.getStart(), 3001)
+                self.assertEqual(transcript.getEnd(), 4000)
+                self.assertEqual(transcript.getDirection(), 1)
+                self.assertEqual(transcript.getNbExons(), 1)
+
+
+if __name__ == '__main__':
+        unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/testInstall.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,103 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""
+Test if the configuration is sound
+"""
+
+import sys
+import os
+import subprocess
+
+# Test Python files
+try :
+    from SMART.Java.Python.misc.RPlotter import *
+except:
+    print "Cannot find Python scripts! Update PYTHONPATH (currently %s) environment variable and see configuration in the documentation!" % (os.environ["PYTHONPATH"] if "PYTHONPATH" in os.environ else "empty")
+    sys.exit(3)
+
+try :
+    from SMART.Java.Python.mySql.MySqlTranscriptTable import *
+    from SMART.Java.Python.mySql.MySqlConnection import *
+except:
+    print "SQLite is not installed ! Please read the documentation!"
+    sys.exit(4)
+
+
+if __name__ == "__main__":
+    
+    print "Python scripts are correctly read."
+    
+    # Test mySQL
+    connection = MySqlConnection()
+    table = MySqlTranscriptTable(connection)
+
+    try:
+        table.createTranscriptTable()
+    except:
+        print "Cannot connect to the SQLite database! See configuration in the documentation!"
+        sys.exit(5)
+        
+    print "SQLite database is correctly set up."
+
+        
+    # Test R
+    fileName = "tmpFile.R"
+    file = open(fileName, "w")
+    file.write("?licence\n")
+    file.close()
+    rCommand = "R"
+    if "SMARTRPATH" in os.environ:
+        rCommand = os.environ["SMARTRPATH"]
+    command = "\"%s\" CMD BATCH %s" % (rCommand, fileName)
+    status    = subprocess.call(command, shell=True)
+    os.remove(fileName)
+    outputFileName = "%sout" % (fileName)
+    if os.path.exists(outputFileName):
+        os.remove(outputFileName)
+
+    if status != 0:
+        print "Problem with the execution of R script (command '%s' did not work, current directory is %s, status is %d)! See configuration in the documentation!" % (command, os.getcwd(), status)
+        sys.exit(6)
+
+    line = {0: 1, 1: 2}
+    pngFileName = "tmpFile.png"
+    plotter = RPlotter(pngFileName)
+    plotter.addLine(line)
+    try:
+        plotter.plot()
+    except:
+        print "Problem with the execution of R script: library 'RColorBrewer' is missing! See configuration in the documentation!"
+        sys.exit(7)
+    os.remove(pngFileName)
+
+    print "R is available."
+
+    print "Set up is fine! Enjoy S-MART!"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/toolLauncher/RnaFoldLauncher.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,379 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os
+import sys
+import random
+import subprocess
+from SMART.Java.Python.structure.TranscriptList import TranscriptList
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.misc.Progress import Progress
+from commons.core.parsing.FastaParser import FastaParser
+
+
+class RnaFoldStructure(object):
+    """
+    A structure to store the output of RNAFold
+    @ivar name:         the name of the sequence
+    @type name:         string
+    @ivar sequence:     the sequence (with gaps)
+    @type sequence:     string
+    @ivar structure:    the bracket structure
+    @type structure:    string
+    @ivar energy:       the energy of the fold
+    @type energy:       float
+    @ivar interactions: the interactions inside the structure
+    @ivar interactions: the interactions inside the structure
+    """
+
+    def __init__(self, name, sequence, structure, energy):
+        """
+        Initialize the structure
+        @param name       the name of the sequence
+        @type  name:      string
+        @param sequence:  the sequence (with gaps)
+        @type  sequence:  string
+        @param structure: the bracket structure
+        @type  structure: string
+        @param energy:    the energy of the fold
+        @type  energy:    float
+        """
+        self.name         = name        
+        self.sequence     = sequence
+        self.structure    = structure
+        self.energy       = energy
+        self.interactions = None
+
+    
+    def analyze(self):
+        """
+        Analyze the output, assign the interactions
+        """
+        if len(self.sequence) != len(self.structure):
+            sys.exit("Sizes of sequence and structure differ ('%s' and '%s')!\n" % (self.sequence, self.structure))
+        stack                         = []
+        self.interactions = [None for i in range(len(self.sequence))]
+        for i in range(len(self.sequence)):
+            if self.structure[i] == "(":
+                stack.append(i)
+            elif self.structure[i] == ")":
+                if not stack:
+                    sys.exit("Something wrong in the interaction line '%s'!\n" % (self.structure))
+                otherI = stack.pop()
+                self.interactions[i]      = otherI
+                self.interactions[otherI] = i
+        if stack:
+            sys.exit("Something wrong in the interaction line '%s'!\n" % (self.structure))
+
+
+    def getNbBulges(self, start = None, end = None):
+        """
+        Get the number of insertions in a given range (in number of letters)
+        @param start: where to start the count
+        @type    start: int
+        @param end:     where to end the co
+        @type    end:     int
+        """
+        if start == None:
+            start = 0
+        if end == None:
+            end = len(self.sequence)
+        previousInt = None
+        nbBulges    = 0
+        inRegion    = False
+        for i in range(len(self.sequence)):
+            if i == start:
+                inRegion = True
+            if i > end:
+                return nbBulges
+            if inRegion:
+                if self.interactions[i] == None:
+                    nbBulges += 1
+                elif previousInt != None and abs(self.interactions[i] - previousInt) != 1:
+                    nbBulges += 1
+            previousInt = self.interactions[i]
+        return nbBulges
+
+
+    def getStar(self, start = None, end = None):
+        """
+        Get the supposed miRNA*
+        @param start: where to start the count
+        @type    start: int
+        @param end:     where to end the co
+        @type    end:     int
+        """
+        if start == None:
+            start = 0
+        if end == None:
+            end = len(self.sequence)
+        minStar  = 1000000
+        maxStar  = 0
+        inRegion = False
+        for i in range(len(self.sequence)):
+            if i == start:
+                inRegion = True
+            if i > end:
+                return (minStar, maxStar)
+            if inRegion:
+                if self.interactions[i] != None:
+                    minStar = min(minStar, self.interactions[i])
+                    maxStar = max(maxStar, self.interactions[i])
+        return (minStar, maxStar)
+
+
+
+class RnaFoldLauncher(object):
+    """
+    Start and parse a RNAFold instance
+    @ivar inputTranscriptList:  a list of transcripts
+    @type inputTranscriptList:  class L{TranscriptList<TranscriptList>}
+    @ivar genomeFileParser:     a parser to the genome file
+    @type genomeFileParser:     class L{SequenceListParser<SequenceListParser>}
+    @ivar bothStrands:          whether folding is done on both strands
+    @type bothStrands:          bool
+    @ivar fivePrimeExtension:   extension towards the 5' end
+    @type fivePrimeExtension:   int
+    @ivar threePrimeExtension:  extension towards the 3' end
+    @type threePrimeExtension:  int
+    @ivar inputTranscriptList:  the input list of transcripts
+    @type inputTranscriptList:  class L{TranscriptList<TranscriptList>}
+    @ivar outputTranscriptList: the output list of transcripts
+    @type outputTranscriptList: class L{TranscriptList<TranscriptList>}
+    @ivar tmpInputFileName:     the name of the temporary input file for RNAFold
+    @type tmpInputFileName:     string
+    @ivar tmpOutputFileName:    the name of the temporary output file for RNAFold
+    @type tmpOutputFileName:    string
+    @ivar verbosity:            verbosity
+    @type verbosity:            int [default: 0]
+    """
+
+    def __init__(self, verbosity = 0):
+        """
+        Constructor
+        @param verbosity: verbosity
+        @type  verbosity: int
+        """
+        self.verbosity            = verbosity
+        self.transcriptNames      = []
+        randomNumber              = random.randint(0, 100000)
+        self.bothStrands          = True
+        self.tmpInputFileName     = "tmpInput_%d.fas" % (randomNumber)
+        self.tmpOutputFileName    = "tmpOutput_%d.fas" % (randomNumber)
+        self.outputTranscriptList = None
+        self.fivePrimeExtension   = 0
+        self.threePrimeExtension  = 0
+
+
+    def __del__(self):
+        for file in (self.tmpInputFileName, self.tmpOutputFileName):
+            if os.path.isfile(file):
+                os.remove(file)
+
+
+    def setTranscriptList(self, inputTranscriptList):
+        """
+        Set the list of transcripts
+        @ivar inputTranscriptList: a list of transcripts
+        @type inputTranscriptList: class L{TranscriptList<TranscriptList>}
+        """
+        self.inputTranscriptList = inputTranscriptList
+
+
+    def setExtensions(self, fivePrime, threePrime):
+        """
+        Set extension sizes
+        @ivar fivePrime:  extension towards the 5' end
+        @type fivePrime:  int
+        @ivar threePrime: extension towards the 3' end
+        @type threePrime: int
+        """
+        self.fivePrimeExtension  = fivePrime
+        self.threePrimeExtension = threePrime
+
+
+    def setNbStrands(self, nbStrands):
+        """
+        Set number of strands
+        @ivar nbStrands: if 2, the work is done on both strands
+        @type nbStrands: int
+        """
+        self.nbStrands = nbStrands
+
+
+    def setGenomeFile(self, fileName):
+        """
+        Set the genome file
+        @ivar genomeFileName: the multi-FASTA file containing the genome
+        @type genomeFileName: a string
+        """
+        self.genomeFileParser = FastaParser(fileName, self.verbosity)
+
+
+    def writeInputFile(self, transcript, reverse, fivePrimeExtension, threePrimeExtension):
+        """
+        Write the RNAFold input file, containing the sequence corresponding to the transcript
+        @ivar transcript: a transcript
+        @type transcript: class L{Transcript<Transcript>}
+        @ivar reverse:    invert the extensions
+        @type reverse:    bool
+        """
+        transcriptCopy = Transcript(transcript)
+        transcriptCopy.removeExons()
+        if not reverse:
+            transcriptCopy.extendStart(fivePrimeExtension)
+            transcriptCopy.extendEnd(threePrimeExtension)
+        else:
+            transcriptCopy.extendStart(threePrimeExtension)
+            transcriptCopy.extendEnd(fivePrimeExtension)
+        sequence = transcriptCopy.extractSequence(self.genomeFileParser)
+        handle   = open(self.tmpInputFileName, "w")
+        handle.write(">%s\n%s\n" % (sequence.getName().replace(":", "_").replace(".", "_"), sequence.getSequence()))
+        handle.close()
+
+
+    def startRnaFold(self):
+        """
+        Start RNAFold
+        """
+        command = "RNAfold < %s > %s" % (self.tmpInputFileName, self.tmpOutputFileName)
+        if self.verbosity > 100:
+            print "Launching command '%s'" % (command)
+        status = subprocess.call(command, shell=True)
+        if status != 0:
+            raise Exception("Problem with RNAFold! Input file is %s, status is: %s" % (self.tmpInputFileName, status))
+
+    
+    def parseRnaFoldOutput(self):
+        """
+        Parse an output file of RNAFold
+        @return: an RnaFoldStructure
+        """
+        lines = open(self.tmpOutputFileName).readlines()
+        if len(lines) != 3:
+            raise Exception("Problem in RNAfold output! '%s'" % (lines))
+        name      = lines[0].strip()[1:].split()[0]
+        sequence  = lines[1].strip()
+        structure = lines[2].strip().split()[0]
+        energy    = float(lines[2].strip().split(" ", 1)[1][1:-1].strip())
+        if self.verbosity > 100:
+            print "Getting sequence %s, structure %s" % (sequence, structure)
+        return RnaFoldStructure(name, sequence, structure, energy)
+
+
+    def analyzeRnaFoldOutput(self, transcript, rnaFoldOutput, reverse, fivePrimeExtension, threePrimeExtension):
+        """
+        Analyze the RNAFold
+        @ivar transcript:    a transcript
+        @type transcript:    class L{Transcript<Transcript>}
+        @ivar rnaFoldOutput: the output of RNAFold
+        @type rnaFoldOutput: class L{RnaFoldStructure<RnaFoldStructure>}
+        @ivar reverse:       invert the extensions
+        @type reverse:       bool
+        @return:             a t-uple of energy, number of insertions, number of bulges, strand
+        """
+        rnaFoldOutput.analyze()
+        transcriptSize     = transcript.end - transcript.start + 1
+        start              = fivePrimeExtension if not reverse else threePrimeExtension
+        end                = start + transcriptSize
+        energy             = rnaFoldOutput.energy
+        nbBulges           = rnaFoldOutput.getNbBulges(start, end)
+        (minStar, maxStar) = rnaFoldOutput.getStar(start, end)
+        minStar           += transcript.start - start
+        maxStar           += transcript.start - start
+        if self.verbosity > 100:
+            print "Getting structure with energy %d, nbBulges %d, miRna* %d-%d, strand %s" % (energy, nbBulges, minStar, maxStar, "-" if reverse else "+")
+        return (energy, nbBulges, minStar, maxStar, reverse)
+
+    
+    def fold(self, transcript):
+        """
+        Fold a transcript (in each strand)
+        @ivar transcript: a transcript
+        @type transcript: class L{Transcript<Transcript>}
+        @return:          a t-uple of energy, number of insertions, number of bulges, strand
+        """
+        results     = [None] * self.nbStrands
+        strands     = [False, True] if self.nbStrands == 2 else [False]
+        minNbBulges = 1000000
+        for i, reverse in enumerate(strands):
+            self.writeInputFile(transcript, reverse, self.fivePrimeExtension, self.threePrimeExtension)
+            self.startRnaFold()
+            output = self.parseRnaFoldOutput()
+            results[i]  = self.analyzeRnaFoldOutput(transcript, output, reverse, self.fivePrimeExtension, self.threePrimeExtension)
+            minNbBulges = min(minNbBulges, results[i][1])
+        for result in results:
+            if result[1] == minNbBulges:
+                return result
+        return None
+
+
+    def refold(self, transcript):
+        """
+        Fold a transcript, knowing where the miRNA starts and end
+        @ivar transcript: a transcript
+        @type transcript: class L{Transcript<Transcript>}
+        @return:          the energy
+        """
+        miStar              = transcript.getTagValue("miRnaStar")
+        startMiStar         = int(miStar.split("-")[0])
+        endMiStart          = int(miStar.split("-")[1])
+        fivePrimeExtension  = max(0, transcript.start - startMiStar) + 5
+        threePrimeExtension = max(0, endMiStart - transcript.end) + 5
+        self.writeInputFile(transcript, False, fivePrimeExtension, threePrimeExtension)
+        self.startRnaFold()
+        output = self.parseRnaFoldOutput()
+        result = self.analyzeRnaFoldOutput(transcript, output, False, fivePrimeExtension, threePrimeExtension)
+        return result[0]
+
+
+    def computeResults(self):
+        """
+        Fold all and fill an output transcript list with the values
+        """
+        progress = Progress(self.inputTranscriptList.getNbTranscripts(), "Handling transcripts", self.verbosity)
+        self.outputTranscriptList = TranscriptList()
+        for transcript in self.inputTranscriptList.getIterator():
+            result = self.fold(transcript)
+            transcript.setTagValue("nbBulges", result[1])
+            transcript.setTagValue("miRnaStar", "%d-%d" % (result[2], result[3]))
+            transcript.setTagValue("miRNAstrand", result[4])
+            transcript.setTagValue("energy", self.refold(transcript))
+            self.outputTranscriptList.addTranscript(transcript)
+            progress.inc()
+        progress.done()
+
+
+    def getResults(self):
+        """
+        Get an output transcript list with the values
+        """
+        if self.outputTranscriptList == None:
+            self.computeResults()
+        return self.outputTranscriptList
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/trimAdaptor.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,107 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Trim the sequences from a 5' adaptor"""
+
+import sys
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import FastaParser
+from commons.core.parsing.FastqParser import FastqParser
+from commons.core.writer.FastaWriter import FastaWriter
+from commons.core.writer.FastqWriter import FastqWriter
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc import Utils
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Trim Adaptor v1.0.1: Remove the 3' adaptor of a list of reads. [Category: Data Modification]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",               type="string", help="input file [compulsory] [format: file in sequence format given by -f]")
+    parser.add_option("-f", "--format",    dest="format",         action="store",               type="string", help="format of file [compulsory] [format: sequence file format]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",               type="string", help="output file [compulsory] [format: output file in sequence format given by -f]")
+    parser.add_option("-a", "--adaptor",   dest="adaptor",        action="store",               type="string", help="adaptor [compulsory] [format: string]")
+    parser.add_option("-e", "--errors",    dest="errors",         action="store", default=0,    type="int" ,   help="number of errors in percent [format: int] [default: 0]")
+    parser.add_option("-n", "--noAdaptor", dest="noAdaptor",      action="store", default=None, type="string", help="file name where to print sequences with no adaptor [format: output file in sequence format given by -f]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store", default=1,    type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    minSize = 2
+
+    if options.format == "fasta":
+        parser = FastaParser(options.inputFileName, options.verbosity)
+    elif options.format == "fastq":
+        parser = FastqParser(options.inputFileName, options.verbosity)
+    else:
+        sys.exit("Cannot handle files with '%s' format." % (options.format))
+
+    if options.format == "fasta":
+        writer = FastaWriter(options.outputFileName, options.verbosity)
+    elif options.format == "fastq":
+        writer = FastqWriter(options.outputFileName, options.verbosity)
+    else:
+        sys.exit("Cannot handle files with '%s' format." % (options.format))
+
+    writerNoAdaptor = None
+    if options.noAdaptor != None:
+        if options.format == "fasta":
+            writerNoAdaptor = FastaWriter(options.noAdaptor, options.verbosity)
+        elif options.format == "fastq":
+            writerNoAdaptor = FastqWriter(options.noAdaptor, options.verbosity)
+        else:
+            sys.exit("Cannot handle files with '%s' format." % (options.format))
+
+    nbFound = 0
+        
+    progress = Progress(parser.getNbSequences(), "Reading %s" % (options.inputFileName), options.verbosity)
+    for sequence in parser.getIterator():
+        progress.inc()
+        nucleotides = sequence.getSequence()
+        found       = False
+        for i in range(len(nucleotides) - minSize):
+            nucleotidesPart = nucleotides[i:]
+            adaptorPart     = options.adaptor if len(nucleotidesPart) >= len(options.adaptor) else options.adaptor[:len(nucleotidesPart)]
+            nucleotidesPart = nucleotidesPart if len(adaptorPart) == len(nucleotidesPart) else nucleotidesPart[:len(adaptorPart)]
+            if Utils.getHammingDistance(adaptorPart, nucleotidesPart) <= int(options.errors / 100.0 * len(adaptorPart)):
+                nbFound += 1
+                sequence.shrinkToFirstNucleotides(i)
+                writer.addSequence(sequence)
+                found = True
+                break
+        if not found:
+            writer.addSequence(sequence)
+            if writerNoAdaptor != None:
+                writerNoAdaptor.addSequence(sequence)
+    progress.done()
+
+    print "%d sequences with adaptors on %d (%.2f%%)" % (nbFound, parser.getNbSequences(), float(nbFound) / parser.getNbSequences() * 100)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/trimSequence.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,102 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Remove sequences with low reliability"""
+
+from optparse import OptionParser
+from commons.core.parsing.SequenceListParser import *
+from commons.core.writer.FastaWriter import *
+from SMART.Java.Python.misc.Progress import *
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Trim Sequences v1.0.1: Remove sequences with low reliability: low occurrences and highly repeted. [Category: Personnal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",         dest="inputFileName",    action="store",                                         type="string", help="input file [compulsory] [format: file in FASTA format]")
+    parser.add_option("-o", "--output",        dest="outputFileName", action="store",                                         type="string", help="output file [compulsory] [format: output file in FASTA format]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",            action="store",            default=1,         type="int",        help="trace level [format: int]")
+    parser.add_option("-l", "--log",             dest="log",                        action="store_true", default=False,                                help="write a log file [format: bool] [default: false]")
+    (options, args) = parser.parse_args()
+
+    parser            = SequenceListParser(options.inputFileName, options.verbosity)
+    nbSequences = parser.getNbSequences()
+    progress        = Progress(nbSequences, "Parsing file %s" % (options.inputFileName), options.verbosity)
+    
+    writer = FastaWriter(options.outputFileName, options.verbosity)
+    if options.log:
+        logHandle = open("log.txt", "w")
+    
+    letters                            = ("A", "C", "G", "T")
+    nbLowComplexity            = 0
+    nbTooManyOccurrences = 0
+    
+    for sequence in parser.getIteractor():
+        halfSize                     = len(sequence.sequence) / 2
+        occurrences                = set()
+        nbOccurrences            = dict(zip(letters, [0 for letter in letters]))
+        tooManyOccurrences = False
+        good                             = True
+        
+        for char in sequence.sequence:
+            if char in letters:
+                occurrences.add(char)
+                nbOccurrences[char] += 1
+                
+            
+        if len(occurrences) < 4:
+            nbLowComplexity += 1
+            if options.log:
+                logHandle.write("Low complexity for %s\n" % (sequence.sequence))
+            good = False
+
+        if good:
+            for letter, nbOccurrence in nbOccurrences.iteritems():
+                if nbOccurrence > halfSize:
+                    if not tooManyOccurrences:
+                        nbTooManyOccurrences += 1
+                        if options.log:
+                            logHandle.write("Too many occurrences for %s\n" % (sequence.sequence))
+                    tooManyOccurrences = True
+                    good = False
+            
+        if good:
+            writer.addSequence(sequence)
+                    
+        progress.inc()
+    progress.done()
+    
+    if options.log:
+        logHandle.close()
+        
+    print "%d out of %d have low complexity (%f%%)"             % (nbLowComplexity, nbSequences, (float(nbLowComplexity) / nbSequences * 100))        
+    print "%d out of %d have too many occurrences (%f%%)" % (nbTooManyOccurrences, nbSequences, (float(nbTooManyOccurrences) / nbSequences * 100))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/trimSequences.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,149 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import FastaParser
+from commons.core.parsing.FastqParser import FastqParser
+from commons.core.writer.FastaWriter import FastaWriter
+from commons.core.writer.FastqWriter import FastqWriter
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc import Utils
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Trim Sequences v1.0.3: Remove the 5' and/or 3' adaptors of a list of reads. [Category: Data Modification]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",         dest="inputFileName",  action="store",                     type="string", help="input file [compulsory] [format: file in sequence format given by -f]")
+    parser.add_option("-f", "--format",        dest="format",         action="store",                     type="string", help="format of file [compulsory] [format: sequence file format]")
+    parser.add_option("-o", "--output",        dest="outputFileName", action="store",                     type="string", help="output file [compulsory] [format: output file in sequence format given by -f]")
+    parser.add_option("-3", "--threePAdaptor", dest="threePAdaptor",  action="store",      default=None,  type="string", help="3' adaptor [format: string] [default: None]")
+    parser.add_option("-5", "--fivePAdaptor",  dest="fivePAdaptor",   action="store",      default=None,  type="string", help="5' adaptor [format: string] [default: None]")
+    parser.add_option("-e", "--errors",        dest="errors",         action="store",      default=0,     type="int",    help="number of errors in percent [format: int] [default: 0]")
+    parser.add_option("-d", "--indels",        dest="indels",         action="store_true", default=False,                help="also accept indels [format: bool] [default: False]")
+    parser.add_option("-n", "--noAdaptor5p",   dest="noAdaptor5p",    action="store",      default=None,  type="string", help="print sequences with no 5' adaptor [format: output file in sequence format given by -f]")
+    parser.add_option("-m", "--noAdaptor3p",   dest="noAdaptor3p",    action="store",      default=None,  type="string", help="print sequences with no 3' adaptor [format: output file in sequence format given by -f]")
+    parser.add_option("-v", "--verbosity",     dest="verbosity",      action="store",      default=1,     type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    minSize = 3
+
+    if options.format == "fasta":
+        parser = FastaParser(options.inputFileName, options.verbosity)
+    elif options.format == "fastq":
+        parser = FastqParser(options.inputFileName, options.verbosity)
+    else:
+        raise Exception("Cannot handle files with '%s' format." % (options.format))
+
+    if options.format == "fasta":
+        writer = FastaWriter(options.outputFileName, options.verbosity)
+    elif options.format == "fastq":
+        writer = FastqWriter(options.outputFileName, options.verbosity)
+    else:
+        raise Exception("Cannot handle files with '%s' format." % (options.format))
+
+
+    if options.noAdaptor5p != None:
+        if options.format == "fasta":
+            writer5pNoAdaptor = FastaWriter(options.noAdaptor5p, options.verbosity)
+        elif options.format == "fastq":
+            writer5pNoAdaptor = FastqWriter(options.noAdaptor5p, options.verbosity)
+        else:
+            raise Exception("Cannot handle files with '%s' format." % (options.format))
+    nbFound5p = 0
+    
+    if options.noAdaptor3p != None:
+        if options.format == "fasta":
+            writer3pNoAdaptor = FastaWriter(options.noAdaptor3p, options.verbosity)
+        elif options.format == "fastq":
+            writer3pNoAdaptor = FastqWriter(options.noAdaptor3p, options.verbosity)
+        else:
+            raise Exception("Cannot handle files with '%s' format." % (options.format))
+    nbFound3p = 0
+            
+    progress = Progress(parser.getNbSequences(), "Reading %s" % (options.inputFileName), options.verbosity)
+    for sequence in parser.getIterator():
+        progress.inc()
+        if options.threePAdaptor != None:
+            nucleotides = sequence.sequence
+            found       = False
+            bestScore   = 10000
+            bestRegion  = 0
+            for i in range(len(nucleotides) - minSize):
+                nucleotidesPart = nucleotides[i:]
+                adaptorPart     = options.threePAdaptor if len(nucleotidesPart) >= len(options.threePAdaptor) else options.threePAdaptor[:len(nucleotidesPart)]
+                nucleotidesPart = nucleotidesPart if len(adaptorPart) == len(nucleotidesPart) else nucleotidesPart[:len(adaptorPart)]
+                if options.indels:
+                    score = Utils.getLevenshteinDistance(adaptorPart, nucleotidesPart)
+                else:
+                    score = Utils.getHammingDistance(adaptorPart, nucleotidesPart)
+                if score <= int(options.errors / 100.0 * len(adaptorPart)) and score < bestScore:
+                    bestScore  = score
+                    bestRegion = i
+                    found      = True
+            if found:
+                nbFound3p += 1
+                sequence.shrinkToFirstNucleotides(bestRegion)
+            elif options.noAdaptor3p:
+                writer3pNoAdaptor.addSequence(sequence)
+        if options.fivePAdaptor != None:
+            nucleotides = sequence.sequence
+            found       = False
+            bestScore   = 10000
+            bestRegion  = 0
+            for i in reversed(range(minSize, len(nucleotides))):
+                nucleotidesPart = nucleotides[:i]
+                adaptorPart     = options.fivePAdaptor if len(nucleotidesPart) >= len(options.fivePAdaptor) else options.fivePAdaptor[-len(nucleotidesPart):]
+                nucleotidesPart = nucleotidesPart if len(adaptorPart) == len(nucleotidesPart) else nucleotidesPart[-len(adaptorPart):]
+                if options.indels:
+                    score = Utils.getLevenshteinDistance(adaptorPart, nucleotidesPart)
+                else:
+                    score = Utils.getHammingDistance(adaptorPart, nucleotidesPart)
+                if score <= int(options.errors / 100.0 * len(adaptorPart)) and score < bestScore:
+                    bestScore  = score
+                    bestRegion = i
+                    found      = True
+            if found:
+                nbFound5p += 1
+                sequence.shrinkToLastNucleotides(len(nucleotides) - bestRegion)
+            elif options.noAdaptor5p:
+                writer5pNoAdaptor.addSequence(sequence)
+        writer.addSequence(sequence)
+    progress.done()
+    writer.close()
+
+    print "%d sequences" % (parser.getNbSequences())
+    if options.fivePAdaptor != None:
+        print "%d sequences with 5' adaptors (%.2f%%)" % (nbFound5p, float(nbFound5p) / parser.getNbSequences() * 100)
+    if options.threePAdaptor != None:
+        print "%d sequences with 3' adaptors (%.2f%%)" % (nbFound3p, float(nbFound3p) / parser.getNbSequences() * 100)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/txtToFasta.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,63 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Transform a plain text file to a FASTA file"""
+
+import os
+from optparse import OptionParser
+from SMART.Java.Python.structure.Sequence import *
+from SMART.Java.Python.misc.Progress import *
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    parser = OptionParser()
+    description = "Txt to Fasta v1.0.1: Convert a Txt file (one sequence per line) into Fasta file. [Category: Personnal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",     dest="inputFileName",  action="store",            type="string", help="input file [compulsory] [format: file in TXT format]")
+    parser.add_option("-o", "--output",    dest="outputFileName", action="store",            type="string", help="output file [compulsory] [format: output file in FASTA format]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",      action="store", default=1, type="int",    help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    inputFile = open(options.inputFileName)
+    outputFile = open(options.outputFileName, "w")
+    
+    for line in inputFile:
+        line = line.strip()
+        splittedLine = line.split()
+        sequence = splittedLine[0]
+        nb = 1 if len(splittedLine) == 1 else int(splittedLine[1])
+        for i in range(nb):
+            outputFile.write(">%s\n%s\n" % (sequence, sequence))
+    
+    inputFile.close()
+    outputFile.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/updateQual.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,86 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Update a .qual file given a .fasta file"""
+
+from optparse import OptionParser
+from commons.core.parsing.FastaParser import *
+from SMART.Java.Python.misc.Progress import *
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Update Qual v1.0.1: Remove the sequence in a Qual file which are not in the corresponding Fasta file. [Category: Personnal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-f", "--fasta",         dest="fastaFile",    action="store",                                         type="string", help="fasta file [compulsory] [format: file in FASTA format]")
+    parser.add_option("-q", "--qual",            dest="qualFile",     action="store",                                         type="string", help="qual file [compulsory] [format: file in QUAL format]")
+    parser.add_option("-o", "--output",        dest="outputFile", action="store",                                         type="string", help="output file [compulsory] [format: output file in QUAL format]")
+    parser.add_option("-v", "--verbosity", dest="verbosity",    action="store",            default=1,         type="int",        help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    parser             = SequenceListParser(options.fastaFile, options.verbosity)
+    nbSequences    = parser.getNbSequences()
+    progress         = Progress(nbSequences, "Parsing file %s" % (options.fastaFile), options.verbosity)
+    qualHandle     = open(options.qualFile)
+    outputHandle = open(options.outputFile, "w")
+    nbRefused        = 0
+    nbTotal            = 0
+    
+    names = []
+    while parser.getNextSequence():
+        sequence = parser.getCurrentSequence()
+        nbTotal += 1
+    
+        found = False
+        name    = None
+        for line in qualHandle:
+            line = line.strip()
+            if line[0] == ">":
+                name = line[1:]
+                if name == sequence.name:
+                    found = True
+                else:
+                    nbRefused += 1
+            else:
+                if found:
+                    outputHandle.write(">%s\n%s\n" % (name, line))
+                    found = False
+                    name    = None
+                    break
+        progress.inc()
+    progress.done()
+
+    
+    outputHandle.close()
+    qualHandle.close()
+    
+    print "%d out of %d are refused (%f%%)"             % (nbRefused, nbTotal, (float(nbRefused) / nbTotal * 100))        
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/wigExploder.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,99 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Explode wig files into several files, one for each chromosome"""
+
+import os, re, sys
+from optparse import OptionParser
+
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Wig Exploder v1.0.1: Explode a big WIG file into several smaller WIG files (one per chromosome). [Category: Personal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",                        dest="inputFileName", action="store",                                         type="string", help="input file [compulsory] [format: file in WIG format]")
+    parser.add_option("-o", "--output",                     dest="output",                action="store",            default=None,    type="string", help="output directory [compulsory] [format: directory]")
+    parser.add_option("-s", "--strand",                     dest="strand",                action="store",            default=None,    type="string", help="strand of the input WIG file (if any) [format: choice (+, -)]")
+    parser.add_option("-v", "--verbosity",                dest="verbosity",         action="store",            default=1,         type="int",        help="trace level [format: int]")
+    (options, args) = parser.parse_args()
+
+    inputFile = open(options.inputFileName)
+
+    files         = {}
+    file            = None
+    trackLine = None
+    strand        = ""
+    if options.strand != None:
+        strand = options.strand
+
+    for line in inputFile:
+        line = line.strip()
+
+        if line.startswith("track"):
+            trackLine = line
+            continue
+
+        m1 = re.search(r"^\s*fixedStep\s+chrom=(\S+)\s+start=\d+\s+step=\d+\s*$", line)
+        m2 = re.search(r"^\s*fixedStep\s+chrom=(\S+)\s+start=\d+\s+step=\d+\s+span=\d+\s*$", line)
+        m3 = re.search(r"^\s*variableStep\s+chrom=(\S+)\s*$", line)
+        m4 = re.search(r"^\s*variableStep\s+chrom=(\S+)span=\d+\s*$", line)
+
+        m = None
+        if m1 != None:
+            m = m1
+        elif m2 != None:
+            m = m2
+        elif m3 != None:
+            m = m3
+        elif m4 != None:
+            m = m4
+
+        if m != None:
+            chromosome = m.group(1)
+
+            if chromosome in files:
+                file = files[chromosome]
+            else:
+                file = open("%s%s%s%s.wig" % (options.output, os.sep, chromosome, strand), "w")
+                files[chromosome] = file
+                if trackLine != None:
+                    file.write("%s\n" % (trackLine))
+
+        if file == None:
+            sys.exit("Header is missing (current first line is '%s')! Aborting..." % (line))
+
+        file.write("%s\n" % (line))
+
+    inputFile.close()
+
+    for chromosome in files:
+        files[chromosome].close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Python/wrongFastqToQual.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,81 @@
+#! /usr/bin/env python
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+"""Convert a pseudo-FASTQ file to QUAL files"""
+
+import os
+from optparse import OptionParser
+from SMART.Java.Python.misc.Progress import *
+from math import *
+
+if __name__ == "__main__":
+    
+    # parse command line
+    description = "Wrong FastQ to Qual v1.0.1: Convert a pseudo-FastQ (i.e. a FastQ file with a wrong format) into a Qual file. [Category: Personnal]"
+
+    parser = OptionParser(description = description)
+    parser.add_option("-i", "--input",            dest="inputFileName",         action="store",                                                type="string", help="input file [compulsory] [format: file in FASTQ format]")
+    parser.add_option("-o", "--output",         dest="outputFileName",        action="store",                                                type="string", help="output file [compulsory] [format: output file in QUAL format]")
+    parser.add_option("-v", "--verbosity",    dest="verbosity",                 action="store",            default=1,                type="int",        help="trace level [format: int] [default: 1]")
+    (options, args) = parser.parse_args()
+
+    inputFile             = open(options.inputFileName)
+    outputFastaFile = open("%s.fasta" % (options.outputFileName), "w")
+    outputQualFile    = open("%s.qual" % (options.outputFileName), "w")
+    
+    inSequence     = False
+    inQuality        = True
+    sequenceName = None
+    for line in inputFile:
+        line = line.strip()
+        if line[0] == "@":
+            if inQuality == False:
+                sys.exit("Quality of %s is missing" % (sequenceName))
+            inSequence     = True
+            inQuality        = False
+            sequenceName = line[1:]
+            outputFastaFile.write(">%s\n" % (sequenceName))
+        elif line[0] == "+":
+            if inSequence == False:
+                sys.exit("Sequence of %s is missing" % (line[1:]))
+            inSequence     = False
+            inQuality        = True
+            if sequenceName != line[1:]:
+                sys.exit("Names in sequence and qual are different (%s, %s)" % (sequenceName, line[1:]))
+            outputQualFile.write(">%s\n" % (sequenceName))
+        else:
+            if inSequence:
+                outputFastaFile.write("%s\n" % (line))
+            elif inQuality:
+                outputQualFile.write("%s\n" % (line))
+    
+    inputFile.close()
+    outputFastaFile.close()
+    outputQualFile.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/PythonHelperReader.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,336 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.io.File;
+import java.io.*;
+import java.util.regex.*;
+
+public class PythonHelperReader {
+
+  String         fileName;
+  Program        program;
+  BufferedReader reader;
+  String         message;
+
+  public PythonHelperReader(String fileName) {
+    this.fileName = fileName;  
+    this.reader   = reader;
+    this.message  = null;
+  }
+
+  public void setReader(BufferedReader reader) {
+    this.reader = reader;
+  }
+  
+  public void run() {
+    this.program                     = new Program();
+    boolean         inBeginning      = true;
+    boolean         inUsage          = false;
+    boolean         afterUsage       = false;
+    boolean         inDescription    = false;
+    boolean         afterDescription = false;
+    boolean         inOptions        = false;
+    boolean         inOptionBlank    = false;
+    boolean         inError          = false;
+    String          usage            = null;
+    String          description      = null;
+    String          option           = null;
+    Vector <String> options          = new Vector < String > ();
+    String[]        optionSplitted;
+
+    // Parse file
+    try {
+      String line = null;
+
+      while ((line = reader.readLine()) != null) {
+        line = line.trim();
+        if (line.startsWith("Traceback")) {
+          this.message     = "Problem with header of '" + this.fileName + "':\n" + line + "\n";
+          inError          = true;
+          inBeginning      = false;
+          inUsage          = false;
+          afterUsage       = false;
+          inDescription    = false;
+          afterDescription = false;
+          inOptions        = false;
+          inOptionBlank    = false;
+        }
+        else if (inError) {
+          this.message += line + "\n";
+        }
+        else if (inBeginning) {
+          if (line.startsWith("Usage:")) {
+            inUsage     = true;
+            inBeginning = false;
+            usage       = line;
+          }
+        }
+        else if (inUsage) {
+          if ("".equals(line)) {
+            inUsage    = false;
+            afterUsage = true;
+          }
+          else {
+            usage += " " + line;
+          }
+        }
+        else if (afterUsage) {
+          if (! "".equals(line)) {
+            description   = line;
+            afterUsage    = false;
+            inDescription = true;
+          }
+        }
+        else if (inDescription) {
+          if ("".equals(line)) {
+            inDescription    = false;
+            afterDescription = true;
+          }
+          else {
+            description += " " + line;
+          }
+        }
+        else if (afterDescription) {
+          if (! "".equals(line)) {
+            afterDescription = false;
+            inOptions        = true;
+          }
+        }
+        else if (inOptions) {
+          if ("".equals(line)) {
+            inOptions     = false;
+            inOptionBlank = true;
+          }
+          else {
+            if (option == null) {
+              option = line;
+            }
+            else {
+              if (line.charAt(0) == '-') {
+                options.add(option);
+                option = line;
+              }
+              else {
+                option += " " + line;
+              }
+            }
+          }
+        }
+        else if (inOptionBlank) {
+          if (! "".equals(line)) {
+            inOptionBlank = false;
+            inOptions     = true;
+          }
+        }
+        else {
+          this.message = "Something is wrong in the file '" + this.fileName + "'.\n";
+          return;
+        }
+      }
+
+      reader.close();
+    }
+    catch (FileNotFoundException e) {
+      this.message = "File " + this.fileName + " not found.\n";
+      return;
+    }
+    catch (IOException e) {
+      this.message = "IOException while reading file " + this.fileName;
+      return;
+    }
+
+    if (inError) {
+      return;
+    }
+
+    if (option != null) {
+      options.add(option);
+    }
+
+    HashMap < String, ProgramOption > identifierToOptions = new HashMap < String, ProgramOption > ();
+    HashMap < ProgramOption, String > associatedOption    = new HashMap < ProgramOption, String > ();
+
+    if (usage == null) {
+      this.message = "Cannot read the usage of file " + this.fileName + ".\n";
+      return;
+    }
+    program.setShortName(usage.split(" ")[1].trim());
+    program.setName(description.split(":")[0].trim());
+
+    Pattern pattern = Pattern.compile("\\[Category: .*\\]");
+    Matcher matcher = pattern.matcher(description);
+    if (matcher.find()) {
+      program.setSection(description.substring(matcher.start() + "[Category: ".length(), matcher.end() - 1));
+      program.setDescription(description.substring(0, matcher.start() - 1).trim());
+    }
+    else {
+      this.message = "Cannot find category in description '" + description + "' in file " + this.fileName + ".\n";
+      return;
+    }
+    for (int i = 0; i < options.size(); i++) {
+      option         = options.get(i).replace("\t", " ");
+      optionSplitted = option.split(" ");
+      option         = "";
+      for (int j = 3; j < optionSplitted.length; j++) {
+        option += optionSplitted[j] + " ";
+      }
+      
+      String identifier = optionSplitted[0].replace("-", "").replace(",", "");
+      // Skip -h and -v options
+      if (("h".equals(identifier)) || ("v".equals(identifier)))
+        continue;
+
+      ProgramOption programOption = new ProgramOption();
+      programOption.setIdentifier("-" + identifier);
+      int commentEnd = option.indexOf("[");
+      if (commentEnd == -1) {
+        this.message = "Do not understand option line '" + option + "' in file " + this.fileName + ".\n";
+        return;
+      }
+      programOption.setComment(option.substring(0, commentEnd).trim());
+      identifierToOptions.put(identifier, programOption);
+
+      pattern = Pattern.compile("\\[[^\\]]*\\]");
+      matcher = pattern.matcher(option);
+      while (matcher.find()) {
+        String inner = option.substring(matcher.start()+1, matcher.end()-1);
+        if (inner.contains(":")) {
+          String type  = inner.substring(0, inner.indexOf(":")).trim();
+          String value = inner.substring(inner.indexOf(":")+1).trim();
+          // Types of the options
+          if ("format".compareToIgnoreCase(type) == 0) {
+            String currentWord = "";
+            String rest        = "";
+            if (value.contains(" ")) {
+              int pos     = value.indexOf(" ");
+              currentWord = value.substring(0, pos);
+              rest        = value.substring(pos+1);
+            }
+            else {
+              currentWord = value;
+            }
+            // Output file type
+            if ("output".compareToIgnoreCase(currentWord) == 0) {
+              programOption.setInput(false);
+              int pos     = rest.indexOf(" ");
+              currentWord = rest.substring(0, pos).trim();
+              rest        = rest.substring(pos+1).trim();
+            }
+            // File (input or output file)
+            if ("file".compareToIgnoreCase(currentWord) == 0) {
+              programOption.setType("file");
+              // Format given by an associated option (to be found later)
+              if (rest.startsWith("in format given by ")) {
+                associatedOption.put(programOption, rest.substring(rest.indexOf("format given by ") + "format given by ".length() + 1).trim());
+              }
+              else {
+                if (! rest.startsWith("in ")) {
+                  this.message = "Descriptor " + option + " does not have a proper format.\n";
+                  return;
+                }
+                rest = rest.substring("in ".length());
+                int pos = rest.indexOf(" format");
+                if (pos == -1) {
+                  this.message = "Descriptor " + option + " does not have a proper format.\n";
+                  return;
+                }
+                programOption.setFormat(rest.substring(0, pos).trim().toLowerCase().split(" or "));
+              }
+            }
+            // Format type
+            else if (rest.endsWith("file format")) {
+              programOption.setFormat((currentWord + " " + rest.substring(0, rest.indexOf("file format"))).trim().toLowerCase().split(" or "));
+              programOption.setType("format");
+            }
+            // Choice type
+            else if ("choice".compareToIgnoreCase(currentWord) == 0) {
+              programOption.setChoices(rest.replace("(", "").replace(")", "").split(", "));
+              programOption.setType("choice");
+            }
+            // Boolean type
+            else if ("bool".compareToIgnoreCase(currentWord) == 0) {
+              programOption.setType("boolean");
+            }
+            // Other type
+            else {
+              if (currentWord == null) {
+                this.message = "Program '" + this.fileName + "' has a problem concerning the type of option '" + identifier + "'.\n";
+                return;
+              }
+              programOption.setType(currentWord);
+            }
+          }
+          // Default value
+          else if ("default".compareToIgnoreCase(type) == 0) {
+            programOption.setDefault(value);
+          }
+          else {
+            this.message = "Do not understand option descriptor '" + inner + "'.\n";
+            return;
+          }
+        }
+        else {
+          // Compulsory option
+          if ("compulsory".compareToIgnoreCase(inner) == 0) {
+            programOption.setCompulsory(true);
+          }
+          else {
+            this.message = "Do not understand option descriptor '" + inner + "'.\n";
+            return;
+          }
+        }
+      }
+      if (! programOption.checkSettings()) {
+        this.message = "Program '" + this.fileName + "' has a problem concerning option '" + identifier + "'.\n";
+        return;
+      }
+      program.addOption(programOption);
+    }
+
+    // Set associated option
+    Iterator it = associatedOption.keySet().iterator();
+    while (it.hasNext()) {
+      ProgramOption programOption = (ProgramOption) it.next();
+      programOption.setAssociatedOption(identifierToOptions.get(associatedOption.get(programOption)));
+    }
+  }
+
+  public String getMessage () {
+    return this.message;
+  }
+
+  public Program getProgram () {
+    return this.program;
+  }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/PythonProgramFinder.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,92 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.io.*;
+import java.util.*;
+
+public class PythonProgramFinder {
+
+  String             dirName;
+  Vector < Program > programs;
+
+  public PythonProgramFinder(String dirName) {
+    this.dirName = dirName;  
+  }
+
+  public String findPrograms() {
+    java.io.File directory = new java.io.File(this.dirName);
+    String[] files         = directory.list(new FilenameFilter() {public boolean accept(java.io.File dir, String name) {return ((! name.startsWith(".")) && (! name.startsWith("test")) && ((new java.io.File(dir, name)).isFile()) && (name.endsWith(".py")) && (name.compareToIgnoreCase("__init__.py") != 0));}});
+    this.programs          = new Vector < Program > ();
+
+    for (int i = 0; i < files.length; i++) {
+      String[] commandList  = {Global.pythonCommand, "Python" + java.io.File.separator + files[i], "-h"};
+      String command = "";
+      for (int j = 0; j < commandList.length; j++) {
+        command += commandList[j] + " ";
+      }
+      ProcessBuilder pb = new ProcessBuilder(commandList);
+      pb = pb.redirectErrorStream(true);
+      Map<String, String> env = pb.environment();
+      env.put("PYTHONPATH", System.getProperty("user.dir") + java.io.File.separator + "Python");
+      env.put("SMARTPATH", System.getProperty("user.dir") + java.io.File.separator + "Python");
+      env.put("SMARTMYSQLPATH", Global.mysqlCommand);
+      env.put("SMARTRPATH", Global.rCommand);
+
+      PythonHelperReader helperReader = new PythonHelperReader(files[i]);
+      try {
+        final Process process = pb.start();
+        InputStream is        = process.getInputStream();
+        InputStreamReader isr = new InputStreamReader(is);
+        BufferedReader br     = new BufferedReader(isr);
+        helperReader.setReader(br);
+        helperReader.run();
+      }
+      catch (IOException e) {
+        final Writer result = new StringWriter();
+        final PrintWriter printWriter = new PrintWriter(result);
+        e.printStackTrace(printWriter);
+        return "Command '" + command + "' failed (I/O error)...\n" + result.toString();
+      }
+      String comments = helperReader.getMessage();
+      if (comments != null) return comments;
+      Program program = helperReader.getProgram();
+      if (("Personnal".compareToIgnoreCase(program.getSection()) != 0) && ("Personal".compareToIgnoreCase(program.getSection()) != 0)) {
+        this.programs.add(program);
+      }
+    }
+    return null;
+  }
+
+  public Vector <Program> getPrograms () {
+    return this.programs;
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/README.txt	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,51 @@
+----------
+|  NAME  |
+----------
+S-MART
+
+
+Description
+-----------
+Several tools are now available for mapping high-throughput sequencing data from a genome, but few can extract biological knowledge from the mapped reads. We have developed a toolbox, S-MART, which handles mapped RNA-Seq and ChIP-Seq data.
+
+S-MART is an intuitive and lightweight tool, performing several tasks that are usually required during the analysis of mapped RNA-Seq and ChIP-Seq reads, including data selection and data visualization.
+
+S-MART does not require a computer science background and thus can be used by all biologists through a graphical interface. S-MART can run on any personal computer, yielding results within an hour for most queries. 
+
+
+Instructions
+------------
+Installation instructions and the user guide are available in the file "doc.pdf".
+
+
+Copyright
+---------
+Copyright INRA-URGI 2009-2010
+
+
+Authors
+-------
+Matthias Zytnicki
+
+
+Contact
+-------
+urgi-contact@versailles.inra.fr
+
+
+License
+-------
+This library is distributed under the terms of the CeCILL license 
+(http://www.cecill.info/index.en.html).
+See the LICENSE.txt file.
+
+
+Acknowledgements
+----------------
+This product needs the following softwares :
+ * R, under the GNU General Public License
+ * MySQL, under the GNU General Public License
+ * Python, under the Python License, compatible with the GNU General Public License
+ * MySQL for Python, under the GNU General Public License
+ * Java, under the GNU General Public License
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Sav/File.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,55 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+public class File {
+  String name;
+  String formatType;
+  String format;
+
+
+  public File(String name, String type, String format) {
+    this.name       = name;
+    this.formatType = type;
+    this.format     = format;
+  }
+
+  public String getName() {
+    return this.name;
+  }
+
+  public String getFormatType() {
+    return this.formatType;
+  }
+
+  public String getFormat() {
+    return this.format;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Sav/Files.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,71 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+
+public class Files {
+  HashMap <String, File> files;  
+
+  public Files () {
+    files = new HashMap < String, File> ();
+  }
+
+  public void addFile(String fileName, String type, String format) {
+    this.addFile(new File(fileName, type, format));
+  }
+
+  public void addFile(File file) {
+    files.put(file.name, file);
+  }
+
+  public String getType(String fileName) {
+    if (fileName == null) {
+      System.out.println("Error! Looking for format of empty file name!");
+    }
+    if (! files.containsKey(fileName)) {
+      System.out.println("Oops! Format type of file " + fileName + " is not found!");
+      return null;
+    }
+    return files.get(fileName).formatType;
+  }
+
+  public String getFormat(String fileName) {
+    if (fileName == null) {
+      System.out.println("Error! Looking for format of empty file name!");
+    }
+    if (! files.containsKey(fileName)) {
+      System.out.println("Oops! Format of file " + fileName + " is not found!");
+      return null;
+    }
+    return files.get(fileName).format;
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Sav/FormatType.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,64 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+
+public class FormatType {
+  String type;
+  Vector < String > formats;
+
+  public FormatType (String type) {
+    this.type    = type;
+    this.formats = new Vector < String > ();
+  }
+
+  public String getType () {
+    return this.type;
+  }
+
+  public void addFormat (String format) {
+    formats.add(format);
+  }
+
+  public boolean containsFormat (String format) {
+    for (int i = 0; i < formats.size(); i++) {
+      if (((String) formats.get(i)).compareToIgnoreCase(format) == 0) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public Vector < String > getFormats () {
+    return formats;
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Sav/FormatsContainer.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,81 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+
+public class FormatsContainer {
+
+  HashMap < String, FormatType > formatTypes;
+
+
+  public FormatsContainer() {
+    this.formatTypes = new HashMap < String, FormatType > ();
+  }
+
+
+  public void addFormat(String type, String format) {
+    FormatType formatType;
+    if (formatTypes.containsKey(type)) {
+      formatType = this.formatTypes.get(type);
+    }
+    else {
+      formatType = new FormatType(type);
+      this.formatTypes.put(type, formatType);
+    }
+    formatType.addFormat(format);
+  }
+
+
+  public Vector < String > getFormatTypes () {
+    Vector < String > v = new Vector < String > ();
+    v.addAll(this.formatTypes.keySet());
+    return v;
+  }
+
+
+  public FormatType getFormats (String type) {
+    return formatTypes.get(type);
+  }
+
+
+  public String getFormatType (String format) {
+    for (Iterator it = formatTypes.keySet().iterator(); it.hasNext(); ) {
+      Object type       =  it.next();
+      Object formatType = formatTypes.get(type);
+      if (((FormatType) formatType).containsFormat(format)) {
+        return (String) type;
+      }
+    }
+    return null;
+  }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Sav/FormatsReader.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,83 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.io.File;
+import java.io.*;
+
+
+public class FormatsReader {
+
+  String fileName;
+  Vector < FormatType > formatTypes;
+  Vector < String > typeNames;
+
+
+  public FormatsReader(String fileName) {
+    this.fileName    = fileName;  
+    this.formatTypes = new Vector < FormatType > ();
+  }
+
+
+  public boolean read() {
+    File file = new File(this.fileName);
+
+    try {
+      BufferedReader reader = new BufferedReader(new FileReader(file));
+      String     line = null;
+      String[]   lineElements;
+      String[]   formats;
+      String     typeName;
+
+      while ((line = reader.readLine()) != null) {
+        if (line.length() > 0) {
+          lineElements = line.split(":");
+          typeName     = lineElements[0].trim();
+          formats      = lineElements[1].split(",");
+          for (int i = 0; i < formats.length; i++) {
+            Global.formats.addFormat(typeName, formats[i].trim());
+          }
+        }
+      }
+
+      reader.close();
+    }
+    catch (FileNotFoundException e) {
+      return false;
+    }
+    catch (IOException e) {
+      return false;
+    }
+
+    return true;
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Sav/Global.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,70 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.Vector;
+import java.util.HashMap;
+import javax.swing.DefaultListModel;
+import javax.swing.JButton;
+import javax.swing.JTextField;
+
+public class Global {
+
+  public static int logAreaSize = 100;
+
+  public static String smartConfFileName = "smart.conf";
+
+  public static String smartProgramsFileName = "programs.txt";
+
+  public static String smartFormatsFileName = "formats.txt";
+
+  public static String pythonPath = new String();
+
+  public static String pythonCommand = "python";
+
+  public static String mysqlCommand = "mysql";
+
+  public static String rCommand = "R";
+
+  public static Files files = new Files();
+
+  public static DefaultListModel fileNames = new DefaultListModel();
+
+  public static FormatsContainer formats = new FormatsContainer();
+
+  public static boolean programRunning = false;
+
+  public static HashMap < JButton, JTextField > otherFilesChooser = new HashMap < JButton, JTextField >();
+
+  public static HashMap < JButton, JTextField > otherDirectoriesChooser = new HashMap < JButton, JTextField >();
+
+  public static HashMap < JButton, JTextField > otherFileConcatenationChooser = new HashMap < JButton, JTextField >();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Sav/Program.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,175 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.awt.*;
+import javax.swing.*;
+
+
+public class Program {
+  String                 shortName;
+  String                 name;
+  String                 section;
+  String                 description;
+  Vector <ProgramOption> options;
+  JPanel                 panel;
+  JButton                button;
+
+
+  public Program() {
+    this.shortName = null;  
+    this.name      = null;  
+    this.options   = new Vector <ProgramOption> ();  
+  }
+
+
+  public void setShortName(String shortName) {
+    this.shortName = shortName;
+  }
+
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+
+  public void setSection(String section) {
+    this.section = section;
+  }
+
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
+
+  public void addOption(ProgramOption option) {
+    options.add(option);
+  }
+
+
+  public String getShortName() {
+    return this.shortName;
+  }
+
+
+  public String getName() {
+    return this.name;
+  }
+
+
+  public String getSection() {
+    return this.section;
+  }
+
+  public String getDescription() {
+    return this.description;
+  }
+
+
+  public String checkValues() {
+    for (int i = 0; i < options.size(); i++) {
+      String comment = options.get(i).checkValue();
+      if (comment != null) {
+        return comment;
+      }
+    }
+    return null;
+  }
+
+
+  public LinkedList<String> getCommand() {
+    LinkedList<String> parameterList = new LinkedList<String>();
+    parameterList.add(Global.pythonCommand);
+    parameterList.add("Python" + java.io.File.separator + this.shortName);
+    for (int i = 0; i < options.size(); i++) {
+      ProgramOption option = options.get(i);
+      parameterList.addAll(option.getCommand());
+    }
+    return parameterList;
+  }
+
+
+  public JPanel getPanel() {
+    if (this.panel != null) {
+      return this.panel;
+    }
+    
+    this.panel = new JPanel(false);
+    this.panel.setLayout(new FlowLayout());
+    Box box = Box.createVerticalBox();
+
+    JPanel descriptionPanel = new JPanel(false);
+    JLabel descriptionLabel = new JLabel(this.description);
+    descriptionPanel.add(descriptionLabel);
+    box.add(descriptionPanel);
+
+    for (int i = 0; i < options.size(); i++) {
+      ProgramOption option = options.get(i);
+      JPanel        panel  = option.getPanel();
+      if (panel == null) {
+        System.out.println("Problem with Python program '" + this.shortName + "'.");
+        return null;
+      }
+      box.add(option.getPanel());
+    }
+
+    JPanel buttonPanel = new JPanel(false);
+    this.button = new JButton("GO!");
+
+    buttonPanel.add(button);
+
+    box.add(buttonPanel);
+
+    this.panel.add(box);
+
+    return this.panel;
+  }
+
+
+  public JButton getButton() {
+    if (this.button == null) {
+      this.getPanel();
+    }
+    return this.button;
+  }
+
+  
+  public Vector < File > getOutputFiles() {
+    Vector < File > files = new Vector < File > ();
+    for (int i = 0; i < options.size(); i++) {
+      ProgramOption option = options.get(i);
+      if (! option.isInput()) {
+        files.add(option.getOutputFile());
+      }
+    }
+    return files;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Sav/ProgramFileReader.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,174 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.io.File;
+import java.io.*;
+
+
+public class ProgramFileReader {
+  String fileName;
+  Vector <Program> programs;
+
+
+  public ProgramFileReader(String fileName) {
+    this.fileName = fileName;  
+    this.programs = new Vector <Program> ();
+  }
+
+
+  public boolean read() {
+//  File    file    = new File(this.fileName);
+//  Program program = null;
+//  int     step    = 0;
+//  TreeMap <String, ProgramOption> options = new TreeMap <String, ProgramOption> ();
+
+//  try {
+//    BufferedReader reader = new BufferedReader(new FileReader(file));
+//    String line    = null;
+//    String section = null;
+
+//    while ((line = reader.readLine()) != null) {
+
+//      line = line.trim();
+
+//      if (line.length() == 0) {
+//        if (program != null) {
+//          programs.add(program);
+//        }
+//        program = null;
+//        step = 0;
+//        continue;
+//      }
+
+//      if ((line.charAt(0) == '[') && (line.charAt(line.length() - 1) == ']')) {
+//        section = line.substring(1, line.length() - 1).trim();
+//        continue;
+//      }
+//      switch (step) {
+//        case 0:
+//        program = new Program();
+//          program.setName(line);
+//          if (section == null) {
+//            System.out.println("Error! Section of program '" + line + "' is not set!");
+//          }
+//          program.setSection(section);
+//          step = 1;
+//          break;
+//        case 1:
+//          program.setShortName(line);
+//          step = 2;
+//          break;
+//        case 2:
+//          ProgramOption option = new ProgramOption();
+
+//          String[] elements    = line.split(":");
+//          boolean  input       = elements[0].trim().equalsIgnoreCase("input")? true: false;
+//          String[] subElements = elements[1].split(";");
+//          String   identifier = subElements[0].trim();
+
+//          option.setInput(input);
+
+//          if (input) {
+
+//            if (subElements.length < 4) {
+//              System.out.println("Line '" + line + "' is weird...");
+//            }
+
+//            String   type       = subElements[1].trim();
+//            String   comment    = subElements[2].trim();
+//            boolean  compulsory = subElements[3].trim().equalsIgnoreCase("0")? false: true;
+
+//            option.setIdentifier(identifier);
+//            option.setType(type);
+//            option.setComment(comment);
+//            option.setCompulsory(compulsory);
+
+//            if ("file".compareToIgnoreCase(type) == 0) {
+//              if (subElements.length < 5) {
+//                System.out.println("Line '" + line + "' is weird...");
+//              }
+
+//              String formatIdentifier = subElements[4].trim();
+//              option.setFormatIdentifier(formatIdentifier);
+//            }
+//            else if ("choice".compareToIgnoreCase(type) == 0) {
+//              if (subElements.length < 5) {
+//                System.out.println("Line '" + line + "' is weird...");
+//              }
+
+//              String[] choices = subElements[4].trim().split(",");
+//              for (int i = 0; i < choices.length; i++) {
+//                choices[i] = choices[i].trim();
+//              }
+//              option.setChoices(choices);
+//            }
+//            options.put(identifier, option);
+//          }
+//          else {
+//            String format = subElements[1].trim();
+
+//            option.setFormat(format);
+//            option.setAssociatedOption(options.get(identifier));
+//          }
+
+//          program.addOption(option);
+
+//          break;
+//        default:
+//          return false;
+//      }
+//    }
+
+//    reader.close();
+//  }
+//  catch (FileNotFoundException e) {
+//    return false;
+//  }
+//  catch (IOException e) {
+//    return false;
+//  }
+
+//  if (program != null) {
+//    programs.add(program);
+//  }
+
+    return true;
+  }
+
+  public int getNbPrograms() {
+    return programs.size();
+  }
+
+  public Program getProgram(int i) {
+    return programs.get(i);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Sav/ProgramLauncher.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,191 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.io.*;
+import javax.swing.SwingUtilities;
+import javax.swing.*;
+import java.util.concurrent.CountDownLatch;
+
+public class ProgramLauncher extends SwingWorker<Boolean, String>  {
+
+  String[]     command;
+  JTextArea    logArea;
+  JLabel       messageField;
+  JProgressBar progressBar;
+  JLabel       etaField;
+  int          exitValue;
+  
+
+  public ProgramLauncher (LinkedList <String> c, JTextArea la, JLabel mf, JProgressBar pb, JLabel ef) {
+    command       = new String[c.size()];
+    logArea       = la;
+    messageField  = mf;
+    progressBar   = pb;
+    etaField      = ef;
+    exitValue     = -1;
+    c.toArray(command);
+  }
+
+
+  public ProgramLauncher (String[] c, JTextArea la, JLabel mf, JProgressBar pb, JLabel ef) {
+    command       = c;
+    logArea       = la;
+    messageField  = mf;
+    progressBar   = pb;
+    etaField      = ef;
+    exitValue     = -1;
+  }
+
+
+  @Override
+  public Boolean doInBackground() {
+    ProcessBuilder pb           = new ProcessBuilder(command);
+    Process process             = null;
+    BufferedReader outputReader = null;
+    pb                          = pb.redirectErrorStream(true);
+    Map<String, String> env     = pb.environment();
+    env.put("PYTHONPATH", System.getProperty("user.dir") + java.io.File.separator + "Python");
+    env.put("SMARTPATH", System.getProperty("user.dir") + java.io.File.separator + "Python");
+    env.put("SMARTMYSQLPATH", Global.mysqlCommand);
+    env.put("SMARTRPATH", Global.rCommand);
+    String commandJoined = Arrays.toString(command);
+
+    try {
+      publish("=== Starting command '" + commandJoined.trim() + "' ===\n");
+      process = pb.start();
+
+      BufferedInputStream outputStream = new BufferedInputStream(process.getInputStream());
+      InputStream is                   = process.getInputStream();
+      InputStreamReader isr            = new InputStreamReader(is);
+      outputReader                     = new BufferedReader(isr);
+    }
+    catch (Exception exception) {
+      publish("!Process cannot be started (command is '" + commandJoined + "')!\n");
+      exception.printStackTrace();
+      return Boolean.FALSE;
+    }
+    if (outputReader == null) {
+      publish("!Problem in the output of the command!\n");
+      return Boolean.FALSE;
+    }
+    else {
+      try {
+        String line;
+        while ((line = outputReader.readLine()) != null) {
+          publish(line + "\n");
+        }
+      }
+      catch (IOException e) {
+        e.printStackTrace();
+        publish("!Cannot get the output of the command!\n");
+        return Boolean.FALSE;
+      }
+    }
+    try {
+      process.waitFor();
+    }
+    catch (InterruptedException e) {
+      e.printStackTrace();
+      publish("!Cannot wait for the end of the command!\n");
+      return Boolean.FALSE;
+    }
+    try {
+      exitValue = process.exitValue();
+      System.out.println(exitValue);
+    }
+    catch (IllegalThreadStateException e) {
+      e.printStackTrace();
+      publish("!Cannot get the exit value of the command!\n");
+      return Boolean.FALSE;
+    }
+    if (exitValue != 0) {
+      publish("!Problem during the execution of the command '" + commandJoined + "'!\n");
+      return Boolean.FALSE;
+    }
+    publish("=== Ending command '" + commandJoined.trim() + "' ===\n");
+    return Boolean.TRUE;
+  }
+
+
+  @Override
+  protected void process(List<String> chunks) {
+    String message = "";
+    String text    = logArea.getText();
+    for (String chunk: chunks) {
+      text += chunk;
+    }
+    for (String lineSeparatedByCarriageReturn: text.split("\n")) {
+      for (String line: lineSeparatedByCarriageReturn.split("\r")) {
+        boolean progressLine = false;
+        if (line.matches(".*\\[=*\\s*\\]\\s*\\d*/\\d*\\s*")) {
+          String[] ratioElements = line.split("\\]")[1].trim().split("/");
+          int      current       = Integer.parseInt(ratioElements[0].trim());
+          int      aim           = Integer.parseInt(ratioElements[1].trim());
+          messageField.setText(line.split("\\[")[0].trim());
+          progressBar.setValue(current * 100 / aim);
+          etaField.setText("");
+          progressLine = true;
+        }
+        else if (line.matches(".*\\[=*\\s*\\]\\s*\\d*/\\d*\\s*ETA:\\s*.*")) {
+          String[] ratioElements = line.split("\\]")[1].split("E")[0].trim().split("/");
+          int      current       = Integer.parseInt(ratioElements[0].trim());
+          int      aim           = Integer.parseInt(ratioElements[1].trim());
+          String   eta           = line.split("ETA:")[1].trim();
+          messageField.setText(line.split("\\[")[0].trim());
+          progressBar.setValue(current * 100 / aim);
+          etaField.setText("ETA: " + eta);
+          progressLine = true;
+        }
+        else if (line.matches(".*\\[=*\\s*\\]\\s*\\d*\\s*completed in.*")) {
+          String nbElements = line.split("\\]")[1].split("completed")[0].trim();
+          String timeSpent  = line.split("completed in")[1].trim();
+          message          += line.split("\\[")[0].trim() + ": " + nbElements + " elements completed in " + timeSpent + "\n";
+          messageField.setText(line.split("\\[")[0].trim());
+          progressLine = true;
+        }
+        if (! progressLine) {
+          message += line + "\n";
+        }
+      }
+    }
+    String lines[]     = message.split("\n");
+    String toBeWritten = "";
+    for (int i = Math.max(0, lines.length - Global.logAreaSize); i < lines.length; i++) {
+      toBeWritten += lines[i] + "\n";
+    }
+    logArea.setText(toBeWritten);
+  }
+
+  public int getExitValue() {
+    return exitValue;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Sav/ProgramOption.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,329 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.*;
+import javax.swing.*;
+import javax.swing.filechooser.*;
+import javax.swing.border.*;
+import javax.swing.SwingUtilities;
+
+
+public class ProgramOption {
+  boolean       input;
+  String        identifier;
+  String        type;
+  String        comment;
+  boolean       compulsory;
+  String[]      format;
+  String        formatIdentifier;
+  ProgramOption associatedOption;
+  String        defaultValue;
+  String[]      choices;
+  JComponent    component;
+  JPanel        panel;
+
+
+  public ProgramOption() {
+    this.input            = true;
+    this.identifier       = null;
+    this.type             = null;
+    this.comment          = null;
+    this.compulsory       = false;
+    this.format           = null;
+    this.formatIdentifier = null;
+    this.associatedOption = null;
+    this.defaultValue     = "";
+    this.choices          = null;
+    this.component        = null;
+    this.panel            = null;
+  }
+
+
+  public void setInput(boolean input) {
+    this.input = input;
+  }
+
+
+  public void setIdentifier(String identifier) {
+    this.identifier = identifier;
+  }
+
+
+  public void setType(String type) {
+    this.type = type;
+  }
+
+
+  public void setComment(String comment) {
+    this.comment = comment;
+  }
+
+
+  public void setCompulsory(boolean compulsory) {
+    this.compulsory = compulsory;
+  }
+
+
+  public void setFormat(String[] format) {
+    this.format = format;
+  }
+
+
+  public void setFormat(String format) {
+    this.format    = new String[1];
+    this.format[0] = format;
+  }
+
+
+  public void setFormatIdentifier(String formatIdentifier) {
+    this.formatIdentifier = formatIdentifier;
+  }
+
+
+  public void setAssociatedOption(ProgramOption option) {
+    this.associatedOption = option;
+  }
+
+
+  public void setChoices(String[] choices) {
+    this.choices = choices;
+  }
+
+
+  public void setDefault(String defaultValue) {
+    this.defaultValue = defaultValue;
+  }
+
+
+  public boolean isInput() {
+    return this.input;
+  }
+
+
+  public JPanel getPanel() {
+    if (this.panel != null) {
+      return this.panel;
+    }
+    String comment = this.comment;
+    if (this.compulsory) {
+      comment += " [*]";
+    }
+
+    GridLayout horizontalLayout = new GridLayout(1, 0);
+    this.panel = new JPanel(false);
+    this.panel.setLayout(horizontalLayout);
+    JLabel label = new JLabel(comment);
+
+    if (this.type == null) {
+      System.out.println("Error! Option '" + this.identifier + "' is not set!");
+    }
+
+    if (("int".compareToIgnoreCase(this.type) == 0) || ("float".compareToIgnoreCase(this.type) == 0) || ("string".compareToIgnoreCase(this.type) == 0) || (("file".compareToIgnoreCase(this.type) == 0) && (!this.input))) {
+      this.component = new JTextField();
+      if (this.defaultValue != null) {
+        ((JTextField) this.component).setText(this.defaultValue);
+      }
+      label.setLabelFor(this.component);
+      this.panel.add(label);
+      this.panel.add(this.component);
+    }
+    else if ("file".compareToIgnoreCase(this.type) == 0) {
+      this.component = new JList(Global.fileNames);
+      ((JList) this.component).setVisibleRowCount(1);
+      JScrollPane scroll = new JScrollPane(this.component);
+
+      Box box = Box.createHorizontalBox();
+      box.add(Box.createRigidArea(new Dimension(0, 100)));
+      box.add(scroll);
+
+      label.setLabelFor(this.component);
+      this.panel.add(label);
+      this.panel.add(box);
+    }
+    else if ("boolean".compareToIgnoreCase(this.type) == 0) {
+      this.component = new JCheckBox();
+      if ((this.defaultValue != null) && (this.defaultValue.compareToIgnoreCase("true") == 0)) {
+        ((JCheckBox) this.component).setSelected(true);
+      }
+      label.setLabelFor(this.component);
+      this.panel.add(label);
+      this.panel.add(this.component);
+    }
+    else if ("format".compareToIgnoreCase(this.type) == 0) {
+      Vector < String > formats = new Vector < String > ();
+      for (String format: this.format) {
+        formats.addAll(Global.formats.getFormats(format).getFormats());
+      }
+      this.component = new JComboBox(formats);
+      label.setLabelFor(this.component);
+      this.panel.add(label);
+      this.panel.add(this.component);
+    }
+    else if ("files".compareToIgnoreCase(this.type) == 0) {
+      JButton button = new JButton("file...");
+      this.component = new JTextField();
+      label.setLabelFor(this.component);
+      this.panel.add(label);
+      this.panel.add(this.component);
+      this.panel.add(button);
+      Global.otherFileConcatenationChooser.put(button, (JTextField) this.component);
+    }
+    else if ("directory".compareToIgnoreCase(this.type) == 0) {
+      JButton button = new JButton("directory...");
+      this.component = new JTextField();
+      label.setLabelFor(this.component);
+      this.panel.add(label);
+      JPanel rightPanel = new JPanel(false);
+      rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.LINE_AXIS));
+      rightPanel.add(this.component);
+      rightPanel.add(button);
+      this.panel.add(rightPanel);
+      Global.otherDirectoriesChooser.put(button, (JTextField) this.component);
+    }
+    else if ("choice".compareToIgnoreCase(this.type) == 0) {
+      this.component = new JComboBox(this.choices);
+      label.setLabelFor(this.component);
+      this.panel.add(label);
+      this.panel.add(this.component);
+    }
+    else {
+      System.out.println("Do not know how to read type " + this.type);
+    }
+
+    return this.panel;
+  }
+
+
+  public JComponent getComponent() {
+    if (component == null) {
+      this.getPanel();
+    }
+    return this.component;
+  }
+
+
+  private String getValue() {
+    if (("int".equals(this.type)) || ("float".equals(this.type)) || ("string".equals(this.type)) || (("file".equals(this.type)) && (! this.input)) || ("directory".equals(this.type)) || ("files".equals(this.type)))  {
+      String s = ((JTextField) this.component).getText();
+      if ("None".equals(s)) {
+        return "";
+      }
+      return s;
+    }
+    if ("file".equals(this.type)) {
+      return (String) ((JList) this.component).getSelectedValue();
+    }
+    if ("boolean".equals(this.type)) {
+      return ((JCheckBox) this.component).isSelected()? "true": "false";
+    }
+    if ("format".equals(this.type)) {
+      return (String) ((JComboBox) this.component).getSelectedItem();
+    }
+    return null;
+  }
+
+
+  public String checkValue() {
+    String value = this.getValue();
+    if ((this.compulsory) && ((value == null) || ("".equals(value)))) {
+      return "Option '" + this.comment + "' has no value... Please specify it.\n";
+    }
+    if ("int".equals(this.type)) {
+      if ((value != null) && (! "".equals(value)) && (! "None".equals(value))) {
+        try {
+          int i = Integer.parseInt(value);
+        }
+        catch (NumberFormatException e) {
+          return "Option '" + this.comment + "' should be an integer... Please correct it.\n";
+        }
+      }
+    }
+    else if ("float".equals(this.type)) {
+      if ((value != null) && (! "".equals(value))) {
+        try {
+          float i = Float.parseFloat(value);
+        }
+        catch (NumberFormatException e) {
+          return "Option '" + this.comment + "' should be a float... Please correct it.\n";
+        }
+      }
+    }
+    return null;
+  }
+
+
+  public LinkedList <String> getCommand() {
+    LinkedList <String> list = new LinkedList <String> ();
+
+    if (("int".equals(this.type)) || ("float".equals(this.type)) || ("string".equals(this.type)) || (("file".equals(this.type)) && (! this.input)) || ("format".equals(this.type)) || ("directory".equals(this.type)) || ("files".equals(this.type))) {
+      String value = this.getValue();
+      if (value.length() == 0) {
+        return list;
+      }
+      list.add(this.identifier);
+      list.add(value);
+      return list;
+    }
+    if ("file".equals(this.type)) {
+      String fileName = (String) ((JList) this.component).getSelectedValue();
+      if (fileName == null) {
+        return list;
+      }
+      list.add(this.identifier);
+      list.add(this.getValue());
+      return list;
+    }
+    if ("boolean".equals(this.type)) {
+      if ("true".equals(this.getValue())) {
+        list.add(this.identifier);
+      }
+      return list;
+    }
+    return null;
+  }
+
+
+  public File getOutputFile() {
+    if (this.input) return null;
+    String format = "";
+    if (this.format != null) {
+      format = this.format[0];
+    }
+    if (this.associatedOption != null) {
+      format = this.associatedOption.getValue();
+    }
+    return new File(this.getValue() + "." + format, Global.formats.getFormatType(format), format);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Sav/PythonHelperReader.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,323 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.io.File;
+import java.io.*;
+import java.util.regex.*;
+
+public class PythonHelperReader {
+
+  String         fileName;
+  Program        program;
+  BufferedReader reader;
+  String         message;
+
+  public PythonHelperReader(String fileName) {
+    this.fileName = fileName;  
+    this.reader   = reader;
+    this.message  = null;
+  }
+
+  public void setReader(BufferedReader reader) {
+    this.reader = reader;
+  }
+  
+  public void run() {
+    this.program                     = new Program();
+    boolean         inBeginning      = true;
+    boolean         inUsage          = false;
+    boolean         afterUsage       = false;
+    boolean         inDescription    = false;
+    boolean         afterDescription = false;
+    boolean         inOptions        = false;
+    boolean         inOptionBlank    = false;
+    boolean         inError          = false;
+    String          usage            = null;
+    String          description      = null;
+    String          option           = null;
+    Vector <String> options          = new Vector < String > ();
+    String[]        optionSplitted;
+
+    // Parse file
+    try {
+      String line = null;
+
+      while ((line = reader.readLine()) != null) {
+        line = line.trim();
+        if (line.startsWith("Traceback")) {
+          this.message     = "Problem with header of '" + this.fileName + "':\n" + line + "\n";
+          inError          = true;
+          inBeginning      = false;
+          inUsage          = false;
+          afterUsage       = false;
+          inDescription    = false;
+          afterDescription = false;
+          inOptions        = false;
+          inOptionBlank    = false;
+        }
+        else if (inError) {
+          this.message += line + "\n";
+        }
+        else if (inBeginning) {
+          if (line.startsWith("Usage:")) {
+            inUsage     = true;
+            inBeginning = false;
+            usage       = line;
+          }
+        }
+        else if (inUsage) {
+          if ("".equals(line)) {
+            inUsage    = false;
+            afterUsage = true;
+          }
+          else {
+            usage += " " + line;
+          }
+        }
+        else if (afterUsage) {
+          if (! "".equals(line)) {
+            description   = line;
+            afterUsage    = false;
+            inDescription = true;
+          }
+        }
+        else if (inDescription) {
+          if ("".equals(line)) {
+            inDescription    = false;
+            afterDescription = true;
+          }
+          else {
+            description += " " + line;
+          }
+        }
+        else if (afterDescription) {
+          if (! "".equals(line)) {
+            afterDescription = false;
+            inOptions        = true;
+          }
+        }
+        else if (inOptions) {
+          if ("".equals(line)) {
+            inOptions     = false;
+            inOptionBlank = true;
+          }
+          else {
+            if (option == null) {
+              option = line;
+            }
+            else {
+              if (line.charAt(0) == '-') {
+                options.add(option);
+                option = line;
+              }
+              else {
+                option += " " + line;
+              }
+            }
+          }
+        }
+        else if (inOptionBlank) {
+          if (! "".equals(line)) {
+            inOptionBlank = false;
+            inOptions     = true;
+          }
+        }
+        else {
+          this.message = "Something is wrong in the file '" + this.fileName + "'.";
+          return;
+        }
+      }
+
+      reader.close();
+    }
+    catch (FileNotFoundException e) {
+      this.message = "File " + this.fileName + " not found";
+      return;
+    }
+    catch (IOException e) {
+      this.message = "IOException while reading file " + this.fileName;
+      return;
+    }
+
+    if (inError) {
+      return;
+    }
+
+    if (option != null) {
+      options.add(option);
+    }
+
+    HashMap < String, ProgramOption > identifierToOptions = new HashMap < String, ProgramOption > ();
+    HashMap < ProgramOption, String > associatedOption    = new HashMap < ProgramOption, String > ();
+
+    if (usage == null) {
+      this.message = "Cannot read the usage of file " + this.fileName;
+      return;
+    }
+    program.setShortName(usage.split(" ")[1].trim());
+    program.setName(description.split(":")[0].trim());
+
+    Pattern pattern = Pattern.compile("\\[Category: .*\\]");
+    Matcher matcher = pattern.matcher(description);
+    if (matcher.find()) {
+      program.setSection(description.substring(matcher.start() + "[Category: ".length(), matcher.end() - 1));
+      program.setDescription(description.substring(0, matcher.start() - 1).trim());
+    }
+    else {
+      this.message = "Cannot find category in description '" + description + "' in file " + this.fileName;
+      return;
+    }
+    for (int i = 0; i < options.size(); i++) {
+      option         = options.get(i).replace("\t", " ");
+      optionSplitted = option.split(" ");
+      option         = "";
+      for (int j = 3; j < optionSplitted.length; j++) {
+        option += optionSplitted[j] + " ";
+      }
+      
+      String identifier = optionSplitted[0].replace("-", "").replace(",", "");
+      // Skip -h and -v options
+      if (("h".equals(identifier)) || ("v".equals(identifier)))
+        continue;
+
+      ProgramOption programOption = new ProgramOption();
+      programOption.setIdentifier("-" + identifier);
+      programOption.setComment(option.substring(0, option.indexOf("[")).trim());
+      identifierToOptions.put(identifier, programOption);
+
+      pattern = Pattern.compile("\\[[^\\]]*\\]");
+      matcher = pattern.matcher(option);
+      while (matcher.find()) {
+        String inner = option.substring(matcher.start()+1, matcher.end()-1);
+        if (inner.contains(":")) {
+          String type  = inner.substring(0, inner.indexOf(":")).trim();
+          String value = inner.substring(inner.indexOf(":")+1).trim();
+          // Types of the options
+          if ("format".compareToIgnoreCase(type) == 0) {
+            String currentWord = "";
+            String rest        = "";
+            if (value.contains(" ")) {
+              int pos     = value.indexOf(" ");
+              currentWord = value.substring(0, pos);
+              rest        = value.substring(pos+1);
+            }
+            else {
+              currentWord = value;
+            }
+            // Output file type
+            if ("output".compareToIgnoreCase(currentWord) == 0) {
+              programOption.setInput(false);
+              int pos     = rest.indexOf(" ");
+              currentWord = rest.substring(0, pos).trim();
+              rest        = rest.substring(pos+1).trim();
+            }
+            // File (input or output file)
+            if ("file".compareToIgnoreCase(currentWord) == 0) {
+              programOption.setType("file");
+              // Format given by an associated option (to be found later)
+              if (rest.startsWith("in format given by ")) {
+                associatedOption.put(programOption, rest.substring(rest.indexOf("format given by ") + "format given by ".length() + 1).trim());
+              }
+              else {
+                if (! rest.startsWith("in ")) {
+                  this.message = "Descriptor " + option + " does not have a proper format.";
+                  return;
+                }
+                rest = rest.substring("in ".length());
+                int pos = rest.indexOf(" format");
+                if (pos == -1) {
+                  this.message = "Descriptor " + option + " does not have a proper format.";
+                  return;
+                }
+                programOption.setFormat(rest.substring(0, pos).trim().toLowerCase().split(" or "));
+              }
+            }
+            // Format type
+            else if (rest.endsWith("file format")) {
+              programOption.setFormat((currentWord + " " + rest.substring(0, rest.indexOf("file format"))).trim().toLowerCase().split(" or "));
+              programOption.setType("format");
+            }
+            // Choice type
+            else if ("choice".compareToIgnoreCase(currentWord) == 0) {
+              programOption.setChoices(rest.replace("(", "").replace(")", "").split(", "));
+              programOption.setType("choice");
+            }
+            // Boolean type
+            else if ("bool".compareToIgnoreCase(currentWord) == 0) {
+              programOption.setType("boolean");
+            }
+            // Other type
+            else {
+              programOption.setType(currentWord);
+            }
+          }
+          // Default value
+          else if ("default".compareToIgnoreCase(type) == 0) {
+            programOption.setDefault(value);
+          }
+          else {
+            this.message = "Do not understand option descriptor '" + inner + "'.";
+            return;
+          }
+        }
+        else {
+          // Compulsory option
+          if ("compulsory".compareToIgnoreCase(inner) == 0) {
+            programOption.setCompulsory(true);
+          }
+          else {
+            this.message = "Do not understand option descriptor '" + inner + "'.";
+            return;
+          }
+        }
+      }
+      program.addOption(programOption);
+    }
+
+    // Set associated option
+    Iterator it = associatedOption.keySet().iterator();
+    while (it.hasNext()) {
+      ProgramOption programOption = (ProgramOption) it.next();
+      programOption.setAssociatedOption(identifierToOptions.get(associatedOption.get(programOption)));
+    }
+  }
+
+  public String getMessage () {
+    return this.message;
+  }
+
+  public Program getProgram () {
+    return this.program;
+  }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Sav/PythonProgramFinder.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,90 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.io.*;
+import java.util.*;
+
+public class PythonProgramFinder {
+
+  String             dirName;
+  Vector < Program > programs;
+
+  public PythonProgramFinder(String dirName) {
+    this.dirName = dirName;  
+  }
+
+  public String findPrograms() {
+    java.io.File directory = new java.io.File(this.dirName);
+    String[] files         = directory.list(new FilenameFilter() {public boolean accept(java.io.File dir, String name) {return ((! name.startsWith(".")) && (! name.startsWith("test")) && ((new java.io.File(dir, name)).isFile()) && (name.endsWith(".py")));}});
+    this.programs          = new Vector < Program > ();
+
+    for (int i = 0; i < files.length; i++) {
+      String[] commandList  = {Global.pythonCommand, "Python" + java.io.File.separator + files[i], "-h"};
+      String command = "";
+      for (int j = 0; j < commandList.length; j++) {
+        command += commandList[j] + " ";
+      }
+      ProcessBuilder pb = new ProcessBuilder(commandList);
+      pb = pb.redirectErrorStream(true);
+      Map<String, String> env = pb.environment();
+      env.put("PYTHONPATH", System.getProperty("user.dir") + java.io.File.separator + "Python");
+      env.put("SMARTPATH", System.getProperty("user.dir") + java.io.File.separator + "Python");
+      env.put("SMARTMYSQLPATH", Global.mysqlCommand);
+      env.put("SMARTRPATH", Global.rCommand);
+
+      PythonHelperReader helperReader = new PythonHelperReader(files[i]);
+      try {
+        final Process process = pb.start();
+        InputStream is        = process.getInputStream();
+        InputStreamReader isr = new InputStreamReader(is);
+        BufferedReader br     = new BufferedReader(isr);
+        helperReader.setReader(br);
+        helperReader.run();
+      }
+      catch (IOException e) {
+        e.printStackTrace();
+        return "Command '" + command + "' failed (I/O error)...\n";
+      }
+      String comments = helperReader.getMessage();
+      if (comments != null) return comments;
+      Program program = helperReader.getProgram();
+      if ("Personnal".compareToIgnoreCase(program.getSection()) != 0) {
+        this.programs.add(program);
+      }
+    }
+    return null;
+  }
+
+  public Vector <Program> getPrograms () {
+    return this.programs;
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Sav/Smart.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,489 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.*;
+import javax.swing.*;
+import javax.swing.filechooser.*;
+import javax.swing.border.*;
+import javax.swing.SwingUtilities;
+
+
+public class Smart extends JPanel implements ActionListener {
+
+  String version = "1.0.2";
+
+  JFrame mainFrame;
+  JButton openButton;
+  JButton comparisonGoButton;
+
+  JComboBox formatTypes;
+  JComboBox fileFormats;
+  String[]  emptyFormats = {"Choose a type first..."};
+
+  JFrame  askFrame;
+  JButton pythonButton;
+  JButton mySqlButton;
+  JButton rButton;
+
+  HashMap <JButton, Program> callingProgram;
+
+  // comparison
+  JList comparisonFile1List;
+  JList comparisonFile2List;
+  JTextField comparisonOutputTextField;
+  JTextField comparisonFiveQueryExtensionTextField;
+  JCheckBox comparisonColinearCheckBox;
+  JCheckBox comparisonAntisenseCheckBox;
+  JCheckBox comparisonInvertCheckBox;
+
+  JList        fileList;
+  JTextArea    logArea;
+
+  // progress bar
+  JLabel       messageField;
+  JProgressBar progressBar;
+  JLabel       etaField;
+
+  // process
+  Program           currentProgram;
+  Process           process;
+  javax.swing.Timer processTimer;
+
+
+  int previousStatus;
+
+  public Smart() {
+    super(new BorderLayout());
+
+    callingProgram = new HashMap <JButton, Program> ();
+
+    previousStatus = -1;
+
+    processTimer = new javax.swing.Timer(1000, this);
+    processTimer.stop();
+
+    // Ask frame buttons
+    pythonButton = new JButton("find...");
+    mySqlButton  = new JButton("find...");
+    rButton      = new JButton("find...");
+
+    // Get available formats
+    FormatsReader formatReader = new FormatsReader(Global.smartFormatsFileName);
+    if (! formatReader.read()) {
+      System.out.println("Something was wrong while reading file format...");
+    }
+
+    // Get screen size
+    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+
+    // Log
+    logArea = new JTextArea(512, Global.logAreaSize);
+    logArea.setPreferredSize(new Dimension(screenSize.width, (int) (screenSize.height * 0.22)));
+    logArea.setFont(new Font("Monospaced", logArea.getFont().getStyle(), logArea.getFont().getSize()));
+    JScrollPane logScroll  = new JScrollPane(logArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+    TitledBorder logBorder = BorderFactory.createTitledBorder("Log");
+    logScroll.setBorder(logBorder);
+    logArea.append("Using S-MART " + version + "\n");
+
+    GridLayout horizontalLayout = new GridLayout(1, 0);
+
+    // check configuration
+    this.readConfigurationFile();
+    this.checkConfiguration();
+
+    // Tabs
+    JTabbedPane tabbedPane = new JTabbedPane();
+    tabbedPane.setPreferredSize(new Dimension(screenSize.width, (int) (screenSize.height * 0.75)));
+
+    // File panel
+    JPanel filePanel = new JPanel(false);
+    filePanel.setLayout(new FlowLayout());
+    tabbedPane.add("Files", filePanel);
+
+    // Format sub-panel
+    JPanel         formatComboPanel  = new JPanel(false);
+    JPanel         formatPanel       = new JPanel(false);
+    Vector<String> formatTypesString = Global.formats.getFormatTypes();
+    formatPanel.setLayout(horizontalLayout);
+    formatTypesString.insertElementAt("Choose the format type", 0);
+    JLabel formatLabel = new JLabel("Format");
+    formatTypes        = new JComboBox(formatTypesString);
+    fileFormats        = new JComboBox(emptyFormats);
+    formatLabel.setLabelFor(fileFormats);
+    formatTypes.addActionListener(this);
+    formatComboPanel.add(formatTypes);
+    formatComboPanel.add(fileFormats);
+
+    formatPanel.add(formatLabel);
+    formatPanel.add(formatComboPanel);
+
+    // File chooser sub-panel
+    JPanel fileChooserPanel = new JPanel(false);
+    fileChooserPanel.setLayout(horizontalLayout);
+    JLabel fileLabel = new JLabel("File");
+    openButton = new JButton("Open a File...");
+    openButton.addActionListener(this);
+
+    fileChooserPanel.add(fileLabel);
+    fileChooserPanel.add(openButton);
+
+    // File list sub-panel
+    JPanel existingFilesPanel = new JPanel(false);
+    existingFilesPanel.setLayout(horizontalLayout);
+    existingFilesPanel.setMinimumSize(new Dimension(10000, 10000));
+    JLabel existingFilesLabel = new JLabel("Existing files");
+    Box fileListBox = Box.createHorizontalBox();
+    fileListBox.add(Box.createRigidArea(new Dimension(0, 100)));
+    JList fileList = new JList(Global.fileNames);
+    fileList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
+    fileList.setVisibleRowCount(4);
+    JScrollPane listScroller = new JScrollPane(fileList);
+    fileListBox.add(listScroller);
+
+    existingFilesPanel.add(existingFilesLabel);
+    existingFilesPanel.add(fileListBox);
+
+    // File panel layout
+    Box box = Box.createVerticalBox();
+    box.add(formatPanel);
+    box.add(fileChooserPanel);
+    box.add(existingFilesPanel);
+    filePanel.add(box);
+
+    // Program panels
+    TreeMap < String, JTabbedPane > panels = new TreeMap < String, JTabbedPane >();
+    PythonProgramFinder programFinder = new PythonProgramFinder("Python");
+    String comments = programFinder.findPrograms();
+    if (comments != null) {
+      logArea.append(comments);
+    }
+    for (int i = 0; i < programFinder.getPrograms().size(); i++) {
+      Program program         = programFinder.getPrograms().get(i);
+      JPanel programPanel     = program.getPanel();
+      String section          = program.getSection();
+      JTabbedPane sectionPane = null;
+      if (panels.containsKey(section)) {
+        sectionPane = panels.get(section);
+      }
+      else {
+        sectionPane = new JTabbedPane();
+        tabbedPane.addTab(section, sectionPane);
+        panels.put(section, sectionPane);
+      }
+
+      JScrollPane programScroll  = new JScrollPane(programPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+      sectionPane.addTab(program.getName(), programScroll);
+
+      JButton button  = program.getButton();
+      button.addActionListener(this);
+      callingProgram.put(button, program);
+    }
+
+    // Progress bar
+    JPanel progressPanel = new JPanel(new GridLayout(1, 0), false);
+    progressPanel.setPreferredSize(new Dimension(screenSize.width, (int) (screenSize.height * 0.02)));
+    messageField = new JLabel();
+    progressBar  = new JProgressBar(0, 100);
+    etaField     = new JLabel();
+    messageField.setHorizontalAlignment(JLabel.LEFT);
+    progressBar.setValue(0);
+    etaField.setHorizontalAlignment(JLabel.RIGHT);
+    progressBar.setStringPainted(true);
+    progressPanel.add(messageField);
+    progressPanel.add(progressBar);
+    progressPanel.add(etaField);
+      
+    add(tabbedPane, BorderLayout.PAGE_START);
+    add(logScroll, BorderLayout.CENTER);
+    add(progressPanel, BorderLayout.PAGE_END);
+  }
+
+
+  public boolean checkConfiguration() {
+    int status = this.testConfiguration();
+  
+    if (status == previousStatus) {
+      logArea.append("S-MART does not seem to work properly... Tried to manage it by myself, unsuccessfully... Check documentation for further explanation...\n");
+      return false;
+    }
+
+    switch (status) {
+      case 0:
+        return true;
+      case 1:
+        logArea.append("S-MART does not seem to work properly... Check documentation for further explanation...\n");
+        break;
+      case 3:
+        this.askWhereIsProgram("python");
+        break;
+      case 4:
+        break;
+      case 5:
+        this.askWhereIsProgram("mySQL");
+        break;
+      case 6:
+        this.askWhereIsProgram("R");
+        break;
+      case 7:
+        logArea.append("Please install 'ColorBrewer' R package...\n");
+        break;
+      default:
+        logArea.append("Weird configuration test status: " + status + "...\n");
+    }
+    previousStatus = status;
+    return true;
+  }
+
+
+  public int testConfiguration() {
+    String[]        command  = {Global.pythonCommand, "Python" + java.io.File.separator + "testInstall.py"};
+    ProgramLauncher launcher = new ProgramLauncher(command, logArea, messageField, progressBar, etaField);
+    String          line;
+    launcher.execute();
+    (new Exception("hello")).printStackTrace();
+    return launcher.getExitValue();
+  }
+
+
+  public void readConfigurationFile() {
+    java.io.File   file      = new java.io.File(Global.smartConfFileName);
+    String         line      = null;
+
+    if (! file.exists()) {
+      return;
+    }
+
+    try {
+      BufferedReader reader = new BufferedReader(new FileReader(file));
+
+      while ((line = reader.readLine()) != null) {
+        line = line.trim();
+        if      (line.startsWith("python:")) Global.pythonCommand = line.substring("python:".length()).trim();
+        else if (line.startsWith("mysql:"))  Global.mysqlCommand  = line.substring("mysql:".length()).trim();
+        else if (line.startsWith("r:"))      Global.rCommand      = line.substring("r:".length()).trim();
+      }
+      reader.close();
+    }
+    catch (FileNotFoundException e) {
+      logArea.append("Configuration file is empty: " + e.getMessage() + "!\n");
+      return;
+    }
+    catch (IOException e) {
+      logArea.append("Weird with configuration file: " + e.getMessage() + "!\n");
+      return;
+    }
+  }
+
+
+  public void askWhereIsProgram(String program) {
+    askFrame = new JFrame("Where is " + program + "?");
+    askFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+    JLabel label = new JLabel("Where is your " + program + " (or " + program + ".exe) file?");
+    JButton button = null;
+    if ("python".equals(program)) {
+      button = pythonButton;
+    }
+    else if ("mySQL".equals(program)) {
+      button = mySqlButton;
+    }
+    else if ("R".equals(program)) {
+      button = rButton;
+    }
+    else {
+      logArea.append("Problem with the button!\n");
+    }
+    askFrame.getContentPane().add(label, BorderLayout.WEST);
+    askFrame.getContentPane().add(button, BorderLayout.EAST);
+    button.addActionListener(this);
+    askFrame.pack();
+    askFrame.setVisible(true);
+    askFrame.setAlwaysOnTop(true);
+  }
+
+
+  public void actionPerformed(ActionEvent e) {
+
+    // Python command chooser
+    if (e.getSource() == pythonButton) {
+      JFileChooser chooser = new JFileChooser();
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        Global.pythonCommand = chooser.getSelectedFile().getPath();
+        askFrame.setVisible(false);
+        askFrame.dispose();
+        try {
+          BufferedWriter out = new BufferedWriter(new FileWriter(Global.smartConfFileName, true));
+          out.write("python: " + Global.pythonCommand + "\n");
+          out.close();
+        }
+        catch (IOException exception) {
+          logArea.append("Cannot write configuration file!\n");
+        }
+      }
+      this.checkConfiguration();
+    }
+    // MySQL command chooser
+    else if (e.getSource() == mySqlButton) {
+      JFileChooser chooser = new JFileChooser();
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        Global.mysqlCommand = chooser.getSelectedFile().getPath();
+        askFrame.setVisible(false);
+        askFrame.dispose();
+        try {
+          BufferedWriter out = new BufferedWriter(new FileWriter(Global.smartConfFileName, true));
+          out.write("mysql: " + Global.mysqlCommand + "\n");
+          out.close();
+        }
+        catch (IOException exception) {
+          logArea.append("Cannot write configuration file!\n");
+        }
+      }
+      this.checkConfiguration();
+    }
+    // R command chooser
+    else if (e.getSource() == rButton) {
+      JFileChooser chooser = new JFileChooser();
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        Global.rCommand = chooser.getSelectedFile().getPath();
+        askFrame.setVisible(false);
+        askFrame.dispose();
+        try {
+          BufferedWriter out = new BufferedWriter(new FileWriter(Global.smartConfFileName, true));
+          out.write("r: " + Global.rCommand + "\n");
+          out.close();
+        }
+        catch (IOException exception) {
+          logArea.append("Cannot write configuration file!\n");
+        }
+      }
+      this.checkConfiguration();
+    }
+    // Format type
+    else if (e.getSource() == formatTypes) {
+      fileFormats.removeAllItems();
+      Vector < String > selectedFormats = Global.formats.getFormats((String) formatTypes.getSelectedItem()).getFormats();
+      for (int i = 0; i < selectedFormats.size(); i++) {
+        fileFormats.addItem(selectedFormats.get(i));
+      }
+    }
+    // Main file chooser
+    else if (e.getSource() == openButton) {
+      JFileChooser chooser = new JFileChooser();
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        String fileName = chooser.getSelectedFile().getPath();
+        Global.fileNames.addElement(fileName);
+        Global.files.addFile(fileName, (String) formatTypes.getSelectedItem(), (String) fileFormats.getSelectedItem());
+      }
+    }
+    // Other file choosers
+    else if (Global.otherFilesChooser.containsKey(e.getSource())) {
+      JTextField textField = Global.otherFilesChooser.get(e.getSource());
+      JFileChooser chooser = new JFileChooser();
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        textField.setText(chooser.getSelectedFile().getPath());
+      }
+    }
+    // Other directories choosers
+    else if (Global.otherDirectoriesChooser.containsKey(e.getSource())) {
+      JTextField textField = Global.otherDirectoriesChooser.get(e.getSource());
+      JFileChooser chooser = new JFileChooser();
+      chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        textField.setText(chooser.getSelectedFile().getPath());
+      }
+    }
+    else if (Global.otherFileConcatenationChooser.containsKey(e.getSource())) {
+      JTextField textField = Global.otherDirectoriesChooser.get(e.getSource());
+      JFileChooser chooser = new JFileChooser();
+      chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        String text = textField.getText();
+        if ((text == null) || ("".equals(text))) {
+          textField.setText(chooser.getSelectedFile().getPath());
+        }
+        else {
+          textField.setText(text + "," + chooser.getSelectedFile().getPath());
+        }
+      }
+    }
+    // Programs
+    else {
+      currentProgram = callingProgram.get(e.getSource());
+      String comment = currentProgram.checkValues();
+      if (comment != null) {
+        logArea.append(comment);
+        return;
+      }
+      LinkedList <String> command = currentProgram.getCommand();
+      ProgramLauncher launcher = new ProgramLauncher(command, logArea, messageField, progressBar, etaField);
+      launcher.execute();
+      Vector < File > outputFiles = currentProgram.getOutputFiles();
+      for (int i = 0; i < outputFiles.size(); i++) {
+        File file = outputFiles.get(i);
+        if (file.getFormatType().compareToIgnoreCase("other") != 0) {
+          Global.fileNames.addElement(file.getName());
+          Global.files.addFile(file);
+        }
+      }
+      currentProgram = null;
+    }
+  }
+
+
+  private static void createAndShowGUI() {
+    // Create and set up the window.
+    JFrame mainFrame = new JFrame("S-Mart");
+    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+    //Create and set up the content pane.
+    JComponent newContentPane = new Smart();
+    newContentPane.setOpaque(true);
+    mainFrame.setContentPane(newContentPane);
+
+    // Display the window.
+    mainFrame.pack();
+    mainFrame.setVisible(true);
+    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+    mainFrame.setBounds(0, 0, screenSize.width, screenSize.height);
+  }
+
+
+  public static void main(String[] args) {
+    javax.swing.SwingUtilities.invokeLater(new Runnable() {
+      public void run() {
+        createAndShowGUI();
+      }
+    });
+  }
+}
Binary file smart_toolShed/SMART/Java/Smart.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/Smart.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,668 @@
+/**
+ *
+ * Copyright INRA-URGI 2009-2010
+ * 
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/ or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ * 
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ * 
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ * 
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+import java.util.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowAdapter;
+import java.io.*;
+import javax.swing.*;
+import javax.swing.filechooser.*;
+import javax.swing.border.*;
+import javax.swing.SwingUtilities;
+import java.util.prefs.BackingStoreException;
+
+
+public class Smart extends JPanel implements ActionListener {
+
+  String version = "1.1.0";
+
+  JFrame mainFrame;
+  JButton openButton;
+  JButton resetFileButton;
+
+  JComboBox formatTypes;
+  JComboBox fileFormats;
+  String[]  emptyFormats = {"Choose a type first..."};
+
+  JFrame  askFrame;
+  JButton pythonButton;
+  JButton mySqlButton;
+  JButton rButton;
+
+  HashMap <JButton, Program> callingProgram;
+
+  static JList        fileList;
+  static JTextArea    logArea;
+
+  // progress bar
+  static JLabel       messageField;
+  static JProgressBar progressBar;
+  static JLabel       etaField;
+
+  // process
+  Program           currentProgram;
+  Process           process;
+  javax.swing.Timer processTimer;
+
+
+  int previousStatus;
+
+  public Smart() {
+    super(new BorderLayout());
+
+    callingProgram = new HashMap <JButton, Program> ();
+
+    previousStatus = -1;
+
+    processTimer = new javax.swing.Timer(1000, this);
+    processTimer.stop();
+
+    // Ask frame buttons
+    pythonButton = new JButton("find...");
+    mySqlButton  = new JButton("find...");
+    rButton      = new JButton("find...");
+
+    // Get available formats
+    FormatsReader formatReader = new FormatsReader(Global.smartFormatsFileName);
+    if (! formatReader.read()) {
+      System.out.println("Something was wrong while reading file format...");
+    }
+
+    // Get screen size
+    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+
+    // Log
+    logArea = new JTextArea(512, Global.logAreaSize);
+    logArea.setPreferredSize(new Dimension(screenSize.width, (int) (screenSize.height * 0.22)));
+    logArea.setFont(new Font("Monospaced", logArea.getFont().getStyle(), logArea.getFont().getSize()));
+    JScrollPane logScroll  = new JScrollPane(logArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+    TitledBorder logBorder = BorderFactory.createTitledBorder("Log");
+    logScroll.setBorder(logBorder);
+    logArea.append("Using S-MART " + version + "\n");
+
+    GridLayout horizontalLayout = new GridLayout(1, 0);
+
+    // check configuration
+    this.readConfigurationFile();
+    if (System.getProperty("os.name").matches("(?i).*Windows.*")) {
+      if (! this.checkDefaultDir()) {
+        this.checkRegistries();
+      }
+    }
+    this.checkConfiguration();
+
+    // Tabs
+    JTabbedPane tabbedPane = new JTabbedPane();
+    tabbedPane.setPreferredSize(new Dimension(screenSize.width, (int) (screenSize.height * 0.75)));
+
+    // File panel
+    JPanel filePanel = new JPanel(false);
+    filePanel.setLayout(new FlowLayout());
+    tabbedPane.add("Files", filePanel);
+
+    // Format sub-panel
+    JPanel         formatComboPanel  = new JPanel(false);
+    JPanel         formatPanel       = new JPanel(false);
+    Vector<String> formatTypesString = Global.formats.getFormatTypes();
+    formatPanel.setLayout(horizontalLayout);
+    formatTypesString.insertElementAt("Choose the format type", 0);
+    JLabel formatLabel = new JLabel("Format");
+    formatTypes        = new JComboBox(formatTypesString);
+    fileFormats        = new JComboBox(emptyFormats);
+    formatLabel.setLabelFor(fileFormats);
+    formatTypes.addActionListener(this);
+    formatComboPanel.add(formatTypes);
+    formatComboPanel.add(fileFormats);
+
+    formatPanel.add(formatLabel);
+    formatPanel.add(formatComboPanel);
+
+    // File chooser sub-panel
+    JPanel fileChooserPanel = new JPanel(false);
+    fileChooserPanel.setLayout(horizontalLayout);
+    JLabel fileLabel = new JLabel("File");
+    openButton = new JButton("Open a File...");
+    openButton.addActionListener(this);
+
+    fileChooserPanel.add(fileLabel);
+    fileChooserPanel.add(openButton);
+
+    // File list sub-panel
+    JPanel existingFilesPanel = new JPanel(false);
+    existingFilesPanel.setLayout(horizontalLayout);
+    existingFilesPanel.setMinimumSize(new Dimension(10000, 10000));
+    JLabel existingFilesLabel = new JLabel("Existing files");
+    Box fileListBox = Box.createHorizontalBox();
+    fileListBox.add(Box.createRigidArea(new Dimension(0, 100)));
+    fileList = new JList(new DefaultListModel());
+    fileList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
+    fileList.setVisibleRowCount(4);
+    JScrollPane listScroller = new JScrollPane(fileList);
+    fileListBox.add(listScroller);
+
+    existingFilesPanel.add(existingFilesLabel);
+    existingFilesPanel.add(fileListBox);
+
+    // Reset sub-panel
+    JPanel resetFilePanel = new JPanel(false);
+    resetFileButton = new JButton("Reset");
+    resetFileButton.addActionListener(this);
+
+    // File panel layout
+    Box box = Box.createVerticalBox();
+    box.add(formatPanel);
+    box.add(fileChooserPanel);
+    box.add(existingFilesPanel);
+    box.add(resetFileButton);
+    filePanel.add(box);
+
+    // Program panels
+    TreeMap < String, JTabbedPane > panels = new TreeMap < String, JTabbedPane >();
+    PythonProgramFinder programFinder = new PythonProgramFinder("Python");
+    String comments = programFinder.findPrograms();
+    if (comments != null) {
+      logArea.append(comments);
+    }
+    for (int i = 0; i < programFinder.getPrograms().size(); i++) {
+      Program program         = programFinder.getPrograms().get(i);
+      JPanel programPanel     = program.getPanel();
+      String section          = program.getSection();
+      JTabbedPane sectionPane = null;
+      if (panels.containsKey(section)) {
+        sectionPane = panels.get(section);
+      }
+      else {
+        sectionPane = new JTabbedPane();
+        tabbedPane.addTab(section, sectionPane);
+        panels.put(section, sectionPane);
+      }
+
+      JScrollPane programScroll  = new JScrollPane(programPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+      sectionPane.addTab(program.getName(), programScroll);
+
+      JButton button  = program.getButton();
+      button.addActionListener(this);
+      callingProgram.put(button, program);
+    }
+
+    // Progress bar
+    JPanel progressPanel = new JPanel(new GridLayout(1, 0), false);
+    progressPanel.setPreferredSize(new Dimension(screenSize.width, (int) (screenSize.height * 0.02)));
+    messageField = new JLabel();
+    progressBar  = new JProgressBar(0, 100);
+    etaField     = new JLabel();
+    messageField.setHorizontalAlignment(JLabel.LEFT);
+    progressBar.setValue(0);
+    etaField.setHorizontalAlignment(JLabel.RIGHT);
+    progressBar.setStringPainted(true);
+    progressPanel.add(messageField);
+    progressPanel.add(progressBar);
+    progressPanel.add(etaField);
+      
+    add(tabbedPane, BorderLayout.PAGE_START);
+    add(logScroll, BorderLayout.CENTER);
+    add(progressPanel, BorderLayout.PAGE_END);
+  }
+
+
+  public String checkSubKey(int hkey, String key, String subKey, String trace) {
+    try {
+      for (String currentSubKey: WindowsRegistry.readStringSubKeys(hkey, key)) {
+        trace += "Looking at sub-key " + currentSubKey;
+        if (currentSubKey.matches(subKey)) {
+          trace += "  OK";
+          return subKey;
+        }
+        trace += "\n";
+      }
+    }
+    catch (Exception e) {
+      final Writer writer = new StringWriter();
+      final PrintWriter printWriter = new PrintWriter(writer);
+      e.printStackTrace(printWriter);
+      trace += writer.toString();          
+    }
+    return null;
+  }
+
+  public void debugRegistry(int hkey, String keys[], String valueName, String trace) {
+    String concatenatedKeys = "";
+    String selectedKey      = null;
+    for (String key: keys) {
+      selectedKey = checkSubKey(hkey, concatenatedKeys, key, trace);
+      if (selectedKey != null) {
+        concatenatedKeys += "\\" + selectedKey;
+      }
+      else {
+        return;
+      }
+    }
+  }
+
+
+  public String checkRegistry(int hkey, String key, String valueName, String trace) {
+    String result = null;
+    try {
+      result = WindowsRegistry.readString(hkey, key, valueName);
+    }
+    catch (Exception e) {
+      final Writer writer = new StringWriter();
+      final PrintWriter printWriter = new PrintWriter(writer);
+      e.printStackTrace(printWriter);
+      trace += result.toString();          
+    }
+    return result;
+  }
+
+
+  public boolean checkDefaultDir() {
+    String       defaultPythonPath = System.getProperty("user.dir") + "\\Apps\\Python\\python.exe";
+    java.io.File defaultPythonFile = new java.io.File(defaultPythonPath);
+    String       defaultRPath      = System.getProperty("user.dir") + "\\Apps\\R\\bin\\R.exe";
+    java.io.File defaultRFile      = new java.io.File(defaultRPath);
+    if (defaultPythonFile.exists()) {
+        Global.pythonCommand = defaultPythonPath;
+        logArea.append("Python found in default directory: " + defaultPythonPath + "\n");
+    }
+    else {
+        logArea.append("Python not found in default directory: " + defaultPythonPath + "\n");
+        return false;
+    }
+    if (defaultRFile.exists()) {
+        logArea.append("R found in default directory: " + defaultRPath + "\n");
+        Global.rCommand = defaultRPath;
+        return true;
+    }
+    logArea.append("Python not found in default directory: " + defaultPythonPath + "\n");
+    return false;
+  }
+
+
+  public boolean checkRegistries() {
+    String          pythonDir  = null;
+    String          validValue = null;
+    String          rDir;
+    String[]        pythonFlavors     = {"2.5", "2.6", "2.7"};
+    String[]        pythonDirectories = {"Python25", "Python26", "Python27"};
+    String[]        rDirectories      = {"R-2.11.0", "R-2.11.0-x64"};
+    String          trace             = "";
+    for (String pythonFlavor: pythonFlavors) {
+      pythonDir = checkRegistry(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Python\\PythonCore\\" + pythonFlavor + "\\InstallPath", "", trace);
+      if (pythonDir != null) {
+        break;
+      }
+    }
+    if (pythonDir == null) {
+      try {
+        logArea.append("Using OS: " + WindowsRegistry.readString(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductName") + "\n");
+      }
+      catch (Exception e) {
+        logArea.append("Cannot do simple registry test. Strange...\n");
+      }
+      String keys[] = {"SOFTWARE", "Python", "PythonCore", "2.[567]", "InstallPath"};
+      debugRegistry(WindowsRegistry.HKEY_LOCAL_MACHINE, keys, "", trace);
+      logArea.append("S-MART cannot find Python installation directory using registry. Trying desperate move...\n");
+      for (String currentDirectory: pythonDirectories) {
+        String fileName = "C:\\" + currentDirectory;
+        java.io.File file = new java.io.File(fileName);
+        if (file.exists()) {
+          pythonDir = fileName;
+          break;
+        }
+      }
+      if (pythonDir == null) {
+        logArea.append("S-MART cannot find Python installation directory despite all my efforts...\n" + trace);
+        return false;
+      }
+    }
+    rDir = checkRegistry(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\R-core\\R", "InstallPath", trace);
+    if (rDir == null) {
+      logArea.append("S-MART cannot find R installation directory using registry. Trying desperate move...\n");
+      for (String currentDirectory: rDirectories) {
+        String fileName = "C:\\Program Files\\R\\" + currentDirectory;
+        java.io.File file = new java.io.File(fileName);
+        if (file.exists()) {
+          rDir = fileName;
+          break;
+        }
+      }
+      if (rDir == null) {
+        logArea.append("S-MART cannot find R installation directory despite all my efforts...\n" + trace);
+        return false;
+      }
+    }
+    Global.pythonCommand = pythonDir + "\\" + "python.exe";
+    Global.rCommand      = rDir + "\\" + "bin\\R.exe";
+    return true;
+  }
+
+
+  public boolean checkConfiguration() {
+    int status = this.testConfiguration();
+  
+    if (status == previousStatus) {
+      logArea.append("S-MART does not seem to work properly... Tried to manage it by myself, unsuccessfully... Check documentation for further explanation...\n");
+      return false;
+    }
+
+    switch (status) {
+      case 0:
+        return true;
+      case 1:
+        logArea.append("S-MART does not seem to work properly... Check documentation for further explanation...\n");
+        break;
+      case 3:
+        this.askWhereIsProgram("python");
+        break;
+      case 4:
+        break;
+      case 5:
+        this.askWhereIsProgram("mySQL");
+        break;
+      case 6:
+        this.askWhereIsProgram("R");
+        break;
+      case 7:
+        logArea.append("Please install 'ColorBrewer' R package...\n");
+        break;
+      default:
+        logArea.append("Weird configuration test status: " + status + "...\n");
+    }
+    previousStatus = status;
+    return true;
+  }
+
+
+  public int testConfiguration() {
+    String[]        command  = {Global.pythonCommand, "Python" + java.io.File.separator + "testInstall.py"};
+    ProgramLauncher launcher = new ProgramLauncher(command, logArea, messageField, progressBar, etaField);
+    String          line;
+    launcher.execute();
+    return launcher.getExitValue();
+  }
+
+
+  public void readConfigurationFile() {
+    java.io.File   file      = new java.io.File(Global.smartConfFileName);
+    String         line      = null;
+
+    if (! file.exists()) {
+      return;
+    }
+
+    try {
+      BufferedReader reader = new BufferedReader(new FileReader(file));
+
+      while ((line = reader.readLine()) != null) {
+        line = line.trim();
+        if      (line.startsWith("python:")) Global.pythonCommand = line.substring("python:".length()).trim();
+        else if (line.startsWith("mysql:"))  Global.mysqlCommand  = line.substring("mysql:".length()).trim();
+        else if (line.startsWith("r:"))      Global.rCommand      = line.substring("r:".length()).trim();
+      }
+      reader.close();
+    }
+    catch (FileNotFoundException e) {
+      logArea.append("Configuration file is empty: " + e.getMessage() + "!\n");
+      return;
+    }
+    catch (IOException e) {
+      logArea.append("Weird with configuration file: " + e.getMessage() + "!\n");
+      return;
+    }
+  }
+
+
+  public void askWhereIsProgram(String program) {
+    askFrame = new JFrame("Where is " + program + "?");
+    askFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+    JLabel label = new JLabel("Where is your " + program + " (or " + program + ".exe) file?");
+    JButton button = null;
+    if ("python".equals(program)) {
+      button = pythonButton;
+    }
+    else if ("mySQL".equals(program)) {
+      button = mySqlButton;
+    }
+    else if ("R".equals(program)) {
+      button = rButton;
+    }
+    else {
+      logArea.append("Problem with the button!\n");
+    }
+    askFrame.getContentPane().add(label, BorderLayout.WEST);
+    askFrame.getContentPane().add(button, BorderLayout.EAST);
+    button.addActionListener(this);
+    askFrame.pack();
+    askFrame.setVisible(true);
+    askFrame.setAlwaysOnTop(true);
+  }
+
+
+  public void actionPerformed(ActionEvent e) {
+
+    // Python command chooser
+    if (e.getSource() == pythonButton) {
+      JFileChooser chooser = new JFileChooser();
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        Global.pythonCommand = chooser.getSelectedFile().getPath();
+        askFrame.setVisible(false);
+        askFrame.dispose();
+        try {
+          BufferedWriter out = new BufferedWriter(new FileWriter(Global.smartConfFileName, true));
+          out.write("python: " + Global.pythonCommand + "\n");
+          out.close();
+        }
+        catch (IOException exception) {
+          logArea.append("Cannot write configuration file!\n");
+        }
+      }
+      this.checkConfiguration();
+    }
+    // MySQL command chooser
+    else if (e.getSource() == mySqlButton) {
+      JFileChooser chooser = new JFileChooser();
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        Global.mysqlCommand = chooser.getSelectedFile().getPath();
+        askFrame.setVisible(false);
+        askFrame.dispose();
+        try {
+          BufferedWriter out = new BufferedWriter(new FileWriter(Global.smartConfFileName, true));
+          out.write("mysql: " + Global.mysqlCommand + "\n");
+          out.close();
+        }
+        catch (IOException exception) {
+          logArea.append("Cannot write configuration file!\n");
+        }
+      }
+      this.checkConfiguration();
+    }
+    // R command chooser
+    else if (e.getSource() == rButton) {
+      JFileChooser chooser = new JFileChooser();
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        Global.rCommand = chooser.getSelectedFile().getPath();
+        askFrame.setVisible(false);
+        askFrame.dispose();
+        try {
+          BufferedWriter out = new BufferedWriter(new FileWriter(Global.smartConfFileName, true));
+          out.write("r: " + Global.rCommand + "\n");
+          out.close();
+        }
+        catch (IOException exception) {
+          logArea.append("Cannot write configuration file!\n");
+        }
+      }
+      this.checkConfiguration();
+    }
+    // Format type
+    else if (e.getSource() == formatTypes) {
+      if (((String) formatTypes.getSelectedItem()).startsWith("Choose")) {
+        return;
+      }
+      fileFormats.removeAllItems();
+      Vector < String > selectedFormats = Global.formats.getFormats((String) formatTypes.getSelectedItem()).getFormats();
+      for (int i = 0; i < selectedFormats.size(); i++) {
+        fileFormats.addItem(selectedFormats.get(i));
+      }
+    }
+    // Main file chooser
+    else if (e.getSource() == openButton) {
+      if (((String) formatTypes.getSelectedItem()).startsWith("Choose")) {
+        logArea.append("Please choose a type and format before selecting a file!\n");
+        return;
+      }
+      JFileChooser chooser = new JFileChooser();
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        String fileName = chooser.getSelectedFile().getPath();
+        Global.fileNames.addElement(fileName);
+        Global.files.addFile(fileName, (String) formatTypes.getSelectedItem(), (String) fileFormats.getSelectedItem());
+        DefaultListModel defaultListModel = (DefaultListModel) fileList.getModel();
+        defaultListModel.addElement(fileName);
+      }
+    }
+    // Reset file chooser
+    else if (e.getSource() == resetFileButton) {
+      Global.files.clear();
+      Global.fileNames.clear();
+      DefaultListModel defaultListModel = (DefaultListModel) fileList.getModel();
+      defaultListModel.clear();
+    }
+    // Other file choosers
+    else if (Global.otherFilesChooser.containsKey(e.getSource())) {
+      JTextField textField = Global.otherFilesChooser.get(e.getSource());
+      JFileChooser chooser = new JFileChooser();
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        textField.setText(chooser.getSelectedFile().getPath());
+      }
+    }
+    // Other directories choosers
+    else if (Global.otherDirectoriesChooser.containsKey(e.getSource())) {
+      JTextField textField = Global.otherDirectoriesChooser.get(e.getSource());
+      JFileChooser chooser = new JFileChooser();
+      chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        textField.setText(chooser.getSelectedFile().getPath());
+      }
+    }
+    else if (Global.otherFileConcatenationChooser.containsKey(e.getSource())) {
+      JTextField textField = Global.otherDirectoriesChooser.get(e.getSource());
+      JFileChooser chooser = new JFileChooser();
+      chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
+        String text = textField.getText();
+        if ((text == null) || ("".equals(text))) {
+          textField.setText(chooser.getSelectedFile().getPath());
+        }
+        else {
+          textField.setText(text + "," + chooser.getSelectedFile().getPath());
+        }
+      }
+    }
+    // Programs
+    else {
+      currentProgram = callingProgram.get(e.getSource());
+      String comment = currentProgram.checkValues();
+      if (comment != null) {
+        logArea.append(comment);
+        return;
+      }
+      LinkedList <String> command = currentProgram.getCommand();
+      ProgramLauncher launcher = new ProgramLauncher(command, logArea, messageField, progressBar, etaField);
+      launcher.execute();
+      Vector < File > outputFiles = currentProgram.getOutputFiles();
+      for (int i = 0; i < outputFiles.size(); i++) {
+        File file = outputFiles.get(i);
+        if (file.getFormatType().compareToIgnoreCase("other") != 0) {
+          Global.fileNames.addElement(file.getName());
+          Global.files.addFile(file);
+        }
+      }
+      currentProgram = null;
+    }
+  }
+
+
+  private static void removeTmpFiles() {
+    logArea.append("You want to quit already?\nRemoving temporary files...");
+    String[]        command  = {Global.pythonCommand, "Python" + java.io.File.separator + "removeAllTmpTables.py"};
+    ProgramLauncher launcher = new ProgramLauncher(command, logArea, messageField, progressBar, etaField);
+    launcher.execute();
+    logArea.append(" done.\nNow quitting.\nBye!");
+  }
+
+
+  private static void printJavaVersions() {
+    String[] pro = {"java.version", "java.vm.version", "java.runtime.version"};
+
+    Properties properties = System.getProperties();
+    for (int i = 0; i < pro.length; i++) {
+      logArea.append(pro[i] + ": " + properties.getProperty(pro[i]) + "\n");
+    }
+  }
+  
+  private static void createAndShowGUI() {
+    // Create and set up the window.
+    JFrame mainFrame = new JFrame("S-Mart");
+    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+    //Create and set up the content pane.
+    JComponent newContentPane = new Smart();
+    newContentPane.setOpaque(true);
+    mainFrame.setContentPane(newContentPane);
+
+    // Display the window.
+    mainFrame.pack();
+    mainFrame.setVisible(true);
+    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+    mainFrame.setBounds(0, 0, screenSize.width, screenSize.height);
+    printJavaVersions();
+
+    // Remove tmp file while quitting.
+    mainFrame.addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowClosing(WindowEvent e) {
+        removeTmpFiles();
+      }
+    });
+  }
+
+
+  public static void main(String[] args) {
+    javax.swing.SwingUtilities.invokeLater(new Runnable() {
+      public void run() {
+        createAndShowGUI();
+      }
+    });
+  }
+}
Binary file smart_toolShed/SMART/Java/SmartInstaller.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/WindowsRegistry.java	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,387 @@
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.prefs.Preferences;
+
+public class WindowsRegistry {
+  public static final int HKEY_CURRENT_USER = 0x80000001;
+  public static final int HKEY_LOCAL_MACHINE = 0x80000002;
+  public static final int REG_SUCCESS = 0;
+  public static final int REG_NOTFOUND = 2;
+  public static final int REG_ACCESSDENIED = 5;
+
+  private static final int KEY_ALL_ACCESS = 0xf003f;
+  private static final int KEY_READ = 0x20019;
+  private static Preferences userRoot = Preferences.userRoot();
+  private static Preferences systemRoot = Preferences.systemRoot();
+  private static Class<? extends Preferences> userClass = userRoot.getClass();
+  private static Method regOpenKey = null;
+  private static Method regCloseKey = null;
+  private static Method regQueryValueEx = null;
+  private static Method regEnumValue = null;
+  private static Method regQueryInfoKey = null;
+  private static Method regEnumKeyEx = null;
+  private static Method regCreateKeyEx = null;
+  private static Method regSetValueEx = null;
+  private static Method regDeleteKey = null;
+  private static Method regDeleteValue = null;
+
+  static {
+    try {
+      regOpenKey = userClass.getDeclaredMethod("WindowsRegOpenKey",
+          new Class[] { int.class, byte[].class, int.class });
+      regOpenKey.setAccessible(true);
+      regCloseKey = userClass.getDeclaredMethod("WindowsRegCloseKey",
+          new Class[] { int.class });
+      regCloseKey.setAccessible(true);
+      regQueryValueEx = userClass.getDeclaredMethod("WindowsRegQueryValueEx",
+          new Class[] { int.class, byte[].class });
+      regQueryValueEx.setAccessible(true);
+      regEnumValue = userClass.getDeclaredMethod("WindowsRegEnumValue",
+          new Class[] { int.class, int.class, int.class });
+      regEnumValue.setAccessible(true);
+      regQueryInfoKey = userClass.getDeclaredMethod("WindowsRegQueryInfoKey1",
+          new Class[] { int.class });
+      regQueryInfoKey.setAccessible(true);
+      regEnumKeyEx = userClass.getDeclaredMethod(  
+          "WindowsRegEnumKeyEx", new Class[] { int.class, int.class,  
+              int.class });  
+      regEnumKeyEx.setAccessible(true);
+      regCreateKeyEx = userClass.getDeclaredMethod(  
+          "WindowsRegCreateKeyEx", new Class[] { int.class,  
+              byte[].class });  
+      regCreateKeyEx.setAccessible(true);  
+      regSetValueEx = userClass.getDeclaredMethod(  
+          "WindowsRegSetValueEx", new Class[] { int.class,  
+              byte[].class, byte[].class });  
+      regSetValueEx.setAccessible(true); 
+      regDeleteValue = userClass.getDeclaredMethod(  
+          "WindowsRegDeleteValue", new Class[] { int.class,  
+              byte[].class });  
+      regDeleteValue.setAccessible(true); 
+      regDeleteKey = userClass.getDeclaredMethod(  
+          "WindowsRegDeleteKey", new Class[] { int.class,  
+              byte[].class });  
+      regDeleteKey.setAccessible(true); 
+    }
+    catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  private WindowsRegistry() {  }
+
+  /**
+   * Read a value from key and value name
+   * @param hkey   HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
+   * @param key
+   * @param valueName
+   * @return the value
+   * @throws IllegalArgumentException
+   * @throws IllegalAccessException
+   * @throws InvocationTargetException
+   */
+  public static String readString(int hkey, String key, String valueName) 
+    throws IllegalArgumentException, IllegalAccessException,
+    InvocationTargetException 
+  {
+    if (hkey == HKEY_LOCAL_MACHINE) {
+      return readString(systemRoot, hkey, key, valueName);
+    }
+    else if (hkey == HKEY_CURRENT_USER) {
+      return readString(userRoot, hkey, key, valueName);
+    }
+    else {
+      throw new IllegalArgumentException("hkey=" + hkey);
+    }
+  }
+
+  /**
+   * Read value(s) and value name(s) form given key 
+   * @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
+   * @param key
+   * @return the value name(s) plus the value(s)
+   * @throws IllegalArgumentException
+   * @throws IllegalAccessException
+   * @throws InvocationTargetException
+   */
+  public static Map<String, String> readStringValues(int hkey, String key) 
+    throws IllegalArgumentException, IllegalAccessException,
+    InvocationTargetException 
+  {
+    if (hkey == HKEY_LOCAL_MACHINE) {
+      return readStringValues(systemRoot, hkey, key);
+    }
+    else if (hkey == HKEY_CURRENT_USER) {
+      return readStringValues(userRoot, hkey, key);
+    }
+    else {
+      throw new IllegalArgumentException("hkey=" + hkey);
+    }
+  }
+
+  /**
+   * Read the value name(s) from a given key
+   * @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
+   * @param key
+   * @return the value name(s)
+   * @throws IllegalArgumentException
+   * @throws IllegalAccessException
+   * @throws InvocationTargetException
+   */
+  public static List<String> readStringSubKeys(int hkey, String key) 
+    throws IllegalArgumentException, IllegalAccessException,
+    InvocationTargetException 
+  {
+    if (hkey == HKEY_LOCAL_MACHINE) {
+      return readStringSubKeys(systemRoot, hkey, key);
+    }
+    else if (hkey == HKEY_CURRENT_USER) {
+      return readStringSubKeys(userRoot, hkey, key);
+    }
+    else {
+      throw new IllegalArgumentException("hkey=" + hkey);
+    }
+  }
+
+  /**
+   * Create a key
+   * @param hkey  HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
+   * @param key
+   * @throws IllegalArgumentException
+   * @throws IllegalAccessException
+   * @throws InvocationTargetException
+   */
+  public static void createKey(int hkey, String key) 
+    throws IllegalArgumentException, IllegalAccessException,
+    InvocationTargetException 
+  {
+    int [] ret;
+    if (hkey == HKEY_LOCAL_MACHINE) {
+      ret = createKey(systemRoot, hkey, key);
+      regCloseKey.invoke(systemRoot, new Object[] { new Integer(ret[0]) });
+    }
+    else if (hkey == HKEY_CURRENT_USER) {
+      ret = createKey(userRoot, hkey, key);
+      regCloseKey.invoke(userRoot, new Object[] { new Integer(ret[0]) });
+    }
+    else {
+      throw new IllegalArgumentException("hkey=" + hkey);
+    }
+    if (ret[1] != REG_SUCCESS) {
+      throw new IllegalArgumentException("rc=" + ret[1] + "  key=" + key);
+    }
+  }
+
+  /**
+   * Write a value in a given key/value name
+   * @param hkey
+   * @param key
+   * @param valueName
+   * @param value
+   * @throws IllegalArgumentException
+   * @throws IllegalAccessException
+   * @throws InvocationTargetException
+   */
+  public static void writeStringValue
+    (int hkey, String key, String valueName, String value) 
+    throws IllegalArgumentException, IllegalAccessException,
+    InvocationTargetException 
+  {
+    if (hkey == HKEY_LOCAL_MACHINE) {
+      writeStringValue(systemRoot, hkey, key, valueName, value);
+    }
+    else if (hkey == HKEY_CURRENT_USER) {
+      writeStringValue(userRoot, hkey, key, valueName, value);
+    }
+    else {
+      throw new IllegalArgumentException("hkey=" + hkey);
+    }
+  }
+
+  /**
+   * Delete a given key
+   * @param hkey
+   * @param key
+   * @throws IllegalArgumentException
+   * @throws IllegalAccessException
+   * @throws InvocationTargetException
+   */
+  public static void deleteKey(int hkey, String key) 
+    throws IllegalArgumentException, IllegalAccessException,
+    InvocationTargetException 
+  {
+    int rc = -1;
+    if (hkey == HKEY_LOCAL_MACHINE) {
+      rc = deleteKey(systemRoot, hkey, key);
+    }
+    else if (hkey == HKEY_CURRENT_USER) {
+      rc = deleteKey(userRoot, hkey, key);
+    }
+    if (rc != REG_SUCCESS) {
+      throw new IllegalArgumentException("rc=" + rc + "  key=" + key);
+    }
+  }
+
+  /**
+   * delete a value from a given key/value name
+   * @param hkey
+   * @param key
+   * @param value
+   * @throws IllegalArgumentException
+   * @throws IllegalAccessException
+   * @throws InvocationTargetException
+   */
+  public static void deleteValue(int hkey, String key, String value) 
+    throws IllegalArgumentException, IllegalAccessException,
+    InvocationTargetException 
+  {
+    int rc = -1;
+    if (hkey == HKEY_LOCAL_MACHINE) {
+      rc = deleteValue(systemRoot, hkey, key, value);
+    }
+    else if (hkey == HKEY_CURRENT_USER) {
+      rc = deleteValue(userRoot, hkey, key, value);
+    }
+    if (rc != REG_SUCCESS) {
+      throw new IllegalArgumentException("rc=" + rc + "  key=" + key + "  value=" + value);
+    }
+  }
+
+  // =====================
+
+  private static int deleteValue
+    (Preferences root, int hkey, String key, String value)
+    throws IllegalArgumentException, IllegalAccessException,
+    InvocationTargetException 
+  {
+    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
+        new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS) });
+    if (handles[1] != REG_SUCCESS) {
+      return handles[1];  // can be REG_NOTFOUND, REG_ACCESSDENIED
+    }
+    int rc =((Integer) regDeleteValue.invoke(root,  
+        new Object[] { 
+          new Integer(handles[0]), toCstr(value) 
+          })).intValue();
+    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
+    return rc;
+  }
+
+  private static int deleteKey(Preferences root, int hkey, String key) 
+    throws IllegalArgumentException, IllegalAccessException,
+    InvocationTargetException 
+  {
+    int rc =((Integer) regDeleteKey.invoke(root,  
+        new Object[] { new Integer(hkey), toCstr(key) })).intValue();
+    return rc;  // can REG_NOTFOUND, REG_ACCESSDENIED, REG_SUCCESS
+  }
+
+  private static String readString(Preferences root, int hkey, String key, String value)
+    throws IllegalArgumentException, IllegalAccessException,
+    InvocationTargetException 
+  {
+    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
+        new Integer(hkey), toCstr(key), new Integer(KEY_READ) });
+    if (handles[1] != REG_SUCCESS) {
+      return null; 
+    }
+    byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[] {
+        new Integer(handles[0]), toCstr(value) });
+    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
+    return (valb != null ? new String(valb).trim() : null);
+  }
+
+  private static Map<String,String> readStringValues
+    (Preferences root, int hkey, String key)
+    throws IllegalArgumentException, IllegalAccessException,
+    InvocationTargetException 
+  {
+    HashMap<String, String> results = new HashMap<String,String>();
+    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
+        new Integer(hkey), toCstr(key), new Integer(KEY_READ) });
+    if (handles[1] != REG_SUCCESS) {
+      return null;
+    }
+    int[] info = (int[]) regQueryInfoKey.invoke(root,
+        new Object[] { new Integer(handles[0]) });
+
+    int count = info[2]; // count  
+    int maxlen = info[3]; // value length max
+    for(int index=0; index<count; index++)  {
+      byte[] name = (byte[]) regEnumValue.invoke(root, new Object[] {
+          new Integer
+            (handles[0]), new Integer(index), new Integer(maxlen + 1)});
+      String value = readString(hkey, key, new String(name));
+      results.put(new String(name).trim(), value);
+    }
+    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
+    return results;
+  }
+
+  private static List<String> readStringSubKeys
+    (Preferences root, int hkey, String key)
+    throws IllegalArgumentException, IllegalAccessException,
+    InvocationTargetException 
+  {
+    List<String> results = new ArrayList<String>();
+    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
+        new Integer(hkey), toCstr(key), new Integer(KEY_READ) 
+        });
+    if (handles[1] != REG_SUCCESS) {
+      return null;
+    }
+    int[] info = (int[]) regQueryInfoKey.invoke(root,
+        new Object[] { new Integer(handles[0]) });
+
+    int count = info[2]; // count  
+    int maxlen = info[3]; // value length max
+    for(int index=0; index<count; index++)  {
+      byte[] name = (byte[]) regEnumKeyEx.invoke(root, new Object[] {
+          new Integer
+            (handles[0]), new Integer(index), new Integer(maxlen + 1)
+          });
+      results.add(new String(name).trim());
+    }
+    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
+    return results;
+  }
+
+  private static int [] createKey(Preferences root, int hkey, String key)
+    throws IllegalArgumentException, IllegalAccessException,
+    InvocationTargetException 
+  {
+    return  (int[]) regCreateKeyEx.invoke(root,
+        new Object[] { new Integer(hkey), toCstr(key) });
+  }
+
+  private static void writeStringValue 
+    (Preferences root, int hkey, String key, String valueName, String value) 
+    throws IllegalArgumentException, IllegalAccessException,
+    InvocationTargetException 
+  {
+    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
+        new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS) });
+
+    regSetValueEx.invoke(root,  
+        new Object[] { 
+          new Integer(handles[0]), toCstr(valueName), toCstr(value) 
+          }); 
+    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
+  }
+
+  // utility
+  private static byte[] toCstr(String str) {
+    byte[] result = new byte[str.length() + 1];
+
+    for (int i = 0; i < str.length(); i++) {
+      result[i] = (byte) str.charAt(i);
+    }
+    result[str.length()] = 0;
+    return result;
+  }
+}
+
Binary file smart_toolShed/SMART/Java/__init__.pyc has changed
Binary file smart_toolShed/SMART/Java/doc.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/formats.txt	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,4 @@
+sequence: fasta, fastq
+transcript: bed, gff, gff2, gff3, csv
+mapping: axt, blast, bowtie, exo, maq, nucmer, psl, sam, seqmap, shrimp, soap, soap2
+other: txt, wig, png, nclist
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/Java/manifest.txt	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Created-By: Matthias Zytnicki
+Main-Class: Smart
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/CleanTranscriptFile.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,60 @@
+<tool id="CleanTranscriptFile" name="Clean Transcript File">
+	<description> Clean a transcript file so that it is useable for S-MART.</description>
+	<command interpreter="python"> ../Java/Python/CleanTranscriptFile.py -i $formatType.inputFileName 
+		#if $formatType.FormatInputFileName == 'gff':
+		 	-f gff
+		#elif $formatType.FormatInputFileName == 'gtf':
+			-f gtf
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#end if	
+		#if $optionType.type == 'Yes':
+			-t $optionType.value
+		#end if 
+		-o $outputFile 
+	</command> 
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName"  type="select" label="Input File Format">
+				<option value="gff">gff</option>
+				<option value="gtf">gtf</option>
+				<option value="gff3">gff3</option>
+			 </param>
+			 <when value="gff">
+				 <param name="inputFileName" format="gff" type="data" label="Input File"/>	 
+			</when>
+			<when value="gtf"> 
+			         <param name="inputFileName" format="gtf" type="data" label="Input File"/> 
+			 </when>
+			<when value="gff3"> 
+			         <param name="inputFileName" format="gff3" type="data" label="Input File"/> 
+			 </when>
+		 </conditional>
+ 
+		 <conditional name="optionType">
+
+		<param name="type" type="select" label="You can choose the tag that you are interested in, like tRNA,rRNA,ncRNA,CDS,exon, etc." help="Name of the types you want to keep in GFF/GTF (list separated by commas)">
+			<option value="Yes">Yes</option>
+			<option value="No" selected="true">No</option>
+		</param>
+		<when value="Yes">
+			 <param name="value" type="text" value="tRNA,rRNA,ncRNA,CDS,exon"/>
+		</when>
+		<when value="No">
+		</when>
+	</conditional>
+
+	</inputs>
+
+
+	<outputs>
+		<data name="outputFile" format="gtf">
+			<change_format>
+			<when input="formatType.FormatInputFileName" value="gff" format="gff" />
+			<when input="formatType.FormatInputFileName" value="gff3" format="gff3" />
+		</change_format> 
+		</data>
+
+	</outputs>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/Clusterize.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,73 @@
+<tool id="MergingDataClusterize" name="Clusterize">
+	<description>Clusterizes the reads when their genomic intervals overlap.</description>
+	<command interpreter="python">
+		../Java/Python/clusterize.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName == 'csv':
+			-f csv
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName == 'gtf':
+			-f gtf
+		#end if
+		-o $outputFileGff 
+		$colinear
+		$normalize
+		-d $distance
+		$log $outputFileLog
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="csv">csv</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="csv">
+				<param name="inputFileName" format="csv" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName" format="gtf" type="data" label="Input File"/>
+			</when>
+		</conditional>
+
+		<param name="colinear" type="boolean" truevalue="-c" falsevalue="" checked="false" label="colinear option" help="This option clusterizes only the same strand reads"/>
+		<param name="normalize" type="boolean" truevalue="-n" falsevalue="" checked="false" label="normalize option for only GFF3 file format" help="This option normalize (attention!! Only for GFF3 file!!!!!)"/>
+		<param name="log" type="boolean" truevalue="-l" falsevalue="" checked="false" label="log option" help="This option create a log file"/>
+		<param name="distance" type="text" value="0" label="distance option" help="Limit the maximum distance between two reads"/>
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3"/>
+		<data name="outputFileLog" format="txt">
+			<filter>log</filter>
+		</data>
+	</outputs> 
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/CollapseReads.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,59 @@
+<tool id="collapseReads" name="collapse reads">
+	<description>Merges two reads if they have exactly the same genomic coordinates.</description>
+	<command interpreter="python">
+		../Java/Python/CollapseReads.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName == 'gtf':
+			-f gtf
+		#end if
+		-$strand
+		-o $outputFileGff 
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName" format="gtf" type="data" label="Input File"/>
+			</when>
+		</conditional>
+
+		<param name="strand" type="boolean" truevalue="-s" falsevalue="" checked="false" label="Strand option merges 2 different strands[default:False]."/>
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3"/>
+	</outputs> 
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/CompareOverlappingSmallQuery.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,134 @@
+<tool id="CompareOverlappingSmallQuery" name="Compare Overlapping Small Query">
+	<description>Provide the queries that overlap with a reference, when the query is small.</description>  
+	<command interpreter="python">
+		../Java/Python/CompareOverlappingSmallQuery.py -i $formatType.inputFileName1 
+		#if $formatType.FormatInputFileName1 == 'bed':  
+		-f bed
+		#elif $formatType.FormatInputFileName1 == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName1 == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName1 == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName1 == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName1 == 'gtf':
+			-f gtf
+		#end if
+		-j $formatType2.inputFileName2
+		#if $formatType2.FormatInputFileName2 == 'bed':
+			-g bed
+		#elif $formatType2.FormatInputFileName2 == 'gff':
+			-g gff	
+		#elif $formatType2.FormatInputFileName2 == 'gff2':
+			-g gff2
+		#elif $formatType2.FormatInputFileName2 == 'gff3':
+			-g gff3
+		#elif $formatType2.FormatInputFileName2 == 'sam':
+			-g sam
+		#elif $formatType2.FormatInputFileName2 == 'gtf':
+		    -g gtf
+		#end if
+		-o $outputFileGff 
+		#if $OptionDistance.Dist == 'Yes':
+			-d $OptionDistance.distance
+		#end if
+		#if $OptionColinearOrAntiSens.OptionCA == 'Colinear':
+			-c 
+		#elif $OptionColinearOrAntiSens.OptionCA == 'AntiSens':
+			-a
+		#end if	
+		$InvertMatch
+		$NotOverlapping
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName1" type="select" label="Input Query File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName1" format="bed" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName1" format="gff" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName1" format="gff2" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName1" format="gff3" type="data" label="Input File 1"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName1" format="sam" type="data" label="Input File 1"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName1" format="gtf" type="data" label="Input File 1"/>
+								                        </when>
+		</conditional>
+
+		<conditional name="formatType2">
+			<param name="FormatInputFileName2" type="select" label="Input Reference File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName2" format="bed" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName2" format="gff" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName2" format="gff2" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName2" format="gff3" type="data" label="Input File 2"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName2" format="sam" type="data" label="Input File 2"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName2" format="gtf" type="data" label="Input File 2"/>
+			</when>
+		</conditional>
+		<conditional name="OptionDistance">
+			<param name="Dist" type="select" label="Maximum Distance between two reads">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="distance" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		<conditional name="OptionColinearOrAntiSens">
+			<param name="OptionCA" type="select" label="Colinear or anti-sens">
+				<option value="Colinear">Colinear</option>
+				<option value="AntiSens">AntiSens</option>
+				<option value="NONE" selected="true">NONE</option>
+			</param>
+			<when value="Colinear">
+			</when>
+			<when value="AntiSens">
+			</when>
+			<when value="NONE">
+			</when>
+		</conditional>
+		<param name="InvertMatch" type="boolean" truevalue="-x" falsevalue="" checked="false" label="Invert match"/>
+		<param name="NotOverlapping" type="boolean" truevalue="-O" falsevalue="" checked="false" label="When there is no overlapping, the number of Overlapping will be set to 0 by defalt."/>
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3"/>
+	</outputs> 
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/CompareOverlappingSmallRef.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,137 @@
+<tool id="CompareOverlappingSmallRef" name="Compare Overlapping Small Reference">
+	<description>Provide the queries that overlap with a reference, when the reference is small.</description>  
+	<command interpreter="python">
+		../Java/Python/CompareOverlappingSmallQuery.py -i $formatType.inputFileName1 
+		#if $formatType.FormatInputFileName1 == 'bed':  
+		-f bed
+		#elif $formatType.FormatInputFileName1 == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName1 == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName1 == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName1 == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName1 == 'gtf':
+			-f gtf
+		#end if
+		-j $formatType2.inputFileName2
+		#if $formatType2.FormatInputFileName2 == 'bed':
+			-g bed
+		#elif $formatType2.FormatInputFileName2 == 'gff':
+			-g gff	
+		#elif $formatType2.FormatInputFileName2 == 'gff2':
+			-g gff2
+		#elif $formatType2.FormatInputFileName2 == 'gff3':
+			-g gff3
+		#elif $formatType2.FormatInputFileName2 == 'sam':
+			-g sam
+		#elif $formatType2.FormatInputFileName2 == 'gtf':
+		    -g gtf
+		#end if
+		-o $outputFileGff 
+		#if $OptionDistance.Dist == 'Yes':
+			-d $OptionDistance.distance
+		#end if
+		#if $OptionColinearOrAntiSens.OptionCA == 'Colinear':
+			-c 
+		#elif $OptionColinearOrAntiSens.OptionCA == 'AntiSens':
+			-a
+		#end if	
+		$InvertMatch
+		$NotOverlapping
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName1" type="select" label="Input Query File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName1" format="bed" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName1" format="gff" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName1" format="gff2" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName1" format="gff3" type="data" label="Input File 1"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName1" format="sam" type="data" label="Input File 1"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName1" format="gtf" type="data" label="Input File 1"/>
+								                        </when>
+		</conditional>
+
+		<conditional name="formatType2">
+			<param name="FormatInputFileName2" type="select" label="Input Reference File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName2" format="bed" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName2" format="gff" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName2" format="gff2" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName2" format="gff3" type="data" label="Input File 2"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName2" format="sam" type="data" label="Input File 2"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName2" format="gtf" type="data" label="Input File 2"/>
+			</when>
+		</conditional>
+		<conditional name="OptionDistance">
+			<param name="Dist" type="select" label="Maximum Distance between two reads">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="distance" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		<conditional name="OptionColinearOrAntiSens">
+			<param name="OptionCA" type="select" label="Colinear or anti-sens">
+				<option value="Colinear">Colinear</option>
+				<option value="AntiSens">AntiSens</option>
+				<option value="NONE" selected="true">NONE</option>
+			</param>
+			<when value="Colinear">
+			</when>
+			<when value="AntiSens">
+			</when>
+			<when value="NONE">
+			</when>
+		</conditional>
+
+		<conditional name="OptionDistance">
+		<param name="InvertMatch" type="boolean" truevalue="-x" falsevalue="" checked="false" label="Invert match"/>
+		<param name="NotOverlapping" type="boolean" truevalue="-O" falsevalue="" checked="false" label="When there is no overlapping, the number of Overlapping will be set to 0 by defalt."/>
+		</conditional>
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3"/>
+	</outputs> 
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,119 @@
+<tool id="ConvertTranscriptFile" name="Convert transcript file">
+  <description>Convert a file from a format to another.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFormatType.inputFileName 
+	  #if $inputFormatType.FormatInputFileName == 'gff3':
+	  	-f gff3
+	  #elif $inputFormatType.FormatInputFileName == 'bed': 
+	 	-f bed 
+	  #elif $inputFormatType.FormatInputFileName == 'gff2': 
+	 	-f gff2
+	  #elif $inputFormatType.FormatInputFileName == 'bam': 
+	 	-f blast
+	  #elif $inputFormatType.FormatInputFileName == 'sam': 
+	 	-f sam
+	  #elif $inputFormatType.FormatInputFileName == 'gtf': 
+	 	-f gtf
+          #end if
+	  
+	 -g $outputFormatType.outFormat
+  	  #if $optionSequence.choose == 'Yes':
+	  	-s $optionSequence.value
+		#end if 
+	
+	  
+	  -n $name
+	  $strand
+	  -o $outputFile
+	 
+  </command>
+  <inputs>
+	  <conditional name="inputFormatType">
+		  <param name="FormatInputFileName"  type="select" label="Input File Format">
+			  <option value="gff3">GFF3</option> 
+			  <option value="bed">BED</option> 
+			  <option value="gff2">GFF2</option> 
+			  <option value="bam">BAM</option> 
+			  <option value="sam">SAM</option> 
+			  <option value="gtf">GTF</option> 
+		  </param>
+		  <when value="gff3">  
+			  <param name="inputFileName" format="gff3" type="data" label="Input File"/>
+		  </when>
+		  <when value="bed">  
+			  <param name="inputFileName" format="bed" type="data" label="Input File"/>
+		  </when>
+		  <when value="gff2">  
+			  <param name="inputFileName" format="gff2" type="data" label="Input File"/>
+		  </when>
+		  <when value="bam">  
+			  <param name="inputFileName" format="bam" type="data" label="Input File"/>
+		  </when>
+		  <when value="sam">  
+			  <param name="inputFileName" format="sam" type="data" label="Input File"/>
+		  </when>
+		  <when value="gtf">  
+			  <param name="inputFileName" format="gtf" type="data" label="Input File"/>
+		  </when>
+		</conditional>    
+  
+  
+ 	  <conditional name="outputFormatType">
+		  <param name="outFormat"  type="select" label="Please choose the format that you want to convert to (corresponding to your input file format).">
+			  <option value="gff3">GFF3</option> 
+			  <option value="bed">BED</option> 
+			  <option value="gff2">GFF2</option> 
+			  <option value="wig">WIG</option> 
+			  <option value="sam">SAM</option> 
+			  <option value="csv">CSV</option> 
+			  <option value="gtf">GTF</option> 
+		  </param> 
+  		  <when value="gff3">  
+		  </when>
+		  <when value="bed">  
+		  </when>
+  		  <when value="gff2">  
+		  </when>
+		  <when value="wig">  
+		  </when>
+  		  <when value="sam">  
+		  </when>
+		  <when value="csv">  
+		  </when>
+		  <when value="gtf">  
+		  </when>
+ 		</conditional>  
+ 		
+ 		<param name="name" type="text" value="SMART" label="name for the transcripts"/>
+ 		
+ 		<conditional name="optionSequence">
+ 		<param name="choose" type="select" label="give the corresponding Multi-Fasta file (useful for EMBL format)">
+			<option value="Yes">Yes</option>
+			<option value="No" selected="true">No</option>
+		</param>
+		<when value="Yes">
+			 <param name="value" type="data" format="mfa" />
+		</when>
+		<when value="No">
+		</when>
+		</conditional>
+ 		 
+ 		<param name="strand" type="boolean" truevalue="-t" falsevalue="" checked="false" label="consider the 2 strands as different (only useful for writing WIG files)"/>
+ 		 
+  </inputs>
+
+  <outputs>
+  		<data name="outputFile" format="gff3" label="$inputFormatType.FormatInputFileName to $outputFormatType.outFormat">
+			<change_format>
+			<when input="outputFormatType.outFormat" value="bed" format="bed" />
+			<when input="outputFormatType.outFormat" value="gff2" format="gff2" />
+			<when input="outputFormatType.outFormat" value="wig" format="wig" />
+			<when input="outputFormatType.outFormat" value="sam" format="sam" />
+			<when input="outputFormatType.outFormat" value="csv" format="csv" />
+			<when input="outputFormatType.outFormat" value="gtf" format="gtf" />
+			</change_format> 
+		</data>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BedToCsv.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_BedToCsv" name="Bed -> Csv">
+  <description>Convert Bed File to Csv File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f bed -o $outputFile -g csv yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="bed"/>
+  </inputs>
+
+  <outputs>
+    <data format="csv" name="outputFile" label="[bed -> csv] Output File"/>
+    <data format="txt" name="logFile" label="[bed -> csv] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BedToGff2.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_BedToGff2" name="Bed -> Gff2">
+  <description>Convert Bed File to Gff2 File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f bed -o $outputFile -g gff yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="bed"/>
+  </inputs>
+
+  <outputs>
+    <data format="gff" name="outputFile" label="[bed -> gff2] Output File"/>
+    <data format="txt" name="logFile" label="[bed -> gff2] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BedToGff3.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_BedToGff3" name="Bed -> Gff3">
+  <description>Convert Bed File to Gff3 File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f bed -o $outputFile -g gff3 yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="bed"/>
+  </inputs>
+
+  <outputs>
+    <data format="gff3" name="outputFile" label="[bed -> gff3] Output File"/>
+    <data format="txt" name="logFile" label="[bed -> gff3] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BedToSam.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_BedToSam" name="Bed -> Sam">
+  <description>Convert Bed File to Sam File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f bed -o $outputFile -g sam yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="bed"/>
+  </inputs>
+
+  <outputs>
+    <data format="sam" name="outputFile" label="[bed -> sam] Output File"/>
+    <data format="txt" name="logFile" label="[bed -> sam] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BlastToCsv.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_BlastToCsv" name="Blast (-m 8) -> Csv">
+  <description>Convert Blast (-m 8) File to Csv File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f blast -o $outputFile -g csv yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="tabular"/>
+  </inputs>
+
+  <outputs>
+    <data format="csv" name="outputFile" label="[blast -> csv] Output File"/>
+    <data format="txt" name="logFile" label="[blast -> csv] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BlastToGff2.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_BlastToGff2" name="Blast (-m 8) -> Gff2">
+  <description>Convert Blast (-m 8) File to Gff2 File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f blast -o $outputFile -g gff2 yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="tabular"/>
+  </inputs>
+
+  <outputs>
+    <data format="gff" name="outputFile" label="[blast -> gff2] Output File"/>
+    <data format="txt" name="logFile" label="[blast -> gff2] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BlastToGff3.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_BlastToGff3" name="Blast (-m 8) -> Gff3">
+  <description>Convert Blast (-m 8) File to Gff3 File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f blast -o $outputFile -g gff3 yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="tabular"/>
+  </inputs>
+
+  <outputs>
+    <data format="gff3" name="outputFile" label="[blast -> gff3] Output File"/>
+    <data format="txt" name="logFile" label="[blast -> gff3] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_BlastToSam.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_BlastToSam" name="Blast (-m 8) -> Sam">
+  <description>Convert Blast (-m 8) File to Sam File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f blast -o $outputFile -g sam yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="tabular"/>
+  </inputs>
+
+  <outputs>
+    <data format="sam" name="outputFile" label="[blast -> sam] Output File"/>
+    <data format="txt" name="logFile" label="[blast -> sam] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_FastqToFasta.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_FastqToFasta" name="Fastq -> Fasta">
+  <description>Convert Fastq File to Fasta File.</description>
+  <command interpreter="python"> ../Java/Python/fastqToFasta.py -i $inputFile -o $outputFile 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="fastq"/>
+  </inputs>
+
+  <outputs>
+    <data format="fasta" name="outputFile" label="[fastq -> fasta] Output File"/>
+    <data format="txt" name="logFile" label="[fastq -> fasta] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_Gff2ToCsv.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_Gff2ToCsv" name="Gff2 -> Csv">
+  <description>Convert Gff2 File to Csv File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f gff2 -o $outputFile -g csv yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="gff"/>
+  </inputs>
+
+  <outputs>
+    <data format="csv" name="outputFile" label="[gff2 -> csv] Output File"/>
+    <data format="txt" name="logFile" label="[gff2 -> csv] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_Gff2ToGff3.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_Gff2ToGff3" name="Gff2 -> Gff3">
+  <description>Convert Gff2 File to Gff3 File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f gff2 -o $outputFile -g gff3 yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="gff"/>
+  </inputs>
+
+  <outputs>
+    <data format="gff3" name="outputFile" label="[gff2 -> gff3] Output File"/>
+    <data format="txt" name="logFile" label="[gff2 -> gff3] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_Gff2ToSam.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_Gff2ToSam" name="Gff2 -> Sam">
+  <description>Convert Gff2 File to Sam File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f gff2 -o $outputFile -g sam yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="gff"/>
+  </inputs>
+
+  <outputs>
+    <data format="sam" name="outputFile" label="[gff2 -> sam] Output File"/>
+    <data format="txt" name="logFile" label="[gff2 -> sam] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_Gff3ToCsv.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_Gff3ToCsv" name="Gff3 -> Csv">
+  <description>Convert Gff3 File to Csv File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f gff3 -o $outputFile -g csv yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="gff3"/>
+  </inputs>
+
+  <outputs>
+    <data format="csv" name="outputFile" label="[gff3 -> csv] Output File"/>
+    <data format="txt" name="logFile" label="[gff3 -> csv] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_Gff3ToGff2.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_Gff3ToGff2" name="Gff3 -> Gff2">
+  <description>Convert Gff3 File to Gff2 File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f gff3 -o $outputFile -g gff2 yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="gff3"/>
+  </inputs>
+
+  <outputs>
+    <data format="gff" name="outputFile" label="[gff3 -> gff2] Output File"/>
+    <data format="txt" name="logFile" label="[gff3 -> gff2] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_Gff3ToSam.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_Gff3ToSam" name="Gff3 -> Sam">
+  <description>Convert Gff3 File to Sam File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f gff3 -o $outputFile -g sam yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="gff3"/>
+  </inputs>
+
+  <outputs>
+    <data format="sam" name="outputFile" label="[gff3 -> sam] Output File"/>
+    <data format="txt" name="logFile" label="[gff3 -> sam] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_Gff3ToWig.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_Gff3ToWig" name="Gff3 -> Wig">
+  <description>Convert Gff3 File to Wig File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f gff3 -o $outputFile -g wig yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="gff3"/>
+  </inputs>
+
+  <outputs>
+    <data format="wig" name="outputFile" label="[gff3 -> wig] Output File"/>
+    <data format="txt" name="logFile" label="[gff3 -> wig] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_SamToCsv.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_SamToCsv" name="Sam -> Csv">
+  <description>Convert Sam File to Csv File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f sam -o $outputFile -g csv yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="sam"/>
+  </inputs>
+
+  <outputs>
+    <data format="csv" name="outputFile" label="[sam -> csv] Output File"/>
+    <data format="txt" name="logFile" label="[sam -> csv] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_SamToGff2.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_SamToGff2" name="Sam -> Gff2">
+  <description>Convert Sam File to Gff2 File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f sam -o $outputFile -g gff2 yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="sam"/>
+  </inputs>
+
+  <outputs>
+    <data format="gff" name="outputFile" label="[sam -> gff2] Output File"/>
+    <data format="txt" name="logFile" label="[sam -> gff2] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/ConvertTranscriptFile_SamToGff3.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="ConvertTranscriptFile_SamToGff3" name="Sam -> Gff3">
+  <description>Convert Sam File to Gff3 File.</description>
+  <command interpreter="python"> ../Java/Python/convertTranscriptFile.py -i $inputFile -f sam -o $outputFile -g gff3 yes 2>$logFile </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="sam"/>
+  </inputs>
+
+  <outputs>
+    <data format="gff3" name="outputFile" label="[sam -> gff3] Output File"/>
+    <data format="txt" name="logFile" label="[sam -> gff3] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/CountReadGCPercent.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,16 @@
+<tool id="CountReadGCPercent" name="count read GCpercent">
+    <description>Count GC percent for each read against a genome.</description>
+    <command interpreter="python"> ../Java/Python/CountReadGCPercent.py -i $inputFastaFile -j $inputGffFile -o $outputFile</command>
+  <inputs>
+      <param name="inputFastaFile" type="data" label="Input reference fasta File" format="fasta"/>
+      <param name="inputGffFile" type="data" label="Input File" format="gff3"/>
+  </inputs>
+
+  <outputs>
+    <data format="gff3" name="outputFile" label="[CountReadGCPercent] Output File"/>
+   </outputs>
+
+  <help>
+  </help>
+</tool>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/DiffExpAnal.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,19 @@
+<tool id="testDiffExpAnal" name="Differential Expression Analysis">
+  <description>Differential expression analysis for sequence count data</description>
+  <command interpreter="sh"> ../DiffExpAnal/testR.sh $inputFile $columnsOfGeneName $columnsOfCondition1 $columnsOfCondition2 $outputFileCSV $outputFilePNG 2>$outputLog </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="tabular"/>
+	<param name="columnsOfGeneName" type="text" value="0" label="Please indicate the column numbers of gene names with ',' separator. If There are not gene names, default value is 0."/>
+	<param name="columnsOfCondition1" type="text" value="1,2" label="Please indicate the column numbers of condition1 with ',' separator."/>
+	<param name="columnsOfCondition2" type="text" value="3,4" label="Please indicate the column numbers of condition2 with ',' separator."/>
+  </inputs>
+
+  <outputs>
+    <data format="tabular" name="outputFileCSV" label="[DiffExpAnal] Output CSV File"/>
+	<data format="png" name="outputFilePNG" label="[DiffExpAnal] Output PNG File"/>
+    <data format="tabular" name="outputLog" label="[DiffExpAnal] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/FindOverlaps_optim.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,16 @@
+<tool id="findOverlaps" name="findOverlaps">
+	<description>Finds the overlapped reference reads.</description>
+	<command interpreter="python">
+		../Java/Python/FindOverlaps_optim.py -i $inputRef -j $inputQ -o $outputFileGff 
+	</command>
+	
+  <inputs>
+    <param name="inputRef" type="data" label="Input Reference File" format="gff3"/>
+    <param name="inputQ" type="data" label="Input Query File" format="gff3"/>
+  </inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3"/>
+	</outputs> 
+	
+</tool>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/GetDifferentialExpression.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,210 @@
+<tool id="GetDifferentialExpression" name="get differential expression">
+	<description>Get the differential expression between 2 conditions using Fisher's exact test, on regions defined by a third file.</description>
+	<command interpreter="python">
+		../Java/Python/GetDifferentialExpression.py -i $formatType.inputFileName1
+		#if $formatType.FormatInputFileName1 == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName1 == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName1 == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName1 == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName1 == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName1 == 'gtf':
+			-f gtf
+		#end if
+			
+		-j $formatType2.inputFileName2
+		#if $formatType2.FormatInputFileName2 == 'bed':
+			-g bed
+		#elif $formatType2.FormatInputFileName2 == 'gff':
+			-g gff	
+		#elif $formatType2.FormatInputFileName2 == 'gff2':
+			-g gff2
+		#elif $formatType2.FormatInputFileName2 == 'gff3':
+			-g gff3
+		#elif $formatType2.FormatInputFileName2 == 'sam':
+			-g sam
+		#elif $formatType2.FormatInputFileName2 == 'gtf':
+			-g gtf
+		#end if
+			
+		-k $formatTypeRef.inputFileNameRef
+		#if $formatTypeRef.FormatInputFileNameRef == 'bed':
+			-l bed
+		#elif $formatTypeRef.FormatInputFileNameRef == 'gff':
+			-l gff	
+		#elif $formatTypeRef.FormatInputFileNameRef == 'gff2':
+			-l gff2
+		#elif $formatTypeRef.FormatInputFileNameRef == 'gff3':
+			-l gff3
+		#elif $formatTypeRef.FormatInputFileNameRef == 'sam':
+			-l sam
+		#elif $formatTypeRef.FormatInputFileNameRef == 'gtf':
+			-l gtf
+		#end if
+		
+		-o $outputFileGff 
+		
+		$simple
+		$adjusted
+
+
+		#if $optionSimplePara.simplePara == 'Yes':
+			-S $optionSimplePara.paraValue
+		#end if		
+		
+		#if $optionFixedSizeFactor.FSF == 'Yes':
+			-x $optionFixedSizeFactor.FSFValue
+		#end if
+		
+		#if $optionFDR.FDR == 'Yes':
+			-d $optionFDR.FDRValue
+		#end if
+		$plot $outputFilePNG
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName1" type="select" label="Input File Format 1">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName1" format="bed" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName1" format="gff" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName1" format="gff2" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName1" format="gff3" type="data" label="Input File 1"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName1" format="sam" type="data" label="Input File 1"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName1" format="gtf" type="data" label="Input File 1"/>
+			</when>
+		</conditional>
+
+		<conditional name="formatType2">
+			<param name="FormatInputFileName2" type="select" label="Input File Format 2">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName2" format="bed" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName2" format="gff" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName2" format="gff2" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName2" format="gff3" type="data" label="Input File 2"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName2" format="sam" type="data" label="Input File 2"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName2" format="gtf" type="data" label="Input File 2"/>
+			</when>
+		</conditional>
+
+		<conditional name="formatTypeRef">
+			<param name="FormatInputFileNameRef" type="select" label="Input Ref File Format ">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileNameRef" format="bed" type="data" label="Input Ref File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileNameRef" format="gff" type="data" label="Input Ref File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileNameRef" format="gff2" type="data" label="Input Ref File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileNameRef" format="gff3" type="data" label="Input Ref File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileNameRef" format="sam" type="data" label="Input Ref File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileNameRef" format="gtf" type="data" label="Input Ref File"/>
+			</when>
+		</conditional>
+
+		<param name="simple" type="boolean" truevalue="-s" falsevalue="" checked="false" label="normalize using the number of reads in each condition"/>
+		<param name="adjusted" type="boolean" truevalue="-a" falsevalue="" checked="false" label="normalize using the number of reads of 'mean' regions"/>
+		
+		<conditional name="optionSimplePara">
+			<param name="simplePara" type="select" label="provide the number of reads" >
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="paraValue" type="text" value="None" label="provide the number of reads" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionFixedSizeFactor">
+			<param name="FSF" type="select" label="give the magnification factor for the normalization using fixed size sliding windows in reference regions (leave empty for no such normalization)">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="FSFValue" type="integer" value="0" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<conditional name="optionFDR">
+			<param name="FDR" type="select" label="use FDR">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="FDRValue" type="float" value="0.0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<param name="plot" type="boolean" truevalue="-p" falsevalue="" checked="false" label="plot option" help="plot cloud plot"/>
+
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3" label="[GetDifferentialExpression]out file"/>
+		<data name="outputFilePNG" format="PNG" label="[GetDifferentialExpression]PNG file">
+			<filter>plot</filter>
+		</data>
+	</outputs> 
+	
+	<help>
+		example: python GetDifferentialExpression.py -i input1 -f gff3 -j input2 -g gff3 -k ref -l gff3 -o output.gff3
+	</help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/GetFlanking.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,179 @@
+<tool id="GetFlanking" name="get flanking">
+	<description>Get the flanking regions of a set of reference.</description>
+	<command interpreter="python">
+		../Java/Python/GetFlanking.py -i $formatType.inputFileName1
+		#if $formatType.FormatInputFileName1 == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName1 == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName1 == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName1 == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName1 == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName1 == 'gtf':
+			-f gtf
+		#end if
+			
+		-j $formatType2.inputFileName2
+		#if $formatType2.FormatInputFileName2 == 'bed':
+			-g bed
+		#elif $formatType2.FormatInputFileName2 == 'gff':
+			-g gff	
+		#elif $formatType2.FormatInputFileName2 == 'gff2':
+			-g gff2
+		#elif $formatType2.FormatInputFileName2 == 'gff3':
+			-g gff3
+		#elif $formatType2.FormatInputFileName2 == 'sam':
+			-g sam
+		#elif $formatType2.FormatInputFileName2 == 'gtf':
+			-g gtf
+		#end if
+
+  		#if $OptionUpDownStream.OptionUD == 'UpStream':
+			-5 
+		#elif $OptionUpDownStream.OptionUD == 'DownStream':
+			-3
+		#end if	
+
+
+  		#if $OptionColinearOrAntiSens.OptionCA == 'Colinear':
+			-c 
+		#elif $OptionColinearOrAntiSens.OptionCA == 'AntiSens':
+			-a
+		#end if	
+		
+		#if $OptionMax.maximum == "Yes":
+			-D $OptionMax.max
+		#end if		
+		#if $OptionMin.minimum == "Yes":
+			-d $OptionMin.min
+		#end if	
+  		
+  		-o $outputFile  
+
+		
+		
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName1" type="select" label="query File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName1" format="bed" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName1" format="gff" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName1" format="gff2" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName1" format="gff3" type="data" label="Input File 1"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName1" format="sam" type="data" label="Input File 1"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName1" format="gtf" type="data" label="Input File 1"/>
+			</when>
+		</conditional>
+
+		<conditional name="formatType2">
+			<param name="FormatInputFileName2" type="select" label="Refence File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName2" format="bed" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName2" format="gff" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName2" format="gff2" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName2" format="gff3" type="data" label="Input File 2"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName2" format="sam" type="data" label="Input File 2"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName2" format="gtf" type="data" label="Input File 2"/>
+			</when>
+		</conditional>
+		
+		<conditional name="OptionUpDownStream">
+			<param name="OptionUD" type="select" label="UpStream or DownStream">
+				<option value="UpStream">UpStream</option>
+				<option value="DownStream">DownStream</option>
+				<option value="NONE" selected="true">NONE</option>
+			</param>
+			<when value="UpStream">
+			</when>
+			<when value="DownStream">
+			</when>
+			<when value="NONE">
+			</when>
+		</conditional>
+				
+		<conditional name="OptionColinearOrAntiSens">
+			<param name="OptionCA" type="select" label="Colinear or anti-sens">
+				<option value="Colinear">Colinear</option>
+				<option value="AntiSens">AntiSens</option>
+				<option value="NONE" selected="true">NONE</option>
+			</param>
+			<when value="Colinear">
+			</when>
+			<when value="AntiSens">
+			</when>
+			<when value="NONE">
+			</when>
+		</conditional>
+		
+		<conditional name="OptionMax">
+			<param name="maximum" type="select" label="maximum distance between 2 elements">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="max" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<conditional name="OptionMin">
+			<param name="minimum" type="select" label="minimum distance between 2 elements">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="min" type="integer" value="0" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>	
+		
+	</inputs>
+
+
+  	<outputs>
+   		<data format="gff3" name="outputFile" label="[GetFlanking] Output File"/>
+  	</outputs>
+	
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/SelectByTag.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,122 @@
+<tool id="SelectByTag" name="select by tag">
+	<description>Keeps the genomic coordinates such that a value of a given tag.</description>
+	<command interpreter="python">
+		../Java/Python/SelectByTag.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName == 'gtf':
+			-f gtf
+		#end if
+
+		-g $Tag
+		#if $OptionValue.Value == "Yes":
+			-a $OptionValue.valeur
+		#end if	
+		#if $OptionMax.maximum == "Yes":
+			-M $OptionMax.max
+		#end if		
+		#if $OptionMin.minimum == "Yes":
+			-m $OptionMin.min
+		#end if	
+
+		#if $OptionDefault.default == "Yes":
+			-d $OptionDefault.defaultValue
+		#end if	
+				
+		-o $outputFileGff 
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName" format="gtf" type="data" label="Input File"/>
+			</when>
+		</conditional>
+
+		<param name="Tag" type="text" value="None" label="tag option" help="A given tag, you must choose a tag."/>
+				
+		<conditional name="OptionValue">
+			<param name="Value" type="select" label="value of tag">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="valeur" type="integer" value="1" help="Be Careful! The value must be upper than 0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<conditional name="OptionMax">
+			<param name="maximum" type="select" label="maximum value of tag">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="max" type="integer" value="1" help="Be Careful! The value must be upper than 0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<conditional name="OptionMin">
+			<param name="minimum" type="select" label="minimum value of tag">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="min" type="integer" value="1" help="Be Careful! The value must be upper than 0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>	
+		
+		<conditional name="OptionDefault">
+			<param name="default" type="select" label="gives this value if tag is not present">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="defaultValue" type="float" value="0" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>		
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3" label="[SelectByTag] Output File"/>
+	</outputs> 
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/WrappGetLetterDistribution.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,97 @@
+#! /usr/bin/env python
+
+import os
+import sys
+import getopt
+from pyRepetUnit.commons.checker.CheckerException import CheckerException
+
+SMART_PATH = "%s/SMART" % os.environ["REPET_PATH"]
+
+class WrappGetLetterDistribution(object):
+    
+    def __init__(self):
+        self._inputFileName = ""
+        self._inputFileFormat = ""
+        self._outputFileName = "tmpOutputFile"
+        self._csv = False
+
+    def help( self ):
+        print 
+        print "usage: %s [ options ]" % ( sys.argv[0] )
+        print "options:"
+        print "     -h: this help"
+        print "     -i: input file"
+        print "     -f: 'fasta' or 'fastq'"
+        print "     -c: CSV output file"
+        print "     -a: first PNG output file"
+        print "     -b: second PNG output file"
+        print
+        print "Exemple:"
+        print
+        print "1:\n\tpython WrappGetLetterDistribution.py -i inputFile.fasta -f fasta -c outputFile1.csv -a outputFile2.png -b outputFile3.png"
+        print
+        print "2:\n\tpython WrappGetLetterDistribution.py -i inputFile.fastq -f fastq -c outputFile1.csv -a outputFile2.png -b outputFile3.png"
+        print
+        print
+
+
+    def setAttributesFromCommandLine(self):
+        try:
+            opts, args = getopt.getopt( sys.argv[1:], "hi:f:a:b:c:" )
+        except getopt.GetoptError, err:
+            print str(err); sys.exit(1)
+        for o, a in opts:
+            if o == "-h":
+                self.help()
+                sys.exit(0)
+            if o == "-i":
+                self._inputFileName = a
+            elif o == "-f":
+                self._inputFileFormat = a
+            elif o == "-c":             
+                self._outputFileNameCSV = a  
+                self._csv = True
+            elif o == "-a":
+                self._outputFileNamePNG = a
+            elif o == "-b":
+                self._outputFileNamePerNtPNG = a 
+
+    def checkAttributes(self):
+        lMsg = []
+        if self._inputFileName == "" and not os.path.exists(self._inputFileName):
+            lMsg.append("ERROR: This input file doesn't exist!")
+        if self._inputFileFormat == "":
+            lMsg.append("ERROR: No input file format specified in option!")
+        if self._outputFileNamePNG == "":
+            lMsg.append("ERROR: No output file.png specified in option!")            
+        if self._outputFileNamePerNtPNG == "":
+            lMsg.append("ERROR: No output filePerNt.png specified in option!")
+        if self._outputFileNameCSV == "" and self._csv == True :
+            lMsg.append("ERROR: No output file.csv specified in option!")   
+            
+        print ">>> lMsg " + str(lMsg)
+        if lMsg != []:
+            exp = CheckerException()
+            exp.setMessages(lMsg)
+            raise (exp)
+
+    def _cleanWorkingDir(self, cDir):
+        os.system("rm %s/tmpData* %s/tmpScript*" % (cDir, cDir))
+        
+    def wrapp(self):
+        self.checkAttributes()
+	cDir = os.getcwd()
+
+        if self._csv == True:
+            os.system("python %s/Java/Python/getLetterDistribution.py -i %s -f %s -o %s/%s -c" % (SMART_PATH, self._inputFileName, self._inputFileFormat, cDir, self._outputFileName))
+            os.system("mv %s/%s.csv %s" % (cDir, self._outputFileName, self._outputFileNameCSV))
+            os.system("mv %s/%s.png %s" % (cDir, self._outputFileName, self._outputFileNamePNG))
+            os.system("mv %s/%sPerNt.png %s" % (cDir, self._outputFileName, self._outputFileNamePerNtPNG))
+
+        self._cleanWorkingDir(cDir)
+
+if __name__ == '__main__':
+    launcher = WrappGetLetterDistribution()
+    launcher.setAttributesFromCommandLine()
+    launcher.wrapp()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/WrappGetLetterDistribution.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,33 @@
+<tool id="getLetterDistribution1" name="Get Letter Distribution">
+    <description>Calculate distribution for each nucleotide per position for all short reads (S-MART)</description>
+    <command interpreter="python">
+	    WrappGetLetterDistribution.py -i $inputFileName
+	#if $formatType.FormatInputFileName == 'fasta':
+		-f fasta
+	#else :
+		-f fastq
+	#end if
+	-c $ouputFileNameCSV -a $ouputFileNamePNG1 -b $ouputFileNamePNG2
+    </command>
+    <inputs>
+             <conditional name="formatType">
+      			<param name="FormatInputFileName" type="select" label="Input File Format">
+	        		<option value="fasta">fasta</option>
+       				<option value="fastq" selected="true">fastq</option>
+      			</param>
+      			<when value="fasta">
+             			<param name="inputFileName" format="fasta" type="data" label="Fasta Input File"/>
+      			</when>
+      			<when value="fastq">
+             			<param name="inputFileName" format="fastq" type="data" label="Fastq Input File"/>
+      			</when>
+             </conditional>
+    </inputs>
+        
+    <outputs>
+               	<data name="ouputFileNameCSV" format="tabular" label="[getLetterDistribution] CSV File"/>
+               	<data name="ouputFileNamePNG1" format="png" label="[getLetterDistribution] PNG File 1"/>
+               	<data name="ouputFileNamePNG2" format="png" label="[getLetterDistribution] PNG File 2"/>
+    </outputs> 
+</tool>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/changeGffFeatures.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,16 @@
+<tool id="changeGffFeatures" name="change gff Features">
+	<description>Changes one feature name by an other name (the feature name can be found on the 3rd column).</description>
+		<command interpreter="bash">
+			../Java/Python/changeGffFeatures.sh $inputFile $inputFeature $outputFeature >$outputFile
+		</command>
+      <inputs>
+	      <param name="inputFile" type="data" label="Input File" format="gff"/>	
+	      <param name="inputFeature" type="text" value="exon" label="A given feature, you must choose a feature name(on the 3rd column)."/>
+	      <param name="outputFeature" type="text" value="exon" label="You must choose an other feature name(on the 3rd column)."/>
+      </inputs>
+
+      <outputs>
+             <data name="outputFile" format="gff" label="[changeGffFeatures] Output File"/>
+      </outputs> 
+</tool>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/changeTagName.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,54 @@
+<tool id="changeTagName" name="change tag name">
+	<description>Changes the name of tag of a list of transcripts.</description>
+	<command interpreter="python">
+		../Java/Python/changeTagName.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#end if
+
+		-t $Tag
+		-n $name
+			
+		-o $outputFileGff 
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+		</conditional>
+
+		<param name="Tag" type="text" value="None" label="tag option" help="A given tag, you must choose a tag."/>
+		<param name="name" type="text" value="None" label="name option" help="new name for the tag, you must choose a new name."/>		
+	
+		
+
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3" label="[changeTagName] Output File"/>
+	</outputs> 
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/cleanGff.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,18 @@
+<tool id="cleanGff" name="clean Gff">
+	  <description>Cleans a GFF file as given by NCBI and outpus a Gff3 file.</description>
+	  <command interpreter="python"> ../Java/Python/cleanGff.py -i $inputFile 
+		  -t $type 
+		  -o $outputFile
+	  </command>
+
+	      <inputs>
+		      <param name="inputFile" type="data" label="Input File" format="gff"/>
+		      <param name="type" type="text" value="tRNA,rRNA,ncRNA,CDS" label="tag option, compulsory option" help="lists of comma separated types that you want to keep.EX: ncRNA,tRNA,rRNA,CDS"/>
+	      </inputs>
+
+	      <outputs>
+	          <data format="gff3" name="outputFile" label="[cleanGff] Output File"/>
+	      </outputs>
+
+</tool>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/clusterize.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,67 @@
+<tool id="MergingDataClusterize" name="Clusterize">
+	<description>Clusterizes the reads when their genomic intervals overlap.</description>
+	<command interpreter="python">
+		../Java/Python/clusterize.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName == 'csv':
+			-f csv
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#end if
+		-o $outputFileGff 
+		$colinear
+		$normalize
+		-d $distance
+		$log $outputFileLog
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="csv">csv</option>
+				<option value="sam">sam</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="csv">
+				<param name="inputFileName" format="csv" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+		</conditional>
+
+		<param name="colinear" type="boolean" truevalue="-c" falsevalue="" checked="false" label="colinear option" help="This option clusterizes only the same strand reads"/>
+		<param name="normalize" type="boolean" truevalue="-n" falsevalue="" checked="false" label="normalize option for only GFF3 file format" help="This option normalize (attention!! Only for GFF3 file!!!!!)"/>
+		<param name="log" type="boolean" truevalue="-l" falsevalue="" checked="false" label="log option" help="This option create a log file"/>
+		<param name="distance" type="integer" value="0" label="distance option" help="Limit the maximum distance between two reads"/>
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3" label="[clusterize]output file"/>
+		<data name="outputFileLog" format="txt" label="[clusterize]output file">
+			<filter>log</filter>
+		</data>
+	</outputs> 
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/clusterizeBySlidingWindows.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,132 @@
+<tool id="clusterizeBySlidingWindows" name="clusterize By SlidingWindows">
+	<description>Produces a GFF3 file that clusters a list of transcripts using a sliding window. Cluster the data into regions (defined by size and overlap with next region) and keep only highest peaks.</description>
+	<command interpreter="python">
+		../Java/Python/clusterizeBySlidingWindows.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName == 'gtf':
+			-f gtf
+		#end if
+		-s $size
+		-e $overlap
+		-o $outputFileGff 
+		$normalize
+		$strands
+		
+		#if $OptionTag.tag == "Yes":
+			-g $OptionTag.value
+		#end if	
+
+		#if $OptionsOperation.operation == "Yes":
+			-r $OptionsOperation.value
+		#end if
+		
+		#if $OptionWriteTag.writeTag == "Yes":
+			-w $OptionWriteTag.value
+		#end if	
+		
+		$strand
+		$plot $plotPng
+		$excel $excelOutput
+		
+		
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName" format="gtf" type="data" label="Input File"/>
+			</when>
+		</conditional>
+
+
+		<param name="size" type="text" value="50000" label="Size option" help="Size of the regions."/>
+		<param name="overlap" type="text" value="50" label="Overlap option" help="Overlap between two consecutive regions."/>	
+		<param name="normalize" type="boolean" truevalue="-m" falsevalue="" checked="false" label="Normalize option for only GFF3 file format" help="This option normalizes (Warning!! Only for GFF3 file!)"/>
+		<param name="strands" type="boolean" truevalue="-2" falsevalue="" checked="false" label="strands option" help="Consider the two strands separately."/>
+
+		<conditional name="OptionTag">
+			<param name="tag" type="select" label="use a given tag as input (instead of summing number of features)">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="value" type="text" value="None" label="tag option" help="write a tag name you want to observe."/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+
+		<conditional name="OptionsOperation">
+			<param name="operation" type="select" label="combine tag value with given operation [choice (sum, avg, med, min, max)]">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="value" type="text" value="None" label="operation option" help="You can ONLY choose one of fowlling operation : sum, avg, med, min, max."/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		
+		<conditional name="OptionWriteTag">
+			<param name="writeTag" type="select" label="write a new tag in output file">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="value" type="text" value="nbElements" label="write tag option" help="print the result in the given tag (default usually is 'nbElements')"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<param name="strand" type="boolean" truevalue="-2" falsevalue="" checked="false" label="strand option" help="This option considers the two strands separately."/>
+		<param name="plot" type="boolean" truevalue="-p" falsevalue="" checked="false" label="plot option" help="This option creates a png file."/>
+		<param name="excel" type="boolean" truevalue="-x" falsevalue="" checked="false" label="excel option" help="This option creates a csv file."/>
+
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3"/>
+		<data name="excelOutput" format="csv">
+			<filter>excel</filter>
+		</data>	
+		<data name="plotPng" format="png">
+			<filter>plot</filter>
+		</data>	
+	</outputs> 
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/compareOverlapping.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,288 @@
+<tool id="CompareOverlapping" name="Compare Overlapping">
+	<description>Print all the transcripts from a first file which overlap with the transcripts from a second file.</description>
+	<command interpreter="python">
+		../Java/Python/CompareOverlapping.py -i $formatType.inputFileName1
+		#if $formatType.FormatInputFileName1 == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName1 == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName1 == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName1 == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName1 == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName1 == 'gtf':
+			-f gtf
+		#end if
+			
+		-j $formatType2.inputFileName2
+		#if $formatType2.FormatInputFileName2 == 'bed':
+			-g bed
+		#elif $formatType2.FormatInputFileName2 == 'gff':
+			-g gff	
+		#elif $formatType2.FormatInputFileName2 == 'gff2':
+			-g gff2
+		#elif $formatType2.FormatInputFileName2 == 'gff3':
+			-g gff3
+		#elif $formatType2.FormatInputFileName2 == 'sam':
+			-g sam
+		#elif $formatType2.FormatInputFileName2 == 'gtf':
+		    -g gtf
+		#end if
+
+		-o $outputFileGff 
+
+		#if $optionNFirstFile1.NFirstForFile1 == 'Yes':
+			-S $optionNFirstFile1.firstNtFile1
+		#end if
+		#if $optionNFirstFile2.NFirstForFile2 == 'Yes':
+			-s $optionNFirstFile2.firstNtFile2
+		#end if
+		#if $optionNLastFile1.NLastForFile1 == 'Yes':
+			-U $optionNLastFile1.lastNtFile1
+		#end if
+		#if $optionNLastFile2.NLastForFile2 == 'Yes':
+			-u $optionNLastFile2.lastNtFile2
+		#end if
+	
+		#if $optionExtentionCinqFile1.extentionFile1 == 'Yes':
+			-E $optionExtentionCinqFile1.extention51
+		#end if
+		#if $optionExtentionCinqFile2.extentionFile2 == 'Yes':
+			-e $optionExtentionCinqFile2.extention52
+		#end if
+
+		#if $optionExtentionTroisFile1.extentionFile1 == 'Yes':
+			-N $optionExtentionTroisFile1.extention31
+		#end if
+		#if $optionExtentionTroisFile2.extentionFile2 == 'Yes':
+			-n $optionExtentionTroisFile2.extention32
+		#end if	
+
+		#if $OptionColinearOrAntiSens.OptionCA == 'Colinear':
+			-c 
+		#elif $OptionColinearOrAntiSens.OptionCA == 'AntiSens':
+			-a
+		#end if	
+
+		#if $OptionDistance.Dist == 'Yes':
+			-d $OptionDistance.distance
+		#end if
+
+		#if $OptionMinOverlap.MO == 'Yes':
+			-m $OptionMinOverlap.minOverlap
+		#end if
+
+		$InvertMatch
+		$ReportIntron
+		$NotOverlapping
+		
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName1" type="select" label="Input File Format 1">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName1" format="bed" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName1" format="gff" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName1" format="gff2" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName1" format="gff3" type="data" label="Input File 1"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName1" format="sam" type="data" label="Input File 1"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName1" format="gtf" type="data" label="Input File 1"/>
+								                        </when>
+		</conditional>
+
+		<conditional name="formatType2">
+			<param name="FormatInputFileName2" type="select" label="Input File Format 2">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName2" format="bed" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName2" format="gff" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName2" format="gff2" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName2" format="gff3" type="data" label="Input File 2"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName2" format="sam" type="data" label="Input File 2"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName2" format="gtf" type="data" label="Input File 2"/>
+			</when>
+		</conditional>
+
+
+
+		<conditional name="optionNFirstFile1">
+			<param name="NFirstForFile1" type="select" label="NFirst for file 1" help="only consider the n first nucleotides of the transcripts in file 1">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="firstNtFile1" type="integer" value="1" label="n first nucleotides for input file 1" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		<conditional name="optionNFirstFile2">
+			<param name="NFirstForFile2" type="select" label="NFirst for file 2" help="only consider the n first nucleotides of the transcripts in file 2">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="firstNtFile2" type="integer" value="1" label="n first nucleotides for input file 1" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionNLastFile1">
+			<param name="NLastForFile1" type="select" label="NLast for file 1">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="lastNtFile1" type="integer" value="1" label="n last nucleotides for input file 1" help="only consider the n last nucleotides of the transcripts in file 1"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		<conditional name="optionNLastFile2">
+			<param name="NLastForFile2" type="select" label="NLast for file 2">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="lastNtFile2" type="integer" value="1" label="n last nucleotides for input file 2" help="only consider the n last nucleotides of the transcripts in file 2"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+
+
+		<conditional name="optionExtentionCinqFile1">
+			<param name="extentionFile1" type="select" label="Extension towards 5 for file 1">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="extention51" type="integer" value="1" label="in file 1" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+
+		<conditional name="optionExtentionCinqFile2">
+			<param name="extentionFile2" type="select" label="Extension towards 5 for file 2">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="extention52" type="integer" value="1" label="in file 2"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionExtentionTroisFile1">
+			<param name="extentionFile1" type="select" label="Extension towards 3 for file 1">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="extention31" type="integer" value="1" label="in file 1" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionExtentionTroisFile2">
+			<param name="extentionFile2" type="select" label="Extension towards 3 for file 2">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="extention32" type="integer" value="1" label="in file 2" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="OptionColinearOrAntiSens">
+			<param name="OptionCA" type="select" label="Colinear or anti-sens">
+				<option value="Colinear">Colinear</option>
+				<option value="AntiSens">AntiSens</option>
+				<option value="NONE" selected="true">NONE</option>
+			</param>
+			<when value="Colinear">
+			</when>
+			<when value="AntiSens">
+			</when>
+			<when value="NONE">
+			</when>
+		</conditional>
+
+		<conditional name="OptionDistance">
+			<param name="Dist" type="select" label="Maximum Distance between two reads">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="distance" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="OptionMinOverlap">
+			<param name="MO" type="select" label="Minimum number of overlapping between two reads">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="minOverlap" type="integer" value="1"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		<param name="InvertMatch" type="boolean" truevalue="-x" falsevalue="" checked="false" label="Invert match"/>
+		<param name="ReportIntron" type="boolean" truevalue="-t" falsevalue="" checked="false" label="Report intron"/>
+		<param name="NotOverlapping" type="boolean" truevalue="-O" falsevalue="" checked="false" label="When there is no overlapping, the number of Overlapping will be set to 0 by defalt."/>
+		
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3"/>
+	</outputs> 
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/computeCoverage.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,107 @@
+<tool id="ComputeCoverage" name="Compute coverage">
+    <description>Compute the coverage of a set with respect to another set.</description>
+    <command interpreter="python">
+        ../Java/Python/ComputeCoverage.py -i $formatType.inputFileName1
+		#if $formatType.FormatInputFileName1 == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName1 == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName1 == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName1 == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName1 == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName1 == 'gtf':
+			-f gtf
+		#end if
+			
+		-j $formatType2.inputFileName2
+		#if $formatType2.FormatInputFileName2 == 'bed':
+			-g bed
+		#elif $formatType2.FormatInputFileName2 == 'gff':
+			-g gff	
+		#elif $formatType2.FormatInputFileName2 == 'gff2':
+			-g gff2
+		#elif $formatType2.FormatInputFileName2 == 'gff3':
+			-g gff3
+		#elif $formatType2.FormatInputFileName2 == 'sam':
+			-g sam
+		#elif $formatType2.FormatInputFileName2 == 'gtf':
+			-g gtf
+		#end if
+
+                $ReportIntron
+                -o $outputFileGff
+
+    </command>
+
+    <inputs>
+        <conditional name="formatType">
+			<param name="FormatInputFileName1" type="select" label="Input File Format 1">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName1" format="bed" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName1" format="gff" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName1" format="gff2" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName1" format="gff3" type="data" label="Input File 1"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName1" format="sam" type="data" label="Input File 1"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName1" format="gtf" type="data" label="Input File 1"/>
+			</when>
+		</conditional>
+
+		<conditional name="formatType2">
+			<param name="FormatInputFileName2" type="select" label="Input File Format 2">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName2" format="bed" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName2" format="gff" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName2" format="gff2" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName2" format="gff3" type="data" label="Input File 2"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName2" format="sam" type="data" label="Input File 2"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName2" format="gtf" type="data" label="Input File 2"/>
+			</when>
+                </conditional>
+
+                <param name="ReportIntron" type="boolean" truevalue="-t" falsevalue="" checked="false" label="Include introns."/>
+
+        </inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3" label="[computeCoverage] OUTPUT file"/>
+	</outputs> 
+	
+</tool>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/coordinatesToSequence.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,62 @@
+<tool id="coordinatesToSequence" name="coordinates to sequence">
+	<description>Coordinates to Sequences: Extract the sequences from a list of coordinates.</description>
+	<command interpreter="python">
+		../Java/Python/coordinatesToSequence.py -i $formatType.inputFileName1
+		#if $formatType.FormatInputFileName1 == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName1 == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName1 == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName1 == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName1 == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName1 == 'gtf':
+			-f gtf
+		#end if
+			
+		-s $sequence
+		-o $outputFileFasta
+		
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName1" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName1" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName1" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName1" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName1" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName1" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName1" format="gtf" type="data" label="Input File"/>
+			</when>
+		</conditional>
+
+ 	    <param name="sequence" type="data" label="Reference fasta File" format="fasta"/>
+
+	</inputs>
+
+	<outputs>
+		<data name="outputFileFasta" format="fasta" label="coordinates to sequences output"/>
+	</outputs> 
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/findTss.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,59 @@
+<tool id="findTss" name="findTss">
+	<description>Find the transcription start site of a list of transcripts.</description>
+	<command interpreter="python">
+		../Java/Python/findTss.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#end if
+			
+
+		-o $outputFileGff 
+		$colinear
+		$normalize
+		-d $distance
+		$excel $excelOutput
+		
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+		</conditional>
+
+		<param name="colinear" type="boolean" truevalue="-e" falsevalue="" checked="false" label="colinear option" help="This option clusterizes only the same strand reads"/>
+		<param name="normalize" type="boolean" truevalue="-n" falsevalue="" checked="false" label="normalize option for only GFF3 file format" help="This option normalize (Warning!! Only for GFF3 file!!!!!)"/>
+		<param name="distance" type="text" value="10" label="distance option" help="Limit the maximum distance between two reads"/>
+		<param name="excel" type="boolean" truevalue="-c" falsevalue="" checked="false" label="excel option" help="This option creates a csv file."/>
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3" label="[findTss] Output File"/>
+		<data name="excelOutput" format="csv" label="[findTss] CSV File">
+			<filter>excel</filter>
+		</data>	
+	</outputs> 
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/getDifference.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,127 @@
+<tool id="getDifference" name="get Difference">
+	<description>Gets all the regions of the genome, except the one given or get all the elements from the first set which does not ovelap with the second set (at the nucleotide level).</description>
+	<command interpreter="python">
+		../Java/Python/getDifference.py -i $formatType.inputFileName1
+		#if $formatType.FormatInputFileName1 == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName1 == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName1 == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName1 == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName1 == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName1 == 'gtf':
+			-f gtf
+		#end if
+			
+		-j $formatType2.inputFileName2
+		#if $formatType2.FormatInputFileName2 == 'bed':
+			-g bed
+		#elif $formatType2.FormatInputFileName2 == 'gff':
+			-g gff	
+		#elif $formatType2.FormatInputFileName2 == 'gff2':
+			-g gff2
+		#elif $formatType2.FormatInputFileName2 == 'gff3':
+			-g gff3
+		#elif $formatType2.FormatInputFileName2 == 'sam':
+			-g sam
+		#elif $formatType2.FormatInputFileName2 == 'gtf':
+			-g gtf
+		#end if
+
+
+		$split
+		
+		#if $OptionSequence.option == "Yes":
+			-s $OptionSequence.sequence
+		#end if
+		
+		-o $outputFileGff
+
+
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName1" type="select" label="Input File Format 1">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName1" format="bed" type="data" label="Input File "/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName1" format="gff" type="data" label="Input File "/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName1" format="gff2" type="data" label="Input File "/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName1" format="gff3" type="data" label="Input File "/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName1" format="sam" type="data" label="Input File "/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName1" format="gtf" type="data" label="Input File "/>
+			</when>
+		</conditional>
+
+		<conditional name="formatType2">
+			<param name="FormatInputFileName2" type="select" label="Input File Format 2">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName2" format="bed" type="data" label="reference file"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName2" format="gff" type="data" label="reference file"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName2" format="gff2" type="data" label="reference file"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName2" format="gff3" type="data" label="reference file"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName2" format="sam" type="data" label="reference file"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName2" format="gtf" type="data" label="reference file"/>
+			</when>
+		</conditional>
+
+		<param name="split" type="boolean" truevalue="-p" falsevalue="" checked="false" label="split option" help="When comparing to a set of genomic coordinates, do not join."/>
+
+		
+		<conditional name="OptionSequence">
+			<param name="option" type="select" label="Compare with a reference fasta file.">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="sequence" type="data" label="Fasta File" format="fasta"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+	</inputs>
+
+
+	<outputs>
+		<data name="outputFileGff" format="gff3" label="[getDifference]output File."/>
+	</outputs> 
+
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/getDistance.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,275 @@
+<tool id="GetDistance" name="get distance">
+	<description>Give the distances between every data from the first input set and the data from the second input set</description>
+	<command interpreter="python">
+		../Java/Python/getDistance.py -i $formatType.inputFileName1
+		#if $formatType.FormatInputFileName1 == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName1 == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName1 == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName1 == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName1 == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName1 == 'gtf':
+			-f gtf
+		#end if
+			
+		-j $formatType2.inputFileName2
+		#if $formatType2.FormatInputFileName2 == 'bed':
+			-g bed
+		#elif $formatType2.FormatInputFileName2 == 'gff':
+			-g gff	
+		#elif $formatType2.FormatInputFileName2 == 'gff2':
+			-g gff2
+		#elif $formatType2.FormatInputFileName2 == 'gff3':
+			-g gff3
+		#elif $formatType2.FormatInputFileName2 == 'sam':
+			-g sam
+		#elif $formatType2.FormatInputFileName2 == 'gtf':
+			-g gtf
+		#end if
+
+
+		$absolute $proportion
+
+		#if $OptionColinearOrAntiSens.OptionCA == "Colinear":
+			-c 
+		#elif $OptionColinearOrAntiSens.OptionCA == 'AntiSens':
+			-a
+		#end if
+
+		#if $OptionFirstNucl5.FirstNu5 == "Yes":
+			-s $OptionFirstNucl5.first5File1
+			-S $OptionFirstNucl5.first5File2
+		#end if		
+
+		#if $OptionFirstNucl3.FirstNu3 == "Yes":
+			-e $OptionFirstNucl3.first3File1
+			-E $OptionFirstNucl3.first3File2
+		#end if
+
+		#if $OptionMinDistance.MinD == "Yes":
+			-m $OptionMinDistance.minDistance
+		#end if
+
+		#if $OptionMaxDistance.MaxD == "Yes":
+			-M $OptionMaxDistance.maxDistance
+		#end if
+
+		$fivePrime $threePrime $spearMan
+
+		#if $OptionBuckets.OBuckets == "Yes":
+			-u $OptionBuckets.buckets
+		#end if
+
+		#if $OptionMinXaxis.MinX == "Yes":
+			-x $OptionMinXaxis.minXaxis
+		#end if
+
+		#if $OptionMaxXaxis.MaxX == "Yes":
+			-X $OptionMaxXaxis.maxXaxis
+		#end if
+
+		#if $OptionTitle.OTitle == "Yes":
+			-t $OptionTitle.title
+		#end if
+		
+		-o $outputFilePng
+		$outputDistance $outputFileDistance
+
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName1" type="select" label="Input File Format 1">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName1" format="bed" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName1" format="gff" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName1" format="gff2" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName1" format="gff3" type="data" label="Input File 1"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName1" format="sam" type="data" label="Input File 1"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName1" format="gtf" type="data" label="Input File 1"/>
+			</when>
+		</conditional>
+
+		<conditional name="formatType2">
+			<param name="FormatInputFileName2" type="select" label="Input File Format 2">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName2" format="bed" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName2" format="gff" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName2" format="gff2" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName2" format="gff3" type="data" label="Input File 2"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName2" format="sam" type="data" label="Input File 2"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName2" format="gtf" type="data" label="Input File 2"/>
+			</when>
+		</conditional>
+
+		<param name="outputDistance" type="boolean" truevalue="-O" falsevalue="" checked="false" label="distance option" help="This option create a GFF3 output file containing the distance for each element of the query."/>
+
+		<param name="absolute" type="boolean" truevalue="-b" falsevalue="" checked="false" label="absolute value option" help="This option gives the absolute value of the distance."/>
+		<param name="proportion" type="boolean" truevalue="-p" falsevalue="" checked="false" label="proportion option" help="This option gives the proportion on the y-axis instead of the number of distances."/>
+
+		<conditional name="OptionColinearOrAntiSens">
+			<param name="OptionCA" type="select" label="Colinear or anti-sens">
+				<option value="Colinear">Colinear</option>
+				<option value="AntiSens">AntiSens</option>
+				<option value="NONE" selected="true">NONE</option>
+			</param>
+			<when value="Colinear">
+			</when>
+			<when value="AntiSens">
+			</when>
+			<when value="NONE">
+			</when>
+		</conditional>
+
+		<conditional name="OptionFirstNucl5">
+			<param name="FirstNu5" type="select" label="only consider the n first 5' nucleotides for input files">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="first5File1" type="integer" value="1" label="in file 1" help="Be Careful! The value must be upper than 0"/>
+				<param name="first5File2" type="integer" value="1" label="in file 2" help="Be Careful! The value must be upper than 0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="OptionFirstNucl3">
+			<param name="FirstNu3" type="select" label="only consider the n first 3' nucleotides for input files">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="first3File1" type="integer" value="1" label="in file 1" help="Be Careful! The value must be upper than 0"/>
+				<param name="first3File2" type="integer" value="1" label="in file 2" help="Be Careful! The value must be upper than 0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="OptionMinDistance">
+			<param name="MinD" type="select" label="minimum distance considered between two transcripts">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="minDistance" type="integer" value="1"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="OptionMaxDistance">
+			<param name="MaxD" type="select" label="maximum distance considered between two transcripts">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="maxDistance" type="integer" value="1000"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<param name="fivePrime" type="boolean" truevalue="-5" falsevalue="" checked="false" label="five prime option" help="Consider the elements from input file 1 which are upstream of elements of input file 2"/>
+		<param name="threePrime" type="boolean" truevalue="-3" falsevalue="" checked="false" label="three prime option" help="Consider the elements from input file1 which are downstream of elements of input file 2"/>
+		<param name="spearMan" type="boolean" truevalue="-r" falsevalue="" checked="false" label="spearman option" help="Compute Spearman rho."/>
+
+
+		<conditional name="OptionBuckets">
+			<param name="OBuckets" type="select" label="Plots histogram instead of line plot with given interval size.">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="buckets" type="integer" value="1" label="Interval size"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="OptionMinXaxis">
+			<param name="MinX" type="select" label="Minimum value on the x-axis to plot.">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="minXaxis" type="integer" value="1"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="OptionMaxXaxis">
+			<param name="MaxX" type="select" label="Maximum value on the x-axis to plot.">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="maxXaxis" type="integer" value="1"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="OptionTitle">
+			<param name="OTitle" type="select" label="Title for the graph.">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="title" type="text" value=""/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+	</inputs>
+
+
+	<outputs>
+		<data name="outputFilePng" format="png"/>
+		<data name="outputFileDistance" format="gff3">
+			<filter>outputDistance</filter>
+		</data>
+	</outputs> 
+
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/getDistribution.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,237 @@
+<tool id="getDistribution" name="get distribution">
+	<description>Get Distribution: Get the distribution of the genomic coordinates on a genome.</description>
+	<command interpreter="python">
+		../Java/Python/GetDistribution.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName == 'csv':
+			-f csv
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName == 'gtf':
+			-f gtf
+		#end if
+		
+		-r $refFile
+		
+		#if $optionNbBin.Nb == 'Yes':
+			-b $optionNbBin.nbBins
+		#end if
+		
+		#if $optionStart.start == 'Yes':
+			-s $optionStart.startValue
+		#end if	
+		
+		#if $optionEnd.end == 'Yes':
+			-e $optionEnd.endValue
+		#end if	
+		
+		#if $optionHeight.height == 'Yes':
+			-H $optionHeight.heightValue
+		#end if	
+		
+		#if $optionWidth.width == 'Yes':
+			-W $optionWidth.widthValue
+		#end if	
+		
+		#if $optionYMin.YMin == 'Yes':
+			-y $optionYMin.YMinValue
+		#end if
+		
+		#if $optionYMax.YMax == 'Yes':
+			-Y $optionYMax.YMaxValue
+		#end if
+		
+		#if $optionChrom.chrom == 'Yes':
+			-c $optionChrom.chromValue
+		#end if
+	
+		#if $optionColor.color == 'Yes':
+			-l $optionColor.colorValue
+		#end if
+
+		$bothStrands
+		$average
+		-n $names
+		$normalize
+		$csv $outputCSV
+		$gff $outputGFF
+		-m
+		-o $outputFile
+
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="csv">csv</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="csv">
+				<param name="inputFileName" format="csv" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName" format="gtf" type="data" label="Input File"/>
+			</when>
+		</conditional>
+		
+		<param name="refFile" format="fasta" type="data" label="reference genome file"/>
+		
+		<conditional name="optionNbBin">
+			<param name="Nb" type="select" label="number of bins">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="nbBins" type="integer" value="1000" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionStart">
+			<param name="start" type="select" label="start from a given region">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="startValue" type="integer" value="0" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionEnd">
+			<param name="end" type="select" label="end from a given region">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="endValue" type="integer" value="0" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionHeight">
+			<param name="height" type="select" label="height of the graphics">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="heightValue" type="integer" value="300" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionWidth">
+			<param name="width" type="select" label="width of the graphics">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="widthValue" type="integer" value="1000" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionYMin">
+			<param name="YMin" type="select" label="minimum value on the y-axis to plot">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="YMinValue" type="integer" value="1000" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionYMax">
+			<param name="YMax" type="select" label="maximum value on the y-axis to plot">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="YMaxValue" type="integer" value="1000" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionChrom">
+			<param name="chrom" type="select" label="plot only one given chromosome">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="chromValue" type="text" value="chromName" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionColor">
+			<param name="color" type="select" label="color of the lines (separated by commas and no space)">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="colorValue" type="text" value="red,blue" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+
+		<param name="bothStrands" type="boolean" truevalue="-2" falsevalue="" checked="false" label="plot one curve per strand"/>
+		<param name="average" type="boolean" truevalue="-a" falsevalue="" checked="false" label="plot plot average (instead of sum)"/>
+		<param name="names" type="text" value="nbElements" label="name for the tags (separated by commas and no space)"/>
+		<param name="normalize" type="boolean" truevalue="-z" falsevalue="" checked="false" label="normalize data (when panels are different)"/>
+		<param name="csv" type="boolean" truevalue="-x" falsevalue="" checked="false" label="write a .csv file."/>
+		<param name="gff" type="boolean" truevalue="-g" falsevalue="" checked="false" label="write a .gff file."/>
+	</inputs>
+
+	<outputs>
+		<data name="outputFile" format="png" label="[getDistribution] out png file"/>
+		<data name="outputCSV" format="csv" label="[getDistribution] output csv file">
+			<filter>csv</filter>
+		</data>
+
+		<data name="outputGFF" format="gff" label="[getDistribution] output gff file">
+			<filter>gff</filter>
+		</data>
+	</outputs> 
+
+    <help>
+        This script gives a .tar out file, if you want to take look at the results, you have to download it.
+    </help>	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/getExons.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,72 @@
+<tool id="getExons" name="get exons">
+    <description>Get the exons of a set of transcripts.</description>
+    <command interpreter="python">
+		../Java/Python/getExons.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName == 'gtf':
+			-f gtf
+		#end if
+		
+		#if $optionSelect.Value == "Yes":
+			-s $optionSelect.selectValue
+		#end if
+		
+		-o $outputFileGff 
+	</command>
+	
+    <inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName" format="gtf" type="data" label="Input File"/>
+			</when>
+		</conditional>
+
+		<conditional name="optionSelect">
+			<param name="Value" type="select" label="select some of the exons (like '1,2,5..-3,-1')">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="selectValue" type="text" value="None" label="select option" help="like '1,2,5..-3,-1'"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+    </inputs>
+        
+    <outputs>
+        <data format="gff3" name="outputFileGff" label="[getExons -> gff3] Output File"/>       
+    </outputs> 
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/getIntrons.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,56 @@
+<tool id="getIntrons" name="get introns">
+    <description>Get the introns of a set of transcripts.</description>
+    <command interpreter="python">
+		../Java/Python/getIntrons.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName == 'gtf':
+			-f gtf
+		#end if
+		-o $outputFileGff 
+	</command>
+	
+    <inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName" format="gtf" type="data" label="Input File"/>
+			</when>
+		</conditional>
+
+    </inputs>
+        
+    <outputs>
+        <data format="gff3" name="outputFileGff" label="[getIntrons -> gff3] Output File"/>       
+    </outputs> 
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/getNb.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,78 @@
+<tool id="getNumber" name="get number">
+	<description>Get the distribution of exons per transcripts, or mapping per read, or transcript per cluster.</description>
+	<command interpreter="python">
+		../Java/Python/getNb.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName == 'gtf':
+			-f gtf
+		#end if
+		-o $outputFilePNG
+		-q $query
+		$barPlot
+		#if $optionXMAX.XMAX == 'Yes':
+			-x $optionXMAX.xMaxValue
+		#end if		
+
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName" format="gtf" type="data" label="Input File"/>
+			</when>
+		</conditional>
+		
+		<param name="query" type="text" value="None" label="compulsory option, choice (exon, transcript, cluster)" />
+		<param name="barPlot" type="boolean" truevalue="-b" falsevalue="" checked="false" label="use barplot representation"/>
+		
+		<conditional name="optionXMAX">
+			<param name="XMAX" type="select" label="maximum value on the x-axis to plot ">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="xMaxValue" type="integer" value="0" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+	</inputs>
+
+	<outputs>
+		<data name="outputFilePNG" format="png" label="[getNB]out file"/>
+	</outputs> 
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/getReadDistribution.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,67 @@
+<tool id="getReadDistribution" name="get read distribution">
+	<description>Get Read Distribution v1.0.1: Plot the number of identical reads and give the most represented.</description>
+	<command interpreter="python">
+		../Java/Python/WrappGetReadDistribution.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'fasta':
+			-f fasta
+		#elif $formatType.FormatInputFileName == 'fastq':
+			-f fastq	
+		#end if
+			
+		#if $optionnumber.number == 'Yes':
+			-n $optionnumber.bestNumber
+		#end if
+		#if $optionpercent.percent == 'Yes':
+			-p $optionpercent.percentage
+		#end if
+		-o $outputFile
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Sequence input File Format ">
+				<option value="fasta">fasta</option>
+				<option value="fastq">fastq</option>
+			</param>
+			<when value="fasta">
+				<param name="inputFileName" format="fasta" type="data" label="Sequence input File"/>
+			</when>
+			<when value="fastq">
+				<param name="inputFileName" format="fastq" type="data" label="Sequence input File"/>
+			</when>
+		</conditional>
+		
+		<conditional name="optionnumber">
+			<param name="number" type="select" label="keep the best n">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="bestNumber" type="integer" value="0"  />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<conditional name="optionpercent">
+			<param name="percent" type="select" label="keep the best n percentage">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="percentage" type="integer" value="0" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+	</inputs>
+
+	<outputs>
+		<data name="outputFile" format="tar" label="[getReadDistribution] tar out file" help="You can not see the results directly from galaxy, but you can download this tar output file."/>
+	</outputs> 
+
+    <help>
+        This script gives a .tar out file, if you want to take look at the results, you have to download it.
+    </help>	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/getSequence.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,21 @@
+<tool id="getSequence" name="get sequence">
+  <description>Get a single sequence in a FASTA file.</description>
+  <command interpreter="python"> ../Java/Python/getSequence.py -i $inputFile 
+	-n $name
+  	-o $outputFile  
+  
+  </command>
+  
+  
+  <inputs>
+    <param name="inputFile" type="data" label="Input fasta File" format="fasta"/>
+  	<param name="name" type="text" value="None" label="name of the sequence [compulsory option]"/>
+  </inputs>
+
+  <outputs>
+    <data format="fasta" name="outputFile" label="[getSequence] Output File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/getSizes.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,135 @@
+<tool id="GetSizes" name="get sizes">
+	<description>Get the sizes of a set of genomic coordinates.</description>
+	<command interpreter="python">
+		../Java/Python/getSizes.py -i $formatType.inputFileName $formatType.FormatInputFileName
+	
+		#if $OptionQuery.OptionQ == 'NONE':
+			-q size
+		#else:
+			$OptionQuery.OptionQ
+		#end if
+
+		-o $outputFile
+
+		#if $OptionXMax.xMax == "Yes":
+			-x $OptionXMax.maxValue
+		#end if
+		#if $OptionX.xLab == "Yes":
+		        -a $OptionX.xLabValue
+		#end if
+                #if $OptionY.yLab == "Yes":
+		        -b $OptionY.yLabValue
+		#end if
+		$barPlot
+		$excel $excelOutput
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="-f bed">bed</option>
+				<option value="-f gff">gff</option>
+				<option value="-f gff2">gff2</option>
+				<option value="-f gff3">gff3</option>
+				<option value="-f sam">sam</option>
+				<option value="-f gtf">gtf</option>
+				<option value="-f fasta">fasta</option>
+				<option value="-f fastq">fastq</option>
+			</param>
+			<when value="-f bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="-f gff">
+				<param name="inputFileName" format="gff" type="data" label="Input gff File"/>
+			</when>
+			<when value="-f gff2">
+				<param name="inputFileName" format="gff" type="data" label="Input gff2 File"/>
+			</when>
+			<when value="-f gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input gff3 File"/>
+			</when>
+			<when value="-f sam">
+				<param name="inputFileName" format="sam" type="data" label="Input gff2 File"/>
+			</when>
+			<when value="-f gtf">
+				<param name="inputFileName" format="gtf" type="data" label="Input gff3 File"/>
+			</when>
+			<when value="-f fasta">
+				<param name="inputFileName" format="fasta" type="data" label="Input fasta File"/>
+			</when>
+			<when value="-f fastq">
+				<param name="inputFileName" format="fastq" type="data" label="Input fastq File"/>
+			</when>
+		</conditional>
+
+		<conditional name="OptionQuery">
+			<param name="OptionQ" type="select" label="mesure type">
+				<option value="-q size">size</option>
+				<option value="-q intron size">intron size</option>
+				<option value="-q exon size">exon size</option>
+				<option value="-q 1st exon size">1st exon size</option>
+				<option value="NONE" selected="true">NONE</option>
+			</param>
+			<when value="-q size">
+			</when>
+			<when value="-q intron size">
+			</when>
+			<when value="-q exon size">
+			</when>
+			<when value="-q 1st exon size">
+			</when>
+			<when value="NONE">
+			
+			</when>
+		</conditional>
+
+		<conditional name="OptionXMax">
+			<param name="xMax" type="select" label="maximum value on the x-axis to plot [format: int]">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="maxValue" type="integer" value="1000"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="OptionX">
+			 <param name="xLab" type="select" label="X label title">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="xLabValue" type="text" value="Size" label="Notice: The title should not have spaces. EX. Size_of_transcript"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="OptionY">
+			<param name="yLab" type="select" label="Y label title">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="yLabValue" type="text" value="#_reads" label="Notice: The title should not have spaces. EX. Number_of_reads"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+
+
+		<param name="barPlot" type="boolean" truevalue="-B" falsevalue="" checked="false" label="use barplot representation"/>
+
+		<param name="excel" type="boolean" truevalue="-c" falsevalue="" checked="false" label="excel option" help="This option creates a csv file."/>
+	</inputs>
+	
+	<outputs>
+		<data name="outputFile" format="png" label="[Get size] Output file"/>
+		<data name="excelOutput" format="csv">
+			<filter>excel</filter>
+		</data>
+	</outputs>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/getWigData.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,17 @@
+<tool id="getWigData" name="get wig data">
+    <description>Compute the average data for some genomic coordinates using WIG files</description>
+    <command interpreter="python">
+		../Java/Python/getWigData.py -i $inputGff3File -f gff3 -w $inputWigFile -t $tagName -$strand -o $outputFile
+	</command>
+	
+    <inputs>
+    	<param name="inputGff3File" type="data" label="Input Gff3 File (compulsory option)" format="gff3"/>
+   		<param name="inputWigFile" type="data" label="Input Wig File (compulsory option)" format="wig"/>
+		<param name="tagName" type="text" value="None" label="tag option (compulsory option)" help="choose a tag name to write the wig information to output file."/>
+		<param name="strand" type="boolean" truevalue="-s" falsevalue="" checked="false" label="consider both strands separately."/>    
+    </inputs>
+        
+    <outputs>
+        <data format="gff3" name="outputFile" label="[getWigData -> gff3] Output File"/>       
+    </outputs> 
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/getWigDistance.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,17 @@
+<tool id="getWigDistance" name="get wig distance">
+    <description>Compute the average data around some genomic coordinates using WIG files (thus covering a large proportion of the genome).</description>
+    <command interpreter="python">
+		../Java/Python/getWigDistance.py -i $inputGff3File -f gff3 -w $inputWigFile -a 0.0 -d $distance $strand -o $outputFile
+	</command>
+	
+    <inputs>
+    	<param name="inputGff3File" type="data" label="Input Gff3 File (compulsory option)" format="gff3"/>
+   		<param name="inputWigFile" type="data" label="Input Wig File (compulsory option)" format="wig"/>
+		<param name="distance" type="integer" value="1000" label="distance option (compulsory option)" help="Distance around position.Be Careful! The value must be upper than 0"/>
+		<param name="strand" type="boolean" truevalue="-s" falsevalue="" checked="false" label="consider both strands separately."/>    
+    </inputs>
+        
+    <outputs>
+       	<data name="outputFile" format="png" label="[getWigDistance] PNG output File"/>    
+    </outputs> 
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/getWigProfile.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,70 @@
+<tool id="getWigProfile" name="get wig profile">
+	<description>Compute the average profile of some genomic coordinates using WIG files (thus covering a large proportion of the genome).</description>
+	<command interpreter="python">
+		../Java/Python/getWigProfile.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#end if
+		-w $inputWigFile
+		-p $nbPoints
+		-d $distance
+		$strands
+		-o $outputFilePNG
+		#if $optionSMO.SMO == 'Yes':
+			-m $optionSMO.smoothen
+		#end if		
+
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+		</conditional>
+		
+		<param name="inputWigFile" type="data" label="Input Wig File" format="wig"/>
+		<param name="nbPoints" type="integer" value="1000" label="number of points on the x-axis"/>
+		<param name="distance" type="integer" value="0" label="distance around genomic coordinates"/>
+		<param name="strands" type="boolean" truevalue="-s" falsevalue="" checked="false" label="consider both strands separately"/>
+		
+		<conditional name="optionSMO">
+			<param name="SMO" type="select" label="smoothen the curve">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="smoothen" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+	</inputs>
+
+	<outputs>
+		<data name="outputFilePNG" format="png" label="[getWigProfile]out file"/>
+	</outputs> 
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/mapperAnalyzer.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,186 @@
+<tool id="mapperAnalyzer" name="mapper analyzer">
+	<description>Read the output of an aligner, print statistics and possibly translate into BED or GBrowse formats. </description>
+	<command interpreter="python">
+		../Java/Python/mapperAnalyzer.py -i $formatType.inputFileName1
+		#if $formatType.FormatInputFileName1 == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName1 == 'gff3':
+			-f gff3	
+		#elif $formatType.FormatInputFileName1 == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName1 == 'bam':
+			-f bam
+		#elif $formatType.FormatInputFileName1 == 'seqmap':
+			-f seqmap
+		#end if
+			
+		-q $formatType2.inputFileName2
+		#if $formatType2.FormatInputFileName2 == 'fasta':
+			-k fasta
+		#elif $formatType2.FormatInputFileName2 == 'fastq':
+			-k fastq	
+		#end if
+		
+
+		#if $optionnumber.number == 'Yes':
+			-n $optionnumber.numberVal
+		#end if
+		#if $optionsize.size == 'Yes':
+			-s $optionsize.sizeVal
+		#end if
+		#if $optionidentity.identity == 'Yes':
+			-d $optionidentity.identityVal
+		#end if
+		#if $optionmismatch.mismatch == 'Yes':
+			-m $optionmismatch.mismatchVal
+		#end if
+		#if $optiongap.gap == 'Yes':
+			-p $optiongap.gapVal
+		#end if		
+		#if $optiontitle.title == 'Yes':
+			-t $optiontitle.titleVal
+		#end if	
+		#if $optionappend.append == 'Yes':
+			-a $optionappend.appendfile
+		#end if	
+			
+		$merge
+		$remove
+		$remain
+		-o $outputFileGFF
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName1" type="select" label="Input File mapping Format">
+				<option value="bed">bed</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="bam">bam</option>
+				<option value="seqmap" selected="true">seqmap</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName1" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName1" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName1" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="bam">
+				<param name="inputFileName1" format="bam" type="data" label="Input File"/>
+			</when>
+			<when value="seqmap">
+				<param name="inputFileName1" format="seqmap" type="data" label="Input File"/>
+			</when>
+		</conditional>
+
+		<conditional name="formatType2">
+			<param name="FormatInputFileName2" type="select" label="Reference sequence File Format">
+				<option value="fasta" selected="true">fasta</option>
+				<option value="fastq">fastq</option>
+			</param>
+			<when value="fasta">
+				<param name="inputFileName2" format="fasta" type="data" label="Reference sequence File Format"/>
+			</when>
+			<when value="fastq">
+				<param name="inputFileName2" format="fastq" type="data" label="Reference sequence File Format"/>
+			</when>
+		</conditional>
+
+
+		<conditional name="optionnumber">
+			<param name="number" type="select" label="max. number of occurrences of a sequence">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="numberVal" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<conditional name="optionsize">
+			<param name="size" type="select" label="minimum pourcentage of size ">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="sizeVal" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionidentity">
+			<param name="identity" type="select" label="minimum pourcentage of identity ">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="identityVal" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionmismatch">
+			<param name="mismatch" type="select" label="maximum number of mismatches">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="mismatchVal" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optiongap">
+			<param name="gap" type="select" label="maximum number of gaps">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="gapVal" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optiontitle">
+			<param name="title" type="select" label="title of the plots ">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="titleVal" type="text" value="title of the UCSC track" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<conditional name="optionappend">
+			<param name="append" type="select" label="append to GFF3 file">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="appendfile" type="data" format="gff3" label="append a file"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<param name="merge" type="boolean" truevalue="-e" falsevalue="" checked="false" label="merge exons when introns are short "/>
+		<param name="remove" type="boolean" truevalue="-x" falsevalue="" checked="false" label="remove transcripts when exons are short"/>
+		<param name="remain" type="boolean" truevalue="-r" falsevalue="" checked="false" label="print the unmatched sequences "/>
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGFF" format="gff3" label="[mapperAnalyzer] out file"/>
+	</outputs> 
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/mappingToCoordinates.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,57 @@
+<tool id="mappingToCoordinates" name="mapping to coordinates">
+	<description>Converts a mapping type file(given by a mapping tool) to a GFF3 type file.</description>
+	<command interpreter="python">
+		../Java/Python/mappingToCoordinates.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName == 'blast -8'
+			-f blast
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#end if
+
+		-o $outputFileGff 
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="sam">sam</option>
+				<option value="blast -8">blast</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="blast -8">
+				<param name="inputFileName" format="blast" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+		</conditional>
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3"/>
+	</outputs> 
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/mergeSlidingWindowsClusters.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,103 @@
+<tool id="mergeSlidingWindowsClusters" name="merge sliding windows clusters">
+	<description>Merges two files containing the results of a sliding windows clustering.</description>
+	<command interpreter="python">
+		../Java/Python/mergeSlidingWindowsClusters.py -i $formatType.inputFileName1
+		#if $formatType.FormatInputFileName1 == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName1 == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName1 == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName1 == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName1 == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName1 == 'gtf':
+			-f gtf
+		#end if
+			
+		-j $formatType2.inputFileName2
+		#if $formatType2.FormatInputFileName2 == 'bed':
+			-g bed
+		#elif $formatType2.FormatInputFileName2 == 'gff':
+			-g gff	
+		#elif $formatType2.FormatInputFileName2 == 'gff2':
+			-g gff2
+		#elif $formatType2.FormatInputFileName2 == 'gff3':
+			-g gff3
+		#elif $formatType2.FormatInputFileName2 == 'sam':
+			-g sam
+		#elif $formatType2.FormatInputFileName2 == 'gtf':
+			-g gtf
+		#end if
+
+		-o $outputFileGff 
+
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName1" type="select" label="Input File Format 1">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName1" format="bed" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName1" format="gff" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName1" format="gff2" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName1" format="gff3" type="data" label="Input File 1"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName1" format="sam" type="data" label="Input File 1"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName1" format="gtf" type="data" label="Input File 1"/>
+			</when>
+		</conditional>
+
+		<conditional name="formatType2">
+			<param name="FormatInputFileName2" type="select" label="Input File Format 2">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName2" format="bed" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName2" format="gff" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName2" format="gff2" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName2" format="gff3" type="data" label="Input File 2"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName2" format="sam" type="data" label="Input File 2"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName2" format="gtf" type="data" label="Input File 2"/>
+			</when>
+		</conditional>
+
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3"/>
+	</outputs> 
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/mergeTranscriptLists.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,148 @@
+<tool id="mergeTranscriptLists" name="merge transcript lists">
+	<description>Merge the elements of two lists of genomic coordinates.</description>
+	<command interpreter="python">
+		../Java/Python/mergeTranscriptLists.py -i $formatType.inputFileName1
+		#if $formatType.FormatInputFileName1 == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName1 == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName1 == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName1 == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName1 == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName1 == 'gtf':
+			-f gtf
+		#end if
+			
+		-j $formatType2.inputFileName2
+		#if $formatType2.FormatInputFileName2 == 'bed':
+			-g bed
+		#elif $formatType2.FormatInputFileName2 == 'gff':
+			-g gff	
+		#elif $formatType2.FormatInputFileName2 == 'gff2':
+			-g gff2
+		#elif $formatType2.FormatInputFileName2 == 'gff3':
+			-g gff3
+		#elif $formatType2.FormatInputFileName2 == 'sam':
+			-g sam
+		#elif $formatType2.FormatInputFileName2 == 'gtf':
+			-g gtf
+		#end if
+			
+		$all
+		$normalize
+				
+		#if $OptionDistance.dis == 'Yes':
+			-d $OptionDistance.disVal
+		#end if	
+		
+		#if $OptionColinearOrAntiSens.OptionCA == 'Colinear':
+			-c 
+		#elif $OptionColinearOrAntiSens.OptionCA == 'AntiSens':
+			-a
+		#end if	
+		
+		-o $outputFileGff 
+		
+	
+
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName1" type="select" label="Input File Format 1">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName1" format="bed" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName1" format="gff" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName1" format="gff2" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName1" format="gff3" type="data" label="Input File 1"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName1" format="sam" type="data" label="Input File 1"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName1" format="gtf" type="data" label="Input File 1"/>
+			</when>
+		</conditional>
+
+		<conditional name="formatType2">
+			<param name="FormatInputFileName2" type="select" label="Input File Format 2">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName2" format="bed" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName2" format="gff" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName2" format="gff2" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName2" format="gff3" type="data" label="Input File 2"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName2" format="sam" type="data" label="Input File 2"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName2" format="gtf" type="data" label="Input File 2"/>
+			</when>
+		</conditional>
+
+
+		<param name="all" type="boolean" truevalue="-k" falsevalue="" checked="false" label="print all the transcripts, not only those overlapping"/>
+		<param name="normalize" type="boolean" truevalue="-n" falsevalue="" checked="false" label="normalize the number of reads per cluster by the number of mappings per read "/>
+		
+		<conditional name="OptionDistance">
+			<param name="dis" type="select" label="provide the number of reads" >
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="disVal" type="integer" value="0" label="max. distance between two transcripts" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<conditional name="OptionColinearOrAntiSens">
+			<param name="OptionCA" type="select" label="Colinear or anti-sens">
+				<option value="Colinear">Colinear</option>
+				<option value="AntiSens">AntiSens</option>
+				<option value="NONE" selected="true">NONE</option>
+			</param>
+			<when value="Colinear">
+			</when>
+			<when value="AntiSens">
+			</when>
+			<when value="NONE">
+			</when>
+		</conditional>
+
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3" label="[mergeTranscriptLists]out file"/>
+	</outputs> 
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/modifyFasta.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,49 @@
+<tool id="modifyFasta" name="modify fasta">
+  <description>Extend or shring a list of sequences.</description>
+  <command interpreter="python"> ../Java/Python/modifyFasta.py -i $inputFile 
+  	#if $OptionStart.start == "Yes":
+			-s $OptionStart.startValue
+  	#end if
+  	
+  	#if $OptionEnd.end == "Yes":
+			-e $OptionEnd.endValue
+  	#end if
+  	-o $outputFile  
+  
+  </command>
+  
+  
+  <inputs>
+    <param name="inputFile" type="data" label="Input fasta File" format="fasta"/>
+	<conditional name="OptionStart">
+			<param name="start" type="select" label="keep first nucleotides">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="startValue" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+	</conditional>
+		
+	<conditional name="OptionEnd">
+			<param name="end" type="select" label="keep last nucleotides">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="endValue" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+	</conditional>   
+  </inputs>
+
+  <outputs>
+    <data format="fasta" name="outputFile" label="[modifyFasta] Output File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/modifyGenomicCoordinates.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,126 @@
+<tool id="modifyGenomicCoordinates" name="modify genomic coordinates">
+  <description>Extend or shrink a list of genomic coordinates.</description>
+  <command interpreter="python"> ../Java/Python/modifyGenomicCoordinates.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName == 'gtf':
+			-f gtf
+		#end if
+		
+  		#if $OptionStart.start == "Yes":
+			-s $OptionStart.startValue
+  		#end if
+  	
+  		#if $OptionEnd.end == "Yes":
+			-e $OptionEnd.endValue
+  		#end if
+  		
+  		#if $OptionFivePrim.five == "Yes":
+			-5 $OptionFivePrim.fivePValue
+  		#end if
+  	
+  		#if $OptionTroisP.TroisP == "Yes":
+			-3 $OptionTroisP.ThreePValue
+  		#end if
+  		
+  		-o $outputFile  
+  </command>
+  
+  
+  <inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName" format="gtf" type="data" label="Input File"/>
+			</when>
+		</conditional>
+  
+		<conditional name="OptionStart">
+			<param name="start" type="select" label="restrict to the start of the transcript">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="startValue" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<conditional name="OptionEnd">
+			<param name="end" type="select" label="restrict to the end of the transcript">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="endValue" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>    
+
+		
+		<conditional name="OptionFivePrim">
+			<param name="five" type="select" label="extend to the 5' direction">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="fivePValue" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>  
+		
+		<conditional name="OptionTroisP">
+			<param name="TroisP" type="select" label="extend to the 3' direction">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="ThreePValue" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		 
+  </inputs>
+
+  <outputs>
+    <data format="gff3" name="outputFile" label="[modifyGenomicCoordinates] Output File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/modifySequenceList.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,46 @@
+<tool id="modifySequenceList" name="modify sequence list">
+  <description>Extend or shring a list of sequences. </description>
+  <command interpreter="python"> ../Java/Python/modifySequenceList.py -i $inputFile -f fasta
+	#if $OptionStart.Start == "Yes":
+		-s $OptionStart.StartVal
+	#end if		
+	#if $OptionEnd.End == "Yes":
+		-e $OptionEnd.EndVal
+	#end if	
+  	-o $outputFile  
+  </command>
+  
+  
+  <inputs>
+	<param name="inputFile" type="data" format="fasta" label="input file"/>
+
+	<conditional name="OptionStart">
+		<param name="Start" type="select" label="keep first nucleotides">
+			<option value="Yes">Yes</option>
+			<option value="No" selected="true">No</option>
+		</param>
+		<when value="Yes">
+			<param name="StartVal" type="integer" value="0" />
+		</when>
+		<when value="No">
+		</when>
+	</conditional>
+		
+	<conditional name="OptionEnd">
+		<param name="End" type="select" label="keep last nucleotides">
+			<option value="Yes">Yes</option>
+			<option value="No" selected="true">No</option>
+		</param>
+		<when value="Yes">
+			<param name="EndVal" type="integer" value="0"/>
+		</when>
+		<when value="No">
+		</when>
+	</conditional>	
+  </inputs>
+
+  <outputs>
+    	<data format="fasta" name="outputFile" label="[modifySequenceList] Output File"/>
+  </outputs>
+
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/plot.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,71 @@
+<tool id="plot" name="Plot">
+	<description>Plot some information from a list of transcripts.</description>
+	<command interpreter="python">
+		../Java/Python/plot.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'gff':
+			-f gff
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#end if
+		
+		-x $xLabel
+		
+                -y $yLabel
+
+	        -X $XVal
+                -Y $YVal
+
+	        #if $optionLog.log == 'Yes' :
+		    -l $optionLog.logOnAxisLabel
+                #end if
+                
+                -s $shape
+		-o $outputFile
+
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+			</param>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+		</conditional>
+		
+		<param name="xLabel" type="text" value="value1" label="x label option" help="Choose one of the tags of 9th column in GFF file to be plotted as X-axis. Warning: You can only choose the tag value is digital."/>
+                <param name="yLabel" type="text" value="value2" label="y label option" help="Choose one of the tags of 9th column in GFF file to be plotted as Y-axis. You can only choose the tag value is digital."/>
+                <param name="XVal" type="float" value="0.0" label="value for x when tag is not present "/>
+		
+		<param name="YVal" type="float" value="0.0" label="value for y when tag is not present"/>
+
+
+                <conditional name="optionLog">
+			<param name="log" type="select" label="calculate log option" help="use log on x- or y-axis (write 'x', 'y' or 'xy')">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="logOnAxisLabel" type="text" value="y" label="use log on x- or y-axis (write 'x', 'y' or 'xy')"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+                <param name="shape" type="text" value="barplot" label="shape of the plot [format: choice (barplot, line, points, heatPoints)]"/>
+	</inputs>
+	
+	<outputs>
+		<data name="outputFile" format="png" label="[plot] Output file"/>
+	</outputs>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/plotCoverage.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,265 @@
+<tool id="plotCoverage" name="plot coverage">
+	<description>Plot the coverage of the first data with respect to the second one.</description>
+	<command interpreter="python">
+		../Java/Python/WrappPlotCoverage.py -i $formatType.inputFileName1
+		#if $formatType.FormatInputFileName1 == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName1 == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName1 == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName1 == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName1 == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName1 == 'gtf':
+			-f gtf
+		#end if
+			
+		-j $formatType2.inputFileName2
+		#if $formatType2.FormatInputFileName2 == 'bed':
+			-g bed
+		#elif $formatType2.FormatInputFileName2 == 'gff':
+			-g gff	
+		#elif $formatType2.FormatInputFileName2 == 'gff2':
+			-g gff2
+		#elif $formatType2.FormatInputFileName2 == 'gff3':
+			-g gff3
+		#elif $formatType2.FormatInputFileName2 == 'sam':
+			-g sam
+		#elif $formatType2.FormatInputFileName2 == 'gtf':
+			-g gtf
+		#end if
+
+
+		#if $optionRef.Ref == 'Yes':
+			-q $optionRef.inputSequenceFile
+		#end if
+
+		#if $optionwidth.width == 'Yes':
+			-w $optionwidth.widthVal
+		#end if
+		#if $optionheight.height == 'Yes':
+			-e $optionheight.heightVal
+		#end if
+		#if $optionXlab.Xlab == 'Yes':
+			-x $optionXlab.XlabVal
+		#end if
+		#if $optionYlab.Ylab == 'Yes':
+			-y $optionYlab.YlabVal
+		#end if
+		#if $optiontitle.title == 'Yes':
+			-t $optiontitle.titleVal
+		#end if	
+	
+		#if $optionplusColor.plusColor == 'Yes':
+			-p $optionplusColor.plusColorVal
+		#end if
+		#if $optionminusColor.minusColor == 'Yes':
+			-m $optionminusColor.minusColorVal
+		#end if
+
+		#if $optionsumColor.sumColor == 'Yes':
+			-s $optionsumColor.sumColorVal
+		#end if
+		#if $optionlineColor.lineColor == 'Yes':
+			-l $optionlineColor.lineColorVal
+		#end if	
+
+		$merge
+		-o $outputFile
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName1" type="select" label="Input File Format 1">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName1" format="bed" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName1" format="gff" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName1" format="gff2" type="data" label="Input File 1"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName1" format="gff3" type="data" label="Input File 1"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName1" format="sam" type="data" label="Input File 1"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName1" format="gtf" type="data" label="Input File 1"/>
+			</when>
+		</conditional>
+
+		<conditional name="formatType2">
+			<param name="FormatInputFileName2" type="select" label="Input File Format 2">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="gff2">sam</option>
+				<option value="gff3">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName2" format="bed" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName2" format="gff" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName2" format="gff2" type="data" label="Input File 2"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName2" format="gff3" type="data" label="Input File 2"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName2" format="sam" type="data" label="Input File 2"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName2" format="gtf" type="data" label="Input File 2"/>
+			</when>
+		</conditional>
+
+		<conditional name="optionRef">
+			<param name="Ref" type="select" label="reference sequence file">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="inputSequenceFile" format="fasta" type="data" value="None"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		
+
+
+		<conditional name="optionwidth">
+			<param name="width" type="select" label="width of the plots (in px)">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="widthVal" type="integer" value="1500"  />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<conditional name="optionheight">
+			<param name="height" type="select" label="height of the plots (in px)">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="heightVal" type="integer" value="1000" />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optiontitle">
+			<param name="title" type="select" label="title of the plots ">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="titleVal" type="text" value=" " />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<conditional name="optionXlab">
+			<param name="Xlab" type="select" label="label on the x-axis">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="XlabVal" type="text" value=" "/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionYlab">
+			<param name="Ylab" type="select" label="label on the y-axis">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="YlabVal" type="text" value=" " />
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionplusColor">
+			<param name="plusColor" type="select" label="color for the elements on the plus strand">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="plusColorVal" type="text" value="red"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionminusColor">
+			<param name="minusColor" type="select" label="color for the elements on the minus strand">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="minusColorVal" type="text" value="blue"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionsumColor">
+			<param name="sumColor" type="select" label="color for 2 strands coverage line">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="sumColorVal" type="text" value="black"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<conditional name="optionlineColor">
+			<param name="lineColor" type="select" label="color for the lines">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="lineColorVal" type="text" value="black"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<param name="merge" type="boolean" truevalue="-1" falsevalue="" checked="false" label="merge the 2 plots in 1"/>
+	</inputs>
+
+	<outputs>
+		<data name="outputFile" format="tar" label="[plotCoverage] tar out file" help="You can not see the results directly from galaxy, but you can download this tar output file."/>
+	</outputs> 
+	
+    <help>
+        This script gives a .tar out file, if you want to take look at the results, you have to download it.
+    </help>		
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/plotGenomeCoverage.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,62 @@
+<tool id="plotGenomeCoverage" name="plot genome coverage">
+  <description>Get the coverage of a genome. </description>
+  <command interpreter="python"> ../Java/Python/plotGenomeCoverage.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName == 'gtf':
+			-f gtf
+		#end if
+		
+ 		-r $reference
+  		-o $outputFile  
+  </command>
+  
+  
+  <inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName" format="gtf" type="data" label="Input File"/>
+			</when>
+		</conditional>
+		
+		<param name="reference" type="data" label="reference Fasta File" format="fasta"/> 
+  </inputs>
+
+  <outputs>
+    <data format="png" name="outputFile" label="[plotGenomeCoverage] Output File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/plotRepartition.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,59 @@
+<tool id="plotRepartition" name="plot repartition">
+	<description>Plot the repartition of different data on a whole genome. (This tool uses only 1 input file, the different values are stored in the tags. )</description>
+	<command interpreter="python">
+		../Java/Python/WrappPlotRepartition.py -i $inputFileName
+		-n $names
+		$normalize
+		#if $optionColor.Color == 'Yes':
+			-c $optionColor.colValue
+		#end if		
+		-f $format
+		
+		#if $optionLog.log == 'Yes':
+			-l $optionLog.logVal
+		#end if	
+		
+		-o $outputFilePNG
+	</command>
+
+	<inputs>
+		<param name="inputFileName" type="data" label="Input Gff3 File" format="gff3"/>
+		<param name="names" type="text" value="None" label="name for the tags (separated by commas and no space) [compulsory option]"/>
+		<param name="normalize" type="boolean" truevalue="-r" falsevalue="" checked="false" label="normalize data (when panels are different)"/>
+		<param name="format" type="text" value="png" label="format of the output file[default: png]"/>
+		
+		<conditional name="optionColor">
+			<param name="Color" type="select" label="scolor of the lines (separated by commas and no space) ">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="colValue" type="text" value="None"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<conditional name="optionLog">
+			<param name="log" type="select" label="use log on x- or y-axis (write 'x', 'y' or 'xy')">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="logVal" type="text" value=" "/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>	
+		
+	</inputs>
+
+	<outputs>
+		<data name="outputFilePNG" format="tar" label="[plotRepartition]out file"/>
+	</outputs> 
+	
+	<help>
+        This script gives a .tar out file, if you want to take look at the results, you have to download it.
+    </help>	
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/plotTranscriptList.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,141 @@
+<tool id="plotTranscriptList" name="plot transcript list">
+	<description>Plot some information from a list of transcripts. </description>
+	<command interpreter="python">
+		../Java/Python/plotTranscriptList.py  -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName == 'gtf':
+			-f gtf
+		#end if
+		
+		-x $xVal
+		-y $yVal
+		#if $optionz.z == 'Yes':
+			-z $optionz.zVal
+		#end if		
+			
+		-X $XVal
+		-Y $YVal
+		-Z $ZVal
+			
+		#if $optionxLab.xLab == 'Yes':
+			-n $optionxLab.labVal
+		#end if
+		#if $optionyLab.yLab == 'Yes':
+			-m $optionyLab.labVal
+		#end if	
+
+		#if $optionyLog.log == 'Yes':
+			-l $optionyLog.logVal
+		#end if	
+					
+		-s $shape
+		-b $bucket
+		
+		-o $outputFilePNG
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName" format="gtf" type="data" label="Input File"/>
+			</when>
+		</conditional>
+		
+		<param name="xVal" type="text" value="None" label="tag for the x value [compulsory option]"/>
+		<param name="yVal" type="text" value="None" label="tag for the y value [compulsory option]"/>
+			
+		<conditional name="optionz">
+			<param name="z" type="select" label="tag for the z value ">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="zVal" type="text" value="None"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+
+		<param name="XVal" type="float" value="0.0" label="value for x when tag is not present "/>
+		
+		<param name="YVal" type="float" value="0.0" label="value for y when tag is not present"/>
+
+		<param name="ZVal" type="float" value="0.0" label="value for z when tag is not present"/>
+			
+		<conditional name="optionxLab">
+			<param name="xLab" type="select" label="label on the x-axis ">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="labVal" type="text" value=" "/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		<conditional name="optionyLab">
+			<param name="yLab" type="select" label="label on the y-axis ">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="labVal" type="text" value=" "/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>	
+
+		<conditional name="optionyLog">
+			<param name="log" type="select" label="use log on x- or y-axis (write 'x', 'y' or 'xy')">
+					<option value="Yes">Yes</option>
+					<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="logVal" type="text" value=" "/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>	
+		
+		<param name="shape" type="text" value="barplot" label="shape of the plot [format: choice (barplot, line, points, heatPoints)]"/>
+		<param name="bucket" type="float" value="1.0" label="bucket size (for the line plot)"/>
+		
+	</inputs>
+
+	<outputs>
+		<data name="outputFilePNG" format="png" label="[plotTranscriptList]out file"/>
+	</outputs> 
+	
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/qualToFastq.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="qualToFastq" name="qual -> Fastq">
+  <description>Convert a file in FASTA/Qual format to FastQ format.</description>
+  <command interpreter="python"> ../Java/Python/qualToFastq.py -f $inputFastaFile -q $inputQualFile -o $outputFile </command>
+  <inputs>
+    <param name="inputFastaFile" type="data" label="Input fasta File" format="fasta"/>
+    <param name="inputQualFile" type="data" label="Input qual File" format="txt"/>
+  </inputs>
+
+  <outputs>
+    <data format="fastq" name="outputFile" label="[qual -> Fastq] Output File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/removeExonLines.sh	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,2 @@
+#!/bin/bash
+sed '/exon/d' $1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/removeExonLines.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,15 @@
+<tool id="removeExonLines" name="remove exon lines">
+  <description>Removes the lines containing Exon.</description>
+  <command interpreter="sh"> ../Java/Python/removeExonLines.sh $inputFile > $outputFile  </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="gff3"/>
+  </inputs>
+
+  <outputs>
+    <data format="gff3" name="outputFile" label="[removeExonLine] Output File"/>
+  </outputs>
+
+  <help>
+	command example: sh removeExonLines.sh input.gff3
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/restrictFromSize.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,93 @@
+<tool id="restrictFromSize" name="restrict from size">
+	<description>Select the elements of a list of sequences or transcripts with a given size.</description>
+	<command interpreter="python">
+		../Java/Python/restrictFromSize.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName == 'gtf':
+			-f gtf
+		#end if
+
+		#if $OptionMax.maximum == "Yes":
+			-M $OptionMax.max
+		#end if		
+		#if $OptionMin.minimum == "Yes":
+			-m $OptionMin.min
+		#end if	
+				
+		-o $outputFileGff 
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName" format="gtf" type="data" label="Input File"/>
+			</when>
+		</conditional>
+		
+		<conditional name="OptionMax">
+			<param name="maximum" type="select" label="maximum number of np">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="max" type="integer" value="1" help="Be Careful! The value must be upper than 0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>
+		
+		<conditional name="OptionMin">
+			<param name="minimum" type="select" label="minimum number of np">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="min" type="integer" value="1" help="Be Careful! The value must be upper than 0"/>
+			</when>
+			<when value="No">
+			</when>
+		</conditional>	
+		
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3" label="[restrictFromSize] Output File"/>
+	</outputs> 
+	
+	<help>
+		command example: restrictFromSize.py -i cis_e10_cluster20InSeed2515_nbEUp10.gff3 -f gff -o cis_e10_cluster20InSeed2515_nbEUp10_lgUp50 -m 50
+	</help>
+
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/restrictSequenceList.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,16 @@
+<tool id="restrictSequenceList" name="restrict sequence list">
+  <description>Keep the elements of a list of sequences whose name is mentionned in a given file.</description>
+  <command interpreter="python"> ../Java/Python/restrictSequenceList.py -i $inputFile -f fasta -n $name -o $outputFile </command>
+  
+  <inputs>
+	<param name="inputFile" type="data" label="Input fasta File" format="fasta"/>
+	<param name="name" type="data" label="The txt file contains the names of the transcripts." format="txt"/> 
+  </inputs>
+
+  <outputs>
+    <data format="fasta" name="outputFile" label="[restrictSequenceList] Output File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/restrictTranscriptList.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,108 @@
+<tool id="restrictTranscriptList" name="restrict transcript list">
+  <description>Keep the coordinates which are located in a given position.</description>
+  <command interpreter="python"> ../Java/Python/restrictTranscriptList.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#elif $formatType.FormatInputFileName == 'sam':
+			-f sam
+		#elif $formatType.FormatInputFileName == 'gtf':
+			-f gtf
+		#end if
+		
+  		#if $OptionChrom.Chrom == "Yes":
+			-c $OptionChrom.ChromName
+  		#end if
+  				
+  		#if $OptionStart.start == "Yes":
+			-s $OptionStart.startValue
+  		#end if
+  	
+  		#if $OptionEnd.end == "Yes":
+			-e $OptionEnd.endValue
+  		#end if
+  		
+  	-o $outputFile  
+  
+  </command>
+  
+  
+  <inputs>
+    <conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+				<option value="sam">sam</option>
+				<option value="gtf">gtf</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+			<when value="sam">
+				<param name="inputFileName" format="sam" type="data" label="Input File"/>
+			</when>
+			<when value="gtf">
+				<param name="inputFileName" format="gtf" type="data" label="Input File"/>
+			</when>
+	</conditional>
+	
+	<conditional name="OptionChrom">
+			<param name="Chrom" type="select" label="chromosome name">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="ChromName" type="text" value="None"/>
+			</when>
+			<when value="No">
+			</when>
+	</conditional>	
+  
+	<conditional name="OptionStart">
+			<param name="start" type="select" label="restrict to the start of the transcript">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="startValue" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+	</conditional>
+		
+	<conditional name="OptionEnd">
+			<param name="end" type="select" label="restrict to the end of the transcript">
+				<option value="Yes">Yes</option>
+				<option value="No" selected="true">No</option>
+			</param>
+			<when value="Yes">
+				<param name="endValue" type="integer" value="0"/>
+			</when>
+			<when value="No">
+			</when>
+	</conditional>    
+  </inputs>
+
+  <outputs>
+    <data format="gff3" name="outputFile" label="[restrictTranscriptList] Output File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/test/CollapseReads.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,49 @@
+<tool id="collapseReads" name="collapseReads">
+	<description>Merges two reads if they have exactly the same genomic coordinates.</description>
+	<command interpreter="python">
+		../Java/Python/CollapseReads.py -i $formatType.inputFileName
+		#if $formatType.FormatInputFileName == 'bed':
+			-f bed
+		#elif $formatType.FormatInputFileName == 'gff':
+			-f gff	
+		#elif $formatType.FormatInputFileName == 'gff2':
+			-f gff2
+		#elif $formatType.FormatInputFileName == 'gff3':
+			-f gff3
+		#end if
+
+		-$strand
+		-o $outputFileGff 
+		--galaxy
+	</command>
+
+	<inputs>
+		<conditional name="formatType">
+			<param name="FormatInputFileName" type="select" label="Input File Format">
+				<option value="bed">bed</option>
+				<option value="gff">gff</option>
+				<option value="gff2">gff2</option>
+				<option value="gff3">gff3</option>
+			</param>
+			<when value="bed">
+				<param name="inputFileName" format="bed" type="data" label="Input File"/>
+			</when>
+			<when value="gff">
+				<param name="inputFileName" format="gff" type="data" label="Input File"/>
+			</when>
+			<when value="gff2">
+				<param name="inputFileName" format="gff2" type="data" label="Input File"/>
+			</when>
+			<when value="gff3">
+				<param name="inputFileName" format="gff3" type="data" label="Input File"/>
+			</when>
+		</conditional>
+
+		<param name="strand" type="boolean" truevalue="-s" falsevalue="" checked="false" label="Strand option merges 2 different strands[default:False]."/>
+	</inputs>
+
+	<outputs>
+		<data name="outputFileGff" format="gff3"/>
+	</outputs> 
+	
+</tool>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/test/Test_F_WrappGetLetterDistribution.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,91 @@
+import unittest
+import os
+from commons.core.utils.FileUtils import FileUtils
+from SMART.galaxy.WrappGetLetterDistribution import WrappGetLetterDistribution
+
+SMART_PATH = "%s/SMART" % os.environ["REPET_PATH"]
+SMART_DATA = SMART_PATH + "/data"
+
+class Test_F_WrappGetLetterDistribution(unittest.TestCase):
+
+
+    def setUp(self):
+        self._dirTest = "%s/galaxy/test" % SMART_PATH
+        self._iwrappFastq = WrappGetLetterDistribution()
+        self._iwrappFasta = WrappGetLetterDistribution()
+        self._expOutputCSV = "expOutputTomate.csv" 
+       
+    def test_wrappFasta(self):
+        self._iwrappFasta._inputFileName = "%s/SR1.fasta" % SMART_DATA
+        self._iwrappFasta._outputFileNamePrefix = "%s/galaxy/test/TomateFasta_res" % SMART_PATH
+        self._iwrappFasta._outputFileNamePNG = "%s/galaxy/test/TomateFasta_res.png" % SMART_PATH
+        self._iwrappFasta._outputFileNamePerNtPNG = "%s/galaxy/test/TomateFasta_resPerNt.png" % SMART_PATH
+        self._iwrappFasta._outputFileNameCSV = "%s/galaxy/test/TomateFasta_res.csv" % SMART_PATH
+        self._iwrappFasta._inputFileFormat = "fasta"
+        self._iwrappFasta._csv = True
+        if not(FileUtils.isEmpty(self._iwrappFasta._inputFileName)):
+            self._iwrappFasta.wrapp()
+            self.assertTrue(os.path.exists(self._iwrappFasta._outputFileNamePNG))
+            self.assertTrue (os.path.exists(self._iwrappFasta._outputFileNamePerNtPNG))    
+            self.assertTrue (os.path.exists(self._iwrappFasta._outputFileNameCSV))
+            self.assertTrue(FileUtils.are2FilesIdentical(self._iwrappFasta._outputFileNameCSV,self._expOutputCSV))
+        else:
+            print "Problem : the input fasta file %s is empty!" % self._inputFileFasta
+         
+            
+#    def test_wrappFasta_withoutCSV_Opt(self):
+#        self._iwrappFasta._inputFileName = "%s/SR1.fasta" % SMART_DATA
+#        self._iwrappFasta._outputFileNamePrefix = "%s/galaxy/test/TomateFasta_res" % SMART_PATH
+#        self._iwrappFasta._outputFileNamePNG = "%s/galaxy/test/TomateFasta_res.png" % SMART_PATH
+#        self._iwrappFasta._outputFileNamePerNtPNG = "%s/galaxy/test/TomateFasta_resPerNt.png" % SMART_PATH
+#        self._iwrappFasta._outputFileNameCSV = "%s/galaxy/test/TomateFasta_res.csv" % SMART_PATH
+#        self._iwrappFasta._inputFileFormat = "fasta"
+#        self._iwrappFasta._csv = False
+#        if not(FileUtils.isEmpty(self._iwrappFasta._inputFileName)):
+#            self._iwrappFasta.wrapp()
+#            self.assertTrue(os.path.exists(self._iwrappFasta._outputFileNamePNG))
+#            self.assertTrue (os.path.exists(self._iwrappFasta._outputFileNamePerNtPNG)) 
+#        else:            
+#            print "Problem : the input fasta file %s is empty!" % self._inputFileFasta
+#        os.system("rm %s/galaxy/test/*_res*.png" %SMART_PATH)
+#        os.system("rm %s/galaxy/test/*_res.csv" %SMART_PATH) 
+#        
+#                
+#    def test_wrappFastq(self):
+#        self._iwrappFastq._inputFileName = "%s/SR1.fastq" % SMART_DATA
+#        self._iwrappFastq._outputFileNamePrefix = "%s/galaxy/test/TomateFastq_res" % SMART_PATH
+#        self._iwrappFastq._outputFileNamePNG = "%s/galaxy/test/TomateFastq_res.png" % SMART_PATH
+#        self._iwrappFastq._outputFileNamePerNtPNG = "%s/galaxy/test/TomateFastq_resPerNt.png" % SMART_PATH
+#        self._iwrappFastq._outputFileNameCSV = "%s/galaxy/test/TomateFastq_res.csv" % SMART_PATH
+#        self._iwrappFastq._inputFileFormat = "fastq"
+#        self._iwrappFastq._csv = True
+#        if not(FileUtils.isEmpty(self._iwrappFastq._inputFileName)):
+#            self._iwrappFastq.wrapp()
+#            self.assertTrue(os.path.exists(self._iwrappFastq._outputFileNamePNG))
+#            self.assertTrue (os.path.exists(self._iwrappFastq._outputFileNamePerNtPNG))    
+#            self.assertTrue (os.path.exists(self._iwrappFastq._outputFileNameCSV))
+#            self.assertTrue(FileUtils.are2FilesIdentical(self._iwrappFastq._outputFileNameCSV,self._expOutputCSV))
+#        else:
+#            print "Problem : the input fastq file %s is empty!" % self._inputFileFastq   
+#          
+#        
+#    def test_wrappFastq_withoutCSV_Opt(self):
+#        self._iwrappFastq._inputFileName = "%s/SR1.fastq" % SMART_DATA
+#        self._iwrappFastq._outputFileNamePrefix = "%s/galaxy/test/TomateFastq_res" % SMART_PATH
+#        self._iwrappFastq._outputFileNamePNG = "%s/galaxy/test/TomateFastq_res.png" % SMART_PATH
+#        self._iwrappFastq._outputFileNamePerNtPNG = "%s/galaxy/test/TomateFastq_resPerNt.png" % SMART_PATH
+#        self._iwrappFastq._outputFileNameCSV = "%s/galaxy/test/TomateFastq_res.csv" % SMART_PATH
+#        self._iwrappFastq._inputFileFormat = "fastq"
+#        self._iwrappFastq._csv = False
+#        if not(FileUtils.isEmpty(self._iwrappFastq._inputFileName)):
+#            self._iwrappFastq.wrapp()
+#            self.assertTrue(os.path.exists(self._iwrappFastq._outputFileNamePNG))
+#            self.assertTrue (os.path.exists(self._iwrappFastq._outputFileNamePerNtPNG)) 
+#        else:            
+#            print "Problem : the input fastq file %s is empty!" % self._inputFileFastq
+#        os.system("rm %s/galaxy/test/*_res*.png" %SMART_PATH)
+#        os.system("rm %s/galaxy/test/*_res.csv" %SMART_PATH)
+       
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/testArgum.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,24 @@
+<tool id="test_argument" name="test_argu" version="1.0.0">
+  <description>To test the arguments from shell.</description>
+  <command> 
+../testArgu.sh $test_out 
+#for $i in $replicate_groups
+#for $j in $i.replicates
+$j.bam_alignment:#slurp
+#end for
+#end for
+    >> $Log_File </command>
+  <inputs>
+	<param format="gff3" name="anno_input_selected" type="data" label="Genome annotation in GFF3 file" help="A tab delimited format for storing sequence features and annotations"/>
+   <repeat name="replicate_groups" title="Replicate group" min="2">
+     <repeat name="replicates" title="Replicate">
+      <param format="fastq" name="bam_alignment" type="data" label="BAM alignment file" help="BAM alignment file. Can be generated from SAM files using the SAM Tools."/>
+     </repeat>
+   </repeat>
+  </inputs>
+
+  <outputs>
+    <data format="txt" name="test_out" label="DESeq result"/>
+	<data format="txt" name="Log_File" label="DESeq result"/>
+  </outputs>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/testR.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,19 @@
+<tool id="testDiffExpAnal" name="Differential Expression Analysis">
+  <description>Differential expression analysis for sequence count data (DESeq)</description>
+  <command interpreter="sh"> ../DiffExpAnal/testR.sh $inputFile $columnsOfGeneName $columnsOfCondition1 $columnsOfCondition2 $outputFileCSV $outputFilePNG 2>$outputLog </command>
+  <inputs>
+    <param name="inputFile" type="data" label="Input File" format="tabular"/>
+	<param name="columnsOfGeneName" type="text" value="0" label="Please indicate the column numbers of gene names with ',' separator. If There are not gene names, default value is 0."/>
+	<param name="columnsOfCondition1" type="text" value="1,2" label="Please indicate the column numbers of condition1 with ',' separator."/>
+	<param name="columnsOfCondition2" type="text" value="3,4" label="Please indicate the column numbers of condition2 with ',' separator."/>
+  </inputs>
+
+  <outputs>
+    <data format="tabular" name="outputFileCSV" label="[DiffExpAnal] Output CSV File"/>
+	<data format="png" name="outputFilePNG" label="[DiffExpAnal] Output PNG File"/>
+    <data format="tabular" name="outputLog" label="[DiffExpAnal] Log File"/>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/trimAdaptor.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,39 @@
+<tool id="trimAdaptor" name="trim adaptors">
+  <description>Remove the 3' adaptor of a list of reads.</description>
+  <command interpreter="python"> ../Java/Python/trimAdaptor.py -i $inputFile -f fastq
+  	-a $adaptor
+  	#if $OptionError.Error == "Yes":
+		-e $OptionError.ErrorVal
+	#end if	
+  	$noAdaptor $noAdaptorFile
+  	-o $outputFile  
+  </command>
+  
+  
+  <inputs>
+    <param name="inputFile" type="data" label="Input fastq File" format="fastq"/>
+	<param name="adaptor" type="text" value="None" label="adaptor [compulsory option]"/> 
+	<conditional name="OptionError">
+		<param name="Error" type="select" label="number of errors in percent">
+			<option value="Yes">Yes</option>
+			<option value="No" selected="true">No</option>
+		</param>
+		<when value="Yes">
+			<param name="ErrorVal" type="integer" value="0" />
+		</when>
+		<when value="No">
+		</when>
+	</conditional>	
+	<param name="noAdaptor" type="boolean" truevalue="-n" falsevalue="" checked="false" label="log option" help="file name where to print sequences with no adaptor"/>
+  </inputs>
+
+  <outputs>
+    <data format="fastq" name="outputFile" label="[trimAdaptor] Output File"/>
+	<data name="noAdaptorFile" format="fastq" label="[trimAdaptor] Log File">
+		<filter>noAdaptor</filter>
+	</data>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/SMART/galaxy/trimSequences.xml	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,81 @@
+<tool id="trimSequences" name="trim sequences">
+  <description>Remove the 5' and/or 3' adaptors of a list of reads.</description>
+  <command interpreter="python"> ../Java/Python/trimSequences.py -i $inputFile -f fastq
+  	#if $OptionFPADP.FPADP == "Yes":
+		-5 $OptionFPADP.fivePAdaptor
+	#end if	  
+	 #if $OptionTPADP.TPADP == "Yes":
+		-3 $OptionTPADP.threePAdaptor
+	#end if	
+  	#if $OptionError.Error == "Yes":
+		-e $OptionError.ErrorVal
+	#end if	
+
+	$indels
+  	$noAdaptor5p $noAdaptorFile5p
+  	$noAdaptor3p $noAdaptorFile3p
+  	-o $outputFile  
+  
+  </command>
+  
+  
+  <inputs>
+    <param name="inputFile" type="data" label="Input fastq File" format="fastq"/>
+	
+	<conditional name="OptionFPADP">
+		<param name="FPADP" type="select" label="5'adaptor">
+			<option value="Yes">Yes</option>
+			<option value="No" selected="true">No</option>
+		</param>
+		<when value="Yes">
+			<param name="fivePAdaptor" type="text" value="None" />
+		</when>
+		<when value="No">
+		</when>
+	</conditional>	
+	
+	<conditional name="OptionTPADP">
+		<param name="TPADP" type="select" label="3'adaptor">
+			<option value="Yes">Yes</option>
+			<option value="No" selected="true">No</option>
+		</param>
+		<when value="Yes">
+			<param name="threePAdaptor" type="text" value="None" />
+		</when>
+		<when value="No">
+		</when>
+	</conditional>
+	
+	<conditional name="OptionError">
+		<param name="Error" type="select" label="number of errors in percent">
+			<option value="Yes">Yes</option>
+			<option value="No" selected="true">No</option>
+		</param>
+		<when value="Yes">
+			<param name="ErrorVal" type="integer" value="0" />
+		</when>
+		<when value="No">
+		</when>
+	</conditional>	
+	
+	<param name="indels" type="boolean" truevalue="-d" falsevalue="" checked="false" label="indels option" help="also accept indels"/>
+	<param name="noAdaptor5p" type="boolean" truevalue="-n" falsevalue="" checked="false" label="noAdaptor 5' option" help="file name where to print sequences with no 5' adaptor "/>
+	<param name="noAdaptor3p" type="boolean" truevalue="-m" falsevalue="" checked="false" label="noAdaptor 3' option" help="file name where to print sequences with no 3' adaptor "/>
+	
+	
+	
+  </inputs>
+
+  <outputs>
+    <data format="fastq" name="outputFile" label="[trimSequences] Output File"/>
+	<data name="noAdaptorFile5p" format="fastq" label="[trimSequences] noAdaptor5p File">
+		<filter>noAdaptor5p</filter>
+	</data>
+	<data name="noAdaptorFile3p" format="fastq" label="[trimSequences] noAdaptor3p File">
+		<filter>noAdaptor3p</filter>
+	</data>
+  </outputs>
+
+  <help>
+  </help>
+</tool>
Binary file smart_toolShed/commons/__init__.pyc has changed
Binary file smart_toolShed/commons/core/__init__.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/AbstractChecker.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,61 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.checker.IChecker import IChecker
+from commons.core.LoggerFactory import LoggerFactory
+
+
+## Enable a Logger in your Checker.
+#
+#  Subclasses of  AbstractChecker have a already a logger enabled (referenced by self._log attribute). Subclasses also already implements IChecker.
+#  All you have to do is to call __init__() method in your own constructor.
+class AbstractChecker( IChecker ):
+    
+    ## Constructor 
+    #
+    # @param logFileName name of log file where logger outputs
+    #
+    def __init__(self, logFileName):
+        self._log = LoggerFactory.createLogger(logFileName)
+        
+        
+    ## Set (change) default logger
+    #
+    # @param logger a new logger
+    # 
+    def setLogger(self, logger):
+        self._log = logger
+        
+        
+    ## Return the logger instance
+    #
+    def getLogger(self):
+        return self._log
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/CheckerException.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,52 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+## Exception raised during check 
+#
+# This class wraps Exception class
+#
+class CheckerException( Exception ):
+    
+    ## Constructor
+    #
+    # @param msg  message embedded in Exception class   
+    def __init__(self,msg=""):
+        self.messages = []
+        self.msg = msg
+        Exception.__init__(self, msg)
+        
+        
+    def setMessages(self,lMessages):
+        self.messages = lMessages
+        
+        
+    def getMessages(self):
+        return self.messages
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/CheckerUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,316 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import os
+import sys
+import re
+import glob
+import ConfigParser
+from ConfigParser import NoOptionError
+from ConfigParser import NoSectionError
+from commons.core.checker.CheckerException import CheckerException
+
+
+## A set of static methods used to perform checks.
+#
+#
+class CheckerUtils( object ):
+    
+    ## Check if blastName param is in ["blastn", "blastp", "blastx", "tblastn", "tblastx"]
+    # 
+    # @param blastName name to check
+    # @return True if name is in list False otherwise
+    #
+    def isBlastNameNotInBlastValues( blastName ):
+        blastValuesSet = set( ["blastn", "blastp", "blastx", "tblastn", "tblastx"] )
+        blastNameSet = set( [ blastName ] )
+        return not blastNameSet.issubset( blastValuesSet )
+    
+    isBlastNameNotInBlastValues = staticmethod( isBlastNameNotInBlastValues )
+    
+    
+    ## Check if param is NOT "TRUE" and NOT false "FALSE"
+    #
+    # @param param str to check
+    # @return True if param is not eq to "TRUE" AND not eq to "FALSE", false otherwise 
+    #
+    def isNotTRUEisNotFALSE( param ):
+        return param != "TRUE" and param != "FALSE"
+    
+    isNotTRUEisNotFALSE = staticmethod( isNotTRUEisNotFALSE )
+    
+    
+    ## Check if resource (file or dir) do NOT exists
+    #  
+    # @param resource file or dir to check
+    # @return True if resource exists False otherwise
+    #
+    def isRessourceNotExits( resource ):
+        return not os.path.exists( resource )
+    
+    isRessourceNotExits = staticmethod( isRessourceNotExits )
+    
+    
+    ## Check a specific E-value format: de-dd 
+    #
+    # @param param E-value to check
+    # @return True if format is de-dd False otherwise
+    #
+    def isNotAeValueWithOneDigit2DecimalsAtLeast( param ):
+        # \d\d stands for 2 digits and more ???
+        return not re.match( "\de\-\d\d", param )
+    
+    isNotAeValueWithOneDigit2DecimalsAtLeast = staticmethod( isNotAeValueWithOneDigit2DecimalsAtLeast )
+    
+    
+    ## Check a number format
+    #
+    # @param param value to check
+    # @return True if param is a number (d+) False otherwise
+    #
+    def isNotANumber( param ):
+        return not re.match( "\d+", param )
+    
+    isNotANumber = staticmethod( isNotANumber )
+    
+
+    ## Check if an executable is in the user's PATH
+    #
+    # @param exeName name of the executable
+    # @return True if executable in user's PATH, False otherwise
+    #
+    def isExecutableInUserPath( exeName ):
+        dirPathList = os.environ["PATH"].split(":")
+        for dirPath in dirPathList:
+            if os.path.isdir( dirPath ):
+                try:
+                    binPathList = glob.glob( dirPath + "/*" )
+                except OSError, e:
+                    continue
+                for binPath in binPathList:
+                    bin = os.path.basename( binPath )
+                    if bin == exeName:
+                        return True
+        return False
+    
+    isExecutableInUserPath = staticmethod( isExecutableInUserPath )
+    
+    
+    ## Return the full path of a given executable
+    #
+    def getFullPathFromExecutable( exeName ):
+        lDirFromUserPath = os.environ["PATH"].split(":")
+        for dir in lDirFromUserPath:
+            if os.path.isdir( dir ):
+                try:
+                    lExecutables = glob.glob( "%s/*" % ( dir ) )
+                except OSError, e:
+                    continue
+                for exe in lExecutables:
+                    path, exe = os.path.split( exe )
+                    if exe == exeName:
+                        return path
+        return ""
+    
+    getFullPathFromExecutable = staticmethod( getFullPathFromExecutable )
+    
+    
+    #TODO: to remove ?
+    ## Check if a queue Name is valid. Warning: Only with the queue manager SGE
+    #
+    # @param fullQueueName name of the queue to test (with or without parameters)
+    # @return True if queue name is valid, False otherwise
+    #
+    def isQueueNameValid( fullQueueName ):
+        queueName = fullQueueName.split()[0]
+        if queueName == "none":
+            return True
+        queueFile = "queueName.txt"
+        if not CheckerUtils.isExecutableInUserPath( "qconf" ):
+            msg = "executable 'qconf' can't be found"
+            sys.stderr.write( "%s\n" % ( msg ) )
+            return False
+        cmd = "qconf -sql > " + queueFile
+        os.system( cmd )
+        queueFileHandler = open( queueFile, "r" )
+        lQueueNames = queueFileHandler.readlines()
+        queueFileHandler.close()
+        os.remove( queueFile )
+        queueNameValid = False
+        for qName in lQueueNames:
+            qName = qName.strip()
+            if qName == queueName:
+                queueNameValid = True
+                break
+        return queueNameValid
+    
+    isQueueNameValid = staticmethod( isQueueNameValid )
+    
+    
+    ## Check if a string length is lower or equal than 15
+    #
+    # @param strName any string
+    # @return True if string length is <= 15, False otherwise
+    #
+    def isMax15Char( strName ):
+        return (len(strName) <= 15 )
+    
+    isMax15Char = staticmethod( isMax15Char )
+    
+    
+    ## Check if a string is made with only alphanumeric or underscore character
+    #
+    # @param strName any string
+    # @return True if string is with alphanumeric or underscore, False otherwise
+    #
+    def isCharAlphanumOrUnderscore( strName ):
+        # authorized ALPHABET [a-z,A-Z,0-9,_]
+        p = re.compile('\W')
+        errList=p.findall(strName)
+        if len( errList ) > 0 :
+            return False
+        else:
+            return True
+        
+    isCharAlphanumOrUnderscore = staticmethod( isCharAlphanumOrUnderscore )
+    
+    
+    ## Check if sectionName is in the configuration file
+    #
+    # @param config filehandle of configuration file
+    # @param sectionName string of section name to check
+    # @exception NoSectionError: if section not found raise a NoSectionError 
+    # 
+    def checkSectionInConfigFile( config, sectionName ):
+        if not (config.has_section(sectionName)):
+            raise NoSectionError(sectionName)
+        
+    checkSectionInConfigFile = staticmethod( checkSectionInConfigFile )
+    
+    
+    ## Check if an option is in a specified section in the configuration file
+    #
+    # @param config filehandle of configuration file
+    # @param sectionName string of section name
+    # @param optionName string of option name to check
+    # @exception NoOptionError: if option not found raise a NoOptionError
+    #
+    def checkOptionInSectionInConfigFile( config, sectionName, optionName ):
+        config.get( sectionName, optionName )
+    
+    checkOptionInSectionInConfigFile = staticmethod( checkOptionInSectionInConfigFile )
+    
+    
+    ## Check version number coherency between configFile and CHANGELOG
+    #
+    # @param config ConfigParser Instance of configuration file
+    # @param changeLogFileHandle CHANGELOG file handle
+    # @exception NoOptionError: if option not found raise a NoOptionError
+    #
+    def checkConfigVersion( changeLogFileHandle, config ):
+        line = changeLogFileHandle.readline()
+        while not line.startswith("REPET release "):
+            line = changeLogFileHandle.readline()
+        numVersionChangeLog = line.split()[2]
+        
+        numVersionConfig = config.get("repet_env", "repet_version")
+        
+        if not numVersionChangeLog == numVersionConfig:
+            message = "*** Error: wrong config file version. Expected version num is " + numVersionChangeLog + " but actual in config file is " + numVersionConfig
+            raise CheckerException(message)
+    
+    checkConfigVersion = staticmethod( checkConfigVersion )
+    
+    
+    ## Get version number from CHANGELOG
+    #
+    # @param changeLogFile CHANGELOG file name
+    #
+    def getVersionFromChangelogFile(changeLogFileName):
+        with open(changeLogFileName) as changeLogFileHandle:
+            line = changeLogFileHandle.readline()
+            while not line.startswith("REPET release "):
+                line = changeLogFileHandle.readline()
+            numVersionChangeLog = line.split()[2]
+            return numVersionChangeLog
+        
+            
+    getVersionFromChangelogFile = staticmethod( getVersionFromChangelogFile )
+    
+    
+    ## Check if headers of an input file contain only alpha numeric characters and "_ : . -"
+    #
+    # @param fileHandler file handle
+    # @exception CheckerException if bad header raise a CheckerException
+    #
+    def checkHeaders( fileHandler ):
+        lHeaders = CheckerUtils._getHeaderFromFastaFile(fileHandler)
+        p = re.compile('[^a-zA-Z0-9_:\.\-]', re.IGNORECASE)
+        lWrongHeaders = []
+        for header in lHeaders:
+            errList=p.findall(header)
+            if len( errList ) > 0 :
+                lWrongHeaders.append(header)
+        if lWrongHeaders != []:
+            exception = CheckerException()
+            exception.setMessages(lWrongHeaders)
+            raise exception
+        
+    checkHeaders = staticmethod( checkHeaders )  
+    
+    
+    def _getHeaderFromFastaFile( inFile ):
+        lHeaders = []
+        while True:
+            line = inFile.readline()
+            if line == "":
+                break
+            if line[0] == ">":
+                lHeaders.append( line[1:-1] )
+        return lHeaders
+    
+    _getHeaderFromFastaFile = staticmethod( _getHeaderFromFastaFile ) 
+
+
+    ## Return True if an option is in a specified section in the configuration file, False otherwise
+    #
+    # @param config handler of configuration file
+    # @param sectionName string of section name
+    # @param optionName string of option name to check
+    #
+    def isOptionInSectionInConfig( configHandler, section, option ):
+        try:
+            CheckerUtils.checkOptionInSectionInConfigFile( configHandler, section, option ) 
+        except NoOptionError:
+            return False
+        return True
+    
+    isOptionInSectionInConfig = staticmethod( isOptionInSectionInConfig )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/ConfigChecker.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,226 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import re
+import sys
+from commons.core.utils.RepetConfigParser import RepetConfigParser
+from commons.core.checker.ConfigValue import ConfigValue
+from commons.core.checker.IChecker import IChecker
+from commons.core.checker.RepetException import RepetException
+from commons.core.utils.FileUtils import FileUtils
+
+
+class Rule(object):
+    
+    def __init__(self, mandatory= False, isPattern=False, type="", set=(), help =""):
+        self.mandatory = mandatory
+        self.isPattern = isPattern
+        self.type = type
+        self.set = set
+        self.help = help
+        
+class ConfigRules(object):
+    
+    def __init__(self, configName = "", configDescription = ""):
+        self.configName = configName
+        self.configDescription = configDescription
+        self.dRules4Sections={}
+        
+    def _addRule(self, section, option="DEFAULT", mandatory=False, isPattern=False, type="", set=(), help =""):
+        if not self.dRules4Sections.has_key(section):
+            self.dRules4Sections[section] = {}
+        self.dRules4Sections[section][option]=Rule(mandatory, isPattern, type.lower(), set) 
+        
+    def addRuleSection(self, section, mandatory=False, isPattern=False, help = ""):
+        self._addRule(section = section, option = "DEFAULT", mandatory = mandatory, isPattern =  isPattern, help = "")
+   
+    def addRuleOption(self, section, option, mandatory=False, isPattern=False, type="", set=(), help = ""):
+        self._addRule(section = section, option = option, mandatory = mandatory, isPattern =  isPattern, type = type, set=set , help = "")
+            
+    def isSectionMandatory(self, section):
+        if self.dRules4Sections.has_key(section):
+            if self.dRules4Sections[section].has_key("DEFAULT"):
+                return self.dRules4Sections[section]["DEFAULT"].mandatory
+        return False
+        
+    def isOptionMandatory(self, section, option):
+        if self.dRules4Sections.has_key(section):
+            if self.dRules4Sections[section].has_key(option):
+                return self.dRules4Sections[section][option].mandatory
+        return False
+    
+    def getRule(self, section, option):
+        if self.dRules4Sections.has_key(section):
+            if self.dRules4Sections[section].has_key(option):
+                return self.dRules4Sections[section][option]
+        return None
+    
+class ConfigChecker(IChecker):
+    
+    def __init__ (self, cfgFileName, iCfgRules):
+        self._configFileName = cfgFileName
+        self._iConfigRules = iCfgRules
+        self._iRawConfig = ConfigValue()
+        self._iExtendedConfigRules = ConfigRules()
+        
+    def readConfigFile(self):
+        iConfig = RepetConfigParser()
+        try:
+            iConfig.readfp(open(self._configFileName))
+            return iConfig
+# TODO USE OF CONFIG ERROR
+#            if DuplicateSectionError:
+#                raise Exception ("Duplicate section exist in config file %s" %(self._configFileName ))
+        except :
+            raise RepetException ("Unexpected error: %s" %  sys.exc_info()[0])
+        
+    def setRawConfig(self, iConfig ):
+        for sectionName in iConfig.sections(): 
+            for optionName in iConfig.options(sectionName):
+                optionValue = iConfig.get(sectionName, optionName)
+                self._iRawConfig.set(sectionName, optionName, optionValue)
+                
+    def getOptionValueAccordingRule(self, iConfig, sectionName, optionName):
+        optionRule = self._iExtendedConfigRules.getRule(sectionName, optionName)
+        if optionRule == None : 
+            return iConfig.get(sectionName, optionName)
+        
+        if optionRule.type == "int":
+            optionValue = iConfig.getint(sectionName, optionName)
+        elif optionRule.type == "float":
+            optionValue = iConfig.getfloat(sectionName, optionName)
+        elif optionRule.type == "bool" or optionRule.type == "boolean":
+            optionValue = iConfig.getboolean(sectionName, optionName)
+        else:
+            optionValue = iConfig.get(sectionName, optionName)
+        if optionRule.set!=() and not(optionValue in optionRule.set):  
+            #TODO : test and fix    
+            raise RepetException ("value must be in %s " % set.__repr__())
+        
+        return optionValue
+    
+    def setConfig(self, iConfig ):
+        config = ConfigValue()
+        valueErr = ""
+        for sectionName in iConfig.sections():
+            for optionName in iConfig.options(sectionName):
+                try:    
+                    optionValue = self.getOptionValueAccordingRule(iConfig, sectionName, optionName )
+                    config.set(sectionName, optionName, optionValue)
+                except RepetException, re :
+                    #TODO : test and fix    
+                    valueErr += "\n - [%s]: %s %s" % re.getMessage()
+        if valueErr == "":
+            self._iRawConfig = config
+        else:
+            raise RepetException ("Following errors occurs:%s\n" %valueErr)
+        
+    def checkIfExistsConfigFile (self):   
+        if not (FileUtils.isRessourceExists(self._configFileName)):
+            raise RepetException("CONFIG FILE not found - '%s'" % self._configFileName)
+    
+    def checkMandatorySections (self):
+        missingSection = ""
+        for sectionName in self._iExtendedConfigRules.dRules4Sections.keys():
+            if self._iExtendedConfigRules.isSectionMandatory(sectionName) and not self._iRawConfig.has_section(sectionName):
+                    missingSection += "\n - %s" %(sectionName)
+        if missingSection != "":
+            raise RepetException ("Error in configuration file %s, following sections are missing:%s\n" % (self._configFileName, missingSection))
+    
+    def checkMandatoryOptions (self):
+        missingOption = ""
+        for sectionName in self._iExtendedConfigRules.dRules4Sections.keys():
+            if self._iExtendedConfigRules.isSectionMandatory(sectionName) or self._iRawConfig.has_section(sectionName) :
+                dRules4OptionsOfThisSection = self._iExtendedConfigRules.dRules4Sections[sectionName]
+                for optionName in dRules4OptionsOfThisSection.keys():
+                    if optionName != "DEFAULT" and self._iExtendedConfigRules.isOptionMandatory(sectionName, optionName) and not self._iRawConfig.has_option(sectionName, optionName):
+                        missingOption += "\n - [%s]: %s" % (sectionName, optionName)
+        if missingOption != "":
+            raise RepetException ("Error in configuration file %s, following options are missing: %s\n" % (self._configFileName, missingOption))
+    
+    def getSectionNamesAccordingPatternRules (self, sectionWordOrPattern, isPattern):          
+        lSectionsFoundAccordingPatternRules=[]
+        if isPattern == False:
+            if self._iRawConfig.has_section(sectionWordOrPattern):
+                lSectionsFoundAccordingPatternRules.append(sectionWordOrPattern)
+        else:
+            for sectionName in self._iRawConfig.sections():
+                if re.search(sectionWordOrPattern, sectionName, re.IGNORECASE):
+                    lSectionsFoundAccordingPatternRules.append(sectionName)
+        return lSectionsFoundAccordingPatternRules
+    
+    def getOptionsNamesAccordingPatternRules(self, sectionName, optionWordOrPattern, isPattern):
+        lOptionsFoundAccordingPatternRules=[]
+        if isPattern == False:
+            if self._iRawConfig.has_option(sectionName, optionWordOrPattern):
+                lOptionsFoundAccordingPatternRules.append(optionWordOrPattern)
+        else :
+            for optionName in self._iRawConfig.options(sectionName):
+                if re.search(optionWordOrPattern, optionName, re.IGNORECASE)!= None:
+                    lOptionsFoundAccordingPatternRules.append(optionName)
+        return lOptionsFoundAccordingPatternRules
+    
+    def extendConfigRulesWithPatternRules(self):
+        for sectionName in self._iConfigRules.dRules4Sections.keys():
+            dRules4OptionsOfThisSection = self._iConfigRules.dRules4Sections[sectionName] 
+            lRawSections=[]
+            if dRules4OptionsOfThisSection.has_key("DEFAULT"):
+                mandatorySection = dRules4OptionsOfThisSection["DEFAULT"].mandatory
+                isPatternSection = dRules4OptionsOfThisSection["DEFAULT"].isPattern
+                lRawSections=self.getSectionNamesAccordingPatternRules(sectionName, isPatternSection)
+                for rawSectionName in lRawSections:
+                    self._iExtendedConfigRules.addRuleSection(rawSectionName, "DEFAULT", mandatorySection )
+                if mandatorySection and (len(lRawSections)==0):
+                    self._iExtendedConfigRules.addRuleSection(sectionName, "DEFAULT", mandatorySection )
+            else:
+                lRawSections.append(sectionName) 
+            for optionName in dRules4OptionsOfThisSection.keys():
+                setOption = dRules4OptionsOfThisSection[optionName].set
+                isPatternOption = dRules4OptionsOfThisSection[optionName].isPattern
+                mandatoryOption = dRules4OptionsOfThisSection[optionName].mandatory
+                typeOption = dRules4OptionsOfThisSection[optionName].type
+                if optionName != "DEFAULT":
+                    for rawSectionName in lRawSections:
+                        lRawOptions=self.getOptionsNamesAccordingPatternRules(rawSectionName, optionName, isPatternOption)
+                        for rawOptionName in lRawOptions:
+                            self._iExtendedConfigRules.addRuleOption(rawSectionName, rawOptionName, mandatoryOption, False, typeOption, setOption)
+                        if mandatoryOption and (len(lRawOptions)==0):
+                            self._iExtendedConfigRules.addRuleOption(rawSectionName, optionName, mandatoryOption, False, typeOption, setOption)
+                                                          
+    def getConfig(self):
+        self.checkIfExistsConfigFile()
+        iConfig = self.readConfigFile()
+        self.setRawConfig(iConfig)
+        self.extendConfigRulesWithPatternRules()
+        self.checkMandatorySections()
+        self.checkMandatoryOptions()
+        self.setConfig(iConfig)
+        return self._iRawConfig
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/ConfigException.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,53 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+from commons.core.checker.RepetException import RepetException
+
+##  A exception raised by check() method of class ConfigChecker
+#
+# This class allow storage of multiple messages (see messages attribute).
+# Example: use one instance of ConfigException class for one section in configuration file.
+# All messages relatives to this section are stored in messages attribute.
+class ConfigException( RepetException ):
+    
+    ## Constructor
+    #
+    # @param msg message embedded in Exception class   
+    #
+    def __init__(self, msg, messages = []):
+        RepetException.__init__(self, msg)
+        self.messages = messages
+        
+    def getMessages(self):
+        return self.messages
+        
+    def setMessages(self, messages):
+        self.messages = messages
+        
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/ConfigValue.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,70 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+class ConfigValue(object):
+    
+    def __init__(self):
+        self.dOptionsValues4Sections={}
+        
+    def has_section(self,sectionName):
+        return self.dOptionsValues4Sections.has_key(sectionName)
+    
+    def has_option(self, sectionName, optionName):
+        isOptionExist = False
+        if self.has_section(sectionName):
+            isOptionExist = self.dOptionsValues4Sections[sectionName].has_key(optionName)
+        return isOptionExist
+        
+    def sections(self):    
+        lSectionsKeys = self.dOptionsValues4Sections.keys()
+        return lSectionsKeys
+    
+    def options(self, sectionName):
+        lOptionsKeys = [] 
+        if self.has_section(sectionName):
+            lOptionsKeys = self.dOptionsValues4Sections[sectionName].keys()
+        return lOptionsKeys
+    
+    def get(self, sectionName, optionName):   
+        if self.has_option(sectionName, optionName):
+            return self.dOptionsValues4Sections[sectionName][optionName]
+        return None
+    
+    def set(self, sectionName, optionName, optionValue):   
+        if not (self.has_section(sectionName)):
+            self.dOptionsValues4Sections[sectionName] = {}
+        self.dOptionsValues4Sections[sectionName][optionName] = optionValue
+        
+    def setdOptionsValues4Sections(self, dOptionsValues4Sections):
+        self.dOptionsValues4Sections = dOptionsValues4Sections
+        
+    def __eq__(self, o):
+        return self.dOptionsValues4Sections == o.dOptionsValues4Sections
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/IChecker.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,45 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+## Interface for a checker
+#
+# This class emulates an interface for a checker.
+#
+# All checkers are subclasses of IChecker. 
+#
+class IChecker( object ):
+    
+    ## perform check, raise a CheckerException if error occurred
+    #
+    # @param arg a collecting parameter: put here all you need to perform check
+    # 
+    def check(self, arg=""):
+        pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/OldConfigChecker.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,101 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import ConfigParser
+from ConfigParser import NoOptionError
+from commons.core.checker.IChecker import IChecker
+from commons.core.checker.ConfigException import ConfigException
+
+
+## A checker for a configuration file
+#
+#
+# A configuration file is formatted as follow:
+#
+# [section1]
+#
+# option_name1: option_value1
+# 
+# option_name2: option_value2
+#
+# option_name3: option_value3
+#
+# [section2]
+# 
+# ...
+#
+# 
+# This class performs 3 checkes on a configuration file: 
+#
+# (i) check if file exists
+#
+# (ii) check if section exists
+#
+# (iii) check if option exists
+#
+class ConfigChecker( IChecker ):
+    
+    ## Constructor A checker for configuration file.
+    #
+    # @param  sectionName name of section to check in configuration file
+    # @param  optionsDict dictionary with option(s) to check as keys and empty strings ("") as values
+    def __init__ (self, sectionName, optionsDict):
+        self._sectionName = sectionName
+        self._optionsDict = optionsDict
+        
+        
+    ## Perform 3 checks : file exists, sections exists, option exists
+    # 
+    # @param configFile configuration file to check
+    # @exception ConfigException with a list of messages
+    def check (self, configFile):
+        config = ConfigParser.ConfigParser()
+        msg = []
+        try:
+            config.readfp( open(configFile) )
+        except IOError, e:
+            msg.append("CONFIG FILE not found - " + e.message)
+            raise ConfigException("", msg) 
+
+        if not (config.has_section(self._sectionName)):
+            msg.append("[" + self._sectionName + "]" + " section not found - ")
+            raise ConfigException("", msg)
+         
+        isExceptionOccured = False        
+        for key in self._optionsDict.keys():
+            try:
+                self._optionsDict[key] = config.get(self._sectionName, key) 
+            except NoOptionError, e:
+                msg.append("[" + self._sectionName + "]" + " - " + e.message)
+                isExceptionOccured = True
+        
+        if (isExceptionOccured):
+            raise ConfigException("", msg)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/RepetException.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,51 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+class RepetException(Exception):
+    
+    def __init__(self, msg):
+        Exception.__init__(self)
+        self._message = msg
+    
+    def __str__(self):
+        return self._message
+               
+    def getMessage(self):
+        return self._message
+    
+    def setMessage(self, msg):
+        self._message = msg
+
+
+class RepetDataException(RepetException):
+    
+    def __init__(self, msg):
+        RepetException.__init__(self, msg)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/test/TestSuite_Checker.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import sys
+import unittest
+import Test_CheckerUtils
+import Test_ConfigChecker
+
+
+def main():
+    
+    TestSuite_Checker = unittest.TestSuite()
+    
+    TestSuite_Checker.addTest( unittest.makeSuite( Test_CheckerUtils.Test_CheckerUtils, "test" ) )     
+    TestSuite_Checker.addTest( unittest.makeSuite( Test_ConfigChecker.Test_ConfigChecker, "test" ) )    
+    
+    runner = unittest.TextTestRunner( sys.stderr, 2, 2 )
+    runner.run( TestSuite_Checker )
+    
+if __name__ == "__main__":                 
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/test/Test_CheckerUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,535 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+import ConfigParser
+from commons.core.checker.CheckerUtils import CheckerUtils
+from commons.core.checker.CheckerException import CheckerException
+from ConfigParser import NoOptionError
+from ConfigParser import NoSectionError
+
+class Test_CheckerUtils( unittest.TestCase ):
+    
+    def setUp(self):
+        self.queueFileName = "queueName.txt"
+        self.configFileName = "dummyConfig.cfg"
+    
+    def tearDown(self):
+        if os.path.exists(self.queueFileName):
+            os.remove(self.queueFileName)
+        if os.path.exists(self.configFileName):
+            os.remove(self.configFileName)
+    
+    def test_isBlastNameInBlastValues( self ):
+        correctValueList = [ "blastn", "blastp", "blastx", "tblastn", "tblastx" ]
+        for value in correctValueList:
+            self.assertFalse( CheckerUtils.isBlastNameNotInBlastValues( value ) )
+            
+        incorrectValueList = [ "badbalst", "wublast" ]
+        for value in incorrectValueList:
+            self.assertTrue( CheckerUtils.isBlastNameNotInBlastValues( value ) )
+            
+    def test_isNotTRUEisNotFALSE( self ):
+        correctValueList = [ "TRUE", "FALSE" ]
+        for value in correctValueList:
+            self.assertFalse( CheckerUtils.isNotTRUEisNotFALSE( value ) )
+            
+        incorrectValueList = [ "True", "False" ]
+        for value in incorrectValueList:
+            self.assertTrue( CheckerUtils.isNotTRUEisNotFALSE( value ) )
+            
+    def test_isRessourceNotExists( self ):
+        fileName = "dummyFile.txt"
+        self.assertTrue( CheckerUtils.isRessourceNotExits( fileName ) )
+        os.system( "touch %s" % ( fileName ) )
+        self.assertFalse( CheckerUtils.isRessourceNotExits( fileName ) )
+        os.remove( fileName )
+        
+    def test_isNotAeValueWithOneDigit2DecimalsAtLeast( self ):
+        correctEValueList = [ "5e-32", "7e-45", "1e-2122", "9e-32" ]
+        for value in correctEValueList:
+            self.assertFalse( CheckerUtils.isNotAeValueWithOneDigit2DecimalsAtLeast( value ) )
+            
+        incorrecEValueStr = [ "10e-32", "2e-3", "2e-2", "1", "cxhhe" ]
+        for value in incorrecEValueStr:
+            self.assertTrue( CheckerUtils.isNotAeValueWithOneDigit2DecimalsAtLeast( value ) )
+            
+    def test_isNotADigit( self ):
+        correctDigitList = [ "1", "21", "345" ]
+        for value in correctDigitList:
+            self.assertFalse( CheckerUtils.isNotANumber( value ) )
+            
+        incorrectDigitList = [ "A", "dfdf", "((((" ]
+        for value in incorrectDigitList:
+            self.assertTrue( CheckerUtils.isNotANumber( value ) )
+            
+    def test_isExecutableInUserPath( self ):
+        exeName = "ls"
+        self.assertTrue( CheckerUtils.isExecutableInUserPath( exeName ) )
+
+        exeName = "hsvegdtefaobfbcheta"
+        self.assertFalse( CheckerUtils.isExecutableInUserPath( exeName ) )
+    
+    def test_isExecutableInUserPath_case_endsWith( self ):
+        exeName = "s"
+        self.assertFalse( CheckerUtils.isExecutableInUserPath( exeName ) )
+
+    def test_isQueueNameValid_valid(self):
+        cmd = "qconf -sql > " + self.queueFileName
+        os.system(cmd)
+        f = open(self.queueFileName, "r")
+        lQueueNames = f.readlines()
+        f.close()
+        if lQueueNames == []:
+            print "Warning you need SGE installed\n"
+        else:
+            self.assertTrue(CheckerUtils.isQueueNameValid(lQueueNames[0].strip()))
+        
+    def test_isQueueNameValid_not_valid(self):
+        cmd = "qconf -sql > " + self.queueFileName
+        os.system(cmd)
+        f = open(self.queueFileName, "r")
+        lQueueNames = f.readlines()
+        f.close()
+        if lQueueNames == []:
+            print "Warning you need SGE installed\n"
+        else:
+            self.assertFalse(CheckerUtils.isQueueNameValid("dummyQueueName"))
+
+    def test_isQueueNameValid_valid_with_parameter(self):
+        cmd = "qconf -sql > " + self.queueFileName
+        os.system(cmd)
+        f = open(self.queueFileName, "r")
+        lQueueNames = f.readlines()
+        f.close()
+        if lQueueNames == []:
+            print "Warning you need SGE installed\n"
+        else:
+            queueNameWithParameter = lQueueNames[0].strip() + " test=TRUE"
+            self.assertTrue(CheckerUtils.isQueueNameValid(queueNameWithParameter))
+            
+    def test_isCharAlphanumOrUnderscore_valid(self):
+        project_name = "Project_Name"
+        self.assertTrue(CheckerUtils.isCharAlphanumOrUnderscore(project_name))
+        
+    def test_isCharAlphanumOrUnderscore_not_valid(self):
+        project_name = "Project_Name,"
+        self.assertFalse(CheckerUtils.isCharAlphanumOrUnderscore(project_name))
+        
+    def test_isMax15Char_valid(self):
+        project_name = "Project_Name"
+        self.assertTrue(CheckerUtils.isMax15Char(project_name))
+        
+    def test_isMax15Char_not_valid(self):
+        project_name = "Project_Name_tooLong"
+        self.assertFalse(CheckerUtils.isMax15Char(project_name))
+        
+    def test_checkSectionInConfigFile_empty_section(self):
+        sectionName = "sectionName"
+        line = "[" + sectionName + "]"
+        configFile = open(self.configFileName, "w")
+        configFile.write(line)
+        configFile.close()
+        configFile = open(self.configFileName, "r")
+        
+        config = ConfigParser.ConfigParser()
+        config.readfp(configFile)
+        
+        isSectionExceptionRaised = False
+        try:
+            CheckerUtils.checkSectionInConfigFile(config, sectionName)
+        except NoSectionError:
+            isSectionExceptionRaised = True
+        configFile.close()
+        self.assertFalse(isSectionExceptionRaised)
+    
+    def test_checkSectionInConfigFile(self):
+        sectionName = "sectionName"
+        lines = "[" + sectionName + "]\ndummyOption : dummyOption\n"
+        configFile = open(self.configFileName, "w")
+        configFile.write(lines)
+        configFile.close()
+        configFile = open(self.configFileName, "r")
+        
+        config = ConfigParser.ConfigParser()
+        config.readfp(configFile)
+        
+        isSectionExceptionRaised = False
+        try:
+            CheckerUtils.checkSectionInConfigFile(config, sectionName)
+        except NoSectionError:
+            isSectionExceptionRaised = True
+        configFile.close()
+        self.assertFalse(isSectionExceptionRaised)
+        
+    def test_checkSectionInConfigFile_not_valid(self):
+        sectionName = "sectionName"
+        line = " "
+        configFile = open(self.configFileName, "w")
+        configFile.write(line)
+        configFile.close()
+        configFile = open(self.configFileName, "r")
+        
+        config = ConfigParser.ConfigParser()
+        config.readfp(configFile)
+        
+        isSectionExceptionRaised = False
+        try:
+            CheckerUtils.checkSectionInConfigFile(config, sectionName)
+        except NoSectionError:
+            isSectionExceptionRaised = True
+        configFile.close()
+        self.assertTrue(isSectionExceptionRaised)
+        
+    def test_checkOptionInSectionInConfigFile(self):
+        optionName = "optionName"
+        sectionName = "sectionName"
+        configFile = open(self.configFileName, "w")
+        configFile.write("[" + sectionName + "]\n")
+        configFile.write(optionName + ": ")
+        configFile.close()
+        configFile = open(self.configFileName, "r")
+        
+        config = ConfigParser.ConfigParser()
+        config.readfp(configFile)
+        
+        isSectionExceptionRaised = False
+        try:
+            CheckerUtils.checkOptionInSectionInConfigFile(config, sectionName, optionName)
+        except NoOptionError:
+            isSectionExceptionRaised = True
+        configFile.close()
+        self.assertFalse(isSectionExceptionRaised)
+        
+    def test_checkOptionInSectionInConfigFile_not_present(self):
+        optionName = " "
+        sectionName = "sectionName"
+        configFile = open(self.configFileName, "w")
+        configFile.write("[" + sectionName + "]\n")
+        configFile.write(optionName)
+        configFile.close()
+        configFile = open(self.configFileName, "r")
+        
+        config = ConfigParser.ConfigParser()
+        config.readfp(configFile)
+        
+        isSectionExceptionRaised = False
+        try:
+            CheckerUtils.checkOptionInSectionInConfigFile(config, sectionName, optionName)
+        except NoOptionError:
+            isSectionExceptionRaised = True
+        configFile.close()
+        self.assertTrue(isSectionExceptionRaised)
+        
+    def test_checkOptionInSectionInConfigFile_not_in_the_right_section(self):
+        optionName = "optionName"
+        rightSection = "dummySection2"
+        configFile = open(self.configFileName, "w")
+        configFile.write("[dummySection1]\n")
+        configFile.write(optionName + ": \n")
+        configFile.write("[" + rightSection + "]")
+        configFile.close()
+        configFile = open(self.configFileName, "r")
+        
+        config = ConfigParser.ConfigParser()
+        config.readfp(configFile)
+        
+        isSectionExceptionRaised = False
+        try:
+            CheckerUtils.checkOptionInSectionInConfigFile(config, rightSection, optionName)
+        except NoOptionError:
+            isSectionExceptionRaised = True
+        configFile.close()
+        self.assertTrue(isSectionExceptionRaised)
+        
+    def test_checkConfigVersion_different_version_between_changeLog_and_configFile(self):
+        changeLogFileName = "dummyCHANGELOG"
+        
+        self._writeChangeLogFile(changeLogFileName)
+        self._writeConfigFile("repet_version: 1.3.5\n")
+        
+        changeLogFileHandler = open(changeLogFileName, "r")
+        configFileHandler = open(self.configFileName, "r")
+        config = ConfigParser.ConfigParser()
+        config.readfp(configFileHandler)
+        
+        self.assertRaises(CheckerException, CheckerUtils.checkConfigVersion, changeLogFileHandler, config)
+        
+        changeLogFileHandler.close()
+        configFileHandler.close()
+        os.remove(changeLogFileName)
+        
+    def test_checkConfigVersion_same_version_between_changeLog_and_configFile(self):
+        changeLogFileName = "dummyCHANGELOG"
+        self._writeChangeLogFile(changeLogFileName)
+        self._writeConfigFile("repet_version: 1.3.6\n")
+        
+        changeLogFileHandler = open(changeLogFileName, "r")
+        configFileHandler = open(self.configFileName, "r")
+        config = ConfigParser.ConfigParser()
+        config.readfp(configFileHandler)
+        
+        isCheckerExceptionRaised = False
+        try:
+            CheckerUtils.checkConfigVersion(changeLogFileHandler, config)
+        except CheckerException:
+            isCheckerExceptionRaised = True
+        self.assertFalse(isCheckerExceptionRaised)
+        
+        changeLogFileHandler.close()
+        configFileHandler.close()
+        os.remove(changeLogFileName)
+        
+    def test_getVersionFromChangelogFile(self):
+        changeLogFileName = "dummyCHANGELOG"
+        self._writeChangeLogFile(changeLogFileName)
+        obsVer = CheckerUtils.getVersionFromChangelogFile(changeLogFileName)
+        expVer = "1.3.6"
+        
+        self.assertEquals(obsVer, expVer)
+        
+        os.remove(changeLogFileName)
+        
+    def test_checkConfigVersion_check_exception_message(self):
+        changeLogFileName = "dummyCHANGELOG"
+        self._writeChangeLogFile(changeLogFileName)
+        self._writeConfigFile("repet_version: 1.3.5\n")
+        
+        changeLogFileHandler = open(changeLogFileName, "r")
+        configFileHandler = open(self.configFileName, "r")
+        config = ConfigParser.ConfigParser()
+        config.readfp(configFileHandler)
+        
+        checkerExceptionInstance = None
+        try:
+            CheckerUtils.checkConfigVersion(changeLogFileHandler, config)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "*** Error: wrong config file version. Expected version num is 1.3.6 but actual in config file is 1.3.5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+        
+    def test_checkHeaders_first_header_with_question_mark(self):
+        fastaFileName = "dummyFasta.fa"
+        self._writeFastaFile_first_header_with_question_mark(fastaFileName)
+        fastaFileHandler = open(fastaFileName,"r")
+        isExceptionRaised = False
+        try:
+            CheckerUtils.checkHeaders(fastaFileHandler)
+        except CheckerException, e:
+            isExceptionRaised = True
+            
+        fastaFileHandler.close()
+        os.remove(fastaFileName)
+            
+        self.assertTrue(isExceptionRaised)
+        
+        expMessages = ["DmelChr4_Bla?ster_Piler_0.0_Map_3"] 
+        obsMessages = e.getMessages()
+        
+        self.assertEquals(expMessages, obsMessages)
+
+    def test_checkHeaders_with_2_wrong_headers(self):
+        fastaFileName = "dummyFasta.fa"
+        self._writeFastaFile_with_2_wrong_headers(fastaFileName)
+        fastaFileHandler = open(fastaFileName,"r")
+        isExceptionRaised = False
+        try:
+            CheckerUtils.checkHeaders(fastaFileHandler)
+        except CheckerException, e:
+            isExceptionRaised = True
+            
+        fastaFileHandler.close()
+        os.remove(fastaFileName)
+            
+        self.assertTrue(isExceptionRaised)
+        
+        expMessages = ["DmelChr4_Bla?ster_Piler_0.0_Map_3","DmelChr4_Bla!ster_Piler_1.0_Map_9"] 
+        obsMessages = e.getMessages()
+        
+        self.assertEquals(expMessages, obsMessages)
+
+    def test_checkHeaders_with_pipe(self):
+        fastaFileName = "dummyFasta.fa"
+        self._writeFastaFile_with_pipe(fastaFileName)
+        fastaFileHandler = open(fastaFileName,"r")
+        isExceptionRaised = False
+        try:
+            CheckerUtils.checkHeaders(fastaFileHandler)
+        except CheckerException, e:
+            isExceptionRaised = True
+            
+        fastaFileHandler.close()
+        os.remove(fastaFileName)
+            
+        self.assertTrue(isExceptionRaised)
+        
+        expMessages = ["DmelC|hr4_Blas-ter_Piler_1.0_Map_9"] 
+        obsMessages = e.getMessages()
+        
+        self.assertEquals(expMessages, obsMessages)
+
+    def test_checkHeaders_with_equal(self):
+        fastaFileName = "dummyFasta.fa"
+        self._writeFastaFile_with_equal(fastaFileName)
+        fastaFileHandler = open(fastaFileName,"r")
+        isExceptionRaised = False
+        try:
+            CheckerUtils.checkHeaders(fastaFileHandler)
+        except CheckerException, e:
+            isExceptionRaised = True
+            
+        fastaFileHandler.close()
+        os.remove(fastaFileName)
+            
+        self.assertTrue(isExceptionRaised)
+        
+        expMessages = ["DmelC:hr4_Blas=ter_Piler_1.0_Map_9"] 
+        obsMessages = e.getMessages()
+        
+        self.assertEquals(expMessages, obsMessages)
+
+    def test_checkHeaders_all_headers_ok(self):
+        fastaFileName = "dummyFasta.fa"
+        self._writeFastaFile_all_headers_ok(fastaFileName)
+        fastaFileHandler = open(fastaFileName,"r")
+        isExceptionRaised = False
+        try:
+            CheckerUtils.checkHeaders(fastaFileHandler)
+        except CheckerException:
+            isExceptionRaised = True
+            
+        fastaFileHandler.close()
+        os.remove(fastaFileName)
+            
+        self.assertFalse(isExceptionRaised)
+
+    def _writeFastaFile_first_header_with_question_mark(self, fastaFileName):    
+        fastaFileHandler = open(fastaFileName, "w")
+        fastaFileHandler.write(">DmelChr4_Bla?ster_Piler_0.0_Map_3\n")
+        fastaFileHandler.write("ACCAAAGACACTAGAATAACAAGATGCGTAACGCCATACGATTTTTTGGCACACTATTTT\n")
+        fastaFileHandler.write("TTCGCCGTGGCTCTAGAGGTGGCTCCAGGCTCTCTCGAATTTTTGTTAGAGAGCGAGAGA\n")
+        fastaFileHandler.write("GCTGAGAGCGCTACAGCGAACAGCTCTTTTCTACACATAAAGTGATAGCAGACAACTGTA\n")
+        fastaFileHandler.write("TGTGTGCACACGTGTGCTCATGCATTGTAAATTTGACAAAATATGCCCTTCACCTTCAAA\n")
+        fastaFileHandler.write(">DmelChr4_Blaster_Piler_1.0_Map_9\n")
+        fastaFileHandler.write("AGTTTAAAAACCAAAGACACTAGAATAACAAGATGCGTAACGGCCATACATTGGTTTGGC\n")
+        fastaFileHandler.write("ACTATGCAGCCACTTTTTTGGTGACGGCCAAAATTACTCTCTTTCCGCTCACTCCCGCTG\n")
+        fastaFileHandler.write("AGAGCGTAAGAAATCTAAAAATATAATTTGCTTGCTTGTGTGAGTAAAAACAAGAGACGA\n")
+        fastaFileHandler.write("GAACGCGTATAAGTGTGCGTGTTGTGCTAGAAGACGATTTTCGGGACCGAAATCAATTCT\n")
+        fastaFileHandler.write("GATCGAAGAAACGAATTTACATGGTACATATTAGGGTAGTTTTTGCCAATTTCCTAGCAA\n")
+        fastaFileHandler.close()
+    
+    def _writeFastaFile_with_2_wrong_headers(self, fastaFileName):    
+        fastaFileHandler = open(fastaFileName, "w")
+        fastaFileHandler.write(">DmelChr4_Bla?ster_Piler_0.0_Map_3\n")
+        fastaFileHandler.write("ACCAAAGACACTAGAATAACAAGATGCGTAACGCCATACGATTTTTTGGCACACTATTTT\n")
+        fastaFileHandler.write("TTCGCCGTGGCTCTAGAGGTGGCTCCAGGCTCTCTCGAATTTTTGTTAGAGAGCGAGAGA\n")
+        fastaFileHandler.write("GCTGAGAGCGCTACAGCGAACAGCTCTTTTCTACACATAAAGTGATAGCAGACAACTGTA\n")
+        fastaFileHandler.write("TGTGTGCACACGTGTGCTCATGCATTGTAAATTTGACAAAATATGCCCTTCACCTTCAAA\n")
+        fastaFileHandler.write(">DmelChr4_Bla!ster_Piler_1.0_Map_9\n")
+        fastaFileHandler.write("AGTTTAAAAACCAAAGACACTAGAATAACAAGATGCGTAACGGCCATACATTGGTTTGGC\n")
+        fastaFileHandler.write("ACTATGCAGCCACTTTTTTGGTGACGGCCAAAATTACTCTCTTTCCGCTCACTCCCGCTG\n")
+        fastaFileHandler.write("AGAGCGTAAGAAATCTAAAAATATAATTTGCTTGCTTGTGTGAGTAAAAACAAGAGACGA\n")
+        fastaFileHandler.write("GAACGCGTATAAGTGTGCGTGTTGTGCTAGAAGACGATTTTCGGGACCGAAATCAATTCT\n")
+        fastaFileHandler.write("GATCGAAGAAACGAATTTACATGGTACATATTAGGGTAGTTTTTGCCAATTTCCTAGCAA\n")
+        fastaFileHandler.close()
+    
+    def _writeFastaFile_all_headers_ok(self, fastaFileName):    
+        fastaFileHandler = open(fastaFileName, "w")
+        fastaFileHandler.write(">DmelChr4_Blaster_Piler_0.0_Map_3\n")
+        fastaFileHandler.write("ACCAAAGACACTAGAATAACAAGATGCGTAACGCCATACGATTTTTTGGCACACTATTTT\n")
+        fastaFileHandler.write("TTCGCCGTGGCTCTAGAGGTGGCTCCAGGCTCTCTCGAATTTTTGTTAGAGAGCGAGAGA\n")
+        fastaFileHandler.write("GCTGAGAGCGCTACAGCGAACAGCTCTTTTCTACACATAAAGTGATAGCAGACAACTGTA\n")
+        fastaFileHandler.write("TGTGTGCACACGTGTGCTCATGCATTGTAAATTTGACAAAATATGCCCTTCACCTTCAAA\n")
+        fastaFileHandler.write(">DmelC:hr4_Blas-ter_Piler_1.0_Map_9\n")
+        fastaFileHandler.write("AGTTTAAAAACCAAAGACACTAGAATAACAAGATGCGTAACGGCCATACATTGGTTTGGC\n")
+        fastaFileHandler.write("ACTATGCAGCCACTTTTTTGGTGACGGCCAAAATTACTCTCTTTCCGCTCACTCCCGCTG\n")
+        fastaFileHandler.write("AGAGCGTAAGAAATCTAAAAATATAATTTGCTTGCTTGTGTGAGTAAAAACAAGAGACGA\n")
+        fastaFileHandler.write("GAACGCGTATAAGTGTGCGTGTTGTGCTAGAAGACGATTTTCGGGACCGAAATCAATTCT\n")
+        fastaFileHandler.write("GATCGAAGAAACGAATTTACATGGTACATATTAGGGTAGTTTTTGCCAATTTCCTAGCAA\n")
+        fastaFileHandler.close()
+    
+    def _writeFastaFile_with_pipe(self, fastaFileName):    
+        fastaFileHandler = open(fastaFileName, "w")
+        fastaFileHandler.write(">DmelChr4_Blaster_Piler_0.0_Map_3\n")
+        fastaFileHandler.write("ACCAAAGACACTAGAATAACAAGATGCGTAACGCCATACGATTTTTTGGCACACTATTTT\n")
+        fastaFileHandler.write("TTCGCCGTGGCTCTAGAGGTGGCTCCAGGCTCTCTCGAATTTTTGTTAGAGAGCGAGAGA\n")
+        fastaFileHandler.write("GCTGAGAGCGCTACAGCGAACAGCTCTTTTCTACACATAAAGTGATAGCAGACAACTGTA\n")
+        fastaFileHandler.write("TGTGTGCACACGTGTGCTCATGCATTGTAAATTTGACAAAATATGCCCTTCACCTTCAAA\n")
+        fastaFileHandler.write(">DmelC|hr4_Blas-ter_Piler_1.0_Map_9\n")
+        fastaFileHandler.write("AGTTTAAAAACCAAAGACACTAGAATAACAAGATGCGTAACGGCCATACATTGGTTTGGC\n")
+        fastaFileHandler.write("ACTATGCAGCCACTTTTTTGGTGACGGCCAAAATTACTCTCTTTCCGCTCACTCCCGCTG\n")
+        fastaFileHandler.write("AGAGCGTAAGAAATCTAAAAATATAATTTGCTTGCTTGTGTGAGTAAAAACAAGAGACGA\n")
+        fastaFileHandler.write("GAACGCGTATAAGTGTGCGTGTTGTGCTAGAAGACGATTTTCGGGACCGAAATCAATTCT\n")
+        fastaFileHandler.write("GATCGAAGAAACGAATTTACATGGTACATATTAGGGTAGTTTTTGCCAATTTCCTAGCAA\n")
+        fastaFileHandler.close()
+    
+    def _writeFastaFile_with_equal(self, fastaFileName):    
+        fastaFileHandler = open(fastaFileName, "w")
+        fastaFileHandler.write(">DmelChr4_Blaster_Piler_0.0_Map_3\n")
+        fastaFileHandler.write("ACCAAAGACACTAGAATAACAAGATGCGTAACGCCATACGATTTTTTGGCACACTATTTT\n")
+        fastaFileHandler.write("TTCGCCGTGGCTCTAGAGGTGGCTCCAGGCTCTCTCGAATTTTTGTTAGAGAGCGAGAGA\n")
+        fastaFileHandler.write("GCTGAGAGCGCTACAGCGAACAGCTCTTTTCTACACATAAAGTGATAGCAGACAACTGTA\n")
+        fastaFileHandler.write("TGTGTGCACACGTGTGCTCATGCATTGTAAATTTGACAAAATATGCCCTTCACCTTCAAA\n")
+        fastaFileHandler.write(">DmelC:hr4_Blas=ter_Piler_1.0_Map_9\n")
+        fastaFileHandler.write("AGTTTAAAAACCAAAGACACTAGAATAACAAGATGCGTAACGGCCATACATTGGTTTGGC\n")
+        fastaFileHandler.write("ACTATGCAGCCACTTTTTTGGTGACGGCCAAAATTACTCTCTTTCCGCTCACTCCCGCTG\n")
+        fastaFileHandler.write("AGAGCGTAAGAAATCTAAAAATATAATTTGCTTGCTTGTGTGAGTAAAAACAAGAGACGA\n")
+        fastaFileHandler.write("GAACGCGTATAAGTGTGCGTGTTGTGCTAGAAGACGATTTTCGGGACCGAAATCAATTCT\n")
+        fastaFileHandler.write("GATCGAAGAAACGAATTTACATGGTACATATTAGGGTAGTTTTTGCCAATTTCCTAGCAA\n")
+        fastaFileHandler.close()
+
+    def _writeChangeLogFile(self, changeLogFileName ):
+        changeLogFileHandler = open(changeLogFileName, "w")
+        changeLogFileHandler.write("ChangeLog of REPET\n")
+        changeLogFileHandler.write("\n")
+        changeLogFileHandler.write("\n")
+        changeLogFileHandler.write("\n")
+        changeLogFileHandler.write("REPET release 1.3.6\n")
+        changeLogFileHandler.write("(release date XX/XX/2010)\n")
+        changeLogFileHandler.write("\n")
+        changeLogFileHandler.close()
+
+    def _writeConfigFile(self, lineVersion):
+        configFileHandler = open(self.configFileName, "w")
+        configFileHandler.write("[repet_env]\n")
+        configFileHandler.write(lineVersion)
+        configFileHandler.write("repet_host: <your_MySQL_host>\n")
+        configFileHandler.close()
+        
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_CheckerUtils ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/test/Test_ConfigChecker.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,569 @@
+from commons.core.checker.ConfigChecker import ConfigChecker 
+from commons.core.checker.ConfigChecker import ConfigRules
+from commons.core.checker.RepetException import RepetException
+import os
+import unittest
+
+class Test_ConfigChecker(unittest.TestCase):
+    
+    def setUp(self):
+        self._configFileName = "testConfigChecker.cfg"
+        self._iMock = MockConfig()
+     
+    def test_checkIfExistsConfigFile_file_exist(self):
+        f=open(self._configFileName, "w")
+        f.close()
+        
+        doesFileExists = True
+        iConfigRules = ConfigRules()
+        try:
+            iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+            iConfigChecker.checkIfExistsConfigFile()
+        except RepetException:
+            doesFileExists = False
+        os.remove(self._configFileName)        
+        self.assertTrue(doesFileExists)
+        
+    def test_checkIfExistsConfigFile_file_not_exist(self):
+        iConfigRules = ConfigRules()
+        expMsg ="CONFIG FILE not found - '%s'" %self._configFileName
+        doesFileExists = True
+        try:
+            iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)   
+            iConfigChecker.checkIfExistsConfigFile()     
+        except RepetException, re:
+            doesFileExists = False
+        self.assertFalse(doesFileExists)
+        self.assertEqual(expMsg, re.getMessage())
+        
+    def test_readConfigFile(self):
+        self._iMock.write_config(self._configFileName)
+        iConfigRules = ConfigRules()
+        expDictRawConfigValues = {"dir_name" : {"work_dir":"toto"},
+                                  "organism" : {"abbreviation":"T.aestivum",
+                                                "genus":"triticum",
+                                                "species":"aestivum",
+                                                "common_name":"wheat",
+                                                "comment":""},
+                                  'analysis1': {'description': '',
+                                                'gff_name': 'BLASTX.gff2',
+                                                'name': 'BLASTXWheat2',
+                                                'program': 'BLASTX2',
+                                                'programversion': '3.32',
+                                                'sourcename': 'dummyDesc_BLASTX2'}
+                                 }
+        isNoExceptionRaised = True
+        try: 
+            iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+            iConfig = iConfigChecker.readConfigFile()
+            iConfigChecker.setRawConfig(iConfig)
+            obsDictRawConfigValues = iConfigChecker._iRawConfig.dOptionsValues4Sections
+        except RepetException:
+            isNoExceptionRaised = False
+        os.remove(self._configFileName)
+        self.assertTrue(isNoExceptionRaised)
+        self.assertEquals(obsDictRawConfigValues, expDictRawConfigValues)
+        
+    def test_readConfigFile_section_define_twice(self):
+        self._iMock.write_case_section_define_twice(self._configFileName)
+        iConfigRules = ConfigRules()
+        expMsg = "Duplicate section exist in config file %s"  %self._configFileName
+        expDictRawConfigValues = {"dir_name": {"work_dir":"toto"},
+                                  "analysis1" : {"name": "BLASTXWheat2",
+                                                 "program" : "BLASTX2",
+                                                 "programversion" : "3.32",
+                                                 "sourcename" :"dummyDesc_BLASTX2",
+                                                 "description" : "",
+                                                 "gff_name" :"BLASTX.gff2"}
+                                 }
+        doesNoExceptionRaised = True
+        try:
+            iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+            iConfig = iConfigChecker.readConfigFile()
+            iConfigChecker.setRawConfig(iConfig)
+            obsDictRawConfigValues = iConfigChecker._iRawConfig.dOptionsValues4Sections
+        except RepetException, re:
+            doesNoExceptionRaised = False
+        os.remove(self._configFileName)
+#       self.assertFalse(doesNoExceptionRaised)
+#       self.assertEqual(expMsg, re.getMessage())
+#
+        self.assertTrue(doesNoExceptionRaised)
+        self.assertEquals(obsDictRawConfigValues, expDictRawConfigValues)
+
+    def test_readConfigFile_option_define_twice(self):
+        self._iMock.write_case_option_define_twice(self._configFileName)
+        iConfigRules = ConfigRules()
+        doesNoExceptionRaised = True
+        expDictRawConfigValues = {"dir_name": {"work_dir":"toto"},
+                                  "analysis1" : {"name": "BLASTXWheat",
+                                       "program" : "BLASTX2",
+                                       "programversion" : "3.3",
+                                       "sourcename" :"dummyDesc_BLASTX",
+                                       "description" : "",
+                                       "gff_name" :"BLASTX.gff"}
+                    }
+        try:
+            iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+            iConfig = iConfigChecker.readConfigFile()
+            iConfigChecker.setRawConfig(iConfig)
+            obsDictRawConfigValues = iConfigChecker._iRawConfig.dOptionsValues4Sections
+        except RepetException, re:
+            doesNoExceptionRaised = False
+        os.remove(self._configFileName)
+##       self.assertFalse(doesNoExceptionRaised)
+##       self.assertEqual(expMsg, re.getMessage())
+
+        self.assertTrue(doesNoExceptionRaised)
+        self.assertEquals(obsDictRawConfigValues, expDictRawConfigValues)
+       
+    def test_checkMandatorySections(self):
+        self._iMock.write_config(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection(section="dir_name", mandatory=True)
+        iConfigRules.addRuleSection(section="organism", mandatory=True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        areAllMandatorySectionsFound = True
+        try:
+            iConfigChecker.checkMandatorySections()
+        except RepetException:
+            areAllMandatorySectionsFound = False
+        os.remove(self._configFileName)
+        self.assertTrue(areAllMandatorySectionsFound)
+ 
+    def test_checkMandatorySections_one_missing (self):
+        self._iMock.write_config(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection(section="dir_name", mandatory=True)
+        iConfigRules.addRuleSection(section="target", mandatory=True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        expMsg = "Error in configuration file %s, following sections are missing:\n - target\n"% self._configFileName
+        areAllMandatorySectionsFound = True
+        try:
+            iConfigChecker.checkMandatorySections()
+        except RepetException, re:
+            areAllMandatorySectionsFound = False
+        os.remove(self._configFileName)
+        self.assertFalse(areAllMandatorySectionsFound)
+        self.assertEquals(expMsg, re.getMessage())
+        
+    def test_checkMandatorySections_mandatory_section_with_pattern_section_is_missing (self):
+        self._iMock.write_config(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection(section="dir_name", mandatory=True)
+        iConfigRules.addRuleSection(section="mandatorySection", mandatory=True, isPattern = True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        expMsg = "Error in configuration file %s, following sections are missing:\n - mandatorySection\n"% self._configFileName 
+        areAllMandatorySectionsFound = True
+        try:
+            iConfigChecker.checkMandatorySections()
+        except RepetException, re:
+            areAllMandatorySectionsFound = False
+        os.remove(self._configFileName)
+        self.assertFalse(areAllMandatorySectionsFound)
+        self.assertEquals(expMsg, re.getMessage())
+
+    def test_checkMandatorySections_mandatory_section_is_pattern (self):
+        self._iMock.write_case_pattern_rule(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection(section="dir_name", mandatory=True)
+        iConfigRules.addRuleSection(section="analysis[0-9]*", mandatory=True, isPattern = True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        areAllMandatorySectionsFound = True
+        try:
+            iConfigChecker.checkMandatorySections()
+        except RepetException:
+            areAllMandatorySectionsFound = False
+        os.remove(self._configFileName)
+        self.assertTrue(areAllMandatorySectionsFound)
+
+    def test_checkMandatoryOptions_in_mandatory_section (self):
+        self._iMock.write_config(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection(section="organism", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="genus", mandatory=True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        areAllMandatoryOptionsFound = True
+        try:
+            iConfigChecker.checkMandatoryOptions()
+        except RepetException:
+            areAllMandatoryOptionsFound = False
+        os.remove(self._configFileName)
+        self.assertTrue(areAllMandatoryOptionsFound)
+
+    def test_checkMandatoryOptions_in_mandatory_section_option_is_missing (self):
+        self._iMock.write_config(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection(section="organism", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="MissingOption", mandatory=True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        expMsg = "Error in configuration file %s, following options are missing: \n - [organism]: MissingOption\n" % self._configFileName
+        areAllMandatoryOptionsFound = True
+        try:
+            iConfigChecker.checkMandatoryOptions()
+        except RepetException, re:
+            areAllMandatoryOptionsFound = False
+        os.remove(self._configFileName)
+        self.assertFalse(areAllMandatoryOptionsFound)
+        self.assertEquals(expMsg, re.getMessage())
+
+    def test_checkMandatoryOptions_in_non_mandatory_section_and_section_and_option_exist (self):
+        self._iMock.write_config(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleOption(section="organism", option ="genus", mandatory=True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        areAllMandatoryOptionsFound = True
+        try:
+            iConfigChecker.checkMandatoryOptions()
+        except RepetException:
+            areAllMandatoryOptionsFound = False
+        os.remove(self._configFileName)
+        self.assertTrue(areAllMandatoryOptionsFound)
+        
+    def test_checkMandatoryOptions_in_non_mandatory_section_and_section_exist_option_is_missing (self):
+        self._iMock.write_config(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleOption(section="organism", option ="MissingOption", mandatory=True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        expMsg = "Error in configuration file %s, following options are missing: \n - [organism]: MissingOption\n" % self._configFileName
+        areAllMandatoryOptionsFound = True
+        try:
+            iConfigChecker.checkMandatoryOptions()
+        except RepetException, re:
+            areAllMandatoryOptionsFound = False
+        os.remove(self._configFileName)
+        self.assertFalse(areAllMandatoryOptionsFound)
+        self.assertEquals(expMsg,re.getMessage())
+        
+    def test_checkMandatoryOptions_in_non_mandatory_section_and_section_does_not_exist (self):
+        self._iMock.write_config(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleOption(section="NonExistingAndNonMandatorySection", option ="genus", mandatory=True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        areAllMandatoryOptionsFound = True
+        try:
+            iConfigChecker.checkMandatoryOptions()
+        except RepetException:
+            areAllMandatoryOptionsFound = False
+        os.remove(self._configFileName)
+        self.assertTrue(areAllMandatoryOptionsFound)
+        
+    def test_checkMandatoryOptions_with_Pattern_rules_in_section  (self):
+        self._iMock.write_case_pattern_rule(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection(section="analysis", isPattern=True)
+        iConfigRules.addRuleOption(section="analysis", option ="name", mandatory=True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        areAllMandatoryOptionsFound = True
+        try:
+            iConfigChecker.checkMandatoryOptions()
+        except RepetException:
+            areAllMandatoryOptionsFound = False
+        os.remove(self._configFileName)
+        self.assertTrue(areAllMandatoryOptionsFound)
+
+    def test_checkMandatoryOptions_with_pattern_rules_in_option_section_is_mandatory (self):
+        self._iMock.write_case_pattern_rule(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection(section="section_with_option_pattern", mandatory=True)
+        iConfigRules.addRuleOption(section="section_with_option_pattern", option ="option", isPattern= True, mandatory=True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        areAllMandatoryOptionsFound = True
+        try:
+            iConfigChecker.checkMandatoryOptions()
+        except RepetException:
+            areAllMandatoryOptionsFound = False
+        os.remove(self._configFileName)
+        self.assertTrue(areAllMandatoryOptionsFound)
+
+    def test_checkMandatoryOptions_with_pattern_rules_in_option_in_mandatory_section_option_is_missing (self):
+        self._iMock.write_case_pattern_rule(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection(section="section_with_option_pattern", mandatory=True)
+        iConfigRules.addRuleOption(section="section_with_option_pattern", option ="MissingOption", isPattern= True, mandatory=True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        expMsg = "Error in configuration file %s, following options are missing: \n - [section_with_option_pattern]: MissingOption\n" % self._configFileName
+        areAllMandatoryOptionsFound = True
+        try:
+            iConfigChecker.checkMandatoryOptions()
+        except RepetException, re:
+            areAllMandatoryOptionsFound = False
+        os.remove(self._configFileName)
+        self.assertFalse(areAllMandatoryOptionsFound)
+        self.assertEquals(expMsg, re.getMessage())
+
+    def test_checkMandatoryOptions_with_pattern_rules_in_non_mandatory_section_and_section_and_option_exist (self):
+        self._iMock.write_case_pattern_rule(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleOption(section="section_with_option_pattern", option ="option", isPattern= True, mandatory=True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        areAllMandatoryOptionsFound = True
+        try:
+            iConfigChecker.checkMandatoryOptions()
+        except RepetException:
+            areAllMandatoryOptionsFound = False
+        os.remove(self._configFileName)
+        self.assertTrue(areAllMandatoryOptionsFound)
+        
+    def test_checkMandatoryOptions_with_pattern_rules_in_non_mandatory_section_and_section_exist_option_is_missing (self):
+        self._iMock.write_case_pattern_rule(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleOption(section="section_with_option_pattern", option ="MissingOption", isPattern= True, mandatory=True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        expMsg = "Error in configuration file %s, following options are missing: \n - [section_with_option_pattern]: MissingOption\n" % self._configFileName
+        areAllMandatoryOptionsFound = True
+        try:
+            iConfigChecker.checkMandatoryOptions()
+        except RepetException, re:
+            areAllMandatoryOptionsFound = False
+        os.remove(self._configFileName)
+        self.assertFalse(areAllMandatoryOptionsFound)
+        self.assertEquals(expMsg,re.getMessage())
+        
+    def test_checkMandatoryOptions_with_pattern_rules_in_non_mandatory_section_and_section_does_not_exist (self):
+        self._iMock.write_case_pattern_rule(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleOption(section="non_mandatory_section", option ="MissingOption", isPattern= True, mandatory=True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        areAllMandatoryOptionsFound = True
+        try:
+            iConfigChecker.checkMandatoryOptions()
+        except RepetException:
+            areAllMandatoryOptionsFound = False
+        os.remove(self._configFileName)
+        self.assertTrue(areAllMandatoryOptionsFound)
+        
+    def test_checkMandatoryOptions_with_pattern_rules_for_both_section_and_option  (self):
+        self._iMock.write_case_pattern_rule(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection(section="section_with_option_pattern", isPattern=True)
+        iConfigRules.addRuleOption(section="section_with_option_pattern", option ="option", isPattern= True, mandatory=True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        areAllMandatoryOptionsFound = True
+        try:
+            iConfigChecker.checkMandatoryOptions()
+        except RepetException:
+            areAllMandatoryOptionsFound = False
+        os.remove(self._configFileName)
+        self.assertTrue(areAllMandatoryOptionsFound)
+       
+    def test_checkMandatoryOptions_case(self):
+        self._iMock.write_config_case(self._configFileName)
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection("dir_name", True)
+        iConfigRules.addRuleSection("organism", True)
+        iConfigRules.addRuleOption("organism", "min_SSR_coverage", True)
+        iConfigChecker = ConfigChecker(self._configFileName, iConfigRules)
+        iConfig = iConfigChecker.readConfigFile()
+        iConfigChecker.setRawConfig(iConfig)
+        iConfigChecker.extendConfigRulesWithPatternRules()
+        areAllMandatorySectionsFound = True
+        try:
+            iConfigChecker.checkMandatoryOptions()
+        except RepetException:
+            areAllMandatorySectionsFound = False
+        os.remove(self._configFileName)
+        self.assertTrue(areAllMandatorySectionsFound)
+
+#TODO Test de extendConfigRulesWithPatternRules et de applyRuleToRawValue
+# option avec une liste de valeurs possibles dans un ensemble
+# option type=string type="num" type="date"???.
+#option define twice and options use in other
+             
+class MockConfig (object):
+    
+    def write_config(self, configFileName):
+        configF = open(configFileName, "w" )
+        configF.write( "[dir_name]\n")
+        configF.write( "work_dir : toto \n") 
+        configF.write( "\n")
+        configF.write( "[organism]\n")
+        configF.write( "abbreviation: T.aestivum\n")
+        configF.write( "genus: triticum\n")
+        configF.write( "species: aestivum\n")
+        configF.write( "common_name: wheat\n")
+        configF.write( "comment: \n")
+        configF.write( "[analysis1]\n")
+        configF.write( "name: BLASTXWheat2\n")
+        configF.write( "program: BLASTX2\n")
+        configF.write( "programversion: 3.32\n")
+        configF.write( "sourcename: dummyDesc_BLASTX2\n")
+        configF.write( "description: \n")
+        configF.write( "gff_name: BLASTX.gff2\n")
+        configF.write( "\n")
+        configF.close()
+        
+    def write_case_section_define_twice(self, configFileName):
+        configF = open(configFileName, "w" )
+        configF.write( "[dir_name]\n")
+        configF.write( "work_dir : toto \n") 
+        configF.write( "\n")
+        configF.write( "[analysis1]\n")
+        configF.write( "name: BLASTXWheat\n")
+        configF.write( "program: BLASTX\n")
+        configF.write( "programversion: 3.3\n")
+        configF.write( "sourcename: dummyDesc_BLASTX\n")
+        configF.write( "description: \n")
+        configF.write( "gff_name: BLASTX.gff\n")
+        configF.write( "\n")
+        configF.write( "[analysis1]\n")
+        configF.write( "name: BLASTXWheat2\n")
+        configF.write( "program: BLASTX2\n")
+        configF.write( "programversion: 3.32\n")
+        configF.write( "sourcename: dummyDesc_BLASTX2\n")
+        configF.write( "description: \n")
+        configF.write( "gff_name: BLASTX.gff2\n")
+        configF.write( "\n")
+        configF.close()
+        
+    def write_case_option_define_twice(self, configFileName):
+        configF = open(configFileName, "w" )
+        configF.write( "[dir_name]\n")
+        configF.write( "work_dir : toto \n") 
+        configF.write( "\n")
+        configF.write( "[analysis1]\n")
+        configF.write( "name: BLASTXWheat\n")
+        configF.write( "program: BLASTX\n")
+        configF.write( "programversion: 3.3\n")
+        configF.write( "sourcename: dummyDesc_BLASTX\n")
+        configF.write( "program: BLASTX2\n")
+        configF.write( "description: \n")
+        configF.write( "gff_name: BLASTX.gff\n")
+        configF.write( "\n")
+        configF.write( "\n")
+        configF.close()
+        
+    #configuration file with section with option depends on presence of other options
+    def write_with_one_option_depends_of_an_other_one(self, configFileName ):
+        configF = open(configFileName, "w" )
+        configF.write( "[dir_name]\n")
+        configF.write( "work_dir : toto\n") 
+        configF.write( "\n")
+        configF.write( "[organism]\n")
+        configF.write( "abbreviation: T.aestivum\n")
+        configF.write( "genus: Triticum\n")
+        configF.write( "species: aestivum\n")
+        configF.write( "common_name: wheat\n")
+        configF.write( "comment: \n")
+        configF.write( "\n")
+        configF.write( "[analysis1]\n")
+        configF.write( "name: BLASTXWheat\n")
+        configF.write( "program: BLASTX\n")
+        configF.write( "programversion: 3.3\n")
+        configF.write( "sourcename: src_BLASTX\n")
+        configF.write( "description: \n")
+        configF.write( "gff_name: BLASTX.gff\n")
+        configF.write( "\n")
+        configF.write( "[analysis2]\n")
+        configF.write( "name: GMHMMWheat\n")
+        configF.write( "program: GMHMM\n")
+        configF.write( "programversion: 4.3\n")
+        configF.write( "sourcename: src_GMHMM\n")
+        configF.write( "description: \n")
+        configF.write( "gff_name: GMHMM.gff\n")
+        configF.write( "\n")
+        configF.write( "[target]\n")
+        configF.write( "target_used: yes\n")
+        configF.write( "target_used_list: target.lst\n")
+        configF.close()
+        
+    def write_case_pattern_rule(self, configFileName ):
+        configF = open(configFileName, "w" )
+        configF.write( "[dir_name]\n")
+        configF.write( "work_dir : toto\n" ) 
+        configF.write( "\n")
+        configF.write( "[organism]\n")
+        configF.write( "abbreviation: T.aestivum\n")
+        configF.write( "genus: Triticum\n")
+        configF.write( "species: aestivum\n")
+        configF.write( "common_name: wheat\n")
+        configF.write( "comment: \n")
+        configF.write( "\n")
+        configF.write( "[analysis1]\n")
+        configF.write( "name: BLASTXWheat\n")
+        configF.write( "program: BLASTX\n")
+        configF.write( "programversion: 3.3\n")
+        configF.write( "sourcename: src_BLASTX\n")
+        configF.write( "description: \n")
+        configF.write( "gff_name: BLASTX.gff\n")
+        configF.write( "\n")
+        configF.write( "[analysis2]\n")
+        configF.write( "name: GMHMMWheat\n")
+        configF.write( "program: GMHMM\n")
+        configF.write( "programversion: 4.3\n")
+        configF.write( "sourcename: src_GMHMM\n")
+        configF.write( "description: \n")
+        configF.write( "gff_name: GMHMM.gff\n")
+        configF.write( "\n")
+        configF.write( "[target]\n")
+        configF.write( "target_used: yes\n")
+        configF.write( "target_used_list: target.lst\n")
+        configF.write( "\n")
+        configF.write( "[section_with_option_pattern]\n")
+        configF.write( "option1: value1\n")
+        configF.write( "option2: value2\n")
+        configF.write( "[second_section_with_option_pattern]\n")
+        configF.write( "option1: value1\n")
+        configF.write( "option2: value2\n")
+        configF.close()
+        
+    def write_config_case(self, configFileName):
+        configF = open(configFileName, "w" )
+        configF.write( "[dir_name]\n")
+        configF.write( "work_dir : toto \n") 
+        configF.write( "\n")
+        configF.write( "[organism]\n")
+        configF.write( "min_SSR_coverage: 0.50\n")
+        configF.write( "\n")
+        configF.close()
+        
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/test/Test_ConfigValue.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,217 @@
+import unittest
+from commons.core.checker.ConfigValue import ConfigValue
+
+class Test_ConfigValue(unittest.TestCase):
+    
+    def setUp(self):
+        self._iConfigValue = ConfigValue()
+        
+    def test__eq__True(self):
+        self._iConfigValue.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organism" : {"abbreviation":"T.aestivum",
+                                  "genus":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                                        }
+        iConfigValue1 = ConfigValue()                         
+        iConfigValue1.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organism" : {"abbreviation":"T.aestivum",
+                                  "genus":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                                }
+        
+        self.assertEqual(self._iConfigValue, iConfigValue1)
+        
+    def test__eq__False_not_same_section(self):
+        self._iConfigValue.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organisms" : {"abbreviation":"T.aestivum",
+                                  "genus":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                                        }
+        iConfigValue1 = ConfigValue()                         
+        iConfigValue1.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organism" : {"abbreviation":"T.aestivum",
+                                  "genus":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                                }
+        
+        self.assertNotEqual(self._iConfigValue, iConfigValue1)
+                                                
+                                                
+    def test__eq__False_not_same_option(self):
+        self._iConfigValue.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organism" : {"abbreviation":"T.aestivum",
+                                  "family":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                                        }
+        iConfigValue1 = ConfigValue()                         
+        iConfigValue1.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organism" : {"abbreviation":"T.aestivum",
+                                  "genus":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                                }
+        
+        self.assertNotEqual(self._iConfigValue, iConfigValue1)
+        
+    def test__eq__False_not_same_value(self):
+        self._iConfigValue.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organism" : {"abbreviation":"T.aestivum",
+                                  "genus":"vitis",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                                        }
+        iConfigValue1 = ConfigValue()                         
+        iConfigValue1.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organism" : {"abbreviation":"T.aestivum",
+                                  "genus":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                                }
+        
+        self.assertNotEqual(self._iConfigValue, iConfigValue1)
+                                                
+    def test_has_section_true(self):
+        self._iConfigValue.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organism" : {"abbreviation":"T.aestivum",
+                                  "genus":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                 }
+        
+        obsSectionExist = self._iConfigValue.has_section("organism")
+        self.assertTrue(obsSectionExist)
+ 
+    def test_has_section_false(self):
+        self._iConfigValue.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organism" : {"abbreviation":"T.aestivum",
+                                  "genus":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                 }
+        
+        obsSectionExist = self._iConfigValue.has_section("toto")
+        self.assertFalse(obsSectionExist)  
+        
+    def test_has_option_true(self):
+        self._iConfigValue.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organism" : {"abbreviation":"T.aestivum",
+                                  "genus":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                 }
+        
+        obsOptionExist = self._iConfigValue.has_option("organism","genus")
+        self.assertTrue(obsOptionExist)
+ 
+    def test_has_option_false(self):
+        self._iConfigValue.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organism" : {"abbreviation":"T.aestivum",
+                                  "genus":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                 }
+        
+        obsOptionExist = self._iConfigValue.has_option("organism","toto")
+        self.assertFalse(obsOptionExist)
+        obsOptionExist = self._iConfigValue.has_option("toto","genus")
+        self.assertFalse(obsOptionExist)
+
+    def test_sections(self):
+        self._iConfigValue.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organism" : {"abbreviation":"T.aestivum",
+                                  "genus":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                 }
+        expListSections = ["dir_name", "organism"]
+        obsListSections = self._iConfigValue.sections()
+        self.assertEquals(expListSections, obsListSections)
+        
+    def test_sections_empty_config(self):
+        self._iConfigValue.dOptionsValues4Sections = {}
+        expListSections = []
+        obsListSections = self._iConfigValue.sections()
+        self.assertEquals(expListSections, obsListSections)
+
+    def test_options(self):
+        self._iConfigValue.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organism" : {"abbreviation":"T.aestivum",
+                                  "genus":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                 }
+        expListOptions = ['abbreviation', 'common_name', 'genus', 'species', 'comment']
+        obsListOptions = self._iConfigValue.options("organism")
+        self.assertEquals(expListOptions, obsListOptions)
+   
+        expListOptions = ["work_dir"]
+        obsListOptions = self._iConfigValue.options("dir_name")
+        self.assertEquals(expListOptions, obsListOptions)
+             
+    def test_options_empty_config(self):
+        self._iConfigValue.dOptionsValues4Sections = {}
+        expListOptions = []
+        obsListOptions = self._iConfigValue.options("toto")
+        self.assertEquals(expListOptions, obsListOptions)
+
+    def test_set(self):
+        self._iConfigValue.dOptionsValues4Sections = {}
+        expDictOptionsValue = {"dir_name" : {"work_dir":"toto"}}
+        self._iConfigValue.set("dir_name", "work_dir", "toto")
+        obsDictOptionsValue = self._iConfigValue.dOptionsValues4Sections
+        self.assertEquals(expDictOptionsValue, obsDictOptionsValue)
+        
+    def test_get(self):
+        self._iConfigValue.dOptionsValues4Sections = {
+                    "dir_name" : {"work_dir":"toto"},
+                    "organism" : {"abbreviation":"T.aestivum",
+                                  "genus":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""}
+                                 }
+        expValue = "aestivum"
+        obsValue = self._iConfigValue.get("organism", "species")
+        self.assertEquals(expValue, obsValue)
+        expValue = None
+        obsValue = self._iConfigValue.get("toto", "species")
+        self.assertEquals(expValue, obsValue)
+        expValue = None
+        obsValue = self._iConfigValue.get("organism", "dummyopt")
+        self.assertEquals(expValue, obsValue)       
+        
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/test/Test_F_ConfigChecker.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,214 @@
+from commons.core.checker.ConfigChecker import ConfigChecker 
+from commons.core.checker.ConfigChecker import ConfigRules
+from commons.core.checker.ConfigValue import ConfigValue
+from commons.core.checker.RepetException import RepetException
+import unittest
+import os
+
+class Test_F_ConfigChecker(unittest.TestCase):
+    
+    #TODO: AJouter test (wrong type, etc..)
+    def setUp(self):
+        self._configFileName = "test_conf_checker"
+        
+    def tearDown(self):
+        os.remove(self._configFileName)
+     
+    def test_run(self):
+        iMock = MockConfig()
+        iMock.write_config(self._configFileName)
+        
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection(section="dir_name", mandatory=True)
+        iConfigRules.addRuleOption(section="dir_name", option ="work_dir", mandatory=True)
+        iConfigRules.addRuleSection(section="organism", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="abbreviation", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="genus", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="species", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="common_name", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="comment")
+        iConfigRules.addRuleSection(section="analysis", mandatory=True, isPattern=True)
+        iConfigRules.addRuleOption(section="analysis", option ="name", mandatory=True)
+        iConfigRules.addRuleOption(section="analysis", option ="program", mandatory=True)
+        iConfigRules.addRuleOption(section="analysis", option ="sourcename", mandatory=True)
+        iConfigRules.addRuleOption(section="analysis", option ="description")
+        iConfigRules.addRuleOption(section="analysis", option ="gff_name")
+        
+        iConfigChecker = ConfigChecker(self._configFileName,iConfigRules)
+        
+        obsValidatedConfig = iConfigChecker.getConfig()
+        
+        expValidatedConfig = ConfigValue()
+        d = {"dir_name" : {"work_dir":"toto"},
+             "organism" : {"abbreviation":"T.aestivum",
+                                  "genus":"triticum",
+                                  "species":"aestivum",
+                                  "common_name":"wheat",
+                                  "comment":""},
+                           'analysis1': {'description': '',
+                                  'gff_name': 'BLASTX.gff2',
+                                  'name': 'BLASTXWheat2',
+                                  'program': 'BLASTX2',
+                                  'programversion': '3.32',
+                                  'sourcename': 'dummyDesc_BLASTX2'}
+                                 }
+        expValidatedConfig.setdOptionsValues4Sections(d)
+        
+        self.assertEquals(expValidatedConfig, obsValidatedConfig)
+        
+        
+    def test_run_exception_section_missing(self):
+        iMock = MockConfig()
+        iMock.write_config_section_missing(self._configFileName)
+        
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection(section="dir_name", mandatory=True)
+        iConfigRules.addRuleOption(section="dir_name", option ="work_dir", mandatory=True)
+        iConfigRules.addRuleSection(section="organism", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="abbreviation", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="genus", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="species", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="common_name", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="comment")
+        iConfigRules.addRuleSection(section="analysis", mandatory=True, isPattern=True)
+        iConfigRules.addRuleOption(section="analysis", option ="name", mandatory=True)
+        iConfigRules.addRuleOption(section="analysis", option ="program", mandatory=True)
+        iConfigRules.addRuleOption(section="analysis", option ="sourcename", mandatory=True)
+        iConfigRules.addRuleOption(section="analysis", option ="description")
+        iConfigRules.addRuleOption(section="analysis", option ="gff_name")
+        
+        iConfigChecker = ConfigChecker(self._configFileName,iConfigRules)
+        
+        expMessage = "Error in configuration file %s, following sections are missing:\n - organism\n"% self._configFileName
+        
+        try :
+            obsValidatedConfig = iConfigChecker.getConfig()
+        except RepetException, e:
+            obsMessage = e.getMessage()
+
+        self.assertEquals(expMessage, obsMessage)
+        
+        
+    def test_run_exception_section_pattern_false(self):
+        iMock = MockConfig()
+        iMock.write_config(self._configFileName)
+        
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection(section="dir_name", mandatory=True)
+        iConfigRules.addRuleOption(section="dir_name", option ="work_dir", mandatory=True)
+        iConfigRules.addRuleSection(section="organism", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="abbreviation", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="genus", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="species", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="common_name", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="comment")
+        iConfigRules.addRuleSection(section="analysis", mandatory=True)
+        iConfigRules.addRuleOption(section="analysis", option ="name", mandatory=True)
+        iConfigRules.addRuleOption(section="analysis", option ="program", mandatory=True)
+        iConfigRules.addRuleOption(section="analysis", option ="sourcename", mandatory=True)
+        iConfigRules.addRuleOption(section="analysis", option ="description")
+        iConfigRules.addRuleOption(section="analysis", option ="gff_name")
+        
+        iConfigChecker = ConfigChecker(self._configFileName,iConfigRules)
+        
+        expMessage = "Error in configuration file %s, following sections are missing:\n - analysis\n"% self._configFileName
+        
+        try :
+            obsValidatedConfig = iConfigChecker.getConfig()
+        except RepetException, e:
+            obsMessage = e.getMessage()
+
+        self.assertEquals(expMessage, obsMessage)
+        
+        
+    def test_run_exception_option_missing(self):
+        iMock = MockConfig()
+        iMock.write_config_option_missing(self._configFileName)
+        
+        iConfigRules = ConfigRules()
+        iConfigRules.addRuleSection(section="dir_name", mandatory=True)
+        iConfigRules.addRuleOption(section="dir_name", option ="work_dir", mandatory=True)
+        iConfigRules.addRuleSection(section="organism", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="abbreviation", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="genus", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="species", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="common_name", mandatory=True)
+        iConfigRules.addRuleOption(section="organism", option ="comment")
+        iConfigRules.addRuleSection(section="analysis", mandatory=True, isPattern=True)
+        iConfigRules.addRuleOption(section="analysis", option ="name", mandatory=True)
+        iConfigRules.addRuleOption(section="analysis", option ="program", mandatory=True)
+        iConfigRules.addRuleOption(section="analysis", option ="sourcename", mandatory=True)
+        iConfigRules.addRuleOption(section="analysis", option ="description")
+        iConfigRules.addRuleOption(section="analysis", option ="gff_name")
+        
+        iConfigChecker = ConfigChecker(self._configFileName,iConfigRules)
+        
+        expMessage = "Error in configuration file %s, following options are missing: \n - [organism]: abbreviation\n"% self._configFileName
+        
+        try :
+            obsValidatedConfig = iConfigChecker.getConfig()
+        except RepetException, e:
+            obsMessage = e.getMessage()
+
+        self.assertEquals(expMessage, obsMessage)
+            
+class MockConfig (object):
+   
+    def write_config(self, configFileName):
+        configF = open(configFileName, "w" )
+        configF.write( "[dir_name]\n")
+        configF.write( "work_dir : toto \n") 
+        configF.write( "\n")
+        configF.write( "[organism]\n")
+        configF.write( "abbreviation: T.aestivum\n")
+        configF.write( "genus: triticum\n")
+        configF.write( "species: aestivum\n")
+        configF.write( "common_name: wheat\n")
+        configF.write( "comment: \n")
+        configF.write( "[analysis1]\n")
+        configF.write( "name: BLASTXWheat2\n")
+        configF.write( "program: BLASTX2\n")
+        configF.write( "programversion: 3.32\n")
+        configF.write( "sourcename: dummyDesc_BLASTX2\n")
+        configF.write( "description: \n")
+        configF.write( "gff_name: BLASTX.gff2\n")
+        configF.write( "\n")
+        configF.close()
+        
+    def write_config_section_missing(self, configFileName):
+        configF = open(configFileName, "w" )
+        configF.write( "[dir_name]\n")
+        configF.write( "work_dir : toto \n") 
+        configF.write( "\n")
+        configF.write( "[analysis1]\n")
+        configF.write( "name: BLASTXWheat2\n")
+        configF.write( "program: BLASTX2\n")
+        configF.write( "programversion: 3.32\n")
+        configF.write( "sourcename: dummyDesc_BLASTX2\n")
+        configF.write( "description: \n")
+        configF.write( "gff_name: BLASTX.gff2\n")
+        configF.write( "\n")
+        configF.close()
+        
+    def write_config_option_missing(self, configFileName):
+        configF = open(configFileName, "w" )
+        configF.write( "[dir_name]\n")
+        configF.write( "work_dir : toto \n") 
+        configF.write( "\n")
+        configF.write( "[organism]\n")
+        configF.write( "genus: triticum\n")
+        configF.write( "species: aestivum\n")
+        configF.write( "common_name: wheat\n")
+        configF.write( "comment: \n")
+        configF.write( "[analysis1]\n")
+        configF.write( "name: BLASTXWheat2\n")
+        configF.write( "program: BLASTX2\n")
+        configF.write( "programversion: 3.32\n")
+        configF.write( "sourcename: dummyDesc_BLASTX2\n")
+        configF.write( "description: \n")
+        configF.write( "gff_name: BLASTX.gff2\n")
+        configF.write( "\n")
+        configF.close()
+        
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/checker/test/Test_OldConfigChecker.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,104 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+from commons.core.checker.OldConfigChecker import ConfigChecker
+from commons.core.checker.ConfigException import ConfigException
+
+class Test_ConfigChecker( unittest.TestCase ):
+    
+    def setUp(self):
+        pass
+    
+    def tearDown(self):
+        pass
+    
+    
+    def testFileNotFound(self):
+        exceptionExpected = None
+        configChecker = ConfigChecker("",{})
+        try :
+            configChecker.check("noExistsFile.cfg")
+        except ConfigException, ce:
+            exceptionExpected = ce
+        
+        self.assertTrue(exceptionExpected != None)
+        msg = exceptionExpected.messages[0]
+        self.assertTrue(msg.startswith("CONFIG FILE not found - "))
+        
+        
+    def testNoSectionInConfigFile (self):
+        exceptionExpected = None
+        dummyFile = open("dummyFile.cfg", "w")
+        configChecker = ConfigChecker("dummySection",{})
+        try :
+            configChecker.check("dummyFile.cfg")
+        except ConfigException, ce:
+            exceptionExpected = ce
+        
+        self.assertTrue(exceptionExpected != None)
+        msg = exceptionExpected.messages[0]
+        self.assertTrue(msg.startswith("[dummySection]" + " section not found - "))
+        
+        os.remove("dummyFile.cfg")
+        
+        
+    def testNoOptionInConfigFile (self):
+        exceptionExpected = None
+        MockConfigFile("dummyConfig.cfg",{})
+        configChecker = ConfigChecker("blaster_config",{"dummy":""})
+        try :
+            configChecker.check("dummyConfig.cfg")
+        except ConfigException, ce:
+            exceptionExpected = ce
+        
+        self.assertTrue(exceptionExpected != None)
+        msg = exceptionExpected.messages[0]
+        self.assertTrue(msg.startswith("[blaster_config] - No option 'dummy' in section: 'blaster_config'"))
+        os.remove("dummyConfig.cfg")
+        
+        
+class MockConfigFile:
+    
+    def __init__ (self, fileName, optionsDict):
+        self._fileName = fileName
+        config = open(fileName, "w");
+        config.write("[blaster_config]\n")
+        for key in optionsDict.keys():
+            config.write(key + ":" + optionsDict[key] + "\n")
+        config.close()
+        
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_ConfigChecker ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/Align.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,428 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+import time
+
+from commons.core.coord.Range import Range
+from commons.core.coord.Map import Map
+
+
+## Handle a match between two sequences, query and subject (pair of coordinates with E-value, score and identity)
+#
+class Align( object ):
+    
+    ## Constructor
+    #
+    # @param range_q: a Range instance for the query
+    # @param range_s: a Range instance for the subject
+    # @param e_value: E-value of the match 
+    # @param identity: identity percentage of the match
+    # @param score: score of the match
+    #
+    def __init__(self, range_q=Range(), range_s=Range(), e_value=0, score=0, identity=0):
+        self.range_query = range_q
+        self.range_subject = range_s
+        self.e_value = float(e_value)
+        self.score = float(score)
+        self.identity = float(identity)
+       
+    ## Return True if the instance is empty, False otherwise
+    #
+    def isEmpty(self):
+        return self.range_query.isEmpty() or self.range_subject.isEmpty()
+        
+    ## Equal operator
+    #
+    def __eq__(self, o):
+        if self.range_query==o.range_query and self.range_subject==o.range_subject and \
+        self.e_value==o.e_value and self.score==o.score and self.identity==o.identity:
+            return True
+        return False
+    
+    ## Unequal operator
+    #
+    # @param o a Range instance
+    #
+    def __ne__(self, o):
+        return not self.__eq__(o)
+    
+    ## Convert the object into a string
+    #
+    # @note used in 'print myObject'
+    #
+    def __str__( self ):
+        return self.toString()
+    
+    ## Read attributes from an Align file
+    # 
+    # @param fileHandler: file handler of the file being read
+    # @return: 1 on success, 0 at the end of the file 
+    #
+    def read(self, fileHandler):
+        self.reset()
+        line = fileHandler.readline()
+        if line == "":
+            return 0
+        tokens = line.split("\t")
+        if len(tokens) < len(self.__dict__.keys()):
+            return 0
+        self.setFromTuple(tokens)
+        return 1
+    
+    ## Set attributes from tuple
+    #
+    # @param tuple a tuple with (queryName,queryStart,queryEnd,subjectName,subjectStar,subjectEnd,E-value,score,identity)
+    # @note data are loaded such that the query is always on the direct strand
+    #
+    def setFromTuple( self, tuple ):
+        #TODO: we need to create Range instances because of __eq__() and isEmpty() tests, but WHY ???
+        self.range_query = Range()
+        self.range_subject = Range()
+        if int(tuple[1]) < int(tuple[2]):
+            self.range_query.setFromTuple( ( tuple[0], tuple[1], tuple[2] ) )
+            self.range_subject.setFromTuple( ( tuple[3], tuple[4], tuple[5] ) )
+        else:
+            self.range_query.setFromTuple( ( tuple[0], tuple[2], tuple[1] ) )
+            self.range_subject.setFromTuple( ( tuple[3], tuple[5], tuple[4] ) )
+        self.e_value = float(tuple[6])
+        self.score = float(tuple[7])
+        self.identity = float(tuple[8])
+        
+    ## Reset
+    #
+    def reset( self ):
+        self.range_query.reset()
+        self.range_subject.reset()
+        self.e_value = 0
+        self.score = 0
+        self.identity = 0
+        
+    ## Return the attributes as a formatted string
+    #
+    def toString(self):
+        string = "%s" % ( self.range_query.toString() )
+        string += "\t%s" % ( self.range_subject.toString() )
+        string += "\t%g\t%i\t%f" % ( self.e_value, self.score, self.identity )
+        return string
+    
+    
+    ## Return the attributes as a GFF-formatted string
+    #
+    def toStringAsGff( self, source="REPET", type="match", phase=".", ID="", Parent="" ):
+        if not self.isSubjectOnDirectStrand():
+            self.reverse()
+        string = "%s" % ( self.getQueryName() )
+        string += "\t%s" % ( source )
+        string += "\t%s" % ( type )
+        string += "\t%s" % ( self.getQueryMin() )
+        string += "\t%s" % ( self.getQueryMax() )
+        string += "\t%g" % ( self.e_value )
+        string += "\t%s" % ( self.getQueryStrand() )
+        string += "\t%s" % ( phase )
+        attributes = ""
+        if ID != "":
+            attributes += "ID=%s" % ( ID )
+        else:
+            attributes += "ID=%i" % ( str(time.time())[-8:-1].replace(".","") )
+        if Parent != "":
+            attributes += ";Parent=%s" % ( Parent )
+        attributes += ";Target=%s %i %i" % ( self.getSubjectName(), self.getSubjectStart(), self.getSubjectEnd() )
+        string += "\t%s" % ( attributes )
+        return string
+    
+    
+    ## Reverse query and subject
+    #
+    def reverse(self):
+        self.range_query.reverse()
+        self.range_subject.reverse()
+        
+    ## Show the attributes
+    #
+    def show(self):
+        print self.toString()
+ 
+    ## Write attributes into an Align file
+    #
+    # @param fileHandler: file handler of the file being filled
+    #
+    def write(self, fileHandler):
+        fileHandler.write("%s\n" % (self.toString()))
+        
+    ## Save attributes into an Align file
+    #
+    # @param file: name of the file being filled
+    #
+    def save(self, file):
+        fileHandler = open( file, "a" )
+        self.write( fileHandler )
+        fileHandler.close()
+        
+    ## Return the score
+    #
+    def getScore(self):
+        return self.score
+
+    ## Return the identity
+    #
+    def getIdentity(self):
+        return self.identity
+    
+    def getEvalue(self):
+        return self.e_value
+    
+    ## Return the length on the query
+    #
+    def getLengthOnQuery(self):
+        return self.range_query.getLength()
+    
+    ## Return the name of the query
+    #
+    def getQueryName( self ):
+        return self.range_query.seqname
+    
+    ## Return the start of the query
+    #
+    def getQueryStart( self ):
+        return self.range_query.start
+    
+    ## Return the end of the query
+    #
+    def getQueryEnd( self ):
+        return self.range_query.end
+    
+    ## Return the min of the query
+    #
+    def getQueryMin( self ):
+        return self.range_query.getMin()
+    
+    ## Return the max of the query
+    #
+    def getQueryMax( self ):
+        return self.range_query.getMax()
+    
+    ## Return the strand of the query
+    #
+    def getQueryStrand( self ):
+        return self.range_query.getStrand()
+    
+    ## Return the length on the subject
+    #
+    def getLengthOnSubject(self):
+        return self.range_subject.getLength()
+    
+    ## Return the name of the subject
+    #
+    def getSubjectName( self ):
+        return self.range_subject.seqname
+    
+    ## Return the start of the subject
+    #
+    def getSubjectStart( self ):
+        return self.range_subject.start
+    
+    ## Return the end of the subject
+    #
+    def getSubjectEnd( self ):
+        return self.range_subject.end
+    
+    ## Return the min of the subject
+    #
+    def getSubjectMin( self ):
+        return self.range_subject.getMin()
+    
+    ## Return the max of the subject
+    #
+    def getSubjectMax( self ):
+        return self.range_subject.getMax()
+    
+    ## Return the strand of the subject
+    #
+    def getSubjectStrand( self ):
+        return self.range_subject.getStrand()
+    
+    ## Return the query as a Range instance
+    #
+    def getQueryAsRange( self ):
+        return self.range_query
+    
+    ## Return the subject as a Range instance
+    #
+    def getSubjectAsRange( self ):
+        return self.range_subject
+    
+    ## Set the name of the query
+    #
+    def setQueryName( self, name ):
+        self.range_query.seqname = name
+        
+    ## Set the start of the query
+    #
+    def setQueryStart( self, start ):
+        self.range_query.start = start
+        
+    ## Set the end of the query
+    #
+    def setQueryEnd( self, end ):
+        self.range_query.end = end
+    
+    ## Set the name of the subject
+    #
+    def setSubjectName( self, name ):
+        self.range_subject.seqname = name
+        
+    ## Set the start of the subject
+    #
+    def setSubjectStart( self, start ):
+        self.range_subject.start = start
+        
+    ## Set the end of the subject
+    #
+    def setSubjectEnd( self, end ):
+        self.range_subject.end = end
+        
+    ## Merge the instance with another Align instance
+    #
+    # @param o an Align instance
+    #
+    def merge(self, o):
+        if self.range_query.seqname != o.range_query.seqname \
+               or self.range_subject.seqname != o.range_subject.seqname:
+            return
+        self.range_query.merge(o.range_query)
+        self.range_subject.merge(o.range_subject)
+        self.score = max(self.score,o.score)
+        self.e_value = min(self.e_value,o.e_value)
+        self.identity = max(self.identity,o.identity)
+        
+    ## Return a Map instance with the subject mapped on the query
+    #
+    def getSubjectAsMapOfQuery(self):
+        iMap = Map()
+        iMap.name = self.range_subject.seqname
+        iMap.seqname = self.range_query.seqname
+        if self.range_subject.isOnDirectStrand():
+            iMap.start = self.range_query.start
+            iMap.end = self.range_query.end
+        else:
+            iMap.start = self.range_query.end
+            iMap.end = self.range_query.start
+        return iMap
+    
+    ## Return True if query is on direct strand
+    #
+    def isQueryOnDirectStrand( self ):
+        return self.range_query.isOnDirectStrand()
+    
+    ## Return True if subject is on direct strand
+    #
+    def isSubjectOnDirectStrand( self ):
+        return self.range_subject.isOnDirectStrand()
+    
+    ## Return True if query and subject are on the same strand, False otherwise
+    #
+    def areQrySbjOnSameStrand(self):
+        return self.isQueryOnDirectStrand() == self.isSubjectOnDirectStrand()
+    
+    ## Return False if query and subject are on the same strand, True otherwise
+    #
+    def areQrySbjOnOppositeStrands(self):
+        return not self.areQrySbjOnSameStrand()
+
+    ## Set attributes from string
+    #
+    # @param string a string formatted like queryName queryStart queryEnd subjectName subjectStart subjectEnd E-value score identity
+    # @param sep field separator
+    #
+    def setFromString(self, string, sep="\t"):
+        if string[-1] == "\n":
+            string = string[:-1]
+        self.setFromTuple( string.split(sep) )
+        
+    ## Return a first Map instance for the query and a second for the subject
+    #
+    def getMapsOfQueryAndSubject(self):
+        iMapQuery = Map( name="repet",
+                         seqname=self.range_query.seqname,
+                         start=self.range_query.start,
+                         end=self.range_query.end )
+        iMapSubject = Map( name="repet",
+                         seqname=self.range_subject.seqname,
+                         start=self.range_subject.start,
+                         end=self.range_subject.end )
+        return iMapQuery, iMapSubject
+    
+    ## Write query coordinates as Map in a file
+    #
+    # @param fileHandler: file handler of the file being filled
+    #
+    def writeSubjectAsMapOfQuery( self, fileHandler ):
+        m = self.getSubjectAsMapOfQuery()
+        m.write( fileHandler )
+        
+    ## Return a bin for fast database access
+    #
+    def getBin(self):
+        return self.range_query.getBin()
+    
+    ## Switch query and subject
+    #
+    def switchQuerySubject( self ):
+        tmpRange = self.range_query
+        self.range_query = self.range_subject
+        self.range_subject = tmpRange
+        if not self.isQueryOnDirectStrand():
+            self.reverse()
+            
+    ## Return True if the query overlaps with the query of another Align instance, False otherwise
+    #
+    def isQueryOverlapping( self, iAlign ):
+        return self.getQueryAsRange().isOverlapping( iAlign.getQueryAsRange() )
+    
+    ## Return True if the subject overlaps with the subject of another Align instance, False otherwise
+    #
+    def isSubjectOverlapping( self, iAlign ):
+        return self.getSubjectAsRange().isOverlapping( iAlign.getSubjectAsRange() )
+    
+    ## Return True if the Align instance overlaps with another Align instance, False otherwise
+    #
+    def isOverlapping( self, iAlign ):
+        if self.isQueryOverlapping( iAlign ) and self.isSubjectOverlapping( iAlign ):
+            return True
+        else:
+            return False
+        
+    ## Update the score
+    #
+    # @note the new score is the length on the query times the percentage of identity
+    #
+    def updateScore( self ):
+        newScore = self.getLengthOnQuery() * self.getIdentity() / 100.0
+        self.score = newScore
Binary file smart_toolShed/commons/core/coord/Align.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/AlignUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,359 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import os
+import sys
+import shutil
+from commons.core.coord.Align import Align
+
+
+## Static methods manipulating Align instances
+#
+class AlignUtils( object ):
+    
+    ## Return a list with Align instances from the given file
+    #
+    # @param inFile name of a file in the Align format
+    #
+    def getAlignListFromFile( inFile ):
+        lAlignInstances = []
+        inFileHandler = open( inFile, "r" )
+        while True:
+            line = inFileHandler.readline()
+            if line == "":
+                break
+            a = Align()
+            a.setFromString( line )
+            lAlignInstances.append( a )
+        inFileHandler.close()
+        return lAlignInstances
+
+    getAlignListFromFile = staticmethod( getAlignListFromFile )
+    
+    
+    ## Return a list with all the scores
+    #
+    # @param lAlignInstances: list of Align instances
+    #
+    def getListOfScores( lAlignInstances ):
+        lScores = []
+        for iAlign in lAlignInstances:
+            lScores.append( iAlign.score )
+        return lScores
+    
+    getListOfScores = staticmethod( getListOfScores )
+
+    
+    ## Return a list with all the scores from the given file
+    #
+    # @param inFile name of a file in the Align format
+    #
+    def getScoreListFromFile(inFile):
+        lScores = []
+        append = lScores.append
+        with open(inFile, "r") as inFileHandler:
+            line = inFileHandler.readline()
+            while line:
+                if line != "\n":
+                    append(int(line.split('\t')[7]))
+                line = inFileHandler.readline()
+        return lScores
+    
+    getScoreListFromFile = staticmethod( getScoreListFromFile )
+    
+    
+    ## for each line of a given Align file, write the coordinates on the query and the subject as two distinct lines in a Map file
+    #
+    # @param alignFile: name of the input Align file
+    # @param mapFile: name of the output Map file
+    #
+    def convertAlignFileIntoMapFileWithQueriesAndSubjects( alignFile, mapFile ):
+        alignFileHandler = open( alignFile, "r" )
+        mapFileHandler = open( mapFile, "w" )
+        iAlign = Align()
+        while True:
+            line = alignFileHandler.readline()
+            if line == "":
+                break
+            iAlign.setFromString( line )
+            iMapQ, iMapS = iAlign.getMapsOfQueryAndSubject()
+            iMapQ.write( mapFileHandler )
+            iMapS.write( mapFileHandler )
+        alignFileHandler.close()
+        mapFileHandler.close()
+        
+    convertAlignFileIntoMapFileWithQueriesAndSubjects = staticmethod( convertAlignFileIntoMapFileWithQueriesAndSubjects )
+    
+    
+    ## for each line of a given Align file, write the coordinates of the subject on the query as one line in a Map file
+    #
+    # @param alignFile: name of the input Align file
+    # @param mapFile: name of the output Map file
+    #
+    def convertAlignFileIntoMapFileWithSubjectsOnQueries( alignFile, mapFile ):
+        alignFileHandler = open( alignFile, "r" )
+        mapFileHandler = open( mapFile, "w" )
+        iAlign = Align()
+        while True:
+            line = alignFileHandler.readline()
+            if line == "":
+                break
+            iAlign.setFromString( line )
+            iMapQ = iAlign.getSubjectAsMapOfQuery()
+            iMapQ.write( mapFileHandler )
+        alignFileHandler.close()
+        mapFileHandler.close()
+        
+    convertAlignFileIntoMapFileWithSubjectsOnQueries = staticmethod( convertAlignFileIntoMapFileWithSubjectsOnQueries )
+    
+    
+    ## return a list of Align instances sorted in decreasing order according to their score, then their length on the query and finally their initial order
+    #
+    # @param lAligns: list of Align instances
+    #
+    def getAlignListSortedByDecreasingScoreThenLength( lAligns ):
+        return sorted( lAligns, key=lambda iAlign: ( 1 / float(iAlign.getScore()), 1 / float(iAlign.getLengthOnQuery()) ) )
+    
+    getAlignListSortedByDecreasingScoreThenLength = staticmethod( getAlignListSortedByDecreasingScoreThenLength )
+    
+    
+    ## Convert an Align file into a Path file
+    #
+    # @param alignFile string name of the input Align file
+    # @param pathFile string name of the output Path file
+    #
+    def convertAlignFileIntoPathFile( alignFile, pathFile ):
+        alignFileHandler = open( alignFile, "r" )
+        pathFileHandler = open( pathFile, "w" )
+        iAlign = Align()
+        countAlign = 0
+        while True:
+            line = alignFileHandler.readline()
+            if line == "":
+                break
+            countAlign += 1
+            iAlign.setFromString( line, "\t" )
+            pathFileHandler.write( "%i\t%s\n" % ( countAlign, iAlign.toString() ) )
+        alignFileHandler.close()
+        pathFileHandler.close()
+        
+    convertAlignFileIntoPathFile = staticmethod( convertAlignFileIntoPathFile )
+    
+    
+    ## Sort an Align file
+    #
+    def sortAlignFile( inFile, outFile="" ):
+        if outFile == "":
+            outFile = "%s.sort" % ( inFile )
+        prg = "sort"
+        cmd = prg
+        cmd += " -k 1,1 -k 4,4 -k 2,2n -k 3,3n -k 5,5n -k 6,6n -k 8,8n"
+        cmd += " %s" % ( inFile )
+        cmd += " > %s" % ( outFile )
+        exitStatus = os.system( cmd )
+        if exitStatus != 0:
+            msg = "ERROR: '%s' returned '%i'" % ( prg, exitStatus )
+            sys.stderr.write( "%s\n" % ( msg ) )
+            sys.exit( exitStatus )
+            
+    sortAlignFile = staticmethod( sortAlignFile )
+    
+    
+    ## Write Align instances contained in the given list
+    #
+    # @param lAlign a list of Align instances
+    # @param fileName name of the file to write the Align instances
+    # @param mode the open mode of the file ""w"" or ""a"" 
+    #
+    def writeListInFile( lAlign, fileName, mode="w" ):
+        fileHandler = open( fileName, mode )
+        for iAlign in lAlign:
+            iAlign.write( fileHandler )
+        fileHandler.close()
+        
+    writeListInFile = staticmethod( writeListInFile )
+
+        
+    ## Split a list of Align instances according to the name of the query
+    #
+    # @param lInAlign list of align instances
+    # @return lOutAlignList list of align instances lists 
+    #
+    def splitAlignListByQueryName( lInAlign ):
+        lSortedAlign = sorted(lInAlign, key=lambda o: o.range_query.seqname)
+        lOutAlignList = []
+        if len(lSortedAlign) != 0 :
+            lAlignForCurrentQuery = [] 
+            previousQuery = lSortedAlign[0].range_query.seqname
+            for align in lSortedAlign :
+                currentQuery = align.range_query.seqname
+                if previousQuery != currentQuery :
+                    lOutAlignList.append(lAlignForCurrentQuery)
+                    previousQuery = currentQuery 
+                    lAlignForCurrentQuery = []
+                lAlignForCurrentQuery.append(align)
+                    
+            lOutAlignList.append(lAlignForCurrentQuery)         
+                
+        return lOutAlignList
+    
+    splitAlignListByQueryName = staticmethod( splitAlignListByQueryName )
+    
+    
+    ## Create an Align file from each list of Align instances in the input list
+    #
+    # @param lAlignList list of lists with Align instances
+    # @param pattern string
+    # @param dirName string 
+    #
+    def createAlignFiles( lAlignList, pattern, dirName="" ):
+        savedDir = os.getcwd()
+        nbFiles = len(lAlignList)
+        countFile = 1
+        if dirName != "" :
+            try:
+                os.makedirs(dirName)
+            except:
+                pass
+            os.chdir(dirName)
+            
+        for lAlign in lAlignList:
+            fileName = "%s_%s.align" % (pattern, str(countFile).zfill(len(str(nbFiles))))
+            AlignUtils.writeListInFile(lAlign, fileName)
+            countFile += 1
+        os.chdir(savedDir)
+            
+    createAlignFiles = staticmethod( createAlignFiles )
+    
+    
+    ## Return a list with Align instances sorted by query name, subject name, query start, query end and score
+    #
+    def sortList( lAligns ):
+        return sorted( lAligns, key=lambda iAlign: ( iAlign.getQueryName(),
+                                                     iAlign.getSubjectName(),
+                                                     iAlign.getQueryStart(),
+                                                     iAlign.getQueryEnd(),
+                                                     iAlign.getScore() ) )
+        
+    sortList = staticmethod( sortList )
+    
+    
+    ## Return a list after merging all overlapping Align instances
+    #
+    def mergeList( lAligns ):
+        lMerged = []
+        
+        lSorted = AlignUtils.sortList( lAligns )
+        
+        prev_count = 0
+        for iAlign in lSorted:
+            if prev_count != len(lSorted):
+                for i in lSorted[ prev_count + 1: ]:
+                    if iAlign.isOverlapping( i ):
+                        iAlign.merge( i )
+                IsAlreadyInList = False
+                for newAlign in lMerged:
+                    if newAlign.isOverlapping( iAlign ):
+                        IsAlreadyInList = True
+                        newAlign.merge( iAlign )
+                        lMerged [ lMerged.index( newAlign ) ] = newAlign
+                if not IsAlreadyInList:
+                    lMerged.append( iAlign )
+                prev_count += 1
+                
+        return lMerged
+    
+    mergeList = staticmethod( mergeList )
+    
+    
+    ## Merge all Align instance in a given Align file
+    #
+    def mergeFile( inFile, outFile="" ):
+        if outFile == "":
+            outFile = "%s.merged" % ( inFile )
+        if os.path.exists( outFile ):
+            os.remove( outFile )
+            
+        tmpFile = "%s.sorted" % ( inFile )
+        AlignUtils.sortAlignFile( inFile, tmpFile )
+        
+        tmpF = open( tmpFile, "r" )
+        dQrySbj2Aligns = {}
+        prevPairQrySbj = ""
+        while True:
+            line = tmpF.readline()
+            if line == "":
+                break
+            iAlign = Align()
+            iAlign.setFromString( line )
+            pairQrySbj = "%s_%s" % ( iAlign.getQueryName(), iAlign.getSubjectName() )
+            if not dQrySbj2Aligns.has_key( pairQrySbj ):
+                if prevPairQrySbj != "":
+                    lMerged = AlignUtils.mergeList( dQrySbj2Aligns[ prevPairQrySbj ] )
+                    AlignUtils.writeListInFile( lMerged, outFile, "a" )
+                    del dQrySbj2Aligns[ prevPairQrySbj ]
+                    prevPairQrySbj = pairQrySbj
+                else:
+                    prevPairQrySbj = pairQrySbj
+                dQrySbj2Aligns[ pairQrySbj ] = []
+            dQrySbj2Aligns[ pairQrySbj ].append( iAlign )
+        lMerged = []
+        if len(dQrySbj2Aligns.keys()) > 0:
+            lMerged = AlignUtils.mergeList( dQrySbj2Aligns[ prevPairQrySbj ] )
+        AlignUtils.writeListInFile( lMerged, outFile, "a" )
+        tmpF.close()
+        os.remove( tmpFile )
+        
+    mergeFile = staticmethod( mergeFile )
+
+
+    ## Update the scores of each match in the input file
+    #
+    # @note the new score is the length on the query times the percentage of identity
+    #
+    def updateScoresInFile( inFile, outFile ):
+        inHandler = open( inFile, "r" )
+        outHandler = open( outFile, "w" )
+        iAlign = Align()
+        
+        while True:
+            line = inHandler.readline()
+            if line == "":
+                break
+            iAlign.reset()
+            iAlign.setFromString( line, "\t" )
+            iAlign.updateScore()
+            iAlign.write( outHandler )
+            
+        inHandler.close()
+        outHandler.close()
+        
+    updateScoresInFile = staticmethod( updateScoresInFile )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/ConvCoord.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,504 @@
+#!/usr/bin/env python
+
+##@file
+# Convert coordinates from chunks to chromosomes or the opposite.
+#
+# usage: ConvCoord.py [ options ]
+# options:
+#      -h: this help
+#      -i: input data with coordinates to convert (file or table)
+#      -f: input data format (default='align'/'path')
+#      -c: coordinates to convert (query, subject or both; default='q'/'s'/'qs')
+#      -m: mapping of chunks on chromosomes (format='map')
+#      -x: convert from chromosomes to chunks (opposite by default)
+#      -o: output data (file or table, same as input)
+#      -C: configuration file (for database connection)
+#      -v: verbosity level (default=0/1/2)
+
+
+import os
+import sys
+import getopt
+import time
+from commons.core.sql.DbFactory import DbFactory
+from commons.core.coord.MapUtils import MapUtils
+from commons.core.sql.TableMapAdaptator import TableMapAdaptator
+from commons.core.sql.TablePathAdaptator import TablePathAdaptator
+from commons.core.coord.PathUtils import PathUtils
+from commons.core.coord.Align import Align
+from commons.core.coord.Path import Path
+from commons.core.coord.Range import Range
+
+
+## Class to handle coordinate conversion
+#
+class ConvCoord( object ):
+    
+    ## Constructor
+    #
+    def __init__( self, inData="", mapData="", outData="", configFile="", verbosity=0):
+        self._inData = inData
+        self._formatInData = "align"
+        self._coordToConvert = "q"
+        self._mapData = mapData
+        self._mergeChunkOverlaps = True
+        self._convertChunks = True
+        self._outData = outData
+        self._configFile = configFile
+        self._verbose = verbosity
+        self._typeInData = "file"
+        self._typeMapData = "file"
+        self._tpa = None
+        if self._configFile != "" and os.path.exists(self._configFile):
+            self._iDb = DbFactory.createInstance(self._configFile)
+        else:
+            self._iDb = DbFactory.createInstance()
+        
+        
+    ## Display the help on stdout
+    #
+    def help( self ):
+        print
+        print "usage: ConvCoord.py [ options ]"
+        print "options:"
+        print "     -h: this help"
+        print "     -i: input data with coordinates to convert (file or table)"
+        print "     -f: input data format (default='align'/'path')"
+        print "     -c: coordinates to convert (query, subject or both; default='q'/'s'/'qs')"
+        print "     -m: mapping of chunks on chromosomes (format='map')"
+        print "     -M: merge chunk overlaps (default=yes/no)"
+        print "     -x: convert from chromosomes to chunks (opposite by default)"
+        print "     -o: output data (file or table, same as input)"
+        print "     -C: configuration file (for database connection)"
+        print "     -v: verbosity level (default=0/1/2)"
+        print
+        
+        
+    ## Set the attributes from the command-line
+    #
+    def setAttributesFromCmdLine( self ):
+        try:
+            opts, args = getopt.getopt(sys.argv[1:],"hi:f:c:m:M:xo:C:v:")
+        except getopt.GetoptError, err:
+            sys.stderr.write( "%s\n" % ( str(err) ) )
+            self.help(); sys.exit(1)
+        for o,a in opts:
+            if o == "-h":
+                self.help(); sys.exit(0)
+            elif o == "-i":
+                self.setInputData( a )
+            elif o == "-f":
+                self.setInputFormat( a )
+            elif o == "-c":
+                self.setCoordinatesToConvert( a )
+            elif o == "-m":
+                self.setMapData( a )
+            elif o == "-M":
+                self.setMergeChunkOverlaps( a )
+            elif o == "-o":
+                self.setOutputData( a )
+            elif o == "-C":
+                self.setConfigFile( a )
+            elif o == "-v":
+                self.setVerbosityLevel( a )
+                
+                
+    def setInputData( self, inData ):
+        self._inData = inData
+        
+    def setInputFormat( self, formatInData ):
+        self._formatInData = formatInData
+        
+    def setCoordinatesToConvert( self, coordToConvert ):
+        self._coordToConvert = coordToConvert
+        
+    def setMapData( self, mapData ):
+        self._mapData = mapData
+        
+    def setMergeChunkOverlaps( self, mergeChunkOverlaps ):
+        if mergeChunkOverlaps == "yes":
+            self._mergeChunkOverlaps = True
+        else:
+            self._mergeChunkOverlaps = False
+            
+    def setOutputData( self, outData ):
+        self._outData = outData
+        
+    def setConfigFile( self, configFile ):
+        self._configFile = configFile
+        
+    def setVerbosityLevel( self, verbose ):
+        self._verbose = int(verbose)
+        
+        
+    ## Check the attributes are valid before running the algorithm
+    #
+    def checkAttributes( self ):
+        if self._inData == "":
+            msg = "ERROR: missing input data (-i)"
+            sys.stderr.write( "%s\n" % ( msg ) )
+            self.help(); sys.exit(1)
+        if self._formatInData not in ["align","path"]:
+            msg = "ERROR: unrecognized format '%s' (-f)" % ( self._formatInData )
+            sys.stderr.write( "%s\n" % ( msg ) )
+            self.help(); sys.exit(1)
+        if self._configFile == "":
+            self._iDb = DbFactory.createInstance()
+        elif not os.path.exists( self._configFile ):
+            msg = "ERROR: configuration file '%s' doesn't exist" % ( self._configFile )
+            sys.stderr.write( "%s\n" % ( msg ) )
+            self.help(); sys.exit(1)
+        else:
+            self._iDb = DbFactory.createInstance(self._configFile)
+        if not os.path.exists( self._inData ) and not self._iDb.doesTableExist( self._inData ):
+            msg = "ERROR: input data '%s' doesn't exist" % ( self._inData )
+            sys.stderr.write( "%s\n" % ( msg ) )
+            self.help(); sys.exit(1)
+        if os.path.exists( self._inData ):
+            self._typeInData = "file"
+        elif self._iDb.doesTableExist( self._inData ):
+            self._typeInData = "table"
+        if self._coordToConvert == "":
+            msg = "ERROR: missing coordinates to convert (-c)"
+            sys.stderr.write( "%s\n" % ( msg ) )
+            self.help(); sys.exit(1)
+        if self._coordToConvert not in [ "q", "s", "qs" ]:
+            msg = "ERROR: unrecognized coordinates to convert '%s' (-c)" % ( self._coordToConvert )
+            sys.stderr.write( "%s\n" % ( msg ) )
+            self.help(); sys.exit(1)
+        if self._mapData == "":
+            msg = "ERROR: missing mapping coordinates of chunks on chromosomes (-m)"
+            sys.stderr.write( "%s\n" % ( msg ) )
+            self.help(); sys.exit(1)
+        if not os.path.exists( self._mapData ) and not self._iDb.doesTableExist( self._mapData ):
+            msg = "ERROR: mapping data '%s' doesn't exist" % ( self._mapData )
+            sys.stderr.write( "%s\n" % ( msg ) )
+            self.help(); sys.exit(1)
+        if os.path.exists( self._mapData ):
+            self._typeMapData = "file"
+        elif self._iDb.doesTableExist( self._mapData ):
+            self._typeMapData = "table"
+        if self._outData == "":
+            if self._convertChunks:
+                self._outData = "%s.onChr" % ( self._inData )
+            else:
+                self._outData = "%s.onChk" % ( self._inData )
+            if self._typeInData == "table":
+                self._outData = self._outData.replace(".","_")
+                
+                
+    ## Return a dictionary with the mapping of the chunks on the chromosomes
+    #
+    def getChunkCoordsOnChromosomes( self ):
+        if self._typeMapData == "file":
+            dChunks2CoordMaps = MapUtils.getDictPerNameFromMapFile( self._mapData )
+        elif self._typeMapData == "table":
+            tma = TableMapAdaptator( self._iDb, self._mapData )
+            dChunks2CoordMaps = tma.getDictPerName()
+        if self._verbose > 0:
+            msg = "nb of chunks: %i" % ( len(dChunks2CoordMaps.keys()) )
+            sys.stdout.write( "%s\n" % ( msg ) )
+        return dChunks2CoordMaps
+    
+    
+    def getRangeOnChromosome( self, chkRange, dChunks2CoordMaps ):
+        chrRange = Range()
+        chunkName = chkRange.seqname
+        chrRange.seqname = dChunks2CoordMaps[ chunkName ].seqname
+        if dChunks2CoordMaps[ chunkName ].start == 1:
+            chrRange.start = chkRange.start
+            chrRange.end = chkRange.end
+        else:
+            startOfChkOnChr = dChunks2CoordMaps[ chunkName ].start
+            chrRange.start = startOfChkOnChr + chkRange.start - 1
+            chrRange.end = startOfChkOnChr + chkRange.end - 1
+        return chrRange
+    
+    
+    def convCoordsChkToChrFromAlignFile( self, inFile, dChunks2CoordMaps ):
+        return self.convCoordsChkToChrFromAlignOrPathFile( inFile, dChunks2CoordMaps, "align" )
+    
+    
+    def convCoordsChkToChrFromPathFile( self, inFile, dChunks2CoordMaps ):
+        return self.convCoordsChkToChrFromAlignOrPathFile( inFile, dChunks2CoordMaps, "path" )
+    
+    
+    
+    ## Convert coordinates of a Path or Align file from chunks to chromosomes
+    #
+    def convCoordsChkToChrFromAlignOrPathFile( self, inFile, dChunks2CoordMaps, format ):
+        if self._verbose > 0:
+            msg = "start method 'convCoordsChkToChrFromAlignOrPathFile'"
+            sys.stdout.write( "%s\n" % ( msg ) )
+        outFile = "%s.tmp" % ( inFile )
+        inFileHandler = open( inFile, "r" )
+        outFileHandler = open( outFile, "w" )
+        if format == "align":
+            iObject = Align()
+        else:
+            iObject = Path()
+        countLine = 0
+        
+        while True:
+            line = inFileHandler.readline()
+            if line == "":
+                break
+            countLine += 1
+            iObject.setFromString( line )
+            if self._coordToConvert in [ "q", "qs" ]:
+                queryOnChr = self.getRangeOnChromosome( iObject.range_query, dChunks2CoordMaps )
+                iObject.range_query = queryOnChr
+            if self._coordToConvert in [ "s", "qs" ]:
+                subjectOnChr = self.getRangeOnChromosome( iObject.range_subject, dChunks2CoordMaps )
+                iObject.range_subject = subjectOnChr
+            iObject.write( outFileHandler )
+            iObject.reset()
+            
+        inFileHandler.close()
+        outFileHandler.close()
+        if self._verbose > 0:
+            msg = "end method 'convCoordsChkToChrFromAlignOrPathFile'"
+            sys.stdout.write( "%s\n" % ( msg ) )
+        return outFile
+    
+    ## Convert coordinates of a file from chunks to chromosomes
+    #
+    def convCoordsChkToChrFromFile( self, inFile, format, dChunks2CoordMaps ):
+        if self._verbose > 0:
+            msg = "start convCoordsChkToChrFromFile"
+            sys.stdout.write( "%s\n" % ( msg ) )
+        if format == "align":
+            tmpAlignFile = self.convCoordsChkToChrFromAlignFile( inFile, dChunks2CoordMaps )
+            tmpAlignTable = tmpAlignFile.replace(".","_").replace("-","_")
+            self._iDb.createTable( tmpAlignTable, "align", tmpAlignFile, True)
+            os.remove( tmpAlignFile )
+            self._iDb.removeDoublons( tmpAlignTable )
+            outTable = "%s_path" % ( tmpAlignTable )
+            self._iDb.convertAlignTableIntoPathTable( tmpAlignTable, outTable )
+            self._iDb.dropTable( tmpAlignTable )
+        elif format == "path":
+            tmpPathFile = self.convCoordsChkToChrFromPathFile( inFile, dChunks2CoordMaps )
+            outTable = tmpPathFile.replace(".","_").replace("-","_")
+            self._iDb.createTable( outTable, "path", tmpPathFile, True)
+            os.remove( tmpPathFile )
+        if self._verbose > 0:
+            msg = "end convCoordsChkToChrFromFile"
+            sys.stdout.write( "%s\n" % ( msg ) )
+        return outTable
+    
+    
+    ## Convert coordinates of a table from chunks to chromosomes
+    #
+    def convCoordsChkToChrFromTable( self, inTable, format, dChunks2CoordMaps ):
+        tmpFile = inTable
+        self._iDb.exportDataToFile( inTable, tmpFile, False )
+        outTable = self.convCoordsChkToChrFromFile( tmpFile, format, dChunks2CoordMaps )
+        os.remove( tmpFile )
+        return outTable
+    
+    
+    def getListsDirectAndReversePaths( self, lPaths ):
+        lDirectPaths = []
+        lReversePaths = []
+        for iPath in lPaths:
+            if iPath.isQueryOnDirectStrand() and iPath.isSubjectOnDirectStrand():
+                lDirectPaths.append( iPath )
+            else:
+                lReversePaths.append( iPath )
+        return lDirectPaths, lReversePaths
+    
+    
+    def mergePaths( self, lPaths, lIdsToInsert, lIdsToDelete, dOldIdToNewId ):
+        if len(lPaths) < 2:
+            lIdsToInsert.append( lPaths[0].id )
+            return
+        i = 0
+        while i < len(lPaths) - 1:
+            i += 1
+            if self._verbose > 1 and i==1 :
+                print lPaths[i-1]
+            if self._verbose > 1:
+                print lPaths[i]
+                sys.stdout.flush()
+            idPrev = lPaths[i-1].id
+            idNext = lPaths[i].id
+            if lPaths[i-1].canMerge( lPaths[i] ):
+                dOldIdToNewId[ idNext ] = idPrev
+                if idPrev not in lIdsToInsert:
+                    lIdsToInsert.append( idPrev )
+                if idNext not in lIdsToDelete:
+                    lIdsToDelete.append( idNext )
+                lPaths[i-1].merge( lPaths[i] )
+                del lPaths[i]
+                i -= 1
+                    
+                    
+    def insertPaths( self, lPaths, lIdsToInsert, dOldIdToNewId ):
+        for iPath in lPaths:
+            if dOldIdToNewId.has_key( iPath.id ):
+                iPath.id = dOldIdToNewId[ iPath.id ]
+            if iPath.id in lIdsToInsert:
+                self._tpa.insert( iPath )
+                
+                
+    ## Merge Path instances in a Path table when they correspond to chunk overlaps
+    #
+    def mergeCoordsOnChunkOverlaps( self, dChunks2CoordMaps, tmpPathTable ):
+        if self._verbose > 0:
+            msg = "start method 'mergeCoordsOnChunkOverlaps'"
+            sys.stdout.write( "%s\n" % ( msg ) )
+        self._tpa = TablePathAdaptator( self._iDb, tmpPathTable )
+        nbChunks = len(dChunks2CoordMaps.keys())
+        for numChunk in range(1,nbChunks):
+            chunkName1 = "chunk%s" % ( str(numChunk).zfill( len(str(nbChunks)) ) )
+            chunkName2 = "chunk%s" % ( str(numChunk+1).zfill( len(str(nbChunks)) ) )
+            if not dChunks2CoordMaps.has_key( chunkName2 ):
+                break
+            if self._verbose > 1:
+                msg = "try merge on '%s' and '%s'" % ( chunkName1, chunkName2 )
+                sys.stdout.write( "%s\n" % ( msg ) )
+                sys.stdout.flush()
+            chrName = dChunks2CoordMaps[ chunkName1 ].seqname
+            if dChunks2CoordMaps[ chunkName2 ].seqname != chrName:
+                if self._verbose > 1:
+                    msg = "not on same chromosome (%s != %s)" % ( dChunks2CoordMaps[ chunkName2 ].seqname, chrName )
+                    sys.stdout.write( "%s\n" % ( msg ) )
+                    sys.stdout.flush()
+                continue
+            minCoord = min( dChunks2CoordMaps[ chunkName1 ].end, dChunks2CoordMaps[ chunkName2 ].start )
+            maxCoord = max( dChunks2CoordMaps[ chunkName1 ].end, dChunks2CoordMaps[ chunkName2 ].start )
+            lPaths = self._tpa.getChainListOverlappingQueryCoord( chrName, minCoord, maxCoord )
+            if len(lPaths) == 0:
+                if self._verbose > 1:
+                    msg = "no overlapping matches on %s (%i->%i)" % ( chrName, minCoord, maxCoord )
+                    sys.stdout.write( "%s\n" % ( msg ) )
+                    sys.stdout.flush()
+                continue
+            if self._verbose > 1:
+                msg = "%i overlapping matche(s) on %s (%i->%i)" % ( len(lPaths), chrName, minCoord, maxCoord )
+                sys.stdout.write( "%s\n" % ( msg ) )
+                sys.stdout.flush()
+            lSortedPaths = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQueryThenIdentifier( lPaths )
+            lDirectPaths, lReversePaths = self.getListsDirectAndReversePaths( lSortedPaths )
+            lIdsToInsert = []
+            lIdsToDelete = []
+            dOldIdToNewId = {}
+            if len(lDirectPaths) > 0:
+                self.mergePaths( lDirectPaths, lIdsToInsert, lIdsToDelete, dOldIdToNewId )
+            if len(lReversePaths) > 0:
+                self.mergePaths( lReversePaths, lIdsToInsert, lIdsToDelete, dOldIdToNewId )
+            self._tpa.deleteFromIdList( lIdsToDelete )
+            self._tpa.deleteFromIdList( lIdsToInsert )
+            self.insertPaths( lDirectPaths, lIdsToInsert, dOldIdToNewId )
+            self.insertPaths( lReversePaths, lIdsToInsert, dOldIdToNewId )
+        if self._verbose > 0:
+            msg = "end method 'mergeCoordsOnChunkOverlaps'"
+            sys.stdout.write( "%s\n" % ( msg ) )
+            sys.stdout.flush()
+            
+            
+    def saveChrCoordsAsFile( self, tmpPathTable, outFile ):
+        self._iDb.exportDataToFile( tmpPathTable, tmpPathTable, False )
+        self._iDb.dropTable( tmpPathTable )
+        if self._formatInData == "align":
+            PathUtils.convertPathFileIntoAlignFile( tmpPathTable, outFile )
+            os.remove( tmpPathTable )
+        elif self._formatInData == "path":
+            os.rename( tmpPathTable, outFile )
+            
+            
+    def saveChrCoordsAsTable( self, tmpPathTable, outTable ):
+        if self._formatInData == "align":
+            self._iDb.convertPathTableIntoAlignTable( tmpPathTable, outTable )
+            self._iDb.dropTable( tmpPathTable )
+        elif self._formatInData == "path":
+            self._iDb.renameTable( tmpPathTable, outTable )
+            
+            
+    ## Convert coordinates from chunks to chromosomes
+    #
+    def convertCoordinatesFromChunksToChromosomes( self ):
+        dChunks2CoordMaps = self.getChunkCoordsOnChromosomes()
+        
+        if self._typeInData == "file":
+            tmpPathTable = self.convCoordsChkToChrFromFile( self._inData, self._formatInData, dChunks2CoordMaps )
+        elif self._typeInData == "table":
+            tmpPathTable = self.convCoordsChkToChrFromTable( self._inData, self._formatInData, dChunks2CoordMaps )
+            
+        if self._mergeChunkOverlaps:
+            self.mergeCoordsOnChunkOverlaps( dChunks2CoordMaps, tmpPathTable );
+            
+        if self._typeInData == "file":
+            self.saveChrCoordsAsFile( tmpPathTable, self._outData )
+        elif self._typeInData == "table":
+            self.saveChrCoordsAsTable( tmpPathTable, self._outData )
+            
+            
+    ## Convert coordinates from chromosomes to chunks
+    #
+    def convertCoordinatesFromChromosomesToChunks( self ):
+        msg = "ERROR: convert coordinates from chromosomes to chunks not yet available"
+        sys.stderr.write( "%s\n" % ( msg ) )
+        sys.exit(1)
+        
+        
+    ## Useful commands before running the program
+    #
+    def start( self ):
+        self.checkAttributes()
+        if self._verbose > 0:
+            msg = "START ConvCoord.py (%s)" % ( time.strftime("%m/%d/%Y %H:%M:%S") )
+            msg += "\ninput data: %s" % ( self._inData )
+            if self._typeInData == "file":
+                msg += " (file)\n"
+            else:
+                msg += " (table)\n"
+            msg += "format: %s\n" % ( self._formatInData )
+            msg += "coordinates to convert: %s\n" % ( self._coordToConvert )
+            msg += "mapping data: %s" % ( self._mapData )
+            if self._typeMapData == "file":
+                msg += " (file)\n"
+            else:
+                msg += " (table)\n"
+            if self._mergeChunkOverlaps:
+                msg += "merge chunk overlaps\n"
+            else:
+                msg += "don't merge chunk overlaps\n"
+            if self._convertChunks:
+                msg += "convert chunks to chromosomes\n"
+            else:
+                msg += "convert chromosomes to chunks\n"
+            msg += "output data: %s" % ( self._outData )
+            if self._typeInData == "file":
+                msg += " (file)\n"
+            else:
+                msg += " (table)\n"
+            sys.stdout.write( msg )
+            
+            
+    ## Useful commands before ending the program
+    #
+    def end( self ):
+        self._iDb.close()
+        if self._verbose > 0:
+            msg = "END ConvCoord.py (%s)" % ( time.strftime("%m/%d/%Y %H:%M:%S") )
+            sys.stdout.write( "%s\n" % ( msg ) )
+            
+            
+    ## Run the program
+    #
+    def run( self ):
+        self.start()
+        
+        if self._convertChunks:
+            self.convertCoordinatesFromChunksToChromosomes()
+        else:
+            self.convertCoordinatesFromChromosomesToChunks()
+            
+        self.end()
+        
+        
+if __name__ == "__main__":
+    i = ConvCoord()
+    i.setAttributesFromCmdLine()
+    i.run()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/Map.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,161 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.coord.Range import Range
+
+
+## Record a named region on a given sequence
+#
+class Map( Range ):
+    
+    ## Constructor
+    #
+    # @param name the name of the region
+    # @param seqname the name of the sequence
+    # @param start the start coordinate
+    # @param end the end coordinate
+    # 
+    def __init__(self, name="", seqname="", start=-1, end=-1):
+        self.name = name
+        Range.__init__( self, seqname, start, end )
+        
+    ## Equal operator
+    #
+    # @param o a Map instance
+    #    
+    def __eq__(self, o):
+        if self.name == o.name:
+            return Range.__eq__(self, o)
+        return False
+    
+    ## Return name
+    #
+    def getName( self ):
+        return self.name
+    
+    ## Set attributes from tuple
+    #
+    # @param tuple: a tuple with (name,seqname,start,end)
+    # 
+    def setFromTuple(self, tuple):
+        self.name = tuple[0]
+        Range.setFromTuple(self, tuple[1:])
+    
+    ## Set attributes from string
+    #
+    # @param string a string formatted like name<sep>seqname<sep>start<sep>end
+    # @param sep field separator
+    #
+    def setFromString(self, string, sep="\t"):
+        if string[-1] == "\n":
+            string = string[:-1]
+        self.setFromTuple( string.split(sep) )
+        
+    ## Reset
+    #
+    def reset(self):
+        self.setFromTuple( [ "", "", -1, -1 ] )
+        
+    ## Read attributes from a Map file
+    # 
+    # @param fileHandler: file handler of the file being read
+    # @return: 1 on success, 0 at the end of the file
+    #
+    def read(self, fileHandler):
+        self.reset()
+        line = fileHandler.readline()
+        if line == "":
+            return 0
+        tokens = line.split("\t")
+        if len(tokens) < len(self.__dict__.keys()):
+            return 0
+        self.setFromTuple(tokens)
+        return 1
+    
+    ## Return the attributes as a formatted string
+    #
+    def toString(self):
+        string = "%s" % (self.name)
+        string += "\t%s" % (Range.toString(self))
+        return string
+    
+    ## Write attributes into a Map file
+    #
+    # @param fileHandler: file handler of the file being filled
+    #
+    def write(self, fileHandler):
+        fileHandler.write("%s\n" % (self.toString()))
+        
+    ## Save attributes into a Map file
+    #
+    # @param file: name of the file being filled
+    #
+    def save(self, file):
+        fileHandler = open( file, "a" )
+        self.write( fileHandler )
+        fileHandler.close()
+        
+    ## Return a Range instance with the attributes
+    #
+    def getRange(self):
+        return Range( self.seqname, self.start, self.end)
+    
+    ## Remove in the instance the region overlapping with another Map instance
+    #
+    # @param o a Map instance
+    # 
+    def diff(self, o):
+        iRange = Range.diff(self, o.getRange())
+        new = Map()
+        if not iRange.isEmpty():
+            new.name = self.name
+            new.seqname = self.seqname
+            new.start = iRange.start
+            new.end = iRange.end
+        return new
+    
+    ## Write attributes in a Path file, the name being the subject and the rest the Range query
+    #
+    # @param fileHandler: file handler of a Path file
+    #
+    def writeAsQueryOfPath(self, fileHandler):
+        string = "0"
+        string += "\t%s" % ( self.seqname )
+        string += "\t%i" % ( self.getMin() )
+        string += "\t%i" % ( self.getMax() )
+        string += "\t%s" % ( self.name )
+        string += "\t0"
+        string += "\t0"
+        string += "\t0.0"
+        string += "\t0"
+        string += "\t0"
+        fileHandler.write( "%s\n" % ( string ) )
+        
Binary file smart_toolShed/commons/core/coord/Map.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/MapUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,246 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import sys
+import os
+from commons.core.coord.Map import Map
+from commons.core.coord.Set import Set
+try:
+    from commons.core.checker.CheckerUtils import CheckerUtils
+except ImportError:
+    pass
+
+
+## static methods manipulating Map instances
+#
+class MapUtils( object ):
+    
+    ## Return a list of Map instances sorted in increasing order according to the min, then the max, and finally their initial order
+    #
+    # @param lMaps list of Map instances
+    #
+    def getMapListSortedByIncreasingMinThenMax( lMaps ):
+        return sorted( lMaps, key=lambda iMap: ( iMap.getMin(), iMap.getMax() ) )    
+    
+    getMapListSortedByIncreasingMinThenMax = staticmethod( getMapListSortedByIncreasingMinThenMax )
+    
+    
+    ## Return a list of Map instances sorted in increasing order according to the name, then the seqname, then the min, then the max
+    #
+    # @param lMaps list of Map instances
+    #
+    def getMapListSortedByIncreasingNameThenSeqnameThenMinThenMax( lMaps ):
+        return sorted( lMaps, key=lambda iMap: ( iMap.getName(), iMap.getSeqname(), iMap.getMin(), iMap.getMax() ) )    
+    
+    getMapListSortedByIncreasingNameThenSeqnameThenMinThenMax = staticmethod( getMapListSortedByIncreasingNameThenSeqnameThenMinThenMax )
+    
+    
+    ## Return a dictionary which keys are Map names and values the corresponding Map instances
+    #
+    def getDictPerNameFromMapFile( mapFile ):
+        dName2Maps = {}
+        mapFileHandler = open( mapFile, "r" )
+        while True:
+            line = mapFileHandler.readline()
+            if line == "":
+                break
+            iMap = Map()
+            iMap.setFromString( line, "\t" )
+            if dName2Maps.has_key( iMap.name ):
+                if iMap == dName2Maps[ iMap.name ]:
+                    continue
+                else:
+                    msg = "ERROR: in file '%s' two different Map instances have the same name '%s'" % ( mapFile, iMap.name )
+                    sys.stderr.write( "%s\n" % ( msg ) )
+                    sys.exit(1)
+            dName2Maps[ iMap.name ] = iMap
+        mapFileHandler.close()
+        return dName2Maps
+    
+    getDictPerNameFromMapFile = staticmethod( getDictPerNameFromMapFile )
+
+    
+    ## Give a list of Set instances from a list of Map instances
+    #
+    # @param lMaps list of Map instances
+    # @return lSets list of Set instances
+    #
+    def mapList2SetList( lMaps ):
+        lSets = []
+        c = 0
+        for iMap in lMaps:
+            c += 1
+            iSet = Set()
+            iSet.id = c
+            iSet.name = iMap.getName()
+            iSet.seqname = iMap.getSeqname()
+            iSet.start = iMap.getStart()
+            iSet.end = iMap.getEnd()
+            lSets.append( iSet )
+        return lSets
+    
+    mapList2SetList = staticmethod( mapList2SetList )
+    
+    
+    ## Merge the Map instances in a Map file using 'mapOp'
+    #
+    def mergeCoordsInFile( inFile, outFile ):
+        if not sys.modules.has_key( "commons.core.checker.CheckerUtils" ):
+            msg = "WARNING: can't find module 'CheckerUtils'"
+            sys.stderr.write( "%s\n" % msg )
+        elif not CheckerUtils.isExecutableInUserPath( "mapOp" ):
+            msg = "WARNING: can't find executable 'mapOp'"
+            sys.stderr.write( "%s\n" % msg )
+        else:
+            cmd = "mapOp"
+            cmd += " -q %s" % ( inFile )
+            cmd += " -m"
+            cmd += " 2>&1 > /dev/null"
+            returnStatus = os.system( cmd )
+            if returnStatus != 0:
+                print "ERROR: mapOp returned %i" % ( returnStatus )
+                sys.exit(1)
+            os.rename( "%s.merge" % inFile,
+                       outFile )
+            
+    mergeCoordsInFile = staticmethod( mergeCoordsInFile )
+    
+    
+    ## Return a dictionary which keys are Map seqnames and values the corresponding Map instances
+    #
+    def getDictPerSeqNameFromMapFile( mapFile ):
+        dSeqName2Maps = {}
+        mapFileHandler = open( mapFile, "r" )
+        while True:
+            line = mapFileHandler.readline()
+            if line == "":
+                break
+            iMap = Map()
+            iMap.setFromString( line, "\t" )
+            if not dSeqName2Maps.has_key( iMap.seqname ):
+                dSeqName2Maps[ iMap.seqname ] = []
+            dSeqName2Maps[ iMap.seqname ].append( iMap )
+        mapFileHandler.close()
+        return dSeqName2Maps
+    
+    getDictPerSeqNameFromMapFile = staticmethod( getDictPerSeqNameFromMapFile )
+    
+    
+    ## Convert an Map file into a Set file
+    #
+    # @param mapFile string input map file name
+    # @param setFile string output set file name
+    #
+    def convertMapFileIntoSetFile( mapFileName, setFileName = "" ):
+        if setFileName == "":
+            setFileName = "%s.set" % mapFileName
+        mapFileHandler = open( mapFileName, "r" )
+        setFileHandler = open( setFileName, "w" )
+        iMap = Map()
+        count = 0
+        while True:
+            line = mapFileHandler.readline()
+            if line == "":
+                break
+            iMap.setFromString(line)
+            count += 1
+            iSet = Set()
+            iSet.id = count
+            iSet.name = iMap.getName()
+            iSet.seqname = iMap.getSeqname()
+            iSet.start = iMap.getStart()
+            iSet.end = iMap.getEnd()
+            iSet.write(setFileHandler)
+        mapFileHandler.close()
+        setFileHandler.close()
+        
+    convertMapFileIntoSetFile = staticmethod( convertMapFileIntoSetFile )
+    
+    ## Write Map instances contained in the given list
+    #
+    # @param lMaps list of Map instances
+    # @param fileName a file name
+    # @param mode the open mode of the file '"w"' or '"a"' 
+    #
+    def writeListInFile(lMaps, fileName, mode="w"):
+        fileHandler = open(fileName, mode)
+        for iMap in lMaps:
+            iMap.write(fileHandler)
+        fileHandler.close()
+        
+    writeListInFile = staticmethod( writeListInFile )
+
+    
+    ## Get the length of the shorter seq in map file
+    #
+    # @param mapFileName
+    # @param mode the open mode of the file '"w"' or '"a"' 
+    #
+    def getMinLengthOfMapFile(self, mapFileName):
+        fileHandler = open(mapFileName, "r")
+        line = fileHandler.readline()
+        start = int (line.split('\t')[2])
+        end = int (line.split('\t')[3])
+        min = end - start + 1
+        while True:
+            line = fileHandler.readline()
+            if line == "":
+                break
+            start = int (line.split('\t')[2])
+            end = int (line.split('\t')[3])
+            currentMin = end - start + 1
+            if min >= currentMin:
+                min = currentMin
+        fileHandler.close()
+        return min
+
+    ## Get the max length of the shorter seq in map file
+    #
+    # @param mapFileName
+    # @param mode the open mode of the file '"w"' or '"a"' 
+    #
+    def getMaxLengthOfMapFile(self, mapFileName):
+        fileHandler = open(mapFileName, "r")
+        line = fileHandler.readline()
+        start = int (line.split('\t')[2])
+        end = int (line.split('\t')[3])
+        max = end - start + 1
+        while True:
+            line = fileHandler.readline()
+            if line == "":
+                break
+            start = int (line.split('\t')[2])
+            end = int (line.split('\t')[3])
+            currentMax = end - start + 1
+            if max <= currentMax:
+                max = currentMax
+        fileHandler.close()
+        return max
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/Match.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,206 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import sys
+from commons.core.coord.Range import Range
+from commons.core.coord.Path import Path
+
+
+## Handle a chain of match(es) between two sequences, query and subject, with an identifier and the length of the input sequences
+#
+class Match( Path ):
+    
+    ## Constructor
+    #
+    def __init__(self):
+        Path.__init__(self)
+        self.query_length = -1
+        self.query_length_perc = -1    # length of the match on the query / length of the query
+        self.query_seqlength = -1
+        self.match_length_perc = -1    # length of the match on the query / total length of the subject
+        self.subject_length = -1
+        self.subject_length_perc = -1    # length of the match on the subject / length of the subject
+        self.subject_seqlength = -1
+        
+    ## Equal operator
+    #
+    def __eq__(self, o):
+        if o == None \
+        or self.query_length != o.query_length or self.query_length_perc != o.query_length_perc\
+        or self.query_seqlength != o.query_seqlength or self.subject_length != o.subject_length\
+        or self.subject_length_perc != o.subject_length_perc or self.subject_seqlength != o.subject_seqlength\
+        or self.match_length_perc != o.match_length_perc:
+            return False
+        return Path.__eq__(self, o)
+        
+    ## Return the length of the match on the query divided by the total length of the query
+    #
+    def getLengthPercOnQuery(self):
+        return self.query_length_perc
+    
+    ## Return the length of the match on the subject divided by the total length of the subject
+    #
+    def getLengthPercOnSubject(self):
+        return self.subject_length_perc
+    
+    ## Return the length of the match on the subject
+    #
+    def getLengthMatchOnSubject(self):
+        return self.subject_length
+    
+    ## Set attributes from a tuple
+    # 
+    # @param tuple: a tuple with (query name,query start,query end,
+    #  query length, query length perc (between 0-1), match length perc (between 0-1), subject name,
+    #  subject start,subject end,subject length, subject length percentage (between 0-1), e_value,score,identity,id)
+    #
+    def setFromTuple( self, tuple ):
+        queryStart = int(tuple[1])
+        queryEnd = int(tuple[2])
+        subjectStart = int(tuple[7])
+        subjectEnd = int(tuple[8])
+        if queryStart < queryEnd:
+            self.range_query = Range(tuple[0],queryStart,queryEnd)
+            self.range_subject = Range(tuple[6],subjectStart,subjectEnd)
+        else:
+            self.range_query = Range(tuple[0],queryEnd,queryStart)
+            self.range_subject = Range(tuple[6],subjectEnd,subjectStart)
+        self.query_length = int(tuple[3])
+        self.query_length_perc = float(tuple[4])
+        self.query_seqlength = int( self.query_length / self.query_length_perc )
+        self.match_length_perc = float(tuple[5])
+        self.subject_length = int(tuple[9])
+        self.subject_length_perc = float(tuple[10])
+        self.subject_seqlength = int( self.subject_length / self.subject_length_perc )
+        self.e_value = float(tuple[11])
+        self.score = float(tuple[12])
+        self.identity = float(tuple[13])
+        self.id = int(tuple[14])
+        
+    ## Reset
+    #
+    def reset( self ):
+        Path.reset( self )
+        self.query_length = -1
+        self.query_length_perc = -1
+        self.query_seqlength = -1
+        self.match_length_perc = -1
+        self.subject_length = -1
+        self.subject_length_perc = -1
+        self.subject_seqlength = -1
+        
+    ## Return a formated string of the attribute data
+    # 
+    def toString( self ):
+        string = "%s" % ( self.range_query.toString() )
+        string += "\t%i\t%f" % ( self.query_length,
+                                     self.query_length_perc )
+        string += "\t%f" % ( self.match_length_perc )
+        string += "\t%s" % ( self.range_subject.toString() )
+        string += "\t%i\t%f" % ( self.subject_length,
+                                 self.subject_length_perc )
+        string += "\t%g\t%i\t%f" % ( self.e_value,
+                                     self.score,
+                                     self.identity )
+        string += "\t%i" % ( self.id )
+        return string
+    
+    ## Return a Path instance
+    #
+    def getPathInstance( self ):
+        p = Path()
+        tuple = ( self.id,
+                  self.range_query.seqname,
+                  self.range_query.start,
+                  self.range_query.end,
+                  self.range_subject.seqname,
+                  self.range_subject.start,
+                  self.range_subject.end,
+                  self.e_value,
+                  self.score,
+                  self.identity )
+        p.setFromTuple( tuple )
+        return p
+    
+    ## Give information about a match whose query is included in the subject
+    # 
+    # @return string
+    #
+    def getQryIsIncluded( self ):
+        string = "query %s (%d bp: %d-%d) is contained in subject %s (%d bp: %d-%d): id=%.2f - %.3f - %.3f - %.3f" %\
+                 ( self.range_query.seqname, self.query_seqlength, self.range_query.start, self.range_query.end,
+                   self.range_subject.seqname, self.subject_seqlength, self.range_subject.start, self.range_subject.end,
+                   self.identity, self.query_length_perc, self.match_length_perc, self.subject_length_perc )
+        return string
+    
+    def increaseLengthPercOnQuery(self, coverage):
+        self.query_length_perc += coverage
+    
+    ## Compare the object with another match and see if they are equal
+    # (same identity, E-value and score + same subsequences whether in query or subject)
+    #
+    # @return True if objects are equals False otherwise
+    #
+    def isDoublonWith( self, match, verbose=0 ):
+
+        # if both matches have same identity, score and E-value
+        if self.identity == match.identity and self.score == match.score and self.e_value == match.e_value:
+
+            # if query and subject are identical
+            if ( self.range_query.seqname == match.range_query.seqname \
+                 and self.range_subject.seqname == match.range_subject.seqname ):
+
+                # if the coordinates are equal
+                if self.range_query.__eq__( match.range_query ) and self.range_subject.__eq__( match.range_subject ):
+                    return True
+
+                else:
+                    if verbose > 0: print "different coordinates"; sys.stdout.flush()
+                    return False
+
+            # if query and subject are reversed but identical
+            elif self.range_query.seqname == match.range_subject.seqname and self.range_subject.seqname == match.range_query.seqname:
+
+                # if the coordinates are equal
+                if self.range_query.__eq__( match.range_subject ) and self.range_subject.__eq__( match.range_query ):
+                    return True
+
+                else:
+                    if verbose > 0: print "different coordinates"; sys.stdout.flush()
+                    return False
+
+            else:
+                if verbose > 0: print "different sequence names"; sys.stdout.flush()
+                return False
+
+        else:
+            if verbose > 0: print "different match numbers"; sys.stdout.flush()
+            return False
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/MatchUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,288 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+import math
+import os
+import sys
+from commons.core.coord.Match import Match
+from commons.core.checker.RepetException import RepetException
+
+## Static methods for the manipulation of Match instances
+#
+class MatchUtils ( object ):
+    
+    ## Return a list with Match instances from the given file
+    #
+    # @param inFile name of a file in the Match format
+    # @return a list of Match instances
+    #
+    def getMatchListFromFile(inFile ):
+        lMatchInstances = []
+        inFileHandler = open( inFile, "r" )
+        while True:
+            line = inFileHandler.readline()
+            if line == "":
+                break
+            if line[0:10] == "query.name":
+                continue
+            m = Match()
+            m.setFromString( line )
+            lMatchInstances.append( m )
+        inFileHandler.close()
+        return lMatchInstances
+    
+    getMatchListFromFile = staticmethod( getMatchListFromFile )
+    
+    ##  Split a Match list in several Match lists according to the subject
+    #
+    #  @param lMatches a list of Match instances
+    #  @return a dictionary which keys are subject names and values Match lists
+    #
+    def getDictOfListsWithSubjectAsKey( lMatches ):
+        dSubject2MatchList = {}
+        for iMatch in lMatches:
+            if not dSubject2MatchList.has_key( iMatch.range_subject.seqname ):
+                dSubject2MatchList[ iMatch.range_subject.seqname ] = []
+            dSubject2MatchList[ iMatch.range_subject.seqname ].append( iMatch )
+        return dSubject2MatchList
+    
+    getDictOfListsWithSubjectAsKey = staticmethod( getDictOfListsWithSubjectAsKey )
+    
+    ##  Split a Match list in several Match lists according to the query
+    #
+    #  @param lMatches a list of Match instances
+    #  @return a dictionary which keys are query names and values Match lists
+    #
+    def getDictOfListsWithQueryAsKey ( lMatches ):
+        dQuery2MatchList = {}
+        for iMatch in lMatches:
+            if not dQuery2MatchList.has_key( iMatch.range_query.seqname ):
+                dQuery2MatchList[ iMatch.range_query.seqname ] = []
+            dQuery2MatchList[ iMatch.range_query.seqname ].append( iMatch )
+        return dQuery2MatchList
+    
+    getDictOfListsWithQueryAsKey = staticmethod( getDictOfListsWithQueryAsKey )   
+         
+    ## Write Match instances contained in the given list
+    #
+    # @param lMatches a list of Match instances
+    # @param fileName name of the file to write the Match instances
+    # @param mode the open mode of the file ""w"" or ""a"" 
+    #
+    def writeListInFile( lMatches, fileName, mode="w", header=None ):
+        fileHandler = open( fileName, mode )
+        if header:
+            fileHandler.write( header )
+        for iMatch in lMatches:
+            iMatch.write( fileHandler )
+        fileHandler.close()
+        
+    writeListInFile = staticmethod( writeListInFile )
+
+    ## Give path id list from a list of Match instances
+    #
+    # @param lMatch list of Match instances
+    #
+    # @return lId integer list
+    #
+    def getIdListFromMatchList(lMatch):
+        lId = []
+        for iMatch in lMatch:
+            lId.append(iMatch.id)
+        return lId
+    
+    getIdListFromMatchList = staticmethod(getIdListFromMatchList)
+    
+    ## Remove duplicated matches in a match list
+    # ## replace old PyRepet.MatchDB.rmvDoublons()
+    # @param lMatch list of Match instances
+    #
+    # @return lMatchesUniq match unique list
+    #
+    def rmvDuplicateMatches(lMatch):
+        lMatchesUniq = []
+        for match in lMatch:
+            if len(lMatchesUniq) == 0:
+                lMatchesUniq.append( match )
+            else:
+                nbDoublons = 0
+                for m in lMatchesUniq:
+                    if match.isDoublonWith( m ):
+                        nbDoublons += 1
+                if nbDoublons == 0:
+                    lMatchesUniq.append( match )
+                    
+        for match1 in lMatchesUniq:
+            for match2 in lMatchesUniq:
+                if match1.id != match2.id:
+                    if match1.isDoublonWith( match2 ):
+                        raise RepetException ( "*** Error: doublon not removed" )
+        return lMatchesUniq
+    
+    rmvDuplicateMatches = staticmethod(rmvDuplicateMatches)
+
+    ## Return the list of queries 'included' in subjects when two different databanks are used.
+    ##replace old pyRepet.MatchDB.filterDiffQrySbj()
+    #
+    # @param iBioseqDB bioseqDB databank of queries
+    #
+    # @param thresIdentity float identity threshold
+    #
+    # @param thresLength float length threshold
+    #
+    # @param verbose int verbosity
+    #
+    # @return lMatches match list to keep according to length and identity thresholds
+    #TODO: don't take into account match for sequence against itself. To do ? 
+    def filterDiffQrySbj(iBioseqDB, matchFile, thresIdentity=0.95, thresLength=0.98, verbose=0 ):
+        if verbose > 0:
+            print "filtering matches (id>=%.2f,qlgth>=%.2f)..." % ( thresIdentity, thresLength ); sys.stdout.flush()
+
+        thresIdentityPerc = math.floor( thresIdentity*100 )
+        lQryToKeep = []
+        dQry2Matches = MatchUtils.getDictOfListsWithQueryAsKey(MatchUtils.getMatchListFromFile(matchFile))
+
+        for seqH in iBioseqDB.idx.keys():
+            # keep it if it has no match
+            if not dQry2Matches.has_key( seqH ):
+                if seqH not in lQryToKeep:
+                    lQryToKeep.append( seqH )
+            else:
+                isConditionsMet = False
+                for match in dQry2Matches[ seqH ]:
+                    # check if they are above the thresholds
+                    if match.identity >= thresIdentityPerc and match.query_length_perc >= thresLength:
+                        isConditionsMet = True
+                        break
+                if not isConditionsMet and  seqH not in lQryToKeep:
+                    lQryToKeep.append( seqH )
+        return lQryToKeep
+    
+    filterDiffQrySbj = staticmethod(filterDiffQrySbj)
+    
+    ## Count the number of distinct matches involved in at least one match above the thresholds.
+    ##replace old pyRepet.coord.MatchDB.getNbDistinctSbjWithThres() and pyRepet.coord.MatchDB.getNbDistinctSbjWithThres()
+    # @param thresIdentity float identity threshold
+    #
+    # @param thresLength float length threshold 
+    #
+    def getNbDistinctSequencesInsideMatchesWithThresh(lMatches, thresIdentity=0.95, thresLength=0.98, whatToCount="query" ):
+        thresIdentityPerc = math.floor( thresIdentity*100 )
+        countSbj = 0
+        if whatToCount.lower() == "query":
+            dMatches = MatchUtils.getDictOfListsWithQueryAsKey(lMatches)
+        else:
+            dMatches = MatchUtils.getDictOfListsWithSubjectAsKey(lMatches)
+            
+        for qry in dMatches.keys():
+            countMatch = 0
+            for match in dMatches[ qry ]:
+                
+                if match.identity >= thresIdentityPerc and getattr(match,whatToCount.lower() +"_length_perc") >= thresLength:
+                    countMatch += 1
+            if countMatch > 0:
+                countSbj += 1
+        return countSbj
+    
+    getNbDistinctSequencesInsideMatchesWithThresh = staticmethod(getNbDistinctSequencesInsideMatchesWithThresh)
+    
+    ## Convert a 'match' file (output from Matcher) into an 'align' file
+    ## replace old parser.tab2align
+    #
+    # @param inFileName  a string input file name
+    #
+    def convertMatchFileToAlignFile(inFileName):
+        basename = os.path.splitext(inFileName)[0]
+        outFileName = "%s.align" % basename
+        outFile = open(outFileName, "w")
+        
+        lMatches = MatchUtils.getMatchListFromFile(inFileName) 
+        
+        for match in lMatches:
+            string = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % ( match.getQueryName(), match.getQueryStart(), match.getQueryEnd(), match.getSubjectName(), match.getSubjectStart(), match.getSubjectEnd(), match.getEvalue(), match.getScore(), match.getIdentity() )
+            outFile.write( string )
+            
+        outFile.close()
+        
+    convertMatchFileToAlignFile = staticmethod(convertMatchFileToAlignFile)
+    
+    ## Convert a 'match' file (output from Matcher) into an 'abc' file (MCL input file)
+    # Use coverage on query for arc value
+    #
+    # @param matchFileName string input match file name
+    # @param outFileName string output abc file name
+    # @param coverage float query coverage filter threshold
+    #
+    @staticmethod
+    def convertMatchFileIntoABCFileOnQueryCoverage(matchFileName, outFileName, coverage = 0):
+        with open(matchFileName) as inF:
+            with open(outFileName, "w") as outF:
+                inF.readline()
+                inLine = inF.readline()
+                while inLine:
+                    splittedLine = inLine.split("\t")
+                    if float(splittedLine[4]) >= coverage:
+                        outLine = "\t".join([splittedLine[0], splittedLine[6], splittedLine[4]])
+                        outLine += "\n"
+                        outF.write(outLine)
+                    inLine = inF.readline()
+
+    ## Adapt the path IDs as the input file is the concatenation of several 'Match' files, and remove the extra header lines. 
+    ## replace old parser.tabnum2id
+    #
+    # @param fileName  a string input file name
+    # @param  outputFileName  a string output file name (optional)
+    #
+    def generateMatchFileWithNewPathId(fileName, outputFileName=None):
+        if outputFileName is None:   
+            outFile = open(fileName, "w")
+        else:
+            outFile = open(outputFileName, "w")      
+        outFile.write("query.name\tquery.start\tquery.end\tquery.length\tquery.length.%\tmatch.length.%\tsubject.name\tsubject.start\tsubject.end\tsubject.length\tsubject.length.%\tE.value\tScore\tIdentity\tpath\n")
+      
+        lMatches = MatchUtils.getMatchListFromFile(fileName) 
+        count = 1
+        dMatchKeyIdcount = {}
+        
+        for match in lMatches:
+            key_id = str(match.getIdentifier()) + "-" + match.getQueryName() + "-" + match.getSubjectName()
+            if not key_id in dMatchKeyIdcount.keys():
+                newPath = count
+                count += 1
+                dMatchKeyIdcount[ key_id ] = newPath
+            else:
+                newPath = dMatchKeyIdcount[ key_id ]
+                
+            match.id = newPath
+            outFile.write( match.toString()+"\n" )  
+        outFile.close()
+        
+    generateMatchFileWithNewPathId = staticmethod(generateMatchFileWithNewPathId)
+     
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/MergedRange.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,98 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+## Record a region on multiple sequence using Path ID information
+#
+class MergedRange(object):
+    
+    ## Constructor
+    #
+    # @param lId list of Path ID
+    # @param start the start coordinate
+    # @param end the end coordinate
+    #
+    def __init__(self, lId = None, start = -1, end = -1):
+        self._lId = lId or []
+        self._start = start
+        self._end = end 
+        
+    ## Equal operator
+    #
+    # @param o a MergedRange instance
+    #        
+    def __eq__(self, o):
+        return o._lId == self._lId and o._start == self._start and o._end == self._end
+    
+    
+    ## Return True if the MergedRange instance overlaps with another MergedRange instance, False otherwise 
+    #
+    # @param o a MergedRange instance
+    # @return boolean False or True
+    #
+    def isOverlapping(self, o):
+        if o._start <= self._start and o._end >= self._end:
+            return True
+        if o._start >= self._start and o._start <= self._end or o._end >= self._start and o._end <= self._end:
+            return True
+        return False
+    
+    ## Merge coordinates and ID of two Merged Range     
+    #
+    # @param o a MergedRange instance
+    #
+    def merge(self, o):
+        self._start = min(self._start, o._start)
+        self._end = max(self._end, o._end)   
+        self._lId.extend(o._lId)
+        self._lId.sort()
+        
+    ## Set a Merged Range instance using a Match instance
+    #
+    # @param iMatch instance Match instance 
+    # 
+    def setFromMatch(self, iMatch):
+        self._lId= [iMatch.id]
+        self._start = iMatch.range_query.start
+        self._end = iMatch.range_query.end
+     
+    ## Get a Merged Range instance list using a Match instance list
+    #
+    # @param lIMatch list Match instance list
+    # @return lMergedRange list MergedRange instance list
+    #     
+    def getMergedRangeListFromMatchList(lIMatch):
+        lMergedRange = []
+        for iMatch in lIMatch:
+            mr = MergedRange()
+            mr.setFromMatch(iMatch)
+            lMergedRange.append(mr)
+        return lMergedRange
+    
+    getMergedRangeListFromMatchList = staticmethod(getMergedRangeListFromMatchList)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/Path.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,149 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.coord.Align import Align
+from commons.core.coord.Set import Set
+from commons.core.coord.Range import Range
+
+
+## Handle a match between two sequences, query and subject (pair of coordinates with E-value, score and identity) with an identifier
+#
+class Path( Align ):
+    
+    ## Constructor
+    #
+    # @param id identifier
+    # @param range_q: a Range instance for the query
+    # @param range_s: a Range instance for the subject
+    # @param e_value: E-value of the match 
+    # @param score: score of the match
+    # @param identity: identity percentage of the match
+    #
+    def __init__( self, id=-1, range_q=Range(), range_s=Range(), e_value=0, score=0, identity=0 ):
+        self.id = int( id )
+        Align.__init__( self, range_q, range_s, e_value, score, identity )
+        
+    ## Equal operator
+    #
+    def __eq__(self, o):
+        if o == None or self.id != o.id:
+            return False
+        return Align.__eq__(self, o)
+        
+    ## Set attributes from tuple
+    #
+    # @param tuple a tuple with (id,queryName,queryStart,queryEnd,subjectName,subjectStar,subjectEnd,E-value,score,identity)
+    # @note data are loaded such that the query is always on the direct strand
+    #
+    def setFromTuple(self, tuple):
+        self.id = int(tuple[0])
+        Align.setFromTuple(self, tuple[1:])
+        
+    ## Reset
+    #
+    def reset(self):
+        self.id = -1
+        Align.reset(self)
+        
+    ## Return the attributes as a formatted string
+    #
+    def toString(self):
+        string = "%i" % ( self.id )
+        string += "\t%s" % (Align.toString(self))
+        return string
+    
+    
+    ## Return the identifier of the Path instance
+    #
+    def getIdentifier( self ):
+        return self.id
+    
+    ## Return a Set instance with the subject mapped on the query
+    #
+    def getSubjectAsSetOfQuery(self):
+        iSet = Set()
+        iSet.id = self.id
+        iSet.name = self.range_subject.seqname
+        iSet.seqname = self.range_query.seqname
+        if self.range_subject.isOnDirectStrand():
+            iSet.start = self.range_query.start
+            iSet.end = self.range_query.end
+        else:
+            iSet.start = self.range_query.end
+            iSet.end = self.range_query.start
+        return iSet
+    
+    #TODO: add tests !!!!
+    #WARNING: subject always in direct strand !!!
+    ## Return a Set instance with the subject mapped on the query
+    #
+    def getQuerySetOfSubject(self):
+        iSet = Set()
+        iSet.id = self.id
+        iSet.name = self.range_query.seqname
+        iSet.seqname = self.range_subject.seqname
+        if self.range_subject.isOnDirectStrand():
+            iSet.start = self.range_subject.start
+            iSet.end = self.range_subject.end
+        else:
+            iSet.start = self.range_subject.end
+            iSet.end = self.range_subject.start
+        return iSet
+    
+    ## Return True if the instance can be merged with another Path instance, False otherwise
+    #
+    # @param o a Path instance
+    #
+    def canMerge(self, o):
+        return o.id != self.id \
+            and o.range_query.seqname == self.range_query.seqname \
+            and o.range_subject.seqname == self.range_subject.seqname \
+            and o.range_query.isOnDirectStrand() == self.range_query.isOnDirectStrand() \
+            and o.range_subject.isOnDirectStrand() == self.range_subject.isOnDirectStrand() \
+            and o.range_query.isOverlapping(self.range_query) \
+            and o.range_subject.isOverlapping(self.range_subject)
+            
+    ## Return an Align instance with the same attributes, except the identifier
+    #
+    def getAlignInstance(self):
+        iAlign = Align()
+        lAttributes = []
+        lAttributes.append( self.range_query.seqname )
+        lAttributes.append( self.range_query.start )
+        lAttributes.append( self.range_query.end )
+        lAttributes.append( self.range_subject.seqname )
+        lAttributes.append( self.range_subject.start )
+        lAttributes.append( self.range_subject.end )
+        lAttributes.append( self.e_value )
+        lAttributes.append( self.score )
+        lAttributes.append( self.identity )
+        iAlign.setFromTuple( lAttributes )
+        return iAlign
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/PathUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,858 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import os
+import sys
+import copy
+from commons.core.coord.Path import Path
+from commons.core.coord.SetUtils import SetUtils
+from commons.core.coord.Map import Map
+from commons.core.coord.AlignUtils import AlignUtils
+from commons.core.checker.RepetException import RepetDataException
+
+## Static methods for the manipulation of Path instances
+#
+class PathUtils ( object ):
+    
+    ## Change the identifier of each Set instance in the given list
+    #
+    # @param lPaths list of Path instances
+    # @param newId new identifier
+    #
+    def changeIdInList(lPaths, newId):
+        for iPath in lPaths:
+            iPath.id = newId
+            
+    changeIdInList = staticmethod( changeIdInList )
+    
+    
+    ## Return a list of Set instances containing the query range from a list of Path instances
+    # 
+    # @param lPaths a list of Path instances
+    #  
+    def getSetListFromQueries(lPaths):
+        lSets = []
+        for iPath in lPaths:
+            lSets.append( iPath.getSubjectAsSetOfQuery() )
+        return lSets
+    
+    getSetListFromQueries = staticmethod( getSetListFromQueries )
+    
+    #TODO: add tests !!!!
+    ## Return a list of Set instances containing the query range from a list of Path instances
+    # 
+    # @param lPaths a list of Path instances
+    #
+    @staticmethod
+    def getSetListFromSubjects(lPaths):
+        lSets = []
+        for iPath in lPaths:
+            lSets.append( iPath.getQuerySetOfSubject() )
+        return lSets
+    
+    
+    ## Return a sorted list of Range instances containing the subjects from a list of Path instances
+    # 
+    # @param lPaths a list of Path instances
+    # @note meaningful only if all Path instances have same identifier
+    #
+    def getRangeListFromSubjects( lPaths ):
+        lRanges = []
+        for iPath in lPaths:
+            lRanges.append( iPath.range_subject )
+        if lRanges[0].isOnDirectStrand():
+            return sorted( lRanges, key=lambda iRange: ( iRange.getMin(), iRange.getMax() ) )
+        else:
+            return sorted( lRanges, key=lambda iRange: ( iRange.getMax(), iRange.getMin() ) )
+        
+    getRangeListFromSubjects = staticmethod( getRangeListFromSubjects )
+    
+    
+    ## Return a tuple with min and max of query coordinates from Path instances in the given list
+    #
+    # @param lPaths a list of Path instances
+    #
+    def getQueryMinMaxFromPathList(lPaths):
+        qmin = -1
+        qmax = -1
+        for iPath in lPaths:
+            if qmin == -1:
+                qmin = iPath.range_query.start
+            qmin = min(qmin, iPath.range_query.getMin())
+            qmax = max(qmax, iPath.range_query.getMax())
+        return (qmin, qmax)
+    
+    getQueryMinMaxFromPathList = staticmethod( getQueryMinMaxFromPathList )
+    
+    
+    ## Return a tuple with min and max of subject coordinates from Path instances in the given list
+    #
+    # @param lPaths lists of Path instances
+    #
+    def getSubjectMinMaxFromPathList(lPaths):
+        smin = -1
+        smax = -1
+        for iPath in lPaths:
+            if smin == -1:
+                smin = iPath.range_subject.start
+            smin = min(smin, iPath.range_subject.getMin())
+            smax = max(smax, iPath.range_subject.getMax())
+        return (smin, smax)
+    
+    getSubjectMinMaxFromPathList = staticmethod( getSubjectMinMaxFromPathList )
+    
+    
+    ## Return True if the query range of any Path instance from the first list overlaps with the query range of any Path instance from the second list
+    #
+    #  @param lPaths1: list of Path instances
+    #  @param lPaths2: list of Path instances
+    #  @return boolean
+    #  
+    def areQueriesOverlappingBetweenPathLists( lPaths1, lPaths2 ):
+        lSortedPaths1 = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( lPaths1 )
+        lSortedPaths2 = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( lPaths2 )
+        i = 0
+        j = 0
+        while i != len(lSortedPaths1):
+            while j != len(lSortedPaths2):
+                if not lSortedPaths1[i].range_query.isOverlapping( lSortedPaths2[j].range_query ):
+                    j += 1
+                else:
+                    return True
+            i += 1
+        return False
+    
+    areQueriesOverlappingBetweenPathLists = staticmethod( areQueriesOverlappingBetweenPathLists )
+    
+
+    ## Show Path instances contained in the given list
+    #
+    # @param lPaths a list of Path instances
+    #      
+    def showList(lPaths):
+        for iPath in lPaths:
+            iPath.show()
+            
+    showList = staticmethod( showList )
+    
+    
+    ## Write Path instances contained in the given list
+    #
+    # @param lPaths a list of Path instances
+    # @param fileName name of the file to write the Path instances
+    # @param mode the open mode of the file ""w"" or ""a"" 
+    #
+    def writeListInFile(lPaths, fileName, mode="w"):
+        AlignUtils.writeListInFile(lPaths, fileName, mode)
+        
+    writeListInFile = staticmethod( writeListInFile )
+    
+    
+    ## Return new list of Path instances with no duplicate
+    #
+    # @param lPaths a list of Path instances
+    # @param useOnlyCoord boolean if True, check only coordinates and sequence names
+    # @return lUniqPaths a path instances list
+    #
+    def getPathListWithoutDuplicates(lPaths, useOnlyCoord = False):
+        if len(lPaths) < 2:
+            return lPaths
+        lSortedPaths = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQueryThenIdentifier( lPaths )
+        lUniqPaths = [ lSortedPaths[0] ]
+        if useOnlyCoord:
+            for iPath in lSortedPaths[1:]:
+                if iPath.range_query.start != lUniqPaths[-1].range_query.start \
+                or iPath.range_query.end != lUniqPaths[-1].range_query.end \
+                or iPath.range_query.seqname != lUniqPaths[-1].range_query.seqname \
+                or iPath.range_subject.start != lUniqPaths[-1].range_subject.start \
+                or iPath.range_subject.end != lUniqPaths[-1].range_subject.end \
+                or iPath.range_subject.seqname != lUniqPaths[-1].range_subject.seqname:
+                    lUniqPaths.append( iPath )
+        else:
+            for iPath in lSortedPaths[1:]:
+                if iPath != lUniqPaths[-1]:
+                    lUniqPaths.append( iPath )
+        return lUniqPaths
+    
+    getPathListWithoutDuplicates = staticmethod( getPathListWithoutDuplicates )
+    
+    
+    def getPathListWithoutDuplicatesOnQueryCoord(lPaths):
+        if len(lPaths) < 2:
+            return lPaths
+        lSortedPaths = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQueryThenIdentifier( lPaths )
+        lUniqPaths = [ lSortedPaths[0] ]
+        for iPath in lSortedPaths[1:]:
+            if iPath.range_query.start != lUniqPaths[-1].range_query.start \
+            or iPath.range_query.end != lUniqPaths[-1].range_query.end \
+            or iPath.range_query.seqname != lUniqPaths[-1].range_query.seqname:
+                lUniqPaths.append( iPath )
+        return lUniqPaths
+    
+    getPathListWithoutDuplicatesOnQueryCoord = staticmethod(getPathListWithoutDuplicatesOnQueryCoord)
+    
+    
+    ##  Split a Path list in several Path lists according to the identifier
+    #
+    #  @param lPaths a list of Path instances
+    #  @return a dictionary which keys are identifiers and values Path lists
+    #
+    def getDictOfListsWithIdAsKey( lPaths ):
+        dId2PathList = {}
+        for iPath in lPaths:
+            if dId2PathList.has_key( iPath.id ):
+                dId2PathList[ iPath.id ].append( iPath )
+            else:
+                dId2PathList[ iPath.id ] = [ iPath ]
+        return dId2PathList
+    
+    getDictOfListsWithIdAsKey = staticmethod( getDictOfListsWithIdAsKey )
+    
+    
+    ##  Split a Path file in several Path lists according to the identifier
+    #
+    #  @param pathFile name of the input Path file
+    #  @return a dictionary which keys are identifiers and values Path lists
+    #
+    def getDictOfListsWithIdAsKeyFromFile( pathFile ):
+        dId2PathList = {}
+        pathFileHandler = open( pathFile, "r" )
+        while True:
+            line = pathFileHandler.readline()
+            if line == "":
+                break
+            iPath = Path()
+            iPath.setFromString( line )
+            if dId2PathList.has_key( iPath.id ):
+                dId2PathList[ iPath.id ].append( iPath )
+            else:
+                dId2PathList[ iPath.id ] = [ iPath ]
+        pathFileHandler.close()
+        return dId2PathList
+    
+    getDictOfListsWithIdAsKeyFromFile = staticmethod( getDictOfListsWithIdAsKeyFromFile )
+    
+    
+    ## Return a list of Path list(s) obtained while splitting a list of connected Path instances according to another based on query coordinates
+    #  
+    # @param lToKeep: a list of Path instances to keep (reference)
+    # @param lToUnjoin: a list of Path instances to unjoin
+    # @return: list of Path list(s) (can be empty if one of the input lists is empty)
+    # @warning: all the path instances in a given list MUST be connected (i.e. same identifier)
+    # @warning: all the path instances in a given list MUST NOT overlap neither within each other nor with the Path instances of the other list
+    #
+    def getPathListUnjoinedBasedOnQuery( lToKeep, lToUnjoin ):
+        lSortedToKeep = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( lToKeep )
+        lSortedToUnjoin = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( lToUnjoin )
+        if lToUnjoin == []:
+            return []
+        if lToKeep == []:
+            return [ lToUnjoin ]
+        
+        lLists = []
+        k = 0
+        while k < len(lSortedToKeep):
+            j1 = 0
+            while j1 < len(lSortedToUnjoin) and lSortedToKeep[k].range_query.getMin() > lSortedToUnjoin[j1].range_query.getMax():
+                j1 += 1
+            if j1 == len(lSortedToUnjoin):
+                break
+            if j1 != 0:
+                lLists.append( lSortedToUnjoin[:j1] )
+                del lSortedToUnjoin[:j1]
+                j1 = 0
+            if k+1 == len(lSortedToKeep):
+                break
+            j2 = j1
+            if j2 < len(lSortedToUnjoin) and lSortedToKeep[k+1].range_query.getMin() > lSortedToUnjoin[j2].range_query.getMax():
+                while j2 < len(lSortedToUnjoin) and lSortedToKeep[k+1].range_query.getMin() > lSortedToUnjoin[j2].range_query.getMax():
+                    j2 += 1
+                lLists.append( lSortedToUnjoin[j1:j2] )
+                del lSortedToUnjoin[j1:j2]
+            k += 1
+            
+        if lLists != [] or k == 0:
+            lLists.append( lSortedToUnjoin )
+        return lLists
+    
+    getPathListUnjoinedBasedOnQuery = staticmethod( getPathListUnjoinedBasedOnQuery )
+    
+    
+    ## Return the identity of the Path list, the identity of each instance being weighted by the length of each query range
+    #  All Paths should have the same query and subject.
+    #  The Paths are merged using query coordinates only.
+    #
+    # @param lPaths list of Path instances
+    #
+    def getIdentityFromPathList( lPaths, checkSubjects=True ):
+        if len( PathUtils.getListOfDistinctQueryNames( lPaths ) ) > 1:
+            msg = "ERROR: try to compute identity from Paths with different queries"
+            sys.stderr.write( "%s\n" % msg )
+            sys.stderr.flush()
+            raise Exception
+        if checkSubjects and len( PathUtils.getListOfDistinctSubjectNames( lPaths ) ) > 1:
+            msg = "ERROR: try to compute identity from Paths with different subjects"
+            sys.stderr.write( "%s\n" % msg )
+            sys.stderr.flush()
+            raise Exception
+        identity = 0
+        lMergedPaths = PathUtils.mergePathsInListUsingQueryCoordsOnly( lPaths )
+        lQuerySets = PathUtils.getSetListFromQueries( lMergedPaths )
+        lMergedQuerySets = SetUtils.mergeSetsInList( lQuerySets )
+        totalLengthOnQry = SetUtils.getCumulLength( lMergedQuerySets )
+        for iPath in lMergedPaths:
+            identity += iPath.identity * iPath.getLengthOnQuery()
+        weightedIdentity = identity / float(totalLengthOnQry)
+        if weightedIdentity < 0:
+            msg = "ERROR: weighted identity '%.2f' outside range" % weightedIdentity
+            sys.stderr.write("%s\n" % msg)
+            sys.stderr.flush()
+            raise Exception
+        elif weightedIdentity > 100:
+            msg = "ERROR: weighted identity '%.2f' outside range" % weightedIdentity
+            sys.stderr.write("%s\n" % msg)
+            sys.stderr.flush()
+            raise RepetDataException(msg)
+        return weightedIdentity
+    
+    getIdentityFromPathList = staticmethod( getIdentityFromPathList )
+    
+    
+    ## Return a list of Path instances sorted in increasing order according to the min of the query, then the max of the query, and finally their initial order.
+    #
+    # @param lPaths list of Path instances
+    #
+    def getPathListSortedByIncreasingMinQueryThenMaxQuery(lPaths):
+        return sorted( lPaths, key=lambda iPath: ( iPath.getQueryMin(), iPath.getQueryMax() ) )
+    
+    getPathListSortedByIncreasingMinQueryThenMaxQuery = staticmethod( getPathListSortedByIncreasingMinQueryThenMaxQuery )
+    
+    
+    ## Return a list of Path instances sorted in increasing order according to the min of the query, then the max of the query, then their identifier, and finally their initial order.
+    #
+    # @param lPaths list of Path instances
+    #
+    def getPathListSortedByIncreasingMinQueryThenMaxQueryThenIdentifier(lPaths):
+        return sorted( lPaths, key=lambda iPath: ( iPath.getQueryMin(), iPath.getQueryMax(), iPath.getIdentifier() ) )
+    
+    getPathListSortedByIncreasingMinQueryThenMaxQueryThenIdentifier = staticmethod( getPathListSortedByIncreasingMinQueryThenMaxQueryThenIdentifier )
+    
+    
+    ## Return a list of Path instances sorted in increasing order according to the min of the query, then the max of the query, then the min of the subject, then the max of the subject and finally their initial order.
+    #
+    # @param lPaths list of Path instances
+    #
+    @staticmethod
+    def getPathListSortedByIncreasingMinQueryThenMaxQueryThenMinSubjectThenMaxSubject(lPaths):
+        return sorted(lPaths, key=lambda iPath: (iPath.getQueryMin(), iPath.getQueryMax(), iPath.getSubjectMin(), iPath.getSubjectMax()))
+    
+    
+    ## Return a list of the distinct identifiers
+    #
+    # @param lPaths list of Path instances
+    #
+    def getListOfDistinctIdentifiers( lPaths ):
+        sDistinctIdentifiers = set()
+        for iPath in lPaths:
+            sDistinctIdentifiers.add(iPath.id)
+        return list(sDistinctIdentifiers)
+    
+    getListOfDistinctIdentifiers = staticmethod( getListOfDistinctIdentifiers )
+    
+    
+    ## Return a list of the distinct query names present in the collection
+    #
+    # @param lPaths list of Path instances
+    #
+    def getListOfDistinctQueryNames( lPaths ):
+        sDistinctQueryNames = set()
+        for iPath in lPaths:
+            sDistinctQueryNames.add(iPath.range_query.seqname)
+        return list(sDistinctQueryNames)
+    
+    getListOfDistinctQueryNames = staticmethod( getListOfDistinctQueryNames )
+    
+    
+    ## Return a list of the distinct subject names present in the collection
+    #
+    # @param lPaths list of Path instances
+    #
+    def getListOfDistinctSubjectNames( lPaths ):
+        sDistinctSubjectNames = set()
+        for iPath in lPaths:
+            sDistinctSubjectNames.add(iPath.range_subject.seqname)
+        return list(sDistinctSubjectNames)
+    
+    getListOfDistinctSubjectNames = staticmethod( getListOfDistinctSubjectNames )
+    
+    
+    ## Return a list of lists containing query coordinates of the connections sorted in increasing order.
+    #
+    # @param lConnectedPaths: list of Path instances having the same identifier
+    # @param minLength: threshold below which connections are not reported (default= 0 bp)
+    # @note: return only connections longer than threshold
+    # @note: if coordinate on query ends at 100, return 101
+    # @warning: Path instances MUST be sorted in increasing order according to query coordinates
+    # @warning: Path instances MUST be on direct query strand (and maybe on reverse subject strand)
+    #
+    def getListOfJoinCoordinatesOnQuery(lConnectedPaths, minLength=0):
+        lJoinCoordinates = []
+        for i in xrange(1,len(lConnectedPaths)):
+            startJoin = lConnectedPaths[i-1].range_query.end
+            endJoin = lConnectedPaths[i].range_query.start
+            if endJoin - startJoin + 1 > minLength:
+                lJoinCoordinates.append( [ startJoin + 1, endJoin - 1 ] )
+        return lJoinCoordinates
+
+    getListOfJoinCoordinatesOnQuery = staticmethod( getListOfJoinCoordinatesOnQuery )
+    
+    
+    ## Return the length on the query of all Path instance in the given list
+    #
+    # @param lPaths list of Path instances
+    # @note overlapping ranges are not summed but truncated.
+    #
+    def getLengthOnQueryFromPathList( lPaths ):
+        lSets = PathUtils.getSetListFromQueries( lPaths )
+        lMergedSets = SetUtils.mergeSetsInList( lSets )
+        length = SetUtils.getCumulLength( lMergedSets )
+        return length
+
+    getLengthOnQueryFromPathList = staticmethod( getLengthOnQueryFromPathList )
+    
+    
+    ## Convert a Path file into an Align file
+    #
+    # @param pathFile: name of the input Path file
+    # @param alignFile: name of the output Align file
+    #
+    def convertPathFileIntoAlignFile(pathFile, alignFile):
+        pathFileHandler = open( pathFile, "r" )
+        alignFileHandler = open( alignFile, "w" )
+        iPath = Path()
+        while True:
+            line = pathFileHandler.readline()
+            if line == "":
+                break
+            iPath.setFromString( line )
+            iAlign = iPath.getAlignInstance()
+            iAlign.write( alignFileHandler )
+        pathFileHandler.close()
+        alignFileHandler.close()
+        
+    convertPathFileIntoAlignFile = staticmethod( convertPathFileIntoAlignFile )
+    
+    #TODO: duplicated method => to rename with the name of the next method (which is called) ?
+    ## Convert a Path File into a Map file with query coordinates only
+    #
+    # @param pathFile: name of the input Path file
+    # @param mapFile: name of the output Map file
+    #
+    def convertPathFileIntoMapFileWithQueryCoordsOnly( pathFile, mapFile ):
+        pathFileHandler = open( pathFile, "r" )
+        mapFileHandler = open( mapFile, "w" )
+        p = Path()
+        while True:
+            line = pathFileHandler.readline()
+            if line == "":
+                break
+            p.reset()
+            p.setFromTuple( line.split("\t") )
+            p.writeSubjectAsMapOfQuery( mapFileHandler )
+        pathFileHandler.close()
+        mapFileHandler.close()
+        
+    convertPathFileIntoMapFileWithQueryCoordsOnly = staticmethod( convertPathFileIntoMapFileWithQueryCoordsOnly )
+    
+    
+    ## for each line of a given Path file, write the coordinates of the subject on the query as one line in a Map file
+    #
+    # @param pathFile: name of the input Path file
+    # @param mapFile: name of the output Map file
+    #
+    def convertPathFileIntoMapFileWithSubjectsOnQueries( pathFile, mapFile ):
+        PathUtils.convertPathFileIntoMapFileWithQueryCoordsOnly( pathFile, mapFile )
+    convertPathFileIntoMapFileWithSubjectsOnQueries = staticmethod( convertPathFileIntoMapFileWithSubjectsOnQueries )
+    
+    
+    ## Merge matches on queries
+    #
+    # @param inFile: name of the input Path file
+    # @param outFile: name of the output Path file
+    #
+    def mergeMatchesOnQueries(inFile, outFile):
+        mapFile = "%s.map" % ( inFile )
+        PathUtils.convertPathFileIntoMapFileWithQueryCoordsOnly( inFile, mapFile )
+        cmd = "mapOp"
+        cmd += " -q %s" % ( mapFile )
+        cmd += " -m"
+        cmd += " 2>&1 > /dev/null"
+        exitStatus = os.system( cmd )
+        if exitStatus != 0:
+            print "ERROR: mapOp returned %i" % ( exitStatus )
+            sys.exit(1)
+        os.remove( mapFile )
+        mergeFile = "%s.merge" % ( mapFile )
+        mergeFileHandler = open( mergeFile, "r" )
+        outFileHandler = open( outFile, "w" )
+        m = Map()
+        while True:
+            line = mergeFileHandler.readline()
+            if line == "":
+                break
+            m.reset()
+            m.setFromString( line, "\t" )
+            m.writeAsQueryOfPath( outFileHandler )
+        mergeFileHandler.close()
+        os.remove( mergeFile )
+        outFileHandler.close()
+        
+    mergeMatchesOnQueries = staticmethod( mergeMatchesOnQueries )
+    
+    
+    ## Filter chains of Path(s) which length is below a given threshold
+    #
+    # @param lPaths: list of Path instances
+    # @param minLengthChain: minimum length of a chain to be kept
+    # @note: a chain may contain a single Path instance
+    # @return: a list of Path instances
+    #
+    def filterPathListOnChainLength( lPaths, minLengthChain ):
+        lFilteredPaths = []
+        dPathnum2Paths = PathUtils.getDictOfListsWithIdAsKey( lPaths )
+        for pathnum in dPathnum2Paths.keys():
+            length = PathUtils.getLengthOnQueryFromPathList( dPathnum2Paths[ pathnum ] )
+            if length >= minLengthChain:
+                lFilteredPaths += dPathnum2Paths[ pathnum ]
+        return lFilteredPaths
+    
+    filterPathListOnChainLength = staticmethod( filterPathListOnChainLength )
+    
+    
+    ## Return a Path list from a Path file
+    #
+    # @param pathFile string name of a Path file
+    # @return a list of Path instances
+    #
+    def getPathListFromFile( pathFile ):
+        lPaths = []
+        pathFileHandler = open( pathFile, "r" )
+        while True:
+            line = pathFileHandler.readline()
+            if line == "":
+                break
+            iPath = Path()
+            iPath.setFromString( line )
+            lPaths.append( iPath )
+        pathFileHandler.close()
+        return lPaths
+    
+    getPathListFromFile = staticmethod( getPathListFromFile )
+    
+    
+    ## Convert a chain into a 'pathrange'
+    #
+    # @param lPaths a list of Path instances with the same identifier
+    # @note: the min and max of each Path is used
+    #
+    def convertPathListToPathrange( lPaths ):
+        if len(lPaths) == 0:
+            return
+        if len(lPaths) == 1:
+            return lPaths[0]
+        iPathrange = copy.deepcopy( lPaths[0] )
+        iPathrange.identity = lPaths[0].identity * lPaths[0].getLengthOnQuery()
+        cumulQueryLength = iPathrange.getLengthOnQuery()
+        for iPath in lPaths[1:]:
+            if iPath.id != iPathrange.id:
+                msg = "ERROR: two Path instances in the chain have different identifiers"
+                sys.stderr.write( "%s\n" % ( msg ) )
+                sys.exit(1)
+            if iPathrange.range_subject.isOnDirectStrand() != iPath.range_subject.isOnDirectStrand():
+                msg = "ERROR: two Path instances in the chain are on different strands"
+                sys.stderr.write( "%s\n" % ( msg ) )
+                sys.exit(1)
+            iPathrange.range_query.start = min( iPathrange.range_query.start, iPath.range_query.start )
+            iPathrange.range_query.end = max( iPathrange.range_query.end, iPath.range_query.end )
+            if iPathrange.range_subject.isOnDirectStrand():
+                iPathrange.range_subject.start = min( iPathrange.range_subject.start, iPath.range_subject.start )
+                iPathrange.range_subject.end = max( iPathrange.range_subject.end, iPath.range_subject.end )
+            else:
+                iPathrange.range_subject.start = max( iPathrange.range_subject.start, iPath.range_subject.start )
+                iPathrange.range_subject.end = min( iPathrange.range_subject.end, iPath.range_subject.end )
+            iPathrange.e_value = min( iPathrange.e_value, iPath.e_value )
+            iPathrange.score += iPath.score
+            iPathrange.identity += iPath.identity * iPath.getLengthOnQuery()
+            cumulQueryLength += iPath.getLengthOnQuery()
+        iPathrange.identity = iPathrange.identity / float(cumulQueryLength)
+        return iPathrange
+    
+    convertPathListToPathrange = staticmethod( convertPathListToPathrange )
+    
+    
+    ## Convert a Path file into an Align file via 'pathrange'
+    #
+    # @param pathFile: name of the input Path file
+    # @param alignFile: name of the output Align file
+    # @param verbose integer verbosity level
+    # @note: the min and max of each Path is used
+    #
+    def convertPathFileIntoAlignFileViaPathrange( pathFile, alignFile, verbose=0 ):
+        lPaths = PathUtils.getPathListFromFile( pathFile )
+        dId2PathList = PathUtils.getDictOfListsWithIdAsKey( lPaths )
+        lIds = dId2PathList.keys()
+        lIds.sort()
+        if verbose > 0:
+            msg = "number of chains: %i" % ( len(lIds) )
+            sys.stdout.write( "%s\n" % ( msg ) )
+            sys.stdout.flush()
+        alignFileHandler = open( alignFile, "w" )
+        for identifier in lIds:
+            iPath = PathUtils.convertPathListToPathrange( dId2PathList[ identifier ] )
+            iAlign = iPath.getAlignInstance()
+            iAlign.write( alignFileHandler )
+        alignFileHandler.close()
+        
+    convertPathFileIntoAlignFileViaPathrange = staticmethod( convertPathFileIntoAlignFileViaPathrange )
+    
+    
+    ## Split a list of Path instances according to the name of the query
+    #
+    # @param lInPaths list of align instances
+    # @return lOutPathLists list of align instances lists 
+    #
+    def splitPathListByQueryName( lInPaths ):
+        lInSortedPaths = sorted( lInPaths, key=lambda o: o.range_query.seqname )
+        lOutPathLists = []
+        if len(lInSortedPaths) != 0 :
+            lPathsForCurrentQuery = [] 
+            previousQuery = lInSortedPaths[0].range_query.seqname
+            for iPath in lInSortedPaths :
+                currentQuery = iPath.range_query.seqname
+                if previousQuery != currentQuery :
+                    lOutPathLists.append( lPathsForCurrentQuery )
+                    previousQuery = currentQuery
+                    lPathsForCurrentQuery = []
+                lPathsForCurrentQuery.append( iPath )
+                
+            lOutPathLists.append(lPathsForCurrentQuery)         
+            
+        return lOutPathLists
+    
+    splitPathListByQueryName = staticmethod( splitPathListByQueryName )
+    
+    
+    ## Create an Path file from each list of Path instances in the input list
+    #
+    # @param lPathList list of lists with Path instances
+    # @param pattern string
+    # @param dirName string 
+    #
+    def createPathFiles( lPathList, pattern, dirName="" ):
+        nbFiles = len(lPathList)
+        countFile = 1
+        if dirName != "" :
+            if dirName[-1] != "/":
+                dirName = dirName + '/'
+            os.mkdir( dirName ) 
+            
+        for lPath in lPathList:
+            fileName = dirName + pattern  + "_%s.path" % ( str(countFile).zfill( len(str(nbFiles)) ) )
+            PathUtils.writeListInFile( lPath, fileName )
+            countFile += 1
+            
+    createPathFiles = staticmethod( createPathFiles )
+    
+    
+    ## Return a list of Path instances sorted in increasing order according to the min, then the inverse of the query length, and finally their initial order
+    #
+    # @param lPaths: list of Path instances
+    #
+    def getPathListSortedByIncreasingQueryMinThenInvQueryLength( lPaths ):
+        return sorted( lPaths, key=lambda iPath: ( iPath.getQueryMin(), 1 / float(iPath.getLengthOnQuery()) ) )
+    
+    getPathListSortedByIncreasingQueryMinThenInvQueryLength = staticmethod( getPathListSortedByIncreasingQueryMinThenInvQueryLength )
+    
+    
+    ## Merge all overlapping Path instances in a list without considering the identifiers
+    #  Start by sorting the Path instances by their increasing min coordinate
+    #
+    # @return: a new list with the merged Path instances
+    #
+    def mergePathsInList( lPaths ):
+        lMergedPaths = []
+        if len(lPaths)==0:
+            return lMergedPaths
+        
+        lSortedPaths = PathUtils.getPathListSortedByIncreasingQueryMinThenInvQueryLength( lPaths )
+        
+        prev_count = 0
+        for iPath in lSortedPaths[0:]:
+            if prev_count != len(lSortedPaths):
+                for i in lSortedPaths[ prev_count + 1: ]:
+                    if iPath.isOverlapping( i ):
+                        iPath.merge( i )
+                isAlreadyInList = False
+                for newPath in lMergedPaths:
+                    if newPath.isOverlapping( iPath ):
+                        isAlreadyInList = True
+                        newPath.merge( iPath )
+                        lMergedPaths [ lMergedPaths.index( newPath ) ] = newPath
+                if not isAlreadyInList:
+                    lMergedPaths.append( iPath )
+                prev_count += 1
+        return lMergedPaths
+    
+    mergePathsInList = staticmethod( mergePathsInList )
+    
+    
+    ## Merge all overlapping Path instances in a list without considering if subjects are overlapping.
+    #  Start by sorting the Path instances by their increasing min coordinate.
+    #
+    # @return: a new list with the merged Path instances
+    #
+    def mergePathsInListUsingQueryCoordsOnly( lPaths ):
+        lMergedPaths = []
+        if len(lPaths)==0:
+            return lMergedPaths
+        
+        lSortedPaths = PathUtils.getPathListSortedByIncreasingQueryMinThenInvQueryLength( lPaths )
+        
+        prev_count = 0
+        for iPath in lSortedPaths[0:]:
+            if prev_count != len(lSortedPaths):
+                for i in lSortedPaths[ prev_count + 1: ]:
+                    if iPath.isQueryOverlapping( i ):
+                        iPath.merge( i )
+                isAlreadyInList = False
+                for newPath in lMergedPaths:
+                    if newPath.isQueryOverlapping( iPath ):
+                        isAlreadyInList = True
+                        newPath.merge( iPath )
+                        lMergedPaths [ lMergedPaths.index( newPath ) ] = newPath
+                if not isAlreadyInList:
+                    lMergedPaths.append( iPath )
+                prev_count += 1
+        return lMergedPaths
+    
+    mergePathsInListUsingQueryCoordsOnly = staticmethod( mergePathsInListUsingQueryCoordsOnly )
+    
+    
+    ## Convert a Path file into a GFF file
+    #
+    # @param pathFile: name of the input Path file
+    # @param gffFile: name of the output GFF file
+    # @param source: source to write in the GFF file (column 2)
+    #
+    # @note the 'path' query is supposed to correspond to the 'gff' first column
+    #
+    def convertPathFileIntoGffFile( pathFile, gffFile, source="REPET", verbose=0 ):
+        dId2PathList = PathUtils.getDictOfListsWithIdAsKeyFromFile( pathFile )
+        if verbose > 0:
+            msg = "number of chains: %i" % ( len(dId2PathList.keys()) )
+            sys.stdout.write( "%s\n" % msg )
+            sys.stdout.flush()
+        gffFileHandler = open( gffFile, "w" )
+        for id in dId2PathList.keys():
+            if len( dId2PathList[ id ] ) == 1:
+                iPath = dId2PathList[ id ][0]
+                string = iPath.toStringAsGff( ID="%i" % iPath.getIdentifier(),
+                                              source=source )
+                gffFileHandler.write( "%s\n" % string )
+            else:
+                iPathrange = PathUtils.convertPathListToPathrange( dId2PathList[ id ] )
+                string = iPathrange.toStringAsGff( ID="ms%i" % iPathrange.getIdentifier(),
+                                                   source=source )
+                gffFileHandler.write( "%s\n" % string )
+                count = 0
+                for iPath in dId2PathList[ id ]:
+                    count += 1
+                    string = iPath.toStringAsGff( type="match_part",
+                                                  ID="mp%i-%i" % ( iPath.getIdentifier(), count ),
+                                                  Parent="ms%i" % iPathrange.getIdentifier(),
+                                                  source=source )
+                    gffFileHandler.write( "%s\n" % string )
+        gffFileHandler.close()
+        
+    convertPathFileIntoGffFile = staticmethod( convertPathFileIntoGffFile )
+    
+    
+    ## Convert a Path file into a Set file
+    # replace old parser.pathrange2set
+    # @param pathFile: name of the input Path file
+    # @param setFile: name of the output Set file
+    #
+    def convertPathFileIntoSetFile( pathFile, setFile ):
+        pathFileHandler = open( pathFile, "r" )
+        setFileHandler = open( setFile, "w" )
+        iPath = Path()
+        while True:
+            line = pathFileHandler.readline()
+            if line == "":
+                break
+            iPath.setFromString( line )
+            iSet = iPath.getSubjectAsSetOfQuery()
+            iSet.write( setFileHandler )
+        pathFileHandler.close()
+        setFileHandler.close()
+        
+    convertPathFileIntoSetFile = staticmethod( convertPathFileIntoSetFile )
+    
+    ## Write Path File without duplicated Path (same query, same subject and same coordinate)
+    #
+    # @param inputFile: name of the input Path file
+    # @param outputFile: name of the output Path file
+    #
+    def removeInPathFileDuplicatedPathOnQueryNameQueryCoordAndSubjectName(inputFile, outputFile):
+        f = open(inputFile, "r")
+        line = f.readline()
+        previousQuery = ""
+        previousSubject = ""
+        lPaths = []
+        while line:
+            iPath = Path()
+            iPath.setFromString(line)
+            query = iPath.getQueryName()
+            subject = iPath.getSubjectName()
+            if (query != previousQuery or subject != previousSubject) and lPaths != []: 
+                lPathsWithoutDuplicate = PathUtils.getPathListWithoutDuplicatesOnQueryCoord(lPaths)
+                PathUtils.writeListInFile(lPathsWithoutDuplicate, outputFile, "a")
+                lPaths = []
+            lPaths.append(iPath)
+            previousQuery = query
+            previousSubject = subject
+            line = f.readline()
+        lPathsWithoutDuplicate = PathUtils.getPathListWithoutDuplicatesOnQueryCoord(lPaths)
+        PathUtils.writeListInFile(lPathsWithoutDuplicate, outputFile, "a")
+        f.close()
+    removeInPathFileDuplicatedPathOnQueryNameQueryCoordAndSubjectName = staticmethod(removeInPathFileDuplicatedPathOnQueryNameQueryCoordAndSubjectName)
+ 
+   
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/Range.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,361 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+## Record a region on a given sequence
+#
+class Range( object ):
+
+    ## Constructor
+    #
+    # @param seqname the name of the sequence
+    # @param start the start coordinate
+    # @param end the end coordinate
+    #
+    def __init__(self, seqname="", start=-1, end=-1):
+        self.seqname = seqname
+        self.start = int(start)
+        self.end = int(end)
+        
+    ## Equal operator
+    #
+    # @param o a Range instance
+    #
+    def __eq__(self, o):
+        if self.seqname == o.seqname and self.start == o.start and self.end == o.end:
+            return True
+        return False
+        
+    ## Unequal operator
+    #
+    # @param o a Range instance
+    #
+    def __ne__(self, o):
+        return not self.__eq__(o)
+    
+    ## Convert the object into a string
+    #
+    # @note used in 'print myObject'
+    #
+    def __str__( self ):
+        return self.toString()
+    
+    ## Convert the object into a string
+    #
+    # @note used in 'repr(myObject)' for debugging
+    #
+    def __repr__( self ):
+        return self.toString().replace("\t",";")
+    
+    def setStart(self, start):
+        self.start = start
+        
+    def setEnd(self, end):
+        self.end = end
+        
+    def setSeqName(self, seqName):
+        self.seqname = seqName
+    
+    ## Reset
+    #
+    def reset(self):
+        self.seqname = ""
+        self.start = -1
+        self.end = -1
+        
+    ## Return the attributes as a formatted string
+    #   
+    def toString(self):
+        string = "%s" % (self.seqname)
+        string += "\t%d" % (self.start)
+        string += "\t%d" % (self.end)
+        return string
+    
+    ## Show the attributes
+    #
+    def show(self):
+        print self.toString()
+    
+    ## Return seqname
+    #
+    def getSeqname(self):
+        return self.seqname
+    
+    ## Return the start coordinate
+    #
+    def getStart(self):
+        return self.start
+    
+    ## Return the end coordinate
+    #
+    def getEnd(self):
+        return self.end
+    
+    ## Return the lowest value between start and end coordinates
+    #
+    def getMin(self):
+        return min(self.start, self.end)
+    
+    ## Return the greatest value between start and end attributes
+    # 
+    def getMax(self):
+        return max(self.start, self.end)
+    
+    ## Return True if the instance is on the direct strand, False otherwise
+    # 
+    def isOnDirectStrand(self):
+        if self.start <= self.end:
+            return True
+        else:
+            return False
+        
+    ## Return True if the instance is on the reverse strand, False otherwise
+    # 
+    def isOnReverseStrand(self):
+        return not self.isOnDirectStrand()
+    
+    ## Return '+' if the instance is on the direct strand, '-' otherwise
+    # 
+    def getStrand(self):
+        if self.isOnDirectStrand():
+            return '+'
+        else:
+            return '-'
+        
+    ## Exchange start and end coordinates
+    #
+    def reverse(self):
+        tmp = self.start
+        self.start = self.end
+        self.end = tmp
+        
+    ## Return the length of the instance
+    #
+    # @warning old name is 'length'
+    #
+    def getLength(self):
+        return int(abs(self.start-self.end))+1
+    
+    ## Return True if the instance is empty, False otherwise
+    #
+    def isEmpty(self):
+        if self.start==self.end and (self.start==0 or self.start==-1):
+            return True
+        return False
+    
+    ## Set attributes from tuple
+    #
+    # @param tuple a tuple with (name,start,end)
+    #
+    def setFromTuple(self, tuple):
+        self.seqname = tuple[0]
+        self.start = int(tuple[1])
+        self.end = int(tuple[2])
+        
+    ## Set attributes from string
+    #
+    # @param string a string formatted like name<sep>start<sep>end
+    # @param sep field separator
+    #
+    def setFromString(self, string, sep="\t"):
+        if string[-1] == "\n":
+            string = string[:-1]
+        self.setFromTuple( string.split(sep) )
+        
+    ## Merge the instance with another Range instance
+    #
+    # @param o a Range instance
+    #
+    def merge(self, o):
+        if self.seqname != o.seqname:
+            return
+        if self.isOnDirectStrand():
+            self.start = min(self.getMin(), o.getMin())
+            self.end = max(self.getMax(), o.getMax())
+        else:
+            self.start = max(self.getMax(), o.getMax())
+            self.end = min(self.getMin(), o.getMin())
+            
+    ## Return True if the instance overlaps with another Range instance, False otherwise
+    #
+    # @param o a Range instance
+    #
+    def isOverlapping(self, o):
+        if o.seqname != self.seqname:
+            return False
+        smin = self.getMin()
+        smax = self.getMax()
+        omin = o.getMin()
+        omax = o.getMax()
+        if omin <= smin and omax >= smax:
+            return True
+        if omin >= smin and omin <= smax or omax >= smin and omax <= smax:
+            return True
+        return False
+    
+    
+    ## Return the length of the overlap between the instance and another Range, 0 if no overlap
+    #
+    # @param o a Range instance
+    #
+    def getOverlapLength( self, o ):
+        if self.isOverlapping( o ):
+            if self.isIncludedIn( o ):
+                return self.getLength()
+            elif o.isIncludedIn( self ):
+                return o.getLength()
+            elif o.getMin() <= self.getMax() and o.getMin() >= self.getMin():
+                return self.getMax() - o.getMin() + 1
+            elif o.getMax() <= self.getMax() and o.getMax() >= self.getMin():
+                return o.getMax() - self.getMin() + 1
+        return 0
+    
+    
+    ## Return True if the instance is included within another Range, False otherwise
+    #
+    # @param o a Range instance
+    #
+    # @note the min (respectively max) coordinates can be equal
+    #
+    def isIncludedIn( self, o ):
+        if o.seqname != self.seqname:
+            return False
+        if self.getMin() >= o.getMin() and self.getMax() <= o.getMax():
+            return True
+        else:
+            return False
+
+        
+    ## Return the distance between the start of the instance and the start of another Range instance
+    #
+    # @param o a Range instance
+    #
+    def getDistance(self, o):
+        if self.isOnDirectStrand() == o.isOnDirectStrand():
+            if self.isOverlapping(o):
+                return 0
+            elif self.isOnDirectStrand():
+                if self.start > o.start:
+                    return self.start - o.end
+                else:
+                    return o.start - self.end
+            else:
+                if self.start > o.start:
+                    return self.end - o.start
+                else:
+                    return o.end - self.start
+        return -1
+    
+    ## Remove in the instance the region overlapping with another Range instance
+    #
+    # @param o a Range instance
+    # 
+    def diff(self, o):
+        new_range = Range(self.seqname)
+        if not self.isOverlapping(o) or self.seqname != o.seqname:
+            return new_range
+
+        istart = min(self.start, self.end)
+        iend = max(self.start, self.end)
+        jstart = min(o.start, o.end)
+        jend = max(o.start, o.end)
+        if istart < jstart:
+            if iend <= jend:
+                if self.isOnDirectStrand():
+                    self.start = istart
+                    self.end = jstart - 1
+                else:
+                    self.start = jstart - 1
+                    self.end = istart
+            else:
+                if self.isOnDirectStrand():
+                    self.start = istart
+                    self.end = jstart - 1
+                    new_range.start = jend + 1
+                    new_range.end = iend
+                else:
+                    self.start = jstart - 1;
+                    self.end = istart;
+                    new_range.start = iend
+                    new_range.end = jend + 1
+        else: #istart>=jstart
+            if iend <= jend:
+                self.start = 0
+                self.end = 0
+            else:
+                if self.isOnDirectStrand():
+                    self.start = jend + 1
+                    self.end = iend
+                else:
+                    self.start = iend
+                    self.end = jend + 1
+        return new_range
+        
+    ## Find the bin that contains the instance and compute its index
+    #
+    # @note Required for coordinate indexing via a hierarchical bin system
+    #
+    def findIdx(self):
+        min_lvl = 3
+        max_lvl = 6
+        for bin_lvl in xrange(min_lvl, max_lvl):
+            if getBin(self.start, bin_lvl) == getBin(self.end, bin_lvl):
+                return getIdx(self.start, bin_lvl)
+        return getIdx(self.start, max_lvl) 
+    
+    ## Get a bin for fast database access
+    #
+    # @return bin number (float)
+    #
+    def getBin(self):
+        for i in xrange(3, 8):
+            bin_lvl = pow(10, i)
+            if int(self.start/bin_lvl) == int(self.end/bin_lvl):
+                return float(bin_lvl+(int(self.start/bin_lvl)/1e10))
+        bin_lvl = pow(10, 8)
+        return float(bin_lvl+(int(self.start/bin_lvl)/1e10))
+    
+    
+# Functions
+
+# Get the bin number of a coordinate according to the bin level. Required for coordinate indexing with hierarchical bin system
+#    
+def getBin(val, bin_lvl):
+    bin_size = pow(10, bin_lvl)
+    return long(val / bin_size)
+    
+# Get an index from a coordinate according to the bin level. Required for coordinate indexing with hierarchical bin system
+#
+def getIdx(val, bin_lvl):
+    min_lvl = 3
+    max_lvl = 6
+    if bin_lvl >= max_lvl:
+        return long((bin_lvl-min_lvl+1)*pow(10,max_lvl))
+    return long(((bin_lvl-min_lvl+1)*pow(10,max_lvl))+getBin(val,bin_lvl))
Binary file smart_toolShed/commons/core/coord/Range.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/Set.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,125 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.coord.Map import Map
+
+
+## Record a named region on a given sequence with an identifier
+#  
+class Set( Map ):
+    
+    ## Constructor
+    #
+    # @param id identifier
+    # @param name the name of the region
+    # @param seqname the name of the sequence
+    # @param start the start coordinate
+    # @param end the end coordinate
+    #
+    def __init__(self, id=-1, name="", seqname="", start=-1, end=-1):
+        Map.__init__( self, name, seqname, start, end )
+        self.id = id
+        
+    ## Equal operator
+    #    
+    def __eq__(self, o):
+        if self.id != o.id:
+            return False
+        else:
+            return Map.__eq__(self, o)
+    
+    def getId(self):
+        return self.id
+        
+    ## Reset
+    #
+    def reset(self):
+        self.setFromTuple([-1, "", "", -1, -1 ])
+            
+    ## Set attributes from tuple
+    #
+    # @param tuple: a tuple with (id, name, seqname, start, end)
+    # 
+    def setFromTuple(self, tuple):
+        self.id = int(tuple[0])
+        Map.setFromTuple(self, tuple[1:])
+        
+    ## Return the attributes as a formatted string
+    #
+    def toString(self):
+        string = "%i" % (self.id)
+        string += "\t%s" % (Map.toString(self))
+        return string
+    
+    ## Merge the instance with another Set instance
+    #
+    # @param o a Set instance
+    #
+    def merge(self, o):
+        if self.seqname == o.seqname:
+            Map.merge(self, o)
+            self.id = min(self.id, o.id)
+    
+    ## Return a Map instance with the attributes
+    #
+    def getMap(self):
+        return Map(self.name, self.seqname, self.start, self.end)
+    
+    ## Remove in the instance the region overlapping with another Set instance
+    #
+    # @param o a Set instance
+    #  
+    def diff(self, o):
+        iMap = Map.diff(self, o.getMap())
+        new = Set()
+        if not iMap.isEmpty():
+            new.id = self.id
+            new.name = self.name
+            new.seqname = self.seqname
+            new.start = iMap.start
+            new.end = iMap.end
+        return new
+    
+    ## Return a Map instance with the identifier in the name
+    #
+    def set2map(self):
+        return Map(self.name+"::"+str(self.id),self.seqname,self.start,self.end)
+    
+    
+    def getMapInstance( self ):
+        iMap = Map()
+        lAttributes = []
+        lAttributes.append( self.name )
+        lAttributes.append( self.seqname )
+        lAttributes.append( self.start )
+        lAttributes.append( self.end )
+        iMap.setFromTuple( lAttributes )
+        return iMap
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/SetUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,553 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.coord.Set import Set
+
+## Static methods for the manipulation of Path instances
+#
+class SetUtils( object ):
+    
+    ## Change the identifier of each Set instance in the given list
+    #
+    # @param lSets list of Set instances
+    # @param newId new identifier
+    #
+    def changeIdInList(lSets, newId):
+        for iSet in lSets:
+            iSet.id = newId
+            
+    changeIdInList = staticmethod( changeIdInList )
+    
+    ## Return the length of the overlap between two lists of Set instances
+    #
+    # @param lSets1 list of Set instances
+    # @param lSets2 list of Set instances
+    # @return length of overlap
+    # @warning sequence names are supposed to be identical
+    #
+    def getOverlapLengthBetweenLists(lSets1, lSets2):
+        lSet1Sorted = SetUtils.getSetListSortedByIncreasingMinThenMax(lSets1)
+        lSet2Sorted = SetUtils.getSetListSortedByIncreasingMinThenMax(lSets2)
+        osize = 0
+        i = 0
+        j = 0
+        while i!= len(lSet1Sorted):
+            while j!= len(lSet2Sorted) and lSet1Sorted[i].getMin()>lSet2Sorted[j].getMax()\
+                and not(lSet1Sorted[i].isOverlapping(lSet2Sorted[j])):
+                j+=1
+            jj=j
+            while jj!= len(lSet2Sorted) and lSet1Sorted[i].isOverlapping(lSet2Sorted[jj]):
+                osize+=lSet1Sorted[i].getOverlapLength(lSet2Sorted[jj])
+                jj+=1
+            i+=1
+        return osize
+    
+    getOverlapLengthBetweenLists = staticmethod( getOverlapLengthBetweenLists )
+    
+    ## Return True if the two lists of Set instances overlap, False otherwise    
+    #
+    # @param lSets1 list of Set instances
+    # @param lSets2 list of Set instances
+    #    
+    def areSetsOverlappingBetweenLists( lSets1, lSets2 ):
+        lSet1Sorted = SetUtils.getSetListSortedByIncreasingMinThenMax(lSets1)
+        lSet2Sorted = SetUtils.getSetListSortedByIncreasingMinThenMax(lSets2)
+        i=0
+        j=0
+        while i!= len(lSet1Sorted):
+            while j!= len(lSet2Sorted) and lSet1Sorted[i].getMin()>lSet2Sorted[j].getMax()\
+                and not(lSet1Sorted[i].isOverlapping(lSet2Sorted[j])):
+                j+=1
+            if j!= len(lSet2Sorted) and lSet1Sorted[i].isOverlapping(lSet2Sorted[j]):
+                return True
+            i+=1
+        return False
+    
+    areSetsOverlappingBetweenLists = staticmethod( areSetsOverlappingBetweenLists )
+    
+    ## Merge all overlapping Set instances between two lists of Set and give the next identifier 
+    #
+    # @param lSets1 list of Set instances
+    # @param lSets2 list of Set instances
+    # @param max_id start id value for inserting new Set
+    # @return a new list of the merged Set instances and the next identifier
+    # 
+    def getListOfMergedSetsAndNextId(lSets1, lSets2, max_id=0):
+        lSets_merged = []
+        list2merge = SetUtils.getListOfIdListOfOverlappingSets ( lSets1,lSets2 )
+        idlist1 = SetUtils.getDictOfListsWithIdAsKey(lSets1)
+        idlist2 = SetUtils.getDictOfListsWithIdAsKey(lSets2)
+        if max_id == 0:
+            max_id = max(idlist1.keys()) + 1
+        for i in list2merge:
+            if i == []:
+                continue
+            l = []
+            min_id = max(i)
+            for j in i:
+                if j>0:
+                    if min_id>j:
+                        min_id=j
+                    l.extend(idlist1[j])
+                    del idlist1[j]
+                else:
+                    l.extend(idlist2[j*-1])
+                    del idlist2[j*-1]
+            l = SetUtils.mergeSetsInList(l)
+            SetUtils.changeIdInList(l, min_id)
+            lSets_merged.extend(l)
+        for id, alist in idlist1.items():
+            lSets_merged.extend(alist)
+        for id,alist in idlist2.items():
+            SetUtils.changeIdInList(alist,max_id)
+            lSets_merged.extend(alist)
+            max_id+=1
+        return lSets_merged, max_id
+    
+    getListOfMergedSetsAndNextId = staticmethod ( getListOfMergedSetsAndNextId )
+    
+#    ## Concatenate two Set instance lists and give the next identifier 
+#    #
+#    # @param lSets1 list of Set instances
+#    # @param lSets2 list of Set instances
+#    # @param maxId start id value for inserting new Set
+#    # @return a new list of Set instances and the next identifier
+#    # 
+#    @staticmethod
+#    def getSetsListOfTwoConcatenatedSetsListAndNextId(lSets1, lSets2, maxId = 0):
+#        lOutSets = lSets1
+#        dId2SetsList2 = SetUtils.getDictOfListsWithIdAsKey(lSets2)
+#        if maxId == 0:
+#            dId2SetsList1 = SetUtils.getDictOfListsWithIdAsKey(lSets1)
+#            maxId = max(dId2SetsList1.keys())
+#        for lSets in dId2SetsList2.values():
+#            SetUtils.changeIdInList(lSets, maxId)
+#            lOutSets.extend(lSets)
+#            maxId += 1
+#        return lOutSets, maxId
+    
+    ## Return the sum of the length of each Set instance in the given list
+    #
+    # @param lSets: list of Set instances
+    #
+    def getCumulLength(lSets):
+        length = 0
+        for i in lSets:
+            length += i.getLength()
+        return length
+    
+    getCumulLength = staticmethod( getCumulLength )
+    
+    ## Return a tuple with min and max coordinates of Set instances in the given list
+    #
+    # @param lSets list of Set instances
+    # 
+    def getListBoundaries(lSets):
+        qmin = -1
+        qmax = -1
+        for iSet in lSets:
+            if qmin == -1:
+                qmin = iSet.start
+            qmin = min(qmin, iSet.getMin())
+            qmax = max(qmax, iSet.getMax())
+        return (qmin, qmax)
+    
+    getListBoundaries = staticmethod( getListBoundaries )
+    
+    ## Show Set instances contained in the given list
+    #
+    # @param lSets list of Set instances
+    # 
+    def showList(lSets):
+        for iSet in lSets:
+            iSet.show()
+            
+    showList = staticmethod( showList )
+    
+    ## Write Set instances contained in the given list
+    #
+    # @param lSets list of Set instances
+    # @param fileName a file name
+    # @param mode the open mode of the file '"w"' or '"a"' 
+    #
+    def writeListInFile(lSets, fileName, mode="w"):
+        fileHandler = open(fileName, mode)
+        for iSet in lSets:
+            iSet.write(fileHandler)
+        fileHandler.close()
+        
+    writeListInFile = staticmethod( writeListInFile )
+    
+    ## Split a Set list in several Set lists according to the identifier
+    #
+    # @param lSets list of Set instances
+    # @return a dictionary which keys are identifiers and values Set lists
+    #
+    def getDictOfListsWithIdAsKey(lSets):
+        dId2SetList = {}
+        for iSet in lSets:
+            if dId2SetList.has_key(iSet.id):
+                dId2SetList[iSet.id].append(iSet)
+            else:
+                dId2SetList[iSet.id] = [iSet]
+        return dId2SetList
+    
+    getDictOfListsWithIdAsKey = staticmethod( getDictOfListsWithIdAsKey )
+    
+    
+    ## Split a Set list in several Set lists according to the identifier
+    #
+    # @param lSets list of Set instances
+    # @return a dictionary which keys are identifiers and values Set lists
+    #
+    def getDictOfListsWithIdAsKeyFromFile( setFile ):
+        dId2SetList = {}
+        setFileHandler = open( setFile, "r" )
+        while True:
+            line = setFileHandler.readline()
+            if line == "":
+                break
+            iSet = Set()
+            iSet.setFromTuple( line[:-1].split("\t") )
+            if not dId2SetList.has_key( iSet.id ):
+                dId2SetList[ iSet.id ] = []
+            dId2SetList[ iSet.id ].append( iSet )
+        setFileHandler.close()
+        return dId2SetList
+    
+    getDictOfListsWithIdAsKeyFromFile = staticmethod( getDictOfListsWithIdAsKeyFromFile )
+    
+    
+    ## Return a Map list from the given Set List
+    #
+    # @param lSets list of Set instances
+    # 
+    def getMapListFromSetList(lSets):
+        lMaps = []
+        for iSet in lSets:
+            lMaps.append(iSet.set2map())
+        return lMaps
+    
+    getMapListFromSetList = staticmethod( getMapListFromSetList )
+    
+    ## Construct a Set list from a Map list
+    #
+    # @param lMaps list of Map instances
+    # 
+    def getSetListFromMapList(lMaps):
+        lSets = []
+        c = 0
+        for iMap in lMaps:
+            c += 1
+            lSets.append( Set(c, iMap.name, iMap.seqname, iMap.start, iMap.end) )
+        return lSets
+    
+    getSetListFromMapList = staticmethod( getSetListFromMapList )
+    
+    ## Merge all overlapping Set instances in a list without considering the identifiers.
+    #  Start by sorting Set instances by their increasing Min coordinate.
+    #
+    # @return: a new list of the merged Set instances
+    #
+    def mergeSetsInList(lSets):
+        l=[]
+        if len(lSets)==0:
+            return l
+        
+        lSortedSets = SetUtils.getSetListSortedByIncreasingMinThenInvLength( lSets )
+        
+        prev_count = 0
+        for iSet in lSortedSets[0:]:
+            if prev_count != len(lSortedSets):
+                for i in lSortedSets[ prev_count + 1: ]:
+                    if iSet.isOverlapping( i ):
+                        iSet.merge( i )
+                IsAlreadyInList = False
+                for newSet in l:
+                    if newSet.isOverlapping( iSet ):
+                        IsAlreadyInList = True
+                        newSet.merge( iSet )
+                        l [ l.index( newSet ) ] = newSet
+                if not IsAlreadyInList:
+                    l.append( iSet )
+                prev_count += 1
+        return l
+    
+    mergeSetsInList = staticmethod( mergeSetsInList )
+    
+    ## Unjoin a Set list according to another
+    #
+    # @param lToKeep: a list of Set instances to keep 
+    # @param lToUnjoin: a list of Set instances to unjoin
+    # @return: lToUnjoin split in several list
+    #    
+    def getSetListUnjoined(lToKeep, lToUnjoin):
+        lSortedToKeep = SetUtils.getSetListSortedByIncreasingMinThenMax( lToKeep )
+        lSortedToUnjoin = SetUtils.getSetListSortedByIncreasingMinThenMax( lToUnjoin )
+        if lSortedToUnjoin == []:
+            return []
+        if lSortedToKeep == []:
+            return [ lSortedToUnjoin ]
+        
+        i=0
+        resultListSet=[]
+        while i<len(lSortedToKeep):
+            j1=0
+            while j1<len(lSortedToUnjoin) and lSortedToKeep[i].getMin() > lSortedToUnjoin[j1].getMax():
+                j1+=1
+            if j1==len(lSortedToUnjoin):
+                break
+            if j1!=0:
+                resultListSet.append(lSortedToUnjoin[:j1])
+                del lSortedToUnjoin[:j1]
+                j1=0
+            if i+1==len(lSortedToKeep):
+                break
+            j2=j1
+            if j2<len(lSortedToUnjoin) and lSortedToKeep[i+1].getMin() > lSortedToUnjoin[j2].getMax():
+                while j2<len(lSortedToUnjoin) and lSortedToKeep[i+1].getMin() > lSortedToUnjoin[j2].getMax():
+                    j2+=1
+                resultListSet.append(lSortedToUnjoin[j1:j2])
+                del lSortedToUnjoin[j1:j2]
+            i+=1
+    
+        if resultListSet!=[] or i == 0:
+            resultListSet.append(lSortedToUnjoin)
+        return resultListSet
+    
+    getSetListUnjoined = staticmethod(getSetListUnjoined)
+      
+    ## Return new list of Set instances with no duplicate
+    #
+    # @param lSets list of Set instances
+    #
+    def getSetListWithoutDuplicates( lSets ):
+        if len(lSets) < 2:
+            return lSets
+        lSortedSet = SetUtils.getSetListSortedByIncreasingMinThenMax( lSets )
+        lUniqSet = [ lSortedSet[0] ]
+        for iSet in lSortedSet[1:]:
+            if iSet != lUniqSet[-1]:
+                lUniqSet.append( iSet )
+        return lUniqSet
+    
+    getSetListWithoutDuplicates = staticmethod( getSetListWithoutDuplicates )
+    
+    ## Return a list of Set instances sorted in increasing order according to the Min, then the Max, and finally their initial order
+    #
+    # @param lSets: list of Set instances
+    #
+    def getSetListSortedByIncreasingMinThenMax( lSets ):
+        return sorted( lSets, key=lambda iSet: ( iSet.getMin(), iSet.getMax() ) )
+    
+    getSetListSortedByIncreasingMinThenMax = staticmethod( getSetListSortedByIncreasingMinThenMax )
+    
+    ## Return a list of Set instances sorted in increasing order according to the min, then the inverse of the length, and finally their initial order
+    #
+    # @param lSets: list of Set instances
+    #
+    def getSetListSortedByIncreasingMinThenInvLength( lSets ):
+        return sorted( lSets, key=lambda iSet: ( iSet.getMin(), 1 / float(iSet.getLength()) ) )
+    
+    getSetListSortedByIncreasingMinThenInvLength = staticmethod( getSetListSortedByIncreasingMinThenInvLength )
+ 
+    ## Return a list of Set instances sorted in increasing order according to the SeqName, then the Name, then the Min, then the Max and finally their initial order
+    #
+    # @param lSets: list of Set instances
+    #   
+    def getSetListSortedBySeqThenRegionThenMinThenMax(lSets):
+        return sorted(lSets, key=lambda iSet: (iSet.getSeqname(), iSet.getName(), iSet.getMin(), iSet.getMax()))
+    
+    getSetListSortedBySeqThenRegionThenMinThenMax = staticmethod(getSetListSortedBySeqThenRegionThenMinThenMax)
+    
+    ## Return a list of identifier lists of overlapping Sets from the subject list, according to the reference list
+    #
+    # @param lRef list of Set instances
+    # @param lSubject list of Set instances
+    #
+    def getListOfIdListOfOverlappingSets(lRef,lSubject):
+        lSortedRef = SetUtils.getSetListSortedByIncreasingMinThenMax( lRef )
+        lSortedSubject = SetUtils.getSetListSortedByIncreasingMinThenMax( lSubject )
+
+        lOverlappingSet = []
+        lOverlappingSetCounter = 0
+
+        id2LOverlappingSet_pos = {}
+    
+        i = 0
+        j = 0
+        while i!= len(lSortedRef):
+            while j!= len(lSortedSubject) and lSortedRef[i].getMin()>lSortedSubject[j].getMax()\
+                and not(lSortedRef[i].isOverlapping(lSortedSubject[j])\
+                      and lSortedRef[i].isOnDirectStrand()==lSortedSubject[j].isOnDirectStrand()):
+                j+=1
+            jj=j
+            while jj!= len(lSortedSubject) and lSortedRef[i].isOverlapping(lSortedSubject[jj])\
+                  and lSortedRef[i].isOnDirectStrand()==lSortedSubject[jj].isOnDirectStrand():
+                id1=lSortedRef[i].id
+                id2=lSortedSubject[jj].id*-1
+                if id2LOverlappingSet_pos.has_key(id1) \
+                   and not id2LOverlappingSet_pos.has_key(id2):
+                    lOverlappingSet[id2LOverlappingSet_pos[id1]].append(id2)
+                    id2LOverlappingSet_pos[id2]=id2LOverlappingSet_pos[id1]
+                if id2LOverlappingSet_pos.has_key(id2) \
+                   and not id2LOverlappingSet_pos.has_key(id1):
+                    lOverlappingSet[id2LOverlappingSet_pos[id2]].append(id1)
+                    id2LOverlappingSet_pos[id1]=id2LOverlappingSet_pos[id2]
+                if not id2LOverlappingSet_pos.has_key(id2) \
+                   and not id2LOverlappingSet_pos.has_key(id1):
+                    lOverlappingSet.append([id1,id2])
+                    id2LOverlappingSet_pos[id1]=lOverlappingSetCounter
+                    id2LOverlappingSet_pos[id2]=lOverlappingSetCounter
+                    lOverlappingSetCounter+=1
+                jj+=1
+            i+=1
+    
+        return lOverlappingSet
+    
+    getListOfIdListOfOverlappingSets = staticmethod (getListOfIdListOfOverlappingSets)
+    
+    ## Return a list of sets without overlapping between two lists of sets
+    #
+    # @param lSet1 and lSet2 
+    #
+    def getListOfSetWithoutOverlappingBetweenTwoListOfSet(lSet1, lSet2):
+        for i in lSet1:
+            for idx,j in enumerate(lSet2):
+                n=j.diff(i)
+                if not n.isEmpty() and n.getLength()>=20:
+                    lSet2.append(n)
+        lSet2WithoutOverlaps=[]
+        for i in lSet2:
+            if not i.isEmpty() and i.getLength()>=20:
+                lSet2WithoutOverlaps.append(i)
+        return lSet2WithoutOverlaps
+        
+    getListOfSetWithoutOverlappingBetweenTwoListOfSet = staticmethod (getListOfSetWithoutOverlappingBetweenTwoListOfSet)
+
+    ## Return a Set list from a Set file
+    #
+    # @param setFile string name of a Set file
+    # @return a list of Set instances
+    #
+    def getSetListFromFile( setFile ):
+        lSets = []
+        setFileHandler = open( setFile, "r" )
+        while True:
+            line = setFileHandler.readline()
+            if line == "":
+                break
+            iSet = Set()
+            iSet.setFromString( line )
+            lSets.append( iSet )
+        setFileHandler.close()
+        return lSets
+    
+    getSetListFromFile = staticmethod( getSetListFromFile )
+    
+    
+    def convertSetFileIntoMapFile( setFile, mapFile ):
+        setFileHandler = open( setFile, "r" )
+        mapFileHandler = open( mapFile, "w" )
+        iSet = Set()
+        while True:
+            line = setFileHandler.readline()
+            if line == "":
+                break
+            iSet.setFromString( line )
+            iMap = iSet.getMapInstance()
+            iMap.write( mapFileHandler )
+        setFileHandler.close()
+        mapFileHandler.close()
+        
+    convertSetFileIntoMapFile = staticmethod( convertSetFileIntoMapFile )
+
+
+    def getDictOfListsWithSeqnameAsKey( lSets ):
+        dSeqnamesToSetList = {}
+        for iSet in lSets:
+            if not dSeqnamesToSetList.has_key( iSet.seqname ):
+                dSeqnamesToSetList[ iSet.seqname ] = []
+            dSeqnamesToSetList[ iSet.seqname ].append( iSet )
+        return dSeqnamesToSetList
+    
+    getDictOfListsWithSeqnameAsKey = staticmethod( getDictOfListsWithSeqnameAsKey )
+    
+    
+    def filterOnLength( lSets, minLength=0, maxLength=10000000000 ):
+        if minLength == 0 and maxLength == 0:
+            return lSets
+        lFiltered = []
+        for iSet in lSets:
+            if minLength <= iSet.getLength() <= maxLength:
+                lFiltered.append( iSet )
+        return lFiltered
+    
+    filterOnLength = staticmethod( filterOnLength )
+    
+    
+    def getListOfNames( setFile ):
+        lNames = []
+        setFileHandler = open( setFile, "r" )
+        iSet = Set()
+        while True:
+            line = setFileHandler.readline()
+            if line == "":
+                break
+            iSet.setFromTuple( line[:-1].split("\t") )
+            if iSet.name not in lNames:
+                lNames.append( iSet.name )
+        setFileHandler.close()
+        return lNames
+    
+    getListOfNames = staticmethod( getListOfNames )
+
+
+    def getDictOfDictsWithNamesThenIdAsKeyFromFile( setFile ):
+        dNames2DictsId = {}
+        setFileHandler = open( setFile, "r" )
+        while True:
+            line = setFileHandler.readline()
+            if line == "":
+                break
+            iSet = Set()
+            iSet.setFromTuple( line[:-1].split("\t") )
+            if not dNames2DictsId.has_key( iSet.name ):
+                dNames2DictsId[ iSet.name ] = { iSet.id: [ iSet ] }
+            else:
+                if not dNames2DictsId[ iSet.name ].has_key( iSet.id ):
+                    dNames2DictsId[ iSet.name ][ iSet.id ] = [ iSet ]
+                else:
+                    dNames2DictsId[ iSet.name ][ iSet.id ].append( iSet )
+        setFileHandler.close()
+        return dNames2DictsId
+    
+    getDictOfDictsWithNamesThenIdAsKeyFromFile = staticmethod( getDictOfDictsWithNamesThenIdAsKeyFromFile )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/SlidingWindow.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,73 @@
+class SlidingWindow(object):
+        
+    def __init__( self, length = 1, overlap = 1 ):        
+        self._length = length
+        self._overlap = overlap
+        self._start = 1
+        self._end = length
+        self._step = length - overlap
+
+    def slideWindowOnce(self):
+        self._start = self._start + self._step
+        self._end = self._end + self._step
+    
+    def getStart(self):
+        return self._start
+    
+    def getEnd(self):
+        return self._end
+    
+    def setStart(self, start):
+        self._start = start
+    
+    def setEnd(self, end):
+        self._end = end
+    
+    def getLength(self):
+        return self._length
+    
+    def getOverlap(self):
+        return self._overlap
+    
+    def setLength(self, length):
+        self._length = length
+        
+    def setOverlap(self, overlap):
+        self._overlap = overlap
+    
+    def getSlidingMsg(self):
+        return "Window is sliding : %s %s" %(self._start, self._end)
+
+class SlidingWindowToCountMatchingBases(SlidingWindow):
+    
+    def getSetLengthOnWindow( self, iSet ):
+        if self._isSetIncludedInTheWindow(iSet):
+            return iSet.getLength()
+        if self._isWindowIncludedInTheSet(iSet):
+            return self._length
+        elif self._isSetOverlapTheRightSideOfTheWindow(iSet):
+            return self._end - iSet.getMin()+1
+        elif self._isSetOverlapTheLeftSideOfTheWindow(iSet):
+            return iSet.getMax() - self._start+1
+        
+    def getCoordSetOnWindow( self, iSet ):
+        if self._isSetIncludedInTheWindow(iSet):
+            return iSet.getStart(), iSet.getEnd()
+        if self._isWindowIncludedInTheSet(iSet):
+            return self.getStart(), self.getEnd()
+        elif self._isSetOverlapTheRightSideOfTheWindow(iSet):
+            return iSet.getStart(), self.getEnd()
+        elif self._isSetOverlapTheLeftSideOfTheWindow(iSet):
+            return self.getStart(), iSet.getEnd()
+        
+    def _isSetIncludedInTheWindow(self, feature):
+        return feature.getMin() >= self._start and feature.getMax() <= self._end
+    
+    def _isWindowIncludedInTheSet(self, feature):
+        return self._start >= feature.getMin() and self._end <= feature.getMax()
+
+    def _isSetOverlapTheRightSideOfTheWindow(self, feature):
+        return feature.getMin() <= self._end and feature.getMin() >= self._start
+
+    def _isSetOverlapTheLeftSideOfTheWindow(self, feature):
+        return feature.getMax() <= self._end and feature.getMax() >= self._start    
Binary file smart_toolShed/commons/core/coord/__init__.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/align2set.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+
+import sys
+import getopt
+from commons.core.coord.Align import Align
+
+def help():
+    print
+    print "usage: %s [ options ]" % ( sys.argv[0].split("/")[-1] )
+    print "options:"
+    print "     -h: this help"
+    print "     -i: input file name (format='align')"
+    print "     -o: output file name (format='set', default=inFileName+'.set')"
+    print "     -v: verbosity level (default=0/1)"
+    print
+    
+
+def align2set( inFileName, outFileName ):
+    alignFileHandler = open( inFileName, "r" )
+    setFileHandler = open( outFileName, "w" )
+    iAlign = Align()
+    countAlign = 0
+    while True:
+        line = alignFileHandler.readline()
+        if line == "":
+            break
+        countAlign += 1
+        iAlign.setFromString( line, "\t" )
+        setFileHandler.write( "%i\t%s\t%s\t%i\t%i\n" % ( countAlign,
+                                                         iAlign.getSubjectName(),
+                                                         iAlign.getQueryName(),
+                                                         iAlign.getQueryStart(),
+                                                         iAlign.getQueryEnd() ) )
+    alignFileHandler.close()
+    setFileHandler.close()
+
+
+def main():
+
+    inFileName = ""
+    outFileName = ""
+    verbose = 0
+
+    try:
+        opts, args = getopt.getopt( sys.argv[1:], "hi:o:v:" )
+    except getopt.GetoptError, err:
+        print str(err)
+        help()
+        sys.exit(1)
+    for o,a in opts:
+        if o == "-h":
+            help()
+            sys.exit(0)
+        elif o == "-i":
+            inFileName = a
+        elif o == "-o":
+            outFileName = a
+        elif o == "-v":
+            verbose = int(a)
+
+    if  inFileName == "":
+        print "ERROR: missing input file name"
+        help()
+        sys.exit(1)
+
+    if verbose > 0:
+        print "START %s" % ( sys.argv[0].split("/")[-1] )
+        sys.stdout.flush()
+
+    if outFileName == "":
+        outFileName = "%s.set" % ( inFileName )
+
+#TODO: move 'align2set' into 'AlignUtils.convertAlignFileIntoPSetFile' with a test
+#    AlignUtils.convertAlignFileIntoPSetFile( inFileName, outFileName )
+
+    align2set( inFileName, outFileName )
+
+    if verbose > 0:
+        print "END %s" % ( sys.argv[0].split("/")[-1] )
+        sys.stdout.flush()
+
+    return 0
+
+
+if __name__ == "__main__":
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/TestSuite_coord.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import sys
+import Test_Align
+import Test_AlignUtils
+import Test_Map
+import Test_MapUtils
+import Test_Match
+import Test_MatchUtils
+import Test_Path
+import Test_PathUtils
+import Test_Range
+import Test_Set
+import Test_SetUtils
+
+
+def main():
+    
+    TestSuite_coord = unittest.TestSuite() 
+    
+    TestSuite_coord.addTest( unittest.makeSuite( Test_Align.Test_Align, "test" ) )
+    TestSuite_coord.addTest( unittest.makeSuite( Test_AlignUtils.Test_AlignUtils, "test" ) )
+    TestSuite_coord.addTest( unittest.makeSuite( Test_Map.Test_Map, "test" ) )
+    TestSuite_coord.addTest( unittest.makeSuite( Test_MapUtils.Test_MapUtils, "test" ) )
+    TestSuite_coord.addTest( unittest.makeSuite( Test_Match.Test_Match, "test" ) )
+    TestSuite_coord.addTest( unittest.makeSuite( Test_MatchUtils.Test_MatchUtils, "test" ) )
+    TestSuite_coord.addTest( unittest.makeSuite( Test_Path.Test_Path, "test" ) )
+    TestSuite_coord.addTest( unittest.makeSuite( Test_PathUtils.Test_PathUtils, "test" ) )
+    TestSuite_coord.addTest( unittest.makeSuite( Test_Range.Test_Range, "test" ) )
+    TestSuite_coord.addTest( unittest.makeSuite( Test_Set.Test_Set, "test" ) )
+    TestSuite_coord.addTest( unittest.makeSuite( Test_SetUtils.Test_SetUtils, "test" ) )
+    
+    runner = unittest.TextTestRunner( sys.stderr, 2, 2 )
+    runner.run( TestSuite_coord )
+    
+    
+if __name__ == "__main__":
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_Align.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,518 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+import time
+from commons.core.coord.Align import Align
+from commons.core.coord.Map import Map
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.coord.Range import Range
+
+
+class Test_Align( unittest.TestCase ):
+    
+    def setUp(self):
+        self._align = Align()
+        self._uniqId = "%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        
+    def tearDown(self):
+        self._align = None
+        
+    def test_isEmpty_True(self):
+        alignInstance = Align()
+        
+        self.assertTrue(alignInstance.isEmpty())
+        
+    def test_isEmpty_True_query_is_empty(self):
+        alignInstance = Align()
+        line = "\t-1\t-1\tTE2\t3\t10\t1e-20\t30\t90.2\n"
+        alignInstance.setFromString(line)
+        
+        self.assertTrue(alignInstance.isEmpty())
+        
+    def test_isEmpty_True_subject_is_empty(self):
+        alignInstance = Align()
+        line = "chr1\t2\t20\t\t-1\t-1\t1e-20\t30\t90.2\n"
+        alignInstance.setFromString(line)
+        
+        self.assertTrue(alignInstance.isEmpty())
+        
+    def test_isEmpty_False(self):
+        alignInstance = Align()
+        line = "chr1\t2\t20\tTE2\t3\t10\t1e-20\t30\t90.2\n"
+        alignInstance.setFromString(line)
+        
+        self.assertFalse(alignInstance.isEmpty())
+        
+    def test_read(self):
+        line = "chr2\t1\t10\tTE3\t11\t17\t1e-20\t30\t90.2\n"
+        expReturn = 1
+
+        dummyMockAlignFile = "dummyMockAlignFile"
+        mockAlignFileHandle = open(dummyMockAlignFile, "w")
+        mockAlignFileHandle.write(line)
+        mockAlignFileHandle.close()
+        
+        expAlignInstance = Align()
+        expAlignInstance.setFromString(line)
+
+        mockAlignFileHandle = open(dummyMockAlignFile, "r")
+        obsAlignInstance = Align()
+        obsReturn = obsAlignInstance.read(mockAlignFileHandle)
+        
+        mockAlignFileHandle.close()
+        os.remove(dummyMockAlignFile)   
+        
+        self.assertEquals(expAlignInstance, obsAlignInstance)    
+        self.assertEquals(expReturn, obsReturn)    
+        
+    def test_read_empty_file(self):
+        expReturn = 0
+         
+        dummyMockAlignFile = "dummyMockAlignFile"
+        mockAlignFileHandle = open(dummyMockAlignFile, "w")
+        mockAlignFileHandle.close()
+       
+        mockAlignFileHandle = open(dummyMockAlignFile, "r")
+        obsAlignInstance = Align()
+        obsReturn = obsAlignInstance.read(mockAlignFileHandle)
+        os.remove(dummyMockAlignFile)   
+        
+        self.assertEquals(expReturn, obsReturn)
+        
+    def test_write (self):
+        expAlignFile = "expMockAlignFile"
+        expAlignFileHandle = open(expAlignFile, "w")
+        expLine = "chr1\t1\t10\tTE2\t3\t10\t0\t30\t90.200000\n"
+        expAlignFileHandle.write(expLine)
+        expAlignFileHandle.close()
+       
+        obsAlignFile = "obsAlignFile"
+        obsAlignFileHandle = open(obsAlignFile, "w")
+        obsAlignInstance = Align()
+        obsAlignTuple = ("chr1", 1, 10, "TE2", 3, 10, 0.0, 30, 90.2)
+        obsAlignInstance.setFromTuple(obsAlignTuple) 
+        obsAlignInstance.write(obsAlignFileHandle)
+        obsAlignFileHandle.close()   
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expAlignFile, obsAlignFile ) )
+        os.remove(expAlignFile)
+        os.remove(obsAlignFile)
+        
+    def test_merge (self):
+        alignInstanceChr1 = Align()
+        alignInstanceChr2 = Align()
+
+        line1 = "chr1\t1\t10\tTE2\t3\t10\t1e-20\t30\t90.2\n"
+        line2 = "chr2\t1\t10\tTE2\t11\t17\t1e-20\t30\t90.2\n"
+
+        alignInstanceChr1.setFromString(line1)
+        alignInstanceChr2.setFromString(line2)
+        
+        expResult = None
+        obsResult = alignInstanceChr1.merge(alignInstanceChr2)
+        
+        self.assertEquals(expResult, obsResult)
+        
+        line1 = "chr1\t1\t10\tTE2\t3\t10\t1e-20\t30\t90.2\n"
+        line2 = "chr1\t1\t10\tTE3\t11\t17\t1e-20\t30\t90.2\n"
+
+        alignInstanceTE2 = Align()
+        alignInstanceTE3 = Align()
+ 
+        alignInstanceTE2.setFromString(line1)
+        alignInstanceTE3.setFromString(line2)
+        
+        expResult = None
+        obsResult = alignInstanceTE2.merge(alignInstanceTE3)
+        
+        self.assertEquals(expResult, obsResult)
+        
+    def test_merge_plus_strand1 (self):
+        alignInstance1 = Align()
+        alignInstance2 = Align()
+
+        line1 = "chr1\t2\t20\tTE2\t3\t10\t1e-20\t30\t90.2\n"
+        line2 = "chr1\t1\t10\tTE2\t1\t9\t1e-20\t30\t90.2\n"
+
+        alignInstance1.setFromString(line1)
+        alignInstance2.setFromString(line2)
+        
+        expLine = "chr1\t1\t20\tTE2\t1\t10\t1e-20\t30\t90.2\n"
+        expAlign = Align()
+        expAlign.setFromString(expLine)
+
+        alignInstance1.merge(alignInstance2)
+        obsAlign = alignInstance1
+
+        self.assertEquals(expAlign, obsAlign)
+        
+    def test_merge_plus_strand2 (self ):
+        alignInstance1 = Align()
+        alignInstance2 = Align()
+
+        line1 = "chr1\t2\t20\tTE2\t3\t10\t1e-20\t30\t90.2\n"
+        line2 = "chr1\t4\t30\tTE2\t4\t12\t1e-20\t30\t90.2\n"
+
+        alignInstance1.setFromString(line1)
+        alignInstance2.setFromString(line2)
+        
+        expLine = "chr1\t2\t30\tTE2\t3\t12\t1e-20\t30\t90.2\n"
+        expAlign = Align()
+        expAlign.setFromString(expLine)
+
+        alignInstance1.merge(alignInstance2)
+        obsAlign = alignInstance1
+
+        self.assertEquals(expAlign, obsAlign)
+        
+    def test_merge_plus_strand3 (self ):
+        alignInstance1 = Align()
+        alignInstance2 = Align()
+
+        line1 = "chr1\t2\t10\tTE2\t3\t10\t1e-20\t30\t90.2\n"
+        line2 = "chr1\t1\t20\tTE2\t1\t12\t1e-20\t30\t90.2\n"
+
+        alignInstance1.setFromString(line1)
+        alignInstance2.setFromString(line2)
+        
+        expLine = "chr1\t1\t20\tTE2\t1\t12\t1e-20\t30\t90.2\n"
+        expAlign = Align()
+        expAlign.setFromString(expLine)
+
+        alignInstance1.merge(alignInstance2)
+        obsAlign = alignInstance1
+
+        self.assertEquals(expAlign, obsAlign)
+        
+    def test_merge_plus_strand4 (self ):
+        alignInstance1 = Align()
+        alignInstance2 = Align()
+
+        line1 = "chr1\t1\t20\tTE2\t1\t12\t1e-20\t30\t90.2\n"
+        line2 = "chr1\t2\t10\tTE2\t2\t10\t1e-20\t30\t90.2\n"
+
+        alignInstance1.setFromString(line1)
+        alignInstance2.setFromString(line2)
+        
+        expLine = "chr1\t1\t20\tTE2\t1\t12\t1e-20\t30\t90.2\n"
+        expAlign = Align()
+        expAlign.setFromString(expLine)
+
+        alignInstance1.merge(alignInstance2)
+        obsAlign = alignInstance1
+
+        self.assertEquals(expAlign, obsAlign)
+        
+    def test_merge__neg_strand1 (self):
+
+        rangeQuery1 = Range("chr1", 20, 2); rangeSubject1 = Range("TE2", 10, 3)
+        rangeQuery2 = Range("chr1", 1, 10); rangeSubject2 = Range("TE2", 1, 9)
+
+        alignInstance1 = Align(rangeQuery1, rangeSubject1, 0, 30, 90.2)
+        alignInstance2 = Align(rangeQuery2, rangeSubject2, 0, 30, 90.2)
+        
+        expRangeQuery = Range("chr1", 20, 1); expRangeSubject = Range("TE2", 10, 1)
+        expAlign = Align(expRangeQuery, expRangeSubject, 0, 30, 90.2)
+
+        alignInstance1.merge(alignInstance2)
+        obsAlign = alignInstance1
+        
+        self.assertEquals(expAlign, obsAlign)
+        
+    def test_merge__neg_strand2 (self):
+        rangeQuery1 = Range("chr1", 20, 2); rangeSubject1 = Range("TE2", 10, 3)
+        rangeQuery2 = Range("chr1", 4, 30); rangeSubject2 = Range("TE2", 4, 12)
+
+        alignInstance1 = Align(rangeQuery1, rangeSubject1, 0, 30, 90.2)
+        alignInstance2 = Align(rangeQuery2, rangeSubject2, 0, 30, 90.2)
+        
+        expRangeQuery = Range("chr1", 30, 2); expRangeSubject = Range("TE2", 12, 3)
+        expAlign = Align(expRangeQuery, expRangeSubject, 0, 30, 90.2)
+
+        alignInstance1.merge(alignInstance2)
+        obsAlign = alignInstance1
+
+        self.assertEquals(expAlign, obsAlign)
+        
+    def test_merge_neg_strand3 (self ):
+        rangeQuery1 = Range("chr1", 10, 2); rangeSubject1 = Range("TE2", 10, 3)
+        rangeQuery2 = Range("chr1", 1, 20); rangeSubject2 = Range("TE2", 1, 12)
+
+        alignInstance1 = Align(rangeQuery1, rangeSubject1, 0, 30, 90.2)
+        alignInstance2 = Align(rangeQuery2, rangeSubject2, 0, 30, 90.2)
+       
+        expRangeQuery = Range("chr1", 20, 1); expRangeSubject = Range("TE2", 12, 1)
+        expAlign = Align(expRangeQuery, expRangeSubject, 0, 30, 90.2)
+
+        alignInstance1.merge(alignInstance2)
+        obsAlign = alignInstance1
+
+        self.assertEquals(expAlign, obsAlign)
+        
+    def test_merge_neg_strand4 (self ):
+        rangeQuery1 = Range("chr1", 20, 1); rangeSubject1 = Range("TE2", 12, 1)
+        rangeQuery2 = Range("chr1", 2, 10); rangeSubject2 = Range("TE2", 2, 10)
+
+        alignInstance1 = Align(rangeQuery1, rangeSubject1, 0, 30, 90.2)
+        alignInstance2 = Align(rangeQuery2, rangeSubject2, 0, 30, 90.2)
+        
+        expRangeQuery = Range("chr1", 20, 1); expRangeSubject = Range("TE2", 12, 1)
+        expAlign = Align(expRangeQuery, expRangeSubject, 0, 30, 90.2)
+
+        alignInstance1.merge(alignInstance2)
+        obsAlign = alignInstance1
+
+        self.assertEquals(expAlign, obsAlign)
+        
+    def test_merge_id_score_identity_eValue (self):
+        rangeQuery1 = Range("chr1", 20, 1); rangeSubject1 = Range("TE2", 12, 1)
+        rangeQuery2 = Range("chr1", 2, 10); rangeSubject2 = Range("TE2", 2, 10)
+
+        alignInstance1 = Align(rangeQuery1, rangeSubject1, 0.05, 20, 90.2)
+        alignInstance1.id = 1
+        alignInstance2 = Align(rangeQuery2, rangeSubject2, 0, 30, 90.3)
+        alignInstance2.id = 2
+
+        expRangeQuery = Range("chr1", 20, 1); expRangeSubject = Range("TE2", 12, 1)
+        expAlign = Align(expRangeQuery, expRangeSubject, 0, 30, 90.3)
+        expAlign.id = 1
+        
+        alignInstance1.merge(alignInstance2)
+        obsAlign = alignInstance1
+
+        self.assertEquals(expAlign, obsAlign)
+        self.assertEquals(expAlign.id, obsAlign.id)
+        
+    def test_setFromTuple_QryRev(self):
+        self._align.setFromTuple( ( "qry1", 100, 1, "sbj1", 201, 300, 0.0, 135, 97.2 ) )
+        self.assertEqual( self._align.range_query.seqname, "qry1" )
+        self.assertEqual( self._align.range_query.start, 1 )
+        self.assertEqual( self._align.range_query.end, 100 )
+        self.assertEqual( self._align.range_subject.seqname, "sbj1" )
+        self.assertEqual( self._align.range_subject.start, 300 )
+        self.assertEqual( self._align.range_subject.end, 201 )
+        self.assertEqual( self._align.e_value, 0.0 )
+        self.assertEqual( self._align.score, 135 )
+        self.assertEquals( self._align.identity, 97.2 )
+        
+    def test_setFromTuple_identityAsFloat(self):
+        self._align.setFromTuple( ( "qry1", "301", "600", "sbj1", "1", "300", "0.0", "135", 0.0) )
+        self.assertEqual( self._align.range_query.seqname, "qry1" )
+        self.assertEqual( self._align.range_query.start, 301 )
+        self.assertEqual( self._align.range_query.end, 600 )
+        self.assertEqual( self._align.range_subject.seqname, "sbj1" )
+        self.assertEqual( self._align.range_subject.start, 1 )
+        self.assertEqual( self._align.range_subject.end, 300 )
+        self.assertEqual( self._align.e_value, float("0.0") )
+        self.assertEqual( self._align.score, float("135") )
+        self.assertEquals( self._align.identity, 0.0 )
+        
+    def test_setFromString(self):
+        line = "chr1\t1\t10\tTE2\t11\t17\t1e-20\t30\t90.2\n"
+        self._align.setFromString( line )
+        self.assertEqual( self._align.range_query.seqname, "chr1" )
+        self.assertEqual( self._align.range_query.start, 1 )
+        self.assertEqual( self._align.range_query.end, 10 )
+        self.assertEqual( self._align.range_subject.seqname, "TE2" )
+        self.assertEqual( self._align.range_subject.start, 11 )
+        self.assertEqual( self._align.range_subject.end, 17 )
+        self.assertEqual( self._align.e_value, float("1e-20") )
+        self.assertEqual( self._align.score, float("30") )
+        self.assertEquals( float(self._align.identity), float("90.2") )
+        
+    def test__eq__(self):
+        self._align.setFromString( "chr1\t1\t6\tTE2\t11\t16\t1e-20\t30\t90.2\n" )
+        o = Align()
+        o.setFromString( "chr1\t1\t6\tTE2\t11\t16\t1e-20\t30\t90.2\n" )
+        self.assertEqual( self._align,  o )
+        o.setFromString( "chromosome1\t1\t6\tTE2\t11\t16\t1e-20\t30\t90.2\n" )
+        self.assertNotEqual( self._align, o )
+        o.setFromString( "chr1\t1\t6\ttranspElem2\t11\t16\t1e-20\t30\t90.2\n" )
+        self.assertNotEqual( self._align, o )
+        o.setFromString( "chr1\t100\t600\tTE2\t11\t16\t1e-20\t30\t90.2\n" )
+        self.assertNotEqual( self._align, o )
+        o.setFromString( "chr1\t1\t6\tTE2\t1100\t1600\t1e-20\t30\t90.2\n" )
+        self.assertNotEqual( self._align, o )
+        o.setFromString( "chr1\t1\t6\tTE2\t11\t16\t1e-20\t30000\t90.2\n" )
+        self.assertNotEqual( self._align, o )
+        
+    def test_getSubjectAsMapOfQuery_direct(self):
+        exp = Map( name="TE2", seqname="chr1", start=1, end=6 )
+        self._align.setFromString( "chr1\t1\t6\tTE2\t11\t16\t1e-20\t30\t90.2\n" )
+        obs = self._align.getSubjectAsMapOfQuery()
+        self.assertEqual( obs, exp )
+        
+    def test_getSubjectAsMapOfQuery_reverse(self):
+        exp = Map( name="TE2", seqname="chr1", start=6, end=1 )
+        self._align.setFromString( "chr1\t1\t6\tTE2\t16\t11\t1e-20\t30\t90.2\n" )
+        obs = self._align.getSubjectAsMapOfQuery()
+        self.assertEqual( obs, exp )
+        
+    def test_writeSubjectAsMapOfQuery( self ):
+        self._align.setFromTuple( ( "chr3", "250", "151", "seq5", "1", "100", "1e-32", "147", "87.9" ) )
+        expFile = "dummyExpFile_%s" % ( self._uniqId )
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "seq5\tchr3\t250\t151\n" )
+        expFileHandler.close()
+        obsFile = "dummyObsFile_%s" % ( self._uniqId )
+        obsFileHandler = open( obsFile, "w" )
+        self._align.writeSubjectAsMapOfQuery( obsFileHandler )
+        obsFileHandler.close()
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        for f in [ expFile, obsFile ]:
+            if os.path.exists( f ):
+                os.remove( f )
+                
+    def test_areQrySbjOnOppositeStrands(self):
+        self._align.setFromTuple( ( "qry1", "1", "100", "sbj1", "1", "100", "0.0", "135", "95.7" ) )
+        obs = self._align.areQrySbjOnOppositeStrands()
+        self.assertFalse( obs )
+        self._align.setFromTuple( ( "qry1", "600", "301", "sbj1", "1", "300", "0.0", "135", "95.7" ) )
+        obs = self._align.areQrySbjOnOppositeStrands()
+        self.assertTrue( obs )
+        
+    def test_reverse(self):
+        line = "chr1\t1\t10\tTE2\t11\t17\t1e-20\t30\t90.2"
+        expLine = "chr1\t10\t1\tTE2\t17\t11\t1e-20\t30\t90.200000"
+        
+        obsAlignInstance = Align()
+        obsAlignInstance.setFromString(line)
+        obsAlignInstance.reverse()
+        obsLine = obsAlignInstance.toString()
+
+        self.assertEquals(expLine, obsLine)
+        
+    def test_getMapsOfQueryAndSubject(self):
+        self._align.setFromTuple( ( "qry1", "1", "100", "sbj1", "1", "100", "0.0", "135", "95.7" ) )
+        
+        expMapQuery = Map()
+        expMapQuery.setFromTuple( ( "repet", "qry1", "1", "100" ) )
+        expMapSubject = Map()
+        expMapSubject.setFromTuple( ( "repet", "sbj1", "1", "100" ) )
+        
+        obsMapQuery, obsMapSubject = self._align.getMapsOfQueryAndSubject()
+        
+        self.assertEqual( expMapQuery, obsMapQuery )
+        self.assertEqual( expMapSubject, obsMapSubject )
+        
+    def test_getBin_bin_level_9(self):
+        tuple = ("chr1","190000000","390000000","TE2","11","17","1e-20","30","90.2")
+        self._align.setFromTuple(tuple)
+        expRes = 100000000.0
+        obsRes = self._align.getBin()
+        self.assertEquals(expRes, obsRes)
+
+    def test_getBin_bin_level_8(self):
+        tuple = ("chr1","19000000","39000000","TE2","11","17","1e-20","30","90.2")
+        self._align.setFromTuple(tuple)
+        expRes = 100000000.0
+        obsRes = self._align.getBin()
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_7(self):
+        tuple = ("chr1","1900000","3900000","TE2","11","17","1e-20","30","90.2")
+        self._align.setFromTuple(tuple)
+        expRes = 10000000.0
+        obsRes = self._align.getBin()
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_6(self):
+        tuple = ("chr1","190000","390000","TE2","11","17","1e-20","30","90.2")
+        self._align.setFromTuple(tuple)
+        obsRes = self._align.getBin()
+        expRes = 1000000.0
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_5(self):
+        tuple = ("chr1","19000","39000","TE2","11","17","1e-20","30","90.2")
+        self._align.setFromTuple(tuple)
+        obsRes = self._align.getBin()
+        expRes = 100000.0
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_4(self):
+        tuple = ("chr1","1900","3900","TE2","11","17","1e-20","30","90.2")
+        self._align.setFromTuple(tuple)
+        obsRes = self._align.getBin()
+        expRes = 10000.0
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_3(self):
+        tuple = ("chr1","190","390","TE2","11","17","1e-20","30","90.2")
+        self._align.setFromTuple(tuple)
+        obsRes = self._align.getBin()
+        expRes = 1000.0
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_2(self):
+        tuple = ("chr1","19","39","TE2","11","17","1e-20","30","90.2")
+        self._align.setFromTuple(tuple)
+        obsRes = self._align.getBin()
+        expRes = 1000.0
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_1(self):
+        tuple = ("chr1","1","3","TE2","11","17","1e-20","30","90.2")
+        self._align.setFromTuple(tuple)
+        obsRes = self._align.getBin()
+        expRes = 1000.0
+        self.assertEquals(expRes, obsRes)
+        
+        
+    def test_switchQuerySubject_directS( self ):
+        tuple = ("chr1","1","3","TE2","11","17","1e-20","30","90.2")
+        self._align.setFromTuple( tuple )
+        exp = Align( Range("TE2","11","17"), Range("chr1","1","3"), "1e-20", "30", "90.2" )
+        self._align.switchQuerySubject()
+        self.assertEquals( exp, self._align )
+        
+        
+    def test_switchQuerySubject_reverseS( self ):
+        tuple = ("chr1","1","3","TE2","17","11","1e-20","30","90.2")
+        self._align.setFromTuple( tuple )
+        exp = Align( Range("TE2","11","17"), Range("chr1","3","1"), "1e-20", "30", "90.2" )
+        self._align.switchQuerySubject()
+        self.assertEquals( exp, self._align )
+        
+        
+    def test_toStringAsGff( self ):
+        self._align.setFromString( "chr1\t1\t10\tTE3\t11\t17\t1e-20\t30\t85.2\n" )
+        exp = "chr1\tREPET\tmatch\t1\t10\t1e-20\t+\t.\tID=23;Target=TE3 11 17"
+        obs = self._align.toStringAsGff( ID="23" )
+        self.assertEqual( obs, exp )
+        
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_Align ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_AlignUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,777 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+import time
+import shutil
+from commons.core.coord.AlignUtils import AlignUtils
+from commons.core.coord.Align import Align
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.coord.Range import Range
+
+
+class Test_AlignUtils( unittest.TestCase ):
+    
+    def setUp( self ):
+        self._uniqId = "%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        
+        
+    def tearDown( self ):
+        self._uniqId = ""
+        
+        
+    def test_getAlignListFromFile( self ):
+        a1 = Align()
+        a1.setFromTuple( ( "chr1", "1", "100", "seq3", "1", "100", "1e-23", "89", "97.26" ) )
+        a2 = Align()
+        a2.setFromTuple( ( "chr2", "121", "210", "seq5", "21", "110", "1e-32", "95", "98.13" ) )
+        
+        inFileName = "dummyFile_%s" % ( self._uniqId )
+        inFileHandler = open( inFileName, "w" )
+        a1.write( inFileHandler )
+        a2.write( inFileHandler )
+        inFileHandler.close()
+        
+        lExp = [ a1, a2 ]
+        lObs = AlignUtils.getAlignListFromFile( inFileName )
+        
+        self.assertEqual( lExp, lObs )
+        
+        if os.path.exists( inFileName ):
+            os.remove( inFileName )
+            
+            
+    def test_getListOfScores( self ):
+        a1 = Align()
+        a1.setFromTuple( ( "chr1", "1", "100", "seq3", "1", "100", "1e-23", "89", "97.26" ) )
+        a2 = Align()
+        a2.setFromTuple( ( "chr2", "121", "210", "seq5", "21", "110", "1e-32", "95", "98.13" ) )
+        lAligns = [ a1, a2 ]
+        
+        lExp = [ 89, 95 ]
+        lObs = AlignUtils.getListOfScores( lAligns )
+        
+        self.assertEqual( lExp, lObs )
+        
+        
+    def test_getScoreListFromFile( self ):
+        alignFile = "dummyAlignFile"
+        alignFileHandler = open( alignFile, "w" )
+        alignFileHandler.write( "chr3\t1\t100\tchr5\t11\t110\t1e-52\t133\t87.2\n" )
+        alignFileHandler.write( "chr7\t1\t200\tchr2\t11\t210\t1e-78\t235\t98.9\n" )
+        alignFileHandler.close()
+        
+        lExp = [ 133, 235 ]
+        lObs = AlignUtils.getScoreListFromFile( alignFile )
+        self.assertEqual( lExp, lObs )
+        
+        os.remove( alignFile )
+        
+        
+    def test_getScoreListFromFile_empty_file( self ):
+        alignFile = "dummyAlignFile"
+        alignFileHandler = open( alignFile, "w" )
+        alignFileHandler.close()
+        
+        lExp = []
+        lObs = AlignUtils.getScoreListFromFile( alignFile )
+        
+        self.assertEqual( lExp, lObs )
+        
+        os.remove( alignFile )
+        
+        
+    def test_getScoreListFromFile_with_endline_char( self ):
+        alignFile = "dummyAlignFile"
+        alignFileHandler = open( alignFile, "w" )
+        alignFileHandler.write( "chr3\t1\t100\tchr5\t11\t110\t1e-52\t133\t87.2\n" )
+        alignFileHandler.write( "\n" )
+        alignFileHandler.write( "chr7\t1\t200\tchr2\t11\t210\t1e-78\t235\t98.9\n" )
+        alignFileHandler.write( "\n" )
+        alignFileHandler.close()
+        
+        lExp = [133, 235]
+        lObs = AlignUtils.getScoreListFromFile( alignFile )
+        
+        self.assertEqual( lExp, lObs )
+        
+        os.remove( alignFile )
+        
+        
+    def test_convertAlignFileIntoMapFileWithQueriesAndSubjects( self ):
+        alignFile = "dummyAlignFile_%s" % ( self._uniqId )
+        alignFileHandler = open( alignFile, "w" )
+        alignFileHandler.write( "chr3\t1\t100\tchr5\t11\t110\t1e-52\t133\t87.2\n" )
+        alignFileHandler.write( "chr7\t1\t200\tchr2\t11\t210\t1e-78\t235\t98.9\n" )
+        alignFileHandler.close()
+        
+        expFile = "dummyExpFile_%s" % ( self._uniqId )
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "repet\tchr3\t1\t100\n" )
+        expFileHandler.write( "repet\tchr5\t11\t110\n" )
+        expFileHandler.write( "repet\tchr7\t1\t200\n" )
+        expFileHandler.write( "repet\tchr2\t11\t210\n" )
+        expFileHandler.close()
+        
+        obsFile = "dummyObsFile_%s" % ( self._uniqId )
+        
+        AlignUtils.convertAlignFileIntoMapFileWithQueriesAndSubjects( alignFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ alignFile, expFile, obsFile ]:
+            if os.path.exists( f ):
+                os.remove( f )
+                
+                
+    def test_convertAlignFileIntoMapFileWithSubjectsOnQueries( self ):
+        alignFile = "dummyAlignFile_%s" % ( self._uniqId )
+        alignFileHandler = open( alignFile, "w" )
+        alignFileHandler.write( "chr3\t1\t100\tTE1\t11\t110\t1e-52\t133\t87.2\n" )
+        alignFileHandler.write( "chr7\t1\t200\tTE1\t11\t210\t1e-78\t235\t98.9\n" )
+        alignFileHandler.close()
+        
+        expFile = "dummyExpFile_%s" % ( self._uniqId )
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "TE1\tchr3\t1\t100\n" )
+        expFileHandler.write( "TE1\tchr7\t1\t200\n" )
+        expFileHandler.close()
+        
+        obsFile = "dummyObsFile_%s" % ( self._uniqId )
+        
+        AlignUtils.convertAlignFileIntoMapFileWithSubjectsOnQueries( alignFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ alignFile, expFile, obsFile ]:
+            if os.path.exists( f ):
+                os.remove( f )
+                
+                
+    def test_getAlignListSortedByDecreasingScoreThenLength( self ):
+        a1 = Align()
+        a1.setFromTuple( ( "chr1", "1", "100", "seq3", "1", "100", "1e-23", "89", "97.26" ) )
+        a2 = Align()
+        a2.setFromTuple( ( "chr7", "121", "200", "seq9", "21", "110", "1e-32", "95", "98.13" ) )
+        a3 = Align()
+        a3.setFromTuple( ( "chr2", "121", "210", "seq5", "21", "110", "1e-32", "95", "98.13" ) )
+        lAligns = [ a1, a2, a3 ]
+        
+        lExp = [ a3, a2, a1 ]
+        
+        lObs = AlignUtils.getAlignListSortedByDecreasingScoreThenLength( lAligns )
+        
+        self.assertEqual( lExp, lObs )
+        
+        
+    def test_convertAlignFileIntoPathFile( self ):
+        alignFile = "dummyAlignFile_%s" % ( self._uniqId )
+        alignFileHandler = open( alignFile, "w" )
+        alignFileHandler.write( "chr3\t1\t100\tchr5\t11\t110\t1e-52\t133\t87.200000\n" )
+        alignFileHandler.write( "chr7\t1\t200\tchr2\t11\t210\t1e-78\t235\t98.900000\n" )
+        alignFileHandler.close()
+        
+        expFile = "dummyExpFile_%s" % ( self._uniqId )
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "1\tchr3\t1\t100\tchr5\t11\t110\t1e-52\t133\t87.200000\n" )
+        expFileHandler.write( "2\tchr7\t1\t200\tchr2\t11\t210\t1e-78\t235\t98.900000\n" )
+        expFileHandler.close()
+        
+        obsFile = "dummyObsFile_%s" % ( self._uniqId )
+        
+        AlignUtils.convertAlignFileIntoPathFile( alignFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ alignFile, expFile, obsFile ]:
+            if os.path.exists( f ):
+                os.remove( f )
+                
+                
+    def test_sortAlignFile( self ):
+        alignFile = "dummyAlignFile_%s" % ( self._uniqId )
+        alignFileHandler = open( alignFile, "w" )
+        alignFileHandler.write( "chr7\t1\t200\tchr2\t11\t210\t1e-78\t235\t98.900000\n" )
+        alignFileHandler.write( "chr3\t1\t100\tchr5\t11\t110\t1e-52\t133\t87.200000\n" )
+        alignFileHandler.write( "chr8\t1\t100\tchr5\t11\t110\t1e-52\t133\t87.200000\n" )
+        alignFileHandler.write( "chr8\t1\t100\tchr5\t15\t90\t1e-52\t133\t87.200000\n" )
+        alignFileHandler.write( "chr8\t1\t100\tchr5\t11\t100\t1e-52\t133\t87.200000\n" )
+        alignFileHandler.close()
+        
+        expFile = "dummyExpFile_%s" % ( self._uniqId )
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "chr3\t1\t100\tchr5\t11\t110\t1e-52\t133\t87.200000\n" )
+        expFileHandler.write( "chr7\t1\t200\tchr2\t11\t210\t1e-78\t235\t98.900000\n" )
+        expFileHandler.write( "chr8\t1\t100\tchr5\t11\t100\t1e-52\t133\t87.200000\n" )
+        expFileHandler.write( "chr8\t1\t100\tchr5\t11\t110\t1e-52\t133\t87.200000\n" )
+        expFileHandler.write( "chr8\t1\t100\tchr5\t15\t90\t1e-52\t133\t87.200000\n" )
+        expFileHandler.close()
+        
+        obsFile = "dummyObsFile_%s" % ( self._uniqId )
+        
+        AlignUtils.sortAlignFile( alignFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ alignFile, expFile, obsFile ]:
+            if os.path.exists( f ):
+                os.remove( f )
+    
+    def test_writeListInFile( self ):
+        line1 = ("chr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        line2 = ("chr1\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        line3 = ("chr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        
+        expFileName = "expFileName.align"
+        expFileHandle = open ( expFileName, 'w' )
+        expFileHandle.write(line1)
+        expFileHandle.write(line2)
+        expFileHandle.write(line3)
+        expFileHandle.close()
+        
+        iAlign1 = Align()
+        iAlign1.setFromString("chr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign2 = Align()
+        iAlign2.setFromString("chr1\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign3 = Align()
+        iAlign3.setFromString("chr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        
+        obsFileName = "obsFileName.align"
+        obsPathList =[iAlign1, iAlign2, iAlign3] 
+        
+        AlignUtils.writeListInFile( obsPathList, obsFileName )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        
+        os.remove( obsFileName )
+        os.remove( expFileName )
+        
+        
+    def test_splitAlignListByQueryName_empty_list( self ):
+        lAlign = []
+        
+        obsLAlign = AlignUtils.splitAlignListByQueryName( lAlign )
+        
+        expLAlign = []
+        
+        self.assertEquals( expLAlign, obsLAlign )
+        
+        
+    def test_splitAlignListByQueryName( self ):
+        iAlign1 = Align()
+        iAlign1.setFromString("chr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign2 = Align()
+        iAlign2.setFromString("chr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign3 = Align()
+        iAlign3.setFromString("chr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        lAlign = [ iAlign1, iAlign2, iAlign3 ]
+        
+        obsLAlign = AlignUtils.splitAlignListByQueryName( lAlign )
+        
+        expLAlign = [ [ iAlign1, iAlign3 ],
+                     [ iAlign2 ] ]
+        
+        self.assertEquals( expLAlign, obsLAlign )
+        
+        
+    def test_splitAlignListByQueryName_last_align_alone( self ):
+        iAlign1 = Align()
+        iAlign1.setFromString("chr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign2 = Align()
+        iAlign2.setFromString("chr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign3 = Align()
+        iAlign3.setFromString("chr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign4 = Align()
+        iAlign4.setFromString("chr3\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign5 = Align()
+        iAlign5.setFromString("chr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign6 = Align()
+        iAlign6.setFromString("chr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign7 = Align()
+        iAlign7.setFromString("chr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign8 = Align()
+        iAlign8.setFromString("chr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign9 = Align()
+        iAlign9.setFromString("chr4\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        lAlign = [ iAlign1, iAlign2, iAlign3, iAlign4, iAlign5, iAlign6, iAlign7, iAlign8, iAlign9 ]
+
+        obsLAlign = AlignUtils.splitAlignListByQueryName( lAlign )
+        
+        expLAlign = [ [ iAlign1, iAlign3, iAlign6, iAlign7 ],
+                     [ iAlign2, iAlign5, iAlign8 ],
+                     [ iAlign4 ],
+                     [ iAlign9 ] ]
+        
+        self.assertEquals( expLAlign, obsLAlign )
+        
+        
+    def test_createAlignFiles( self ):
+        expFile1 = "dummyExpAlignFile.align_1"
+        expFile2 = "dummyExpAlignFile.align_2"
+        expFile3 = "dummyExpAlignFile.align_3"
+        expFile4 = "dummyExpAlignFile.align_4"
+        
+        f1 = open(expFile1, "w")
+        iAlign1 = Align()
+        iAlign1.setFromString("chr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign1.write(f1)
+        iAlign3 = Align()
+        iAlign3.setFromString("chr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign3.write(f1)
+        iAlign6 = Align()
+        iAlign6.setFromString("chr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign6.write(f1)
+        iAlign7 = Align()
+        iAlign7.setFromString("chr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign7.write(f1)
+        f1.close()
+        
+        f2 = open(expFile2, "w")
+        iAlign2 = Align()
+        iAlign2.setFromString("chr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign2.write(f2)
+        iAlign5 = Align()
+        iAlign5.setFromString("chr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign5.write(f2)
+        iAlign8 = Align()
+        iAlign8.setFromString("chr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign8.write(f2)
+        f2.close()
+        
+        f3 = open(expFile3, "w")
+        iAlign4 = Align()
+        iAlign4.setFromString("chr3\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign4.write(f3)
+        f3.close()
+        
+        f4 = open(expFile4, "w")
+        iAlign9 = Align()
+        iAlign9.setFromString("chr4\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign9.write(f4)
+        f4.close()
+        
+        lAlignList = [ [ iAlign1, iAlign3, iAlign6, iAlign7 ],
+                      [ iAlign2, iAlign5, iAlign8 ],
+                      [ iAlign4 ],
+                      [ iAlign9 ] ]
+        
+        AlignUtils.createAlignFiles( lAlignList, "dummyAlignFile" )
+        
+        obsFile1 = "dummyAlignFile_1.align"
+        obsFile2 = "dummyAlignFile_2.align"
+        obsFile3 = "dummyAlignFile_3.align"
+        obsFile4 = "dummyAlignFile_4.align"
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile1, obsFile1 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile2, obsFile2 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile3, obsFile3 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile4, obsFile4 ) )
+        
+        os.remove(expFile1)
+        os.remove(expFile2)
+        os.remove(expFile3)
+        os.remove(expFile4)
+        os.remove(obsFile1)
+        os.remove(obsFile2)
+        os.remove(obsFile3)
+        os.remove(obsFile4)
+        
+
+    def test_createAlignFiles_eleven_output_files( self ):
+        expFile1 = "dummyExpAlignFile.align_01"
+        expFile2 = "dummyExpAlignFile.align_02"
+        expFile3 = "dummyExpAlignFile.align_03"
+        expFile4 = "dummyExpAlignFile.align_04"
+        expFile5 = "dummyExpAlignFile.align_05"
+        expFile6 = "dummyExpAlignFile.align_06"
+        expFile7 = "dummyExpAlignFile.align_07"
+        expFile8 = "dummyExpAlignFile.align_08"
+        expFile9 = "dummyExpAlignFile.align_09"
+        expFile10 = "dummyExpAlignFile.align_10"
+        expFile11 = "dummyExpAlignFile.align_11"
+        lExpFiles = [expFile1, expFile2, expFile3, expFile4, expFile5, expFile6, expFile7, expFile8, expFile9, expFile10, expFile11]
+        
+        f1 = open(expFile1, "w")
+        iAlign1 = Align()
+        iAlign1.setFromString("chr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign1.write(f1)
+        f1.close()
+        
+        f2 = open(expFile2, "w")
+        iAlign2 = Align()
+        iAlign2.setFromString("chr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign2.write(f2)
+        f2.close()
+        
+        f3 = open(expFile3, "w")
+        iAlign3 = Align()
+        iAlign3.setFromString("chr3\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign3.write(f3)
+        f3.close()
+        
+        f4 = open(expFile4, "w")
+        iAlign4 = Align()
+        iAlign4.setFromString("chr4\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign4.write(f4)
+        f4.close()
+        
+        f = open(expFile5, "w")
+        iAlign5 = Align()
+        iAlign5.setFromString("chr5\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign5.write(f)
+        f.close()
+        
+        f = open(expFile6, "w")
+        iAlign6 = Align()
+        iAlign6.setFromString("chr6\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign6.write(f)
+        f.close()
+        
+        f = open(expFile7, "w")
+        iAlign7 = Align()
+        iAlign7.setFromString("chr7\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign7.write(f)
+        f.close()
+        
+        f = open(expFile8, "w")
+        iAlign8 = Align()
+        iAlign8.setFromString("chr8\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign8.write(f)
+        f.close()
+        
+        f = open(expFile9, "w")
+        iAlign9 = Align()
+        iAlign9.setFromString("chr9\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign9.write(f)
+        f.close()
+        
+        f = open(expFile10, "w")
+        iAlign10 = Align()
+        iAlign10.setFromString("chr10\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign10.write(f)
+        f.close()
+        
+        f = open(expFile11, "w")
+        iAlign11 = Align()
+        iAlign11.setFromString("chr11\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign11.write(f)
+        f.close()
+        
+        lAlignList = [[iAlign1], [iAlign2], [iAlign3], [iAlign4], [iAlign5], [iAlign6], [iAlign7], [iAlign8], [iAlign9], [iAlign10], [iAlign11]]
+        
+        AlignUtils.createAlignFiles(lAlignList, "dummyAlignFile")
+
+        obsFile1 = "dummyAlignFile_01.align"
+        obsFile2 = "dummyAlignFile_02.align"
+        obsFile3 = "dummyAlignFile_03.align"
+        obsFile4 = "dummyAlignFile_04.align"
+        obsFile5 = "dummyAlignFile_05.align"
+        obsFile6 = "dummyAlignFile_06.align"
+        obsFile7 = "dummyAlignFile_07.align"
+        obsFile8 = "dummyAlignFile_08.align"
+        obsFile9 = "dummyAlignFile_09.align"
+        obsFile10 = "dummyAlignFile_10.align"
+        obsFile11 = "dummyAlignFile_11.align"
+        lObsFiles = [obsFile1, obsFile2, obsFile3, obsFile4, obsFile5, obsFile6, obsFile7, obsFile8, obsFile9, obsFile10, obsFile11]
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile1, obsFile1 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile2, obsFile2 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile3, obsFile3 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile4, obsFile4 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile5, obsFile5 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile6, obsFile6 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile7, obsFile7 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile8, obsFile8 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile9, obsFile9 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile10, obsFile10 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile11, obsFile11 ) )
+        
+        for file in lExpFiles:
+            os.remove(file)
+        for file in lObsFiles:
+            os.remove(file)
+            
+            
+    def test_createAlignFiles_dirName_specified( self ):
+        expFile1 = "dummyExpAlignFile.align_1"
+        expFile2 = "dummyExpAlignFile.align_2"
+        expFile3 = "dummyExpAlignFile.align_3"
+        expFile4 = "dummyExpAlignFile.align_4"
+        
+        f1 = open(expFile1, "w")
+        iAlign1 = Align()
+        iAlign1.setFromString("chr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign1.write(f1)
+        iAlign3 = Align()
+        iAlign3.setFromString("chr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign3.write(f1)
+        iAlign6 = Align()
+        iAlign6.setFromString("chr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign6.write(f1)
+        iAlign7 = Align()
+        iAlign7.setFromString("chr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign7.write(f1)
+        f1.close()
+        
+        f2 = open(expFile2, "w")
+        iAlign2 = Align()
+        iAlign2.setFromString("chr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign2.write(f2)
+        iAlign5 = Align()
+        iAlign5.setFromString("chr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign5.write(f2)
+        iAlign8 = Align()
+        iAlign8.setFromString("chr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign8.write(f2)
+        f2.close()
+        
+        f3 = open(expFile3, "w")
+        iAlign4 = Align()
+        iAlign4.setFromString("chr3\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign4.write(f3)
+        f3.close()
+        
+        f4 = open(expFile4, "w")
+        iAlign9 = Align()
+        iAlign9.setFromString("chr4\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign9.write(f4)
+        f4.close()
+        
+        lAlignList = [[iAlign1, iAlign3, iAlign6, iAlign7], [iAlign2, iAlign5, iAlign8], [iAlign4], [iAlign9]]
+ 
+        dirName = "dummyAlignDir"    
+            
+        AlignUtils.createAlignFiles(lAlignList, "dummyAlignFile", dirName)
+
+        obsFile1 = dirName + "/dummyAlignFile_1.align"
+        obsFile2 = dirName + "/dummyAlignFile_2.align"
+        obsFile3 = dirName + "/dummyAlignFile_3.align"
+        obsFile4 = dirName + "/dummyAlignFile_4.align"
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile1, obsFile1 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile2, obsFile2 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile3, obsFile3 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile4, obsFile4 ) )
+        
+        os.remove(expFile1)
+        os.remove(expFile2)
+        os.remove(expFile3)
+        os.remove(expFile4)
+        shutil.rmtree (dirName)
+        
+        
+    def test_createAlignFiles_dirName_specified_with_ended_slash( self ):
+        expFile1 = "dummyExpAlignFile.align_1"
+        expFile2 = "dummyExpAlignFile.align_2"
+        expFile3 = "dummyExpAlignFile.align_3"
+        expFile4 = "dummyExpAlignFile.align_4"
+        
+        f1 = open(expFile1, "w")
+        iAlign1 = Align()
+        iAlign1.setFromString("chr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign1.write(f1)
+        iAlign3 = Align()
+        iAlign3.setFromString("chr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign3.write(f1)
+        iAlign6 = Align()
+        iAlign6.setFromString("chr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign6.write(f1)
+        iAlign7 = Align()
+        iAlign7.setFromString("chr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign7.write(f1)
+        f1.close()
+        
+        f2 = open(expFile2, "w")
+        iAlign2 = Align()
+        iAlign2.setFromString("chr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign2.write(f2)
+        iAlign5 = Align()
+        iAlign5.setFromString("chr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign5.write(f2)
+        iAlign8 = Align()
+        iAlign8.setFromString("chr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign8.write(f2)
+        f2.close()
+        
+        f3 = open(expFile3, "w")
+        iAlign4 = Align()
+        iAlign4.setFromString("chr3\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign4.write(f3)
+        f3.close()
+        
+        f4 = open(expFile4, "w")
+        iAlign9 = Align()
+        iAlign9.setFromString("chr4\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iAlign9.write(f4)
+        f4.close()
+        
+        lAlignList = [[iAlign1, iAlign3, iAlign6, iAlign7], [iAlign2, iAlign5, iAlign8], [iAlign4], [iAlign9]]
+ 
+        dirName = "dummyAlignDir/"    
+            
+        AlignUtils.createAlignFiles(lAlignList, "dummyAlignFile", dirName)
+
+        obsFile1 = dirName + "dummyAlignFile_1.align"
+        obsFile2 = dirName + "dummyAlignFile_2.align"
+        obsFile3 = dirName + "dummyAlignFile_3.align"
+        obsFile4 = dirName + "dummyAlignFile_4.align"
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile1, obsFile1 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile2, obsFile2 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile3, obsFile3 ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile4, obsFile4 ) )
+        
+        os.remove(expFile1)
+        os.remove(expFile2)
+        os.remove(expFile3)
+        os.remove(expFile4)
+        shutil.rmtree (dirName)
+        
+        
+    def test_sortList( self ):
+        iAlign1 = Align( Range("qry1",3,80), Range("sbj1",3,80), 1e-20, 103, 97.3 )  # higher query start
+        iAlign2 = Align( Range("qry1",1,100), Range("sbj1",1,100), 1e-20, 113, 97.3 )  # higher score
+        iAlign3 = Align( Range("qry2",1,100), Range("sbj1",1,100), 1e-20, 103, 97.3 )  # different query
+        iAlign4 = Align( Range("qry1",1,100), Range("sbj1",1,100), 1e-20, 103, 97.3 )  # canonical
+        iAlign5 = Align( Range("qry1",1,100), Range("sbj2",1,100), 1e-20, 103, 97.3 )  # different subject
+        iAlign6 = Align( Range("qry1",201,300), Range("sbj1",100,1), 1e-20, 103, 97.3 )  # subject on reverse strand
+        iAlign7 = Align( Range("qry1",401,500), Range("sbj1",1,100), 1e-20, 103, 97.3 )  # higher query start
+        lAligns = [ iAlign1, iAlign2, iAlign3, iAlign4, iAlign5, iAlign6, iAlign7 ]
+        lExp = [iAlign4, iAlign2, iAlign1, iAlign6, iAlign7, iAlign5, iAlign3]
+        lObs = AlignUtils.sortList( lAligns )
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_isOverlapping( self ):
+        iAlign1 = Align( Range("chr1",1,100), Range("TE1",11,110), 1e-20, 90.2, 30 )
+        iAlign2 = Align( Range("chr1",51,80), Range("TE1",61,90), 1e-20, 90.2, 30 )
+        self.assertTrue( iAlign1.isOverlapping( iAlign2 ) )
+        
+        iAlign1 = Align( Range("chr1",1,100), Range("TE1",11,110), 1e-20, 90.2, 30 )
+        iAlign2 = Align( Range("chr1",51,80), Range("TE1",161,190), 1e-20, 90.2, 30 )
+        self.assertFalse( iAlign1.isOverlapping( iAlign2 ) )
+        
+        
+    def test_mergeList( self ):
+        iAlign1 = Align( Range("chr1",81,120), Range("TE1",91,130), 1e-20, 90.2, 30 )
+        iAlign2 = Align( Range("chr2",51,80), Range("TE1",61,90), 1e-20, 90.2, 30 )  # different query
+        iAlign3 = Align( Range("chr1",1,100), Range("TE1",11,110), 1e-20, 90.2, 30 )  # to be merged with 1st line
+        iAlign4 = Align( Range("chr1",1,200), Range("TE2",11,210), 1e-20, 90.2, 30 )  # different subject
+        iAlign5 = Align( Range("chr1",1,100), Range("TE1",501,600), 1e-20, 90.2, 30 )  # non-overlapping subject
+        lAligns = [ iAlign1, iAlign2, iAlign3, iAlign4, iAlign5 ]
+        
+        iAlign6 = Align( Range("chr1",1,120), Range("TE1",11,130), 1e-20, 90.2, 30 )
+        lExp = [ iAlign6, iAlign5, iAlign4, iAlign2 ]
+        
+        lObs = AlignUtils.mergeList( lAligns )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_mergeFile_empty( self ):
+        inFile = "dummyInFile.align"
+        inF = open( inFile, "w" )
+        inF.close()
+        
+        expFile = "dummyExpFile.align"
+        expF = open( expFile, "w" )
+        expF.close()
+        
+        obsFile = "dummyObsFile.align"
+        AlignUtils.mergeFile( inFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ inFile, expFile, obsFile ]:
+            os.remove( f )
+            
+            
+    def test_mergeFile( self ):
+        iAlign = Align()
+        
+        inFile = "dummyInFile.align"
+        inF = open( inFile, "w" )
+        iAlign.setFromString( "chr1\t81\t120\tTE1\t91\t130\t1e-20\t30\t90.2\n" )
+        iAlign.write( inF )
+        iAlign.setFromString( "chr2\t51\t80\tTE1\t61\t90\t1e-20\t30\t90.2\n" )  # different query
+        iAlign.write( inF )
+        iAlign.setFromString( "chr1\t1\t100\tTE1\t11\t110\t1e-20\t30\t90.2\n" )  # to be merged with 1st line
+        iAlign.write( inF )
+        iAlign.setFromString( "chr1\t1\t200\tTE2\t11\t210\t1e-20\t30\t90.2\n" )  # different subject
+        iAlign.write( inF )
+        inF.close()
+        
+        expFile = "dummyExpFile.align"
+        expF = open( expFile, "w" )
+        iAlign.setFromString( "chr1\t1\t120\tTE1\t11\t130\t1e-20\t30\t90.2\n" )
+        iAlign.write( expF )
+        iAlign.setFromString( "chr1\t1\t200\tTE2\t11\t210\t1e-20\t30\t90.2\n" )
+        iAlign.write( expF )
+        iAlign.setFromString( "chr2\t51\t80\tTE1\t61\t90\t1e-20\t30\t90.2\n" )
+        iAlign.write( expF )
+        expF.close()
+        
+        obsFile = "dummyObsFile.align"
+        AlignUtils.mergeFile( inFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ inFile, expFile, obsFile ]:
+            os.remove( f )
+            
+            
+    def test_updateScoresInFile( self ):
+        iAlign = Align()
+        
+        inFile = "dummyInFile.align"
+        inHandler = open( inFile, "w" )
+        iAlign.setFromString( "query1\t1\t100\tsubject1\t1\t95\t1e-180\t230\t90.2\n" )
+        iAlign.write( inHandler )
+        inHandler.close()
+        
+        expFile = "dummyExpFile.align"
+        expHandler = open( expFile, "w" )
+        iAlign.setFromString( "query1\t1\t100\tsubject1\t1\t95\t1e-180\t%i\t90.2\n" % ( ( 100 - 1 + 1 ) * 90.2 / 100.0 ) )
+        iAlign.write( expHandler )
+        expHandler.close()
+        
+        obsFile = "dummyObsFile.align"
+        AlignUtils.updateScoresInFile( inFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ inFile, expFile, obsFile ]:
+            os.remove( f )
+            
+            
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_ConvCoord.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,205 @@
+import unittest
+import os
+import time
+from commons.core.coord.ConvCoord import ConvCoord
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.sql.DbFactory import DbFactory
+from commons.core.coord.Map import Map
+
+class Test_ConvCoord( unittest.TestCase ):
+    
+    def setUp( self ):
+        self._i = ConvCoord()
+        self._uniqId = "%s_%s" % ( time.strftime("%Y%m%d%H%M%S") , os.getpid() )
+        self._inData = "dummyInData_%s" % ( self._uniqId )
+        self._mapData = "dummyMapData_%s" % ( self._uniqId )
+        self._expData = "dummyExpData_%s" % ( self._uniqId )
+        self._obsData = "dummyObsData_%s" % ( self._uniqId )
+        self._iDb = DbFactory.createInstance()
+        self._i._iDb = self._iDb
+        
+    def tearDown( self ):
+        self._iDb.close()
+
+#TODO: handle duplicated matchs for path
+#    def test_convCoordsChkToChrFromFile_duplicated_matchs( self ):
+#        dChunks2CoordMaps = {"chunk1": Map( "chunk1", "dmel_chr4", 760001, 960000 ),
+#                             "chunk2": Map( "chunk2", "dmel_chr4", 950001, 1150000 ) }
+#        tmpPathFileName = "dummyPathCoordOnChr_%s" % self._uniqId 
+#        self._writePathFileCoordOnChunk(tmpPathFileName)
+#        
+#        expPathFile = "dummyExpPathFile_%s" % self._uniqId
+#        self._writePathFileCoordOnChrWithOutDoublons(expPathFile)
+#        
+#        outTableName = self._i.convCoordsChkToChrFromFile(tmpPathFileName, "path", dChunks2CoordMaps)
+#        
+#        obsPathFile = "dummyObsPathFile_%s" % self._uniqId
+#        self._iDb.exportDataToFile(outTableName, obsPathFile)
+#        
+#        self.assertTrue(FileUtils.are2FilesIdentical(expPathFile, obsPathFile))
+#        
+#        for f in [ expPathFile, obsPathFile, tmpPathFileName ]:
+#            os.remove( f )
+#        self._iDb.dropTable(outTableName)
+ 
+#TODO: handle matchs out of chunk overlap ? For one side (=> path 128, remove path 152) ? For two sides (path 129, fusion with path 154) ?
+#    def test_convCoordsChkToChrFromFile_matchs_out_of_overlap( self ):
+#        dChunks2CoordMaps = {"chunk1": Map( "chunk1", "dmel_chr4", 760001, 960000 ),
+#                             "chunk2": Map( "chunk2", "dmel_chr4", 950001, 1150000 ) }
+#        tmpPathFileName = "dummyPathCoordOnChr_%s" % self._uniqId 
+#        self._writePathFileCoordOnChunk_outOfOverlap(tmpPathFileName)
+#        
+#        expPathFile = "dummyExpPathFile_%s" % self._uniqId
+#        self._writePathFileCoordOnChrWithOutDoublons_outOfOverlap(expPathFile)
+#        
+#        outTableName = self._i.convCoordsChkToChrFromFile(tmpPathFileName, "path", dChunks2CoordMaps)
+#        
+#        obsPathFile = "dummyObsPathFile_%s" % self._uniqId
+#        self._iDb.exportDataToFile(outTableName, obsPathFile)
+#        
+#        self.assertTrue(FileUtils.are2FilesIdentical(expPathFile, obsPathFile))
+#        
+#        for f in [ expPathFile, obsPathFile, tmpPathFileName ]:
+#            os.remove( f )
+#        self._iDb.dropTable(outTableName)
+        
+    def test_mergeCoordsOnChunkOverlaps( self ):
+        dChunks2CoordMaps = { "chunk1": Map( "chunk1", "chromosome1", 1, 100 ),
+                             "chunk2": Map( "chunk2", "chromosome1", 91, 190 ),
+                             "chunk3": Map( "chunk3", "chromosome2", 1, 100 ) }
+        tmpPathTable = "dummyTmpPathTable"
+        linesToProcess = [
+                          "1" + "\t" + "chromosome1" + "\t" + "21" + "\t" + "37" + "\t" + "TE1" + "\t" + "1" + "\t" + "27" + "\t" + "8e-58" + "\t" + "30" + "\t" + "97.8" + "\n",  # hit within the 1st chunk
+                          "3" + "\t" + "chromosome1" + "\t" + "92" + "\t" + "99" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.8" + "\n",       # hit included within the chunk overlap, on the 2nd chunk
+                          "2" + "\t" + "chromosome1" + "\t" + "92" + "\t" + "99" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.8" + "\n",   # hit included within the chunk overlap, on the 1st chunk
+                          ]
+        FileUtils.writeLineListInFile( tmpPathTable, linesToProcess )
+        self._iDb.createTable( tmpPathTable, "path", tmpPathTable, True)
+        os.remove( tmpPathTable )
+        
+        expPathFile = "dummyExpPathFile"
+        linesToProcess = [ "1" + "\t" + "chromosome1" + "\t" + "21" + "\t" + "37" + "\t" + "TE1" + "\t" + "1" + "\t" + "27" + "\t" + "8e-58" + "\t" + "30" + "\t" + "97.8" + "\n",  # hit within the 1st chunk
+                           "2" + "\t" + "chromosome1" + "\t" + "92" + "\t" + "99" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.8" + "\n",   # hit included within the chunk overlap, on the 1st chunk
+                           ]
+        FileUtils.writeLineListInFile( expPathFile, linesToProcess )
+        
+        self._i.mergeCoordsOnChunkOverlaps( dChunks2CoordMaps, tmpPathTable)
+        
+        obsPathFile = "dummyObsPathFile"
+        self._iDb.exportDataToFile( tmpPathTable, obsPathFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expPathFile, obsPathFile ) )
+        
+        for f in [ expPathFile, obsPathFile ]:
+            os.remove( f )
+        self._iDb.dropTable( tmpPathTable )
+        
+    def test_mergeCoordsOnChunkOverlaps_withConnectedMatches( self ):
+        dChunks2CoordMaps = { "chunk1": Map( "chunk1", "chromosome1", 1, 100 ),
+                             "chunk2": Map( "chunk2", "chromosome1", 91, 190 ),
+                             "chunk3": Map( "chunk3", "chromosome2", 1, 100 ) }
+        tmpPathTable = "dummyTmpPathTable"
+        linesToProcess = [
+                          "1" + "\t" + "chromosome1" + "\t" + "21" + "\t" + "37" + "\t" + "TE1" + "\t" + "1" + "\t" + "27" + "\t" + "8e-58" + "\t" + "30" + "\t" + "97.8" + "\n",  # hit on the 1st chunk
+                          "1" + "\t" + "chromosome1" + "\t" + "92" + "\t" + "99" + "\t" + "TE1" + "\t" + "28" + "\t" + "36" + "\t" + "8e-58" + "\t" + "10" + "\t" + "97.8" + "\n",  # hit included within the chunk overlap, on the 1st chunk, connected to the previous                          
+                          "2" + "\t" + "chromosome1" + "\t" + "92" + "\t" + "99" + "\t" + "TE1" + "\t" + "28" + "\t" + "36" + "\t" + "8e-58" + "\t" + "10" + "\t" + "97.8" + "\n",  # hit included within the chunk overlap, on the 2nd chunk
+                          "2" + "\t" + "chromosome1" + "\t" + "111" + "\t" + "120" + "\t" + "TE1" + "\t" + "37" + "\t" + "46" + "\t" + "8e-58" + "\t" + "15" + "\t" + "97.8" + "\n",  # hit on the 2nd chunk, connected to the previous
+                          ]
+        FileUtils.writeLineListInFile( tmpPathTable, linesToProcess )
+        self._iDb.createTable( tmpPathTable, "path", tmpPathTable, True)
+        os.remove( tmpPathTable )
+        
+        expPathFile = "dummyExpPathFile"
+        linesToProcess = [ "1" + "\t" + "chromosome1" + "\t" + "21" + "\t" + "37" + "\t" + "TE1" + "\t" + "1" + "\t" + "27" + "\t" + "8e-58" + "\t" + "30" + "\t" + "97.8" + "\n",  # hit within the 1st chunk
+                           "1" + "\t" + "chromosome1" + "\t" + "92" + "\t" + "99" + "\t" + "TE1" + "\t" + "28" + "\t" + "36" + "\t" + "8e-58" + "\t" + "10" + "\t" + "97.8" + "\n",   # hit included within the chunk overlap, on the 1st chunk
+                           "1" + "\t" + "chromosome1" + "\t" + "111" + "\t" + "120" + "\t" + "TE1" + "\t" + "37" + "\t" + "46" + "\t" + "8e-58" + "\t" + "15" + "\t" + "97.8" + "\n",  # hit on the 2nd chunk, connected to the previous
+                           ]
+        FileUtils.writeLineListInFile( expPathFile, linesToProcess )
+        
+        self._i.mergeCoordsOnChunkOverlaps( dChunks2CoordMaps, tmpPathTable )
+        
+        obsPathFile = "dummyObsPathFile"
+        self._iDb.exportDataToFile( tmpPathTable, obsPathFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expPathFile, obsPathFile ) )
+        
+        for f in [ expPathFile, obsPathFile ]:
+            os.remove( f )
+        self._iDb.dropTable( tmpPathTable )
+        
+    def _writePathFileCoordOnChrWithOutDoublons(self, pathFileName):
+        file = open( pathFileName, "w" )
+        file.write("123\tdmel_chr4\t868397\t868531\tMariner2_AG_1p:classII:TIR\t53\t97\t8e-19\t28\t35.56\n")
+        file.write("123\tdmel_chr4\t868545\t869120\tMariner2_AG_1p:classII:TIR\t102\t333\t8e-19\t87\t27.97\n")
+        file.write("124\tdmel_chr4\t819607\t819714\tLINER1-2_NVi_2p:classI:?\t502\t537\t3e-20\t30\t36.11\n")
+        file.write("124\tdmel_chr4\t819695\t820156\tLINER1-2_NVi_2p:classI:?\t533\t725\t3e-20\t90\t36.79\n")
+        file.write("125\tdmel_chr4\t953027\t953101\tCR1-8_AG_1p:classI:LINE\t470\t448\t1e-27\t11\t28.57\n")
+        file.write("126\tdmel_chr4\t862131\t862178\tTc1-1_TCa_1p:classII:TIR\t288\t274\t5e-29\t18\t52.5\n")
+        file.write("127\tdmel_chr4\t819520\t819606\tNotoAg1_2p:classI:?\t482\t508\t1e-13\t14\t30.61\n")
+#        file.write("128\tdmel_chr4\t953866\t953889\tCR1-19_HM_1p:classI:LINE\t898\t891\t5e-21\t4\t34.98\n")
+#        file.write("129\tdmel_chr4\t953866\t953889\tCR1-83_HM_1p:classI:LINE\t912\t905\t3e-21\t4\t34.62\n")
+        file.write("150\tdmel_chr4\t971176\t971250\tTc1-1_TCa_1p:classII:TIR\t135\t109\t8e-32\t21\t41.57\n")
+        file.write("151\tdmel_chr4\t1066603\t1066698\tMARWOLEN1_1p:classII:TIR\t285\t320\t7e-25\t28\t41.67\n")
+        file.write("152\tdmel_chr4\t953866\t953889\tCR1-19_HM_1p:classI:LINE\t898\t891\t5e-21\t4\t34.98\n")
+        file.write("153\tdmel_chr4\t953951\t954343\tCR1-1_DWil_1p:classI:LINE\t127\t2\t4e-18\t92\t37.59\n")
+        file.write("154\tdmel_chr4\t953866\t953889\tCR1-83_HM_1p:classI:LINE\t912\t905\t3e-21\t4\t34.62\n")
+        file.write("155\tdmel_chr4\t953102\t953199\tCR1-1_DWil_2p:classI:LINE\t869\t837\t2e-26\t38\t57.89\n")
+        file.close()
+        
+    def _writePathFileCoordOnChunk(self, pathFileName):
+        pathFile = open( pathFileName, "w" )
+        pathFile.write("123\tchunk1\t108397\t108531\tMariner2_AG_1p:classII:TIR\t53\t97\t8e-19\t28\t35.56\n")
+        pathFile.write("123\tchunk1\t108545\t109120\tMariner2_AG_1p:classII:TIR\t102\t333\t8e-19\t87\t27.97\n")
+        pathFile.write("124\tchunk1\t59607\t59714\tLINER1-2_NVi_2p:classI:?\t502\t537\t3e-20\t30\t36.11\n")
+        pathFile.write("124\tchunk1\t59695\t60156\tLINER1-2_NVi_2p:classI:?\t533\t725\t3e-20\t90\t36.79\n")
+        pathFile.write("125\tchunk1\t193027\t193101\tCR1-8_AG_1p:classI:LINE\t470\t448\t1e-27\t11\t28.57\n")
+        pathFile.write("126\tchunk1\t102131\t102178\tTc1-1_TCa_1p:classII:TIR\t288\t274\t5e-29\t18\t52.5\n")
+        pathFile.write("127\tchunk1\t59520\t59606\tNotoAg1_2p:classI:?\t482\t508\t1e-13\t14\t30.61\n")
+        pathFile.write("128\tchunk1\t193866\t193889\tCR1-19_HM_1p:classI:LINE\t898\t891\t5e-21\t4\t34.98\n")
+        pathFile.write("129\tchunk1\t193866\t193889\tCR1-83_HM_1p:classI:LINE\t912\t905\t3e-21\t4\t34.62\n")
+        pathFile.write("150\tchunk2\t21176\t21250\tTc1-1_TCa_1p:classII:TIR\t135\t109\t8e-32\t21\t41.57\n")
+        pathFile.write("151\tchunk2\t116603\t116698\tMARWOLEN1_1p:classII:TIR\t285\t320\t7e-25\t28\t41.67\n")
+        pathFile.write("152\tchunk2\t3866\t3889\tCR1-19_HM_1p:classI:LINE\t898\t891\t5e-21\t4\t34.98\n")
+        pathFile.write("153\tchunk2\t3951\t4343\tCR1-1_DWil_1p:classI:LINE\t127\t2\t4e-18\t92\t37.59\n")
+        pathFile.write("154\tchunk2\t3866\t3889\tCR1-83_HM_1p:classI:LINE\t912\t905\t3e-21\t4\t34.62\n")
+        pathFile.write("155\tchunk2\t3102\t3199\tCR1-1_DWil_2p:classI:LINE\t869\t837\t2e-26\t38\t57.89\n")
+        pathFile.close()
+        
+#    def _writePathFileCoordOnChunk_outOfOverlap(self, pathFileName):
+#        pathFile = open( pathFileName, "w" )
+#        pathFile.write("123\tchunk1\t108397\t108531\tMariner2_AG_1p:classII:TIR\t53\t97\t8e-19\t28\t35.56\n")
+#        pathFile.write("123\tchunk1\t108545\t109120\tMariner2_AG_1p:classII:TIR\t102\t333\t8e-19\t87\t27.97\n")
+#        pathFile.write("124\tchunk1\t59607\t59714\tLINER1-2_NVi_2p:classI:?\t502\t537\t3e-20\t30\t36.11\n")
+#        pathFile.write("124\tchunk1\t59695\t60156\tLINER1-2_NVi_2p:classI:?\t533\t725\t3e-20\t90\t36.79\n")
+#        pathFile.write("125\tchunk1\t193027\t193101\tCR1-8_AG_1p:classI:LINE\t470\t448\t1e-27\t11\t28.57\n")
+#        pathFile.write("126\tchunk1\t102131\t102178\tTc1-1_TCa_1p:classII:TIR\t288\t274\t5e-29\t18\t52.5\n")
+#        pathFile.write("127\tchunk1\t59520\t59606\tNotoAg1_2p:classI:?\t482\t508\t1e-13\t14\t30.61\n")
+#        pathFile.write("128\tchunk1\t183866\t193889\tCR1-19_HM_1p:classI:LINE\t898\t1891\t5e-21\t4\t34.98\n")
+#        pathFile.write("129\tchunk1\t183866\t200000\tCR1-83_HM_1p:classI:LINE\t912\t905\t3e-21\t4\t34.62\n")
+#        pathFile.write("150\tchunk2\t21176\t21250\tTc1-1_TCa_1p:classII:TIR\t135\t109\t8e-32\t21\t41.57\n")
+#        pathFile.write("151\tchunk2\t116603\t116698\tMARWOLEN1_1p:classII:TIR\t285\t320\t7e-25\t28\t41.67\n")
+#        pathFile.write("152\tchunk2\t1\t3889\tCR1-19_HM_1p:classI:LINE\t898\t1891\t5e-21\t4\t34.98\n")
+#        pathFile.write("153\tchunk2\t3951\t4343\tCR1-1_DWil_1p:classI:LINE\t127\t2\t4e-18\t92\t37.59\n")
+#        pathFile.write("154\tchunk2\t1\t13889\tCR1-83_HM_1p:classI:LINE\t912\t905\t3e-21\t4\t34.62\n")
+#        pathFile.write("155\tchunk2\t3102\t3199\tCR1-1_DWil_2p:classI:LINE\t869\t837\t2e-26\t38\t57.89\n")
+#        pathFile.close()
+#        
+#    def _writePathFileCoordOnChrWithOutDoublons_outOfOverlap(self, pathFileName):
+#        file = open( pathFileName, "w" )
+#        file.write("123\tdmel_chr4\t868397\t868531\tMariner2_AG_1p:classII:TIR\t53\t97\t8e-19\t28\t35.56\n")
+#        file.write("123\tdmel_chr4\t868545\t869120\tMariner2_AG_1p:classII:TIR\t102\t333\t8e-19\t87\t27.97\n")
+#        file.write("124\tdmel_chr4\t819607\t819714\tLINER1-2_NVi_2p:classI:?\t502\t537\t3e-20\t30\t36.11\n")
+#        file.write("124\tdmel_chr4\t819695\t820156\tLINER1-2_NVi_2p:classI:?\t533\t725\t3e-20\t90\t36.79\n")
+#        file.write("125\tdmel_chr4\t953027\t953101\tCR1-8_AG_1p:classI:LINE\t470\t448\t1e-27\t11\t28.57\n")
+#        file.write("126\tdmel_chr4\t862131\t862178\tTc1-1_TCa_1p:classII:TIR\t288\t274\t5e-29\t18\t52.5\n")
+#        file.write("127\tdmel_chr4\t819520\t819606\tNotoAg1_2p:classI:?\t482\t508\t1e-13\t14\t30.61\n")
+#        file.write("128\tdmel_chr4\t943866\t953889\tCR1-19_HM_1p:classI:LINE\t898\t1891\t5e-21\t4\t34.98\n")
+#        file.write("129\tdmel_chr4\t943866\t963889\tCR1-83_HM_1p:classI:LINE\t912\t905\t3e-21\t4\t34.62\n")
+#        file.write("150\tdmel_chr4\t971176\t971250\tTc1-1_TCa_1p:classII:TIR\t135\t109\t8e-32\t21\t41.57\n")
+#        file.write("151\tdmel_chr4\t1066603\t1066698\tMARWOLEN1_1p:classII:TIR\t285\t320\t7e-25\t28\t41.67\n")
+#        file.write("153\tdmel_chr4\t953951\t954343\tCR1-1_DWil_1p:classI:LINE\t127\t2\t4e-18\t92\t37.59\n")
+#        file.write("155\tdmel_chr4\t953102\t953199\tCR1-1_DWil_2p:classI:LINE\t869\t837\t2e-26\t38\t57.89\n")
+#        file.close()
+       
+if __name__ == "__main__":
+        unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_F_ConvCoord.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,213 @@
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.sql.DbFactory import DbFactory
+from commons.core.coord.ConvCoord import ConvCoord
+import time
+import subprocess
+import os
+import unittest
+
+class Test_F_ConvCoord(unittest.TestCase):
+    
+    def setUp( self ):
+        self._i = ConvCoord()
+        self._uniqId = "%s_%s" % ( time.strftime("%Y%m%d%H%M%S") , os.getpid() )
+        self._inData = "dummyInData_%s" % ( self._uniqId )
+        self._mapData = "dummyMapData_%s" % ( self._uniqId )
+        self._expData = "dummyExpData_%s" % ( self._uniqId )
+        self._obsData = "dummyObsData_%s" % ( self._uniqId )
+        self._iDb = DbFactory.createInstance()
+        self._i._iDb = self._iDb
+        
+    def tearDown( self ):
+        self._iDb.close()
+        
+    def test_run_as_script_alignFile_query( self ):
+        configFile = "%s/dummyConfigFile_%s" % ( os.getcwd(), self._uniqId )
+        configF = open( configFile, "w" )
+        configF.write( "[repet_env]\n" )
+        configF.write( "repet_host: %s\n" % ( os.environ["REPET_HOST"] ) )
+        configF.write( "repet_user: %s\n" % ( os.environ["REPET_USER"] ) )
+        configF.write( "repet_pw: %s\n" % ( os.environ["REPET_PW"] ) )
+        configF.write( "repet_db: %s\n" % ( os.environ["REPET_DB"] ) )
+        configF.write( "repet_port: %s\n" % ( os.environ["REPET_PORT"] ) )
+        configF.close()
+        self._writeMapFile( self._mapData )
+        
+        linesToProcess = [ "chunk1" + "\t" + "21" + "\t" + "37" + "\t" + "TE1" + "\t" + "1" + "\t" + "27" + "\t" + "8e-58" + "\t" + "30" + "\t" + "97.800000" + "\n",  # hit within the 1st chunk
+                           "chunk1" + "\t" + "92" + "\t" + "99" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",   # hit included within the chunk overlap, on the 1st chunk
+                           "chunk2" + "\t" + "2" + "\t" + "9" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",       # hit included within the chunk overlap, on the 2nd chunk
+                           "chunk2" + "\t" + "51" + "\t" + "58" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",     # hit inside the 2nd chunk
+                           "chunk2" + "\t" + "51" + "\t" + "70" + "\t" + "TE1" + "\t" + "8" + "\t" + "1" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n"     # subject on reverse strand
+                           ]
+        FileUtils.writeLineListInFile( self._inData, linesToProcess )
+        
+        refLines = [ "chromosome1" + "\t" + "21" + "\t" + "37" + "\t" + "TE1" + "\t" + "1" + "\t" + "27" + "\t" + "8e-58" + "\t" + "30" + "\t" + "97.800000" + "\n",
+                     "chromosome1" + "\t" + "92" + "\t" + "99" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",
+                     "chromosome1" + "\t" + "141" + "\t" + "148" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",
+                     "chromosome1" + "\t" + "141" + "\t" + "160" + "\t" + "TE1" + "\t" + "8" + "\t" + "1" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n"
+                     ]
+        FileUtils.writeLineListInFile( self._expData, refLines )
+        
+        cmd = "ConvCoord.py"
+        cmd += " -i %s" % ( self._inData )
+        cmd += " -f %s" % ( "align" )
+        cmd += " -c %s" % ( "q" )
+        cmd += " -m %s" % ( self._mapData )
+        cmd += " -o %s" % ( self._obsData )
+        cmd += " -C %s" % ( configFile )
+        process = subprocess.Popen(cmd, shell = True)
+        process.communicate()
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( self._expData, self._obsData ) )
+        
+        os.remove( self._inData )
+        os.remove(configFile)
+        os.remove( self._mapData )
+        os.remove( self._expData )
+        os.remove( self._obsData )
+        
+    def test_run_as_script_alignFile_queryAndSubject( self ):
+        self._writeMapFile( self._mapData )
+        linesToProcess = [ "chunk1" + "\t" + "21" + "\t" + "37" + "\t" + "chunk3" + "\t" + "1" + "\t" + "27" + "\t" + "8e-58" + "\t" + "30" + "\t" + "97.800000" + "\n",  # hit within the 1st chunk
+                           "chunk1" + "\t" + "92" + "\t" + "99" + "\t" + "chunk2" + "\t" + "2" + "\t" + "9" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",   # hit included within the chunk overlap, on the 1st chunk
+                           "chunk2" + "\t" + "51" + "\t" + "58" + "\t" + "chunk1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",     # hit inside the 2nd chunk
+                           "chunk2" + "\t" + "51" + "\t" + "70" + "\t" + "chunk1" + "\t" + "8" + "\t" + "1" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n"     # subject on reverse strand
+                           "chunk2" + "\t" + "51" + "\t" + "70" + "\t" + "chunk1" + "\t" + "8" + "\t" + "1" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n"     # doublon of previous line
+                           ]
+        FileUtils.writeLineListInFile( self._inData, linesToProcess )
+        
+        refLines = [ "chromosome1" + "\t" + "21" + "\t" + "37" + "\t" + "chromosome2" + "\t" + "1" + "\t" + "27" + "\t" + "8e-58" + "\t" + "30" + "\t" + "97.800000" + "\n",
+                     "chromosome1" + "\t" + "92" + "\t" + "99" + "\t" + "chromosome1" + "\t" + "92" + "\t" + "99" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",
+                     "chromosome1" + "\t" + "141" + "\t" + "148" + "\t" + "chromosome1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",
+                     "chromosome1" + "\t" + "141" + "\t" + "160" + "\t" + "chromosome1" + "\t" + "8" + "\t" + "1" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n"
+                     ]
+        FileUtils.writeLineListInFile( self._expData, refLines )
+        
+        cmd = "ConvCoord.py"
+        cmd += " -i %s" % ( self._inData )
+        cmd += " -f %s" % ( "align" )
+        cmd += " -c %s" % ( "qs" )
+        cmd += " -m %s" % ( self._mapData )
+        cmd += " -o %s" % ( self._obsData )
+        process = subprocess.Popen(cmd, shell = True)
+        process.communicate()
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( self._expData, self._obsData ) )
+        
+        os.remove( self._inData )
+        self._iDb.dropTable( self._mapData )
+        os.remove( self._expData )
+        os.remove( self._obsData )
+        os.remove( self._mapData )
+        
+    def test_run_as_script_pathTable_query( self ):
+        self._writeMapFile( self._mapData )
+        self._iDb.createTable( self._mapData, "map", self._mapData, True )
+        os.remove( self._mapData )
+        
+        linesToProcess = [ "1" + "\t" + "chunk1" + "\t" + "21" + "\t" + "37" + "\t" + "TE1" + "\t" + "1" + "\t" + "27" + "\t" + "8e-58" + "\t" + "30" + "\t" + "97.800000" + "\n",  # hit within the 1st chunk
+                           "2" + "\t" + "chunk1" + "\t" + "92" + "\t" + "99" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",   # hit included within the chunk overlap, on the 1st chunk
+                           "3" + "\t" + "chunk2" + "\t" + "2" + "\t" + "9" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",       # hit included within the chunk overlap, on the 2nd chunk
+                           "4" + "\t" + "chunk2" + "\t" + "51" + "\t" + "58" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",     # hit inside the 2nd chunk
+                           "5" + "\t" + "chunk2" + "\t" + "51" + "\t" + "70" + "\t" + "TE1" + "\t" + "8" + "\t" + "1" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n"     # subject on reverse strand
+                           ]
+        FileUtils.writeLineListInFile( self._inData, linesToProcess )
+        self._iDb.createTable( self._inData, "path", self._inData, True )
+        os.remove( self._inData )
+        
+        refLines = [ "1" + "\t" + "chromosome1" + "\t" + "21" + "\t" + "37" + "\t" + "TE1" + "\t" + "1" + "\t" + "27" + "\t" + "8e-58" + "\t" + "30" + "\t" + "97.8" + "\n",
+                     "2" + "\t" + "chromosome1" + "\t" + "92" + "\t" + "99" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.8" + "\n",
+                     "4" + "\t" + "chromosome1" + "\t" + "141" + "\t" + "148" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.8" + "\n",
+                     "5" + "\t" + "chromosome1" + "\t" + "141" + "\t" + "160" + "\t" + "TE1" + "\t" + "8" + "\t" + "1" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.8" + "\n"
+                     ]
+        FileUtils.writeLineListInFile( self._expData, refLines )
+        
+        cmd = "ConvCoord.py"
+        cmd += " -i %s" % ( self._inData )
+        cmd += " -f %s" % ( "path" )
+        cmd += " -c %s" % ( "q" )
+        cmd += " -m %s" % ( self._mapData )
+        cmd += " -o %s" % ( self._obsData )
+        process = subprocess.Popen(cmd, shell = True)
+        process.communicate()
+        
+        self._iDb.exportDataToFile( self._obsData, self._obsData )
+        self.assertTrue( FileUtils.are2FilesIdentical( self._expData, self._obsData ) )
+        
+        os.remove( self._obsData )
+        os.remove( self._expData )
+        self._iDb.dropTable( self._mapData )
+        self._iDb.dropTable( self._inData )
+        self._iDb.dropTable( self._expData )
+        self._iDb.dropTable( self._obsData )
+        
+    def test_run_as_script_pathTable_query_noMergeChunkOverlaps( self ):
+        self._writeMapFile( self._mapData )
+        self._iDb.createTable( self._mapData, "map", self._mapData, True )
+        os.remove( self._mapData )
+        
+        linesToProcess = [ "1" + "\t" + "chunk1" + "\t" + "21" + "\t" + "37" + "\t" + "TE1" + "\t" + "1" + "\t" + "27" + "\t" + "8e-58" + "\t" + "30" + "\t" + "97.800000" + "\n",  # hit within the 1st chunk
+                           "2" + "\t" + "chunk1" + "\t" + "92" + "\t" + "99" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",   # hit included within the chunk overlap, on the 1st chunk
+                           "3" + "\t" + "chunk2" + "\t" + "2" + "\t" + "9" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",       # hit included within the chunk overlap, on the 2nd chunk
+                           "4" + "\t" + "chunk2" + "\t" + "51" + "\t" + "58" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n",     # hit inside the 2nd chunk
+                           "5" + "\t" + "chunk2" + "\t" + "51" + "\t" + "70" + "\t" + "TE1" + "\t" + "8" + "\t" + "1" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.800000" + "\n"     # subject on reverse strand
+                           ]
+        FileUtils.writeLineListInFile( self._inData, linesToProcess )
+        self._iDb.createTable( self._inData, "path", self._inData, True )
+        os.remove( self._inData )
+        
+        refLines = [ "1" + "\t" + "chromosome1" + "\t" + "21" + "\t" + "37" + "\t" + "TE1" + "\t" + "1" + "\t" + "27" + "\t" + "8e-58" + "\t" + "30" + "\t" + "97.8" + "\n",
+                     "2" + "\t" + "chromosome1" + "\t" + "92" + "\t" + "99" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.8" + "\n",
+                     "3" + "\t" + "chromosome1" + "\t" + "92" + "\t" + "99" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.8" + "\n",       # hit included within the chunk overlap, on the 2nd chunk
+                     "4" + "\t" + "chromosome1" + "\t" + "141" + "\t" + "148" + "\t" + "TE1" + "\t" + "1" + "\t" + "8" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.8" + "\n",
+                     "5" + "\t" + "chromosome1" + "\t" + "141" + "\t" + "160" + "\t" + "TE1" + "\t" + "8" + "\t" + "1" + "\t" + "8e-58" + "\t" + "11" + "\t" + "97.8" + "\n"
+                     ]
+        FileUtils.writeLineListInFile( self._expData, refLines )
+        
+        cmd = "ConvCoord.py"
+        cmd += " -i %s" % ( self._inData )
+        cmd += " -f %s" % ( "path" )
+        cmd += " -c %s" % ( "q" )
+        cmd += " -m %s" % ( self._mapData )
+        cmd += " -M %s" % ( "no" )
+        cmd += " -o %s" % ( self._obsData )
+        process = subprocess.Popen(cmd, shell = True)
+        process.communicate()
+        
+        self._iDb.exportDataToFile( self._obsData, self._obsData )
+        self.assertTrue( FileUtils.are2FilesIdentical( self._expData, self._obsData ) )
+        
+        os.remove( self._obsData )
+        os.remove( self._expData )
+        self._iDb.dropTable( self._mapData )
+        self._iDb.dropTable( self._inData )
+        self._iDb.dropTable( self._expData )
+        self._iDb.dropTable( self._obsData )
+
+    def test_run(self):
+        inFileName = "DmelChr4_chk.align.not_over.filtered"
+        expFileName = "%s/Tools/DmelChr4_chr.align.not_over.filtered" % os.environ["REPET_DATA"]
+        obsFileName = "obs.align"
+        os.symlink("%s/Tools/%s" % (os.environ["REPET_DATA"], inFileName), inFileName)
+        iConvCoord = ConvCoord()
+        iConvCoord.setInputData(inFileName)
+        iConvCoord.setMapData("%s/Tools/DmelChr4_chunks.map" % os.environ["REPET_DATA"])
+        iConvCoord.setCoordinatesToConvert("qs")
+        iConvCoord.setMergeChunkOverlaps(False)
+        iConvCoord.setOutputData(obsFileName)
+        iConvCoord.run()
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(inFileName)
+        os.remove(obsFileName)
+        
+    def _writeMapFile( self, mapFile ):
+        mapF = open( mapFile, "w" )
+        mapF.write( "chunk1\tchromosome1\t1\t100\n" )
+        mapF.write( "chunk2\tchromosome1\t91\t190\n" )
+        mapF.write( "chunk3\tchromosome2\t1\t100\n" )
+        mapF.close()
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_Map.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,183 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+from commons.core.coord.Map import Map
+from commons.core.utils.FileUtils import FileUtils
+
+
+class Test_Map( unittest.TestCase ):
+    
+    def setUp(self):
+        self._map = Map()
+        
+    def test_setFromString(self):
+        line = "MbQ12Gr2Cl2\tconsensus1\t51\t1230\n"   # test with '\t' separator
+        self._map.setFromString(line)
+        self.assertEqual( self._map.name, "MbQ12Gr2Cl2" )
+        self.assertEqual( self._map.seqname, "consensus1" )
+        self.assertEqual( self._map.start, 51 )
+        self.assertEqual( self._map.end, 1230 )
+        line = "MbQ12Gr2Cl2;consensus1;51;1230"   # test with ';' separator
+        self._map.setFromString(line,";")
+        self.assertEqual( self._map.name, "MbQ12Gr2Cl2" )
+        self.assertEqual( self._map.seqname, "consensus1" )
+        self.assertEqual( self._map.start, 51 )
+        self.assertEqual( self._map.end, 1230 )
+    
+    def test___eq__(self):
+        self._map.setFromString( "MbQ12Gr2Cl2\tconsensus1\t51\t1230\n" )
+        o = Map()
+        o.setFromString( "MbQ12Gr2Cl2\tconsensus1\t51\t1230\n" )
+        self.assertEqual( self._map, o )   # same data
+        o.setFromString( "MbQ12Gr2Cl1\tconsensus1\t51\t1230\n" )
+        self.assertNotEqual( self._map, o )   # different name
+        o.setFromString( "MbQ12Gr2Cl2\tconsensus2\t51\t1230\n" )
+        self.assertNotEqual( self._map, o )   # different seqname
+        o.setFromString( "MbQ12Gr2Cl2\tconsensus1\t15\t1230\n" )
+        self.assertNotEqual( self._map, o )   # different start
+        o.setFromString( "MbQ12Gr2Cl2\tconsensus1\t51\t123000\n" )
+        self.assertNotEqual( self._map, o )   # different end
+        o.setFromString( "MbQ12Gr2Cl2\tconsensus1\t1230\t51\n" )
+        self.assertNotEqual( self._map, o )   # same start/end but in different order
+        
+    def test_setFromTuple(self):
+        tuple = ("MbQ12Gr2Cl2", "consensus1","51","1230")
+        self._map.setFromTuple(tuple)
+
+        expMap = Map("MbQ12Gr2Cl2", "consensus1",51,1230)
+        obsMap = self._map
+        
+        self.assertEquals(expMap, obsMap)
+    
+    def test_read_empty_file(self):
+        
+        fileName = "dummyFile"
+        os.system("touch " + fileName) 
+        fileHandle = open(fileName, "r")
+        
+        obsResult = self._map.read(fileHandle)
+        expResult = 0
+         
+        fileHandle.close()
+        os.remove(fileName) 
+        
+        self.assertEquals(expResult, obsResult)
+    
+    def test_read_uncompleted_line( self):
+        uncompletedLine = "MbQ12Gr2Cl2\tconsensus1\t51"
+        fileName = "dummyFile"
+
+        fileHandle = open(fileName, "w")
+        fileHandle.write(uncompletedLine)
+        fileHandle.close()
+
+        fileHandle = open(fileName, "r")
+       
+        obsResult = self._map.read(fileHandle)
+        expResult = 0
+
+        fileHandle.close()
+        os.remove(fileName)
+
+        self.assertEquals(obsResult, expResult)
+
+    def test_read(self):
+        line =  "MbQ12Gr2Cl2\tconsensus1\t51\t1230\n"
+        fileName = "dummyFile"
+
+        fileHandle = open(fileName, "w")
+        fileHandle.write(line)
+        fileHandle.close()
+
+        fileHandle = open(fileName, "r")
+        self._map.read(fileHandle)
+        obsResult = self._map
+        
+        expResult = Map()
+        expResult.setFromString(line) 
+
+        fileHandle.close()
+        os.remove(fileName)
+
+        self.assertEquals(obsResult, expResult) 
+     
+    def test_write(self):
+        line =  "MbQ12Gr2Cl2\tconsensus1\t51\t1230\n"
+        expFileName = "expFileName"
+
+        fileHandle = open(expFileName, "w")
+        fileHandle.write(line)
+        fileHandle.close()
+        
+        obsFileName = "obsFileName"
+        fileHandle = open(obsFileName, "w")
+        self._map.setFromString(line)
+        self._map.write(fileHandle)
+        fileHandle.close()
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        
+        os.remove(obsFileName)
+        os.remove(expFileName)
+        
+    def test_diff1(self):
+        map1 = Map("seq1","DmelChr4", 190000, 390000)
+        map2 = Map("seq2","DmelChr4", 290000, 590000)
+        
+        expMap1 = Map("seq1", "DmelChr4", 190000, 289999)
+        expReturnedMap = Map()
+        
+        obsReturnedMap = map1.diff(map2)
+        obsMap1 = map1
+        
+        self.assertEquals(expMap1, obsMap1)
+        self.assertEquals(expReturnedMap, obsReturnedMap)
+        
+    def test_diff2(self):
+        map1 = Map("seq1","DmelChr4", 190000, 590000)
+        map2 = Map("seq2","DmelChr4", 290000, 390000)
+
+        expMap1 = Map("seq1", "DmelChr4", 190000, 289999)
+        expReturnedMap = Map("seq1", "DmelChr4", 390001, 590000)
+        
+        obsReturnedMap = map1.diff(map2)
+        obsMap1 = map1
+        
+        self.assertEquals(expMap1, obsMap1)
+        self.assertEquals(expReturnedMap, obsReturnedMap)
+        
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_Map ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_MapUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,384 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+import sys
+from commons.core.coord.MapUtils import MapUtils
+from commons.core.coord.Map import Map
+from commons.core.coord.Set import Set
+from commons.core.utils.FileUtils import FileUtils
+
+
+class Test_MapUtils( unittest.TestCase ):
+    
+    def test_getMapListSortedByIncreasingMinThenMax( self ):
+        iMap1 = Map("name1", "chr1", 1, 350)
+        iMap2 = Map("name2", "chr1", 1, 100)
+        iMap3 = Map("name3", "chr1", 50, 350)
+        iMap4 = Map("name4", "chr1", 5, 450)
+        lMaps = [ iMap1, iMap2, iMap3, iMap4 ]
+        
+        expLMaps = [ iMap2, iMap1, iMap4, iMap3 ]
+        
+        obsLMaps = MapUtils.getMapListSortedByIncreasingMinThenMax( lMaps )
+        
+        self.assertEquals( expLMaps, obsLMaps )
+        
+        
+    def test_getMapListSortedByIncreasingMinThenMax_ordered( self ):
+        iMap1 = Map("name1", "chr1", 1, 100)
+        iMap2 = Map("name2", "chr1", 1, 350)
+        
+        lMaps = [ iMap1, iMap2 ]
+        expLMaps = [ iMap1, iMap2 ]
+        
+        obsLMaps = MapUtils.getMapListSortedByIncreasingMinThenMax( lMaps )
+        
+        self.assertEquals( expLMaps, obsLMaps )
+        
+        
+    def test_getMapListSortedByIncreasingMinThenMax_unordered( self ):
+        iMap1 = Map("name1", "chr1", 1, 350)
+        iMap2 = Map("name2", "chr1", 1, 100)
+        
+        lMaps = [ iMap1, iMap2 ]
+        expLMaps = [ iMap2, iMap1 ]
+        
+        obsLMaps = MapUtils.getMapListSortedByIncreasingMinThenMax( lMaps )
+        
+        self.assertEquals( expLMaps, obsLMaps )
+        
+        
+    def test_getMapListSortedByIncreasingMinThenMax_nonOverlapping( self ):
+        iMap1 = Map("name1", "chr1", 1, 350)
+        iMap2 = Map("name2", "chr1", 400, 600)
+        
+        lMaps = [ iMap2, iMap1 ]
+        expLMaps = [ iMap1, iMap2 ]
+        
+        obsLMaps = MapUtils.getMapListSortedByIncreasingMinThenMax( lMaps )
+        
+        self.assertEquals( expLMaps, obsLMaps )
+        
+        
+    def test_getMapListSortedByIncreasingMinThenMax_sameMinThreeMaps( self ):
+        iMap1 = Map("name1", "chr1", 350, 1)
+        iMap2 = Map("name2", "chr1", 400, 1)
+        iMap3 = Map("name3", "chr1", 500, 1)
+        
+        lMaps = [ iMap2, iMap1, iMap3 ]
+        expLMaps = [ iMap1, iMap2, iMap3 ]
+        
+        obsLMaps = MapUtils.getMapListSortedByIncreasingMinThenMax( lMaps )
+        
+        self.assertEquals( expLMaps, obsLMaps )
+        
+        
+    def test_getMapListSortedByIncreasingMinThenMax_included( self ):
+        iMap1 = Map("name1", "chr1", 350, 1)
+        iMap2 = Map("name2", "chr1", 300, 10)
+        
+        lMaps = [ iMap2, iMap1 ]
+        expLMaps = [ iMap1, iMap2]
+        
+        obsLMaps = MapUtils.getMapListSortedByIncreasingMinThenMax( lMaps )
+        
+        self.assertEquals( expLMaps, obsLMaps )
+        
+        
+    def test_getMapListSortedByIncreasingMinThenMax_equal( self ):
+        iMap1 = Map("name1", "chr1", 350, 1)
+        iMap2 = Map("name2", "chr1", 350, 1)
+        
+        lMaps = [ iMap2, iMap1 ]
+        expLMaps = [ iMap2, iMap1 ]
+        notExpLMaps = [ iMap1, iMap2 ]
+        
+        obsLMaps = MapUtils.getMapListSortedByIncreasingMinThenMax( lMaps )
+        
+        self.assertEquals( expLMaps, obsLMaps )
+        self.assertNotEquals( notExpLMaps, obsLMaps )
+        
+        
+    def test_getMapListSortedByIncreasingNameThenSeqnameThenMinThenMax( self ):
+        iMap1 = Map("name1", "chr1", 1, 350)
+        iMap2 = Map("name4", "chr2", 5, 450)
+        iMap3 = Map("name4", "chr1", 10, 450)
+        iMap4 = Map("name4", "chr1", 10, 500)
+        iMap5 = Map("name4", "chr1", 5, 450)
+        iMap6 = Map("name3", "chr1", 50, 350)
+        iMap7 = Map("name2", "chr1", 1, 100)
+
+        lMaps = [ iMap1, iMap2, iMap3, iMap4, iMap5, iMap6, iMap7 ]
+        
+        expLMaps = [ iMap1, iMap7, iMap6, iMap5, iMap3, iMap4, iMap2 ]
+        
+        obsLMaps = MapUtils.getMapListSortedByIncreasingNameThenSeqnameThenMinThenMax( lMaps )
+        
+        self.assertEquals( expLMaps, obsLMaps )
+        
+        
+    def test_getMapListSortedByIncreasingNameThenSeqnameThenMinThenMax_ordered( self ):
+        iMap1 = Map("name1", "chr1", 1, 100)
+        iMap2 = Map("name1", "chr2", 1, 350)
+        
+        lMaps = [ iMap1, iMap2 ]
+        expLMaps = [ iMap1, iMap2 ]
+        
+        obsLMaps = MapUtils.getMapListSortedByIncreasingNameThenSeqnameThenMinThenMax( lMaps )
+        
+        self.assertEquals( expLMaps, obsLMaps )
+        
+        
+    def test_getMapListSortedByIncreasingNameThenSeqnameThenMinThenMax_unordered( self ):
+        iMap1 = Map("name1", "chr2", 1, 350)
+        iMap2 = Map("name1", "chr1", 1, 100)
+        
+        lMaps = [ iMap1, iMap2 ]
+        expLMaps = [ iMap2, iMap1 ]
+        
+        obsLMaps = MapUtils.getMapListSortedByIncreasingNameThenSeqnameThenMinThenMax( lMaps )
+        
+        self.assertEquals( expLMaps, obsLMaps )
+        
+        
+    def test_getMapListSortedByIncreasingNameThenSeqnameThenMinThenMax_nonOverlapping( self ):
+        iMap1 = Map("name1", "chr1", 1, 350)
+        iMap2 = Map("name2", "chr1", 400, 600)
+        
+        lMaps = [ iMap2, iMap1 ]
+        expLMaps = [ iMap1, iMap2 ]
+        
+        obsLMaps = MapUtils.getMapListSortedByIncreasingNameThenSeqnameThenMinThenMax( lMaps )
+        
+        self.assertEquals( expLMaps, obsLMaps )
+        
+        
+    def test_getMapListSortedByIncreasingNameThenSeqnameThenMinThenMax_sameMinThreeMaps( self ):
+        iMap1 = Map("name2", "chr1", 150, 10)
+        iMap2 = Map("name2", "chr1", 1, 100)
+        iMap3 = Map("name2", "chr1", 100, 1)
+        
+        lMaps = [ iMap1, iMap2, iMap3 ]
+        expLMaps = [ iMap2, iMap3, iMap1 ]
+        
+        obsLMaps = MapUtils.getMapListSortedByIncreasingNameThenSeqnameThenMinThenMax( lMaps )
+        
+        self.assertEquals( expLMaps, obsLMaps )
+        
+
+    def test_getDictPerNameFromMapFile( self ):
+        iMap1 = Map( "chunk1", "chromosome1", 1, 100 )
+        iMap2 = Map( "chunk2", "chromosome1", 91, 190 )
+        iMap3 = Map( "chunk3", "chromosome2", 1, 100 )
+        iMap4 = Map( "chunk1", "chromosome1", 1, 100 )  # redundant with iMap1
+        
+        mapFile = "dummyFile.map"
+        mapFileHandler = open( mapFile, "w" )
+        for iMap in [ iMap1, iMap2, iMap3, iMap4 ]:
+            iMap.write( mapFileHandler )
+        mapFileHandler.close()
+        
+        dExp = { "chunk1": iMap1, "chunk2": iMap2, "chunk3": iMap3 }
+        
+        dObs = MapUtils.getDictPerNameFromMapFile( mapFile )
+        
+        self.assertEquals( dExp, dObs )
+        
+        os.remove( mapFile )
+        
+        
+    def test_mapList2SetList(self):
+        map1 = Map( "name1", "desc1", 1, 120 )
+        map2 = Map( "name2", "desc2", 1, 20 )
+        lMap = [ map1, map2 ]
+        set1 = Set( 1, "name1", "desc1", 1, 120 )
+        set2 = Set( 2, "name2", "desc2", 1, 20 )
+        explMapSet = [ set1, set2 ]
+        obslMapSet = MapUtils.mapList2SetList( lMap )
+        
+        self.assertEquals( explMapSet, obslMapSet )
+        
+        
+    def test_mergeCoordsInFile( self ):
+        if sys.modules.has_key( "commons.core.checker.CheckerUtils" ):
+            inFile = "dummyInFile"
+            inFileHandler = open( inFile, "w" )
+            inFileHandler.write( "TE1\tchr1\t1501\t2500\n" )
+            inFileHandler.write( "TE3\tchr1\t4000\t3401\n" )
+            inFileHandler.write( "TE3\tchr1\t3800\t3601\n" )
+            inFileHandler.close()
+            expFile = "dummyExpFile"
+            expFileHandler = open( expFile, "w" )
+            expFileHandler.write( "TE1\tchr1\t1501\t2500\n" )
+            expFileHandler.write( "TE3\tchr1\t4000\t3401\n" )
+            expFileHandler.close()
+            obsFile = "dummyObsFile"
+            MapUtils.mergeCoordsInFile( inFile, obsFile )
+            self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+            for f in [ inFile, expFile, obsFile ]:
+                os.remove( f )
+                
+                
+    def test_getDictPerSeqNameFromMapFile( self ):
+        inFile = "dummyInFile"
+        inFileHandler = open( inFile, "w" )
+        inFileHandler.write( "TE1\tchr1\t1\t10\n" )
+        inFileHandler.write( "TE2\tchr1\t60\t41\n" )
+        inFileHandler.write( "TE3\tchr2\t5\t36\n" )
+        inFileHandler.close()
+        dExp = { "chr1": [ Map( "TE1", "chr1", 1, 10 ), Map( "TE2", "chr1", 60, 41 ) ],
+                "chr2": [ Map( "TE3", "chr2", 5, 36 ) ] }
+        dObs = MapUtils.getDictPerSeqNameFromMapFile( inFile )
+        self.assertEqual( dExp, dObs )
+        os.remove( inFile )
+
+    def test_convertMapFileIntoSetFile(self):
+        mapInputFile = "dummyExpFile"
+        mapFileHandler = open( mapInputFile, "w" )
+        mapFileHandler.write( "seq31\tchr1\t151\t250\n" )
+        mapFileHandler.write( "seq27\tchr2\t301\t500\n" )
+        mapFileHandler.write( "seq40\tchr2\t600\t700\n" )
+        mapFileHandler.write( "seq2\tchr3\t301\t500\n" )
+        mapFileHandler.close()
+
+        expSetFile = "dummyexpSetFile"
+        expSetFileHandler = open( expSetFile, "w" )
+        expSetFileHandler.write( "1\tseq31\tchr1\t151\t250\n" )
+        expSetFileHandler.write( "2\tseq27\tchr2\t301\t500\n" )
+        expSetFileHandler.write( "3\tseq40\tchr2\t600\t700\n" )
+        expSetFileHandler.write( "4\tseq2\tchr3\t301\t500\n" )
+        expSetFileHandler.close()
+        
+        obsFile = "dummyObsFile"
+        
+        MapUtils.convertMapFileIntoSetFile( mapInputFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expSetFile, obsFile ) )
+        
+        for f in [ expSetFile, mapInputFile, obsFile ]:
+            os.remove( f )
+
+    def test_convertMapFileIntoSetFile_one_line(self):
+        mapInputFile = "dummyExpFile"
+        mapFileHandler = open( mapInputFile, "w" )
+        mapFileHandler.write( "seq31\tchr1\t151\t250\n" )
+        mapFileHandler.close()
+
+        expSetFile = "dummyexpSetFile"
+        expSetFileHandler = open( expSetFile, "w" )
+        expSetFileHandler.write( "1\tseq31\tchr1\t151\t250\n" )
+        expSetFileHandler.close()
+        
+        obsFile = "dummyObsFile"
+        
+        MapUtils.convertMapFileIntoSetFile( mapInputFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expSetFile, obsFile ) )
+        
+        for f in [ expSetFile, mapInputFile, obsFile ]:
+            os.remove( f )
+
+    def test_convertMapFileIntoSetFile_empty_file(self):
+        mapInputFile = "dummyFile.map"
+        mapFileHandler = open( mapInputFile, "w" )
+        mapFileHandler.close()
+        
+        expFile = "dummyExpFile.map.set"
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.close()
+        
+        obsFile = "dummyFile.map.set"
+        
+        MapUtils.convertMapFileIntoSetFile( mapInputFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ expFile, mapInputFile, obsFile ]:
+            os.remove( f )
+            
+    def test_writeListInFile_empty_list(self):
+        lMaps = [ ]
+        expFileName = "expFileName"
+        fileHandle = open(expFileName, "w")
+        fileHandle.close()
+ 
+        obsFileName = "obsFileName"
+        fileHandle = open(obsFileName, "w")
+        MapUtils.writeListInFile(lMaps, obsFileName, "w")
+        fileHandle.close()
+         
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        
+        os.remove(obsFileName)
+        os.remove(expFileName)
+        
+    def test_writeListInFile_list_one_set(self):
+        lMaps = [ Map( "map1", "map1seq", 1, 10 ) ]
+        line =  "map1\tmap1seq\t1\t10\n"
+       
+        expFileName = "expFileName"
+ 
+        fileHandle = open(expFileName, "w")
+        fileHandle.write(line)
+        fileHandle.close()
+ 
+        obsFileName = "obsFileName"
+        fileHandle = open(obsFileName, "w")
+        MapUtils.writeListInFile(lMaps, obsFileName, "w")
+        fileHandle.close()
+         
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        
+        os.remove(obsFileName)
+        os.remove(expFileName)
+
+    def test_getMinLengthOfMapFile(self):
+        mapFileName = "%s/Gnome_tools/Vein_v4_scaffold_00001.fa.Nstretch.map" % os.environ["REPET_DATA"]
+        expMinLengthofMapFile = 20
+        iMap = MapUtils()
+        obsMinLengthofMapFile = iMap.getMinLengthOfMapFile(mapFileName)
+        self.assertEquals(expMinLengthofMapFile, obsMinLengthofMapFile)
+       
+    def test_getMaxLengthOfMapFile(self):
+        mapFileName = "%s/Gnome_tools/Vein_v4_scaffold_00001.fa.Nstretch.map" % os.environ["REPET_DATA"]
+        expMinLengthofMapFile = 6344
+        iMap = MapUtils()
+        obsMinLengthofMapFile = iMap.getMaxLengthOfMapFile(mapFileName)
+        self.assertEquals(expMinLengthofMapFile, obsMinLengthofMapFile)
+       
+
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_MapUtils ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_Match.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,363 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+from commons.core.coord.Match import Match
+from commons.core.coord.Path import Path
+
+
+class Test_Match( unittest.TestCase ):
+    
+    def test_eq_match_equals( self ):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_query_name( self ):
+        tuple1 = ("Name", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_query_start( self ):
+        tuple1 = ("QName", 2, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_query_end( self ):
+        tuple1 = ("QName", 1, 6, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_query_length( self ):
+        tuple1 = ("QName", 1, 5, 6, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_query_length_perc( self ):
+        tuple1 = ("QName", 1, 5, 5, 0.15, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_match_length_perc( self ):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.25, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_subject_name( self ):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "Name", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_subject_start( self ):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 6, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_subject_end( self ):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 26, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_subject_length( self ):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 21, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_subject_length_perc( self ):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.16, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_subject_e_value( self ):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-21, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_subject_score( self ):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 16, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_subject_identity( self ):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 85.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_eq_match_not_equals_subject_id( self ):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 2)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertNotEquals( match1, match2 )
+        
+    def test_setFromTuple_direct_strand( self ):
+        tuple = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        obsMatch = Match()
+        obsMatch.setFromTuple(tuple)
+        expMatch = Match()
+        expMatch.range_query.seqname = "QName"
+        expMatch.range_query.start = 1
+        expMatch.range_query.end = 5
+        expMatch.query_length = 5
+        expMatch.query_length_perc = 0.1
+        expMatch.match_length_perc = 0.2
+        expMatch.range_subject.seqname = "SName"
+        expMatch.range_subject.start = 5
+        expMatch.range_subject.end = 25
+        expMatch.subject_length = 20
+        expMatch.subject_length_perc = 0.15
+        expMatch.e_value = 1e-20
+        expMatch.score = 15
+        expMatch.identity = 87.2
+        expMatch.id = 1
+        expMatch.subject_seqlength = int( expMatch.subject_length / expMatch.subject_length_perc )
+        expMatch.query_seqlength = int( expMatch.query_length / expMatch.query_length_perc )
+        self.assertEquals( expMatch, obsMatch )
+   
+    def test_setFromTuple_reverse_strand_on_subject( self ):
+        tuple = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 25, 5, 20, 0.15, 1e-20, 15, 87.2, 1)
+        obsMatch = Match()
+        obsMatch.setFromTuple(tuple)
+        expMatch = Match()
+        expMatch.range_query.seqname = "QName"
+        expMatch.range_query.start = 1
+        expMatch.range_query.end = 5
+        expMatch.query_length = 5
+        expMatch.query_length_perc = 0.1
+        expMatch.match_length_perc = 0.2
+        expMatch.range_subject.seqname = "SName"
+        expMatch.range_subject.start = 25
+        expMatch.range_subject.end = 5
+        expMatch.subject_length = 20
+        expMatch.subject_length_perc = 0.15
+        expMatch.e_value = 1e-20
+        expMatch.score = 15
+        expMatch.identity = 87.2
+        expMatch.id = 1
+        expMatch.subject_seqlength = int( expMatch.subject_length / expMatch.subject_length_perc )
+        expMatch.query_seqlength = int( expMatch.query_length / expMatch.query_length_perc )
+        self.assertEquals( expMatch, obsMatch )
+        
+    def test_setFromTuple_reverse_strand_on_query( self ):
+        tuple = ("QName", 5, 1, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        obsMatch = Match()
+        obsMatch.setFromTuple(tuple)
+        expMatch = Match()
+        expMatch.range_query.seqname = "QName"
+        expMatch.range_query.start = 1
+        expMatch.range_query.end = 5
+        expMatch.query_length = 5
+        expMatch.query_length_perc = 0.1
+        expMatch.match_length_perc = 0.2
+        expMatch.range_subject.seqname = "SName"
+        expMatch.range_subject.start = 25
+        expMatch.range_subject.end = 5
+        expMatch.subject_length = 20
+        expMatch.subject_length_perc = 0.15
+        expMatch.e_value = 1e-20
+        expMatch.score = 15
+        expMatch.identity = 87.2
+        expMatch.id = 1
+        expMatch.subject_seqlength = int( expMatch.subject_length / expMatch.subject_length_perc )
+        expMatch.query_seqlength = int( expMatch.query_length / expMatch.query_length_perc )
+        self.assertEquals( expMatch, obsMatch )
+        
+    def test_setFromTuple_reverse_strand_on_query_and_subject( self ):
+        tuple = ("QName", 5, 1, 5, 0.1, 0.2, "SName", 25, 5, 20, 0.15, 1e-20, 15, 87.2, 1)
+        obsMatch = Match()
+        obsMatch.setFromTuple(tuple)
+        expMatch = Match()
+        expMatch.range_query.seqname = "QName"
+        expMatch.range_query.start = 1
+        expMatch.range_query.end = 5
+        expMatch.query_length = 5
+        expMatch.query_length_perc = 0.1
+        expMatch.match_length_perc = 0.2
+        expMatch.range_subject.seqname = "SName"
+        expMatch.range_subject.start = 5
+        expMatch.range_subject.end = 25
+        expMatch.subject_length = 20
+        expMatch.subject_length_perc = 0.15
+        expMatch.e_value = 1e-20
+        expMatch.score = 15
+        expMatch.identity = 87.2
+        expMatch.id = 1
+        expMatch.subject_seqlength = int( expMatch.subject_length / expMatch.subject_length_perc )
+        expMatch.query_seqlength = int( expMatch.query_length / expMatch.query_length_perc )
+        self.assertEquals( expMatch, obsMatch )
+        
+    def test_toString( self ):        
+        tuple = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match = Match()
+        match.setFromTuple(tuple)
+        expString = "QName\t1\t5\t5\t%f\t%f\tSName\t5\t25\t20\t%f\t%g\t15\t%f\t1" % (0.1,0.2,0.15,1e-20, 87.2)
+        obsString = match.toString()
+        self.assertEquals(expString, obsString)
+        
+    def test_getPathInstance( self ):
+        tuple = ( "QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1 )
+        match = Match()
+        match.setFromTuple( tuple )
+        tuple = ( 1, "QName", 1, 5, "SName", 5, 25, 1e-20, 15, 87.2 )
+        exp = Path()
+        exp.setFromTuple( tuple )
+        obs = match.getPathInstance()
+        self.assertEqual( exp, obs )
+        
+    def test_getQryIsIncluded(self):
+        tuple = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match = Match()
+        match.setFromTuple(tuple)
+        expString = "query QName (50 bp: 1-5) is contained in subject SName (133 bp: 5-25): id=87.20 - 0.100 - 0.200 - 0.150"
+        obsString = match.getQryIsIncluded()
+        self.assertEquals(expString, obsString)
+        
+    def test_isDoublonWith_Matchs_equals(self):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertTrue(match1.isDoublonWith(match2))
+        
+    def test_isDoublonWith_Matchs_unequals_on_MatchNumbers(self):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 86.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertFalse(match1.isDoublonWith(match2))
+        
+    def test_isDoublonWith_Matchs_unequals_on_SeqNames(self):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 5, 5, 0.1, 0.2, "Name", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertFalse(match1.isDoublonWith(match2))
+        
+    def test_isDoublonWith_Matchs_unequals_on_Coordinates(self):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("QName", 1, 6, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertFalse(match1.isDoublonWith(match2))
+        
+    def test_isDoublonWith_Reversed_Matchs_equals(self):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("SName", 5, 25, 20, 0.15, 0.2, "QName", 1, 5, 5, 0.1, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertTrue(match1.isDoublonWith(match2))
+        
+    def test_isDoublonWith_Reversed_Matchs_unequals(self):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        match1 = Match()
+        match1.setFromTuple(tuple1)
+        tuple2 = ("SName", 5, 25, 20, 0.15, 0.2, "QName", 1, 6, 5, 0.1, 1e-20, 15, 87.2, 1)
+        match2 = Match()
+        match2.setFromTuple(tuple2)
+        self.assertFalse(match1.isDoublonWith(match2))
+        
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_Match ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_MatchUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,439 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.coord.MatchUtils import MatchUtils
+from commons.core.coord.Match import Match
+from commons.core.seq.BioseqDB import BioseqDB
+
+
+class Test_MatchUtils( unittest.TestCase ):
+    
+    def test_getMatchListFromFile( self ):
+        inFile = "dummyInFile"
+        inFileHandler = open( inFile, "w" )
+        inFileHandler.write( "query.name\tquery.start\tquery.end\tquery.length\tquery.length.%\tmatch.length.%\tsubject.name\tsubject.start\tsubject.end\tsubject.length\tsubject.length.%\tE.value\tScore\tIdentity\tpath\n" )
+        m1 = Match()
+        m1.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName1", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1) )
+        m1.write( inFileHandler )
+        m2 = Match()
+        m2.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName2", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1) )
+        m2.write( inFileHandler )
+        inFileHandler.close()
+        
+        lExp = [ m1, m2 ]
+        
+        lObs = MatchUtils.getMatchListFromFile( inFile )
+        
+        self.assertEquals( lExp, lObs )
+        
+        os.remove( inFile )
+        
+    def test_getDictOfListsWithSubjectAsKey( self ):
+        m1 = Match()
+        m1.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName1", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1) )
+        m2 = Match()
+        m2.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName2", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1) )
+        lMatch = [ m1, m2 ]
+        
+        dExp = { "SName1": [ m1 ], "SName2": [ m2 ] }
+        
+        dObs = MatchUtils.getDictOfListsWithSubjectAsKey( lMatch )
+        
+        self.assertEquals( dExp, dObs )
+        
+    def test_getDictOfListsWithQueryAsKey( self ):
+        m1 = Match()
+        m1.setFromTuple( ("QName1", 1, 5, 5, 0.1, 0.2, "SName1", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1) )
+        m2 = Match()
+        m2.setFromTuple( ("QName2", 1, 5, 5, 0.1, 0.2, "SName2", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1) )
+        m3 = Match()
+        m3.setFromTuple( ("QName1", 1, 5, 5, 0.1, 0.2, "SName3", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1) )
+        lMatch = [ m1, m2, m3 ]
+        
+        dExp = { "QName1": [ m1, m3 ], "QName2": [ m2 ] }
+        
+        dObs = MatchUtils.getDictOfListsWithQueryAsKey( lMatch )
+        
+        self.assertEquals( dExp, dObs )
+    
+    def test_getIdListFromMatchList( self ):
+        m1 = Match()
+        m1.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName1", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1) )
+        m2 = Match()
+        m2.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName2", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 10) )
+        lMatch = [ m1, m2 ]  
+        
+        lExp = [1, 10]       
+        
+        lObs = MatchUtils.getIdListFromMatchList( lMatch )
+        
+        self.assertEquals(lExp, lObs)
+        
+    def test_getIdListFromMatchList_empty_list( self ):
+        lMatch = []  
+        lExp = []       
+        
+        lObs = MatchUtils.getIdListFromMatchList( lMatch )
+        
+        self.assertEquals(lExp, lObs)
+        
+    def test_writeListInFile_without_header( self ):
+        m1 = Match()
+        m1.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName1", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1) )
+        m2 = Match()
+        m2.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName2", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 10) )
+        lMatch = [ m1, m2 ]  
+        
+        line1 = "QName\t1\t5\t5\t0.100000\t0.200000\tSName1\t5\t25\t20\t0.150000\t1e-20\t15\t87.200000\t1\n"
+        line2 = "QName\t1\t5\t5\t0.100000\t0.200000\tSName2\t5\t25\t20\t0.150000\t1e-20\t15\t87.200000\t10\n"
+        
+        expFileName = "expFileName.match"
+        expFileHandle = open ( expFileName, 'w' )
+        expFileHandle.write(line1)
+        expFileHandle.write(line2)
+        expFileHandle.close()
+        
+        obsFileName = "obsFileName.match"
+        
+        MatchUtils.writeListInFile( lMatch, obsFileName )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        
+        os.remove( obsFileName )
+        os.remove( expFileName )
+
+    def test_writeListInFile_with_header( self ):
+        m1 = Match()
+        m1.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName1", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1) )
+        m2 = Match()
+        m2.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName2", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 10) )
+        lMatch = [ m1, m2 ]  
+        
+        headerLine = "query.name\tquery.start\tquery.end\tquery.length\tquery.length.%\tmatch.length.%\tsubject.name\tsubject.start\tsubject.end\tsubject.length\tsubject.length.%\tE.value\tScore\tIdentity\tpath\n"
+        
+        line1 = headerLine
+        line2 = "QName\t1\t5\t5\t0.100000\t0.200000\tSName1\t5\t25\t20\t0.150000\t1e-20\t15\t87.200000\t1\n"
+        line3 = "QName\t1\t5\t5\t0.100000\t0.200000\tSName2\t5\t25\t20\t0.150000\t1e-20\t15\t87.200000\t10\n"
+        
+        expFileName = "expFileName.match"
+        expFileHandle = open ( expFileName, 'w' )
+        expFileHandle.write(line1)
+        expFileHandle.write(line2)
+        expFileHandle.write(line3)
+        expFileHandle.close()
+        
+        obsFileName = "obsFileName.match"
+        
+        MatchUtils.writeListInFile( lMatch, obsFileName, header=headerLine )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        
+        os.remove( obsFileName )
+        os.remove( expFileName )
+        
+    def test_writeListInFile_with_append_mode( self ):
+        m1 = Match()
+        m1.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName1", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1) )
+        m2 = Match()
+        m2.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName2", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 10) )
+        lMatch = [ m1, m2 ]  
+        
+        line1 = "QName\t1\t5\t5\t0.100000\t0.200000\tSName1\t5\t25\t20\t0.150000\t1e-20\t15\t87.200000\t1\n"
+        line2 = "QName\t1\t5\t5\t0.100000\t0.200000\tSName2\t5\t25\t20\t0.150000\t1e-20\t15\t87.200000\t10\n"
+        
+        expFileName = "expFileName.match"
+        expFileHandle = open ( expFileName, 'w' )
+        expFileHandle.write(line1)
+        expFileHandle.write(line1)
+        expFileHandle.write(line2)
+        expFileHandle.close()
+        
+        obsFileName = "obsFileName.match"
+        obsFileHandle = open ( obsFileName, 'w' )
+        obsFileHandle.write(line1)
+        obsFileHandle.close()
+        
+        MatchUtils.writeListInFile( lMatch, obsFileName, 'a' )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        
+        os.remove( obsFileName )
+        os.remove( expFileName )       
+
+    def test_rmvDuplicateMatches(self):
+        m1 = Match()
+        m1.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1) )
+        m2 = Match()
+        m2.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName2", 5, 25, 20, 0.15, 1e-20, 15, 86.2, 1) )
+        m3 = Match()
+        m3.setFromTuple( ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1) )
+        lMatch = [ m1, m3, m2 ]  
+        
+        lExp = [m1, m2]
+        lObs = MatchUtils.rmvDuplicateMatches(lMatch)
+        
+        self.assertEquals(lExp, lObs)
+        
+    def test_filterDiffQrySbj_same_seq(self):
+        fastaFileName = "file.fa"
+        self._writeFastaFile(fastaFileName)
+        qryDB = BioseqDB(fastaFileName)
+        tabFileName = "file.tab"
+        self._writeMatchFile(tabFileName)
+        
+        expListToKeep = ["HELITRON2"]
+        obsListToKeep = MatchUtils.filterDiffQrySbj(qryDB,tabFileName, 0.95, 0.98, 2)
+        self.assertEquals(expListToKeep, obsListToKeep)
+        os.remove(fastaFileName)
+        os.remove(tabFileName)
+
+    def test_filterDiffQrySbj_TE_included_in_67percent_in_other_TE(self):
+        fastaFileName = "file.fa"
+        self._writeFastaFile2(fastaFileName)
+        qryDB = BioseqDB(fastaFileName)
+        tabFileName = "file.tab"
+        self._writeMatchFile2(tabFileName)
+        expListToKeep = []
+        obsListToKeep = MatchUtils.filterDiffQrySbj(qryDB, tabFileName, 0.95, 0.98, 2)
+        self.assertEquals(expListToKeep, obsListToKeep)
+        os.remove(fastaFileName)
+        os.remove(tabFileName)
+        
+    def test_getNbDistinctSequencesInsideMatchesWithThresh_query(self):
+        tabFileName = "file.tab"
+        self._writeMatchFile3(tabFileName)
+        lMatches = MatchUtils.getMatchListFromFile(tabFileName)
+        expNbDistinctMatches = 1
+        obsNbDistinctMatches = MatchUtils.getNbDistinctSequencesInsideMatchesWithThresh(lMatches,0.95, 0.98,"query")
+        self.assertEquals(expNbDistinctMatches, obsNbDistinctMatches)
+        os.remove(tabFileName)
+        
+    def test_getNbDistinctSequencesInsideMatchesWithThresh_subject(self):
+        tabFileName = "file.tab"
+        self._writeMatchFile3(tabFileName)
+        lMatches = MatchUtils.getMatchListFromFile(tabFileName)
+        expNbDistinctMatches = 1
+        obsNbDistinctMatches = MatchUtils.getNbDistinctSequencesInsideMatchesWithThresh(lMatches,0.95, 0.98,"subject")
+        self.assertEquals(expNbDistinctMatches, obsNbDistinctMatches)
+        os.remove(tabFileName)
+        
+    def test_convertMatchFileToAlignFile(self):
+        inputMatchFileName = "file.tab"
+        expAlignFileName = "expected.align"
+        obsAlignFileName = "file.align"
+        
+        self._writeExpAlignFile(expAlignFileName)
+        self._writeMatchFile4(inputMatchFileName)
+        MatchUtils.convertMatchFileToAlignFile(inputMatchFileName)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expAlignFileName, obsAlignFileName))
+        
+        os.remove(inputMatchFileName)
+        os.remove(expAlignFileName)
+        os.remove(obsAlignFileName)
+    
+    def test_convertMatchFileToAlignFile_empty_file(self):
+        inputMatchFileName = "file.tab"
+        expAlignFileName = "expected.align"
+        obsAlignFileName = "file.align"
+        
+        f = open(expAlignFileName, "w")
+        f.close()
+        f = open(inputMatchFileName, "w")
+        f.close()
+        MatchUtils.convertMatchFileToAlignFile(inputMatchFileName)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expAlignFileName, obsAlignFileName))
+        
+        os.remove(inputMatchFileName)
+        os.remove(expAlignFileName)
+        os.remove(obsAlignFileName)
+            
+    def test_generateMatchFileWithNewPathId(self):
+        inputMatchFileName = "file.tab"
+        expMatchFileName = "expected.tab"
+        obsMatchFileName = "obsFile.tab"
+        
+        self._writeMatchFile5(inputMatchFileName)
+        self._writeExpMatchFile(expMatchFileName)        
+        MatchUtils.generateMatchFileWithNewPathId(inputMatchFileName, obsMatchFileName)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expMatchFileName, obsMatchFileName))
+        
+        os.remove(inputMatchFileName)
+        os.remove(expMatchFileName)
+        os.remove(obsMatchFileName)
+        
+    def test_generateMatchFileWithNewPathId_empty_file(self):
+        inputMatchFileName = "file.tab"
+        expMatchFileName = "expected.tab"
+        obsMatchFileName = "obsFile.tab"
+        
+        f = open(expMatchFileName, "w")
+        f.write("query.name\tquery.start\tquery.end\tquery.length\tquery.length.%\tmatch.length.%\tsubject.name\tsubject.start\tsubject.end\tsubject.length\tsubject.length.%\tE.value\tScore\tIdentity\tpath\n")
+        f.close()
+        f = open(inputMatchFileName, "w")
+        f.close()
+        MatchUtils.generateMatchFileWithNewPathId(inputMatchFileName, obsMatchFileName)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expMatchFileName, obsMatchFileName))
+        
+        os.remove(inputMatchFileName)
+        os.remove(expMatchFileName)
+        os.remove(obsMatchFileName)
+        
+    def test_convertMatchFileIntoABCFileOnQueryCoverage(self):
+        matchFileName = "dummy.tab"
+        with open(matchFileName, "w") as f:
+            f.write("query.name\tquery.start\tquery.end\tquery.length\tquery.length.%\tmatch.length.%\tsubject.name\tsubject.start\tsubject.end\tsubject.length\tsubject.length.%\tE.value\tScore\tIdentity\tpath\n")
+            f.write("chr3\t1\t100\t100\t0.98\t0.95\tchr5\t11\t110\t100\t0.95\t1e-52\t133\t87.200000\n")
+            f.write("chr7\t1\t200\t200\t0.98\t0.95\tchr2\t11\t210\t200\t0.95\t1e-78\t235\t98.900000\n")
+            f.write("chr5\t1\t100\t100\t0.95\t0.95\tchr3\t11\t110\t100\t0.98\t1e-52\t133\t87.200000\n")
+            f.write("chr2\t1\t200\t200\t0.95\t0.95\tchr7\t11\t210\t200\t0.98\t1e-78\t235\t98.900000\n")
+        expFileName = "exp.abc"
+        with open(expFileName, "w") as f:
+            f.write("chr3\tchr5\t0.98\n")
+            f.write("chr7\tchr2\t0.98\n")
+            f.write("chr5\tchr3\t0.95\n")
+            f.write("chr2\tchr7\t0.95\n")
+        obsFileName = "obs.abc"
+        
+        MatchUtils.convertMatchFileIntoABCFileOnQueryCoverage(matchFileName, obsFileName)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(matchFileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_convertMatchFileIntoABCFileOnQueryCoverage_coverage_threshold_85(self):
+        matchFileName = "dummy.tab"
+        with open(matchFileName, "w") as f:
+            f.write("query.name\tquery.start\tquery.end\tquery.length\tquery.length.%\tmatch.length.%\tsubject.name\tsubject.start\tsubject.end\tsubject.length\tsubject.length.%\tE.value\tScore\tIdentity\tpath\n")
+            f.write("chr3\t1\t100\t100\t0.98\t0.95\tchr5\t11\t110\t100\t0.95\t1e-52\t133\t87.200000\n")
+            f.write("chr7\t1\t200\t200\t0.98\t0.95\tchr2\t11\t210\t200\t0.95\t1e-78\t235\t98.900000\n")
+            f.write("chr5\t1\t100\t100\t0.85\t0.95\tchr3\t11\t110\t100\t0.98\t1e-52\t133\t87.200000\n")
+            f.write("chr2\t1\t200\t200\t0.80\t0.95\tchr7\t11\t210\t200\t0.98\t1e-78\t235\t98.900000\n")
+        expFileName = "exp.abc"
+        with open(expFileName, "w") as f:
+            f.write("chr3\tchr5\t0.98\n")
+            f.write("chr7\tchr2\t0.98\n")
+            f.write("chr5\tchr3\t0.85\n")
+        obsFileName = "obs.abc"
+        
+        MatchUtils.convertMatchFileIntoABCFileOnQueryCoverage(matchFileName, obsFileName, coverage = 0.85)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(matchFileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def _writeFastaFile(self, fileName):
+        f = open(fileName, "w")
+        f.write(">HELITRON3\n")
+        f.write("GGCCAGTCACAATGGGGGTTTCACTGGTGTGTCATGCACATTTAATAGGGGTAAGACTGA\n")
+        f.write("ATAAAAAATGATTATTTGCATGAAATGGGGATGAGAGAGAAGGAAAGAGTTTCATCCTGG\n")
+        f.write("GATTCGTTTCATTCACCGGATCTCTTGCGTCCGCCTCCGCCGTGCGACCTCCGCATTCTC\n")
+        f.write(">HELITRON2\n")
+        f.write("GGCCAGTCACAATGGGGGTTTCACTGGTGTGTCATGCACATTTAATAGGGGTAAGACTGA\n")
+        f.write("ATAAAAAATGATTATTTGCATGAAATGGGGATGAGAGAGAAGGAAAGAGTTTCATCCTGG\n")
+        f.write("GATTCGTTTCATTCACCGGATCTCTTGCGTCCGCCTCCGCCGTGCGACCTCCGCATTCTC\n")
+        f.close()
+
+    def _writeMatchFile(self, fileName):
+        f = open(fileName, "w")
+        f.write("query.name\tquery.start\tquery.end\tquery.length\tquery.length.%\tmatch.length.%\tsubject.name\tsubject.start\tsubject.end\tsubject.length\tsubject.length.%\tE.value\tScore\tIdentity\tpath\n")
+        f.write("HELITRON3\t1\t180\t180\t1\t1\tHELITRON2\t1\t180\t180\t1\t2e-103\t357\t100\t1\n")
+        f.close()
+        
+    def _writeFastaFile2(self, fileName):
+        f = open(fileName, "w")
+        f.write(">header2\n")
+        f.write("TTTCACTGGTGTGTCATGCACATTTAATAGGGGTAAGACTGAATAAAAAATGATTATTTG\n")
+        f.write("CATGAAATGGGGATGAGAGAGAAGGAAAGAGTTTCATCCTGGGATTCGTTTCATTCACCG\n")
+        f.close()
+
+    def _writeMatchFile2(self, fileName):
+        f = open(fileName, "w")
+        f.write("query.name\tquery.start\tquery.end\tquery.length\tquery.length.%\tmatch.length.%\tsubject.name\tsubject.start\tsubject.end\tsubject.length\tsubject.length.%\tE.value\tScore\tIdentity\tpath\n")
+        f.write("header2\t1\t120\t120\t1\t0.674157\tBS31790\t19\t138\t120\t0.674157\t3e-68\t238\t100\t1\n")
+        f.close()
+        
+    def _writeMatchFile3(self, fileName):
+        f = open(fileName, "w")
+        f.write("query.name\tquery.start\tquery.end\tquery.length\tquery.length.%\tmatch.length.%\tsubject.name\tsubject.start\tsubject.end\tsubject.length\tsubject.length.%\tE.value\tScore\tIdentity\tpath\n")
+        f.write("header2\t1\t120\t120\t0.674157\t0.674157\tBS31790\t19\t138\t120\t0.674157\t3e-68\t238\t100\t1\n")
+        f.write("header3\t1\t120\t120\t0.99\t0.994157\tBS31790\t19\t138\t120\t0.994157\t3e-68\t238\t100\t1\n")
+        f.write("header4\t1\t120\t120\t1\t0.94157\tBS31790\t19\t138\t120\t0.674157\t3e-68\t238\t67\t1\n")
+        f.close()
+        
+    def _writeMatchFile4(self, fileName):
+        f = open(fileName, "w")
+        f.write("query.name\tquery.start\tquery.end\tquery.length\tquery.length.%\tmatch.length.%\tsubject.name\tsubject.start\tsubject.end\tsubject.length\tsubject.length.%\tE.value\tScore\tIdentity\tpath\n")
+        f.write("header2\t1\t120\t120\t0.674157\t0.674157\tBS31790\t19\t138\t120\t0.674157\t3e-68\t238\t100\t1\n")
+        f.write("header3\t120\t220\t120\t0.99\t0.994157\tBS31790\t19\t138\t120\t0.994157\t3e-65\t238\t100\t1\n")
+        f.write("header4\t1\t120\t120\t1\t0.94157\tBS31790\t19\t138\t120\t0.674157\t3e-67\t244\t90\t1\n")
+        f.close()
+        
+    def _writeExpAlignFile(self,fileName):
+        f = open(fileName, "w")
+        f.write("header2\t1\t120\tBS31790\t19\t138\t3e-68\t238.0\t100.0\n")
+        f.write("header3\t120\t220\tBS31790\t19\t138\t3e-65\t238.0\t100.0\n")
+        f.write("header4\t1\t120\tBS31790\t19\t138\t3e-67\t244.0\t90.0\n")
+        f.close()
+        
+    def _writeMatchFile5(self,fileName):
+        f = open(fileName, "w")
+        f.write("query.name\tquery.start\tquery.end\tquery.length\tquery.length.%\tmatch.length.%\tsubject.name\tsubject.start\tsubject.end\tsubject.length\tsubject.length.%\tE.value\tScore\tIdentity\tpath\n")
+        f.write("header2\t1\t120\t120\t0.674157\t0.674157\tBS31790\t19\t138\t120\t0.674157\t3e-68\t238\t100\t1\n")
+        f.write("header2\t124\t144\t120\t0.674157\t0.674157\tBS31790\t19\t138\t120\t0.674157\t3e-68\t238\t100\t1\n")
+        f.write("header3\t120\t220\t120\t0.99\t0.994157\tBS31790\t19\t138\t120\t0.994157\t3e-65\t238\t100\t1\n")
+        f.write("header4\t1\t120\t120\t1\t0.94157\tBS31790\t19\t138\t120\t0.674157\t3e-67\t244\t90\t1\n")
+        f.close()
+        
+    def _writeExpMatchFile(self,fileName):
+        f = open(fileName, "w")
+        f.write("query.name\tquery.start\tquery.end\tquery.length\tquery.length.%\tmatch.length.%\tsubject.name\tsubject.start\tsubject.end\tsubject.length\tsubject.length.%\tE.value\tScore\tIdentity\tpath\n")
+        f.write("header2\t1\t120\t120\t0.674157\t0.674157\tBS31790\t19\t138\t120\t0.674157\t3e-68\t238\t100.000000\t1\n")
+        f.write("header2\t124\t144\t120\t0.674157\t0.674157\tBS31790\t19\t138\t120\t0.674157\t3e-68\t238\t100.000000\t1\n")
+        f.write("header3\t120\t220\t120\t0.990000\t0.994157\tBS31790\t19\t138\t120\t0.994157\t3e-65\t238\t100.000000\t2\n")
+        f.write("header4\t1\t120\t120\t1.000000\t0.941570\tBS31790\t19\t138\t120\t0.674157\t3e-67\t244\t90.000000\t3\n")
+        f.close()
+    
+
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_MatchUtils ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_MergedRange.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,119 @@
+import unittest
+from commons.core.coord.MergedRange import MergedRange
+from commons.core.coord.Match import Match
+
+class Test_MergedRange(unittest.TestCase):
+    
+    def test_eq_True(self):
+        mr1 = MergedRange([1], 6, 10)
+        mr2 = MergedRange([1], 6, 10)
+        self.assertEquals(mr1, mr2)
+    
+    def test_eq_different_list(self):
+        mr1 = MergedRange([1], 6, 10)
+        mr2 = MergedRange([1, 2], 6, 10)
+        self.assertNotEquals(mr1, mr2)
+    
+    def test_eq_different_start(self):
+        mr1 = MergedRange([1], 5, 10)
+        mr2 = MergedRange([1], 6, 10)
+        self.assertNotEquals(mr1, mr2)
+    
+    def test_eq_different_end(self):
+        mr1 = MergedRange([1], 6, 10)
+        mr2 = MergedRange([1], 6, 11)
+        self.assertNotEquals(mr1, mr2)
+
+    def test_isOverlapping_no( self ):
+        mr1 = MergedRange([1], 6, 10)
+        mr2 = MergedRange([2], 16, 20)
+        exp = False
+        obs = mr1.isOverlapping( mr2 )
+        self.assertEquals( exp, obs )
+        
+    def test_isOverlapping_yes( self ):
+        mr1 = MergedRange([1], 6, 10)
+        mr2 = MergedRange([2], 5, 20)
+        exp = True
+        obs = mr1.isOverlapping( mr2 )
+        self.assertEquals( exp, obs )
+
+    def test_isOverlapping_range1_before_range2( self ):
+        mr1 = MergedRange([1], 6, 10)
+        mr2 = MergedRange([2], 8, 15)
+        exp = True
+        obs = mr1.isOverlapping( mr2 )
+        self.assertEquals( exp, obs )
+        
+    def test_isOverlapping_range1_after_range2( self ):
+        mr1 = MergedRange([1], 6, 10)
+        mr2 = MergedRange([2], 1, 8)
+        exp = True
+        obs = mr1.isOverlapping( mr2 )
+        self.assertEquals( exp, obs )
+        
+    def test_isOverlapping_range1_equal_range2( self ):
+        mr1 = MergedRange([1], 6, 10)
+        mr2 = MergedRange([2], 6, 10)
+        exp = True
+        obs = mr1.isOverlapping( mr2 )
+        self.assertEquals( exp, obs )
+    
+    def test_merge_mr1_with_mr2(self):
+        otherMergedRange = MergedRange()
+        otherMergedRange._lId.append(3)
+        otherMergedRange._start = 1
+        otherMergedRange._end = 10
+        
+        mr1 = MergedRange()
+        mr1._lId.append(1)
+        mr1._start = 6
+        mr1._end = 10
+        
+        mr2 = MergedRange([2], 1, 15)
+        mr1.merge(mr2)
+        
+        exp = MergedRange([1, 2], 1, 15)
+        self.assertEquals(exp, mr1)
+        
+    def test_merge_mr2_with_mr1(self):
+        mr1 = MergedRange([1], 6, 10)
+        mr2 = MergedRange([2], 1, 15)
+        mr2.merge(mr1)
+        exp = MergedRange([1, 2], 1, 15)
+        self.assertEquals(exp, mr2)
+        
+    def test_setFromMatch(self):
+        tuple = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        iMatch = Match()
+        iMatch.setFromTuple(tuple)
+        
+        expMergedRange = MergedRange([1], 1, 5)
+        obsMergedRange = MergedRange()
+        obsMergedRange.setFromMatch(iMatch)
+        
+        self.assertEquals(expMergedRange, obsMergedRange)
+    
+    def test_getMergedRangeListFromMatchList(self):
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        iMatch1 = Match()
+        iMatch1.setFromTuple(tuple1)
+        tuple2 = ("QName", 10, 15, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 2)
+        iMatch2 = Match()
+        iMatch2.setFromTuple(tuple2)
+        lMatch = [iMatch1, iMatch2]
+        
+        explMergedRange = [MergedRange([1], 1, 5), MergedRange([2], 10, 15)]
+        obslMergedRange = MergedRange.getMergedRangeListFromMatchList(lMatch)
+
+        self.assertEquals(explMergedRange, obslMergedRange)
+    
+    def test_getMergedRangeListFromMatchList_empty_list(self):
+        lMatch = []
+        explMergedRange = []
+        obslMergedRange = MergedRange.getMergedRangeListFromMatchList(lMatch)
+
+        self.assertEquals(explMergedRange, obslMergedRange)
+        
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_Path.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,146 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+from commons.core.coord.Path import Path
+from commons.core.coord.Align import Align
+from commons.core.coord.Set import Set
+
+
+class Test_Path( unittest.TestCase ):
+    
+    def setUp( self ):
+        self._path = Path()
+        
+    def test_setFromTuple( self ):
+        line = "1\tchr1\t1\t10\tTE2\t11\t17\t1e-20\t30\t90.2"
+        self._path.setFromTuple( line.split("\t") )
+        self.assertEqual( self._path.id, 1 )
+        self.assertEqual( self._path.range_query.seqname, "chr1" )
+        self.assertEqual( self._path.range_query.start, 1 )
+        self.assertEqual( self._path.range_query.end, 10 )
+        self.assertEqual( self._path.range_subject.seqname, "TE2" )
+        self.assertEqual( self._path.range_subject.start, 11 )
+        self.assertEqual( self._path.range_subject.end, 17 )
+        self.assertEqual( self._path.e_value, float("1e-20") )
+        self.assertEqual( self._path.score, float("30") )
+        self.assertEqual( self._path.identity, float("90.2") )
+        
+    def test___eq__( self ):
+        self._path.setFromString( "1\tchr1\t1\t6\tTE2\t11\t16\t1e-20\t30\t90.2\n" )
+        o = Path()
+        o.setFromString( "1\tchr1\t1\t6\tTE2\t11\t16\t1e-20\t30\t90.2\n" )
+        self.assertEqual( self._path,  o )
+        o.setFromString( "2\tchr1\t1\t6\tTE2\t11\t16\t1e-20\t30\t90.2\n" )
+        self.assertNotEqual( self._path,  o )
+        o.setFromString( "1\tchr1\t1\t6\tTE2\t11\t16\t1e-20\t3000000\t90.2\n" )
+        self.assertNotEqual( self._path,  o )
+        
+    def test_canMerge( self ):
+        tuple = ("1", "chr1","1", "10","TE2","11","17","1e-20","30","90.2")
+        self._path.setFromTuple(tuple)
+        tuple = ("2", "chr1","2", "9","TE2","10","13","1e-20","30","90.2")
+        o = Path()
+        o.setFromTuple(tuple)
+        self.assertTrue(self._path.canMerge(o))
+        
+    def test_canMerge_on_same_id ( self ): 
+        tuple = ("1", "chr1","1", "10","TE2","11","17","1e-20","30","90.2")
+        self._path.setFromTuple(tuple)
+        tuple = ("1", "chr1","2", "9","TE2","10","13","1e-20","30","90.2")
+        o = Path()
+        o.setFromTuple(tuple)
+        self.assertFalse(self._path.canMerge(o))
+        
+    def test_canMerge_on_same_chr( self ):     
+        tuple = ("1", "chr1","1", "10","TE2","11","17","1e-20","30","90.2")
+        self._path.setFromTuple(tuple)
+        tuple = ("2", "chr2","2", "9","TE2","10","13","1e-20","30","90.2")
+        o = Path()
+        o.setFromTuple(tuple)
+        self.assertFalse(self._path.canMerge(o))
+        
+    def test_canMerge_on_diff_subj( self ):      
+        tuple = ("1", "chr1","1", "10","TE2","11","17","1e-20","30","90.2")
+        self._path.setFromTuple(tuple)
+        tuple = ("2", "chr1","2", "9","TE3","10","13","1e-20","30","90.2")
+        o = Path()
+        o.setFromTuple(tuple)
+        self.assertFalse(self._path.canMerge(o)) 
+        
+    def test_canMerge_on_queries_that_do_not_overlap( self ):
+        tuple = ("1", "chr1","5", "11","TE2","11","17","1e-20","30","90.2")
+        self._path.setFromTuple(tuple)
+        tuple = ("2", "chr1","1", "4","TE2","10","13","1e-20","30","90.2")
+        o = Path()
+        o.setFromTuple(tuple)
+        self.assertFalse(self._path.canMerge(o)) 
+        
+    def test_canMerge_on_subjects_that_do_not_overlap( self ):    
+        tuple = ("1", "chr1","1", "10","TE2","11","17","1e-20","30","90.2")
+        self._path.setFromTuple(tuple)
+        tuple = ("2", "chr1","2", "9","TE2","1","10","1e-20","30","90.2")
+        o = Path()
+        o.setFromTuple(tuple)
+        self.assertFalse(self._path.canMerge(o))
+        
+    def test_getSubjectAsSetOfQuery( self ):
+        tuple = ("1","chr1","1","10","TE2","11","17","1e-20","30","90.2")
+        self._path.setFromTuple(tuple)
+        exp = Set(1,"TE2","chr1",1,10)
+        obs = self._path.getSubjectAsSetOfQuery()
+        self.assertEqual( exp, obs )
+        
+    def test_getSubjectAsSetOfQuery_on_neg_strand( self ):
+        tuple = ("1","chr1","10","1","TE2","11","17","1e-20","30","90.2")
+        self._path.setFromTuple(tuple)
+        exp = Set(1,"TE2","chr1",10,1)
+        obs = self._path.getSubjectAsSetOfQuery()
+        self.assertEqual( exp, obs )
+        
+    def test_toString( self ):
+        self._path.setFromString( "1\tchr1\t1\t10\tTE3\t11\t17\t1e-20\t30\t85.2\n" )
+        exp = "1\tchr1\t1\t10\tTE3\t11\t17\t%g\t30\t%f" % ( 1e-20, 85.2 )
+        obs = self._path.toString()
+        self.assertEqual( obs, exp )
+        
+    def test_getAlignInstance( self ):
+        self._path.setFromTuple( ( "2", "chr3", "250", "151", "seq5", "1", "100", "1e-32", "147", "87.9" ) )
+        expAlign = Align()
+        expAlign.setFromTuple( ( "chr3", "151", "250", "seq5", "100", "1", "1e-32", "147", "87.9" ) )
+        obsAlign = self._path.getAlignInstance()
+        self.assertEqual( expAlign, obsAlign )
+        
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_Path ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_PathUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,1667 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+import time
+from commons.core.coord.PathUtils import PathUtils
+from commons.core.coord.Path import Path
+from commons.core.coord.Set import Set
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.coord.Range import Range
+from commons.core.coord.Align import Align
+
+
+class Test_PathUtils ( unittest.TestCase ):
+
+    def test_getSetListFromQueries( self ):
+        set1 = Set(1,"TE2","chr1",1,10)
+        set2 = Set(1,"TE2","chr1",10,1)
+        set3 = Set(1,"TE3","chr4",12,22)
+    
+        expList = [set1, set2, set3]
+
+        tuple1 = ("1","chr1","1","10","TE2","11","17","1e-20","30","90.2")
+        tuple2 = ("1","chr1","10","1","TE2","11","17","1e-20","30","90.2")
+        tuple3 = ("1","chr4","12","22","TE3","11","17","1e-20","30","90.2")
+
+        pathList = self._makePathListFromTupleList( [ tuple1, tuple2, tuple3 ] )
+
+        obsList = PathUtils.getSetListFromQueries( pathList )
+
+        self.assertEquals( expList, obsList )
+        
+    
+    def test_getSetListFromQueries_on_empty_list( self ):
+        expList = []
+        obsList = PathUtils.getSetListFromQueries( [] )
+
+        self.assertEquals( expList, obsList )
+        
+        
+    def test_getSetListFromQueries_on_list_size1( self ):
+        set1 = Set(1,"TE2","chr1",1,10)
+        
+        expList = [set1]
+        
+        tuple1 = ("1","chr1","1","10","TE2","11","17","1e-20","30","90.2")
+        path1 = Path()
+        path1.setFromTuple(tuple1)
+        
+        pathList = [path1]
+        obsList = PathUtils.getSetListFromQueries( pathList )
+        
+        self.assertEquals( expList, obsList )
+        
+        
+    def test_getRangeListFromSubjects_initiallyOrdered_directStrand( self ):
+        tuple1 = ("1","chr1","1","10","TE2","1","10","1e-20","30","90.2")
+        tuple2 = ("1","chr1","21","30","TE2","11","20","1e-20","30","90.2")
+        tuple3 = ("1","chr1","41","50","TE2","21","30","1e-20","30","90.2")
+        lPaths = self._makePathListFromTupleList( [ tuple1, tuple2, tuple3 ] )
+        
+        iSet1 = Range( "TE2", 1, 10 )
+        iSet2 = Range( "TE2", 11, 20 )
+        iSet3 = Range( "TE2", 21, 30 )
+        lExp = [ iSet1, iSet2, iSet3 ]
+        
+        lObs = PathUtils.getRangeListFromSubjects( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_getRangeListFromSubjects_initiallyUnordered_directStrand( self ):
+        tuple1 = ("1","chr1","1","10","TE2","1","10","1e-20","30","90.2")
+        tuple2 = ("1","chr1","41","50","TE2","21","30","1e-20","30","90.2")
+        tuple3 = ("1","chr1","21","30","TE2","11","20","1e-20","30","90.2")
+        lPaths = self._makePathListFromTupleList( [ tuple1, tuple2, tuple3 ] )
+        
+        iSet1 = Range( "TE2", 1, 10 )
+        iSet2 = Range( "TE2", 11, 20 )
+        iSet3 = Range( "TE2", 21, 30 )
+        lExp = [ iSet1, iSet2, iSet3 ]
+        
+        lObs = PathUtils.getRangeListFromSubjects( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_getRangeListFromSubjects_initiallyUnordered_reverseStrand( self ):
+        tuple1 = ("1","chr1","1","10","TE2","10","1","1e-20","30","90.2")
+        tuple2 = ("1","chr1","41","50","TE2","30","21","1e-20","30","90.2")
+        tuple3 = ("1","chr1","21","30","TE2","20","11","1e-20","30","90.2")
+        lPaths = self._makePathListFromTupleList( [ tuple1, tuple2, tuple3 ] )
+        
+        iSet3 = Range( "TE2", 30, 21 )
+        iSet2 = Range( "TE2", 20, 11 )
+        iSet1 = Range( "TE2", 10, 1 )
+        lExp = [ iSet1, iSet2, iSet3 ]
+        
+        lObs = PathUtils.getRangeListFromSubjects( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_getQueryMinMaxFromPathList( self ):
+        tuple1 = ("1","chr1","1","10","TE2","11","17","1e-20","30","90.2")
+        tuple2 = ("1","chr1","10","1","TE2","11","17","1e-20","30","90.2")
+        tuple3 = ("1","chr4","12","22","TE3","11","17","1e-20","30","90.2")
+        
+        pathList = self._makePathListFromTupleList([tuple1, tuple2, tuple3])
+        
+        obsTuple = PathUtils.getQueryMinMaxFromPathList( pathList )
+        expTuple = (1,22) 
+        
+        self.assertEquals(expTuple, obsTuple)
+        
+    def test_getQueryMinMaxFromPathList_on_empty_list( self ):
+        obsTuple = PathUtils.getQueryMinMaxFromPathList( [] )
+        expTuple = (-1,-1)
+        self.assertEquals( expTuple, obsTuple )
+        
+    def test_getQueryMinMaxFromPathList_on_list_size1( self ):
+        tuple1 = ("1","chr1","1","10","TE2","11","17","1e-20","30","90.2")
+        path1 = Path()
+        path1.setFromTuple(tuple1)
+        
+        pathList = [path1]
+        obsTuple = PathUtils.getQueryMinMaxFromPathList( pathList )
+        
+        expTuple = (1,10) 
+        
+        self.assertEquals(expTuple, obsTuple)
+        
+    def test_getSubjectMinMaxFromPathList( self ):
+        tuple1 = ("1","chr1","1","10","TE2","11","17","1e-20","30","90.2")
+        tuple2 = ("1","chr1","10","1","TE2","17","11","1e-20","30","90.2")
+        tuple3 = ("1","chr4","12","22","TE3","22","34","1e-20","30","90.2")
+        
+        pathList = self._makePathListFromTupleList([tuple1, tuple2, tuple3])
+        obsTuple = PathUtils.getSubjectMinMaxFromPathList(pathList)
+        
+        expTuple = (11,34) 
+        
+        self.assertEquals(expTuple, obsTuple)
+        
+    def test_getSubjectMinMaxFromPathList_on_empty_list( self ):
+        obsTuple = PathUtils.getSubjectMinMaxFromPathList([])
+        expTuple = (-1,-1)
+        self.assertEquals(expTuple, obsTuple)
+        
+    def test_getSubjectMinMaxFromPathList_on_list_size1( self ):
+        tuple1 = ("1","chr1","1","10","TE2","11","17","1e-20","30","90.2")
+        path1 = Path()
+        path1.setFromTuple(tuple1)
+        
+        pathList = [path1]
+        obsTuple = PathUtils.getSubjectMinMaxFromPathList(pathList)
+        
+        expTuple = (11,17) 
+        
+        self.assertEquals(expTuple, obsTuple)
+        
+    def test_areQueriesOverlappingBetweenPathLists_list2_empty( self ):
+        tuple1 = ("1","chr1","100","110","TE2","15","10","1e-20","30","90.2")
+        tuple2 = ("1","chr1","200","220","TE2","15","10","1e-20","30","90.2")
+        tuple3 = ("1","chr1","300","330","TE2","15","10","1e-20","30","90.2")
+        pathList1 = self._makePathListFromTupleList([tuple1, tuple2, tuple3])
+        
+        pathList2 = []
+        
+        expRes = False
+        obsRes = PathUtils.areQueriesOverlappingBetweenPathLists( pathList1, pathList2 )
+        
+        self.assertEquals( expRes, obsRes )
+        
+    def test_areQueriesOverlappingBetweenPathLists_list2_size1( self ):
+        tuple1 = ("1","chr1","9","11","TE2","150","200","1e-20","30","90.2")
+        tuple2 = ("1","chr1","20","22","TE2","150","200","1e-20","30","90.2")
+        tuple3 = ("1","chr1","30","33","TE2","150","200","1e-20","30","90.2")
+        pathList1 = self._makePathListFromTupleList( [ tuple1, tuple2, tuple3 ] )
+        
+        tuple11 = ("1","chr1","8","11","TE2","150","200","1e-20","30","90.2")
+        pathList2 = self._makePathListFromTupleList( [ tuple11 ] )
+        
+        expRes = True
+        obsRes = PathUtils.areQueriesOverlappingBetweenPathLists( pathList1, pathList2 )
+        
+        self.assertEquals( expRes, obsRes )
+        
+    def test_areQueriesOverlappingBetweenPathLists_list1_greater_list2( self ):
+        tuple1 = ("1","chr1","100","110","TE2","15","10","1e-20","30","90.2")
+        tuple2 = ("1","chr1","200","220","TE2","15","10","1e-20","30","90.2")
+        tuple3 = ("1","chr1","300","330","TE2","15","10","1e-20","30","90.2")
+        pathList1 = self._makePathListFromTupleList( [ tuple1, tuple2, tuple3 ] )
+        
+        tuple11 = ("1","chr1","10","11","TE2","150","200","1e-20","30","90.2")
+        tuple22 = ("1","chr1","20","22","TE2","150","200","1e-20","30","90.2")
+        tuple33 = ("1","chr1","30","33","TE2","150","200","1e-20","30","90.2")
+        pathList2 = self._makePathListFromTupleList( [ tuple11, tuple22, tuple33 ] )
+        
+        expRes = False
+        obsRes = PathUtils.areQueriesOverlappingBetweenPathLists( pathList1, pathList2 )
+        
+        self.assertEquals( expRes, obsRes )
+        
+    def test_areQueriesOverlappingBetweenPathLists_unordered_first_item_of_list1_greater_second_item_smaller( self ):
+        tuple1 = ("1","chr1","400","440","TE2","15","10","1e-20","30","90.2")
+        tuple2 = ("1","chr1","1","11","TE2","15","10","1e-20","30","90.2")
+        pathList1 = self._makePathListFromTupleList( [ tuple1, tuple2 ] )
+        
+        tuple11 = ("1","chr1","15","17","TE2","150","200","1e-20","30","90.2")
+        tuple22 = ("1","chr1","20","22","TE2","150","200","1e-20","30","90.2")
+        tuple33 = ("1","chr1","30","33","TE2","150","200","1e-20","30","90.2")
+        pathList2 = self._makePathListFromTupleList( [ tuple11, tuple22, tuple33 ] )
+        
+        expRes = False
+        obsRes = PathUtils.areQueriesOverlappingBetweenPathLists( pathList1, pathList2 )
+        
+        self.assertEquals( expRes, obsRes )
+        
+    def test_areQueriesOverlappingBetweenPathLists_unorderd_second_item_of_list1_overlap_first_item( self ):
+        tuple1 = ("1","chr1","400","440","TE2","15","10","1e-20","30","90.2")
+        tuple2 = ("1","chr1","1","18","TE2","15","10","1e-20","30","90.2")
+        pathList1 = self._makePathListFromTupleList( [ tuple1, tuple2 ] )
+        
+        tuple11 = ("1","chr1","15","17","TE2","150","200","1e-20","30","90.2")
+        tuple22 = ("1","chr1","20","22","TE2","150","200","1e-20","30","90.2")
+        tuple33 = ("1","chr1","30","33","TE2","150","200","1e-20","30","90.2")
+        pathList2 = self._makePathListFromTupleList( [ tuple11, tuple22, tuple33 ] )
+        
+        expRes = True
+        obsRes = PathUtils.areQueriesOverlappingBetweenPathLists( pathList1, pathList2 )
+        
+        self.assertEquals( expRes, obsRes )
+        
+    def test_areQueriesOverlappingBetweenPathLists_last_item_list1_overlap_last_item_list2( self ):
+        tuple1 = ("1","chr1","400","440","TE2","15","10","1e-20","30","90.2")
+        tuple2 = ("1","chr1","320","340","TE2","15","10","1e-20","30","90.2")
+        pathList1 = self._makePathListFromTupleList( [ tuple1, tuple2 ] )
+        
+        tuple11 = ("1","chr1","100","110","TE2","150","200","1e-20","30","90.2")
+        tuple22 = ("1","chr1","200","220","TE2","150","200","1e-20","30","90.2")
+        tuple33 = ("1","chr1","300","330","TE2","150","200","1e-20","30","90.2")
+        pathList2 = self._makePathListFromTupleList( [ tuple11, tuple22, tuple33 ] )
+        
+        expRes = True
+        obsRes = PathUtils.areQueriesOverlappingBetweenPathLists( pathList1, pathList2 )
+        
+        self.assertEquals( expRes, obsRes )
+        
+    def test_writeListInFile( self ):
+        line1 = ("1\tchr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        line2 = ("1\tchr1\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        line3 = ("1\tchr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        
+        expFileName = "expFileName.path"
+        expFileHandle = open ( expFileName, 'w' )
+        expFileHandle.write(line1)
+        expFileHandle.write(line2)
+        expFileHandle.write(line3)
+        expFileHandle.close()
+        
+        line1 = ("1\tchr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        line2 = ("1\tchr1\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        line3 = ("1\tchr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        
+        obsFileName = "obsFileName.path"
+        obsPathList = self._makePathListFromStringList( [ line1, line2, line3 ] )
+        
+        PathUtils.writeListInFile( obsPathList, obsFileName )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        
+        os.remove( obsFileName )
+        os.remove( expFileName )
+
+    def test_writeListInFile_in_append_mode( self ):
+        line1 = ("1\tchr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        line2 = ("1\tchr1\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        line3 = ("1\tchr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        line4 = ("1\tchr1\t400\t410\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        line5 = ("1\tchr1\t500\t520\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        line6 = ("1\tchr1\t600\t630\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        
+        expFileName = "expFileName.path"
+        expFileHandle = open ( expFileName, 'w' )
+        expFileHandle.write(line1)
+        expFileHandle.write(line2)
+        expFileHandle.write(line3)
+        expFileHandle.write(line4)
+        expFileHandle.write(line5)
+        expFileHandle.write(line6)
+        expFileHandle.close()
+        
+        line1 = ("1\tchr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        line2 = ("1\tchr1\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        line3 = ("1\tchr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.200000\n")
+        line4 = ("1\tchr1\t400\t410\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        line5 = ("1\tchr1\t500\t520\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        line6 = ("1\tchr1\t600\t630\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        
+        obsFileName = "obsFileName.path"
+        obsFileHandle = open( obsFileName, 'w' )
+        obsFileHandle.write(line1)
+        obsFileHandle.write(line2)
+        obsFileHandle.write(line3)
+        obsFileHandle.close()
+      
+        obsPathList = self._makePathListFromStringList( [ line4, line5, line6 ] )
+
+        PathUtils.writeListInFile( obsPathList, obsFileName, "a" )
+
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+
+        os.remove(obsFileName)
+        os.remove(expFileName)
+
+    def test_getPathListWithoutDuplicates_empty_list( self ):
+        pathList = []
+        obsPathList = PathUtils.getPathListWithoutDuplicates( pathList )
+        
+        expPathList = []
+        
+        self.assertEquals( expPathList, obsPathList )
+        
+    def test_getPathListWithoutDuplicates_list_size1( self ):
+        line1 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathList = self._makePathListFromStringList([line1])
+        
+        obsPathList = PathUtils.getPathListWithoutDuplicates( pathList )
+        
+        expPathList = pathList
+        
+        self.assertEquals( expPathList, obsPathList )
+        
+    def test_getPathListWithoutDuplicates_list_with_only_doublons( self ):
+        line1 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line2 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line3 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line4 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathList = self._makePathListFromStringList( [ line1, line2, line3, line4 ] )
+        
+        obsPathList = PathUtils.getPathListWithoutDuplicates( pathList )
+        
+        expPathList = self._makePathListFromStringList( [ line1 ] )
+        
+        self.assertEquals( expPathList, obsPathList )
+        
+    def test_getPathListWithoutDuplicates_list_with_doublons_at_start_and_at_end( self ):
+        line1 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line2 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line3 = ("1\tchr1\t300\t310\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line4 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathList = self._makePathListFromStringList( [ line1, line2, line3, line4 ] )
+        
+        obsPathList = PathUtils.getPathListWithoutDuplicates( pathList )
+        
+        expPathList = self._makePathListFromStringList( [ line1, line2, line3 ] )
+        expPathList = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( expPathList )
+        
+        self.assertEquals( expPathList, obsPathList )
+        
+    def test_getPathListWithoutDuplicates_list_with_contiguus_doublons( self ):
+        line1 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line2 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line3 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line4 = ("1\tchr1\t300\t310\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathList = self._makePathListFromStringList( [ line1, line2, line3, line4 ] )
+        
+        obsPathList = PathUtils.getPathListWithoutDuplicates( pathList )
+        
+        expPathList = self._makePathListFromStringList( [ line1, line2, line4 ] )
+        expPathList = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( expPathList )
+        
+        self.assertEquals( expPathList, obsPathList )
+        
+    def test_getPathListWithoutDuplicates_list_with_one_doublon( self ):
+        line1 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line2 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line3 = ("1\tchr1\t210\t250\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line4 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line5 = ("1\tchr1\t300\t310\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathList = self._makePathListFromStringList( [ line1, line2, line3, line4, line5 ] )
+        
+        obsPathList = PathUtils.getPathListWithoutDuplicates( pathList )
+        
+        expPathList = self._makePathListFromStringList( [ line1, line2, line3, line5 ] )
+        expPathList = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( expPathList )
+        
+        self.assertEquals( expPathList, obsPathList )
+        
+    def test_getPathListWithoutDuplicates_list_with_two_doublons( self ):
+        line1 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line2 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line3 = ("1\tchr1\t210\t250\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line4 = ("1\tchr1\t230\t250\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line5 = ("1\tchr1\t210\t250\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line6 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line7 = ("1\tchr1\t300\t310\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathList = self._makePathListFromStringList( [ line1, line2, line3, line4, line5, line6, line7 ] )
+        
+        obsPathList = PathUtils.getPathListWithoutDuplicates( pathList )
+        
+        expPathList = self._makePathListFromStringList( [ line1, line2, line3, line4, line7 ] )
+        expPathList = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( expPathList )
+        
+        self.assertEquals( expPathList, obsPathList )
+        
+    def test_getPathListWithoutDuplicates_list_with_two_doublons_useOnlyCoord_is_False_different_id( self ):
+        line1 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line2 = ("2\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line3 = ("3\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line4 = ("4\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line5 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line6 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line7 = ("5\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathList = self._makePathListFromStringList( [ line1, line2, line3, line4, line5, line6, line7 ] )
+        
+        obsPathList = PathUtils.getPathListWithoutDuplicates( pathList )
+        
+        expPathList = self._makePathListFromStringList( [ line1, line2, line3, line4, line7 ] )
+        expPathList = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( expPathList )
+        
+        self.assertEquals( expPathList, obsPathList )
+        
+    def test_getPathListWithoutDuplicates_list_with_two_doublons_useOnlyCoord_is_True_different_id( self ):
+        line1 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line2 = ("2\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line3 = ("3\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line4 = ("4\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line5 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line6 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line7 = ("5\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathList = self._makePathListFromStringList( [ line1, line2, line3, line4, line5, line6, line7 ] )
+        
+        obsPathList = PathUtils.getPathListWithoutDuplicates( pathList, True )
+        
+        expPathList = self._makePathListFromStringList( [ line1 ] )
+        expPathList = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( expPathList )
+        
+        self.assertEquals( expPathList, obsPathList )
+        
+    def test_path_getDictOfListsWithIdAsKey_empty_list( self ):
+        pathList = []
+      
+        obsDict = PathUtils.getDictOfListsWithIdAsKey( pathList )
+        expDict = {}
+      
+        self.assertEquals( expDict, obsDict )
+        
+    def test_path_getDictOfListsWithIdAsKey_list_size1( self ):
+        line1 = ( "1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        pathList = self._makePathListFromStringList( [ line1 ] )
+        
+        obsDict = PathUtils.getDictOfListsWithIdAsKey( pathList )
+        
+        expPathInstance = Path()
+        expPathInstance.setFromString( line1 )
+        expDict = { 1: [ expPathInstance ] }
+        
+        self.assertEquals( expDict, obsDict )
+        
+    def test_getDictOfListsWithIdAsKey_ids_only_once( self ):
+        line1 = ( "1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        line2 = ( "2\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        line3 = ( "3\tchr1\t210\t250\tTE2\t150\t200\t0.000000\t30\t90.200000\n" ) 
+        
+        pathList = self._makePathListFromStringList( [ line1, line2, line3 ] )
+        
+        obsDict = PathUtils.getDictOfListsWithIdAsKey( pathList )
+        
+        expPathInstance1 = Path()
+        expPathInstance1.setFromString( line1 )
+        
+        expPathInstance2 = Path()
+        expPathInstance2.setFromString( line2 )
+        
+        expPathInstance3 = Path()
+        expPathInstance3.setFromString( line3 )
+        
+        expDict = { 1: [ expPathInstance1 ], 2: [ expPathInstance2 ], 3: [ expPathInstance3 ] }
+        
+        self.assertEquals( expDict, obsDict )
+        
+    def test_getDictOfListsWithIdAsKey_ids_more_than_only_once( self ):
+        line1 = ( "1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        line2 = ( "2\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        line3 = ( "3\tchr1\t210\t250\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        
+        line4 = ( "1\tchr1\t100\t120\tTE2\t150\t200\t0.000000\t30\t90.200000\n" ) 
+        line5 = ( "2\tchr1\t200\t220\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        line6 = ( "3\tchr1\t210\t260\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        
+        line7 = ( "1\tchr1\t110\t120\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        line8 = ( "2\tchr1\t210\t220\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        line9 = ( "3\tchr1\t220\t260\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        
+        pathList = self._makePathListFromStringList( [ line1, line2, line3, line4, line5, line6, line7, line8, line9 ] )
+        
+        obsDict = PathUtils.getDictOfListsWithIdAsKey( pathList )
+        
+        expPathInstance1 = Path()
+        expPathInstance1.setFromString( line1 )
+        
+        expPathInstance2 = Path()
+        expPathInstance2.setFromString( line2 )
+        
+        expPathInstance3 = Path()
+        expPathInstance3.setFromString( line3 )
+        
+        expPathInstance4 = Path()
+        expPathInstance4.setFromString( line4 )
+        
+        expPathInstance5 = Path()
+        expPathInstance5.setFromString( line5 )
+        
+        expPathInstance6 = Path()
+        expPathInstance6.setFromString( line6 )
+        
+        expPathInstance7 = Path()
+        expPathInstance7.setFromString( line7 )
+        
+        expPathInstance8 = Path()
+        expPathInstance8.setFromString( line8 )
+        
+        expPathInstance9 = Path()
+        expPathInstance9.setFromString( line9 )
+        
+        expDict = { 1: [ expPathInstance1, expPathInstance4, expPathInstance7 ], 2 :[ expPathInstance2, expPathInstance5, expPathInstance8 ], 3: [ expPathInstance3, expPathInstance6, expPathInstance9 ] }
+        
+        self.assertEquals( expDict, obsDict )
+        
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_empty_listToUnjoin_empty( self ):
+        pathListToKeep = []
+        pathListToUnjoin = []
+        
+        expList = []
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        self.assertEquals( expList, obsList )
+        
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_empty_listToUnjoin_size1( self ):
+        pathListToKeep = []
+        
+        line1 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToUnjoin = self._makePathListFromStringList( [ line1 ] ) 
+        
+        expList = [ pathListToUnjoin ]
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        self.assertEquals( expList, obsList )
+        
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_size1_listToUnjoin_empty( self ):
+        lineKeep1 = ("1\tchr1\t1\t11\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToKeep = self._makePathListFromStringList( [ lineKeep1 ] )
+        
+        pathListToUnjoin = []
+        
+        expList = []
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        self.assertEquals( expList, obsList )
+        
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_empty( self ):
+        pathListToKeep = []
+        
+        line1 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line2 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line3 = ("1\tchr1\t250\t280\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToUnjoin = self._makePathListFromStringList( [ line1, line2, line3 ] )
+        
+        expList = [ pathListToUnjoin ]
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        self.assertEquals( expList, obsList )
+        
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_size1_listToUnjoin_size1( self ):
+        lineKeep1 = ("1\tchr1\t1\t11\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToKeep = self._makePathListFromStringList( [ lineKeep1 ] )
+        
+        lineUnjoin1 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToUnjoin = self._makePathListFromStringList( [ lineUnjoin1 ] )
+        
+        expList = [ pathListToUnjoin ]
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        self.assertEquals( expList, obsList )
+        
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_size1_listToUnjoin_size2_noSplit_minKeep( self ):
+        lineKeep1 = ("1\tchr1\t1\t10\tTE2\t150\t90\t0.000000\t30\t90.200000\n")
+        pathListToKeep = self._makePathListFromStringList( [ lineKeep1 ] )
+        
+        lineUnjoin1 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineUnjoin2 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToUnjoin = self._makePathListFromStringList( [ lineUnjoin1, lineUnjoin2 ] )
+        
+        expList = [ pathListToUnjoin ]
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        self.assertEquals( expList, obsList )
+        
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_size1_listToUnjoin_size3_noSplit_minKeep( self ):
+        lineKeep1 = ("1\tchr1\t1\t10\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToKeep = self._makePathListFromStringList( [ lineKeep1 ] )
+        
+        lineUnjoin1 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineUnjoin2 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineUnjoin3 = ("1\tchr1\t250\t280\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToUnjoin = self._makePathListFromStringList( [ lineUnjoin1, lineUnjoin2, lineUnjoin3 ] )
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        expList = [ pathListToUnjoin ]
+        
+        self.assertEquals( expList, obsList )
+        
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_size1_listToUnjoin_size2_noSplit_minUnjoin( self ):
+        lineKeep1 = ("1\tchr1\t101\t150\tTE2\t150\t90\t0.000000\t30\t90.200000\n")
+        pathListToKeep = self._makePathListFromStringList( [ lineKeep1 ] )
+        
+        lineUnjoin1 = ("1\tchr1\t1\t10\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineUnjoin2 = ("1\tchr1\t21\t40\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToUnjoin = self._makePathListFromStringList( [ lineUnjoin1, lineUnjoin2 ] )
+        
+        expList = [ pathListToUnjoin ]
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        self.assertEquals( expList, obsList )
+        
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_size3_listToUnjoin_size2_oneSplit_minKeep( self ):
+        lineKeep1 = ("1\tchr1\t1\t10\tTE2\t150\t90\t0.000000\t30\t90.200000\n")
+        lineKeep2 = ("1\tchr1\t21\t30\tTE2\t150\t90\t0.000000\t30\t90.200000\n")
+        lineKeep3 = ("1\tchr1\t61\t70\tTE2\t150\t90\t0.000000\t30\t90.200000\n")
+        pathListToKeep = self._makePathListFromStringList( [ lineKeep1, lineKeep2, lineKeep3 ] )
+        
+        lineUnjoin1 = ("1\tchr1\t41\t50\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineUnjoin2 = ("1\tchr1\t81\t90\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToUnjoin = self._makePathListFromStringList( [ lineUnjoin1, lineUnjoin2 ] )
+        
+        expList = []
+        expList.append( self._makePathListFromStringList( [ lineUnjoin1 ] ) )
+        expList.append( self._makePathListFromStringList( [ lineUnjoin2 ] ) )
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        self.assertEquals( expList, obsList )
+        
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_size3_listToUnjoin_size3_twoSplits_minUnjoin( self ):
+        lineKeep1 = ("1\tchr1\t21\t30\tTE2\t150\t90\t0.000000\t30\t90.200000\n")
+        lineKeep2 = ("1\tchr1\t41\t50\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineKeep3 = ("1\tchr1\t81\t90\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToKeep = self._makePathListFromStringList( [ lineKeep1, lineKeep2, lineKeep3 ] )
+        
+        lineUnjoin1 = ("1\tchr1\t1\t10\tTE2\t150\t90\t0.000000\t30\t90.200000\n")
+        lineUnjoin2 = ("1\tchr1\t61\t70\tTE2\t150\t90\t0.000000\t30\t90.200000\n")
+        lineUnjoin3 = ("1\tchr1\t101\t110\tTE2\t150\t90\t0.000000\t30\t90.200000\n")
+        pathListToUnjoin = self._makePathListFromStringList( [ lineUnjoin1, lineUnjoin2, lineUnjoin3 ] )
+        
+        expList = []
+        expList.append( self._makePathListFromStringList( [ lineUnjoin1 ] ) )
+        expList.append( self._makePathListFromStringList( [ lineUnjoin2 ] ) )
+        expList.append( self._makePathListFromStringList( [ lineUnjoin3 ] ) )
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        self.assertEquals( expList, obsList )
+        
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_size1_listToUnjoin_size2_split( self ):
+        lineKeep1 = ("1\tchr1\t51\t80\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToKeep = self._makePathListFromStringList( [ lineKeep1 ] )
+        
+        lineUnjoin1 = ("1\tchr1\t21\t40\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineUnjoin2 = ("1\tchr1\t101\t150\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToUnjoin = self._makePathListFromStringList( [ lineUnjoin1, lineUnjoin2 ] )
+        
+        expList = []
+        expList.append( self._makePathListFromStringList( [ lineUnjoin1 ] ) )
+        expList.append( self._makePathListFromStringList( [ lineUnjoin2 ] ) )
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        self.assertEquals( expList, obsList )
+        
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_size2_listToUnjoin_size2_split( self ):
+        lineKeep1 = ("1\tchr1\t1\t15\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineKeep2 = ("1\tchr1\t81\t130\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToKeep = self._makePathListFromStringList( [ lineKeep1, lineKeep2 ] )
+        
+        lineUnjoin1 = ("1\tchr1\t21\t40\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineUnjoin2 = ("1\tchr1\t201\t250\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToUnjoin = self._makePathListFromStringList( [ lineUnjoin1, lineUnjoin2 ] )
+        
+        expList = []
+        expList.append( self._makePathListFromStringList( [ lineUnjoin1 ] ) )
+        expList.append( self._makePathListFromStringList( [ lineUnjoin2 ] ) )
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        self.assertEquals( expList, obsList )
+        
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_size1_listToUnjoin_ordered_OneSplit( self ):
+        lineKeep1 = ("1\tchr1\t120\t180\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToKeep = self._makePathListFromStringList( [ lineKeep1 ] )
+        
+        lineUnjoin1 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineUnjoin2 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineUnjoin3 = ("1\tchr1\t250\t280\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToUnjoin = self._makePathListFromStringList( [ lineUnjoin1, lineUnjoin2, lineUnjoin3 ] )
+        
+        expList = []
+        expList.append( self._makePathListFromStringList( [ lineUnjoin1 ] ) )
+        expList.append( self._makePathListFromStringList( [ lineUnjoin2, lineUnjoin3 ] ) )
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        self.assertEquals( expList, obsList )
+        
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_size1_listToUnjoin_unordered_OneSplit( self ):
+        lineKeep1 = ("1\tchr1\t120\t180\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToKeep = self._makePathListFromStringList( [ lineKeep1 ] )
+        
+        lineUnjoin1 = ("1\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineUnjoin2 = ("1\tchr1\t250\t280\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineUnjoin3 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToUnjoin = self._makePathListFromStringList( [ lineUnjoin1, lineUnjoin2, lineUnjoin3 ] )
+        
+        expList = []
+        expList.append( self._makePathListFromStringList( [ lineUnjoin3 ] ) )
+        expList.append( self._makePathListFromStringList( [ lineUnjoin1, lineUnjoin2 ] ) )
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        self.assertEquals( expList, obsList )
+
+    def test_getPathListUnjoinedBasedOnQuery_listToKeep_size2_listToUnjoin_size4_twoSplits( self ):
+        lineKeep1 = ("1\tchr1\t21\t30\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineKeep2 = ("1\tchr1\t81\t90\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToKeep = self._makePathListFromStringList( [ lineKeep1, lineKeep2 ] )
+        
+        lineUnjoin1 = ("1\tchr1\t1\t10\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineUnjoin2 = ("1\tchr1\t41\t50\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineUnjoin3 = ("1\tchr1\t61\t70\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        lineUnjoin4 = ("1\tchr1\t101\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        pathListToUnjoin = self._makePathListFromStringList( [ lineUnjoin1, lineUnjoin2, lineUnjoin3, lineUnjoin4 ] )
+        
+        expList = []
+        expList.append( self._makePathListFromStringList( [ lineUnjoin1 ] ) )
+        expList.append( self._makePathListFromStringList( [ lineUnjoin2, lineUnjoin3 ] ) )
+        expList.append( self._makePathListFromStringList( [ lineUnjoin4 ] ) )
+        
+        obsList = PathUtils.getPathListUnjoinedBasedOnQuery( pathListToKeep, pathListToUnjoin )
+        
+        self.assertEquals( expList, obsList )
+
+    def test_changeIdInList_empty_list ( self ):
+        pathList = []
+        
+        PathUtils.changeIdInList(pathList,1)
+        
+        obsList = pathList
+        expList = []
+        
+        self.assertEquals(expList, obsList)
+        
+    def test_changeIdInList_list_size1 ( self ):
+        line1 = ("1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        line2 = ("2\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n")
+        
+        pathList = self._makePathListFromStringList([line1]) 
+        PathUtils.changeIdInList(pathList,2)
+        
+        expPathList = pathList   
+        
+        obsPathList = self._makePathListFromStringList([line2])  
+        
+        self.assertEquals(expPathList, obsPathList)
+        
+    def test_changeIdInList( self ):
+        line1 = ( "1\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        line2 = ( "2\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        line3 = ( "3\tchr1\t300\t310\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        
+        pathList = self._makePathListFromStringList( [ line1, line2, line3 ] ) 
+        PathUtils.changeIdInList( pathList, 2 )
+        obsPathList = pathList
+        
+        line11 = ( "2\tchr1\t100\t110\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        line22 = ( "2\tchr1\t200\t210\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        line33 = ( "2\tchr1\t300\t310\tTE2\t150\t200\t0.000000\t30\t90.200000\n" )
+        
+        expPathList = self._makePathListFromStringList( [ line11, line22, line33 ] )
+        
+        self.assertEquals( expPathList, obsPathList )
+        
+        
+    def test_getIdentityFromPathList( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "0.0", "239", "90.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "121", "350", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        lPaths = [ p1, p2 ]
+        exp = ( 90.0 * ( 100-1+1) + 91.2 * (350-121+1) ) / ( (100-1+1) + (350-121+1) )   # 90.836363636363643
+        obs = PathUtils.getIdentityFromPathList( lPaths )
+        self.assertEqual( exp, obs )
+        
+        
+    def test_getIdentityFromPathList_withOverlap( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "0.0", "239", "90.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "21", "80", "sbj1", "21", "80", "0.0", "176", "91.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "2", "qry1", "121", "350", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        lPaths = [ p1, p2, p3 ]
+        exp = ( 91.2 * ( 100-1+1) + 91.2 * (350-121+1) ) / ( (100-1+1) + (350-121+1) )
+        obs = PathUtils.getIdentityFromPathList( lPaths )
+        self.assertEqual( exp, obs )
+        
+        
+    def test_getIdentityFromPathList_diffQueries( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "0.0", "239", "90.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry2", "121", "350", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        lPaths = [ p1, p2 ]
+        try:
+            obs = PathUtils.getIdentityFromPathList( lPaths )
+        except:
+            pass
+        
+        
+    def test_getIdentityFromPathList_diffSubjects_check( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "0.0", "239", "90.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "1", "qry1", "121", "350", "sbj2", "101", "200", "0.0", "176", "91.2" ) )
+        lPaths = [ p1, p2 ]
+        try:
+            obs = PathUtils.getIdentityFromPathList( lPaths, True )
+        except:
+            pass
+        
+        
+    def test_getIdentityFromPathList_diffSubjects_noCheck( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "0.0", "239", "90.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "1", "qry1", "121", "350", "sbj2", "101", "200", "0.0", "176", "91.2" ) )
+        lPaths = [ p1, p2 ]
+        exp = ( 90.0 * ( 100-1+1) + 91.2 * (350-121+1) ) / ( (100-1+1) + (350-121+1) )   # 90.836363636363643
+        obs = PathUtils.getIdentityFromPathList( lPaths, False )
+        self.assertEqual( exp, obs )
+        
+        
+    def test_getPathListSortedByIncreasingMinQueryThenMaxQuery_alreadyOrdered_diffIdentifier( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "1", "10", "sbj1", "1", "100", "0.0", "239", "90.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "21", "30", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        lPaths = [ p1, p2 ]
+        
+        expList = [ p1, p2 ]
+        
+        obsList = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( lPaths )
+        
+        self.assertEqual( expList, obsList )
+        
+    def test_getPathListSortedByIncreasingMinQueryThenMaxQuery_unordered_diffIdentifier( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "2", "qry1", "21", "30", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "1", "qry1", "1", "10", "sbj1", "1", "100", "0.0", "239", "90.0" ) )
+        lPaths = [ p1, p2 ]
+        
+        expList = [ p2, p1 ]
+        
+        obsList = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( lPaths )
+        
+        self.assertEqual( expList, obsList )
+        
+    def test_getPathListSortedByIncreasingMinQueryThenMaxQuery_unordered_sameIdentifier( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "21", "30", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "1", "qry1", "1", "10", "sbj1", "1", "100", "0.0", "239", "90.0" ) )
+        lPaths = [ p1, p2 ]
+        
+        expList = [ p2, p1 ]
+        
+        obsList = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( lPaths )
+        
+        self.assertEqual( expList, obsList )
+        
+    def test_getPathListSortedByIncreasingMinQueryThenMaxQuery_unordered_overlapping( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "6", "15", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "1", "10", "sbj1", "1", "100", "0.0", "239", "90.0" ) )
+        lPaths = [ p1, p2 ]
+        
+        expList = [ p2, p1 ]
+        
+        obsList = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( lPaths )
+        
+        self.assertEqual( expList, obsList )
+        
+    def test_getPathListSortedByIncreasingMinQueryThenMaxQuery_unordered_sameMin_threeSets( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "1", "15", "sbj1", "1", "100", "0.0", "239", "90.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "1", "10", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "2", "qry1", "1", "12", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        lPaths = [ p1, p2, p3 ]
+        
+        expList = [ p2, p3, p1 ]
+        
+        obsList = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( lPaths )
+        
+        self.assertEqual( expList, obsList )
+        
+    def test_getPathListSortedByIncreasingMinQueryThenMaxQuery_unordered_included( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "2", "4", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "1", "5", "sbj1", "1", "100", "0.0", "239", "90.0" ) )
+        lPaths = [ p1, p2 ]
+        
+        expList = [ p2, p1 ]
+        
+        obsList = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( lPaths )
+        
+        self.assertEqual( expList, obsList )
+        
+    def test_getPathListSortedByIncreasingMinQueryThenMaxQueryThenIdentifier_sameCoord_diffId( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "1", "5", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "1", "5", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        lPaths = [ p2, p1 ]
+        
+        expList = [ p1, p2 ]
+        
+        obsList = PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQueryThenIdentifier( lPaths )
+        
+        self.assertEqual( expList, obsList )
+        
+    def test_getListOfDistinctIdentifiers( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "0.0", "239", "90.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "121", "350", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "2", "qry1", "121", "350", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        lPaths = [ p1, p2, p3 ]
+        lExp = [ 1, 2 ]
+        lObs = PathUtils.getListOfDistinctIdentifiers( lPaths )
+        lExp.sort()
+        lObs.sort()
+        self.assertEqual( lObs, lExp )
+        
+    def test_getListOfDistinctQueryNames( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "0.0", "239", "90.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry2", "121", "350", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "2", "qry2", "121", "350", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        lPaths = [ p1, p2, p3 ]
+        lExp = [ "qry1", "qry2" ]
+        lObs = PathUtils.getListOfDistinctQueryNames( lPaths )
+        lExp.sort()
+        lObs.sort()
+        self.assertEqual( lObs, lExp )
+        
+    def test_getListOfDistinctSubjectNames( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "0.0", "239", "90.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry2", "121", "350", "sbj1", "101", "200", "0.0", "176", "91.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "2", "qry2", "121", "350", "sbj2", "101", "200", "0.0", "176", "91.2" ) )
+        lPaths = [ p1, p2, p3 ]
+        lExp = [ "sbj1", "sbj2" ]
+        lObs = PathUtils.getListOfDistinctSubjectNames( lPaths )
+        lExp.sort()
+        lObs.sort()
+        self.assertEqual( lObs, lExp )
+        
+    def test_getListOfJoinCoordinatesOnQuery_returnCoord( self ):
+        p1a = Path()
+        p1a.setFromTuple( ( "1", "qry1", "1", "500", "sbj1", "1", "500", "0.0", "532", "95.0" ) )
+        p1b = Path()
+        p1b.setFromTuple( ( "1", "qry1", "701", "900", "sbj1", "501", "700", "0.0", "232", "95.3" ) )
+        lExp = [ [ 501, 700 ] ]
+        lPaths = [ p1a, p1b ]
+        lObs = PathUtils.getListOfJoinCoordinatesOnQuery( lPaths )
+        lExp.sort()
+        lObs.sort()
+        self.assertEqual( lObs, lExp )
+        
+    def test_getListOfJoinCoordinatesOnQuery_overlap( self ):
+        p1a = Path()
+        p1a.setFromTuple( ( "1", "qry1", "1", "500", "sbj1", "1", "500", "0.0", "532", "95.0" ) )
+        p1b = Path()
+        p1b.setFromTuple( ( "1", "qry1", "491", "900", "sbj1", "501", "770", "0.0", "232", "95.3" ) )
+        lExp = []
+        lPaths = [ p1a, p1b ]
+        minLength = 100
+        lObs = PathUtils.getListOfJoinCoordinatesOnQuery( lPaths, minLength )
+        lExp.sort()
+        lObs.sort()
+        self.assertEqual( lObs, lExp )
+        
+    def test_getListOfJoinCoordinates_tooShort( self ):
+        p1a = Path()
+        p1a.setFromTuple( ( "1", "qry1", "1", "500", "sbj1", "1", "500", "0.0", "532", "95.0" ) )
+        p1b = Path()
+        p1b.setFromTuple( ( "1", "qry1", "551", "900", "sbj1", "501", "750", "0.0", "232", "95.3" ) )
+        lExp = []
+        lPaths = [ p1a, p1b ]
+        minLength = 100
+        lObs = PathUtils.getListOfJoinCoordinatesOnQuery( lPaths, minLength )
+        lExp.sort()
+        lObs.sort()
+        self.assertEqual( lObs, lExp )
+        
+    def test_getLengthOnQueryFromPathList( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "1", "70", "sbj1", "1", "70", "0.0", "132", "95.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "51", "90", "sbj2", "40", "1", "0.0", "132", "95.0" ) )
+        lPaths = [ p1, p2 ]
+        exp = 90
+        obs = PathUtils.getLengthOnQueryFromPathList( lPaths )
+        self.assertEqual( obs, exp )
+        
+    def test_convertPathFileIntoAlignFile( self ):
+        pathFile = "dummyPathFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        pathFileHandler = open( pathFile, "w" )
+        pathFileHandler.write( "3\tchr2\t250\t151\tseq5\t1\t100\t1e-31\t147\t98.3\n" )
+        pathFileHandler.close()
+        
+        expFile = "dummyExpFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "chr2\t151\t250\tseq5\t100\t1\t1e-31\t147\t98.300000\n" )
+        expFileHandler.close()
+        
+        obsFile = "dummyObsFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        
+        PathUtils.convertPathFileIntoAlignFile( pathFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ pathFile, expFile, obsFile ]:
+            if os.path.exists( f ):
+                os.remove ( f )
+                
+    def test_convertPathFileIntoMapFileWithQueryCoordsOnly( self ):
+        pathFile = "dummyPathFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        pathFileHandler = open( pathFile, "w" )
+        pathFileHandler.write( "3\tchr2\t250\t151\tseq5\t1\t100\t1e-31\t147\t98.3\n" )
+        pathFileHandler.write( "4\tchr2\t191\t230\tseq8\t237\t387\t1e-11\t187\t95.3\n" )
+        pathFileHandler.write( "3\tchr2\t500\t301\tseq5\t101\t300\t1e-81\t247\t96.2\n" )
+        pathFileHandler.close()
+        
+        expFile = "dummyExpFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "seq5\tchr2\t250\t151\n" )
+        expFileHandler.write( "seq8\tchr2\t191\t230\n" )
+        expFileHandler.write( "seq5\tchr2\t500\t301\n" )
+        expFileHandler.close()
+        
+        obsFile = "dummyObsFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        
+        PathUtils.convertPathFileIntoMapFileWithQueryCoordsOnly( pathFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ pathFile, expFile, obsFile ]:
+            if os.path.exists( f ):
+                os.remove( f )
+                
+                
+    def test_mergeMatchesOnQueries( self ):
+        pathFile = "dummyPathFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        pathFileHandler = open( pathFile, "w" )
+        pathFileHandler.write( "3\tchr2\t250\t151\tseq5\t1\t100\t1e-31\t147\t98.3\n" )
+        pathFileHandler.write( "4\tchr2\t230\t191\tseq8\t237\t387\t1e-11\t187\t95.3\n" )
+        pathFileHandler.write( "3\tchr2\t500\t301\tseq5\t101\t300\t1e-81\t247\t96.2\n" )
+        pathFileHandler.close()
+        
+        expFile = "dummyExpFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "0\tchr2\t151\t250\tseq5\t0\t0\t0.0\t0\t0\n" )
+        expFileHandler.write( "0\tchr2\t301\t500\tseq5\t0\t0\t0.0\t0\t0\n" )
+        expFileHandler.close()
+        
+        obsFile = "dummyObsFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        
+        PathUtils.mergeMatchesOnQueries( pathFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ pathFile, expFile, obsFile ]:
+            if os.path.exists( f ):
+                os.remove( f )
+                
+                
+    def test_filterPathListOnChainLength( self ):
+        p1a = Path()
+        p1a.setFromTuple( ( "1", "qry1", "1", "12", "sbj1", "1", "12", "0.0", "132", "95.0" ) )
+        p1b = Path()
+        p1b.setFromTuple( ( "1", "qry1", "15", "30", "sbj1", "13", "28", "0.0", "132", "95.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "51", "90", "sbj2", "40", "1", "0.0", "132", "95.0" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry2", "1", "12", "sbj3", "15", "1", "0.0", "132", "95.0" ) )
+        lPaths = [ p1a, p1b, p2, p3 ]
+        lExp = [ p1a, p1b, p2 ]
+        lObs = PathUtils.filterPathListOnChainLength( lPaths, 20 )
+        self.assertEqual( lExp, lObs )
+        
+    def test_getPathListFromFile(self):
+        file = "dummyFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        fileHandler = open( file, "w" )
+        fileHandler.write( "1\tchr2\t151\t250\tseq5\t0\t0\t0.0\t0\t0\n" )
+        fileHandler.write( "2\tchr2\t301\t500\tseq5\t0\t0\t0.0\t0\t0\n" )
+        fileHandler.close()
+        p1 = Path()
+        p1.setFromTuple( ( "1", "chr2", "151", "250", "seq5", "0", "0", "0.0", "0", "0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "chr2", "301", "500", "seq5", "0", "0", "0.0", "0", "0" ) )
+        expLPath = [ p1, p2 ]
+        obsLPath = PathUtils.getPathListFromFile(file)
+        expLPathSorted = PathUtils.getPathListSortedByIncreasingQueryMinThenInvQueryLength(expLPath)
+        obsLPathSorted = PathUtils.getPathListSortedByIncreasingQueryMinThenInvQueryLength(obsLPath)
+        os.remove(file)
+        self.assertEqual( expLPathSorted, obsLPathSorted )
+        
+    def test_getPathListFromFile_empty_file(self):
+        file = "dummyFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        fileHandler = open( file, "w" )
+        fileHandler.close()
+        expLPath = []
+        obsLPath = PathUtils.getPathListFromFile(file)
+        expLPathSorted = PathUtils.getPathListSortedByIncreasingQueryMinThenInvQueryLength(expLPath)
+        obsLPathSorted = PathUtils.getPathListSortedByIncreasingQueryMinThenInvQueryLength(obsLPath)
+        os.remove(file)
+        self.assertEqual( expLPathSorted, obsLPathSorted )
+        
+    def test_convertPathFileIntoAlignFileViaPathrange_sortedInput( self ):
+        p1a = Path()
+        p1a.setFromTuple( ( "1", "qry1", "1", "12", "sbj1", "1", "12", "0.0", "132", "95.0" ) )
+        p1b = Path()
+        p1b.setFromTuple( ( "1", "qry1", "16", "30", "sbj1", "13", "28", "1e-270", "150", "97.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "51", "90", "sbj2", "40", "1", "0.0", "132", "95.0" ) )
+        inFile = "dummyInFile"
+        inF = open( inFile, "w" )
+        for iPath in [ p1a, p1b, p2 ]:
+            iPath.write( inF )
+        inF.close()
+
+        expFile = "dummyExpFile"
+        expF = open( expFile, "w" )
+        a1 = Align()
+        a1.setFromTuple( ( "qry1", "1", "30", "sbj1", "1", "28", "0.0", "282", str((95*12+97*15)/float(12+15)) ) )
+        a2 = Align()
+        a2.setFromTuple( ( "qry1", "51", "90", "sbj2", "40", "1", "0.0", "132", "95.0" ) )
+        for iAlign in [ a1, a2 ]:
+            iAlign.write( expF )
+        expF.close()
+        
+        obsFile = "dummyObsFile"
+        
+        PathUtils.convertPathFileIntoAlignFileViaPathrange( inFile, obsFile, 0 )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ inFile, expFile, obsFile ]:
+            os.remove( f )
+            
+            
+    def test_convertPathFileIntoAlignFileViaPathrange_unsortedInput( self ):
+        p1a = Path()
+        p1a.setFromTuple( ( "1", "qry1", "1", "12", "sbj1", "1", "12", "0.0", "132", "95.0" ) )
+        p1b = Path()
+        p1b.setFromTuple( ( "1", "qry1", "16", "30", "sbj1", "13", "28", "0.0", "150", "97.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "51", "90", "sbj2", "40", "1", "0.0", "132", "95.0" ) )
+        inFile = "dummyInFile"
+        inF = open( inFile, "w" )
+        for iPath in [ p1b, p2, p1a ]:
+            iPath.write( inF )
+        inF.close()
+
+        expFile = "dummyExpFile"
+        expF = open( expFile, "w" )
+        a1 = Align()
+        a1.setFromTuple( ( "qry1", "1", "30", "sbj1", "1", "28", "0.0", "282", str((95*12+97*15)/float(12+15)) ) )
+        a2 = Align()
+        a2.setFromTuple( ( "qry1", "51", "90", "sbj2", "40", "1", "0.0", "132", "95.0" ) )
+        for iAlign in [ a1, a2 ]:
+            iAlign.write( expF )
+        expF.close()
+        
+        obsFile = "dummyObsFile"
+        
+        PathUtils.convertPathFileIntoAlignFileViaPathrange( inFile, obsFile, 0 )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ inFile, expFile, obsFile ]:
+            os.remove( f )
+            
+            
+    def test_convertPathFileIntoAlignFileViaPathrange_sortedInput_subjectReverseStrand( self ):
+        p1a = Path()
+        p1a.setFromTuple( ( "1", "qry1", "1", "12", "sbj1", "12", "1", "0.0", "132", "95.0" ) )
+        p1b = Path()
+        p1b.setFromTuple( ( "1", "qry1", "16", "30", "sbj1", "28", "13", "0.0", "150", "97.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "51", "90", "sbj2", "40", "1", "0.0", "132", "95.0" ) )
+        inFile = "dummyInFile"
+        inF = open( inFile, "w" )
+        for iPath in [ p1a, p1b, p2 ]:
+            iPath.write( inF )
+        inF.close()
+
+        expFile = "dummyExpFile"
+        expF = open( expFile, "w" )
+        a1 = Align()
+        a1.setFromTuple( ( "qry1", "1", "30", "sbj1", "28", "1", "0.0", "282", str((95*12+97*15)/float(12+15)) ) )
+        a2 = Align()
+        a2.setFromTuple( ( "qry1", "51", "90", "sbj2", "40", "1", "0.0", "132", "95.0" ) )
+        for iAlign in [ a1, a2 ]:
+            iAlign.write( expF )
+        expF.close()
+        
+        obsFile = "dummyObsFile"
+        
+        PathUtils.convertPathFileIntoAlignFileViaPathrange( inFile, obsFile, 0 )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ inFile, expFile, obsFile ]:
+            os.remove( f )
+        
+        
+    def test_splitPathListByQueryName_empty_list( self ):
+        lPath = []
+        
+        obsLPath = PathUtils.splitPathListByQueryName( lPath )
+        
+        expLPath = []
+        
+        self.assertEquals( expLPath, obsLPath )
+        
+        
+    def test_splitPathListByQueryName( self ):
+        iPath1 = Path()
+        iPath1.setFromString("1\tchr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iPath2 = Path()
+        iPath2.setFromString("2\tchr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iPath3 = Path()
+        iPath3.setFromString("3\tchr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        lPath = [ iPath1, iPath2, iPath3 ]
+        
+        obsLPath = PathUtils.splitPathListByQueryName( lPath )
+        
+        expLPath = [ [ iPath1, iPath3 ],
+                     [ iPath2 ] ]
+        
+        self.assertEquals( expLPath, obsLPath )
+        
+        
+    def test_splitPathListByQueryName_last_align_alone( self ):
+        iPath1 = Path()
+        iPath1.setFromString("1\tchr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iPath2 = Path()
+        iPath2.setFromString("2\tchr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iPath3 = Path()
+        iPath3.setFromString("3\tchr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iPath4 = Path()
+        iPath4.setFromString("4\tchr3\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iPath5 = Path()
+        iPath5.setFromString("5\tchr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iPath6 = Path()
+        iPath6.setFromString("6\tchr1\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iPath7 = Path()
+        iPath7.setFromString("7\tchr1\t100\t110\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iPath8 = Path()
+        iPath8.setFromString("8\tchr2\t200\t220\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        iPath9 = Path()
+        iPath9.setFromString("9\tchr4\t300\t330\tTE2\t150\t200\t1e-20\t30\t90.2\n")
+        lPath = [ iPath1, iPath2, iPath3, iPath4, iPath5, iPath6, iPath7, iPath8, iPath9 ]
+        
+        obsLPath = PathUtils.splitPathListByQueryName( lPath )
+        
+        expLPath = [ [ iPath1, iPath3, iPath6, iPath7 ],
+                     [ iPath2, iPath5, iPath8 ],
+                     [ iPath4 ],
+                     [ iPath9 ] ]
+        
+        self.assertEquals( expLPath, obsLPath )
+        
+        
+    def test_getPathListSortedByIncreasingQueryMinThenInvQueryLength_alreadyOrdered_diffIdentifier( self ):
+        iPath1 = Path( 1, Range("qry1",1,10), Range("sbj1",1,10), 0.0, 10, 98.7 )
+        iPath2 = Path( 2, Range("qry1",21,30), Range("sbj1",11,20), 0.0, 10, 98.7 )
+        lPaths = [ iPath1, iPath2 ]
+        
+        lExp = [ Path( 1, Range("qry1",1,10), Range("sbj1",1,10), 0.0, 10, 98.7 ),
+                Path( 2, Range("qry1",21,30), Range("sbj1",11,20), 0.0, 10, 98.7 ) ]
+        
+        lObs = PathUtils.getPathListSortedByIncreasingQueryMinThenInvQueryLength( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_getPathListSortedByIncreasingQueryMinThenInvQueryLength_unordered_diffIdentifier( self ):
+        iPath1 = Path( 1, Range("qry1",1,10), Range("sbj1",1,10), 0.0, 10, 98.7 )
+        iPath2 = Path( 2, Range("qry1",21,30), Range("sbj1",11,20), 0.0, 10, 98.7 )
+        lPaths = [ iPath2, iPath1 ]
+        
+        lExp = [ Path( 1, Range("qry1",1,10), Range("sbj1",1,10), 0.0, 10, 98.7 ),
+                Path( 2, Range("qry1",21,30), Range("sbj1",11,20), 0.0, 10, 98.7 ) ]
+        
+        lObs = PathUtils.getPathListSortedByIncreasingQueryMinThenInvQueryLength( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_getPathListSortedByIncreasingQueryMinThenInvQueryLength_unordered_sameIdentifier( self ):
+        iPath1a = Path( 1, Range("qry1",1,10), Range("sbj1",1,10), 0.0, 10, 98.7 )
+        iPath1b = Path( 1, Range("qry1",21,30), Range("sbj1",11,20), 0.0, 10, 98.7 )
+        lPaths = [ iPath1b, iPath1a ]
+        
+        lExp = [ Path( 1, Range("qry1",1,10), Range("sbj1",1,10), 0.0, 10, 98.7 ),
+                Path( 1, Range("qry1",21,30), Range("sbj1",11,20), 0.0, 10, 98.7 ) ]
+        
+        lObs = PathUtils.getPathListSortedByIncreasingQueryMinThenInvQueryLength( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_getPathListSortedByIncreasingQueryMinThenInvQueryLength_unordered_overlapping( self ):
+        iPath1 = Path( 1, Range("qry1",1,6), Range("sbj1",1,6), 0.0, 10, 98.7 )
+        iPath2 = Path( 2, Range("qry1",5,10), Range("sbj1",5,10), 0.0, 10, 98.7 )
+        lPaths = [ iPath2, iPath1 ]
+        
+        lExp = [ Path( 1, Range("qry1",1,6), Range("sbj1",1,6), 0.0, 10, 98.7 ),
+                Path( 2, Range("qry1",5,10), Range("sbj1",5,10), 0.0, 10, 98.7 ) ]
+        
+        lObs = PathUtils.getPathListSortedByIncreasingQueryMinThenInvQueryLength( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_getPathListSortedByIncreasingQueryMinThenInvQueryLength_threePaths_2sameMin( self ):
+        iPath1 = Path( 1, Range("qry1",1,6), Range("sbj1",1,6), 0.0, 10, 98.7 )
+        iPath2 = Path( 2, Range("qry1",5,12), Range("sbj1",5,12), 0.0, 10, 98.7 )
+        iPath3 = Path( 3, Range("qry1",5,10), Range("sbj1",5,10), 0.0, 10, 98.7 )
+        lPaths = [ iPath3, iPath2, iPath1 ]
+        
+        lExp = [ Path( 1, Range("qry1",1,6), Range("sbj1",1,6), 0.0, 10, 98.7 ),
+                Path( 2, Range("qry1",5,12), Range("sbj1",5,12), 0.0, 10, 98.7 ),
+                Path( 3, Range("qry1",5,10), Range("sbj1",5,10), 0.0, 10, 98.7 ) ]
+        
+        lObs = PathUtils.getPathListSortedByIncreasingQueryMinThenInvQueryLength( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_getPathListSortedByIncreasingQueryMinThenInvQueryLength_unordered_included( self ):
+        iPath1 = Path( 1, Range("qry1",1,6), Range("sbj1",1,6), 0.0, 10, 98.7 )
+        iPath2 = Path( 2, Range("qry1",2,5), Range("sbj1",2,5), 0.0, 10, 98.7 )
+        lPaths = [ iPath2, iPath1 ]
+        
+        lExp = [ Path( 1, Range("qry1",1,6), Range("sbj1",1,6), 0.0, 10, 98.7 ),
+                Path( 2, Range("qry1",2,5), Range("sbj1",2,5), 0.0, 10, 98.7 ) ]
+        
+        lObs = PathUtils.getPathListSortedByIncreasingQueryMinThenInvQueryLength( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_mergePathsInList_emptyList( self ):
+        lPaths = []
+        lExp = []
+        lObs = PathUtils.mergePathsInList( lPaths )
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_mergePathsInList_onePath( self ):
+        iPath1 = Path( 1, Range("qry1",1,10), Range("sbj1",1,10), 0.0, 10, 98.7 )
+        lPaths = [ iPath1 ]
+        lExp = [ Path( 1, Range("qry1",1,10), Range("sbj1",1,10), 0.0, 10, 98.7 ) ]
+        lObs = PathUtils.mergePathsInList( lPaths )
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_mergePathsInList_noOverlap( self ):
+        iPath1 = Path( 1, Range("qry1",1,10), Range("sbj1",1,10), 0.0, 10, 98.7 )
+        iPath2 = Path( 1, Range("qry1",21,30), Range("sbj1",11,20), 0.0, 10, 98.7 )
+        lPaths = [ iPath1, iPath2 ]
+        
+        lExp = [ Path( 1, Range("qry1",1,10), Range("sbj1",1,10), 0.0, 10, 98.7 ),
+                Path( 1, Range("qry1",21,30), Range("sbj1",11,20), 0.0, 10, 98.7 ) ]
+        
+        lObs = PathUtils.mergePathsInList( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_mergePathsInList_withOverlap( self ):
+        iPath1 = Path( 1, Range("qry1",1,10), Range("sbj1",1,10), 0.0, 10, 98.7 )
+        iPath2 = Path( 1, Range("qry1",6,15), Range("sbj1",6,15), 0.0, 10, 98.7 )
+        lPaths = [ iPath2, iPath1 ]
+        
+        lExp = [ Path( 1, Range("qry1",1,15), Range("sbj1",1,15), 0.0, 10, 98.7 ) ]
+        
+        lObs = PathUtils.mergePathsInList( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_mergePathsInList_withOverlap_reverseOnly( self ):
+        iPath1 = Path( 1, Range("qry1",10,1), Range("sbj1",10,1), 0.0, 10, 98.7 )
+        iPath2 = Path( 1, Range("qry1",15,6), Range("sbj1",15,6), 0.0, 10, 98.7 )
+        lPaths = [ iPath2, iPath1 ]
+        
+        lExp = [ Path( 1, Range("qry1",15,1), Range("sbj1",15,1), 0.0, 10, 98.7 ) ]
+        
+        lObs = PathUtils.mergePathsInList( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_mergePathsInList_withOverlap_directAndReverse( self ):
+        iPath1 = Path( 1, Range("qry1",10,1), Range("sbj1",10,1), 0.0, 10, 98.7 )
+        iPath2 = Path( 1, Range("qry1",15,6), Range("sbj1",15,6), 0.0, 10, 98.7 )
+        iPath3 = Path( 1, Range("qry1",2,5), Range("sbj1",2,5), 0.0, 10, 98.7 )
+        lPaths = [ iPath3, iPath2, iPath1 ]
+        
+        lExp = [ Path( 1, Range("qry1",15,1), Range("sbj1",15,1), 0.0, 10, 98.7 ) ]
+        
+        lObs = PathUtils.mergePathsInList( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_mergePathsInList_diffQueries_withOverlap( self ):
+        iPath1 = Path( 1, Range("qry1",1,10), Range("sbj1",1,10), 0.0, 10, 98.7 )
+        iPath2 = Path( 2, Range("qry2",6,15), Range("sbj1",6,15), 0.0, 10, 98.7 )
+        lPaths = [ iPath2, iPath1 ]
+        
+        lExp = [ Path( 1, Range("qry1",1,10), Range("sbj1",1,10), 0.0, 10, 98.7 ),
+                Path( 2, Range("qry2",6,15), Range("sbj1",6,15), 0.0, 10, 98.7 ) ]
+        
+        lObs = PathUtils.mergePathsInList( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_mergePathsInList_nonOverlappingSubjects( self ):
+        iPath1 = Path( 1, Range("qry1",398,491), Range("sbj1",10,112), 0.0, 10, 98.7 )
+        iPath2 = Path( 1, Range("qry1",451,492), Range("sbj1",124,169), 0.0, 10, 98.7 )
+        iPath3 = Path( 1, Range("qry1",493,531), Range("sbj1",249,294), 0.0, 10, 98.7 )
+        lPaths = [ iPath3, iPath2, iPath1 ]
+        
+        lExp = [ Path( 1, Range("qry1",398,491), Range("sbj1",10,112), 0.0, 10, 98.7 ),
+                Path( 1, Range("qry1",451,492), Range("sbj1",124,169), 0.0, 10, 98.7 ),
+                Path( 1, Range("qry1",493,531), Range("sbj1",249,294), 0.0, 10, 98.7 ) ]
+        
+        lObs = PathUtils.mergePathsInList( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_mergePathsInListUsingQueryCoordsOnly( self ):
+        iPath1 = Path( 1, Range("qry1",398,491), Range("sbj1",10,112), 0.0, 10, 98.7 )
+        iPath2 = Path( 1, Range("qry1",451,492), Range("sbj1",124,169), 0.0, 10, 98.7 )
+        iPath3 = Path( 1, Range("qry1",493,531), Range("sbj1",249,294), 0.0, 10, 98.7 )
+        lPaths = [ iPath3, iPath2, iPath1 ]
+        
+        lExp = [ Path( 1, Range("qry1",398,492), Range("sbj1",10,169), 0.0, 10, 98.7 ),
+                Path( 1, Range("qry1",493,531), Range("sbj1",249,294), 0.0, 10, 98.7 ) ]
+        
+        lObs = PathUtils.mergePathsInListUsingQueryCoordsOnly( lPaths )
+        
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_convertPathFileIntoGffFile( self ):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "12", "1", "sbj1", "1", "12", "0.0", "132", "95.0" ) )
+        p2a = Path()
+        p2a.setFromTuple( ( "2", "qry1", "16", "30", "sbj2", "1", "15", "1e-270", "150", "97.0" ) )
+        p2b = Path()
+        p2b.setFromTuple( ( "2", "qry1", "51", "90", "sbj2", "21", "60", "0.0", "132", "95.9" ) )
+        inFile = "dummyInFile"
+        PathUtils.writeListInFile( [ p1, p2a, p2b ], inFile, "w" )
+        
+        expFile = "dummyExpFile"
+        expF = open( expFile, "w" )
+        expF.write( "qry1\tREPET\tmatch\t1\t12\t0\t-\t.\tID=1;Target=sbj1 1 12\n" )
+        expF.write( "qry1\tREPET\tmatch\t16\t90\t0\t+\t.\tID=ms2;Target=sbj2 1 60\n" )
+        expF.write( "qry1\tREPET\tmatch_part\t16\t30\t1e-270\t+\t.\tID=mp2-1;Parent=ms2;Target=sbj2 1 15\n" )
+        expF.write( "qry1\tREPET\tmatch_part\t51\t90\t0\t+\t.\tID=mp2-2;Parent=ms2;Target=sbj2 21 60\n" )
+        expF.close()
+        
+        obsFile = "dummyObsFile"
+        
+        PathUtils.convertPathFileIntoGffFile( inFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ inFile, expFile, obsFile ]:
+            os.remove( f )
+            
+            
+    def test_convertPathFileIntoSetFile( self ):
+        pathFile = "dummyPathFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        pathFileHandler = open( pathFile, "w" )
+        pathFileHandler.write( "3\tchr2\t250\t151\tseq5\t1\t100\t1e-31\t147\t98.3\n" )
+        pathFileHandler.close()
+        
+        expFile = "dummyExpFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "3\tseq5\tchr2\t250\t151\n" )
+        expFileHandler.close()
+        
+        obsFile = "dummyObsFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        
+        PathUtils.convertPathFileIntoSetFile( pathFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ pathFile, expFile, obsFile ]:
+            if os.path.exists( f ):
+                os.remove ( f )
+                
+                
+    def test_removeInPathFileDuplicatedPathOnQueryNameQueryCoordAndSubjectName(self):
+        pathFile = "dummyPathFile"
+        f = open(pathFile, "w")
+        f.write("1\tG4\t1\t3856\tAtha5Chr4_Pals_Piler_3590_69_MAP_3\t1\t3856\t0\t7642\t99.9741\n")
+        f.write("1\tG4\t1\t3856\tAtha5Chr4_Pals_Piler_3590_69_MAP_3\t100\t3956\t0\t7642\t99.9741\n")
+        f.write("2\trooA\t1\t386\tAtha5Chr4_Pals_Piler_3589_69_MAP_3\t1\t386\t6.3e-220\t758\t99.4819\n")
+        f.write("3\trooA\t7236\t7621\tAtha5Chr4_Pals_Piler_3536_69_MAP_3\t1\t386\t6.3e-220\t758\t99.4819\n")
+        f.write("4\trooA\t387\t7235\tAtha5Chr4_Pals_Piler_3596_69_MAP_3\t1\t6849\t0\t13580\t99.9854\n")
+        f.write("5\taurora-element\t4046\t4257\tAtha5Chr4_Pals_Piler_3540_69_MAP_3\t1\t204\t6.1e-80\t300\t96.5686\n")
+        f.write("6\taurora-element\t274\t381\tAtha5Chr4_Pals_Piler_3595_23_MAP_3\t177\t284\t0\t191\t97.2222\n")
+        f.write("6\taurora-element\t116\t287\tAtha5Chr4_Pals_Piler_3595_30_MAP_3\t3\t170\t0\t290\t98.8095\n")
+        f.write("7\taurora-element\t393\t902\tAtha5Chr4_Pals_Piler_3595_31_MAP_3\t1467\t1945\t0\t873\t97.2441\n")
+        f.write("7\taurora-element\t393\t902\tAtha5Chr4_Pals_Piler_3595_31_MAP_3\t276\t100784\t0\t869\t98.1211\n")
+        f.write("7\taurora-element\t1387\t2271\tAtha5Chr4_Pals_Piler_3595_31_MAP_3\t276\t10780\t0\t1576\t97.6244\n")
+        f.write("8\taurora-element\t2486\t2828\tAtha5Chr4_Pals_Piler_3595_50_MAP_3\t4301\t4641\t0\t585\t97.3607\n")
+        f.write("9\taurora-element\t2265\t2483\tAtha5Chr4_Pals_Piler_3595_62_MAP_3\t3999\t4218\t0\t361\t96.347\n")
+        f.write("10\taurora-element\t2834\t4045\tAtha5Chr4_Pals_Piler_3595_69_MAP_3\t4800\t6011\t0\t2074\t97.0248\n")
+        f.write("11\taurora-element\t2\t113\tAtha5Chr4_Pals_Piler_3598_69_MAP_3\t205\t317\t8.5e-37\t157\t93.75\n")
+        f.write("11\taurora-element\t2\t113\tAtha5Chr4_Pals_Piler_3598_69_MAP_3\t305\t417\t8.5e-37\t157\t93.75\n")
+        f.write("11\taurora-element\t2\t113\tAtha5Chr4_Pals_Piler_3598_69_MAP_3\t305\t417\t8.5e-37\t157\t93.75\n")
+        f.close()            
+        
+        obsPathFile = "obsDummyPathFile"
+        PathUtils.removeInPathFileDuplicatedPathOnQueryNameQueryCoordAndSubjectName(pathFile, obsPathFile)
+        
+        expPathFile = "expDummyPathFile"
+        f = open(expPathFile, "w")
+        f.write("1\tG4\t1\t3856\tAtha5Chr4_Pals_Piler_3590_69_MAP_3\t1\t3856\t0\t7642\t99.974100\n")
+        f.write("2\trooA\t1\t386\tAtha5Chr4_Pals_Piler_3589_69_MAP_3\t1\t386\t6.3e-220\t758\t99.481900\n")
+        f.write("3\trooA\t7236\t7621\tAtha5Chr4_Pals_Piler_3536_69_MAP_3\t1\t386\t6.3e-220\t758\t99.481900\n")
+        f.write("4\trooA\t387\t7235\tAtha5Chr4_Pals_Piler_3596_69_MAP_3\t1\t6849\t0\t13580\t99.985400\n")
+        f.write("5\taurora-element\t4046\t4257\tAtha5Chr4_Pals_Piler_3540_69_MAP_3\t1\t204\t6.1e-80\t300\t96.568600\n")
+        f.write("6\taurora-element\t274\t381\tAtha5Chr4_Pals_Piler_3595_23_MAP_3\t177\t284\t0\t191\t97.222200\n")
+        f.write("6\taurora-element\t116\t287\tAtha5Chr4_Pals_Piler_3595_30_MAP_3\t3\t170\t0\t290\t98.809500\n")
+        f.write("7\taurora-element\t393\t902\tAtha5Chr4_Pals_Piler_3595_31_MAP_3\t1467\t1945\t0\t873\t97.244100\n")
+        f.write("7\taurora-element\t1387\t2271\tAtha5Chr4_Pals_Piler_3595_31_MAP_3\t276\t10780\t0\t1576\t97.624400\n")
+        f.write("8\taurora-element\t2486\t2828\tAtha5Chr4_Pals_Piler_3595_50_MAP_3\t4301\t4641\t0\t585\t97.360700\n")
+        f.write("9\taurora-element\t2265\t2483\tAtha5Chr4_Pals_Piler_3595_62_MAP_3\t3999\t4218\t0\t361\t96.347000\n")
+        f.write("10\taurora-element\t2834\t4045\tAtha5Chr4_Pals_Piler_3595_69_MAP_3\t4800\t6011\t0\t2074\t97.024800\n")
+        f.write("11\taurora-element\t2\t113\tAtha5Chr4_Pals_Piler_3598_69_MAP_3\t205\t317\t8.5e-37\t157\t93.750000\n")
+        f.close()
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expPathFile, obsPathFile))
+        
+        os.remove(pathFile)
+        os.remove(expPathFile)
+        os.remove(obsPathFile)
+        
+        
+    def test_getPathListWithoutDuplicatesOnQueryCoord(self):
+        iPath1 = Path(1, Range("qry1",398,491), Range("sbj1",10,112), 0.0, 10, 98.7)
+        iPath2 = Path(1, Range("qry1",451,492), Range("sbj1",124,169), 0.0, 10, 98.7)
+        iPath3 = Path(1, Range("qry1",451,492), Range("sbj1",249,294), 0.0, 10, 98.7)
+        lPaths = [iPath3, iPath2, iPath1]
+       
+        obslPaths = PathUtils.getPathListWithoutDuplicatesOnQueryCoord(lPaths)
+       
+        explPaths = [iPath1, iPath3]
+        
+        self.assertEquals(explPaths, obslPaths)
+        
+                
+    def _makePathListFromTupleList ( self, tupleList ):
+        pathList = []
+        for tuple in tupleList:
+            path = Path()
+            path.setFromTuple(tuple)
+            pathList.append(path)
+        return pathList
+    
+    def _makePathListFromStringList (self, stringList):
+        pathList = []
+        for string in stringList:
+            path = Path()
+            path.setFromString(string)
+            pathList.append(path)
+        return pathList
+    
+    def _show (self, list):
+        for item in list:
+            print item.toString()
+            
+            
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_PathUtils ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_Range.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,671 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+from commons.core.coord.Range import Range
+from commons.core.coord.Range import getBin, getIdx
+
+
+class Test_Range( unittest.TestCase ):
+    
+    def setUp(self):
+        self._range = Range()
+        
+    def test_setFromString(self):
+        line = "chunk1\t190000\t390000"
+        self._range.setFromString( line )
+        self.assertEqual( self._range.seqname, "chunk1" )
+        self.assertEqual( self._range.start, 190000 )
+        self.assertEqual( self._range.end, 390000 )
+        
+        line = "chunk1\t190000\t390000\n"
+        self._range.setFromString( line )
+        self.assertEqual( self._range.seqname, "chunk1" )
+        self.assertEqual( self._range.start, 190000 )
+        self.assertEqual( self._range.end, 390000 )
+        
+        line = "chunk1;190000;390000"
+        self._range.setFromString( line, ";" )
+        self.assertEqual( self._range.seqname, "chunk1" )
+        self.assertEqual( self._range.start, 190000 )
+        self.assertEqual( self._range.end, 390000 )
+        
+    def test_setFromTuple(self):
+        tuple = ("chunk1","190000","390000")
+        self._range.setFromTuple( tuple)
+        
+        self.assertEqual( self._range.seqname, "chunk1" )
+        self.assertEqual( self._range.start, 190000 )
+        self.assertEqual( self._range.end, 390000 )
+        
+    def test___eq__(self):
+        self._range.setFromString( "chunk1\t190000\t390000\n" )
+        o = Range()
+        o.setFromString( "chunk1\t190000\t390000\n" )
+        self.assertEqual( self._range, o )
+        
+        o.setFromString( "chunk1\t190000\t39" )
+        self.assertNotEquals( self._range, o )
+        
+        o.setFromString( "chromosome1\t190000\t390000" )
+        self.assertNotEquals( self._range, o )
+        
+        o.setFromString( "chunk1\t390000\t190000" )
+        self.assertNotEquals( self._range, o )
+        
+        o.setFromString( "chromosome1\t390000\t190000" )
+        self.assertNotEquals( self._range, o )
+        
+    def test_getMin(self):
+        self._range.setFromTuple( ("chunk1", 190000, 390000) )
+        expMin = 190000
+        obsMin = self._range.getMin() 
+        self.assertTrue(expMin, obsMin)
+        
+    def test_getMax(self):
+        self._range.setFromTuple( ("chunk1", 190000, 390000) )
+        expMax = 390000
+        obsMax = self._range.getMax() 
+        self.assertTrue(expMax, obsMax)
+        
+    def test_isOnDirectStrand_true(self):
+        self._range.setFromTuple( ("chunk1", 190000, 390000) )
+        self.assertTrue(self._range.isOnDirectStrand())
+        
+    def test_isOnDirectStrand_false(self):
+        self._range.setFromTuple( ("chunk1", 390000, 190000) )
+        self.assertFalse(self._range.isOnDirectStrand())
+        
+    def test_isOnReverseStrand_true(self):
+        self._range.setFromTuple( ("chunk1", 390000, 190000) )
+        self.assertTrue(self._range.isOnReverseStrand())
+        
+    def test_isOnReverseStrand_false(self):
+        self._range.setFromTuple( ("chunk1", 190000, 390000) )
+        self.assertFalse(self._range.isOnReverseStrand())
+        
+    def test_getStrand_direct(self):
+        self._range.setFromTuple( ("chunk1", 190000, 390000) )
+        expStrand = '+'
+        obsStrand = self._range.getStrand()
+        self.assertEqual(expStrand, obsStrand)
+        
+    def test_getStrand_reverse(self):
+        self._range.setFromTuple( ("chunk1", 390000, 190000) )
+        expStrand = '-'
+        obsStrand = self._range.getStrand()
+        self.assertEqual(expStrand, obsStrand)
+        
+    def test_reverse(self):
+        obsRange = Range("chunk1", 190000, 390000)
+        expRange = Range("chunk1", 390000, 190000)
+        obsRange.reverse()
+        self.assertEquals(expRange, obsRange)
+        
+    def test_getLength(self):
+        self._range.setFromTuple( ("chunk1", 190000, 390000) )
+        expLength = 200001 
+        obsLength = self._range.getLength()
+        self.assertEquals(expLength, obsLength)
+        
+    def test_isEmpty_true( self ):
+        exp = True
+        obs = self._range.isEmpty()
+        self.assertEquals( exp, obs )
+        
+    def test_isEmpty_false( self ):
+        self._range.setFromTuple( ( "seq1", 1, 10 ) )
+        exp = False
+        obs = self._range.isEmpty()
+        self.assertEquals( exp, obs )
+        
+    def test_merge_diff_sequences( self ):
+        self._range.setFromTuple( ( "seq1", 6, 10 ) )
+        range2 = Range( "seq2", 6, 12 )
+        expReturn = None
+        expRange = Range( "seq1", 6, 10 )
+        obsReturn = self._range.merge( range2 )
+        obsRange = self._range
+        self.assertEquals( expReturn, obsReturn )
+        self.assertEquals( expRange, obsRange )
+        
+    def test_merge_no_overlapping_ranges( self ):
+        self._range.setFromTuple( ( "seq1", 6, 10 ) )
+        range2 = Range( "seq1", 12, 20 )
+        expReturn = None
+        expRange = Range( "seq1", 6, 20 )
+        obsReturn = self._range.merge( range2 )
+        obsRange = self._range
+        self.assertEquals( expReturn, obsReturn )
+        self.assertEquals( expRange, obsRange )
+        
+    def test_merge_no_overlapping_ranges_range1_on_neg_strand( self ):
+        self._range.setFromTuple( ( "seq1", 10, 6 ) )
+        range2 = Range( "seq1", 12, 20 )
+        expReturn = None
+        expRange = Range( "seq1", 20, 6 )
+        obsReturn = self._range.merge( range2 )
+        obsRange = self._range
+        self.assertEquals( expReturn, obsReturn )
+        self.assertEquals( expRange, obsRange )
+        
+    def test_merge_overlapping_ranges_range1_and_range2_on_neg_strand( self ):
+        self._range.setFromTuple( ( "seq1", 10, 6 ) )
+        range2 = Range( "seq1", 20, 12 )
+        expReturn = None
+        expRange = Range( "seq1", 20, 6 )
+        obsReturn = self._range.merge( range2 )
+        obsRange = self._range
+        self.assertEquals( expReturn, obsReturn )
+        self.assertEquals( expRange, obsRange )
+        
+    def test_merge_on_overlapping_ranges_range1_and_range2( self ):
+        self._range.setFromTuple( ( "seq1", 6, 10 ) )
+        range2 = Range( "seq1", 8, 20 )
+        expReturn = None
+        expRange = Range( "seq1", 6, 20 )
+        obsReturn = self._range.merge( range2 )
+        obsRange = self._range
+        self.assertEquals( expReturn, obsReturn )
+        self.assertEquals( expRange, obsRange )
+        
+    def test_isOverlapping_diff_sequences( self ):
+        self._range.setFromTuple( ( "seq1", 6, 10 ) )
+        r2 = Range( "seq2", 6, 10 )
+        exp = False
+        obs = self._range.isOverlapping( r2 )
+        self.assertEquals( exp, obs )
+        
+    def test_isOverlapping_no( self ):
+        self._range.setFromTuple( ( "seq1", 6, 10 ) )
+        r2 = Range( "seq1", 16, 20 )
+        exp = False
+        obs = self._range.isOverlapping( r2 )
+        self.assertEquals( exp, obs )
+        
+    def test_isOverlapping_yes( self ):
+        self._range.setFromTuple( ( "seq1", 6, 10 ) )
+        r2 = Range( "seq1", 1, 15 )
+        exp = True
+        obs = self._range.isOverlapping( r2 )
+        self.assertEquals( exp, obs )
+        
+    def test_isOverlapping_yes_range2_on_neg_strand( self ):
+        self._range.setFromTuple( ( "seq1", 6, 10 ) )
+        r2 = Range( "seq1", 15, 1 )
+        exp = True
+        obs = self._range.isOverlapping( r2 )
+        self.assertEquals( exp, obs )
+        
+    def test_isOverlapping_range1_before_range2( self ):
+        self._range.setFromTuple( ( "seq1", 6, 10 ) )
+        r2 = Range( "seq1", 8, 15 )
+        exp = True
+        obs = self._range.isOverlapping( r2 )
+        self.assertEquals( exp, obs )
+        
+    def test_isOverlapping_range1_after_range2( self ):
+        self._range.setFromTuple( ( "seq1", 6, 10 ) )
+        r2 = Range( "seq1", 1, 8 )
+        exp = True
+        obs = self._range.isOverlapping( r2 )
+        self.assertEquals( exp, obs )
+        
+    def test_isOverlapping_range1_equal_range2( self ):
+        self._range.setFromTuple( ( "seq1", 6, 10 ) )
+        r2 = Range( "seq1", 6, 10 )
+        exp = True
+        obs = self._range.isOverlapping( r2 )
+        self.assertEquals( exp, obs )
+        
+    def test_isOverlapping_yes_edges_left( self ):
+        self._range.setFromTuple( ( "seq1", 6, 10 ) )
+        r2 = Range( "seq1", 1, 6 )
+        exp = True
+        obs = self._range.isOverlapping( r2 )
+        self.assertEquals( exp, obs )
+        
+    def test_isOverlapping_yes_edges_right( self ):
+        self._range.setFromTuple( ( "seq1", 6, 10 ) )
+        r2 = Range( "seq1", 10, 20 )
+        exp = True
+        obs = self._range.isOverlapping( r2 )
+        self.assertEquals( exp, obs )
+        
+    def test_isOverlapping_yes_one_nt( self ):
+        self._range.setFromTuple( ( "seq1", 10, 10 ) )
+        r2 = Range( "seq1", 10, 20 )
+        exp = True
+        obs = self._range.isOverlapping( r2 )
+        self.assertEquals( exp, obs )
+        
+        
+    def test_getOverlapLength_on_different_range( self ):
+        range1 = Range( "chunk1", 190000, 390000 )
+        range2 = Range( "chunk2", 290000, 590000 )
+        expSize = 0
+        obsSize = range1.getOverlapLength( range2 )
+        self.assertEquals( expSize, obsSize )
+        
+        
+    def test_getOverlapLength_on_no_overalping_range( self ):
+        range1 =Range( "chunk1", 190000, 390000 )
+        range2 =Range( "chunk1", 490000, 590000 )
+        expSize = 0
+        obsSize = range1.getOverlapLength( range2 )
+        self.assertEquals( expSize, obsSize )
+        
+        
+    def test_getOverlapLength_range2_included_in_range1( self ):
+        range1 = Range( "chunk1", 19, 39 )
+        range2 = Range( "chunk1", 22, 25 )
+        expSize = 4
+        obsSize = range1.getOverlapLength( range2 )
+        self.assertEquals( expSize, obsSize )
+        obsSize = range2.getOverlapLength( range1 )
+        self.assertEquals( expSize, obsSize )
+        
+        
+    def test_getOverlapLength_range1_included_in_range2( self ):
+        range1 = Range( "chunk1", 220000, 250000 )
+        range2 = Range( "chunk1", 190000, 390000 )
+        expSize = 30001
+        obsSize = range1.getOverlapLength( range2 )
+        self.assertEquals( expSize, obsSize )
+        
+        
+    def test_getOverlapLength_range1_before_range2( self ):
+        range1 = Range( "chunk1", 190000, 390000 )
+        range2 = Range( "chunk1", 290000, 590000 )
+        expSize = 100001
+        obsSize = range1.getOverlapLength( range2 )
+        self.assertEquals( expSize, obsSize )
+        
+        
+    def test_getOverlapLength_range1_after_range2( self ):
+        range1 = Range( "chunk1", 390000, 790000 )
+        range2 = Range( "chunk1", 290000, 590000 )
+        expSize = 200001
+        obsSize = range1.getOverlapLength( range2 )
+        self.assertEquals( expSize, obsSize )
+        
+        
+    def test_isIncludedIn( self ):
+        iRange1 = Range( "chunk1", 21, 30 )
+        iRange2 = Range( "chunk1", 11, 40 )
+        self.assertTrue( iRange1.isIncludedIn( iRange2 ) )
+        
+        
+    def test_isIncludedIn_diffStrand( self ):
+        iRange1 = Range( "chunk1", 21, 30 )
+        iRange2 = Range( "chunk1", 40, 11 )
+        self.assertTrue( iRange1.isIncludedIn( iRange2 ) )
+        
+        
+    def test_isIncludedIn_onlyOverlap( self ):
+        iRange1 = Range( "chunk1", 21, 50 )
+        iRange2 = Range( "chunk1", 11, 40 )
+        self.assertFalse( iRange1.isIncludedIn( iRange2 ) )
+        
+        
+    def test_isIncludedIn_diffSeqname( self ):
+        iRange1 = Range( "chunk1", 21, 30 )
+        iRange2 = Range( "chunk2", 11, 40 )
+        self.assertFalse( iRange1.isIncludedIn( iRange2 ) )
+        
+        
+    def test_getDistance_on_overlapping_range(self):
+        overlapTuple1 = ("chunk1", 220000, 250000)
+        overlapRange1 = Range()
+        overlapRange1.setFromTuple(overlapTuple1)
+        
+        overlapTuple2 = ("chunk1", 190000, 390000)
+        overlapRange2 = Range()
+        overlapRange2.setFromTuple(overlapTuple2)
+        
+        expDistance = 0
+        obsDistance = overlapRange1.getDistance(overlapRange2)
+        
+        self.assertEquals(expDistance, obsDistance)
+        
+    def test_getDistance_on_range1_on_plus_strand_included_in_range2_on_neg_strand(self):
+        tuple1 = ("chunk1", 220000, 250000)
+        range1 = Range()
+        range1.setFromTuple(tuple1)
+        
+        tuple2 = ("chunk1", 390000, 190000)
+        range2 = Range()
+        range1.setFromTuple(tuple2)
+        
+        expDistance = -1
+        obsDistance = range1.getDistance(range2)
+        
+        self.assertEquals(expDistance, obsDistance)
+        
+    def test_getDistance_range1_after_range2(self):
+        tuple1 = ("chunk1", 390000, 590000)
+        range1 = Range()
+        range1.setFromTuple(tuple1)
+        
+        tuple2 = ("chunk1", 190000, 290000)
+        range2 = Range()
+        range2.setFromTuple(tuple2)
+        
+        expDistance = 100000
+        obsDistance = range1.getDistance(range2)
+        
+        self.assertEquals(expDistance, obsDistance)
+        
+    def test_getDistance_range1_before_range2(self):
+        tuple1 = ("chunk1", 190000, 290000)
+        range1 = Range()
+        range1.setFromTuple(tuple1)
+        
+        tuple2 = ("chunk1", 390000, 590000)
+        range2 = Range()
+        range2.setFromTuple(tuple2)
+        
+        expDistance = 100000
+        obsDistance = range1.getDistance(range2)
+        
+        self.assertEquals(expDistance, obsDistance)
+        
+    def test_getDistance_range1_after_range2_both_on_neg_strand(self):   
+        tuple1 = ("chunk1", 590000, 390000)
+        range1 = Range()
+        range1.setFromTuple(tuple1)
+        
+        tuple2 = ("chunk1", 290000, 190000)
+        range2 = Range()
+        range2.setFromTuple(tuple2)
+        
+        expDistance = 100000
+        obsDistance = range1.getDistance(range2)
+        
+        self.assertEquals(expDistance, obsDistance)
+        
+    def test_getDistance_range1_before_range2_both_on_neg_strand(self):   
+        tuple1 = ("chunk1", 290000, 190000)
+        range1 = Range()
+        range1.setFromTuple(tuple1)
+        
+        tuple2 = ("chunk1", 590000, 390000)
+        range2 = Range()
+        range2.setFromTuple(tuple2)
+        
+        expDistance = 100000
+        obsDistance = range1.getDistance(range2)
+        
+        self.assertEquals(expDistance, obsDistance)
+        
+    def test_diff_on_no_overlapping_range(self):
+        range1 = Range("chunk1", 190000, 390000)
+        range2 = Range("chunk1", 490000, 590000)
+        
+        expRange1 = Range("chunk1",190000,390000)
+        expReturnedRange = Range("chunk1")
+        
+        obsReturnedRange = range1.diff(range2)
+        obsRange1 = range1
+        
+        self.assertEquals(expRange1, obsRange1)
+        self.assertEquals(expReturnedRange, obsReturnedRange)
+        
+    def test_diff_on_different_chunks(self):
+        range1 = Range("chunk1", 190000, 390000)
+        range2 = Range("chunk2", 290000, 590000)
+        
+        expRange1 = Range("chunk1", 190000, 390000)
+        expReturnedRange = Range("chunk1")
+        
+        obsReturnedRange = range1.diff(range2)
+        obsRange1 = range1
+        
+        self.assertEquals(expRange1, obsRange1)
+        self.assertEquals(expReturnedRange, obsReturnedRange)
+        
+    def test_diff_range1_before_range2(self):
+        range1 = Range("chunk1", 190000, 390000)
+        range2 = Range("chunk1", 290000, 590000)
+        
+        expRange1 = Range("chunk1", 190000, 289999)
+        expReturnedRange = Range("chunk1")
+        
+        obsReturnedRange = range1.diff(range2)
+        obsRange1 = range1
+        
+        self.assertEquals(expRange1, obsRange1)
+        self.assertEquals(expReturnedRange, obsReturnedRange)
+        
+    def test_diff_range1_before_range2_range1_on_neg_strand(self):
+        range1 = Range("chunk1", 390000, 190000)
+        range2 = Range("chunk1", 290000, 590000)
+        
+        expRange1 = Range("chunk1", 289999, 190000)
+        expReturnedRange = Range("chunk1")
+        
+        obsReturnedRange = range1.diff(range2)
+        obsRange1 = range1
+        
+        self.assertEquals(expRange1, obsRange1)
+        self.assertEquals(expReturnedRange, obsReturnedRange)
+        
+    def test_diff_range2_included_in_range1(self):
+        range1 = Range("chunk1", 190000, 590000)
+        range2 = Range("chunk1", 290000, 390000)
+        
+        expRange1 = Range("chunk1", 190000, 289999)
+        expReturnedRange = Range("chunk1", 390001, 590000)
+        
+        obsReturnedRange = range1.diff(range2)
+        obsRange1 = range1
+        
+        self.assertEquals(expRange1, obsRange1)
+        self.assertEquals(expReturnedRange, obsReturnedRange)
+        
+    def test_diff_range2_included_in_range1_range1_on_reverse_strand(self):
+        range1 = Range("chunk1", 590000, 190000)
+        range2 = Range("chunk1", 290000, 390000)
+        
+        expRange1 = Range("chunk1", 289999, 190000)
+        expReturnedRange = Range("chunk1", 590000, 390001)
+        
+        obsReturnedRange = range1.diff(range2)
+        obsRange1 = range1
+        
+        self.assertEquals(expRange1, obsRange1)
+        self.assertEquals(expReturnedRange, obsReturnedRange)
+        
+    def test_diff_range1_included_in_range2(self):
+        range1 = Range("chunk1", 390000, 490000)
+        range2 = Range("chunk1", 290000, 590000)
+        
+        expRange1 = Range("chunk1",0,0)
+        expReturnedRange = Range("chunk1")
+        
+        obsReturnedRange = range1.diff(range2)
+        obsRange1 = range1
+        
+        self.assertEquals(expRange1, obsRange1)
+        self.assertEquals(expReturnedRange, obsReturnedRange)
+        
+    def test_diff_range1_after_range2(self):
+        range1 = Range("chunk1", 390000, 590000)
+        range2 = Range("chunk1", 290000, 490000)
+        
+        expRange1 = Range("chunk1", 490001, 590000)
+        expReturnedRange = Range("chunk1")
+        
+        obsReturnedRange = range1.diff(range2)
+        obsRange1 = range1
+        
+        self.assertEquals(expRange1, obsRange1)
+        self.assertEquals(expReturnedRange, obsReturnedRange)
+        
+    def test_diff_range1_after_range2_range1_on_neg_strand(self):
+        range1 = Range("chunk1", 590000, 390000)
+        range2 = Range("chunk1", 290000, 490000)
+        
+        expRange1 = Range("chunk1", 590000, 490001)
+        expReturnedRange = Range("chunk1")
+        
+        obsReturnedRange = range1.diff(range2)
+        obsRange1 = range1
+        
+        self.assertEquals(expRange1, obsRange1)
+        self.assertEquals(expReturnedRange, obsReturnedRange)
+        
+    def test_getIdx(self):
+        self.assertEqual(getIdx(1000,3),1000001)
+        self.assertEqual(getIdx(999,3),1000000)
+        self.assertEqual(getIdx(2000,3),1000002)
+        self.assertEqual(getIdx(2000,4),2000000)
+        self.assertEqual(getIdx(2000,5),3000000)
+        self.assertEqual(getIdx(20000000,6),4000000)
+        self.assertEqual(getIdx(20000000,5),3000200)
+        self.assertEqual(getIdx(20000000,4),2002000)
+        self.assertEqual(getIdx(20000000,3),1020000)
+        
+    def test_getBin_bin_level_9(self):
+        tuple1 = ("chunk1", 190000000, 390000000)
+        range1 =Range()
+        range1.setFromTuple(tuple1)
+        
+        expRes = 100000000.0
+        obsRes = range1.getBin()
+        
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_8(self):
+        tuple1 = ("chunk1", 19000000, 39000000)
+        range1 =Range()
+        range1.setFromTuple(tuple1)
+        
+        expRes = 100000000.0
+        obsRes = range1.getBin()
+        
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_7(self):
+        tuple1 = ("chunk1", 1900000, 3900000)
+        range1 =Range()
+        range1.setFromTuple(tuple1)
+        
+        expRes = 10000000.0
+        obsRes = range1.getBin()
+        
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_6(self):
+        tuple1 = ("chunk1", 190000, 390000)
+        range1 =Range()
+        range1.setFromTuple(tuple1)
+        
+        expRes = 1000000.0
+        obsRes = range1.getBin()
+        
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_5(self):
+        tuple = ("chunk1", 19000, 39000)
+        range =Range()
+        range.setFromTuple(tuple)
+        expRes = 100000.0
+        obsRes = range.getBin()
+        
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_4(self):
+        tuple = ("chunk1", 1900, 3900)
+        range =Range()
+        range.setFromTuple(tuple)
+        
+        expRes = 10000.0
+        obsRes = range.getBin()
+        
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_3(self):
+        tuple = ("chunk1", 190, 390)
+        range =Range()
+        range.setFromTuple(tuple)
+        
+        expRes = 1000.0
+        obsRes = range.getBin()
+        
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_2(self):
+        tuple = ("chunk1", 19, 39)
+        range =Range()
+        range.setFromTuple(tuple)
+        
+        expRes = 1000.0
+        obsRes = range.getBin()
+        
+        self.assertEquals(expRes, obsRes)
+        
+    def test_getBin_bin_level_1(self):
+        tuple = ("chunk1", 1, 3)
+        range =Range()
+        range.setFromTuple(tuple)
+        
+        expRes = 1000.0
+        obsRes = range.getBin()
+        
+        self.assertEquals(expRes, obsRes)
+        
+        
+    def test_getBin_function(self):
+        expBin = 2L
+        obsBin = getBin(200, 2)
+        
+        self.assertEquals(expBin, obsBin)
+        
+    def test_findIdx(self):
+        o = Range()
+        o.setFromString( "chunk1\t1000\t2000\n" )
+        self.assertEqual(o.findIdx(),2000000)
+        
+        o.setFromString( "chunk1\t2000\t1000\n" )       
+        self.assertEqual(o.findIdx(),2000000)
+        
+        o.setFromString( "chunk1\t200\t999\n" )       
+        self.assertEqual(o.findIdx(),1000000)
+        
+        o.setFromString( "chunk1\t1\t20000000\n" )       
+        self.assertEqual(o.findIdx(),4000000)
+        
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_Range ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_Set.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,282 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+from commons.core.coord.Set import Set
+from commons.core.coord.Map import Map
+
+
+class Test_Set( unittest.TestCase ):
+    
+    def test__eq__sets_equals(self):
+        set1 = Set( 1, "set1", "seq1", 1, 2 )
+        set2 = Set( 1, "set1", "seq1", 1 ,2 )   
+        self.assertEquals( set1, set2 )
+        
+    def test__eq__sets_not_equals_ids(self):
+        set1 = Set( 1, "set1", "seq1", 1, 2 )
+        set2 = Set( 2, "set1", "seq1", 1 ,2 )   
+        self.assertNotEquals( set1, set2 )
+        
+    def test__eq__sets_not_equals_name(self):
+        set1 = Set( 1, "set1", "seq1", 1, 2 )
+        set2 = Set( 1, "set2", "seq1", 1 ,2 )   
+        self.assertNotEquals( set1, set2 )
+    
+    def test__eq__on_empty_set(self):
+        set1 = Set()
+        set2 = Set()
+        self.assertEquals( set1, set2 )
+        
+    def test_setFromTuple_equals_instances(self):
+        tuple = ( 1, "set1", "seq1", 1, 2 )
+        obsSet = Set()
+        obsSet.setFromTuple(tuple)
+        expSet = Set( 1, "set1", "seq1", 1, 2 )
+        self.assertEquals( expSet, obsSet )
+   
+    def test_setFromTuple_not_equals_instances(self):
+        tuple = ( 1, "set1", "seq1", 1, 2 )
+        obsSet = Set()
+        obsSet.setFromTuple(tuple)
+        expSet = Set( 2, "set1", "seq1", 1, 2 )
+        self.assertNotEquals( expSet, obsSet )
+        
+    def test_read_empty_line_file(self):
+        fileName = "dummyFile"
+        
+        os.system(" touch " + fileName)
+        
+        fileHandler = open(fileName, "r")
+        
+        obsSet = Set()
+        
+        obsRes = obsSet.read( fileHandler )
+        expRes = 0
+        
+        fileHandler.close()
+        os.remove(fileName)
+        
+        self.assertEquals( expRes, obsRes )
+
+    def test_read_one_line_file(self):
+        line = ( "1\tset1\tseq1\t1\t2" )
+        fileName = "dummyFile"
+        
+        fileHandler = open( fileName, "w" )
+        fileHandler.write( line )
+        fileHandler.close()
+        
+        fileHandler = open( fileName, "r" )
+        
+        tuple = line.split("\t")
+        expSet = Set()
+        expSet.setFromTuple(tuple)
+        
+        obsSet = Set()
+        
+        expRes = 1
+        obsRes = obsSet.read(fileHandler)
+        
+        fileHandler.close()
+        os.remove(fileName)
+        self.assertEquals( expRes, obsRes )
+        self.assertEquals( expSet, obsSet ) 
+        
+    def test_read_two_line_file(self):
+        line1 = ( "1\tset1\tseq1\t1\t2\n" )
+        line2 = ( "2\tset2\tseq2\t3\t4" )
+        fileName = "dummyFile"
+        
+        fileHandler = open( fileName, "w" )
+        fileHandler.write( line1 )
+        fileHandler.write( line2 )
+        fileHandler.close()
+        
+        tuple1 = line1.split("\t")
+        tuple2 = line2.split("\t")
+        
+        expSet1 = Set()
+        expSet2 = Set()
+        
+        expSet1.setFromTuple(tuple1)
+        expSet2.setFromTuple(tuple2)
+        
+        expSetList = [ expSet1, expSet2 ]
+        expResList = [ 1, 1 ]
+        
+        fileHandler = open( fileName, "r" )
+        
+        obsSet1 = Set()
+        obsSet2 = Set()
+
+        obsRes1 = obsSet1.read(fileHandler)
+        obsRes2 = obsSet2.read(fileHandler)
+        
+        obsSetList= [ obsSet1, obsSet2 ]
+        obsResList = [ obsRes1, obsRes2 ]
+        
+        fileHandler.close()
+        os.remove(fileName)
+        
+        self.assertEquals( expSetList, obsSetList )
+        self.assertEquals( expResList, obsResList )
+        
+    def test_merge_first_id_greater_than_second_id(self):
+        firstSet = Set( 2, "set1", "seq1", 10, 40 )
+        secondSet = Set( 1, "set2", "seq1", 20, 60 )
+        
+        firstSet.merge( secondSet )
+        
+        expSet = Set( 1, "set1", "seq1", 10, 60)
+        obsSet = firstSet
+        
+        self.assertEquals( expSet, obsSet)
+        
+    def test_merge_first_id_smaller_than_second_id(self):
+        firstSet = Set( 1, "set1", "seq1", 10, 40 )
+        secondSet = Set( 2, "set2", "seq1", 20, 60 )
+        
+        firstSet.merge( secondSet )
+        
+        expSet = Set( 1, "set1", "seq1", 10, 60)
+        obsSet = firstSet
+        
+        self.assertEquals( expSet, obsSet)
+
+    def test_merge_first_id_equals_second_id(self):
+        firstSet = Set( 1, "set1", "seq1", 10, 40 )
+        secondSet = Set( 1, "set2", "seq1", 20, 60 )
+        
+        firstSet.merge( secondSet )
+        
+        expSet = Set( 1, "set1", "seq1", 10, 60)
+        obsSet = firstSet
+        
+        self.assertEquals( expSet, obsSet)
+    
+    def test_merge_different_seqnames(self):
+        firstSet = Set( 2, "set1", "seq1", 10, 40 )
+        secondSet = Set( 1, "set1", "seq2", 20, 60 )
+        expSet = Set( 2, "set1", "seq1", 10, 40 )
+        firstSet.merge( secondSet )
+        obsSet = firstSet
+        self.assertEquals( expSet, obsSet )
+        
+    def test_diff_on_empty_sets(self):
+        firstSet = Set()
+        firstSet.seqname = "seq1"
+        secondSet = Set()
+        secondSet.seqname = "seq2"
+        
+        obsSet = firstSet.diff( secondSet )
+        expSet = Set()
+        
+        self.assertEquals( expSet, obsSet )
+    
+    def test_diff(self):
+        firstSet = Set( 2, "set1", "seq1", 10, 80 )
+        secondSet = Set( 1, "set2", "seq1", 20, 60 )
+        
+        expSet1 = Set( 2, "set1", "seq1", 10, 19 )
+        expSet2 = Set( 2, "set1", "seq1", 61, 80 )        
+        
+        obsSet2 = firstSet.diff( secondSet )
+        obsSet1 = firstSet
+                
+        self.assertEquals( expSet1, obsSet1 ) 
+        self.assertEquals( expSet2, obsSet2 )
+        
+    def test_diff_reverse(self):
+        firstSet = Set( 2, "set1", "seq1", 20, 60 )
+        secondSet = Set( 1, "set2", "seq1", 10, 80 )
+        
+        expSet1 = Set( 2, "set1", "seq1", 0, 0 )
+        expSet2 = Set( )        
+        
+        obsSet2 = firstSet.diff( secondSet )
+        obsSet1 = firstSet
+                
+        self.assertEquals( expSet1, obsSet1 ) 
+        self.assertEquals( expSet2, obsSet2 )
+        
+    def test_diff_list1_overlap_end_list2(self):
+        firstSet = Set( 2, "set1", "seq1", 20, 100 )
+        secondSet = Set( 1, "set2", "seq1", 10, 80 )
+        
+        expSet1 = Set( 2, "set1", "seq1", 81, 100 )  
+        expSet2 = Set( )             
+        
+        obsSet2 = firstSet.diff( secondSet )
+        obsSet1 = firstSet
+                
+        self.assertEquals( expSet1, obsSet1 ) 
+        self.assertEquals( expSet2, obsSet2 )
+        
+    def test_diff_with_empty_set1(self):
+        set2 = Set( 1, "set1", "seq1", 2, 45 )
+        set1 = Set( )
+        
+        expSet1 = Set( )
+        expSet2 = Set( )
+        
+        obsSet2 = set1.diff( set2 )
+        obsSet1 = set1
+        
+        self.assertEquals( expSet1, obsSet1 ) 
+        self.assertEquals( expSet2, obsSet2 )
+        
+    def test_diff_list2_overlap_end_list1(self):
+        firstSet = Set( 2, "set1", "seq1", 10, 70 )
+        secondSet = Set( 1, "set2", "seq1", 40, 100 )
+        
+        expSet1 = Set( 2, "set1", "seq1", 10, 39 )
+        expSet2 = Set( )        
+        
+        obsSet2 = firstSet.diff( secondSet )
+        obsSet1 = firstSet
+                
+        self.assertEquals( expSet1, obsSet1 ) 
+        self.assertEquals( expSet2, obsSet2 )
+        
+    def test_set2map(self):
+        set = Set( 1, "set", "seq", 1, 2 )
+        
+        expMap = Map( "set::1", "seq", 1, 2 )
+        obsMap = set.set2map()
+        
+        self.assertEquals( expMap, obsMap )
+    
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_Set ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_SetUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,1689 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+import time
+from commons.core.coord.Set import Set
+from commons.core.coord.Map import Map
+from commons.core.coord.SetUtils import SetUtils
+from commons.core.utils.FileUtils import FileUtils
+
+
+class Test_SetUtils( unittest.TestCase ):
+    
+    def test_changeIdInList_on_empty_list(self):
+        lSets = []
+        SetUtils.changeIdInList( lSets , 1 )
+        obsLSets = lSets
+        expLSets = []
+        self.assertEquals( expLSets , obsLSets )
+        
+    def test_changeIdInList_on_list_size_one(self):
+        set1 = Set( 1, "set1", "seq1", 1, 2 )
+        lSets = [ set1 ]
+        SetUtils.changeIdInList( lSets , 9 )
+        obsLSets = lSets
+        set1 = Set( 9, "set1", "seq1", 1, 2 )
+        expLSets = [ set1 ]
+        self.assertEquals( expLSets , obsLSets )
+        
+    def test_changeIdInList(self):
+        set1 = Set( 1, "set1", "seq1", 1, 2 )
+        set2 = Set( 2, "set2", "seq2", 2, 3 )
+        lSets = [ set1, set2 ]
+        SetUtils.changeIdInList( lSets , 9 )
+        obsLSets = lSets
+        set1 = Set( 9, "set1", "seq1", 1, 2 )
+        set2 = Set( 9, "set2", "seq2", 2, 3 )
+        expLSets = [ set1, set2 ]
+        
+        self.assertEquals( expLSets , obsLSets )
+        
+    def test_getOverlapLengthBetweenLists_all_list_are_empty (self):
+        lSets1 = []
+        lSets2 = []
+        
+        expOverlapSize = 0
+        obsOverlapSize = SetUtils.getOverlapLengthBetweenLists( lSets1, lSets2 )
+        
+        self.assertEquals( expOverlapSize, obsOverlapSize )
+        
+    def test_getOverlapLengthBetweenLists_list1_empty_list2_size_one (self):
+        lSets1 = []
+        lSets2 = [ Set( 9, "set1", "seq1", 1, 2 ) ]
+        
+        expOverlapSize = 0
+        obsOverlapSize = SetUtils.getOverlapLengthBetweenLists( lSets1, lSets2 )
+        
+        self.assertEquals( expOverlapSize, obsOverlapSize )
+        
+    def test_getOverlapLengthBetweenLists_list1_empty_list2_size_two (self):
+        lSets1 = []
+        lSets2 = [ Set( 9, "set1", "seq1", 1, 2 ), Set( 9, "set2", "seq2", 2, 3 ) ]
+        
+        expOverlapSize = 0
+        obsOverlapSize = SetUtils.getOverlapLengthBetweenLists( lSets1, lSets2 )
+        
+        self.assertEquals( expOverlapSize, obsOverlapSize )
+        
+    def test_getOverlapLengthBetweenLists_list1_size_one_list2_empty (self):
+        lSets1 = [ Set( 9, "set1", "seq1", 1, 2 ) ]
+        lSets2 = []
+        
+        expOverlapSize = 0
+        obsOverlapSize = SetUtils.getOverlapLengthBetweenLists( lSets1, lSets2 )
+        
+        self.assertEquals( expOverlapSize, obsOverlapSize )
+        
+    def test_getOverlapLengthBetweenLists_list1_size_one_list2_size_one_without_overlapp (self):
+        lSets1 = [ Set( 1, "set1", "seq1", 1, 2 ) ]
+        lSets2 = [ Set( 2, "set2", "seq2", 2, 3 ) ]
+        
+        expOverlapSize = 0
+        obsOverlapSize = SetUtils.getOverlapLengthBetweenLists( lSets1, lSets2 )
+        
+        self.assertEquals( expOverlapSize, obsOverlapSize )
+        
+    def test_getOverlapLengthBetweenLists_list1_size_one_list2_size_one_with_overlap_size_1 (self):
+        lSets1 = [ Set( 1, "set1", "seq1", 1, 2 ) ]
+        lSets2 = [ Set( 2, "set1", "seq1", 2, 3 ) ]
+        
+        expOverlapSize = 1
+        obsOverlapSize = SetUtils.getOverlapLengthBetweenLists( lSets1, lSets2 )
+        
+        self.assertEquals( expOverlapSize, obsOverlapSize )
+        
+    def test_getOverlapLengthBetweenLists_list1_size_one_list2_size_one_with_overlap_size_2 (self):
+        lSets1 = [ Set( 1, "set1", "seq1", 1, 2 ) ]
+        lSets2 = [ Set( 2, "set1", "seq1", 1, 3 ) ]
+        
+        expOverlapSize = 2
+        obsOverlapSize = SetUtils.getOverlapLengthBetweenLists( lSets1, lSets2 )
+        
+        self.assertEquals( expOverlapSize, obsOverlapSize )
+        
+    def test_getOverlapLengthBetweenLists_list1_size_one_list2_size_two_without_overlap_sets_in_list1_greater_than_sets_in_list2 (self):
+        lSets1 = [ Set( 1, "set1", "seq1", 4, 6 ) ]
+        lSets2 = [ Set( 2, "set2", "seq1", 2, 3 ), Set( 3, "set3", "seq3", 1, 2 ) ]
+        
+        expOverlapSize = 0
+        obsOverlapSize = SetUtils.getOverlapLengthBetweenLists( lSets1, lSets2 )
+        
+        self.assertEquals( expOverlapSize, obsOverlapSize )
+        
+    def test_getOverlapLengthBetweenLists_list1_size_one_list2_size_two_with_overlap_sets_in_list1_greater_than_sets_in_list2 (self):
+        lSets1 = [ Set( 1, "set1", "seq1", 4, 6 ) ]
+        lSets2 = [ Set( 2, "set2", "seq2", 2, 3 ), Set( 3, "set3", "seq1", 4, 5 ) ]
+        
+        expOverlapSize = 2
+        obsOverlapSize = SetUtils.getOverlapLengthBetweenLists( lSets1, lSets2 )
+        
+        self.assertEquals( expOverlapSize, obsOverlapSize )
+        
+    def test_getOverlapLengthBetweenLists_list1_size_one_list2_size_two_with_overlap_on_redundant_position (self):
+        lSets1 = [ Set( 1, "set1", "seq1", 1, 2 ) ]
+        lSets2 = [ Set( 2, "set2", "seq1", 2, 3 ), Set( 3, "set1", "seq1", 1, 2 ) ]
+        
+        expOverlapSize = 3
+        obsOverlapSize = SetUtils.getOverlapLengthBetweenLists( lSets1, lSets2 )
+        
+        self.assertEquals( expOverlapSize, obsOverlapSize )
+        
+    def test_getOverlapLengthBetweenLists_list1_size_two_list2_empty (self):
+        lSets1 = [ Set( 1, "set1", "seq1", 1, 2 ), Set( 2, "set2", "seq2", 2, 3 ) ]
+        lSets2 = []
+        
+        expOverlapSize = 0
+        obsOverlapSize = SetUtils.getOverlapLengthBetweenLists( lSets1, lSets2 )
+        
+        self.assertEquals( expOverlapSize, obsOverlapSize )
+        
+    def test_getOverlapLengthBetweenLists_on_different_seq_names (self):
+        lSets1 = [ Set( 1, "set1", "seq1", 1, 2 ), Set( 2, "set2", "seq2", 2, 3 ) ]
+        lSets2 = [ Set( 3, "set1", "seq2", 4, 5 ), Set( 5, "set2", "seq4", 2, 3 ) ]
+        
+        expOverlapSize = 0
+        obsOverlapSize = SetUtils.getOverlapLengthBetweenLists( lSets1, lSets2 )
+        
+        self.assertEquals( expOverlapSize, obsOverlapSize )
+        
+    def test_getOverlapLengthBetweenLists_list1_size_two_list2_size_two_with_overlap (self):
+        lSets1 = [ Set( 1, "set1", "seq1", 1, 6 ), Set( 2, "set2", "seq2", 2, 3 ) ]
+        lSets2 = [ Set( 3, "set1", "seq1", 1, 2 ), Set( 2, "set2", "seq3", 2, 3 ) ]
+        
+        expOverlapSize = 2
+        obsOverlapSize = SetUtils.getOverlapLengthBetweenLists( lSets1, lSets2 )
+        
+        self.assertEquals( expOverlapSize, obsOverlapSize )
+        
+    def test_areSetsOverlappingBetweenLists_list2_empty(self):
+        tuple1 = ("1","chr1","seq1", "100","110")
+        tuple2 = ("1","chr1","seq1", "200","220")
+        tuple3 = ("1","chr1","seq1", "300","330")
+        setList1 = self._makeSetListFromTupleList([tuple1, tuple2, tuple3])
+        
+        setList2 = []
+        
+        expRes = False
+        obsRes = SetUtils.areSetsOverlappingBetweenLists( setList1, setList2 )
+        
+        self.assertEquals( expRes, obsRes )
+        
+    def test_areSetsOverlappingBetweenLists_list2_size1(self):
+        tuple1 = ("1","chr1","seq1", "9","11")
+        tuple2 = ("1","chr1","seq1", "20","22")
+        tuple3 = ("1","chr1","seq1", "30","33")
+        setList1 = self._makeSetListFromTupleList( [ tuple1, tuple2, tuple3 ] )
+        
+        tuple11 = ("1","chr1", "seq1", "8","11")
+        setList2 = self._makeSetListFromTupleList( [ tuple11 ] )
+        
+        expRes = True
+        obsRes = SetUtils.areSetsOverlappingBetweenLists( setList1, setList2 )
+        
+        self.assertEquals( expRes, obsRes )
+        
+    def test_areSetsOverlappingBetweenLists_list1_greater_list2(self):
+        tuple1 = ("1","chr1","seq1","100","110")
+        tuple2 = ("1","chr1","seq1","200","220")
+        tuple3 = ("1","chr1","seq1","300","330")
+        setList1 = self._makeSetListFromTupleList( [ tuple1, tuple2, tuple3 ] )
+        
+        tuple11 = ("1","chr1","seq1", "10","11")
+        tuple22 = ("1","chr1","seq1", "20","22")
+        tuple33 = ("1","chr1","seq1", "30","33")
+        setList2 = self._makeSetListFromTupleList( [ tuple11, tuple22, tuple33 ] )
+        
+        expRes = False
+        obsRes = SetUtils.areSetsOverlappingBetweenLists( setList1, setList2 )
+        
+        self.assertEquals( expRes, obsRes )
+    
+    def test_areSetsOverlappingBetweenLists_unordered_first_item_of_list1_greater_second_item_smaller(self):
+        tuple1 = ("1","chr1","seq1","400","440")
+        tuple2 = ("1","chr1","seq1","1","11")
+        setList1 = self._makeSetListFromTupleList( [ tuple1, tuple2 ] )
+        
+        tuple11 = ("1","chr1","seq1","15","17")
+        tuple22 = ("1","chr1","seq1", "20","22")
+        tuple33 = ("1","chr1","seq1","30","33")
+        setList2 = self._makeSetListFromTupleList( [ tuple11, tuple22, tuple33 ] )
+        
+        expRes = False
+        obsRes = SetUtils.areSetsOverlappingBetweenLists( setList1, setList2 )
+        
+        self.assertEquals( expRes, obsRes )
+ 
+    def test_areSetsOverlappingBetweenLists_unorderd_second_item_of_list1_overlap_first_item(self):
+        tuple1 = ("1","chr1","seq1","400","440")
+        tuple2 = ("1","chr1","seq1", "1","18")
+        setList1 = self._makeSetListFromTupleList( [ tuple1, tuple2 ] )
+        
+        tuple11 = ("1","chr1","seq1","15","17")
+        tuple22 = ("1","chr1","seq1","20","22")
+        tuple33 = ("1","chr1","seq1","30","33")
+        setList2 = self._makeSetListFromTupleList( [ tuple11, tuple22, tuple33 ] )
+        
+        expRes = True
+        obsRes = SetUtils.areSetsOverlappingBetweenLists( setList1, setList2 )
+        
+        self.assertEquals( expRes, obsRes )
+    
+    def test_areSetsOverlappingBetweenLists_last_item_list1_overlap_last_item_list2(self):
+        tuple1 = ("1","chr1","seq1","400","440")
+        tuple2 = ("1","chr1","seq1","320","340")
+        pathList1 = self._makeSetListFromTupleList( [ tuple1, tuple2 ] )
+        
+        tuple11 = ("1","chr1","seq1","100","110")
+        tuple22 = ("1","chr1","seq1","200","220")
+        tuple33 = ("1","chr1","seq1","300","330")
+        pathList2 = self._makeSetListFromTupleList( [ tuple11, tuple22, tuple33 ] )
+        
+        expRes = True
+        obsRes = SetUtils.areSetsOverlappingBetweenLists( pathList1, pathList2 )
+        
+        self.assertEquals( expRes, obsRes )
+                
+    def test_getCumulLength_empty_list(self):
+        lSets = []
+        
+        expSize = 0
+        obsSize = SetUtils.getCumulLength( lSets )
+        
+        self.assertEquals( expSize, obsSize )
+        
+    def test_getCumulLength_1_item(self):
+        lSets = [ Set( 1, "set1", "seq1", 1, 6 ) ]
+        
+        expSize = 6
+        obsSize = SetUtils.getCumulLength( lSets )
+        
+        self.assertEquals( expSize, obsSize )
+        
+    def test_getCumulLength_2_items(self):
+        lSets = [ Set( 1, "set1", "seq1", 1, 6 ), Set( 1, "set1", "seq1", 1, 2 ) ]
+        
+        expSize = 8
+        obsSize = SetUtils.getCumulLength( lSets )
+        
+        self.assertEquals( expSize, obsSize )
+        
+    def test_getCumulLength_complex(self):
+        set8 = Set(498, "(TACATA)25", "Mela_Blaster_Grouper_611_MAP_20", 17, 348)
+        set5 = Set(502, "(GGAGA)2", "Mela_Blaster_Grouper_611_MAP_20", 356, 366)
+        set6 = Set(503, "(TTTAAAGAACCC)2", "Mela_Blaster_Grouper_611_MAP_20", 433, 457)
+        set7 = Set(504, "(TATAA)2", "Mela_Blaster_Grouper_611_MAP_20", 484, 495) 
+        lSets = [ set8, set5, set6, set7 ] 
+        expSize = 380
+        obsSize = SetUtils.getCumulLength( lSets )
+        
+        self.assertEquals( expSize, obsSize )
+        
+    def test_getListBoundaries_one_set(self):
+        lSets = [ Set( 1, "set1", "seq1", 3, 8 ) ]
+        
+        expTuple = ( 3, 8 )
+        obsTuple = SetUtils.getListBoundaries( lSets )
+        
+        self.assertEquals( expTuple, obsTuple )
+        
+    def test_getListBoundaries_two_sets(self):
+        lSets = [ Set( 1, "set1", "seq1", 3, 8 ), Set( 2, "set2", "seq2", 5, 10 ) ]
+        
+        expTuple = ( 3, 10 )
+        obsTuple = SetUtils.getListBoundaries( lSets )
+        
+        self.assertEquals( expTuple, obsTuple )
+ 
+    def test_writeListInFile_empty_list(self):
+        lSets = [ ]
+        expFileName = "expFileName"
+        fileHandle = open(expFileName, "w")
+        fileHandle.close()
+ 
+        obsFileName = "obsFileName"
+        fileHandle = open(obsFileName, "w")
+        SetUtils.writeListInFile(lSets, obsFileName, "w")
+        fileHandle.close()
+         
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        
+        os.remove(obsFileName)
+        os.remove(expFileName)
+        
+    def test_writeListInFile_list_one_set(self):
+        lSets = [ Set( 1, "set1", "seq1", 3, 8 ) ]
+        line =  "1\tset1\tseq1\t3\t8\n"
+        expFileName = "expFileName"
+ 
+        fileHandle = open(expFileName, "w")
+        fileHandle.write(line)
+        fileHandle.close()
+ 
+        obsFileName = "obsFileName"
+        fileHandle = open(obsFileName, "w")
+        SetUtils.writeListInFile(lSets, obsFileName, "w")
+        fileHandle.close()
+         
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        
+        os.remove(obsFileName)
+        os.remove(expFileName)
+        
+        
+    def test_getDictOfListsWithIdAsKey_empty_list( self ):
+        lSets = []
+        expDic = {}
+        obsDic = SetUtils.getDictOfListsWithIdAsKey( lSets )
+        self.assertEquals( expDic, obsDic )
+        
+        
+    def test_getDictOfListsWithIdAsKey_one_set( self ):
+        lSets = [ Set( 2, "set2", "seq2", 3, 8 ) ]
+        expDic = { 2: [ Set( 2, "set2", "seq2", 3, 8 ) ] }
+        obsDic = SetUtils.getDictOfListsWithIdAsKey( lSets )
+        self.assertEquals( expDic, obsDic )
+        
+        
+    def test_getDictOfListsWithIdAsKey_two_sets_with_same_id( self ):
+        lSets = [ Set( 2, "set2", "seq2", 10, 50 ), Set( 2, "set2", "seq2", 3, 8 )]
+        expDic = { 2: [Set( 2, "set2", "seq2", 10, 50 ), Set( 2, "set2", "seq2", 3, 8 )] }
+        obsDic = SetUtils.getDictOfListsWithIdAsKey( lSets )
+        self.assertEquals( expDic, obsDic )
+        
+        
+    def test_getDictOfListsWithIdAsKey_sets_with_3_different_id( self ):
+        set1 = Set( 1, "set2", "seq2", 10, 50 )
+        set2 = Set( 1, "set2", "seq2", 20, 50 )
+        set3 = Set( 2, "set2", "seq2", 30, 50 )
+        set4 = Set( 2, "set2", "seq2", 40, 50 )
+        set5 = Set( 3, "set2", "seq2", 1, 2 )
+        lSets = [ set1, set2, set3, set4, set5 ]
+        expDic = { 1: [set1, set2],
+                   2: [set3, set4],
+                   3: [set5] }
+        obsDic = SetUtils.getDictOfListsWithIdAsKey( lSets )
+        self.assertEquals( expDic, obsDic )
+        
+        
+    def test_getDictOfListsWithIdAsKeyFromFile(self):
+        setFile = "dummySetFile"
+        setFileHandler = open( setFile, "w" )
+        setFileHandler.write( "1\tseq31\tchr1\t151\t250\n" )
+        setFileHandler.write( "2\tseq27\tchr2\t301\t500\n" )
+        setFileHandler.write( "2\tseq27\tchr2\t601\t650\n" )
+        setFileHandler.close()
+        
+        dExp = { 1: [ Set( 1, "seq31", "chr1", 151, 250 ) ],
+                2: [ Set( 2, "seq27", "chr2", 301, 500 ),
+                    Set( 2, "seq27", "chr2", 601, 650 ) ] }
+        dObs = SetUtils.getDictOfListsWithIdAsKeyFromFile( setFile )
+        
+        self.assertEquals( dExp, dObs )
+        
+        os.remove( setFile )
+        
+        
+    def test_getMapListFromSetList_empty_list(self):
+        lSets = []
+        
+        expLMap = []
+        obsLMap = SetUtils.getMapListFromSetList(lSets)
+        
+        self.assertEquals(expLMap, obsLMap)
+        
+    def test_getMapListFromSetList_one_set(self):
+        lSets = [ Set( 1, "set", "seq1", 1, 6 )]
+        map1 = Map("set::1","seq1",1,6)
+        
+        expLMap = [ map1 ]
+        obsLMap = SetUtils.getMapListFromSetList(lSets)
+        
+        self.assertEquals(expLMap, obsLMap)
+                    
+    def test_getMapListFromSetList_two_sets(self):
+        lSets = [ Set( 1, "set", "seq1", 1, 6 ), Set( 2, "set", "seq2", 3, 8 ) ]
+        map1 = Map("set::1","seq1",1,6)
+        map2 = Map("set::2","seq2",3,8)
+        
+        expLMap = [ map1, map2 ]
+        obsLMap = SetUtils.getMapListFromSetList(lSets)
+        
+        self.assertEquals(expLMap, obsLMap)
+        
+    def test_getSetListFromMapList_empty_list(self):
+        lMap =[]
+        expLSets = []
+        obsLSets = SetUtils.getSetListFromMapList(lMap)
+        
+        self.assertEquals(expLSets, obsLSets)
+        
+    def test_getSetListFromMapList_one_map(self):
+        map1 = Map( "map1","seq1",1,6)
+        lMap =[ map1 ]
+        expLSets = [ Set( 1, "map1", "seq1", 1, 6 ) ]
+        obsLSets = SetUtils.getSetListFromMapList(lMap)
+                            
+        self.assertEquals(expLSets, obsLSets)
+        
+    def test_getSetListFromMapList_two_maps(self):
+        map1 = Map( "map1","seq1",1,6)
+        map2 = Map( "map2","seq2",3,8)
+        lMap =[ map1,map2 ]
+        expLSets = [ Set( 1, "map1", "seq1", 1, 6 ), Set( 2, "map2", "seq2", 3, 8 ) ]
+        obsLSets = SetUtils.getSetListFromMapList(lMap)
+        
+        self.assertEquals(expLSets, obsLSets)
+        
+    def test_getSetListFromMapList_list_with_one_empty_map(self):
+        map1 = Map( "map1","seq1",1,6)
+        map2 = Map()
+        lMap =[ map1,map2 ]
+        expLSets = [ Set( 1, "map1", "seq1", 1, 6 ), Set(2, ) ]
+        obsLSets = SetUtils.getSetListFromMapList(lMap)
+        
+        self.assertEquals(expLSets, obsLSets)
+        
+    def test_mergeSetsInList(self):
+        set1 = Set( 1, "set1", "seq1", 1, 6 )
+        set2 = Set( 2, "set2", "seq1", 3, 6 )
+        set3 = Set( 3, "set3", "seq1", 3, 5 )
+        set4 = Set( 4, "set4", "seq1", 1, 2 )
+        lSets = [ set1, set2, set3, set4 ]
+        
+        obsList = SetUtils.mergeSetsInList( lSets )
+        expList = [ Set( 1, "set1", "seq1", 1, 6 ) ]
+        
+        self.assertEquals( expList, obsList )
+        
+        
+    def test_mergeSetsInList_with_reverse_only(self):
+        set1 = Set( 1, "set1", "seq1", 6, 1 )
+        set2 = Set( 2, "set2", "seq1", 6, 3 )
+        set3 = Set( 3, "set3", "seq1", 5, 3 )
+        set4 = Set( 4, "set4", "seq1", 2, 1 )
+        lSets = [ set1, set2, set3, set4 ]
+        
+        obsList = SetUtils.mergeSetsInList( lSets )
+        expList = [ Set( 1, "set1", "seq1", 6, 1 ) ]
+        
+        self.assertEquals( expList, obsList )
+        
+        
+    def test_mergeSetsInList_with_direct_and_reverse(self):
+        set1 = Set( 1, "set1", "seq1", 6, 1 )
+        set2 = Set( 2, "set2", "seq1", 6, 3 )
+        set3 = Set( 3, "set3", "seq1", 3, 5 )
+        set4 = Set( 4, "set4", "seq1", 2, 1 )
+        lSets = [ set1, set2, set3, set4 ]
+        
+        obsList = SetUtils.mergeSetsInList( lSets )
+        expList = [ set1 ]
+        
+        self.assertEquals( expList, obsList )
+        
+        
+    def test_mergeSetsInList_with_empty_set(self):
+        set1 = Set( 1, "set1", "seq1", 1, 6 )
+        set2 = Set()
+        set3 = Set( 3, "set3", "seq1", 3, 5 )
+        set4 = Set( 4, "set4", "seq1", 1, 2 )
+        lSets = [ set1, set2, set3, set4 ]
+        
+        obsList = SetUtils.mergeSetsInList( lSets )
+        expList = [ set2, set1 ]
+        
+        self.assertEquals( expList, obsList )
+        
+        
+    def test_mergeSetsInList_empty_list(self):
+        lSets = []
+        
+        obsList = SetUtils.mergeSetsInList( lSets )
+        expList = []
+         
+        self.assertEquals( expList, obsList )
+        
+        
+    def test_mergeSetsInList_one_set (self):
+        set1 = Set( 1, "set1", "seq1", 1, 6 )
+        lSets = [ set1 ]
+        
+        obsLSets = SetUtils.mergeSetsInList( lSets )
+        expLSets = [ set1 ]
+         
+        self.assertEquals( expLSets, obsLSets )
+        
+        
+    def test_mergeSetsInList_diffSeqnames_without_overlapping(self):
+        set1 = Set( 1, "set1", "seq1", 1, 6 )
+        set2 = Set( 1, "set2", "seq2", 11, 16 )
+        lSets = [ set1, set2 ]
+        
+        obsLSets = SetUtils.mergeSetsInList( lSets )
+        expLSets = [ set1, set2 ]
+        
+        self.assertEquals( expLSets, obsLSets )
+        
+ 
+    def test_mergeSetsInList_diffSeqnames_overlapping(self):
+        set1 = Set( 1, "set1", "seq1", 1, 6 )
+        set2 = Set( 1, "set2", "seq2", 2, 5 )
+        lSets = [ set1, set2 ]
+        
+        obsLSets = SetUtils.mergeSetsInList( lSets )
+        expLSets = [ set1, set2 ]
+        
+        self.assertEquals( expLSets, obsLSets )
+        
+ 
+    def test_mergeSetsInList_sameSeqnames_without_overlapping(self):
+        set1 = Set( 1, "set1", "seq1", 1, 6 )
+        set2 = Set( 1, "set2", "seq1", 11, 16 )
+        lSets = [ set1, set2 ]
+        
+        obsLSets = SetUtils.mergeSetsInList( lSets )
+        expLSets = [ set1, set2 ]
+        
+        self.assertEquals( expLSets, obsLSets )
+        
+    def test_mergeSetsInList_complex(self):
+        set1 = Set(498, "(ACATATAATAA)10", "Mela_Blaster_Grouper_611_MAP_20", 77, 181)
+        set2 = Set(499, "(TACATA)25", "Mela_Blaster_Grouper_611_MAP_20", 17, 166)
+        set3 = Set(500, "(ATAAAATAC)26", "Mela_Blaster_Grouper_611_MAP_20", 94, 348)
+        set4 = Set(501, "(TAA)15", "Mela_Blaster_Grouper_611_MAP_20", 257, 303)
+        set5 = Set(502, "(GGAGA)2", "Mela_Blaster_Grouper_611_MAP_20", 356, 366)
+        set6 = Set(503, "(TTTAAAGAACCC)2", "Mela_Blaster_Grouper_611_MAP_20", 433, 457)
+        set7 = Set(504, "(TATAA)2", "Mela_Blaster_Grouper_611_MAP_20", 484, 495)    
+        lSets = [ set1, set2, set3, set4, set5, set6, set7 ]  
+        obsLSets = SetUtils.mergeSetsInList( lSets )
+        
+        set8 = Set(498, "(TACATA)25", "Mela_Blaster_Grouper_611_MAP_20", 17, 348)
+        
+        expLSets = [ set8, set5, set6, set7 ]
+        
+        self.assertEquals( expLSets, obsLSets )
+        
+    def test_getSetListUnjoined_listToKeep_empty_listToUnjoin_empty (self):
+        setListToKeep = []
+        setListToUnjoin = []
+ 
+        obsLSets = SetUtils.getSetListUnjoined(setListToKeep, setListToUnjoin)
+        expLSets = []
+ 
+        self.assertEquals(expLSets, obsLSets)
+        
+    def test_getSetListUnjoined_listToKeep_empty (self):
+        setListToKeep = []
+        
+        setUnjoin1 = Set( 1, "set", "seq", 1, 3 )
+        setUnjoin2 = Set( 1, "set", "seq", 2, 3 )
+        setUnjoin3 = Set( 1, "set", "seq", 5, 7 )
+        setListToUnjoin = [ setUnjoin1, setUnjoin2, setUnjoin3 ]
+ 
+        obsLSets = SetUtils.getSetListUnjoined(setListToKeep, setListToUnjoin)
+        expLSets = [ setListToUnjoin ]
+ 
+        self.assertEquals(expLSets, obsLSets)       
+        
+    def test_getSetListUnjoined_listToKeep_empty_listToUnjoin_size1 (self):
+        setListToKeep = []
+        
+        setUnjoin = Set( 1, "set", "seq", 1, 3 )
+        setListToUnjoin = [ setUnjoin ]
+ 
+        obsLSets = SetUtils.getSetListUnjoined(setListToKeep, setListToUnjoin)
+        expLSets = [ setListToUnjoin ]
+ 
+        self.assertEquals(expLSets, obsLSets)     
+        
+    def test_getSetListUnjoined_listToKeep_size1_listToUnjoin_empty (self):
+        setKeep = Set( 1, "set", "seq", 1, 3 )
+        setListToKeep = [ setKeep ]
+        
+        setListToUnjoin = []
+ 
+        obsLSets = SetUtils.getSetListUnjoined(setListToKeep, setListToUnjoin)
+        expLSets = []
+ 
+        self.assertEquals(expLSets, obsLSets)  
+       
+    def test_getSetListUnjoined_listToKeep_size1_listToUnjoin_size1 (self):
+        setKeep = Set( 1, "set", "seq", 1, 3 )
+        setListToKeep = [ setKeep ]
+        
+        setUnjoin = Set( 1, "set", "seq", 5, 9 )
+        setListToUnjoin = [ setUnjoin ]
+ 
+        obsLSets = SetUtils.getSetListUnjoined(setListToKeep, setListToUnjoin)
+        expLSets = [ setListToUnjoin ]
+ 
+        self.assertEquals(expLSets, obsLSets)
+ 
+    def test_getSetListUnjoined_listToKeep_size1_listToUnjoin_size2_noSplit_item_in_listToKeep_smaller_item_in_listToUnjoin (self):
+        setKeep = Set( 1, "set", "seq", 1, 3 )
+        setListToKeep = [ setKeep ]
+        
+        setUnjoin1 = Set( 1, "set", "seq", 5, 9 )
+        setUnjoin2 = Set( 1, "set", "seq", 11, 16 )
+        setListToUnjoin = [ setUnjoin1, setUnjoin2 ]
+ 
+        obsLSets = SetUtils.getSetListUnjoined(setListToKeep, setListToUnjoin)
+        expLSets = [ setListToUnjoin ]
+ 
+        self.assertEquals(expLSets, obsLSets)  
+ 
+    def test_getSetListUnjoined_listToKeep_size1_listToUnjoin_size3_noSplit_item_in_listToKeep_smaller_item_in_listToUnjoin (self):
+        setKeep = Set( 1, "set", "seq", 1, 3 )
+        setListToKeep = [ setKeep ]
+        
+        setUnjoin1 = Set( 1, "set", "seq", 5, 9 )
+        setUnjoin2 = Set( 1, "set", "seq", 11, 16 )
+        setUnjoin3 = Set( 1, "set", "seq", 21, 26 )
+        setListToUnjoin = [ setUnjoin1, setUnjoin2, setUnjoin3 ]
+ 
+        obsLSets = SetUtils.getSetListUnjoined(setListToKeep, setListToUnjoin)
+        expLSets = [ setListToUnjoin ]
+ 
+        self.assertEquals(expLSets, obsLSets)  
+ 
+    def test_getSetListUnjoined_listToKeep_size1_listToUnjoin_size2_noSplit_item_in_listToUnjoin_smaller_item_in_listToKeep (self):
+        setKeep = Set( 1, "set", "seq", 10, 13 )
+        setListToKeep = [ setKeep ]
+        
+        setUnjoin1 = Set( 1, "set", "seq", 5, 9 )
+        setUnjoin2 = Set( 1, "set", "seq", 1, 3 )
+        setListToUnjoin = [ setUnjoin1, setUnjoin2 ]
+ 
+        obsLSets = SetUtils.getSetListUnjoined(setListToKeep, setListToUnjoin)
+        expLSets = [ SetUtils.getSetListSortedByIncreasingMinThenMax( setListToUnjoin ) ]
+ 
+        self.assertEquals(expLSets, obsLSets)   
+ 
+    def test_getSetListUnjoined_listToKeep_size3_listToUnjoin_size2_oneSplit_item_in_listToKeep_smaller_item_in_listToUnjoin (self):
+        setKeep1 = Set( 1, "set", "seq", 1, 1 )
+        setKeep2 = Set( 1, "set", "seq", 21, 30 )
+        setKeep3 = Set( 1, "set", "seq", 61, 70 )
+        setListToKeep = [ setKeep1, setKeep2, setKeep3 ]
+        
+        setUnjoin1 = Set( 1, "set", "seq", 41, 50 )
+        setUnjoin2 = Set( 2, "set", "seq", 81, 90 )
+        setListToUnjoin = [ setUnjoin1, setUnjoin2 ]
+ 
+        expLSets = [ [ setUnjoin1 ], [ setUnjoin2 ] ]
+        
+        obsLSets = SetUtils.getSetListUnjoined(setListToKeep, setListToUnjoin)
+ 
+        self.assertEquals(expLSets, obsLSets) 
+        
+    def test_getSetListUnjoined_listToKeep_size3_listToUnjoin_size3_twoSplits_item_in_listToUnjoin_smaller_item_in_listToKeep(self):
+        setKeep1 = Set( 1, "set", "seq", 21, 30 )
+        setKeep2 = Set( 1, "set", "seq", 41, 50 )
+        setKeep3 = Set( 1, "set", "seq", 81, 90 )
+        setListToKeep = [ setKeep1, setKeep2, setKeep3 ]
+        
+        setUnjoin1 = Set( 1, "set", "seq", 1, 10 )
+        setUnjoin2 = Set( 2, "set", "seq", 61, 70 )
+        setUnjoin3 = Set( 2, "set", "seq", 101, 110 )
+        setListToUnjoin = [ setUnjoin1, setUnjoin2, setUnjoin3 ]
+        
+        expLSets = [ [ setUnjoin1 ], [ setUnjoin2 ], [ setUnjoin3 ] ]
+        
+        obsLSets = SetUtils.getSetListUnjoined( setListToKeep, setListToUnjoin )
+        
+        self.assertEquals(expLSets, obsLSets) 
+        
+    def test_getSetListUnjoined_listToKeep_size1_listToUnjoin_size2_split(self):
+        setKeep1 = Set( 1, "set", "seq", 51, 80 )
+        setListToKeep = [ setKeep1 ]        
+        
+        setUnjoin1 = Set( 1, "set", "seq", 21, 40 )
+        setUnjoin2 = Set( 1, "set", "seq", 101, 150 )
+        setListToUnjoin = [ setUnjoin1, setUnjoin2 ]
+        
+        expLSets = [ [setUnjoin1] , [setUnjoin2] ]
+               
+        obsLSets = SetUtils.getSetListUnjoined( setListToKeep, setListToUnjoin )
+        
+        self.assertEquals( expLSets, obsLSets )
+ 
+    def test_getSetListUnjoined_listToKeep_size2_listToUnjoin_size2_split(self):
+        setKeep1 = Set( 1, "set", "seq", 1, 15 )
+        setKeep2 = Set( 1, "set", "seq", 81, 130 )
+        setListToKeep = [ setKeep1, setKeep2 ]
+        
+        setUnjoin1 = Set( 1, "set", "seq", 21, 40 )
+        setUnjoin2 = Set( 1, "set", "seq", 201, 250 )
+        setListToUnjoin = [ setUnjoin1, setUnjoin2 ]
+        
+        expLSets = [ [setUnjoin1] , [setUnjoin2] ] 
+        
+        obsLSets = SetUtils.getSetListUnjoined( setListToKeep, setListToUnjoin )
+        
+        self.assertEquals( expLSets, obsLSets )
+        
+    def test_getSetListUnjoined_listToKeep_size1_listToUnjoin_ordered_OneSplit(self):
+        setKeep = Set( 1, "set", "seq", 120, 180 )
+        setListToKeep = [ setKeep ]
+        
+        setUnjoin1 = Set( 1, "set", "seq", 100, 110 )
+        setUnjoin2 = Set( 1, "set", "seq", 200, 210 )
+        setUnjoin3 = Set( 1, "set", "seq", 250, 280 )
+        setListToUnjoin = [ setUnjoin1, setUnjoin2, setUnjoin3 ]
+ 
+        obsLSets = SetUtils.getSetListUnjoined(setListToKeep, setListToUnjoin)
+        expLSets = [ [setUnjoin1], [setUnjoin2, setUnjoin3] ]
+ 
+        self.assertEquals(expLSets, obsLSets)
+        
+    def test_getSetListUnjoined_listToKeep_size1_listToUnjoin_unordered_OneSplit(self):
+        setKeep = Set( 1, "set", "seq", 120, 180 )
+        setListToKeep = [ setKeep ]
+        
+        setUnjoin1 = Set( 1, "set", "seq", 200, 210 )
+        setUnjoin2 = Set( 1, "set", "seq", 250, 280 )
+        setUnjoin3 = Set( 1, "set", "seq", 100, 110 )
+        setListToUnjoin = [ setUnjoin1, setUnjoin2, setUnjoin3 ]
+ 
+        obsLSets = SetUtils.getSetListUnjoined(setListToKeep, setListToUnjoin)
+        expLSets = [ [setUnjoin3], [setUnjoin1, setUnjoin2] ]
+ 
+        self.assertEquals(expLSets, obsLSets)
+ 
+    def test_getSetListUnjoined_listToKeep_size2_listToUnjoin_size4_twoSplits(self):
+        setKeep1 = Set( 1, "set", "seq", 21, 30 )
+        setKeep2 = Set( 1, "set", "seq", 81, 90 )
+        setListToKeep = [ setKeep1, setKeep2 ]
+                
+        setUnjoin1 = Set( 1, "set", "seq", 1, 10 )
+        setUnjoin2 = Set( 1, "set", "seq", 41, 50 )
+        setUnjoin3 = Set( 1, "set", "seq", 61, 70 )
+        setUnjoin4 = Set( 1, "set", "seq", 101, 110 )
+        setListToUnjoin = [ setUnjoin1, setUnjoin2, setUnjoin3, setUnjoin4 ]
+        
+        expLSets = [ [setUnjoin1], [ setUnjoin2, setUnjoin3 ], [setUnjoin4] ]
+        
+        obsLSets = SetUtils.getSetListUnjoined(setListToKeep, setListToUnjoin)
+        
+        self.assertEquals( expLSets, obsLSets )
+        
+    def test_getSetListWithoutDuplicates_empty_list(self):
+        lSets = []
+        obsLSets = SetUtils.getSetListWithoutDuplicates( lSets )        
+        expLSets = []
+        self.assertEquals( expLSets, obsLSets )
+        
+    def test_getSetListWithoutDuplicates_list_size1(self):
+        set = Set( 1, "set", "seq", 100, 110 )
+        lSets = [ set ]
+        obsLSets = SetUtils.getSetListWithoutDuplicates( lSets )
+        expLSets = lSets
+        self.assertEquals( expLSets, obsLSets )
+        
+    def test_getSetListWithoutDuplicates_list_with_only_doublons(self):
+        set1 = Set( 1, "set", "seq", 100, 110 )
+        set2 = Set( 1, "set", "seq", 100, 110 )
+        set3 = Set( 1, "set", "seq", 100, 110 )
+        set4 = Set( 1, "set", "seq", 100, 110 )
+        lSets = [set1, set2, set3, set4]
+        
+        obsLSets = SetUtils.getSetListWithoutDuplicates( lSets )
+        
+        expLSets = [ set1 ]
+        
+        self.assertEquals( expLSets, obsLSets )
+        
+    def test_getSetListWithoutDuplicates_list_with_doublons_at_start_and_at_end(self):
+        set1 = Set( 1, "set", "seq", 200, 210 )
+        set2 = Set( 1, "set", "seq", 100, 110 )
+        set3 = Set( 1, "set", "seq", 300, 310 )
+        set4 = Set( 1, "set", "seq", 100, 110 )
+        lSets = [set1, set2, set3, set4]
+        
+        obsLSets = SetUtils.getSetListWithoutDuplicates( lSets )
+        
+        expLSets = [ set1, set2, set3 ]
+        expLSets = SetUtils.getSetListSortedByIncreasingMinThenMax(expLSets)
+        
+        self.assertEquals( expLSets, obsLSets )
+        
+    def test_getSetListWithoutDuplicates_list_with_contiguous_doublons(self):
+        set1 = Set( 1, "set", "seq", 200, 210 )
+        set2 = Set( 1, "set", "seq", 100, 110 )
+        set3 = Set( 1, "set", "seq", 100, 110 )
+        set4 = Set( 1, "set", "seq", 300, 310 )
+        lSets = [set1, set2, set3, set4]
+        
+        obsLSets = SetUtils.getSetListWithoutDuplicates( lSets )
+        
+        expLSets = [ set1, set2, set4 ]
+        expLSets = SetUtils.getSetListSortedByIncreasingMinThenMax(expLSets)
+        
+        self.assertEquals( expLSets, obsLSets )
+        
+    def test_getSetListWithoutDuplicates_list_with_one_doublon(self):
+        set1 = Set( 1, "set", "seq", 200, 210 )
+        set2 = Set( 1, "set", "seq", 100, 110 )
+        set3 = Set( 1, "set", "seq", 210, 250 )
+        set4 = Set( 1, "set", "seq", 100, 110 )
+        set5 = Set( 1, "set", "seq", 300, 310 )
+        lSets = [set1, set2, set3, set4, set5]
+        
+        obsLSets = SetUtils.getSetListWithoutDuplicates( lSets )
+        
+        expLSets = [ set1, set2, set3, set5 ]
+        expLSets = SetUtils.getSetListSortedByIncreasingMinThenMax(expLSets)
+        
+        self.assertEquals( expLSets, obsLSets )
+        
+    def test_getSetListWithoutDuplicates_list_with_two_doublons(self):
+        set1 = Set( 1, "set", "seq", 200, 210 )
+        set2 = Set( 1, "set", "seq", 100, 110 )
+        set3 = Set( 1, "set", "seq", 210, 250 )
+        set4 = Set( 1, "set", "seq", 230, 250 )
+        set5 = Set( 1, "set", "seq", 210, 250 )
+        set6 = Set( 1, "set", "seq", 100, 110 )
+        set7 = Set( 1, "set", "seq", 300, 310 )
+        lSets = [set1, set2, set3, set4, set5, set6, set7]
+        
+        obsLSets = SetUtils.getSetListWithoutDuplicates( lSets )
+        
+        expLSets = [ set1, set2, set3, set4, set7 ]
+        expLSets = SetUtils.getSetListSortedByIncreasingMinThenMax(expLSets)
+        
+        self.assertEquals( expLSets, obsLSets )
+       
+    def test_getSetListSortedByIncreasingMinThenMax_alreadyOrdered_diffIdentifier(self):
+        set1 = Set( 1, "set1", "seq1", 1, 10 )
+        set2 = Set( 2, "set1", "seq1", 21, 30 )
+        lSets = [ set1, set2 ]
+        
+        expList = [ set1, set2 ]
+        
+        obsList = SetUtils.getSetListSortedByIncreasingMinThenMax( lSets )
+        
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getSetListSortedByIncreasingMinThenMax_unordered_diffIdentifier(self):
+        set1 = Set( 1, "set1", "seq1", 21, 30 )
+        set2 = Set( 2, "set1", "seq1", 1, 10 )
+        lSets = [ set1, set2 ]
+        
+        expList = [ set2, set1 ]
+        
+        obsList = SetUtils.getSetListSortedByIncreasingMinThenMax( lSets )
+        
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getSetListSortedByIncreasingMinThenMax_unordered_sameIdentifier(self):
+        set1 = Set( 1, "set1", "seq1", 21, 30 )
+        set2 = Set( 1, "set1", "seq1", 1, 10 )
+        lSets = [ set1, set2 ]
+        
+        expList = [ set2, set1 ]
+        
+        obsList = SetUtils.getSetListSortedByIncreasingMinThenMax( lSets )
+        
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getSetListSortedByIncreasingMinThenMax_unordered_overlapping(self):
+        set1 = Set( 2, "set1", "seq1", 6, 15 )
+        set2 = Set( 1, "set1", "seq1", 1, 10 )
+        lSets = [ set1, set2 ]
+        
+        expList = [ set2, set1 ]
+        
+        obsList = SetUtils.getSetListSortedByIncreasingMinThenMax( lSets )
+        
+        self.assertEqual( expList, obsList )
+        
+    def test_getSetListSortedByIncreasingMinThenMax_unordered_sameMin_threeSets(self):
+        set1 = Set( 1, "set1", "seq1", 1, 15 )
+        set2 = Set( 2, "set2", "seq1", 1, 10 )
+        set3 = Set( 3, "set3", "seq1", 1, 12 )
+        lSets = [ set1, set2, set3 ]
+        
+        expList = [ set2, set3, set1 ]
+        
+        obsList = SetUtils.getSetListSortedByIncreasingMinThenMax( lSets )
+        
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getSetListSortedByIncreasingMinThenMax_unordered_included(self):
+        set1 = Set( 1, "set1", "seq1", 2, 4 )
+        set2 = Set( 2, "set2", "seq1", 1, 5 )
+        lSets = [ set1, set2 ]
+        
+        expList = [ set2, set1 ]
+        
+        obsList = SetUtils.getSetListSortedByIncreasingMinThenMax( lSets )
+        
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getSetListSortedByIncreasingMinThenInvLength_alreadyOrdered_diffIdentifier(self):
+        set1 = Set( 1, "set1", "seq1", 1, 10 )
+        set2 = Set( 2, "set1", "seq1", 21, 30 )
+        lSets = [ set1, set2 ]
+        
+        expList = [ set1, set2 ]
+        
+        obsList = SetUtils.getSetListSortedByIncreasingMinThenInvLength( lSets )
+        
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getSetListSortedByIncreasingMinThenInvLength_unordered_diffIdentifier(self):
+        set1 = Set( 1, "set1", "seq1", 21, 30 )
+        set2 = Set( 2, "set1", "seq1", 1, 10 )
+        lSets = [ set1, set2 ]
+        
+        expList = [ set2, set1 ]
+        
+        obsList = SetUtils.getSetListSortedByIncreasingMinThenInvLength( lSets )
+        
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getSetListSortedByIncreasingMinThenInvLength_unordered_sameIdentifier(self):
+        set1 = Set( 1, "set1", "seq1", 21, 30 )
+        set2 = Set( 1, "set1", "seq1", 1, 10 )
+        lSets = [ set1, set2 ]
+        
+        expList = [ set2, set1 ]
+        
+        obsList = SetUtils.getSetListSortedByIncreasingMinThenInvLength( lSets )
+        
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getSetListSortedByIncreasingMinThenInvLength_unordered_overlapping(self):
+        set1 = Set( 2, "set1", "seq1", 6, 15 )
+        set2 = Set( 1, "set1", "seq1", 1, 10 )
+        lSets = [ set1, set2 ]
+        
+        expList = [ set2, set1 ]
+        
+        obsList = SetUtils.getSetListSortedByIncreasingMinThenInvLength( lSets )
+        
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getSetListSortedByIncreasingMinThenInvLength_unordered_sameMin_threeSets(self):
+        set1 = Set( 1, "set1", "seq1", 1, 10 )
+        set2 = Set( 2, "set2", "seq1", 3, 8 )
+        set3 = Set( 3, "set3", "seq1", 3, 17 )
+        lSets = [ set1, set2, set3 ]
+        
+        expList = [ set1, set3, set2 ]
+        
+        obsList = SetUtils.getSetListSortedByIncreasingMinThenInvLength( lSets )
+        
+        self.assertEqual( expList, obsList )
+        
+    def test_getSetListSortedByIncreasingMinThenInvLength_unordered_included(self):
+        set1 = Set( 1, "set1", "seq1", 2, 4 )
+        set2 = Set( 2, "set2", "seq1", 1, 5 )
+        lSets = [ set1, set2 ]
+        
+        expList = [ set2, set1 ]
+        
+        obsList = SetUtils.getSetListSortedByIncreasingMinThenInvLength( lSets )
+        
+        self.assertEqual( expList, obsList )
+        
+    def test_getSetListSortedBySeqThenRegionThenMinThenMax_already_sorted(self):
+        set1 = Set(1, "set1", "seq1", 2, 4)
+        set2 = Set(2, "set2", "seq2", 1, 5)
+        set3 = Set(3, "set3", "seq2", 8, 10)
+        lSets = [set1, set2, set3]
+        
+        expList = [set1, set2, set3]
+        
+        obsList = SetUtils.getSetListSortedBySeqThenRegionThenMinThenMax(lSets)
+        
+        self.assertEqual(expList, obsList)
+        
+    def test_getSetListSortedBySeqThenRegionThenMinThenMax_not_sorted_by_seqname(self):
+        set1 = Set(1, "set1", "seq1", 2, 4)
+        set2 = Set(2, "set2", "seq2", 1, 5)
+        set3 = Set(3, "set3", "seq2", 8, 10)
+        lSets = [set2, set1, set3]
+        
+        expList = [set1, set2, set3]
+        
+        obsList = SetUtils.getSetListSortedBySeqThenRegionThenMinThenMax(lSets)
+        
+        self.assertEqual(expList, obsList)
+         
+    def test_getSetListSortedBySeqThenRegionThenMinThenMax_not_sorted_by_region_and_start(self):
+        set1 = Set(1, "set1", "seq1", 2, 4)
+        set2 = Set(2, "set2", "seq2", 1, 5)
+        set3 = Set(3, "set3", "seq2", 8, 10)
+        lSets = [set3, set2, set1]
+        
+        expList = [set1, set2, set3]
+        
+        obsList = SetUtils.getSetListSortedBySeqThenRegionThenMinThenMax(lSets)
+        
+        self.assertEqual(expList, obsList)
+         
+    def test_getSetListSortedBySeqThenRegionThenMinThenMax_not_sorted_with_overlap(self):
+        set1 = Set(1, "set1", "seq1", 2, 4)
+        set2 = Set(2, "set2", "seq2", 1, 5)
+        set3 = Set(3, "set2", "seq2", 8, 10)
+        set4 = Set(4, "set2", "seq3", 7, 9)
+        set5 = Set(5, "set3", "seq3", 8, 12)
+        lSets = [set3, set2, set1, set5, set4]
+        
+        expList = [set1, set2, set3, set4, set5]
+        
+        obsList = SetUtils.getSetListSortedBySeqThenRegionThenMinThenMax(lSets)
+        
+        self.assertEqual(expList, obsList)
+
+    def test_getSetListSortedBySeqThenRegionThenMinThenMax_not_sorted_with_reverse(self):
+        set1 = Set(1, "set1", "seq1", 2, 4)
+        set2 = Set(2, "set2", "seq2", 1, 5)
+        set3 = Set(3, "set2", "seq2", 8, 10)
+        set4 = Set(4, "set3", "seq3", 7, 9)
+        set5 = Set(5, "set3", "seq3", 12, 5)
+        lSets = [set3, set2, set5, set1, set4]
+        
+        expList = [set1, set2, set3, set5, set4]
+        
+        obsList = SetUtils.getSetListSortedBySeqThenRegionThenMinThenMax(lSets)
+        
+        self.assertEqual(expList, obsList)
+
+    def test_getListOfIdListOfOverlappingSets_2_item_in_reference_list_overlaps_with_one_item_in_subject_list(self):
+        set1 = Set( 1, "set1", "seq1", 10, 30 )
+        set2 = Set( 2, "set2", "seq1", 40, 60 )
+        
+        lRef = [set1, set2]
+
+        set3 = Set( 3, "set2", "seq1", 25, 45 )
+        lSubj = [set3]
+        
+        lExp = [[1,-3,2]]
+        lObs = SetUtils.getListOfIdListOfOverlappingSets(lRef, lSubj)
+        
+        self.assertEquals(lExp, lObs)
+        
+    def test_getListOfIdListOfOverlappingSets_one_item_in_reference_list_overlaps_with_2_item_in_subject_list(self):
+        set1 = Set( 1, "set2", "seq1", 25, 45 )
+        lRef = [set1]
+        
+        set2 = Set( 2, "set1", "seq1", 10, 30 )
+        set3 = Set( 3, "set2", "seq1", 40, 60 )
+        
+        lSubj = [set2, set3]
+        
+        lExp = [[1,-2,-3]]
+        lObs = SetUtils.getListOfIdListOfOverlappingSets(lRef, lSubj)
+        
+        self.assertEquals(lExp, lObs)
+        
+    def test_getListOfIdListOfOverlappingSets_all_item_in_reference_list_overlaps_with_items_in_subject_list(self):
+        set1 = Set( 1, "set1", "seq1", 10, 30 )
+        set2 = Set( 2, "set2", "seq1", 40, 60 )
+        set3 = Set( 3, "set2", "seq1", 70, 90 )
+        
+        lRef = [set1, set2, set3]
+        
+        set4 = Set( 4, "set1", "seq1", 5, 9 )
+        set5 = Set( 5, "set1", "seq1", 15, 29 )
+        set6 = Set( 6, "set2", "seq1", 45, 55 )
+        set7 = Set( 7, "set2", "seq1", 57, 68 )
+        set8 = Set( 8, "set2", "seq1", 73, 85 )
+        set9 = Set( 9, "set2", "seq1", 100, 115 )
+        
+        lSubj = [set4, set5, set6, set7, set8, set9]
+        
+        lExp = [[1,-5], [2,-6,-7], [3,-8]]
+        lObs = SetUtils.getListOfIdListOfOverlappingSets(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)
+            
+    def test_getListOfIdListOfOverlappingSets_all_item_in_subject_list_overlaps_with_items_in_reference_list(self):
+        set1 = Set( 1, "set1", "seq1", 5, 9 )
+        set2 = Set( 2, "set1", "seq1", 15, 29 )
+        set3 = Set( 3, "set2", "seq1", 45, 55 )
+        set4 = Set( 4, "set2", "seq1", 57, 68 )
+        set5 = Set( 5, "set2", "seq1", 73, 85 )
+        set6 = Set( 6, "set2", "seq1", 100, 115 )
+        
+        lRef = [set1, set2, set3, set4, set5, set6]
+        
+        set7 = Set( 7, "set1", "seq1", 10, 30 )
+        set8 = Set( 8, "set2", "seq1", 40, 60 )
+        set9 = Set( 9, "set2", "seq1", 70, 90 )
+        
+        lSubj = [set7, set8, set9]
+              
+        lExp = [[2, -7], [3, -8, 4], [5, -9]]
+        lObs = SetUtils.getListOfIdListOfOverlappingSets(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp) 
+               
+    def test_getListOfIdListOfOverlappingSets_all_item_overlaps_one_by_one(self):
+        set1 = Set( 1, "set1", "seq1", 10, 20 )
+        set2 = Set( 2, "set1", "seq1", 30, 40 )
+        set3 = Set( 3, "set2", "seq1", 50, 60 )
+        
+        lRef = [set1, set2, set3]
+        
+        lSubj = [set1, set2, set3]
+              
+        lExp = [[1, -1], [2, -2], [3, -3]]
+        lObs = SetUtils.getListOfIdListOfOverlappingSets(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp) 
+        
+    def test_getListOfIdListOfOverlappingSets_continuus_overlap_between_item_in_reference_list_and_item_in_subject_list(self):
+        set1 = Set( 1, "set1", "seq1", 10, 20 )
+        set2 = Set( 2, "set1", "seq1", 30, 40 )
+        set3 = Set( 3, "set2", "seq1", 50, 60 )
+        set4 = Set( 4, "set2", "seq1", 70, 80 )
+        
+        lRef = [set1, set2, set3, set4]
+        
+        set5 = Set( 5, "set1", "seq1", 15, 32 )
+        set6 = Set( 6, "set2", "seq1", 35, 52 )
+        set7 = Set( 7, "set2", "seq1", 55, 75 )
+        
+        lSubj = [set5, set6, set7]
+              
+        lExp = [[ 1, -5, 2, -6, 3, -7, 4 ]]
+        lObs = SetUtils.getListOfIdListOfOverlappingSets(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)   
+        
+        
+    def test_getListOfIdListOfOverlappingSets_first_item_in_reference_overlap_with_one_item_in_subject_list(self):
+        set1 = Set( 1, "set1", "seq1", 10, 20 )
+        set2 = Set( 2, "set1", "seq1", 30, 40 )
+        
+        lRef = [set1, set2]
+        
+        set3 = Set( 3, "set1", "seq1", 5, 9 )
+        set4 = Set( 4, "set2", "seq1", 12, 25 )
+        set5 = Set( 5, "set2", "seq1", 55, 75 )
+        
+        lSubj = [set3, set4, set5]
+              
+        lExp = [[1, -4]]
+        lObs = SetUtils.getListOfIdListOfOverlappingSets(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)
+        
+    def test_getListOfIdListOfOverlappingSets_last_item_in_reference_overlap_with_one_item_in_subject_list(self):
+        set1 = Set( 1, "set1", "seq1", 10, 20 )
+        set2 = Set( 2, "set1", "seq1", 30, 40 )
+        
+        lRef = [set1, set2]
+        
+        set3 = Set( 3, "set1", "seq1", 5, 9 )
+        set4 = Set( 4, "set2", "seq1", 32, 45 )
+        set5 = Set( 5, "set2", "seq1", 55, 75 )
+        
+        lSubj = [set3, set4, set5]
+              
+        lExp = [[2, -4]]
+        lObs = SetUtils.getListOfIdListOfOverlappingSets(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)       
+                
+    def test_getListOfIdListOfOverlappingSets_one_item_in_reference_in_the_middle_overlap_with_one_item_in_subject_list(self):
+        set1 = Set( 1, "set1", "seq1", 10, 20 )
+        set2 = Set( 2, "set1", "seq1", 30, 40 )
+        set3 = Set( 3, "set1", "seq1", 50, 60 )
+        set4 = Set( 4, "set1", "seq1", 70, 80 )
+        
+        lRef = [set1, set2, set3, set4]
+        
+        set5 = Set( 5, "set1", "seq1", 2, 9 )
+        set6 = Set( 6, "set2", "seq1", 55, 65 )
+        set7 = Set( 7, "set2", "seq1", 90, 100 )
+        
+        lSubj = [set5, set6, set7]
+              
+        lExp = [[3, -6]]
+        lObs = SetUtils.getListOfIdListOfOverlappingSets(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)
+        
+    def test_getListOfIdListOfOverlappingSets_first_item_in_subject_overlap_with_one_item_in_reference_list(self):
+        set1 = Set( 1, "set1", "seq1", 10, 20 )
+        set2 = Set( 2, "set1", "seq1", 30, 40 )
+        
+        lRef = [set1, set2]
+        
+        set3 = Set( 3, "set1", "seq1", 15, 25 )
+        set4 = Set( 4, "set2", "seq1", 45, 50 )
+        set5 = Set( 5, "set2", "seq1", 55, 75 )
+        
+        lSubj = [set3, set4, set5]
+              
+        lExp = [[1, -3]]
+        lObs = SetUtils.getListOfIdListOfOverlappingSets(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)
+                
+    def test_getListOfIdListOfOverlappingSets_last_item_in_subject_overlap_with_one_item_in_reference_list(self):
+        set1 = Set( 1, "set1", "seq1", 10, 20 )
+        set2 = Set( 2, "set1", "seq1", 30, 40 )
+        
+        lRef = [set1, set2]
+        
+        set3 = Set( 3, "set1", "seq1", 1, 9 )
+        set4 = Set( 4, "set2", "seq1", 21, 29 )
+        set5 = Set( 5, "set2", "seq1", 35, 50 )
+        
+        lSubj = [set3, set4, set5]
+              
+        lExp = [[2, -5]]
+        lObs = SetUtils.getListOfIdListOfOverlappingSets(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp) 
+        
+    def test_getListOfIdListOfOverlappingSets_one_item_in_subject_in_the_middle_overlap_with_one_item_in_reference_list(self):
+        set1 = Set( 1, "set1", "seq1", 10, 20 )
+        set2 = Set( 2, "set1", "seq1", 30, 40 )
+        
+        lRef = [set1, set2]
+        
+        set3 = Set( 3, "set1", "seq1", 1, 9 )
+        set4 = Set( 4, "set2", "seq1", 21, 29 )
+        set5 = Set( 5, "set2", "seq1", 35, 50 )
+        set6 = Set( 6, "set2", "seq1", 60, 70 )
+        
+        lSubj = [set3, set4, set5, set6]
+              
+        lExp = [[2, -5]]
+        lObs = SetUtils.getListOfIdListOfOverlappingSets(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)
+        
+    def test_getListOfMergedSetsAndNextId_each_item_in_reference_list_overlap_with_one_different_item_in_subject_list(self):
+        setRef1 = Set( 1, "set1", "seq1", 10, 20 )
+        setRef2 = Set( 2, "set1", "seq1", 30, 40 )
+        setRef3 = Set( 3, "set1", "seq1", 50, 60 )
+        
+        lRef = [setRef1, setRef2, setRef3]
+        
+        setSubj1 = Set( 1, "set1", "seq1", 12, 25 )
+        setSubj2 = Set( 2, "set1", "seq1", 31, 45 )
+        setSubj3 = Set( 3, "set1", "seq1", 55, 80 )
+        
+        lSubj = [setSubj1, setSubj2, setSubj3]
+        
+        setRef1merged = Set( 1, "set1", "seq1", 10, 25 )
+        setRef2merged = Set( 2, "set1", "seq1", 30, 45 )
+        setRef3merged = Set( 3, "set1", "seq1", 50, 80 )
+        
+        nextId = 4
+        
+        lExp = ([setRef1merged, setRef2merged, setRef3merged], nextId)
+        lObs = SetUtils.getListOfMergedSetsAndNextId(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)
+        
+    def test_getListOfMergedSetsAndNextId_all_items_in_reference_list_overlap_with_the_same_item_in_subject_list(self):
+        setRef1 = Set( 1, "set1", "seq1", 10, 20 )
+        setRef2 = Set( 2, "set1", "seq1", 15, 25 )
+        setRef3 = Set( 3, "set1", "seq1", 20, 30 )
+        
+        lRef = [setRef1, setRef2, setRef3]
+        
+        setSubj1 = Set( 1, "set1", "seq1", 12, 35 )
+        setSubj2 = Set( 2, "set1", "seq1", 40, 45 )
+        setSubj3 = Set( 3, "set1", "seq1", 55, 80 )
+        
+        lSubj = [setSubj1, setSubj2, setSubj3]
+        
+        setRef1merged = Set( 1, "set1", "seq1", 10, 35 )
+        setSubj2Exp = Set( 4, "set1", "seq1", 40, 45 )
+        setSubj3Exp = Set( 5, "set1", "seq1", 55, 80 )
+        
+        nextId = 6
+        
+        lExp = ([setRef1merged, setSubj2Exp, setSubj3Exp], nextId)
+        lObs = SetUtils.getListOfMergedSetsAndNextId(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)
+                
+    def test_getListOfMergedSetsAndNextId_two_last_ref_items_overlap_with_last_subject_item(self):
+        setRef1 = Set( 1, "set1", "seq1", 10, 20 )
+        setRef2 = Set( 2, "set1", "seq1", 30, 40 )
+        setRef3 = Set( 3, "set1", "seq1", 50, 60 )
+        
+        lRef = [setRef1, setRef2, setRef3]
+        
+        setSubj1 = Set( 1, "set1", "seq1", 1, 5 )
+        setSubj2 = Set( 2, "set1", "seq1", 6, 9 )
+        setSubj3 = Set( 3, "set1", "seq1", 35, 55 )
+        
+        lSubj = [setSubj1, setSubj2, setSubj3]
+        
+        setRef1Exp = Set( 1, "set1", "seq1", 10, 20 )
+        setRef2merged = Set( 2, "set1", "seq1", 30, 60 )
+        setSubj1Exp = Set( 4, "set1", "seq1", 1, 5 )
+        setSubj2Exp = Set( 5, "set1", "seq1", 6, 9 )
+        
+        nextId = 6
+        
+        lExp = ([setRef2merged, setRef1Exp, setSubj1Exp, setSubj2Exp], nextId)
+        lObs = SetUtils.getListOfMergedSetsAndNextId(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)
+        
+    def test_getListOfMergedSetsAndNextId_all_items_in_reference_list_overlap_with_all_items_in_subject_list(self):
+        setRef1 = Set( 1, "set1", "seq1", 10, 20 )
+        setRef2 = Set( 2, "set1", "seq1", 30, 40 )
+        
+        lRef = [setRef1, setRef2]
+        
+        setSubj1 = Set( 1, "set1", "seq1", 10, 20 )
+        setSubj2 = Set( 2, "set1", "seq1", 30, 40 )
+        
+        lSubj = [setSubj1, setSubj2]
+        
+        setRef1merged = Set( 1, "set1", "seq1", 10, 20 )
+        setRef2merged = Set( 2, "set1", "seq1", 30, 40 )
+        
+        nextId = 3
+        
+        lExp = ([setRef1merged, setRef2merged], nextId)
+        lObs = SetUtils.getListOfMergedSetsAndNextId(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)
+        
+    def test_getListOfMergedSetsAndNextId_one_item_in_reference_list_overlap_with_all_items_in_subject_list(self):
+        setRef1 = Set( 1, "set1", "seq1", 10, 20 )
+        setRef2 = Set( 2, "set1", "seq1", 30, 40 )
+        setRef3 = Set( 3, "set1", "seq1", 50, 60 )
+        
+        lRef = [setRef1, setRef2, setRef3]
+        
+        setSubj1 = Set( 1, "set1", "seq1", 11, 13 )
+        setSubj2 = Set( 2, "set1", "seq1", 14, 16 )
+        setSubj3 = Set( 3, "set1", "seq1", 17, 25 )
+        
+        lSubj = [setSubj1, setSubj2, setSubj3]
+        
+        setRef1merged = Set( 1, "set1", "seq1", 10, 25 )
+        setRef2Exp = Set( 2, "set1", "seq1", 30, 40 )
+        setRef3Exp = Set( 3, "set1", "seq1", 50, 60 )
+        
+        nextId = 4
+        
+        lExp = ([setRef1merged, setRef2Exp, setRef3Exp], nextId)
+        lObs = SetUtils.getListOfMergedSetsAndNextId(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)
+        
+    def test_getListOfMergedSetsAndNextId_one_item_in_reference_list_overlap_with_one_item_in_subject_list(self):
+        setRef1 = Set( 1, "set1", "seq1", 10, 20 )
+        setRef2 = Set( 2, "set1", "seq1", 30, 40 )
+        setRef3 = Set( 3, "set1", "seq1", 50, 60 )
+        
+        lRef = [setRef1, setRef2, setRef3]
+        
+        setSubj1 = Set( 1, "set1", "seq1", 1, 9 )
+        setSubj2 = Set( 2, "set1", "seq1", 31, 45 )
+        setSubj3 = Set( 3, "set1", "seq1", 70, 80 )
+        
+        lSubj = [setSubj1, setSubj2, setSubj3]
+        
+        setRef1Exp = Set( 1, "set1", "seq1", 10, 20 )
+        setRef2merged = Set( 2, "set1", "seq1", 30, 45 )
+        setRef3Exp = Set( 3, "set1", "seq1", 50, 60 )
+        setSubj1Exp = Set( 4, "set1", "seq1", 1, 9 )
+        setSubj3Exp = Set( 5, "set1", "seq1", 70, 80 )
+        
+        nextId = 6
+        
+        lExp = ([setRef2merged, setRef1Exp, setRef3Exp, setSubj1Exp, setSubj3Exp], nextId)
+        
+        lObs = SetUtils.getListOfMergedSetsAndNextId(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)
+        
+    def test_getListOfMergedSetsAndNextId_one_item_in_reference_list_overlap_with_one_item_in_subject_list_with_strange_output_order(self):
+        setRef1 = Set( 5, "set1", "seq1", 10, 20 )
+        setRef2 = Set( 6, "set1", "seq1", 30, 40 )
+        setRef3 = Set( 7, "set1", "seq1", 50, 60 )
+        setRef4 = Set( 8, "set1", "seq1", 90, 92 )
+        
+        lRef = [setRef1, setRef2, setRef3, setRef4]
+        
+        setSubj1 = Set( 1, "set1", "seq1", 1, 9 )
+        setSubj2 = Set( 2, "set1", "seq1", 35, 45 )
+        setSubj3 = Set( 3, "set1", "seq1", 70, 80 )
+        setSubj4 = Set( 4, "set1", "seq1", 130, 140 )
+        
+        lSubj = [setSubj1, setSubj2, setSubj3, setSubj4]
+        
+        setRef1Exp = Set( 5, "set1", "seq1", 10, 20 )
+        setRef2merged = Set( 6, "set1", "seq1", 30, 45 )
+        setRef3Exp = Set( 7, "set1", "seq1", 50, 60 )
+        setRef4Exp = Set( 8, "set1", "seq1", 90, 92 )
+        setSubj1Exp = Set( 9, "set1", "seq1", 1, 9 )
+        setSubj3Exp = Set( 10, "set1", "seq1", 70, 80 )
+        setSubj4Exp = Set( 11, "set1", "seq1", 130, 140 )
+        
+        nextId = 12
+        
+        lExp = ([setRef2merged, setRef4Exp, setRef1Exp, setRef3Exp, setSubj1Exp, setSubj3Exp, setSubj4Exp], nextId)
+        
+        lObs = SetUtils.getListOfMergedSetsAndNextId(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)
+        
+    def test_getListOfMergedSetsAndNextId_all_items_overlap_between_lists_with_same_length(self):
+        setRef1 = Set( 1, "set1", "seq1", 10, 20 )
+        setRef2 = Set( 2, "set1", "seq1", 30, 40 )
+        setRef3 = Set( 3 , "set1", "seq1", 50, 60 )
+        
+        lRef = [setRef1, setRef2, setRef3]
+        
+        setSubj1 = Set( 1, "set1", "seq1", 15, 35 )
+        setSubj2 = Set( 2, "set1", "seq1", 36, 55 )
+        setSubj3 = Set( 3, "set1", "seq1", 56, 65 )
+        
+        lSubj = [setSubj1, setSubj2, setSubj3]
+        
+        setRef1merged = Set( 1, "set1", "seq1", 10, 65 )
+        
+        nextId = 4
+        
+        lExp = ([setRef1merged], nextId)
+        lObs = SetUtils.getListOfMergedSetsAndNextId(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)
+        
+    def test_getListOfMergedSetsAndNextId_all_items_overlap_between_lists_with_different_length(self):
+        setRef1 = Set( 1, "set1", "seq1", 10, 20 )
+        setRef2 = Set( 2, "set1", "seq1", 30, 40 )
+        setRef3 = Set( 3 , "set1", "seq1", 50, 60 )
+        
+        lRef = [setRef1, setRef2, setRef3]
+        
+        setSubj1 = Set( 1, "set1", "seq1", 15, 35 )
+        setSubj2 = Set( 2, "set1", "seq1", 36, 55 )
+        
+        lSubj = [setSubj1, setSubj2]
+        
+        setRef1merged = Set( 1, "set1", "seq1", 10, 60 )
+        
+        nextId = 4
+        
+        lExp = ([setRef1merged], nextId)
+        lObs = SetUtils.getListOfMergedSetsAndNextId(lRef, lSubj)
+        
+        self.assertEquals(lObs, lExp)
+        
+    def test_getListOfSetWithoutOverlappingBetweenTwoListOfSet(self):
+        set1 = Set( 1, "set1", "seq1", 10, 20 )
+        set2 = Set( 2, "set1", "seq1", 30, 40 )
+        set3 = Set( 3, "set1", "seq1", 50, 60 )
+        
+        lSet1 = [set1, set2, set3]
+        
+        set4 = Set( 1, "set1", "seq1", 15, 35 )
+        set5 = Set( 2, "set1", "seq1", 36, 55 )
+        set6 = Set( 3, "set1", "seq1", 66, 95 )
+        
+        lSet2 = [set4, set5, set6]
+        
+        expLSet = [set6]
+        obsLSet = SetUtils.getListOfSetWithoutOverlappingBetweenTwoListOfSet(lSet1, lSet2)
+        
+        self.assertEquals(expLSet, obsLSet)
+        
+    def test_getListOfSetWithoutOverlappingBetweenTwoListOfSet_Empty_Result(self):
+        set1 = Set( 1, "set1", "seq1", 10, 20 )
+        set2 = Set( 2, "set1", "seq1", 30, 40 )
+        set3 = Set( 3, "set1", "seq1", 50, 60 )
+        
+        lSet1 = [set1, set2, set3]
+        
+        set4 = Set( 1, "set1", "seq1", 15, 35 )
+        set5 = Set( 2, "set1", "seq1", 36, 55 )
+        
+        lSet2 = [set4, set5]
+        
+        expLSet = []
+        obsLSet = SetUtils.getListOfSetWithoutOverlappingBetweenTwoListOfSet(lSet1, lSet2)
+        
+        self.assertEquals(expLSet, obsLSet)
+        
+    def test_getListOfSetWithoutOverlappingBetweenTwoListOfSet_Empty_Result_Length_Condition(self):
+        set1 = Set( 1, "set1", "seq1", 10, 20 )
+        set2 = Set( 2, "set1", "seq1", 30, 40 )
+        set3 = Set( 3, "set1", "seq1", 50, 60 )
+        
+        lSet1 = [set1, set2, set3]
+        
+        set4 = Set( 1, "set1", "seq1", 15, 35 )
+        set5 = Set( 2, "set1", "seq1", 36, 55 )
+        set6 = Set( 3, "set1", "seq1", 66, 68 )
+        
+        lSet2 = [set4, set5, set6]
+        
+        expLSet = []
+        obsLSet = SetUtils.getListOfSetWithoutOverlappingBetweenTwoListOfSet(lSet1, lSet2)
+        
+        self.assertEquals(expLSet, obsLSet)
+        
+        
+    def test_getSetListFromFile(self):
+        file = "dummyFile_%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        fileHandler = open( file, "w" )
+        fileHandler.write( "1\tseq1\tchr1\t151\t250\n" )
+        fileHandler.write( "2\tseq2\tchr2\t301\t500\n" )
+        fileHandler.close()
+        s1 = Set()
+        s1.setFromTuple( ( "1", "seq1", "chr1", "151", "250" ) )
+        s2 = Set()
+        s2.setFromTuple( ( "2", "seq2", "chr2", "301", "500" ) )
+        expLSet = [ s1, s2 ]
+        obsLSet = SetUtils.getSetListFromFile(file)
+        os.remove(file)
+        self.assertEqual( expLSet, obsLSet )
+        
+        
+    def test_convertSetFileIntoMapFile( self ):
+        setFile = "dummySetFile"
+        setFileHandler = open( setFile, "w" )
+        setFileHandler.write( "1\tseq31\tchr1\t151\t250\n" )
+        setFileHandler.write( "2\tseq27\tchr2\t301\t500\n" )
+        setFileHandler.close()
+        
+        expFile = "dummyExpFile"
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "seq31\tchr1\t151\t250\n" )
+        expFileHandler.write( "seq27\tchr2\t301\t500\n" )
+        expFileHandler.close()
+        
+        obsFile = "dummyObsFile"
+        
+        SetUtils.convertSetFileIntoMapFile( setFile, obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        for f in [ setFile, expFile, obsFile ]:
+            os.remove( f )
+            
+            
+    def test_getDictOfListsWithSeqnameAsKey_empty( self ):
+        lSets = []
+        dExp = {}
+        dObs = SetUtils.getDictOfListsWithSeqnameAsKey( lSets )
+        self.assertEquals( dExp, dObs )
+            
+            
+    def test_getDictOfListsWithSeqnameAsKey( self ):
+        lSets = [ Set( 1, "TE3", "chr2", 10, 50 ),
+                 Set( 2, "gene74", "chr1", 31, 800 ),
+                 Set( 3, "TE1", "chr1", 1, 30 ) ]
+        dExp = { "chr1": [ Set( 2, "gene74", "chr1", 31, 800 ),
+                          Set( 3, "TE1", "chr1", 1, 30 ) ],
+                "chr2": [ Set( 1, "TE3", "chr2", 10, 50 ) ] }
+        dObs = SetUtils.getDictOfListsWithSeqnameAsKey( lSets )
+        self.assertEquals( dExp, dObs )
+        
+        
+    def test_filterOnLength( self ):
+        lSets = [ Set( 1, "TE3", "chr2", 10, 50 ),
+                 Set( 2, "gene74", "chr1", 31, 800 ),
+                 Set( 3, "TE1", "chr1", 1, 30 ) ]
+        lExp = [ Set( 2, "gene74", "chr1", 31, 800 ) ]
+        lObs = SetUtils.filterOnLength( lSets, 100 )
+        self.assertEqual( lExp, lObs )
+        
+        
+    def test_getListOfNames( self ):
+        setFile = "dummySetFile"
+        setFileHandler = open( setFile, "w" )
+        setFileHandler.write( "1\tseq31\tchr1\t151\t250\n" )
+        setFileHandler.write( "2\tseq27\tchr2\t301\t500\n" )
+        setFileHandler.close()
+        
+        lExp = [ "seq31", "seq27" ]
+        lObs = SetUtils.getListOfNames( setFile )
+        
+        self.assertEquals( lExp, lObs )
+        
+        os.remove( setFile )
+        
+        
+    def test_getDictOfDictsWithNamesThenIdAsKeyFromFile( self ):
+        setFile = "dummySetFile"
+        setFileHandler = open( setFile, "w" )
+        setFileHandler.write( "1\tseq31\tchr1\t151\t250\n" )
+        setFileHandler.write( "3\tseq27\tchr3\t1\t100\n" )
+        setFileHandler.write( "2\tseq27\tchr2\t301\t500\n" )
+        setFileHandler.write( "2\tseq27\tchr2\t601\t650\n" )
+        setFileHandler.close()
+        
+        dExp = { "seq31": { 1: [ Set( 1, "seq31", "chr1", 151, 250 ) ] },
+                "seq27": { 2: [ Set( 2, "seq27", "chr2", 301, 500 ),
+                               Set( 2, "seq27", "chr2", 601, 650 ) ],
+                               3: [ Set( 3, "seq27", "chr3", 1, 100 ) ]
+                               }
+                }
+        dObs = SetUtils.getDictOfDictsWithNamesThenIdAsKeyFromFile( setFile )
+        
+        self.assertEquals( dExp, dObs )
+        
+        os.remove( setFile )
+        
+        
+    def _makeSetListFromTupleList (self, tupleList):
+        setList = []
+        for tuple in tupleList:
+            set = Set()
+            set.setFromTuple(tuple)
+            setList.append(set)
+        return setList
+        
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_SetUtils ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/coord/test/Test_SlidingWindow.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,109 @@
+import unittest
+from commons.core.coord.SlidingWindow import SlidingWindow
+from commons.core.coord.SlidingWindow import SlidingWindowToCountMatchingBases
+from commons.core.coord.Set import Set
+
+class Test_SlidingWindow( unittest.TestCase ):
+        
+    def test_slideWindowOnce( self ):
+        expStart = 91 
+        expEnd = 190
+        self.sw = SlidingWindow(100, 10)
+        self.sw.slideWindowOnce()
+        obsStart = self.sw._start
+        obsEnd = self.sw._end
+        
+        self.assertEqual(expStart, obsStart)
+        self.assertEqual(expEnd, obsEnd)
+        
+    def test_slideWindowOnceFourTime( self ):
+        expStart = 201 
+        expEnd = 300
+        self.sw = SlidingWindow(100, 50)
+        i = 0
+        for i in range(4):
+            self.sw.slideWindowOnce()
+            i += 1
+        obsStart = self.sw._start
+        obsEnd = self.sw._end
+        
+        self.assertEqual(expStart, obsStart)
+        self.assertEqual(expEnd, obsEnd)
+    
+        
+class Test_SlidingWindowToCountMatchingBases(unittest.TestCase):
+        
+    def test_getSetLengthOnWindow_featureIncluded( self ):
+        self.sw = SlidingWindowToCountMatchingBases(100, 1)
+        iSet = Set( 1, "TE3", "chr1", 21, 30 )
+        exp = 10
+        obs = self.sw.getSetLengthOnWindow( iSet)
+        self.assertEqual( exp, obs )
+        
+    def test_getSetLengthOnWindow_windowIncluded( self ):
+        self.sw = SlidingWindowToCountMatchingBases(100, 10)
+        self.sw.slideWindowOnce()
+        iSet = Set( 1, "TE3", "chr1", 21, 530 )
+        exp = 100
+        obs = self.sw.getSetLengthOnWindow( iSet)
+        self.assertEqual( exp, obs )
+        
+    def test_getSetLengthOnWindow_featureOverlapLeft( self ):
+        self.sw = SlidingWindowToCountMatchingBases(100, 10)
+        self.sw.slideWindowOnce()
+        iSet = Set( 1, "TE3", "chr1", 21, 130 )
+        exp = 40
+        obs = self.sw.getSetLengthOnWindow( iSet)
+        self.assertEqual( exp, obs )
+        
+    def test_getSetLengthOnWindow_featureOverlapRight( self ):
+        self.sw = SlidingWindowToCountMatchingBases(100, 10)
+        self.sw.slideWindowOnce()
+        iSet = Set( 1, "TE3", "chr1", 121, 230 )
+        exp = 70
+        obs = self.sw.getSetLengthOnWindow( iSet)
+        self.assertEqual( exp, obs )
+        
+    def test_getCoordSetOnWindow_featureIncluded( self ):
+        self.sw = SlidingWindowToCountMatchingBases(100, 1)
+        iSet = Set( 1, "TE3", "chr1", 21, 30 )
+        expStart = 21
+        expEnd = 30
+        obsStart,obsEnd = self.sw.getCoordSetOnWindow( iSet)
+        self.assertEqual( expStart, obsStart )
+        self.assertEqual( expEnd, obsEnd )
+        
+    def test_getCoordSetOnWindow_windowIncluded( self ):
+        self.sw = SlidingWindowToCountMatchingBases(100, 10)
+        self.sw.slideWindowOnce()
+        iSet = Set( 1, "TE3", "chr1", 21, 530 )
+        expStart = 91
+        expEnd = 190
+        obsStart,obsEnd = self.sw.getCoordSetOnWindow( iSet)
+        self.assertEqual( expStart, obsStart )
+        self.assertEqual( expEnd, obsEnd )
+        
+    def test_getCoordSetOnWindow_featureOverlapLeft( self ):
+        self.sw = SlidingWindowToCountMatchingBases(100, 10)
+        self.sw.slideWindowOnce()
+        iSet = Set( 1, "TE3", "chr1", 21, 130 )
+        expStart = 91
+        expEnd = 130
+        obsStart,obsEnd = self.sw.getCoordSetOnWindow( iSet)
+        self.assertEqual( expStart, obsStart )
+        self.assertEqual( expEnd, obsEnd )
+        
+    def test_getCoordSetOnWindow_featureOverlapRight( self ):
+        self.sw = SlidingWindowToCountMatchingBases(100, 10)
+        self.sw.slideWindowOnce()
+        iSet = Set( 1, "TE3", "chr1", 121, 230 )
+        expStart = 121
+        expEnd = 190
+        obsStart,obsEnd = self.sw.getCoordSetOnWindow( iSet)
+        self.assertEqual( expStart, obsStart )
+        self.assertEqual( expEnd, obsEnd )
+
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_SlidingWindow ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/launcher/JobScriptTemplate.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import time
+import shutil
+from commons.core.checker.RepetException import RepetException
+from commons.core.sql.TableJobAdaptator import TableJobAdaptator
+from commons.core.sql.DbFactory import DbFactory
+from commons.core.sql.Job import Job
+
+try:
+	newDir = None
+	print os.uname()
+	beginTime = time.time()
+	print 'beginTime=%f' % beginTime
+	print "work in dir '@@tmpDir@@'"
+	sys.stdout.flush()
+	if not os.path.exists( "@@tmpDir@@" ):
+		raise IOError("ERROR: temporary directory '@@tmpDir@@' doesn't exist")
+	
+	minFreeGigaInTmpDir = 1
+	freeSpace = os.statvfs("@@tmpDir@@")
+	if ((freeSpace.f_bavail * freeSpace.f_frsize) / 1073741824.0 < minFreeGigaInTmpDir):
+		raise RepetException("ERROR: less than %iG of input file in '@@tmpDir@@'" % minFreeGigaInTmpDir)
+	
+	os.chdir("@@tmpDir@@")
+	newDir = "@@groupId@@_@@jobName@@_@@time@@"
+	if os.path.exists(newDir):
+		shutil.rmtree(newDir)
+	os.mkdir(newDir)
+	os.chdir(newDir)
+	
+	iJob = Job(jobname = "@@jobName@@", groupid = "@@groupId@@", launcherFile = "@@launcher@@", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "@@jobTableName@@")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "running")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	
+	@@cmdStart@@
+	if log != 0:
+		raise RepetException("ERROR: job returned %i" % log)
+	else:
+		print "job finished successfully"
+	sys.stdout.flush()
+	@@cmdFinish@@
+	
+	os.chdir("..")
+	shutil.rmtree(newDir)
+	
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "@@jobTableName@@")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "finished")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	
+	endTime = time.time()
+	print 'endTime=%f' % endTime
+	print 'executionTime=%f' % (endTime - beginTime)
+	print os.uname()
+	sys.stdout.flush()
+
+except IOError, e :
+	print e
+	iJob = Job(jobname = "@@jobName@@", groupid = "@@groupId@@", launcherFile = "@@launcher@@", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "@@jobTableName@@")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "error")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	sys.exit(1)
+
+except Exception, e :
+	print "tmpDir is : @@tmpDir@@"
+	print "cDir is : @@cDir@@"
+	print e
+	if newDir != None and os.path.exists("../%s" % newDir) and not os.path.exists("@@cDir@@/%s" % newDir):
+		os.chdir("..")
+		shutil.move(newDir, "@@cDir@@/%s" % newDir)
+	iJob = Job(jobname = "@@jobName@@", groupid = "@@groupId@@", launcherFile = "@@launcher@@", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "@@jobTableName@@")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "error")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	sys.exit(1)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/launcher/JobScriptTemplateLight.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import time
+import shutil
+from commons.core.checker.RepetException import RepetException
+try:
+	newDir = None
+	print os.uname()
+	beginTime = time.time()
+	print 'beginTime=%f' % beginTime
+	print "work in dir '@@tmpDir@@'"
+	sys.stdout.flush()
+	if not os.path.exists( "@@tmpDir@@" ):
+		raise IOError("ERROR: temporary directory '@@tmpDir@@' doesn't exist")
+	
+	minFreeGigaInTmpDir = 1
+	freeSpace = os.statvfs("@@tmpDir@@")
+	if ((freeSpace.f_bavail * freeSpace.f_frsize) / 1073741824.0 < minFreeGigaInTmpDir):
+		raise RepetException("ERROR: less than %iG of input file in '@@tmpDir@@'" % minFreeGigaInTmpDir)
+	
+	os.chdir("@@tmpDir@@")
+	newDir = "@@groupId@@_@@jobName@@_@@time@@"
+	if os.path.exists(newDir):
+		shutil.rmtree(newDir)
+	os.mkdir(newDir)
+	os.chdir(newDir)
+	
+	@@cmdStart@@
+	if log != 0:
+		raise RepetException("ERROR: job returned %i" % log)
+	else:
+		print "job finished successfully"
+	sys.stdout.flush()
+	@@cmdFinish@@
+	
+	os.chdir("..")
+	shutil.rmtree(newDir)	
+	endTime = time.time()
+	print 'endTime=%f' % endTime
+	print 'executionTime=%f' % (endTime - beginTime)
+	print os.uname()
+	sys.stdout.flush()
+
+except IOError, e :
+	print e
+	sys.stdout.flush()
+	sys.exit(1)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/launcher/JobScriptWithFilesCopyTemplate.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import time
+import shutil
+from commons.core.checker.RepetException import RepetException
+from commons.core.sql.TableJobAdaptator import TableJobAdaptator
+from commons.core.sql.DbFactory import DbFactory
+from commons.core.sql.Job import Job
+
+try:
+	newDir = None
+	print os.uname()
+	beginTime = time.time()
+	print 'beginTime=%f' % beginTime
+	print "work in dir '@@tmpDir@@'"
+	sys.stdout.flush()
+	if not os.path.exists("@@tmpDir@@"):
+		raise IOError("ERROR: temporary directory '@@tmpDir@@' doesn't exist")
+	
+	fileSize = 0
+	if not os.path.exists("@@groupId@@"):
+		@@cmdSize@@
+	freeGigaNeededInTmpDir = float(1 + fileSize)
+	freeSpace = os.statvfs("@@tmpDir@@")
+	if ((freeSpace.f_bavail * freeSpace.f_frsize) / 1073741824.0 < freeGigaNeededInTmpDir):
+		raise RepetException("ERROR: less than %.2fG of input file in '@@tmpDir@@'" % freeGigaNeededInTmpDir)
+	
+	os.chdir("@@tmpDir@@")
+	if not os.path.exists("@@groupId@@"):
+		try:
+			os.mkdir("@@groupId@@")
+		except OSError, e :
+			if e.args[0] != 17:
+				raise RepetException("ERROR: can't create '@@groupId@@'")
+		os.chdir("@@groupId@@")
+		@@cmdCopy@@
+	else:
+		os.chdir("@@groupId@@")
+	
+	newDir = "@@groupId@@_@@jobName@@_@@time@@"
+	if os.path.exists(newDir):
+		shutil.rmtree(newDir)
+	os.mkdir(newDir)
+	os.chdir(newDir)
+	
+	iJob = Job(jobname = "@@jobName@@", groupid = "@@groupId@@", launcherFile = "@@launcher@@", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "@@jobTableName@@")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "running")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	
+	@@cmdStart@@
+	if log != 0:
+		raise RepetException("ERROR: job returned %i" % log)
+	else:
+		print "job finished successfully"
+	sys.stdout.flush()
+	@@cmdFinish@@
+	
+	os.chdir("..")
+	shutil.rmtree(newDir)
+	
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "@@jobTableName@@")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "finished")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	
+	endTime = time.time()
+	print 'endTime=%f' % endTime
+	print 'executionTime=%f' % (endTime - beginTime)
+	print os.uname()
+	sys.stdout.flush()
+
+except IOError, e :
+	print e
+	iJob = Job(jobname = "@@jobName@@", groupid = "@@groupId@@", launcherFile = "@@launcher@@", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "@@jobTableName@@")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "error")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	sys.exit(1)
+
+except Exception, e :
+	print "tmpDir is : @@tmpDir@@"
+	print "cDir is : @@cDir@@"
+	print e
+	if newDir != None and os.path.exists("../%s" % newDir) and not os.path.exists("@@cDir@@/%s" % newDir):
+		os.chdir("..")
+		shutil.move(newDir, "@@cDir@@/%s" % newDir)
+	iJob = Job(jobname = "@@jobName@@", groupid = "@@groupId@@", launcherFile = "@@launcher@@", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "@@jobTableName@@")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "error")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	sys.exit(1)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/launcher/Launcher.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,229 @@
+from commons.tools.CleanClusterNodesAfterRepet import CleanClusterNodesAfterRepet
+from commons.core.stat.Stat import Stat
+from commons.core.launcher.WriteScript import WriteScript
+from commons.core.sql.TableJobAdaptatorFactory import TableJobAdaptatorFactory
+from commons.core.sql.Job import Job
+import stat
+import os
+import re
+import sys
+import time
+import glob
+
+class Launcher(object):
+
+    #TODO: remove unused parameters : query="", subject="", param="", job_table=""
+    def __init__( self, jobdb, query="", subject="", param="", cdir="",
+                  tmpdir="", job_table="", queue="", groupid="", acro="X",
+                  chooseTemplateWithCopy = False, chooseTemplateLight = False):
+        if jobdb.__class__.__name__ == "RepetJob":
+            self.jobdb = TableJobAdaptatorFactory.createInstance(jobdb, "jobs")
+        else:
+            self.jobdb = jobdb
+        self.jobdb.checkJobTable()
+        if cdir == "":
+            cdir = os.getcwd()
+        self.cdir = cdir
+        self.tmpdir = tmpdir
+        self.groupid = groupid
+        self.acronyme = acro
+        self._chooseTemplateWithCopy = chooseTemplateWithCopy
+        self._chooseTemplateLight = chooseTemplateLight
+        self.queue, self.lResources = self.getQueueNameAndResources(queue)
+        self._createJobInstance()
+        self._nbJobs = 0
+        
+    def getQueueNameAndResources(self, configQueue):
+        tokens = configQueue.replace("'","").split(" ")
+        queueName = ""
+        lResources = []
+        if tokens[0] != "":
+            if re.match(".*\.q", tokens[0]):
+                queueName = tokens[0]
+                lResources = tokens[1:]
+            else:
+                lResources = tokens
+        return queueName, lResources
+
+    def createGroupidIfItNotExist(self):
+        if self.groupid == "":
+            self.job.groupid = str(os.getpid())
+        else:
+            self.job.groupid = self.groupid
+
+    def beginRun( self ):
+        self.createGroupidIfItNotExist()
+        if self.jobdb.hasUnfinishedJob(self.job.groupid):
+            self.jobdb.waitJobGroup(self.job.groupid)
+        else:
+            self.jobdb.cleanJobGroup(self.job.groupid)
+
+    ## Launch one job in parallel
+    #
+    # @param cmdStart string command-line for the job to be launched
+    # @param cmdFinish string command to retrieve result files
+    # @warning the jobname has to be defined outside from this method
+    #
+    def runSingleJob(self, cmdStart, cmdFinish = "", cmdSize = "", cmdCopy = ""):
+        if self._nbJobs == 0:
+            self._nbJobs = 1
+        pid = str(os.getpid())
+        now = time.localtime()
+        #TODO: rename ClusterLauncher_ ...
+        pyFileName = self.cdir + "/ClusterLauncher_" + self.job.groupid + "_" +\
+                     self.job.jobname + "_" + str(now[0]) + "-" + str(now[1]) +\
+                     "-" + str(now[2]) + "_" + pid + ".py"
+        self.job.launcher = pyFileName
+        
+        #TODO: to remove when refactoring is done
+        cmdStart = self._indentCmd(cmdStart)
+        cmdFinish = self._indentCmd(cmdFinish)
+        
+        iWriteScript = WriteScript(self.job, self.jobdb, self.cdir, self.tmpdir, self._chooseTemplateWithCopy, self._chooseTemplateLight)
+        iWriteScript.run(cmdStart, cmdFinish, pyFileName, cmdSize, cmdCopy)
+        os.chmod(pyFileName, stat.S_IRWXU+stat.S_IRGRP+stat.S_IXGRP+stat.S_IROTH+stat.S_IXOTH)
+        sys.stdout.flush()
+        log = self.jobdb.submitJob(self.job)
+        if log != 0:
+            print "ERROR while submitting job to the cluster"
+            sys.exit(1)
+        
+    def endRun(self, cleanNodes = False):
+        string = "waiting for %i job(s) with groupid '%s' (%s)" % (self._nbJobs, self.job.groupid, time.strftime("%Y-%m-%d %H:%M:%S"))
+        print string; sys.stdout.flush()
+        self.jobdb.waitJobGroup(self.job.groupid)
+        if self._nbJobs > 1:
+            string = "all jobs with groupid '%s' are finished (%s)" % (self.job.groupid, time.strftime("%Y-%m-%d %H:%M:%S"))
+            print string; sys.stdout.flush()
+
+        if cleanNodes:
+            string = "start cleaning cluster nodes (%s)" % time.strftime("%Y-%m-%d %H:%M:%S")
+            print string; sys.stdout.flush()
+            self.cleanNodes()
+            string = "end cleaning cluster nodes (%s)" % time.strftime("%Y-%m-%d %H:%M:%S")
+            print string; sys.stdout.flush()
+            
+        statsExecutionTime = self.getStatsOfExecutionTime()
+        if self._nbJobs > 1:
+            print "execution time of all jobs (seconds): %f" % statsExecutionTime.getSum()
+        print "execution time per job: %s" % statsExecutionTime.string()
+        sys.stdout.flush()
+        self.jobdb.cleanJobGroup(self.job.groupid)
+        
+    def getStatsOfExecutionTime(self, acronyme = ""):
+        stat = Stat()
+        if acronyme == "":
+            pattern = "%s*.o*" % self.acronyme
+        else:
+            pattern = "%s*.o*" % acronyme
+        lJobFiles = glob.glob(pattern)
+        for f in lJobFiles:
+            fH = open(f, "r")
+            while True:
+                line = fH.readline()
+                if line == "":
+                    break
+                if "executionTime" in line:
+                    stat.add( float(line[:-1].split("=")[1] ) )
+                    break
+            fH.close()
+        return stat     
+
+    def clean( self, acronyme = "", stdout = True, stderr = True ):
+        lFileToRemove = []
+        if acronyme == "":
+            acronyme = self.acronyme  
+        pattern = "ClusterLauncher*%s*.py" % ( acronyme )
+        lFileToRemove.extend(glob.glob( pattern ))
+        if stdout:
+            pattern = "%s*.o*" % ( acronyme )
+            lFileToRemove.extend(glob.glob( pattern ))        
+        if stderr:
+            pattern = "%s*.e*" % ( acronyme )
+            lFileToRemove.extend(glob.glob( pattern ))                   
+        for file in lFileToRemove:
+            os.remove(file)
+    
+    #TODO: handle of nodesMustBeCleaned => class attribute ?
+    def runLauncherForMultipleJobs(self, acronymPrefix, lCmdsTuples, cleanMustBeDone = True, nodesMustBeCleaned = False):
+        self.beginRun()
+        print "submitting job(s) with groupid '%s' (%s)" % (self.job.groupid,  time.strftime("%Y-%m-%d %H:%M:%S"))
+        for cmdsTuple in lCmdsTuples:
+            self._nbJobs += 1
+            self.acronyme = "%s_%s" % (acronymPrefix, self._nbJobs)
+            self.job.jobname = self.acronyme
+            if len(cmdsTuple) == 2:
+                self.runSingleJob(cmdsTuple[0], cmdsTuple[1])
+            else:
+                self.runSingleJob(cmdsTuple[0], cmdsTuple[1], cmdsTuple[2], cmdsTuple[3])
+                self._createJobInstance()
+                self.createGroupidIfItNotExist()
+        self.acronyme = acronymPrefix
+        self.endRun(nodesMustBeCleaned)
+        if cleanMustBeDone:
+            self.clean("%s_" % acronymPrefix)
+        self.jobdb.close()
+
+    def prepareCommands(self, lCmds, lCmdStart = [], lCmdFinish = [], lCmdSize = [], lCmdCopy = []):
+        cmdStart = ""
+        for cmd in lCmdStart:
+            cmdStart += "%s\n\t" % cmd
+        for cmd in lCmds:
+            cmdStart += "%s\n\t" % cmd
+        cmdFinish = ""
+        for cmd in lCmdFinish:
+            cmdFinish += "%s\n\t" % cmd
+        cmdSize = ""
+        for cmd in lCmdSize:
+            cmdSize += "%s\n\t\t" % cmd
+        cmdCopy = ""
+        for cmd in lCmdCopy:
+            cmdCopy += "%s\n\t\t" % cmd
+        return (cmdStart, cmdFinish, cmdSize, cmdCopy)
+
+    #TODO: to remove when refactoring is done
+    def prepareCommands_withoutIndentation(self, lCmds, lCmdStart = [], lCmdFinish = [], lCmdSize = [], lCmdCopy = []):
+        cmdStart = ""
+        for cmd in lCmdStart:
+            cmdStart += "%s\n" % cmd
+        for cmd in lCmds:
+            cmdStart += "%s\n" % cmd
+        cmdFinish = ""
+        for cmd in lCmdFinish:
+            cmdFinish += "%s\n" % cmd
+        cmdSize = ""
+        for cmd in lCmdSize:
+            cmdSize += "%s\n\t\t" % cmd
+        cmdCopy = ""
+        for cmd in lCmdCopy:
+            cmdCopy += "%s\n\t\t" % cmd
+        return (cmdStart, cmdFinish, cmdSize, cmdCopy)
+    
+    def getSystemCommand(self, prg, lArgs):
+        systemCmd = "log = os.system(\"" + prg 
+        for arg in lArgs:
+            systemCmd += " " + arg
+        systemCmd += "\")"
+        return systemCmd
+
+    def cleanNodes(self):
+        iCleanClusterNodeAfterRepet = CleanClusterNodesAfterRepet()
+        iCleanClusterNodeAfterRepet.setLNodes(self.jobdb.getNodesListByGroupId(self.groupid))
+        iCleanClusterNodeAfterRepet.setTempDirectory(self.tmpdir)
+        iCleanClusterNodeAfterRepet.setPattern("%s*" % self.groupid)
+        iCleanClusterNodeAfterRepet.run()
+
+    #TODO: to remove when refactoring is done
+    def _indentCmd(self, cmd):
+        lCmd = cmd.split("\n")
+        cmd_Tab = "%s\n" % lCmd[0]
+        for line in lCmd[1:-1]:
+            cmd_Tab += "\t%s\n" % line
+        return cmd_Tab
+    
+    def _createJobInstance(self):
+        if self.lResources == []:
+            #To have mem_free=1G:
+            self.job = Job(queue=self.queue)
+        else:
+            self.job = Job(queue=self.queue, lResources=self.lResources)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/launcher/LauncherUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,31 @@
+class LauncherUtils(object):
+
+    @staticmethod
+    def createHomogeneousSizeList(lStringSizeTuples, maxSize):
+        lStringSizeTuplesSorted = sorted(lStringSizeTuples, key=lambda stringSizeTuple:(stringSizeTuple[1], stringSizeTuple[0]), reverse = True)
+        lStringSizeList = []
+        lStringSize = []
+        sumTupleSize = 0
+        iteratorFromBegin = 0
+        iteratorFromEnd = len(lStringSizeTuplesSorted) - 1
+        for tuple in lStringSizeTuplesSorted:
+            if sumTupleSize + tuple[1] < maxSize:
+                lStringSize.append(tuple[0])
+                sumTupleSize += tuple[1]
+            elif tuple[1] >= maxSize:
+                lStringSizeList.append([tuple[0]])
+            else:
+                tupleFromEnd = lStringSizeTuplesSorted[iteratorFromEnd]
+                while sumTupleSize + tupleFromEnd[1] < maxSize and iteratorFromBegin < iteratorFromEnd:
+                    lStringSize.append(tupleFromEnd[0])
+                    sumTupleSize += tupleFromEnd[1]
+                    del lStringSizeTuplesSorted[iteratorFromEnd]
+                    iteratorFromEnd -= 1
+                    tupleFromEnd = lStringSizeTuplesSorted[iteratorFromEnd]
+                lStringSizeList.append(lStringSize)
+                lStringSize = [tuple[0]]
+                sumTupleSize = tuple[1]
+            iteratorFromBegin += 1
+        if lStringSize:
+            lStringSizeList.append(lStringSize)
+        return lStringSizeList
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/launcher/WriteScript.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,76 @@
+import os
+import time
+
+class WriteScript(object):
+
+    def __init__(self, job = None, jobdb = None, cdir = "", tmpdir = "", chooseTemplateWithCopy = False, chooseTemplateLight = False):
+        self._iJob = job
+        self._iJobdb = jobdb
+        self._cDir = cdir
+        self._tmpDir = tmpdir
+        self._chooseTemplateWithCopy = chooseTemplateWithCopy
+        self._chooseTemplateLight = chooseTemplateLight
+
+    def run(self, cmdStart, cmdFinish, pyFileName, cmdSize = "", cmdCopy = ""):
+        if self._chooseTemplateLight:
+            d = self.createJobScriptLightDict(cmdStart, cmdFinish, cmdSize, cmdCopy)
+        else:
+            d = self.createJobScriptDict(cmdStart, cmdFinish, cmdSize, cmdCopy)
+        self.fillTemplate(pyFileName, d)
+    
+    def fillTemplate(self, outputFileName, dict):
+        if self._chooseTemplateWithCopy:
+            inputFileName = "%s/commons/core/launcher/JobScriptWithFilesCopyTemplate.py" % os.environ["REPET_PATH"]
+        else:
+            inputFileName = "%s/commons/core/launcher/JobScriptTemplate.py" % os.environ["REPET_PATH"]
+
+        if self._chooseTemplateLight:
+            inputFileName = "%s/commons/core/launcher/JobScriptTemplateLight.py" % os.environ["REPET_PATH"]
+            
+        input = open(inputFileName, "r")
+        data = input.read()
+        input.close()
+        for key, value in dict.items():
+            data = data.replace("@@%s@@" % key, value)
+        output = open(outputFileName, "w")
+        output.write(data)
+        output.close()
+    
+    def createJobScriptDict(self, cmdStart, cmdFinish, cmdSize, cmdCopy):
+        dict = {
+         "tmpDir" : self._tmpDir,
+         "jobTableName" : self._iJobdb._table,
+         "groupId" : self._iJob.groupid,
+         "jobName" : self._iJob.jobname,
+         "launcher" : self._iJob.launcher,
+         "time" : time.strftime("%Y%m%d-%H%M%S"),
+         "repet_path" : os.environ["REPET_PATH"],
+         "repet_host" : os.environ["REPET_HOST"],
+         "repet_user" : os.environ["REPET_USER"],
+         "repet_pw" : os.environ["REPET_PW"],
+         "repet_db" : os.environ["REPET_DB"],
+         "repet_port" : os.environ["REPET_PORT"],
+         "cmdStart" : cmdStart,
+         "cmdFinish" : cmdFinish,
+         "cDir" : self._cDir,
+         "cmdSize" : cmdSize,
+         "cmdCopy" : cmdCopy
+            }      
+        return dict
+    
+    def createJobScriptLightDict(self, cmdStart, cmdFinish, cmdSize, cmdCopy):
+        dict = {
+         "tmpDir" : self._tmpDir,
+         "jobTableName" : self._iJobdb._table,
+         "groupId" : self._iJob.groupid,
+         "jobName" : self._iJob.jobname,
+         "launcher" : self._iJob.launcher,
+         "time" : time.strftime("%Y%m%d-%H%M%S"),
+         "repet_path" : os.environ["REPET_PATH"],
+         "cmdStart" : cmdStart,
+         "cmdFinish" : cmdFinish,
+         "cDir" : self._cDir,
+         "cmdSize" : cmdSize,
+         "cmdCopy" : cmdCopy
+            }      
+        return dict
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/launcher/test/Test_Launcher.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,333 @@
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.launcher.Launcher import Launcher
+from commons.core.launcher.WriteScript import WriteScript
+from commons.core.stat.Stat import Stat
+from commons.core.sql.TableJobAdaptatorFactory import TableJobAdaptatorFactory
+from commons.core.sql.DbFactory import DbFactory
+from commons.core.sql.Job import Job
+import unittest
+import os
+import shutil
+import time
+import stat
+
+#TODO: Test_F_Launcher.py : to execute prepareCommands() and runSingleJob()
+#                            to test runLauncherForMultipleJobs()
+#TODO: check clean of "Test_runSingleJob"
+#TODO: refactoring => choose between "self._queue" or "lResources" to set resources
+class Test_Launcher(unittest.TestCase):
+
+    SARUMAN_NAME = "compute-2-46.local"
+    
+    def setUp(self):
+        self._cDir = os.getcwd()
+        self._tmpDir = self._cDir
+        self._groupid = "test"
+        self._jobTable = "dummyJobTable"
+        self._iDb = DbFactory.createInstance()
+        self._iDb.createTable(self._jobTable, "jobs", overwrite = True)
+        self._jobdb = TableJobAdaptatorFactory.createInstance(self._iDb, self._jobTable)
+        self._queue = ""
+        self._configFileName = "dummyConfigFile"
+    
+    def tearDown(self):
+        self._iDb.dropTable(self._jobTable)
+        self._iDb.close()
+        FileUtils.removeFilesByPattern('*.e*')
+        FileUtils.removeFilesByPattern('*.o*')
+        FileUtils.removeFilesByPattern('launcherFileTest_BeginRun.py')
+        FileUtils.removeFilesByPattern(self._configFileName)
+        FileUtils.removeFilesByPattern('ClusterLauncher_*')
+        
+    def test__init__wrong_fields_for_job_table(self):
+        self._iDb.dropTable(self._jobTable)
+        sqlCmd = "CREATE TABLE " + self._jobTable 
+        sqlCmd += " ( jobid INT UNSIGNED"
+        sqlCmd += ", jobname VARCHAR(255)"
+        sqlCmd += ", groupid VARCHAR(255)"
+        sqlCmd += ", command TEXT"
+        sqlCmd += ", launcher VARCHAR(1024)"
+        sqlCmd += ", queue VARCHAR(255)"
+        sqlCmd += ", status VARCHAR(255)"
+        sqlCmd += ", time DATETIME"
+        sqlCmd += ", node VARCHAR(255) )"
+        self._iDb.execute(sqlCmd)
+        acronym = "Test__init__"
+        iLauncher = Launcher(self._jobdb, os.getcwd(), "", "", self._cDir, self._tmpDir, "", self._queue, self._groupid, acronym)
+        lExpFields = sorted(["jobid", "jobname", "groupid", "launcher", "queue", "resources", "status", "time", "node"])
+        lObsFields = sorted(self._iDb.getFieldList(self._jobTable))
+        self.assertEquals(lExpFields, lObsFields)
+        expJob = Job(queue = self._queue)
+        obsJob = iLauncher.job
+        self.assertEquals(expJob, obsJob)
+        
+    def test__init__withResources(self):
+        queue = "main.q mem_free=3G"
+        acronym = "Test__init__"
+        expQueue = "main.q"
+        explResources = ['mem_free=3G']
+        expJob = Job(queue = expQueue, lResources = explResources)
+        iLauncher = Launcher(self._jobdb, os.getcwd(), "", "", self._cDir, self._tmpDir, "", queue, self._groupid, acronym)
+        obsJob = iLauncher.job
+        self.assertEquals(expJob, obsJob)
+
+    def test_createGroupidIfItNotExist(self):
+        acronym = "checkGroupID"
+        iLauncher = Launcher(self._jobdb, os.getcwd(), "", "", self._cDir, self._tmpDir, "", self._queue, self._groupid, acronym)
+        iLauncher.createGroupidIfItNotExist()
+        obsGroupid = iLauncher.job.groupid
+        self.assertEquals(self._groupid, obsGroupid)
+
+    def test_createGroupidIfItNotExist_without_groupid(self):
+        groupid = ""
+        acronym = "checkGroupID"
+        iLauncher = Launcher(self._jobdb, os.getcwd(), "", "", self._cDir, self._tmpDir, "", self._queue, groupid, acronym)
+        iLauncher.createGroupidIfItNotExist()
+        obsGroupid = iLauncher.job.groupid
+        self.assertTrue(obsGroupid != "")
+        
+    def test_beginRun_with_Job_finished_in_Table(self):
+        acronym = "BeginRun"
+        iJob = Job(queue = self._queue)
+        self._jobdb.recordJob(iJob)
+        self._jobdb.changeJobStatus(iJob, "finished")
+        iLauncher = Launcher(self._jobdb, os.getcwd(), "", "", self._cDir, self._tmpDir, "", self._queue, self._groupid, acronym)
+        iLauncher.beginRun()
+        self.assertTrue(self._jobdb.getCountStatus(self._groupid, "finished") == 0)
+        
+    def test_beginRun_with_Job_unfinished_in_Table(self):
+        acronym = "testU_BeginRun"
+        cmd_start = "log = os.system( \"date;sleep 10;date\" )\n"
+        pyFileName = "%s/launcherFileTest_BeginRun.py" % os.getcwd()
+        if Test_Launcher.SARUMAN_NAME == os.getenv("HOSTNAME"):
+            iJob = Job(1, acronym, self._groupid, "", cmd_start, pyFileName, lResources=["test=TRUE"])
+        else: 
+            iJob = Job(1, acronym, self._groupid, "", cmd_start, pyFileName)
+        iWriteScript = WriteScript(iJob, self._jobdb, self._cDir, self._tmpDir)
+        iWriteScript.run(cmd_start, "", pyFileName)
+        os.chmod(pyFileName, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
+        self._jobdb.submitJob(iJob)
+        iLauncher = Launcher(self._jobdb, os.getcwd(), "", "", self._cDir, self._tmpDir, "", self._queue, self._groupid, acronym)
+        
+        iLauncher.beginRun()
+        
+        self.assertTrue(self._jobdb.getCountStatus(self._groupid, "finished") == 1)
+    
+    def test_getStatsOfExecutionTime(self):
+        acronym = "test_statTime"
+        
+        expLValues = [1000.00000, 1000.00000]
+        expStat = Stat(expLValues) 
+        
+        f = open(acronym +".o1", "w")
+        f.write("executionTime=1000.000000")
+        f.close()
+        f = open(acronym +".o2", "w")
+        f.write("executionTime=1000.000000")
+        f.close()
+        
+        iLauncher = Launcher(self._jobdb, os.getcwd(), "", "", self._cDir, self._tmpDir, "", self._queue, self._groupid, acronym)
+        obsStat = iLauncher.getStatsOfExecutionTime(acronym)
+        
+        self.assertEqual(expStat, obsStat)           
+           
+    def test_endRun(self):
+        acronym = "testU_EndRun"
+        cmd_start = "log = os.system( \"date;sleep 10;date\" )\n"
+        pyFileName = "%s/launcherFileTest_EndRun.py" % os.getcwd()
+        if Test_Launcher.SARUMAN_NAME == os.getenv("HOSTNAME"):
+            iJob = Job(1, acronym, self._groupid, "", cmd_start, pyFileName, lResources=["test=TRUE"])
+        else: 
+            iJob = Job(1, acronym, self._groupid, "", cmd_start, pyFileName)
+ 
+        iWriteScript = WriteScript(iJob, self._jobdb, self._cDir, self._tmpDir)
+        iWriteScript.run(cmd_start, "", pyFileName)
+        os.chmod(pyFileName, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
+        self._jobdb.submitJob(iJob)
+        iLauncher = Launcher(self._jobdb, os.getcwd(), "", "", self._cDir, self._tmpDir, "", self._queue, self._groupid, acronym)
+        iLauncher.job.groupid = self._groupid
+        iLauncher.endRun()
+        
+        self.assertTrue(self._jobdb.getCountStatus(self._groupid, "finished") == 0)
+        self.assertTrue(self._jobdb.getCountStatus(self._groupid, "error") == 0)
+        self.assertTrue(self._jobdb.getCountStatus(self._groupid, "waiting") == 0)    
+           
+        os.remove(iJob.launcher)
+
+    def test_clean(self):
+        acronym = "test_clean"
+        f = open("ClusterLauncher" + acronym + ".py", "w")
+        f.close()
+        f = open(acronym + ".o1", "w")
+        f.close()
+        f = open(acronym + ".e1", "w")
+        f.close()
+        iLauncher = Launcher(self._jobdb, os.getcwd(), "", "", self._cDir, self._tmpDir, "", self._queue, self._groupid, acronym)
+        iLauncher.clean(acronym)
+        self.assertFalse(FileUtils.isRessourceExists("ClusterLauncher" + acronym + ".py"))
+
+    def test_clean_without_acronym(self):
+        acronym = ""
+        acronym2 = "toto"
+        f = open("ClusterLauncher" + acronym2 + ".py", "w")
+        f.close()
+        f = open(acronym2 + ".o1", "w")
+        f.close()
+        f = open(acronym2 + ".e1", "w")
+        f.close()
+        iLauncher = Launcher(self._jobdb, os.getcwd(), "", "", self._cDir, self._tmpDir, "", self._queue, self._groupid, acronym2)
+        iLauncher.clean(acronym)
+        self.assertFalse(FileUtils.isRessourceExists("ClusterLauncher" + acronym2 + ".py"))
+        
+    def test_getQueueNameAndResources_queue_no_resource(self):
+        configQueue = "all.q"
+        expQueueName = "all.q"
+        expResources = []
+        iLauncher = Launcher(self._jobdb)
+        obsQueueName, obsResources = iLauncher.getQueueNameAndResources(configQueue)
+        self.assertEquals(expQueueName, obsQueueName)
+        self.assertEquals(expResources, obsResources)
+        
+    def test_getQueueNameAndResources_queue_one_resource(self):
+        configQueue = "test.q 'test=TRUE'"
+        expQueueName = "test.q"
+        expResources = ["test=TRUE"]
+        iLauncher = Launcher(self._jobdb)
+        obsQueueName, obsResources = iLauncher.getQueueNameAndResources(configQueue)
+        self.assertEquals(expQueueName, obsQueueName)
+        self.assertEquals(expResources, obsResources)
+        
+    def test_getQueueNameAndResources_queue_two_resources(self):
+        configQueue = "big.q 's_data=8G s_cpu=96:00:00'"
+        expQueueName = "big.q"
+        expResources = ["s_data=8G", "s_cpu=96:00:00"]
+        iLauncher = Launcher(self._jobdb)
+        obsQueueName, obsResources = iLauncher.getQueueNameAndResources(configQueue)
+        self.assertEquals(expQueueName, obsQueueName)
+        self.assertEquals(expResources, obsResources)
+        
+    def test_getQueueNameAndResources_no_queue_no_resource(self):
+        configQueue = ""
+        expQueueName = ""
+        expResources = []
+        iLauncher = Launcher(self._jobdb)
+        obsQueueName, obsResources = iLauncher.getQueueNameAndResources(configQueue)
+        self.assertEquals(expQueueName, obsQueueName)
+        self.assertEquals(expResources, obsResources)
+        
+    def test_getQueueNameAndResources_no_queue_one_resource(self):
+        configQueue = "s_data=8G"
+        expQueueName = ""
+        expResources = ["s_data=8G"]
+        iLauncher = Launcher(self._jobdb)
+        obsQueueName, obsResources = iLauncher.getQueueNameAndResources(configQueue)
+        self.assertEquals(expQueueName, obsQueueName)
+        self.assertEquals(expResources, obsResources)
+        
+    def test_getQueueNameAndResources_no_queue_two_resource(self):
+        configQueue = "s_data=8G s_cpu=96:00:00"
+        expQueueName = ""
+        expResources = ["s_data=8G", "s_cpu=96:00:00"]
+        iLauncher = Launcher(self._jobdb)
+        obsQueueName, obsResources = iLauncher.getQueueNameAndResources(configQueue)
+        self.assertEquals(expQueueName, obsQueueName)
+        self.assertEquals(expResources, obsResources)      
+
+#   #TODO: test with at least 2 lines in cmd
+    def test_runSingleJob(self):
+        acronym = "Test_runSingleJob"
+        os.mkdir(acronym)
+        os.chdir(acronym)
+        iLauncher = Launcher(self._jobdb, os.getcwd(), "", "", os.getcwd(), self._tmpDir, "", self._queue, self._groupid, acronym)
+        iLauncher.job.groupid = self._groupid
+        iLauncher.job.jobname = acronym
+        iLauncher.job.queue = self._queue
+        if Test_Launcher.SARUMAN_NAME == os.getenv("HOSTNAME"):
+            iLauncher.job.lResources = ["test=TRUE"]
+        cmd = "log = os.system(\"touch 'YuFei'\")\n"
+        iLauncher.runSingleJob(cmd)
+        time.sleep(20)
+        jobStatus = self._jobdb.getJobStatus(iLauncher.job)
+        os.chdir(self._cDir)
+        shutil.rmtree(acronym)
+        self.assertEqual(jobStatus, "finished")
+        
+    def test_runSingleJob_catch_error_wrong_tmpDir(self):
+        acronym = "Test_runSingleJob_catch_error"
+        os.mkdir(acronym)
+        os.chdir(acronym)
+        iLauncher = Launcher(self._jobdb, os.getcwd(), "", "", os.getcwd(), "%s/toto" % self._tmpDir, "", self._queue, self._groupid, acronym)
+        iLauncher.job.groupid = self._groupid
+        iLauncher.job.jobname = acronym
+        iLauncher.job.queue = self._queue
+        if Test_Launcher.SARUMAN_NAME == os.getenv("HOSTNAME"):
+            iLauncher.job.lResources = ["test=TRUE"]
+        cmd = "log = os.system(\"touch 'YuFei'\")\n"
+        iLauncher.runSingleJob(cmd)
+        time.sleep(20)
+        jobStatus = self._jobdb.getJobStatus(iLauncher.job) 
+        os.chdir(self._cDir)
+        shutil.rmtree(acronym)
+        self.assertEqual(jobStatus, "error")
+        
+    def test_runSingleJob_catch_error_wrong_cmd(self):
+        acronym = "Test_runSingleJob_catch_error"
+        os.mkdir(acronym)
+        os.chdir(acronym)
+        iLauncher = Launcher(self._jobdb, os.getcwd(), "", "", os.getcwd(), self._tmpDir, "", self._queue, self._groupid, acronym)
+        iLauncher.job.groupid = self._groupid
+        iLauncher.job.jobname = acronym
+        iLauncher.job.queue = self._queue
+        if Test_Launcher.SARUMAN_NAME == os.getenv("HOSTNAME"):
+            iLauncher.job.lResources = ["test=TRUE"]
+        cmd = "log = os.system(\"truc -i toto\")\n"
+        iLauncher.runSingleJob(cmd)
+        time.sleep(20)
+        jobStatus = self._jobdb.getJobStatus(iLauncher.job) 
+        self._jobdb.cleanJobGroup(self._groupid)
+        os.chdir(self._cDir)
+        shutil.rmtree(acronym)
+        self.assertEqual(jobStatus, "error")
+
+    def test_prepareCommands(self):
+        expCmdStart = "os.symlink(\"../Yufei_chunks.fa\", \"Yufei_chunks.fa\")\n\tos.symlink(\"../Yufei_chunks.fa_cut\", \"Yufei_chunks.fa_cut\")\n\tlog = os.system(\"touch file\")\n\t" 
+        expCmdFinish = "if os.path.exists(\"yufei.align\"):\n\t\tshutil.move(\"yufei.align\", \"yufeiLuo/.\" )\n\t"
+        expCmdSize = "fileSize = 3.2\n\t\t"
+        expCmdCopy = "shutil.copy(\"PY/Yufei_db/Yufei_chunks.fa\", \".\")\n\t\tshutil.copy(\"PY/Yufei_db/Yufei_chunks.fa_cut\", \".\")\n\t\t"
+        
+        lCmdStart = []
+        lCmdStart.append("os.symlink(\"../Yufei_chunks.fa\", \"Yufei_chunks.fa\")")
+        lCmdStart.append("os.symlink(\"../Yufei_chunks.fa_cut\", \"Yufei_chunks.fa_cut\")")
+        lCmds = []
+        lCmds.append("log = os.system(\"touch file\")")
+        lCmdFinish = []
+        lCmdFinish.append("if os.path.exists(\"yufei.align\"):")
+        lCmdFinish.append("\tshutil.move(\"yufei.align\", \"yufeiLuo/.\" )") 
+        lCmdSize = []
+        lCmdSize.append("fileSize = 3.2")    
+        lCmdCopy = []
+        lCmdCopy.append("shutil.copy(\"PY/Yufei_db/Yufei_chunks.fa\", \".\")")
+        lCmdCopy.append("shutil.copy(\"PY/Yufei_db/Yufei_chunks.fa_cut\", \".\")")
+
+        iLauncher = Launcher(self._jobdb)
+        obsCmdStart, obsCmdFinish, obsCmdSize, obsCmdCopy = iLauncher.prepareCommands(lCmds, lCmdStart, lCmdFinish, lCmdSize, lCmdCopy)         
+        
+        self.assertEquals(expCmdStart, obsCmdStart)
+        self.assertEquals(expCmdFinish, obsCmdFinish)      
+        self.assertEquals(expCmdSize, obsCmdSize)
+        self.assertEquals(expCmdCopy, obsCmdCopy)
+        
+    def test_getSystemCommand(self):
+        prg = "touch"
+        lArgs = []
+        lArgs.append("file")
+        expCmd = "log = os.system(\"touch file\")"
+        iLauncher = Launcher(self._jobdb)
+        obsCmd = iLauncher.getSystemCommand(prg, lArgs)
+        self.assertEquals(expCmd, obsCmd)
+
+
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_Launcher ) )
+if __name__ == "__main__":
+        unittest.TextTestRunner(verbosity=2).run( test_suite )    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/launcher/test/Test_LauncherUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,102 @@
+import unittest
+from commons.core.launcher.LauncherUtils import LauncherUtils
+
+class Test_LauncherUtils(unittest.TestCase):
+        
+    def test_createHomogeneousSizeList_empty(self):
+        lHeadersSizeTuples = []
+        maxSize = 500
+        expLHeadersList = []
+        obsLHeadersList = LauncherUtils.createHomogeneousSizeList(lHeadersSizeTuples, maxSize)
+        self.assertEquals(expLHeadersList, obsLHeadersList)
+        
+    def test_createHomogeneousSizeList_one_item_upper_mean(self):
+        lHeadersSizeTuples = [("h1", 300)]
+        maxSize = 500
+        expLHeadersList = [["h1"]]
+        obsLHeadersList = LauncherUtils.createHomogeneousSizeList(lHeadersSizeTuples, maxSize)
+        self.assertEquals(expLHeadersList, obsLHeadersList)
+        
+    def test_createHomogeneousSizeList_one_item_under_mean(self):
+        lHeadersSizeTuples = [("h1", 100)]
+        maxSize = 500
+        expLHeadersList = [["h1"]]
+        obsLHeadersList = LauncherUtils.createHomogeneousSizeList(lHeadersSizeTuples, maxSize)
+        self.assertEquals(expLHeadersList, obsLHeadersList)
+        
+    def test_createHomogeneousSizeList_3items(self):
+        lHeadersSizeTuples = [("h1", 250),
+                              ("h2", 250),
+                              ("h3", 300)]
+        maxSize = 500
+        expLHeadersList = [["h3"], ["h2"], ["h1"]]
+        obsLHeadersList = LauncherUtils.createHomogeneousSizeList(lHeadersSizeTuples, maxSize)
+        self.assertEquals(expLHeadersList, obsLHeadersList)
+
+    def test_createHomogeneousSizeList_4items(self):
+        lHeadersSizeTuples = [("h1", 100),
+                              ("h2", 200),
+                              ("h3", 10),
+                              ("h4", 400)]
+        maxSize = 500
+        expLHeadersList = [["h4", "h3"], ["h2", "h1"]]
+        obsLHeadersList = LauncherUtils.createHomogeneousSizeList(lHeadersSizeTuples, maxSize)
+        self.assertEquals(expLHeadersList, obsLHeadersList)
+        
+    def test_createHomogeneousSizeList_5items(self):
+        lHeadersSizeTuples = [("h1", 300),
+                              ("h2", 300),
+                              ("h3", 250),
+                              ("h4", 100),
+                              ("h5", 90)]
+        maxSize = 500
+        expLHeadersList = [["h2", "h5","h4"], ["h1"], ["h3"]]
+        obsLHeadersList = LauncherUtils.createHomogeneousSizeList(lHeadersSizeTuples, maxSize)
+        self.assertEquals(expLHeadersList, obsLHeadersList)
+        
+    def test_createHomogeneousSizeList_all_upper_max(self):
+        lHeadersSizeTuples = [("h1", 600),
+                              ("h2", 500),
+                              ("h3", 700),
+                              ("h4", 900),
+                              ("h5", 500)]
+        maxSize = 500
+        expLHeadersList = [["h4"], ["h3"], ["h1"], ["h5"], ["h2"]]
+        obsLHeadersList = LauncherUtils.createHomogeneousSizeList(lHeadersSizeTuples, maxSize)
+        self.assertEquals(expLHeadersList, obsLHeadersList)
+        
+    def test_createHomogeneousSizeList_all_upper_mean(self):
+        lHeadersSizeTuples = [("h1", 300),
+                              ("h2", 300),
+                              ("h3", 300),
+                              ("h4", 300),
+                              ("h5", 300)]
+        maxSize = 500
+        expLHeadersList = [["h5"], ["h4"], ["h3"], ["h2"], ["h1"]]
+        obsLHeadersList = LauncherUtils.createHomogeneousSizeList(lHeadersSizeTuples, maxSize)
+        self.assertEquals(expLHeadersList, obsLHeadersList)
+        
+    def test_createHomogeneousSizeList_all_under_mean(self):
+        lHeadersSizeTuples = [("h1", 100),
+                              ("h2", 100),
+                              ("h3", 100),
+                              ("h4", 100),
+                              ("h5", 100)]
+        maxSize = 500
+        expLHeadersList = [["h5", "h4", "h3", "h2"], ["h1"]]
+        obsLHeadersList = LauncherUtils.createHomogeneousSizeList(lHeadersSizeTuples, maxSize)
+        self.assertEquals(expLHeadersList, obsLHeadersList)
+        
+    def test_createHomogeneousSizeList_floats(self):
+        lHeadersSizeTuples = [("h1", 99.1),
+                              ("h2", 100.7),
+                              ("h3", 100.1),
+                              ("h4", 100.1),
+                              ("h5", 100)]
+        maxSize = 500
+        expLHeadersList = [['h2', 'h4', 'h3', 'h5'], ["h1"]]
+        obsLHeadersList = LauncherUtils.createHomogeneousSizeList(lHeadersSizeTuples, maxSize)
+        self.assertEquals(expLHeadersList, obsLHeadersList)
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/launcher/test/Test_WriteScript.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,365 @@
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.launcher.WriteScript import WriteScript
+from commons.core.sql.Job import Job
+from commons.core.sql.DbFactory import DbFactory
+from commons.core.sql.TableJobAdaptatorFactory import TableJobAdaptatorFactory
+import unittest
+import os
+import shutil
+import time
+import threading
+
+class Test_WriteScript(unittest.TestCase):
+
+    def setUp(self):
+        self._testDir = os.getcwd()
+        self._acronym = "dummyAcronym"
+        self._jobTable = "dummyJobsTable"
+        self._iDb = DbFactory.createInstance()
+        self._iDb.createTable(self._jobTable, "jobs", overwrite = True)
+        self._jobdb = TableJobAdaptatorFactory.createInstance(self._iDb, self._jobTable)
+        self._job = Job()
+        self._job.groupid = "groupid"
+        self._job.jobname = self._acronym
+        self._job.launcher = "ClusterLauncher"
+        self._jobdb.recordJob(self._job)
+        self._dummyScratch = "dummyScratch"
+        os.mkdir(self._dummyScratch)
+        os.chdir(self._dummyScratch)
+        self._tmpDir = os.getcwd()
+        self._iScriptWriter = WriteScript(self._job, self._jobdb, self._testDir, self._tmpDir)
+        
+    def tearDown(self):
+        self._iDb.dropTable(self._jobTable)
+        self._iDb.close()
+        if FileUtils.isRessourceExists(self._dummyScratch):
+            shutil.rmtree(self._dummyScratch)
+
+    def test_run(self):
+        isScriptAsRun = False
+        fileToCreate = 'dummyFile'
+        cmdStart = "log = os.system( \"touch %s\" )\n" % fileToCreate
+        cmdFinish = "os.system(\"mv %s %s\" )\n" % (fileToCreate, self._testDir)
+        pyFileName = "%s/ClusterLauncher_%s.py" % (os.getcwd(), self._acronym)       
+        
+        self._iScriptWriter.run(cmdStart, cmdFinish, pyFileName)
+        os.system("python %s" % pyFileName)
+
+        os.chdir(self._testDir)
+        if FileUtils.isRessourceExists(fileToCreate):
+            os.remove(fileToCreate)
+            isScriptAsRun = True
+        expJobStatus = "finished"    
+        obsJobStatus = self._jobdb.getJobStatus(self._job)
+            
+        self.assertTrue(isScriptAsRun)
+        self.assertEquals(expJobStatus, obsJobStatus)
+        
+    def test_run_with_cmdSize_and_cmdCopy(self):
+        isScriptAsRun = False
+        fileToCreate = 'dummyFile'
+        fileSize = 0.5
+        cmdSize = "fileSize = %f\n" % fileSize
+        cmdCopy = "os.system(\"touch bank.fa\")\n"
+        cmdStart = "log = os.system(\"touch %s\")\n" % fileToCreate
+        cmdFinish = "shutil.move(\"%s\", \"%s\")" % (fileToCreate, self._testDir)
+        pyFileName = "%s/ClusterLauncher_%s.py" % (os.getcwd(), self._acronym)       
+        
+        iWriteScript = WriteScript(self._job, self._jobdb, self._testDir, self._tmpDir, True)
+        iWriteScript.run(cmdStart, cmdFinish, pyFileName, cmdSize, cmdCopy)
+        os.system("python %s" % pyFileName)
+
+        os.chdir(self._testDir)
+        if FileUtils.isRessourceExists(fileToCreate):
+            os.remove(fileToCreate)
+            isScriptAsRun = True
+        expJobStatus = "finished"    
+        obsJobStatus = self._jobdb.getJobStatus(self._job)
+            
+        self.assertTrue(isScriptAsRun)
+        self.assertEquals(expJobStatus, obsJobStatus)
+
+#TODO: how to test ?
+#    def test_run_2_jobs_trying_to_create_same_groupIdDir(self):
+#        fileToCreate1 = 'dummyFile1'
+#        fileToCreate2 = 'dummyFile2'
+#        flagFileOSError = "osErrorRaised"
+#        
+#        fileSize = 0.5
+#        cmd_checkSize = ""
+#        cmd_checkSize += "if not os.path.exists( \"%s\" ):\n" % self._job.groupid
+#        cmd_checkSize += "\tfileSize = %f\n" % fileSize
+#        
+#        cmd_checkGroupidDir1 = ""
+#        cmd_checkGroupidDir1 += "if not os.path.exists(\"%s\"):\n" % self._job.groupid
+#        cmd_checkGroupidDir1 += "\ttry:\n"
+#        cmd_checkGroupidDir1 += "\t\ttime.sleep(10)\n"
+#        cmd_checkGroupidDir1 += "\t\tos.mkdir(\"%s\")\n" % self._job.groupid
+#        cmd_checkGroupidDir1 += "\texcept OSError, e :\n"
+#        cmd_checkGroupidDir1 += "\t\tos.system(\"touch %s\")\n" % flagFileOSError
+#        cmd_checkGroupidDir1 += "\t\tif e.args[0] != 17:\n"
+#        cmd_checkGroupidDir1 += "\t\t\traise RepetException(\"ERROR: can't create '%s'\")\n" % self._job.groupid
+#        cmd_checkGroupidDir1 += "\tos.chdir(\"%s\")\n" % self._job.groupid
+#        cmd_checkGroupidDir1 += "\tos.system(\"touch bank.fa\")\n" #cp
+#        cmd_checkGroupidDir1 += "else:\n"
+#        cmd_checkGroupidDir1 += "\tos.chdir(\"%s\")\n" % self._job.groupid
+#        
+#        cmdStart1 = "log = os.system(\"touch %s\")\n" % fileToCreate1
+#        cmdFinish1 = "shutil.move(\"%s\", \"%s\")\n" % (fileToCreate1, self._testDir)
+#        pyFileName1 = "%s/ClusterLauncher1_job1.py" % os.getcwd()
+#       
+#        cmd_checkGroupidDir2 = ""
+#        cmd_checkGroupidDir2 += "if not os.path.exists(\"%s\"):\n" % self._job.groupid
+#        cmd_checkGroupidDir2 += "\ttry:\n"
+#        cmd_checkGroupidDir2 += "\t\tos.mkdir(\"%s\")\n" % self._job.groupid
+#        cmd_checkGroupidDir2 += "\texcept OSError, e :\n"
+#        cmd_checkGroupidDir2 += "\t\tif e.args[0] != 17:\n"
+#        cmd_checkGroupidDir2 += "\t\t\traise RepetException(\"ERROR: can't create '%s'\")\n" % self._job.groupid
+#        cmd_checkGroupidDir2 += "\tos.chdir(\"%s\")\n" % self._job.groupid
+#        cmd_checkGroupidDir2 += "\tos.system(\"touch bank.fa\")\n" #cp
+#        cmd_checkGroupidDir2 += "else:\n"
+#        cmd_checkGroupidDir2 += "\tos.chdir(\"%s\")\n" % self._job.groupid
+#        
+#        cmdStart2 = "log = os.system(\"touch %s\")\n" % fileToCreate2
+#        cmdFinish2 = "shutil.move(\"%s\", \"%s\")\n" % (fileToCreate2, self._testDir)
+#        pyFileName2 = "%s/ClusterLauncher2_job2.py" % os.getcwd()
+#            
+#        job1 = Job(self._jobTable, jobname = "job1", groupid = self._job.groupid)
+#        self._jobdb.recordJob(job1)
+#        job2 = Job(self._jobTable, jobname = "job2", groupid = self._job.groupid)
+#        self._jobdb.recordJob(job2)
+#        iScriptWriter1 = WriteScript(job1, self._jobdb, self._testDir, self._tmpDir)
+#        iScriptWriter1.run(cmdStart1, cmdFinish1, pyFileName1, cmd_checkSize, cmd_checkGroupidDir1)
+#        iScriptWriter2 = WriteScript(job2, self._jobdb, self._testDir, self._tmpDir)
+#        iScriptWriter2.run(cmdStart2, cmdFinish2, pyFileName2, cmd_checkSize, cmd_checkGroupidDir2)
+#    
+#        iCFT1 = CreateFileThread(pyFileName1)
+#        iCFT2 = CreateFileThread(pyFileName2)
+#        iCFT1.start()
+#        iCFT2.start()
+#        while iCFT1.isAlive() or iCFT2.isAlive():
+#            time.sleep(5)
+#        self.assertTrue(FileUtils.isRessourceExists(flagFileOSError))
+#        os.chdir(self._testDir)
+#        
+#        if FileUtils.isRessourceExists(fileToCreate1):
+#            os.remove(fileToCreate1)
+#            
+#        if FileUtils.isRessourceExists(fileToCreate2):            
+#            os.remove(fileToCreate2)
+    
+    def test_run_2_lines_in_cmd_start(self):
+        isScriptAsRun = False
+        fileToCreate = 'dummyFile'
+        
+        cmdStart = "log = 0\n\t"
+        cmdStart += "if True:\n\t"
+        cmdStart += "\tos.system( \"touch dummyFile\" )\n"
+        cmdFinish = "os.system(\"mv %s %s\" )\n" % (fileToCreate, self._testDir)
+        pyFileName = "%s/ClusterLauncher_%s.py" % (os.getcwd(), self._acronym)       
+        
+        self._iScriptWriter.run(cmdStart, cmdFinish, pyFileName)
+        os.system("python %s" % pyFileName)
+        
+        os.chdir(self._testDir)
+        if FileUtils.isRessourceExists(fileToCreate):
+            os.remove(fileToCreate)
+            isScriptAsRun = True
+        self.assertTrue(isScriptAsRun)
+
+    def test_run_2_lines_in_cmd_finish(self):
+        isScriptAsRun = False
+        fileToCreate = 'dummyFile'
+        
+        cmdStart = "log = 0\n\t"
+        cmdStart += "if True:\n\t"
+        cmdStart += "\tos.system( \"touch dummyFile\" )\n"
+        cmdFinish = "if True:\n\t"
+        cmdFinish += "\tos.system(\"mv %s %s\" )\n" % (fileToCreate, self._testDir)
+        pyFileName = "%s/ClusterLauncher_%s.py" % (os.getcwd(), self._acronym)       
+        
+        self._iScriptWriter.run(cmdStart, cmdFinish, pyFileName)
+        os.system("python %s" % pyFileName)
+        
+        os.chdir(self._testDir)
+        if FileUtils.isRessourceExists(fileToCreate):
+            os.remove(fileToCreate)
+            isScriptAsRun = True
+        self.assertTrue(isScriptAsRun)
+        
+    def test_fillTemplate_with_JobScriptTemplate(self):
+        os.chdir("..")
+        d = {
+             "tmpDir" : "/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch",
+             "jobTableName" : "dummyJobsTable",
+             "groupId" : "groupid",
+             "jobName" : "job1",
+             "launcher" : "ClusterLauncher",
+             "time" : "20110505-105353",
+             "repet_path" : "/home/user/workspace/repet_pipe",
+             "repet_host" : "pisano",
+             "repet_user" : "user",
+             "repet_pw" : "user",
+             "repet_db" : "repet_user",
+             "repet_port" : "3306",
+             "cmdStart" : "log = os.system(\"touch dummyFile1\")",
+             "cmdFinish" : "shutil.move(\"dummyFile1\", \"/home/user/workspace/repet_pipe/commons/core/launcher/test\")",
+             "cDir" : "/home/user/workspace/repet_pipe/commons/core/launcher/test/"
+             }
+        expFileName = "expFiles/expJobScriptTemplate.py"
+        obsFileName = "obsFile.py"
+        
+        iWS = WriteScript()
+        iWS.fillTemplate(obsFileName, d)
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        os.remove(obsFileName)
+        
+    def test_fillTemplate_with_JobScriptTemplate_2_lines_in_cmd_start(self):
+        os.chdir("..")
+        d = {
+             "tmpDir" : "/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch",
+             "jobTableName" : "dummyJobsTable",
+             "groupId" : "groupid",
+             "jobName" : "job1",
+             "launcher" : "ClusterLauncher",
+             "time" : "20110505-105353",
+             "repet_path" : "/home/user/workspace/repet_pipe",
+             "repet_host" : "pisano",
+             "repet_user" : "user",
+             "repet_pw" : "user",
+             "repet_db" : "repet_user",
+             "repet_port" : "3306",
+             "cmdStart" : "print \"Hello Yufei\"\n\tlog = os.system(\"touch dummyFile1\")",
+             "cmdFinish" : "shutil.move(\"dummyFile1\", \"/home/user/workspace/repet_pipe/commons/core/launcher/test\")",
+             "cDir" : "/home/user/workspace/repet_pipe/commons/core/launcher/test/"
+             }
+        expFileName = "expFiles/expJobScriptTemplate_cmdWith2Lines.py"
+        obsFileName = "obsFile.py"
+        
+        iWS = WriteScript()
+        iWS.fillTemplate(obsFileName, d)
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        os.remove(obsFileName)
+        
+    def test_fillTemplate_with_JobScriptWithFilesCopyTemplate(self):
+        os.chdir("..")
+        d = {
+             "tmpDir" : "/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch",
+             "jobTableName" : "dummyJobsTable",
+             "groupId" : "groupid",
+             "jobName" : "job1",
+             "launcher" : "ClusterLauncher",
+             "time" : "20110505-105353",
+             "repet_path" : "/home/user/workspace/repet_pipe",
+             "repet_host" : "pisano",
+             "repet_user" : "user",
+             "repet_pw" : "user",
+             "repet_db" : "repet_user",
+             "repet_port" : "3306",
+             "cmdStart" : "log = os.system(\"touch dummyFile1\")",
+             "cmdFinish" : "shutil.move(\"dummyFile1\", \"/home/user/workspace/repet_pipe/commons/core/launcher/test\")",
+             "cDir" : "/home/user/workspace/repet_pipe/commons/core/launcher/test/",
+             "cmdSize" : "fileSize = 0.500000",
+             "cmdCopy" : "os.system(\"touch bank.fa\")"
+             }
+        expFileName = "expFiles/expJobScriptWithFilesCopyTemplate.py"
+        obsFileName = "obsFile.py"
+        
+        iWS = WriteScript(chooseTemplateWithCopy = True)
+        iWS.fillTemplate(obsFileName, d)
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        os.remove(obsFileName)
+
+    def test_fillTemplate_with_JobScriptTemplateLight(self):
+        os.chdir("..")
+        d = {
+             "tmpDir" : "/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch",
+             "jobTableName" : "dummyJobsTable",
+             "groupId" : "groupid",
+             "jobName" : "job1",
+             "launcher" : "ClusterLauncher",
+             "time" : "20110505-105353",
+             "repet_path" : "/home/user/workspace/repet_pipe",
+             "cmdStart" : "log = os.system(\"touch dummyFile1\")",
+             "cmdFinish" : "shutil.move(\"dummyFile1\", \"/home/user/workspace/repet_pipe/commons/core/launcher/test\")",
+             "cDir" : "/home/user/workspace/repet_pipe/commons/core/launcher/test/",
+             "cmdSize" : "fileSize = 0.500000",
+             "cmdCopy" : "os.system(\"touch bank.fa\")"
+             }
+        expFileName = "expFiles/expJobScriptTemplateLight.py"
+        obsFileName = "obs.py"
+        
+        iWS = WriteScript(chooseTemplateLight = True)
+        iWS.fillTemplate(obsFileName, d)
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        os.remove(obsFileName)
+        
+    def test_createJobScriptDict(self):
+        os.chdir("..")
+        cmd_start = "log = os.system(\"touch dummyFile1\")"
+        cmd_finish = "shutil.move(\"dummyFile1\", \"/home/user/workspace/repet_pipe/commons/core/launcher/test\")"
+        cmd_size = ""
+        cmd_copy = ""
+        expDict = {
+             "tmpDir" : self._tmpDir,
+             "jobTableName" : self._jobTable,
+             "groupId" : self._job.groupid,
+             "jobName" : self._acronym,
+             "launcher" : self._job.launcher,
+             "time" : time.strftime("%Y%m%d-%H%M%S"),
+             "repet_path" : os.environ["REPET_PATH"],
+             "repet_host" : os.environ["REPET_HOST"],
+             "repet_user" : os.environ["REPET_USER"],
+             "repet_pw" : os.environ["REPET_PW"],
+             "repet_db" : os.environ["REPET_DB"],
+             "repet_port" : os.environ["REPET_PORT"],
+             "cmdStart" : cmd_start,
+             "cmdFinish" : cmd_finish,
+             "cDir" : self._testDir,
+             "cmdSize" : cmd_size,
+             "cmdCopy" : cmd_copy
+             }
+        obsDict = self._iScriptWriter.createJobScriptDict(cmd_start, cmd_finish, cmd_size, cmd_copy)
+        self.assertEquals(expDict, obsDict)
+        
+    def test_createJobScriptDict_with_cmdSize_and_cmdCopy(self):
+        os.chdir("..")
+        cmd_start = "log = os.system(\"touch dummyFile1\")"
+        cmd_finish = "shutil.move(\"dummyFile1\", \"/home/user/workspace/repet_pipe/commons/core/launcher/test\")"
+        cmd_size = "fileSize = 0.500000"
+        cmd_copy = "os.system(\"touch bank.fa\")"
+        expDict = {
+             "tmpDir" : self._tmpDir,
+             "jobTableName" : self._jobTable,
+             "groupId" : self._job.groupid,
+             "jobName" : self._acronym,
+             "launcher" : self._job.launcher,
+             "time" : time.strftime("%Y%m%d-%H%M%S"),
+             "repet_path" : os.environ["REPET_PATH"],
+             "repet_host" : os.environ["REPET_HOST"],
+             "repet_user" : os.environ["REPET_USER"],
+             "repet_pw" : os.environ["REPET_PW"],
+             "repet_db" : os.environ["REPET_DB"],
+             "repet_port" : os.environ["REPET_PORT"],
+             "cmdStart" : cmd_start,
+             "cmdFinish" : cmd_finish,
+             "cDir" : self._testDir,
+             "cmdSize" : cmd_size,
+             "cmdCopy" : cmd_copy
+             }
+        obsDict = self._iScriptWriter.createJobScriptDict(cmd_start, cmd_finish, cmd_size, cmd_copy)
+        self.assertEquals(expDict, obsDict)
+        
+class CreateFileThread(threading.Thread):
+
+    def __init__(self, pyFileName):
+        threading.Thread.__init__(self)
+        self._pyFileName = pyFileName
+        
+    def run(self):
+        os.system("python %s" % self._pyFileName)
+
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_WriteScript ) )
+if __name__ == "__main__":
+        unittest.TextTestRunner(verbosity=2).run( test_suite )    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/launcher/test/expFiles/expJobScriptSQLiteWithFilesCopyTemplate.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import time
+import shutil
+from commons.core.checker.RepetException import RepetException
+from commons.core.sql.TableJobAdaptator import TableJobAdaptator
+from commons.core.sql.DbMySql import DbMySql
+from commons.core.sql.DbSQLite import DbSQLite
+from commons.core.sql.Job import Job
+
+try:
+	newDir = None
+	print os.uname()
+	beginTime = time.time()
+	print 'beginTime=%f' % beginTime
+	print "work in dir '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch'"
+	sys.stdout.flush()
+	if not os.path.exists("/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch"):
+		raise IOError("ERROR: temporary directory '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch' doesn't exist")
+	
+	fileSize = 0
+	if not os.path.exists("groupid"):
+		fileSize = 0.500000
+	freeGigaNeededInTmpDir = float(1 + fileSize)
+	freeSpace = os.statvfs("/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch")
+	if ((freeSpace.f_bavail * freeSpace.f_frsize) / 1073741824.0 < freeGigaNeededInTmpDir):
+		raise RepetException("ERROR: less than %.2fG of input file in '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch'" % freeGigaNeededInTmpDir)
+	
+	os.chdir("/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch")
+	if not os.path.exists("groupid"):
+		try:
+			os.mkdir("groupid")
+		except OSError, e :
+			if e.args[0] != 17:
+				raise RepetException("ERROR: can't create 'groupid'")
+		os.chdir("groupid")
+		os.system("touch bank.fa")
+	else:
+		os.chdir("groupid")
+	
+	newDir = "groupid_job1_20110505-105353"
+	if os.path.exists(newDir):
+		shutil.rmtree(newDir)
+	os.mkdir(newDir)
+	os.chdir(newDir)
+	
+	queue = "main.q"
+	iJob = Job("jobs", jobname = "job1", groupid = "groupid", queue = queue, node = os.getenv("HOSTNAME"))
+	iDb = DbSQLite("/home/user/workspace/repet_pipe/commons/core/launcher/test/jobs")
+	iTJA = TableJobAdaptator(iDb, "jobs")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "running")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	iDb.close()
+	
+	log = os.system("touch dummyFile1")
+	if log != 0:
+		raise RepetException("ERROR: job returned %i" % log)
+	else:
+		print "job finished successfully"
+	shutil.move("dummyFile1", "/home/user/workspace/repet_pipe/commons/core/launcher/test")
+	
+	os.chdir("..")
+	shutil.rmtree(newDir)
+	
+	iDb = DbSQLite("/home/user/workspace/repet_pipe/commons/core/launcher/test/jobs")
+	iTJA = TableJobAdaptator(iDb, "jobs")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "finished")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	iDb.close()
+	
+	endTime = time.time()
+	print 'endTime=%f' % endTime
+	print 'executionTime=%f' % (endTime - beginTime)
+	print os.uname()
+
+except IOError, e :
+	print e
+	queue = "main.q"
+	iJob = Job("jobs", jobname = "job1", groupid = "groupid", queue = queue, node = os.getenv("HOSTNAME"))
+	iDb = DbSQLite("/home/user/workspace/repet_pipe/commons/core/launcher/test/jobs")
+	iTJA = TableJobAdaptator(iDb, "jobs")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "error")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	iDb.close()
+	sys.exit(1)
+
+except Exception, e :
+	print "tmpDir is : /home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch"
+	print "cDir is : /home/user/workspace/repet_pipe/commons/core/launcher/test/"
+	print e
+	if newDir != None and os.path.exists("../%s" % newDir) and not os.path.exists("/home/user/workspace/repet_pipe/commons/core/launcher/test//%s" % newDir):
+		os.chdir("..")
+		shutil.move(newDir, "/home/user/workspace/repet_pipe/commons/core/launcher/test//%s" % newDir)
+	queue = "main.q"
+	iJob = Job("jobs", jobname = "job1", groupid = "groupid", queue = queue, node = os.getenv("HOSTNAME"))
+	iDb = DbSQLite("/home/user/workspace/repet_pipe/commons/core/launcher/test/jobs")
+	iTJA = TableJobAdaptator(iDb, "jobs")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "error")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	iDb.close()
+	sys.exit(1)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/launcher/test/expFiles/expJobScriptTemplate.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import time
+import shutil
+from commons.core.checker.RepetException import RepetException
+from commons.core.sql.TableJobAdaptator import TableJobAdaptator
+from commons.core.sql.DbFactory import DbFactory
+from commons.core.sql.Job import Job
+
+try:
+	newDir = None
+	print os.uname()
+	beginTime = time.time()
+	print 'beginTime=%f' % beginTime
+	print "work in dir '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch'"
+	sys.stdout.flush()
+	if not os.path.exists( "/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch" ):
+		raise IOError("ERROR: temporary directory '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch' doesn't exist")
+	
+	minFreeGigaInTmpDir = 1
+	freeSpace = os.statvfs("/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch")
+	if ((freeSpace.f_bavail * freeSpace.f_frsize) / 1073741824.0 < minFreeGigaInTmpDir):
+		raise RepetException("ERROR: less than %iG of input file in '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch'" % minFreeGigaInTmpDir)
+	
+	os.chdir("/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch")
+	newDir = "groupid_job1_20110505-105353"
+	if os.path.exists(newDir):
+		shutil.rmtree(newDir)
+	os.mkdir(newDir)
+	os.chdir(newDir)
+	
+	iJob = Job(jobname = "job1", groupid = "groupid", launcherFile = "ClusterLauncher", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "dummyJobsTable")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "running")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	
+	log = os.system("touch dummyFile1")
+	if log != 0:
+		raise RepetException("ERROR: job returned %i" % log)
+	else:
+		print "job finished successfully"
+	sys.stdout.flush()
+	shutil.move("dummyFile1", "/home/user/workspace/repet_pipe/commons/core/launcher/test")
+	
+	os.chdir("..")
+	shutil.rmtree(newDir)
+	
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "dummyJobsTable")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "finished")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	
+	endTime = time.time()
+	print 'endTime=%f' % endTime
+	print 'executionTime=%f' % (endTime - beginTime)
+	print os.uname()
+	sys.stdout.flush()
+
+except IOError, e :
+	print e
+	iJob = Job(jobname = "job1", groupid = "groupid", launcherFile = "ClusterLauncher", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "dummyJobsTable")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "error")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	sys.exit(1)
+
+except Exception, e :
+	print "tmpDir is : /home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch"
+	print "cDir is : /home/user/workspace/repet_pipe/commons/core/launcher/test/"
+	print e
+	if newDir != None and os.path.exists("../%s" % newDir) and not os.path.exists("/home/user/workspace/repet_pipe/commons/core/launcher/test//%s" % newDir):
+		os.chdir("..")
+		shutil.move(newDir, "/home/user/workspace/repet_pipe/commons/core/launcher/test//%s" % newDir)
+	iJob = Job(jobname = "job1", groupid = "groupid", launcherFile = "ClusterLauncher", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "dummyJobsTable")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "error")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	sys.exit(1)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/launcher/test/expFiles/expJobScriptTemplateLight.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import time
+import shutil
+from commons.core.checker.RepetException import RepetException
+try:
+	newDir = None
+	print os.uname()
+	beginTime = time.time()
+	print 'beginTime=%f' % beginTime
+	print "work in dir '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch'"
+	sys.stdout.flush()
+	if not os.path.exists( "/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch" ):
+		raise IOError("ERROR: temporary directory '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch' doesn't exist")
+	
+	minFreeGigaInTmpDir = 1
+	freeSpace = os.statvfs("/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch")
+	if ((freeSpace.f_bavail * freeSpace.f_frsize) / 1073741824.0 < minFreeGigaInTmpDir):
+		raise RepetException("ERROR: less than %iG of input file in '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch'" % minFreeGigaInTmpDir)
+	
+	os.chdir("/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch")
+	newDir = "groupid_job1_20110505-105353"
+	if os.path.exists(newDir):
+		shutil.rmtree(newDir)
+	os.mkdir(newDir)
+	os.chdir(newDir)
+	
+	log = os.system("touch dummyFile1")
+	if log != 0:
+		raise RepetException("ERROR: job returned %i" % log)
+	else:
+		print "job finished successfully"
+	sys.stdout.flush()
+	shutil.move("dummyFile1", "/home/user/workspace/repet_pipe/commons/core/launcher/test")
+	
+	os.chdir("..")
+	shutil.rmtree(newDir)	
+	endTime = time.time()
+	print 'endTime=%f' % endTime
+	print 'executionTime=%f' % (endTime - beginTime)
+	print os.uname()
+	sys.stdout.flush()
+
+except IOError, e :
+	print e
+	sys.stdout.flush()
+	sys.exit(1)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/launcher/test/expFiles/expJobScriptTemplate_cmdWith2Lines.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import time
+import shutil
+from commons.core.checker.RepetException import RepetException
+from commons.core.sql.TableJobAdaptator import TableJobAdaptator
+from commons.core.sql.DbFactory import DbFactory
+from commons.core.sql.Job import Job
+
+try:
+	newDir = None
+	print os.uname()
+	beginTime = time.time()
+	print 'beginTime=%f' % beginTime
+	print "work in dir '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch'"
+	sys.stdout.flush()
+	if not os.path.exists( "/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch" ):
+		raise IOError("ERROR: temporary directory '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch' doesn't exist")
+	
+	minFreeGigaInTmpDir = 1
+	freeSpace = os.statvfs("/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch")
+	if ((freeSpace.f_bavail * freeSpace.f_frsize) / 1073741824.0 < minFreeGigaInTmpDir):
+		raise RepetException("ERROR: less than %iG of input file in '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch'" % minFreeGigaInTmpDir)
+	
+	os.chdir("/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch")
+	newDir = "groupid_job1_20110505-105353"
+	if os.path.exists(newDir):
+		shutil.rmtree(newDir)
+	os.mkdir(newDir)
+	os.chdir(newDir)
+	
+	iJob = Job(jobname = "job1", groupid = "groupid", launcherFile = "ClusterLauncher", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "dummyJobsTable")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "running")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	
+	print "Hello Yufei"
+	log = os.system("touch dummyFile1")
+	if log != 0:
+		raise RepetException("ERROR: job returned %i" % log)
+	else:
+		print "job finished successfully"
+	sys.stdout.flush()
+	shutil.move("dummyFile1", "/home/user/workspace/repet_pipe/commons/core/launcher/test")
+	
+	os.chdir("..")
+	shutil.rmtree(newDir)
+	
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "dummyJobsTable")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "finished")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	
+	endTime = time.time()
+	print 'endTime=%f' % endTime
+	print 'executionTime=%f' % (endTime - beginTime)
+	print os.uname()
+	sys.stdout.flush()
+
+except IOError, e :
+	print e
+	iJob = Job(jobname = "job1", groupid = "groupid", launcherFile = "ClusterLauncher", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "dummyJobsTable")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "error")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	sys.exit(1)
+
+except Exception, e :
+	print "tmpDir is : /home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch"
+	print "cDir is : /home/user/workspace/repet_pipe/commons/core/launcher/test/"
+	print e
+	if newDir != None and os.path.exists("../%s" % newDir) and not os.path.exists("/home/user/workspace/repet_pipe/commons/core/launcher/test//%s" % newDir):
+		os.chdir("..")
+		shutil.move(newDir, "/home/user/workspace/repet_pipe/commons/core/launcher/test//%s" % newDir)
+	iJob = Job(jobname = "job1", groupid = "groupid", launcherFile = "ClusterLauncher", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "dummyJobsTable")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "error")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	sys.exit(1)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/launcher/test/expFiles/expJobScriptWithFilesCopyTemplate.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import time
+import shutil
+from commons.core.checker.RepetException import RepetException
+from commons.core.sql.TableJobAdaptator import TableJobAdaptator
+from commons.core.sql.DbFactory import DbFactory
+from commons.core.sql.Job import Job
+
+try:
+	newDir = None
+	print os.uname()
+	beginTime = time.time()
+	print 'beginTime=%f' % beginTime
+	print "work in dir '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch'"
+	sys.stdout.flush()
+	if not os.path.exists("/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch"):
+		raise IOError("ERROR: temporary directory '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch' doesn't exist")
+	
+	fileSize = 0
+	if not os.path.exists("groupid"):
+		fileSize = 0.500000
+	freeGigaNeededInTmpDir = float(1 + fileSize)
+	freeSpace = os.statvfs("/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch")
+	if ((freeSpace.f_bavail * freeSpace.f_frsize) / 1073741824.0 < freeGigaNeededInTmpDir):
+		raise RepetException("ERROR: less than %.2fG of input file in '/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch'" % freeGigaNeededInTmpDir)
+	
+	os.chdir("/home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch")
+	if not os.path.exists("groupid"):
+		try:
+			os.mkdir("groupid")
+		except OSError, e :
+			if e.args[0] != 17:
+				raise RepetException("ERROR: can't create 'groupid'")
+		os.chdir("groupid")
+		os.system("touch bank.fa")
+	else:
+		os.chdir("groupid")
+	
+	newDir = "groupid_job1_20110505-105353"
+	if os.path.exists(newDir):
+		shutil.rmtree(newDir)
+	os.mkdir(newDir)
+	os.chdir(newDir)
+	
+	iJob = Job(jobname = "job1", groupid = "groupid", launcherFile = "ClusterLauncher", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "dummyJobsTable")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "running")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	
+	log = os.system("touch dummyFile1")
+	if log != 0:
+		raise RepetException("ERROR: job returned %i" % log)
+	else:
+		print "job finished successfully"
+	sys.stdout.flush()
+	shutil.move("dummyFile1", "/home/user/workspace/repet_pipe/commons/core/launcher/test")
+	
+	os.chdir("..")
+	shutil.rmtree(newDir)
+	
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "dummyJobsTable")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "finished")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	
+	endTime = time.time()
+	print 'endTime=%f' % endTime
+	print 'executionTime=%f' % (endTime - beginTime)
+	print os.uname()
+	sys.stdout.flush()
+
+except IOError, e :
+	print e
+	iJob = Job(jobname = "job1", groupid = "groupid", launcherFile = "ClusterLauncher", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "dummyJobsTable")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "error")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	sys.exit(1)
+
+except Exception, e :
+	print "tmpDir is : /home/user/workspace/repet_pipe/commons/core/launcher/test/dummyScratch"
+	print "cDir is : /home/user/workspace/repet_pipe/commons/core/launcher/test/"
+	print e
+	if newDir != None and os.path.exists("../%s" % newDir) and not os.path.exists("/home/user/workspace/repet_pipe/commons/core/launcher/test//%s" % newDir):
+		os.chdir("..")
+		shutil.move(newDir, "/home/user/workspace/repet_pipe/commons/core/launcher/test//%s" % newDir)
+	iJob = Job(jobname = "job1", groupid = "groupid", launcherFile = "ClusterLauncher", node = os.getenv("HOSTNAME"))
+	iDb = DbFactory.createInstance()
+	iTJA = TableJobAdaptator(iDb, "dummyJobsTable")
+	print "current status: %s" % iTJA.getJobStatus(iJob)
+	iTJA.changeJobStatus(iJob, "error")
+	print "updated status: %s" % iTJA.getJobStatus(iJob)
+	sys.stdout.flush()
+	iDb.close()
+	sys.exit(1)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/AxtParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,154 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from SMART.Java.Python.structure.Mapping import Mapping
+from SMART.Java.Python.structure.SubMapping import SubMapping
+from commons.core.parsing.MapperParser import MapperParser
+from SMART.Java.Python.misc import Utils
+from SMART.Java.Python.misc.Utils import getHammingDistance
+
+
+class AxtParser(MapperParser):
+    """A class that parses AXT (as given by Mosaik)"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(AxtParser, self).__init__(fileName, verbosity)
+        self.queryLine = None
+        self.subjectLine = None
+
+    def __del__(self):
+        super(AxtParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["axt"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        pass
+
+
+    def getInfos(self):
+        self.chromosomes = set()
+        self.nbMappings  = 0
+        self.size        = 0
+        cpt              = 0
+        self.reset()
+        for line in self.handle:
+            line = line.strip()
+            if line == "": continue
+            if cpt % 3 == 0:
+                line    = line.strip()
+                parts = line.split(" ")
+                self.chromosomes.add(parts[1])
+                self.size       += int(parts[6])
+                self.nbMappings += 1
+            cpt += 1
+            if self.verbosity >= 10 and self.nbMappings % 100000 == 0:
+                sys.stdout.write("    %d mappings read\r" % (self.nbMappings))
+                sys.stdout.flush()
+        self.reset()
+        if self.verbosity >= 10:
+            print "    %d mappings read" % (self.nbMappings)
+            print "Done."
+        
+
+    def parseLine(self, line):
+
+        if line.strip() == "":
+            for line in self.handle:
+                self.currentLineNb += 1
+                break
+        if line.strip() == "":
+            return None
+
+        m = re.search(r"^\s*\d+\s+(\S+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\d+)\s+(\d+)\s+([+-])\s+\d+\s*$", line)
+        if m != None:
+            #sys.exit("\nLine %d '%s' does not have an AXT format" % (self.currentLineNb, line))
+
+            mapping = Mapping()
+            subMapping = SubMapping()
+    
+            offset = -1 if m.group(7) == "-" else 0
+            subMapping.queryInterval.setName(m.group(4))
+            subMapping.queryInterval.setStart(min(int(m.group(5)), int(m.group(6)))-1)
+            subMapping.queryInterval.setEnd(max(int(m.group(5)), int(m.group(6)))-1)
+            subMapping.queryInterval.setDirection(m.group(7))
+    
+            subMapping.targetInterval.setChromosome(m.group(1))
+            subMapping.targetInterval.setStart(min(int(m.group(2)), int(m.group(3))) + offset)
+            subMapping.targetInterval.setEnd(max(int(m.group(2)), int(m.group(3))) + offset)
+            subMapping.targetInterval.setDirection(1)
+    
+            subMapping.setSize(min(subMapping.targetInterval.getSize(), subMapping.queryInterval.getSize()))
+            subMapping.setDirection(m.group(7))
+    
+            mapping.addSubMapping(subMapping)
+    
+            mapping.setDirection(m.group(7))
+            mapping.targetInterval.setChromosome(m.group(1))
+            mapping.targetInterval.setStart(min(int(m.group(2)), int(m.group(3))) + offset)
+            mapping.targetInterval.setEnd(max(int(m.group(2)), int(m.group(3))) + offset)
+    
+            mapping.queryInterval.setName(m.group(4))
+            mapping.queryInterval.setStart(min(int(m.group(5)), int(m.group(6)))-1)
+            mapping.queryInterval.setEnd(max(int(m.group(5)), int(m.group(6)))-1)
+    
+            mapping.setSize(min(mapping.targetInterval.getSize(), mapping.queryInterval.getSize()))
+    
+            for line in self.handle:
+                string1 = line.strip()
+                self.currentLineNb += 1
+                break
+            for line in self.handle:
+                string2 = line.strip()
+                self.currentLineNb += 1
+                break
+            mapping.setNbMismatches(Utils.getHammingDistance(string1, string2))
+            mapping.setNbGaps(0)
+    
+            self.currentMapping = mapping
+        else:
+            if self.queryLine == None:
+                self.queryLine = line
+            else:
+                self.subjectLine = line
+                seqLen = float(len(self.subjectLine))
+                dist = float(getHammingDistance(self.queryLine, self.subjectLine))
+                identity = ((seqLen-dist)/seqLen) *100
+                self.currentMapping.setIdentity(identity)
+                self.queryLine = None
+                self.subjectLine = None
+                return self.currentMapping
+            
+
+
Binary file smart_toolShed/commons/core/parsing/AxtParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/BamParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,483 @@
+#
+# Copyright INRA-URGI 2009-2012
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re, sys, gzip, struct
+from commons.core.parsing.MapperParser import MapperParser
+from SMART.Java.Python.structure.Mapping import Mapping
+from SMART.Java.Python.structure.SubMapping import SubMapping
+from SMART.Java.Python.structure.Interval import Interval
+
+
+BAM_DNA_LOOKUP = "=ACMGRSVTWYHKDBN"
+
+BAM_CIGAR_LOOKUP = "MIDNSHP=X"
+BAM_CIGAR_SHIFT = 4
+BAM_CIGAR_MASK = ((1 << BAM_CIGAR_SHIFT) - 1)
+
+
+
+def pack_int32(x):
+	return struct.pack('<i', x)
+
+def pack_uint32(x):
+	return struct.pack('<I', x)
+
+def unpack_int8(x):
+	return struct.unpack('<b', x)[0]
+
+def unpack_int16(x):
+	return struct.unpack('<h', x)[0]
+
+def unpack_int32(x):
+	return struct.unpack('<i', x)[0]
+
+def unpack_int64(x):
+	return struct.unpack('<q', x)[0]
+
+def unpack_uint8(x):
+	return struct.unpack('<B', x)[0]
+
+def unpack_uint16(x):
+	return struct.unpack('<H', x)[0]
+
+def unpack_uint32(x):
+	return struct.unpack('<I', x)[0]
+
+def unpack_uint64(x):
+	return struct.unpack('<Q', x)[0]
+
+def unpack_float(x):
+	return struct.unpack('<f', x)[0]
+
+def unpack_string(x):
+	length = len(x)
+	format_string = "<{0}s".format(length)
+	string = struct.unpack(format_string, x)[0]
+	if string[-1] == '\0':
+		return string[:-1]
+	else:
+		return string
+
+
+BAM_TAG_CODE = {"c": unpack_int8, \
+				"C": unpack_uint8, \
+				"s": unpack_int16, \
+				"S": unpack_uint16, \
+				"i": unpack_int32, \
+				"I": unpack_uint32, \
+				"f": unpack_float, \
+				#"A": unpack_int8, \
+				"A": lambda x: x, \
+				"Z": unpack_int8, \
+				"H": unpack_int8}
+
+BAM_TAG_VALUE = {"c": int, \
+				 "C": int, \
+				 "s": int, \
+				 "S": int, \
+				 "i": int, \
+				 "I": int, \
+				 "f": float, \
+				 "A": lambda x: x}
+
+BAM_TAG_SIZE = {"c": 1, \
+				"C": 1, \
+				"s": 2, \
+				"S": 2, \
+				"i": 4, \
+				"I": 4, \
+				"f": 4, \
+				"A": 1}
+
+
+class CigarOp(object):
+	def __init__(self, data):
+		self._length = data >> BAM_CIGAR_SHIFT
+		self._type   = BAM_CIGAR_LOOKUP[ data & BAM_CIGAR_MASK ]
+
+
+class CigarData(object):
+	def __init__(self, data, num_ops):
+		self._ops = []
+		for i in range(num_ops):
+			cigar_data = unpack_uint32(data[i*4: (i+1)*4])
+			self._ops.append(CigarOp(cigar_data))		
+
+	def getCigarData(self):
+		return self._ops
+	
+	def __str__(self):
+		return "".join(["%d%s" % (op._length, op._type) for op in self._ops])
+
+
+class TagsData(object):
+	def __init__(self):
+		self._tags = {}
+
+	def add(self, tag):
+		self._tags[tag._tag] = tag
+
+	def getTags(self):
+		return self._tags
+
+	def __str__(self):
+		return " ".join([self._tags[tag] for tag in sorted(self._tags.keys())])
+		
+
+class TagData(object):
+	def __init__(self, tag, type, value):
+		self._tag = tag
+		self._type = type
+		self._value = value
+
+	def __str__(self):
+		if self._type in "AZHB":
+			return "%s:%s:%s" % (self._tag, self._type, self._value)
+		if self._type in "cCsSiI":
+			return "%s:%s:%d" % (self._tag, self._type, self._value)
+		return "%s:%s:%f" % (self._tag, self._type, self._value)
+
+
+class TagParser(object):
+	def __init__(self, data):
+		self._data = data
+		self._tags = TagsData()
+		self._parse()
+
+	def _parse(self):
+		while self._data:
+			tag  = "%s%s" % (chr(unpack_int8(self._data[0])), chr(unpack_int8(self._data[1])))
+			type = chr(unpack_int8(self._data[2]))
+			self._data = self._data[3:]
+			if type in BAM_TAG_VALUE:
+				value = self._parseUnique(type)
+			elif type == "Z":
+				value = self._parseString()
+			elif type == "H":
+				size = unpack_int8(self._data[0])
+				self._data = self._data[1:]
+				value = self._parseSeveral("C", size)
+			elif type == "B":
+				secondType = unpack_int8(self._data[0])
+				size       = unpack_int8(self._data[1]) + unpack_int8(self._data[2]) * 16 + unpack_int8(self._data[3]) * 16 * 16 + unpack_int8(self._data[4]) * 16 * 16 * 16
+				self._data = self._data[5:]
+				value      = self._parseSeveral(secondType, size)
+			else:
+				raise Exception("Cannot parse type '%s'." % (type))
+			fullTag = TagData(tag, type, value)
+			self._tags.add(fullTag)
+
+	def _parseUnique(self, type):
+		value = BAM_TAG_CODE[type](self._data[:BAM_TAG_SIZE[type]])
+		self._data = self._data[BAM_TAG_SIZE[type]:]
+		return value
+
+	def _parseSeveral(self, type, size):
+		value = []
+		for i in range(size):
+			value.append(self._parseUnique(type))
+		return value
+
+	def _parseString(self):
+		value      = ""
+		char       = self._data[0]
+		self._data = self._data[1:]
+		while unpack_int8(char) != 0:
+			value     += char
+			char       = self._data[0]
+			self._data = self._data[1:]
+		return value
+			
+	def getTags(self):
+		return self._tags.getTags()
+
+	def __str__(self):
+		return self._tags
+
+
+class AlignedRead(object):
+	def __init__(self, data, refs):
+		self._data = data
+		self._refs = refs
+
+	def parse(self):
+		self._parse_common()
+		self._parse_flag_nc()
+		self._parse_bin_mq_nl()
+		self._parse_name()
+		self._parse_cigar()
+		self._parse_sequence()
+		self._parse_quality()
+		self._parse_tags()
+	
+	def _parse_common(self):
+		ref_id           = unpack_int32(self._data[0:4])
+		self._chromosome = self._refs[ref_id]
+		self._pos        = unpack_int32(self._data[4:8]) + 1
+		mate_ref_id      = unpack_int32(self._data[20:24])
+		if mate_ref_id == -1:
+			self._rnext = "*"
+		else:
+			self._rnext = self._refs[mate_ref_id]
+		if self._rnext == self._chromosome:
+			self._rnext = "="
+		self._pnext = unpack_int32(self._data[24:28]) + 1
+		self._tlen  = unpack_int32(self._data[28:32])
+	
+	def _parse_bin_mq_nl(self):
+		bin_mq_nl = unpack_uint32(self._data[8:12])
+		self._bin = bin_mq_nl >> 16
+		self._mappingQuality = bin_mq_nl >> 8 & 0xff
+		self._query_name_length = bin_mq_nl & 0xff
+
+	def _parse_flag_nc(self):
+		flag_nc = unpack_uint32(self._data[12:16])
+		self._flag = flag_nc >> 16
+		self._num_cigar_ops = flag_nc & 0xffff
+		
+	def _parse_name(self):
+		start = 32
+		stop = start + self._query_name_length
+		self._name = unpack_string(self._data[start:stop])
+	
+	def _parse_cigar(self):
+		start = 32 + self._query_name_length
+		stop = start + (self._num_cigar_ops * 4)
+		_buffer = self._data[start:stop]
+		cigar = CigarData(_buffer, self._num_cigar_ops)
+		self._cigar = cigar.getCigarData()
+	
+	def _parse_sequence(self):
+		seq_length = unpack_int32(self._data[16:20])
+		start = 32 + self._query_name_length + (self._num_cigar_ops * 4)
+		stop = start + (seq_length + 1) / 2
+		_buffer = self._data[start:stop]
+		self._sequence = ""
+		for i in range(seq_length):
+			x = unpack_uint8(_buffer[(i / 2)])
+			index = (x >> (4 * (1 - (i % 2)))) & 0xf 
+			base = BAM_DNA_LOOKUP[index]
+			self._sequence += base
+
+	def _parse_quality(self):
+		seq_length = unpack_int32(self._data[16:20])
+		start = 32 + self._query_name_length + (self._num_cigar_ops * 4) + (seq_length + 1) / 2
+		stop = start + seq_length
+		_buffer = self._data[start:stop]
+		self._quality = "".join(["%s" % (chr(unpack_int8(x) + 33)) for x in _buffer])
+
+	def _parse_tags(self):
+		seq_length = unpack_int32(self._data[16:20])
+		start = 32 + self._query_name_length + (self._num_cigar_ops * 4) + (seq_length + 1) / 2 + (seq_length + 1) - 1
+		stop = start + seq_length
+		_buffer = self._data[start:]
+		tagParser = TagParser(_buffer)
+		self._tags = tagParser.getTags()
+		
+
+class FileReader(object):
+
+	def __init__(self, handle):
+		self._handle = handle
+		self._readHeader()
+
+	def _readHeader(self):
+		magic = unpack_string(self._handle.read(4))
+		if magic != "BAM\1":
+			raise Exception("File should start with 'BAM\1', starting with '%s' instead." % (magic))
+		tlen       = unpack_int32(self._handle.read(4))
+		text       = unpack_string(self._handle.read(tlen))
+		nrefs      = unpack_int32(self._handle.read(4))
+		self._refs = []
+		for i in range(nrefs):
+			sizeName = unpack_int32(self._handle.read(4))
+			name     = unpack_string(self._handle.read(sizeName))
+			size     = unpack_int32(self._handle.read(4))
+			self._refs.append(name)
+		self._startPos = self._handle.tell()
+
+	def reset(self):
+		self._handle.seek(self._startPos)
+
+	def getNextAlignment(self):
+		try:
+			blockSize = unpack_int32(self._handle.read(4))
+		except struct.error:
+			return False
+		block       = self._handle.read(blockSize)
+		currentRead = AlignedRead(block, self._refs)
+		return currentRead
+			
+
+
+def parseAlignedRead(read):
+	if (read._flag & 0x4) == 0x4:
+		return None
+
+	mapping	      = Mapping()
+	direction     = 1 if (read._flag & 0x10) == 0x0 else -1
+	genomeStart   = read._pos
+	nbOccurrences = 1
+	nbMismatches  = 0
+	nbMatches	  = 0
+	nbGaps		  = 0
+	subMapping	  = None
+	queryOffset   = 0
+	targetOffset  = 0
+	readStart	  = None
+
+	for tag, value in read._tags.iteritems():
+		if tag == "X0":
+			nbOccurrences = value._value
+		elif tag == "X1":
+			nbOccurrences += value._value
+		elif tag == "XM":
+			nbMismatches = value._value
+	mapping.setTagValue("nbOccurrences", nbOccurrences)
+	mapping.setTagValue("quality", read._mappingQuality)
+
+	for operation in read._cigar:
+		if operation._type == "M":
+			if readStart == None:
+				readStart = queryOffset
+			if subMapping == None:
+				subMapping = SubMapping()
+				subMapping.setSize(operation._length)
+				subMapping.setDirection(direction)
+				subMapping.queryInterval.setName(read._name)
+				subMapping.queryInterval.setStart(queryOffset)
+				subMapping.queryInterval.setDirection(direction)
+				subMapping.targetInterval.setChromosome(read._chromosome)
+				subMapping.targetInterval.setStart(genomeStart + targetOffset)
+				subMapping.targetInterval.setDirection(1)
+			nbMatches	 += operation._length
+			targetOffset += operation._length
+			queryOffset  += operation._length
+			currentNumber = 0
+			continue
+		if operation._type == "I":
+			nbGaps	   += 1
+			queryOffset  += operation._length
+			currentNumber = 0
+			continue
+		if operation._type == "D":
+			if subMapping != None:
+				subMapping.queryInterval.setEnd(queryOffset - 1)
+				subMapping.targetInterval.setEnd(genomeStart + targetOffset - 1)
+				mapping.addSubMapping(subMapping)
+			subMapping	  = None
+			nbGaps	     += 1
+			targetOffset += operation._length
+			currentNumber = 0
+			continue
+		if operation._type == "N":
+			if subMapping != None:
+				subMapping.queryInterval.setEnd(queryOffset - 1)
+				subMapping.targetInterval.setEnd(genomeStart + targetOffset - 1)
+				mapping.addSubMapping(subMapping)
+			subMapping	= None
+			targetOffset += operation._length
+			currentNumber = 0
+			continue
+		if operation._type == "S":
+			nbMismatches += operation._length
+			targetOffset += operation._length
+			queryOffset  += operation._length
+			currentNumber = 0
+			continue
+		if operation._type == "H":
+			targetOffset += operation._length
+			queryOffset  += operation._length
+			currentNumber = 0
+			continue
+		if operation._type == "P":
+			continue
+		raise Exception("Do not understand parameter '%s'" % (operation._type))
+
+	if subMapping != None:
+		subMapping.queryInterval.setEnd(queryOffset - 1)
+		subMapping.targetInterval.setEnd(genomeStart + targetOffset - 1)
+		mapping.addSubMapping(subMapping)
+	mapping.queryInterval.setStart(readStart)
+	mapping.queryInterval.setEnd(queryOffset - 1)
+	mapping.targetInterval.setEnd(genomeStart + targetOffset - 1)
+	mapping.setNbMismatches(nbMismatches)
+	mapping.setNbGaps(nbGaps)
+	mapping.queryInterval.setName(read._name)
+	mapping.queryInterval.setDirection(direction)
+	mapping.targetInterval.setChromosome(read._chromosome)
+	mapping.targetInterval.setStart(genomeStart)
+	mapping.targetInterval.setDirection(direction)
+	mapping.setSize(len(read._sequence))
+	mapping.setDirection(direction)
+	return mapping
+
+	
+class BamParser(MapperParser):
+	"""A class that parses BAM format"""
+
+	def __init__(self, fileName, verbosity = 0):
+		self.verbosity = verbosity
+		self.handle = gzip.open(fileName, "rb")
+		self.reader = FileReader(self.handle)
+		self.nbMappings = None
+		self.fileName   = fileName
+
+
+	def __del__(self):
+		self.handle.close()
+
+
+	def getFileFormats():
+		return ["bam"]
+	getFileFormats = staticmethod(getFileFormats)
+
+
+	def reset(self):
+		self.reader.reset()
+
+
+	def getNextMapping(self):
+		self.currentMapping = None
+		while self.currentMapping == None:
+			read = self.reader.getNextAlignment()
+			if not read:
+				self.currentMapping = False
+				return False
+			read.parse()
+			self.currentMapping = parseAlignedRead(read)
+		return self.currentMapping
+		
+		
+	def setDefaultTagValue(self, name, value):
+		pass
+
+
+	def skipFirstLines(self):
+		pass
Binary file smart_toolShed/commons/core/parsing/BamParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/BedParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,139 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from SMART.Java.Python.structure.Interval import Interval
+from commons.core.parsing.TranscriptListParser import TranscriptListParser
+from SMART.Java.Python.structure.Transcript import Transcript
+
+
+class BedParser(TranscriptListParser):
+    """A class that parses a BED file and create a transcript list"""
+
+
+    def __init__(self, fileName, verbosity = 0):
+        self.title = None
+        TranscriptListParser.__init__(self, fileName, verbosity)
+
+
+#    def __del__(self):
+#        super(BedParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["bed"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        mark = self.handle.tell()
+        line = self.handle.readline()
+        line = line.strip()
+        m = re.search(r"^\s*track\s+name\s*=\s*(\S+)\s+", line)
+        if m != None:
+            self.title = m.group(1)
+            self.currentLineNb += 1
+        else:
+            self.handle.seek(mark)
+        return
+            
+
+
+
+    def parseLine(self, line):
+        m = re.search(r"^\s*(\S+)\t+(\d+)\t+(\d+)\s*$", line)
+        if m != None:
+            transcript = Transcript()
+            transcript.setChromosome(m.group(1))
+            transcript.setStart(min(int(m.group(2)), int(m.group(3))-1))
+            transcript.setEnd(max(int(m.group(2)), int(m.group(3))-1))
+            transcript.setName("Unnamed")
+            transcript.setDirection(1)
+            return transcript
+
+        m = re.search(r"^\s*(\S+)\t+(\d+)\t+(\d+)\t+([^\t]+)\s*$", line)
+        if m != None:
+            transcript = Transcript()
+            transcript.setChromosome(m.group(1))
+            transcript.setStart(min(int(m.group(2)), int(m.group(3))-1))
+            transcript.setEnd(max(int(m.group(2)), int(m.group(3))-1))
+            transcript.setName(m.group(4))
+            transcript.setDirection(1)
+            return transcript
+
+        m = re.search(r"^\s*(\S+)\t+(\d+)\t+(\d+)\t+([^\t]+)\t+\d+\.?\d*\s*$", line)
+        if m != None:
+            transcript = Transcript()
+            transcript.setChromosome(m.group(1))
+            transcript.setStart(min(int(m.group(2)), int(m.group(3))-1))
+            transcript.setEnd(max(int(m.group(2)), int(m.group(3))-1))
+            transcript.setName(m.group(4))
+            transcript.setDirection(1)
+            return transcript
+
+        m = re.search(r"^\s*(\S+)\t+(\d+)\t+(\d+)\t+([^\t]+)\t+\d+\t+([+-])\t+\d+\t+\d+\t+0\t+(\d+)\t+(\S+)\t+(\S+)\s*$", line)
+        if m == None:
+            raise Exception("\nLine %d '%s' does not has a BED format." % (self.currentLineNb, line))
+        transcript = Transcript()
+        transcript.setChromosome(m.group(1))
+        transcript.setStart(min(int(m.group(2)), int(m.group(3))-1))
+        transcript.setEnd(max(int(m.group(2)), int(m.group(3))-1))
+        transcript.setName(m.group(4))
+        transcript.setDirection(m.group(5))
+        nbExons = int(m.group(6))
+        sizes = m.group(7).split(",")
+        starts = m.group(8).split(",")
+
+        # check for comment in name
+        m = re.search(r"^([^\(]*)\((\S+)\)$", transcript.getName())
+        if m != None:
+            transcript.setName(m.group(1))
+            transcript.setTagValues(m.group(2), ";", "=")
+        
+        # check for nb occurrences in name
+        m = re.search(r"(.*)-(\d+)$", transcript.getName())
+        if m != None:
+            transcript.setName(m.group(1))
+            transcript.setOccurrence(int(m.group(2)))
+
+        for i in range(nbExons):
+            exon = Interval(transcript)
+            exon.setStart(int(starts[i])+transcript.getStart())
+            exon.setEnd(transcript.getStart()+int(starts[i])+int(sizes[i])-1)
+            exon.setSize(int(sizes[i]))
+            transcript.addExon(exon)
+            
+        if transcript.exons[0].getStart() != transcript.getStart():
+            sys.exit("There is something wrong with the start of transcript line '%s': transcript starts at %d whereas first exon starts at %d" % (line.strip(), transcript.start, transcript.exons[0].start))
+        if transcript.exons[-1].getEnd() != transcript.getEnd():
+            sys.exit("There is something wrong with the end of transcript line '%s': transcript ends at %d whereas last exon ends at %d" % (line.strip(), transcript.end, transcript.exons[-1].end))
+
+        return transcript
+
Binary file smart_toolShed/commons/core/parsing/BedParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/BlastParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,88 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from commons.core.parsing.MapperParser import MapperParser
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.structure.SubMapping import SubMapping
+from SMART.Java.Python.structure.Mapping import Mapping
+
+
+class BlastParser(MapperParser):
+    """A class that parses the output of Blast (-m 8 format)"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(BlastParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(BlastParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["blast"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        pass
+
+
+    def parseLine(self, line):
+        m = re.search(r"^(\S+)\s+(\S+)\s+(\d+\.?\d*)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([-+]?\d+\.?\d*[eE]?[-+]?\d*)\s+(\d+\.?\d*)\s*$", line)
+        if m == None:
+            sys.exit("\nLine %d '%s' does not have an Blast format" % (self.currentLineNb, line))
+
+        mapping = Mapping()
+
+        queryInterval = Interval()
+        queryInterval.setName(m.group(1))
+        queryInterval.setStart(min(int(m.group(7)), int(m.group(8))))
+        queryInterval.setEnd(max(int(m.group(7)), int(m.group(8))))
+
+        targetInterval = Interval()
+        targetInterval.setChromosome(m.group(2))
+        targetInterval.setStart(min(int(m.group(9)), int(m.group(10))))
+        targetInterval.setEnd(max(int(m.group(9)), int(m.group(10))))
+
+        subMapping = SubMapping()
+        subMapping.setQueryInterval(queryInterval)
+        subMapping.setTargetInterval(targetInterval)
+
+        mapping.addSubMapping(subMapping)
+
+        mapping.setIdentity(round(float(m.group(3))))
+        mapping.setSize(int(m.group(4)))
+        mapping.setNbMismatches(int(m.group(5)))
+        mapping.setNbGaps(int(m.group(6)))
+        mapping.setDirection((int(m.group(8)) - int(m.group(7))) * (int(m.group(10)) - int(m.group(9))))
+        mapping.setEvalue(float(m.group(11)))
+
+        return mapping
Binary file smart_toolShed/commons/core/parsing/BlastParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/BlatFileParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,63 @@
+from commons.core.parsing.BlatParser import BlatParser
+import os
+
+class BlatFileParser(object):
+
+    def __init__(self, blatFileName = None):
+        self._blatFileName = blatFileName
+        self._lBlatHits = []
+        self._dBlatHitsByQueries = {}
+        self._dQueries = {}
+        
+    def getDictOfQueries(self):
+        return self._dQueries
+    
+    def getResultLinesOfOneQuery(self, queryName):
+        return self._dBlatHitsByQueries[queryName]
+    
+    def getDictOfBlatHitsByQueries(self):
+        return self._dBlatHitsByQueries
+    
+    def getListsOfHits(self):
+        return self._lBlatHits
+    
+    def parseBlatFile(self):
+        blatFile = open(self._blatFileName, 'r')
+        line = blatFile.readline()
+        n = 1
+        while line != "":
+            if self._isInteger(line.split("\t")[0]):
+                iBlatParser = BlatParser()
+                iBlatParser.setAttributesFromString(line, n)
+                queryHeader = iBlatParser.getQName()
+                self._dQueries[queryHeader] = 1
+                self._lBlatHits.append(iBlatParser)
+            line = blatFile.readline()
+            n += 1
+        return self._lBlatHits
+    
+    def parseBlatFileByQueries(self):
+        blatFile = open(self._blatFileName, 'r')
+        line = blatFile.readline()
+        n = 1
+        while line != "":
+            if self._isInteger(line.split("\t")[0]):
+                iBlatParser = BlatParser()
+                iBlatParser.setAttributesFromString(line, n)
+                queryHeader = iBlatParser.getQName()
+                self._dQueries[queryHeader] = 1
+                if self._dBlatHitsByQueries.has_key(queryHeader):
+                    self._dBlatHitsByQueries[queryHeader].append(iBlatParser)
+                else:
+                    self._dBlatHitsByQueries[queryHeader] = [iBlatParser]
+            line = blatFile.readline()
+            n += 1
+        blatFile.close()
+        return self._dBlatHitsByQueries
+        
+    def _isInteger(self, string):
+        try:
+            int(string)
+            return True
+        except ValueError:
+            return False
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/BlatParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,351 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+import sys
+
+## this class can parse a Blat results output file
+#
+class BlatParser(object):
+
+
+    def __init__(self, match='', mismatch='', repMatch='', N='', QGapCount='', QGapBases='', TGapCount='', TGapBases='', strand='', QName='', QSize='', QStart='', QEnd='', TName='', TSize='', TStart='', TEnd='', blockCount='', blockSizes='', qStarts='', tStarts=''):
+        self._match = match
+        self._mismatch = mismatch
+        self._repMatch = repMatch
+        self._N = N
+        self._QGapCount = QGapCount
+        self._QGapBases = QGapBases
+        self._TGapCount = TGapCount
+        self._TGapBases = TGapBases
+        self._strand = strand
+        self._QName = QName
+        self._QSize = QSize
+        self._QStart = QStart
+        self._QEnd = QEnd
+        self._TName = TName
+        self._TSize = TSize
+        self._TStart = TStart
+        self._TEnd = TEnd
+        self._blockCount = blockCount
+        self._blockSizes = blockSizes
+        self._qStarts = qStarts
+        self._tStarts = tStarts
+        
+    def __eq__(self, o):
+        return self._TName == o._TName and self._TSize == o._TSize and self._TStart == o._TStart and self._TEnd == o._TEnd
+    
+    def setMatch(self, match):
+        self._match = match
+        
+    def setMismatch(self, mismatch):
+        self._mismatch = mismatch
+        
+    def setRepMatch(self, repMatch):
+        self._repMatch = repMatch
+        
+    def setN(self, N):
+        self._N = N
+        
+    def setQGapCount(self, QGapCount):
+        self._QGapCount = QGapCount
+        
+    def setQGapBases(self, QGapBases):
+        self._QGapBases = QGapBases
+        
+    def setTGapCount(self, TGapCount):
+        self._TGapCount = TGapCount
+        
+    def setTGapBases(self, TGapBases):
+        self._TGapBases = TGapBases
+        
+    def setStrand(self, strand):
+        self._strand = strand
+        
+    def setQName(self, QName):
+        self._QName = QName
+        
+    def setQSize(self, QSize):
+        self._QSize = QSize
+        
+    def setQStart(self, QStart):
+        self._QStart = QStart
+        
+    def setQEnd(self, QEnd):
+        self._QEnd = QEnd
+        
+    def setTName(self, TName):
+        self._TName = TName
+        
+    def setTSize(self, TSize):
+        self._TSize = TSize
+        
+    def setTStart(self, TStart):
+        self._TStart = TStart
+        
+    def setTEnd(self, TEnd):
+        self._TEnd = TEnd
+        
+    def setBlockCount(self, blockCount):
+        self._blockCount = blockCount
+        
+    def setBlockSizes(self, blockSizes):
+        self._blockSizes = blockSizes
+        
+    def setQStarts(self, qStarts):
+        self._qStarts = qStarts
+        
+    def setTStarts(self, tStarts):
+        self._tStarts = tStarts
+        
+    def getMatch(self):
+        return self._match
+        
+    def getMismatch(self):
+        return self._mismatch
+        
+    def getRepMatch(self):
+        return self._repMatch
+        
+    def getN(self):
+        return self._N
+        
+    def getQGapCount(self):
+        return self._QGapCount
+        
+    def getQGapBases(self):
+        return self._QGapBases
+        
+    def getTGapCount(self):
+        return self._TGapCount
+        
+    def getTGapBases(self):
+        return self._TGapBases
+        
+    def getStrand(self):
+        return self._strand
+        
+    def getQName(self):
+        return self._QName
+        
+    def getQSize(self):
+        return self._QSize
+        
+    def getQStart(self):
+        return self._QStart
+        
+    def getQEnd(self):
+        return self._QEnd
+        
+    def getTName(self):
+        return self._TName
+        
+    def getTSize(self):
+        return self._TSize
+        
+    def getTStart(self):
+        return self._TStart
+                
+    def getTEnd(self):
+        return self._TEnd
+                
+    def getBlockCount(self):
+        return self._blockCount
+        
+    def getBlockSizes(self):
+        return self._blockSizes
+        
+    def getQStarts(self):
+        return self._qStarts
+        
+    def getTStarts(self):
+        return self._tStarts
+    
+    def setAttributes(self, lResults, iCurrentLineNumber):
+        error = False
+        
+        if lResults[0] != '':
+            self.setMatch(lResults[0])
+        else:
+            sys.stderr.write("WARNING: The field Match is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[1] != '':
+            self.setMismatch(lResults[1])
+        else:
+            sys.stderr.write("WARNING: The field Mismatch is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[2] != '':
+            self.setRepMatch(lResults[2])
+        else:
+            sys.stderr.write("WARNING: The field RepMatch is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[3] != '':
+            self.setN(lResults[3])
+        else:
+            sys.stderr.write("WARNING: The field N is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[4] != '':
+            self.setQGapCount(lResults[4])
+        else:
+            sys.stderr.write("WARNING: The field QGapCount is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[5] != '':
+            self.setQGapBases(lResults[5])
+        else:
+            sys.stderr.write("WARNING: The field QGapBases is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[6] != '':
+            self.setTGapCount(lResults[6])
+        else:
+            sys.stderr.write("WARNING: The field TGapCount is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[7] != '':
+            self.setTGapBases(lResults[7])
+        else:
+            sys.stderr.write("WARNING: The field TGapBases is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[8] != '':
+            self.setStrand(lResults[8])
+        else:
+            sys.stderr.write("WARNING: The field Strand is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[9] != '':
+            self.setQName(lResults[9])
+        else:
+            sys.stderr.write("WARNING: The field QName is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[10] != '':
+            self.setQSize(lResults[10])
+        else:
+            sys.stderr.write("WARNING: The field QSize is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[11] != '':
+            self.setQStart(lResults[11])
+        else:
+            sys.stderr.write("WARNING: The field QStart is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[12] != '':
+            self.setQEnd(lResults[12])
+        else:
+            sys.stderr.write("WARNING: The field QEnd is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[13] != '':
+            self.setTName(lResults[13])
+        else:
+            sys.stderr.write("WARNING: The field TName is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[14] != '':
+            self.setTSize(lResults[14])
+        else:
+            sys.stderr.write("WARNING: The field TSize is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[15] != '':
+            self.setTStart(lResults[15])
+        else:
+            sys.stderr.write("WARNING: The field TStart is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[16] != '':
+            self.setTEnd(lResults[16])
+        else:
+            sys.stderr.write("WARNING: The field TEnd is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[17] != '':
+            self.setBlockCount(lResults[17])
+        else:
+            sys.stderr.write("WARNING: The field BlockCount is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[18] != '':
+            self.setBlockSizes(lResults[18])
+        else:
+            sys.stderr.write("WARNING: The field BlockSizes is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[19] != '':
+            self.setQStarts(lResults[19])
+        else:
+            sys.stderr.write("WARNING: The field QStarts is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[20] != '':
+            self.setTStarts(lResults[20])
+        else:
+            sys.stderr.write("WARNING: The field TStarts is empty in blat file in line %s\n" % iCurrentLineNumber)
+            error = True
+            
+        if error == True:
+            self._setAllToNull()
+            
+    def setAttributesFromString(self, blatLine, iCurrentLineNumber ="", fieldSeparator ="\t"):
+        blatLine = blatLine.rstrip()
+        lBlatLineItem = blatLine.split(fieldSeparator)
+        if not len(lBlatLineItem) == 21:
+            sys.stderr.write("WARNING: The line %s is not valid blat line (%s columns -> 21 columns needed)\n" % (iCurrentLineNumber, len(lBlatLineItem)))
+        else:
+            self.setAttributes(lBlatLineItem, iCurrentLineNumber)
+            
+    def _setAllToNull(self):
+        self._match = ''
+        self._mismatch = ''
+        self._repMatch = ''
+        self._N = ''
+        self._QGapCount = ''
+        self._QGapBases = ''
+        self._TGapCount = ''
+        self._TGapBases = ''
+        self._strand = ''
+        self._QName = ''
+        self._QSize = ''
+        self._QStart = ''
+        self._QEnd = ''
+        self._TName = ''
+        self._TSize = ''
+        self._TStart = ''
+        self._TEnd = ''
+        self._blockCount = ''
+        self._blockSizes = ''
+        self._qStarts = ''
+        self._tStarts = ''
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/BlatToGff.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,116 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+import optparse
+import os
+from commons.core.parsing.BlatParser import BlatParser
+
+class BlatToGff(object):
+
+
+    def __init__(self):
+        pass
+    
+    def setAttributesFromCmdLine(self):
+        help = '\
+        \nThis Script Launch BlatToGff.\n\n\
+        Example 1: python BlatToGff.py -i blatResultsFile.tab -o outputFile.gff3\n\n'
+        parser = optparse.OptionParser(usage= help, version="CovertSamToFastq.py v1.0")
+        parser.add_option( '-i', '--input', dest='inputBLAT', help='Blat Input File Name [Format: tabular]', default= None )
+        parser.add_option( '-o', '--output', dest='output', help='Output File Name [Format: GFF3]', default= None )
+        parser.add_option( '-n', '--methodname', dest='methodName', help='Method name in col. 3 [Default: None]', default= None )
+        ( options, args ) = parser.parse_args()
+        self._options = options
+    
+    def checkOptions(self):
+        if self._options.inputBLAT == '':
+            raise Exception("ERROR: No Blat file specified for -i !")
+        elif not os.path.exists(self._options.inputBLAT):
+            raise Exception("ERROR: Blat Input File doesn't exist !")
+        else:
+            self._inputFileBlat = self._options.inputBLAT
+            
+        if self._options.output == '':
+            raise Exception("ERROR: No Output file specified for -o !")
+        else:
+            self._outputFileGFF = self._options.output
+            
+        self._methodName = self._options.methodName
+            
+    def run(self):
+        self.checkOptions()
+        self._createGFFOutputFile()
+        BLATFile = open(self._inputFileBlat, 'r')
+        
+        headerBlatLine = BLATFile.readline()
+        headerBlatLine = BLATFile.readline()
+        headerBlatLine = BLATFile.readline()
+        headerBlatLine = BLATFile.readline()
+        headerBlatLine = BLATFile.readline()
+        blatLine = BLATFile.readline()
+        numberLine = 6
+        while blatLine != '':
+            gffLine = self.convertBlatObjectToGffLine(blatLine, numberLine)
+            self._printGFFLinesToOutputFile(gffLine)
+            blatLine = BLATFile.readline()
+            numberLine = numberLine + 1
+            
+    def convertBlatObjectToGffLine(self, blatLine, numberLine):
+        iBlatHit = BlatParser()
+        iBlatHit.setAttributesFromString(blatLine, numberLine)
+        col1 = iBlatHit.getTName()
+        col2 = 'BlatToGff'
+        if self._methodName == '' or self._methodName == None:
+            col3 = 'BES'
+        else:
+            col3 = '%s:BES' % self._methodName
+        col4 = iBlatHit.getTStart()
+        col5 = iBlatHit.getTEnd()
+        col6 = '.'
+        col7 = '+'
+        col8 = '.'
+        col9 = 'ID=%s;Name=%s;bes_start=%s;bes_end=%s;bes_size=%s' % (iBlatHit.getQName(), iBlatHit.getQName(), iBlatHit.getTStart(), iBlatHit.getTEnd(), iBlatHit.getTSize())
+        gffLine = '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (col1, col2, col3, col4, col5, col6, col7, col8, col9)
+        return gffLine
+    
+    def _createGFFOutputFile(self):
+        GFFfile = open(self._outputFileGFF, 'w')
+        GFFfile.write("##gff-version 3\n")
+        GFFfile.close()
+        
+    def _printGFFLinesToOutputFile(self, line):
+        GFFfile = open(self._outputFileGFF, 'a')
+        GFFfile.write(line)
+        GFFfile.close()
+
+if __name__ == '__main__':
+    iBlatToGff = BlatToGff()
+    iBlatToGff.setAttributesFromCmdLine()
+    iBlatToGff.run()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/BlatToGffForBesPaired.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,266 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+import optparse
+import os
+import sys
+import re
+import datetime
+from commons.core.parsing.BlatParser import BlatParser
+from commons.core.seq.FastaUtils import FastaUtils 
+
+class BlatToGffForBesPaired(object):
+
+
+    def __init__(self):
+        pass
+    
+    def setAttributesFromCmdLine(self):
+        help = '\
+        \nThis Script Launch BlatToGffForBesPaired.\n\n\
+        Example 1: python BlatToGffForBesPaired.py -i blatResultsFile.tab -f besSequences.fasta -o outputFile.gff3\n\
+        Example 2: python BlatToGffForBesPaired.py -i blatResultsFile.tab -f besSequences.fasta -o outputFile.gff3 -n muscadine:filtre1\n\n\
+        Note 1: In blat input file, all BAC-Ends must be paired. In addition, they must be one above the other.\nFor example, if you have the BES MRRE1H032F08FM1 (forward), we must have the BES MRRE1H032F08RM1 (reverse) just after, like:\n\
+        554\t26\t0\t0\t1\t16\t1\t17\t+\tMRRE1H032F08FM1\t606\t10\t606\tchr11\t19818926\t3725876\t3726473\t2\t553,27,\t10,579,\t3725876,3726446,\n\
+        620\t23\t0\t0\t0\t0\t0\t0\t-\tMRRE1H032F08RM1\t643\t0\t643\tchr11\t19818926\t3794984\t3795627\t1\t643,\t0,\t3794984,\n\
+        Note 2: the header in Blat results output file must be present (5 lines).\n\n'
+                
+        parser = optparse.OptionParser(usage= help, version="CovertSamToFastq.py v1.0")
+        parser.add_option( '-i', '--input', dest='inputBLAT', help='Blat Input File Name, with BES paired (1 Forward and 1 Reverse) [Format: tabular]', default= None )
+        parser.add_option( '-f', '--fasta', dest='inputFASTA', help='Fasta Input File Name, with all sequences of BES [Format: fasta]', default= None )
+        parser.add_option( '-o', '--output', dest='output', help='Output File Name [Format: GFF3]', default= None )
+        parser.add_option( '-n', '--methodname', dest='methodName', help='Method name in col. 3 [Default: None]', default= None )
+        ( options, args ) = parser.parse_args()
+        self._options = options
+    
+    def checkOptions(self):
+        if self._options.inputBLAT == '':
+            raise Exception("ERROR: No Blat file specified for -i !")
+        elif not os.path.exists(self._options.inputBLAT):
+            raise Exception("ERROR: Blat Input File doesn't exist !")
+        else:
+            self._inputFileBlat = self._options.inputBLAT
+            
+        if self._options.inputFASTA == '':
+            raise Exception("ERROR: No Fasta file specified for -f !")
+        elif not os.path.exists(self._options.inputFASTA):
+            raise Exception("ERROR: Fasta Input File doesn't exist !")
+        else:
+            self._inputFileFasta = self._options.inputFASTA
+            
+        if self._options.output == '':
+            raise Exception("ERROR: No Output file specified for -o !")
+        else:
+            self._outputFileGFF = self._options.output
+            
+        self._methodName = self._options.methodName
+            
+    def run(self):
+        self.checkOptions()
+        self._createGFFOutputFile()
+        BLATFile = open(self._inputFileBlat, 'r')
+        
+        headerBlatLine = BLATFile.readline()
+        headerBlatLine = BLATFile.readline()
+        headerBlatLine = BLATFile.readline()
+        headerBlatLine = BLATFile.readline()
+        headerBlatLine = BLATFile.readline()
+        blatLine = BLATFile.readline()
+        numberLine = 6
+        while blatLine != '':
+            lGffLines = []
+            
+            gffLineBes1, besName1, seqBes1, typeBes1 = self.convertBlatObjectToGffLine(blatLine, numberLine)
+            lGffLines.append(gffLineBes1)
+            
+            blatLine = BLATFile.readline()
+            numberLine = numberLine + 1
+            
+            gffLineBes2, besName2, seqBes2, typeBes2 = self.convertBlatObjectToGffLine(blatLine, numberLine)
+            lGffLines.append(gffLineBes2)
+            
+            gffLineBac = self.createGffLineForBac(gffLineBes1, besName1, seqBes1, typeBes1, gffLineBes2, besName2, seqBes2, typeBes2, numberLine)
+            lGffLines.append(gffLineBac)
+            
+            if gffLineBac != None:
+                self._printGFFLinesToOutputFile(lGffLines)
+                
+            blatLine = BLATFile.readline()
+            numberLine = numberLine + 1
+            
+    def convertBlatObjectToGffLine(self, blatLine, numberLine):
+        iBlatHit = BlatParser()
+        iBlatHit.setAttributesFromString(blatLine, numberLine)
+        besName = iBlatHit.getQName()
+        seqBes = self.extractBesSequenceFromFastaFile(besName, numberLine)
+        
+        typeBes = ''
+        if re.match('^.+FM[0-9]$', besName):
+            typeBes = 'FM'
+        elif re.match('^.+RM[0-9]$', besName):
+            typeBes = 'RM'
+        
+        col1 = iBlatHit.getTName()
+        col2 = 'BlatToGffForBesPaired'
+        if self._methodName == '' or self._methodName == None:
+            col3 = 'BES'
+        else:
+            col3 = '%s:BES' % self._methodName
+        col4 = iBlatHit.getTStart()
+        col5 = iBlatHit.getTEnd()
+        col6 = '.'
+        col7 = '+'
+        col8 = '.'
+        col9 = 'ID=%s;Name=%s;bes_start=%s;bes_end=%s;bes_size=%s;muscadine_seq=%s' % (besName, besName, iBlatHit.getTStart(), iBlatHit.getTEnd(), iBlatHit.getTSize(), seqBes)
+            
+        gffLine = '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (col1, col2, col3, col4, col5, col6, col7, col8, col9)
+        return gffLine, iBlatHit.getQName(),seqBes, typeBes
+    
+    def createGffLineForBac(self, gffLineBes1, besName1, seqBes1, typeBes1, gffLineBes2, besName2, seqBes2, typeBes2, numberLine):
+        lGffLineBes1 = gffLineBes1.split('\t')
+        lGffLineBes2 = gffLineBes2.split('\t')
+        besName1 = self.getBesName(lGffLineBes1[8])
+        besName2 = self.getBesName(lGffLineBes2[8])
+        
+        tBes1 = (lGffLineBes1[0], int(lGffLineBes1[3]), int(lGffLineBes1[4]))
+        tBes2 = (lGffLineBes2[0], int(lGffLineBes2[3]), int(lGffLineBes2[4]))
+        
+        if self.checkBesNames(besName1, besName2, numberLine) == True and self.checkBesPositions(tBes1, tBes2) == True:
+            startBacPos, endBacPos = self.getBacPositions(tBes1, tBes2)
+            sizeBacPos = endBacPos - startBacPos + 1
+            bacName = self.getBacName(besName1)
+            nameBesFM, seqBesFM, nameBesRM, seqBesRM = self.getBesFmAndRmNamesAndSequences(besName1, seqBes1, typeBes1, besName2, seqBes2, typeBes2)
+            
+            col1 = lGffLineBes1[0]
+            col2 = 'BlatToGffForBesPaired'
+            if self._methodName == '' or self._methodName == None:
+                col3 = 'BAC'
+            else:
+                col3 = '%s:BAC' % self._methodName
+            col4 = startBacPos
+            col5 = endBacPos
+            col6 = '.'
+            col7 = '.'
+            col8 = '.'
+            col9 = 'ID=%s;Name=%s;bac_start=%s;bac_end=%s;bac_size=%s;besFM_name=%s;muscadine_besFM_seq=%s;besRM_name=%s;muscadine_besRM_seq=%s' % (bacName, bacName, startBacPos, endBacPos, sizeBacPos, nameBesFM, seqBesFM, nameBesRM, seqBesRM)
+            gffLine = '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (col1, col2, col3, col4, col5, col6, col7, col8, col9)
+            return gffLine
+        return None
+    
+    def getBesFmAndRmNamesAndSequences(self, besName1, seqBes1, typeBes1, besName2, seqBes2, typeBes2):
+        if typeBes1 == 'FM' and typeBes2 == 'RM':
+            return besName1, seqBes1, besName2, seqBes2
+        elif typeBes1== 'RM' and typeBes2 == 'FM':
+            return besName2, seqBes2, besName1, seqBes1
+
+    def getBesName(self, col9):
+        lCol9 = col9.split(';')
+        ID = lCol9[0]
+        besName = ID[3:]
+        return besName
+    
+    def getBacName(self, besName):
+        bacName = besName[:-3]
+        return bacName
+
+    def checkBesNames(self, besName1, besName2, line):
+        bacName1 = besName1[:-3]
+        bacName2 = besName2[:-3]
+        if bacName1 == bacName2:
+            return True
+        else:
+            sys.stderr.write("WARNING: Lines %s and %s the two Bes (%s AND %s) do not belong to the same BAC !!!\n  -> you have to filter this Blat file...\n" % (int(line)-1, line, besName1, besName2))
+            return False
+    
+    def checkBesPositions(self, tBes1, tBes2):
+        if tBes1[0] == tBes2[0]:
+            minBes1 = min(tBes1[1], tBes1[2])
+            maxBes1 = max(tBes1[1], tBes1[2])
+            minBes2 = min(tBes2[1], tBes2[2])
+            maxBes2 = max(tBes2[1], tBes2[2])
+            if (minBes1 < minBes2 and maxBes1 < minBes2) or (minBes2 < minBes1 and maxBes2 < minBes1):
+                return True
+        return False
+    
+    def getBacPositions(self, tBes1, tBes2):
+        startBacPos = 0
+        endBacPos = 0
+        minBes1 = min(tBes1[1], tBes1[2])
+        maxBes1 = max(tBes1[1], tBes1[2])
+        minBes2 = min(tBes2[1], tBes2[2])
+        maxBes2 = max(tBes2[1], tBes2[2])
+        if minBes1 < minBes2:
+            startBacPos = minBes1
+            endBacPos = maxBes2
+        else:
+            startBacPos = minBes2
+            endBacPos = maxBes1
+        return startBacPos, endBacPos
+    
+    def extractBesSequenceFromFastaFile(self, besName, numberLine):
+        seq = ''
+        date = datetime.datetime.now()
+        date = date.strftime("%d%m%Y_%H%M%S")
+        tmpFileName = 'tmp_BlatToGffForBesPaired_%s.fasta' % date
+        iFastaUtils = FastaUtils()
+        iFastaUtils.dbExtractByPattern(besName, self._inputFileFasta, tmpFileName)
+        
+        if os.path.exists(tmpFileName):
+            newFastaFile = open(tmpFileName, 'r')
+            line = newFastaFile.readline()
+            if line != '':
+                while line != '':
+                    if line[0] != '>':
+                        line = line.replace('\n', '')
+                        seq += line
+                    line = newFastaFile.readline()
+                newFastaFile.close()
+                os.remove(tmpFileName)
+                return seq
+            os.remove(tmpFileName)
+        
+        sys.stderr.write("WARNING: At line %s, the BAC-Ends (%s) hasn't got sequence in fasta file (%s) !!\n" % (numberLine, besName, os.path.basename(self._inputFileFasta)))
+        return 'NA'
+    
+    def _createGFFOutputFile(self):
+        GFFfile = open(self._outputFileGFF, 'w')
+        GFFfile.write("##gff-version 3\n")
+        GFFfile.close()
+        
+    def _printGFFLinesToOutputFile(self, lLines):
+        GFFfile = open(self._outputFileGFF, 'a')
+        for line in lLines:
+            GFFfile.write(line)
+        GFFfile.close()
+
+if __name__ == '__main__':
+    iBlatToGffForBesPaired = BlatToGffForBesPaired()
+    iBlatToGffForBesPaired.setAttributesFromCmdLine()
+    iBlatToGffForBesPaired.run()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/BowtieParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,91 @@
+#
+# Copyright INRA-URGI 2009-2011
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from commons.core.parsing.MapperParser import MapperParser
+from SMART.Java.Python.structure.Mapping import Mapping
+from SMART.Java.Python.structure.SubMapping import SubMapping
+from SMART.Java.Python.structure.Interval import Interval
+
+class BowtieParser(MapperParser):
+    """A class that parses BowTie format"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(BowtieParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(BowtieParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["bowtie"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        pass
+
+
+    def parseLine(self, line):
+        line   = line.strip()
+        fields = line.split("\t")
+        if len(fields) not in (7, 8):
+            raise Exception("Line %d '%s' does not look like a BowTie line (number of fields is %d instead of 7 or 8)" % (self.currentLineNb, line, len(fields)))
+        name         = fields[0]
+        direction    = 1 if fields[1] == "+" else -1
+        chromosome   = fields[2]
+        genomeStart  = int(fields[3]) + 1
+        sequence     = fields[4]
+        quality      = fields[5]
+        number       = int(fields[6])
+        nbMismatches = 0
+        if len(fields) == 8:
+            tags         = fields[7]
+            nbMismatches = len(tags.split(","))
+
+        mapping = Mapping()
+        queryInterval = Interval()
+        queryInterval.setName(name)
+        queryInterval.setStart(1)
+        queryInterval.setEnd(len(sequence) + 1)
+        targetInterval = Interval()
+        targetInterval.setChromosome(chromosome)
+        targetInterval.setStart(genomeStart)
+        targetInterval.setEnd(genomeStart + len(sequence) - 1)
+        subMapping = SubMapping()
+        subMapping.setQueryInterval(queryInterval)
+        subMapping.setTargetInterval(targetInterval)
+        mapping.addSubMapping(subMapping)
+        mapping.setSize(len(sequence))
+        mapping.setNbMismatches(nbMismatches)
+        mapping.setDirection(direction)
+        return mapping
+
Binary file smart_toolShed/commons/core/parsing/BowtieParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/CoordsParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,137 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from SMART.Java.Python.structure.Mapping import Mapping
+from commons.core.parsing.MapperParser import MapperParser
+from SMART.Java.Python.structure.SubMapping import SubMapping
+from SMART.Java.Python.misc import Utils
+
+class CoordsParser(MapperParser):
+    """A class that parses the .coords output of Nucmer"""
+
+    def __init__(self, fileName, verbosity = 0):
+        self._lineParseRe = re.compile(r"^\s*(?P<tStart>\d+)\s+(?P<tEnd>\d+)\s+\|\s+(?P<qStart>\d+)\s+(?P<qEnd>\d+)\s+\|\s+(?P<tLength>\d+)\s+(?P<qLength>\d+)\s+\|\s+(?P<identity>\d+\.?\d*)\s+\|\s+(?P<tName>[\w\|\:\-]+)\s+(?P<qName>.*)\s*$")
+        self._lineParseRe2 = re.compile(r"^\s*(?P<tStart>\d+)\s+(?P<tEnd>\d+)\s+(?P<qStart>\d+)\s+(?P<qEnd>\d+)\s+(?P<tLength>\d+)\s+(?P<qLength>\d+)\s+(?P<identity>\d+\.?\d*)\s+(?P<rlen>\d+\.?\d*)\s+(?P<qlen>\d+\.?\d*)\s+(?P<rcov>\d+\.?\d*)\s+(?P<qcov>\d+\.?\d*)\s+(?P<rframe>[-]?\d+\.?\d*)\s+(?P<qframe>[-]?\d+\.?\d*)\s+(?P<tName>[\w\|\:\-]+)\s+(?P<qName>.*)\s*$")
+        self._lineParseRe3 = re.compile(r"^\s*(?P<tStart>\d+)\s+(?P<tEnd>\d+)\s+\|\s+(?P<qStart>\d+)\s+(?P<qEnd>\d+)\s+\|\s+(?P<tLength>\d+)\s+(?P<qLength>\d+)\s+\|\s+(?P<identity>\d+\.?\d*)\s+(?P<sim>\d+\.?\d*)\s+(?P<stp>\d+\.?\d*)\s+\|\s+(?P<rframe>[-]?\d+\.?\d*)\s+(?P<qframe>[-]?\d+\.?\d*)\s+(?P<tName>[\w\|\:\-]+)\s+(?P<qName>.*)\s*$")
+        self._lineParseRe4 = re.compile(r"^\s*(?P<tStart>\d+)\s+(?P<tEnd>\d+)\s+(?P<qStart>\d+)\s+(?P<qEnd>\d+)\s+(?P<tLength>\d+)\s+(?P<qLength>\d+)\s+(?P<identity>\d+\.?\d*)\s+(?P<sim>\d+\.?\d*)\s+(?P<stp>\d+\.?\d*)\s+(?P<rlen>\d+\.?\d*)\s+(?P<qlen>\d+\.?\d*)\s+(?P<rcov>\d+\.?\d*)\s+(?P<qcov>\d+\.?\d*)\s+(?P<rframe>[-]?\d+\.?\d*)\s+(?P<qframe>[-]?\d+\.?\d*)\s+(?P<tName>[\w\|\:\-]+)\s+(?P<qName>.*)\s*$")
+        self.lineType = 1
+        MapperParser.__init__(self, fileName, verbosity)
+        
+    def getFileFormats():
+        return ["coords"]
+    getFileFormats = staticmethod(getFileFormats)
+
+    def skipFirstLines(self):    
+        while True: 
+            line = self.handle.readline()
+            self.currentLineNb += 1
+            if line == "":
+                break
+            if "=====" in line:
+                break
+            if "[S1]\t[E1]\t[S2]\t[E2]\t[LEN 1]\t[LEN 2]\t[% IDY]\t[LEN R]\t[LEN Q]\t[COV R]\t[COV Q]\t[FRM]\t[TAGS]" in line:
+                self.lineType = 2
+                break
+            if "[S1]     [E1]  |     [S2]     [E2]  |  [LEN 1]  [LEN 2]  |  [% IDY]  [% SIM]  [% STP]  | [FRM]  [TAGS]" in line:
+                self.lineType = 3
+           
+            if "[% IDY]\t[% SIM]\t[% STP]" in line and "[LEN Q]"in line:
+                self.lineType = 4 
+                break     
+        
+    def parseLine(self, line):
+        
+        if self.lineType == 1 : 
+            m = self._lineParseRe.search(line)
+        elif self.lineType == 2:
+            m = self._lineParseRe2.search(line)
+        elif self.lineType == 3:
+            m = self._lineParseRe3.search(line)
+        elif self.lineType == 4:
+            m = self._lineParseRe4.search(line)
+        if m == None:
+            sys.exit("\nLine %d '%s' does not have a NucMer format" % (self.currentLineNb, line))
+  
+        mapping = Mapping()
+        
+        subMapping = SubMapping()
+        subMapping.queryInterval.setName(m.group("qName"))
+        subMapping.queryInterval.setStart(min(int(m.group("qStart")), int(m.group("qEnd"))))
+        subMapping.queryInterval.setEnd(max(int(m.group("qStart")), int(m.group("qEnd"))))
+        subMapping.queryInterval.setSize(int(m.group("qLength")))
+        subMapping.queryInterval.setDirection(int(m.group("qEnd")) - int(m.group("qStart")))
+        
+        subMapping.targetInterval.setChromosome(m.group("tName"))
+        subMapping.targetInterval.setStart(min(int(m.group("tStart")), int(m.group("tEnd"))))
+        subMapping.targetInterval.setEnd(max(int(m.group("tStart")), int(m.group("tEnd"))))
+        subMapping.targetInterval.setSize(int(m.group("tLength")))
+        subMapping.targetInterval.setDirection(int(m.group("tEnd")) - int(m.group("tStart")))
+       
+        subMapping.setDirection(int(m.group("qEnd")) - int(m.group("qStart")))
+        subMapping.setSize(min(int(m.group("qLength")), int(m.group("tLength"))))
+        subMapping.setIdentity(float(m.group("identity")))
+        
+        mapping.addSubMapping(subMapping)
+        mapping.targetInterval.setStart(min(int(m.group("tStart")), int(m.group("tEnd"))))
+        mapping.targetInterval.setEnd(max(int(m.group("tStart")), int(m.group("tEnd"))))
+        mapping.targetInterval.setSize(int(m.group("tLength")))
+        mapping.targetInterval.setChromosome(m.group("tName"))
+         
+        mapping.queryInterval.setStart(min(int(m.group("qStart")), int(m.group("qEnd"))))
+        mapping.queryInterval.setEnd(max(int(m.group("qStart")), int(m.group("qEnd"))))
+        mapping.queryInterval.setSize(int(m.group("qLength")))
+        mapping.queryInterval.setName(m.group("qName"))
+        mapping.setDirection(int(m.group("qEnd")) - int(m.group("qStart")))
+        mapping.setSize(min(int(m.group("qLength")), int(m.group("tLength"))))
+        mapping.setIdentity(float(m.group("identity")))
+        mapping.setTagValue("feature", "match")
+        mapping.setTagValue("Target", "%s %d %d" % (m.group("qName"), int(m.group("qStart")), int(m.group("qEnd"))))
+                    
+        if self.lineType ==2 or self.lineType ==4:
+            mapping.setTagValue("target_pident", float(m.group("identity")))
+            mapping.setTagValue("target_pcover", float(m.group("qcov")))
+            mapping.setTagValue("target_length", int(m.group("qlen")))
+            
+        
+# Specific to Mark Work. Commented lines because of possible slowdown.                 
+#        for line in self.handle:
+#            string1 = line.strip()
+#            self.currentLineNb += 1
+#            break
+#        for line in self.handle:
+#            string2 = line.strip()
+#            self.currentLineNb += 1
+#            break
+#        print(len(string1),len(string2))
+#        mapping.setNbMismatches(Utils.getHammingDistance(string1, string2))
+        mapping.setNbGaps(0)
+
+        return mapping
Binary file smart_toolShed/commons/core/parsing/CoordsParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/CrossSsrAndBesMappedByBlatToGff.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,197 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import os
+import optparse
+from commons.core.parsing.SsrParser import SsrParser
+from commons.core.parsing.BlatParser import BlatParser
+
+class CrossSsrAndBesMappedByBlatToGff(object):
+
+
+    def __init__(self):
+        self._inputFileSSR = ''
+        self._inputFileBlat = ''
+        self._outputFileGFF = ''
+    
+    def setAttributesFromCmdLine(self):
+        help = '\
+        \nThis Script Launch CrossSsrAndBesMappedByBlatToGff.\n\n\
+        Example 1: python CrossSsrAndBesMappedByBlatToGff.py -s ssrResultsFile.tab -b blatResultsFile.tab -o outputFile.gff3\n\
+        Example 2: python CrossSsrAndBesMappedByBlatToGff.py -s ssrResultsFile.tab -b blatResultsFile.tab -o outputFile.gff3 -n muscadine:filtre1\n\n'
+        
+        parser = optparse.OptionParser(usage= help, version="CovertSamToFastq.py v1.0")
+        parser.add_option( '-s', '--ssr', dest='inputSSR', help='SSR Input File Name [Format: tabular]', default= None )
+        parser.add_option( '-b', '--blat', dest='inputBLAT', help='Blat Input File Name [Format: tabular]', default= None )
+        parser.add_option( '-o', '--output', dest='output', help='Output File Name [Format: GFF3]', default= None )
+        parser.add_option( '-n', '--methodName', dest='methodName', help='Method name in col. 3 [Default: None]', default= None )
+        ( options, args ) = parser.parse_args()
+        self.options = options
+    
+    def checkOptions(self):
+        if self.options.inputSSR == '':
+            raise Exception("ERROR: No SSR file specified for -s !")
+        elif not os.path.exists(self.options.inputSSR):
+            raise Exception("ERROR: SSR Input File doesn't exist !")
+        else:
+            self._inputFileSSR = self.options.inputSSR
+        
+        if self.options.inputBLAT == '':
+            raise Exception("ERROR: No Blat file specified for -b !")
+        elif not os.path.exists(self.options.inputBLAT):
+            raise Exception("ERROR: Blat Input File doesn't exist !")
+        else:
+            self._inputFileBlat = self.options.inputBLAT
+            
+        if self.options.output == '':
+            raise Exception("ERROR: No Output file specified for -o !")
+        else:
+            self._outputFileGFF = self.options.output
+            
+        self._methodName = self.options.methodName
+    
+    def run(self):
+        self.checkOptions()
+        self._createGFFOutputFile()
+        
+        dictSsrParser = {}
+        dictSsrParser = self.createDictOfSsrParser(dictSsrParser)
+        
+        BLATFile = open(self._inputFileBlat, 'r')
+        
+        headerBlatLine = BLATFile.readline()
+        headerBlatLine = BLATFile.readline()
+        headerBlatLine = BLATFile.readline()
+        headerBlatLine = BLATFile.readline()
+        headerBlatLine = BLATFile.readline()
+        blatLine = BLATFile.readline()
+        numberLine = 6
+        while blatLine != '' and blatLine != '\n':
+            thisBlatHit = BlatParser()
+            thisBlatHit.setAttributesFromString(blatLine, numberLine)
+            besName = thisBlatHit.getQName()
+            
+            if besName in dictSsrParser:
+                lLinesToPrint = self.createListOfGFFLinesForThisBesWithSSR(thisBlatHit, dictSsrParser)
+                self._printGFFLinesToOutputFile(lLinesToPrint)
+            
+            blatLine = BLATFile.readline()
+            numberLine = numberLine + 1
+        
+        BLATFile.close()
+        
+    def createDictOfSsrParser(self, dictSsrParser):
+        dictSsrParser = {}
+        SSRFile = open(self._inputFileSSR, 'r')
+        
+        header = SSRFile.readline()
+        line = SSRFile.readline()
+        numberLine = 2
+        
+        while line != '' and line != '\n':
+            thisSSRHit = SsrParser()
+            thisSSRHit.setAttributesFromString(line, numberLine)
+            
+            BESName = thisSSRHit.getBesName()
+            if not BESName in dictSsrParser:
+                list = [thisSSRHit]
+                dictSsrParser[BESName] = list
+            else:
+                list = dictSsrParser[BESName]
+                list.append(thisSSRHit)
+                dictSsrParser[BESName] = list
+            
+            line = SSRFile.readline()
+            numberLine = numberLine + 1
+            
+        SSRFile.close()
+        return dictSsrParser
+    
+    def createListOfGFFLinesForThisBesWithSSR(self, BlatHitObject, dictSsrParser):
+        listGffLines = []
+        
+        besNameToKeep =  BlatHitObject.getQName()
+        lOfSSRHitObject = dictSsrParser[besNameToKeep]
+        
+        for SSRHitObject in  lOfSSRHitObject:
+            posSSRStart = self.convertSSRPositionsToChromPositions(SSRHitObject.getSsrStart(), BlatHitObject.getTStart(), BlatHitObject.getTEnd(), BlatHitObject.getStrand())
+            posSSREnd = self.convertSSRPositionsToChromPositions(SSRHitObject.getSsrEnd(), BlatHitObject.getTStart(), BlatHitObject.getTEnd(), BlatHitObject.getStrand())
+            ssrSeq = self.getSsrSeq(SSRHitObject.getSsrMotif(), SSRHitObject.getSsrMotifNumber())
+            
+            col1 = BlatHitObject.getTName()
+            col2 = 'CrossSsrAndBesAlignedByBlat'
+            if self._methodName != '' and self._methodName != None:
+                col3 = '%s:SSR' %self._methodName
+            else:
+                col3 = 'SSR'
+            col4 = posSSRStart
+            col5 = posSSREnd
+            col6 = '.'
+            col7 = BlatHitObject.getStrand()
+            col8 = '.'
+            col9 = 'ID=SSR_%s_%s;Name=SSR_%s_%s;bes_name=%s;bes_size=%s;bes_matchstart=%s;bes_matchend=%s;bes_redundancy=%s;ssr_type=%s;ssr_motif=%s;ssr_motif_number=%s;ssr_start=%s;ssr_end=%s;muscadine_seq=%s' % (besNameToKeep, SSRHitObject.getBesRedundancy(), 
+                                                                                                                                                                                           besNameToKeep, SSRHitObject.getBesRedundancy(),
+                                                                                                                                                                                           besNameToKeep, BlatHitObject.getQSize(),
+                                                                                                                                                                                           BlatHitObject.getQStart(), BlatHitObject.getQEnd(), 
+                                                                                                                                                                                           SSRHitObject.getBesRedundancy(), SSRHitObject.getSsrNbNucleotides(),
+                                                                                                                                                                                           SSRHitObject.getSsrMotif(), SSRHitObject.getSsrMotifNumber(),
+                                                                                                                                                                                           SSRHitObject.getSsrStart(), SSRHitObject.getSsrEnd(), ssrSeq)
+            gffLine = '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (col1, col2, col3, col4, col5, col6, col7, col8, col9)
+            listGffLines.append(gffLine)
+            
+        return listGffLines
+    
+    def convertSSRPositionsToChromPositions(self, ssrPos, chromPosStart, chromPosEnd, strand):
+        if strand == '+':
+            newPos =  int(chromPosStart) + int(ssrPos) - 1
+        elif strand == '-':
+            newPos =  int(chromPosEnd) - int(ssrPos) + 1
+        return newPos
+    
+    def getSsrSeq(self, motif, nbMotif):
+        ssrSeq = motif * int(nbMotif)
+        return ssrSeq
+    
+    def _createGFFOutputFile(self):
+        GFFfile = open(self._outputFileGFF, 'w')
+        GFFfile.write("##gff-version 3\n")
+        GFFfile.close()
+        
+    def _printGFFLinesToOutputFile(self, lLinesToPrint):
+        GFFfile = open(self._outputFileGFF, 'a')
+        for line in lLinesToPrint:
+            GFFfile.write(line)
+        GFFfile.close()
+
+if __name__ == '__main__':
+    iCrossSsrAndBesMappedByBlatToGff = CrossSsrAndBesMappedByBlatToGff()
+    iCrossSsrAndBesMappedByBlatToGff.setAttributesFromCmdLine()
+    iCrossSsrAndBesMappedByBlatToGff.run()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/ElandParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,126 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+from commons.core.parsing.MapperParser import MapperParser
+from SMART.Java.Python.structure import Mapping
+
+class ElandParser(MapperParser):
+    """A class that parses ELAND format"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(ElandParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(ElandParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["eland"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        pass
+
+
+    def getInfos(self):
+        super(ElandParser, self).getInfos()
+        
+
+    def parseLine(self, line):
+
+        line = line.strip()
+
+        fields = line.split("\t")
+        if len(fields) < 22:
+            sys.exit("Line %d '%s' does not look like a ELAND line (number of fields is %d instead of 22)" % (self.currentLineNb, line, len(fields)))
+
+        flowCell = fields[0]
+        run = fields[1]
+        lane = fields[2]
+        tile = fields[3]
+        xcoord = fields[4]
+        ycoord = fields[5]
+        index = fields[6]
+        number = fields[7]
+        read = fields[8]
+        quality = fields[9]
+        chromosome = fields[10]
+        contig = fields[11]
+        position = fields[12]
+        strand = fields[13]
+        description = fields[14]
+        singleScore = fields[15]
+        pairScore = fields[16]
+        partnerChromosome = fields[17]
+        partnerContig = fields[18]
+        partnerOffset = fields[19]
+        partnerStrand = fields[20]
+        filtering = fields[21]
+
+        if number != "1":
+            sys.exit("S-MART cannot handle pair-end reads yet!")
+
+        # nothing found
+        if position == "":
+            return None
+
+        name = "%s_%s:%s:%s:%s:%s#0/1" % (flowCell, run, lane, tile, xcoord, ycoord)
+        direction = 1 if strand == "F" else -1
+        nbMismatches = 0
+        for char in description:
+            if ord("A") <= ord(char) and ord(char) <= ord("Z"):
+                nbMismatches += 1
+
+        mapping = Mapping()
+        mapping.setTagValue("qualityString", quality)
+        
+        mapping.queryInterval.setName(name)
+        mapping.queryInterval.setDirection(direction)
+        mapping.queryInterval.setStart(1)
+        mapping.queryInterval.setEnd(len(read))
+
+        mapping.targetInterval.setChromosome(chromosome)
+        mapping.targetInterval.setStart(int(position))
+        mapping.targetInterval.setEnd(int(position) + len(read))
+        mapping.targetInterval.setDirection(1)
+
+        mapping.setSize(len(read))
+        mapping.setDirection(direction)
+
+        mapping.setNbGaps(0)
+        mapping.setNbMismatches(nbMismatches)
+        mapping.setTagValue("score", int(singleScore))
+
+        if filtering == "Y":
+            return mapping
+        # mapping filtered out
+        return None
Binary file smart_toolShed/commons/core/parsing/ElandParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/ExoParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,137 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from commons.core.parsing.MapperParser import MapperParser
+from SMART.Java.Python.structure.Mapping import Mapping
+from SMART.Java.Python.structure.SubMapping import SubMapping
+
+class ExoParser(MapperParser):
+    """A class that parses the output of Exonerate - roll your own format"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(ExoParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(ExoParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["exo", "exonerate"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        while "Hostname" not in self.handle.readline():
+            self.currentLineNb += 1
+            pass
+
+
+    def parseLine(self, line):
+        
+        if line == "-- completed exonerate analysis\n":
+            return None
+        
+        m = re.search(r"^\s*(\S+)\s+(\d+)\s+(\d+)\s+[+-]\s+(\S+)\s+(\d+)\s+(\d+)\s+([+-])\s+\d+\s+(\d+)\s+(\S.*)$", line)
+        if m == None:
+            sys.exit("\nLine %d '%s' does not have a RYO format" % (self.currentLineNb, line))
+
+        mapping = Mapping()
+        name = m.group(1)
+        queryStart = min(int(m.group(2)), int(m.group(3)))
+        queryEnd = max(int(m.group(2)), int(m.group(3)))-1
+        chromosome = m.group(4)
+        targetStart = min(int(m.group(5)), int(m.group(6)))
+        targetEnd = max(int(m.group(5)), int(m.group(6)))-1
+        direction = m.group(7)
+        nbMismatches = int(m.group(8))
+        rest = m.group(9).strip()
+        
+        nbGaps = 0
+        queryOffset = 0
+        targetOffset = 0
+        
+        subMapping = None
+        m = re.search(r"^(\w)\s+(\d+)\s+(\d+)", rest)
+        while m != None:
+            queryDistance    = int(m.group(2))
+            targetDistance = int(m.group(3))
+            if m.group(1) == "M":
+                if subMapping == None:
+                    subMapping = SubMapping()
+    
+                    subMapping.setSize(queryDistance)
+                    subMapping.setDirection(direction)
+        
+                    subMapping.queryInterval.setName(name)
+                    subMapping.queryInterval.setStart(queryStart + queryOffset)
+                    subMapping.queryInterval.setDirection(direction)
+        
+                    subMapping.targetInterval.setChromosome(chromosome)
+                    subMapping.targetInterval.setStart(targetStart + targetOffset)
+                    subMapping.targetInterval.setDirection(1)
+    
+            elif m.group(1) == "G":
+                nbGaps += max(queryDistance, targetDistance)
+                
+            elif m.group(1) == "I" or m.group(1) == "5" or m.group(1) == "3":
+                if subMapping != None:
+                    subMapping.queryInterval.setEnd(queryStart + queryOffset - 1)
+                    subMapping.targetInterval.setEnd(targetStart + targetOffset - 1)
+                    mapping.addSubMapping(subMapping)
+                    subMapping = None
+            else:
+                sys.exit("Cannot understand sign '%s' in line %s" % (m.group(1), line))
+            
+            queryOffset += queryDistance
+            targetOffset += targetDistance
+            rest = rest[m.end():].strip()
+            m = re.search(r"^(\w)\s+(\d+)\s+(\d+)", rest)
+            
+        if subMapping != None:
+            subMapping.queryInterval.setEnd(queryStart + queryOffset - 1)
+            subMapping.targetInterval.setEnd(targetStart + targetOffset - 1)
+            mapping.addSubMapping(subMapping)
+                        
+        mapping.setNbMismatches(nbMismatches)
+        mapping.setNbGaps(nbGaps)
+        mapping.setDirection(direction)
+
+        mapping.queryInterval.setName(name)
+        mapping.queryInterval.setStart(queryStart)
+        mapping.queryInterval.setEnd(queryEnd)
+
+        mapping.targetInterval.setChromosome(chromosome)
+        mapping.targetInterval.setStart(targetStart)
+        mapping.targetInterval.setEnd(targetEnd)
+
+        return mapping
+
Binary file smart_toolShed/commons/core/parsing/ExoParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/FastaParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,173 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+from commons.core.parsing.SequenceListParser import SequenceListParser
+from SMART.Java.Python.structure.Sequence import Sequence
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+
+class FastaParser(SequenceListParser):
+	"""A class that reads a list of sequences in FASTA"""
+
+	def __init__(self, fileName, verbosity = 0):
+		super(FastaParser, self).__init__(fileName, verbosity)
+		self.tags = {}
+		
+		
+	def getTags(self):
+		return self.tags
+
+
+	def getFileFormats():
+		return ["fasta", "mfa", "fas"]
+	getFileFormats = staticmethod(getFileFormats)
+
+
+	def getInfos(self):
+		"""
+		Get some generic information about the sequences
+		"""
+		self.nbSequences = 0
+		self.size		= 0
+		self.reset()
+		progress = UnlimitedProgress(100000, "Reading input file", self.verbosity - 9)
+		for line in self.handle:
+			line = line.strip()
+			if line == "":
+				continue
+			if line[0] == ">":
+				self.nbSequences += 1
+			else:
+				self.size += len(line)
+			progress.inc()
+		progress.done()
+		self.reset()
+
+
+	def parseOne(self):
+		"""
+		Parse only one element in the file
+		"""
+		name	 = None
+		string = ""
+
+		if self.currentLine != None:
+			if self.currentLine[0] != ">":
+				raise Exception("First line is weird: %s" % (self.currentLine))
+			name = self.currentLine[1:].split()[0]
+			self.currentLine = None
+
+		for line in self.handle:
+			line = line.strip()
+			if line == "":
+				pass
+			elif line[0] == ">":
+				if name == None:
+					name = line[1:].split()[0]
+				else:
+					self.currentLine = line
+					return Sequence(name, string)
+			else:
+				string += line
+
+		if name == None:
+			return None
+		return Sequence(name, string)
+	
+	
+	def setTags(self):
+		mark	= self.handle.tell()
+		thisTag = mark
+		
+		line = self.handle.readline()
+		while line != "":
+			if line[0] == ">":
+				line = line.strip()
+				self.tags[line[1:].split()[0]] = thisTag
+			thisTag = self.handle.tell()
+			line = self.handle.readline()
+			
+		self.handle.seek(mark)
+		
+
+	def getSubSequence(self, chromosome, start, end, direction, name = None):
+		if not self.tags:
+			self.setTags()
+
+		if chromosome not in self.tags:
+			raise Exception("Cannot find " + chromosome)
+			
+		if name == None:
+			name = "%s:%d-%d (%d)" % (chromosome, start, end, direction)
+		sequence = Sequence(name)
+
+		# switch from 0-based to 1-based coordinates
+		start -= 1
+		end   -= 1
+		
+		self.handle.seek(self.tags[chromosome])
+		line = self.handle.readline().strip()
+		if line != ">" + chromosome:
+			raise Exception("Arrived in a wrong place (got %s)" % (line))
+			
+		position1 = self.handle.tell()
+		line	  = self.handle.readline().strip()
+		position2 = self.handle.tell()
+		size	  = len(line)
+		address   = position1 + ((start - (start % size)) / size) * (position2 - position1);
+
+		count	 = max(0, start - (start % size));
+		self.handle.seek(address)
+
+		newSequence = ""
+		for line in self.handle:
+			line = line.strip()
+
+			if line[0] == ">":
+				break
+			
+			subStart = start - count
+			if subStart < 0:
+				subStart = 0
+			subEnd  = end - count
+			subSize = subEnd - subStart + 1
+			if subSize + subStart > len(line):
+				subSize = len(line) - subStart
+			if subEnd < 0:
+				break
+			if subStart <= len(line):
+				newSequence += line[subStart:subStart+subSize]
+			count += len(line)
+
+		if newSequence == "":
+			raise Exception("Error, sequence %s is empty" % (name))
+		sequence.sequence = newSequence
+		if direction == -1:
+			sequence.reverseComplement()
+		return sequence
Binary file smart_toolShed/commons/core/parsing/FastaParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/FastqParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,104 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+from commons.core.parsing.SequenceListParser import SequenceListParser
+from SMART.Java.Python.structure.Sequence import Sequence
+
+class FastqParser(SequenceListParser):
+    """A class that reads a list of sequences in FASTQ format"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(FastqParser, self).__init__(fileName, verbosity)
+
+
+    def getFileFormats():
+        return ["fastq", "mfq"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def getInfos(self):
+        """
+        Get some generic information about the sequences
+        """
+        self.nbSequences = 0
+        self.reset()
+        if self.verbosity >= 10:
+            print "Getting information on %s." % (self.fileName)
+
+        nbLines = 0
+        for line in self.handle:
+            line = line.strip()
+            if line == "":
+                continue
+            nbLines += 1
+            if self.verbosity >= 10 and nbLines % 400000 == 0:
+                sys.stdout.write("    %d sequences read\r" % (nbLines / 4))
+                sys.stdout.flush()
+        self.reset()
+        self.nbSequences = nbLines / 4
+        if self.verbosity >= 10:
+            print "    %d sequences read" % (self.nbSequences)
+            print "Done."
+
+
+    def parseOne(self):
+        """
+        Parse only one element in the file
+        """
+        string = ""
+        quality = ""
+        lineType = 0
+
+        for line in self.handle:
+            line = line.strip()
+            if lineType == 0:
+                if line[0] != "@":
+                    raise Exception("Line '%s' should start with '@'!" % (line))
+                name = line[1:]
+                inSequence = True
+                inQuality = False
+            elif lineType == 1:
+                string = line
+            elif lineType == 2:
+                if line[0] != "+":
+                    sys.exit("Line '%s' should start with '+'!" % (line))
+                if line[1:] != name and line != "+":
+                    sys.exit("Weird difference in sequence and quality names (%s and %s) while parsing FASTQ file %s." % (name, line[1:], self.fileName))
+                inQuality = True
+                inSequence = False
+            elif lineType == 3:
+                quality = line
+            lineType += 1
+            if lineType == 4:
+                sequence = Sequence(name, string)
+                sequence.setQuality(quality)
+                return sequence
+                
+        return None
Binary file smart_toolShed/commons/core/parsing/FastqParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/FindRep.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,113 @@
+import re
+from xml.sax.handler import ContentHandler
+
+class FindRep( ContentHandler ):
+    def __init__(self,outfileName, filter=0,count=0):
+        self.inWindowContent = 0
+        self.inSeqNameContent = 0
+        self.inStartContent = 0
+        self.inEndContent = 0
+        self.inPeriodContent = 0
+        self.inUnitContent = 0
+        self.inScoreContent = 0
+        self.count = count
+        self._outfileName = outfileName
+        self.filter=filter
+    
+    def startDocument(self):
+        self._fileout = open(self._outfileName,"w")
+        
+    def startElement(self,name,attrs):
+        if name=="window":
+            self.inWindowContent=1
+        elif name=="sequence-name":
+            self.inSeqNameContent=1
+            self.seqname=""
+        elif name=="repeat":
+            self.inRepContent=1
+            self.start=""
+            self.end=""
+            self.period=""
+            self.type={}
+        elif name=="start":
+            self.inStartContent=1
+        elif name=="end":
+            self.inEndContent=1
+        elif name=="period":
+            self.inPeriodContent=1
+        elif name=="unit":
+            self.inUnitContent=1
+            self.unit=""
+        elif name=="score":
+            self.inScoreContent=1
+            self.score=""
+
+    def characters(self,ch):
+        if self.inSeqNameContent:
+            self.seqname+=ch
+        elif self.inStartContent:
+            self.start+=ch
+        elif self.inEndContent:
+            self.end+=ch
+        elif self.inPeriodContent:
+            self.period+=ch            
+        elif self.inUnitContent:
+            self.unit+=ch            
+        elif self.inScoreContent:
+            self.score+=ch            
+
+    def endElement(self,name):
+        if name=="window":
+            self.inWindowContent=0
+        elif name=="sequence-name":
+            self.inSeqNameContent=0
+        elif name=="repeat":
+            self.inRepContent=0
+            start=int(self.start)
+            end=int(self.end)
+            period=int(self.period)
+            score=float(self.score)
+            if score>self.filter:
+                return
+            max = 0
+            self.count+=1
+            for k,n in self.type.items():
+                if n>max:
+                    max = n
+                    k_max = k
+
+            m=re.match("^[0-9]+.+\{Cut\}",self.seqname)
+            if m!=None:
+                seqname=self.seqname[m.start(0):m.end(0)-5].rstrip()
+                seqname=re.sub("^[0-9]+ ","",seqname).lstrip()
+                tok=self.seqname[m.end(0):].split("..")
+                astart=start+int(tok[0])-1
+                aend=end+int(tok[0])-1
+            else:
+                astart=start
+                aend=end
+                seqname=self.seqname
+            if len(k_max) > 100:
+                k_max=k_max[:48]+"..."+k_max[-51:]
+            strout="%d\t(%s)%d\t%s\t%d\t%d"%\
+                               (self.count,k_max,(abs(start-end)+1)/period,\
+                                seqname,astart,aend)
+            self._fileout.write("%s\n"%(strout))
+
+        elif name=="start":
+            self.inStartContent=0
+        elif name=="end":
+            self.inEndContent=0
+        elif name=="period":
+            self.inPeriodContent=0
+        elif name=="score":
+            self.inScoreContent=0
+        elif name=="unit":
+            self.inUnitContent=0
+            if self.type.has_key(self.unit):
+                self.type[self.unit]+=1
+            else:
+                self.type[self.unit]=1
+                
+    def endDocument(self):  
+        self._fileout.close()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/GbParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,111 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.structure.Transcript import Transcript
+from commons.core.parsing.TranscriptListParser import TranscriptListParser
+
+
+class GbParser(TranscriptListParser):
+    """A class that parses a GBrowse file and create a transcript list"""
+
+
+    def __init__(self, fileName, verbosity = 0):
+        self.reference = None
+        self.color         = None
+        super(GbParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(GbParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["gb", "gbrowse"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        for line in self.handle:
+            self.currentLineNb += 1
+            line = line.strip()
+            m = re.search(r"^\s*bgcolor\s*=\s*(\S+)\s*$", line)
+            if m != None:
+                self.color = m.group(1)
+            if line == "":
+                return
+
+
+    def parseLine(self, line):
+        transcript = Transcript()
+        # first line (reference)
+        m = re.search(r"^\s*reference\s*=\s*(\S+)\s*$", line)
+        if m != None:
+            self.reference = m.group(1)
+            for line in self.handle:
+                line = line.strip()
+                self.currentLineNb += 1
+                break
+        # second line (genomic coordinates)
+        m = re.search(r"^\s*READS\s+(\S+)\s+(\S+)\s+\"([^\"]*)\"\s*$", line)
+        if m == None:
+            sys.exit("\nLine %d '%s' does not have a GBrowse format" % (self.currentLineNb, line))
+        if self.reference == None:
+            sys.exit("Cannot get reference of GBrowse line %d '%s'" % (self.currentLineNb, line))
+        transcript.setChromosome(self.reference)
+        transcript.setName(m.group(1))
+        transcript.setComment(m.group(3))
+        # exons
+        exons = m.group(2).split(",")
+        transcriptStart = 1000000000
+        transcriptEnd = 0
+        direction = 0
+        for exon in exons:
+            m = re.search(r"^(\d+)-(\d+)$", exon)
+            if m == None:
+                sys.exit("\nCannot read GBrowse exon line %d '%s'" % (self.currentLineNb, exon))
+            interval = Interval()
+            interval.setChromosome(transcript.chromosome)
+            direction += int(m.group(2)) - int(m.group(1))
+            start = min(int(m.group(1)), int(m.group(2)))
+            end     = max(int(m.group(1)), int(m.group(2)))
+            interval.setStart(start)
+            interval.setEnd(end)
+            transcriptStart = min(transcriptStart, start)
+            transcriptEnd     = max(transcriptEnd, end)
+            transcript.addExon(interval)
+        transcript.setStart(transcriptStart)
+        transcript.setEnd(transcriptEnd)
+        transcript.setDirection(direction)
+        for exon in transcript.getExons():
+            exon.setDirection(direction)
+        return transcript
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/GffParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,149 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.structure.Transcript import Transcript
+from commons.core.parsing.TranscriptListParser import TranscriptListParser
+
+
+class GffParser(TranscriptListParser):
+	"""A class that parses a GFF file and create a transcript list"""
+
+
+	def __init__(self, fileName, verbosity = 0):
+		super(GffParser, self).__init__(fileName, verbosity)
+
+
+	def __del__(self):
+		super(GffParser, self).__del__()
+
+
+	def getFileFormats():
+		return ["gff", "gff2", "gff3"]
+	getFileFormats = staticmethod(getFileFormats)
+
+
+	def skipFirstLines(self):
+		pass
+
+
+	def getInfos(self):
+		self.chromosomes = set()
+		self.nbTranscripts = 0
+		self.size = 0
+		self.reset()
+		if self.verbosity >= 10:
+			print "Getting information on %s." % (self.fileName)
+		self.reset()
+		for line in self.handle:
+			line = line.strip()
+			if line == "" or line[0] == "#":
+				continue
+			parts = line.split("\t")
+			if len(parts) != 9:
+				raise Exception("Error! Line '%s' has %d tab-separated fields instead of 9!" % (line, len(parts)))
+			self.chromosomes.add(parts[0])
+			if parts[8].find("Parent") == -1:
+				self.nbTranscripts += 1
+			else:
+				self.size += max(int(parts[3]), int(parts[4])) - min(int(parts[3]), int(parts[4])) + 1
+			if self.verbosity >= 10 and self.nbTranscripts % 100000 == 0:
+				sys.stdout.write("	%d transcripts read\r" % (self.nbTranscripts))
+				sys.stdout.flush()
+		self.reset()
+		if self.verbosity >= 10:
+			print "	%d transcripts read" % (self.nbTranscripts)
+			print "Done."
+
+
+	def parseLine(self, line):
+		if not line or line[0] == "#":
+			return None
+		m = re.search(r"^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\S+)\s+([+-.])\s+(\S+)\s+(\S.*)$", line)
+		if m == None:
+			raise Exception("\nLine %d '%s' does not have a GFF format\n" % (self.currentLineNb, line))
+		interval = Interval()
+		interval.setChromosome(m.group(1))
+		interval.setName("unnamed transcript")
+		interval.setStart(min(int(m.group(4)), int(m.group(5))))
+		interval.setEnd(max(int(m.group(4)), int(m.group(5))))
+		if m.group(7) == ".":
+			interval.setDirection("+")
+		else:
+			interval.setDirection(m.group(7))
+		interval.setTagValue("feature", m.group(3))
+		if m.group(6).isdigit():
+			interval.setTagValue("score", m.group(6))
+
+		remainings = m.group(9).split(";")
+		for remaining in remainings:
+			remaining = remaining.strip()
+			if remaining == "":
+				continue
+			posSpace = remaining.find(" ")
+			posEqual = remaining.find("=")
+			if posEqual != -1 and (posEqual < posSpace or posSpace == -1):
+				parts = remaining.split("=")
+			else:
+				parts = remaining.split()
+			field = parts[0].strip()
+			value = " ".join(parts[1:]).strip(" \"")
+			if field in ("Name", "name", "Sequence", "TE", "SAT"):
+				interval.setName(value)
+			else:
+				try:
+					intValue = int(value)
+					interval.setTagValue(field, intValue)
+				except ValueError:
+					interval.setTagValue(field, value)
+
+		self.currentTranscriptAddress = self.previousTranscriptAddress
+		if "Parent" in interval.getTagNames():
+			if self.currentTranscript == None:
+				raise Exception("GFF file does not start with a transcript! First line is '%s'." % (line.strip()))
+			if interval.getTagValue("Parent") != self.currentTranscript.getTagValue("ID"):
+				raise Exception("Exon '%s' is not right after its transcript in GFF file!" % (interval))
+			self.currentTranscript.addExon(interval)
+			if interval.name == None:
+				interval.name = self.currentTranscript.name
+			return None
+		
+		transcript = self.currentTranscript
+		self.currentTranscript = Transcript()
+		self.currentTranscript.copy(interval)
+		self.previousTranscriptAddress = self.currentAddress
+
+		if transcript != None and transcript.name.startswith("unnamed"):
+			if "ID" in transcript.getTagNames():
+				transcript.name = transcript.getTagValue("ID")
+			else:
+				transcript.name = "unnamed transcript %s" % (self.currentLineNb)
+		return transcript
Binary file smart_toolShed/commons/core/parsing/GffParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/GtfParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,113 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.structure.Transcript import Transcript
+from commons.core.parsing.TranscriptListParser import TranscriptListParser
+
+
+class GtfParser(TranscriptListParser):
+    """A class that parses a GTF file and create a transcript list"""
+
+
+    def __init__(self, fileName, verbosity = 0):
+        super(GtfParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(GtfParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["gtf", "gtf2"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        pass
+
+
+    def parseLine(self, line):
+        if line[0] == "#":
+            return None
+        m = re.search(r"^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\S+)\s+([+-.])\s+(\S+)\s+(\S.*)$", line)
+        if m == None:
+            raise Exception("\nLine %d '%s' does not have a GTF format\n" % (self.currentLineNb, line))
+        interval = Interval()
+        interval.setChromosome(m.group(1))
+        interval.setName("unnamed transcript")
+        interval.setStart(min(int(m.group(4)), int(m.group(5))))
+        interval.setEnd(max(int(m.group(4)), int(m.group(5))))
+        if m.group(7) == ".":
+            interval.setDirection("+")
+        else:
+            interval.setDirection(m.group(7))
+        if m.group(6).isdigit():
+            interval.setTagValue("score", m.group(6))
+        type = m.group(3)
+
+        if type not in ("transcript", "exon"):
+            return None
+
+        remainings = m.group(9).split(";")
+        for remaining in remainings:
+            remaining = remaining.strip()
+            if remaining == "":
+                continue
+            parts = remaining.split(" ", 1)
+            field = parts[0].strip()
+            value = " ".join(parts[1:]).strip(" \"")
+            if field == "transcript_id":
+                interval.setTagValue("ID", value)
+            elif field == "gene_name":
+                interval.setName(value)
+            elif field == "transcript_name":
+                interval.setName(value)
+            elif field == "exon_number":
+                continue
+            else:
+                try:
+                    intValue = int(value)
+                    interval.setTagValue(field, intValue)
+                except ValueError:
+                    interval.setTagValue(field, value)
+
+        self.currentTranscriptAddress = self.previousTranscriptAddress
+        if self.currentTranscript == None or interval.getTagValue("ID") != self.currentTranscript.getTagValue("ID"):
+            transcript = self.currentTranscript
+            self.currentTranscript = Transcript()
+            self.currentTranscript.copy(interval)
+            self.currentTranscript.setTagValue("feature", "transcript")
+            self.previousTranscriptAddress = self.currentAddress
+            return transcript
+        if type == "exon":
+            self.currentTranscript.addExon(interval)
+        return None
Binary file smart_toolShed/commons/core/parsing/GtfParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/MapParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,67 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from SMART.Java.Python.structure.Mapping import Mapping
+from commons.core.parsing.MapperParser import MapperParser
+from SMART.Java.Python.structure.SubMapping import SubMapping
+from SMART.Java.Python.misc import Utils
+from SMART.Java.Python.structure.Transcript import Transcript
+from commons.core.parsing.TranscriptListParser import TranscriptListParser
+
+
+class MapParser(TranscriptListParser):
+    """A class that parses the repet .map files"""
+
+    def __init__(self, fileName, verbosity = 0):
+        self._lineParseRe = re.compile(r"(?P<seqName>\w+)\s(?P<chrName>\w+)\s(?P<sStart>\d+)\s(?P<sEnd>\d+)")
+        TranscriptListParser.__init__(self, fileName, verbosity)
+
+    def getFileFormats():
+        return ["map"]
+    getFileFormats = staticmethod(getFileFormats)
+
+    def skipFirstLines(self):    
+        return
+        
+    def parseLine(self, line):
+        m = self._lineParseRe.search(line)
+        
+        if m == None:
+            sys.exit("\nLine %d '%s' does not have a map format" % (self.currentLineNb, line))
+            
+        transcript = Transcript()
+        transcript.setChromosome(m.group("chrName"))
+        transcript.setStart(min(int(m.group("sStart")), int(m.group("sEnd"))))
+        transcript.setEnd(max(int(m.group("sStart")), int(m.group("sEnd"))))
+        transcript.setName(m.group("seqName"))
+        transcript.setDirection(1)
+
+        return transcript
Binary file smart_toolShed/commons/core/parsing/MapParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/MapperParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,129 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+from SMART.Java.Python.structure.Mapping import Mapping
+
+
+class MapperParser(object):
+    """An interface that parses the output of a generic mapper"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(MapperParser, self).__init__()
+        self.verbosity = verbosity
+        self.nbMappings = None
+        self.chromosomes = None
+        self.size = None
+        self.currentMapping = Mapping()
+        self.handle = open(fileName)
+        self.currentLineNb = 0
+        self.skipFirstLines()
+        self.fileName = fileName
+        self.startingPoint = self.handle.tell()
+
+
+    def __del__(self):
+        self.handle.close()
+        
+
+    def reset(self):
+        self.handle.seek(self.startingPoint)
+        self.currentLineNb = 0
+
+
+    def getNextMapping(self):
+        for line in self.handle:
+            mapping = self.parseLine(line)
+            self.currentLineNb += 1
+            if mapping != None:
+                return mapping
+        return False
+        
+        
+    def getIterator(self):
+        self.reset()
+        mapping = self.getNextMapping()
+        while mapping:
+            yield mapping
+            mapping = self.getNextMapping()
+                
+                
+    def getInfos(self):
+        self.chromosomes = set()
+        self.nbMappings = 0
+        self.size = 0
+        self.reset()
+        if self.verbosity >= 10:
+            print "Getting information."
+        for mapping in self.getIterator():
+            transcript = mapping.getTranscript()
+            self.chromosomes.add(transcript.getChromosome())
+            self.nbMappings += 1
+            self.size += transcript.getSize()
+            if self.verbosity >= 10 and self.nbMappings % 100000 == 0:
+                sys.stdout.write("    %d mappings read\r" % (self.nbMappings))
+                sys.stdout.flush()
+        self.reset()
+        if self.verbosity >= 10:
+            print "    %d mappings read" % (self.nbMappings)
+            print "Done."
+
+
+    def getNbMappings(self):
+        if self.nbMappings != None:
+            return self.nbMappings
+        self.getInfos()
+        return self.nbMappings
+
+
+    def getNbItems(self):
+        return self.getNbMappings()
+
+
+    def getChromosomes(self):
+        if self.chromosomes != None:
+            return self.chromosomes
+        self.getInfos()
+        return self.chromosomes
+    
+    
+    def getSize(self):
+        if self.size != None:
+            return self.size
+        self.getInfos()
+        return self.size
+    
+    
+    def getNbNucleotides(self):
+        return self.getSize()
+
+
+    def setDefaultTagValue(self, name, value):
+        for mapping in self.getIterator():
+            mapping.setTagValue(name, value)
Binary file smart_toolShed/commons/core/parsing/MapperParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/MaqParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,77 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from SMART.Java.Python.structure.Mapping import Mapping
+from commons.core.parsing.MapperParser import MapperParser
+
+
+class MaqParser(MapperParser):
+    """A class that parses the output of Maq"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(MaqParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(MaqParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["maq"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        pass
+
+
+    def parseLine(self, line):
+        m = re.search(r"^\s*(\S+)\s+(\S+)\s+(\d+)\s+([+-])\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s*$", line)
+        if m == None:
+            sys.exit("\nLine %d '%s' does not have a MAQ format" % (self.currentLineNb, line))
+
+        mapping = Mapping()
+
+        mapping.targetInterval.setStart(int(m.group(3)))
+        mapping.targetInterval.setSize(int(m.group(14)))
+        mapping.targetInterval.setChromosome(m.group(2))
+
+        mapping.queryInterval.setStart(1)
+        mapping.queryInterval.setSize(int(m.group(14)))
+        mapping.queryInterval.setName(m.group(1))
+
+        mapping.setDirection(m.group(4))
+        mapping.setSize(int(m.group(14)))
+        mapping.setNbMismatches(int(m.group(10)))
+        mapping.setRank(1)
+        mapping.setNbOccurrences(int(m.group(12)) + int(m.group(13)))
+
+        return mapping
Binary file smart_toolShed/commons/core/parsing/MaqParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/MrepsToSet.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,31 @@
+from commons.core.parsing.FindRep import FindRep
+from xml.sax import make_parser
+from xml.sax.handler import feature_namespaces
+import os
+
+
+class MrepsToSet(object):
+
+    def __init__(self, mrepsInputFileName="", mrepsOuputFileName="", outputFileName=None, errorFilter=0):
+        self._mrepsInputFileName = mrepsInputFileName
+        self._mrepsOuputFileName = mrepsOuputFileName
+        self._outputFileName = outputFileName or "%s.Mreps.set" % mrepsOuputFileName  
+        self._errorFilter = errorFilter
+        
+    def run(self):
+        xmlParser = make_parser()
+        xmlParser.setFeature( feature_namespaces, 0 )
+        xmlParser.setContentHandler( FindRep( self._outputFileName, self._errorFilter, 0 ) )
+        xmlParser.parse( self._mrepsOuputFileName )
+
+    def clean( self ):
+        """
+        Remove the output file (xml) from Mreps to keep only the 'set' file.
+        """
+        if os.path.exists(self._mrepsOuputFileName):
+            os.remove(self._mrepsOuputFileName)
+        
+        
+        
+
+        
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/Multifasta2SNPFile.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,846 @@
+import re
+import os
+import logging
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.seq.BioseqDB import BioseqDB
+from commons.core.seq.Bioseq import Bioseq
+from commons.core.LoggerFactory import LoggerFactory
+
+DNA_ALPHABET_WITH_N_AND_DELS = set (['A','T','G','C','N','-'])
+IUPAC = set(['A','T','G','C','U','R','Y','M','K','W','S','B','D','H','V','N', '-', 'a','t','g','c','u','r','y','m','k','w','s','b','d','h','v','n'])
+
+class Multifasta2SNPFile( object ):
+
+    POLYM_TYPE_4_SNP = "SNP"
+    POLYM_TYPE_4_INSERTION = "INSERTION"
+    POLYM_TYPE_4_DELETION = "DELETION"
+    POLYM_DEFAULT_CONFIDENCE_VALUE = "A"
+    SNP_LENGTH = 1
+    FLANK_LENGTH = 250
+    
+    def __init__(self, taxon, batchName="", geneName=""):
+        
+        if(batchName):
+            self._batchName = batchName
+            
+        if(geneName):
+            self._geneName = geneName
+
+        self._taxon = taxon
+        self._outSubSNPFileName = "SubSNP.csv"
+        self._outAlleleFileName = "Allele.csv"
+        self._outIndividualFileName = "Individual.csv"
+        self._outSequenceFSAFileName = "Sequences.fsa"
+        self._outSequenceCSVFileName = "Sequences.csv"
+        self._outBatchFileName = "Batch.txt"
+        self._outBatchLineFileName = "BatchLine.csv"
+        self._logFileName = "multifasta2SNP.log"
+        
+        self._lBatchFileResults = []
+        self._lSubSNPFileResults = []
+        self._lRefSequences = []
+        self._lIndividualFileResults = []
+        self._lBatchLineFileResults = []
+        self._dIndividualNumbers4SubSNPResults = {}
+        self._dAlleleFileResults = {}
+        
+        
+        self.dcurrentIndel = {}
+        self.lIndelsOfTheCurrentLine = []
+        self.lIndelsOverAllLines = []
+        self.dSNPsPositions = {}
+        
+        self._iCurrentLineNumber = 0
+        self._currentBatchNumber = 1
+        self.currentLineName = ""
+        self.currentNucleotide = ""
+        self.currentPosition = 0
+        self._sPolymConfidenceValue = Multifasta2SNPFile.POLYM_DEFAULT_CONFIDENCE_VALUE        
+        self._sPolymType = Multifasta2SNPFile.POLYM_TYPE_4_SNP
+        self._iPolymLength = Multifasta2SNPFile.SNP_LENGTH
+        self._fileUtils = FileUtils()
+        
+        if self._fileUtils.isRessourceExists(self._logFileName):
+            os.remove(self._logFileName)
+        self._logFile = LoggerFactory.createLogger(self._logFileName, logging.INFO, "%(asctime)s %(levelname)s: %(message)s")
+   
+    def runOneBatch( self, inFileName):
+        self._currentFileName = inFileName
+        #TODO: methode a virer; n'utiliser au final que runOneBatchWithoutWriting
+        self._wrapper = self.createWrapperFromFile(inFileName)
+        self._lBatchFileResults = self.completeBatchList()
+        self.detectSNPsAndIndels(self._wrapper) 
+        self._writeAllOutputFiles()
+        self._currentBatchNumber += 1
+        
+    def runOneBatchWithoutWriting( self, inFileName):
+        self.lIndelsOverAllLines = []
+        self._currentFileName = inFileName
+        self._wrapper = self.createWrapperFromFile(inFileName)
+        self._lBatchFileResults = self.completeBatchList()
+        self.detectSNPsAndIndels(self._wrapper) 
+        self._currentBatchNumber += 1
+    
+
+    def _cleanOutputsInTheCurrentDir(self):
+        #TODO: create a list of files to be deleted
+        FileUtils.removeFilesByPattern("*.csv")
+        if (FileUtils.isRessourceExists(self._outBatchFileName)):
+            os.remove(self._outBatchFileName)
+        if (FileUtils.isRessourceExists(self._outSequenceFSAFileName)):
+            os.remove(self._outSequenceFSAFileName)
+
+
+    def _createOutputObjectsIteratingOnCurrentDir(self):
+        #TODO: gerer les extensions multiples
+        extList = [".fasta", ".fsa"]
+        for dirname, dirnames, filenames in os.walk("."):
+            filenames.sort()
+            for filename in filenames:
+                if os.path.splitext(filename)[1] in extList:
+                    self._geneName = os.path.splitext(filename)[0]
+                    self._batchName = "Batch_" + self._geneName
+                    self.runOneBatchWithoutWriting(filename)
+
+    def runSeveralBatches( self, inputDir):
+        #TODO: enlever les chdirs, appeler les fichiers en absolu et modifier les tests en consequences
+        os.chdir(inputDir)
+        self._cleanOutputsInTheCurrentDir()
+        self._createOutputObjectsIteratingOnCurrentDir()
+        self._writeAllOutputFiles()
+        os.chdir("../")
+
+
+    def _treatADeletionClosingWithAnotherBaseThanRefSeq(self, lineName, nucleotide, position):
+        if (self.isTheIndelOpen4ThisLine):
+            self._closeTheCurrentIndel(lineName, nucleotide, position)
+        self._manageSNPs(lineName, nucleotide, position)
+        self.addOnePolymorphicPosition(position)
+
+    def _treatNucleotideDifferentThanRefSeqCase(self, refSeq, lineName, index, nucleotide, position):
+        if (nucleotide == "-" or refSeq[index] == "-"):
+            if (self.isTheIndelOpen4ThisLine):
+                self._expandTheCurrentIndel(position, nucleotide)
+            else:
+                self._startAnIndel(position, nucleotide)
+        else:
+            self._treatADeletionClosingWithAnotherBaseThanRefSeq(lineName, nucleotide, position)
+
+
+    def _treatSameNucleotideInOneIndel(self, refSeq, lineName, index, nucleotide, position):
+        if (self._sPolymType == Multifasta2SNPFile.POLYM_TYPE_4_DELETION):
+            self._closeTheCurrentIndel(lineName, nucleotide, position)
+        elif (self._sPolymType == Multifasta2SNPFile.POLYM_TYPE_4_INSERTION):
+            if (refSeq[index] == "-"):
+                self._expandTheCurrentIndel(position, nucleotide)
+            else:
+                self._closeTheCurrentIndel(lineName, nucleotide, position)
+
+    def detectSNPsAndIndels(self, iRefAndLines):
+        refSeq = iRefAndLines.getReferenceSequence()
+        refSeqLength = len ( refSeq )
+        self.dSNPsPositions = {}
+        
+        for iLineBioseq in iRefAndLines.getLinesBioseqInstances():
+            lineSequence = iLineBioseq.sequence
+            self.currentLineName = iLineBioseq.header
+            self._manageCurrentIndividual(self.currentLineName)
+            
+            index = 0
+            self.isTheIndelOpen4ThisLine = 0
+            self.lIndelsOfTheCurrentLine = []
+            for nucleotide in lineSequence:
+                position = index + 1
+                if  (index <  refSeqLength) and self._isSNPDetected(refSeq, index, nucleotide):
+                    self._treatNucleotideDifferentThanRefSeqCase(refSeq, self.currentLineName, index, nucleotide, position)
+                elif(index <  refSeqLength and self.isTheIndelOpen4ThisLine) :
+                    self._treatSameNucleotideInOneIndel(refSeq, self.currentLineName, index, nucleotide, position)
+                index = index + 1
+                self.currentNucleotide = nucleotide
+                self.currentPosition = position
+                
+            self.lIndelsOverAllLines = self.lIndelsOverAllLines + self.lIndelsOfTheCurrentLine
+        
+        self._postTraitementDetectSNP(self.currentLineName, self.currentNucleotide, self.currentPosition)
+        
+    def _manageCurrentIndividual(self, lineName):
+        self._lIndividualFileResults = self._completeIndividualListWithCurrentIndividual(self._lIndividualFileResults, lineName)
+        self._lBatchLineFileResults = self._completeBatchLineListWithCurrentIndividual(self._lBatchLineFileResults, self._lIndividualFileResults, lineName)
+        if not self._dIndividualNumbers4SubSNPResults.__contains__(lineName):
+            self._dIndividualNumbers4SubSNPResults[lineName] = len(self._lIndividualFileResults)
+        
+
+    def _manageLastPositionIndels(self, lineName, nucleotide, position):
+        if (self.isTheIndelOpen4ThisLine):
+            self._closeTheCurrentIndel(lineName, nucleotide, position)
+            self.lIndelsOverAllLines.append(self.lIndelsOfTheCurrentLine.pop())
+
+    def _postTraitementDetectSNP(self, lineName, nucleotide, position):
+        self._manageLastPositionIndels(lineName, nucleotide, position)
+            
+        self._mergeAllelesAndSubSNPsFromOverlappingIndels()
+        self._addMissingsAllelesAndSubSNPs()
+        
+        self._lSubSNPFileResults = self._sortSubSNPResultByBatchPositionAndLineName(self._lSubSNPFileResults)
+
+    def _manageSNPs(self, lineName, nucleotide, position):
+        self._dAlleleFileResults = self._completeAlleleSetWithCurrentAllele(self._dAlleleFileResults, nucleotide)
+        truePosition = self.getUngappedPositionInRefSeq(position)
+        subSNPName = self._formatSubSNPName(lineName, truePosition, Multifasta2SNPFile.POLYM_TYPE_4_SNP)
+        iAlleleNumber = self._dAlleleFileResults[nucleotide]
+        self._sPolymType = Multifasta2SNPFile.POLYM_TYPE_4_SNP
+        flank5Prime, flank3Prime = self.getFlanksOfASubSNP(lineName, position, Multifasta2SNPFile.SNP_LENGTH, Multifasta2SNPFile.FLANK_LENGTH)
+        dSubSNPResult = {'subSNPName':subSNPName, 'position':truePosition, 'lineName':self._dIndividualNumbers4SubSNPResults[lineName],
+                         'allele':iAlleleNumber, 'batchNumber': self._currentBatchNumber, 'confidenceValue':self._sPolymConfidenceValue,
+                         'type':self._sPolymType, 'length': Multifasta2SNPFile.SNP_LENGTH, 
+                         '5flank':flank5Prime, '3flank':flank3Prime}
+        if(not self.subSNPExistsInSubSNPList(dSubSNPResult, self._lSubSNPFileResults)):
+            self._lSubSNPFileResults.append(dSubSNPResult)
+        
+    def _startAnIndel(self, position, nucleotide):
+        self.dcurrentIndel['start'] = position
+        self.dcurrentIndel['end'] = position
+        self.sCurrentIndelAllele = nucleotide
+        if(nucleotide == "-"):
+            self._sPolymType = Multifasta2SNPFile.POLYM_TYPE_4_DELETION
+        else:
+            self._sPolymType = Multifasta2SNPFile.POLYM_TYPE_4_INSERTION
+        self.isTheIndelOpen4ThisLine = 1
+            
+    def _expandTheCurrentIndel(self, position, nucleotide):
+        self.sCurrentIndelAllele = self.sCurrentIndelAllele + nucleotide
+        self.dcurrentIndel['end'] = position
+        
+    def _closeTheCurrentIndel(self, lineName, nucleotide, position):
+        subSNPName = self._formatSubSNPName(lineName, self.dcurrentIndel['start'], self._sPolymType)
+        
+        dIndel4TheLine = {'name': subSNPName, 'lineName': lineName, 'start': self.dcurrentIndel['start'],'end' :self.dcurrentIndel['end'],
+                          'allele': self.sCurrentIndelAllele, 'type': self._sPolymType, 'length': self._iPolymLength}
+        
+        dIndel4TheLine['length'] = self.getAnIndelLength(dIndel4TheLine)
+        
+        self.lIndelsOfTheCurrentLine.append(dIndel4TheLine)
+        
+        self.dcurrentIndel.clear()
+        self.isTheIndelOpen4ThisLine = 0
+           
+        
+    def _mergeAllelesAndSubSNPsFromOverlappingIndels(self):
+        lIndelList = []
+        for dIndel in self.lIndelsOverAllLines:
+            lIndelList = self.clusteriseIndels(dIndel, self.lIndelsOverAllLines)
+        
+        for dIndel in lIndelList:
+            oldAllele = dIndel['allele']
+            start = dIndel['start']
+            stop = dIndel['end']
+            lineName = dIndel['lineName']
+            
+            LineBioSeq = self._wrapper._iLinesBioseqDB.fetch(lineName)
+            dIndel = self.updateAllele(oldAllele, start, stop, LineBioSeq, dIndel)
+            dSubSNPResult = self.createSubSNPFromAMissingPolym(dIndel, lineName)
+            if(not self.subSNPExistsInSubSNPList(dSubSNPResult, self._lSubSNPFileResults)):
+                self._lSubSNPFileResults.append(dSubSNPResult)
+
+    def updateAllele(self, oldAllele, start, stop, LineBioSeq, dIndel):
+        #TODO: creer le test        
+        newAllele = LineBioSeq.subseq(start, stop).sequence
+        if newAllele != oldAllele:
+            dIndel['allele'] = newAllele
+        self._dAlleleFileResults = self._completeAlleleSetWithCurrentAllele(self._dAlleleFileResults, newAllele)
+        return dIndel
+    
+
+    def getFlanksOfASubSNP(self, lineName, subsnpPosition, polymLength, flankLength):
+        bioSeqOfTheLine = self._wrapper._iLinesBioseqDB.fetch(lineName)
+        flank5Prime = bioSeqOfTheLine.get5PrimeFlank(subsnpPosition, flankLength)
+        flank3Prime = bioSeqOfTheLine.get3PrimeFlank(subsnpPosition, flankLength, polymLength)
+        
+        return flank5Prime, flank3Prime
+
+    def createSubSNPFromAMissingPolym(self, dIndel, lineName):
+        if(dIndel['type'] == Multifasta2SNPFile.POLYM_TYPE_4_INSERTION):
+            start = self.getUngappedPositionInRefSeq(dIndel['start']-1)
+        else:
+            start = self.getUngappedPositionInRefSeq(dIndel['start'])
+            
+        subSNPName = self._formatSubSNPName(dIndel['lineName'], start, dIndel['type'])
+            
+        iAlleleNumber = self._dAlleleFileResults[dIndel['allele']]
+        
+        iPolymLength = self.getAnIndelLength(dIndel)
+        
+        flank5Prime, flank3Prime = self.getFlanksOfASubSNP(lineName, dIndel['start'], iPolymLength, Multifasta2SNPFile.FLANK_LENGTH)
+
+        dSubSNPResult = {'subSNPName':subSNPName, 'position':start, 'lineName':self._dIndividualNumbers4SubSNPResults[lineName], 'allele':iAlleleNumber,
+                         'batchNumber': self._currentBatchNumber, 'confidenceValue':self._sPolymConfidenceValue, 'type':dIndel['type'], 
+                         'length': iPolymLength, '5flank':flank5Prime, '3flank':flank3Prime}
+        
+        return dSubSNPResult
+            
+    def clusteriseIndels(self, dIndel, lIndelsOverAllLines):
+        iIndice = 0
+        for dIndel in lIndelsOverAllLines:
+            iIndice2Compare = 0            
+            for dIndel2Compare in lIndelsOverAllLines:
+                dIndel, dIndel2Compare = self.mergeBoundsForTwoOverlappingIndels(dIndel, dIndel2Compare)
+                lIndelsOverAllLines = self.updateBoundsForAnIndelInAnIndelList(lIndelsOverAllLines, dIndel)
+                lIndelsOverAllLines = self.updateBoundsForAnIndelInAnIndelList(lIndelsOverAllLines, dIndel2Compare)
+                iIndice2Compare = iIndice2Compare + 1
+            iIndice = iIndice + 1
+        
+        return lIndelsOverAllLines
+    
+    def mergeBoundsForTwoOverlappingIndels(self, dIndel1, dIndel2):
+        if((dIndel2['start'] <= dIndel1['start']) and (dIndel2['end'] >= dIndel1['start']) or
+           (dIndel1['start'] <= dIndel2['start']) and (dIndel1['end'] >= dIndel2['start'])):
+            if(dIndel1['start'] <= dIndel2['start']):
+                iStart = dIndel1['start']
+            else:
+                iStart = dIndel2['start']
+            
+            if(dIndel1['end'] >= dIndel2['end']):
+                iEnd = dIndel1['end']
+            else:
+                iEnd = dIndel2['end']
+            
+            dIndel1['start'] = iStart
+            dIndel1['end'] = iEnd
+            dIndel2['start'] = iStart
+            dIndel2['end'] = iEnd            
+        
+        return dIndel1, dIndel2
+                    
+    def updateBoundsForAnIndelInAnIndelList(self, lIndelsList, dIndelWithNewBounds):
+        name = dIndelWithNewBounds['name']
+        dIndelInTheList, iIndice = self.findAnIndelInAListWithHisName(name, lIndelsList)
+        lIndelsList.remove(dIndelInTheList)
+        lIndelsList.insert(iIndice, dIndelWithNewBounds)
+        return lIndelsList
+        
+        
+    def findASubSNPInAListWithHisName(self, name, lSubSNPList):
+        dSubSNP2Find = {}
+        indice = 0
+        indice2Find = -1
+        for dSubSNP in lSubSNPList:            
+            if(dSubSNP['subSNPName'] == name):
+                dSubSNP2Find =  dSubSNP
+                indice2Find = indice
+            indice = indice + 1
+        
+        if dSubSNP2Find == {} or indice2Find == -1:
+            msg = "trying to find a SubSNP not existing: " + name
+            self._logFile.error(msg)
+            raise Exception ("trying to find a SubSNP not existing: " + name)
+        else:
+            return dSubSNP2Find, indice2Find
+        
+    def subSNPExistsInSubSNPList(self, dSubSNP2Find, lSubSNPList):
+        flag = 0
+        for dSubSNP in lSubSNPList:
+            if(dSubSNP2Find['subSNPName'] == dSubSNP['subSNPName']):
+                flag = 1
+        
+        if flag == 1:
+            return True
+        else:
+            return False
+        
+        
+    def findAnIndelInAListWithHisName(self, name, lIndelList):
+        dIndel2Find = {}
+        indice = 0
+        indice2Find = -1
+        for dIndel in lIndelList:            
+            if(dIndel['name'] == name):
+                dIndel2Find =  dIndel
+                indice2Find = indice
+            indice = indice + 1
+        
+        if dIndel2Find == {} or indice2Find == -1:
+            msg = "trying to find an indel not existing: " + name
+            self._logFile.error(msg)
+            raise Exception (msg)
+        else:
+            return dIndel2Find, indice2Find
+        
+    def _addMissingsAllelesAndSubSNPs(self):
+        for dIndel in self.lIndelsOverAllLines:
+                start = dIndel['start']
+                end = dIndel['end']
+                type = dIndel['type']
+                self.addMissingAllelesAndSubSNPsForOnePolym(start, end, type)
+        
+        for position in self.dSNPsPositions:
+            self.addMissingAllelesAndSubSNPsForOnePolym(position, position, "SNP")
+                 
+    def addMissingAllelesAndSubSNPsForOnePolym(self, start, end, polymType):
+        refSeqAllele = self._wrapper._iReferenceBioseq.subseq(start, end).sequence
+        BioSeqDb = self._wrapper.getLinesBioseqInstances()
+        lBioSeqDbAlleles = self.getAllelesOfASubSeq(BioSeqDb, start, end)
+        for subSequence in lBioSeqDbAlleles:
+            if(subSequence['allele'] == refSeqAllele):
+                lineName = subSequence['header']
+                dMissingPolym = {'lineName': lineName, 'start': start,'end' :end,
+                          'allele': subSequence['allele'], 'type':polymType}
+                self._dAlleleFileResults = self._completeAlleleSetWithCurrentAllele(self._dAlleleFileResults, subSequence['allele'])
+                dSubSNPResult = self.createSubSNPFromAMissingPolym(dMissingPolym, lineName)
+                if(not self.subSNPExistsInSubSNPList(dSubSNPResult, self._lSubSNPFileResults)):
+                    self._lSubSNPFileResults.append(dSubSNPResult) 
+                    
+    def addOnePolymorphicPosition(self, position):
+        if(not self.dSNPsPositions.has_key(position)):
+            self.dSNPsPositions[position] = 1
+            
+    def getUngappedPositionInRefSeq(self, position):
+        if(position ==1):
+            nbOfGaps = 0
+        else:
+            seqIn5Prime = self._wrapper._iReferenceBioseq.subseq(1, position-1).sequence
+            nbOfGaps = seqIn5Prime.count("-")  
+        
+        return position - nbOfGaps
+        
+    def getAllelesOfASubSeq(self, BioSeqDb, start, end):
+        lAlleles = []
+        for iBioSeq in BioSeqDb:
+            dAlleles = {}
+            dAlleles['header'] = iBioSeq.header
+            dAlleles['allele'] = iBioSeq.subseq(start, end).sequence
+            lAlleles.append(dAlleles)
+        
+        return lAlleles
+    
+    def getAnIndelLength(self, dIndel):
+        length = 0        
+        if(dIndel['type'] == Multifasta2SNPFile.POLYM_TYPE_4_DELETION):
+            length = dIndel['end'] - dIndel['start'] + 1
+        else:
+            length = len(dIndel['allele'])
+        
+        return length
+            
+    def createWrapperFromFile(self, inFileName):        
+        faF = open(inFileName, "r")
+        iBioSeqDB = self._extractSequencesFromInputFile(faF)
+        faF.close()
+
+        iBioSeqDB.upCase()
+        referenceBioseq = iBioSeqDB[0]
+        linesBioSeqDB = iBioSeqDB.extractPart(1, iBioSeqDB.getSize() - 1)
+        
+        try:
+            if(FileUtils.isEmpty(inFileName)):
+                msg = "The input file is empty!"
+                self._logFile.error(self._prefixeWithLineNumber (msg))
+                raise Exception (self._prefixeWithFileName (msg))
+            if(self.isHeaderInRefSeqList(referenceBioseq.header)):
+                msg = "This reference sequence already exists in one previous file!"
+                self._logFile.error(self._prefixeWithLineNumber (msg))
+                raise Exception (self._prefixeWithLineNumber (msg))
+        except Exception, e :
+            raise Exception ("Problem with one input file: \n" + str(e))
+        
+        self._lRefSequences.append(referenceBioseq)
+        
+        return  ReferenceBioseqAndLinesBioseqDBWrapper(referenceBioseq, linesBioSeqDB, self._logFile, inFileName)
+    
+    def isHeaderInRefSeqList(self, header):
+        isHeader = False
+        for item in self._lRefSequences:
+            if item.header == header:
+                isHeader = True  
+        return isHeader
+                
+    def completeBatchList(self):
+        dBatchResults = {'BatchNumber' : self._currentBatchNumber, 'BatchName' : self._batchName, 'GeneName' : self._geneName,'ContactNumber' : "1", 
+                         'ProtocolNumber' : "1", 'ThematicNumber' : "1", 'RefSeqName': self._wrapper._iReferenceBioseq.header}
+        
+        self._lBatchFileResults.append(dBatchResults)
+        
+        return self._lBatchFileResults
+       
+    def getLineAsAHeader(self, lineToBeCheck, lineNumber = 0):
+        """
+        header line begin with the tag(or token) '>' tag 
+                    ended with an carriage return
+                    contain The name of sequence must respect this alphabet [a-zA-Z0-9_-:]
+        """
+        obsHeader = lineToBeCheck
+        if obsHeader[0]!=">" :
+            msg = "tag '>' omitted before header"
+            self._logFile.error(self._prefixeWithLineNumber (msg))
+            raise Exception (self._prefixeWithLineNumber (msg))
+        else :
+            obsHeader = obsHeader[1:]
+        obsHeader = obsHeader.replace ("\n","")  
+        obsHeader = self._removeRepeatedBlanksInAStr(obsHeader)
+        obsHeader = self._replaceBlankByUnderScoreInAStr(obsHeader) 
+        if self.checkHeaderAlphabet(obsHeader) :
+            return obsHeader
+        self._logFile.error(self._prefixeWithLineNumber ("fatal error on header"))
+        raise Exception (self._prefixeWithLineNumber ("fatal error on header"))
+    
+    def getLineAsASeq(self, lineToBeCheck):
+        """
+        Sequence line 
+                    ended with an carriage return
+                    contain only character of the IUPAC alphabet
+        """
+        obsSeq = str.upper(lineToBeCheck)
+        obsSeq = obsSeq.replace ("\n","")
+        obsSeq = obsSeq.replace ("\r","")      
+        obsLine = obsSeq.replace("-","")
+        if not self.isIUPAC_bases(obsLine) :
+            msg = "the sequence contain a non nucleic character "
+            self._logFile.error(self._prefixeWithLineNumber (msg))
+            raise Exception (self._prefixeWithLineNumber (msg))
+        return obsSeq
+    
+    def checkHeaderAlphabet( self, strToCheck):
+        """
+        Check the string 
+        the string is not a header when founding a pattern not corresponding to the regexp
+        \W Matches any non-alphanumeric character; this is equivalent to the class [^a-zA-Z0-9_-:]. 
+        """
+        if strToCheck=="":
+            return False      
+        p = re.compile('[^a-zA-Z0-9_:\-]', re.IGNORECASE)  #p = re.compile('(\W|-|:)+', re.IGNORECASE)
+        errList=p.findall(strToCheck)
+        if len( errList ) > 0 :
+            return False
+        else:
+            return True
+        
+    ## Check the string is nucleotides sequence from the DNA_ALPHABET_WITH_N = ["A","T","G","C","N"] of IUPAC nomenclature.
+    #  @return True if sequence contain A, T, G, C or N False otherwise  
+    #  
+    def isDNA_bases( self, sequence):
+        if sequence == "" :
+            return False
+        
+        setFromString = set()
+        
+        for nt in sequence :
+            setFromString.add(nt)
+            
+        return  setFromString.issubset(DNA_ALPHABET_WITH_N_AND_DELS)
+    
+    ## Check if the string is nucleotides sequence from the IUPAC ALPHABET .
+    #  @return True if sequence contain IUPAC letters False otherwise  
+    #  
+    def isIUPAC_bases( self, sequence):
+        if sequence == "" :
+            return False
+        
+        setFromString = set()
+        
+        for nt in sequence :
+            setFromString.add(nt)
+            
+        return  setFromString.issubset(IUPAC)
+    
+    def _writeAllOutputFiles(self):
+        writer = Multifasta2SNPFileWriter()
+        writer.write(self)
+        
+    def _sortSubSNPResultByBatchPositionAndLineName(self, lSubSNPResults):
+        return sorted(lSubSNPResults, key=lambda SNPresults: (SNPresults['batchNumber'], SNPresults['position'], SNPresults['lineName']))    
+    
+    def _formatSubSNPName(self, currentLineHeader, position, polymType):
+        shortPolymType = polymType[:3]
+        return  self._batchName + "_" + shortPolymType + "_" + str(position) + "_" + currentLineHeader
+
+    def _isSNPDetected(self, referenceSequence, index, nt):
+        if((nt != referenceSequence[index]) and (nt.upper() != "N") and (referenceSequence[index].upper() != "N")):
+            return True
+        else:
+            return False
+    
+    def _extractSequencesFromInputFile(self, inFile):
+        # attention :  DNA_ALPHABET_WITH_N_AND_DELS = Set (['A','T','G','C','N']) no including "gap"
+        lInFileLines = inFile.readlines()
+        nbOfLines = len(lInFileLines) - 1
+        #premiere lecture 
+        self._iCurrentLineNumber = 0
+        isSameSeq = False
+        newSeq = ""
+        bioseqDB = BioseqDB ()
+        while self._iCurrentLineNumber < nbOfLines :
+            bioseq = Bioseq()
+            bioseq.header = self.getLineAsAHeader( lInFileLines[self._iCurrentLineNumber] )
+            isSameSeq = True
+            while isSameSeq and (self._iCurrentLineNumber < nbOfLines) :
+                self._iCurrentLineNumber +=1
+                if lInFileLines[self._iCurrentLineNumber][0] == ">" :
+                    isSameSeq = False
+                else :
+                    newSeq = newSeq + self.getLineAsASeq( lInFileLines[self._iCurrentLineNumber] )
+                    isSameSeq = True
+            bioseq.setSequence(newSeq)
+            newSeq = ""
+            bioseqDB.add(bioseq)
+        return bioseqDB
+    
+    def _removeRepeatedBlanksInAStr (self, StrToClean ):
+        resStr=StrToClean.expandtabs(2)
+        compResStr=resStr.replace ("  "," ")
+        while compResStr != resStr :
+            resStr=compResStr
+            compResStr=resStr.replace ("  "," ")
+        return resStr  
+    
+    def _replaceBlankByUnderScoreInAStr (self, StrToClean ):
+        resStr = StrToClean.replace (" ","_")  
+        return resStr
+          
+    def _prefixeWithLineNumber (self, strMsg):
+        resStr = "File: " + self._currentFileName + "\t"
+        resStr += "Line %i " % (self._iCurrentLineNumber+1 ) + strMsg
+        return resStr
+    
+    def _prefixeWithFileName (self, strMsg):
+        resStr = "File: " + self._currentFileName + "\n" + strMsg
+        return resStr
+
+    
+    def _completeAlleleSetWithCurrentAllele(self, dAlleleFileResults, dnaBase):
+        if dAlleleFileResults.has_key(dnaBase):
+            return dAlleleFileResults
+        else:
+            iAlleleNumber = len(dAlleleFileResults) + 1
+            dAlleleFileResults[dnaBase] = iAlleleNumber
+            return dAlleleFileResults
+        
+    def _completeIndividualListWithCurrentIndividual(self, lIndividualResults, lineName):
+        if lIndividualResults == []:
+            iIndividualNumber = 1
+        else:
+            iIndividualNumber = len(lIndividualResults) + 1 
+        
+        #TODO: transformer la liste de dictionnaire en liste d'objets
+        if not (self._checkIfALineExistInList(lIndividualResults, lineName)):
+            dIndividual2Add = {'individualNumber': iIndividualNumber, 'individualName': lineName, 'scientificName': self._taxon}
+            lIndividualResults.append(dIndividual2Add)
+        
+        return lIndividualResults
+    
+    def _completeBatchLineListWithCurrentIndividual(self, lBatchLineResults, lIndividualResults, lineName):
+        lineDict = self._getALineDictFromADictListWithALineName(lIndividualResults, lineName)
+
+        if len(lineDict) != 0:
+            if(lineDict.has_key('individualNumber')):
+                indivNumberOfTheLineDict = lineDict['individualNumber']
+            else:
+                msg = "Problem with the batchLine results construction: individual named " + lineName + " has no individual number!"
+                self._logFile.error(msg)
+                raise Exception (msg)
+        else:
+            msg = "Problem with the batchLine results construction: individual named " + lineName + " not in individual list!"
+            self._logFile.error(msg)
+            raise Exception (msg)
+            
+        dResults2Add = {'IndividualNumber': str(indivNumberOfTheLineDict), 'BatchNumber' : self._currentBatchNumber}
+        lBatchLineResults.append(dResults2Add)
+        return lBatchLineResults
+    
+    def _getALineDictFromADictListWithALineName(self, lDictList, lineName):
+        dictToReturn = {}
+        for myDict in lDictList:
+            if myDict['individualName'] == lineName:
+                dictToReturn = myDict
+        
+        return dictToReturn
+    
+    def _checkIfALineExistInList(self, lDictList, lineName):
+        for myDict in lDictList:
+            if myDict['individualName'] == lineName:
+                return True
+        return False
+    
+    def _getCurrentBatchResult(self):
+        return self._lBatchFileResults[self._currentBatchNumber-1]
+    
+
+        
+    
+class ReferenceBioseqAndLinesBioseqDBWrapper (object):
+         
+    def __init__ (self, iReferenceBioseq, iLinesBioSeqDB, logger, fileName):
+        self._iReferenceBioseq = iReferenceBioseq
+        self._iLinesBioseqDB = iLinesBioSeqDB
+        self._logger = logger
+        self._currentFileName = fileName
+        self._checkAllSeqs()
+
+    
+    def _checkAllSeqs(self):
+        self._iReferenceBioseq.checkEOF()
+        refSeqLen = self._iReferenceBioseq.getLength()
+        
+        for seq in self._iLinesBioseqDB.db:
+            seq.checkEOF()
+            if(not seq.getLength() == refSeqLen):
+                msg = "File: " + self._currentFileName + ", problem with the sequence " + seq.header + ": its length is different from the reference seq! All the sequences must have the same length.\n"
+                msg += "refseq length: " + str(refSeqLen) + "\n"
+                msg += "seq length: " + str(seq.getLength()) + "\n"
+                self._logger.error(msg)
+                raise Exception (msg)
+     
+    def getLinesBioseqInstances(self):
+        return self._iLinesBioseqDB.db
+    
+    def getReferenceSequence(self):
+        return self._iReferenceBioseq.sequence
+    
+class Multifasta2SNPFileWriter(object):
+
+    SUB_SNP_FILE_HEADER = ["SubSNPName","ConfidenceValue","Type","Position","5flank",
+                           "3flank","Length","BatchNumber","IndividualNumber","PrimerType","PrimerNumber","Forward_or_Reverse","AlleleNumber"]
+
+    ALLELE_FILE_HEADER = ["AlleleNumber","Value","Motif","NbCopy","Comment"]
+    
+    INDIVIDUAL_FILE_HEADER = ["IndividualNumber","IndividualName","Description","AberrAneuploide",
+                              "FractionLength","DeletionLineSynthesis","UrlEarImage","TypeLine","ChromNumber","ArmChrom","DeletionBin","ScientificName",
+                              "local_germplasm_name","submitter_code","local_institute","donor_institute","donor_acc_id"]
+    
+    SEQUENCE_CSV_FILE_HEADER = ["SequenceName","SeqType","BankName","BankVersion","ACNumber","Locus","ScientificName"]
+    
+    BATCH_TXT_FILE_HEADER = ["BatchNumber", "BatchName", "GeneName", "Description", "ContactNumber", "ProtocolNumber", "ThematicNumber", "RefSeqName", "AlignmentFileName", "SeqName"]
+    
+    BATCH_LINE_FILE_HEADER = ["IndividualNumber", "Pos5", "Pos3", "BatchNumber", "Sequence"]
+    
+    def __init__(self):
+        self._csvFieldSeparator = ";"
+        self._txtSubFieldSeparator = ": "
+        self._txtFieldSeparator = "\n"
+        self._primerType = "Sequence"
+        self._csvLineSeparator = "\n"
+        self._txtLineSeparator = "//\n"
+        
+    def write(self, iMultifasta2SNPFile):
+        self._writeSubSNPFile(iMultifasta2SNPFile._outSubSNPFileName, iMultifasta2SNPFile._lSubSNPFileResults)
+        self._writeAlleleFile(iMultifasta2SNPFile._outAlleleFileName, iMultifasta2SNPFile._dAlleleFileResults)
+        self._writeIndividualFile(iMultifasta2SNPFile._outIndividualFileName, iMultifasta2SNPFile._lIndividualFileResults)
+        self._writeSequenceFiles(iMultifasta2SNPFile._outSequenceFSAFileName, iMultifasta2SNPFile._outSequenceCSVFileName, iMultifasta2SNPFile._lRefSequences, iMultifasta2SNPFile._taxon)
+        self._writeBatchFile(iMultifasta2SNPFile._outBatchFileName, iMultifasta2SNPFile._lBatchFileResults)
+        self._writeBatchLineFile(iMultifasta2SNPFile._outBatchLineFileName, iMultifasta2SNPFile._lBatchLineFileResults)
+        
+    def sortAlleleResultByAlleleNumber(self, dAlleleFileResults):
+        return sorted(dAlleleFileResults.items(), key=lambda(k,v):(v,k))
+    
+    def _writeSubSNPFile(self, subSNPFileName, lSNP2Write):
+        outF = open(subSNPFileName, "w")
+        self._writeSNPFileHeader(outF)
+        for dSNP in lSNP2Write:
+            self._writeSNPFileLine(outF, dSNP)
+        outF.close()
+    
+    def _writeAlleleFile(self, alleleFileName, dAllele2Write):
+        outF = open(alleleFileName, "w")
+        self._writeAlleleFileHeader(outF)
+        lAlleleSortedResults = self.sortAlleleResultByAlleleNumber(dAllele2Write)
+        for tAllele in lAlleleSortedResults:
+            self._writeAlleleFileLine(outF, tAllele[0], tAllele[1])
+                    
+        outF.close()
+        
+    def _writeIndividualFile(self, individualFileName, lIndividual2Write):
+        sorted(lIndividual2Write, key=lambda Individual: (Individual['individualNumber']))
+        outF = open(individualFileName, "w")
+        self._writeIndividualFileHeader(outF)
+        
+        for dIndiv in lIndividual2Write:
+            self._writeIndividualFileLine(outF, dIndiv)
+                    
+        outF.close()
+        
+    def _writeSequenceFiles(self, sequenceFSAFileName, sequenceCSVFileName, lRefSequences, taxon):
+        outFSA = open(sequenceFSAFileName, "w")
+        outCSV = open(sequenceCSVFileName, "w")
+        self._writeSequenceCSVHeader(outCSV)
+       
+        for refSeq in lRefSequences:
+            refSeq.cleanGap()
+            self._writeSequenceFSAFile(outFSA, refSeq)
+            self._writeSequenceCSVLine(outCSV, refSeq, taxon)
+            
+        outFSA.close()
+        outCSV.close()
+    
+    def _writeSequenceFSAFile(self, outF, refSeq):        
+        outF.write( ">%s\n" % ( refSeq.header ) )
+        outF.write( "%s\n" % ( refSeq.sequence[0:refSeq.getLength()] ) )
+        
+        
+    def _writeBatchFile(self, batchFileName, lBatchResults):
+        outF = open(batchFileName, "w")
+        for dBatchResults in lBatchResults:   
+            for head in Multifasta2SNPFileWriter.BATCH_TXT_FILE_HEADER[:]:
+                if dBatchResults.has_key(head):
+                    outF.write(head + self._txtSubFieldSeparator + str(dBatchResults[head]) + self._txtFieldSeparator)
+                else:
+                    outF.write(head + self._txtSubFieldSeparator + self._txtFieldSeparator)
+                    
+            outF.write(self._txtLineSeparator)
+            
+        outF.close()
+        
+    def _writeBatchLineFile(self, batchLineFileName, lBatchLineResults):
+        outF = open(batchLineFileName, "w")
+        self._writeBatchLineFileHeader(outF)
+        for dResult in lBatchLineResults:
+            self._writeBatchLineFileLine(outF, dResult)
+        outF.close()
+        
+    def _writeSNPFileHeader(self, outF):
+        for head in Multifasta2SNPFileWriter.SUB_SNP_FILE_HEADER[:-1]:
+            outF.write(head + self._csvFieldSeparator)
+        outF.write(Multifasta2SNPFileWriter.SUB_SNP_FILE_HEADER[-1] + self._csvLineSeparator)
+ 
+    def _writeAlleleFileHeader(self, outF):
+        for head in Multifasta2SNPFileWriter.ALLELE_FILE_HEADER[:-1]:
+            outF.write(head + self._csvFieldSeparator)
+        outF.write(Multifasta2SNPFileWriter.ALLELE_FILE_HEADER[-1] + self._csvLineSeparator)
+        
+    def _writeIndividualFileHeader(self, outF):
+        for head in Multifasta2SNPFileWriter.INDIVIDUAL_FILE_HEADER[:-1]:
+            outF.write(head + self._csvFieldSeparator)
+        outF.write(Multifasta2SNPFileWriter.INDIVIDUAL_FILE_HEADER[-1] + self._csvLineSeparator)
+        
+    def _writeSequenceCSVHeader(self, outF):
+        for head in Multifasta2SNPFileWriter.SEQUENCE_CSV_FILE_HEADER[:-1]:
+            outF.write(head + self._csvFieldSeparator)
+        outF.write(Multifasta2SNPFileWriter.SEQUENCE_CSV_FILE_HEADER[-1] + self._csvLineSeparator)
+       
+    def _writeBatchLineFileHeader(self, outF):
+        for head in Multifasta2SNPFileWriter.BATCH_LINE_FILE_HEADER[:-1]:
+            outF.write(head + self._csvFieldSeparator)
+        outF.write(Multifasta2SNPFileWriter.BATCH_LINE_FILE_HEADER[-1] + self._csvLineSeparator)        
+               
+    def _writeSNPFileLine(self, outF, dSNP):
+        outF.write(dSNP['subSNPName'] + self._csvFieldSeparator)
+        outF.write(dSNP['confidenceValue'] + self._csvFieldSeparator + dSNP['type'] + self._csvFieldSeparator)
+        outF.write(str(dSNP['position']) + self._csvFieldSeparator + dSNP['5flank'] + self._csvFieldSeparator + dSNP['3flank'] + self._csvFieldSeparator)
+        outF.write(str(dSNP['length']) + self._csvFieldSeparator + str(dSNP['batchNumber']) + self._csvFieldSeparator)
+        outF.write(str(dSNP['lineName']) + self._csvFieldSeparator)
+        outF.write(self._primerType + self._csvFieldSeparator + self._csvFieldSeparator + self._csvFieldSeparator + str(dSNP['allele']) + self._csvLineSeparator)
+
+    def _writeAlleleFileLine(self, outF, sAllele2Write, iAlleleNumber):
+        outF.write(str(iAlleleNumber) + self._csvFieldSeparator)
+        outF.write(sAllele2Write + self._csvFieldSeparator + self._csvFieldSeparator + self._csvFieldSeparator + self._csvLineSeparator)
+    
+    def _writeIndividualFileLine(self, outF, dIndividual):
+        outF.write(str(dIndividual['individualNumber']) + self._csvFieldSeparator)
+        outF.write(dIndividual['individualName'] + self._csvFieldSeparator + self._csvFieldSeparator+ self._csvFieldSeparator+ self._csvFieldSeparator+ self._csvFieldSeparator+ self._csvFieldSeparator+ self._csvFieldSeparator+ self._csvFieldSeparator+ self._csvFieldSeparator+ self._csvFieldSeparator)
+        outF.write(dIndividual['scientificName'] + self._csvFieldSeparator + self._csvFieldSeparator + self._csvFieldSeparator+ self._csvFieldSeparator + self._csvFieldSeparator + self._csvLineSeparator)
+    
+    def _writeSequenceCSVLine(self, outF, refSeq, taxon):
+        outF.write(refSeq.header + self._csvFieldSeparator)
+        outF.write("Reference" + self._csvFieldSeparator + self._csvFieldSeparator + self._csvFieldSeparator + self._csvFieldSeparator + self._csvFieldSeparator)
+        outF.write(taxon + self._csvLineSeparator)        
+    
+    def _writeBatchLineFileLine(self, outF, dResult):
+        outF.write(str(dResult['IndividualNumber']) + self._csvFieldSeparator + self._csvFieldSeparator + self._csvFieldSeparator)
+        outF.write(str(dResult['BatchNumber']) + self._csvFieldSeparator + self._csvLineSeparator)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/MummerParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,93 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from commons.core.parsing.MapperParser import MapperParser
+from SMART.Java.Python.structure.Mapping import Mapping
+from SMART.Java.Python.structure.SubMapping import SubMapping
+
+class MummerParser(MapperParser):
+    """A class that parses the output of Mummer format"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(MummerParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(MummerParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["mummer"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        pass
+
+
+    def parseLine(self, line):
+        mapping = Mapping()
+
+        subMapping = SubMapping()
+
+        # handle header
+        m = re.search(r"^>\s+(\S+)\s+Reverse\s+Len\s+=\s+(\d+)$", line)
+        if m != None:
+            subMapping.queryInterval.setName(m.group(1))
+            subMapping.queryInterval.setSize(int(m.group(2)))
+            subMapping.queryInterval.setDirection(-1)
+        else:
+            m = re.search(r"^>\s+(\S+)\s+Len\s+=\s+(\d+)$", line)
+            if m != None:
+                subMapping.queryInterval.setName(m.group(1))
+                subMapping.queryInterval.setSize(int(m.group(2)))
+                subMapping.queryInterval.setDirection(1)
+            else :
+                sys.exit("Header line %d '%s' is strange in Mummer file" % (self.currentLineNb, line))
+
+        for line in self.handle:
+            self.currentLineNb += 1
+            break
+        line = line.strip()
+
+        # handle line
+        m = re.search(r"^(\w+)\s+(\d+)\s+(\d+)\s+(\d+)$", line)
+        if m != None:
+            subMapping.targetInterval.setName(m.group(1))
+            subMapping.targetInterval.setStart(int(m.group(2)))
+            subMapping.queryInterval.setStart(int(m.group(3)))
+            subMapping.targetInterval.setSize(int(m.group(4)))
+        else:
+            sys.exit("Line %d '%s' is strange in Mummer file" % (self.currentLineNb, line))
+
+        mapping.addSubMapping(subMapping)
+
+        return mapping
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/NCListParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,125 @@
+#
+# Copyright INRA-URGI 2009-2012
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from commons.core.parsing.TranscriptListParser import TranscriptListParser
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.ncList.NCList import NCList
+from SMART.Java.Python.ncList.NCListCursor import NCListCursor
+from SMART.Java.Python.ncList.NCListFilePickle import NCListFileUnpickle
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+try:
+   import cPickle as pickle
+except:
+   import pickle
+
+
+class NCListParser(TranscriptListParser):
+
+
+	def __init__(self, fileName, verbosity = 0):
+		self.title = None
+		TranscriptListParser.__init__(self, fileName, verbosity)
+		self.parse()
+
+	def getFileFormats():
+		return ["nclist"]
+	getFileFormats = staticmethod(getFileFormats)
+
+	def skipFirstLines(self):
+		return
+
+	def parse(self):
+		handle                       = open(self.fileName)
+		self.sortedFileNames         = pickle.load(handle)
+		self.nbElements	             = pickle.load(handle)
+		self.nbElementsPerChromosome = pickle.load(handle)
+		self.ncLists                 = pickle.load(handle)
+		for ncList in self.ncLists.values():
+			ncList._reopenFiles()
+		handle.close()
+		self.chromosomes     = sorted(self.nbElementsPerChromosome.keys())
+		self.fileNames       = dict([chromosome, self.ncLists[chromosome]._transcriptFileName] for chromosome in self.chromosomes)
+		self.currentReader   = None
+		self.currentChrIndex = 0
+
+	def getSortedFileNames(self):
+		return self._sortedFileNames
+
+	def getNbElements(self):
+		return self._nbElements
+
+	def getNbElementsPerChromosome(self):
+		return self._nbElementsPerChromosome
+
+	def getNCLists(self):
+		return self._ncLists
+	
+	def reset(self):
+		self.currentChrIndex = 0
+		self.currentReader   = None
+
+	def gotoAddress(self, address):
+		self.currentReader.gotoAddress(address)
+
+	def getCurrentAddress(self):
+		return self.getCurrentTranscriptAddress()
+
+	def getCurrentTranscriptAddress(self):
+		if self.currentReader == None:
+			return 0
+		return self.currentReader.getCurrentTranscriptAddress()
+
+	def getNextTranscript(self):
+		if self.currentReader == None:
+			self.currentReader = NCListFileUnpickle(self.fileNames[self.chromosomes[0]])
+		transcript = self.currentReader.getNextTranscript()
+		if transcript == False:
+			self.currentChrIndex += 1
+			if self.currentChrIndex >= len(self.chromosomes):
+				return None
+			self.currentReader = NCListFileUnpickle(self.fileNames[self.chromosomes[self.currentChrIndex]])
+			transcript = self.currentReader.getNextTranscript()
+		return transcript
+
+	def getInfos(self):
+		self.size = 0
+		self.reset()
+		progress = UnlimitedProgress(100000, "Getting information on %s." % (self.fileName), self.verbosity-9)
+		transcript = self.getNextTranscript()
+		for transcript in self.getIterator():
+			self.size += transcript.getSize()
+			progress.inc()
+		progress.done()
+		self.reset()
+
+	def getNbTranscripts(self):
+		return self.nbElements
Binary file smart_toolShed/commons/core/parsing/NCListParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/NucmerParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,88 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from SMART.Java.Python.structure.SubMapping import SubMapping
+from SMART.Java.Python.structure.Mapping import Mapping
+from SMART.Java.Python.structure.Interval import Interval
+from commons.core.parsing.MapperParser import MapperParser
+
+
+class NucmerParser(MapperParser):
+    """A class that parses the output of Nucmer"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(NucmerParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(NucmerParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["nucmer"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        pass
+
+
+    def parseLine(self, line):
+        if not line:
+            return None
+        if line[0] == ">":
+            self.currentChromosome = line[1:].split()[0]
+            return None
+        splittedLine = line.strip().split()
+        if len(splittedLine) != 8:
+            raise Exception("Line %d '%s' does not have a NucMer format" % (self.currentLineNb, line))
+
+        subMapping = SubMapping()
+
+        subMapping.targetInterval.setChromosome(self.currentChromosome)
+        subMapping.targetInterval.setName(self.currentChromosome)
+        subMapping.targetInterval.setStart(min(int(splittedLine[0]), int(splittedLine[1])))
+        subMapping.targetInterval.setEnd(max(int(splittedLine[0]), int(splittedLine[1])))
+        subMapping.targetInterval.setDirection(splittedLine[6])
+
+        subMapping.queryInterval.setChromosome(splittedLine[7])
+        subMapping.queryInterval.setName(splittedLine[7])
+        subMapping.queryInterval.setStart(1)
+        subMapping.queryInterval.setEnd(int(splittedLine[3]))
+        subMapping.queryInterval.setDirection("+")
+
+        mapping = Mapping()
+        mapping.addSubMapping(subMapping)
+        mapping.setDirection(splittedLine[6])
+        mapping.setIdentity(float(splittedLine[5]))
+        mapping.setSize(int(splittedLine[3]))
+
+        return mapping
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/PalsToAlign.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,66 @@
+import time
+import os
+
+class PalsToAlign(object):
+    """
+    Convert the output from PALS (GFF2 format) into the 'align' format.
+    """
+    def __init__(self,inputPalsFileName="" , outputAlignFileName="", removeSameSequences=False):
+        self._removeSameSequences = removeSameSequences
+        self._inputPalsFileName = inputPalsFileName
+        self._outputAlignFileName = outputAlignFileName
+
+    def run (self):
+        file = open(self._inputPalsFileName, "r")
+        tmpFileName = "PalsToAlign%s"%str(os.getpid() ) 
+        tmpFile = open(tmpFileName, "w")
+        
+        for line in file.readlines():
+    
+            if line == "":
+                break
+    
+            data = line.split("\t")
+    
+            qryName = data[0]
+            source = data[1]
+            feature = data[2]
+            qryStart = data[3]
+            qryEnd = data[4]
+            score = data[5]
+            strand = data[6]
+            frame = data[7]
+            attributes = data[8][:-1].split()
+    
+            sbjName = attributes[1]
+            sbjStart = attributes[2]
+            sbjEnd = attributes[3][:-1]
+            percId = (1 - float(attributes[-1])) * 100.0
+    
+            if strand != "+":
+                tmp = sbjStart
+                sbjStart = sbjEnd
+                sbjEnd = tmp
+    
+            if self._removeSameSequences \
+            and "chunk" in qryName and "chunk" in sbjName \
+            and min(int(qryStart), int(qryEnd)) == 1 \
+            and min(int(sbjStart), int(sbjEnd)) == 1 \
+            and percId == 100.0:
+                line = self.inFile.readline()
+                continue
+    
+            if qryStart < qryEnd:
+                alignLine = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (qryName, qryStart, qryEnd, sbjName, sbjStart, sbjEnd, "0.0", score, percId)
+            else:
+                alignLine = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (qryName, qryEnd, qryStart, sbjName, sbjEnd, sbjStart, "0.0", score, percId)
+    
+            tmpFile.write(alignLine)
+
+        file.close()
+        tmpFile.close()
+    
+        os.system("sort -k 1,1 -k 4,4 -k 2,2n -k 3,3n -k 5,5n -k 6,6n -k 8,8n %s > %s" % (tmpFileName, self._outputAlignFileName))
+        os.remove(tmpFileName)
+
+        
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/ParserChooser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,128 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+from commons.core.parsing.TranscriptListParser import TranscriptListParser
+from commons.core.parsing.MapperParser import MapperParser
+from commons.core.parsing.SequenceListParser import SequenceListParser
+from commons.core.parsing.BedParser import BedParser
+from commons.core.parsing.GffParser import GffParser
+from commons.core.parsing.MapperParser import MapperParser
+from commons.core.parsing.CoordsParser import CoordsParser
+from commons.core.parsing.SeqmapParser import SeqmapParser
+from commons.core.parsing.SoapParser import SoapParser
+from commons.core.parsing.Soap2Parser import Soap2Parser
+from commons.core.parsing.BlastParser import BlastParser
+from commons.core.parsing.PslParser import PslParser
+from commons.core.parsing.RmapParser import RmapParser
+from commons.core.parsing.ShrimpParser import ShrimpParser
+from commons.core.parsing.AxtParser import AxtParser
+from commons.core.parsing.ExoParser import ExoParser
+from commons.core.parsing.MaqParser import MaqParser
+from commons.core.parsing.SamParser import SamParser
+from commons.core.parsing.BamParser import BamParser
+from commons.core.parsing.BowtieParser import BowtieParser
+from commons.core.parsing.ElandParser import ElandParser
+from commons.core.parsing.GtfParser import GtfParser
+from commons.core.parsing.FastaParser import FastaParser
+from commons.core.parsing.FastqParser import FastqParser
+from commons.core.parsing.MapParser import MapParser
+from commons.core.parsing.NCListParser import NCListParser
+from commons.core.parsing.PklParser import PklParser
+
+#Attention!! Do not delete the imports!! They are used to know the type of file format!!!
+
+class ParserChooser(object):
+    """
+    A class that finds the correct parser
+    @ivar format: the format
+    @type format: string
+    @ivar type: transcript / mapping / sequence parser
+    @type type: string
+    @ivar parser: the parser
+    @type parser: object
+    @ivar verbosity: verbosity
+    @type verbosity: int        
+    """
+
+    def __init__(self, verbosity = 0):
+        """
+        Constructor
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        self.type = None
+        self.parserClass = None
+        self.verbosity = verbosity
+    
+
+    def findFormat(self, format, type = None):
+        """
+        Find the correct parser
+        @ivar format: the format
+        @type format: string
+        @ivar type: transcript / mapping / sequence parser (None is all)
+        @type type: string
+        @return: a parser
+        """
+        classes = {}
+        if (type == "transcript"):
+            classes = {TranscriptListParser: "transcript"}
+        elif (type == "mapping"):
+            classes = {MapperParser: "mapping"}
+        elif (type == "sequence"):
+            classes = {SequenceListParser: "sequence"}
+        elif (type == None):
+            classes = {TranscriptListParser: "transcript", MapperParser: "mapping", SequenceListParser: "sequence"}
+        else:
+            raise Exception("Do not understand format type '%s'" % (type))
+
+        for classType in classes:
+            for parserClass in classType.__subclasses__():
+                if format in parserClass.getFileFormats():
+                    self.parserClass = parserClass
+                    self.type = classes[classType]
+                    return
+        raise Exception("Cannot get parser for format '%s'" % (format))
+
+
+    def getParser(self, fileName):
+        """
+        Get the parser previously found
+        @return: the parser
+        """
+        return self.parserClass(fileName, self.verbosity)
+
+
+    def getType(self):
+        """
+        Get the type of parser previously found
+        @return: the type of parser
+        """
+        return self.type
Binary file smart_toolShed/commons/core/parsing/ParserChooser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/PathNum2Id.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,47 @@
+class PathNum2Id( object ):
+
+    def __init__(self):
+        self._inFileName = None
+        self._outFileName = None
+
+    def setInFileName(self, fileName):  
+        self._inFileName = fileName  
+        
+    def setOutFileName(self, fileName):  
+        self._outFileName = fileName        
+        
+    def run( self ):
+        """
+        Adapt the path IDs as the input file is the concatenation of several 'path' files.
+        """
+        self._inFile = open( self._inFileName, "r" )
+        self._outFile = open( self._outFileName, "w" )
+        lines = self._inFile.readlines()
+        dID2count = {}
+        count = 1
+        for line in lines:
+            if line == "":
+                break
+            strippedLine = line.strip('\n')
+            data = strippedLine.split("\t")
+            path = data[0]
+            qryName = data[1]
+            qryStart = int(data[2])
+            qryEnd = int(data[3])
+            sbjName = data[4]
+            sbjStart = int(data[5])
+            sbjEnd = int(data[6])
+            BLAST_Eval = data[7]
+            BLAST_score = data[8]
+            percId = data[9]
+            key_id = path + "-" + qryName + "-" + sbjName
+            if key_id not in dID2count.keys():
+                newPath = count
+                count += 1
+                dID2count[ key_id ] = newPath
+            else:
+                newPath = dID2count[ key_id ]
+            cmd = "%i\t%s\t%i\t%i\t%s\t%i\t%i\t%s\t%s\t%s\n" % ( newPath, qryName, qryStart, qryEnd, sbjName, sbjStart, sbjEnd, BLAST_Eval, BLAST_score, percId )
+            self._outFile.write( cmd )
+        self._inFile.close()
+        self._outFile.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/PilerTAToGrouperMap.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,85 @@
+import time
+import os
+
+class PilerTAToGrouperMap(object):
+    """
+   Convert the output file from Piler into grouper format.
+    """
+    def __init__(self, inputGffFileName, inputPYRFileName, inputMOTIFFileName, outputFileName):
+        self._inputGffFileName = inputGffFileName
+        self._inputPYRFileName = inputPYRFileName
+        self._inputMOTIFFileName = inputMOTIFFileName
+        self._outFileName = outputFileName
+
+    def run (self):
+        inFileGff = open( self._inputGffFileName, "r" )  
+        inFilePyr = open( self._inputPYRFileName, "r" )   
+        outFile = open(self._outFileName,"w") 
+        
+        #step 0 : get pile Info and write out an info file
+        for pyrLine in inFilePyr.readlines():#-tan_pyr.gff
+            if pyrLine == "":
+                break
+            pileIndex = ""
+            pyrIndex = pyrLine.split('\t')[8].replace ('PyramidIndex', 'Pyramid')
+            for gffLine in inFileGff.readlines(): #-tan.gff
+                if gffLine == "":
+                    break
+                if pyrIndex in gffLine:
+                    pileIndex = gffLine.split(';')[1].strip()
+                    break    
+            line = "%s\t%s" % (pileIndex, pyrIndex)
+            outFile.write(line)
+           
+        inFilePyr.close()
+        inFileGff.close()
+        outFile.close()    
+                
+        #Step 1 : Add pile info to motif file and write out two files one with grouperID and one in map format
+        outFileMotifGrpFileName = self._inputMOTIFFileName + ".grp"
+        outFileMotifGrpMapFileName = self._inputMOTIFFileName + ".grp.map"
+        
+        inFileInfo = open(self._outFileName,"r") 
+        inFileMotif = open(self._inputMOTIFFileName, "r" )
+        outFileMotifGrp = open(outFileMotifGrpFileName, "w" )
+        outFileMotifGrpMap = open(outFileMotifGrpMapFileName, "w" )
+         
+        inFileInfos = inFileInfo.readlines()
+        lineInfoIndex = 0
+        
+        for countMotif,lineMotif in enumerate(inFileMotif.readlines()):
+            if lineMotif == "":
+                    break
+            dataMotif = lineMotif.split(';')
+            motif, pyrNameMotif  = dataMotif[:2]
+            pyrNameMotif = pyrNameMotif.strip()
+            pileNameMotif = ""
+            
+            while lineInfoIndex < len(inFileInfos):
+                lineInfo = inFileInfos[lineInfoIndex]
+                if lineInfo == "":
+                    break
+                if pyrNameMotif in lineInfo:          
+                    pileNameMotif = lineInfo.split('\t')[0]
+                    break
+                lineInfoIndex +=1
+                
+            #translate to Grouper IdFormat
+            pyrID = pyrNameMotif.split(' ')[1]
+            pileID = pileNameMotif.split(' ')[1]
+            dataMotif = motif.split ('\t')
+            chrm = dataMotif [0]
+            start,end = dataMotif [3:5]
+            countMotif += 1
+            memberID = "MbS%sGr" % (countMotif) + pyrID + "Cl" + pileID
+            
+            stringMotif = "%s\t%s\t%s\t%s\n" % ( memberID, motif, pileNameMotif, pyrNameMotif)
+            outFileMotifGrp.write( stringMotif)
+    
+            stringGrpMap = "%s\t%s\t%s\t%s\n" % ( memberID, chrm, start, end )
+            outFileMotifGrpMap.write( stringGrpMap )    
+          
+        inFileMotif.close()
+        inFileInfo.close()
+        outFileMotifGrp.close()
+        outFileMotifGrpMap.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/PklParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,112 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+try:
+	 import cPickle as pickle
+except:
+	 import pickle
+from SMART.Java.Python.structure.Interval import Interval
+from commons.core.parsing.TranscriptListParser import TranscriptListParser
+from SMART.Java.Python.structure.Transcript import Transcript
+
+
+class PklParser(TranscriptListParser):
+	"""A class that parses the intern PKL file and create a transcript list"""
+		
+	def __init__(self, fileName, verbosity = 1):
+		self.title = None
+		super(PklParser, self).__init__(fileName, verbosity)
+		self.handle		   = open(fileName, "rb")
+		self.verbosity	   = verbosity
+		self.initAddress   = 0
+		self.address	   = self.initAddress
+		self.over		   = False
+		self.chromosome	= None
+
+	def __del__(self):
+		super(PklParser, self).__del__()
+
+	def getFileFormats():
+		return ["pkl"]
+	getFileFormats = staticmethod(getFileFormats)
+
+
+	def skipFirstLines(self):
+		return
+
+
+	def reset(self):
+		self.handle.seek(0)
+		self.initAddress = 0
+
+
+	def setChromosome(self, chromosome):
+		self.chromosome = chromosome
+	
+
+	def gotoAddress(self, address):
+		self.handle.seek(address)
+		self.address = address
+
+
+	def getNextTranscript(self):
+		self.address = self.handle.tell()
+		try:
+			transcript = pickle.load(self.handle)
+			if self.chromosome != None and transcript.getChromosome() != self.chromosome:
+				self.over = True
+				return False
+			return transcript
+		except EOFError:
+			self.over = True
+			return False
+
+
+	def getIterator(self):
+		self.gotoAddress(self.initAddress)
+		while True:
+			transcript = self.getNextTranscript()
+			if not transcript:
+				self.over = True
+				return
+			yield transcript
+
+
+	def setInitAddress(self, address):
+		self.initAddress = address
+
+
+	def getCurrentTranscriptAddress(self):
+		return self.address
+
+
+	def isOver(self):
+		return self.over
Binary file smart_toolShed/commons/core/parsing/PklParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/PslParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,155 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from commons.core.parsing.MapperParser import MapperParser
+from SMART.Java.Python.structure.Mapping import Mapping
+from SMART.Java.Python.structure.SubMapping import SubMapping
+from SMART.Java.Python.structure.Interval import Interval
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+
+class PslParser(MapperParser):
+    """A class that parses the output of PSL format (of SSAHA and BLAT)"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(PslParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(PslParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["psl"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def getInfos(self):
+        self.chromosomes = set()
+        self.nbMappings  = 0
+        self.size        = 0
+        self.reset()
+        progress = UnlimitedProgress(100000, "Getting info on PSL file, # mappings read:", self.verbosity)
+        for line in self.handle:
+            progress.inc()
+            line = line.strip()
+            if line == "":
+                continue
+            parts      = line.split("\t")
+            chromosome = parts[13]
+            self.chromosomes.add(chromosome)
+            self.nbMappings += 1
+            self.size += len(parts[0])
+        self.reset()
+        progress.done()
+
+
+    def skipFirstLines(self):
+        while "------" not in self.handle.readline():
+            self.currentLineNb += 1
+            pass
+
+    def _computeStarts(self,seqSize,blockSize,start,targetStrand):
+        if targetStrand == "+":
+            pass
+        else:
+            start = seqSize-blockSize-start
+        return start
+            
+
+
+    def parseLine(self, line):
+        m = re.search(r"^\s*(psl:\s+)?(\d+)\s+(\d+)\s+(\d+)\s+\d+\s+\d+\s+(\d+)\s+\d+\s+(\d+)\s+([+-]{1,2})\s+(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s*$", line)
+        if m == None:
+            raise Exception("\nLine %d '%s' does not have a PSL format" % (self.currentLineNb, line))
+
+        mapping = Mapping()
+
+        queryStrand = m.group(7)[0]
+
+        if len(m.group(7)) == 1:
+            targetStrand = "+"
+        else:
+            targetStrand = m.group(7)[1]
+
+
+        for i in range(0, int(m.group(16))):
+            size        = int(m.group(17).split(",")[i])
+            queryStart  = int(m.group(18).split(",")[i])
+            targetStart = int(m.group(19).split(",")[i])
+            querySize   = int(m.group(9))
+            targetSize  = int(m.group(13))
+            
+            subMapping = SubMapping()
+            subMapping.setSize(size)
+            subMapping.setDirection(m.group(7)[0])
+
+            queryInterval  = Interval()
+            targetInterval = Interval()
+
+            queryInterval.setName(m.group(8))
+            queryStart = self._computeStarts(querySize,size,queryStart,targetStrand)
+            queryInterval.setStart(queryStart + 1)
+            queryInterval.setEnd(queryStart + size)
+            queryInterval.setDirection(queryStrand)
+
+            targetInterval.setChromosome(m.group(12))
+            targetStart = self._computeStarts(targetSize,size,targetStart,targetStrand)
+            targetInterval.setStart(targetStart + 1)
+            targetInterval.setEnd(targetStart + size)
+            targetInterval.setDirection(targetStrand)
+
+            subMapping.setQueryInterval(queryInterval)
+            subMapping.setTargetInterval(targetInterval)
+            mapping.addSubMapping(subMapping)
+
+        mapping.setSize(int(m.group(2)) + int(m.group(3)) + int(m.group(4)))
+        mapping.setNbMismatches(int(m.group(3)) + int(m.group(4)))
+        mapping.setNbGaps(int(m.group(5)))
+        mapping.setDirection(queryStrand)
+
+        queryInterval  = Interval()
+        targetInterval = Interval()
+
+        queryInterval.setName(m.group(8))
+        queryInterval.setStart(min(int(m.group(10)), int(m.group(11))))
+        queryInterval.setEnd(  max(int(m.group(10)), int(m.group(11))))
+        queryInterval.setDirection(queryStrand)
+
+        targetInterval.setChromosome(m.group(12))
+        targetInterval.setStart(min(int(m.group(14))+1, int(m.group(15))))
+        targetInterval.setEnd(  max(int(m.group(14))+1, int(m.group(15))))
+        targetInterval.setDirection(targetStrand)
+
+        mapping.setQueryInterval(queryInterval)
+        mapping.setTargetInterval(targetInterval)
+
+        return mapping
+
Binary file smart_toolShed/commons/core/parsing/PslParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/README_MultiFasta2SNPFile	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,66 @@
+*** DESCRIPTION: ***
+This program takes as input a multifasta file (with sequences already aligned together formated in fasta in the same file), considers the first sequence as the reference sequence, infers polymorphims and generates output files in GnpSNP exchange format.
+
+
+*** INSTALLATION: ***
+Dependancies: 
+- First you need Python installed in your system.
+- Repet libraries are also required.
+
+*** OPTIONS OF THE LAUNCHER: ***
+
+    -h: this help
+
+Mandatory options:    
+         -b: Name of the batch of submitted sequences
+         -g: Name of the gene
+         -t: Scientific name of the taxon concerned
+
+Exclusive options (use either the first or the second)
+         -f: Name of the multifasta input file (for one input file)
+         -d: Name of the directory containing multifasta input file(s) (for several input files)
+
+
+
+*** COMMAND LINE EXAMPLE (for package use): ***
+- First, you need to set up the environment variable PYTHONPATH (lo link with the dependancies).
+
+- Then for one input file (here our example), run:
+
+python multifastaParserLauncher.py -b Batch_test -g GeneX -t "Arabidopsis thaliana" -f Exemple_multifasta_input.fasta
+
+
+- For several input files, create a directory in the root of the uncompressed package and put your input files in it. Then use this type of command line:
+
+python multifastaParserLauncher.py -b Batch_test -g GeneX -t "Arabidopsis thaliana" -d <Name_of_the_directory>
+
+Each one of the input files will generate a directory with his set of output files.
+
+
+*** SIMPLE USE (for package use): ***
+Two executables (one for windows, the other for linux/unix) are in the package.
+They show the command lines to use in order to set up environment variables and then to run the parser on our sample input file (Example_multifasta_input.fasta).
+You can edit the executable and custom the command line to use it with your own input file.
+
+
+*** BACKLOG (next version) ***
+When the launcher is called for several input files (with -d option), the parser should be able to generate only one set of files describing all the batches (one batch per input file).
+So below are listed the tasks of the backlog dedicated to this feature:
+
+- in Multifasta2SNPFile class: 
+  # CONSTRUCTOR: Modify the constructor to add a "several batches" mode called without BatchName and GeneName
+  # RUNNING METHOD: Add the run_several_batches(directory) method that will browse the input files and iterate over them to run each of them successively (see runSeveralInputFile() method of the launcher)
+  => 2 days
+  
+  # BATCH MANAGEMENT: Modify createBatchDict() to create one batch per file in the dictionary and add a class variable to point toward the current batch (ex: self._iCurrentLineNumber)
+  # BATCH-LINE MANAGEMENT: Modify _completeBatchLineListWithCurrentIndividual method to allow several batch and link lines to batches (for the moment hard coded batch no1)
+  # SUBSNP MANAGEMENT: check that all elements (dSUbSNP) added in SubSNP list (lSubSNPFileResults) is linked to the current batch (for the moment hard coded batch no1)
+    Impacted methods: manageSNPs(), createSubSNPFromAMissingPolym(), addMissingAllelesAndSubSNPsForOnePolym(), mergeAllelesAndSubSNPsFromOverlappingIndels()
+  => + 2 days
+  
+- in Multifasta2SNPFileWriter class:
+  # Modify all the method _write<X>File (ex: _writeSubSNPFile) to write in append mode and externalize all open and close file 
+  # Create one method to open all the output files and call it in Multifasta2SNPFile run_several_batches method
+  # Create one method to close all the output files and call it in Multifasta2SNPFile run_several_batches method
+  
+  => + 2 days
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/RmapParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,76 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from commons.core.parsing.MapperParser import MapperParser
+from SMART.Java.Python.structure.Mapping import Mapping
+
+class RmapParser(MapperParser):
+    """A class that parses the output of Rmap format"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(RmapParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(RmapParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["rmap"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        pass
+
+
+    def parseLine(self, line):
+        m = re.search(r"^\s*(\S+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\d+)\s+([+-])\s*$", line)
+        if m == None:
+            sys.exit("\nLine %d '%s' does not have a RMAP format" % (self.currentLineNb, line))
+
+        mapping = Mapping()
+
+        mapping.targetInterval.setChromosome(m.group(1))
+        mapping.targetInterval.setStart(min(int(m.group(2)), int(m.group(3))))
+        mapping.targetInterval.setEnd(max(int(m.group(2)), int(m.group(3))))
+
+        mapping.queryInterval.setName(m.group(4))
+        mapping.queryInterval.setStart(1)
+        mapping.queryInterval.setSize(mapping.targetInterval.getEnd() - mapping.targetInterval.getStart())
+
+        mapping.setSize(mapping.targetInterval.getEnd() - mapping.targetInterval.getStart())
+        mapping.setNbMismatches(int(m.group(5)))
+        mapping.setDirection(m.group(6))
+
+        return mapping
+
+
Binary file smart_toolShed/commons/core/parsing/RmapParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/SamParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,234 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from commons.core.parsing.MapperParser import MapperParser
+from SMART.Java.Python.structure.Mapping import Mapping
+from SMART.Java.Python.structure.SubMapping import SubMapping
+from SMART.Java.Python.structure.Interval import Interval
+
+class SamParser(MapperParser):
+    """A class that parses SAM format (as given by BWA)"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(SamParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(SamParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["sam"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        pass
+
+
+    def getInfos(self):
+        self.chromosomes = set()
+        self.nbMappings  = 0
+        self.size        = 0
+        self.reset()
+        if self.verbosity >= 10:
+            print "Getting information on SAM file"
+        self.reset()
+        for line in self.handle:
+            line = line.strip()
+            if line == "" or line[0] == "@":
+                continue
+            parts      = line.split("\t")
+            chromosome = parts[2]
+            if chromosome != "*":
+                self.chromosomes.add(chromosome)
+            self.nbMappings += 1
+            self.size += len(parts[8])
+            if self.verbosity >= 10 and self.nbMappings % 100000 == 0:
+                sys.stdout.write("    %d mappings read\r" % (self.nbMappings))
+                sys.stdout.flush()
+        self.reset()
+        if self.verbosity >= 10:
+            print "    %d mappings read" % (self.nbMappings)
+            print "Done."
+
+
+    def parseLine(self, line):
+
+        line = line.strip()
+        if line[0] == "@":
+            return
+
+        fields = line.split("\t")
+        if len(fields) < 11:
+            raise Exception("Line %d '%s' does not look like a SAM line (number of fields is %d instead of 11)" % (self.currentLineNb, line, len(fields)))
+
+        name = fields[0]
+        flag = int(fields[1])
+
+        if (flag & 0x4) == 0x4:
+            return None
+
+        direction       = 1 if (flag & 0x10) == 0x0 else -1
+        chromosome      = fields[2]
+        genomeStart     = int(fields[3])
+        quality         = fields[4]
+        cigar           = fields[5]
+        mate            = fields[6]
+        mateGenomeStart = fields[7]
+        gapSize         = fields[8]
+        sequence        = fields[9]
+        quality         = fields[10]
+        tags            = fields[11:]
+
+        if mateGenomeStart != "*":
+            mateGenomeStart = int(mateGenomeStart)
+
+        mapping       = Mapping()
+        nbOccurrences = 1
+        nbMismatches  = 0
+        nbMatches     = 0
+        nbGaps        = 0
+        subMapping    = None
+        queryOffset   = 0
+        targetOffset  = 0
+        currentNumber = 0
+        readStart     = None
+
+        for tag in tags:
+            key = tag[:2]
+            if key == "X0":
+                nbOccurrences = int(tag[5:])
+            elif key == "X1":
+                nbOccurrences += int(tag[5:])
+            elif key == "XM":
+                nbMismatches = int(tag[5:])
+        mapping.setTagValue("nbOccurrences", nbOccurrences)
+        mapping.setTagValue("quality", int(fields[4]))
+
+        for char in cigar:
+            m = re.match(r"[0-9]", char)
+            if m != None:
+                currentNumber = currentNumber * 10 + (ord(char) - ord("0"))
+                continue
+            # match
+            m = re.match(r"[M]", char)
+            if m != None:
+                if readStart == None:
+                    readStart = queryOffset
+                if subMapping == None:
+                    subMapping = SubMapping()
+                    subMapping.setSize(currentNumber)
+                    subMapping.setDirection(direction)
+                    subMapping.queryInterval.setName(name)
+                    subMapping.queryInterval.setStart(queryOffset)
+                    subMapping.queryInterval.setDirection(direction)
+                    subMapping.targetInterval.setChromosome(chromosome)
+                    subMapping.targetInterval.setStart(genomeStart + targetOffset)
+                    subMapping.targetInterval.setDirection(1)
+                nbMatches    += currentNumber
+                targetOffset += currentNumber
+                queryOffset  += currentNumber
+                currentNumber = 0
+                continue
+            # insertion on the read
+            m = re.match(r"[I]", char)
+            if m != None:
+                nbGaps       += 1
+                queryOffset  += currentNumber
+                currentNumber = 0
+                continue
+            # insertion on the genome
+            m = re.match(r"[D]", char)
+            if m != None:
+                if subMapping != None:
+                    subMapping.queryInterval.setEnd(queryOffset - 1)
+                    subMapping.targetInterval.setEnd(genomeStart + targetOffset - 1)
+                    mapping.addSubMapping(subMapping)
+                subMapping    = None
+                nbGaps       += 1
+                targetOffset += currentNumber
+                currentNumber = 0
+                continue
+            # intron
+            m = re.match(r"[N]", char)
+            if m != None:
+                if subMapping != None:
+                    subMapping.queryInterval.setEnd(queryOffset - 1)
+                    subMapping.targetInterval.setEnd(genomeStart + targetOffset - 1)
+                    mapping.addSubMapping(subMapping)
+                subMapping    = None
+                targetOffset += currentNumber
+                currentNumber = 0
+                continue
+            # soft clipping (substitution)
+            m = re.match(r"[S]", char)
+            if m != None:
+                nbMismatches += currentNumber
+                targetOffset += currentNumber
+                queryOffset  += currentNumber
+                currentNumber = 0
+                continue
+            # hard clipping
+            m = re.match(r"[H]", char)
+            if m != None:
+                targetOffset += currentNumber
+                queryOffset  += currentNumber
+                currentNumber = 0
+                continue
+            # padding
+            m = re.match(r"[P]", char)
+            if m != None:
+                continue
+            raise Exception("Do not understand paramer '%s' in line %s" % (char, line))
+
+        if subMapping != None:
+            subMapping.queryInterval.setEnd(queryOffset - 1)
+            subMapping.targetInterval.setEnd(genomeStart + targetOffset - 1)
+            mapping.addSubMapping(subMapping)
+
+        mapping.queryInterval.setStart(readStart)
+        mapping.queryInterval.setEnd(queryOffset - 1)
+        mapping.targetInterval.setEnd(genomeStart + targetOffset - 1)
+        mapping.setNbMismatches(nbMismatches)
+        mapping.setNbGaps(nbGaps)
+
+        mapping.queryInterval.setName(name)
+        mapping.queryInterval.setDirection(direction)
+        mapping.targetInterval.setChromosome(chromosome)
+        mapping.targetInterval.setStart(genomeStart)
+        mapping.targetInterval.setDirection(direction)
+        mapping.setSize(len(sequence))
+        mapping.setDirection(direction)
+
+        return mapping
+
+
Binary file smart_toolShed/commons/core/parsing/SamParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/SeqmapParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,81 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from commons.core.parsing.MapperParser import MapperParser
+from SMART.Java.Python.structure.Mapping import Mapping
+
+
+class SeqmapParser(MapperParser):
+    """A class that parses the output of SeqMap"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(SeqmapParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(SeqmapParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["seqmap"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        self.startingPoint = self.handle.tell()
+        self.currentLineNb += 1
+        if "trans_id" not in self.handle.readline():
+            self.currentLineNb -= 1
+            self.handle.seek(self.startingPoint)
+        self.startingPoint = self.handle.tell()
+
+
+    def parseLine(self, line):
+        m = re.search(r"^\s*(\S+)\t+(\d+)\t+(\w+)\t+([^\t]+)\t+(\w+)\t+(\d+)\t+([+-])\s*$", line)
+        if m == None:
+            sys.exit("\nLine %d '%s' does not have a SeqMap format" % (self.currentLineNb, line))
+
+        mapping = Mapping()
+
+        mapping.targetInterval.setChromosome(m.group(1))
+        mapping.targetInterval.setStart(int(m.group(2)))
+        mapping.targetInterval.setSize(len(m.group(3)))
+
+        mapping.queryInterval.setName(m.group(4))
+        mapping.queryInterval.setStart(1)
+        mapping.queryInterval.setSize(len(m.group(3)))
+
+        mapping.setSize(len(m.group(3)))
+        mapping.setNbMismatches(int(m.group(6)))
+        mapping.setDirection(m.group(7))
+
+        return mapping
+
Binary file smart_toolShed/commons/core/parsing/SeqmapParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/SequenceListParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,228 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+from SMART.Java.Python.structure.SequenceList import SequenceList
+from SMART.Java.Python.misc.Progress import Progress
+
+class SequenceListParser(object):
+	"""
+	A virtual class that reads a list of sequences
+	@ivar verbosity:	   verbosity
+	@type verbosity:	   int
+	@ivar fileName:		   name of the file to parse
+	@type fileName:		   string
+	@ivar handle:		   file to parse
+	@type handle:		   file
+	@ivar nbSequences:	   number of sequences in the file
+	@type nbSequences:	   int
+	@ivar nbReadSequences: number of sequences read
+	@type nbReadSequences: int
+	@ivar currentLine:	   line currently read
+	@type currentLine:	   string
+	@ivar size:			   total number of nucleotides in the sequences
+	@type size:			   int
+	@ivar sizes:		   number of nucleotides per sequences
+	@type sizes:		   dict of string to int
+	"""
+
+	def __init__(self, fileName, verbosity = 0):
+		"""
+		Constructor
+		@param verbosity:  verbosity
+		@type	verbosity: int
+		@param fileName:   name of the file to parse
+		@type	fileName:  string
+		"""
+		self.verbosity = verbosity
+		self.fileName = fileName
+		self.nbSequences = None
+		self.nbReadSequences = 0
+		self.currentLine = None
+		self.size = None
+		self.sizes = None
+		try:
+			self.handle = open(self.fileName, "rb")
+		except IOError:
+			raise Exception("Error! Sequence file '%s' does not exist! Exiting..." % (self.fileName))
+
+
+	def __del__(self):
+		"""
+		Destructor
+		"""
+		if not self.handle.closed:
+			self.handle.close()
+		
+
+	def close(self):
+		"""
+		Close file handle
+		"""
+		self.handle.close()
+		
+
+	def reset(self):
+		"""
+		Prepare the file to be read again from start
+		"""
+		self.handle.seek(0)
+		self.currentLine = None
+		self.nbReadSequences = 0
+				
+		
+	def getFileFormats(self):
+		pass
+	getFileFormats = staticmethod(getFileFormats)
+
+
+	def parse(self):
+		"""
+		Parse the whole file in one shot
+		@return: a list of sequence
+		"""
+		sequenceList = SequenceList()
+		progress = Progress(self.getNbSequences(), "Reading %s" % (self.fileName), self.verbosity)
+		for sequence in self.getIterator():
+			sequenceList.addSequence(sequence)
+			progress.inc()
+		progress.done()
+		return sequenceList
+
+
+	def getIterator(self):
+		"""
+		Iterate on the file, sequence by sequence
+		@return: an iterator to sequences
+		"""
+		self.reset()
+		sequence = self.parseOne()
+		while sequence != None:
+			self.nbReadSequences += 1
+			yield sequence
+			sequence = self.parseOne()
+
+
+	def getInfos(self):
+		"""
+		Get some generic information about the sequences
+		"""
+		self.nbSequences = 0
+		self.size = 0
+		self.reset()
+		if self.verbosity >= 10:
+			print "Getting information on %s." % (self.fileName)
+		for sequence in self.getIterator():
+			self.nbSequences += 1
+			self.size += sequence.getSize()
+			if self.verbosity >= 10 and self.nbSequences % 100000 == 0:
+				sys.stdout.write("	%d sequences read\r" % (self.nbSequences))
+				sys.stdout.flush()
+		self.reset()
+		if self.verbosity >= 10:
+			print "	%d sequences read" % (self.nbSequences)
+			print "Done."
+
+	
+	def getNbSequences(self):
+		"""
+		Get the number of sequences in the file
+		@return: the number of sequences
+		"""
+		if self.nbSequences != None:
+			return self.nbSequences
+		self.getInfos()
+		return self.nbSequences
+
+
+	def getNbItems(self):
+		"""
+		Get the number of sequences in the file
+		@return: the number of sequences
+		"""
+		return self.getNbSequences()
+
+
+	def getSize(self):
+		"""
+		Get the size of all the sequences
+		@return: the size
+		"""
+		if self.size != None:
+			return self.size
+		self.getInfos()
+		return self.size
+	
+
+	def getRegions(self):
+		"""
+		Get the names of the sequences
+		@return: the names
+		"""
+		if self.sizes != None:
+			return self.sizes.keys()
+
+		self.sizes = {}
+		self.reset()
+		if self.verbosity >= 10:
+			print "Getting information on %s." % (self.fileName)
+		self.nbSequences = 0
+		for sequence in self.getIterator():
+			self.sizes[sequence.name] = sequence.getSize()
+			self.nbSequences += 1
+			if self.verbosity >= 10 and self.nbSequences % 100000 == 0:
+				sys.stdout.write("	%d sequences read\r" % (self.nbSequences))
+				sys.stdout.flush()
+		self.reset()
+		if self.verbosity >= 10:
+			print "	%d sequences read" % (self.nbSequences)
+			print "Done."
+		return self.sizes.keys()
+			
+			
+	def getSizeOfRegion(self, region):
+		"""
+		Get the size of a sequence
+		@param region: the name of the sequence
+		@type	region: string
+		@return: the size of the sequence
+		"""
+		if self.sizes != None:
+			if region not in self.sizes:
+				raise Exception("Region %s is not found" % region)
+			return self.sizes[region]
+
+		self.getRegions()
+		if region not in self.sizes:
+			raise Exception("Region %s is not found" % region)
+			
+	def __eq__(self, o):
+		if o == None:
+			return False
+		return self.fileName == o.fileName and self.nbSequences == o.nbSequences
Binary file smart_toolShed/commons/core/parsing/SequenceListParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/ShrimpParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,107 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from SMART.Java.Python.structure.Mapping import Mapping
+from commons.core.parsing.MapperParser import MapperParser
+
+
+class ShrimpParser(MapperParser):
+    """A class that parses the output of Shrimp"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(ShrimpParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(ShrimpParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["shrimp"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        self.handle.readline()
+        self.currentLineNb += 1
+
+
+    def parseLine(self, line):
+        m = re.search(r"^\s*>([^\t]+)\t+(\S+)\s+([+-])\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s*$", line)
+        if m == None:
+            sys.exit("\nLine %d '%s' does not have a Shrimp format" % (self.currentLineNb, line))
+
+        mapping = Mapping()
+
+        mapping.queryInterval.setName(m.group(1))
+        mapping.queryInterval.setStart(min(int(m.group(6)), int(m.group(7))))
+        mapping.queryInterval.setEnd(max(int(m.group(6)), int(m.group(7))))
+
+        mapping.targetInterval.setChromosome(m.group(2))
+        mapping.targetInterval.setStart(min(int(m.group(4)), int(m.group(5))))
+        mapping.targetInterval.setEnd(max(int(m.group(4)), int(m.group(5))))
+
+        mapping.setSize(int(m.group(8)))
+        mapping.setDirection(m.group(3))
+
+        editString = m.group(10)
+        nbMismatches = 0
+        nbGaps = 0
+        while editString != "":
+            m = re.search(r"^(\d+)(\D.*)$", editString)
+            if m != None:
+                editString = m.group(2)
+            else:
+                m = re.search(r"^(\d+)$", editString)
+                if m != None:
+                    editString = ""
+                else:
+                    m = re.search(r"^([A-Z])(.*)$", editString)
+                    if m != None:
+                        nbMismatches += 1
+                        editString = m.group(2)
+                    else:
+                        m = re.search(r"^\((\w+)\)(.*)$", editString)
+                        if m != None:
+                            nbGaps += len(m.group(1))
+                            editString = m.group(2)
+                        else:
+                            m = re.search(r"^-(.*)$", editString)
+                            if m != None:
+                                nbGaps += 1
+                                editString = m.group(1)
+                            else:
+                                sys.exit("Cannot understand edit string %s from line %s" % (editString, line))
+
+        mapping.setNbMismatches(nbMismatches)
+        mapping.setNbGaps(nbGaps)
+
+        return mapping
Binary file smart_toolShed/commons/core/parsing/ShrimpParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/Soap2Parser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,148 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from SMART.Java.Python.structure.Mapping import Mapping
+from SMART.Java.Python.structure.SubMapping import SubMapping
+from commons.core.parsing.MapperParser import MapperParser
+
+
+def mappingToSubMapping(mapping):
+    subMapping = SubMapping()
+    subMapping.targetInterval.copy(mapping.targetInterval)
+    subMapping.queryInterval.copy(mapping.queryInterval)
+    subMapping.setDirection(mapping.getDirection())
+    subMapping.size = mapping.size
+    subMapping.tags = mapping.tags
+    return subMapping
+
+
+
+class Soap2Parser(MapperParser):
+    """A class that parses the output of SOAP2"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(Soap2Parser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(Soap2Parser, self).__del__()
+
+
+    def getFileFormats():
+        return ["soap2"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        pass
+
+
+    def getIterator(self):
+        self.reset()
+        currentName = None
+        currentMappings = []
+        for line in self.handle:
+            mapping = self.parseLine(line)
+            name = mapping.queryInterval.name
+            if name == currentName:
+                if mapping.getTagValue("end") == "a":
+                    currentMappings.append(mapping)
+                else:
+                    otherEndMapping = currentMappings.pop(0)
+
+                    newMapping = Mapping()
+                    subMappingA = mappingToSubMapping(otherEndMapping)
+                    subMappingB = mappingToSubMapping(mapping)
+                    subMappingB.queryInterval.setDirection(subMappingA.queryInterval.getDirection())
+
+                    newMapping.addSubMapping(subMappingA)
+                    newMapping.addSubMapping(subMappingB)
+
+                    newMapping.tags = otherEndMapping.tags
+                    newMapping.setSize(otherEndMapping.size + mapping.size)
+                    newMapping.setNbMismatches(otherEndMapping.getTagValue("nbMismatches") + mapping.getTagValue("nbMismatches"))
+                    print otherEndMapping.getTagValue("nbMismatches")
+                    print mapping.getTagValue("nbMismatches")
+                    print newMapping.getTagValue("nbMismatches")
+                    sys.exit()
+                    newMapping.setTagValue("qualityString", otherEndMapping.getTagValue("qualityString") + mapping.getTagValue("qualityString"))
+                    newMapping.setTagValue("occurrence", "%d" % (newMapping.getTagValue("nbOccurrences") - len(currentMappings)))
+                    newMapping.setTagValue("ID", "%s-%s" % (name, newMapping.getTagValue("occurrence")))
+                    del newMapping.tags["end"]
+                    yield newMapping
+            else:
+                currentName = mapping.queryInterval.name
+                for currentMapping in currentMappings:
+                    yield currentMapping
+                currentMappings = [mapping]
+            self.currentLineNb += 1
+                
+                
+    def parseLine(self, line):
+        m = re.search(r"^\s*(\S+)\s+(\w+)\s+(\S+)\s+(\d+)\s+([ab])\s+(\d+)\s+([+-])\s+(\w+)\s+(\d+)\s+(\d+)\s+", line)
+        if m == None:
+            sys.exit("\nLine %d '%s' does not have a SOAP2 format" % (self.currentLineNb, line))
+
+        name          = m.group(1)
+        read          = m.group(2)
+        qualityString = m.group(3)
+        nbOccurrences = int(m.group(4))
+        end           = m.group(5)
+        size          = int(m.group(6))
+        direction     = m.group(7)
+        chromosome    = m.group(8)
+        genomeStart   = int(m.group(9))
+        nbMismatches  = int(m.group(10))
+
+        mapping = Mapping()
+        if name.endswith("/1") or name.endswith("/2"):
+            name = name[:-2]
+
+        mapping.queryInterval.name = name
+        mapping.queryInterval.setDirection(direction)
+        mapping.queryInterval.setStart(1)
+        mapping.queryInterval.setEnd(size)
+
+        mapping.targetInterval.setChromosome(chromosome)
+        mapping.targetInterval.setStart(genomeStart)
+        mapping.targetInterval.setSize(size)
+
+        mapping.setDirection(direction)
+        mapping.setSize(size)
+
+        mapping.setNbMismatches(nbMismatches)
+        mapping.setNbGaps(0)
+        mapping.setTagValue("qualityString", qualityString)
+        mapping.setTagValue("nbOccurrences", nbOccurrences)
+        mapping.setTagValue("end", end)
+
+        return mapping
+
Binary file smart_toolShed/commons/core/parsing/Soap2Parser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/SoapParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,75 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+from SMART.Java.Python.structure.Mapping import Mapping
+from commons.core.parsing.MapperParser import MapperParser
+
+
+class SoapParser(MapperParser):
+    """A class that parses the output of SOAP"""
+
+    def __init__(self, fileName, verbosity = 0):
+        super(SoapParser, self).__init__(fileName, verbosity)
+
+
+    def __del__(self):
+        super(SoapParser, self).__del__()
+
+
+    def getFileFormats():
+        return ["soap"]
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def skipFirstLines(self):
+        pass
+
+
+    def parseLine(self, line):
+        m = re.search(r"^\s*(\S+)\s+(\w+)\s+(\w+)\s+(\d+)\s+(a)\s+(\d+)\s+([+-])\s+(\w+)\s+(\d+)\s+(\d+)", line)
+        if m == None:
+            sys.exit("\nLine %d '%s' does not have a SOAP format" % (self.currentLineNb, line))
+
+        mapping = Mapping()
+
+        mapping.queryInterval.setName(m.group(1))
+        mapping.queryInterval.setStart(1)
+        mapping.queryInterval.setSize(len(m.group(2)))
+
+        mapping.targetInterval.setChromosome(m.group(8))
+        mapping.targetInterval.setStart(int(m.group(9)))
+        mapping.targetInterval.setSize(len(m.group(2)))
+
+        mapping.setDirection(m.group(7))
+        mapping.setSize(len(m.group(2)))
+        mapping.setNbMismatches(int(m.group(10)))
+
+        return mapping
Binary file smart_toolShed/commons/core/parsing/SoapParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/SsrParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,170 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+import sys
+
+## this class can parse a Ssr results output file. SSR.pl is developped by S.Cartinhour. (5/2000)
+#
+class SsrParser(object):
+
+
+    def __init__(self, BES_name='', BES_redundancy='', SSR_nbNucleotides='', SSR_Motif='', SSR_Motif_number='', SSR_start='', SSR_end='', BES_size=''):
+        self._BesName = BES_name
+        self._BesRedundancy = BES_redundancy
+        self._SsrNbNucleotides = SSR_nbNucleotides
+        self._SsrMotif = SSR_Motif
+        self._SsrMotifNumber = SSR_Motif_number
+        self._SsrStart = SSR_start
+        self._SsrEnd = SSR_end
+        self._BesSize = BES_size
+        
+    def __eq__(self, o):
+        return self._BesName == o._BesName and self._BesRedundancy == o._BesRedundancy and self._SsrNbNucleotides == o._SsrNbNucleotides and self._SsrMotif == o._SsrMotif and self._SsrMotifNumber == o._SsrMotifNumber and self._SsrStart == o._SsrStart and self._SsrEnd == o._SsrEnd and self._BesSize == o._BesSize
+        
+    def setBesName(self, BES_Name):
+        self._BesName = BES_Name
+        
+    def setBesRedundancy(self, BES_redundancy):
+        self._BesRedundancy = BES_redundancy
+        
+    def setSsrNbNucleotides(self, SSR_nbNucleotides):
+        self._SsrNbNucleotides = SSR_nbNucleotides
+        
+    def setSsrMotif(self, SSR_Motif):
+        self._SsrMotif = SSR_Motif
+        
+    def setSsrMotifNumber(self, SSR_Motif_number):
+        self._SsrMotifNumber = SSR_Motif_number
+        
+    def setSsrStart(self, SSR_start):
+        self._SsrStart = SSR_start
+        
+    def setSsrEnd(self, SSR_end):
+        self._SsrEnd = SSR_end
+        
+    def setBesSize(self, BES_size):
+        self._BesSize = BES_size
+        
+    def getBesName(self):
+        return self._BesName
+        
+    def getBesRedundancy(self):
+        return self._BesRedundancy
+        
+    def getSsrNbNucleotides(self):
+        return self._SsrNbNucleotides
+        
+    def getSsrMotif(self):
+        return self._SsrMotif
+        
+    def getSsrMotifNumber(self):
+        return self._SsrMotifNumber
+        
+    def getSsrStart(self):
+        return self._SsrStart
+        
+    def getSsrEnd(self):
+        return self._SsrEnd
+        
+    def getBesSize(self):
+        return self._BesSize
+    
+    def setAttributes(self, lResults, iCurrentLineNumber):
+        error = False
+        
+        if lResults[0] != '':
+            self.setBesName(lResults[0])
+        else:
+            sys.stderr.write("WARNING: The field BES Name is empty in SSR results file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[1] != '':
+            self.setBesRedundancy(lResults[1])
+        else:
+            sys.stderr.write("WARNING: The field BES Redundancy is empty in SSR results file in line %s\n" % iCurrentLineNumber)
+            error = True
+        
+        if lResults[2] != '':
+            self.setSsrNbNucleotides(lResults[2])
+        else:
+            sys.stderr.write("WARNING: The field SSR Number Nucleotides is empty in SSR results file in line %s\n" % iCurrentLineNumber)
+            error = True
+    
+        if lResults[3] != '':
+            self.setSsrMotif(lResults[3])
+        else:
+            sys.stderr.write("WARNING: The field SSR Motif is empty in SSR results file in line %s\n" % iCurrentLineNumber)
+            error = True
+    
+        if lResults[4] != '':
+            self.setSsrMotifNumber(lResults[4])
+        else:
+            sys.stderr.write("WARNING: The field SSR Motif Number is empty in SSR results file in line %s\n" % iCurrentLineNumber)
+            error = True
+    
+        if lResults[5] != '':
+            self.setSsrStart(lResults[5])
+        else:
+            sys.stderr.write("WARNING: The field SSR Start is empty in SSR results file in line %s\n" % iCurrentLineNumber)
+            error = True
+    
+        if lResults[6] != '':
+            self.setSsrEnd(lResults[6])
+        else:
+            sys.stderr.write("WARNING: The field SSR End is empty in SSR results file in line %s\n" % iCurrentLineNumber)
+            error = True
+    
+        if lResults[7] != '':
+            self.setBesSize(lResults[7])
+        else:
+            sys.stderr.write("WARNING: The field BES Size is empty in SSR results file in line %s\n" % iCurrentLineNumber)
+            error = True
+            
+        if error == True:
+            self._setAllToNull()
+            
+    def setAttributesFromString(self, ssrLine, iCurrentLineNumber ="", fieldSeparator ="\t"):
+        ssrLine = ssrLine.rstrip()
+        lSsrLineItem = ssrLine.split(fieldSeparator)
+        if len(lSsrLineItem) < 8:
+            sys.stderr.write("WARNING: The line %s is not a valid SSR Result line\n" % iCurrentLineNumber)
+        else:
+            self.setAttributes(lSsrLineItem, iCurrentLineNumber)
+            
+    def _setAllToNull(self):
+        self._BesName = ''
+        self._BesRedundancy = ''
+        self._SsrNbNucleotides = ''
+        self._SsrMotif = ''
+        self._SsrMotifNumber = ''
+        self._SsrStart = ''
+        self._SsrEnd = ''
+        self._BesSize = ''
+    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/TranscriptListParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,182 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+from SMART.Java.Python.structure.TranscriptList import TranscriptList
+from SMART.Java.Python.misc.Progress import Progress
+from SMART.Java.Python.misc.UnlimitedProgress import UnlimitedProgress
+
+class TranscriptListParser(object):
+    """A (quite generic) class that reads a list of transcripts"""
+
+    def __init__(self, fileName, verbosity = 0):
+        self.verbosity         = verbosity
+        self.fileName          = fileName
+        self.nbTranscripts     = None
+        self.size              = None
+        self.chromosomes       = None
+        self.currentTranscript = None
+        self.currentLineNb     = 0
+        self.previousTranscriptAddress = None
+        try:
+            self.handle = open(self.fileName)
+        except IOError:
+            raise Exception("Error! Transcript file '%s' does not exist! Exiting..." % (self.fileName))
+        self.skipFirstLines()
+
+
+    def __del__(self):
+        self.close()
+        
+
+    def getFileFormats():
+        pass
+    getFileFormats = staticmethod(getFileFormats)
+
+
+    def close(self):
+        if self.handle != None and not self.handle.close:
+            self.handle.close()
+        self.handle = None
+
+
+    def reset(self):
+        self.handle.seek(0)
+        self.skipFirstLines()
+        self.currentTranscript = None
+        self.currentLineNb     = 0
+        self.currentTranscriptAddress  = self.handle.tell()
+        self.currentAddress            = self.handle.tell()
+
+
+    def gotoAddress(self, address):
+        self.reset()
+        self.handle.seek(address)
+        self.currentTranscriptAddress = address
+        self.currentAddress           = address
+                
+        
+    def parse(self):
+        transcriptList = TranscriptList()
+        progress = Progress(self.getNbTranscripts(), "Reading %s" % (self.fileName), self.verbosity)
+        for line in self.handle:
+            self.currentLineNb += 1
+            transcript = self.parseLine(line)
+            transcriptList.addTranscript(transcript)
+            progress.inc()
+        progress.done()
+        return transcriptList
+
+
+    def getIterator(self):
+        self.reset()
+        transcript = self.getNextTranscript()
+        while transcript != None:
+            yield transcript
+            transcript = self.getNextTranscript()
+
+
+    def getCurrentAddress(self):
+        return self.currentAddress
+
+
+    def getCurrentTranscriptAddress(self):
+        return self.currentTranscriptAddress
+
+
+    def getNextTranscript(self):
+        self.currentAddress = self.handle.tell()
+        line = self.handle.readline()
+        while line != "":
+            line = line.strip()
+            self.currentLineNb += 1
+            transcript = self.parseLine(line)
+            if transcript != None:
+                return transcript
+            self.currentAddress = self.handle.tell()
+            line = self.handle.readline()
+        transcript = self.currentTranscript
+        self.currentTranscriptAddress = self.previousTranscriptAddress
+        self.currentTranscript = None
+        return transcript
+
+
+    def getInfos(self):
+        self.chromosomes = set()
+        self.nbTranscripts = 0
+        self.size = 0
+        self.reset()
+        progress = UnlimitedProgress(100000, "Getting information on %s." % (self.fileName), self.verbosity-9)
+        transcript = self.getNextTranscript()
+        for transcript in self.getIterator():
+            self.chromosomes.add(transcript.getChromosome())
+            self.nbTranscripts += 1
+            self.size += transcript.getSize()
+            progress.inc()
+        progress.done()
+        self.reset()
+
+    
+    def getNbTranscripts(self):
+        if self.nbTranscripts != None:
+            return self.nbTranscripts
+        self.getInfos()
+        return self.nbTranscripts
+
+
+    def getNbItems(self):
+        return self.getNbTranscripts()
+
+
+    def getChromosomes(self):
+        if self.chromosomes != None:
+            return self.chromosomes
+        self.getInfos()
+        return self.chromosomes
+    
+    
+    def getSize(self):
+        if self.size != None:
+            return self.size
+        self.getInfos()
+        return self.size
+    
+    
+    def getNbNucleotides(self):
+        return self.getSize()
+
+
+    def setDefaultTagValue(self, name, value):
+        for transcript in self.getIterator():
+            transcript.setTag(name, value)
+            
+    def __eq__(self, o):
+        if o == None:
+            return False
+        return self.fileName == o.fileName and self.nbTranscripts == o.nbTranscripts and self.size == o.size and self.chromosomes == o.chromosomes
Binary file smart_toolShed/commons/core/parsing/TranscriptListParser.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/VarscanFile.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,145 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.parsing.VarscanHit import VarscanHit
+from commons.core.parsing.VarscanHit_WithTag import VarscanHit_WithTag
+from commons.core.parsing.VarscanHit_v2_2_8 import VarscanHit_v2_2_8
+from commons.core.checker.CheckerException import CheckerException
+from commons.core.parsing.VarscanHit_v2_2_8_WithTag import VarscanHit_v2_2_8_WithTag
+
+class VarscanFile(object):
+
+    def __init__(self, varscanFileName = ""):
+        self._varscanFileName = varscanFileName
+        self._varscanFieldSeparator = "\t"
+        self._lVarscanHits = []
+        self._typeOfVarscanFile = ""
+        
+    def __eq__(self, o):
+        return self._varscanFieldSeparator == o._varscanFieldSeparator and self._lVarscanHits == o._lVarscanHits and self._varscanFileName == o._varscanFileName
+             
+    def setVarscanHitsList(self, lVarscanHits):
+        self._lVarscanHits = lVarscanHits
+    
+    def setHeaderVarcanFile(self, headerVarcanFile):
+        self._headerVarcanFile = headerVarcanFile
+        
+    def setTypeOfVarscanFile(self, type):
+        if type == "Varscan_2_2" or type == "Varscan_2_2_WithTag" or type == "Varscan_2_2_8" or type == "Varscan_2_2_8_WithTag":
+            self._typeOfVarscanFile = type
+        else:
+            self._typeOfVarscanFile = ""
+        
+    def getVarscanHitsList(self):
+        return self._lVarscanHits
+    
+    def getHeaderVarcanFile(self):
+        return self._headerVarcanFile
+    
+    def getListOfVarscanHits(self):
+        return self._lVarscanHits
+    
+    def getTypeOfVarscanFile(self):
+        return self._typeOfVarscanFile
+        
+    def parse(self):
+        varscanFile = open(self._varscanFileName, "r")
+        currentLineNumber = 0
+        line = varscanFile.readline()
+        if "Chrom\tPosition" in line:
+            self.setHeaderVarcanFile(line)
+            line = varscanFile.readline()
+        while line != "":
+            if not "Chrom\tPosition" in line:
+                currentLineNumber += 1
+                line = line.strip()
+                lResults = line.split(self._varscanFieldSeparator)
+                if len(lResults) == 12:
+                    currentVarscanLine = self.createVarscanHit(line, currentLineNumber)
+                    self._typeOfVarscanFile = "Varscan_2_2"
+                elif len(lResults) == 13:
+                    currentVarscanLine = self.createVarscanHitWithTag(line, currentLineNumber)
+                    self._typeOfVarscanFile = "Varscan_2_2_WithTag"
+                elif len(lResults) == 19:
+                    currentVarscanLine = self.createVarscanHit_v2_2_8(line, currentLineNumber)
+                    self._typeOfVarscanFile = "Varscan_2_2_8"
+                elif len(lResults) == 20:
+                    currentVarscanLine = self.createVarscanHit_v2_2_8_WithTag(line, currentLineNumber)
+                    self._typeOfVarscanFile = "Varscan_2_2_8_WithTag"
+                else:
+                    raise CheckerException ("Warning: this line (l.%s) is not a valid varscan line !" % currentLineNumber)
+                self._lVarscanHits.append(currentVarscanLine)
+                line = varscanFile.readline()
+        varscanFile.close()
+        
+    def createVarscanObjectFromLine(self, line, currentLineNumber):
+        if self._typeOfVarscanFile == "Varscan_2_2":
+            VarscanHit =  self.createVarscanHit(line, currentLineNumber)
+            return VarscanHit
+        elif self._typeOfVarscanFile == "Varscan_2_2_WithTag":
+            return self.createVarscanHitWithTag(line, currentLineNumber)
+        elif self._typeOfVarscanFile == "Varscan_2_2_8":
+            return self.createVarscanHit_v2_2_8(line, currentLineNumber)
+        elif self._typeOfVarscanFile == "Varscan_2_2_8_WithTag":
+            return self.createVarscanHit_v2_2_8_WithTag(line, currentLineNumber)
+            
+    def createVarscanHit(self, line, currentLineNumber):
+        iVarscanHit =  VarscanHit()
+        iVarscanHit.setAttributesFromString(line, currentLineNumber)
+        return iVarscanHit
+        
+    def createVarscanHitWithTag(self, line, currentLineNumber):
+        iVarscanHitWithTag =  VarscanHit_WithTag()
+        iVarscanHitWithTag.setAttributesFromString(line, currentLineNumber)
+        return iVarscanHitWithTag
+    
+    def createVarscanHit_v2_2_8(self, line, currentLineNumber):
+        iVarscanHit =  VarscanHit_v2_2_8()
+        iVarscanHit.setAttributesFromString(line, currentLineNumber)
+        return iVarscanHit
+    
+    def createVarscanHit_v2_2_8_WithTag(self, line, currentLineNumber):
+        iVarscanHitWithTag =  VarscanHit_v2_2_8_WithTag()
+        iVarscanHitWithTag.setAttributesFromString(line, currentLineNumber)
+        return iVarscanHitWithTag
+    
+    def selectTypeOfVarscanHitObject(self):
+        if self._typeOfVarscanFile == "":
+            raise CheckerException ("Error: no varscan object found !")
+        elif self._typeOfVarscanFile == "Varscan_2_2":
+            return VarscanHit()
+        elif self._typeOfVarscanFile == "Varscan_2_2_WithTag":
+            return VarscanHit_WithTag()
+        elif self._typeOfVarscanFile == "Varscan_2_2_8":
+            return VarscanHit_v2_2_8()
+        elif self._typeOfVarscanFile == "Varscan_2_2_8_WithTag":
+            return VarscanHit_v2_2_8_WithTag()        
+        
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/VarscanFileForGnpSNP.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,72 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.parsing.VarscanHitForGnpSNP import VarscanHitForGnpSNP
+from commons.core.parsing.VarscanFile import VarscanFile
+
+class VarscanFileForGnpSNP(VarscanFile):
+    
+    def __init__(self, varscanFileName, fastqFileName="", refFastaFileName="", taxonName=""):
+        VarscanFile.__init__(self, varscanFileName)
+        self._fastqFileName = fastqFileName
+        self._refFastaFileName = refFastaFileName
+        self._taxonName = taxonName
+        self._previousVarscanHit = None
+        
+    ## Equal operator
+    #
+    # @param o a VarscanFileAnalysis instance
+    #    
+    def __eq__(self, o):
+        return VarscanFile.__eq__(self, o) and self._fastqFileName == o._fastqFileName \
+            and self._refFastaFileName == o._refFastaFileName and self._taxonName == o._taxonName
+             
+    def getVarscanFieldSeparator(self):
+        return self._varscanFieldSeparator
+        
+    def getFastqFileName(self):
+        return self._fastqFileName
+    
+    def getRefFastaFileName(self):
+        return self._refFastaFileName
+    
+    def getTaxonName(self):
+        return self._taxonName
+        
+    def createVarscanHit(self, line, currentLineNumber):
+        line = line.strip()
+        lResults = line.split(self._varscanFieldSeparator)
+        iVarscanHit = VarscanHitForGnpSNP()
+        iVarscanHit.setAttributes(lResults, currentLineNumber)
+        iVarscanHit.formatAlleles2GnpSnp()
+        iVarscanHit.manageOccurrence(self._previousVarscanHit)
+        self._previousVarscanHit = iVarscanHit
+        return iVarscanHit
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/VarscanHit.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,175 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.checker.CheckerException import CheckerException
+
+class VarscanHit(object):
+    
+    def __init__(self, chrom = "", position = "", ref = "", var = "", readsRef = "", readsVar = "", varFreq = "", strandsRef = "", strandsVar = "", qualRef = "", qualVar = "", pValue = ""):
+        self._chrom = chrom
+        self._position = position
+        self._ref = ref
+        self._var = var
+        self._readsRef = readsRef
+        self._readsVar = readsVar
+        self._varFreq = varFreq
+        self._strandsRef = strandsRef
+        self._strandsVar = strandsVar
+        self._qualRef = qualRef
+        self._qualVar = qualVar
+        self._pValue = pValue
+        
+    ## Equal operator
+    #
+    # @param o a VarscanFileAnalysis instance
+    #    
+    def __eq__(self, o):
+        return self._chrom == o._chrom and self._position == o._position and self._ref == o._ref and self._var == o._var
+
+    def setChrom(self, chromosome):
+        self._chrom = chromosome
+    
+    def setPosition(self, position):
+        self._position = position
+    
+    def setRef(self, referenceAllele):
+        self._ref = referenceAllele
+    
+    def setVar(self, variantAllele):
+        self._var = variantAllele
+    
+    def setReadsRef(self, readsRef):
+        self._readsRef = readsRef
+    
+    def setReadsVar(self, readsVar):
+        self._readsVar = readsVar
+        
+    def setVarFreq(self, varFreq):
+        self._varFreq = varFreq
+        
+    def setStrandsRef(self, strandsRef):
+        self._strandsRef = strandsRef
+        
+    def setStrandsVar(self, strandsVar):
+        self._strandsVar = strandsVar
+        
+    def setQualRef(self, qualRef):
+        self._qualRef = qualRef
+        
+    def setQualVar(self, qualVar):
+        self._qualVar = qualVar
+        
+    def setPValue(self, pValue):
+        self._pValue = pValue
+    
+    def getChrom(self):
+        return self._chrom
+    
+    def getPosition(self):
+        return self._position
+    
+    def getRef(self):
+        return self._ref
+    
+    def getVar(self):
+        return self._var
+    
+    def getReadsRef(self):
+        return self._readsRef
+    
+    def getReadsVar(self):
+        return self._readsVar
+    
+    def getVarFreq(self):
+        return self._varFreq
+    
+    def getStrandsRef(self):
+        return self._strandsRef
+    
+    def getStrandsVar(self):
+        return self._strandsVar
+    
+    def getQualRef(self):
+        return self._qualRef
+    
+    def getQualVar(self):
+        return self._qualVar
+    
+    def getPValue(self):
+        return self._pValue
+    
+    def getHeader(self):
+        return "Chrom\tPosition\tRef\tVar\tReads1\tReads2\tVarFreq\tStrands1\tStrands2\tQual1\tQual2\tPvalue\n"
+    
+    def getVarscanLine(self):
+        return "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (self.getChrom(), self.getPosition(), self.getRef(), self.getVar(), self.getReadsRef(), self.getReadsVar(), self.getVarFreq(), self.getStrandsRef(), self.getStrandsVar(),  self.getQualRef(), self.getQualVar(), self.getPValue())
+    
+    def setAttributes(self, lResults, iCurrentLineNumber):
+        if lResults[0] != '':
+            self.setChrom(lResults[0])
+        else:
+            raise CheckerException ("The field Chrom is empty in varscan file in line %s" % iCurrentLineNumber)
+        if lResults[1] != '':
+            self.setPosition(lResults[1])
+        else:
+            raise CheckerException ("The field Position is empty in varscan file in line %s" % iCurrentLineNumber)
+        if lResults[2] != '':
+            self.setRef(lResults[2])
+        else:
+            raise CheckerException ("The field Ref is empty in varscan file in line %s" % iCurrentLineNumber)
+        if lResults[3] != '':
+            self.setVar(lResults[3])
+        else:
+            raise CheckerException ("The field Var is empty in varscan file in line %s" % iCurrentLineNumber)
+        if lResults[4] != '':
+            self.setReadsRef(lResults[4])
+        if lResults[5] != '':
+            self.setReadsVar(lResults[5])
+        if lResults[6] != '':
+            self.setVarFreq(lResults[6])
+        if lResults[7] != '':
+            self.setStrandsRef(lResults[7])
+        if lResults[8] != '':
+            self.setStrandsVar(lResults[8])
+        if lResults[9] != '':
+            self.setQualRef(lResults[9])
+        if lResults[10] != '':
+            self.setQualVar(lResults[10])
+        if lResults[11] != '':
+            self.setPValue(lResults[11])
+            
+    def setAttributesFromString(self, varscanString, iCurrentLineNumber ="", fieldSeparator ="\t"):
+        varscanString = varscanString.rstrip()
+        lvarscanStringItem = varscanString.split(fieldSeparator)
+        if len(lvarscanStringItem)<12:
+            for i in range(len(lvarscanStringItem), 12):
+                lvarscanStringItem.append ("")
+        self.setAttributes(lvarscanStringItem, iCurrentLineNumber)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/VarscanHitForGnpSNP.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,232 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.checker.CheckerException import CheckerException
+from commons.core.parsing.VarscanHit import VarscanHit
+import re
+
+class VarscanHitForGnpSNP(VarscanHit):
+    
+    def __init__(self):
+        VarscanHit.__init__(self)
+        self._reads1 = ''
+        self._reads2 = ''
+        self._varFreq = ''
+        self._strands1 = ''
+        self._strands2 = ''
+        self._qual1 = ''
+        self._qual2 = ''
+        self._pvalue = ''
+        self._5flank = ''
+        self._3flank = ''
+        self._gnpSnp_ref = ''
+        self._gnpSnp_var = ''
+        self._gnpSnp_position = 0
+        self._polymType = ''
+        self._polymLength = 0
+        self._occurrence = 1
+        
+    ## Equal operator
+    #
+    # @param o a VarscanFileAnalysis instance
+    #    
+    def __eq__(self, o):
+        return VarscanHit.__eq__(self, o) \
+             and self._reads1 == o._reads1 and self._reads2 == o._reads2 \
+             and self._varFreq == o._varFreq and self._strands1 == o._strands1 \
+             and self._strands2 == o._strands2 and self._qual1 == o._qual1 \
+             and self._qual2 == o._qual2 and self._pvalue == o._pvalue \
+             and self._3flank == o._3flank and self._5flank == o._5flank \
+             and self._gnpSnp_position == o._gnpSnp_position and self._gnpSnp_ref == o._gnpSnp_ref \
+             and self._gnpSnp_var == o._gnpSnp_var and self._polymLength == o._polymLength \
+             and self._polymType == o._polymType and self._occurrence == o._occurrence
+    
+    def isPolymTypeAlreadyFoundAtThisChromAndThisPosition(self, iVarscanHitForGnpSNP):
+        return self._chrom == iVarscanHitForGnpSNP.getChrom() \
+            and self._position == iVarscanHitForGnpSNP.getPosition() \
+            and self._polymType == iVarscanHitForGnpSNP.getPolymType()
+            
+    def manageOccurrence(self, iVarscanHitForGnpSNP=None):
+        if iVarscanHitForGnpSNP != None and self.isPolymTypeAlreadyFoundAtThisChromAndThisPosition(iVarscanHitForGnpSNP):
+            self._occurrence = iVarscanHitForGnpSNP.getOccurrence() + 1
+    
+    def formatAlleles2GnpSnp(self):
+        if self.getVar().find("-") != -1:
+            self._polymType = "DELETION"
+            self._gnpSnp_position = int(self._position) + 1
+            self._gnpSnp_ref = self._var[1:]
+            self._gnpSnp_var = "-" * len(self._gnpSnp_ref)
+            self._polymLength = len(self._gnpSnp_ref)
+        elif self.getVar().find("+") != -1:
+            self._polymType = "INSERTION"
+            self._gnpSnp_position = int(self._position)
+            self._gnpSnp_var = self._var[1:]
+            self._gnpSnp_ref = "-" * len(self._gnpSnp_var)
+            self._polymLength = 1
+        else:
+            self._polymType = "SNP"
+            self._gnpSnp_position = int(self._position)
+            self._gnpSnp_var = self._var
+            self._gnpSnp_ref = self._ref
+            self._polymLength = 1
+    
+    def setReads1(self, nbReadsLikeRef):
+        self._reads1 = nbReadsLikeRef
+    
+    def setReads2(self, nbReadsLikeVar):
+        self._reads2 = nbReadsLikeVar
+    
+    def setVarFreq(self, frequencyOfVariantAllele):
+        frequencyOfVariantAllele = frequencyOfVariantAllele.replace("%","")
+        frequencyOfVariantAllele = frequencyOfVariantAllele.replace(",",".")
+        self._varFreq = float(frequencyOfVariantAllele)
+    
+    def setStrands1(self, strandsOfReferenceAllele):
+        self._strands1 = strandsOfReferenceAllele
+    
+    def setStrands2(self, strandsOfVariantAllele):
+        self._strands2 = strandsOfVariantAllele
+    
+    def setQual1(self, averageQualityOfRef):
+        self._qual1 = averageQualityOfRef
+    
+    def setQual2(self, averageQualityOfVar):
+        self._qual2 = averageQualityOfVar
+    
+    def setPvalue(self, pvalue):
+        self._pvalue = pvalue
+    
+    def set5flank(self, s5flank):
+        self._5flank = s5flank
+    
+    def set3flank(self, s3flank):
+        self._3flank = s3flank
+        
+    def setGnpSNPRef(self, ref):
+        self._gnpSnp_ref = ref
+        
+    def setGnpSNPVar(self, var):
+        self._gnpSnp_var = var
+        
+    def setGnpSNPPosition(self, position):
+        self._gnpSnp_position = position
+    
+    def setOccurrence(self, occurrence):
+        self._occurrence = occurrence
+        
+    def setPolymType(self, polymType):
+        self._polymType = polymType
+        
+    def setPolymLength(self, polymLength):
+        self._polymLength = polymLength
+    
+    def getReads1(self):
+        return self._reads1
+    
+    def getReads2(self):
+        return self._reads2
+    
+    def getVarFreq(self):
+        return self._varFreq
+    
+    def getStrands1(self):
+        return self._strands1
+    
+    def getStrands2(self):
+        return self._strands2
+    
+    def getQual1(self):
+        return self._qual1
+    
+    def getQual2(self):
+        return self._qual2
+    
+    def getPvalue(self):
+        return self._pvalue
+    
+    def get5flank(self):
+        return self._5flank
+    
+    def get3flank(self):
+        return self._3flank
+    
+    def getPolymType(self):
+        return self._polymType
+    
+    def getGnpSnpVar(self):
+        return self._gnpSnp_var
+    
+    def getGnpSnpRef(self):
+        return self._gnpSnp_ref
+    
+    def getGnpSnpPosition(self):
+        return self._gnpSnp_position
+    
+    def getPolymLength(self):
+        return self._polymLength
+    
+    def getOccurrence(self):
+        return self._occurrence
+    
+    def setAttributes(self, lResults, iCurrentLineNumber):
+        VarscanHit.setAttributes(self, lResults, iCurrentLineNumber)
+        if lResults[4] != '':
+            self.setReads1(lResults[4])
+        else:
+            raise CheckerException ("The field Reads1 is empty in varscan file in line %s" % (iCurrentLineNumber))
+        if lResults[5] != '':
+            self.setReads2(lResults[5])
+        else:
+            raise CheckerException ("The field Reads2 is empty in varscan file in line %s" % (iCurrentLineNumber))
+        if lResults[6] != '' and re.match("[0-9\,\%]+", lResults[6]):
+            self.setVarFreq(lResults[6])
+        else:
+            raise CheckerException ("The field VarFreq is empty or in bad format in varscan file in line %s" % (iCurrentLineNumber))
+        if lResults[7] != '':
+            self.setStrands1(lResults[7])
+        else:
+            raise CheckerException ("The field Strands1 is empty in varscan file in line %s" % (iCurrentLineNumber))
+        if lResults[8] != '':
+            self.setStrands2(lResults[8])
+        else:
+            raise CheckerException ("The field Strands2 is empty in varscan file in line %s" % (iCurrentLineNumber))
+        if lResults[9] != '':
+            self.setQual1(lResults[9])
+        else:
+            raise CheckerException ("The field Qual1 is empty in varscan file in line %s" % (iCurrentLineNumber))
+        if lResults[10] != '':
+            self.setQual2(lResults[10])
+        else:
+            raise CheckerException ("The field Qual2 is empty in varscan file in line %s" % (iCurrentLineNumber))
+        if lResults[11] != '':
+            self.setPvalue(lResults[11])
+        else:
+            raise CheckerException ("The field Pvalue is empty in varscan file in line %s" % (iCurrentLineNumber))
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/VarscanHit_WithTag.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,70 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+
+from commons.core.parsing.VarscanHit import VarscanHit
+
+class VarscanHit_WithTag(VarscanHit):
+    
+    def __init__(self, tag = "", chrom = "", position = "", ref = "", var = "", readsRef = "", readsVar = "", varFreq = "", strandsRef = "", strandsVar = "", qualRef = "", qualVar = "", pValue = ""):
+        self._tag = tag
+        VarscanHit.__init__(self, chrom, position, ref, var, readsRef, readsVar, varFreq, strandsRef, strandsVar, qualRef, qualVar, pValue)
+        
+    def __eq__(self, o):
+        if self._tag == o._tag: 
+            return VarscanHit.__eq__(self, o)
+        return False
+    
+    def setTag(self, tag):
+        self._tag = tag
+        
+    def getTag(self):
+        return self._tag
+    
+    def getHeader(self):
+        return "Chrom\tPosition\tRef\tVar\tReads1\tReads2\tVarFreq\tStrands1\tStrands2\tQual1\tQual2\tPvalue\tTag\n"
+    
+    def getVarscanLine(self):
+        return "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (self.getChrom(), self.getPosition(), self.getRef(), self.getVar(), self.getReadsRef(), self.getReadsVar(), self.getVarFreq(), self.getStrandsRef(), self.getStrandsVar(),  self.getQualRef(), self.getQualVar(), self.getPValue(), self.getTag())
+    
+    def setAttributes(self, lResults, iCurrentLineNumber):
+        VarscanHit.setAttributes(self, lResults, iCurrentLineNumber)
+        if lResults[12] != '':
+            self.setTag(lResults[12])
+            
+    def setAttributesFromString(self, varscanString, iCurrentLineNumber ="", fieldSeparator ="\t"):
+        varscanString = varscanString.rstrip()
+        lvarscanStringItem = varscanString.split(fieldSeparator)
+        if len(lvarscanStringItem)<13:
+            for i in range(len(lvarscanStringItem), 13):
+                lvarscanStringItem.append ("")
+        self.setAttributes(lvarscanStringItem, iCurrentLineNumber)
+    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/VarscanHit_v2_2_8.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,176 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.checker.CheckerException import CheckerException
+from commons.core.parsing.VarscanHit import VarscanHit
+
+class VarscanHit_v2_2_8(VarscanHit):
+    
+    def __init__(self, chrom = "", position = "", ref = "", cns = "", readsRef = "", readsVar = "", varFreq = "", strandsRef = "", strandsVar = "", qualRef = "", qualVar = "", pValue = "", mapQualRef = "", mapQualVar = "", readsRefPlus = "", readsRefMinus = "", readsVarPlus = "", readsVarMinus = "", var = ""):
+        self._cns = cns
+        self._mapQualRef = mapQualRef
+        self._mapQualVar = mapQualVar
+        self._readsRefPlus = readsRefPlus
+        self._readsRefMinus = readsRefMinus
+        self._readsVarPlus = readsVarPlus
+        self._readsVarMinus = readsVarMinus
+        VarscanHit.__init__(self, chrom, position, ref, var, readsRef, readsVar, varFreq, strandsRef, strandsVar, qualRef, qualVar, pValue)
+        
+    ## Equal operator
+    #
+    # @param o a VarscanFileAnalysis instance
+    #    
+    def __eq__(self, o):
+        if self._cns == o._cns:
+            return VarscanHit.__eq__(self, o)
+        return False
+    
+    def setCns(self, consensus):
+        self._cns = consensus
+        
+    def setMapQualRef(self, mapQualRef):
+        self._mapQualRef = mapQualRef
+        
+    def setMapQualVar(self, mapQualVar):
+        self._mapQualVar = mapQualVar
+        
+    def setReadsRefPlus(self, readsRefPlus):
+        self._readsRefPlus = readsRefPlus
+        
+    def setReadsRefMinus(self, readsRefMinus):
+        self._readsRefMinus = readsRefMinus
+        
+    def setReadsVarPlus(self, readsVarPlus):
+        self._readsVarPlus = readsVarPlus
+        
+    def setReadsVarMinus(self, readsVarMinus):
+        self._readsVarMinus = readsVarMinus
+    
+    def getCns(self):
+        return self._cns
+        
+    def getMapQualRef(self):
+        return self._mapQualRef
+        
+    def getMapQualVar(self):
+        return self._mapQualVar
+        
+    def getReadsRefPlus(self):
+        return self._readsRefPlus
+        
+    def getReadsRefMinus(self):
+        return self._readsRefMinus
+        
+    def getReadsVarPlus(self):
+        return self._readsVarPlus
+        
+    def getReadsVarMinus(self):
+        return self._readsVarMinus
+    
+    def getHeader(self):
+        return "Chrom\tPosition\tRef\tCons\tReads1\tReads2\tVarFreq\tStrands1\tStrands2\tQual1\tQual2\tPvalue\tMapQual1\tMapQual2\tReads1Plus\tReads1Minus\tReads2Plus\tReads2Minus\tVarAllele\n"
+    
+    def getVarscanLine(self):
+        return "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (self.getChrom(), self.getPosition(), self.getRef(), self.getCns(), self.getReadsRef(), self.getReadsVar(), self.getVarFreq(), self.getStrandsRef(), self.getStrandsVar(),  self.getQualRef(), self.getQualVar(), self.getPValue(), self.getMapQualRef(), self.getMapQualVar(), self.getReadsRefPlus(), self.getReadsRefMinus(), self.getReadsVarPlus(), self.getReadsVarMinus(), self.getVar())
+    
+    def setAttributes(self, lResults, iCurrentLineNumber):
+        if lResults[0] != '':
+            self.setChrom(lResults[0])
+        else:
+            raise CheckerException ("The field Chrom is empty in varscan file in line %s" % iCurrentLineNumber)
+        if lResults[1] != '':
+            self.setPosition(lResults[1])
+        else:
+            raise CheckerException ("The field Position is empty in varscan file in line %s" % iCurrentLineNumber)
+        if lResults[2] != '':
+            self.setRef(lResults[2])
+        else:
+            raise CheckerException ("The field Ref is empty in varscan file in line %s" % iCurrentLineNumber)
+        if lResults[3] != '':
+            self.setCns(lResults[3])
+        else:
+            raise CheckerException ("The field Cons is empty in varscan file in line %s" % iCurrentLineNumber)
+        if lResults[4] != '':
+            self.setReadsRef(lResults[4])
+        if lResults[5] != '':
+            self.setReadsVar(lResults[5])
+        if lResults[6] != '':
+            self.setVarFreq(lResults[6])
+        if lResults[7] != '':
+            self.setStrandsRef(lResults[7])
+        if lResults[8] != '':
+            self.setStrandsVar(lResults[8])
+        if lResults[9] != '':
+            self.setQualRef(lResults[9])
+        if lResults[10] != '':
+            self.setQualVar(lResults[10])
+        if lResults[11] != '':
+            self.setPValue(lResults[11])
+        if lResults[12] != '':
+            self.setMapQualRef(lResults[12])
+        if lResults[13] != '':
+            self.setMapQualVar(lResults[13])
+        if lResults[14] != '':
+            self.setReadsRefPlus(lResults[14])
+        if lResults[15] != '':
+            self.setReadsRefMinus(lResults[15])
+        if lResults[16] != '':
+            self.setReadsVarPlus(lResults[16])
+        if lResults[17] != '':
+            self.setReadsVarMinus(lResults[17])
+        if lResults[18] != '':
+            self.setVar(lResults[18])
+        else:
+            raise CheckerException ("The field varAllele is empty in varscan file in line %s" % iCurrentLineNumber)
+            
+    def setAttributesFromString(self, varscanString, iCurrentLineNumber ="", fieldSeparator ="\t"):
+        varscanString = varscanString.rstrip()
+        lvarscanStringItem = varscanString.split(fieldSeparator)
+        if len(lvarscanStringItem) < 19:
+            raise CheckerException ("This varscan line (l.%s) is not complete" % iCurrentLineNumber)
+        self.setAttributes(lvarscanStringItem, iCurrentLineNumber)
+        
+    def convertVarscanHit_v2_2_8_To_VarscanHit(self):
+        iVarscanHit = VarscanHit()
+        iVarscanHit.setChrom(self.getChrom())
+        iVarscanHit.setPosition(self.getPosition())
+        iVarscanHit.setRef(self.getRef())
+        iVarscanHit.setVar(self.getVar())
+        iVarscanHit.setReadsRef(self.getReadsRef())
+        iVarscanHit.setReadsVar(self.getReadsVar())
+        iVarscanHit.setVarFreq(self.getVarFreq())
+        iVarscanHit.setStrandsRef(self.getStrandsRef())
+        iVarscanHit.setStrandsVar(self.getStrandsVar())
+        iVarscanHit.setQualRef(self.getQualRef())
+        iVarscanHit.setQualVar(self.getQualVar())
+        iVarscanHit.setPValue(self.getPValue())
+        return iVarscanHit
+        
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/VarscanHit_v2_2_8_WithTag.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,88 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.checker.CheckerException import CheckerException
+from commons.core.parsing.VarscanHit_v2_2_8 import VarscanHit_v2_2_8
+from commons.core.parsing.VarscanHit_WithTag import VarscanHit_WithTag
+
+class VarscanHit_v2_2_8_WithTag(VarscanHit_v2_2_8):
+    
+    def __init__(self, chrom = "", position = "", ref = "", cns = "", readsRef = "", readsVar = "", varFreq = "", strandsRef = "", strandsVar = "", qualRef = "", qualVar = "", pValue = "", mapQualRef = "", mapQualVar = "", readsRefPlus = "", readsRefMinus = "", readsVarPlus = "", readsVarMinus = "", var = "", tag = ""):
+        self._tag = tag
+        VarscanHit_v2_2_8.__init__(self, chrom, position, ref, var, readsRef, readsVar, varFreq, strandsRef, strandsVar, qualRef, qualVar, pValue, mapQualRef, mapQualVar, readsRefPlus, readsRefMinus, readsVarPlus, readsVarMinus, var)
+        
+    def __eq__(self, o):
+        if self._tag == o._tag:
+            return VarscanHit_v2_2_8.__eq__(self, o)
+        return False
+    
+    def setTag(self, tag):
+        self._tag = tag
+        
+    def getTag(self):
+        return self._tag
+    
+    def getHeader(self):
+        return "Chrom\tPosition\tRef\tCons\tReads1\tReads2\tVarFreq\tStrands1\tStrands2\tQual1\tQual2\tPvalue\tMapQual1\tMapQual2\tReads1Plus\tReads1Minus\tReads2Plus\tReads2Minus\tVarAllele\tTag\n"
+    
+    def getVarscanLine(self):
+        return "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (self.getChrom(), self.getPosition(), self.getRef(), self.getCns(), self.getReadsRef(), self.getReadsVar(), self.getVarFreq(), self.getStrandsRef(), self.getStrandsVar(),  self.getQualRef(), self.getQualVar(), self.getPValue(), self.getMapQualRef(), self.getMapQualVar(), self.getReadsRefPlus(), self.getReadsRefMinus(), self.getReadsVarPlus(), self.getReadsVarMinus(), self.getVar(), self.getTag())
+    
+    def setAttributes(self, lResults, iCurrentLineNumber):
+        VarscanHit_v2_2_8.setAttributes(self, lResults, iCurrentLineNumber)
+        if lResults[19] != '':
+            self.setTag(lResults[19])
+        else:
+            raise CheckerException ("The field tag is empty in varscan file in line %s" % iCurrentLineNumber)
+            
+    def setAttributesFromString(self, varscanString, iCurrentLineNumber ="", fieldSeparator ="\t"):
+        varscanString = varscanString.rstrip()
+        lvarscanStringItem = varscanString.split(fieldSeparator)
+        if len(lvarscanStringItem) < 20:
+            raise CheckerException ("This varscan line (l.%s) is not complete" % iCurrentLineNumber)
+        self.setAttributes(lvarscanStringItem, iCurrentLineNumber)
+        
+    def convertVarscanHit_v2_2_8_WithTag_To_VarscanHit_WithTag(self):
+        iVarscanHit = VarscanHit_WithTag()
+        iVarscanHit.setChrom(self.getChrom())
+        iVarscanHit.setPosition(self.getPosition())
+        iVarscanHit.setRef(self.getRef())
+        iVarscanHit.setVar(self.getVar())
+        iVarscanHit.setReadsRef(self.getReadsRef())
+        iVarscanHit.setReadsVar(self.getReadsVar())
+        iVarscanHit.setVarFreq(self.getVarFreq())
+        iVarscanHit.setStrandsRef(self.getStrandsRef())
+        iVarscanHit.setStrandsVar(self.getStrandsVar())
+        iVarscanHit.setQualRef(self.getQualRef())
+        iVarscanHit.setQualVar(self.getQualVar())
+        iVarscanHit.setPValue(self.getPValue())
+        iVarscanHit.setTag(self.getTag())
+        return iVarscanHit
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/WigParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,324 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import re
+import sys
+import os.path
+import struct
+from commons.core.parsing.TranscriptListParser import TranscriptListParser
+from SMART.Java.Python.structure.Transcript import Transcript
+
+STRANDTOSTR = {1: "(+)", 0: "(=)", None: "(=)", -1: "(-)"}
+
+nbOpenHandles = 30
+
+
+class WigParser(TranscriptListParser):
+	"""A class that parses a big WIG file, creates an index and make it possible to quickly retrieve some data"""
+
+	def __init__(self, fileName, verbosity = 1):
+		self.fileName		   = fileName
+		self.filler			   = "\xFF" * struct.calcsize('Q')
+		self.strands		   = False
+		self.indexFiles	   	   = {}
+		self.indexBuilt		   = False
+		self.defaultValue	   = 0.0
+		self.currentChromosome = None
+		self.currentStrand	   = 1
+		self.verbosity         = verbosity
+		super(WigParser, self).__init__(fileName, verbosity)
+
+
+	def __def__(self):
+		for file in self.indexFiles.values():
+			file.close()
+
+
+	def setStrands(self, strands):
+		self.strands = strands
+
+
+	def setDefaultValue(self, value):
+		self.defaultValue = value
+
+
+	def getFileFormats():
+		return ["wig"]
+	getFileFormats = staticmethod(getFileFormats)
+
+
+	def setStrands(self, strands):
+		"""
+		Consider both strands separately
+		"""
+		self.strands = strands
+
+
+	def makeIndexName(self, chromosome, strand = None):
+		"""
+		Create an index name for a file
+		"""
+		directoryName = os.path.dirname(self.fileName)
+		if strand == None:
+			strandName = ""
+		else:
+			strandName = "+" if strand == 1 else "-"
+		indexName = os.path.join(directoryName, ".%s%s.index" % (chromosome, strandName))
+		return indexName
+	
+	
+	def findIndexFile(self, chromosome, strand = None):
+		"""
+		Check if the index of a file exists
+		""" 
+		indexName = self.makeIndexName(chromosome, strand)
+		if os.path.exists(indexName):
+			return indexName
+		return False
+	
+	
+	def makeIndexFile(self):
+		"""
+		Create the index for a file
+		"""
+		if self.indexBuilt:
+			return
+
+		inputFile  = open(self.fileName)
+		outputFile = None
+		index	  = 0
+		mark	   = inputFile.tell()
+		line	   = inputFile.readline().strip()
+		chromosome = None
+
+		while line != "":
+			m1 = re.search(r"^\s*-?\d+\.?\d*\s*$", line)
+			m2 = re.search(r"^\s*(\d+)\s+-?\d+\.?\d*\s*$", line)
+			m3 = re.search(r"^\s*fixedStep\s+chrom=(\S+)\s+start=(\d+)\s+step=1\s*$", line)
+			m4 = re.search(r"^\s*fixedStep\s+chrom=\S+\s+start=\d+\s+step=\d+\s+span=\d+\s*$", line)
+			m5 = re.search(r"^\s*variableStep\s+chrom=(\S+)\s*$", line)
+			m6 = re.search(r"^\s*variableStep\s+chrom=(\S+)span=(\d+)\s*$", line)
+						
+			if m1 != None:
+				outputFile.write(struct.pack("Q", mark))
+				index += 1
+			elif m2 != None:
+				nextIndex = int(m2.group(1))
+				if index < nextIndex - 1:
+					outputFile.write(self.filler * (nextIndex - index - 1))
+				outputFile.write(struct.pack("Q", mark))
+				index = nextIndex
+			elif m3 != None:
+				newChromosome = m3.group(1)
+				if newChromosome != chromosome:
+					if outputFile != None:
+						outputFile.close()
+					outputFile = open(self.makeIndexName(newChromosome), "wb")
+				chromosome = newChromosome
+				nextIndex = int(m3.group(2))
+				outputFile.write(self.filler * (nextIndex - index))
+				index = nextIndex
+			elif m4 != None:
+				raise Exception("Error! Cannot parse fixed step WIG files with step > 1 or span > 1")
+			elif m5 != None:
+				newChromosome = m5.group(1)
+				if newChromosome != chromosome:
+					if outputFile != None:
+						outputFile.close()
+					outputFile = open(self.makeIndexName(newChromosome), "wb")
+					index = 0
+					outputFile.write(self.filler)
+				chromosome = newChromosome
+			elif m6 != None:
+				raise Exception("Error! Cannot parse variable step WIG files with step > 1 or span > 1")
+			elif (len(line) == 0) or line[0] == "#" or line.startswith("track"):
+				pass
+			else:
+				raise Exception("Error! Cannot understand line '%s' of WIG file while creating index file! Aborting." % (line))
+			
+			mark = inputFile.tell()
+			line = inputFile.readline().strip()
+
+		inputFile.close
+		if outputFile != None:
+			outputFile.close()
+		self.indexBuilt = True
+	
+	
+	def getIndexFileHandle(self, chromosome, strand = None):
+		"""
+		Get the handle of an index file
+		"""
+		indexFileKey = chromosome
+		if strand != None:
+			indexFileKey += "+" if strand == 1 else "-"
+		if indexFileKey in self.indexFiles:
+			return self.indexFiles[indexFileKey]
+
+		indexFileName = self.makeIndexName(chromosome, strand)
+		if not self.findIndexFile(chromosome, strand):
+			self.makeIndexFile()
+	
+		if not os.path.exists(indexFileName):
+			print "Warning! Index for chromosome %s, strand %s does not exist." % (chromosome, STRANDTOSTR[strand])
+			return False
+		indexFile = open(indexFileName, "rb")
+
+		if len(self.indexFiles.keys()) > nbOpenHandles:
+			removedKey = set(self.indexFiles.keys()).pop()
+			self.indexFiles[removedKey].close()
+			del self.indexFiles[removedKey]
+		self.indexFiles[indexFileKey] = indexFile
+		return indexFile
+		
+
+	
+	def findIndex(self, chromosome, start, strand = None):
+		"""
+		Find the point where to start reading file
+		"""
+
+		sizeOfLong = struct.calcsize("Q")
+		empty	  = int(struct.unpack("Q", self.filler)[0])
+		offset	 = empty
+		indexFile  = self.getIndexFileHandle(chromosome, strand)
+	
+		if not indexFile:
+			return (None, None)
+		
+		while offset == empty:
+			address = start * sizeOfLong
+			indexFile.seek(address, os.SEEK_SET)
+			
+			buffer = indexFile.read(sizeOfLong)
+			if len(buffer) != sizeOfLong:
+				if buffer == "":
+					print "Warning! Index position %d of chromosome %s on strand %s seems out of range!" % (start, chromosome, STRANDTOSTR[strand])
+					return (None, None)
+				else:
+					raise Exception("Problem fetching position %d of chromosome %s on strand %s seems out of range!" % (start, chromosome, STRANDTOSTR[strand]))
+			
+			offset = int(struct.unpack("Q", buffer)[0])
+			start += 1
+			
+		start -= 1
+		return (offset, start)
+	
+	
+
+	def getRange(self, chromosome, start, end):
+		"""
+		Parse a wig file and output a range
+		"""
+		arrays  = {}
+		strands = {1: "+", -1: "-"} if self.strands else {0: ""}
+
+		for strand in strands:
+
+			array = [self.defaultValue] * (end - start + 1)
+			file  = open(self.fileName)
+			offset, index = self.findIndex(chromosome, start, strand if self.strands else None)
+			if offset == None:
+				arrays[strand] = array
+				continue
+			file.seek(offset, os.SEEK_SET)
+
+			for line in file:
+				line = line.strip()
+
+				m1 = re.search(r"^\s*(-?\d+\.?\d*)\s*$", line)
+				m2 = re.search(r"^\s*(\d+)\s+(-?\d+\.?\d*)\s*$", line)
+				m3 = re.search(r"^\s*fixedStep\s+chrom=(\S+)\s+start=(\d+)\s+step=\d+\s*$", line)
+				m4 = re.search(r"^\s*variableStep\s+chrom=(\S+)\s*$", line)
+
+				if m1 != None:
+					if index > end:
+						break
+					if index >= start:
+						array[index - start] = float(m1.group(1))
+					index += 1
+				elif m2 != None:
+					index = int(m2.group(1))
+					if index > end:
+						break
+					if index >= start:
+						array[index - start] = float(m2.group(2))
+					index += 1
+				elif m3 != None:
+					if m3.group(1) != "%s%s" % (chromosome, strands[strand]):
+						break
+					index = int(m3.group(2))
+				elif m4 != None:
+					if m4.group(1) != "%s%s" % (chromosome, strands[strand]):
+						break
+				elif (len(line) == 0) or (line[0] == "#") or line.startswith("track"):
+					pass
+				else:
+					raise Exception("Error! Cannot read line '%s' of wig file" % (line))
+
+			file.close()
+	
+			arrays[strand] = array
+			
+		if self.strands:
+			return arrays
+		return array
+	
+
+	def skipFirstLines(self):
+		return
+
+	
+	def parseLine(self, line):
+		if line.startswith("track"):
+			return None
+		m = re.search(r"^\s*variableStep\s+chrom=(\S+)", line)
+		if m != None:
+			chromosome = m.group(1)
+			if chromosome.endswith("+"):
+				self.currentStrand = 1
+				self.currentChromosome = chromosome[:-1]
+			elif chromosome.endswith("-"):
+				self.currentStrand = -1
+				self.currentChromosome = chromosome[:-1]
+			else:
+				self.currentStrand = 1
+				self.currentChromosome = chromosome
+			return None
+		position, value = line.split()
+		position = int(position)
+		value	= float(value)
+		transcript = Transcript()
+		transcript.setChromosome(self.currentChromosome)
+		transcript.setStart(position)
+		transcript.setEnd(position)
+		transcript.setDirection(self.currentStrand)
+		transcript.setTagValue("ID", "wig_%s_%d_%d" % (self.currentChromosome, self.currentStrand, position))
+		transcript.setTagValue("nbElements", value)
+		return transcript
Binary file smart_toolShed/commons/core/parsing/__init__.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/multifastaParserLauncher.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+
+"""
+Launcher for the multifasta parser.
+@param b: Name of the batch of sequences
+@param g: Name of the gene
+@param t: Scientific name of the taxon concerned
+@param f: Name of the multifasta input file  
+"""
+
+
+import os
+import sys
+import getopt
+from commons.core.parsing.Multifasta2SNPFile import Multifasta2SNPFile
+
+CURRENT_DIR = os.getcwd()
+
+def help():
+        
+    """
+    Give the list of the command-line options.
+    """
+        
+    print "Usage: ",sys.argv[0],"[ options ]"
+    print "     -h: this help"
+    print "Mandatory option:"
+    print "     -t: Scientific name of the taxon concerned"
+    print "Exclusive options (use either the first or the second, one should be used)"
+    print "     -f: Name of the multifasta input file in one batch mode"
+    print "     -d: Name of the directory containing multifasta input file(s) in multi-batch mode"
+    print "Only in one batch mode: mandatory options (when -f is used):"    
+    print "     -b: Name of the batch of submitted sequences"
+    print "     -g: Name of the gene"
+    print ""
+    
+
+def runOneInputFile(batchName, geneName, taxon, inputFileName):
+    print "Multifasta parseur launched:!\n"
+    print "-- Input File: " + inputFileName + "\n"
+    print "-- Batch name: " + batchName + "\n"
+    print "-- Gene name: " + geneName + "\n"
+    print "-- Taxon: " + taxon + "\n"
+    #TODO: gerer le delete des fichiers(mode append)
+    multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, geneName)
+    multifasta2SNPFile.runOneBatch(inputFileName)
+    print "OK: Files generated!"
+
+
+def runSeveralInputFile(taxon, rootDirectoryName):
+    multifasta2SNPFile = Multifasta2SNPFile(taxon)
+    multifasta2SNPFile.runSeveralBatches(rootDirectoryName)
+
+def main():
+    batchName = ""
+    geneName = ""
+    taxon = ""
+    inputFileName = ""
+    rootDirectoryName = ""
+    
+    
+    try:
+        opts,args = getopt.getopt(sys.argv[1:],"hb:g:t:f:d:")
+    except getopt.GetoptError:
+        print "Invalid options\n"
+        help()
+        sys.exit(2)
+
+    for o, a in opts:
+        if o == "-h":
+            help()
+            exit(0)
+        elif o == "-b":
+            batchName = a
+        elif o == "-g":
+            geneName = a
+        elif o == "-t":
+            taxon = a
+        elif o == "-f":
+            inputFileName = a
+        elif o == "-d":
+            rootDirectoryName = os.path.abspath(a)
+            
+    if taxon == "":
+        print "*** Error: The mandatory option -t is missing"
+        help()
+        sys.exit(1)
+    
+    if (inputFileName == "" and  rootDirectoryName == "") or (inputFileName != "" and  rootDirectoryName != ""):
+        print "*** Error: You have to specify the input mode: choose either -f (for one file) or -d (for one directory of several files)"
+        help()
+        sys.exit(1)
+        
+    if(inputFileName != ""):
+        if batchName == "" or geneName == "":
+            print "*** Error: A mandatory option is missing in one batch mode (-b or -g)"
+            help()
+            sys.exit(1)
+    
+    if(inputFileName != ""):
+        runOneInputFile(batchName, geneName, taxon, inputFileName)
+    else:
+        runSeveralInputFile(taxon, rootDirectoryName)
+    
+    
+    return 0
+
+#------------------------------------------------------------------------------
+if __name__ == "__main__":
+    main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_BedParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,58 @@
+import unittest, os
+from commons.core.parsing.BedParser import BedParser
+
+
+class Test_BedParser(unittest.TestCase):
+    
+    def test_Parser(self):
+        parser = BedParser("data/testBedParser1.bed")
+
+        self.assertEqual(parser.getNbTranscripts(), 1)
+
+        for transcript in parser.getIterator():
+            self.assertEqual(transcript.getChromosome(), "arm_X")
+            self.assertEqual(transcript.getName(), "test1.1")
+            self.assertEqual(transcript.getStart(), 1000)
+            self.assertEqual(transcript.getEnd(), 2999)
+            self.assertEqual(transcript.getDirection(), 1)
+            self.assertEqual(transcript.getNbExons(), 2)
+            exons = transcript.getExons()
+            self.assertEqual(exons[0].getChromosome(), "arm_X")
+            self.assertEqual(exons[0].getStart(), 1000)
+            self.assertEqual(exons[0].getEnd(), 1099)
+            self.assertEqual(exons[0].getDirection(), 1)
+            self.assertEqual(exons[1].getChromosome(), "arm_X")
+            self.assertEqual(exons[1].getStart(), 2000)
+            self.assertEqual(exons[1].getEnd(), 2999)
+            self.assertEqual(exons[1].getDirection(), 1)
+
+    def test_Parser_short(self):
+        tmpFileName = "tmpFile.bed"
+        tmpHandle   = open(tmpFileName, "w")
+        tmpHandle.write("""X\t554748\t554904\texon
+X\t554748\t554904\tCDS
+X\t554748\t554750\tstart_codon
+""")
+        tmpHandle.close()
+        parser = BedParser(tmpFileName)
+        self.assertEqual(parser.getNbTranscripts(), 3)
+        for cpt, transcript in enumerate(parser.getIterator()):
+            self.assertEqual(transcript.getNbExons(), 1)
+            self.assertEqual(transcript.getChromosome(), "X")
+            self.assertEqual(transcript.getStart(), 554748)
+            if cpt == 0:
+                self.assertEqual(transcript.getEnd(), 554903)
+                self.assertEqual(transcript.getName(), "exon")
+            elif cpt == 1:
+                self.assertEqual(transcript.getEnd(), 554903)
+                self.assertEqual(transcript.getName(), "CDS")
+            elif cpt == 2:
+                self.assertEqual(transcript.getEnd(), 554749)
+                self.assertEqual(transcript.getName(), "start_codon")
+        os.remove(tmpFileName)
+
+
+
+if __name__ == '__main__':
+        unittest.main()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_BlatFileParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,61 @@
+import unittest
+from commons.core.parsing.BlatFileParser import BlatFileParser
+
+
+class Test_BlatFileParser(unittest.TestCase):
+
+
+    def test_parseBlatFile(self):
+        fileName = "dummayBlat.psl"
+        self._writeBlatInputFile(fileName)
+        blatFileParser = BlatFileParser(fileName)
+        blatFileParser.parseBlatFile()
+        obsNbHits = len(blatFileParser.getListsOfHits())
+        self.assertTrue(obsNbHits == 10)
+        obsQueries = blatFileParser.getDictOfQueries()
+        expQueries = {'5:574_1:574_539_5:1:G/C': 1, '3:574_1:574_539_5:1:G/C': 1, '5:574_2:574_433_5:1:G/C': 1,"3:574_2:574_433_5:1:G/C":1, "5:574_5:574_607_5:1:G/C": 1, "3:574_5:574_607_5:1:G/C": 1}
+        self.assertEquals(expQueries, obsQueries)
+        
+    def test_parseBlatFileByQueries(self):
+        fileName = "dummayBlat.psl"
+        self._writeBlatInputFile(fileName)
+        blatFileParser = BlatFileParser(fileName)
+        blatFileParser.parseBlatFileByQueries()
+        obsDict = blatFileParser.getDictOfBlatHitsByQueries()
+        obs1 = len(obsDict["5:574_1:574_539_5:1:G/C"])
+        obs2 = len(obsDict["3:574_1:574_539_5:1:G/C"])
+        obs3 = len(obsDict["5:574_2:574_433_5:1:G/C"])
+        obs4 = len(obsDict["3:574_2:574_433_5:1:G/C"])
+        obs5 = len(obsDict["5:574_5:574_607_5:1:G/C"])
+        obs6 = len(obsDict["3:574_5:574_607_5:1:G/C"])
+        self.assertTrue(obs1 == 1)
+        self.assertTrue(obs2 == 1)
+        self.assertTrue(obs3 == 1)
+        self.assertTrue(obs4 == 5)
+        self.assertTrue(obs5 == 1)
+        self.assertTrue(obs6 == 1)
+        obsQueries = blatFileParser.getDictOfQueries()
+        expQueries = {'5:574_1:574_539_5:1:G/C': 1, '3:574_1:574_539_5:1:G/C': 1, '5:574_2:574_433_5:1:G/C': 1,"3:574_2:574_433_5:1:G/C":1, "5:574_5:574_607_5:1:G/C": 1, "3:574_5:574_607_5:1:G/C": 1}
+        self.assertEquals(expQueries, obsQueries)
+        
+    def _writeBlatInputFile(self, fileName):
+        file = open(fileName, "w")
+        file.write("psLayout version 3\n")
+        file.write("\n")
+        file.write("match\tmis- \trep. \tN's\tQ gap\tQ gap\tT gap\tT gap\tstrand\tQ        \tQ   \tQ    \tQ  \tT        \tT   \tT    \tT  \tblock\tblockSizes \tqStarts\t tStarts\n")
+        file.write("     \tmatch\tmatch\t   \tcount\tbases\tcount\tbases\t      \tname     \tsize\tstart\tend\tname     \tsize\tstart\tend\tcount\n")
+        file.write("---------------------------------------------------------------------------------------------------------------------------------------------------------------\n")
+        file.write("246\t0\t0\t4\t0\t0\t0\t0\t-\t5:574_1:574_539_5:1:G/C\t250\t0\t250\ttaecs3B_RPH7\t3109948\t1065213\t1065463\t1\t250,\t0,\t1065213,\n")
+        file.write("247\t0\t0\t2\t0\t0\t0\t0\t-\t3:574_1:574_539_5:1:G/C\t250\t1\t250\ttaecs3B_RPH7\t3109948\t1064962\t1065211\t1\t249,\t0,\t1064962,\n")
+        file.write("249\t0\t0\t1\t0\t0\t0\t0\t-\t5:574_2:574_433_5:1:G/C\t250\t0\t250\ttaecs3B_RPH7\t3109948\t1065319\t1065569\t1\t250,\t0,\t1065319,\n")
+        file.write("245\t0\t0\t5\t0\t0\t0\t0\t-\t3:574_2:574_433_5:1:G/C\t250\t0\t250\ttaecs3B_RPH8\t3109948\t1065068\t1065318\t1\t250,\t0,\t1065068,\n")
+        file.write("247\t0\t0\t3\t0\t0\t0\t0\t-\t3:574_2:574_433_5:1:G/C\t250\t0\t250\ttaecs3B_RPH8\t3109948\t1065310\t1065560\t1\t250,\t0,\t1065310,\n")
+        file.write("247\t0\t0\t3\t0\t0\t0\t0\t-\t3:574_2:574_433_5:1:G/C\t250\t0\t250\ttaecs3B_RPH9\t3109948\t1065059\t1065309\t1\t250,\t0,\t1065059,\n")
+        file.write("247\t0\t0\t3\t0\t0\t0\t0\t-\t3:574_2:574_433_5:1:G/C\t250\t0\t250\ttaecs3B_RPH9\t3109948\t1064805\t1065055\t1\t250,\t0,\t1064805,\n")
+        file.write("68\t0\t0\t1\t0\t0\t0\t0\t-\t3:574_2:574_433_5:1:G/C\t69\t0\t69\ttaecs3B_RPH9\t3109948\t1064733\t1064802\t1\t69,\t0,\t1064733,\n")
+        file.write("245\t0\t0\t5\t0\t0\t0\t0\t-\t5:574_5:574_607_5:1:G/C\t250\t0\t250\ttaecs3B_RPH9\t3109948\t1065145\t1065395\t1\t250,\t0,\t1065145,\n")
+        file.write("247\t0\t0\t3\t0\t0\t0\t0\t-\t3:574_5:574_607_5:1:G/C\t250\t0\t250\ttaecs3B_RPH9\t3109948\t1064894\t1065144\t1\t250,\t0,\t1064894,\n")
+        file.close()
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_BlatParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,445 @@
+from commons.core.parsing.BlatParser import BlatParser
+import unittest
+
+
+class Test_BlatParser(unittest.TestCase):
+
+
+    def test_setAttributesFromString(self):
+        blatLine = "315\t20\t0\t0\t3\t10\t2\t9\t+\tMRRE1H001H13FM1\t378\t0\t345\tchr16\t22053297\t21686950\t21687294\t4\t76,185,7,67,\t0,77,263,278,\t21686950,21687026,21687213,21687227,"
+        
+        iBlatParser = BlatParser()
+        iBlatParser.setAttributesFromString(blatLine)
+        
+        obsmatch = iBlatParser.getMatch()
+        obsmismatch = iBlatParser.getMismatch()
+        obsrepMatch = iBlatParser.getRepMatch()
+        obsN = iBlatParser.getN()
+        obsQGapCount = iBlatParser.getQGapCount()
+        obsQGapBases = iBlatParser.getQGapBases()
+        obsTGapCount = iBlatParser.getTGapCount()
+        obsTGapBases = iBlatParser.getTGapBases()
+        obsstrand = iBlatParser.getStrand()
+        obsQName = iBlatParser.getQName()
+        obsQSize = iBlatParser.getQSize()
+        obsQStart = iBlatParser.getQStart()
+        obsQEnd = iBlatParser.getQEnd()
+        obsTName = iBlatParser.getTName()
+        obsTSize = iBlatParser.getTSize()
+        obsTStart = iBlatParser.getTStart()
+        obsTEnd = iBlatParser.getTEnd()
+        obsblockCount = iBlatParser.getBlockCount()
+        obsblockSizes = iBlatParser.getBlockSizes()
+        obsqStarts = iBlatParser.getQStarts()
+        obstStarts = iBlatParser.getTStarts()
+        
+        expmatch = "315"
+        expmismatch = "20"
+        exprepMatch = "0"
+        expN = "0"
+        expQGapCount = "3"
+        expQGapBases = "10"
+        expTGapCount = "2"
+        expTGapBases = "9"
+        expstrand = "+"
+        expQName = "MRRE1H001H13FM1"
+        expQSize = "378"
+        expQStart = "0"
+        expQEnd = "345"
+        expTName = "chr16"
+        expTSize = "22053297"
+        expTStart = "21686950"
+        expTEnd = "21687294"
+        expblockCount = "4"
+        expblockSizes = "76,185,7,67,"
+        expqStarts = "0,77,263,278,"
+        exptStarts = "21686950,21687026,21687213,21687227,"
+        
+        self.assertEquals(expmatch, obsmatch)
+        self.assertEquals(expmismatch, obsmismatch)
+        self.assertEquals(exprepMatch, obsrepMatch)
+        self.assertEquals(expN, obsN)
+        self.assertEquals(expQGapCount, obsQGapCount)
+        self.assertEquals(expQGapBases, obsQGapBases)
+        self.assertEquals(expTGapCount, obsTGapCount)
+        self.assertEquals(expTGapBases, obsTGapBases)
+        self.assertEquals(expstrand, obsstrand)
+        self.assertEquals(expQName, obsQName)
+        self.assertEquals(expQSize, obsQSize)
+        self.assertEquals(expQStart, obsQStart)
+        self.assertEquals(expQEnd, obsQEnd)
+        self.assertEquals(expTName, obsTName)
+        self.assertEquals(expTSize, obsTSize)
+        self.assertEquals(expTStart, obsTStart)
+        self.assertEquals(expTEnd, obsTEnd)
+        self.assertEquals(expblockCount, obsblockCount)
+        self.assertEquals(expblockSizes, obsblockSizes)
+        self.assertEquals(expqStarts, obsqStarts)
+        self.assertEquals(exptStarts, obstStarts)
+        
+    def test_setAttributesFromString_empty_QName(self):
+        blatLine = "315\t20\t0\t0\t3\t10\t2\t9\t+\t\t378\t0\t345\tchr16\t22053297\t21686950\t21687294\t4\t76,185,7,67,\t0,77,263,278,\t21686950,21687026,21687213,21687227,"
+        
+        iBlatParser = BlatParser()
+        iBlatParser.setAttributesFromString(blatLine)
+        
+        obsmatch = iBlatParser.getMatch()
+        obsmismatch = iBlatParser.getMismatch()
+        obsrepMatch = iBlatParser.getRepMatch()
+        obsN = iBlatParser.getN()
+        obsQGapCount = iBlatParser.getQGapCount()
+        obsQGapBases = iBlatParser.getQGapBases()
+        obsTGapCount = iBlatParser.getTGapCount()
+        obsTGapBases = iBlatParser.getTGapBases()
+        obsstrand = iBlatParser.getStrand()
+        obsQName = iBlatParser.getQName()
+        obsQSize = iBlatParser.getQSize()
+        obsQStart = iBlatParser.getQStart()
+        obsQEnd = iBlatParser.getQEnd()
+        obsTName = iBlatParser.getTName()
+        obsTSize = iBlatParser.getTSize()
+        obsTStart = iBlatParser.getTStart()
+        obsTEnd = iBlatParser.getTEnd()
+        obsblockCount = iBlatParser.getBlockCount()
+        obsblockSizes = iBlatParser.getBlockSizes()
+        obsqStarts = iBlatParser.getQStarts()
+        obstStarts = iBlatParser.getTStarts()
+        
+        expmatch = ""
+        expmismatch = ""
+        exprepMatch = ""
+        expN = ""
+        expQGapCount = ""
+        expQGapBases = ""
+        expTGapCount = ""
+        expTGapBases = ""
+        expstrand = ""
+        expQName = ""
+        expQSize = ""
+        expQStart = ""
+        expQEnd = ""
+        expTName = ""
+        expTSize = ""
+        expTStart = ""
+        expTEnd = ""
+        expblockCount = ""
+        expblockSizes = ""
+        expqStarts = ""
+        exptStarts = ""
+        
+        self.assertEquals(expmatch, obsmatch)
+        self.assertEquals(expmismatch, obsmismatch)
+        self.assertEquals(exprepMatch, obsrepMatch)
+        self.assertEquals(expN, obsN)
+        self.assertEquals(expQGapCount, obsQGapCount)
+        self.assertEquals(expQGapBases, obsQGapBases)
+        self.assertEquals(expTGapCount, obsTGapCount)
+        self.assertEquals(expTGapBases, obsTGapBases)
+        self.assertEquals(expstrand, obsstrand)
+        self.assertEquals(expQName, obsQName)
+        self.assertEquals(expQSize, obsQSize)
+        self.assertEquals(expQStart, obsQStart)
+        self.assertEquals(expQEnd, obsQEnd)
+        self.assertEquals(expTName, obsTName)
+        self.assertEquals(expTSize, obsTSize)
+        self.assertEquals(expTStart, obsTStart)
+        self.assertEquals(expTEnd, obsTEnd)
+        self.assertEquals(expblockCount, obsblockCount)
+        self.assertEquals(expblockSizes, obsblockSizes)
+        self.assertEquals(expqStarts, obsqStarts)
+        self.assertEquals(exptStarts, obstStarts)
+
+    def test_setAttributesFromString_less_than_21_fields(self):
+        blatLine = "315\t20\t0\t0\t3\t10\t2\t9\t378\t0\t345\tchr16\t22053297\t21686950\t21687294\t4\t76,185,7,67,\t0,77,263,278,\t21686950,21687026,21687213,21687227,"
+        
+        iBlatParser = BlatParser()
+        iBlatParser.setAttributesFromString(blatLine)
+        
+        obsmatch = iBlatParser.getMatch()
+        obsmismatch = iBlatParser.getMismatch()
+        obsrepMatch = iBlatParser.getRepMatch()
+        obsN = iBlatParser.getN()
+        obsQGapCount = iBlatParser.getQGapCount()
+        obsQGapBases = iBlatParser.getQGapBases()
+        obsTGapCount = iBlatParser.getTGapCount()
+        obsTGapBases = iBlatParser.getTGapBases()
+        obsstrand = iBlatParser.getStrand()
+        obsQName = iBlatParser.getQName()
+        obsQSize = iBlatParser.getQSize()
+        obsQStart = iBlatParser.getQStart()
+        obsQEnd = iBlatParser.getQEnd()
+        obsTName = iBlatParser.getTName()
+        obsTSize = iBlatParser.getTSize()
+        obsTStart = iBlatParser.getTStart()
+        obsTEnd = iBlatParser.getTEnd()
+        obsblockCount = iBlatParser.getBlockCount()
+        obsblockSizes = iBlatParser.getBlockSizes()
+        obsqStarts = iBlatParser.getQStarts()
+        obstStarts = iBlatParser.getTStarts()
+        
+        expmatch = ""
+        expmismatch = ""
+        exprepMatch = ""
+        expN = ""
+        expQGapCount = ""
+        expQGapBases = ""
+        expTGapCount = ""
+        expTGapBases = ""
+        expstrand = ""
+        expQName = ""
+        expQSize = ""
+        expQStart = ""
+        expQEnd = ""
+        expTName = ""
+        expTSize = ""
+        expTStart = ""
+        expTEnd = ""
+        expblockCount = ""
+        expblockSizes = ""
+        expqStarts = ""
+        exptStarts = ""
+        
+        self.assertEquals(expmatch, obsmatch)
+        self.assertEquals(expmismatch, obsmismatch)
+        self.assertEquals(exprepMatch, obsrepMatch)
+        self.assertEquals(expN, obsN)
+        self.assertEquals(expQGapCount, obsQGapCount)
+        self.assertEquals(expQGapBases, obsQGapBases)
+        self.assertEquals(expTGapCount, obsTGapCount)
+        self.assertEquals(expTGapBases, obsTGapBases)
+        self.assertEquals(expstrand, obsstrand)
+        self.assertEquals(expQName, obsQName)
+        self.assertEquals(expQSize, obsQSize)
+        self.assertEquals(expQStart, obsQStart)
+        self.assertEquals(expQEnd, obsQEnd)
+        self.assertEquals(expTName, obsTName)
+        self.assertEquals(expTSize, obsTSize)
+        self.assertEquals(expTStart, obsTStart)
+        self.assertEquals(expTEnd, obsTEnd)
+        self.assertEquals(expblockCount, obsblockCount)
+        self.assertEquals(expblockSizes, obsblockSizes)
+        self.assertEquals(expqStarts, obsqStarts)
+        self.assertEquals(exptStarts, obstStarts)
+        
+    def test_setAttributes(self):
+        lResults = ['315','20','0','0','3','10','2','9','+','MRRE1H001H13FM1','378','0','345','chr16','22053297','21686950','21687294','4','76,185,7,67,','0,77,263,278,','21686950,21687026,21687213,21687227,']
+        lineNumber = 1
+        
+        iBlatParser = BlatParser()
+        iBlatParser.setAttributes(lResults, lineNumber)
+        
+        obsmatch = iBlatParser.getMatch()
+        obsmismatch = iBlatParser.getMismatch()
+        obsrepMatch = iBlatParser.getRepMatch()
+        obsN = iBlatParser.getN()
+        obsQGapCount = iBlatParser.getQGapCount()
+        obsQGapBases = iBlatParser.getQGapBases()
+        obsTGapCount = iBlatParser.getTGapCount()
+        obsTGapBases = iBlatParser.getTGapBases()
+        obsstrand = iBlatParser.getStrand()
+        obsQName = iBlatParser.getQName()
+        obsQSize = iBlatParser.getQSize()
+        obsQStart = iBlatParser.getQStart()
+        obsQEnd = iBlatParser.getQEnd()
+        obsTName = iBlatParser.getTName()
+        obsTSize = iBlatParser.getTSize()
+        obsTStart = iBlatParser.getTStart()
+        obsTEnd = iBlatParser.getTEnd()
+        obsblockCount = iBlatParser.getBlockCount()
+        obsblockSizes = iBlatParser.getBlockSizes()
+        obsqStarts = iBlatParser.getQStarts()
+        obstStarts = iBlatParser.getTStarts()
+        
+        expmatch = "315"
+        expmismatch = "20"
+        exprepMatch = "0"
+        expN = "0"
+        expQGapCount = "3"
+        expQGapBases = "10"
+        expTGapCount = "2"
+        expTGapBases = "9"
+        expstrand = "+"
+        expQName = "MRRE1H001H13FM1"
+        expQSize = "378"
+        expQStart = "0"
+        expQEnd = "345"
+        expTName = "chr16"
+        expTSize = "22053297"
+        expTStart = "21686950"
+        expTEnd = "21687294"
+        expblockCount = "4"
+        expblockSizes = "76,185,7,67,"
+        expqStarts = "0,77,263,278,"
+        exptStarts = "21686950,21687026,21687213,21687227,"
+        
+        self.assertEquals(expmatch, obsmatch)
+        self.assertEquals(expmismatch, obsmismatch)
+        self.assertEquals(exprepMatch, obsrepMatch)
+        self.assertEquals(expN, obsN)
+        self.assertEquals(expQGapCount, obsQGapCount)
+        self.assertEquals(expQGapBases, obsQGapBases)
+        self.assertEquals(expTGapCount, obsTGapCount)
+        self.assertEquals(expTGapBases, obsTGapBases)
+        self.assertEquals(expstrand, obsstrand)
+        self.assertEquals(expQName, obsQName)
+        self.assertEquals(expQSize, obsQSize)
+        self.assertEquals(expQStart, obsQStart)
+        self.assertEquals(expQEnd, obsQEnd)
+        self.assertEquals(expTName, obsTName)
+        self.assertEquals(expTSize, obsTSize)
+        self.assertEquals(expTStart, obsTStart)
+        self.assertEquals(expTEnd, obsTEnd)
+        self.assertEquals(expblockCount, obsblockCount)
+        self.assertEquals(expblockSizes, obsblockSizes)
+        self.assertEquals(expqStarts, obsqStarts)
+        self.assertEquals(exptStarts, obstStarts)
+        
+    def test_eq_Equals_case1(self):
+        BlatParser1 = BlatParser()
+        BlatParser1.setMatch("315")
+        BlatParser1.setMismatch("20")
+        BlatParser1.setRepMatch("0")
+        BlatParser1.setN("0")
+        BlatParser1.setQGapCount("3")
+        BlatParser1.setQGapBases("10")
+        BlatParser1.setTGapCount("2")
+        BlatParser1.setTGapBases("9")
+        BlatParser1.setStrand("+")
+        BlatParser1.setQName("MRRE1H001H13FM1")
+        BlatParser1.setQSize("378")
+        BlatParser1.setQStart("0")
+        BlatParser1.setQEnd("345")
+        BlatParser1.setTName("chr16")
+        BlatParser1.setTSize("22053297")
+        BlatParser1.setTStart("21686950")
+        BlatParser1.setTEnd("21687294")
+        BlatParser1.setBlockCount("4")
+        BlatParser1.setBlockSizes("76,185,7,67,")
+        BlatParser1.setQStarts("0,77,263,278,")
+        BlatParser1.setTStarts("21686950,21687026,21687213,21687227,")
+        
+        BlatParser2 = BlatParser()
+        BlatParser2.setMatch("315")
+        BlatParser2.setMismatch("20")
+        BlatParser2.setRepMatch("0")
+        BlatParser2.setN("0")
+        BlatParser2.setQGapCount("3")
+        BlatParser2.setQGapBases("10")
+        BlatParser2.setTGapCount("2")
+        BlatParser2.setTGapBases("9")
+        BlatParser2.setStrand("+")
+        BlatParser2.setQName("MRRE1H001H13FM1")
+        BlatParser2.setQSize("378")
+        BlatParser2.setQStart("0")
+        BlatParser2.setQEnd("345")
+        BlatParser2.setTName("chr16")
+        BlatParser2.setTSize("22053297")
+        BlatParser2.setTStart("21686950")
+        BlatParser2.setTEnd("21687294")
+        BlatParser2.setBlockCount("4")
+        BlatParser2.setBlockSizes("76,185,7,67,")
+        BlatParser2.setQStarts("0,77,263,278,")
+        BlatParser2.setTStarts("21686950,21687026,21687213,21687227,")
+        
+        self.assertTrue(BlatParser1 == BlatParser2) 
+        
+    def test_eq_Equals_case2(self):
+        BlatParser1 = BlatParser()
+        BlatParser1.setMatch("315")
+        BlatParser1.setMismatch("20")
+        BlatParser1.setRepMatch("0")
+        BlatParser1.setN("0")
+        BlatParser1.setQGapCount("3")
+        BlatParser1.setQGapBases("10")
+        BlatParser1.setTGapCount("2")
+        BlatParser1.setTGapBases("9")
+        BlatParser1.setStrand("+")
+        BlatParser1.setQName("MRRE1H001H13FM1")
+        BlatParser1.setQSize("378")
+        BlatParser1.setQStart("0")
+        BlatParser1.setQEnd("345")
+        BlatParser1.setTName("chr16")
+        BlatParser1.setTSize("22053297")
+        BlatParser1.setTStart("21686950")
+        BlatParser1.setTEnd("21687294")
+        BlatParser1.setBlockCount("4")
+        BlatParser1.setBlockSizes("76,185,7,67,")
+        BlatParser1.setQStarts("0,77,263,278,")
+        BlatParser1.setTStarts("21686950,21687026,21687213,21687227,")
+        
+        BlatParser2 = BlatParser()
+        BlatParser2.setMatch("315")
+        BlatParser2.setMismatch("20")
+        BlatParser2.setRepMatch("0")
+        BlatParser2.setN("0")
+        BlatParser2.setQGapCount("3")
+        BlatParser2.setQGapBases("10")
+        BlatParser2.setTGapCount("2")
+        BlatParser2.setTGapBases("9")
+        BlatParser2.setStrand("+")
+        BlatParser2.setQName("TotoFM2")
+        BlatParser2.setQSize("378")
+        BlatParser2.setQStart("0")
+        BlatParser2.setQEnd("345")
+        BlatParser2.setTName("chr16")
+        BlatParser2.setTSize("22053297")
+        BlatParser2.setTStart("21686950")
+        BlatParser2.setTEnd("21687294")
+        BlatParser2.setBlockCount("4")
+        BlatParser2.setBlockSizes("76,185,7,67,")
+        BlatParser2.setQStarts("0,77,263,278,")
+        BlatParser2.setTStarts("21686950,21687026,21687213,21687227,")
+        
+        self.assertTrue(BlatParser1 == BlatParser2) 
+        
+    def test_eq_notEquals(self):
+        BlatParser1 = BlatParser()
+        BlatParser1.setMatch("315")
+        BlatParser1.setMismatch("20")
+        BlatParser1.setRepMatch("0")
+        BlatParser1.setN("0")
+        BlatParser1.setQGapCount("3")
+        BlatParser1.setQGapBases("10")
+        BlatParser1.setTGapCount("2")
+        BlatParser1.setTGapBases("9")
+        BlatParser1.setStrand("+")
+        BlatParser1.setQName("MRRE1H001H13FM1")
+        BlatParser1.setQSize("378")
+        BlatParser1.setQStart("0")
+        BlatParser1.setQEnd("345")
+        BlatParser1.setTName("chr16")
+        BlatParser1.setTSize("22053297")
+        BlatParser1.setTStart("21686950")
+        BlatParser1.setTEnd("21687294")
+        BlatParser1.setBlockCount("4")
+        BlatParser1.setBlockSizes("76,185,7,67,")
+        BlatParser1.setQStarts("0,77,263,278,")
+        BlatParser1.setTStarts("21686950,21687026,21687213,21687227,")
+        
+        BlatParser2 = BlatParser()
+        BlatParser2.setMatch("315")
+        BlatParser2.setMismatch("20")
+        BlatParser2.setRepMatch("0")
+        BlatParser2.setN("0")
+        BlatParser2.setQGapCount("3")
+        BlatParser2.setQGapBases("10")
+        BlatParser2.setTGapCount("2")
+        BlatParser2.setTGapBases("9")
+        BlatParser2.setStrand("+")
+        BlatParser2.setQName("TotoFM2")
+        BlatParser2.setQSize("378")
+        BlatParser2.setQStart("0")
+        BlatParser2.setQEnd("345")
+        BlatParser2.setTName("chr8")
+        BlatParser2.setTSize("2205")
+        BlatParser2.setTStart("2124")
+        BlatParser2.setTEnd("2168")
+        BlatParser2.setBlockCount("4")
+        BlatParser2.setBlockSizes("76,185,7,67,")
+        BlatParser2.setQStarts("0,77,263,278,")
+        BlatParser2.setTStarts("21686950,21687026,21687213,21687227,")
+        
+        self.assertFalse(BlatParser1 == BlatParser2) 
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_BlatToGff.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,28 @@
+from commons.core.parsing.BlatToGff import BlatToGff
+import unittest
+
+
+class Test_BlatToGff(unittest.TestCase):
+
+
+    def test_convertBlatObjectToGffLine(self):
+        blatLine = '315\t20\t0\t0\t3\t10\t2\t9\t+\tMRRE1H001H13FM1\t378\t0\t345\tchr16\t22053297\t21686950\t21687294\t4\t76,185,7,67,\t0,77,263,278,\t21686950,21687026,21687213,21687227,\n'
+        nbLine = 15
+        iBlatToGff = BlatToGff()
+        BlatToGff._methodName = ''
+        obsGffLine = iBlatToGff.convertBlatObjectToGffLine(blatLine, nbLine)
+        expGffLine = 'chr16\tBlatToGff\tBES\t21686950\t21687294\t.\t+\t.\tID=MRRE1H001H13FM1;Name=MRRE1H001H13FM1;bes_start=21686950;bes_end=21687294;bes_size=22053297\n'
+        self.assertEquals(expGffLine, obsGffLine)
+
+    def test_convertBlatObjectToGffLine_with_methodName(self):
+        blatLine = '315\t20\t0\t0\t3\t10\t2\t9\t+\tMRRE1H001H13FM1\t378\t0\t345\tchr16\t22053297\t21686950\t21687294\t4\t76,185,7,67,\t0,77,263,278,\t21686950,21687026,21687213,21687227,\n'
+        nbLine = 15
+        iBlatToGff = BlatToGff()
+        BlatToGff._methodName = 'Test'
+        obsGffLine = iBlatToGff.convertBlatObjectToGffLine(blatLine, nbLine)
+        expGffLine = 'chr16\tBlatToGff\tTest:BES\t21686950\t21687294\t.\t+\t.\tID=MRRE1H001H13FM1;Name=MRRE1H001H13FM1;bes_start=21686950;bes_end=21687294;bes_size=22053297\n'
+        self.assertEquals(expGffLine, obsGffLine)
+
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_BlatToGffForBesPaired.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,292 @@
+import unittest, os
+from commons.core.parsing.BlatToGffForBesPaired import BlatToGffForBesPaired
+
+
+class Test_BlatToGffForBesPaired(unittest.TestCase):
+
+
+    def test_convertBlatObjectToGffLine(self):
+        blatLine = '315\t20\t0\t0\t3\t10\t2\t9\t+\tMRRE1H001H13FM1\t378\t0\t345\tchr16\t22053297\t21686950\t21687294\t4\t76,185,7,67,\t0,77,263,278,\t21686950,21687026,21687213,21687227,\n'
+        nbLine = 15
+        besFastaFileName = '%s/commons/core/parsing/test/besSequences.fasta' % os.environ['REPET_PATH']
+        self._writeBesSequences(besFastaFileName)
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        iBlatToGffForBesPaired._methodName = ''
+        iBlatToGffForBesPaired._inputFileFasta = besFastaFileName
+        obsGffLine, obsBesName, obsBesSeq, obsBesType = iBlatToGffForBesPaired.convertBlatObjectToGffLine(blatLine, nbLine)
+        expGffLine = 'chr16\tBlatToGffForBesPaired\tBES\t21686950\t21687294\t.\t+\t.\tID=MRRE1H001H13FM1;Name=MRRE1H001H13FM1;bes_start=21686950;bes_end=21687294;bes_size=22053297;muscadine_seq=AGACCTACTACGACGTACGATCGATCGACTGCTAGCTAGCTAGGCCTAGCTAGCTAGCTAGCTAGCTAGC\n'
+        expBesName = 'MRRE1H001H13FM1'
+        expBesSeq = 'AGACCTACTACGACGTACGATCGATCGACTGCTAGCTAGCTAGGCCTAGCTAGCTAGCTAGCTAGCTAGC'
+        expBesType = 'FM'
+        self.assertEquals(expGffLine, obsGffLine)
+        self.assertEquals(expBesName, obsBesName)
+        self.assertEquals(expBesSeq, obsBesSeq)
+        self.assertEquals(expBesType, obsBesType)
+        os.remove(besFastaFileName)
+
+    def test_convertBlatObjectToGffLine_with_methodName(self):
+        blatLine = '315\t20\t0\t0\t3\t10\t2\t9\t+\tMRRE1H001H13FM1\t378\t0\t345\tchr16\t22053297\t21686950\t21687294\t4\t76,185,7,67,\t0,77,263,278,\t21686950,21687026,21687213,21687227,\n'
+        nbLine = 15
+        besFastaFileName = '%s/commons/core/parsing/test/besSequences.fasta' % os.environ['REPET_PATH']
+        self._writeBesSequences(besFastaFileName)
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        iBlatToGffForBesPaired._methodName = 'Test'
+        iBlatToGffForBesPaired._inputFileFasta = besFastaFileName
+        obsGffLine, obsBesName, obsBesSeq, obsBesType = iBlatToGffForBesPaired.convertBlatObjectToGffLine(blatLine, nbLine)
+        expGffLine = 'chr16\tBlatToGffForBesPaired\tTest:BES\t21686950\t21687294\t.\t+\t.\tID=MRRE1H001H13FM1;Name=MRRE1H001H13FM1;bes_start=21686950;bes_end=21687294;bes_size=22053297;muscadine_seq=AGACCTACTACGACGTACGATCGATCGACTGCTAGCTAGCTAGGCCTAGCTAGCTAGCTAGCTAGCTAGC\n'
+        expBesName = 'MRRE1H001H13FM1'
+        expBesSeq = 'AGACCTACTACGACGTACGATCGATCGACTGCTAGCTAGCTAGGCCTAGCTAGCTAGCTAGCTAGCTAGC'
+        expBesType = 'FM'
+        self.assertEquals(expGffLine, obsGffLine)
+        self.assertEquals(expBesName, obsBesName)
+        self.assertEquals(expBesSeq, obsBesSeq)
+        self.assertEquals(expBesType, obsBesType)
+        os.remove(besFastaFileName)
+    
+    def test_getBesName(self):
+        col9 = 'ID=machin1;Name=machin1;bes_start=21736364;bes_end=21737069;bes_size=22053297\n'
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        obsBesName = iBlatToGffForBesPaired.getBesName(col9)
+        expBesName = 'machin1'
+        self.assertEquals(expBesName, obsBesName)
+                
+    def test_checkBesNames_OK(self):
+        besName1 = 'MRRE1H001H13FM8'
+        besName2 = 'MRRE1H001H13RM2'
+        line = 10
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        self.assertTrue(iBlatToGffForBesPaired.checkBesNames(besName1, besName2, line))
+        
+    def test_checkBesNames_NOK(self):
+        besName1 = 'MRRE1H001H13FM1'
+        besName2 = 'TOTORM2'
+        line = 10
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        self.assertFalse(iBlatToGffForBesPaired.checkBesNames(besName1, besName2, line))
+        
+    def test_checkBesPositions_OK1(self):
+        tBes1 = ('chr16', 25, 150)
+        tBes2 = ('chr16', 300, 350)
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        self.assertTrue(iBlatToGffForBesPaired.checkBesPositions(tBes1, tBes2))
+        
+    def test_checkBesPositions_OK2(self):
+        tBes1 = ('chr16', 300, 350)
+        tBes2 = ('chr16', 3, 50)
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        self.assertTrue(iBlatToGffForBesPaired.checkBesPositions(tBes1, tBes2))
+    
+    def test_checkBesPositions_NOK1(self):
+        tBes1 = ('chr16', 25, 150)
+        tBes2 = ('chr14', 300, 350)
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        self.assertFalse(iBlatToGffForBesPaired.checkBesPositions(tBes1, tBes2))
+    
+    def test_checkBesPositions_NOK2(self):
+        tBes1 = ('chr16', 25, 300)
+        tBes2 = ('chr16', 150, 350)
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        self.assertFalse(iBlatToGffForBesPaired.checkBesPositions(tBes1, tBes2))
+    
+    def test_checkBesPositions_NOK3(self):
+        tBes1 = ('chr16', 25, 300)
+        tBes2 = ('chr16', 1, 50)
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        self.assertFalse(iBlatToGffForBesPaired.checkBesPositions(tBes1, tBes2))
+        
+    def test_getBacName(self):
+        besName = 'MRRE1H001H13FM1'
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        obsBacName = iBlatToGffForBesPaired.getBacName(besName)
+        expBacName = 'MRRE1H001H13'
+        self.assertEquals(expBacName, obsBacName)
+        
+    def test_getBacPositions_case1(self):
+        tBes1 = ('chr16', 25, 300)
+        tBes2 = ('chr16', 1, 50)
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        obsStart, obsEnd = iBlatToGffForBesPaired.getBacPositions(tBes1, tBes2)
+        expStart = 1
+        expEnd = 300
+        self.assertEquals(expStart, obsStart)
+        self.assertEquals(expEnd, obsEnd)
+        
+    def test_getBacPositions_case2(self):
+        tBes1 = ('chr16', 1, 300)
+        tBes2 = ('chr16', 1000, 50000)
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        obsStart, obsEnd = iBlatToGffForBesPaired.getBacPositions(tBes1, tBes2)
+        expStart = 1
+        expEnd = 50000
+        self.assertEquals(expStart, obsStart)
+        self.assertEquals(expEnd, obsEnd)
+        
+    def test_getBacPositions_case3(self):
+        tBes1 = ('chr16', 300, 25)
+        tBes2 = ('chr16', 1, 50)
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        obsStart, obsEnd = iBlatToGffForBesPaired.getBacPositions(tBes1, tBes2)
+        expStart = 1
+        expEnd = 300
+        self.assertEquals(expStart, obsStart)
+        self.assertEquals(expEnd, obsEnd)
+        
+    def test_createGffLineForBac(self):
+        gffLine1 = 'chr16\tBlatToGffForBesPaired\tBES\t10\t1000\t.\t+\t.\tID=MRRE1H001H13FM1;Name=MRRE1H001H13FM1;bes_start=10;bes_end=1000;bes_size=991;muscadine_seq=ATCGATCGATCGATCGTACGACTGACTCGATCAGCTAGCTAGCTAGCACATCG\n'
+        nameBes1 = 'MRRE1H001H13FM1'
+        seqBes1 = 'ATCGATCGATCGATCGTACGACTGACTCGATCAGCTAGCTAGCTAGCACATCG'
+        typeBes1 = 'FM'
+        gffLine2 = 'chr16\tBlatToGffForBesPaired\tBES\t2000\t3000\t.\t+\t.\tID=MRRE1H001H13RM2;Name=MRRE1H001H13RM2;bes_start=2000;bes_end=3000;bes_size=1001;muscadine_seq=CAGCTAGCTACGTACGTACGTACGTAGCATCGATCGAT\n'
+        nameBes2 = 'MRRE1H001H13RM2'
+        seqBes2 = 'CAGCTAGCTACGTACGTACGTACGTAGCATCGATCGAT'
+        typeBes2 = 'RM'
+        line = 2
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        iBlatToGffForBesPaired._methodName = ''
+        obsGffBac = iBlatToGffForBesPaired.createGffLineForBac(gffLine1, nameBes1, seqBes1, typeBes1, gffLine2, nameBes2, seqBes2, typeBes2, line)
+        expGffBac = 'chr16\tBlatToGffForBesPaired\tBAC\t10\t3000\t.\t.\t.\tID=MRRE1H001H13;Name=MRRE1H001H13;bac_start=10;bac_end=3000;bac_size=2991;besFM_name=MRRE1H001H13FM1;muscadine_besFM_seq=ATCGATCGATCGATCGTACGACTGACTCGATCAGCTAGCTAGCTAGCACATCG;besRM_name=MRRE1H001H13RM2;muscadine_besRM_seq=CAGCTAGCTACGTACGTACGTACGTAGCATCGATCGAT\n'
+        self.assertEquals(expGffBac, obsGffBac)
+        
+    def test_createGffLineForBac_with_methodName(self):
+        gffLine1 = 'chr16\tBlatToGffForBesPaired\tBES\t10\t1000\t.\t+\t.\tID=MRRE1H001H13FM1;Name=MRRE1H001H13FM1;bes_start=10;bes_end=1000;bes_size=991;muscadine_seq=ATCGATCGATCGATCGTACGACTGACTCGATCAGCTAGCTAGCTAGCACATCG\n'
+        nameBes1 = 'MRRE1H001H13FM1'
+        seqBes1 = 'ATCGATCGATCGATCGTACGACTGACTCGATCAGCTAGCTAGCTAGCACATCG'
+        typeBes1 = 'FM'
+        gffLine2 = 'chr16\tBlatToGffForBesPaired\tBES\t2000\t3000\t.\t+\t.\tID=MRRE1H001H13RM2;Name=MRRE1H001H13RM2;bes_start=2000;bes_end=3000;bes_size=1001;muscadine_seq=CAGCTAGCTACGTACGTACGTACGTAGCATCGATCGAT\n'
+        nameBes2 = 'MRRE1H001H13RM2'
+        seqBes2 = 'CAGCTAGCTACGTACGTACGTACGTAGCATCGATCGAT'
+        typeBes2 = 'RM'
+        line = 2
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        iBlatToGffForBesPaired._methodName = 'Test'
+        obsGffBac = iBlatToGffForBesPaired.createGffLineForBac(gffLine1, nameBes1, seqBes1, typeBes1, gffLine2, nameBes2, seqBes2, typeBes2, line)
+        expGffBac = 'chr16\tBlatToGffForBesPaired\tTest:BAC\t10\t3000\t.\t.\t.\tID=MRRE1H001H13;Name=MRRE1H001H13;bac_start=10;bac_end=3000;bac_size=2991;besFM_name=MRRE1H001H13FM1;muscadine_besFM_seq=ATCGATCGATCGATCGTACGACTGACTCGATCAGCTAGCTAGCTAGCACATCG;besRM_name=MRRE1H001H13RM2;muscadine_besRM_seq=CAGCTAGCTACGTACGTACGTACGTAGCATCGATCGAT\n'
+        self.assertEquals(expGffBac, obsGffBac)
+        
+    def test_extractBesSequenceFromFastaFileToTmpFile_with_seqInMultipleLines(self):
+        fastaFileName = '%s/commons/core/parsing/test/sequence.fasta' % os.environ['REPET_PATH']
+        fastaFile = open(fastaFileName, 'w')
+        fastaFile.write('>seq1\n')
+        fastaFile.write('ATCGATCGATCGATCGATACGTCAGCGATCGAT\n')
+        fastaFile.write('TACGTACGTACGATCGATCGATCGATCGATCGG\n')
+        fastaFile.write('TACGTACGTACGATCGACGATCGATGCCGATCG\n')
+        fastaFile.write('ATCGAC\n')
+        fastaFile.write('>seq2\n')
+        fastaFile.write('GTCTAGCTAGCTATATCTGACTGACGCGACGGT\n')
+        fastaFile.write('CATGCTAGCTAGCACTGTACAGCTATCGATGCT\n')
+        fastaFile.write('ACTGACACTGTACGTAC\n')
+        fastaFile.write('>seq3\n')
+        fastaFile.write('ACTCGATCGATCG\n')
+        fastaFile.close()
+        
+        seqName = 'seq1'
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        iBlatToGffForBesPaired._inputFileFasta = fastaFileName
+        obsSeq = iBlatToGffForBesPaired.extractBesSequenceFromFastaFile(seqName, 5)
+        expSeq = 'ATCGATCGATCGATCGATACGTCAGCGATCGATTACGTACGTACGATCGATCGATCGATCGATCGGTACGTACGTACGATCGACGATCGATGCCGATCGATCGAC'
+        self.assertEquals(expSeq, obsSeq)
+        os.remove(fastaFileName)
+        
+    def test_extractBesSequenceFromFastaFileToTmpFile_with_seqInUniqueLines(self):
+        fastaFileName = '%s/commons/core/parsing/test/sequence.fasta' % os.environ['REPET_PATH']
+        fastaFile = open(fastaFileName, 'w')
+        fastaFile.write('>seq1\n')
+        fastaFile.write('ATCGATCGATCGATCGATACGTCAGCGATCGAT\n')
+        fastaFile.write('TACGTACGTACGATCGATCGATCGATCGATCGG\n')
+        fastaFile.write('TACGTACGTACGATCGACGATCGATGCCGATCG\n')
+        fastaFile.write('ATCGAC\n')
+        fastaFile.write('>seq2\n')
+        fastaFile.write('GTCTAGCTAGCTATATCTGACTGACGCGACGGT\n')
+        fastaFile.write('CATGCTAGCTAGCACTGTACAGCTATCGATGCT\n')
+        fastaFile.write('ACTGACACTGTACGTAC\n')
+        fastaFile.write('>seq3\n')
+        fastaFile.write('ACTCGATCGATCG\n')
+        fastaFile.close()
+        
+        seqName = 'seq3'
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        iBlatToGffForBesPaired._inputFileFasta = fastaFileName
+        obsSeq = iBlatToGffForBesPaired.extractBesSequenceFromFastaFile(seqName, 5)
+        expSeq = 'ACTCGATCGATCG'
+        self.assertEquals(expSeq, obsSeq)
+        os.remove(fastaFileName)
+        
+    def test_extractBesSequenceFromFastaFileToTmpFile_without_seqInThisFastaFile(self):
+        fastaFileName = '%s/commons/core/parsing/test/sequence.fasta' % os.environ['REPET_PATH']
+        fastaFile = open(fastaFileName, 'w')
+        fastaFile.write('>seq1\n')
+        fastaFile.write('ATCGATCGATCGATCGATACGTCAGCGATCGAT\n')
+        fastaFile.write('TACGTACGTACGATCGATCGATCGATCGATCGG\n')
+        fastaFile.write('TACGTACGTACGATCGACGATCGATGCCGATCG\n')
+        fastaFile.write('ATCGAC\n')
+        fastaFile.write('>seq2\n')
+        fastaFile.write('GTCTAGCTAGCTATATCTGACTGACGCGACGGT\n')
+        fastaFile.write('CATGCTAGCTAGCACTGTACAGCTATCGATGCT\n')
+        fastaFile.write('ACTGACACTGTACGTAC\n')
+        fastaFile.write('>seq3\n')
+        fastaFile.write('ACTCGATCGATCG\n')
+        fastaFile.close()
+        
+        seqName = 'seq4'
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        iBlatToGffForBesPaired._inputFileFasta = fastaFileName
+        obsSeq = iBlatToGffForBesPaired.extractBesSequenceFromFastaFile(seqName, 5)
+        expSeq = 'NA'
+        self.assertEquals(expSeq, obsSeq)
+        os.remove(fastaFileName)
+        
+    def test_getBesFmAndRmNamesAndSequences_case1(self):
+        nameBes1 = 'MRRE1H0072T1FM1'
+        seqBes1 = 'TACGTCAGCTGATCGACATCGATCGATCGATCGATCGATCGTC'
+        typeBes1 = 'FM'
+        nameBes2 = 'MRRE1H0072T1RM3'
+        seqBes2 = 'GCGCAGCGCGACTGACTTGACTATCGGCGACGCGACGATCGATCGATCGATC'
+        typeBes2 = 'RM'
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        obsNameBesFM, obsSeqBesFM, obsNameBesRM, obsSeqBesRM = iBlatToGffForBesPaired.getBesFmAndRmNamesAndSequences(nameBes1, seqBes1, typeBes1, nameBes2, seqBes2, typeBes2)
+        expNameBesFM = 'MRRE1H0072T1FM1'
+        expNameBesRM = 'MRRE1H0072T1RM3'
+        expSeqBesFM = 'TACGTCAGCTGATCGACATCGATCGATCGATCGATCGATCGTC'
+        expSeqBesRM = 'GCGCAGCGCGACTGACTTGACTATCGGCGACGCGACGATCGATCGATCGATC'
+        self.assertEquals(expNameBesFM, obsNameBesFM)
+        self.assertEquals(expNameBesRM, obsNameBesRM)
+        self.assertEquals(expSeqBesFM, obsSeqBesFM)
+        self.assertEquals(expSeqBesRM, obsSeqBesRM)
+        
+    def test_getBesFmAndRmNamesAndSequences_case2(self):
+        nameBes1 = 'MRRE1H0072T1RM1'
+        seqBes1 = 'TACGTCAGCTGATCGACATCGATCGATCGATCGATCGATCGTC'
+        typeBes1 = 'RM'
+        nameBes2 = 'MRRE1H0072T1FM3'
+        seqBes2 = 'GCGCAGCGCGACTGACTTGACTATCGGCGACGCGACGATCGATCGATCGATC'
+        typeBes2 = 'FM'
+        iBlatToGffForBesPaired = BlatToGffForBesPaired()
+        obsNameBesFM, obsSeqBesFM, obsNameBesRM, obsSeqBesRM = iBlatToGffForBesPaired.getBesFmAndRmNamesAndSequences(nameBes1, seqBes1, typeBes1, nameBes2, seqBes2, typeBes2)
+        expNameBesFM = 'MRRE1H0072T1FM3'
+        expNameBesRM = 'MRRE1H0072T1RM1'
+        expSeqBesFM = 'GCGCAGCGCGACTGACTTGACTATCGGCGACGCGACGATCGATCGATCGATC'
+        expSeqBesRM = 'TACGTCAGCTGATCGACATCGATCGATCGATCGATCGATCGTC'
+        self.assertEquals(expNameBesFM, obsNameBesFM)
+        self.assertEquals(expNameBesRM, obsNameBesRM)
+        self.assertEquals(expSeqBesFM, obsSeqBesFM)
+        self.assertEquals(expSeqBesRM, obsSeqBesRM)
+        
+    def _writeBesSequences(self, fileName):
+        file = open(fileName, 'w')
+        file.write('>MRRE1H001H13RM1\n')
+        file.write('ATACGTACGTACGTCAGTACGACTACGTACGTACGTACGTCGTAC\n')
+        file.write('TACGTCAGCATCGTACGTACGTACGTCGTGCTGGCTAGCTGACGA\n')
+        file.write('ATCGATCGATCGATCGACATCGTACG\n')
+        file.write('>MRRE1H001H13FM1\n')
+        file.write('AGACCTACTACGACGTACGATCGATCGACTGCTAGCTAGCTAGGC\n')
+        file.write('CTAGCTAGCTAGCTAGCTAGCTAGC\n')
+        file.write('>MRRE2H007A13FM3\n')
+        file.write('TCAGCTAGCTGACTGACATCGCTAGCTAGCTAGCTAGCTAGCTAG\n')
+        file.write('TACGCAGCTACGGGGCATCGACTAAAAAAAAAAACCCACGACTGG\n')
+        file.write('CTAGCTAGCTAGCTAGCTAGCTACGTCGATCGATCGACTGTTGCC\n')
+        file.write('TCAGCTACTGACTGATCGATCGACTACGTACGTACGTAC\n')
+        file.close()
+        
+        
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_BowtieParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,57 @@
+from commons.core.parsing.BowtieParser import BowtieParser
+import unittest, os
+
+
+class Test_BlatParser(unittest.TestCase):
+
+
+    def test_simple(self):
+        fileName = "tmpFile.bowtie"
+        handle   = open(fileName, "w")
+        handle.write("HWI-EAS179_0053:2:1:1365:7879#0/2\t+\tchrXHet\t191698\tACCGCTGAACCACTTTCATNCNTGGGATTGTGAACTGAAACTGTTCACATGAACTTGGAATTCCCAGTAAGTGTGA\tLcaYcacLaTdd`dacacYBaBTa^^TL^M`]`^aa`Tca`LaLTUa]a_bcLcTMMMMa^a^`bT`ccT_UbM_B\t0\t19:G>N,21:T>N\n")
+        handle.write("HWI-EAS179_0053:2:1:1365:7879#0/1\t-\tchrXHet\t191803\tCCCCTTGTACACACCGCCCGTCGCTACTACCGATTGAATTATGTAGTGAGGTCTCCGGACGTGATCACTGTGACGC\tBBBBBBBBB`O`DS]]aYabaaa[ULYLY]^b`^a^aZZZ_LLLca_a_b^^aYdbd``d^ccaY`_caccc^acc\t0\t33:T>G,72:T>C\n")
+        handle.write("HWI-EAS179_0053:2:1:1371:11420#0/2\t+\tchr3L\t16569206\tTATGAGCGCCAATTTTGCANTTTTATTTTTGTACAAGCCAAGGGTTTTGCAACATTCACAGCGCTTGCCACTTGTC\tcY^bcYLcaL]`]]`aaTaBaab^_ZZ__R[`[cYccc^Ybb^_L`L`Y`aM_a_TcTcc`LL]]MYaYabbTY`^\t0\t19:G>N\n")
+        handle.write("HWI-EAS179_0053:2:1:1371:11420#0/1\t-\tchr3L\t16569298\tAATGAACCATTGTAATTACCCACAACACATACAGTCACACACGAGATGCACACAAGTCGGAAACGGAAGCGAGACG\tBBBBBBBBBBBBBBBBBBBBBB^T`]Y^`KZY__LY_a]^T^ccYaYY__YT]VZbL]`b^cLT^a^caccYbT^b\t0\n")
+        handle.close()
+
+        parser = BowtieParser("tmpFile.bowtie", 0)
+        for cpt, mapping in enumerate(parser.getIterator()):
+            transcript = mapping.getTranscript()
+            if cpt == 0:
+                self.assertEquals(transcript.getName(), "HWI-EAS179_0053:2:1:1365:7879#0/2")
+                self.assertEquals(transcript.getChromosome(), "chrXHet")
+                self.assertEquals(transcript.getDirection(), 1)
+                self.assertEquals(transcript.getStart(), 191699)
+                self.assertEquals(transcript.getEnd(), 191774)
+                self.assertEquals(transcript.getTagValue("nbMismatches"), 2)
+            elif cpt == 1:
+                self.assertEquals(transcript.getName(), "HWI-EAS179_0053:2:1:1365:7879#0/1")
+                self.assertEquals(transcript.getChromosome(), "chrXHet")
+                self.assertEquals(transcript.getDirection(), -1)
+                self.assertEquals(transcript.getStart(), 191804)
+                self.assertEquals(transcript.getEnd(), 191879)
+                self.assertEquals(transcript.getTagValue("nbMismatches"), 2)
+            elif cpt == 2:
+                self.assertEquals(transcript.getName(), "HWI-EAS179_0053:2:1:1371:11420#0/2")
+                self.assertEquals(transcript.getChromosome(), "chr3L")
+                self.assertEquals(transcript.getDirection(), 1)
+                self.assertEquals(transcript.getStart(), 16569207)
+                self.assertEquals(transcript.getEnd(), 16569282)
+                self.assertEquals(transcript.getTagValue("nbMismatches"), 1)
+            elif cpt == 3:
+                self.assertEquals(transcript.getName(), "HWI-EAS179_0053:2:1:1371:11420#0/1")
+                self.assertEquals(transcript.getChromosome(), "chr3L")
+                self.assertEquals(transcript.getDirection(), -1)
+                self.assertEquals(transcript.getStart(), 16569299)
+                self.assertEquals(transcript.getEnd(), 16569374)
+                self.assertEquals(transcript.getTagValue("nbMismatches"), 0)
+            else:
+                self.fail()
+
+        os.remove(fileName)
+        
+        
+
+if __name__ == "__main__":
+    unittest.main()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_CoordsParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,105 @@
+import unittest
+from commons.core.parsing.CoordsParser import CoordsParser
+from SMART.Java.Python.mappingToCoordinates import MappingToCoordinates
+
+
+class Test_CoordsParser(unittest.TestCase):
+    
+
+    def test_Parser(self):
+        parser = CoordsParser("data/testCoordsParser.coords")
+        
+        cpt = 0
+        for mapping in parser.getIterator():
+            transcript = mapping.getTranscript()
+            cpt += 1
+            if cpt == 1:
+                self.assertEqual(transcript.getChromosome(), "scaffold_1")
+                self.assertEqual(transcript.getName(), "gi|240254421:1-30427671")
+                self.assertEqual(transcript.getStart(), 1)
+                self.assertEqual(transcript.getEnd(), 6251)
+                self.assertEqual(transcript.getDirection(), -1)
+                self.assertEqual(transcript.getNbExons(), 1)
+                self.assertEqual(transcript.getTagValue("identity"), 89.030000000000001)
+                exons = transcript.getExons()
+                self.assertEqual(exons[0].getChromosome(), "scaffold_1")
+                self.assertEqual(exons[0].getStart(), 1)
+                self.assertEqual(exons[0].getEnd(), 6251)
+                self.assertEqual(exons[0].getDirection(), -1)
+                self.assertEqual(transcript.getSize(), 6251)
+            elif cpt == 2:
+                self.assertEqual(transcript.getChromosome(), "scaffold_1")
+                self.assertEqual(transcript.getName(), "gi|240254421:1-30427671")
+                self.assertEqual(transcript.getStart(), 9127)
+                self.assertEqual(transcript.getEnd(), 11947)
+                self.assertEqual(transcript.getDirection(), -1)
+                self.assertEqual(transcript.getNbExons(), 1)
+                self.assertEqual(transcript.getTagValue("identity"), 90.450000000000003)
+                exons = transcript.getExons()
+                self.assertEqual(exons[0].getChromosome(), "scaffold_1")
+                self.assertEqual(exons[0].getStart(), 9127)
+                self.assertEqual(exons[0].getEnd(), 11947)
+                self.assertEqual(exons[0].getDirection(), -1)
+                self.assertEqual(transcript.getSize(), 2821)
+            if cpt == 3:
+                self.assertEqual(transcript.getChromosome(), "scaffold_1")
+                self.assertEqual(transcript.getName(), "gi|240254421:1-30427671")
+                self.assertEqual(transcript.getStart(), 12201)
+                self.assertEqual(transcript.getEnd(), 12953)
+                self.assertEqual(transcript.getDirection(), -1)
+                self.assertEqual(transcript.getNbExons(), 1)
+                exons = transcript.getExons()
+                self.assertEqual(exons[0].getChromosome(), "scaffold_1")
+                self.assertEqual(exons[0].getStart(), 12201)
+                self.assertEqual(exons[0].getEnd(), 12953)
+                self.assertEqual(exons[0].getDirection(), -1)
+                self.assertEqual(transcript.getSize(), 753)
+            
+    def test_Parser_showcoord(self):
+        parser = CoordsParser("data/testCoordsParser_showcoord.coords")
+        expTranscriptCount = 1
+        obsTranscriptCount = 0
+        
+        for mapping in parser.getIterator():
+            transcript = mapping.getTranscript()
+            obsTranscriptCount += 1
+            self.assertEqual(transcript.getChromosome(), "mivi_sl_A1_scaffold00001")
+            self.assertEqual(transcript.getName(), "mivi_sl_A2_scaffold00003")
+            self.assertEqual(transcript.getStart(), 296)
+            self.assertEqual(transcript.getEnd(), 2292)
+            self.assertEqual(transcript.getDirection(), 1)
+            self.assertEqual(transcript.getTagValue("identity"), 98.30)
+            self.assertEqual(transcript.getTagValue("target_pident"), 98.30)                
+            self.assertEqual(transcript.getTagValue("target_pcover"), 3.32)
+            self.assertEqual(transcript.getTagValue("target_length"), 60273)                
+            self.assertEqual(transcript.getTagValue("Target"), "mivi_sl_A2_scaffold00003 1 2001")
+            self.assertEqual(transcript.getSize(), 1997)
+                
+        self.assertEquals(expTranscriptCount, obsTranscriptCount)
+                            
+    def test_Parser_showcoord_promer(self):
+        parser = CoordsParser("data/testCoordsParser_showcoord_promer.coords")
+        expTranscriptCount = 1
+        obsTranscriptCount = 0
+        
+        for mapping in parser.getIterator():
+            transcript = mapping.getTranscript()
+            obsTranscriptCount += 1
+            self.assertEqual(transcript.getChromosome(), "mivi_sl_A1_scaffold00001")
+            self.assertEqual(transcript.getName(), "mivi_sl_A2_scaffold00003")
+            self.assertEqual(transcript.getStart(), 291)
+            self.assertEqual(transcript.getEnd(), 1229)
+            self.assertEqual(transcript.getDirection(), -1)
+            self.assertEqual(transcript.getTagValue("identity"), 94.25)
+            self.assertEqual(transcript.getTagValue("target_pident"), 94.25)                
+            self.assertEqual(transcript.getTagValue("target_pcover"), 1.56)
+            self.assertEqual(transcript.getTagValue("target_length"), 60273)                
+            self.assertEqual(transcript.getTagValue("Target"), "mivi_sl_A2_scaffold00003 939 1")
+            self.assertEqual(transcript.getSize(), 939)
+                
+        self.assertEquals(expTranscriptCount, obsTranscriptCount)
+        
+ 
+if __name__ == '__main__':
+        unittest.main()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_CrossSsrAndBesMappedByBlatToGff.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,70 @@
+from commons.core.parsing.CrossSsrAndBesMappedByBlatToGff import CrossSsrAndBesMappedByBlatToGff
+from commons.core.parsing.SsrParser import SsrParser
+
+import unittest
+import os
+
+
+class Test_CrossSsrAndBesMappedByBlatToGff(unittest.TestCase):
+
+
+    def test_createDictOfSsrParser(self):
+        obsDictSsrParser = {}
+        
+        ssrFileName = 'input_SSR_Resuts.tab'
+        SSRFile = open(ssrFileName, 'w')
+        SSRFile.write('BES_name\tBES_redundancy\tSSR_di/tri/tetranucleotide\tSSR_Motif\tSSR_Motif_number\tSSR_start\tSSR_end\tBES_size\n')
+        SSRFile.write('MRRE1H001A12RM1\t1\t4\tttta\t6\t272\t295\t724\n')
+        SSRFile.write('MRRE1H001B01RM1\t1\t3\taat\t8\t264\t287\t683\n')
+        SSRFile.write('MRRE1H001B07RM1\t1\t2\tta\t19\t153\t190\t734\n')
+        SSRFile.write('MRRE1H001B07RM1\t2\t2\taata\t25\t83\t90\t734\n')
+        SSRFile.close()
+        
+        iCrossSsrAndBesMappedByBlatToGff = CrossSsrAndBesMappedByBlatToGff()
+        iCrossSsrAndBesMappedByBlatToGff._inputFileSSR = ssrFileName
+        obsDictSsrParser = iCrossSsrAndBesMappedByBlatToGff.createDictOfSsrParser(obsDictSsrParser)
+        
+        SsrParser1 = SsrParser('MRRE1H001A12RM1', '1', '4', 'ttta', '6', '272', '295', '724')
+        SsrParser2 = SsrParser('MRRE1H001B01RM1', '1', '3', 'aat', '8', '264', '287', '683')
+        SsrParser3 = SsrParser('MRRE1H001B07RM1', '1', '2', 'ta', '19', '153', '190', '734')
+        SsrParser4 = SsrParser('MRRE1H001B07RM1', '2', '2', 'aata', '25', '83', '90', '734')
+        
+        expDictSsrParser = {
+                         'MRRE1H001A12RM1': [SsrParser1], 
+                         'MRRE1H001B01RM1': [SsrParser2],
+                         'MRRE1H001B07RM1': [SsrParser3, SsrParser4]
+                        }
+        
+        self.assertEquals(expDictSsrParser, obsDictSsrParser)
+        os.remove(ssrFileName)
+        
+    def test_convertSSRPositionsToBlatPositions_strand_FW(self):
+        ssrPos = 75
+        blatPosStart = 10501475
+        blatPosEnd = 10501985
+        strand = '+'
+        iCrossSsrAndBesMappedByBlatToGff = CrossSsrAndBesMappedByBlatToGff()
+        obsNewPos = iCrossSsrAndBesMappedByBlatToGff.convertSSRPositionsToChromPositions(ssrPos, blatPosStart, blatPosEnd, strand)
+        expNewPos = 10501549
+        self.assertEquals(expNewPos, obsNewPos)
+        
+    def test_convertSSRPositionsToBlatPositions_strand_RV(self):
+        ssrPos = 75
+        blatPosStart = 10501475
+        blatPosEnd = 10501985
+        strand = '-'
+        iCrossSsrAndBesMappedByBlatToGff = CrossSsrAndBesMappedByBlatToGff()
+        obsNewPos = iCrossSsrAndBesMappedByBlatToGff.convertSSRPositionsToChromPositions(ssrPos, blatPosStart, blatPosEnd, strand)
+        expNewPos = 10501911
+        self.assertEquals(expNewPos, obsNewPos)
+        
+    def test_getSsrMotif(self):
+        ssrMotif = 'atg'
+        ssrNbMotif = 4
+        iCrossSsrAndBesMappedByBlatToGff = CrossSsrAndBesMappedByBlatToGff()
+        obsSsrSeq = iCrossSsrAndBesMappedByBlatToGff.getSsrSeq(ssrMotif, ssrNbMotif)
+        expSsrSeq = 'atgatgatgatg'
+        self.assertEquals(expSsrSeq, obsSsrSeq)
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_F_BlatToGff.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,77 @@
+import unittest
+import os
+from commons.core.utils.FileUtils import FileUtils
+
+
+class Test_F_BlatToGff(unittest.TestCase):
+
+
+    def test_run(self):
+        blatInputFileName = '%s/commons/core/parsing/test/inputFile.tab' % os.environ['REPET_PATH']
+        self._writeBlatInputFile(blatInputFileName)
+        
+        obsOutputFileName = '%s/commons/core/parsing/test/obsOutputFile.tab' % os.environ['REPET_PATH']
+        cmd = 'python %s/commons/core/parsing/BlatToGff.py -i %s -o %s' % (os.environ['REPET_PATH'], blatInputFileName, obsOutputFileName)
+        os.system(cmd)
+        
+        expOutputFileName = '%s/commons/core/parsing/test/expOutputFile.tab' % os.environ['REPET_PATH']
+        self._writeExpOutputFile(expOutputFileName)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expOutputFileName, obsOutputFileName))
+        os.remove(blatInputFileName)
+        os.remove(obsOutputFileName)
+        os.remove(expOutputFileName)
+
+    def test_run_with_methodName(self):
+        blatInputFileName = '%s/commons/core/parsing/test/inputFile.tab' % os.environ['REPET_PATH']
+        self._writeBlatInputFile(blatInputFileName)
+        
+        obsOutputFileName = '%s/commons/core/parsing/test/obsOutputFile.tab' % os.environ['REPET_PATH']
+        cmd = 'python %s/commons/core/parsing/BlatToGff.py -i %s -o %s -n Test_F' % (os.environ['REPET_PATH'], blatInputFileName, obsOutputFileName)
+        os.system(cmd)
+        
+        expOutputFileName = '%s/commons/core/parsing/test/expOutputFile.tab' % os.environ['REPET_PATH']
+        self._writeExpOutputFile_with_methodName(expOutputFileName)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expOutputFileName, obsOutputFileName))
+        os.remove(blatInputFileName)
+        os.remove(obsOutputFileName)
+        os.remove(expOutputFileName)
+    
+    def _writeBlatInputFile(self, blatInputFileName):
+        file = open(blatInputFileName, 'w')
+        file.write('psLayout version 3\n')
+        file.write('\n')
+        file.write('match    mis-     rep.     N\'s    Q gap    Q gap    T gap    T gap    strand    Q            Q       Q        Q      T            T       T        T      block    blockSizes     qStarts     tStarts\n')
+        file.write('         match    match           count    bases    count    bases              name         size    start    end    name         size    start    end    count\n')
+        file.write('---------------------------------------------------------------------------------------------------------------------------------------------------------------\n')
+        file.write('315\t20\t0\t0\t3\t10\t2\t9\t+\tMRRE1H001H13FM1\t378\t0\t345\tchr16\t22053297\t21686950\t21687294\t4\t76,185,7,67,\t0,77,263,278,\t21686950,21687026,21687213,21687227,\n')
+        file.write('690\t11\t0\t0\t1\t3\t2\t4\t-\tmachin1\t704\t0\t704\tchr16\t22053297\t21736364\t21737069\t3\t40,647,14,\t0,43,690,\t21736364,21736406,21737055,\n')
+        file.write('554\t26\t0\t0\t1\t16\t1\t17\t-\tMRRE1H032F08FM1\t606\t10\t606\tchr11\t19818926\t3725876\t3726473\t2\t553,27,\t10,579,\t3725876,3726446,\n')
+        file.write('620\t23\t0\t0\t0\t0\t0\t0\t-\tmachin2\t643\t0\t643\tchr11\t19818926\t3794984\t3795627\t1\t643,\t0,\t3794984,\n')
+        file.write('347\t25\t0\t0\t0\t0\t0\t0\t-\tmachin3\t393\t21\t393\tchr18\t29360087\t12067347\t12067719\t1\t372,\t0,\t12067347,\n')
+        file.close()
+        
+    def _writeExpOutputFile(self, expOutputFileName):
+        file = open(expOutputFileName, 'w')
+        file.write('##gff-version 3\n')
+        file.write('chr16\tBlatToGff\tBES\t21686950\t21687294\t.\t+\t.\tID=MRRE1H001H13FM1;Name=MRRE1H001H13FM1;bes_start=21686950;bes_end=21687294;bes_size=22053297\n')
+        file.write('chr16\tBlatToGff\tBES\t21736364\t21737069\t.\t+\t.\tID=machin1;Name=machin1;bes_start=21736364;bes_end=21737069;bes_size=22053297\n')
+        file.write('chr11\tBlatToGff\tBES\t3725876\t3726473\t.\t+\t.\tID=MRRE1H032F08FM1;Name=MRRE1H032F08FM1;bes_start=3725876;bes_end=3726473;bes_size=19818926\n')
+        file.write('chr11\tBlatToGff\tBES\t3794984\t3795627\t.\t+\t.\tID=machin2;Name=machin2;bes_start=3794984;bes_end=3795627;bes_size=19818926\n')
+        file.write('chr18\tBlatToGff\tBES\t12067347\t12067719\t.\t+\t.\tID=machin3;Name=machin3;bes_start=12067347;bes_end=12067719;bes_size=29360087\n')
+        file.close()
+        
+    def _writeExpOutputFile_with_methodName(self, expOutputFileName):
+        file = open(expOutputFileName, 'w')
+        file.write('##gff-version 3\n')
+        file.write('chr16\tBlatToGff\tTest_F:BES\t21686950\t21687294\t.\t+\t.\tID=MRRE1H001H13FM1;Name=MRRE1H001H13FM1;bes_start=21686950;bes_end=21687294;bes_size=22053297\n')
+        file.write('chr16\tBlatToGff\tTest_F:BES\t21736364\t21737069\t.\t+\t.\tID=machin1;Name=machin1;bes_start=21736364;bes_end=21737069;bes_size=22053297\n')
+        file.write('chr11\tBlatToGff\tTest_F:BES\t3725876\t3726473\t.\t+\t.\tID=MRRE1H032F08FM1;Name=MRRE1H032F08FM1;bes_start=3725876;bes_end=3726473;bes_size=19818926\n')
+        file.write('chr11\tBlatToGff\tTest_F:BES\t3794984\t3795627\t.\t+\t.\tID=machin2;Name=machin2;bes_start=3794984;bes_end=3795627;bes_size=19818926\n')
+        file.write('chr18\tBlatToGff\tTest_F:BES\t12067347\t12067719\t.\t+\t.\tID=machin3;Name=machin3;bes_start=12067347;bes_end=12067719;bes_size=29360087\n')
+        file.close()
+
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_F_BlatToGffForBesPaired.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,117 @@
+import unittest
+import os
+from commons.core.utils.FileUtils import FileUtils
+
+
+class Test_F_BlatToGffForBesPaired(unittest.TestCase):
+
+
+    def test_run(self):
+        blatInputFileName = '%s/commons/core/parsing/test/inputFile.tab' % os.environ['REPET_PATH']
+        self._writeBlatInputFileName(blatInputFileName)
+        fastaInputFileName = '%s/commons/core/parsing/test/sequences.fasta' % os.environ['REPET_PATH']
+        self._writeFastaInputFile(fastaInputFileName)
+        
+        obsOutputFileName = '%s/commons/core/parsing/test/obsOutputFileName.gff' % os.environ['REPET_PATH']
+        cmd = 'python %s/commons/core/parsing/BlatToGffForBesPaired.py -i %s -f %s -o %s' % (os.environ['REPET_PATH'], blatInputFileName, fastaInputFileName, obsOutputFileName)
+        os.system(cmd)
+        
+        expOutputFileName = '%s/commons/core/parsing/test/expOutputFileName.gff' % os.environ['REPET_PATH']
+        self._writeExpOutputFileName(expOutputFileName)
+        self.assertTrue(FileUtils.are2FilesIdentical(expOutputFileName, obsOutputFileName))
+        os.remove(blatInputFileName)
+        os.remove(fastaInputFileName)
+        os.remove(expOutputFileName)
+        os.remove(obsOutputFileName)
+        
+    def test_run_with_methodName(self):
+        blatInputFileName = '%s/commons/core/parsing/test/inputFile.tab' % os.environ['REPET_PATH']
+        self._writeBlatInputFileName(blatInputFileName)
+        fastaInputFileName = '%s/commons/core/parsing/test/sequences.fasta' % os.environ['REPET_PATH']
+        self._writeFastaInputFile(fastaInputFileName)
+        
+        obsOutputFileName = '%s/commons/core/parsing/test/obsOutputFileName.gff' % os.environ['REPET_PATH']
+        cmd = 'python %s/commons/core/parsing/BlatToGffForBesPaired.py -i %s -f %s -o %s -n TestF' % (os.environ['REPET_PATH'], blatInputFileName, fastaInputFileName, obsOutputFileName)
+        os.system(cmd)
+        
+        expOutputFileName = '%s/commons/core/parsing/test/expOutputFileName.gff' % os.environ['REPET_PATH']
+        self._writeExpOutputFileName_with_methodName(expOutputFileName)
+        self.assertTrue(FileUtils.are2FilesIdentical(expOutputFileName, obsOutputFileName))
+        os.remove(blatInputFileName)
+        os.remove(fastaInputFileName)
+        os.remove(expOutputFileName)
+        os.remove(obsOutputFileName)
+
+    def _writeBlatInputFileName(self, blatInputFileName):
+        file = open(blatInputFileName, 'w')
+        file.write('psLayout version 3\n')
+        file.write('\n')
+        file.write('match    mis-     rep.     N\'s    Q gap    Q gap    T gap    T gap    strand    Q            Q       Q        Q      T            T       T        T      block    blockSizes     qStarts     tStarts\n')
+        file.write('         match    match           count    bases    count    bases              name         size    start    end    name         size    start    end    count\n')
+        file.write('---------------------------------------------------------------------------------------------------------------------------------------------------------------\n')
+        file.write('315\t20\t0\t0\t3\t10\t2\t9\t+\tMRRE1H001H13FM1\t378\t0\t345\tchr16\t22053297\t21686950\t21687294\t4\t76,185,7,67,\t0,77,263,278,\t21686950,21687026,21687213,21687227,\n')
+        file.write('690\t11\t0\t0\t1\t3\t2\t4\t-\tMRRE1H001H13RM1\t704\t0\t704\tchr16\t22053297\t21736364\t21737069\t3\t40,647,14,\t0,43,690,\t21736364,21736406,21737055,\n')
+        file.write('554\t26\t0\t0\t1\t16\t1\t17\t+\tMACHINFM1\t606\t10\t606\tchr11\t19818926\t3725876\t3726473\t2\t553,27,\t10,579,\t3725876,3726446,\n')
+        file.write('620\t23\t0\t0\t0\t0\t0\t0\t-\tBIDULERM1\t643\t0\t643\tchr11\t19818926\t3794984\t3795627\t1\t643,\t0,\t3794984,\n')
+        file.write('554\t26\t0\t0\t1\t16\t1\t17\t+\tMRRE1H032F08FM1\t606\t10\t606\tchr11\t19818926\t3725876\t3726473\t2\t553,27,\t10,579,\t3725876,3726446,\n')
+        file.write('620\t23\t0\t0\t0\t0\t0\t0\t-\tMRRE1H032F08RM1\t643\t0\t643\tchr11\t19818926\t3794984\t3795627\t1\t643,\t0,\t3794984,\n')
+        file.write('347\t25\t0\t0\t0\t0\t0\t0\t-\tMRRE1B072N12FM1\t393\t21\t393\tchr18\t29360087\t12067347\t12067719\t1\t372,\t0,\t12067347,\n')
+        file.write('294\t16\t0\t0\t0\t0\t2\t393\t+\tMRRE1B072N12RM1\t339\t21\t331\tchr18\t29360087\t11978635\t11979338\t3\t146,154,10,\t21,167,321,\t11978635,11978783,11979328,\n')
+        file.close()
+        
+    def _writeExpOutputFileName(self, expOutputFileName):
+        file = open(expOutputFileName, 'w')
+        file.write('##gff-version 3\n')
+        file.write('chr16\tBlatToGffForBesPaired\tBES\t21686950\t21687294\t.\t+\t.\tID=MRRE1H001H13FM1;Name=MRRE1H001H13FM1;bes_start=21686950;bes_end=21687294;bes_size=22053297;muscadine_seq=ATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCCTACGTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTAGCACTGCTAGCTACG\n')
+        file.write('chr16\tBlatToGffForBesPaired\tBES\t21736364\t21737069\t.\t+\t.\tID=MRRE1H001H13RM1;Name=MRRE1H001H13RM1;bes_start=21736364;bes_end=21737069;bes_size=22053297;muscadine_seq=ACTGATCGATCGTACGTACGATCGCTGATCGTACGTACGATCGATCGATCGACTCGATCGTAGCTAGCTACGTCAGTCAGACTGACTGCTGCGCTGCATCGTACTGATCGACTGATCGACTGC\n')
+        file.write('chr16\tBlatToGffForBesPaired\tBAC\t21686950\t21737069\t.\t.\t.\tID=MRRE1H001H13;Name=MRRE1H001H13;bac_start=21686950;bac_end=21737069;bac_size=50120;besFM_name=MRRE1H001H13FM1;muscadine_besFM_seq=ATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCCTACGTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTAGCACTGCTAGCTACG;besRM_name=MRRE1H001H13RM1;muscadine_besRM_seq=ACTGATCGATCGTACGTACGATCGCTGATCGTACGTACGATCGATCGATCGACTCGATCGTAGCTAGCTACGTCAGTCAGACTGACTGCTGCGCTGCATCGTACTGATCGACTGATCGACTGC\n')
+        file.write('chr11\tBlatToGffForBesPaired\tBES\t3725876\t3726473\t.\t+\t.\tID=MRRE1H032F08FM1;Name=MRRE1H032F08FM1;bes_start=3725876;bes_end=3726473;bes_size=19818926;muscadine_seq=TCAGCTATCGATCGTACGTACGTCGATCGTACGTACGTACGATCGATCGATATCGATCG\n')
+        file.write('chr11\tBlatToGffForBesPaired\tBES\t3794984\t3795627\t.\t+\t.\tID=MRRE1H032F08RM1;Name=MRRE1H032F08RM1;bes_start=3794984;bes_end=3795627;bes_size=19818926;muscadine_seq=ATCGACTGATCGTCGATCGTACGATCGACTGATCGATCGATCGACTGACTGTACGTACGTAC\n')
+        file.write('chr11\tBlatToGffForBesPaired\tBAC\t3725876\t3795627\t.\t.\t.\tID=MRRE1H032F08;Name=MRRE1H032F08;bac_start=3725876;bac_end=3795627;bac_size=69752;besFM_name=MRRE1H032F08FM1;muscadine_besFM_seq=TCAGCTATCGATCGTACGTACGTCGATCGTACGTACGTACGATCGATCGATATCGATCG;besRM_name=MRRE1H032F08RM1;muscadine_besRM_seq=ATCGACTGATCGTCGATCGTACGATCGACTGATCGATCGATCGACTGACTGTACGTACGTAC\n')
+        file.write('chr18\tBlatToGffForBesPaired\tBES\t12067347\t12067719\t.\t+\t.\tID=MRRE1B072N12FM1;Name=MRRE1B072N12FM1;bes_start=12067347;bes_end=12067719;bes_size=29360087;muscadine_seq=ATCGTACGTACGATCGATCGCATGACTACGT\n')
+        file.write('chr18\tBlatToGffForBesPaired\tBES\t11978635\t11979338\t.\t+\t.\tID=MRRE1B072N12RM1;Name=MRRE1B072N12RM1;bes_start=11978635;bes_end=11979338;bes_size=29360087;muscadine_seq=TACGTACGATCGACTGATGCTAGCTAGCTCC\n')
+        file.write('chr18\tBlatToGffForBesPaired\tBAC\t11978635\t12067719\t.\t.\t.\tID=MRRE1B072N12;Name=MRRE1B072N12;bac_start=11978635;bac_end=12067719;bac_size=89085;besFM_name=MRRE1B072N12FM1;muscadine_besFM_seq=ATCGTACGTACGATCGATCGCATGACTACGT;besRM_name=MRRE1B072N12RM1;muscadine_besRM_seq=TACGTACGATCGACTGATGCTAGCTAGCTCC\n')
+        file.close()
+        
+    def _writeExpOutputFileName_with_methodName(self, expOutputFileName):
+        file = open(expOutputFileName, 'w')
+        file.write('##gff-version 3\n')
+        file.write('chr16\tBlatToGffForBesPaired\tTestF:BES\t21686950\t21687294\t.\t+\t.\tID=MRRE1H001H13FM1;Name=MRRE1H001H13FM1;bes_start=21686950;bes_end=21687294;bes_size=22053297;muscadine_seq=ATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCCTACGTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTAGCACTGCTAGCTACG\n')
+        file.write('chr16\tBlatToGffForBesPaired\tTestF:BES\t21736364\t21737069\t.\t+\t.\tID=MRRE1H001H13RM1;Name=MRRE1H001H13RM1;bes_start=21736364;bes_end=21737069;bes_size=22053297;muscadine_seq=ACTGATCGATCGTACGTACGATCGCTGATCGTACGTACGATCGATCGATCGACTCGATCGTAGCTAGCTACGTCAGTCAGACTGACTGCTGCGCTGCATCGTACTGATCGACTGATCGACTGC\n')
+        file.write('chr16\tBlatToGffForBesPaired\tTestF:BAC\t21686950\t21737069\t.\t.\t.\tID=MRRE1H001H13;Name=MRRE1H001H13;bac_start=21686950;bac_end=21737069;bac_size=50120;besFM_name=MRRE1H001H13FM1;muscadine_besFM_seq=ATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCCTACGTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTAGCACTGCTAGCTACG;besRM_name=MRRE1H001H13RM1;muscadine_besRM_seq=ACTGATCGATCGTACGTACGATCGCTGATCGTACGTACGATCGATCGATCGACTCGATCGTAGCTAGCTACGTCAGTCAGACTGACTGCTGCGCTGCATCGTACTGATCGACTGATCGACTGC\n')
+        file.write('chr11\tBlatToGffForBesPaired\tTestF:BES\t3725876\t3726473\t.\t+\t.\tID=MRRE1H032F08FM1;Name=MRRE1H032F08FM1;bes_start=3725876;bes_end=3726473;bes_size=19818926;muscadine_seq=TCAGCTATCGATCGTACGTACGTCGATCGTACGTACGTACGATCGATCGATATCGATCG\n')
+        file.write('chr11\tBlatToGffForBesPaired\tTestF:BES\t3794984\t3795627\t.\t+\t.\tID=MRRE1H032F08RM1;Name=MRRE1H032F08RM1;bes_start=3794984;bes_end=3795627;bes_size=19818926;muscadine_seq=ATCGACTGATCGTCGATCGTACGATCGACTGATCGATCGATCGACTGACTGTACGTACGTAC\n')
+        file.write('chr11\tBlatToGffForBesPaired\tTestF:BAC\t3725876\t3795627\t.\t.\t.\tID=MRRE1H032F08;Name=MRRE1H032F08;bac_start=3725876;bac_end=3795627;bac_size=69752;besFM_name=MRRE1H032F08FM1;muscadine_besFM_seq=TCAGCTATCGATCGTACGTACGTCGATCGTACGTACGTACGATCGATCGATATCGATCG;besRM_name=MRRE1H032F08RM1;muscadine_besRM_seq=ATCGACTGATCGTCGATCGTACGATCGACTGATCGATCGATCGACTGACTGTACGTACGTAC\n')
+        file.write('chr18\tBlatToGffForBesPaired\tTestF:BES\t12067347\t12067719\t.\t+\t.\tID=MRRE1B072N12FM1;Name=MRRE1B072N12FM1;bes_start=12067347;bes_end=12067719;bes_size=29360087;muscadine_seq=ATCGTACGTACGATCGATCGCATGACTACGT\n')
+        file.write('chr18\tBlatToGffForBesPaired\tTestF:BES\t11978635\t11979338\t.\t+\t.\tID=MRRE1B072N12RM1;Name=MRRE1B072N12RM1;bes_start=11978635;bes_end=11979338;bes_size=29360087;muscadine_seq=TACGTACGATCGACTGATGCTAGCTAGCTCC\n')
+        file.write('chr18\tBlatToGffForBesPaired\tTestF:BAC\t11978635\t12067719\t.\t.\t.\tID=MRRE1B072N12;Name=MRRE1B072N12;bac_start=11978635;bac_end=12067719;bac_size=89085;besFM_name=MRRE1B072N12FM1;muscadine_besFM_seq=ATCGTACGTACGATCGATCGCATGACTACGT;besRM_name=MRRE1B072N12RM1;muscadine_besRM_seq=TACGTACGATCGACTGATGCTAGCTAGCTCC\n')
+        file.close()
+        
+    def _writeFastaInputFile(self, fileName):
+        file = open(fileName, 'w')
+        file.write('>MRRE1H001H13FM1\n')
+        file.write('ATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATC\n')
+        file.write('CTACGTAGCTAGCTAGCTAGCTGATCGATCGATCGTAGCTAGCTAGCTAGC\n')
+        file.write('ACTGCTAGCTACG\n')
+        file.write('>MRRE1H001H13RM1\n')
+        file.write('ACTGATCGATCGTACGTACGATCGCTGATCGTACGTACGATCGATCGATCG\n')
+        file.write('ACTCGATCGTAGCTAGCTACGTCAGTCAGACTGACTGCTGCGCTGCATCGT\n')
+        file.write('ACTGATCGACTGATCGACTGC\n')
+        file.write('>MRRE1H032F08FM1\n')
+        file.write('TCAGCTATCGATCGTACGTACGTCGATCGTACGTACGTACGATCGATCGAT\n')
+        file.write('ATCGATCG\n')
+        file.write('>MRRE1H032F08RM1\n')
+        file.write('ATCGACTGATCGTCGATCGTACGATCGACTGATCGATCGATCGACTGACTG\n')
+        file.write('TACGTACGTAC\n')
+        file.write('>MRRE1B072N12FM1\n')
+        file.write('ATCGTACGTACGATCGATCGCATGACTACGT\n')
+        file.write('>MRRE1B072N12RM1\n')
+        file.write('TACGTACGATCGACTGATGCTAGCTAGCTCC\n')
+        file.write('>MACHINFM1\n')
+        file.write('ATCGTACGCTAGCTAGTCGATCGATCGATCGATCG\n')
+        file.write('>BIDULERM1\n')
+        file.write('ACTCGATCGACTACGTACGTAGACTG\n')
+        file.close()
+        
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_F_CrossSsrAndBesMappedByBlatToGff.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,66 @@
+import unittest
+import os
+from commons.core.utils.FileUtils import FileUtils
+
+class Test_F_CrossSsrAndBesMappedByBlatToGff(unittest.TestCase):
+
+
+    def test_run(self):
+        ssrInputFileName = '%s/commons/core/parsing/test/ssrInputFile.tab' % os.environ['REPET_PATH']
+        self._writeSsrInputFile(ssrInputFileName)
+        blatInputFileName = '%s/commons/core/parsing/test/blatInputFile.tab' % os.environ['REPET_PATH']
+        self._writeBlatInputFile(blatInputFileName)
+        
+        obsOutputFileName = '%s/commons/core/parsing/test/obsOutputFile.tab' % os.environ['REPET_PATH']
+        cmd = 'python %s/commons/core/parsing/CrossSsrAndBesMappedByBlatToGff.py -s %s -b %s -o %s' % (os.environ['REPET_PATH'], ssrInputFileName, blatInputFileName, obsOutputFileName)
+        os.system(cmd)
+        
+        expOutputFileName = '%s/commons/core/parsing/test/expOutputFile.tab' % os.environ['REPET_PATH']
+        self._writeExpOutputFile(expOutputFileName)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expOutputFileName, obsOutputFileName))
+        os.remove(ssrInputFileName)
+        os.remove(blatInputFileName)
+        os.remove(obsOutputFileName)
+        os.remove(expOutputFileName)
+    
+    def _writeBlatInputFile(self, blatInputFileName):
+        file = open(blatInputFileName, 'w')
+        file.write('psLayout version 3\n')
+        file.write('\n')
+        file.write('match    mis-     rep.     N\'s    Q gap    Q gap    T gap    T gap    strand    Q            Q       Q        Q      T            T       T        T      block    blockSizes     qStarts     tStarts\n')
+        file.write('         match    match           count    bases    count    bases              name         size    start    end    name         size    start    end    count\n')
+        file.write('---------------------------------------------------------------------------------------------------------------------------------------------------------------\n')
+        file.write('315\t20\t0\t0\t3\t10\t2\t9\t+\tMRRE1H001H13FM1\t378\t0\t345\tchr16\t22053297\t21686950\t21687294\t4\t76,185,7,67,\t0,77,263,278,\t21686950,21687026,21687213,21687227,\n')
+        file.write('690\t11\t0\t0\t1\t3\t2\t4\t-\tmachin1\t704\t0\t704\tchr16\t22053297\t21736364\t21737069\t3\t40,647,14,\t0,43,690,\t21736364,21736406,21737055,\n')
+        file.write('554\t26\t0\t0\t1\t16\t1\t17\t-\tMRRE1H032F08FM1\t606\t10\t606\tchr11\t19818926\t3725876\t3726473\t2\t553,27,\t10,579,\t3725876,3726446,\n')
+        file.write('620\t23\t0\t0\t0\t0\t0\t0\t-\tmachin2\t643\t0\t643\tchr11\t19818926\t3794984\t3795627\t1\t643,\t0,\t3794984,\n')
+        file.write('347\t25\t0\t0\t0\t0\t0\t0\t-\tmachin3\t393\t21\t393\tchr18\t29360087\t12067347\t12067719\t1\t372,\t0,\t12067347,\n')
+        file.close()
+
+    def _writeSsrInputFile(self, ssrInputFileName):
+        file = open(ssrInputFileName, 'w')
+        file.write('BES_name    BES_redundancy    SSR_di/tri/tetranucleotide    SSR_Motif    SSR_Motif_number    SSR_start    SSR_end    BES_size\n')
+        file.write('truc1\t1\t4\tttta\t6\t272\t295\t724\n')
+        file.write('truc2\t1\t3\taat\t8\t264\t287\t683\n')
+        file.write('MRRE1H001H13FM1\t1\t2\tta\t19\t153\t190\t378\n')
+        file.write('truc3\t2\t4\taaag\t8\t518\t549\t734\n')
+        file.write('MRRE1H032F08FM1\t1\t4\taaat\t7\t544\t571\t606\n')
+        file.write('MRRE1H032F08FM1\t2\t2\tag\t10\t587\t606\t606\n')
+        file.write('truc4\t1\t2\tat\t16\t519\t550\t672\n')
+        file.write('truc5\t1\t3\ttct\t8\t205\t228\t752\n')
+        file.write('truc6\t1\t2\tat\t33\t287\t352\t569\n')
+        file.close()
+        
+    def _writeExpOutputFile(self, expOutputFileName):
+        file = open(expOutputFileName, 'w')
+        file.write('##gff-version 3\n')
+        file.write('chr16\tCrossSsrAndBesAlignedByBlat\tSSR\t21687102\t21687139\t.\t+\t.\tID=SSR_MRRE1H001H13FM1_1;Name=SSR_MRRE1H001H13FM1_1;bes_name=MRRE1H001H13FM1;bes_size=378;bes_matchstart=0;bes_matchend=345;bes_redundancy=1;ssr_type=2;ssr_motif=ta;ssr_motif_number=19;ssr_start=153;ssr_end=190;muscadine_seq=tatatatatatatatatatatatatatatatatatata\n')
+        file.write('chr11\tCrossSsrAndBesAlignedByBlat\tSSR\t3725930\t3725903\t.\t-\t.\tID=SSR_MRRE1H032F08FM1_1;Name=SSR_MRRE1H032F08FM1_1;bes_name=MRRE1H032F08FM1;bes_size=606;bes_matchstart=10;bes_matchend=606;bes_redundancy=1;ssr_type=4;ssr_motif=aaat;ssr_motif_number=7;ssr_start=544;ssr_end=571;muscadine_seq=aaataaataaataaataaataaataaat\n')
+        file.write('chr11\tCrossSsrAndBesAlignedByBlat\tSSR\t3725887\t3725868\t.\t-\t.\tID=SSR_MRRE1H032F08FM1_2;Name=SSR_MRRE1H032F08FM1_2;bes_name=MRRE1H032F08FM1;bes_size=606;bes_matchstart=10;bes_matchend=606;bes_redundancy=2;ssr_type=2;ssr_motif=ag;ssr_motif_number=10;ssr_start=587;ssr_end=606;muscadine_seq=agagagagagagagagagag\n')
+        file.close()
+
+if __name__ == "__main__":
+    unittest.main()
+    
+        
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_FastaParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,75 @@
+from commons.core.parsing.FastaParser import FastaParser
+from SMART.Java.Python.structure.Sequence import Sequence
+import unittest
+
+class Test_FastaParser(unittest.TestCase):
+
+    def test_getSubsequence(self):
+        fastaFile = "myFastaInput.fasta"
+        self._writeInputFastaFile(fastaFile)
+        parser = FastaParser(fastaFile)
+        chromosome = "1"
+        expSeq = Sequence("1:1-20 (1)", "CCTAAGCCATTGCTTGGTGA")
+        obsSeq = parser.getSubSequence(chromosome, 1, 20, 1)
+        self.assertEquals(expSeq, obsSeq)
+
+    def test_getSubsequence_long_sequence(self):
+        fastaFile = "myFastaInput.fasta"
+        self._writeInputFastaFile(fastaFile)
+        parser = FastaParser(fastaFile)
+        chromosome = "2"
+        expSeq = Sequence("subsequence", "TGAAGA")
+        obsSeq = parser.getSubSequence(chromosome, 55, 60, 1, "subsequence")
+        self.assertEquals(expSeq, obsSeq)
+
+    def test_getSubsequence_long_sequence_inside_and_outside(self):
+        fastaFile = "myFastaInput.fasta"
+        self._writeInputFastaFile(fastaFile)
+        parser = FastaParser(fastaFile)
+        chromosome = "2"
+        expSeq = Sequence("subsequence", "TTA")
+        obsSeq = parser.getSubSequence(chromosome, 137, 151, 1, "subsequence")
+        self.assertEquals(expSeq, obsSeq)
+
+    def test_getSubsequence_long_sequence_last_letter(self):
+        fastaFile = "myFastaInput.fasta"
+        self._writeInputFastaFile(fastaFile)
+        parser = FastaParser(fastaFile)
+        chromosome = "2"
+        expSeq = Sequence("subsequence", "A")
+        obsSeq = parser.getSubSequence(chromosome, 139, 151, 1, "subsequence")
+        self.assertEquals(expSeq, obsSeq)
+
+    def test_getSubsequence_long_sequence_totally_outside(self):
+        fastaFile = "myFastaInput.fasta"
+        self._writeInputFastaFile(fastaFile)
+        parser = FastaParser(fastaFile)
+        chromosome = "2"
+        isSysExit = False
+        try:
+            parser.getSubSequence(chromosome, 140, 151, 1, "subsequence")
+        except:
+            isSysExit = True
+        self.assertTrue(isSysExit)
+        
+    def test_setTags(self):
+        fastaFile = "myFastaInput.fasta"
+        self._writeInputFastaFile(fastaFile)
+        parser = FastaParser(fastaFile)
+        parser.setTags()
+        expTags = {"1" : 0,
+                   "2" : 54}
+        obsTags = parser.getTags()
+        self.assertEquals(expTags, obsTags)
+        
+    def _writeInputFastaFile(self, fastaFile):
+        myHandler = open(fastaFile, 'w')
+        myHandler.write(">1\n")
+        myHandler.write("CCTAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAAT\n")
+        myHandler.write(">2\n")
+        myHandler.write("TATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCG\n")
+        myHandler.write("GACCTGAAGAAATTCCTGATTGTACGTTCTGGTTACTCTTCAATTTGGGC\n")
+        myHandler.write("TGCTTAATTATCTCCTCAATTTCAATTTGGCCATGCTTA\n")
+
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_FindRep.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,108 @@
+import unittest
+import os
+from commons.core.utils.FileUtils import FileUtils
+from xml.sax import make_parser
+from xml.sax.handler import feature_namespaces
+from commons.core.parsing.FindRep import FindRep
+
+
+class Test_FindRep(unittest.TestCase):
+    def setUp(self):
+        self._mrepsOuputFileName = "output.xml"
+        self._obsSetFileName = "obsOuput.set"
+        self._expSetFileName = "expOuput.set"
+        self._writeExpSet(self._expSetFileName)
+        self._writeMrepsOutput(self._mrepsOuputFileName)
+ 
+    def tearDown(self):
+        os.remove(self._expSetFileName)
+        os.remove(self._obsSetFileName)
+        os.remove(self._mrepsOuputFileName)
+    
+    def test_parse(self):
+        xmlParser = make_parser()
+        xmlParser.setFeature( feature_namespaces, 0 )
+        xmlParser.setContentHandler( FindRep( self._obsSetFileName,0,  0 ) )
+        xmlParser.parse( self._mrepsOuputFileName )
+        self.assertTrue(FileUtils.are2FilesIdentical(self._obsSetFileName, self._expSetFileName))  
+    
+    def _writeExpSet(self, fileName):
+        f = open(fileName, "w")
+        f.write("1\t(tatt)3\tseq1\t4\t16\n")
+        f.write("2\t(tatt)3\tseq1\t23\t35\n")
+        f.write("3\t(tatt)3\tseq1\t42\t54\n")
+        f.close()
+        
+    def _writeMrepsOutput(self, fileName):
+        f = open(fileName, "w")
+        f.write("<?xml version='1.0' encoding='UTF-8' ?>\n")
+        f.write("<mreps>\n")
+        f.write("<time>Thu Dec  1 17:25:54 2011\n")
+        f.write("</time>\n")
+        f.write("<parameters>\n")
+        f.write("    <type-of-input>file in fasta format</type-of-input>\n")
+        f.write("    <err>3</err>\n")
+        f.write("    <from>1</from>\n")
+        f.write("    <to>-1</to>\n")
+        f.write("    <win>-1</win>\n")
+        f.write("    <minsize>1</minsize>\n")
+        f.write("    <maxsize>-1</maxsize>\n")
+        f.write("    <minperiod>1</minperiod>\n")
+        f.write("   <maxperiod>-1</maxperiod>\n")
+        f.write("   <minexponent>3.00</minexponent>\n")
+        f.write("</parameters>\n")
+        f.write("<results>\n")
+        f.write("<sequence-name>seq1</sequence-name>\n")
+        f.write("<repetitions>\n")
+        f.write("<window>\n")
+        f.write("<windowstart>1</windowstart>\n")
+        f.write("<windowend>60</windowend>\n")
+        f.write("    <repeat>\n")
+        f.write("        <start>4</start>\n")
+        f.write("        <end>16</end>\n")
+        f.write("        <length>13</length>\n")
+        f.write("       <period>4</period>\n")
+        f.write("       <exponent>3.25</exponent>\n")
+        f.write("        <score>0.000</score>\n")
+        f.write("        <sequence>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>t</unit>\n")
+        f.write("        </sequence>\n")
+        f.write("    </repeat>\n")
+        f.write("    <repeat>\n")
+        f.write("        <start>23</start>\n")
+        f.write("        <end>35</end>\n")
+        f.write("        <length>13</length>\n")
+        f.write("        <period>4</period>\n")
+        f.write("        <exponent>3.25</exponent>\n")
+        f.write("        <score>0.000</score>\n")
+        f.write("        <sequence>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>t</unit>\n")
+        f.write("        </sequence>\n")
+        f.write("    </repeat>\n")
+        f.write("    <repeat>\n")
+        f.write("        <start>42</start>\n")
+        f.write("       <end>54</end>\n")
+        f.write("        <length>13</length>\n")
+        f.write("        <period>4</period>\n")
+        f.write("        <exponent>3.25</exponent>\n")
+        f.write("        <score>0.000</score>\n")
+        f.write("        <sequence>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>t</unit>\n")
+        f.write("        </sequence>\n")
+        f.write("    </repeat>\n")
+        f.write("<nbofreps>3</nbofreps>\n")
+        f.write("</window>\n")
+        f.write("</repetitions>\n")
+        f.write("</results>\n")
+        f.write("<errorcode>0</errorcode>\n")
+        f.write("</mreps>\n")
+        f.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_GffParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,62 @@
+import unittest
+from commons.core.parsing.GffParser import GffParser
+
+
+class Test_GffParser(unittest.TestCase):
+    
+
+    def test_Parser(self):
+        parser = GffParser("data/testGffParser1.gff3")
+
+        self.assertEqual(parser.getNbTranscripts(), 3)
+
+        cpt = 0
+        for transcript in parser.getIterator():
+            cpt += 1
+            if cpt == 1:
+                self.assertEqual(transcript.getChromosome(), "arm_X")
+                self.assertEqual(transcript.getName(), "test1")
+                self.assertEqual(transcript.getStart(), 1000)
+                self.assertEqual(transcript.getEnd(), 2000)
+                self.assertEqual(transcript.getDirection(), 1)
+                self.assertEqual(transcript.getNbExons(), 1)
+                self.assertEqual(transcript.getTagValue("field"), "value1")
+                exons = transcript.getExons()
+                self.assertEqual(exons[0].getChromosome(), "arm_X")
+                self.assertEqual(exons[0].getStart(), 1000)
+                self.assertEqual(exons[0].getEnd(), 2000)
+                self.assertEqual(exons[0].getDirection(), 1)
+                self.assertEqual(transcript.getSize(), 1001)
+            elif cpt == 2:
+                self.assertEqual(transcript.getChromosome(), "arm_X")
+                self.assertEqual(transcript.getName(), "test2")
+                self.assertEqual(transcript.getStart(), 10000)
+                self.assertEqual(transcript.getEnd(), 20000)
+                self.assertEqual(transcript.getDirection(), -1)
+                self.assertEqual(transcript.getNbExons(), 2)
+                self.assertEqual(transcript.getTagValue("field"), "value2")
+                exons = transcript.getExons()
+                self.assertEqual(exons[0].getChromosome(), "arm_X")
+                self.assertEqual(exons[0].getStart(), 10000)
+                self.assertEqual(exons[0].getEnd(), 10100)
+                self.assertEqual(exons[0].getDirection(), -1)
+                self.assertEqual(transcript.getSize(), 9602)
+            if cpt == 3:
+                self.assertEqual(transcript.getChromosome(), "arm_X")
+                self.assertEqual(transcript.getName(), "test1.1")
+                self.assertEqual(transcript.getStart(), 1000)
+                self.assertEqual(transcript.getEnd(), 2000)
+                self.assertEqual(transcript.getDirection(), 1)
+                self.assertEqual(transcript.getNbExons(), 1)
+                self.assertEqual(transcript.getTagValue("ID"), "test1.1-1")
+                exons = transcript.getExons()
+                self.assertEqual(exons[0].getChromosome(), "arm_X")
+                self.assertEqual(exons[0].getStart(), 1000)
+                self.assertEqual(exons[0].getEnd(), 2000)
+                self.assertEqual(exons[0].getDirection(), 1)
+                self.assertEqual(transcript.getSize(), 1001)
+
+
+if __name__ == '__main__':
+        unittest.main()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_MapParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,53 @@
+import unittest
+import os
+from commons.core.parsing.MapParser import MapParser
+
+class Test_MapParser(unittest.TestCase):
+
+    
+    def setUp(self):
+        self.inputMapFileName = "testMapParser.map"
+        self._writeInputMapFile()
+        
+    def tearDown(self):
+        if os.path.exists(self.inputMapFileName):
+            os.remove(self.inputMapFileName)
+    
+    def test_Parser(self):
+        parser = MapParser(self.inputMapFileName)
+        
+        cpt = 0
+        for transcript in parser.getIterator():
+            cpt += 1
+            if cpt == 1:
+                self.assertEqual(transcript.getChromosome(), "dmel_chr4")
+                self.assertEqual(transcript.getName(), "aagatgcgtaacggccatac_17")
+                self.assertEqual(transcript.getStart(), 4380)
+                self.assertEqual(transcript.getEnd(), 4400)
+                self.assertEqual(transcript.getDirection(), 1)
+                self.assertEqual(transcript.getSize(), 21)
+            elif cpt == 10:
+                self.assertEqual(transcript.getChromosome(), "dmel_chr4")
+                self.assertEqual(transcript.getName(), "aacggccatacattggtttg_12")
+                self.assertEqual(transcript.getStart(), 4389)
+                self.assertEqual(transcript.getEnd(), 4409)
+                self.assertEqual(transcript.getDirection(), 1)
+                self.assertEqual(transcript.getSize(), 21)
+                
+                
+    def _writeInputMapFile(self):
+        inputFile = open(self.inputMapFileName,'w')
+        inputFile.write("aagatgcgtaacggccatac_17\tdmel_chr4\t4380\t4400\n")
+        inputFile.write("agatgcgtaacggccataca_16\tdmel_chr4\t4381\t4401\n")
+        inputFile.write("gatgcgtaacggccatacat_16\tdmel_chr4\t4382\t4402\n")
+        inputFile.write("atgcgtaacggccatacatt_15\tdmel_chr4\t4383\t4403\n")
+        inputFile.write("tgcgtaacggccatacattg_15\tdmel_chr4\t4384\t4404\n")
+        inputFile.write("gcgtaacggccatacattgg_15\tdmel_chr4\t4385\t4405\n")
+        inputFile.write("cgtaacggccatacattggt_14\tdmel_chr4\t4386\t4406\n")
+        inputFile.write("gtaacggccatacattggtt_14\tdmel_chr4\t4387\t4407\n")
+        inputFile.write("taacggccatacattggttt_14\tdmel_chr4\t4388\t4408\n")
+        inputFile.write("aacggccatacattggtttg_12\tdmel_chr4\t4389\t4409\n")
+        inputFile.close()
+
+if __name__ == '__main__':
+        unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_MrepsToSet.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,105 @@
+import unittest
+import os
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.parsing.MrepsToSet import MrepsToSet
+
+class Test_MrepsToSet(unittest.TestCase):
+    def setUp(self):
+        self._mrepsInputFileName = "mrepsInput.fa"
+        self._mrepsOuputFileName = "mrepsOutput.xml"
+        self._obsSetFileName = "obsOuput.set"
+        self._expSetFileName = "expOuput.set"
+        
+        self._writeExpSet(self._expSetFileName)
+        self._writeMrepsOutput(self._mrepsOuputFileName)
+ 
+    def tearDown(self):
+        os.remove(self._expSetFileName)
+        os.remove(self._obsSetFileName)
+        os.remove(self._mrepsOuputFileName)
+    
+    def test_convert(self):
+        iMrepsToSet = MrepsToSet(self._mrepsInputFileName, self._mrepsOuputFileName, self._obsSetFileName)
+        iMrepsToSet.run()
+        self.assertTrue(FileUtils.are2FilesIdentical(self._obsSetFileName, self._expSetFileName))  
+    
+    def _writeExpSet(self, fileName):
+        f = open(fileName, "w")
+        f.write("1\t(tatt)3\tseq1\t4\t16\n")
+        f.write("2\t(tatt)3\tseq1\t23\t35\n")
+        f.write("3\t(tatt)3\tseq1\t42\t54\n")
+        f.close()
+        
+    def _writeMrepsOutput(self, fileName):
+        f = open(fileName, "w")
+        f.write("<?xml version='1.0' encoding='UTF-8' ?>\n")
+        f.write("<mreps>\n")
+        f.write("<time>Thu Dec  1 17:25:54 2011\n")
+        f.write("</time>\n")
+        f.write("<parameters>\n")
+        f.write("    <type-of-input>file in fasta format</type-of-input>\n")
+        f.write("    <err>3</err>\n")
+        f.write("    <from>1</from>\n")
+        f.write("    <to>-1</to>\n")
+        f.write("    <win>-1</win>\n")
+        f.write("    <minsize>1</minsize>\n")
+        f.write("    <maxsize>-1</maxsize>\n")
+        f.write("    <minperiod>1</minperiod>\n")
+        f.write("   <maxperiod>-1</maxperiod>\n")
+        f.write("   <minexponent>3.00</minexponent>\n")
+        f.write("</parameters>\n")
+        f.write("<results>\n")
+        f.write("<sequence-name>seq1</sequence-name>\n")
+        f.write("<repetitions>\n")
+        f.write("<window>\n")
+        f.write("<windowstart>1</windowstart>\n")
+        f.write("<windowend>60</windowend>\n")
+        f.write("    <repeat>\n")
+        f.write("        <start>4</start>\n")
+        f.write("        <end>16</end>\n")
+        f.write("        <length>13</length>\n")
+        f.write("       <period>4</period>\n")
+        f.write("       <exponent>3.25</exponent>\n")
+        f.write("        <score>0.000</score>\n")
+        f.write("        <sequence>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>t</unit>\n")
+        f.write("        </sequence>\n")
+        f.write("    </repeat>\n")
+        f.write("    <repeat>\n")
+        f.write("        <start>23</start>\n")
+        f.write("        <end>35</end>\n")
+        f.write("        <length>13</length>\n")
+        f.write("        <period>4</period>\n")
+        f.write("        <exponent>3.25</exponent>\n")
+        f.write("        <score>0.000</score>\n")
+        f.write("        <sequence>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>t</unit>\n")
+        f.write("        </sequence>\n")
+        f.write("    </repeat>\n")
+        f.write("    <repeat>\n")
+        f.write("        <start>42</start>\n")
+        f.write("       <end>54</end>\n")
+        f.write("        <length>13</length>\n")
+        f.write("        <period>4</period>\n")
+        f.write("        <exponent>3.25</exponent>\n")
+        f.write("        <score>0.000</score>\n")
+        f.write("        <sequence>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>tatt</unit>\n")
+        f.write("            <unit>t</unit>\n")
+        f.write("        </sequence>\n")
+        f.write("    </repeat>\n")
+        f.write("<nbofreps>3</nbofreps>\n")
+        f.write("</window>\n")
+        f.write("</repetitions>\n")
+        f.write("</results>\n")
+        f.write("<errorcode>0</errorcode>\n")
+        f.write("</mreps>\n")
+        f.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_Multifasta2SNPFile.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,1786 @@
+import os
+import shutil
+import unittest
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.parsing.Multifasta2SNPFile import Multifasta2SNPFile
+from commons.core.parsing.Multifasta2SNPFile import ReferenceBioseqAndLinesBioseqDBWrapper
+from commons.core.seq.Bioseq import Bioseq
+from commons.core.seq.BioseqDB import BioseqDB
+from smac_pipe.tests.Utils4Test import Utils4Test
+
+
+class Test_Multifasta2SNPFile(unittest.TestCase):
+# TODO TEST LOGFILE
+    def setUp(self):
+        os.chdir("%s/commons/core/parsing/test/" % os.environ["REPET_PATH"])
+        self._inFileName = "multifasta_input.fasta"
+        
+        self._expSubSNPFileName = "%s/commons/core/parsing/test/expSubSNP.csv" % os.environ["REPET_PATH"]
+        self._expAlleleFileName = "%s/commons/core/parsing/test/expAllele.csv" % os.environ["REPET_PATH"]
+        
+        self._expIndividualFileName = "%s/commons/core/parsing/test/expIndividual.csv" % os.environ["REPET_PATH"]
+        self._expSequenceFSAFileName = "%s/commons/core/parsing/test/expSequences.fsa" % os.environ["REPET_PATH"]
+        self._expSequenceCSVFileName = "%s/commons/core/parsing/test/expSequences.csv" % os.environ["REPET_PATH"]
+        self._expBatchFileName = "%s/commons/core/parsing/test/expBatch.txt" % os.environ["REPET_PATH"]
+        self._expBatchLineFileName = "%s/commons/core/parsing/test/expBatchLine.csv" % os.environ["REPET_PATH"]
+        
+        self._realInputFileName = "data/real_multifasta_input.fasta"
+        self._realExpSubSNPFileName = "data/realExpSubSNP.csv"
+        self._realExpSequenceFSAFileName = "data/realExpSequences.fsa"
+        self._realExpBatchLineFileName = "data/realExpBatchLine.csv"
+        self._realExpIndividualFileName = "data/realExpIndividual.csv"
+        
+        self._inputDirSeveralBatches = "%s/commons/core/parsing/test/severalBatchDir" % os.environ["REPET_PATH"]
+        
+        self._obsSubSNPFileName = "SubSNP.csv"
+        self._obsAlleleFileName = "Allele.csv"
+        self._obsIndividualFileName = "Individual.csv"
+        self._obsSequenceFSAFileName = "Sequences.fsa"
+        self._obsSequenceCSVFileName = "Sequences.csv"
+        self._obsBatchFileName = "Batch.txt"
+        self._obsBatchLineFileName = "BatchLine.csv"
+        
+        self._fileUtils = FileUtils()
+
+    def tearDown(self):
+        os.chdir("%s/commons/core/parsing/test/" % os.environ["REPET_PATH"])
+        logFileName = "multifasta2SNP.log"
+        if self._fileUtils.isRessourceExists(self._inFileName):
+            os.remove(self._inFileName)
+        if self._fileUtils.isRessourceExists(self._obsSubSNPFileName):
+            os.remove(self._obsSubSNPFileName)
+        if self._fileUtils.isRessourceExists(self._obsSubSNPFileName + "_filtered"):
+            os.remove(self._obsSubSNPFileName + "_filtered")
+        if self._fileUtils.isRessourceExists(self._obsAlleleFileName):
+            os.remove(self._obsAlleleFileName)
+        if self._fileUtils.isRessourceExists(self._obsIndividualFileName):
+            os.remove(self._obsIndividualFileName)
+        if self._fileUtils.isRessourceExists(self._obsSequenceFSAFileName):
+            os.remove(self._obsSequenceFSAFileName)
+        if self._fileUtils.isRessourceExists(self._obsSequenceCSVFileName):
+            os.remove(self._obsSequenceCSVFileName)
+        if self._fileUtils.isRessourceExists(self._obsBatchFileName):
+            os.remove(self._obsBatchFileName)
+        if self._fileUtils.isRessourceExists(self._obsBatchLineFileName):
+            os.remove(self._obsBatchLineFileName)
+
+        if self._fileUtils.isRessourceExists(self._expSubSNPFileName):        
+            os.remove(self._expSubSNPFileName)
+        if self._fileUtils.isRessourceExists(self._realExpSubSNPFileName + "_filtered"):        
+            os.remove(self._realExpSubSNPFileName + "_filtered")
+        if self._fileUtils.isRessourceExists(self._expAlleleFileName):
+            os.remove(self._expAlleleFileName)
+        if self._fileUtils.isRessourceExists(self._expIndividualFileName):
+            os.remove(self._expIndividualFileName)
+        if self._fileUtils.isRessourceExists(self._expSequenceFSAFileName):
+            os.remove(self._expSequenceFSAFileName)
+        if self._fileUtils.isRessourceExists(self._expSequenceCSVFileName):
+            os.remove(self._expSequenceCSVFileName)
+        if self._fileUtils.isRessourceExists(self._expBatchFileName):
+            os.remove(self._expBatchFileName)
+        if self._fileUtils.isRessourceExists(self._expBatchLineFileName):
+            os.remove(self._expBatchLineFileName)
+            
+        if self._fileUtils.isRessourceExists(logFileName):
+            os.remove(logFileName)
+        if self._fileUtils.isRessourceExists(self._inputDirSeveralBatches):
+            shutil.rmtree(self._inputDirSeveralBatches)
+            
+            
+    def test_runOneBatch(self):
+        self._writeInputFile()
+        self._writeExpSubSNPFile()
+        self._writeExpAlleleFile()
+        self._writeExpIndividualFile()
+        self._writeExpSequenceFile()
+        self._writeExpBatchFile()
+        self._writeExpBatchLineFile()
+        
+        multifasta2SNPFile = Multifasta2SNPFile("Arabidopsis thaliana", "Batch1", "methyltransferase")
+        multifasta2SNPFile.runOneBatch(self._inFileName)
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsAlleleFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expAlleleFileName, self._obsAlleleFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsIndividualFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expIndividualFileName, self._obsIndividualFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSequenceFSAFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceFSAFileName, self._obsSequenceFSAFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSequenceCSVFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceCSVFileName, self._obsSequenceCSVFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsBatchFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchFileName, self._obsBatchFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsBatchLineFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchLineFileName, self._obsBatchLineFileName))
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSubSNPFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSubSNPFileName, self._obsSubSNPFileName))             
+
+    def test_runOneBatch_with_a_real_input_file(self):
+        self._writeRealExpAlleleFile()
+        self._writeRealExpSequenceCSVFile()
+        self._writeRealExpBatchFile()
+        
+        multifasta2SNPFile = Multifasta2SNPFile("Pinus pinaster", "INRA_Pinus_pinaster_HDZ31-1", "PpHDZ31")
+        multifasta2SNPFile.runOneBatch(self._realInputFileName)
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsIndividualFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._realExpIndividualFileName, self._obsIndividualFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSequenceFSAFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._realExpSequenceFSAFileName, self._obsSequenceFSAFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSequenceCSVFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceCSVFileName, self._obsSequenceCSVFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsBatchFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchFileName, self._obsBatchFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsBatchLineFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._realExpBatchLineFileName, self._obsBatchLineFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsAlleleFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expAlleleFileName, self._obsAlleleFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSubSNPFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._realExpSubSNPFileName , self._obsSubSNPFileName))
+        
+    def test_runOneBatch_with_errors_in_refSeq(self):
+        self._writeInputFileWithSeqErrorsInRefSeq()
+        multifasta2SNPFile = Multifasta2SNPFile("Arabidopsis thaliana", "Batch1", "methyltransferase")
+        self.assertRaises(Exception, multifasta2SNPFile.runOneBatch, self._inFileName, self._obsSubSNPFileName)
+
+    def test_runOneBatch_with_errors_in_lineSeq(self):
+        self._writeInputFileWithSeqErrorsInOneLineSeq()
+        multifasta2SNPFile = Multifasta2SNPFile("Arabidopsis thaliana", "Batch1", "methyltransferase")
+        self.assertRaises(Exception, multifasta2SNPFile.runOneBatch, self._inFileName, self._obsSubSNPFileName)
+
+    def test_runOneBatch_with_a_several_lineSeq(self):
+        self._writeInputFileWithASeveralLineSeq()
+        self._writeExpSubSNPFileSeveralLineSeq()
+        self._writeExpAlleleFile()
+        self._writeExpIndividualFile()
+        self._writeExpSequenceFileSeveralLineSeq()
+        self._writeExpBatchFile()
+        self._writeExpBatchLineFile()
+        
+        multifasta2SNPFile = Multifasta2SNPFile("Arabidopsis thaliana", "Batch1", "methyltransferase")
+        multifasta2SNPFile.runOneBatch(self._inFileName)
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSubSNPFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSubSNPFileName, self._obsSubSNPFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsAlleleFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expAlleleFileName, self._obsAlleleFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsIndividualFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expIndividualFileName, self._obsIndividualFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSequenceFSAFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceFSAFileName, self._obsSequenceFSAFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSequenceCSVFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceCSVFileName, self._obsSequenceCSVFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsBatchFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchFileName, self._obsBatchFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsBatchLineFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchLineFileName, self._obsBatchLineFileName))
+
+    def test_runOneBatch_with_2_seqs_with_the_same_name(self):
+        self._writeInputFileWith2SeqsWithTheSameName()
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        isSysExitRaised = False
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        
+        try:
+            multifasta2SNPFile.runOneBatch(self._inFileName)
+        except SystemExit:
+            isSysExitRaised = True
+            
+        self.assertTrue(isSysExitRaised)
+    
+    def test_runOneBatch_with_indels_and_snps(self):
+        self._writeInputFileWithSnpsAndIndels()
+        self._writeExpSubSNPFileWithSnpsAndIndels()
+        self._writeExpAlleleFileWithSnpsAndIndels()
+        self._writeExpIndividualFile()
+        self._writeExpSequenceFileWithDeletion()
+        self._writeExpBatchFile()
+        self._writeExpBatchLineFile()
+        
+        batchName = "Batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        multifasta2SNPFile.runOneBatch(self._inFileName)
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsIndividualFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expIndividualFileName, self._obsIndividualFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSequenceFSAFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceFSAFileName, self._obsSequenceFSAFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSequenceCSVFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceCSVFileName, self._obsSequenceCSVFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsBatchFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchFileName, self._obsBatchFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsBatchLineFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchLineFileName, self._obsBatchLineFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsAlleleFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expAlleleFileName, self._obsAlleleFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSubSNPFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSubSNPFileName, self._obsSubSNPFileName))
+        
+    def test_runOneBatchWithPotentialDooblons(self):
+        self._writeInputFileBatchWithPotentialDooblons()
+        
+        batchName = "Batch_AU247387"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        multifasta2SNPFile.runOneBatch(self._inFileName)
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSubSNPFileName))
+        
+        expSubSNPFile = "data/ExpPotDooblonsSubSNP.csv"
+        
+        Utils4Test.removeOneSpecifiedColumn(expSubSNPFile, ";", 8)
+        Utils4Test.removeOneSpecifiedColumn(self._obsSubSNPFileName, ";", 8)
+        
+        Utils4Test.removeOneSpecifiedColumn(expSubSNPFile + "_filtered", ";", 9)
+        Utils4Test.removeOneSpecifiedColumn(self._obsSubSNPFileName + "_filtered", ";", 9)
+        
+        Utils4Test.removeOneSpecifiedColumn(expSubSNPFile + "_filtered_filtered", ";", 13)
+        Utils4Test.removeOneSpecifiedColumn(self._obsSubSNPFileName + "_filtered_filtered", ";", 13)
+        
+        comparableExpSubSNPFile =  expSubSNPFile + "_filtered_filtered_filtered"
+        comparableObsSubSNPFile = self._obsSubSNPFileName +  "_filtered_filtered_filtered"
+        
+        self.assertTrue(FileUtils.isRessourceExists(comparableExpSubSNPFile))
+        self.assertTrue(FileUtils.isRessourceExists(comparableObsSubSNPFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(comparableExpSubSNPFile, comparableObsSubSNPFile))
+        
+        if(self._fileUtils.isRessourceExists(self._obsSubSNPFileName + "_filtered")):
+            os.remove(self._obsSubSNPFileName + "_filtered")
+        if(self._fileUtils.isRessourceExists(expSubSNPFile + "_filtered")):
+            os.remove(expSubSNPFile + "_filtered")
+            
+        if(self._fileUtils.isRessourceExists(self._obsSubSNPFileName + "_filtered_filtered")):
+            os.remove(self._obsSubSNPFileName + "_filtered_filtered")
+        if(self._fileUtils.isRessourceExists(expSubSNPFile + "_filtered_filtered")):
+            os.remove(expSubSNPFile + "_filtered_filtered")
+            
+        if self._fileUtils.isRessourceExists(comparableExpSubSNPFile):
+            os.remove(comparableExpSubSNPFile)
+        if self._fileUtils.isRessourceExists(comparableObsSubSNPFile):
+            os.remove(comparableObsSubSNPFile)
+    
+    def test_runSeveralBatches(self):
+        self._writeInputFileSeveralBatches()
+        self._writeExpSubSNPFileSeveralBatches()
+        self._writeExpAlleleFileSeveralBatches()
+        self._writeExpIndividualFile()
+        self._writeExpSequenceSeveralBatches()
+        self._writeExpBatchFileSeveralBatches()
+        self._writeExpBatchLineFileSeveralBatches()
+        
+        multifasta2SNPFile = Multifasta2SNPFile("Arabidopsis thaliana")
+        multifasta2SNPFile.runSeveralBatches(self._inputDirSeveralBatches)
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._inputDirSeveralBatches + "/" + self._obsAlleleFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expAlleleFileName, self._inputDirSeveralBatches + "/" + self._obsAlleleFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._inputDirSeveralBatches + "/" +self._obsIndividualFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expIndividualFileName, self._inputDirSeveralBatches + "/" + self._obsIndividualFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._inputDirSeveralBatches + "/" + self._obsSequenceFSAFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceFSAFileName, self._inputDirSeveralBatches + "/" + self._obsSequenceFSAFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._inputDirSeveralBatches + "/" + self._obsSequenceCSVFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceCSVFileName, self._inputDirSeveralBatches + "/" + self._obsSequenceCSVFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._inputDirSeveralBatches + "/" + self._obsBatchFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchFileName, self._inputDirSeveralBatches + "/" + self._obsBatchFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._inputDirSeveralBatches + "/" + self._obsBatchLineFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchLineFileName, self._inputDirSeveralBatches + "/" + self._obsBatchLineFileName))
+        self.assertTrue(FileUtils.isRessourceExists(self._inputDirSeveralBatches + "/" + self._obsSubSNPFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSubSNPFileName, self._inputDirSeveralBatches + "/" + self._obsSubSNPFileName))
+    
+    def test_runSeveralBatches_different_lines_between_files(self):
+        self._writeInputFileSeveralBatches_different_lines_between_files()
+        self._writeExpSubSNPFileSeveralBatches_different_lines_between_files()
+        self._writeExpAlleleFileSeveralBatches()
+        self._writeExpIndividualFile_different_lines_between_files()
+        self._writeExpSequenceSeveralBatches()
+        self._writeExpBatchFileSeveralBatches()
+        self._writeExpBatchLineFileSeveralBatches_different_lines_between_files()
+        
+        multifasta2SNPFile = Multifasta2SNPFile("Arabidopsis thaliana")
+        multifasta2SNPFile.runSeveralBatches(self._inputDirSeveralBatches)
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._inputDirSeveralBatches + "/" + self._obsAlleleFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expAlleleFileName, self._inputDirSeveralBatches + "/" + self._obsAlleleFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._inputDirSeveralBatches + "/" +self._obsIndividualFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expIndividualFileName, self._inputDirSeveralBatches + "/" + self._obsIndividualFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._inputDirSeveralBatches + "/" + self._obsSequenceFSAFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceFSAFileName, self._inputDirSeveralBatches + "/" + self._obsSequenceFSAFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._inputDirSeveralBatches + "/" + self._obsSequenceCSVFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceCSVFileName, self._inputDirSeveralBatches + "/" + self._obsSequenceCSVFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._inputDirSeveralBatches + "/" + self._obsBatchFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchFileName, self._inputDirSeveralBatches + "/" + self._obsBatchFileName))
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._inputDirSeveralBatches + "/" + self._obsBatchLineFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchLineFileName, self._inputDirSeveralBatches + "/" + self._obsBatchLineFileName))
+        self.assertTrue(FileUtils.isRessourceExists(self._inputDirSeveralBatches + "/" + self._obsSubSNPFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSubSNPFileName, self._inputDirSeveralBatches + "/" + self._obsSubSNPFileName))
+   
+    def test_runSeveralBatches_different_lines_and_same_refseq_between_files(self):
+        self._writeInputFileSeveralBatches_different_lines_and_same_refseq_between_files()
+        self._writeExpSubSNPFileSeveralBatches_different_lines_between_files()
+        self._writeExpAlleleFileSeveralBatches()
+        self._writeExpIndividualFile_different_lines_between_files()
+        self._writeExpSequenceSeveralBatchesForSameRefSeq()
+        self._writeExpBatchFileSeveralBatchesForSameRefSeq()
+        self._writeExpBatchLineFileSeveralBatches_different_lines_between_files()
+        
+        multifasta2SNPFile = Multifasta2SNPFile("Arabidopsis thaliana")
+        try:
+            multifasta2SNPFile.runSeveralBatches(self._inputDirSeveralBatches)
+        except Exception, e :
+            self.assertRaises(Exception, e)
+
+    def test_detectSNPAndIndels(self):
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        batchName = "batch1"        
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        refBioseq.sequence = "ATTCGCGTATGCGTATGCTT"
+        refBioseq.header = "reference"
+        
+        bs1 = Bioseq( "line1", "ATCCGCGTATGCGTATGATT" )
+        bs2 = Bioseq( "line2", "ATTCGTGTATGCGTATGGTT" )
+        
+        alignedBioseqDB.setData( [ bs1, bs2 ] )
+
+        multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        multifasta2SNPFile._dBatchResults = {'BatchNumber': 1, 'BatchName': "Batch1", 'GeneName': "methyltransferase", 'RefSeqName': "Sequence_de_Reference"}
+        multifasta2SNPFile.detectSNPsAndIndels(multifasta2SNPFile._wrapper)        
+        
+        dExpAllele = {'C': 1, 'A': 2, 'T': 3, 'G': 4 }
+        lExpSNP = [{'subSNPName': batchName + "_SNP_3_line1", 'position': 3, 'lineName': 1, 'allele': 1, '5flank': "AT", '3flank': "CGCGTATGCGTATGATT", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1}, 
+                   {'subSNPName': batchName + "_SNP_3_line2", 'position': 3, 'lineName': 2, 'allele': 3, '5flank': "AT", '3flank': "CGTGTATGCGTATGGTT", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_6_line2", 'position': 6, 'lineName': 2, 'allele': 3, '5flank': "ATTCG", '3flank': "GTATGCGTATGGTT", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_6_line1", 'position': 6, 'lineName': 1, 'allele': 1, '5flank': "ATCCG", '3flank': "GTATGCGTATGATT",'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_18_line1", 'position': 18, 'lineName': 1, 'allele': 2, '5flank': "ATCCGCGTATGCGTATG", '3flank': "TT", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_18_line2", 'position': 18, 'lineName': 2, 'allele': 4, '5flank': "ATTCGTGTATGCGTATG", '3flank': "TT", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1}]
+        lExpIndividual = [{'individualNumber': 1, 'individualName': "line1", 'scientificName': "Arabidopsis thaliana"}, 
+                          {'individualNumber': 2, 'individualName': "line2", 'scientificName': "Arabidopsis thaliana"},]
+        
+        self.assertEquals(multifasta2SNPFile._sortSubSNPResultByBatchPositionAndLineName(lExpSNP), multifasta2SNPFile._lSubSNPFileResults)
+        self.assertEquals(dExpAllele, multifasta2SNPFile._dAlleleFileResults)
+        self.assertEquals(lExpIndividual, multifasta2SNPFile._lIndividualFileResults)
+
+    def test_detectSNPAndIndels_no_polym(self):
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        batchName = "batch1"        
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        refBioseq.sequence = "ATTCGCGTATGCGTATGCTT"
+        refBioseq.header = "reference"
+        
+        bs1 = Bioseq( "line1", "ATTCGCGTATGCGTATGCTT" )
+        bs2 = Bioseq( "line2", "ATTCGCGTATGCGTATGCTT" )
+        
+        alignedBioseqDB.setData( [ bs1, bs2 ] )
+
+        instance = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        
+        multifasta2SNPFile.detectSNPsAndIndels(instance)
+        
+        lExpSNP = []
+        
+        self.assertEquals(lExpSNP, multifasta2SNPFile._lSubSNPFileResults)
+       
+    def test_detectSNPAndIndels_with_only_dels(self):
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        batchName = "batch1"        
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        refBioseq.sequence = "ATTACCGAA"
+        refBioseq.header = "reference"
+        
+        bs1 = Bioseq( "line1", "A--ACCGAA" )
+        bs2 = Bioseq( "line2", "---ACCGAA" )
+        
+        alignedBioseqDB.setData( [ bs1, bs2 ] )
+
+        multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        multifasta2SNPFile._dBatchResults = {'BatchNumber': 1, 'BatchName': "Batch1", 'GeneName': "methyltransferase", 'RefSeqName': "Sequence_de_Reference"}
+        multifasta2SNPFile.detectSNPsAndIndels(multifasta2SNPFile._wrapper)
+        
+        dExpAllele = {'A--': 1, '---': 2}
+        lExpSNP = [{'subSNPName': batchName + "_DEL_1_line2", 'position': 1, 'lineName': 2, 'allele': 2, '5flank': "", '3flank': "ACCGAA", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 3}, 
+                   {'subSNPName': batchName + "_DEL_1_line1", 'position': 1, 'lineName': 1, 'allele': 1, '5flank': "", '3flank': "ACCGAA", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 3}]
+        lExpIndividual = [{'individualNumber': 1, 'individualName': "line1", 'scientificName': "Arabidopsis thaliana"}, 
+                          {'individualNumber': 2, 'individualName': "line2", 'scientificName': "Arabidopsis thaliana"}]
+        
+        self.assertEquals(dExpAllele, multifasta2SNPFile._dAlleleFileResults)
+        self.assertEquals(multifasta2SNPFile._sortSubSNPResultByBatchPositionAndLineName(lExpSNP), multifasta2SNPFile._lSubSNPFileResults)
+        self.assertEquals(lExpIndividual, multifasta2SNPFile._lIndividualFileResults)
+    
+    def test_detectSNPAndIndels_with_dels_and_snps(self):
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        batchName = "batch1"        
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        refBioseq.sequence = "ATTACCGAA"
+        refBioseq.header = "reference"
+        
+        bs1 = Bioseq( "line1", "A--ACCGAA" )
+        bs2 = Bioseq( "line2", "---ACCGAA" )
+        bs3 = Bioseq( "line3", "ATTACCGGA" )
+        bs4 = Bioseq( "line4", "----CCGAA" )
+        
+        alignedBioseqDB.setData( [ bs1, bs2, bs3, bs4 ] )
+
+        multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        multifasta2SNPFile._dBatchResults = {'BatchNumber': 1, 'BatchName': "Batch1", 'GeneName': "methyltransferase", 'RefSeqName': "Sequence_de_Reference"}
+        multifasta2SNPFile.detectSNPsAndIndels(multifasta2SNPFile._wrapper)
+        
+        dExpAllele = {'G': 1, 'A--A': 2, '---A': 3, '----': 4, 'ATTA': 5, 'A': 6}
+        lExpSNP = [{'subSNPName': batchName + "_DEL_1_line2", 'position': 1, 'lineName': 2, 'allele': 3, '5flank': "", '3flank': "CCGAA", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 4}, 
+                   {'subSNPName': batchName + "_DEL_1_line1", 'position': 1, 'lineName': 1, 'allele': 2, '5flank': "", '3flank': "CCGAA",'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 4},
+                   {'subSNPName': batchName + "_SNP_8_line3", 'position': 8, 'lineName': 3, 'allele': 1, '5flank': "ATTACCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_8_line1", 'position': 8, 'lineName': 1, 'allele': 6, '5flank': "A--ACCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_8_line2", 'position': 8, 'lineName': 2, 'allele': 6, '5flank': "---ACCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_8_line4", 'position': 8, 'lineName': 4, 'allele': 6, '5flank': "----CCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_DEL_1_line4", 'position': 1, 'lineName': 4, 'allele': 4, '5flank': "", '3flank': "CCGAA",'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 4},
+                   {'subSNPName': batchName + "_DEL_1_line3", 'position': 1, 'lineName': 3, 'allele': 5, '5flank': "", '3flank': "CCGGA",'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 4}]
+        lExpIndividual = [{'individualNumber': 1, 'individualName': "line1", 'scientificName': "Arabidopsis thaliana"}, 
+                          {'individualNumber': 2, 'individualName': "line2", 'scientificName': "Arabidopsis thaliana"},
+                          {'individualNumber': 3, 'individualName': "line3", 'scientificName': "Arabidopsis thaliana"},
+                          {'individualNumber': 4, 'individualName': "line4", 'scientificName': "Arabidopsis thaliana"}]
+        
+        self.assertEquals(dExpAllele, multifasta2SNPFile._dAlleleFileResults)
+        self.assertEquals(multifasta2SNPFile._sortSubSNPResultByBatchPositionAndLineName(lExpSNP), multifasta2SNPFile._lSubSNPFileResults)
+        self.assertEquals(lExpIndividual, multifasta2SNPFile._lIndividualFileResults)
+    
+    def test_detectSNPAndIndels_with_only_inserts(self):
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        batchName = "batch1"        
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        refBioseq.sequence = "A--ACCGAA"
+        refBioseq.header = "reference"
+        
+        bs1 = Bioseq( "line1", "A--ACCGAA" )
+        bs2 = Bioseq( "line2", "AG-ACCGAA" )
+        bs3 = Bioseq( "line3", "ATTACCGAA" )
+        
+        alignedBioseqDB.setData( [ bs1, bs2, bs3 ] )
+
+        multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        multifasta2SNPFile._dBatchResults = {'BatchNumber': 1, 'BatchName': "Batch1", 'GeneName': "methyltransferase", 'RefSeqName': "Sequence_de_Reference"}
+        multifasta2SNPFile.detectSNPsAndIndels(multifasta2SNPFile._wrapper)
+        
+        dExpAllele = {'G-': 1, 'TT': 2, '--': 3}
+        lExpSNP = [{'subSNPName': batchName + "_INS_1_line2", 'position': 1, 'lineName': 2, 'allele': 1, '5flank': "A", '3flank': "ACCGAA", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "INSERTION", 'length': 2}, 
+                   {'subSNPName': batchName + "_INS_1_line3", 'position': 1, 'lineName': 3, 'allele': 2, '5flank': "A", '3flank': "ACCGAA", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "INSERTION", 'length': 2},
+                   {'subSNPName': batchName + "_INS_1_line1", 'position': 1, 'lineName': 1, 'allele': 3, '5flank': "A", '3flank': "ACCGAA", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "INSERTION", 'length': 2}]
+        lExpIndividual = [{'individualNumber': 1, 'individualName': "line1", 'scientificName': "Arabidopsis thaliana"}, 
+                          {'individualNumber': 2, 'individualName': "line2", 'scientificName': "Arabidopsis thaliana"},
+                          {'individualNumber': 3, 'individualName': "line3", 'scientificName': "Arabidopsis thaliana"}]
+        
+        self.assertEquals(dExpAllele, multifasta2SNPFile._dAlleleFileResults)
+        self.assertEquals(multifasta2SNPFile._sortSubSNPResultByBatchPositionAndLineName(lExpSNP), multifasta2SNPFile._lSubSNPFileResults)
+        self.assertEquals(lExpIndividual, multifasta2SNPFile._lIndividualFileResults)
+
+    def test_detectSNPAndIndels_with_snps_and_inserts(self):
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        batchName = "batch1"        
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        refBioseq.sequence = "A--ACCGAA"
+        refBioseq.header = "reference"
+        
+        bs1 = Bioseq( "line1", "A--ACCGAA" )
+        bs2 = Bioseq( "line2", "AG-ACCGAA" )
+        bs3 = Bioseq( "line3", "ATTACCGCA" )
+        
+        alignedBioseqDB.setData( [ bs1, bs2, bs3 ] )
+
+        multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        multifasta2SNPFile._dBatchResults = {'BatchNumber': 1, 'BatchName': "Batch1", 'GeneName': "methyltransferase", 'RefSeqName': "Sequence_de_Reference"}
+        multifasta2SNPFile.detectSNPsAndIndels(multifasta2SNPFile._wrapper)
+        
+        dExpAllele = {'C': 1, 'G-': 2, 'TT': 3, '--': 4, 'A' : 5}
+        lExpSNP = [{'subSNPName': batchName + "_SNP_6_line3", 'position': 6, 'lineName': 3, 'allele': 1, '5flank': "ATTACCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_6_line1", 'position': 6, 'lineName': 1, 'allele': 5, '5flank': "A--ACCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_6_line2", 'position': 6, 'lineName': 2, 'allele': 5, '5flank': "AG-ACCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1}, 
+                   {'subSNPName': batchName + "_INS_1_line2", 'position': 1, 'lineName': 2, 'allele': 2, '5flank': "A", '3flank': "ACCGAA", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "INSERTION", 'length': 2},
+                   {'subSNPName': batchName + "_INS_1_line3", 'position': 1, 'lineName': 3, 'allele': 3, '5flank': "A", '3flank': "ACCGCA", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "INSERTION", 'length': 2},
+                   {'subSNPName': batchName + "_INS_1_line1", 'position': 1, 'lineName': 1, 'allele': 4, '5flank': "A", '3flank': "ACCGAA", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "INSERTION", 'length': 2}]
+        lExpIndividual = [{'individualNumber': 1, 'individualName': "line1", 'scientificName': "Arabidopsis thaliana"}, 
+                          {'individualNumber': 2, 'individualName': "line2", 'scientificName': "Arabidopsis thaliana"},
+                          {'individualNumber': 3, 'individualName': "line3", 'scientificName': "Arabidopsis thaliana"}]
+        
+        self.assertEquals(dExpAllele, multifasta2SNPFile._dAlleleFileResults)
+        self.assertEquals(multifasta2SNPFile._sortSubSNPResultByBatchPositionAndLineName(lExpSNP), multifasta2SNPFile._lSubSNPFileResults)
+        self.assertEquals(lExpIndividual, multifasta2SNPFile._lIndividualFileResults)
+        
+    def test_detectSNPAndIndels_with_snps_inserts_and_dels(self):
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        batchName = "batch1"        
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        refBioseq.sequence = "A--ACCGAATATAC"
+        refBioseq.header = "reference"
+        
+        bs1 = Bioseq( "line1", "A--ACCGAATATAC" )
+        bs2 = Bioseq( "line2", "AG-ACCGAAT--AC" )
+        bs3 = Bioseq( "line3", "ATTACCGCA-----" )
+        
+        alignedBioseqDB.setData( [ bs1, bs2, bs3 ] )
+
+        multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        multifasta2SNPFile._dBatchResults = {'BatchNumber': 1, 'BatchName': "Batch1", 'GeneName': "methyltransferase", 'RefSeqName': "Sequence_de_Reference"}
+        multifasta2SNPFile.detectSNPsAndIndels(multifasta2SNPFile._wrapper)
+        
+        dExpAllele = {'C': 1, 'G-': 2, 'T--AC': 3, 'TT': 4, '-----': 5, '--': 6, 'TATAC': 7, 'A': 8}
+        lExpSNP = [{'subSNPName': batchName + "_SNP_6_line3", 'position': 6, 'lineName': 3, 'allele': 1, '5flank': "ATTACCG", '3flank': "A-----", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1}, 
+                   {'subSNPName': batchName + "_SNP_6_line1", 'position': 6, 'lineName': 1, 'allele': 8, '5flank': "A--ACCG", '3flank': "ATATAC", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_6_line2", 'position': 6, 'lineName': 2, 'allele': 8, '5flank': "AG-ACCG", '3flank': "AT--AC", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   
+                   {'subSNPName': batchName + "_INS_1_line2", 'position': 1, 'lineName': 2, 'allele': 2, '5flank': "A", '3flank': "ACCGAAT--AC", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "INSERTION", 'length': 2},
+                   {'subSNPName': batchName + "_INS_1_line3", 'position': 1, 'lineName': 3, 'allele': 4, '5flank': "A", '3flank': "ACCGCA-----", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "INSERTION", 'length': 2},
+                   {'subSNPName': batchName + "_INS_1_line1", 'position': 1, 'lineName': 1, 'allele': 6, '5flank': "A", '3flank': "ACCGAATATAC", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "INSERTION", 'length': 2},
+                                      
+                   {'subSNPName': batchName + "_DEL_8_line2", 'position': 8, 'lineName': 2, 'allele': 3, '5flank': "AG-ACCGAA", '3flank': "", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 5},
+                   {'subSNPName': batchName + "_DEL_8_line3", 'position': 8, 'lineName': 3, 'allele': 5, '5flank': "ATTACCGCA", '3flank': "", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 5},
+                   {'subSNPName': batchName + "_DEL_8_line1", 'position': 8, 'lineName': 1, 'allele': 7, '5flank': "A--ACCGAA", '3flank': "", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 5}]
+        lExpIndividual = [{'individualNumber': 1, 'individualName': "line1", 'scientificName': "Arabidopsis thaliana"}, 
+                          {'individualNumber': 2, 'individualName': "line2", 'scientificName': "Arabidopsis thaliana"},
+                          {'individualNumber': 3, 'individualName': "line3", 'scientificName': "Arabidopsis thaliana"}]
+        
+        self.assertEquals(dExpAllele, multifasta2SNPFile._dAlleleFileResults)
+        self.assertEquals(multifasta2SNPFile._sortSubSNPResultByBatchPositionAndLineName(lExpSNP), multifasta2SNPFile._lSubSNPFileResults)
+        self.assertEquals(lExpIndividual, multifasta2SNPFile._lIndividualFileResults)
+        
+    def test_createWrapperFromFile_with_upcase_and_lowcase_nucleotide(self):
+        self._writeInputFileWithUpcaseAndLowcaseNucleotide()
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+       
+        expLineBioseqDB = BioseqDB()
+        expRefBioseq = Bioseq("Sequence_de_Reference",\
+                                 "CCTAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATCCGCAGTAGCCAAACCTCCACAATA")
+        iBioSeq = Bioseq("Line1","CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATCCGCAGTAGCCAAACCTCCACAATA")
+        expLineBioseqDB.add ( iBioSeq )
+        iBioSeq = Bioseq("Line2","CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATACGCAGTAGCCAAACCTCCACAATA")
+        expLineBioseqDB.add ( iBioSeq )
+        
+        expBioseqDBWrapper = ReferenceBioseqAndLinesBioseqDBWrapper (expRefBioseq, expLineBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        
+        obsBioseqDBWrapper = multifasta2SNPFile.createWrapperFromFile(self._inFileName)
+    
+        self.assertEquals(obsBioseqDBWrapper._iReferenceBioseq, expBioseqDBWrapper._iReferenceBioseq)
+        self.assertEquals(obsBioseqDBWrapper._iLinesBioseqDB, expBioseqDBWrapper._iLinesBioseqDB)
+            
+    def test_checkHeaderAlphabet(self):
+        # header ALPHABET [^a-zA-Z0-9_-:]
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        strToBeCheck="abcdefghijklmnopqrstuvwxyz0912834567_:-"
+        self.assertTrue ( multifasta2SNPFile.checkHeaderAlphabet(strToBeCheck))
+        strToBeCheck="ABCDEFGHIJKLMNOPQRSTUVWXYZ0912834567_:-"
+        self.assertTrue ( multifasta2SNPFile.checkHeaderAlphabet(strToBeCheck)) 
+        
+    def test_checkHeaderAlphabet_empty_string(self):
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        strToBeCheck=""
+        self.assertFalse ( multifasta2SNPFile.checkHeaderAlphabet(strToBeCheck))
+      
+    def test_checkHeaderAlphabet_space(self):
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        strToBeCheck=" "
+        self.assertFalse ( multifasta2SNPFile.checkHeaderAlphabet(strToBeCheck))
+      
+    def test_checkHeaderAlphabet_non_aphabetical(self):
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        strToBeCheck="}"
+        self.assertFalse ( multifasta2SNPFile.checkHeaderAlphabet(strToBeCheck))
+    
+    def test_isDNA_bases( self ):
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        strToBeCheck="TGTGGCTTCTAGTTGATCAGTTTATGATCACAATGATTTCACGTAGGTGTCTCGTGGCTCCGACTAATCAACAATATAATGCGAGTAGAGCTTGA"
+        self.assertTrue ( multifasta2SNPFile.isDNA_bases(strToBeCheck))
+
+    def test_isDNA_bases_non_DNA_letter( self ):
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        strToBeCheck="XTAGTTGATCA"
+        self.assertFalse ( multifasta2SNPFile.isDNA_bases(strToBeCheck))
+    
+    def test_isDNA_bases_carriage_return( self ):    
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        strToBeCheck="TA\nGTTGATCA"
+        self.assertFalse ( multifasta2SNPFile.isDNA_bases(strToBeCheck))
+    
+    def test_isDNA_bases_empty_string( self ):
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        strToBeCheck=""
+        self.assertFalse ( multifasta2SNPFile.isDNA_bases(strToBeCheck))
+        
+    def test_isDNA_bases_space( self ):
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        strToBeCheck=" "
+        self.assertFalse ( multifasta2SNPFile.isDNA_bases(strToBeCheck))
+    
+    def test_isDNA_bases_IUPAC_letter_but_non_DNA_bases( self ):
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        strToBeCheck="UMWSB"
+        self.assertFalse ( multifasta2SNPFile.isDNA_bases(strToBeCheck))
+    
+    def test_getLineAsAHeader (self):
+        lineToBeCheck=">test on good header"
+        batchName = "batch1"
+        expHeader = "test_on_good_header"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        obsHeader = multifasta2SNPFile.getLineAsAHeader(lineToBeCheck)
+        self.assertEqual(obsHeader,expHeader)
+                            
+    def test_getLineAsAHeader_warning_bad_header_tag_omitted(self):
+        
+        lineToBeCheck="test on bad header with tag omitted"
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        try :
+            expHeader = multifasta2SNPFile.getLineAsAHeader( lineToBeCheck )
+        except Exception, e :
+            self.assertRaises(Exception, e , self._inFileName, self._obsSubSNPFileName)
+        
+    def test_getLineAsAHeader_warning_repeated_blanks_removed(self):
+        
+        lineToBeCheck =">test     on header \twith  warning"
+        expHeader = "test_on_header_with_warning"
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        obsHeader = multifasta2SNPFile.getLineAsAHeader( lineToBeCheck )
+        self.assertEquals( obsHeader, expHeader)
+        self.assertRaises(Exception, multifasta2SNPFile.getLineAsAHeader( lineToBeCheck ) , self._inFileName, self._obsSubSNPFileName)
+        
+    def test_getLineAsAHeader_fatal_error_bad_header(self):
+        lineToBeCheck=">test\on bad header with fatal error"
+                 
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        try :
+            expHeader = multifasta2SNPFile.getLineAsAHeader( lineToBeCheck )
+        except Exception, e :
+            self.assertRaises(Exception, e , self._inFileName, self._obsSubSNPFileName)
+
+    def test_isHeaderInRefSeqList(self):
+        header = "line1"
+        bs1 = Bioseq( "line1", "A--ACCGAATATAC" )
+        bs2 = Bioseq( "line2", "AG-ACCGAAT--AC" )
+        bs3 = Bioseq( "line3", "ATTACCGCA-----" )
+        
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        multifasta2SNPFile._lRefSequences = [bs1, bs2, bs3]
+        try:
+            isHeader = multifasta2SNPFile.isHeaderInRefSeqList(header)
+        except Exception, e :
+            self.assertRaises(Exception, e)
+            
+    def test_completeAlleleSetWithCurrentAllele_one_allele_added(self):
+        dAlleleSetInInput = {"A" : 1,
+                             "T" : 2,
+                             "G" : 3}
+        alleleToAdd = "C"       
+        dAlleleExpSet =  {"A" : 1,
+                          "T" : 2,
+                          "G" : 3,
+                          "C" : 4}
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        dAlleleObsSet = multifasta2SNPFile._completeAlleleSetWithCurrentAllele(dAlleleSetInInput, alleleToAdd)
+        self.assertEquals(dAlleleObsSet, dAlleleExpSet)
+        
+    def test_completeAlleleSetWithCurrentAllele_no_allele_added(self):
+        dAlleleSetInInput = {"A" : 1,
+                             "T" : 2,
+                             "G" : 3}
+        alleleToAdd = "T"       
+        dAlleleExpSet =  {"A" : 1,
+                          "T" : 2,
+                          "G" : 3}
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        dAlleleObsSet = multifasta2SNPFile._completeAlleleSetWithCurrentAllele(dAlleleSetInInput, alleleToAdd)
+        self.assertEquals(dAlleleObsSet, dAlleleExpSet)
+        
+    def test_completeAlleleSetWithCurrentAllele_with_an_empty_allele_set(self):
+        dAlleleSetInInput = {}
+        alleleToAdd = "T"       
+        dAlleleExpSet =  {"T" : 1}
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        dAlleleObsSet = multifasta2SNPFile._completeAlleleSetWithCurrentAllele(dAlleleSetInInput, alleleToAdd)
+        self.assertEquals(dAlleleObsSet, dAlleleExpSet)
+        
+    def test_completeBatchLineListWithCurrentIndividual(self):
+        #TODO: this test only pass with a batchNumber of 1
+        iCurrentBatchNumber = 1
+        lBatchLineResults = [{'IndividualNumber': "1", 'BatchNumber': iCurrentBatchNumber},
+                             {'IndividualNumber': "2", 'BatchNumber': iCurrentBatchNumber}]
+        lIndividualResults = [{'individualNumber': 1, 'individualName': "Individual1", 'scientificName': "Arabidopsis thaliana"},
+                              {'individualNumber': 2, 'individualName': "Individual2", 'scientificName': "Arabidopsis thaliana"},
+                              {'individualNumber': 3, 'individualName': "Individual3", 'scientificName': "Arabidopsis thaliana"}]
+        lExpBatchLineResults = [{'IndividualNumber': "1", 'BatchNumber': iCurrentBatchNumber},
+                                {'IndividualNumber': "2", 'BatchNumber': iCurrentBatchNumber},
+                                {'IndividualNumber': "3", 'BatchNumber': iCurrentBatchNumber}]
+        lineName2Add = "Individual3"
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        lBatchLineResults = multifasta2SNPFile._completeBatchLineListWithCurrentIndividual(lBatchLineResults, lIndividualResults, lineName2Add)
+        self.assertEquals(lBatchLineResults, lExpBatchLineResults)
+    
+    def test_completeBatchLineListWithCurrentIndividual_no_entries_in_batchline_results_in_input(self):
+        lBatchLineResults = []
+        lIndividualResults = [{'individualNumber': 1, 'individualName': "Individual1", 'scientificName': "Arabidopsis thaliana"},
+                              {'individualNumber': 2, 'individualName': "Individual2", 'scientificName': "Arabidopsis thaliana"},
+                              {'individualNumber': 3, 'individualName': "Individual3", 'scientificName': "Arabidopsis thaliana"}]
+        lExpBatchLineResults = [{'IndividualNumber': "2", 'BatchNumber': 1}]
+        lineName2Add = "Individual2"
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        lBatchLineResults = multifasta2SNPFile._completeBatchLineListWithCurrentIndividual(lBatchLineResults, lIndividualResults, lineName2Add)
+        self.assertEquals(lBatchLineResults, lExpBatchLineResults)
+    
+    def test_completeBatchLineListWithCurrentIndividual_no_individual_in_individualList(self):
+        lBatchLineResults = [{'IndividualNumber': "1", 'BatchNumber': 1},
+                             {'IndividualNumber': "2", 'BatchNumber': 1}]
+        lIndividualResults = []
+
+        lineName2Add = "Individual3"
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        try:
+            lBatchLineResults = multifasta2SNPFile._completeBatchLineListWithCurrentIndividual(lBatchLineResults, lIndividualResults, lineName2Add)
+        except Exception, e :
+            self.assertRaises(Exception, e)
+    
+    def test_completeBatchLineListWithCurrentIndividual_individual_added_has_no_individual_number(self):
+        lBatchLineResults = [{'IndividualNumber': "1", 'BatchNumber': "1"},
+                             {'IndividualNumber': "2", 'BatchNumber': "1"}]
+        lIndividualResults = [{'individualNumber': 1, 'individualName': "Individual1", 'scientificName': "Arabidopsis thaliana"},
+                              {'individualNumber': 2, 'individualName': "Individual2", 'scientificName': "Arabidopsis thaliana"},
+                              {'individualName': "Individual3", 'scientificName': "Arabidopsis thaliana"}]
+
+        lineName2Add = "Individual3"
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        try:
+            lBatchLineResults = multifasta2SNPFile._completeBatchLineListWithCurrentIndividual(lBatchLineResults, lIndividualResults, lineName2Add)
+        except Exception, e :
+            self.assertRaises(Exception, e)
+            
+    def test_completeBatchLineListWithCurrentIndividual_individual_not_present_in_individualList(self):
+        lBatchLineResults = [{'IndividualNumber': "1", 'BatchNumber': "1"},
+                             {'IndividualNumber': "2", 'BatchNumber': "1"}]
+        lIndividualResults = [{'individualNumber': 1, 'individualName': "Individual1", 'scientificName': "Arabidopsis thaliana"},
+                              {'individualNumber': 2, 'individualName': "Individual2", 'scientificName': "Arabidopsis thaliana"},
+                              {'individualNumber': 3, 'individualName': "Individual3", 'scientificName': "Arabidopsis thaliana"}]
+
+        lineName2Add = "Michael Corleone"
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        try:
+            lBatchLineResults = multifasta2SNPFile._completeBatchLineListWithCurrentIndividual(lBatchLineResults, lIndividualResults, lineName2Add)
+        except Exception, e :
+            self.assertRaises(Exception, e)
+      
+    def test_findASubSNPInAListWithHisName(self):
+        lSubSNPList = [{'subSNPName': "SubSNP_batch1_1_line2", 'position': 1, 'lineName': 2, 'allele': 2, 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION"},
+                       {'subSNPName': "SubSNP_batch1_2_line1", 'position': 1, 'lineName': 1, 'allele': 1, 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION"},
+                       {'subSNPName': "SubSNP_batch1_6_line1", 'position': 6, 'lineName': 1, 'allele': 3, 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP"}]
+        name = "SubSNP_batch1_2_line1"
+        
+        dExpSubSNP = {'subSNPName': "SubSNP_batch1_2_line1", 'position': 1, 'lineName': 1, 'allele': 1, 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION"}
+        expIndice = 1
+           
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        
+        dObsSubSNP, obsIndice = multifasta2SNPFile.findASubSNPInAListWithHisName(name, lSubSNPList)
+        
+        self.assertEquals(expIndice, obsIndice)
+        self.assertEquals(dExpSubSNP, dObsSubSNP)
+        
+    def test_findASubSNPInAListWithHisName_SubSNP_not_found(self):
+        lSubSNPList = [{'subSNPName': "SubSNP_batch1_1_line2", 'position': 1, 'lineName': 2, 'allele': 2, 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION"},
+                       {'subSNPName': "SubSNP_batch1_2_line1", 'position': 1, 'lineName': 1, 'allele': 1, 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION"},
+                       {'subSNPName': "SubSNP_batch1_6_line1", 'position': 6, 'lineName': 1, 'allele': 3, 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP"}]
+        name = "SubSNP_fake"
+           
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        
+        try:
+            dObsSubSNP, obsIndice = multifasta2SNPFile.findASubSNPInAListWithHisName(name, lSubSNPList)
+        except Exception, e :
+            self.assertRaises(Exception, e)
+            
+    def test_clusteriseIndels(self):
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        lObsIndelsList = [{'name' : "indel1", 'start': 1, 'end': 6},
+                          {'name' : "indel2", 'start': 12, 'end': 15},
+                          {'name' : "indel3",'start': 5, 'end': 10}]
+        dIndel = {'start': 1, 'end': 6}
+        
+        lObsIndelsList = multifasta2SNPFile.clusteriseIndels(dIndel, lObsIndelsList)
+        lexpIndelsList = [{'name' : "indel1", 'start': 1, 'end': 10},
+                          {'name' : "indel2", 'start': 12, 'end': 15},
+                          {'name' : "indel3", 'start': 1, 'end': 10}]
+        
+        self.assertEquals(lexpIndelsList, lObsIndelsList)
+    
+    def test_clusteriseIndels_no_overlap(self):
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        lObsIndelsList = [{'name' : "indel1", 'start': 1, 'end': 6},
+                          {'name' : "indel2", 'start': 12, 'end': 15},
+                          {'name' : "indel3",'start': 25, 'end': 30}]
+        dIndel = {'start': 1, 'end': 6}
+        
+        lObsIndelsList = multifasta2SNPFile.clusteriseIndels(dIndel, lObsIndelsList)
+        lexpIndelsList = [{'name' : "indel1", 'start': 1, 'end': 6},
+                          {'name' : "indel2", 'start': 12, 'end': 15},
+                          {'name' : "indel3", 'start': 25, 'end': 30}]
+        
+        self.assertEquals(lexpIndelsList, lObsIndelsList)
+        
+    def test_clusteriseIndels_many_overlaps_complicated(self):
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        lObsIndelsList = [{'name' : "indel1", 'start': 1, 'end': 6},
+                          {'name' : "indel2", 'start': 12, 'end': 15},
+                          {'name' : "indel3",'start': 5, 'end': 10},
+                          {'name' : "indel4",'start': 9, 'end': 40}]
+        dIndel = {'start': 5, 'end': 10}
+        
+        lObsIndelsList = multifasta2SNPFile.clusteriseIndels(dIndel, lObsIndelsList)
+        lexpIndelsList = [{'name' : "indel1", 'start': 1, 'end': 40},
+                          {'name' : "indel2", 'start': 1, 'end': 40},
+                          {'name' : "indel3", 'start': 1, 'end': 40},
+                          {'name' : "indel4",'start': 1, 'end': 40}]
+        
+        self.assertEquals(lexpIndelsList, lObsIndelsList)
+    
+    def test_updateBoundsForAnIndelInAnIndelList(self):
+        lIndelsList = [{'name' : "indel1", 'start': 1, 'end': 6},
+                       {'name' : "indel2", 'start': 12, 'end': 15},
+                       {'name' : "indel3",'start': 5, 'end': 10},
+                       {'name' : "indel4",'start': 9, 'end': 40}]
+        dIndelWithNewBounds = {'name': "indel2", 'start': 7, 'end': 19}
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        lObsNewIndelsList = multifasta2SNPFile.updateBoundsForAnIndelInAnIndelList(lIndelsList, dIndelWithNewBounds)
+        lExpNewIndelsList = [{'name' : "indel1", 'start': 1, 'end': 6},
+                             {'name' : "indel2", 'start': 7, 'end': 19},
+                             {'name' : "indel3",'start': 5, 'end': 10},
+                             {'name' : "indel4",'start': 9, 'end': 40}]
+        self.assertEquals(lExpNewIndelsList, lObsNewIndelsList)
+        
+    def test_updateBoundsForAnIndelInAnIndelList_no_update_to_do(self):
+        lIndelsList = [{'name' : "indel1", 'start': 1, 'end': 6},
+                       {'name' : "indel2", 'start': 12, 'end': 15},
+                       {'name' : "indel3",'start': 5, 'end': 10},
+                       {'name' : "indel4",'start': 9, 'end': 40}]
+        dIndelWithNewBounds = {'name': "indel2", 'start': 12, 'end': 15}
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        lObsNewIndelsList = multifasta2SNPFile.updateBoundsForAnIndelInAnIndelList(lIndelsList, dIndelWithNewBounds)
+        lExpNewIndelsList = [{'name' : "indel1", 'start': 1, 'end': 6},
+                             {'name' : "indel2", 'start': 12, 'end': 15},
+                             {'name' : "indel3",'start': 5, 'end': 10},
+                             {'name' : "indel4",'start': 9, 'end': 40}]
+        self.assertEquals(lExpNewIndelsList, lObsNewIndelsList)
+        
+    def test_updateBoundsForAnIndelInAnIndelList_indel_2_update_does_not_exist(self):
+        lIndelsList = [{'name' : "indel1", 'start': 1, 'end': 6},
+                       {'name' : "indel2", 'start': 12, 'end': 15},
+                       {'name' : "indel3",'start': 5, 'end': 10},
+                       {'name' : "indel4",'start': 9, 'end': 40}]
+        dIndelWithNewBounds = {'name': "DeNiro", 'start': 12, 'end': 15}
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        try:
+            lObsNewIndelsList = multifasta2SNPFile.updateBoundsForAnIndelInAnIndelList(lIndelsList, dIndelWithNewBounds)
+        except Exception, e :
+            self.assertRaises(Exception, e)
+        
+    def test_mergeBoundsFor2Indels(self):
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        dIndel1 = {'start': 1, 'end': 4}
+        dIndel2 = {'start': 2, 'end': 15}
+        dIndel1, dIndel2 = multifasta2SNPFile.mergeBoundsForTwoOverlappingIndels(dIndel1, dIndel2)
+        dExpIndel1 = {'start': 1, 'end': 15}
+        dExpIndel2 = {'start': 1, 'end': 15}
+        self.assertEquals(dExpIndel1, dIndel1)
+        self.assertEquals(dExpIndel2, dIndel2)
+    
+    def test_mergeBoundsFor2Indels_no_overlap(self):
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        dIndel1 = {'start': 1, 'end': 4}
+        dIndel2 = {'start': 5, 'end': 15}
+        dIndel1, dIndel2 = multifasta2SNPFile.mergeBoundsForTwoOverlappingIndels(dIndel1, dIndel2)
+        dExpIndel1 = {'start': 1, 'end': 4}
+        dExpIndel2 = {'start': 5, 'end': 15}
+        self.assertEquals(dExpIndel1, dIndel1)
+        self.assertEquals(dExpIndel2, dIndel2)
+        
+    def test_getUngappedPositionInRefSeq(self):
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        refBioseq.sequence = "A--TTACC-GAA"
+        refBioseq.header = "reference"        
+        bs1 = Bioseq( "line1", "AACTTTCCAGAA" )
+        bs2 = Bioseq( "line2", "AACTTACC-GAA" )
+        
+        alignedBioseqDB.setData( [ bs1, bs2 ] )
+
+        multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        
+        expUngappedPositionFor1 = 1
+        obsUngappedPositionFor1 = multifasta2SNPFile.getUngappedPositionInRefSeq(1)
+        expUngappedPositionFor5 = 3
+        obsUngappedPositionFor5 = multifasta2SNPFile.getUngappedPositionInRefSeq(5)
+        expUngappedPositionFor10 = 7
+        obsUngappedPositionFor10 = multifasta2SNPFile.getUngappedPositionInRefSeq(10)
+        
+        self.assertEquals(expUngappedPositionFor1, obsUngappedPositionFor1)
+        self.assertEquals(expUngappedPositionFor5, obsUngappedPositionFor5)
+        self.assertEquals(expUngappedPositionFor10, obsUngappedPositionFor10)
+                  
+    def test_getUngappedPositionInRefSeq_no_gap(self):
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        refBioseq.sequence = "AACTTACCAGAA"
+        refBioseq.header = "reference"        
+        bs1 = Bioseq( "line1", "AACTTTCCAGAA" )
+        bs2 = Bioseq( "line2", "AACTTACC-GAA" )
+        
+        alignedBioseqDB.setData( [ bs1, bs2 ] )
+
+        multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        
+        expUngappedPositionFor1 = 1
+        obsUngappedPositionFor1 = multifasta2SNPFile.getUngappedPositionInRefSeq(1)
+        expUngappedPositionFor5 = 5
+        obsUngappedPositionFor5 = multifasta2SNPFile.getUngappedPositionInRefSeq(5)
+        expUngappedPositionFor10 = 10
+        obsUngappedPositionFor10 = multifasta2SNPFile.getUngappedPositionInRefSeq(10)
+        
+        self.assertEquals(expUngappedPositionFor1, obsUngappedPositionFor1)
+        self.assertEquals(expUngappedPositionFor5, obsUngappedPositionFor5)
+        self.assertEquals(expUngappedPositionFor10, obsUngappedPositionFor10)
+        
+    def test_checkAllSeq_sequences_with_different_sizes_one_seq_longer(self):
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        refBioseq.sequence = "AACTTACCAGAA"
+        refBioseq.header = "reference"        
+        bs1 = Bioseq( "line1", "AACTTTCCAGAA" )
+        bs2 = Bioseq( "line2", "AACTTACC-GAATTTC" )
+        
+        alignedBioseqDB.setData( [ bs1, bs2 ] )
+        
+        try:
+            multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        except Exception, e :
+            self.assertRaises(Exception, e)
+            obsMsg = e.message
+        expMsg = "File: " + self._inFileName + ", problem with the sequence " + bs2.header + ": its length is different from the reference seq! All the sequences must have the same length.\n"
+        expMsg += "refseq length: " + str(len(refBioseq.sequence)) + "\n"
+        expMsg += "seq length: " + str(len(bs2.sequence)) + "\n"
+        self.assertEquals(expMsg, obsMsg)
+        
+    def test_checkAllSeq_sequences_with_different_sizes_one_seq_shorter(self):
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        refBioseq.sequence = "AACTTACCAGAA"
+        refBioseq.header = "reference"        
+        bs1 = Bioseq( "line1", "AACTTTCCAGAA" )
+        bs2 = Bioseq( "line2", "AACTTACC" )
+        
+        alignedBioseqDB.setData( [ bs1, bs2 ] )
+        
+        try:
+            multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        except Exception, e :
+            self.assertRaises(Exception, e)
+            obsMsg = e.message
+        expMsg = "File: " + self._inFileName + ", problem with the sequence " + bs2.header + ": its length is different from the reference seq! All the sequences must have the same length.\n"
+        expMsg += "refseq length: " + str(len(refBioseq.sequence)) + "\n"
+        expMsg += "seq length: " + str(len(bs2.sequence)) + "\n"
+        self.assertEquals(expMsg, obsMsg)
+        
+        
+    def test_getFlanksOfASubSNP(self):    
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        refBioseq.sequence = "AACTTACCAGAA"
+        refBioseq.header = "reference"        
+        bs1 = Bioseq( "line1", "AACTTTCCAGAA" )
+        bs2 = Bioseq( "line2", "AACTTACC-GAA" )
+        alignedBioseqDB.setData( [ bs1, bs2 ] )
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        subsnpPosition = 3
+        polymLength = 3
+        lineName = "line1"
+        exp5flank = "AA"
+        exp3flank = "TCCAGAA"
+        
+        obs5flank, obs3flank = multifasta2SNPFile.getFlanksOfASubSNP(lineName, subsnpPosition, polymLength, 7)
+        self.assertEquals(exp5flank,  obs5flank)
+        self.assertEquals(exp3flank,  obs3flank)
+        
+    def test_getFlanksOfASubSNP_flank_truncated(self):    
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        refBioseq.sequence = "AACTTACCAGAA"
+        refBioseq.header = "reference"        
+        bs1 = Bioseq( "line1", "AACTTTCCAGAA" )
+        bs2 = Bioseq( "line2", "AACTTACC-GAA" )
+        alignedBioseqDB.setData( [ bs1, bs2 ] )
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        subsnpPosition = 3
+        polymLength = 3
+        lineName = "line1"
+        exp5flank = "AA"
+        exp3flank = "TCCAGAA"
+        
+        obs5flank, obs3flank = multifasta2SNPFile.getFlanksOfASubSNP(lineName, subsnpPosition, polymLength, 500)
+        self.assertEquals(exp5flank,  obs5flank)
+        self.assertEquals(exp3flank,  obs3flank)
+        
+    def test_getFlanksOfASubSNP_empty_seq(self):    
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        refBioseq.sequence = ""
+        refBioseq.header = "reference"        
+        bs1 = Bioseq( "line1", "" )
+        bs2 = Bioseq( "line2", "" )
+        alignedBioseqDB.setData( [ bs1, bs2 ] )
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        subsnpPosition = 3
+        polymLength = 3
+        lineName = "line1"
+        exp5flank = ""
+        exp3flank = ""
+        
+        obs5flank, obs3flank = multifasta2SNPFile.getFlanksOfASubSNP(lineName, subsnpPosition, polymLength, 500)
+        self.assertEquals(exp5flank,  obs5flank)
+        self.assertEquals(exp3flank,  obs3flank)
+        
+    def test_getFlanksOfASubSNP_flank_of_first_base(self):    
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        refBioseq.sequence = "AACTTACCAGAA"
+        refBioseq.header = "reference"        
+        bs1 = Bioseq( "line1", "AACTTTCCAGAA" )
+        bs2 = Bioseq( "line2", "AACTTACC-GAA" )
+        alignedBioseqDB.setData( [ bs1, bs2 ] )
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        subsnpPosition = 1
+        polymLength = 1
+        lineName = "line1"
+        exp5flank = ""
+        exp3flank = "ACTTTCCAGAA"
+        
+        obs5flank, obs3flank = multifasta2SNPFile.getFlanksOfASubSNP(lineName, subsnpPosition, polymLength, 500)
+        self.assertEquals(exp5flank,  obs5flank)
+        self.assertEquals(exp3flank,  obs3flank)
+        
+    def test_getFlanksOfASubSNP_flank_of_first_base_with_polym_on_all_sequence(self):    
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        refBioseq.sequence = "AACTTACCAGAA"
+        refBioseq.header = "reference"        
+        bs1 = Bioseq( "line1", "AACTTTCCAGAA" )
+        bs2 = Bioseq( "line2", "AACTTACC-GAA" )
+        alignedBioseqDB.setData( [ bs1, bs2 ] )
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        subsnpPosition = 1
+        polymLength = 12
+        lineName = "line1"
+        exp5flank = ""
+        exp3flank = ""
+        obs5flank, obs3flank = multifasta2SNPFile.getFlanksOfASubSNP(lineName, subsnpPosition, polymLength, 500)
+        self.assertEquals(exp5flank,  obs5flank)
+        self.assertEquals(exp3flank,  obs3flank)
+        
+    def test_getFlanksOfASubSNP_flank_of_last_base_with_polym_on_all_sequence(self):    
+        refBioseq = Bioseq()
+        alignedBioseqDB = BioseqDB()
+        refBioseq.sequence = "AACTTACCAGAA"
+        refBioseq.header = "reference"        
+        bs1 = Bioseq( "line1", "AACTTTCCAGAA" )
+        bs2 = Bioseq( "line2", "AACTTACC-GAA" )
+        alignedBioseqDB.setData( [ bs1, bs2 ] )
+        multifasta2SNPFile = Multifasta2SNPFile("batch1", "gene1", "mouse")
+        multifasta2SNPFile._wrapper = ReferenceBioseqAndLinesBioseqDBWrapper(refBioseq, alignedBioseqDB, multifasta2SNPFile._logFile, self._inFileName)
+        subsnpPosition = 12
+        polymLength = 1
+        lineName = "line1"
+        exp5flank = "AACTTTCCAGA"
+        exp3flank = ""
+        obs5flank, obs3flank = multifasta2SNPFile.getFlanksOfASubSNP(lineName, subsnpPosition, polymLength, 500)
+        self.assertEquals(exp5flank,  obs5flank)
+        self.assertEquals(exp3flank,  obs3flank)
+#    
+    def test_subSNPExistsInSubSNPList_subSNP_exists(self):
+        batchName = "batch1"
+        lSubSNP = [{'subSNPName': batchName + "_DEL_1_line2", 'position': 1, 'lineName': 2, 'allele': 3, '5flank': "", '3flank': "CCGAA", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 4}, 
+                   {'subSNPName': batchName + "_DEL_1_line1", 'position': 1, 'lineName': 1, 'allele': 2, '5flank': "", '3flank': "CCGAA",'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 4},
+                   {'subSNPName': batchName + "_SNP_8_line3", 'position': 8, 'lineName': 3, 'allele': 1, '5flank': "ATTACCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_8_line1", 'position': 8, 'lineName': 1, 'allele': 6, '5flank': "A--ACCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_8_line2", 'position': 8, 'lineName': 2, 'allele': 6, '5flank': "---ACCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_8_line4", 'position': 8, 'lineName': 4, 'allele': 6, '5flank': "----CCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_DEL_1_line4", 'position': 1, 'lineName': 4, 'allele': 4, '5flank': "", '3flank': "CCGAA",'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 4},
+                   {'subSNPName': batchName + "_DEL_1_line3", 'position': 1, 'lineName': 3, 'allele': 5, '5flank': "", '3flank': "CCGGA",'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 4}]
+        multifasta2SNPFile = Multifasta2SNPFile(batchName, "gene1", "mouse")
+        
+        dSearchedSubSNP = {'subSNPName': batchName + "_DEL_1_line1", 'position': 1, 'lineName': 1, 'allele': 2, '5flank': "", '3flank': "CCGAA",'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 4}
+        
+        expResult = multifasta2SNPFile.subSNPExistsInSubSNPList(dSearchedSubSNP, lSubSNP)
+        obsResult = True
+        
+        self.assertEquals(expResult, obsResult)
+        
+    def test_subSNPExistsInSubSNPList_subSNP_does_not_exist(self):
+        batchName = "batch1"
+        lSubSNP = [{'subSNPName': batchName + "_DEL_1_line2", 'position': 1, 'lineName': 2, 'allele': 3, '5flank': "", '3flank': "CCGAA", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 4}, 
+                   {'subSNPName': batchName + "_DEL_1_line1", 'position': 1, 'lineName': 1, 'allele': 2, '5flank': "", '3flank': "CCGAA",'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 4},
+                   {'subSNPName': batchName + "_SNP_8_line3", 'position': 8, 'lineName': 3, 'allele': 1, '5flank': "ATTACCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_8_line1", 'position': 8, 'lineName': 1, 'allele': 6, '5flank': "A--ACCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_8_line2", 'position': 8, 'lineName': 2, 'allele': 6, '5flank': "---ACCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_SNP_8_line4", 'position': 8, 'lineName': 4, 'allele': 6, '5flank': "----CCG", '3flank': "A", 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                   {'subSNPName': batchName + "_DEL_1_line4", 'position': 1, 'lineName': 4, 'allele': 4, '5flank': "", '3flank': "CCGAA",'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 4},
+                   {'subSNPName': batchName + "_DEL_1_line3", 'position': 1, 'lineName': 3, 'allele': 5, '5flank': "", '3flank': "CCGGA",'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 4}]
+        multifasta2SNPFile = Multifasta2SNPFile(batchName, "gene1", "mouse")
+        
+        dSearchedSubSNP = {'subSNPName': batchName + "_DEL_12_line1", 'position': 12, 'lineName': 1, 'allele': 2, '5flank': "", '3flank': "CCGAA",'batchNumber': 1, 'confidenceValue' : "A", 'type' : "DELETION", 'length': 4}
+        
+        expResult = multifasta2SNPFile.subSNPExistsInSubSNPList(dSearchedSubSNP, lSubSNP)
+        obsResult = False
+        
+        self.assertEquals(expResult, obsResult)
+        
+    def _writeExpSubSNPFile(self):
+        expFileHandle = open(self._expSubSNPFileName, "w")
+        expFileHandle.write("SubSNPName;ConfidenceValue;Type;Position;5flank;3flank;Length;BatchNumber;IndividualNumber;PrimerType;PrimerNumber;Forward_or_Reverse;AlleleNumber\n")
+        expFileHandle.write("Batch1_SNP_4_Line1;A;SNP;4;CCT;AGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC;1;1;1;Sequence;;;1\n")
+        expFileHandle.write("Batch1_SNP_4_Line2;A;SNP;4;CCT;AGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;4\n")
+        expFileHandle.write("Batch1_SNP_21_Line1;A;SNP;21;CCTTAGCCATTGCTTGGTGA;TATGAAGGCAGTAGGCAAACCTCCACAATC;1;1;1;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_21_Line2;A;SNP;21;CCTAAGCCATTGCTTGGTGA;TATCAAGGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_25_Line1;A;SNP;25;CCTTAGCCATTGCTTGGTGACTAT;AAGGCAGTAGGCAAACCTCCACAATC;1;1;1;Sequence;;;3\n")
+        expFileHandle.write("Batch1_SNP_25_Line2;A;SNP;25;CCTAAGCCATTGCTTGGTGACTAT;AAGGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_36_Line1;A;SNP;36;CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAG;CAAACCTCCACAATC;1;1;1;Sequence;;;3\n")
+        expFileHandle.write("Batch1_SNP_36_Line2;A;SNP;36;CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAG;CAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_51_Line1;A;SNP;51;CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAAT;;1;1;1;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_51_Line2;A;SNP;51;CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAAT;;1;1;2;Sequence;;;4\n")
+        expFileHandle.close()
+        
+    def _writeExpSubSNPFileWithSnpsAndIndels(self):
+        expFileHandle = open(self._expSubSNPFileName, "w")
+        expFileHandle.write("SubSNPName;ConfidenceValue;Type;Position;5flank;3flank;Length;BatchNumber;IndividualNumber;PrimerType;PrimerNumber;Forward_or_Reverse;AlleleNumber\n")     
+        expFileHandle.write("Batch1_INS_1_Line1;A;INSERTION;1;C;TAGCCA---CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC;2;1;1;Sequence;;;8\n")
+        expFileHandle.write("Batch1_INS_1_Line2;A;INSERTION;1;C;AAGCCATT-CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA;2;1;2;Sequence;;;6\n")
+        expFileHandle.write("Batch1_SNP_2_Line1;A;SNP;2;C--;AGCCA---CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC;1;1;1;Sequence;;;1\n")
+        expFileHandle.write("Batch1_SNP_2_Line2;A;SNP;2;CCT;AGCCATT-CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;4\n")
+        expFileHandle.write("Batch1_DEL_8_Line1;A;DELETION;8;C--TAGCCA;CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC;3;1;1;Sequence;;;5\n")
+        expFileHandle.write("Batch1_DEL_8_Line2;A;DELETION;8;CCTAAGCCA;CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA;3;1;2;Sequence;;;7\n")
+        expFileHandle.write("Batch1_SNP_19_Line1;A;SNP;19;C--TAGCCA---CTTGGTGA;TATGAAGGCAGTAGGCAAACCTCCACAATC;1;1;1;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_19_Line2;A;SNP;19;CCTAAGCCATT-CTTGGTGA;TATCAAGGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_23_Line1;A;SNP;23;C--TAGCCA---CTTGGTGACTAT;AAGGCAGTAGGCAAACCTCCACAATC;1;1;1;Sequence;;;3\n")
+        expFileHandle.write("Batch1_SNP_23_Line2;A;SNP;23;CCTAAGCCATT-CTTGGTGACTAT;AAGGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_34_Line1;A;SNP;34;C--TAGCCA---CTTGGTGACTATGAAGGCAGTAG;CAAACCTCCACAATC;1;1;1;Sequence;;;3\n")
+        expFileHandle.write("Batch1_SNP_34_Line2;A;SNP;34;CCTAAGCCATT-CTTGGTGACTATCAAGGCAGTAG;CAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_49_Line1;A;SNP;49;C--TAGCCA---CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAAT;;1;1;1;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_49_Line2;A;SNP;49;CCTAAGCCATT-CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAAT;;1;1;2;Sequence;;;4\n")
+        expFileHandle.close() 
+        
+    def _writeExpSubSNPFileSeveralBatches(self):
+        expFileHandle = open(self._expSubSNPFileName, "w")
+        expFileHandle.write("SubSNPName;ConfidenceValue;Type;Position;5flank;3flank;Length;BatchNumber;IndividualNumber;PrimerType;PrimerNumber;Forward_or_Reverse;AlleleNumber\n")
+        expFileHandle.write("Batch_Gene1_SNP_4_Line1;A;SNP;4;CCT;AGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC;1;1;1;Sequence;;;1\n")
+        expFileHandle.write("Batch_Gene1_SNP_4_Line2;A;SNP;4;CCT;AGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;4\n")
+        expFileHandle.write("Batch_Gene1_SNP_21_Line1;A;SNP;21;CCTTAGCCATTGCTTGGTGA;TATGAAGGCAGTAGGCAAACCTCCACAATC;1;1;1;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene1_SNP_21_Line2;A;SNP;21;CCTAAGCCATTGCTTGGTGA;TATCAAGGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene1_SNP_25_Line1;A;SNP;25;CCTTAGCCATTGCTTGGTGACTAT;AAGGCAGTAGGCAAACCTCCACAATC;1;1;1;Sequence;;;3\n")
+        expFileHandle.write("Batch_Gene1_SNP_25_Line2;A;SNP;25;CCTAAGCCATTGCTTGGTGACTAT;AAGGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene1_SNP_36_Line1;A;SNP;36;CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAG;CAAACCTCCACAATC;1;1;1;Sequence;;;3\n")
+        expFileHandle.write("Batch_Gene1_SNP_36_Line2;A;SNP;36;CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAG;CAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene1_SNP_51_Line1;A;SNP;51;CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAAT;;1;1;1;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene1_SNP_51_Line2;A;SNP;51;CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAAT;;1;1;2;Sequence;;;4\n")
+
+        expFileHandle.write("Batch_Gene2_INS_1_Line1;A;INSERTION;1;C;TAGCCA---CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC;2;2;1;Sequence;;;8\n")
+        expFileHandle.write("Batch_Gene2_INS_1_Line2;A;INSERTION;1;C;AAGCCATT-CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA;2;2;2;Sequence;;;6\n")
+        expFileHandle.write("Batch_Gene2_SNP_2_Line1;A;SNP;2;C--;AGCCA---CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC;1;2;1;Sequence;;;1\n")
+        expFileHandle.write("Batch_Gene2_SNP_2_Line2;A;SNP;2;CCT;AGCCATT-CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA;1;2;2;Sequence;;;4\n")
+        expFileHandle.write("Batch_Gene2_DEL_8_Line1;A;DELETION;8;C--TAGCCA;CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC;3;2;1;Sequence;;;5\n")
+        expFileHandle.write("Batch_Gene2_DEL_8_Line2;A;DELETION;8;CCTAAGCCA;CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA;3;2;2;Sequence;;;7\n")
+        expFileHandle.write("Batch_Gene2_SNP_19_Line1;A;SNP;19;C--TAGCCA---CTTGGTGA;TATGAAGGCAGTAGGCAAACCTCCACAATC;1;2;1;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene2_SNP_19_Line2;A;SNP;19;CCTAAGCCATT-CTTGGTGA;TATCAAGGCAGTAGCCAAACCTCCACAATA;1;2;2;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene2_SNP_23_Line1;A;SNP;23;C--TAGCCA---CTTGGTGACTAT;AAGGCAGTAGGCAAACCTCCACAATC;1;2;1;Sequence;;;3\n")
+        expFileHandle.write("Batch_Gene2_SNP_23_Line2;A;SNP;23;CCTAAGCCATT-CTTGGTGACTAT;AAGGCAGTAGCCAAACCTCCACAATA;1;2;2;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene2_SNP_34_Line1;A;SNP;34;C--TAGCCA---CTTGGTGACTATGAAGGCAGTAG;CAAACCTCCACAATC;1;2;1;Sequence;;;3\n")
+        expFileHandle.write("Batch_Gene2_SNP_34_Line2;A;SNP;34;CCTAAGCCATT-CTTGGTGACTATCAAGGCAGTAG;CAAACCTCCACAATA;1;2;2;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene2_SNP_49_Line1;A;SNP;49;C--TAGCCA---CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAAT;;1;2;1;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene2_SNP_49_Line2;A;SNP;49;CCTAAGCCATT-CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAAT;;1;2;2;Sequence;;;4\n")
+        expFileHandle.close() 
+        
+    def _writeExpSubSNPFileSeveralBatches_different_lines_between_files(self):
+        expFileHandle = open(self._expSubSNPFileName, "w")
+        expFileHandle.write("SubSNPName;ConfidenceValue;Type;Position;5flank;3flank;Length;BatchNumber;IndividualNumber;PrimerType;PrimerNumber;Forward_or_Reverse;AlleleNumber\n")
+        expFileHandle.write("Batch_Gene1_SNP_4_Line1;A;SNP;4;CCT;AGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC;1;1;1;Sequence;;;1\n")
+        expFileHandle.write("Batch_Gene1_SNP_4_Line2;A;SNP;4;CCT;AGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;4\n")
+        expFileHandle.write("Batch_Gene1_SNP_21_Line1;A;SNP;21;CCTTAGCCATTGCTTGGTGA;TATGAAGGCAGTAGGCAAACCTCCACAATC;1;1;1;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene1_SNP_21_Line2;A;SNP;21;CCTAAGCCATTGCTTGGTGA;TATCAAGGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene1_SNP_25_Line1;A;SNP;25;CCTTAGCCATTGCTTGGTGACTAT;AAGGCAGTAGGCAAACCTCCACAATC;1;1;1;Sequence;;;3\n")
+        expFileHandle.write("Batch_Gene1_SNP_25_Line2;A;SNP;25;CCTAAGCCATTGCTTGGTGACTAT;AAGGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene1_SNP_36_Line1;A;SNP;36;CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAG;CAAACCTCCACAATC;1;1;1;Sequence;;;3\n")
+        expFileHandle.write("Batch_Gene1_SNP_36_Line2;A;SNP;36;CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAG;CAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene1_SNP_51_Line1;A;SNP;51;CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAAT;;1;1;1;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene1_SNP_51_Line2;A;SNP;51;CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAAT;;1;1;2;Sequence;;;4\n")
+
+        expFileHandle.write("Batch_Gene2_INS_1_Line3;A;INSERTION;1;C;TAGCCA---CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC;2;2;3;Sequence;;;8\n")
+        expFileHandle.write("Batch_Gene2_INS_1_Line4;A;INSERTION;1;C;AAGCCATT-CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA;2;2;4;Sequence;;;6\n")
+        expFileHandle.write("Batch_Gene2_SNP_2_Line3;A;SNP;2;C--;AGCCA---CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC;1;2;3;Sequence;;;1\n")
+        expFileHandle.write("Batch_Gene2_SNP_2_Line4;A;SNP;2;CCT;AGCCATT-CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA;1;2;4;Sequence;;;4\n")
+        expFileHandle.write("Batch_Gene2_DEL_8_Line3;A;DELETION;8;C--TAGCCA;CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC;3;2;3;Sequence;;;5\n")
+        expFileHandle.write("Batch_Gene2_DEL_8_Line4;A;DELETION;8;CCTAAGCCA;CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA;3;2;4;Sequence;;;7\n")
+        expFileHandle.write("Batch_Gene2_SNP_19_Line3;A;SNP;19;C--TAGCCA---CTTGGTGA;TATGAAGGCAGTAGGCAAACCTCCACAATC;1;2;3;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene2_SNP_19_Line4;A;SNP;19;CCTAAGCCATT-CTTGGTGA;TATCAAGGCAGTAGCCAAACCTCCACAATA;1;2;4;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene2_SNP_23_Line3;A;SNP;23;C--TAGCCA---CTTGGTGACTAT;AAGGCAGTAGGCAAACCTCCACAATC;1;2;3;Sequence;;;3\n")
+        expFileHandle.write("Batch_Gene2_SNP_23_Line4;A;SNP;23;CCTAAGCCATT-CTTGGTGACTAT;AAGGCAGTAGCCAAACCTCCACAATA;1;2;4;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene2_SNP_34_Line3;A;SNP;34;C--TAGCCA---CTTGGTGACTATGAAGGCAGTAG;CAAACCTCCACAATC;1;2;3;Sequence;;;3\n")
+        expFileHandle.write("Batch_Gene2_SNP_34_Line4;A;SNP;34;CCTAAGCCATT-CTTGGTGACTATCAAGGCAGTAG;CAAACCTCCACAATA;1;2;4;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene2_SNP_49_Line3;A;SNP;49;C--TAGCCA---CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAAT;;1;2;3;Sequence;;;2\n")
+        expFileHandle.write("Batch_Gene2_SNP_49_Line4;A;SNP;49;CCTAAGCCATT-CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAAT;;1;2;4;Sequence;;;4\n")
+        expFileHandle.close() 
+
+    def _writeExpSubSNPFileSeveralLineSeq(self):
+        expFileHandle = open(self._expSubSNPFileName, "w")
+        expFileHandle.write("SubSNPName;ConfidenceValue;Type;Position;5flank;3flank;Length;BatchNumber;IndividualNumber;PrimerType;PrimerNumber;Forward_or_Reverse;AlleleNumber\n")
+        expFileHandle.write("Batch1_SNP_4_Line1;A;SNP;4;CCT;AGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATCCGCAGTAGCCAAACCTCCACAATA;1;1;1;Sequence;;;1\n")
+        expFileHandle.write("Batch1_SNP_4_Line2;A;SNP;4;CCT;AGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATACGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;4\n")
+        expFileHandle.write("Batch1_SNP_21_Line1;A;SNP;21;CCTTAGCCATTGCTTGGTGA;TATGAAGGCAGTAGGCAAACCTCCACAATCCGCAGTAGCCAAACCTCCACAATA;1;1;1;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_21_Line2;A;SNP;21;CCTAAGCCATTGCTTGGTGA;TATCAAGGCAGTAGCCAAACCTCCACAATACGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_25_Line1;A;SNP;25;CCTTAGCCATTGCTTGGTGACTAT;AAGGCAGTAGGCAAACCTCCACAATCCGCAGTAGCCAAACCTCCACAATA;1;1;1;Sequence;;;3\n")
+        expFileHandle.write("Batch1_SNP_25_Line2;A;SNP;25;CCTAAGCCATTGCTTGGTGACTAT;AAGGCAGTAGCCAAACCTCCACAATACGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_36_Line1;A;SNP;36;CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAG;CAAACCTCCACAATCCGCAGTAGCCAAACCTCCACAATA;1;1;1;Sequence;;;3\n")
+        expFileHandle.write("Batch1_SNP_36_Line2;A;SNP;36;CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAG;CAAACCTCCACAATACGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_51_Line1;A;SNP;51;CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAAT;CGCAGTAGCCAAACCTCCACAATA;1;1;1;Sequence;;;2\n")
+        expFileHandle.write("Batch1_SNP_51_Line2;A;SNP;51;CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAAT;CGCAGTAGCCAAACCTCCACAATA;1;1;2;Sequence;;;4\n")
+        expFileHandle.close()
+        
+        
+    def _writeExpAlleleFile(self):
+        expFileHandle = open(self._expAlleleFileName, "w")
+        expFileHandle.write("AlleleNumber;Value;Motif;NbCopy;Comment\n")
+        expFileHandle.write("1;T;;;\n")
+        expFileHandle.write("2;C;;;\n")
+        expFileHandle.write("3;G;;;\n")
+        expFileHandle.write("4;A;;;\n")        
+        expFileHandle.close()
+        
+    def _writeExpAlleleFileWithSnpsAndIndels(self):
+        expFileHandle = open(self._expAlleleFileName, "w")
+        expFileHandle.write("AlleleNumber;Value;Motif;NbCopy;Comment\n")
+        expFileHandle.write("1;T;;;\n")
+        expFileHandle.write("2;C;;;\n")
+        expFileHandle.write("3;G;;;\n")
+        expFileHandle.write("4;A;;;\n")   
+        expFileHandle.write("5;---;;;\n")
+        expFileHandle.write("6;CT;;;\n")
+        expFileHandle.write("7;TT-;;;\n")
+        expFileHandle.write("8;--;;;\n")     
+        expFileHandle.close() 
+        
+        
+    def _writeExpAlleleFileSeveralBatches(self):
+        expFileHandle = open(self._expAlleleFileName, "w")
+        expFileHandle.write("AlleleNumber;Value;Motif;NbCopy;Comment\n")
+        expFileHandle.write("1;T;;;\n")
+        expFileHandle.write("2;C;;;\n")
+        expFileHandle.write("3;G;;;\n")
+        expFileHandle.write("4;A;;;\n")   
+        expFileHandle.write("5;---;;;\n")
+        expFileHandle.write("6;CT;;;\n")
+        expFileHandle.write("7;TT-;;;\n")
+        expFileHandle.write("8;--;;;\n")     
+        expFileHandle.close()
+        
+    def _writeExpIndividualFile(self):
+        expFileHandle = open(self._expIndividualFileName, "w")
+        expFileHandle.write("IndividualNumber;IndividualName;Description;AberrAneuploide;FractionLength;DeletionLineSynthesis;UrlEarImage;TypeLine;ChromNumber;ArmChrom;DeletionBin;ScientificName;local_germplasm_name;submitter_code;local_institute;donor_institute;donor_acc_id\n")
+        expFileHandle.write("1;Line1;;;;;;;;;;Arabidopsis thaliana;;;;;\n")
+        expFileHandle.write("2;Line2;;;;;;;;;;Arabidopsis thaliana;;;;;\n")        
+        expFileHandle.close()
+        
+    def _writeExpIndividualFile_different_lines_between_files(self):
+        expFileHandle = open(self._expIndividualFileName, "w")
+        expFileHandle.write("IndividualNumber;IndividualName;Description;AberrAneuploide;FractionLength;DeletionLineSynthesis;UrlEarImage;TypeLine;ChromNumber;ArmChrom;DeletionBin;ScientificName;local_germplasm_name;submitter_code;local_institute;donor_institute;donor_acc_id\n")
+        expFileHandle.write("1;Line1;;;;;;;;;;Arabidopsis thaliana;;;;;\n")
+        expFileHandle.write("2;Line2;;;;;;;;;;Arabidopsis thaliana;;;;;\n")    
+        expFileHandle.write("3;Line3;;;;;;;;;;Arabidopsis thaliana;;;;;\n")
+        expFileHandle.write("4;Line4;;;;;;;;;;Arabidopsis thaliana;;;;;\n")       
+        expFileHandle.close()
+        
+    def _writeExpSequenceFile(self):
+        SequenceFSAFileHandle = open(self._expSequenceFSAFileName, "w")
+        SequenceFSAFileHandle.write(">Sequence_de_Reference\n")
+        SequenceFSAFileHandle.write("CCTAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+        SequenceCSVFileHandle = open(self._expSequenceCSVFileName, "w")
+        SequenceCSVFileHandle.write("SequenceName;SeqType;BankName;BankVersion;ACNumber;Locus;ScientificName\n")
+        SequenceCSVFileHandle.write("Sequence_de_Reference;Reference;;;;;Arabidopsis thaliana\n")
+        
+    def _writeExpSequenceFileSeveralLineSeq(self):
+        SequenceFSAFileHandle = open(self._expSequenceFSAFileName, "w")
+        SequenceFSAFileHandle.write(">Sequence_de_Reference\n")
+        SequenceFSAFileHandle.write("CCTAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATCCGCAGTAGCCAAACCTCCACAATA\n")
+        SequenceCSVFileHandle = open(self._expSequenceCSVFileName, "w")
+        SequenceCSVFileHandle.write("SequenceName;SeqType;BankName;BankVersion;ACNumber;Locus;ScientificName\n")
+        SequenceCSVFileHandle.write("Sequence_de_Reference;Reference;;;;;Arabidopsis thaliana\n")
+    
+    def _writeExpSequenceFileWithDeletion(self):
+        SequenceFSAFileHandle = open(self._expSequenceFSAFileName, "w")
+        SequenceFSAFileHandle.write(">Sequence_de_Reference\n")
+        SequenceFSAFileHandle.write("CAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+        SequenceCSVFileHandle = open(self._expSequenceCSVFileName, "w")
+        SequenceCSVFileHandle.write("SequenceName;SeqType;BankName;BankVersion;ACNumber;Locus;ScientificName\n")
+        SequenceCSVFileHandle.write("Sequence_de_Reference;Reference;;;;;Arabidopsis thaliana\n")
+        
+    def _writeExpSequenceSeveralBatches(self):
+        SequenceFSAFileHandle = open(self._expSequenceFSAFileName, "w")
+        SequenceFSAFileHandle.write(">Sequence_de_Reference1\n")
+        SequenceFSAFileHandle.write("CCTAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+        SequenceFSAFileHandle.write(">Sequence_de_Reference2\n")
+        SequenceFSAFileHandle.write("CAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+        SequenceCSVFileHandle = open(self._expSequenceCSVFileName, "w")
+        SequenceCSVFileHandle.write("SequenceName;SeqType;BankName;BankVersion;ACNumber;Locus;ScientificName\n")
+        SequenceCSVFileHandle.write("Sequence_de_Reference1;Reference;;;;;Arabidopsis thaliana\n")
+        SequenceCSVFileHandle.write("Sequence_de_Reference2;Reference;;;;;Arabidopsis thaliana\n")
+
+    def _writeExpSequenceSeveralBatchesForSameRefSeq(self):
+        SequenceFSAFileHandle = open(self._expSequenceFSAFileName, "w")
+        SequenceFSAFileHandle.write(">Sequence_de_Reference1\n")
+        SequenceFSAFileHandle.write("CCTAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+        SequenceFSAFileHandle.write(">Sequence_de_Reference1\n")
+        SequenceFSAFileHandle.write("CAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+        SequenceCSVFileHandle = open(self._expSequenceCSVFileName, "w")
+        SequenceCSVFileHandle.write("SequenceName;SeqType;BankName;BankVersion;ACNumber;Locus;ScientificName\n")
+        SequenceCSVFileHandle.write("Sequence_de_Reference1;Reference;;;;;Arabidopsis thaliana\n")
+        SequenceCSVFileHandle.write("Sequence_de_Reference1;Reference;;;;;Arabidopsis thaliana\n")
+        
+    def _writeExpBatchFile(self):
+        BatchFileHandle = open(self._expBatchFileName, "w")
+        BatchFileHandle.write("BatchNumber: 1\n")
+        BatchFileHandle.write("BatchName: Batch1\n")
+        BatchFileHandle.write("GeneName: methyltransferase\n")
+        BatchFileHandle.write("Description: \n")
+        BatchFileHandle.write("ContactNumber: 1\n")
+        BatchFileHandle.write("ProtocolNumber: 1\n")
+        BatchFileHandle.write("ThematicNumber: 1\n")
+        BatchFileHandle.write("RefSeqName: Sequence_de_Reference\n")
+        BatchFileHandle.write("AlignmentFileName: \n")
+        BatchFileHandle.write("SeqName: \n")
+        BatchFileHandle.write("//\n")
+        BatchFileHandle.close()
+        
+    def _writeExpBatchFileSeveralBatches(self):
+        BatchFileHandle = open(self._expBatchFileName, "w")
+        BatchFileHandle.write("BatchNumber: 1\n")
+        BatchFileHandle.write("BatchName: Batch_Gene1\n")
+        BatchFileHandle.write("GeneName: Gene1\n")
+        BatchFileHandle.write("Description: \n")
+        BatchFileHandle.write("ContactNumber: 1\n")
+        BatchFileHandle.write("ProtocolNumber: 1\n")
+        BatchFileHandle.write("ThematicNumber: 1\n")
+        BatchFileHandle.write("RefSeqName: Sequence_de_Reference1\n")
+        BatchFileHandle.write("AlignmentFileName: \n")
+        BatchFileHandle.write("SeqName: \n")
+        BatchFileHandle.write("//\n")
+        BatchFileHandle.write("BatchNumber: 2\n")
+        BatchFileHandle.write("BatchName: Batch_Gene2\n")
+        BatchFileHandle.write("GeneName: Gene2\n")
+        BatchFileHandle.write("Description: \n")
+        BatchFileHandle.write("ContactNumber: 1\n")
+        BatchFileHandle.write("ProtocolNumber: 1\n")
+        BatchFileHandle.write("ThematicNumber: 1\n")
+        BatchFileHandle.write("RefSeqName: Sequence_de_Reference2\n")
+        BatchFileHandle.write("AlignmentFileName: \n")
+        BatchFileHandle.write("SeqName: \n")
+        BatchFileHandle.write("//\n")
+        BatchFileHandle.close()
+        
+    def _writeExpBatchFileSeveralBatchesForSameRefSeq(self):
+        BatchFileHandle = open(self._expBatchFileName, "w")
+        BatchFileHandle.write("BatchNumber: 1\n")
+        BatchFileHandle.write("BatchName: Batch_Gene1\n")
+        BatchFileHandle.write("GeneName: Gene1\n")
+        BatchFileHandle.write("Description: \n")
+        BatchFileHandle.write("ContactNumber: 1\n")
+        BatchFileHandle.write("ProtocolNumber: 1\n")
+        BatchFileHandle.write("ThematicNumber: 1\n")
+        BatchFileHandle.write("RefSeqName: Sequence_de_Reference1\n")
+        BatchFileHandle.write("AlignmentFileName: \n")
+        BatchFileHandle.write("SeqName: \n")
+        BatchFileHandle.write("//\n")
+        BatchFileHandle.write("BatchNumber: 2\n")
+        BatchFileHandle.write("BatchName: Batch_Gene2\n")
+        BatchFileHandle.write("GeneName: Gene2\n")
+        BatchFileHandle.write("Description: \n")
+        BatchFileHandle.write("ContactNumber: 1\n")
+        BatchFileHandle.write("ProtocolNumber: 1\n")
+        BatchFileHandle.write("ThematicNumber: 1\n")
+        BatchFileHandle.write("RefSeqName: Sequence_de_Reference1\n")
+        BatchFileHandle.write("AlignmentFileName: \n")
+        BatchFileHandle.write("SeqName: \n")
+        BatchFileHandle.write("//\n")
+        BatchFileHandle.close()
+        
+        
+        BatchFileHandle.close()
+        
+    def _writeExpBatchLineFile(self):
+        BatchLineFileHandle = open(self._expBatchLineFileName, "w")
+        BatchLineFileHandle.write("IndividualNumber;Pos5;Pos3;BatchNumber;Sequence\n")
+        BatchLineFileHandle.write("1;;;1;\n")
+        BatchLineFileHandle.write("2;;;1;\n")
+        BatchLineFileHandle.close()
+    
+    
+    def _writeExpBatchLineFileSeveralBatches(self):
+        BatchLineFileHandle = open(self._expBatchLineFileName, "w")
+        BatchLineFileHandle.write("IndividualNumber;Pos5;Pos3;BatchNumber;Sequence\n")
+        BatchLineFileHandle.write("1;;;1;\n")
+        BatchLineFileHandle.write("2;;;1;\n")
+        BatchLineFileHandle.write("1;;;2;\n")
+        BatchLineFileHandle.write("2;;;2;\n")
+        BatchLineFileHandle.close()
+    
+    def _writeExpBatchLineFileSeveralBatches_different_lines_between_files(self):
+        BatchLineFileHandle = open(self._expBatchLineFileName, "w")
+        BatchLineFileHandle.write("IndividualNumber;Pos5;Pos3;BatchNumber;Sequence\n")
+        BatchLineFileHandle.write("1;;;1;\n")
+        BatchLineFileHandle.write("2;;;1;\n")
+        BatchLineFileHandle.write("3;;;2;\n")
+        BatchLineFileHandle.write("4;;;2;\n")
+        BatchLineFileHandle.close()
+        
+    def _writeInputFile(self):
+        inFileHandle = open(self._inFileName, "w")
+        inFileHandle.write(">Sequence_de_Reference\n")
+        inFileHandle.write("CCTAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+        inFileHandle.write(">Line1\n")
+        inFileHandle.write("CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC\n")
+        inFileHandle.write(">Line2\n")
+        inFileHandle.write("CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA")
+        inFileHandle.close()
+    
+    def _writeInputFileWithSnpsAndIndels(self):
+        inFileHandle = open(self._inFileName, "w")
+        inFileHandle.write(">Sequence_de_Reference\n")
+        inFileHandle.write("C--AAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+        inFileHandle.write(">Line1\n")
+        inFileHandle.write("C--TAGCCA---CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC\n")
+        inFileHandle.write(">Line2\n")
+        inFileHandle.write("CCTAAGCCATT-CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA")
+        inFileHandle.close()
+        
+    def _writeInputFileWithSeqErrorsInRefSeq(self):
+        inFileHandle = open(self._inFileName, "w")
+        inFileHandle.write(">Sequence_de_Reference\n")
+        inFileHandle.write("CCTA7GCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+        inFileHandle.write(">Line1\n")
+        inFileHandle.write("CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC\n")
+        inFileHandle.write(">Line2\n")
+        inFileHandle.write("CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA")
+        inFileHandle.close()
+        
+    def _writeInputFileWithSeqErrorsInOneLineSeq(self):
+        inFileHandle = open(self._inFileName, "w")
+        inFileHandle.write(">Sequence_de_Reference\n")
+        inFileHandle.write("CCTAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+        inFileHandle.write(">Line1\n")
+        inFileHandle.write("CCTTAGCCATTGCTTGGTGACTATXAAGGCAGTAGGCAAACCTCCACAATC\n")
+        inFileHandle.write(">Line2\n")
+        inFileHandle.write("CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA")
+        inFileHandle.close()
+        
+    def _writeInputFileWithASeveralLineSeq(self):
+        inFileHandle = open(self._inFileName, "w")
+        inFileHandle.write(">Sequence_de_Reference\n")
+        inFileHandle.write("CCTAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATCCGCAGTAGCCAAACCTCCACAATA\n")
+        inFileHandle.write(">Line1\n")
+        inFileHandle.write("CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATCCGCAGTAGCCAAACCTCCACAATA\n")
+        inFileHandle.write(">Line2\n")
+        inFileHandle.write("CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA\nCGCAGTAGCCAAA\nCCTCCACAATA\n")
+        inFileHandle.close()
+        
+        
+    def _writeInputFileWithUpcaseAndLowcaseNucleotide(self):
+        inFileHandle = open(self._inFileName, "w")
+        inFileHandle.write(">Sequence_de_Reference\n")
+        inFileHandle.write("CCTAAGCCATTGCTTGGtGATTATGAAGgCAGTAGTCAAACCTCCACAATC\nCGCAGTAGCCAAA\nCCTCCACAATA\n")
+        inFileHandle.write(">Line1\n")
+        inFileHandle.write("CCTTAGCCATTGCtTGGTGACTATGAAGGcAGTAGGCAAACCTCCACAATC\nCGCAGTAGCCAAA\nCCTCCACAATA\n")
+        inFileHandle.write(">Line2\n")
+        inFileHandle.write("CCTAAGCCAtTGCTTGGTGACTATCaAGGCAGTAGCCAAACCTCCACAATA\nCGCAGTAGCCAAA\nCCTCCACAATA\n")
+        inFileHandle.close()
+    
+    def _writeInputFileWith2SeqsWithTheSameName(self):
+        inFileHandle = open(self._inFileName, "w")
+        inFileHandle.write(">Sequence_de_Reference\n")
+        inFileHandle.write("CCTAAGCCATTGCTTGGtGATTATGAAGgCAGTAGTCAAACCTCCACAATC\nCGCAGTAGCCAAA\nCCTCCACAATA\n")
+        inFileHandle.write(">Line1\n")
+        inFileHandle.write("CCTTAGCCATTGCtTGGTGACTATGAAGGcAGTAGGCAAACCTCCACAATC\n")
+        inFileHandle.write(">Line2\n")
+        inFileHandle.write("CCTAAGCCAtTGCTTGGTGACTATCaAGGCAGTAGCCAAACCTCCACAATA\n")
+        inFileHandle.write(">Line2\n")
+        inFileHandle.write("CCTAAGCCAtTGCTTGGTGACTATCaAGGCAGTAGCCAAACCTCCACAATA\n")
+        inFileHandle.close()
+        
+    def _writeInputFileBatchWithPotentialDooblons(self):
+        inFileHandle = open(self._inFileName, "w")
+        inFileHandle.write(">AU247387ref\n")
+        inFileHandle.write("CACTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGTTCTGGTTACTCTTCAATTTGGGCATGCTTAATTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTTTATAGCCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCTGGGTTCTTTCTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTGTGCTGCAACAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCATACGAGTTGTGAACTGATGACATCCTCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG\n")
+        inFileHandle.write(">10102\n")
+        inFileHandle.write("NNNtatagctcctaacattcctgaagtgaagatcacrgaggacnnggctgtcaatgttgcccgctcgctgagatatgagatcaacaggggcttygctagcttgagggcgattggNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write(">10954\n")
+        inFileHandle.write("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNtcaatgttgcccgctcgctgagatatgagatcaacaggggctttgctagcctgagggcgattggtcaaggccgtgacctgaagaaattcctgattgtacgt---------------------------ttaat---------------------------------------------------------------------------------------------tggttgcatggcttcgttctctttagccttcgctgtttgtggctttgttatgtgaccaagcacttgctatactgtctatttgttcgcaggtgattgcaggtctgtggatcctct---------ctgcccttgggagctgctgcaatttcctcaccttgttctacataggtaatgtgcttcgctgctacagcctgaacttg--------cagatgtgcagtaactgtacctagcattgtttacccat------------------------tctcgctttcttacNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write(">ABERAVON\n")
+        inFileHandle.write("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNggtcaaggccgtgacctgaagaaattcctgattgtacgt---------------------------ttaat---------------------------------------------------------------------------------------------tggttgcatggcttcgttctctttagccttcgctgtttgtggctttgttatgtgaccNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write(">CARILLON\n")
+        inFileHandle.write("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNcaacattgcccgctcgctgagatatgagatcaacaggggcttctttactttgaaggagatcggtcagggccgtgatctgaagaaattcctcattgtatgttctggttactcttcaatttgggcatgcttaat---------------------------------gttgggtgctttctttat--cctgctcaccaacatgtgatctgttctttgtatgctcaggtggttgccgg---------------------------------------------------------------------------------------------------cctctgggttctttctgttcttgggagctcttgcaacttcttgacattggcatatataggtaat------------------tttaacttgtgctgcaacacttgagttcataaccaccctag------ttgtccatacgagttgtgaactgatgacatccgttctttttcccragtgcagtcttcgtggtgctctacacggtgccagttctgtatgaNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write(">CONCERTO\n")
+        inFileHandle.write("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNctttgttatgtgaccaagcacttgctatactgtctatttgttcgcaggtgattgcaggtctgtggatcctct---------ctgcccttgggagctgctgcaatttcctcaccttgttctacataggtaatgtgcttcgctgctacagcctgaacttg--------cagatgtgcagtaactgtacctagcattgtttacccat------------------------tctcgctttcttacttgcagtcttcatggttctctacactgtgccNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write(">F14-13\n")
+        inFileHandle.write("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNtsaatgttgcccgctcgctgagatatgagatcaacaggggctttgctagcctgagggcgattggtcaaggccgtgacctgaagaaaNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write(">GAGNY\n")
+        inFileHandle.write("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNcattgcccgctcgctgagatatgagatcaacaggggcttctttactttgaaggagatyggtcagggccgtgayctgaagaaattcctsattgtaygtNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write(">GREECE\n")
+        inFileHandle.write("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNtsaacattgcccgctcgctgagatatgagatcaacaggggcttctttactttgaaggagatyggycagggccgtgatctgaagaaattcctcattgtatgtNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write(">IMAGINE\n")
+        inFileHandle.write("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNtcaatgttgcccgctcgctgagatatgagatcaacaggggctttgctagcctgagggcgattggtcaaggccgtgacctgaagaaattcctgattgtacgt---------------------------ttaat---------------------------------------------------------------------------------------------tggttgcatggcttcgttctctttagccttcgctgtttgtggctttgttatgtgaccaagcacttgctatactgtctatttgttcgcaggtgattgcaggtctgtggatcctct---------ctgcccttgggagctgctgcaatttcctcaccttgttctacataggtaatgtgcttcgctgctacagcctgaacttg--------cagatgtgcagtaactgtacctagcattgtttacccat------------------------tctcgctttcttacttgcagtcttcatggttctctacactgtgccNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write(">IRELAND\n")
+        inFileHandle.write("NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write(">NEMOF\n")
+        inFileHandle.write("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNtcaatgttgcccgctcgctgagatatgagatcaacaggggctttgctagcctgagggcgattggtcaaggccgtgacctgaagaaattcctgattgtacgt---------------------------ttaat---------------------------------------------------------------------------------------------tggttgcatggcttcgttctctttagccttcgctgtttgtggctttgttatgtgaccaagcacttgctatactgtctatttgttcgcaggtgattgcaggtctgtggatcctct---------ctgcccttgggNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write(">NEMOH\n")
+        inFileHandle.write("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNtcaatgttgcccgctcgctgagatatgagatcaacaggggctttgctagcctgagggcgattggtcaaggccgtgacctgaagaaattcctgattgtacgt---------------------------ttaat---------------------------------------------------------------------------------------------tggttgcatggcttcgttctctttagccttcgctgtttgtggctttgttatgtgaccaagcacttgctatactgtctatttgttcgcaggtgattgcaggtctgtggatcctct---------ctgcccttgggagctgctgcaatttcctcaccttgttctacataggtaatgtgcttcgctgctacagcctgaacttg--------cagatgtgcagtaactgtacctagcattgtttacccat------------------------tctcgctttcttacNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write(">POLAND\n")
+        inFileHandle.write("NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write(">SPAIN\n")
+        inFileHandle.write("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNtcaacattgcccgctcgctgagatatgagatcaacaggggcttctttactttgaaggagatcggtcagggccgtgatctgaagaaattcctcattgtatgttctggttactcttcaatttgggcatgcttaat---------------------------------gttgggtgctttctttat--cctgctcaccaacatgtgatctgttctttgtatgctcaggtggttgccgg---------------------------------------------------------------------------------------------------cctctgggttctttctgttcttgggagctcttgcaacttcttgacattggcatatataggtaat------------------tttaacttgtgctgcaacacttgagttcataaccaccctag------ttgtccatacgagttgtgaactgatgacatccgttctttttcccgagtgcagtcttcgtggtgctctacacggtgccagttctgtatgagaagtacgacgacaaggttgatgcttttggtgagaag\n")
+        inFileHandle.write(">TRANSATE\n")
+        inFileHandle.write("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNcgctcgctgagatatgagatcaacaggggcttctttactttgaaggagatYggccagggtcgcgacctcaagaaattcctcattgtatgttgcttgt-ctcttcaatttcaacatgcttgat---------------------------------gttgggtgctttctttat--cctgctcaccaacatgtgatctcttctttgtatgctcaggtggttgcggg---------------------------------------------------------------------------------------------------tctctgggttctttctgttcttgggagctcttgcaacttcttgacattggcatatataggtaaK------------------tataRcttgtgctgcaacacttgagttcataaccNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN\n")
+        inFileHandle.write(">VIGOR\n")
+        inFileHandle.write("NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG\n")
+        inFileHandle.close()
+        
+    def _writeRealExpAlleleFile(self):
+        expFileHandle = open(self._expAlleleFileName, "w")
+        expFileHandle.write("AlleleNumber;Value;Motif;NbCopy;Comment\n")
+        expFileHandle.write("1;G;;;\n")
+        expFileHandle.write("2;T;;;\n")
+        expFileHandle.write("3;A;;;\n")   
+        expFileHandle.write("4;C;;;\n")
+        expFileHandle.write("5;-;;;\n")
+        expFileHandle.close();
+        
+    def _writeRealExpSequenceCSVFile(self):
+        SequenceFSAFileHandle = open(self._expSequenceCSVFileName, "w")
+        SequenceFSAFileHandle.write("SequenceName;SeqType;BankName;BankVersion;ACNumber;Locus;ScientificName\n")
+        SequenceFSAFileHandle.write("PpHDZ31_ref;Reference;;;;;Pinus pinaster\n")
+        SequenceFSAFileHandle.close()
+        
+    def _writeRealExpBatchFile(self):
+        FileHandle = open(self._expBatchFileName, "w")
+        FileHandle.write("BatchNumber: 1\n")
+        FileHandle.write("BatchName: INRA_Pinus_pinaster_HDZ31-1\n")
+        FileHandle.write("GeneName: PpHDZ31\n")
+        FileHandle.write("Description: \n")
+        FileHandle.write("ContactNumber: 1\n")
+        FileHandle.write("ProtocolNumber: 1\n")
+        FileHandle.write("ThematicNumber: 1\n")
+        FileHandle.write("RefSeqName: PpHDZ31_ref\n")
+        FileHandle.write("AlignmentFileName: \n")
+        FileHandle.write("SeqName: \n")
+        FileHandle.write("//\n")
+        FileHandle.close()
+        
+        
+    def _writeInputFileSeveralBatches(self):
+        if(not FileUtils.isRessourceExists(self._inputDirSeveralBatches)):
+            os.mkdir(self._inputDirSeveralBatches)
+         
+            inFileHandle = open(self._inputDirSeveralBatches+"/Gene1.fasta","w")
+            inFileHandle.write(">Sequence_de_Reference1\n")
+            inFileHandle.write("CCTAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+            inFileHandle.write(">Line1\n")
+            inFileHandle.write("CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC\n")
+            inFileHandle.write(">Line2\n")
+            inFileHandle.write("CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA")
+            inFileHandle.close()
+            
+            inFileHandle2 = open(self._inputDirSeveralBatches+"/Gene2.fasta","w")
+            inFileHandle2.write(">Sequence_de_Reference2\n")
+            inFileHandle2.write("C--AAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+            inFileHandle2.write(">Line1\n")
+            inFileHandle2.write("C--TAGCCA---CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC\n")
+            inFileHandle2.write(">Line2\n")
+            inFileHandle2.write("CCTAAGCCATT-CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA")
+            inFileHandle2.close()
+            
+    def _writeInputFileSeveralBatches_different_lines_between_files(self):
+        if(not FileUtils.isRessourceExists(self._inputDirSeveralBatches)):
+            os.mkdir(self._inputDirSeveralBatches)
+         
+            inFileHandle = open(self._inputDirSeveralBatches+"/Gene1.fasta","w")
+            inFileHandle.write(">Sequence_de_Reference1\n")
+            inFileHandle.write("CCTAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+            inFileHandle.write(">Line1\n")
+            inFileHandle.write("CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC\n")
+            inFileHandle.write(">Line2\n")
+            inFileHandle.write("CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA")
+            inFileHandle.close()
+            
+            inFileHandle2 = open(self._inputDirSeveralBatches+"/Gene2.fasta","w")
+            inFileHandle2.write(">Sequence_de_Reference2\n")
+            inFileHandle2.write("C--AAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+            inFileHandle2.write(">Line3\n")
+            inFileHandle2.write("C--TAGCCA---CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC\n")
+            inFileHandle2.write(">Line4\n")
+            inFileHandle2.write("CCTAAGCCATT-CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA")
+            inFileHandle2.close()
+        
+    def _writeInputFileSeveralBatches_different_lines_and_same_refseq_between_files(self): 
+        if(not FileUtils.isRessourceExists(self._inputDirSeveralBatches)):
+            os.mkdir(self._inputDirSeveralBatches)
+         
+            inFileHandle = open(self._inputDirSeveralBatches+"/Gene1.fasta","w")
+            inFileHandle.write(">Sequence_de_Reference1\n")
+            inFileHandle.write("CCTAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+            inFileHandle.write(">Line1\n")
+            inFileHandle.write("CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC\n")
+            inFileHandle.write(">Line2\n")
+            inFileHandle.write("CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA")
+            inFileHandle.close()
+            
+            inFileHandle2 = open(self._inputDirSeveralBatches+"/Gene2.fasta","w")
+            inFileHandle2.write(">Sequence_de_Reference1\n")
+            inFileHandle2.write("C--AAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+            inFileHandle2.write(">Line3\n")
+            inFileHandle2.write("C--TAGCCA---CTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC\n")
+            inFileHandle2.write(">Line4\n")
+            inFileHandle2.write("CCTAAGCCATT-CTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA")
+            inFileHandle2.close()
+    
+        
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_Multifasta2SNPFileWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,292 @@
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.seq.BioseqDB import BioseqDB
+from commons.core.seq.Bioseq import Bioseq
+from commons.core.parsing.Multifasta2SNPFile import Multifasta2SNPFileWriter
+from commons.core.parsing.Multifasta2SNPFile import Multifasta2SNPFile
+from commons.core.parsing.Multifasta2SNPFile import ReferenceBioseqAndLinesBioseqDBWrapper
+from commons.core.LoggerFactory import LoggerFactory
+import os
+import logging
+import unittest
+
+class Test_Multifasta2SNPFileWriter(unittest.TestCase):
+
+    def setUp(self):
+        self._obsSubSNPFile = "SubSNP.csv"
+        self._expSubSNPFile = "ExpSubSNP.csv"
+        
+        self._obsAlleleFile = "Allele.csv"
+        self._expAlleleFile = "ExpAllele.csv"
+        
+        self._obsIndividualFile = "Individual.csv"
+        self._expIndividualFile = "ExpIndividual.csv"
+        
+        self._obsSequenceFSAFile = "Sequences.fsa"
+        self._expSequenceFSAFile = "ExpSequences.fsa"
+        
+        self._obsSequenceCSVFile = "Sequences.csv"
+        self._expSequenceCSVFile = "ExpSequences.csv"
+        
+        self._obsBatchFile = "Batch.txt"
+        self._expBatchFile = "ExpBatch.txt"
+        
+        self._obsBatchLineFile = "BatchLine.csv"
+        self._expBatchLineFile = "ExpBatchLine.csv"
+        
+        self._logFileName = "Test_Multifasta2SNPWriter.log"
+        
+        self._inputFileName = "multifasta.fsa"
+        
+        self._lSNPResult = []
+        self._dAlleleResult = {}
+        self._lIndividualResult = []
+        self._refSeq = Bioseq()
+        self._seqDb= BioseqDB()
+        
+        self._logFile = LoggerFactory.createLogger(self._logFileName, logging.INFO, "%(asctime)s %(levelname)s: %(message)s")
+        self._lSequenceWrapper = ReferenceBioseqAndLinesBioseqDBWrapper(self._refSeq, self._seqDb,  self._logFile, self._inputFileName)
+        self._lBatchLineResults = []
+        
+        self._Multifasta2SNPFileWriter = Multifasta2SNPFileWriter()
+        
+        self._inFileName = "multifasta.txt"
+        self._taxon = "Arabidopsis thaliana"
+
+    def tearDown(self):
+        if FileUtils.isRessourceExists(self._inFileName):
+            os.remove(self._inFileName)
+        if FileUtils.isRessourceExists("multifasta2SNP.log"):
+            os.remove("multifasta2SNP.log")
+        if FileUtils.isRessourceExists("Test_Multifasta2SNPWriter.log"):
+            os.remove("Test_Multifasta2SNPWriter.log")
+            
+        if FileUtils.isRessourceExists(self._obsSubSNPFile):
+            os.remove(self._obsSubSNPFile)
+        if FileUtils.isRessourceExists(self._expSubSNPFile):
+            os.remove(self._expSubSNPFile)
+            
+        if FileUtils.isRessourceExists(self._obsAlleleFile):
+            os.remove(self._obsAlleleFile)
+        if FileUtils.isRessourceExists(self._expAlleleFile):
+            os.remove(self._expAlleleFile)
+            
+        if FileUtils.isRessourceExists(self._obsIndividualFile):
+            os.remove(self._obsIndividualFile)
+        if FileUtils.isRessourceExists(self._expIndividualFile):
+            os.remove(self._expIndividualFile)
+            
+        if FileUtils.isRessourceExists(self._obsSequenceFSAFile):
+            os.remove(self._obsSequenceFSAFile)
+        if FileUtils.isRessourceExists(self._expSequenceFSAFile):
+            os.remove(self._expSequenceFSAFile)
+            
+        if FileUtils.isRessourceExists(self._obsSequenceCSVFile):
+            os.remove(self._obsSequenceCSVFile)
+        if FileUtils.isRessourceExists(self._expSequenceCSVFile):
+            os.remove(self._expSequenceCSVFile)
+
+        if FileUtils.isRessourceExists(self._obsBatchFile):
+            FileUtils.removeFilesByPattern(self._obsBatchFile)
+        if FileUtils.isRessourceExists(self._expBatchFile):
+            FileUtils.removeFilesByPattern(self._expBatchFile)
+        
+        if FileUtils.isRessourceExists(self._obsBatchLineFile):
+            FileUtils.removeFilesByPattern(self._obsBatchLineFile)
+        if FileUtils.isRessourceExists(self._expBatchLineFile):
+            FileUtils.removeFilesByPattern(self._expBatchLineFile)
+        
+    def test_writeSubSNPFileWithSubSNPList(self):
+        self._lSNPResult = [{'subSNPName': "SubSNP1", '5flank': "A", '3flank': "T", 'position': 1, 'lineName': "1", 'allele': 1, 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1}, 
+                            {'subSNPName': "SubSNP2", '5flank': "T", '3flank': "A", 'position': 10, 'lineName': "1", 'allele': 2, 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                            {'subSNPName': "SubSNP3", '5flank': "T", '3flank': "A", 'position': 20, 'lineName': "2", 'allele': 3, 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1}]
+        
+        self._writeExpSubSNPFile()
+        self._Multifasta2SNPFileWriter._writeSubSNPFile(self._obsSubSNPFile, self._lSNPResult)
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSubSNPFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSubSNPFile, self._obsSubSNPFile))
+    
+    def test_writeAlleleFileWithAlleleDict(self):
+        self._dAlleleResult['A'] = 1
+        self._dAlleleResult['C'] = 2
+        self._dAlleleResult['T'] = 3
+                        
+        self._writeExpAlleleFile()
+        self._Multifasta2SNPFileWriter._writeAlleleFile(self._obsAlleleFile, self._dAlleleResult)
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsAlleleFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expAlleleFile, self._obsAlleleFile))
+        
+    def test_writeIndividualFileWithIndivList(self):
+        self._lIndividualResult = [{'individualNumber': 1, 'individualName': "Individual1", 'scientificName': "Arabidopsis thaliana"},
+                                   {'individualNumber': 2, 'individualName': "Individual2", 'scientificName': "Arabidopsis thaliana"}]
+              
+        self._writeExpIndividualFile()
+        
+        self._Multifasta2SNPFileWriter._writeIndividualFile(self._obsIndividualFile, self._lIndividualResult)
+        
+        self.assertTrue(FileUtils.isRessourceExists(self._obsIndividualFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expIndividualFile, self._obsIndividualFile))
+    
+    def test_writeSequenceFilesWithSequenceWrapper(self):        
+        self._writeInputFile()
+        self._writeExpSequenceFiles()
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(batchName, gene, taxon)
+        self._lSequenceWrapper = multifasta2SNPFile.createWrapperFromFile(self._inFileName)
+        lRefseq = []
+        lRefseq.append(self._lSequenceWrapper._iReferenceBioseq)
+        self._Multifasta2SNPFileWriter._writeSequenceFiles(self._obsSequenceFSAFile, self._obsSequenceCSVFile, lRefseq, taxon)
+
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSequenceFSAFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceFSAFile, self._obsSequenceFSAFile))
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSequenceCSVFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceCSVFile, self._obsSequenceCSVFile))        
+    
+    def test_writeBatchFile(self):        
+        self._dBatchResults = {'BatchNumber': "1", 'BatchName': "batch1", 'GeneName': "gene1", 'RefSeqName': "Sequence de Reference"}
+        lBatchResults = []
+        lBatchResults.append(self._dBatchResults)
+        self._writeExpBatchFile()
+        self._Multifasta2SNPFileWriter._writeBatchFile(self._obsBatchFile, lBatchResults)
+        self.assertTrue(FileUtils.isRessourceExists(self._obsBatchFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchFile, self._obsBatchFile))
+        
+    def test_writeBatchLineFile(self):        
+        self._lBatchLineResults = [{'IndividualNumber': "1", 'BatchNumber': "1"},
+                                   {'IndividualNumber': "2", 'BatchNumber': "1"}]
+        self._writeExpBatchLineFile()
+        self._Multifasta2SNPFileWriter._writeBatchLineFile(self._obsBatchLineFile, self._lBatchLineResults)
+        self.assertTrue(FileUtils.isRessourceExists(self._obsBatchLineFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchLineFile, self._obsBatchLineFile))
+        
+    def test_sortAlleleResultByAlleleNumber(self):
+        dAlleleResults = {'A': 3,
+                          'G': 1,
+                          'C': 2}
+        
+        lExpAlleleSortedList = [('G', 1),
+                                ('C', 2),
+                                ('A', 3)]        
+        
+        lObsAlleleSortedList = self._Multifasta2SNPFileWriter.sortAlleleResultByAlleleNumber(dAlleleResults)
+        self.assertEquals(lExpAlleleSortedList, lObsAlleleSortedList)
+        
+    def test_write(self):
+        
+        self._writeInputFile()
+        batchName = "batch1"
+        taxon = "Arabidopsis thaliana"
+        gene = "methyltransferase"
+        multifasta2SNPFile = Multifasta2SNPFile(taxon, batchName, gene)
+        self._lSequenceWrapper = multifasta2SNPFile.createWrapperFromFile(self._inFileName)
+        
+        
+        multifasta2SNPFile._lSubSNPFileResults = [{'subSNPName': "SubSNP1", '5flank': "A", '3flank': "T", 'position': 1, 'lineName': "1", 'allele': 1, 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1}, 
+                            {'subSNPName': "SubSNP2", '5flank': "T", '3flank': "A", 'position': 10, 'lineName': "1", 'allele': 2, 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1},
+                            {'subSNPName': "SubSNP3", '5flank': "T", '3flank': "A", 'position': 20, 'lineName': "2", 'allele': 3, 'batchNumber': 1, 'confidenceValue' : "A", 'type' : "SNP", 'length': 1}]
+        multifasta2SNPFile._dAlleleFileResults['A'] = 1
+        multifasta2SNPFile._dAlleleFileResults['C'] = 2
+        multifasta2SNPFile._dAlleleFileResults['T'] = 3
+        
+        multifasta2SNPFile._lIndividualFileResults = [{'individualNumber': 1, 'individualName': "Individual1", 'scientificName': "Arabidopsis thaliana"},
+                                   {'individualNumber': 2, 'individualName': "Individual2", 'scientificName': "Arabidopsis thaliana"}]
+        
+        multifasta2SNPFile._lBatchFileResults = [{'BatchNumber': "1", 'BatchName': "batch1", 'GeneName': "gene1", 'RefSeqName': "Sequence de Reference"}]
+        
+        multifasta2SNPFile._lBatchLineFileResults = [{'IndividualNumber': "1", 'BatchNumber': "1"},
+                                   {'IndividualNumber': "2", 'BatchNumber': "1"}] 
+        
+        
+        self._writeExpSubSNPFile()
+        self._writeExpAlleleFile()
+        self._writeExpIndividualFile()
+        self._writeExpSequenceFiles()
+        self._writeExpBatchFile()
+        self._writeExpBatchLineFile()
+        
+        self._Multifasta2SNPFileWriter.write(multifasta2SNPFile)
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSubSNPFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSubSNPFile, self._obsSubSNPFile))
+        self.assertTrue(FileUtils.isRessourceExists(self._obsAlleleFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expAlleleFile, self._obsAlleleFile))
+        self.assertTrue(FileUtils.isRessourceExists(self._obsIndividualFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expIndividualFile, self._obsIndividualFile))
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSequenceFSAFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceFSAFile, self._obsSequenceFSAFile))
+        self.assertTrue(FileUtils.isRessourceExists(self._obsSequenceCSVFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expSequenceCSVFile, self._obsSequenceCSVFile))
+        self.assertTrue(FileUtils.isRessourceExists(self._obsBatchFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchFile, self._obsBatchFile))
+        self.assertTrue(FileUtils.isRessourceExists(self._obsBatchLineFile))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expBatchLineFile, self._obsBatchLineFile))      
+    
+    def _writeExpSubSNPFile(self):
+        expFile = open(self._expSubSNPFile, "w")
+        expFile.write("SubSNPName;ConfidenceValue;Type;Position;5flank;3flank;Length;BatchNumber;IndividualNumber;PrimerType;PrimerNumber;Forward_or_Reverse;AlleleNumber\n")
+        expFile.write("SubSNP1;A;SNP;1;A;T;1;1;1;Sequence;;;1\n")
+        expFile.write("SubSNP2;A;SNP;10;T;A;1;1;1;Sequence;;;2\n")
+        expFile.write("SubSNP3;A;SNP;20;T;A;1;1;2;Sequence;;;3\n")
+        expFile.close()
+        
+    def _writeExpAlleleFile(self):
+        expFile = open(self._expAlleleFile, "w")
+        expFile.write("AlleleNumber;Value;Motif;NbCopy;Comment\n")
+        expFile.write("1;A;;;\n")
+        expFile.write("2;C;;;\n")
+        expFile.write("3;T;;;\n")
+        expFile.close()        
+        
+        
+    def _writeExpIndividualFile(self):
+        expFile = open(self._expIndividualFile, "w")
+        expFile.write("IndividualNumber;IndividualName;Description;AberrAneuploide;FractionLength;DeletionLineSynthesis;UrlEarImage;TypeLine;ChromNumber;ArmChrom;DeletionBin;ScientificName;local_germplasm_name;submitter_code;local_institute;donor_institute;donor_acc_id\n")
+        expFile.write("1;Individual1;;;;;;;;;;Arabidopsis thaliana;;;;;\n")
+        expFile.write("2;Individual2;;;;;;;;;;Arabidopsis thaliana;;;;;\n")
+        expFile.close()        
+
+    def _writeInputFile(self):
+        inFileHandle = open(self._inFileName, "w")
+        inFileHandle.write(">Sequence_de_Reference\n")
+        inFileHandle.write("CCTAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+        inFileHandle.write(">Line1\n")
+        inFileHandle.write("CCTTAGCCATTGCTTGGTGACTATGAAGGCAGTAGGCAAACCTCCACAATC\n")
+        inFileHandle.write(">Line2\n")
+        inFileHandle.write("CCTAAGCCATTGCTTGGTGACTATCAAGGCAGTAGCCAAACCTCCACAATA")
+        inFileHandle.close()
+        
+    def _writeExpSequenceFiles(self):
+        SequenceFSAFileHandle = open(self._expSequenceFSAFile, "w")
+        SequenceFSAFileHandle.write(">Sequence_de_Reference\n")
+        SequenceFSAFileHandle.write("CCTAAGCCATTGCTTGGTGATTATGAAGGCAGTAGTCAAACCTCCACAATC\n")
+        SequenceFSAFileHandle.close()
+        SequenceCSVFileHandle = open(self._expSequenceCSVFile, "w")
+        SequenceCSVFileHandle.write("SequenceName;SeqType;BankName;BankVersion;ACNumber;Locus;ScientificName\n")
+        SequenceCSVFileHandle.write("Sequence_de_Reference;Reference;;;;;Arabidopsis thaliana\n")
+        SequenceCSVFileHandle.close()
+        
+    def _writeExpBatchFile(self):
+        BatchFileHandle = open(self._expBatchFile, "w")
+        BatchFileHandle.write("BatchNumber: 1\n")
+        BatchFileHandle.write("BatchName: batch1\n")
+        BatchFileHandle.write("GeneName: gene1\n")
+        BatchFileHandle.write("Description: \n")
+        BatchFileHandle.write("ContactNumber: \n")
+        BatchFileHandle.write("ProtocolNumber: \n")
+        BatchFileHandle.write("ThematicNumber: \n")
+        BatchFileHandle.write("RefSeqName: Sequence de Reference\n")
+        BatchFileHandle.write("AlignmentFileName: \n")
+        BatchFileHandle.write("SeqName: \n")
+        BatchFileHandle.write("//\n")
+        BatchFileHandle.close()
+        
+    def _writeExpBatchLineFile(self):
+        BatchLineFileHandle = open(self._expBatchLineFile, "w")
+        BatchLineFileHandle.write("IndividualNumber;Pos5;Pos3;BatchNumber;Sequence\n")
+        BatchLineFileHandle.write("1;;;1;\n")
+        BatchLineFileHandle.write("2;;;1;\n")
+        BatchLineFileHandle.close()
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_PalsToAlign.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,43 @@
+import unittest
+from commons.core.utils.FileUtils import FileUtils
+import os
+from commons.core.parsing.PalsToAlign import PalsToAlign
+
+class Test_PalsToAlign(unittest.TestCase):
+    
+    def setUp(self):
+        self._palsFileName = "input.gff"
+        self._expAlignFileName = "file.align"
+        self._obsAlignFileName = "output.align"
+        
+    def tearDown(self):
+        os.remove(self._palsFileName)
+        os.remove(self._expAlignFileName)
+        os.remove(self._obsAlignFileName)
+
+    def testRun(self):
+        self._writePalsFile(self._palsFileName)
+        self._writeExpAlignFile(self._expAlignFileName)
+        
+        iPalsToAlign = PalsToAlign(self._palsFileName,self._obsAlignFileName)
+        iPalsToAlign.run()
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expAlignFileName, self._obsAlignFileName))
+
+
+    def _writePalsFile(self, fileName):
+        f = open(fileName, "w")
+        f.write("chunk01\tpals\thit\t32290\t32583\t252\t+\t.\tTarget chunk02 28975 29268; maxe 0.035\n")
+        f.write("chunk01\tpals\thit\t28975\t29268\t252\t+\t.\tTarget chunk02 32290 32583; maxe 0.035\n") 
+        f.write("chunk01\tpals\thit\t65932\t66032\t68\t+\t.\tTarget chunk02 59293 59395; maxe 0.085\n")
+        f.close()
+        
+    def _writeExpAlignFile(self, fileName):
+        f = open(fileName, "w")
+        f.write("chunk01\t28975\t29268\tchunk02\t32290\t32583\t0.0\t252\t96.5\n") 
+        f.write("chunk01\t32290\t32583\tchunk02\t28975\t29268\t0.0\t252\t96.5\n")
+        f.write("chunk01\t65932\t66032\tchunk02\t59293\t59395\t0.0\t68\t91.5\n")
+        f.close()
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_PathNum2Id.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,69 @@
+import unittest
+import os
+from commons.core.parsing.PathNum2Id import PathNum2Id
+from commons.core.utils.FileUtils import FileUtils
+
+
+class Test_PathNum2Id(unittest.TestCase):
+
+    def setUp(self):
+        self._inputFileName = "dummyInputPathFile.path"
+        self._outputFileName = "dummyOutputPathFile.path"
+        self._expectedFileName = "expectedpathFile.path"
+        self._pathNum2Id = PathNum2Id()
+
+    def tearDown(self):
+        os.remove( self._inputFileName )
+        os.remove( self._outputFileName )
+        os.remove( self._expectedFileName )
+
+    def test_RunWhithoutReturnAtEndOfFile(self):
+        self._createAndFillInputFileWhithoutReturnAtTheEnd()
+        self._createExpectedFile()
+        self._pathNum2Id.setInFileName( self._inputFileName )
+        self._pathNum2Id.setOutFileName( self._outputFileName )
+        self._pathNum2Id.run()
+        fileutils = FileUtils()
+        self.assertTrue(fileutils.are2FilesIdentical(self._outputFileName, self._expectedFileName))
+      
+    def test_RunWhithReturnAtEndOfFile(self):
+        self._createAndFillInputFileWhithReturnAtTheEnd()
+        self._createExpectedFile()
+        self._pathNum2Id.setInFileName( self._inputFileName )
+        self._pathNum2Id.setOutFileName( self._outputFileName )
+        self._pathNum2Id.run()
+        fileutils = FileUtils()
+        self.assertTrue(fileutils.are2FilesIdentical(self._outputFileName, self._expectedFileName))
+        
+    def _createExpectedFile(self):
+        f = open(self._expectedFileName, "w")
+        f.write("1\tblumeria_Grouper_590_20:NoCat_1\t91\t108\tDUF234\t5\t22\t1.5\t3.2\t0\n")
+        f.write("2\tblumeria_Grouper_590_20:NoCat_1\t111\t119\tDUF1414\t1\t9\t6.3\t2.9\t0\n")
+        f.write("3\tblumeria_Grouper_590_20:NoCat_3\t30\t37\tCPW_WPC\t1\t9\t7.7\t1.5\t0\n")
+        f.write("4\tblumeria_Grouper_590_20:NoCat_3\t55\t69\tHECT\t341\t355\t9.2e-06\t0.0\t0\n")
+        f.write("5\tblumeria_Grouper_590_20:NoCat_4\t82\t91\tDUF46\t173\t182\t0.11\t6.4\t0\n")
+        f.write("6\tblumeria_Grouper_590_20:NoCat_5\t121\t125\tPOC4\t276\t280\t6.3\t-1.7\t0\n")
+        f.close()
+
+    def _createAndFillInputFileWhithoutReturnAtTheEnd(self):
+        f = open(self._inputFileName, "w")
+        f.write("1\tblumeria_Grouper_590_20:NoCat_1\t91\t108\tDUF234\t5\t22\t1.5\t3.2\t0\n")
+        f.write("2\tblumeria_Grouper_590_20:NoCat_1\t111\t119\tDUF1414\t1\t9\t6.3\t2.9\t0\n")
+        f.write("3\tblumeria_Grouper_590_20:NoCat_3\t30\t37\tCPW_WPC\t1\t9\t7.7\t1.5\t0\n")
+        f.write("1\tblumeria_Grouper_590_20:NoCat_3\t55\t69\tHECT\t341\t355\t9.2e-06\t0.0\t0\n")
+        f.write("2\tblumeria_Grouper_590_20:NoCat_4\t82\t91\tDUF46\t173\t182\t0.11\t6.4\t0\n")
+        f.write("3\tblumeria_Grouper_590_20:NoCat_5\t121\t125\tPOC4\t276\t280\t6.3\t-1.7\t0")
+        f.close()
+        
+    def _createAndFillInputFileWhithReturnAtTheEnd(self):
+        f = open(self._inputFileName, "w")
+        f.write("1\tblumeria_Grouper_590_20:NoCat_1\t91\t108\tDUF234\t5\t22\t1.5\t3.2\t0\n")
+        f.write("2\tblumeria_Grouper_590_20:NoCat_1\t111\t119\tDUF1414\t1\t9\t6.3\t2.9\t0\n")
+        f.write("3\tblumeria_Grouper_590_20:NoCat_3\t30\t37\tCPW_WPC\t1\t9\t7.7\t1.5\t0\n")
+        f.write("1\tblumeria_Grouper_590_20:NoCat_3\t55\t69\tHECT\t341\t355\t9.2e-06\t0.0\t0\n")
+        f.write("2\tblumeria_Grouper_590_20:NoCat_4\t82\t91\tDUF46\t173\t182\t0.11\t6.4\t0\n")
+        f.write("3\tblumeria_Grouper_590_20:NoCat_5\t121\t125\tPOC4\t276\t280\t6.3\t-1.7\t0\n")
+        f.close()
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_PslParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,165 @@
+from commons.core.parsing.PslParser import PslParser
+import unittest, os
+
+
+class Test_PslParser(unittest.TestCase):
+
+    def test_forward(self):
+        fileName = "tmpFile.psl"
+        handle   = open(fileName, "w")
+        handle.write("psLayout version 3\n\nmatch\tmis-\trep.\tN's\tQ gap\tQ gap\tT gap\tT gap\tstrand\tQ\tQ\tQ\tQ\T\tT\tT\tT\tblock\tblockSizes\tqStarts\ttStarts\nmatch\tmatch\tcount\tbases\tcount\tbases\tname\tsize\tstart\tend\tname\tsize\tstart\tend\tcount\n---------------------------------------------------------------------------------------------------------------------------------------------------------------\n158\t0\t0\t0\t0\t0\t1\t158\t+\ttest\t158\t0\t158\tchr1\t1501\t237\t553\t2\t79,79,\t0,79,\t237,474,\n")
+        handle.close()
+
+        parser = PslParser(fileName, 0)
+        self.assertEquals(parser.getNbMappings(), 1)
+        for mapping in parser.getIterator():
+            transcript = mapping.getTranscript()
+            self.assertEquals(transcript.getName(), "test")
+            self.assertEquals(transcript.getChromosome(), "chr1")
+            self.assertEquals(transcript.getDirection(), 1)
+            self.assertEquals(transcript.getStart(), 238)
+            self.assertEquals(transcript.getEnd(),   553)
+            self.assertEquals(transcript.getNbExons(), 2)
+            for i, exon in enumerate(transcript.getExons()):
+                if i == 0:
+                    self.assertEquals(exon.getStart(), 238)
+                    self.assertEquals(exon.getEnd(),   316)
+                elif i == 1:
+                    self.assertEquals(exon.getStart(), 475)
+                    self.assertEquals(exon.getEnd(),   553)
+        os.remove(fileName)
+        
+        
+    def test_backward(self):
+        fileName = "tmpFile.psl"
+        handle   = open(fileName, "w")
+        handle.write("psLayout version 3\n\nmatch\tmis-\trep.\tN's\tQ gap\tQ gap\tT gap\tT gap\tstrand\tQ\tQ\tQ\tQ\tT\tT\tT\tT\tblock\tblockSizes\tqStarts\ttStarts\nmatch\tmatch\tcount\tbases\tcount\tbases\tname\tsize\tstart\tend\tname\tsize\tstart\tend\tcount\n---------------------------------------------------------------------------------------------------------------------------------------------------------------\n158\t0\t0\t0\t0\t0\t1\t158\t-\ttest\t158\t0\t158\tchr1\t1501\t237\t553\t2\t79,79,\t0,79,\t237,474,\n")
+
+        handle.close()
+
+        parser = PslParser(fileName, 0)
+        self.assertEquals(parser.getNbMappings(), 1)
+        for mapping in parser.getIterator():
+            transcript = mapping.getTranscript()
+            self.assertEquals(transcript.getName(), "test")
+            self.assertEquals(transcript.getChromosome(), "chr1")
+            self.assertEquals(transcript.getDirection(), -1)
+            self.assertEquals(transcript.getStart(), 238)
+            self.assertEquals(transcript.getEnd(),   553)
+            self.assertEquals(transcript.getNbExons(), 2)
+            for i, exon in enumerate(transcript.getExons()):
+                if i == 1:
+                    self.assertEquals(exon.getStart(), 238)
+                    self.assertEquals(exon.getEnd(),   316)
+                elif i == 0:
+                    self.assertEquals(exon.getStart(), 475)
+                    self.assertEquals(exon.getEnd(),   553)
+        os.remove(fileName)
+
+
+    def test_query_forward_target_forward(self):
+        fileName = "tmpFile.psl"
+        handle   = open(fileName, "w")
+        handle.write("psLayout version 3\n\nmatch\tmis-\trep.\tN's\tQ gap\tQ gap\tT gap\tT gap\tstrand\tQ\tQ\tQ\tQ\tT\tT\tT\tT\tblock\tblockSizes\tqStarts\ttStarts\nmatch\tmatch\tcount\tbases\tcount\tbases\tname\tsize\tstart\tend\tname\tsize\tstart\tend\tcount\n---------------------------------------------------------------------------------------------------------------------------------------------------------------\n241\t0\t0\t0\t0\t0\t1\t60\t++\tseq1\t255\t9\t250\tref\t2262\t59\t360\t2\t121,120,\t9,130,\t59,240,\n")
+        handle.close()
+
+        parser = PslParser(fileName, 0)
+        self.assertEquals(parser.getNbMappings(), 1)
+        for mapping in parser.getIterator():
+            transcript = mapping.getTranscript()
+            self.assertEquals(transcript.getName(), "seq1")
+            self.assertEquals(transcript.getChromosome(), "ref")
+            self.assertEquals(transcript.getDirection(), 1)
+            self.assertEquals(transcript.getStart(), 60)
+            self.assertEquals(transcript.getEnd(),   360)
+            self.assertEquals(transcript.getNbExons(), 2)
+            for i, exon in enumerate(transcript.getExons()):
+                if i == 0:
+                    self.assertEquals(exon.getStart(), 60)
+                    self.assertEquals(exon.getEnd(),   180)
+                elif i == 1:
+                    self.assertEquals(exon.getStart(), 241)
+                    self.assertEquals(exon.getEnd(),   360)
+        os.remove(fileName)
+
+    def test_query_backward_target_forward(self):
+        fileName = "tmpFile.psl"
+        handle   = open(fileName, "w")
+        handle.write("psLayout version 3\n\nmatch\tmis-\trep.\tN's\tQ gap\tQ gap\tT gap\tT gap\tstrand\tQ\tQ\tQ\tQ\tT\tT\tT\tT\tblock\tblockSizes\tqStarts\ttStarts\nmatch\tmatch\tcount\tbases\tcount\tbases\tname\tsize\tstart\tend\tname\tsize\tstart\tend\tcount\n---------------------------------------------------------------------------------------------------------------------------------------------------------------\n241\t0\t0\t0\t0\t0\t1\t60\t-+\tseq2\t255\t5\t246\tref\t2262\t59\t360\t2\t121,120,\t9,130,\t59,240,\n")
+        handle.close()
+
+        parser = PslParser(fileName, 0)
+        self.assertEquals(parser.getNbMappings(), 1)
+        for mapping in parser.getIterator():
+            transcript = mapping.getTranscript()
+            self.assertEquals(transcript.getName(), "seq2")
+            self.assertEquals(transcript.getChromosome(), "ref")
+            self.assertEquals(transcript.getDirection(), -1)
+            self.assertEquals(transcript.getStart(), 60)
+            self.assertEquals(transcript.getEnd(),   360)
+            self.assertEquals(transcript.getNbExons(), 2)
+            for i, exon in enumerate(transcript.getExons()):
+                if i == 1:
+                    self.assertEquals(exon.getStart(), 60)
+                    self.assertEquals(exon.getEnd(),   180)
+                elif i == 0:
+                    self.assertEquals(exon.getStart(), 241)
+                    self.assertEquals(exon.getEnd(),   360)
+        os.remove(fileName)
+
+    def test_query_backward_target_backward(self):
+        fileName = "tmpFile.psl"
+        handle   = open(fileName, "w")
+        handle.write("psLayout version 3\n\nmatch\tmis-\trep.\tN's\tQ gap\tQ gap\tT gap\tT gap\tstrand\tQ\tQ\tQ\tQ\tT\tT\tT\tT\tblock\tblockSizes\tqStarts\ttStarts\nmatch\tmatch\tcount\tbases\tcount\tbases\tname\tsize\tstart\tend\tname\tsize\tstart\tend\tcount\n---------------------------------------------------------------------------------------------------------------------------------------------------------------\n241\t1\t0\t0\t0\t0\t1\t60\t--\tseq1\t255\t8\t250\tref\t2262\t58\t360\t2\t120,122,\t5,125,\t1902,2082,\n")
+        handle.close()
+
+        parser = PslParser(fileName, 0)
+        self.assertEquals(parser.getNbMappings(), 1)
+        for mapping in parser.getIterator():
+            transcript = mapping.getTranscript()
+            self.assertEquals(transcript.getName(), "seq1")
+            self.assertEquals(transcript.getChromosome(), "ref")
+            self.assertEquals(transcript.getDirection(), 1)
+            self.assertEquals(transcript.getStart(), 59)
+            self.assertEquals(transcript.getEnd(),   360)
+            self.assertEquals(transcript.getNbExons(), 2)
+            for i, exon in enumerate(transcript.getExons()):
+                if i == 0:
+                    self.assertEquals(exon.getStart(), 59)
+                    self.assertEquals(exon.getEnd(),   180)
+                elif i == 1:
+                    self.assertEquals(exon.getStart(), 241)
+                    self.assertEquals(exon.getEnd(),   360)
+        os.remove(fileName)
+
+
+    def test_query_forward_target_backward(self):
+        fileName = "tmpFile.psl"
+        handle   = open(fileName, "w")
+        handle.write("psLayout version 3\n\nmatch\tmis-\trep.\tN's\tQ gap\tQ gap\tT gap\tT gap\tstrand\tQ\tQ\tQ\tQ\tT\tT\tT\tT\tblock\tblockSizes\tqStarts\ttStarts\nmatch\tmatch\tcount\tbases\tcount\tbases\tname\tsize\tstart\tend\tname\tsize\tstart\tend\tcount\n---------------------------------------------------------------------------------------------------------------------------------------------------------------\n241\t1\t0\t0\t0\t0\t1\t60\t+-\tseq2\t255\t5\t247\tref\t2262\t58\t360\t2\t120,122,\t5,125,\t1902,2082,\n")
+        handle.close()
+
+        parser = PslParser(fileName, 0)
+        self.assertEquals(parser.getNbMappings(), 1)
+        for mapping in parser.getIterator():
+            transcript = mapping.getTranscript()
+            self.assertEquals(transcript.getName(), "seq2")
+            self.assertEquals(transcript.getChromosome(), "ref")
+            self.assertEquals(transcript.getDirection(), -1)
+            self.assertEquals(transcript.getStart(), 59)
+            self.assertEquals(transcript.getEnd(),   360)
+            self.assertEquals(transcript.getNbExons(), 2)
+            for i, exon in enumerate(transcript.getExons()):
+                if i == 1:
+                    self.assertEquals(exon.getStart(), 59)
+                    self.assertEquals(exon.getEnd(),   180)
+                elif i == 0:
+                    self.assertEquals(exon.getStart(), 241)
+                    self.assertEquals(exon.getEnd(),   360)
+        os.remove(fileName)
+
+
+if __name__ == "__main__":
+    unittest.main()
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_SsrParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,154 @@
+from commons.core.parsing.SsrParser import SsrParser
+import unittest
+
+
+class Test_SsrParser(unittest.TestCase):
+
+
+    def test_setAttributesFromString(self):
+        ssrLine = "MRRE1H001B07RM1\t1\t2\tta\t19\t153\t190\t734"
+        
+        iSsrParser = SsrParser()
+        iSsrParser.setAttributesFromString(ssrLine)
+        
+        obsBES_name = iSsrParser.getBesName()
+        obsBES_redundancy = iSsrParser.getBesRedundancy()
+        obsSSR_nbNucleotides = iSsrParser.getSsrNbNucleotides()
+        obsSSR_Motif = iSsrParser.getSsrMotif()
+        obsSSR_Motif_number = iSsrParser.getSsrMotifNumber()
+        obsSSR_start = iSsrParser.getSsrStart()
+        obsSSR_end = iSsrParser.getSsrEnd()
+        obsBES_size = iSsrParser.getBesSize()
+        
+        expBES_name = 'MRRE1H001B07RM1'
+        expBES_redundancy = '1'
+        expSSR_nbNucleotides = '2'
+        expSSR_Motif = 'ta'
+        expSSR_Motif_number = '19'
+        expSSR_start = '153'
+        expSSR_end = '190'
+        expBES_size = '734'
+        
+        self.assertEquals(expBES_name, obsBES_name)
+        self.assertEquals(expBES_redundancy, obsBES_redundancy)
+        self.assertEquals(expSSR_nbNucleotides, obsSSR_nbNucleotides)
+        self.assertEquals(expSSR_Motif, obsSSR_Motif)
+        self.assertEquals(expSSR_Motif_number, obsSSR_Motif_number)
+        self.assertEquals(expSSR_start, obsSSR_start)
+        self.assertEquals(expSSR_end, obsSSR_end)
+        self.assertEquals(expBES_size, obsBES_size)
+        
+    def test_setAttributesFromString_empty_BESName(self):
+        ssrLine = "\t1\t2\tta\t19\t153\t190\t734"
+        
+        iSsrParser = SsrParser()
+        iSsrParser.setAttributesFromString(ssrLine)
+        
+        obsBES_name = iSsrParser.getBesName()
+        obsBES_redundancy = iSsrParser.getBesRedundancy()
+        obsSSR_nbNucleotides = iSsrParser.getSsrNbNucleotides()
+        obsSSR_Motif = iSsrParser.getSsrMotif()
+        obsSSR_Motif_number = iSsrParser.getSsrMotifNumber()
+        obsSSR_start = iSsrParser.getSsrStart()
+        obsSSR_end = iSsrParser.getSsrEnd()
+        obsBES_size = iSsrParser.getBesSize()
+        
+        expBES_name = ''
+        expBES_redundancy = ''
+        expSSR_nbNucleotides = ''
+        expSSR_Motif = ''
+        expSSR_Motif_number = ''
+        expSSR_start = ''
+        expSSR_end = ''
+        expBES_size = ''
+        
+        self.assertEquals(expBES_name, obsBES_name)
+        self.assertEquals(expBES_redundancy, obsBES_redundancy)
+        self.assertEquals(expSSR_nbNucleotides, obsSSR_nbNucleotides)
+        self.assertEquals(expSSR_Motif, obsSSR_Motif)
+        self.assertEquals(expSSR_Motif_number, obsSSR_Motif_number)
+        self.assertEquals(expSSR_start, obsSSR_start)
+        self.assertEquals(expSSR_end, obsSSR_end)
+        self.assertEquals(expBES_size, obsBES_size)
+
+    def test_setAttributesFromString_less_than_8_fields(self):
+        ssrLine = "1\t2\tta\t19\t153\t190\t734"
+        
+        iSsrParser = SsrParser()
+        iSsrParser.setAttributesFromString(ssrLine)
+        
+        obsBES_name = iSsrParser.getBesName()
+        obsBES_redundancy = iSsrParser.getBesRedundancy()
+        obsSSR_nbNucleotides = iSsrParser.getSsrNbNucleotides()
+        obsSSR_Motif = iSsrParser.getSsrMotif()
+        obsSSR_Motif_number = iSsrParser.getSsrMotifNumber()
+        obsSSR_start = iSsrParser.getSsrStart()
+        obsSSR_end = iSsrParser.getSsrEnd()
+        obsBES_size = iSsrParser.getBesSize()
+        
+        expBES_name = ''
+        expBES_redundancy = ''
+        expSSR_nbNucleotides = ''
+        expSSR_Motif = ''
+        expSSR_Motif_number = ''
+        expSSR_start = ''
+        expSSR_end = ''
+        expBES_size = ''
+        
+        self.assertEquals(expBES_name, obsBES_name)
+        self.assertEquals(expBES_redundancy, obsBES_redundancy)
+        self.assertEquals(expSSR_nbNucleotides, obsSSR_nbNucleotides)
+        self.assertEquals(expSSR_Motif, obsSSR_Motif)
+        self.assertEquals(expSSR_Motif_number, obsSSR_Motif_number)
+        self.assertEquals(expSSR_start, obsSSR_start)
+        self.assertEquals(expSSR_end, obsSSR_end)
+        self.assertEquals(expBES_size, obsBES_size)
+        
+    def test_setAttributes(self):
+        lResults = ['MRRE1H001B07RM1','1','2','ta','19','153','190','734']
+        lineNumber = 1
+        
+        iSsrParser = SsrParser()
+        iSsrParser.setAttributes(lResults, lineNumber)
+        
+        obsBES_name = iSsrParser.getBesName()
+        obsBES_redundancy = iSsrParser.getBesRedundancy()
+        obsSSR_nbNucleotides = iSsrParser.getSsrNbNucleotides()
+        obsSSR_Motif = iSsrParser.getSsrMotif()
+        obsSSR_Motif_number = iSsrParser.getSsrMotifNumber()
+        obsSSR_start = iSsrParser.getSsrStart()
+        obsSSR_end = iSsrParser.getSsrEnd()
+        obsBES_size = iSsrParser.getBesSize()
+        
+        expBES_name = 'MRRE1H001B07RM1'
+        expBES_redundancy = '1'
+        expSSR_nbNucleotides = '2'
+        expSSR_Motif = 'ta'
+        expSSR_Motif_number = '19'
+        expSSR_start = '153'
+        expSSR_end = '190'
+        expBES_size = '734'
+        
+        self.assertEquals(expBES_name, obsBES_name)
+        self.assertEquals(expBES_redundancy, obsBES_redundancy)
+        self.assertEquals(expSSR_nbNucleotides, obsSSR_nbNucleotides)
+        self.assertEquals(expSSR_Motif, obsSSR_Motif)
+        self.assertEquals(expSSR_Motif_number, obsSSR_Motif_number)
+        self.assertEquals(expSSR_start, obsSSR_start)
+        self.assertEquals(expSSR_end, obsSSR_end)
+        self.assertEquals(expBES_size, obsBES_size)
+        
+    def test_eq_Equals(self):
+        SsrParser1 = SsrParser('MRRE1H001A12RM1', '1', '4', 'ttta', '6', '272', '295', '724')
+        SsrParser2 = SsrParser('MRRE1H001A12RM1', '1', '4', 'ttta', '6', '272', '295', '724')
+        
+        self.assertTrue(SsrParser1 == SsrParser2)
+        
+    def test_eq_NotEquals(self):
+        SsrParser1 = SsrParser('MRRE1H001A12RM1', '1', '4', 'ttta', '6', '272', '295', '724')
+        SsrParser2 = SsrParser('MRRE1H001A12RM3', '1', '5', 'ttta', '6', '272', '295', '852')
+        
+        self.assertFalse(SsrParser1 == SsrParser2)
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_VarscanFile.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,287 @@
+from commons.core.parsing.VarscanFile import VarscanFile
+from commons.core.parsing.VarscanHit import VarscanHit
+import unittest
+import os
+from commons.core.parsing.VarscanHit_WithTag import VarscanHit_WithTag
+from commons.core.parsing.VarscanHit_v2_2_8 import VarscanHit_v2_2_8
+from commons.core.parsing.VarscanHit_v2_2_8_WithTag import VarscanHit_v2_2_8_WithTag
+from commons.core.checker.CheckerException import CheckerException
+
+class Test_VarscanFile(unittest.TestCase):
+
+    def test_parse_fileWithHeader(self):
+        varscanFileName = "file.varscan"
+        self._writeVarscanFile(varscanFileName)
+        
+        varscanHit1 = VarscanHit()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('32')
+        varscanHit1.setRef('C')
+        varscanHit1.setVar('T')
+        
+        varscanHit2 = VarscanHit()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('34')
+        varscanHit2.setRef('A')
+        varscanHit2.setVar('T')
+        expVarscanHitsList = [varscanHit1, varscanHit2]
+        
+        iVarscanFile = VarscanFile(varscanFileName)
+        iVarscanFile.parse()
+        obsVarscanHitsList = iVarscanFile.getVarscanHitsList()
+        os.remove(varscanFileName)
+        
+        self.assertEquals(expVarscanHitsList, obsVarscanHitsList)   
+
+    def test_parse_FileWithoutHeader(self):
+        varscanFileName = "file.varscan"
+        self._writeVarscanFileWithoutHeader(varscanFileName)
+        
+        varscanHit1 = VarscanHit()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('32')
+        varscanHit1.setRef('C')
+        varscanHit1.setVar('T')
+        
+        varscanHit2 = VarscanHit()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('34')
+        varscanHit2.setRef('A')
+        varscanHit2.setVar('T')
+        expVarscanHitsList = [varscanHit1, varscanHit2]
+        
+        iVarscanFile = VarscanFile(varscanFileName)
+        iVarscanFile.parse()
+        obsVarscanHitsList = iVarscanFile.getVarscanHitsList()
+        obsTypeOfVarscanFile = iVarscanFile.getTypeOfVarscanFile()
+        expTypeOfVarscanFile = "Varscan_2_2"
+        
+        self.assertEquals(expVarscanHitsList, obsVarscanHitsList) 
+        self.assertEquals(expTypeOfVarscanFile, obsTypeOfVarscanFile) 
+        os.remove(varscanFileName)
+        
+    def test_parse_VarscanFileWithTag(self):
+        inputFileName = "%s/commons/core/parsing/test/varscan.tab" % os.environ["REPET_PATH"]
+        self._writeVarscanFileWithTag(inputFileName)
+        launcher = VarscanFile(inputFileName)
+        launcher.parse()
+        obsListOfVarscanHits = launcher.getListOfVarscanHits() 
+        
+        varscanHit1 = VarscanHit_WithTag()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('32')
+        varscanHit1.setRef('C')
+        varscanHit1.setVar('T')
+        varscanHit1.setTag('EspeceA')
+        
+        varscanHit2 = VarscanHit_WithTag()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('34')
+        varscanHit2.setRef('A')
+        varscanHit2.setVar('T')
+        varscanHit2.setTag('EspeceA')
+        expVarscanHitsList = [varscanHit1, varscanHit2] 
+        
+        obsTypeOfVarscanFile = launcher.getTypeOfVarscanFile()
+        expTypeOfVarscanFile = "Varscan_2_2_WithTag"
+        
+        self.assertEquals(expVarscanHitsList, obsListOfVarscanHits) 
+        self.assertEquals(expTypeOfVarscanFile, obsTypeOfVarscanFile) 
+        os.remove(inputFileName)
+        
+    def test_parse_VarscanFile_v2_2_8(self):
+        inputFileName = "%s/commons/core/parsing/test/varscan.tab" % os.environ["REPET_PATH"]
+        self._writeVarscanFile_v2_2_8(inputFileName)
+        launcher = VarscanFile(inputFileName)
+        launcher.parse()
+        obsListOfVarscanHits = launcher.getListOfVarscanHits() 
+        
+        varscanHit1 = VarscanHit_v2_2_8()
+        varscanHit1.setChrom('C11HBa0064J13_LR285')
+        varscanHit1.setPosition('3227')
+        varscanHit1.setRef('G')
+        varscanHit1.setVar('A')
+        varscanHit1.setCns('A')
+        
+        varscanHit2 = VarscanHit_v2_2_8()
+        varscanHit2.setChrom('C11HBa0064J13_LR285')
+        varscanHit2.setPosition('3230')
+        varscanHit2.setRef('G')
+        varscanHit2.setVar('T')
+        varscanHit2.setCns('T')
+        expVarscanHitsList = [varscanHit1, varscanHit2] 
+        
+        obsTypeOfVarscanFile = launcher.getTypeOfVarscanFile()
+        expTypeOfVarscanFile = "Varscan_2_2_8"
+        
+        self.assertEquals(expVarscanHitsList, obsListOfVarscanHits) 
+        self.assertEquals(expTypeOfVarscanFile, obsTypeOfVarscanFile) 
+        os.remove(inputFileName)
+    
+    def test_parse_other(self):
+        inputFileName = "%s/commons/core/parsing/test/varscan.tab" % os.environ["REPET_PATH"]
+        self._writeOther(inputFileName)
+        launcher = VarscanFile(inputFileName)
+        try:
+            launcher.parse()
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        expMessage = "Warning: this line (l.1) is not a valid varscan line !"
+        obsMessage = checkerExceptionInstance.msg
+        os.remove(inputFileName)
+        self.assertEquals(expMessage, obsMessage) 
+        
+    def test__eq__notEqual(self):
+        lVarscanHits1 = [VarscanHit("chrom", "12", "T", "G"), VarscanHit("chrom", "14", "T", "G")]
+        iVarscanFile1 = VarscanFile()
+        iVarscanFile1.setVarscanHitsList(lVarscanHits1)
+        lVarscanHits2 = [VarscanHit("chrom", "12", "T", "G"), VarscanHit("chrom", "14", "T", "C")]
+        iVarscanFile2 = VarscanFile()
+        iVarscanFile2.setVarscanHitsList(lVarscanHits2)
+
+        self.assertNotEquals(iVarscanFile1, iVarscanFile2)
+        
+    def test__eq__equal(self):
+        lVarscanHits1 = [VarscanHit("chrom", "12", "T", "G"), VarscanHit("chrom", "14", "T", "G")]
+        iVarscanFile1 = VarscanFile()
+        iVarscanFile1.setVarscanHitsList(lVarscanHits1)
+        lVarscanHits2 = [VarscanHit("chrom", "12", "T", "G"), VarscanHit("chrom", "14", "T", "G")]
+        iVarscanFile2 = VarscanFile()
+        iVarscanFile2.setVarscanHitsList(lVarscanHits2)
+
+        self.assertEquals(iVarscanFile1, iVarscanFile2)
+        
+    def test_selectTypeOfVarscanHitObject_noVarscanHit(self):
+        launcher = VarscanFile()
+        launcher.setTypeOfVarscanFile("")
+        try:
+            launcher.selectTypeOfVarscanHitObject()
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        expMessage = "Error: no varscan object found !"
+        obsMessage = checkerExceptionInstance.msg
+        self.assertEquals(expMessage, obsMessage) 
+        
+    def test_selectTypeOfVarscanHitObject_VarscanHit(self):
+        launcher = VarscanFile()
+        launcher.setTypeOfVarscanFile("Varscan_2_2")
+        obsVarscanHit = launcher.selectTypeOfVarscanHitObject()
+        expVarscanHit = VarscanHit()
+        self.assertEquals(expVarscanHit, obsVarscanHit)
+        
+    def test_selectTypeOfVarscanHitObject_VarscanHitWithTag(self):
+        launcher = VarscanFile()
+        launcher.setTypeOfVarscanFile("Varscan_2_2_WithTag")
+        obsVarscanHit = launcher.selectTypeOfVarscanHitObject()
+        expVarscanHit = VarscanHit_WithTag()
+        self.assertEquals(expVarscanHit, obsVarscanHit)
+        
+    def test_selectTypeOfVarscanHitObject_noVarscanHit_2_2_8(self):
+        launcher = VarscanFile()
+        launcher.setTypeOfVarscanFile("Varscan_2_2_8")
+        obsVarscanHit = launcher.selectTypeOfVarscanHitObject()
+        expVarscanHit = VarscanHit_v2_2_8()
+        self.assertEquals(expVarscanHit, obsVarscanHit)
+        
+    def test_selectTypeOfVarscanHitObject_noVarscanHit_2_2_8_WithTag(self):
+        launcher = VarscanFile()
+        launcher.setTypeOfVarscanFile("Varscan_2_2_8_WithTag")
+        obsVarscanHit = launcher.selectTypeOfVarscanHitObject()
+        expVarscanHit = VarscanHit_v2_2_8_WithTag()
+        self.assertEquals(expVarscanHit, obsVarscanHit)
+        
+    def test_createVarscanObjectFromLine_VarscanHit(self):
+        line = "C02HBa0291P19_LR48\t32\tC\tT\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n"
+        nbLine = 1
+        launcher = VarscanFile()
+        launcher.setTypeOfVarscanFile("Varscan_2_2")
+        obsVarscanHit = launcher.createVarscanObjectFromLine(line, nbLine)
+        expVarscanHit = VarscanHit()
+        expVarscanHit.setChrom('C02HBa0291P19_LR48')
+        expVarscanHit.setPosition('32')
+        expVarscanHit.setRef('C')
+        expVarscanHit.setVar('T')
+        self.assertEquals(expVarscanHit, obsVarscanHit)
+        
+    def test_createVarscanObjectFromLine_VarscanHitWithTag(self):
+        line = "C02HBa0291P19_LR48\t32\tC\tT\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\tEspeceA\n"
+        nbLine = 1
+        launcher = VarscanFile()
+        launcher.setTypeOfVarscanFile("Varscan_2_2_WithTag")
+        obsVarscanHit = launcher.createVarscanObjectFromLine(line, nbLine)
+        expVarscanHit = VarscanHit_WithTag()
+        expVarscanHit.setChrom('C02HBa0291P19_LR48')
+        expVarscanHit.setPosition('32')
+        expVarscanHit.setRef('C')
+        expVarscanHit.setVar('T')
+        expVarscanHit.setTag('EspeceA')
+        self.assertEquals(expVarscanHit, obsVarscanHit)
+        
+    def test_createVarscanObjectFromLine_VarscanHit_v2_2_8(self):
+        line = "C11HBa0064J13_LR285\t3227\tG\tA\t0\t1\t100%\t0\t1\t0\t54\t0.98\t0\t1\t0\t0\t1\t0\tA\n"
+        nbLine = 1
+        launcher = VarscanFile()
+        launcher.setTypeOfVarscanFile("Varscan_2_2_8")
+        obsVarscanHit = launcher.createVarscanObjectFromLine(line, nbLine)
+        expVarscanHit = VarscanHit_v2_2_8()
+        expVarscanHit.setChrom('C11HBa0064J13_LR285')
+        expVarscanHit.setPosition('3227')
+        expVarscanHit.setRef('G')
+        expVarscanHit.setVar('A')
+        expVarscanHit.setCns('A')
+        self.assertEquals(expVarscanHit, obsVarscanHit)
+        
+    def test_createVarscanObjectFromLine_VarscanHit_v2_2_8_WithTag(self):
+        line = "C11HBa0064J13_LR285\t3227\tG\tA\t0\t1\t100%\t0\t1\t0\t54\t0.98\t0\t1\t0\t0\t1\t0\tA\tEspeceA\n"
+        nbLine = 1
+        launcher = VarscanFile()
+        launcher.setTypeOfVarscanFile("Varscan_2_2_8_WithTag")
+        obsVarscanHit = launcher.createVarscanObjectFromLine(line, nbLine)
+        expVarscanHit = VarscanHit_v2_2_8_WithTag()
+        expVarscanHit.setChrom('C11HBa0064J13_LR285')
+        expVarscanHit.setPosition('3227')
+        expVarscanHit.setRef('G')
+        expVarscanHit.setVar('A')
+        expVarscanHit.setCns('A')
+        expVarscanHit.setTag('EspeceA')
+        self.assertEquals(expVarscanHit, obsVarscanHit)
+    
+    def _writeVarscanFile(self, varscanFileName):
+        varscanFile = open(varscanFileName, 'w')
+        varscanFile.write("Chrom\tPosition\tRef\tVar\tReads1\tReads2\tVarFreq\tStrands1\tStrands2\tQual1\tQual2\tPvalue\n")
+        varscanFile.write("C02HBa0291P19_LR48\t32\tC\tT\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n")
+        varscanFile.write("C02HBa0291P19_LR48\t34\tA\tT\t1\t2\t66,67%\t1\t1\t40\t34\t0.3999999999999999\n")
+        varscanFile.close()
+
+    def _writeVarscanFileWithoutHeader(self, varscanFileName):
+        varscanFile = open(varscanFileName, 'w')
+        varscanFile.write("C02HBa0291P19_LR48\t32\tC\tT\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n")
+        varscanFile.write("C02HBa0291P19_LR48\t34\tA\tT\t1\t2\t66,67%\t1\t1\t40\t34\t0.3999999999999999\n")
+        varscanFile.close()
+    
+    def _writeVarscanFileWithTag(self, varscanFileName):
+        varscanFile = open(varscanFileName, 'w')
+        varscanFile.write("Chrom\tPosition\tRef\tVar\tReads1\tReads2\tVarFreq\tStrands1\tStrands2\tQual1\tQual2\tPvalue\n")
+        varscanFile.write("C02HBa0291P19_LR48\t32\tC\tT\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\tEspeceA\n")
+        varscanFile.write("C02HBa0291P19_LR48\t34\tA\tT\t1\t2\t66,67%\t1\t1\t40\t34\t0.3999999999999999\tEspeceA\n")
+        varscanFile.close()
+    
+    def _writeVarscanFile_v2_2_8(self, varscanFileName):
+        varscanFile = open(varscanFileName, 'w')
+        varscanFile.write("Chrom\tPosition\tRef\tCons\tReads1\tReads2\tVarFreq\tStrands1\tStrands2\tQual1\tQual2\tPvalue\tMapQual1\tMapQual2\tReads1Plus\tReads1Minus\tReads2Plus\tReads2Minus\tVarAllele\n")
+        varscanFile.write("C11HBa0064J13_LR285\t3227\tG\tA\t0\t1\t100%\t0\t1\t0\t54\t0.98\t0\t1\t0\t0\t1\t0\tA\n")
+        varscanFile.write("C11HBa0064J13_LR285\t3230\tG\tT\t0\t1\t100%\t0\t1\t0\t54\t0.98\t0\t1\t0\t0\t1\t0\tT\n")
+        varscanFile.close()
+    
+    def _writeOther(self, fileName):
+        file = open(fileName, 'w')
+        file.write('##gff-version 3\n')
+        file.write('chr16\tBlatToGff\tBES\t21686950\t21687294\t.\t+\t.\tID=MRRE1H001H13FM1;Name=MRRE1H001H13FM1;bes_start=21686950;bes_end=21687294;bes_size=22053297\n')
+        file.write('chr16\tBlatToGff\tBES\t21736364\t21737069\t.\t+\t.\tID=machin1;Name=machin1;bes_start=21736364;bes_end=21737069;bes_size=22053297\n')
+        file.write('chr11\tBlatToGff\tBES\t3725876\t3726473\t.\t+\t.\tID=MRRE1H032F08FM1;Name=MRRE1H032F08FM1;bes_start=3725876;bes_end=3726473;bes_size=19818926\n')
+        file.write('chr11\tBlatToGff\tBES\t3794984\t3795627\t.\t+\t.\tID=machin2;Name=machin2;bes_start=3794984;bes_end=3795627;bes_size=19818926\n')
+        file.write('chr18\tBlatToGff\tBES\t12067347\t12067719\t.\t+\t.\tID=machin3;Name=machin3;bes_start=12067347;bes_end=12067719;bes_size=29360087\n')
+        file.close()
+        
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_VarscanFileForGnpSNP.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,305 @@
+import unittest
+import os
+
+from commons.core.parsing.VarscanFileForGnpSNP import VarscanFileForGnpSNP
+from commons.core.parsing.VarscanHitForGnpSNP import VarscanHitForGnpSNP
+
+class Test_VarscanFileForGnpSNP(unittest.TestCase):
+
+    def test__init__(self):
+        expFastqFileName = "SR.fastq"
+        expRefFastaFileName = "ref.fasta"
+        expTaxonName = "Arabidopsis thaliana"
+        expVarscanFieldSeparator = "\t"
+        expVarscanHitsList = []
+        
+        iVarscanFileForGnpSNP = VarscanFileForGnpSNP("", expFastqFileName, expRefFastaFileName, expTaxonName)
+        
+        obsFastaqFileName = iVarscanFileForGnpSNP.getFastqFileName()
+        obsRefFastaFileName = iVarscanFileForGnpSNP.getRefFastaFileName()
+        obsTaxonName = iVarscanFileForGnpSNP.getTaxonName()
+        obsVarscanFieldSeparator = iVarscanFileForGnpSNP.getVarscanFieldSeparator()
+        obsVarscanHitsList = iVarscanFileForGnpSNP.getVarscanHitsList()
+        
+        self.assertEquals(expFastqFileName, obsFastaqFileName)
+        self.assertEquals(expRefFastaFileName, obsRefFastaFileName)
+        self.assertEquals(expTaxonName, obsTaxonName)
+        self.assertEquals(expVarscanFieldSeparator, obsVarscanFieldSeparator)
+        self.assertEquals(expVarscanHitsList, obsVarscanHitsList)
+
+    def test_parse(self):
+        varscanFileName = "varscan.tab"
+        self._writeVarscanFile(varscanFileName)
+        
+        varscanHit1 = VarscanHitForGnpSNP()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('32')
+        varscanHit1.setRef('C')
+        varscanHit1.setVar('T')
+        varscanHit1.setReads1('1')
+        varscanHit1.setReads2('2')
+        varscanHit1.setVarFreq('66,67%')
+        varscanHit1.setStrands1('1')
+        varscanHit1.setStrands2('1')
+        varscanHit1.setQual1('37')
+        varscanHit1.setQual2('35')
+        varscanHit1.setPvalue('0.3999999999999999')
+        varscanHit1.setGnpSNPRef("C")
+        varscanHit1.setGnpSNPVar("T")
+        varscanHit1.setGnpSNPPosition(32)
+        varscanHit1.setOccurrence(1)
+        varscanHit1.setPolymType("SNP")
+        varscanHit1.setPolymLength(1)
+        
+        varscanHit2 = VarscanHitForGnpSNP()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('34')
+        varscanHit2.setRef('A')
+        varscanHit2.setVar('T')
+        varscanHit2.setReads1('1')
+        varscanHit2.setReads2('2')
+        varscanHit2.setVarFreq('66,67%')
+        varscanHit2.setStrands1('1')
+        varscanHit2.setStrands2('1')
+        varscanHit2.setQual1('40')
+        varscanHit2.setQual2('34')
+        varscanHit2.setPvalue('0.3999999999999999')
+        varscanHit2.setGnpSNPRef("A")
+        varscanHit2.setGnpSNPVar("T")
+        varscanHit2.setGnpSNPPosition(34)
+        varscanHit2.setOccurrence(1)
+        varscanHit2.setPolymType("SNP")
+        varscanHit2.setPolymLength(1)
+        expVarscanHitsList = [varscanHit1, varscanHit2]
+        
+        iVarscanFileForGnpSNP = VarscanFileForGnpSNP(varscanFileName, '', '', '')
+        iVarscanFileForGnpSNP.parse()
+        obsVarscanHitsList = iVarscanFileForGnpSNP.getVarscanHitsList()
+        os.remove(varscanFileName)
+        
+        self.assertEquals(expVarscanHitsList, obsVarscanHitsList)
+    
+    def test_parse_with_same_position_and_chr_and_type(self):
+        varscanFileName = "varscan.tab"
+        self._writeVarscanFile_2(varscanFileName)
+        
+        varscanHit1 = VarscanHitForGnpSNP()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('32')
+        varscanHit1.setRef('C')
+        varscanHit1.setVar('T')
+        varscanHit1.setReads1('1')
+        varscanHit1.setReads2('2')
+        varscanHit1.setVarFreq('66,67%')
+        varscanHit1.setStrands1('1')
+        varscanHit1.setStrands2('1')
+        varscanHit1.setQual1('37')
+        varscanHit1.setQual2('35')
+        varscanHit1.setPvalue('0.3999999999999999')
+        varscanHit1.setOccurrence(1)
+        varscanHit1._polymType = "SNP"
+        varscanHit1._gnpSnp_position = 32
+        varscanHit1._gnpSnp_ref = "C"
+        varscanHit1._gnpSnp_var = "T"
+        
+        varscanHit2 = VarscanHitForGnpSNP()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('32')
+        varscanHit2.setRef('C')
+        varscanHit2.setVar('A')
+        varscanHit2.setReads1('1')
+        varscanHit2.setReads2('2')
+        varscanHit2.setVarFreq('66,67%')
+        varscanHit2.setStrands1('1')
+        varscanHit2.setStrands2('1')
+        varscanHit2.setQual1('37')
+        varscanHit2.setQual2('35')
+        varscanHit2.setPvalue('0.3999999999999999')
+        varscanHit2.setOccurrence(2)
+        varscanHit2._polymType = "SNP"
+        varscanHit2._gnpSnp_position = 32
+        varscanHit2._gnpSnp_ref = "C"
+        varscanHit2._gnpSnp_var = "T"
+        
+        expVarscanHitsOccurence = varscanHit2._occurrence
+        
+        iVarscanFileForGnpSNP = VarscanFileForGnpSNP(varscanFileName, '', '', '')
+        iVarscanFileForGnpSNP.parse()
+        obsVarscanHitsList = iVarscanFileForGnpSNP.getVarscanHitsList()
+        obsVarscanHitsOccurence = obsVarscanHitsList[1]._occurrence
+        os.remove(varscanFileName)
+        
+        self.assertEquals(expVarscanHitsOccurence, obsVarscanHitsOccurence)    
+        
+    def test_parse_with_same_position_and_chr_and_different_type(self):
+        varscanFileName = "varscan.tab"
+        self._writeVarscanFile_3(varscanFileName)
+        
+        varscanHit1 = VarscanHitForGnpSNP()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('32')
+        varscanHit1.setRef('C')
+        varscanHit1.setVar('T')
+        varscanHit1.setReads1('1')
+        varscanHit1.setReads2('2')
+        varscanHit1.setVarFreq('66,67%')
+        varscanHit1.setStrands1('1')
+        varscanHit1.setStrands2('1')
+        varscanHit1.setQual1('37')
+        varscanHit1.setQual2('35')
+        varscanHit1.setPvalue('0.3999999999999999')
+        varscanHit1.setOccurrence(1)
+        varscanHit1._polymType = "SNP"
+        varscanHit1._gnpSnp_position = 32
+        varscanHit1._gnpSnp_ref = "C"
+        varscanHit1._gnpSnp_var = "T"
+        
+        varscanHit2 = VarscanHitForGnpSNP()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('32')
+        varscanHit2.setRef('C')
+        varscanHit2.setVar('+A')
+        varscanHit2.setReads1('1')
+        varscanHit2.setReads2('2')
+        varscanHit2.setVarFreq('66,67%')
+        varscanHit2.setStrands1('1')
+        varscanHit2.setStrands2('1')
+        varscanHit2.setQual1('37')
+        varscanHit2.setQual2('35')
+        varscanHit2.setPvalue('0.3999999999999999')
+        varscanHit2.setOccurrence(1)
+        varscanHit2._polymType = "SNP"
+        varscanHit2._gnpSnp_position = 32
+        varscanHit2._gnpSnp_ref = "C"
+        varscanHit2._gnpSnp_var = "T"
+        
+        expVarscanHitsOccurence = varscanHit2._occurrence
+        
+        iVarscanFileForGnpSNP = VarscanFileForGnpSNP(varscanFileName)
+        iVarscanFileForGnpSNP.parse()
+        obsVarscanHitsList = iVarscanFileForGnpSNP.getVarscanHitsList()
+        obsVarscanHitsOccurence = obsVarscanHitsList[1].getOccurrence()
+        os.remove(varscanFileName)
+        
+        self.assertEquals(expVarscanHitsOccurence, obsVarscanHitsOccurence)    
+        
+    def test_parse_on_occurence(self):
+        varscanFileName = "varscan.tab"
+        self._writeVarscanFile_4(varscanFileName)
+        
+        expOccurrence1 = 1
+        expOccurrence2 = 1
+        expOccurrence3 = 2
+        expOccurrence4 = 1
+        expOccurrence5 = 1
+        expOccurrence6 = 2
+        
+        iVarscanFileForGnpSNP = VarscanFileForGnpSNP(varscanFileName)
+        iVarscanFileForGnpSNP.parse()
+        obsVarscanHitsList = iVarscanFileForGnpSNP.getVarscanHitsList()
+        obsOccurrence1 = obsVarscanHitsList[0].getOccurrence()
+        obsOccurrence2 = obsVarscanHitsList[1].getOccurrence()
+        obsOccurrence3 = obsVarscanHitsList[2].getOccurrence()
+        obsOccurrence4 = obsVarscanHitsList[3].getOccurrence()
+        obsOccurrence5 = obsVarscanHitsList[4].getOccurrence()
+        obsOccurrence6 = obsVarscanHitsList[5].getOccurrence()
+        os.remove(varscanFileName)
+        
+        self.assertEquals(expOccurrence1, obsOccurrence1)
+        self.assertEquals(expOccurrence2, obsOccurrence2)
+        self.assertEquals(expOccurrence3, obsOccurrence3)
+        self.assertEquals(expOccurrence4, obsOccurrence4)
+        self.assertEquals(expOccurrence5, obsOccurrence5)
+        self.assertEquals(expOccurrence6, obsOccurrence6)
+        
+    def test__eq__notEqual(self):
+        fastqFileName = "SR.fastq"
+        refFastaFileName = "ref.fasta"
+        taxonName = "Arabidopsis thaliana"
+        
+        iVarscanFileForGnpSNP1 = VarscanFileForGnpSNP("", fastqFileName, refFastaFileName, taxonName)
+        
+        fastqFileName = "SR.fastq2"
+        refFastaFileName = "ref.fasta"
+        taxonName = "Arabidopsis thaliana"
+        
+        iVarscanFileForGnpSNP2 = VarscanFileForGnpSNP("", fastqFileName, refFastaFileName, taxonName)
+
+        self.assertFalse(iVarscanFileForGnpSNP1 == iVarscanFileForGnpSNP2)
+        
+    def test__eq__equal(self):
+        fastqFileName = "SR.fastq"
+        refFastaFileName = "ref.fasta"
+        taxonName = "Arabidopsis thaliana"
+        
+        varscanHit1 = VarscanHitForGnpSNP()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('34')
+        varscanHit1.setRef('A')
+        varscanHit1.setVar('T')
+        varscanHit1.setReads1('1')
+        varscanHit1.setReads2('2')
+        varscanHit1.setVarFreq('66,67%')
+        varscanHit1.setStrands1('1')
+        varscanHit1.setStrands2('1')
+        varscanHit1.setQual1('40')
+        varscanHit1.setQual2('34')
+        varscanHit1.setPvalue('0.3999999999999999')
+        lVarscanHits1 = [varscanHit1]
+        
+        iVarscanFileForGnpSNP1 = VarscanFileForGnpSNP("", fastqFileName, refFastaFileName, taxonName)
+        iVarscanFileForGnpSNP1.setVarscanHitsList(lVarscanHits1)
+        
+        varscanHit2 = VarscanHitForGnpSNP()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('34')
+        varscanHit2.setRef('A')
+        varscanHit2.setVar('T')
+        varscanHit2.setReads1('1')
+        varscanHit2.setReads2('2')
+        varscanHit2.setVarFreq('66,67%')
+        varscanHit2.setStrands1('1')
+        varscanHit2.setStrands2('1')
+        varscanHit2.setQual1('40')
+        varscanHit2.setQual2('34')
+        varscanHit2.setPvalue('0.3999999999999999')
+        lVarscanHits2 = [varscanHit2]
+
+        iVarscanFileForGnpSNP2 = VarscanFileForGnpSNP("", fastqFileName, refFastaFileName, taxonName)
+        iVarscanFileForGnpSNP2.setVarscanHitsList(lVarscanHits2)
+
+        self.assertTrue(iVarscanFileForGnpSNP1 == iVarscanFileForGnpSNP2)
+    
+    def _writeVarscanFile(self, varscanFileName):
+        varscanFile = open(varscanFileName, 'w')
+        varscanFile.write("Chrom\tPosition\tRef\tVar\tReads1\tReads2\tVarFreq\tStrands1\tStrands2\tQual1\tQual2\tPvalue\n")
+        varscanFile.write("C02HBa0291P19_LR48\t32\tC\tT\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n")
+        varscanFile.write("C02HBa0291P19_LR48\t34\tA\tT\t1\t2\t66,67%\t1\t1\t40\t34\t0.3999999999999999\n")
+        varscanFile.close()
+    
+    def _writeVarscanFile_2(self, varscanFileName):
+        varscanFile = open(varscanFileName, 'w')
+        varscanFile.write("Chrom\tPosition\tRef\tVar\tReads1\tReads2\tVarFreq\tStrands1\tStrands2\tQual1\tQual2\tPvalue\n")
+        varscanFile.write("C02HBa0291P19_LR48\t32\tC\tT\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n")
+        varscanFile.write("C02HBa0291P19_LR48\t32\tA\tT\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n")
+        varscanFile.close()
+        
+    def _writeVarscanFile_3(self, varscanFileName):
+        varscanFile = open(varscanFileName, 'w')
+        varscanFile.write("Chrom\tPosition\tRef\tVar\tReads1\tReads2\tVarFreq\tStrands1\tStrands2\tQual1\tQual2\tPvalue\n")
+        varscanFile.write("C02HBa0291P19_LR48\t32\tC\tT\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n")
+        varscanFile.write("C02HBa0291P19_LR48\t32\tC\t+A\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n")
+        varscanFile.close()
+
+    def _writeVarscanFile_4(self, varscanFileName):
+        varscanFile = open(varscanFileName, 'w')
+        varscanFile.write("Chrom\tPosition\tRef\tVar\tReads1\tReads2\tVarFreq\tStrands1\tStrands2\tQual1\tQual2\tPvalue\n")
+        varscanFile.write("seqname\t2\tA\tT\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n")
+        varscanFile.write("seqname\t4\tC\tG\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n")
+        varscanFile.write("seqname\t4\tC\tA\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n")
+        varscanFile.write("seqname\t8\tT\tA\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n")
+        varscanFile.write("chrom\t4\tC\tG\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n")
+        varscanFile.write("chrom\t4\tC\tA\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n")
+        varscanFile.close()
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_VarscanHit.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,165 @@
+import unittest
+from commons.core.parsing.VarscanHit import VarscanHit
+from commons.core.checker.CheckerException import CheckerException
+
+class Test_VarscanHit(unittest.TestCase):
+
+    def test_setAttributesFromString(self):
+        line = "C02HBa0291P19_LR48\t32\tC\tT\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n"
+        
+        expChrom = "C02HBa0291P19_LR48"
+        expPosition = "32"
+        expRef = "C"
+        expVar = "T"
+        
+        varscanHit = VarscanHit()
+        varscanHit.setAttributesFromString(line)
+        
+        obsChrom = varscanHit.getChrom()
+        obsPosition = varscanHit.getPosition()
+        obsRef = varscanHit.getRef()
+        obsVar = varscanHit.getVar()
+        
+        self.assertEquals(expChrom, obsChrom)
+        self.assertEquals(expPosition, obsPosition)
+        self.assertEquals(expRef, obsRef)
+        self.assertEquals(expVar, obsVar)
+        
+    def test_setAttributesFromString_empty_chrom(self):
+        line = "\t32\tC\tT\t1\t2\t66,67%\t1\t1\t37\t35\t0.3999999999999999\n"
+        iVarscanHit = VarscanHit()
+        try :
+            iVarscanHit.setAttributesFromString(line)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Chrom is empty in varscan file in line "
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def  test_setAttributesFromString_less_than_12_fields(self):
+        line = "C02HBa0291P19_LR48\t32\tC\tT\t1\t2\t66,67%\t1\t1\t37\n"
+        iVarscanHit = VarscanHit()
+        iVarscanHit.setAttributesFromString(line)
+        self.assertEquals("", iVarscanHit.getQualVar())
+        self.assertEquals("", iVarscanHit.getPValue())
+        
+    def test_setAttributes(self):
+        lResults = ["C02HBa0291P19_LR48", "32", "C", "T", "1", "2", "66,67%", "1", "1", "37", "35", "0.3999999999999999"]
+        lineNumber = 1
+        
+        expChrom = "C02HBa0291P19_LR48"
+        expPosition = "32"
+        expRef = "C"
+        expVar = "T"
+        
+        varscanHit = VarscanHit()
+        varscanHit.setAttributes(lResults, lineNumber)
+        
+        obsChrom = varscanHit.getChrom()
+        obsPosition = varscanHit.getPosition()
+        obsRef = varscanHit.getRef()
+        obsVar = varscanHit.getVar()
+        
+        self.assertEquals(expChrom, obsChrom)
+        self.assertEquals(expPosition, obsPosition)
+        self.assertEquals(expRef, obsRef)
+        self.assertEquals(expVar, obsVar)
+
+    def test_setAttributes_empty_chrom(self):
+        lResults = ["", "", "", "", "", "", "10", "", "", "", "", ""]
+        lineNumber = 1
+        
+        varscanHit = VarscanHit()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Chrom is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_position(self):
+        lResults = ["chrom", "", "", "", "", "", "10", "", "", "", "", ""]
+        lineNumber = 5
+        
+        varscanHit = VarscanHit()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Position is empty in varscan file in line 5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_ref(self):
+        lResults = ["chrom", "position", "", "", "", "", "10", "", "", "", "", ""]
+        lineNumber = 5
+        
+        varscanHit = VarscanHit()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Ref is empty in varscan file in line 5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_var(self):
+        lResults = ["chrom", "position", "ref", "", "", "", "10", "", "", "", "", ""]
+        lineNumber = 5
+        
+        varscanHit = VarscanHit()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Var is empty in varscan file in line 5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test__eq__notEquals(self):
+        varscanHit1 = VarscanHit()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('32')
+        varscanHit1.setRef('C')
+        varscanHit1.setVar('T')
+        
+        varscanHit2 = VarscanHit()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('34')
+        varscanHit2.setRef('A')
+        varscanHit2.setVar('T')
+        
+        self.assertFalse(varscanHit1 == varscanHit2)
+
+    def test__eq__Equals(self):
+        varscanHit1 = VarscanHit()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('32')
+        varscanHit1.setRef('C')
+        varscanHit1.setVar('T')
+        
+        varscanHit2 = VarscanHit()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('32')
+        varscanHit2.setRef('C')
+        varscanHit2.setVar('T')
+        
+        self.assertTrue(varscanHit1 == varscanHit2)        
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_VarscanHitForGnpSNP.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,412 @@
+import unittest
+from commons.core.parsing.VarscanHitForGnpSNP import VarscanHitForGnpSNP
+from commons.core.checker.CheckerException import CheckerException
+
+class Test_VarscanHitForGnpSNP(unittest.TestCase):
+
+    def test_setAttributes(self):
+        lResults = ["C02HBa0291P19_LR48", "32", "C", "T", "1", "2", "66,67%", "1", "1", "37", "35", "0.3999999999999999"]
+        lineNumber = 1
+    
+        expChrom = "C02HBa0291P19_LR48"
+        expPosition = "32"
+        expRef = "C"
+        expVar = "T"
+        expReads1 = "1"
+        expReads2 = "2"
+        expVarFreq = 66.67
+        expStrands1 = "1"
+        expStrands2 = "1"
+        expQual1 = "37"
+        expQual2 = "35"
+        expPvalue = "0.3999999999999999"
+        
+        varscanHit = VarscanHitForGnpSNP()
+        varscanHit.setAttributes(lResults, lineNumber)
+        
+        obsChrom = varscanHit.getChrom()
+        obsPosition = varscanHit.getPosition()
+        obsRef = varscanHit.getRef()
+        obsVar = varscanHit.getVar()
+        obsReads1 = varscanHit.getReads1()
+        obsReads2 = varscanHit.getReads2()
+        obsVarFreq = varscanHit.getVarFreq()
+        obsStrands1 = varscanHit.getStrands1()
+        obsStrands2 = varscanHit.getStrands2()
+        obsQual1 = varscanHit.getQual1()
+        obsQual2 = varscanHit.getQual2()
+        obsPvalue = varscanHit.getPvalue()
+        
+        self.assertEquals(expChrom, obsChrom)
+        self.assertEquals(expPosition, obsPosition)
+        self.assertEquals(expRef, obsRef)
+        self.assertEquals(expVar, obsVar)
+        self.assertEquals(expReads1, obsReads1)
+        self.assertEquals(expReads2, obsReads2)
+        self.assertEquals(expVarFreq, obsVarFreq)
+        self.assertEquals(expStrands1, obsStrands1)
+        self.assertEquals(expStrands2, obsStrands2)
+        self.assertEquals(expQual1, obsQual1)
+        self.assertEquals(expQual2, obsQual2)
+        self.assertEquals(expPvalue, obsPvalue)
+
+    def test_setAttributes_empty_chrom(self):
+        lResults = ["", "", "", "", "", "", "10", "", "", "", "", ""]
+        lineNumber = 1
+        
+        varscanHit = VarscanHitForGnpSNP()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Chrom is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_position(self):
+        lResults = ["chrom", "", "", "", "", "", "10", "", "", "", "", ""]
+        lineNumber = 5
+        
+        varscanHit = VarscanHitForGnpSNP()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Position is empty in varscan file in line 5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_ref(self):
+        lResults = ["chrom", "position", "", "", "", "", "10", "", "", "", "", ""]
+        lineNumber = 5
+        
+        varscanHit = VarscanHitForGnpSNP()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Ref is empty in varscan file in line 5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_var(self):
+        lResults = ["chrom", "position", "ref", "", "", "", "10", "", "", "", "", ""]
+        lineNumber = 5
+        
+        varscanHit = VarscanHitForGnpSNP()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Var is empty in varscan file in line 5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_reads1(self):
+        lResults = ["chrom", "position", "ref", "var", "", "", "10", "", "", "", "", ""]
+        lineNumber = 5
+        
+        varscanHit = VarscanHitForGnpSNP()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Reads1 is empty in varscan file in line 5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_reads2(self):
+        lResults = ["chrom", "position", "ref", "var", "reads1", "", "10", "", "", "", "", ""]
+        lineNumber = 5
+        
+        varscanHit = VarscanHitForGnpSNP()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Reads2 is empty in varscan file in line 5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_varFreq(self):
+        lResults = ["chrom", "position", "ref", "var", "reads1", "reads2", "", "", "", "", "", ""]
+        lineNumber = 5
+        
+        varscanHit = VarscanHitForGnpSNP()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field VarFreq is empty or in bad format in varscan file in line 5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_strands1(self):
+        lResults = ["chrom", "position", "ref", "var", "reads1", "reads2", "10", "", "", "", "", ""]
+        lineNumber = 5
+        
+        varscanHit = VarscanHitForGnpSNP()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Strands1 is empty in varscan file in line 5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_strands2(self):
+        lResults = ["chrom", "position", "ref", "var", "reads1", "reads2", "10", "strands1", "", "", "", ""]
+        lineNumber = 5
+        
+        varscanHit = VarscanHitForGnpSNP()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Strands2 is empty in varscan file in line 5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_qual1(self):
+        lResults = ["chrom", "position", "ref", "var", "reads1", "reads2", "10", "strands1", "strands2", "", "", ""]
+        lineNumber = 5
+        
+        varscanHit = VarscanHitForGnpSNP()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Qual1 is empty in varscan file in line 5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_qual2(self):
+        lResults = ["chrom", "position", "ref", "var", "reads1", "reads2", "10", "strands1", "strands2", "qual1", "", ""]
+        lineNumber = 5
+        
+        varscanHit = VarscanHitForGnpSNP()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Qual2 is empty in varscan file in line 5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_pvalue(self):
+        lResults = ["chrom", "position", "ref", "var", "reads1", "reads2", "10", "strands1", "strands2", "qual1", "qual2", ""]
+        lineNumber = 5
+        
+        varscanHit = VarscanHitForGnpSNP()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Pvalue is empty in varscan file in line 5"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+        
+    def test__eq__notEquals(self):
+        varscanHit1 = VarscanHitForGnpSNP()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('32')
+        varscanHit1.setRef('C')
+        varscanHit1.setVar('T')
+        varscanHit1.setReads1('1')
+        varscanHit1.setReads2('2')
+        varscanHit1.setVarFreq('66,67%')
+        varscanHit1.setStrands1('1')
+        varscanHit1.setStrands2('1')
+        varscanHit1.setQual1('37')
+        varscanHit1.setQual2('35')
+        varscanHit1.setPvalue('0.3999999999999999')
+        
+        varscanHit2 = VarscanHitForGnpSNP()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('34')
+        varscanHit2.setRef('A')
+        varscanHit2.setVar('T')
+        varscanHit2.setReads1('1')
+        varscanHit2.setReads2('2')
+        varscanHit2.setVarFreq('66,67%')
+        varscanHit2.setStrands1('1')
+        varscanHit2.setStrands2('1')
+        varscanHit2.setQual1('40')
+        varscanHit2.setQual2('34')
+        varscanHit2.setPvalue('0.3999999999999999')
+        
+        self.assertFalse(varscanHit1 == varscanHit2)
+
+    def test__eq__Equals(self):
+        varscanHit1 = VarscanHitForGnpSNP()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('32')
+        varscanHit1.setRef('C')
+        varscanHit1.setVar('T')
+        varscanHit1.setReads1('1')
+        varscanHit1.setReads2('2')
+        varscanHit1.setVarFreq('66,67%')
+        varscanHit1.setStrands1('1')
+        varscanHit1.setStrands2('1')
+        varscanHit1.setQual1('37')
+        varscanHit1.setQual2('35')
+        varscanHit1.setPvalue('0.3999999999999999')
+        
+        varscanHit2 = VarscanHitForGnpSNP()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('32')
+        varscanHit2.setRef('C')
+        varscanHit2.setVar('T')
+        varscanHit2.setReads1('1')
+        varscanHit2.setReads2('2')
+        varscanHit2.setVarFreq('66,67%')
+        varscanHit2.setStrands1('1')
+        varscanHit2.setStrands2('1')
+        varscanHit2.setQual1('37')
+        varscanHit2.setQual2('35')
+        varscanHit2.setPvalue('0.3999999999999999')
+        
+        self.assertTrue(varscanHit1 == varscanHit2)        
+
+    def test_formatAlleles2GnpSnp_for_Deletion(self):
+        varscanHit1 = VarscanHitForGnpSNP()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('32')
+        varscanHit1.setRef('C')
+        varscanHit1.setVar('-ATT')
+        varscanHit1.setReads1('1')
+        varscanHit1.setReads2('2')
+        varscanHit1.setVarFreq('66,67%')
+        varscanHit1.setStrands1('1')
+        varscanHit1.setStrands2('1')
+        varscanHit1.setQual1('37')
+        varscanHit1.setQual2('35')
+        varscanHit1.setPvalue('0.3999999999999999')
+        
+        expPolymType = "DELETION"
+        expGnpSnpRef = "ATT"
+        expGnpSnpVar = "---"
+        expGnpSnpPosition = 33
+        
+        varscanHit1.formatAlleles2GnpSnp()
+        
+        obsPolymType = varscanHit1.getPolymType()
+        obsGnpSnpRef = varscanHit1.getGnpSnpRef()
+        obsGnpSnpVar = varscanHit1.getGnpSnpVar()
+        obsGnpSnpPosition = varscanHit1.getGnpSnpPosition()
+        
+        self.assertEquals(expPolymType,obsPolymType)
+        self.assertEquals(expGnpSnpRef, obsGnpSnpRef)
+        self.assertEquals(expGnpSnpVar, obsGnpSnpVar)
+        self.assertEquals(expGnpSnpPosition, obsGnpSnpPosition)
+        
+    def test_setVarFreq(self):
+        varscanHit1 = VarscanHitForGnpSNP()  
+        exp = 66.67      
+        varscanHit1.setVarFreq('66,67%')
+        obs = varscanHit1.getVarFreq()
+        self.assertEquals(exp, obs)
+            
+    def test_formatAlleles2GnpSnp_for_Insertion(self):
+        varscanHit1 = VarscanHitForGnpSNP()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('32')
+        varscanHit1.setRef('C')
+        varscanHit1.setVar('+TG')
+        varscanHit1.setReads1('1')
+        varscanHit1.setReads2('2')
+        varscanHit1.setVarFreq('66,67%')
+        varscanHit1.setStrands1('1')
+        varscanHit1.setStrands2('1')
+        varscanHit1.setQual1('37')
+        varscanHit1.setQual2('35')
+        varscanHit1.setPvalue('0.3999999999999999')
+        
+        expPolymType = "INSERTION"
+        expGnpSnpRef = "--"
+        expGnpSnpVar = "TG"
+        expGnpSnpPosition = 32
+        
+        varscanHit1.formatAlleles2GnpSnp()
+        
+        obsPolymType = varscanHit1.getPolymType()
+        obsGnpSnpRef = varscanHit1.getGnpSnpRef()
+        obsGnpSnpVar = varscanHit1.getGnpSnpVar()
+        obsGnpSnpPosition = varscanHit1.getGnpSnpPosition()
+        
+        self.assertEquals(expPolymType,obsPolymType)
+        self.assertEquals(expGnpSnpRef, obsGnpSnpRef)
+        self.assertEquals(expGnpSnpVar, obsGnpSnpVar)
+        self.assertEquals(expGnpSnpPosition, obsGnpSnpPosition)
+        
+    def test_formatAlleles2GnpSnp_for_SNP(self):
+        varscanHit1 = VarscanHitForGnpSNP()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('12')
+        varscanHit1.setRef('G')
+        varscanHit1.setVar('T')
+        varscanHit1.setReads1('1')
+        varscanHit1.setReads2('2')
+        varscanHit1.setVarFreq('66,67%')
+        varscanHit1.setStrands1('1')
+        varscanHit1.setStrands2('1')
+        varscanHit1.setQual1('37')
+        varscanHit1.setQual2('35')
+        varscanHit1.setPvalue('0.3999999999999999')
+        
+        expPolymType = "SNP"
+        expGnpSnpRef = "G"
+        expGnpSnpVar = "T"
+        expGnpSnpPosition = 12
+        
+        varscanHit1.formatAlleles2GnpSnp()
+        
+        obsPolymType = varscanHit1.getPolymType()
+        obsGnpSnpRef = varscanHit1.getGnpSnpRef()
+        obsGnpSnpVar = varscanHit1.getGnpSnpVar()
+        obsGnpSnpPosition = varscanHit1.getGnpSnpPosition()
+        
+        self.assertEquals(expPolymType,obsPolymType)
+        self.assertEquals(expGnpSnpRef, obsGnpSnpRef)
+        self.assertEquals(expGnpSnpVar, obsGnpSnpVar)
+        self.assertEquals(expGnpSnpPosition, obsGnpSnpPosition)
+        
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_VarscanHit_WithTag.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,212 @@
+import unittest
+from commons.core.checker.CheckerException import CheckerException
+from commons.core.parsing.VarscanHit_WithTag import VarscanHit_WithTag
+
+class Test_VarscanHit_WithTag(unittest.TestCase):
+
+    def test_setAttributesFromString(self):
+        line = "chr1\t1804\tT\tC\t0\t1\t100%\t0\t1\t0\t53\t0.98\tEspeceA\n"
+        
+        expChrom = "chr1"
+        expPosition = "1804"
+        expRef = "T"
+        expVar = "C"
+        expReadsRef = "0"
+        expReadsVar = "1"
+        expVarFreq = "100%"
+        expStrandsRef = "0"
+        expStrandsVar = "1"
+        expQualRef = "0"
+        expQualVar = "53"
+        expPValue = "0.98"
+        expTag = "EspeceA"
+        
+        varscanHit = VarscanHit_WithTag()
+        varscanHit.setAttributesFromString(line)
+        
+        obsChrom = varscanHit.getChrom()
+        obsPosition = varscanHit.getPosition()
+        obsRef = varscanHit.getRef()
+        obsVar = varscanHit.getVar()
+        obsReadsRef = varscanHit.getReadsRef()
+        obsReadsVar = varscanHit.getReadsVar()
+        obsVarFreq = varscanHit.getVarFreq()
+        obsStrandsRef = varscanHit.getStrandsRef()
+        obsStrandsVar = varscanHit.getStrandsVar()
+        obsQualRef = varscanHit.getQualRef()
+        obsQualVar = varscanHit.getQualVar()
+        obsPValue = varscanHit.getPValue()
+        obsTag = varscanHit.getTag()
+        
+        self.assertEquals(expChrom, obsChrom)
+        self.assertEquals(expPosition, obsPosition)
+        self.assertEquals(expRef, obsRef)
+        self.assertEquals(expVar, obsVar)
+        self.assertEquals(expReadsRef, obsReadsRef)
+        self.assertEquals(expReadsVar, obsReadsVar)
+        self.assertEquals(expVarFreq, obsVarFreq)
+        self.assertEquals(expStrandsRef, obsStrandsRef)
+        self.assertEquals(expStrandsVar, obsStrandsVar)
+        self.assertEquals(expQualRef, obsQualRef)
+        self.assertEquals(expQualVar, obsQualVar)
+        self.assertEquals(expPValue, obsPValue)
+        self.assertEquals(expTag, obsTag)
+        
+    def test_setAttributesFromString_empty_chrom(self):
+        line = "\t1804\tT\tC\t0\t1\t100%\t0\t1\t0\t53\t0.98\tEspeceA\n"
+        varscanHit = VarscanHit_WithTag()
+        try :
+            varscanHit.setAttributesFromString(line)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        expMessage = "The field Chrom is empty in varscan file in line "
+        obsMessage = checkerExceptionInstance.msg
+        self.assertEquals(expMessage, obsMessage)
+        
+    def test_setAttributes(self):
+        lResults = ['chr1', '1804', 'T', 'C', '0', '1', '100%', '0', '1', '0', '53', '0.98', 'EspeceA']
+        lineNumber = 1
+        
+        expChrom = "chr1"
+        expPosition = "1804"
+        expRef = "T"
+        expVar = "C"
+        expReadsRef = "0"
+        expReadsVar = "1"
+        expVarFreq = "100%"
+        expStrandsRef = "0"
+        expStrandsVar = "1"
+        expQualRef = "0"
+        expQualVar = "53"
+        expPValue = "0.98"
+        expTag = "EspeceA"
+        
+        varscanHit = VarscanHit_WithTag()
+        varscanHit.setAttributes(lResults, lineNumber)
+        
+        obsChrom = varscanHit.getChrom()
+        obsPosition = varscanHit.getPosition()
+        obsRef = varscanHit.getRef()
+        obsVar = varscanHit.getVar()
+        obsReadsRef = varscanHit.getReadsRef()
+        obsReadsVar = varscanHit.getReadsVar()
+        obsVarFreq = varscanHit.getVarFreq()
+        obsStrandsRef = varscanHit.getStrandsRef()
+        obsStrandsVar = varscanHit.getStrandsVar()
+        obsQualRef = varscanHit.getQualRef()
+        obsQualVar = varscanHit.getQualVar()
+        obsPValue = varscanHit.getPValue()
+        obsTag = varscanHit.getTag()
+        
+        self.assertEquals(expChrom, obsChrom)
+        self.assertEquals(expPosition, obsPosition)
+        self.assertEquals(expRef, obsRef)
+        self.assertEquals(expVar, obsVar)
+        self.assertEquals(expReadsRef, obsReadsRef)
+        self.assertEquals(expReadsVar, obsReadsVar)
+        self.assertEquals(expVarFreq, obsVarFreq)
+        self.assertEquals(expStrandsRef, obsStrandsRef)
+        self.assertEquals(expStrandsVar, obsStrandsVar)
+        self.assertEquals(expQualRef, obsQualRef)
+        self.assertEquals(expQualVar, obsQualVar)
+        self.assertEquals(expPValue, obsPValue)
+        self.assertEquals(expTag, obsTag)
+
+    def test_setAttributes_empty_chrom(self):
+        lResults = ['', '1804', 'T', 'C', '0', '1', '100%', '0', '1', '0', '53', '0.98', 'EspeceA']
+        lineNumber = 1
+        
+        varscanHit = VarscanHit_WithTag()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Chrom is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_position(self):
+        lResults = ['chr1', '', 'T', 'C', '0', '1', '100%', '0', '1', '0', '53', '0.98', 'EspeceA']
+        lineNumber = 1
+        
+        varscanHit = VarscanHit_WithTag()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Position is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_ref(self):
+        lResults = ['chr1', '1000', '', 'C', '0', '1', '100%', '0', '1', '0', '53', '0.98', 'EspeceA']
+        lineNumber = 1
+        
+        varscanHit = VarscanHit_WithTag()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Ref is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_cns(self):
+        lResults = ['chr1', '1000', 'T', '', '0', '1', '100%', '0', '1', '0', '53', '0.98', 'EspeceA']
+        lineNumber = 1
+        
+        varscanHit = VarscanHit_WithTag()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Var is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test__eq__notEquals(self):
+        varscanHit1 = VarscanHit_WithTag()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('34')
+        varscanHit1.setRef('A')
+        varscanHit1.setVar('T')
+        varscanHit1.setVar('EspeceA')
+        
+        varscanHit2 = VarscanHit_WithTag()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('34')
+        varscanHit2.setRef('A')
+        varscanHit2.setVar('T')
+        varscanHit2.setVar('EspeceB')
+        
+        self.assertFalse(varscanHit1 == varscanHit2)
+
+    def test__eq__Equals(self):
+        varscanHit1 = VarscanHit_WithTag()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('34')
+        varscanHit1.setRef('A')
+        varscanHit1.setVar('T')
+        varscanHit1.setVar('EspeceA')
+        
+        varscanHit2 = VarscanHit_WithTag()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('34')
+        varscanHit2.setRef('A')
+        varscanHit2.setVar('T')
+        varscanHit2.setVar('EspeceA')
+    
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_VarscanHit_v2_2_8.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,290 @@
+import unittest
+from commons.core.checker.CheckerException import CheckerException
+from commons.core.parsing.VarscanHit_v2_2_8 import VarscanHit_v2_2_8
+from commons.core.parsing.VarscanHit import VarscanHit
+
+class Test_VarscanHit_v2_2_8(unittest.TestCase):
+
+    def test_setAttributesFromString(self):
+        line = "chr1\t1804\tT\tC\t0\t1\t100%\t0\t1\t0\t53\t0.98\t0\t1\t0\t0\t1\t0\tC\n"
+        
+        expChrom = "chr1"
+        expPosition = "1804"
+        expRef = "T"
+        expCns = "C"
+        expReadsRef = "0"
+        expReadsVar = "1"
+        expVarFreq = "100%"
+        expStrandsRef = "0"
+        expStrandsVar = "1"
+        expQualRef = "0"
+        expQualVar = "53"
+        expPValue = "0.98"
+        expMapQualRef = "0"
+        expMapQualVar = "1"
+        expReadsRefPlus = "0"
+        expReadsRefMinus = "0"
+        expReadsVarPlus = "1"
+        expReadsVarMinus = "0"
+        expVar = "C"
+        
+        varscanHit = VarscanHit_v2_2_8()
+        varscanHit.setAttributesFromString(line)
+        
+        obsChrom = varscanHit.getChrom()
+        obsPosition = varscanHit.getPosition()
+        obsRef = varscanHit.getRef()
+        obsCns = varscanHit.getCns()
+        obsReadsRef = varscanHit.getReadsRef()
+        obsReadsVar = varscanHit.getReadsVar()
+        obsVarFreq = varscanHit.getVarFreq()
+        obsStrandsRef = varscanHit.getStrandsRef()
+        obsStrandsVar = varscanHit.getStrandsVar()
+        obsQualRef = varscanHit.getQualRef()
+        obsQualVar = varscanHit.getQualVar()
+        obsPValue = varscanHit.getPValue()
+        obsMapQualRef = varscanHit.getMapQualRef()
+        obsMapQualVar = varscanHit.getMapQualVar()
+        obsReadsRefPlus = varscanHit.getReadsRefPlus()
+        obsReadsRefMinus = varscanHit.getReadsRefMinus()
+        obsReadsVarPlus = varscanHit.getReadsVarPlus()
+        obsReadsVarMinus = varscanHit.getReadsVarMinus()
+        obsVar = varscanHit.getVar()
+        
+        self.assertEquals(expChrom, obsChrom)
+        self.assertEquals(expPosition, obsPosition)
+        self.assertEquals(expRef, obsRef)
+        self.assertEquals(expCns, obsCns)
+        self.assertEquals(expReadsRef, obsReadsRef)
+        self.assertEquals(expReadsVar, obsReadsVar)
+        self.assertEquals(expVarFreq, obsVarFreq)
+        self.assertEquals(expStrandsRef, obsStrandsRef)
+        self.assertEquals(expStrandsVar, obsStrandsVar)
+        self.assertEquals(expQualRef, obsQualRef)
+        self.assertEquals(expQualVar, obsQualVar)
+        self.assertEquals(expPValue, obsPValue)
+        self.assertEquals(expMapQualRef, obsMapQualRef)
+        self.assertEquals(expMapQualVar, obsMapQualVar)
+        self.assertEquals(expReadsRefPlus, obsReadsRefPlus)
+        self.assertEquals(expReadsRefMinus, obsReadsRefMinus)
+        self.assertEquals(expReadsVarPlus, obsReadsVarPlus)
+        self.assertEquals(expReadsVarMinus, obsReadsVarMinus)
+        self.assertEquals(expVar, obsVar)
+        
+    def test_setAttributesFromString_empty_chrom(self):
+        line = "\t1804\tT\tC\t0\t1\t100%\t0\t1\t0\t53\t0.98\t0\t1\t0\t0\t1\t0\tC\n"
+        varscanHit = VarscanHit_v2_2_8()
+        try :
+            varscanHit.setAttributesFromString(line)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        expMessage = "The field Chrom is empty in varscan file in line "
+        obsMessage = checkerExceptionInstance.msg
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributesFromString_less_than_19_fields(self):
+        line = "chr1\t1804\tT\tC\t0\t1\t100%\t0\t1\t53\t0.98\t0\t1\t0\t0\t1\t0\tC\n"
+        varscanHit = VarscanHit_v2_2_8()
+        try :
+            varscanHit.setAttributesFromString(line)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        expMessage = "This varscan line (l.) is not complete"
+        obsMessage = checkerExceptionInstance.msg
+        self.assertEquals(expMessage, obsMessage)
+        
+    def test_setAttributes(self):
+        lResults = ['chr1', '1804', 'T', 'C', '0', '1', '100%', '0', '1', '0', '53', '0.98', '0', '1', '0', '0', '1', '0', 'C']
+        lineNumber = 1
+        
+        expChrom = "chr1"
+        expPosition = "1804"
+        expRef = "T"
+        expCns = "C"
+        expReadsRef = "0"
+        expReadsVar = "1"
+        expVarFreq = "100%"
+        expStrandsRef = "0"
+        expStrandsVar = "1"
+        expQualRef = "0"
+        expQualVar = "53"
+        expPValue = "0.98"
+        expMapQualRef = "0"
+        expMapQualVar = "1"
+        expReadsRefPlus = "0"
+        expReadsRefMinus = "0"
+        expReadsVarPlus = "1"
+        expReadsVarMinus = "0"
+        expVar = "C"
+        
+        varscanHit = VarscanHit_v2_2_8()
+        varscanHit.setAttributes(lResults, lineNumber)
+        
+        obsChrom = varscanHit.getChrom()
+        obsPosition = varscanHit.getPosition()
+        obsRef = varscanHit.getRef()
+        obsCns = varscanHit.getCns()
+        obsReadsRef = varscanHit.getReadsRef()
+        obsReadsVar = varscanHit.getReadsVar()
+        obsVarFreq = varscanHit.getVarFreq()
+        obsStrandsRef = varscanHit.getStrandsRef()
+        obsStrandsVar = varscanHit.getStrandsVar()
+        obsQualRef = varscanHit.getQualRef()
+        obsQualVar = varscanHit.getQualVar()
+        obsPValue = varscanHit.getPValue()
+        obsMapQualRef = varscanHit.getMapQualRef()
+        obsMapQualVar = varscanHit.getMapQualVar()
+        obsReadsRefPlus = varscanHit.getReadsRefPlus()
+        obsReadsRefMinus = varscanHit.getReadsRefMinus()
+        obsReadsVarPlus = varscanHit.getReadsVarPlus()
+        obsReadsVarMinus = varscanHit.getReadsVarMinus()
+        obsVar = varscanHit.getVar()
+        
+        self.assertEquals(expChrom, obsChrom)
+        self.assertEquals(expPosition, obsPosition)
+        self.assertEquals(expRef, obsRef)
+        self.assertEquals(expCns, obsCns)
+        self.assertEquals(expReadsRef, obsReadsRef)
+        self.assertEquals(expReadsVar, obsReadsVar)
+        self.assertEquals(expVarFreq, obsVarFreq)
+        self.assertEquals(expStrandsRef, obsStrandsRef)
+        self.assertEquals(expStrandsVar, obsStrandsVar)
+        self.assertEquals(expQualRef, obsQualRef)
+        self.assertEquals(expQualVar, obsQualVar)
+        self.assertEquals(expPValue, obsPValue)
+        self.assertEquals(expMapQualRef, obsMapQualRef)
+        self.assertEquals(expMapQualVar, obsMapQualVar)
+        self.assertEquals(expReadsRefPlus, obsReadsRefPlus)
+        self.assertEquals(expReadsRefMinus, obsReadsRefMinus)
+        self.assertEquals(expReadsVarPlus, obsReadsVarPlus)
+        self.assertEquals(expReadsVarMinus, obsReadsVarMinus)
+        self.assertEquals(expVar, obsVar)
+
+    def test_setAttributes_empty_chrom(self):
+        lResults = ['', '1804', 'T', 'C', '0', '1', '100%', '0', '1', '0', '53', '0.98', '0', '1', '0', '0', '1', '0', 'C']
+        lineNumber = 1
+        
+        varscanHit = VarscanHit_v2_2_8()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Chrom is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_position(self):
+        lResults = ['chr1', '', 'T', 'C', '0', '1', '100%', '0', '1', '0', '53', '0.98', '0', '1', '0', '0', '1', '0', 'C']
+        lineNumber = 1
+        
+        varscanHit = VarscanHit_v2_2_8()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Position is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_ref(self):
+        lResults = ['chr1', '1000', '', 'C', '0', '1', '100%', '0', '1', '0', '53', '0.98', '0', '1', '0', '0', '1', '0', 'C']
+        lineNumber = 1
+        
+        varscanHit = VarscanHit_v2_2_8()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Ref is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_cns(self):
+        lResults = ['chr1', '1000', 'T', '', '0', '1', '100%', '0', '1', '0', '53', '0.98', '0', '1', '0', '0', '1', '0', 'C']
+        lineNumber = 1
+        
+        varscanHit = VarscanHit_v2_2_8()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Cons is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_var(self):
+        lResults = ['chr1', '1000', 'T', 'C', '0', '1', '100%', '0', '1', '0', '53', '0.98', '0', '1', '0', '0', '1', '0', '']
+        lineNumber = 1
+        
+        varscanHit = VarscanHit_v2_2_8()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field varAllele is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test__eq__notEquals(self):
+        varscanHit1 = VarscanHit_v2_2_8()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('32')
+        varscanHit1.setRef('C')
+        varscanHit1.setCns('T')
+        varscanHit1.setVar('T')
+        
+        varscanHit2 = VarscanHit_v2_2_8()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('34')
+        varscanHit2.setRef('A')
+        varscanHit2.setCns('T')
+        varscanHit2.setVar('T')
+        
+        self.assertFalse(varscanHit1 == varscanHit2)
+
+    def test__eq__Equals(self):
+        varscanHit1 = VarscanHit_v2_2_8()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('34')
+        varscanHit1.setRef('A')
+        varscanHit1.setCns('T')
+        varscanHit1.setVar('T')
+        
+        varscanHit2 = VarscanHit_v2_2_8()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('34')
+        varscanHit2.setRef('A')
+        varscanHit2.setCns('T')
+        varscanHit2.setVar('T')
+        
+        self.assertTrue(varscanHit1 == varscanHit2)
+        
+    def test_convertVarscanHit_v2_2_8_To_VarscanHit(self):
+        line = "chr1\t1804\tT\tC\t0\t1\t100%\t0\t1\t0\t53\t0.98\t0\t1\t0\t0\t1\t0\tC\n"
+        iVarscanHit_v2_2_8_WithTag = VarscanHit_v2_2_8()
+        iVarscanHit_v2_2_8_WithTag.setAttributesFromString(line)
+        obsVarcanHit_WithTag = iVarscanHit_v2_2_8_WithTag.convertVarscanHit_v2_2_8_To_VarscanHit()
+        
+        line = "chr1\t1804\tT\tC\t0\t1\t100%\t0\t1\t0\t53\t0.98\n"
+        expVarcanHit_WithTag = VarscanHit()
+        expVarcanHit_WithTag.setAttributesFromString(line)
+        
+        self.assertEquals(expVarcanHit_WithTag, obsVarcanHit_WithTag)
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_VarscanHit_v2_2_8_WithTag.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,300 @@
+import unittest
+from commons.core.checker.CheckerException import CheckerException
+from commons.core.parsing.VarscanHit_v2_2_8_WithTag import VarscanHit_v2_2_8_WithTag
+from commons.core.parsing.VarscanHit_WithTag import VarscanHit_WithTag
+
+class Test_VarscanHit_v2_2_8_WithTag(unittest.TestCase):
+
+    def test_setAttributesFromString(self):
+        line = "chr1\t1804\tT\tC\t0\t1\t100%\t0\t1\t0\t53\t0.98\t0\t1\t0\t0\t1\t0\tC\tEspeceA\n"
+        
+        expChrom = "chr1"
+        expPosition = "1804"
+        expRef = "T"
+        expCns = "C"
+        expReadsRef = "0"
+        expReadsVar = "1"
+        expVarFreq = "100%"
+        expStrandsRef = "0"
+        expStrandsVar = "1"
+        expQualRef = "0"
+        expQualVar = "53"
+        expPValue = "0.98"
+        expMapQualRef = "0"
+        expMapQualVar = "1"
+        expReadsRefPlus = "0"
+        expReadsRefMinus = "0"
+        expReadsVarPlus = "1"
+        expReadsVarMinus = "0"
+        expVar = "C"
+        expTag = "EspeceA"
+        
+        varscanHit = VarscanHit_v2_2_8_WithTag()
+        varscanHit.setAttributesFromString(line)
+        
+        obsChrom = varscanHit.getChrom()
+        obsPosition = varscanHit.getPosition()
+        obsRef = varscanHit.getRef()
+        obsCns = varscanHit.getCns()
+        obsReadsRef = varscanHit.getReadsRef()
+        obsReadsVar = varscanHit.getReadsVar()
+        obsVarFreq = varscanHit.getVarFreq()
+        obsStrandsRef = varscanHit.getStrandsRef()
+        obsStrandsVar = varscanHit.getStrandsVar()
+        obsQualRef = varscanHit.getQualRef()
+        obsQualVar = varscanHit.getQualVar()
+        obsPValue = varscanHit.getPValue()
+        obsMapQualRef = varscanHit.getMapQualRef()
+        obsMapQualVar = varscanHit.getMapQualVar()
+        obsReadsRefPlus = varscanHit.getReadsRefPlus()
+        obsReadsRefMinus = varscanHit.getReadsRefMinus()
+        obsReadsVarPlus = varscanHit.getReadsVarPlus()
+        obsReadsVarMinus = varscanHit.getReadsVarMinus()
+        obsVar = varscanHit.getVar()
+        obsTag = varscanHit.getTag()
+        
+        self.assertEquals(expChrom, obsChrom)
+        self.assertEquals(expPosition, obsPosition)
+        self.assertEquals(expRef, obsRef)
+        self.assertEquals(expCns, obsCns)
+        self.assertEquals(expReadsRef, obsReadsRef)
+        self.assertEquals(expReadsVar, obsReadsVar)
+        self.assertEquals(expVarFreq, obsVarFreq)
+        self.assertEquals(expStrandsRef, obsStrandsRef)
+        self.assertEquals(expStrandsVar, obsStrandsVar)
+        self.assertEquals(expQualRef, obsQualRef)
+        self.assertEquals(expQualVar, obsQualVar)
+        self.assertEquals(expPValue, obsPValue)
+        self.assertEquals(expMapQualRef, obsMapQualRef)
+        self.assertEquals(expMapQualVar, obsMapQualVar)
+        self.assertEquals(expReadsRefPlus, obsReadsRefPlus)
+        self.assertEquals(expReadsRefMinus, obsReadsRefMinus)
+        self.assertEquals(expReadsVarPlus, obsReadsVarPlus)
+        self.assertEquals(expReadsVarMinus, obsReadsVarMinus)
+        self.assertEquals(expVar, obsVar)
+        self.assertEquals(expTag, obsTag)
+        
+    def test_setAttributesFromString_empty_chrom(self):
+        line = "\t1804\tT\tC\t0\t1\t100%\t0\t1\t0\t53\t0.98\t0\t1\t0\t0\t1\t0\tC\tEspeceA\n"
+        varscanHit = VarscanHit_v2_2_8_WithTag()
+        try :
+            varscanHit.setAttributesFromString(line)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        expMessage = "The field Chrom is empty in varscan file in line "
+        obsMessage = checkerExceptionInstance.msg
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributesFromString_less_than_20_fields(self):
+        line = "chr1\t1804\tT\tC\t0\t1\t100%\t0\t1\t53\t0.98\t0\t1\t0\t0\t1\t0\tC\tEspeceA\n"
+        varscanHit = VarscanHit_v2_2_8_WithTag()
+        try :
+            varscanHit.setAttributesFromString(line)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        expMessage = "This varscan line (l.) is not complete"
+        obsMessage = checkerExceptionInstance.msg
+        self.assertEquals(expMessage, obsMessage)
+        
+    def test_setAttributes(self):
+        lResults = ['chr1', '1804', 'T', 'C', '0', '1', '100%', '0', '1', '0', '53', '0.98', '0', '1', '0', '0', '1', '0', 'C', 'EspeceA']
+        lineNumber = 1
+        
+        expChrom = "chr1"
+        expPosition = "1804"
+        expRef = "T"
+        expCns = "C"
+        expReadsRef = "0"
+        expReadsVar = "1"
+        expVarFreq = "100%"
+        expStrandsRef = "0"
+        expStrandsVar = "1"
+        expQualRef = "0"
+        expQualVar = "53"
+        expPValue = "0.98"
+        expMapQualRef = "0"
+        expMapQualVar = "1"
+        expReadsRefPlus = "0"
+        expReadsRefMinus = "0"
+        expReadsVarPlus = "1"
+        expReadsVarMinus = "0"
+        expVar = "C"
+        expTag = "EspeceA"
+        
+        varscanHit = VarscanHit_v2_2_8_WithTag()
+        varscanHit.setAttributes(lResults, lineNumber)
+        
+        obsChrom = varscanHit.getChrom()
+        obsPosition = varscanHit.getPosition()
+        obsRef = varscanHit.getRef()
+        obsCns = varscanHit.getCns()
+        obsReadsRef = varscanHit.getReadsRef()
+        obsReadsVar = varscanHit.getReadsVar()
+        obsVarFreq = varscanHit.getVarFreq()
+        obsStrandsRef = varscanHit.getStrandsRef()
+        obsStrandsVar = varscanHit.getStrandsVar()
+        obsQualRef = varscanHit.getQualRef()
+        obsQualVar = varscanHit.getQualVar()
+        obsPValue = varscanHit.getPValue()
+        obsMapQualRef = varscanHit.getMapQualRef()
+        obsMapQualVar = varscanHit.getMapQualVar()
+        obsReadsRefPlus = varscanHit.getReadsRefPlus()
+        obsReadsRefMinus = varscanHit.getReadsRefMinus()
+        obsReadsVarPlus = varscanHit.getReadsVarPlus()
+        obsReadsVarMinus = varscanHit.getReadsVarMinus()
+        obsVar = varscanHit.getVar()
+        obsTag = varscanHit.getTag()
+        
+        self.assertEquals(expChrom, obsChrom)
+        self.assertEquals(expPosition, obsPosition)
+        self.assertEquals(expRef, obsRef)
+        self.assertEquals(expCns, obsCns)
+        self.assertEquals(expReadsRef, obsReadsRef)
+        self.assertEquals(expReadsVar, obsReadsVar)
+        self.assertEquals(expVarFreq, obsVarFreq)
+        self.assertEquals(expStrandsRef, obsStrandsRef)
+        self.assertEquals(expStrandsVar, obsStrandsVar)
+        self.assertEquals(expQualRef, obsQualRef)
+        self.assertEquals(expQualVar, obsQualVar)
+        self.assertEquals(expPValue, obsPValue)
+        self.assertEquals(expMapQualRef, obsMapQualRef)
+        self.assertEquals(expMapQualVar, obsMapQualVar)
+        self.assertEquals(expReadsRefPlus, obsReadsRefPlus)
+        self.assertEquals(expReadsRefMinus, obsReadsRefMinus)
+        self.assertEquals(expReadsVarPlus, obsReadsVarPlus)
+        self.assertEquals(expReadsVarMinus, obsReadsVarMinus)
+        self.assertEquals(expVar, obsVar)
+        self.assertEquals(expTag, obsTag)
+
+    def test_setAttributes_empty_chrom(self):
+        lResults = ['', '1804', 'T', 'C', '0', '1', '100%', '0', '1', '0', '53', '0.98', '0', '1', '0', '0', '1', '0', 'C', 'EspeceA']
+        lineNumber = 1
+        
+        varscanHit = VarscanHit_v2_2_8_WithTag()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Chrom is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_position(self):
+        lResults = ['chr1', '', 'T', 'C', '0', '1', '100%', '0', '1', '0', '53', '0.98', '0', '1', '0', '0', '1', '0', 'C', 'EspeceA']
+        lineNumber = 1
+        
+        varscanHit = VarscanHit_v2_2_8_WithTag()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Position is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_ref(self):
+        lResults = ['chr1', '1000', '', 'C', '0', '1', '100%', '0', '1', '0', '53', '0.98', '0', '1', '0', '0', '1', '0', 'C', 'EspeceA']
+        lineNumber = 1
+        
+        varscanHit = VarscanHit_v2_2_8_WithTag()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Ref is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_cns(self):
+        lResults = ['chr1', '1000', 'T', '', '0', '1', '100%', '0', '1', '0', '53', '0.98', '0', '1', '0', '0', '1', '0', 'C', 'EspeceA']
+        lineNumber = 1
+        
+        varscanHit = VarscanHit_v2_2_8_WithTag()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field Cons is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test_setAttributes_empty_var(self):
+        lResults = ['chr1', '1000', 'T', 'C', '0', '1', '100%', '0', '1', '0', '53', '0.98', '0', '1', '0', '0', '1', '0', '', 'EspeceA']
+        lineNumber = 1
+        
+        varscanHit = VarscanHit_v2_2_8_WithTag()
+        checkerExceptionInstance = None
+        try:
+            varscanHit.setAttributes(lResults, lineNumber)
+        except CheckerException, e:
+            checkerExceptionInstance = e
+        
+        expMessage = "The field varAllele is empty in varscan file in line 1"
+        obsMessage = checkerExceptionInstance.msg
+           
+        self.assertEquals(expMessage, obsMessage)
+
+    def test__eq__notEquals(self):
+        varscanHit1 = VarscanHit_v2_2_8_WithTag()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('34')
+        varscanHit1.setRef('A')
+        varscanHit1.setCns('T')
+        varscanHit1.setVar('T')
+        varscanHit1.setVar('EspeceA')
+        
+        varscanHit2 = VarscanHit_v2_2_8_WithTag()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('34')
+        varscanHit2.setRef('A')
+        varscanHit2.setCns('T')
+        varscanHit2.setVar('T')
+        varscanHit2.setVar('EspeceB')
+        
+        self.assertFalse(varscanHit1 == varscanHit2)
+
+    def test__eq__Equals(self):
+        varscanHit1 = VarscanHit_v2_2_8_WithTag()
+        varscanHit1.setChrom('C02HBa0291P19_LR48')
+        varscanHit1.setPosition('34')
+        varscanHit1.setRef('A')
+        varscanHit1.setCns('T')
+        varscanHit1.setVar('T')
+        varscanHit1.setVar('EspeceA')
+        
+        varscanHit2 = VarscanHit_v2_2_8_WithTag()
+        varscanHit2.setChrom('C02HBa0291P19_LR48')
+        varscanHit2.setPosition('34')
+        varscanHit2.setRef('A')
+        varscanHit2.setCns('T')
+        varscanHit2.setVar('T')
+        varscanHit2.setVar('EspeceA')
+        
+        self.assertTrue(varscanHit1 == varscanHit2)
+        
+    def test_convertVarscanHit_v2_2_8_WithTag_To_VarscanHit_WithTag(self):
+        line = "chr1\t1804\tT\tC\t0\t1\t100%\t0\t1\t0\t53\t0.98\t0\t1\t0\t0\t1\t0\tC\tEspeceA\n"
+        iVarscanHit_v2_2_8_WithTag = VarscanHit_v2_2_8_WithTag()
+        iVarscanHit_v2_2_8_WithTag.setAttributesFromString(line)
+        obsVarcanHit_WithTag = iVarscanHit_v2_2_8_WithTag.convertVarscanHit_v2_2_8_WithTag_To_VarscanHit_WithTag()
+        
+        line = "chr1\t1804\tT\tC\t0\t1\t100%\t0\t1\t0\t53\t0.98\tEspeceA\n"
+        expVarcanHit_WithTag = VarscanHit_WithTag()
+        expVarcanHit_WithTag.setAttributesFromString(line)
+        
+        self.assertEquals(expVarcanHit_WithTag, obsVarcanHit_WithTag)
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_WigParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,31 @@
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.parsing.WigParser import WigParser
+import glob
+import unittest
+import os
+
+class Test_WigParser(unittest.TestCase):
+    
+    def tearDown(self):
+        for file in glob.glob("data/.chr*.index"):
+              os.remove(file)
+
+    def test_GetRange1(self):
+        self.parser = WigParser("data/test.wig")
+        outputRange = [0.0, 1.1, 1.2, 0.0, 1.4, 1.5, 0.0, 1.7, 0.0, 1.9, 0.0]
+        self.assertEqual(self.parser.getRange("chr1", 10, 20), outputRange)
+        outputRange = [0.0, 9.5, 9.6, 0.0]
+        self.assertEqual(self.parser.getRange("chrX", 4, 7), outputRange)
+
+    def test_GetRange2(self):
+        self.parser = WigParser("data/test1.wig")
+        outputRange = [0.0, 1.1, 1.2, 0.0, 1.4, 1.5, 0.0, 1.7, 0.0, 1.9, 0.0]
+        self.assertEqual(self.parser.getRange("chr2", 10, 20), outputRange)
+
+    def test_GetRange3(self):
+        self.parser = WigParser("data/test2.wig")
+        outputRange = [1.4, 1.5]
+        self.assertEqual(self.parser.getRange("chr3", 14, 15), outputRange)
+
+if __name__ == '__main__':
+        unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/Test_pilerTAToGrouperMap.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,108 @@
+import unittest
+import os
+from commons.core.parsing.PilerTAToGrouperMap import PilerTAToGrouperMap
+from commons.core.utils.FileUtils import FileUtils
+
+class Test_pilerTAToGrouperMap(unittest.TestCase):
+
+    def setUp(self):
+        self._inputGffFileName = "input.gff"
+        self._inputPYRFileName = "input_pyr.gff"
+        self._inputMOTIFFileName = "input_motif.gff"
+        
+        self._obsOutFileName = "output.info"
+        self._obsGrouperFileName = "input_motif.gff.grp"
+        self._obsGrpMapFileName = "input_motif.gff.grp.map"
+        
+        self._expOutFileName = "exp_output.info"
+        self._expGrouperFileName = "exp_motif.gff.grp"
+        self._expGrpMapFileName = "exp_motif.gff.grp.map"
+        
+    def tearDown(self):
+        os.remove(self._inputGffFileName)
+        os.remove(self._inputPYRFileName)
+        os.remove(self._inputMOTIFFileName)
+        
+        os.remove(self._obsOutFileName)
+        os.remove(self._obsGrouperFileName)
+        os.remove(self._obsGrpMapFileName)
+        
+        os.remove(self._expOutFileName)
+        os.remove(self._expGrouperFileName)
+        os.remove(self._expGrpMapFileName)
+
+    def testRun(self):
+        self._writePilerTAFilePYR(self._inputPYRFileName)
+        self._writePilerTAFileMOTIF(self._inputMOTIFFileName)
+        self._writePilerTAGff(self._inputGffFileName)
+        
+        self._writeExpOutputFile(self._expOutFileName)
+        self._writeExpGrouperFile(self._expGrouperFileName)
+        self._writeExpGrouperMapFile(self._expGrpMapFileName)
+        
+        iPilerTAToGrouperMap = PilerTAToGrouperMap(self._inputGffFileName, self._inputPYRFileName,self._inputMOTIFFileName, self._obsOutFileName)
+        iPilerTAToGrouperMap.run()
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expOutFileName, self._obsOutFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expGrouperFileName, self._obsGrouperFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(self._expGrpMapFileName, self._obsGrpMapFileName))
+
+
+    def _writePilerTAGff(self, fileName):
+        f = open(fileName, "w")
+        f.write("chunk21\tpiler\thit\t155146\t156020\t0\t+\t.\tTarget chunk21 150519 151392 ; Pile 510 ; Pyramid 0\n")
+        f.write("chunk21\tpiler\thit\t154790\t156023\t0\t+\t.\tTarget chunk21 150519 151751 ; Pile 510 ; Pyramid 0\n")
+        f.write("chunk21\tpiler\thit\t154078\t156023\t0\t+\t.\tTarget chunk21 150519 152463 ; Pile 510 ; Pyramid 0\n")
+        f.write("chunk21\tpiler\thit\t154256\t156023\t0\t+\t.\tTarget chunk21 150519 152285 ; Pile 510 ; Pyramid 0\n")
+        f.write("chunk21\tpiler\thit\t154434\t156023\t0\t+\t.\tTarget chunk21 150519 152107 ; Pile 510 ; Pyramid 0\n")
+        f.close()
+
+    def _writePilerTAFilePYR(self, fileName):
+        f = open(fileName, "w")
+        f.write("chunk21\tpiler\tpyramid\t150519\t156023\t0\t.\t.\tPyramidIndex 0\n")
+        f.write("chunk21\tpiler\tpyramid\t150519\t156023\t0\t.\t.\tPyramidIndex 1\n")
+        f.write("chunk21\tpiler\tpyramid\t165574\t174424\t0\t.\t.\tPyramidIndex 2\n")
+        f.write("chunk21\tpiler\tpyramid\t166301\t174424\t0\t.\t.\tPyramidIndex 3\n")
+        f.write("chunk21\tpiler\tpyramid\t168967\t174424\t0\t.\t.\tPyramidIndex 4\n")
+        f.write("chunk21\tpiler\tpyramid\t170215\t174424\t0\t.\t.\tPyramidIndex 5\n")
+        f.close()
+        
+    def _writePilerTAFileMOTIF(self, fileName):
+        f = open(fileName, "w")
+        f.write("chunk21\tpiler\ttandemmotif\t155843\t156020\t0\t.\t.\tTarget chunk21 151215 151392 ; Pyramid 0\n")
+        f.write("chunk21\tpiler\ttandemmotif\t151215\t151392\t0\t.\t.\tTarget chunk21 155843 156020 ; Pyramid 0\n")
+        f.write("chunk21\tpiler\ttandemmotif\t151574\t151751\t0\t.\t.\tTarget chunk21 155843 156020 ; Pyramid 0\n")
+        f.write("chunk21\tpiler\ttandemmotif\t152286\t152463\t0\t.\t.\tTarget chunk21 155843 156020 ; Pyramid 0\n")
+        f.write("chunk21\tpiler\ttandemmotif\t152108\t152285\t0\t.\t.\tTarget chunk21 155843 156020 ; Pyramid 0\n")
+        f.close()
+        
+    def _writeExpOutputFile(self, fileName):
+        f = open(fileName, "w")
+        f.write("Pile 510\tPyramid 0\n")
+        f.write("\tPyramid 1\n")
+        f.write("\tPyramid 2\n")
+        f.write("\tPyramid 3\n")
+        f.write("\tPyramid 4\n")
+        f.write("\tPyramid 5\n")
+        f.close()
+    
+    def _writeExpGrouperFile(self, fileName):
+        f = open(fileName, "w")
+        f.write("MbS1Gr0Cl510\tchunk21\tpiler\ttandemmotif\t155843\t156020\t0\t.\t.\tTarget chunk21 151215 151392 \tPile 510\tPyramid 0\n")
+        f.write("MbS2Gr0Cl510\tchunk21\tpiler\ttandemmotif\t151215\t151392\t0\t.\t.\tTarget chunk21 155843 156020 \tPile 510\tPyramid 0\n")
+        f.write("MbS3Gr0Cl510\tchunk21\tpiler\ttandemmotif\t151574\t151751\t0\t.\t.\tTarget chunk21 155843 156020 \tPile 510\tPyramid 0\n")
+        f.write("MbS4Gr0Cl510\tchunk21\tpiler\ttandemmotif\t152286\t152463\t0\t.\t.\tTarget chunk21 155843 156020 \tPile 510\tPyramid 0\n")
+        f.write("MbS5Gr0Cl510\tchunk21\tpiler\ttandemmotif\t152108\t152285\t0\t.\t.\tTarget chunk21 155843 156020 \tPile 510\tPyramid 0\n")
+        f.close()
+        
+    def _writeExpGrouperMapFile(self, fileName):
+        f = open(fileName, "w")
+        f.write("MbS1Gr0Cl510\tchunk21\t155843\t156020\n") 
+        f.write("MbS2Gr0Cl510\tchunk21\t151215\t151392\n") 
+        f.write("MbS3Gr0Cl510\tchunk21\t151574\t151751\n") 
+        f.write("MbS4Gr0Cl510\tchunk21\t152286\t152463\n") 
+        f.write("MbS5Gr0Cl510\tchunk21\t152108\t152285\n") 
+        f.close()
+        
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/ExpPotDooblonsSubSNP.csv	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,832 @@
+SubSNPName;ConfidenceValue;Type;Position;5flank;3flank;Length;BatchNumber;IndividualNumber;PrimerType;PrimerNumber;Forward_or_Reverse;AlleleNumber
+Batch_AU247387_SNP_30_10102;A;SNP;30;NNNTATAGCTCCTAACATTCCTGAAGTGA;GATCACRGAGGACNNGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTAGCTTGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;9
+Batch_AU247387_SNP_30_IRELAND;A;SNP;30;NNNTATAGCTCCTAACATTCCTGAAGTGA;GATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGT;1;12;15;Sequence;;;7
+Batch_AU247387_SNP_30_POLAND;A;SNP;30;NNNTATAGCTCCTAACATTCCTGAAGTGA;GATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGT;1;12;20;Sequence;;;9
+Batch_AU247387_SNP_30_VIGOR;A;SNP;30;NNNTATAGCTCCTAACATTCCTGAAGTGA;GATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGT;1;12;23;Sequence;;;9
+Batch_AU247387_SNP_34_10102;A;SNP;34;NNNTATAGCTCCTAACATTCCTGAAGTGAAGAT;ACRGAGGACNNGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTAGCTTGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;7
+Batch_AU247387_SNP_34_IRELAND;A;SNP;34;NNNTATAGCTCCTAACATTCCTGAAGTGACGAT;CCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCT;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_34_POLAND;A;SNP;34;NNNTATAGCTCCTAACATTCCTGAAGTGAAGAT;ACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCA;1;12;20;Sequence;;;7
+Batch_AU247387_SNP_34_VIGOR;A;SNP;34;NNNTATAGCTCCTAACATTCCTGAAGTGAAGAT;ACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCA;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_35_10102;A;SNP;35;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATC;CRGAGGACNNGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTAGCTTGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;9
+Batch_AU247387_SNP_35_IRELAND;A;SNP;35;NNNTATAGCTCCTAACATTCCTGAAGTGACGATT;CAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTG;1;12;15;Sequence;;;7
+Batch_AU247387_SNP_35_POLAND;A;SNP;35;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATC;CGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCAT;1;12;20;Sequence;;;9
+Batch_AU247387_SNP_35_VIGOR;A;SNP;35;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATC;CGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCAT;1;12;23;Sequence;;;9
+Batch_AU247387_SNP_37_10102;A;SNP;37;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCAC;GAGGACNNGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTAGCTTGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;5
+Batch_AU247387_SNP_37_IRELAND;A;SNP;37;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCC;GAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG-;1;12;15;Sequence;;;9
+Batch_AU247387_SNP_37_POLAND;A;SNP;37;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCAC;GAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGG;1;12;20;Sequence;;;6
+Batch_AU247387_SNP_37_VIGOR;A;SNP;37;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCAC;GAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGG;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_44_IRELAND;A;SNP;44;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGAC;CGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG--------;1;12;15;Sequence;;;9
+Batch_AU247387_SNP_44_POLAND;A;SNP;44;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGAC;TGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTT;1;12;20;Sequence;;;7
+Batch_AU247387_SNP_44_VIGOR;A;SNP;44;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGAC;TGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTT;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_45_IRELAND;A;SNP;45;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACA;GATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------;1;12;15;Sequence;;;7
+Batch_AU247387_SNP_45_POLAND;A;SNP;45;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACC;GGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTC;1;12;20;Sequence;;;10
+Batch_AU247387_SNP_45_VIGOR;A;SNP;45;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACC;GGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTC;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_47_10102;A;SNP;47;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACRGAGGACNNG;CTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTAGCTTGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;6
+Batch_AU247387_SNP_47_IRELAND;A;SNP;47;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACG;TTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG-----------;1;12;15;Sequence;;;9
+Batch_AU247387_SNP_47_POLAND;A;SNP;47;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTG;CTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTC;1;12;20;Sequence;;;6
+Batch_AU247387_SNP_47_VIGOR;A;SNP;47;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTG;CTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTC;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_48_10102;A;SNP;48;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACRGAGGACNNGG;TGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTAGCTTGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;7
+Batch_AU247387_SNP_48_IRELAND;A;SNP;48;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGA;TGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG------------;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_48_POLAND;A;SNP;48;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGG;TGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCT;1;12;20;Sequence;;;7
+Batch_AU247387_SNP_48_VIGOR;A;SNP;48;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGG;TGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCT;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_52_10102;A;SNP;52;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACRGAGGACNNGGCTGT;AATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTAGCTTGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;7
+Batch_AU247387_SNP_52_10954;A;SNP;52;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNT;AATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAG;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_52_CARILLON;A;SNP;52;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;AACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG----------------;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_52_F14-13;A;SNP;52;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNT;AATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;4
+Batch_AU247387_SNP_52_GREECE;A;SNP;52;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNT;AACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGYCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;4
+Batch_AU247387_SNP_52_IMAGINE;A;SNP;52;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNT;AATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAG;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_52_IRELAND;A;SNP;52;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGT;AACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG----------------;1;12;15;Sequence;;;6
+Batch_AU247387_SNP_52_NEMOF;A;SNP;52;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNT;AATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAG;1;12;18;Sequence;;;7
+Batch_AU247387_SNP_52_NEMOH;A;SNP;52;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNT;AATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAG;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_52_POLAND;A;SNP;52;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGT;AATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAG;1;12;20;Sequence;;;7
+Batch_AU247387_SNP_52_SPAIN;A;SNP;52;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNT;AACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG----------------;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_52_VIGOR;A;SNP;52;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGT;AATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_55_10102;A;SNP;55;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACRGAGGACNNGGCTGTCAA;GTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTAGCTTGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;10
+Batch_AU247387_SNP_55_10954;A;SNP;55;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAA;GTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCT;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_55_CARILLON;A;SNP;55;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAA;ATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG-------------------;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_55_F14-13;A;SNP;55;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAA;GTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;10
+Batch_AU247387_SNP_55_GAGNY;A;SNP;55;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;ATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGTCAGGGCCGTGAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;7
+Batch_AU247387_SNP_55_GREECE;A;SNP;55;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAA;ATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGYCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;7
+Batch_AU247387_SNP_55_IMAGINE;A;SNP;55;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAA;GTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCT;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_55_IRELAND;A;SNP;55;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAA;ATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG-------------------;1;12;15;Sequence;;;7
+Batch_AU247387_SNP_55_NEMOF;A;SNP;55;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAA;GTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCT;1;12;18;Sequence;;;10
+Batch_AU247387_SNP_55_NEMOH;A;SNP;55;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAA;GTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCT;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_55_POLAND;A;SNP;55;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAA;GTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCT;1;12;20;Sequence;;;10
+Batch_AU247387_SNP_55_SPAIN;A;SNP;55;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAA;ATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG-------------------;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_55_VIGOR;A;SNP;55;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAA;GTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCT;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_56_10102;A;SNP;56;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACRGAGGACNNGGCTGTCAAT;TTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTAGCTTGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;6
+Batch_AU247387_SNP_56_10954;A;SNP;56;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAAT;TTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTT;1;12;6;Sequence;;;6
+Batch_AU247387_SNP_56_CARILLON;A;SNP;56;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAAC;TTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG--------------------;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_56_F14-13;A;SNP;56;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAAT;TTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;6
+Batch_AU247387_SNP_56_GAGNY;A;SNP;56;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNC;TTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGTCAGGGCCGTGAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;9
+Batch_AU247387_SNP_56_GREECE;A;SNP;56;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAAC;TTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGYCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;9
+Batch_AU247387_SNP_56_IMAGINE;A;SNP;56;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAAT;TTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTT;1;12;14;Sequence;;;6
+Batch_AU247387_SNP_56_IRELAND;A;SNP;56;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAAC;TTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG--------------------;1;12;15;Sequence;;;9
+Batch_AU247387_SNP_56_NEMOF;A;SNP;56;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAAT;TTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTT;1;12;18;Sequence;;;6
+Batch_AU247387_SNP_56_NEMOH;A;SNP;56;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAAT;TTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTT;1;12;19;Sequence;;;6
+Batch_AU247387_SNP_56_POLAND;A;SNP;56;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAAT;TTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTT;1;12;20;Sequence;;;6
+Batch_AU247387_SNP_56_SPAIN;A;SNP;56;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAAC;TTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG--------------------;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_56_VIGOR;A;SNP;56;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAAT;TTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTT;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_94_10102;A;SNP;94;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACRGAGGACNNGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTT;GCTAGCTTGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;1
+Batch_AU247387_SNP_94_10954;A;SNP;94;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTT;GCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCT;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_94_CARILLON;A;SNP;94;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTT;TTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG----------------------------------------------------------;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_94_F14-13;A;SNP;94;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTT;GCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;10
+Batch_AU247387_SNP_94_GAGNY;A;SNP;94;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTT;TTTACTTTGAAGGAGATYGGTCAGGGCCGTGAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;7
+Batch_AU247387_SNP_94_GREECE;A;SNP;94;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTT;TTTACTTTGAAGGAGATYGGYCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;7
+Batch_AU247387_SNP_94_IMAGINE;A;SNP;94;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTT;GCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCT;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_94_IRELAND;A;SNP;94;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTT;TTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG----------------------------------------------------------;1;12;15;Sequence;;;7
+Batch_AU247387_SNP_94_NEMOF;A;SNP;94;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTT;GCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCT;1;12;18;Sequence;;;10
+Batch_AU247387_SNP_94_NEMOH;A;SNP;94;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTT;GCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCT;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_94_POLAND;A;SNP;94;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTT;GCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNN;1;12;20;Sequence;;;10
+Batch_AU247387_SNP_94_SPAIN;A;SNP;94;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTT;TTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG----------------------------------------------------------;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_94_TRANSATE;A;SNP;94;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTT;TTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG----------------------------------------------------------;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_94_VIGOR;A;SNP;94;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTT;GCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCT;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_95_10102;A;SNP;95;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACRGAGGACNNGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTY;CTAGCTTGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;6
+Batch_AU247387_SNP_95_10954;A;SNP;95;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTT;CTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTA;1;12;6;Sequence;;;6
+Batch_AU247387_SNP_95_CARILLON;A;SNP;95;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTC;TTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG-----------------------------------------------------------;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_95_F14-13;A;SNP;95;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTT;CTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;6
+Batch_AU247387_SNP_95_GAGNY;A;SNP;95;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTC;TTACTTTGAAGGAGATYGGTCAGGGCCGTGAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;10
+Batch_AU247387_SNP_95_GREECE;A;SNP;95;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTC;TTACTTTGAAGGAGATYGGYCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;10
+Batch_AU247387_SNP_95_IMAGINE;A;SNP;95;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTT;CTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTA;1;12;14;Sequence;;;6
+Batch_AU247387_SNP_95_IRELAND;A;SNP;95;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTC;TTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG-----------------------------------------------------------;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_95_NEMOF;A;SNP;95;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTT;CTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTA;1;12;18;Sequence;;;6
+Batch_AU247387_SNP_95_NEMOH;A;SNP;95;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTT;CTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTA;1;12;19;Sequence;;;6
+Batch_AU247387_SNP_95_POLAND;A;SNP;95;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTT;CTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNN;1;12;20;Sequence;;;6
+Batch_AU247387_SNP_95_SPAIN;A;SNP;95;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTC;TTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG-----------------------------------------------------------;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_95_TRANSATE;A;SNP;95;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTC;TTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG-----------------------------------------------------------;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_95_VIGOR;A;SNP;95;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTT;CTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTA;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_96_10102;A;SNP;96;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACRGAGGACNNGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYG;TAGCTTGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;7
+Batch_AU247387_SNP_96_10954;A;SNP;96;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTG;TAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTAT;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_96_CARILLON;A;SNP;96;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCT;TACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG------------------------------------------------------------;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_96_F14-13;A;SNP;96;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTG;TAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;7
+Batch_AU247387_SNP_96_GAGNY;A;SNP;96;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCT;TACTTTGAAGGAGATYGGTCAGGGCCGTGAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;10
+Batch_AU247387_SNP_96_GREECE;A;SNP;96;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCT;TACTTTGAAGGAGATYGGYCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;10
+Batch_AU247387_SNP_96_IMAGINE;A;SNP;96;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTG;TAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTAT;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_96_IRELAND;A;SNP;96;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCT;TACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG------------------------------------------------------------;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_96_NEMOF;A;SNP;96;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTG;TAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTAT;1;12;18;Sequence;;;7
+Batch_AU247387_SNP_96_NEMOH;A;SNP;96;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTG;TAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTAT;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_96_POLAND;A;SNP;96;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTG;TAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNN;1;12;20;Sequence;;;7
+Batch_AU247387_SNP_96_SPAIN;A;SNP;96;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCT;TACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG------------------------------------------------------------;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_96_TRANSATE;A;SNP;96;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCT;TACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG------------------------------------------------------------;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_96_VIGOR;A;SNP;96;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTG;TAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTAT;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_99_10102;A;SNP;99;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACRGAGGACNNGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTA;CTTGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;6
+Batch_AU247387_SNP_99_10954;A;SNP;99;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTA;CCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACT;1;12;6;Sequence;;;6
+Batch_AU247387_SNP_99_CARILLON;A;SNP;99;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTA;TTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_99_F14-13;A;SNP;99;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTA;CCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;6
+Batch_AU247387_SNP_99_GAGNY;A;SNP;99;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTA;TTTGAAGGAGATYGGTCAGGGCCGTGAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;7
+Batch_AU247387_SNP_99_GREECE;A;SNP;99;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTA;TTTGAAGGAGATYGGYCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;7
+Batch_AU247387_SNP_99_IMAGINE;A;SNP;99;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTA;CCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACT;1;12;14;Sequence;;;6
+Batch_AU247387_SNP_99_IRELAND;A;SNP;99;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTA;TTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------;1;12;15;Sequence;;;7
+Batch_AU247387_SNP_99_NEMOF;A;SNP;99;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTA;CCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACT;1;12;18;Sequence;;;6
+Batch_AU247387_SNP_99_NEMOH;A;SNP;99;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTA;CCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACT;1;12;19;Sequence;;;6
+Batch_AU247387_SNP_99_POLAND;A;SNP;99;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTA;CCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNN;1;12;20;Sequence;;;6
+Batch_AU247387_SNP_99_SPAIN;A;SNP;99;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTA;TTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_99_TRANSATE;A;SNP;99;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTA;TTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_99_VIGOR;A;SNP;99;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTA;CCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACT;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_100_10102;A;SNP;100;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACRGAGGACNNGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTAG;TTGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;7
+Batch_AU247387_SNP_100_10954;A;SNP;100;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAG;CTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTG;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_100_CARILLON;A;SNP;100;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTAC;TTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG----------------------------------------------------------------;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_100_F14-13;A;SNP;100;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAG;CTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;7
+Batch_AU247387_SNP_100_GAGNY;A;SNP;100;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTAC;TTGAAGGAGATYGGTCAGGGCCGTGAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;10
+Batch_AU247387_SNP_100_GREECE;A;SNP;100;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTAC;TTGAAGGAGATYGGYCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;10
+Batch_AU247387_SNP_100_IMAGINE;A;SNP;100;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAG;CTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTG;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_100_IRELAND;A;SNP;100;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTAC;TTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG----------------------------------------------------------------;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_100_NEMOF;A;SNP;100;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAG;CTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTG;1;12;18;Sequence;;;7
+Batch_AU247387_SNP_100_NEMOH;A;SNP;100;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAG;CTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTG;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_100_POLAND;A;SNP;100;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAG;CTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNN;1;12;20;Sequence;;;7
+Batch_AU247387_SNP_100_SPAIN;A;SNP;100;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTAC;TTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG----------------------------------------------------------------;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_100_TRANSATE;A;SNP;100;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTAC;TTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG----------------------------------------------------------------;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_100_VIGOR;A;SNP;100;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAG;CTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_101_10102;A;SNP;101;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACRGAGGACNNGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTAGC;TGAGGGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;10
+Batch_AU247387_SNP_101_10954;A;SNP;101;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGC;TGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGT;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_101_CARILLON;A;SNP;101;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACT;TGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG-----------------------------------------------------------------;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_101_F14-13;A;SNP;101;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGC;TGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;7
+Batch_AU247387_SNP_101_GAGNY;A;SNP;101;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACT;TGAAGGAGATYGGTCAGGGCCGTGAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;10
+Batch_AU247387_SNP_101_GREECE;A;SNP;101;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACT;TGAAGGAGATYGGYCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;10
+Batch_AU247387_SNP_101_IMAGINE;A;SNP;101;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGC;TGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGT;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_101_IRELAND;A;SNP;101;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACT;TGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG-----------------------------------------------------------------;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_101_NEMOF;A;SNP;101;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGC;TGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGT;1;12;18;Sequence;;;7
+Batch_AU247387_SNP_101_NEMOH;A;SNP;101;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGC;TGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGT;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_101_POLAND;A;SNP;101;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGC;TGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNN;1;12;20;Sequence;;;7
+Batch_AU247387_SNP_101_SPAIN;A;SNP;101;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACT;TGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG-----------------------------------------------------------------;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_101_TRANSATE;A;SNP;101;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACT;TGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG-----------------------------------------------------------------;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_101_VIGOR;A;SNP;101;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGC;TGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGT;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_105_10102;A;SNP;105;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACRGAGGACNNGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTAGCTTGA;GGCGATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;6
+Batch_AU247387_SNP_105_10954;A;SNP;105;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGA;GGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTAT;1;12;6;Sequence;;;6
+Batch_AU247387_SNP_105_CARILLON;A;SNP;105;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGA;GGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_105_F14-13;A;SNP;105;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGA;GGCGATTGGTCAAGGCCGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;6
+Batch_AU247387_SNP_105_GAGNY;A;SNP;105;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGA;GGAGATYGGTCAGGGCCGTGAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;9
+Batch_AU247387_SNP_105_GREECE;A;SNP;105;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGA;GGAGATYGGYCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;9
+Batch_AU247387_SNP_105_IMAGINE;A;SNP;105;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGA;GGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTAT;1;12;14;Sequence;;;6
+Batch_AU247387_SNP_105_IRELAND;A;SNP;105;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGA;GGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_105_NEMOF;A;SNP;105;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGA;GGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTAT;1;12;18;Sequence;;;6
+Batch_AU247387_SNP_105_NEMOH;A;SNP;105;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGA;GGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTAT;1;12;19;Sequence;;;6
+Batch_AU247387_SNP_105_POLAND;A;SNP;105;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGA;GGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;6
+Batch_AU247387_SNP_105_SPAIN;A;SNP;105;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGA;GGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_105_TRANSATE;A;SNP;105;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGA;GGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------;1;12;22;Sequence;;;9
+Batch_AU247387_SNP_105_VIGOR;A;SNP;105;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGA;GGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTAT;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_108_10102;A;SNP;108;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACRGAGGACNNGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTAGCTTGAGGG;GATTGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;7
+Batch_AU247387_SNP_108_10954;A;SNP;108;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGG;GATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTG;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_108_CARILLON;A;SNP;108;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGG;GATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG------------------------------------------------------------------------;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_108_F14-13;A;SNP;108;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGG;GATTGGTCAAGGCCGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;7
+Batch_AU247387_SNP_108_GAGNY;A;SNP;108;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGG;GATYGGTCAGGGCCGTGAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;9
+Batch_AU247387_SNP_108_GREECE;A;SNP;108;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGG;GATYGGYCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;9
+Batch_AU247387_SNP_108_IMAGINE;A;SNP;108;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGG;GATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTG;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_108_IRELAND;A;SNP;108;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGG;GATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG------------------------------------------------------------------------;1;12;15;Sequence;;;9
+Batch_AU247387_SNP_108_NEMOF;A;SNP;108;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGG;GATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTG;1;12;18;Sequence;;;7
+Batch_AU247387_SNP_108_NEMOH;A;SNP;108;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGG;GATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTG;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_108_POLAND;A;SNP;108;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGG;GATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;7
+Batch_AU247387_SNP_108_SPAIN;A;SNP;108;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGG;GATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG------------------------------------------------------------------------;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_108_TRANSATE;A;SNP;108;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGG;GATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG------------------------------------------------------------------------;1;12;22;Sequence;;;9
+Batch_AU247387_SNP_108_VIGOR;A;SNP;108;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGG;GATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_112_10102;A;SNP;112;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACRGAGGACNNGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTYGCTAGCTTGAGGGCGAT;GGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;1;Sequence;;;10
+Batch_AU247387_SNP_112_10954;A;SNP;112;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGAT;GGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCG;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_112_CARILLON;A;SNP;112;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGAT;GGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG----------------------------------------------------------------------------;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_112_F14-13;A;SNP;112;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGAT;GGTCAAGGCCGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;10
+Batch_AU247387_SNP_112_GAGNY;A;SNP;112;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGAT;GGTCAGGGCCGTGAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;1
+Batch_AU247387_SNP_112_GREECE;A;SNP;112;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGAT;GGYCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;1
+Batch_AU247387_SNP_112_IMAGINE;A;SNP;112;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGAT;GGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCG;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_112_IRELAND;A;SNP;112;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGAT;GGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG----------------------------------------------------------------------------;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_112_NEMOF;A;SNP;112;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGAT;GGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCG;1;12;18;Sequence;;;10
+Batch_AU247387_SNP_112_NEMOH;A;SNP;112;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGAT;GGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCG;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_112_POLAND;A;SNP;112;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGAT;GGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;10
+Batch_AU247387_SNP_112_SPAIN;A;SNP;112;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGAT;GGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG----------------------------------------------------------------------------;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_112_TRANSATE;A;SNP;112;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGAT;GGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG----------------------------------------------------------------------------;1;12;22;Sequence;;;1
+Batch_AU247387_SNP_112_VIGOR;A;SNP;112;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGAT;GGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_115_10954;A;SNP;115;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGG;CAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAG;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_115_ABERAVON;A;SNP;115;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGG;CAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;7;Sequence;;;10
+Batch_AU247387_SNP_115_CARILLON;A;SNP;115;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGG;CAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG-------------------------------------------------------------------------------;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_115_F14-13;A;SNP;115;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGG;CAAGGCCGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;10
+Batch_AU247387_SNP_115_GAGNY;A;SNP;115;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGG;CAGGGCCGTGAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;10
+Batch_AU247387_SNP_115_GREECE;A;SNP;115;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGG;CAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;1
+Batch_AU247387_SNP_115_IMAGINE;A;SNP;115;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGG;CAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAG;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_115_IRELAND;A;SNP;115;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGG;CAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG-------------------------------------------------------------------------------;1;12;15;Sequence;;;7
+Batch_AU247387_SNP_115_NEMOF;A;SNP;115;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGG;CAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAG;1;12;18;Sequence;;;10
+Batch_AU247387_SNP_115_NEMOH;A;SNP;115;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGG;CAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAG;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_115_POLAND;A;SNP;115;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGG;CAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;10
+Batch_AU247387_SNP_115_SPAIN;A;SNP;115;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGG;CAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG-------------------------------------------------------------------------------;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_115_TRANSATE;A;SNP;115;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGG;CAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG-------------------------------------------------------------------------------;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_115_VIGOR;A;SNP;115;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGG;CAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_118_10954;A;SNP;118;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCA;GGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTG;1;12;6;Sequence;;;9
+Batch_AU247387_SNP_118_ABERAVON;A;SNP;118;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTCA;GGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;7;Sequence;;;9
+Batch_AU247387_SNP_118_CARILLON;A;SNP;118;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCA;GGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG----------------------------------------------------------------------------------;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_118_F14-13;A;SNP;118;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCA;GGCCGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;9
+Batch_AU247387_SNP_118_GAGNY;A;SNP;118;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGTCA;GGCCGTGAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;6
+Batch_AU247387_SNP_118_GREECE;A;SNP;118;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGYCA;GGCCGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;6
+Batch_AU247387_SNP_118_IMAGINE;A;SNP;118;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCA;GGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTG;1;12;14;Sequence;;;9
+Batch_AU247387_SNP_118_IRELAND;A;SNP;118;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCA;GGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG----------------------------------------------------------------------------------;1;12;15;Sequence;;;6
+Batch_AU247387_SNP_118_NEMOF;A;SNP;118;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCA;GGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTG;1;12;18;Sequence;;;9
+Batch_AU247387_SNP_118_NEMOH;A;SNP;118;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCA;GGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTG;1;12;19;Sequence;;;9
+Batch_AU247387_SNP_118_POLAND;A;SNP;118;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCA;GGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;9
+Batch_AU247387_SNP_118_SPAIN;A;SNP;118;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCA;GGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG----------------------------------------------------------------------------------;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_118_TRANSATE;A;SNP;118;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCA;GGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG----------------------------------------------------------------------------------;1;12;22;Sequence;;;6
+Batch_AU247387_SNP_118_VIGOR;A;SNP;118;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCA;GGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTG;1;12;23;Sequence;;;9
+Batch_AU247387_SNP_121_10954;A;SNP;121;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGG;CGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATT;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_121_ABERAVON;A;SNP;121;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTCAAGG;CGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;7;Sequence;;;7
+Batch_AU247387_SNP_121_CARILLON;A;SNP;121;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGG;CGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG-------------------------------------------------------------------------------------;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_121_F14-13;A;SNP;121;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGG;CGTGACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;7
+Batch_AU247387_SNP_121_GAGNY;A;SNP;121;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGTCAGGG;CGTGAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;7
+Batch_AU247387_SNP_121_GREECE;A;SNP;121;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGYCAGGG;CGTGATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;7
+Batch_AU247387_SNP_121_IMAGINE;A;SNP;121;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGG;CGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATT;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_121_IRELAND;A;SNP;121;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGG;CGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG-------------------------------------------------------------------------------------;1;12;15;Sequence;;;7
+Batch_AU247387_SNP_121_NEMOF;A;SNP;121;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGG;CGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATT;1;12;18;Sequence;;;7
+Batch_AU247387_SNP_121_NEMOH;A;SNP;121;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGG;CGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATT;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_121_POLAND;A;SNP;121;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGG;CGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;7
+Batch_AU247387_SNP_121_SPAIN;A;SNP;121;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGG;CGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG-------------------------------------------------------------------------------------;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_121_TRANSATE;A;SNP;121;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGG;CGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG-------------------------------------------------------------------------------------;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_121_VIGOR;A;SNP;121;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGG;CGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATT;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_124_10954;A;SNP;124;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCG;GACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCA;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_124_ABERAVON;A;SNP;124;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTCAAGGCCG;GACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;7;Sequence;;;10
+Batch_AU247387_SNP_124_CARILLON;A;SNP;124;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCG;GATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG----------------------------------------------------------------------------------------;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_124_F14-13;A;SNP;124;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCG;GACCTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;10
+Batch_AU247387_SNP_124_GAGNY;A;SNP;124;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGTCAGGGCCG;GAYCTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;10
+Batch_AU247387_SNP_124_GREECE;A;SNP;124;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGYCAGGGCCG;GATCTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;10
+Batch_AU247387_SNP_124_IMAGINE;A;SNP;124;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCG;GACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCA;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_124_IRELAND;A;SNP;124;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCG;GATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG----------------------------------------------------------------------------------------;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_124_NEMOF;A;SNP;124;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCG;GACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCA;1;12;18;Sequence;;;10
+Batch_AU247387_SNP_124_NEMOH;A;SNP;124;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCG;GACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCA;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_124_POLAND;A;SNP;124;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCG;GACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;10
+Batch_AU247387_SNP_124_SPAIN;A;SNP;124;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCG;GATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG----------------------------------------------------------------------------------------;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_124_TRANSATE;A;SNP;124;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCG;GACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG----------------------------------------------------------------------------------------;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_124_VIGOR;A;SNP;124;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCG;GACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCA;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_127_10954;A;SNP;127;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGA;CTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGT;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_127_ABERAVON;A;SNP;127;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTCAAGGCCGTGA;CTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;7;Sequence;;;7
+Batch_AU247387_SNP_127_CARILLON;A;SNP;127;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGA;CTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG-------------------------------------------------------------------------------------------;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_127_F14-13;A;SNP;127;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGA;CTGAAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;7
+Batch_AU247387_SNP_127_GAGNY;A;SNP;127;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGTCAGGGCCGTGA;CTGAAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;1
+Batch_AU247387_SNP_127_GREECE;A;SNP;127;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGYCAGGGCCGTGA;CTGAAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;10
+Batch_AU247387_SNP_127_IMAGINE;A;SNP;127;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGA;CTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGT;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_127_IRELAND;A;SNP;127;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGA;CTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG-------------------------------------------------------------------------------------------;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_127_NEMOF;A;SNP;127;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGA;CTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGT;1;12;18;Sequence;;;7
+Batch_AU247387_SNP_127_NEMOH;A;SNP;127;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGA;CTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGT;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_127_POLAND;A;SNP;127;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGA;CTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;7
+Batch_AU247387_SNP_127_SPAIN;A;SNP;127;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGA;CTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG-------------------------------------------------------------------------------------------;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_127_TRANSATE;A;SNP;127;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGA;CTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG-------------------------------------------------------------------------------------------;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_127_VIGOR;A;SNP;127;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGA;CTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGT;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_130_10954;A;SNP;130;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCT;AAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTG;1;12;6;Sequence;;;6
+Batch_AU247387_SNP_130_ABERAVON;A;SNP;130;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTCAAGGCCGTGACCT;AAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;7;Sequence;;;6
+Batch_AU247387_SNP_130_CARILLON;A;SNP;130;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCT;AAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG----------------------------------------------------------------------------------------------;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_130_F14-13;A;SNP;130;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCT;AAGAAANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;11;Sequence;;;6
+Batch_AU247387_SNP_130_GAGNY;A;SNP;130;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGTCAGGGCCGTGAYCT;AAGAAATTCCTSATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;6
+Batch_AU247387_SNP_130_GREECE;A;SNP;130;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGYCAGGGCCGTGATCT;AAGAAATTCCTCATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;6
+Batch_AU247387_SNP_130_IMAGINE;A;SNP;130;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCT;AAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTG;1;12;14;Sequence;;;6
+Batch_AU247387_SNP_130_IRELAND;A;SNP;130;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCT;AAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG----------------------------------------------------------------------------------------------;1;12;15;Sequence;;;6
+Batch_AU247387_SNP_130_NEMOF;A;SNP;130;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCT;AAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTG;1;12;18;Sequence;;;6
+Batch_AU247387_SNP_130_NEMOH;A;SNP;130;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCT;AAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTG;1;12;19;Sequence;;;6
+Batch_AU247387_SNP_130_POLAND;A;SNP;130;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCT;AAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;6
+Batch_AU247387_SNP_130_SPAIN;A;SNP;130;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCT;AAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG----------------------------------------------------------------------------------------------;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_130_TRANSATE;A;SNP;130;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCT;AAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG----------------------------------------------------------------------------------------------;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_130_VIGOR;A;SNP;130;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCT;AAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTG;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_142_10954;A;SNP;142;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCT;ATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT--;1;12;6;Sequence;;;6
+Batch_AU247387_SNP_142_ABERAVON;A;SNP;142;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTCAAGGCCGTGACCTGAAGAAATTCCT;ATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;7;Sequence;;;6
+Batch_AU247387_SNP_142_CARILLON;A;SNP;142;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCT;ATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGG;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_142_GAGNY;A;SNP;142;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGTCAGGGCCGTGAYCTGAAGAAATTCCT;ATTGTAYGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;4
+Batch_AU247387_SNP_142_GREECE;A;SNP;142;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGYCAGGGCCGTGATCTGAAGAAATTCCT;ATTGTATGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;7
+Batch_AU247387_SNP_142_IMAGINE;A;SNP;142;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCT;ATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT--;1;12;14;Sequence;;;6
+Batch_AU247387_SNP_142_IRELAND;A;SNP;142;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCT;ATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGG;1;12;15;Sequence;;;7
+Batch_AU247387_SNP_142_NEMOF;A;SNP;142;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCT;ATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT--;1;12;18;Sequence;;;6
+Batch_AU247387_SNP_142_NEMOH;A;SNP;142;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCT;ATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT--;1;12;19;Sequence;;;6
+Batch_AU247387_SNP_142_POLAND;A;SNP;142;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCT;ATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;6
+Batch_AU247387_SNP_142_SPAIN;A;SNP;142;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCT;ATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGG;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_142_TRANSATE;A;SNP;142;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCT;ATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGG;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_142_VIGOR;A;SNP;142;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCT;ATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT--;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_149_10954;A;SNP;149;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTA;GT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_149_ABERAVON;A;SNP;149;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTA;GT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;7;Sequence;;;7
+Batch_AU247387_SNP_149_CARILLON;A;SNP;149;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTA;GTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTT;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_149_GAGNY;A;SNP;149;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGTCAGGGCCGTGAYCTGAAGAAATTCCTSATTGTA;GTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;12;Sequence;;;1
+Batch_AU247387_SNP_149_GREECE;A;SNP;149;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTSAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGYCAGGGCCGTGATCTGAAGAAATTCCTCATTGTA;GTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;13;Sequence;;;10
+Batch_AU247387_SNP_149_IMAGINE;A;SNP;149;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTA;GT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_149_IRELAND;A;SNP;149;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTA;GT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTT;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_149_NEMOF;A;SNP;149;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTA;GT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------;1;12;18;Sequence;;;7
+Batch_AU247387_SNP_149_NEMOH;A;SNP;149;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTA;GT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_149_POLAND;A;SNP;149;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTA;GT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;1
+Batch_AU247387_SNP_149_SPAIN;A;SNP;149;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTA;GTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTT;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_149_TRANSATE;A;SNP;149;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTA;GTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTT;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_149_VIGOR;A;SNP;149;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTA;GT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------;1;12;23;Sequence;;;7
+Batch_AU247387_DEL_152_10954;A;DELETION;152;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT;TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTC;27;12;6;Sequence;;;54
+Batch_AU247387_DEL_152_ABERAVON;A;DELETION;152;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT;TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;27;12;7;Sequence;;;54
+Batch_AU247387_DEL_152_CARILLON;A;DELETION;152;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT;TTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTG;27;12;9;Sequence;;;64
+Batch_AU247387_DEL_152_IMAGINE;A;DELETION;152;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT;TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTC;27;12;14;Sequence;;;54
+Batch_AU247387_DEL_152_IRELAND;A;DELETION;152;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT;TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTG;27;12;15;Sequence;;;54
+Batch_AU247387_DEL_152_NEMOF;A;DELETION;152;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT;TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGNNNNNNNNNNNNNNNNNN;27;12;18;Sequence;;;54
+Batch_AU247387_DEL_152_NEMOH;A;DELETION;152;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT;TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTC;27;12;19;Sequence;;;54
+Batch_AU247387_DEL_152_POLAND;A;DELETION;152;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT;TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;27;12;20;Sequence;;;54
+Batch_AU247387_DEL_152_SPAIN;A;DELETION;152;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT;TTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTG;27;12;21;Sequence;;;64
+Batch_AU247387_DEL_152_TRANSATE;A;DELETION;152;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGT;TTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTG;27;12;22;Sequence;;;62
+Batch_AU247387_DEL_152_VIGOR;A;DELETION;152;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT;TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTC;27;12;23;Sequence;;;54
+Batch_AU247387_SNP_153_CARILLON;A;SNP;153;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTT;TGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGT;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_153_SPAIN;A;SNP;153;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTT;TGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGT;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_153_TRANSATE;A;SNP;153;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTT;CTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGT;1;12;22;Sequence;;;6
+Batch_AU247387_SNP_154_CARILLON;A;SNP;154;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTC;GGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTT;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_154_SPAIN;A;SNP;154;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTC;GGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTT;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_154_TRANSATE;A;SNP;154;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTG;TTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTT;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_155_CARILLON;A;SNP;155;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCT;GTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTC;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_155_SPAIN;A;SNP;155;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCT;GTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTC;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_155_TRANSATE;A;SNP;155;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGC;TGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTC;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_156_CARILLON;A;SNP;156;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTG;TTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCT;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_156_SPAIN;A;SNP;156;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTG;TTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCT;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_156_TRANSATE;A;SNP;156;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCT;GT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCT;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_157_CARILLON;A;SNP;157;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGG;TACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTT;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_157_SPAIN;A;SNP;157;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGG;TACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTT;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_157_TRANSATE;A;SNP;157;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTT;T-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTT;1;12;22;Sequence;;;6
+Batch_AU247387_SNP_171_CARILLON;A;SNP;171;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTT;GGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAA;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_171_SPAIN;A;SNP;171;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTT;GGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAA;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_171_TRANSATE;A;SNP;171;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTT;AACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAA;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_172_CARILLON;A;SNP;172;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTG;GCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAAC;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_172_SPAIN;A;SNP;172;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTG;GCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAAC;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_172_TRANSATE;A;SNP;172;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTC;ACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAAC;1;12;22;Sequence;;;9
+Batch_AU247387_SNP_173_CARILLON;A;SNP;173;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGG;CATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACT;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_173_SPAIN;A;SNP;173;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGG;CATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACT;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_173_TRANSATE;A;SNP;173;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCA;CATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACT;1;12;22;Sequence;;;9
+Batch_AU247387_SNP_181_10954;A;SNP;181;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TT;AT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACC;1;12;6;Sequence;;;9
+Batch_AU247387_SNP_181_ABERAVON;A;SNP;181;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TT;AT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;7;Sequence;;;9
+Batch_AU247387_SNP_181_CARILLON;A;SNP;181;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTT;AT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACA;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_181_IMAGINE;A;SNP;181;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TT;AT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACC;1;12;14;Sequence;;;9
+Batch_AU247387_SNP_181_IRELAND;A;SNP;181;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TT;TTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACN;1;12;15;Sequence;;;6
+Batch_AU247387_SNP_181_NEMOF;A;SNP;181;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TT;AT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGNNNNNNNNNNNNNNNNNNNNN;1;12;18;Sequence;;;9
+Batch_AU247387_SNP_181_NEMOH;A;SNP;181;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TT;AT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACC;1;12;19;Sequence;;;9
+Batch_AU247387_SNP_181_POLAND;A;SNP;181;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TT;AT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;9
+Batch_AU247387_SNP_181_SPAIN;A;SNP;181;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTT;AT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACA;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_181_TRANSATE;A;SNP;181;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTT;AT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACA;1;12;22;Sequence;;;6
+Batch_AU247387_SNP_181_VIGOR;A;SNP;181;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TT;AT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACC;1;12;23;Sequence;;;9
+Batch_AU247387_SNP_182_10954;A;SNP;182;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTA;T---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCT;1;12;6;Sequence;;;9
+Batch_AU247387_SNP_182_ABERAVON;A;SNP;182;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTA;T---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;7;Sequence;;;9
+Batch_AU247387_SNP_182_CARILLON;A;SNP;182;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTA;T---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACAT;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_182_IMAGINE;A;SNP;182;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTA;T---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCT;1;12;14;Sequence;;;9
+Batch_AU247387_SNP_182_IRELAND;A;SNP;182;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTG;TTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNT;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_182_NEMOF;A;SNP;182;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTA;T---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGNNNNNNNNNNNNNNNNNNNNNN;1;12;18;Sequence;;;9
+Batch_AU247387_SNP_182_NEMOH;A;SNP;182;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTA;T---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCT;1;12;19;Sequence;;;9
+Batch_AU247387_SNP_182_POLAND;A;SNP;182;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTA;T---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;9
+Batch_AU247387_SNP_182_SPAIN;A;SNP;182;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTA;T---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACAT;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_182_TRANSATE;A;SNP;182;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTG;T---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACAT;1;12;22;Sequence;;;9
+Batch_AU247387_SNP_182_VIGOR;A;SNP;182;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTA;T---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCT;1;12;23;Sequence;;;9
+Batch_AU247387_DEL_184_10954;A;DELETION;184;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT;TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT----;93;12;6;Sequence;;;55
+Batch_AU247387_DEL_184_ABERAVON;A;DELETION;184;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT;TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;93;12;7;Sequence;;;55
+Batch_AU247387_DEL_184_CARILLON;A;DELETION;184;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT;TGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGA;93;12;9;Sequence;;;58
+Batch_AU247387_DEL_184_IMAGINE;A;DELETION;184;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT;TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT----;93;12;14;Sequence;;;55
+Batch_AU247387_DEL_184_NEMOF;A;DELETION;184;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT;TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;93;12;18;Sequence;;;55
+Batch_AU247387_DEL_184_NEMOH;A;DELETION;184;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT;TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT----;93;;;Sequence;;;
+Batch_AU247387_DEL_184_POLAND;A;DELETION;184;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT;TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;93;12;20;Sequence;;;55
+Batch_AU247387_DEL_184_SPAIN;A;DELETION;184;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT;TGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGA;93;12;21;Sequence;;;58
+Batch_AU247387_DEL_184_TRANSATE;A;DELETION;184;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT;TGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNN;93;12;22;Sequence;;;63
+Batch_AU247387_DEL_184_VIGOR;A;DELETION;184;NNNTATAGCTCCTAACATTCCTGAAGTGAAGATCACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT;TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT----;93;12;23;Sequence;;;55
+Batch_AU247387_SNP_231_CARILLON;A;SNP;231;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCT;TAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTG;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_231_IRELAND;A;SNP;231;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCT;TATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;6
+Batch_AU247387_SNP_231_SPAIN;A;SNP;231;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCT;TAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_231_TRANSATE;A;SNP;231;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCT;TAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTG;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_249_CARILLON;A;SNP;249;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAA;ATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAA;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_249_IRELAND;A;SNP;249;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAA;GTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;6
+Batch_AU247387_SNP_249_SPAIN;A;SNP;249;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAA;ATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAA;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_249_TRANSATE;A;SNP;249;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAA;ATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAA;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_250_CARILLON;A;SNP;250;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAAC;TGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAAC;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_250_IRELAND;A;SNP;250;NNNTATAGCTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAG;TGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;6
+Batch_AU247387_SNP_250_SPAIN;A;SNP;250;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAAC;TGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAAC;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_250_TRANSATE;A;SNP;250;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAAC;TGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAAC;1;12;22;Sequence;;;9
+Batch_AU247387_SNP_259_CARILLON;A;SNP;259;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCT;TTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG-;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_259_IRELAND;A;SNP;259;CTCCTAACATTCCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCT;TTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;7
+Batch_AU247387_SNP_259_SPAIN;A;SNP;259;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCT;TTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG-;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_259_TRANSATE;A;SNP;259;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCT;TTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNN;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_270_CARILLON;A;SNP;270;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTAT;CTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCC;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_270_IRELAND;A;SNP;270;CCTGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTAT;CACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;9
+Batch_AU247387_SNP_270_SPAIN;A;SNP;270;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTAT;CTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCC;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_270_TRANSATE;A;SNP;270;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTAT;CTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;6
+Batch_AU247387_SNP_272_CARILLON;A;SNP;272;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGC;CAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCAT;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_272_IRELAND;A;SNP;272;TGAAGTGACGATTCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATAC;CAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;9
+Batch_AU247387_SNP_272_SPAIN;A;SNP;272;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGC;CAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCAT;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_272_TRANSATE;A;SNP;272;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGC;CAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_284_10954;A;SNP;284;NNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGC;TGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------;1;12;6;Sequence;;;9
+Batch_AU247387_SNP_284_ABERAVON;A;SNP;284;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGC;TGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;7;Sequence;;;9
+Batch_AU247387_SNP_284_CARILLON;A;SNP;284;NNNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGC;GG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAA;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_284_IMAGINE;A;SNP;284;NNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGC;TGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------;1;12;14;Sequence;;;9
+Batch_AU247387_SNP_284_IRELAND;A;SNP;284;TCCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGC;GG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_284_NEMOF;A;SNP;284;NNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGC;TGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;18;Sequence;;;9
+Batch_AU247387_SNP_284_NEMOH;A;SNP;284;NNNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGC;TGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------;1;12;19;Sequence;;;9
+Batch_AU247387_SNP_284_POLAND;A;SNP;284;CACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGC;TGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;9
+Batch_AU247387_SNP_284_SPAIN;A;SNP;284;NNNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGC;GG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAA;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_284_TRANSATE;A;SNP;284;NNNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGC;GG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;6
+Batch_AU247387_SNP_284_VIGOR;A;SNP;284;CACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGC;TGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------;1;12;23;Sequence;;;9
+Batch_AU247387_SNP_285_10954;A;SNP;285;NNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCA;GGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT-------------;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_285_ABERAVON;A;SNP;285;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCA;GGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;7;Sequence;;;10
+Batch_AU247387_SNP_285_CARILLON;A;SNP;285;NNNNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCC;G---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAAC;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_285_IMAGINE;A;SNP;285;NNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCA;GGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT-------------;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_285_IRELAND;A;SNP;285;CCAGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCT;G---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;6
+Batch_AU247387_SNP_285_NEMOF;A;SNP;285;NNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCA;GGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;18;Sequence;;;10
+Batch_AU247387_SNP_285_NEMOH;A;SNP;285;NNNNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCA;GGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT-------------;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_285_POLAND;A;SNP;285;ACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTAYGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCA;GGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;20;Sequence;;;10
+Batch_AU247387_SNP_285_SPAIN;A;SNP;285;NNNNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCC;G---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAAC;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_285_TRANSATE;A;SNP;285;NNNNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCG;G---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;6
+Batch_AU247387_SNP_285_VIGOR;A;SNP;285;ACGGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCA;GGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT-------------;1;12;23;Sequence;;;10
+Batch_AU247387_DEL_287_10954;A;DELETION;287;NNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATG;CCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;99;12;6;Sequence;;;68
+Batch_AU247387_DEL_287_CARILLON;A;DELETION;287;NNNNNNNNNNNNNNNCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG;CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;99;12;9;Sequence;;;59
+Batch_AU247387_DEL_287_IMAGINE;A;DELETION;287;NNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATG;CCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;99;12;14;Sequence;;;68
+Batch_AU247387_DEL_287_IRELAND;A;DELETION;287;AGAGGACACGATTGTGAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGATGGAGATTGGCCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG;CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;99;12;15;Sequence;;;59
+Batch_AU247387_DEL_287_NEMOF;A;DELETION;287;NNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATG;CCTCT---------CTGCCCTTGGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;99;12;18;Sequence;;;68
+Batch_AU247387_DEL_287_NEMOH;A;DELETION;287;NNNNNNNNNNNNNNTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATG;CCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;99;12;19;Sequence;;;68
+Batch_AU247387_DEL_287_SPAIN;A;DELETION;287;NNNNNNNNNNNNNNTCAACATTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATCGGTCAGGGCCGTGATCTGAAGAAATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG;CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTG;99;12;21;Sequence;;;59
+Batch_AU247387_DEL_287_TRANSATE;A;DELETION;287;NNNNNNNNNNNNNNNNNNNNNNNNNCGCTCGCTGAGATATGAGATCAACAGGGGCTTCTTTACTTTGAAGGAGATYGGCCAGGGTCGCGACCTCAAGAAATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG;TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;99;12;22;Sequence;;;59
+Batch_AU247387_DEL_287_VIGOR;A;DELETION;287;GGAGGACCTGGCTGTCAATGTTGCCCGCTCGCTGAGATATGAGATCAACAGGGGCTTTGCTAGCCTGAGGGCGATTGGTCAAGGCCGTGACCTGAAGAAATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATG;CCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAG;99;12;23;Sequence;;;68
+Batch_AU247387_SNP_386_10954;A;SNP;386;ATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGAT;CTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_386_CARILLON;A;SNP;386;ATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------;CTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_386_CONCERTO;A;SNP;386;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGAT;CTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_386_IMAGINE;A;SNP;386;ATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGAT;CTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_386_IRELAND;A;SNP;386;ATTCCTCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------;CTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;7
+Batch_AU247387_SNP_386_NEMOF;A;SNP;386;ATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGAT;CTCT---------CTGCCCTTGGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;18;Sequence;;;7
+Batch_AU247387_SNP_386_NEMOH;A;SNP;386;ATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGAT;CTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_386_SPAIN;A;SNP;386;ATTCCTCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------;CTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGA;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_386_TRANSATE;A;SNP;386;ATTCCTCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------;CTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_386_VIGOR;A;SNP;386;ATTCCTGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGAT;CTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGA;1;12;23;Sequence;;;7
+Batch_AU247387_DEL_391_10954;A;DELETION;391;TGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT;CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;9;12;6;Sequence;;;56
+Batch_AU247387_DEL_391_CARILLON;A;DELETION;391;TCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCT;CTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;9;12;9;Sequence;;;65
+Batch_AU247387_DEL_391_CONCERTO;A;DELETION;391;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT;CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;9;12;10;Sequence;;;56
+Batch_AU247387_DEL_391_IMAGINE;A;DELETION;391;TGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT;CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;9;12;14;Sequence;;;56
+Batch_AU247387_DEL_391_IRELAND;A;DELETION;391;TCATTGTATGT---------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCT;CTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;9;12;15;Sequence;;;65
+Batch_AU247387_DEL_391_NEMOF;A;DELETION;391;TGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT;CTGCCCTTGGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;9;12;18;Sequence;;;56
+Batch_AU247387_DEL_391_NEMOH;A;DELETION;391;TGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT;CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;9;12;19;Sequence;;;56
+Batch_AU247387_DEL_391_SPAIN;A;DELETION;391;TCATTGTATGTTCTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCT;CTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;9;12;21;Sequence;;;65
+Batch_AU247387_DEL_391_TRANSATE;A;DELETION;391;TCATTGTATGTTGCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCT;CTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;9;12;22;Sequence;;;65
+Batch_AU247387_DEL_391_VIGOR;A;DELETION;391;TGATTGTACGT---------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT;CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;9;12;23;Sequence;;;56
+Batch_AU247387_SNP_403_10954;A;SNP;403;--------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTG;CCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_403_CARILLON;A;SNP;403;CTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTG;TCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_403_CONCERTO;A;SNP;403;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTG;CCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_403_IMAGINE;A;SNP;403;--------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTG;CCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_403_IRELAND;A;SNP;403;--------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTG;TCTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_403_NEMOF;A;SNP;403;--------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTG;CCTTGGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;18;Sequence;;;7
+Batch_AU247387_SNP_403_NEMOH;A;SNP;403;--------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTG;CCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_403_SPAIN;A;SNP;403;CTGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTG;TCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_403_TRANSATE;A;SNP;403;GCTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTG;TCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_403_VIGOR;A;SNP;403;--------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTG;CCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_404_10954;A;SNP;404;-------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGC;CTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_404_CARILLON;A;SNP;404;TGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGT;CTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_404_CONCERTO;A;SNP;404;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGC;CTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_404_IMAGINE;A;SNP;404;-------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGC;CTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_404_IRELAND;A;SNP;404;-------------------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGT;CTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_404_NEMOF;A;SNP;404;-------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGC;CTTGGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;18;Sequence;;;7
+Batch_AU247387_SNP_404_NEMOH;A;SNP;404;-------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGC;CTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_404_SPAIN;A;SNP;404;TGGTTACTCTTCAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGT;CTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_404_TRANSATE;A;SNP;404;CTTGT-CTCTTCAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGT;CTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_404_VIGOR;A;SNP;404;-------------------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGC;CTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_415_10954;A;SNP;415;--------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCT;CTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;6
+Batch_AU247387_SNP_415_CARILLON;A;SNP;415;CAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCT;TTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_415_CONCERTO;A;SNP;415;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCT;CTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;6
+Batch_AU247387_SNP_415_IMAGINE;A;SNP;415;--------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCT;CTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;6
+Batch_AU247387_SNP_415_IRELAND;A;SNP;415;--------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCT;TTGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;7
+Batch_AU247387_SNP_415_NEMOH;A;SNP;415;--------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCT;CTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;6
+Batch_AU247387_SNP_415_SPAIN;A;SNP;415;CAATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCT;TTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_415_TRANSATE;A;SNP;415;CAATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCT;TTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_415_VIGOR;A;SNP;415;--------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCT;CTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_416_10954;A;SNP;416;-------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTG;TGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_416_CARILLON;A;SNP;416;AATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTC;TGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_416_CONCERTO;A;SNP;416;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTG;TGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_416_IMAGINE;A;SNP;416;-------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTG;TGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_416_IRELAND;A;SNP;416;-------------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTC;TGCAACTTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_416_NEMOH;A;SNP;416;-------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTG;TGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_416_SPAIN;A;SNP;416;AATTTGGGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTC;TGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_416_TRANSATE;A;SNP;416;AATTTCAACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTC;TGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_416_VIGOR;A;SNP;416;-------------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTG;TGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_422_10954;A;SNP;422;-------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAA;TTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_422_CARILLON;A;SNP;422;GGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAA;TTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_422_CONCERTO;A;SNP;422;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAA;TTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_422_IMAGINE;A;SNP;422;-------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAA;TTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_422_IRELAND;A;SNP;422;-------TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAA;TTCTTGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;7
+Batch_AU247387_SNP_422_NEMOH;A;SNP;422;-------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAA;TTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_422_SPAIN;A;SNP;422;GGCATGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAA;TTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_422_TRANSATE;A;SNP;422;AACATGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAA;TTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_422_VIGOR;A;SNP;422;-------TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAA;TTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_426_10954;A;SNP;426;---TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTC;TCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_426_CARILLON;A;SNP;426;TGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTC;TGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_426_CONCERTO;A;SNP;426;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTC;TCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_426_IMAGINE;A;SNP;426;---TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTC;TCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_426_IRELAND;A;SNP;426;---TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTC;TGACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_426_NEMOH;A;SNP;426;---TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTC;TCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_426_SPAIN;A;SNP;426;TGCTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTC;TGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_426_TRANSATE;A;SNP;426;TGCTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTC;TGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_426_VIGOR;A;SNP;426;---TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTC;TCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_428_10954;A;SNP;428;-TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCT;ACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_428_CARILLON;A;SNP;428;CTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTT;ACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_428_CONCERTO;A;SNP;428;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCT;ACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_428_IMAGINE;A;SNP;428;-TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCT;ACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_428_IRELAND;A;SNP;428;-TTGTTTATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTT;ACNTTGGCATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;6
+Batch_AU247387_SNP_428_NEMOH;A;SNP;428;-TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCT;ACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_428_SPAIN;A;SNP;428;CTTAAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTT;ACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_428_TRANSATE;A;SNP;428;CTTGAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTT;ACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;6
+Batch_AU247387_SNP_428_VIGOR;A;SNP;428;-TTAAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCT;ACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_431_10954;A;SNP;431;AAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCAC;TTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_431_CARILLON;A;SNP;431;AAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGAC;TTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_431_CONCERTO;A;SNP;431;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCAC;TTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_431_IMAGINE;A;SNP;431;AAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCAC;TTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_431_NEMOH;A;SNP;431;AAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCAC;TTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_431_SPAIN;A;SNP;431;AAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGAC;TTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_431_TRANSATE;A;SNP;431;GAT---------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGAC;TTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;9
+Batch_AU247387_SNP_431_VIGOR;A;SNP;431;AAT---------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCAC;TTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_435_10954;A;SNP;435;--------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTG;TCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_435_CARILLON;A;SNP;435;--------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTG;CATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_435_CONCERTO;A;SNP;435;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTG;TCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_435_IMAGINE;A;SNP;435;--------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTG;TCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_435_IRELAND;A;SNP;435;ATCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTG;CATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;6
+Batch_AU247387_SNP_435_NEMOH;A;SNP;435;--------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTG;TCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_435_SPAIN;A;SNP;435;--------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTG;CATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_435_TRANSATE;A;SNP;435;--------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTG;CATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;6
+Batch_AU247387_SNP_435_VIGOR;A;SNP;435;--------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTG;TCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_436_10954;A;SNP;436;-------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGT;CTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_436_CARILLON;A;SNP;436;-------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGG;ATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_436_CONCERTO;A;SNP;436;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGT;CTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_436_IMAGINE;A;SNP;436;-------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGT;CTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_436_IRELAND;A;SNP;436;TCTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGG;ATATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;7
+Batch_AU247387_SNP_436_NEMOH;A;SNP;436;-------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGT;CTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_436_SPAIN;A;SNP;436;-------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGG;ATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_436_TRANSATE;A;SNP;436;-------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGG;ATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_436_VIGOR;A;SNP;436;-------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGT;CTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_437_10954;A;SNP;437;------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTT;TACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_437_CARILLON;A;SNP;437;------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGC;TATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_437_CONCERTO;A;SNP;437;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTT;TACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_437_IMAGINE;A;SNP;437;------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTT;TACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_437_IRELAND;A;SNP;437;CTCCTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGGC;TATATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;9
+Batch_AU247387_SNP_437_NEMOH;A;SNP;437;------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTT;TACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_437_SPAIN;A;SNP;437;------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGC;TATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_437_TRANSATE;A;SNP;437;------------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGC;TATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;9
+Batch_AU247387_SNP_437_VIGOR;A;SNP;437;------------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTT;TACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_440_10954;A;SNP;440;---------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTA;ATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_440_CARILLON;A;SNP;440;---------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATA;ATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_440_CONCERTO;A;SNP;440;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTA;ATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_440_IMAGINE;A;SNP;440;---------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTA;ATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_440_IRELAND;A;SNP;440;CTCAATTTCAATTTGGCCATGCTTAATGTTGGGTGCTTTCTGTATAGCCTGCTCACCAAGGTGTGATCTCTTCTTTGTATACACAGGTGGTTGCTGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACNTTGGCATA;ATAGGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;15;Sequence;;;10
+Batch_AU247387_SNP_440_NEMOH;A;SNP;440;---------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTA;ATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_440_SPAIN;A;SNP;440;---------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATA;ATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_440_TRANSATE;A;SNP;440;---------------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATA;ATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_440_VIGOR;A;SNP;440;---------------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTA;ATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_449_10954;A;SNP;449;------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAA;GTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_449_CARILLON;A;SNP;449;------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAA;------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_449_CONCERTO;A;SNP;449;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAA;GTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_449_IMAGINE;A;SNP;449;------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAA;GTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_449_NEMOH;A;SNP;449;------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAA;GTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_449_SPAIN;A;SNP;449;------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAA;------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_449_TRANSATE;A;SNP;449;------------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAA;------------------TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;3
+Batch_AU247387_SNP_449_VIGOR;A;SNP;449;------------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAA;GTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_DEL_450_10954;A;DELETION;450;-----------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAAT;CTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;18;12;6;Sequence;;;69
+Batch_AU247387_DEL_450_CARILLON;A;DELETION;450;-----------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT;TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;18;12;9;Sequence;;;60
+Batch_AU247387_DEL_450_CONCERTO;A;DELETION;450;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAAT;CTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;18;12;10;Sequence;;;69
+Batch_AU247387_DEL_450_IMAGINE;A;DELETION;450;-----------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAAT;CTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;18;12;14;Sequence;;;69
+Batch_AU247387_DEL_450_NEMOH;A;DELETION;450;-----------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAAT;CTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;18;12;19;Sequence;;;69
+Batch_AU247387_DEL_450_SPAIN;A;DELETION;450;-----------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT;TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;18;12;21;Sequence;;;60
+Batch_AU247387_DEL_450_TRANSATE;A;DELETION;450;-----------------GTTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK;TATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;18;12;22;Sequence;;;60
+Batch_AU247387_DEL_450_VIGOR;A;DELETION;450;-----------------------------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAAT;CTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;18;12;23;Sequence;;;69
+Batch_AU247387_SNP_468_10954;A;SNP;468;-----------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGC;TGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_468_CARILLON;A;SNP;468;TTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------;TTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_468_CONCERTO;A;SNP;468;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGC;TGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_468_IMAGINE;A;SNP;468;-----------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGC;TGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_468_NEMOH;A;SNP;468;-----------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGC;TGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_468_SPAIN;A;SNP;468;TTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------;TTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_468_TRANSATE;A;SNP;468;TTGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------;ATARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_468_VIGOR;A;SNP;468;-----------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGC;TGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_469_10954;A;SNP;469;----------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCC;GAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_469_CARILLON;A;SNP;469;TGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------T;TAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_469_CONCERTO;A;SNP;469;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCC;GAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_469_IMAGINE;A;SNP;469;----------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCC;GAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_469_NEMOH;A;SNP;469;----------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCC;GAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_469_SPAIN;A;SNP;469;TGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------T;TAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_469_TRANSATE;A;SNP;469;TGGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------T;TARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;9
+Batch_AU247387_SNP_469_VIGOR;A;SNP;469;----------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCC;GAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_470_10954;A;SNP;470;---------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCT;AACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;6
+Batch_AU247387_SNP_470_CARILLON;A;SNP;470;GGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TT;AACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_470_CONCERTO;A;SNP;470;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCT;AACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;6
+Batch_AU247387_SNP_470_IMAGINE;A;SNP;470;---------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCT;AACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;6
+Batch_AU247387_SNP_470_NEMOH;A;SNP;470;---------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCT;AACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;6
+Batch_AU247387_SNP_470_SPAIN;A;SNP;470;GGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TT;AACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_470_TRANSATE;A;SNP;470;GGGTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TA;ARCTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_470_VIGOR;A;SNP;470;---------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCT;AACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_472_10954;A;SNP;472;-------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGA;CTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;9
+Batch_AU247387_SNP_472_CARILLON;A;SNP;472;GTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTA;CTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_472_CONCERTO;A;SNP;472;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGA;CTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;9
+Batch_AU247387_SNP_472_IMAGINE;A;SNP;472;-------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGA;CTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;9
+Batch_AU247387_SNP_472_NEMOH;A;SNP;472;-------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGA;CTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;9
+Batch_AU247387_SNP_472_SPAIN;A;SNP;472;GTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTA;CTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_472_TRANSATE;A;SNP;472;GTGCTTTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATA;CTTGTGCTGCAACACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;5
+Batch_AU247387_SNP_472_VIGOR;A;SNP;472;-------------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGA;CTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;9
+Batch_AU247387_DEL_477_10954;A;DELETION;477;--------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG;CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;8;12;6;Sequence;;;43
+Batch_AU247387_DEL_477_CARILLON;A;DELETION;477;TTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTG;CACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;8;12;9;Sequence;;;66
+Batch_AU247387_DEL_477_CONCERTO;A;DELETION;477;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG;CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;8;12;10;Sequence;;;43
+Batch_AU247387_DEL_477_IMAGINE;A;DELETION;477;--------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG;CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;8;12;14;Sequence;;;43
+Batch_AU247387_DEL_477_NEMOH;A;DELETION;477;--------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG;CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;8;12;19;Sequence;;;43
+Batch_AU247387_DEL_477_SPAIN;A;DELETION;477;TTCTTTAT--CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTG;CACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;8;12;21;Sequence;;;66
+Batch_AU247387_DEL_477_TRANSATE;A;DELETION;477;TTCTTTAT--CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTG;CACTTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;8;12;22;Sequence;;;66
+Batch_AU247387_DEL_477_VIGOR;A;DELETION;477;--------------------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG;CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;8;12;23;Sequence;;;43
+Batch_AU247387_SNP_487_10954;A;SNP;487;----------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CA;ATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;6
+Batch_AU247387_SNP_487_CARILLON;A;SNP;487;CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACA;TTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_487_CONCERTO;A;SNP;487;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CA;ATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;6
+Batch_AU247387_SNP_487_IMAGINE;A;SNP;487;----------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CA;ATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;6
+Batch_AU247387_SNP_487_NEMOH;A;SNP;487;----------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CA;ATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;6
+Batch_AU247387_SNP_487_SPAIN;A;SNP;487;CCTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACA;TTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_487_TRANSATE;A;SNP;487;CCTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACA;TTGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_487_VIGOR;A;SNP;487;----------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CA;ATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_488_10954;A;SNP;488;---------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAG;TGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;9
+Batch_AU247387_SNP_488_CARILLON;A;SNP;488;CTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACAC;TGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_488_CONCERTO;A;SNP;488;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAG;TGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;9
+Batch_AU247387_SNP_488_IMAGINE;A;SNP;488;---------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAG;TGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;9
+Batch_AU247387_SNP_488_NEMOH;A;SNP;488;---------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAG;TGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;9
+Batch_AU247387_SNP_488_SPAIN;A;SNP;488;CTGCTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACAC;TGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_488_TRANSATE;A;SNP;488;CTGCTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACAC;TGAGTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_488_VIGOR;A;SNP;488;---------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAG;TGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;9
+Batch_AU247387_SNP_491_10954;A;SNP;491;------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATG;GCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_491_CARILLON;A;SNP;491;CTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTG;GTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_491_CONCERTO;A;SNP;491;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATG;GCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_491_IMAGINE;A;SNP;491;------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATG;GCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_491_NEMOH;A;SNP;491;------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATG;GCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_491_SPAIN;A;SNP;491;CTCACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTG;GTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_491_TRANSATE;A;SNP;491;CTCACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTG;GTTCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;9
+Batch_AU247387_SNP_491_VIGOR;A;SNP;491;------------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATG;GCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_493_10954;A;SNP;493;----------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTG;AGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_493_CARILLON;A;SNP;493;CACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAG;TCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_493_CONCERTO;A;SNP;493;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTG;AGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_493_IMAGINE;A;SNP;493;----------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTG;AGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_493_NEMOH;A;SNP;493;----------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTG;AGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_493_SPAIN;A;SNP;493;CACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAG;TCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_493_TRANSATE;A;SNP;493;CACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAG;TCATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_493_VIGOR;A;SNP;493;----------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTG;AGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_494_10954;A;SNP;494;---------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGC;GTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;9
+Batch_AU247387_SNP_494_CARILLON;A;SNP;494;ACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGT;CATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_494_CONCERTO;A;SNP;494;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGC;GTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;9
+Batch_AU247387_SNP_494_IMAGINE;A;SNP;494;---------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGC;GTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;9
+Batch_AU247387_SNP_494_NEMOH;A;SNP;494;---------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGC;GTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;9
+Batch_AU247387_SNP_494_SPAIN;A;SNP;494;ACCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGT;CATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_494_TRANSATE;A;SNP;494;ACCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGT;CATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_494_VIGOR;A;SNP;494;---------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGC;GTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;9
+Batch_AU247387_SNP_495_10954;A;SNP;495;--------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCA;TAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;6
+Batch_AU247387_SNP_495_CARILLON;A;SNP;495;CCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTT;ATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_495_CONCERTO;A;SNP;495;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCA;TAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;6
+Batch_AU247387_SNP_495_IMAGINE;A;SNP;495;--------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCA;TAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;6
+Batch_AU247387_SNP_495_NEMOH;A;SNP;495;--------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCA;TAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;6
+Batch_AU247387_SNP_495_SPAIN;A;SNP;495;CCAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTT;ATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_495_TRANSATE;A;SNP;495;CCAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTT;ATAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_495_VIGOR;A;SNP;495;--------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCA;TAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_496_10954;A;SNP;496;-------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAG;AACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_496_CARILLON;A;SNP;496;CAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTC;TAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_496_CONCERTO;A;SNP;496;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAG;AACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_496_IMAGINE;A;SNP;496;-------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAG;AACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_496_NEMOH;A;SNP;496;-------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAG;AACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_496_SPAIN;A;SNP;496;CAACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTC;TAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_496_TRANSATE;A;SNP;496;CAACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTC;TAACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;9
+Batch_AU247387_SNP_496_VIGOR;A;SNP;496;-------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAG;AACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_497_10954;A;SNP;497;------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGT;ACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;9
+Batch_AU247387_SNP_497_CARILLON;A;SNP;497;AACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCA;AACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_497_CONCERTO;A;SNP;497;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGT;ACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;9
+Batch_AU247387_SNP_497_IMAGINE;A;SNP;497;------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGT;ACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;9
+Batch_AU247387_SNP_497_NEMOH;A;SNP;497;------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGT;ACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;9
+Batch_AU247387_SNP_497_SPAIN;A;SNP;497;AACATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCA;AACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_497_TRANSATE;A;SNP;497;AACATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCA;AACCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;10
+Batch_AU247387_SNP_497_VIGOR;A;SNP;497;------------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGT;ACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;9
+Batch_AU247387_SNP_499_10954;A;SNP;499;----------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAA;TGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_499_CARILLON;A;SNP;499;CATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATA;CCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_499_CONCERTO;A;SNP;499;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAA;TGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_499_IMAGINE;A;SNP;499;----------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAA;TGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_499_NEMOH;A;SNP;499;----------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAA;TGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_499_SPAIN;A;SNP;499;CATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATA;CCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_499_TRANSATE;A;SNP;499;CATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATA;CCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;9
+Batch_AU247387_SNP_499_VIGOR;A;SNP;499;----------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAA;TGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_500_10954;A;SNP;500;---------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAAC;GTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_500_CARILLON;A;SNP;500;ATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAA;CACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_500_CONCERTO;A;SNP;500;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAAC;GTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_500_IMAGINE;A;SNP;500;---------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAAC;GTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_500_NEMOH;A;SNP;500;---------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAAC;GTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_500_SPAIN;A;SNP;500;ATGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAA;CACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_500_TRANSATE;A;SNP;500;ATGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAA;CNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_500_VIGOR;A;SNP;500;---------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAAC;GTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_501_10954;A;SNP;501;--------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACT;TACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;6
+Batch_AU247387_SNP_501_CARILLON;A;SNP;501;TGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAAC;ACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_501_CONCERTO;A;SNP;501;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACT;TACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;6
+Batch_AU247387_SNP_501_IMAGINE;A;SNP;501;--------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACT;TACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;6
+Batch_AU247387_SNP_501_NEMOH;A;SNP;501;--------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACT;TACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;6
+Batch_AU247387_SNP_501_SPAIN;A;SNP;501;TGTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAAC;ACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_501_TRANSATE;A;SNP;501;TGTGATCTCTTCTTTGTATGCTCAGGTGGTTGCGGG---------------------------------------------------------------------------------------------------TCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAK------------------TATARCTTGTGCTGCAACACTTGAGTTCATAAC;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;22;Sequence;;;7
+Batch_AU247387_SNP_501_VIGOR;A;SNP;501;--------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACT;TACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_502_10954;A;SNP;502;-------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTG;ACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_502_CARILLON;A;SNP;502;GTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACC;CCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_502_CONCERTO;A;SNP;502;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTG;ACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_502_IMAGINE;A;SNP;502;-------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTG;ACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_502_NEMOH;A;SNP;502;-------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTG;ACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_502_SPAIN;A;SNP;502;GTGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACC;CCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_502_VIGOR;A;SNP;502;-------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTG;ACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_503_10954;A;SNP;503;------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGT;CCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;9
+Batch_AU247387_SNP_503_CARILLON;A;SNP;503;TGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCA;CCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_503_CONCERTO;A;SNP;503;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGT;CCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;9
+Batch_AU247387_SNP_503_IMAGINE;A;SNP;503;------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGT;CCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;9
+Batch_AU247387_SNP_503_NEMOH;A;SNP;503;------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGT;CCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;9
+Batch_AU247387_SNP_503_SPAIN;A;SNP;503;TGATCTGTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCA;CCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_503_VIGOR;A;SNP;503;------------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGT;CCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;9
+Batch_AU247387_DEL_509_10954;A;DELETION;509;------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAG;TTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;6;12;6;Sequence;;;70
+Batch_AU247387_DEL_509_CARILLON;A;DELETION;509;GTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG;TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;6;12;9;Sequence;;;61
+Batch_AU247387_DEL_509_CONCERTO;A;DELETION;509;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAG;TTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;6;12;10;Sequence;;;70
+Batch_AU247387_DEL_509_IMAGINE;A;DELETION;509;------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAG;TTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;6;12;14;Sequence;;;70
+Batch_AU247387_DEL_509_NEMOH;A;DELETION;509;------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAG;TTACCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;6;12;19;Sequence;;;70
+Batch_AU247387_DEL_509_SPAIN;A;DELETION;509;GTTCTTTGTATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG;TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;6;12;21;Sequence;;;61
+Batch_AU247387_DEL_509_VIGOR;A;DELETION;509;------------------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAG;TTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;6;12;23;Sequence;;;70
+Batch_AU247387_SNP_517_10954;A;SNP;517;----------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTT;CCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;9
+Batch_AU247387_SNP_517_CARILLON;A;SNP;517;TATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TT;TCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_517_CONCERTO;A;SNP;517;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTT;CCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;9
+Batch_AU247387_SNP_517_IMAGINE;A;SNP;517;----------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTT;CCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;9
+Batch_AU247387_SNP_517_NEMOH;A;SNP;517;----------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTT;CCCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;9
+Batch_AU247387_SNP_517_SPAIN;A;SNP;517;TATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TT;TCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_517_VIGOR;A;SNP;517;----------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTT;CCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;9
+Batch_AU247387_SNP_518_10954;A;SNP;518;---------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTA;CCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_518_CARILLON;A;SNP;518;ATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTG;CCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_518_CONCERTO;A;SNP;518;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTA;CCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_518_IMAGINE;A;SNP;518;---------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTA;CCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_518_NEMOH;A;SNP;518;---------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTA;CCAT------------------------TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_518_SPAIN;A;SNP;518;ATGCTCAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTG;CCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_518_VIGOR;A;SNP;518;---------TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTA;CCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_DEL_523_10954;A;DELETION;523;----TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT;TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;24;12;6;Sequence;;;57
+Batch_AU247387_DEL_523_CARILLON;A;DELETION;523;CAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCAT;GTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;24;12;9;Sequence;;;67
+Batch_AU247387_DEL_523_CONCERTO;A;DELETION;523;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT;TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;24;12;10;Sequence;;;57
+Batch_AU247387_DEL_523_IMAGINE;A;DELETION;523;----TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT;TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;24;12;14;Sequence;;;57
+Batch_AU247387_DEL_523_NEMOH;A;DELETION;523;----TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT;TCTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;24;12;19;Sequence;;;57
+Batch_AU247387_DEL_523_SPAIN;A;DELETION;523;CAGGTGGTTGCCGG---------------------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCAT;GTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;24;12;21;Sequence;;;67
+Batch_AU247387_DEL_523_VIGOR;A;DELETION;523;----TGGTTGCATGGCTTCGTTCTCTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT;TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;24;12;23;Sequence;;;57
+Batch_AU247387_SNP_547_10954;A;SNP;547;CTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------;CTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_547_CARILLON;A;SNP;547;-----------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCC;TTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_547_CONCERTO;A;SNP;547;NNNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------;CTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_547_IMAGINE;A;SNP;547;CTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------;CTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_547_NEMOH;A;SNP;547;CTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------;CTCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_547_SPAIN;A;SNP;547;-----------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCC;TTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_547_VIGOR;A;SNP;547;CTTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------;CTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_548_10954;A;SNP;548;TTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------T;TCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_548_CARILLON;A;SNP;548;----------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCG;TCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_548_CONCERTO;A;SNP;548;NNNNNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------T;TCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_548_IMAGINE;A;SNP;548;TTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------T;TCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_548_NEMOH;A;SNP;548;TTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------T;TCGCTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_548_SPAIN;A;SNP;548;----------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCG;TCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_548_VIGOR;A;SNP;548;TTTAGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------T;TCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_551_10954;A;SNP;551;AGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTC;CTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;6
+Batch_AU247387_SNP_551_CARILLON;A;SNP;551;-------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTC;TTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_551_CONCERTO;A;SNP;551;NNNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTC;CTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;6
+Batch_AU247387_SNP_551_IMAGINE;A;SNP;551;AGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTC;CTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;6
+Batch_AU247387_SNP_551_NEMOH;A;SNP;551;AGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTC;CTTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;6
+Batch_AU247387_SNP_551_SPAIN;A;SNP;551;-------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTC;TTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_551_VIGOR;A;SNP;551;AGCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTC;CTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_552_10954;A;SNP;552;GCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCG;TTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_552_CARILLON;A;SNP;552;------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCT;TTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_552_CONCERTO;A;SNP;552;NNNNNNNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCG;TTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_552_IMAGINE;A;SNP;552;GCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCG;TTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_552_NEMOH;A;SNP;552;GCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCG;TTTCTTACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_552_SPAIN;A;SNP;552;------------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCT;TTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_552_VIGOR;A;SNP;552;GCCTTCGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCG;TTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_557_10954;A;SNP;557;CGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTC;TACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_557_CARILLON;A;SNP;557;-------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTC;CRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_557_CONCERTO;A;SNP;557;NNNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTC;TACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_557_IMAGINE;A;SNP;557;CGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTC;TACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_557_NEMOH;A;SNP;557;CGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTC;TACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_557_SPAIN;A;SNP;557;-------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTC;CGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_557_VIGOR;A;SNP;557;CGCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTC;TACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_558_10954;A;SNP;558;GCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCT;ACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;10
+Batch_AU247387_SNP_558_CARILLON;A;SNP;558;------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCC;RAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;7
+Batch_AU247387_SNP_558_CONCERTO;A;SNP;558;NNNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCT;ACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_558_IMAGINE;A;SNP;558;GCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCT;ACTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_558_NEMOH;A;SNP;558;GCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCT;ACNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;10
+Batch_AU247387_SNP_558_SPAIN;A;SNP;558;------------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCC;GAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_558_VIGOR;A;SNP;558;GCTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCT;ACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_559_10954;A;SNP;559;CTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTT;CNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;9
+Batch_AU247387_SNP_559_CARILLON;A;SNP;559;-----------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCC;AGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;5
+Batch_AU247387_SNP_559_CONCERTO;A;SNP;559;NNNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTT;CTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;9
+Batch_AU247387_SNP_559_IMAGINE;A;SNP;559;CTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTT;CTTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;9
+Batch_AU247387_SNP_559_NEMOH;A;SNP;559;CTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTT;CNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;9
+Batch_AU247387_SNP_559_SPAIN;A;SNP;559;-----------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCC;AGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_559_VIGOR;A;SNP;559;CTGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTT;CTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;9
+Batch_AU247387_SNP_560_10954;A;SNP;560;TGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTA;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;6;Sequence;;;7
+Batch_AU247387_SNP_560_CARILLON;A;SNP;560;----------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCR;GTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_560_CONCERTO;A;SNP;560;NNNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTA;TTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;7
+Batch_AU247387_SNP_560_IMAGINE;A;SNP;560;TGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTA;TTGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;7
+Batch_AU247387_SNP_560_NEMOH;A;SNP;560;TGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTA;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;19;Sequence;;;7
+Batch_AU247387_SNP_560_SPAIN;A;SNP;560;----------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCG;GTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_560_VIGOR;A;SNP;560;TGTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTA;TTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_561_CARILLON;A;SNP;561;---------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRA;TGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_561_CONCERTO;A;SNP;561;NNNNNNNNCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTAC;TGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_561_IMAGINE;A;SNP;561;GTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTAC;TGCAGTCTTCATGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_561_SPAIN;A;SNP;561;---------------------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGA;TGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_561_VIGOR;A;SNP;561;GTTTGTGGCTTTGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTAC;TGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_572_CARILLON;A;SNP;572;----------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTC;TGGTGCTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_572_CONCERTO;A;SNP;572;TGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTC;TGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;9
+Batch_AU247387_SNP_572_IMAGINE;A;SNP;572;TGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTC;TGGTTCTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;9
+Batch_AU247387_SNP_572_SPAIN;A;SNP;572;----------------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTC;TGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_572_VIGOR;A;SNP;572;TGTTATGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTC;TGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;9
+Batch_AU247387_SNP_577_CARILLON;A;SNP;577;-----------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGT;CTCTACACGGTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_577_CONCERTO;A;SNP;577;TGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGT;CTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_577_IMAGINE;A;SNP;577;TGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGT;CTCTACACTGTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_577_SPAIN;A;SNP;577;-----------------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGT;CTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_577_VIGOR;A;SNP;577;TGTGACCAAGCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGT;CTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_586_CARILLON;A;SNP;586;--------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACAC;GTGCCAGTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;6
+Batch_AU247387_SNP_586_CONCERTO;A;SNP;586;GCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACAC;GTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;10;Sequence;;;10
+Batch_AU247387_SNP_586_IMAGINE;A;SNP;586;GCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACAC;GTGCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;14;Sequence;;;10
+Batch_AU247387_SNP_586_SPAIN;A;SNP;586;--------------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACAC;GTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_586_VIGOR;A;SNP;586;GCACTTGCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACAC;GTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;10
+Batch_AU247387_SNP_592_CARILLON;A;SNP;592;--------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCC;GTTCTGTATGANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;9
+Batch_AU247387_SNP_592_SPAIN;A;SNP;592;--------------------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCC;GTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;9
+Batch_AU247387_SNP_592_VIGOR;A;SNP;592;GCTATACTGTCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCC;GTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_601_CARILLON;A;SNP;601;-----------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCRAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTA;GANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;12;9;Sequence;;;10
+Batch_AU247387_SNP_601_SPAIN;A;SNP;601;-----------------------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTA;GAGAAGTACGACGACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_601_VIGOR;A;SNP;601;TCTATTTGTTCGCAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTA;GAGAAGTACGAGGACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_613_SPAIN;A;SNP;613;-----------------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGA;GACAAGGTTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;7
+Batch_AU247387_SNP_613_VIGOR;A;SNP;613;CAGGTGATTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGA;GACAAGATCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;6
+Batch_AU247387_SNP_620_SPAIN;A;SNP;620;----------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAG;TTGATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;6
+Batch_AU247387_SNP_620_VIGOR;A;SNP;620;TTGCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAG;TCGATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;9
+Batch_AU247387_SNP_622_SPAIN;A;SNP;622;--------------CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGT;GATGCTTTTGGTGAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_622_VIGOR;A;SNP;622;GCAGGTCTGTGGATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGAT;GATGCTTTTGGAGAGAAG;1;12;23;Sequence;;;7
+Batch_AU247387_SNP_634_SPAIN;A;SNP;634;--CCTCTGGGTTCTTTCTGTTCTTGGGAGCTCTTGCAACTTCTTGACATTGGCATATATAGGTAAT------------------TTTAACTTGTGCTGCAACACTTGAGTTCATAACCACCCTAG------TTGTCCATACGAGTTGTGAACTGATGACATCCGTTCTTTTTCCCGAGTGCAGTCTTCGTGGTGCTCTACACGGTGCCAGTTCTGTATGAGAAGTACGACGACAAGGTTGATGCTTTTGG;GAGAAG;1;12;21;Sequence;;;10
+Batch_AU247387_SNP_634_VIGOR;A;SNP;634;ATCCTCT---------CTGCCCTTGGGAGCTGCTGCAATTTCCTCACCTTGTTCTACATAGGTAATGTGCTTCGCTGCTACAGCCTGAACTTG--------CAGATGTGCAGTAACTGTACCTAGCATTGTTTACCCAT------------------------TCTCGCTTTCTTACTTGCAGTCTTCATGGTTCTCTACACTGTGCCGGTTCTGTACGAGAAGTACGAGGACAAGATCGATGCTTTTGG;GAGAAG;1;12;23;Sequence;;;9
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/Wig/chr1.wig	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,9 @@
+fixedStep  chrom=chr1  start=11  step=1
+1.1
+1.2
+fixedStep  chrom=chr1  start=14  step=1
+1.4
+1.5
+variableStep chrom=chr1
+17  1.7
+19  1.9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/realExpBatchLine.csv	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,41 @@
+IndividualNumber;Pos5;Pos3;BatchNumber;Sequence
+1;;;1;
+2;;;1;
+3;;;1;
+4;;;1;
+5;;;1;
+6;;;1;
+7;;;1;
+8;;;1;
+9;;;1;
+10;;;1;
+11;;;1;
+12;;;1;
+13;;;1;
+14;;;1;
+15;;;1;
+16;;;1;
+17;;;1;
+18;;;1;
+19;;;1;
+20;;;1;
+21;;;1;
+22;;;1;
+23;;;1;
+24;;;1;
+25;;;1;
+26;;;1;
+27;;;1;
+28;;;1;
+29;;;1;
+30;;;1;
+31;;;1;
+32;;;1;
+33;;;1;
+34;;;1;
+35;;;1;
+36;;;1;
+37;;;1;
+38;;;1;
+39;;;1;
+40;;;1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/realExpIndividual.csv	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,41 @@
+IndividualNumber;IndividualName;Description;AberrAneuploide;FractionLength;DeletionLineSynthesis;UrlEarImage;TypeLine;ChromNumber;ArmChrom;DeletionBin;ScientificName;local_germplasm_name;submitter_code;local_institute;donor_institute;donor_acc_id
+1;Treesnips_40-4-3;;;;;;;;;;Pinus pinaster;;;;;
+2;Treesnips_40-8-3;;;;;;;;;;Pinus pinaster;;;;;
+3;Treesnips_40-1-2;;;;;;;;;;Pinus pinaster;;;;;
+4;Treesnips_40-14-1;;;;;;;;;;Pinus pinaster;;;;;
+5;Treesnips_40-15-2;;;;;;;;;;Pinus pinaster;;;;;
+6;Treesnips_40-20-2;;;;;;;;;;Pinus pinaster;;;;;
+7;Treesnips_40-25-1;;;;;;;;;;Pinus pinaster;;;;;
+8;Treesnips_41-3-3;;;;;;;;;;Pinus pinaster;;;;;
+9;Treesnips_41-8-1;;;;;;;;;;Pinus pinaster;;;;;
+10;Treesnips_41-1-3;;;;;;;;;;Pinus pinaster;;;;;
+11;Treesnips_41-2-1;;;;;;;;;;Pinus pinaster;;;;;
+12;Treesnips_41-3-2;;;;;;;;;;Pinus pinaster;;;;;
+13;Treesnips_41-6-2;;;;;;;;;;Pinus pinaster;;;;;
+14;Treesnips_41-9-1;;;;;;;;;;Pinus pinaster;;;;;
+15;Treesnips_42-1-3;;;;;;;;;;Pinus pinaster;;;;;
+16;Treesnips_42-8-2;;;;;;;;;;Pinus pinaster;;;;;
+17;Treesnips_42-1-2;;;;;;;;;;Pinus pinaster;;;;;
+18;Treesnips_42-2-1;;;;;;;;;;Pinus pinaster;;;;;
+19;Treesnips_42-2-2;;;;;;;;;;Pinus pinaster;;;;;
+20;Treesnips_42-8-1;;;;;;;;;;Pinus pinaster;;;;;
+21;Treesnips_42-9-2;;;;;;;;;;Pinus pinaster;;;;;
+22;Treesnips_43-4-3;;;;;;;;;;Pinus pinaster;;;;;
+23;Treesnips_43-5-3;;;;;;;;;;Pinus pinaster;;;;;
+24;Treesnips_43-1-1;;;;;;;;;;Pinus pinaster;;;;;
+25;Treesnips_43-2-1;;;;;;;;;;Pinus pinaster;;;;;
+26;Treesnips_43-7-2;;;;;;;;;;Pinus pinaster;;;;;
+27;Treesnips_43-9-3;;;;;;;;;;Pinus pinaster;;;;;
+28;Treesnips_43-10-2;;;;;;;;;;Pinus pinaster;;;;;
+29;Treesnips_44-3-3;;;;;;;;;;Pinus pinaster;;;;;
+30;Treesnips_44-6-2;;;;;;;;;;Pinus pinaster;;;;;
+31;Treesnips_44-3-1;;;;;;;;;;Pinus pinaster;;;;;
+32;Treesnips_44-5-2;;;;;;;;;;Pinus pinaster;;;;;
+33;Treesnips_44-7-1;;;;;;;;;;Pinus pinaster;;;;;
+34;Treesnips_44-10-2;;;;;;;;;;Pinus pinaster;;;;;
+35;Treesnips_45-5-3;;;;;;;;;;Pinus pinaster;;;;;
+36;Treesnips_45-8-3;;;;;;;;;;Pinus pinaster;;;;;
+37;Treesnips_45-1-1;;;;;;;;;;Pinus pinaster;;;;;
+38;Treesnips_45-4-1;;;;;;;;;;Pinus pinaster;;;;;
+39;Treesnips_45-7-1;;;;;;;;;;Pinus pinaster;;;;;
+40;Treesnips_45-9-1;;;;;;;;;;Pinus pinaster;;;;;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/realExpSequences.fsa	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,2 @@
+>PpHDZ31_ref
+GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATTTATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTTAGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCTTGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGCACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCTATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATACCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCTTGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGTCGCAAAAGTA
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/realExpSubSNP.csv	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,799 @@
+SubSNPName;ConfidenceValue;Type;Position;5flank;3flank;Length;BatchNumber;IndividualNumber;PrimerType;PrimerNumber;Forward_or_Reverse;AlleleNumber
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_40-4-3;A;SNP;136;NNNNNNNNNNNNNNNNNNGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;1;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_40-8-3;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;2;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_40-1-2;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;3;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_40-14-1;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;4;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_40-15-2;A;SNP;136;GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;5;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_40-20-2;A;SNP;136;GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;6;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_40-25-1;A;SNP;136;GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;7;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_41-3-3;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;8;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_41-8-1;A;SNP;136;GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;9;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_41-1-3;A;SNP;136;NNNNNNCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;10;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_41-2-1;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;11;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_41-3-2;A;SNP;136;NNNNNNCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;12;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_41-6-2;A;SNP;136;GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;13;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_41-9-1;A;SNP;136;GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;14;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_42-1-3;A;SNP;136;NNNAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;15;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_42-8-2;A;SNP;136;GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;16;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_42-1-2;A;SNP;136;NNNNNCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;17;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_42-2-1;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;18;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_42-2-2;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;19;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_42-8-1;A;SNP;136;NNNNGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;20;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_42-9-2;A;SNP;136;NNNNNCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;21;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_43-4-3;A;SNP;136;NNTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;22;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_43-5-3;A;SNP;136;GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;23;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_43-1-1;A;SNP;136;NNNNGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;24;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_43-2-1;A;SNP;136;NNNNGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;25;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_43-7-2;A;SNP;136;GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;26;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_43-9-3;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;27;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_43-10-2;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;28;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_44-3-3;A;SNP;136;NNNNNNNNNNNNNNNNNNNTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;29;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_44-6-2;A;SNP;136;NNNNNNCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;30;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_44-3-1;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;31;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_44-5-2;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;32;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_44-7-1;A;SNP;136;GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;33;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_44-10-2;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;34;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_45-5-3;A;SNP;136;NNNNNNCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;35;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_45-8-3;A;SNP;136;GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;36;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_45-1-1;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;37;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_45-4-1;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;38;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_45-7-1;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;39;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_136_Treesnips_45-9-1;A;SNP;136;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGAC;GAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAA;1;1;40;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_40-4-3;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;1;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_40-8-3;A;SNP;287;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;2;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_40-1-2;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;3;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_40-14-1;A;SNP;287;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;4;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_40-15-2;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;5;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_40-20-2;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;6;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_40-25-1;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;7;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_41-3-3;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;8;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_41-8-1;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;9;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_41-1-3;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;10;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_41-2-1;A;SNP;287;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;11;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_41-3-2;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;12;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_41-6-2;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;13;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_41-9-1;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;14;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_42-1-3;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;15;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_42-8-2;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;16;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_42-1-2;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;17;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_42-2-1;A;SNP;287;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;18;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_42-2-2;A;SNP;287;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;19;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_42-8-1;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;20;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_42-9-2;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;21;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_43-4-3;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;22;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_43-5-3;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;23;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_43-1-1;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;24;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_43-2-1;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;25;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_43-7-2;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;26;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_43-9-3;A;SNP;287;NNNNNNNNNNNNNNNNNNNNNTATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;27;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_43-10-2;A;SNP;287;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;28;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_44-3-3;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;29;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_44-6-2;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;30;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_44-3-1;A;SNP;287;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;31;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_44-5-2;A;SNP;287;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;32;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_44-7-1;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;33;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_44-10-2;A;SNP;287;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;34;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_45-5-3;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;35;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_45-8-3;A;SNP;287;TCCAAATTATGGGAAACATTATATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;36;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_45-1-1;A;SNP;287;NNNNNNNNNNNNNNNNNNNNNTATTGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;37;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_45-4-1;A;SNP;287;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;38;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_45-7-1;A;SNP;287;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;39;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_287_Treesnips_45-9-1;A;SNP;287;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGCAGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTT;TGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTT;1;1;40;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_40-4-3;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;1;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_40-8-3;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;2;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_40-1-2;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;3;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_40-14-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;4;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_40-15-2;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;5;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_40-20-2;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;6;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_40-25-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;7;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_41-3-3;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;8;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_41-8-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;9;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_41-1-3;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;10;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_41-2-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;11;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_41-3-2;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;12;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_41-6-2;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;13;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_41-9-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;14;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_42-1-3;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;15;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_42-8-2;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;16;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_42-1-2;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;17;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_42-2-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;18;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_42-2-2;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;19;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_42-8-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;20;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_42-9-2;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;21;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_43-4-3;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;22;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_43-5-3;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;23;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_43-1-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;24;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_43-2-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;25;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_43-7-2;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;26;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_43-9-3;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;27;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_43-10-2;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;28;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_44-3-3;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;29;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_44-6-2;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;30;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_44-3-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;31;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_44-5-2;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;32;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_44-7-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;33;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_44-10-2;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;34;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_45-5-3;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;35;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_45-8-3;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;36;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_45-1-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;37;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_45-4-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;38;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_45-7-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;39;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_409_Treesnips_45-9-1;A;SNP;409;GAGCTGCTGTCGATTGGGTCCAGATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTTGCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCCGGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTGCGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGT;TTTTGCTATTCAGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTGCAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGACTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATTCTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGAT;1;1;40;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_40-4-3;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;1;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_40-8-3;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;2;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_40-1-2;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;3;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_40-14-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;4;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_40-15-2;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;5;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_40-20-2;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;6;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_40-25-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;7;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_41-3-3;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;8;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_41-8-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;9;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_41-1-3;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;10;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_41-2-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;11;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_41-3-2;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;12;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_41-6-2;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;13;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_41-9-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;14;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_42-1-3;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;15;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_42-8-2;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;16;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_42-1-2;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;17;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_42-2-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;18;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_42-2-2;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;19;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_42-8-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;20;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_42-9-2;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;21;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_43-4-3;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;22;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_43-5-3;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;23;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_43-1-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;24;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_43-2-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;25;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_43-7-2;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;26;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_43-9-3;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;27;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_43-10-2;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;28;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_44-3-3;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;29;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_44-6-2;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;30;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_44-3-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;31;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_44-5-2;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;32;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_44-7-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;33;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_44-10-2;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;34;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_45-5-3;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;35;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_45-8-3;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;36;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_45-1-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;37;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_45-4-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;38;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_45-7-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;39;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1324_Treesnips_45-9-1;A;SNP;1324;ACATGCTAGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTATTCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCCTGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGA;TGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGG;1;1;40;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_40-4-3;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;1;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_40-8-3;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;2;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_40-1-2;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;3;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_40-14-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;4;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_40-15-2;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;5;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_40-20-2;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;6;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_40-25-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;7;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_41-3-3;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;8;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_41-8-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;9;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_41-1-3;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;10;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_41-2-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;11;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_41-3-2;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;12;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_41-6-2;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;13;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_41-9-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;14;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_42-1-3;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;15;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_42-8-2;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;16;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_42-1-2;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;17;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_42-2-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;18;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_42-2-2;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;19;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_42-8-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;20;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_42-9-2;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;21;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_43-4-3;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGATTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;22;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_43-5-3;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;23;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_43-1-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;24;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_43-2-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;25;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_43-7-2;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;26;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_43-9-3;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;27;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_43-10-2;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;28;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_44-3-3;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;29;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_44-6-2;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;30;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_44-3-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;31;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_44-5-2;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;32;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_44-7-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;33;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_44-10-2;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;34;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_45-5-3;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTTCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;35;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_45-8-3;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;36;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_45-1-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;37;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_45-4-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;38;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_45-7-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;39;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1471_Treesnips_45-9-1;A;SNP;1471;ATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGCAGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCACTGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCACAGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGAT;ATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTC;1;1;40;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_40-4-3;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;1;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_40-8-3;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;2;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_40-1-2;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;3;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_40-14-1;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;4;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_40-15-2;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;5;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_40-20-2;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;6;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_40-25-1;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;7;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_41-3-3;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;8;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_41-8-1;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;9;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_41-1-3;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;10;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_41-2-1;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;11;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_41-3-2;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;12;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_41-6-2;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;13;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_41-9-1;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;14;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_42-1-3;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;15;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_42-8-2;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;16;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_42-1-2;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;17;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_42-2-1;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;18;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_42-2-2;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;19;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_42-8-1;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;20;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_42-9-2;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;21;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_43-4-3;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;22;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_43-5-3;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;23;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_43-1-1;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;24;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_43-2-1;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;25;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_43-7-2;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;26;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_43-9-3;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;27;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_43-10-2;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;28;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_44-3-3;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;29;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_44-6-2;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;30;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_44-3-1;A;SNP;1632;NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;31;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_44-5-2;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;32;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_44-7-1;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;33;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_44-10-2;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;34;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_45-5-3;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;35;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_45-8-3;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;36;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_45-1-1;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;37;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_45-4-1;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;38;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_45-7-1;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;39;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_1632_Treesnips_45-9-1;A;SNP;1632;GGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAGGTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATGATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCT;CAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCC;1;1;40;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_40-4-3;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;1;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_40-8-3;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;2;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_40-1-2;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;3;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_40-14-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;4;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_40-15-2;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;5;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_40-20-2;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;6;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_40-25-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;7;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_41-3-3;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;8;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_41-8-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;9;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_41-1-3;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;10;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_41-2-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;11;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_41-3-2;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;12;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_41-6-2;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;13;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_41-9-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;14;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_42-1-3;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;15;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_42-8-2;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;16;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_42-1-2;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;17;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_42-2-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;18;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_42-2-2;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;19;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_42-8-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;20;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_42-9-2;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;21;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_43-4-3;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;22;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_43-5-3;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;23;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_43-1-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;24;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_43-2-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;25;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_43-7-2;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;26;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_43-9-3;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;27;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_43-10-2;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;28;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_44-3-3;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;29;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_44-6-2;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;30;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_44-3-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;31;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_44-5-2;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;32;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_44-7-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;33;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_44-10-2;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;34;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_45-5-3;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTTCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;35;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_45-8-3;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;36;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_45-1-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;37;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_45-4-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;38;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_45-7-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;39;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_INS_1754_Treesnips_45-9-1;A;INSERTION;1754;TGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGATTTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTATCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAACTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAGTTATTTAAAAAAAA;TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGGGAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGG;1;1;40;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_40-4-3;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;1;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_40-8-3;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;2;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_40-1-2;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;3;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_40-14-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;4;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_40-15-2;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;5;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_40-20-2;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;6;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_40-25-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;7;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_41-3-3;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;8;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_41-8-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;9;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_41-1-3;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;10;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_41-2-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;11;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_41-3-2;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;12;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_41-6-2;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;13;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_41-9-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;14;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_42-1-3;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;15;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_42-8-2;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;16;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_42-1-2;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;17;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_42-2-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;18;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_42-2-2;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;19;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_42-8-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;20;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_42-9-2;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;21;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_43-4-3;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATCTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;22;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_43-5-3;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;23;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_43-1-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;24;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_43-2-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;25;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_43-7-2;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;26;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_43-9-3;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;27;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_43-10-2;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;28;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_44-3-3;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;29;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_44-6-2;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;30;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_44-3-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;31;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_44-5-2;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;32;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_44-7-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;33;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_44-10-2;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;34;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_45-5-3;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;35;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_45-8-3;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;36;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_45-1-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;37;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_45-4-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;38;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_45-7-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;39;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2086_Treesnips_45-9-1;A;SNP;2086;TTTGATAGAGGAACTGATGACGTGTAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGC;TGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTC;1;1;40;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_40-4-3;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;1;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_40-8-3;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;2;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_40-1-2;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;3;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_40-14-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;4;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_40-15-2;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;5;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_40-20-2;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;6;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_40-25-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;7;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_41-3-3;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;8;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_41-8-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;9;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_41-1-3;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;10;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_41-2-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;11;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_41-3-2;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;12;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_41-6-2;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;13;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_41-9-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;14;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_42-1-3;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;15;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_42-8-2;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;16;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_42-1-2;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;17;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_42-2-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;18;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_42-2-2;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;19;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_42-8-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;20;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_42-9-2;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;21;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_43-4-3;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;22;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_43-5-3;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;23;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_43-1-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;24;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_43-2-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;25;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_43-7-2;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;26;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_43-9-3;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;27;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_43-10-2;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;28;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_44-3-3;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;29;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_44-6-2;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;30;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_44-3-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;31;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_44-5-2;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;32;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_44-7-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;33;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_44-10-2;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;34;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_45-5-3;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;35;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_45-8-3;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;36;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_45-1-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;37;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_45-4-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;38;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_45-7-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;39;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2137_Treesnips_45-9-1;A;SNP;2137;CATTACTTGTACGTTTCTTGCGCGAGCACCGATCAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTTATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATAT;TTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGT;1;1;40;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_40-4-3;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;1;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_40-8-3;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;2;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_40-1-2;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;3;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_40-14-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;4;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_40-15-2;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;5;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_40-20-2;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;6;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_40-25-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;7;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_41-3-3;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;8;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_41-8-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;9;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_41-1-3;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;10;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_41-2-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;11;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_41-3-2;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;12;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_41-6-2;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;13;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_41-9-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;14;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_42-1-3;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;15;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_42-8-2;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;16;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_42-1-2;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;17;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_42-2-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;18;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_42-2-2;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;19;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_42-8-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;20;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_42-9-2;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;21;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_43-4-3;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATCTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;22;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_43-5-3;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;23;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_43-1-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;24;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_43-2-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;25;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_43-7-2;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;26;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_43-9-3;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;27;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_43-10-2;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;28;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_44-3-3;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;29;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_44-6-2;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;30;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_44-3-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;31;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_44-5-2;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;32;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_44-7-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;33;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_44-10-2;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;34;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_45-5-3;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;35;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_45-8-3;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;36;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_45-1-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;37;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_45-4-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;38;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_45-7-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;39;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2267_Treesnips_45-9-1;A;SNP;2267;GAGTCAAGTAATCCTTCCCTTGGCACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTTTGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTATATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATGTAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTAC;CAGGAGGAAGCTGTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTATACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAACAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGAACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCT;1;1;40;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_40-4-3;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;1;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_40-8-3;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;2;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_40-1-2;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;3;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_40-14-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;4;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_40-15-2;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;5;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_40-20-2;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;6;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_40-25-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;7;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_41-3-3;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;8;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_41-8-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;9;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_41-1-3;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;10;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_41-2-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;11;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_41-3-2;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;12;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_41-6-2;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;13;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_41-9-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;14;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_42-1-3;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;15;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_42-8-2;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;16;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_42-1-2;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;17;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_42-2-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;18;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_42-2-2;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;19;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_42-8-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;20;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_42-9-2;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;21;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_43-4-3;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;22;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_43-5-3;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;23;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_43-1-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;24;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_43-2-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;25;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_43-7-2;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;26;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_43-9-3;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;27;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_43-10-2;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;28;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_44-3-3;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGTTTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;29;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_44-6-2;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;30;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_44-3-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGTTTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;31;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_44-5-2;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;32;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_44-7-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;33;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_44-10-2;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;34;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_45-5-3;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;35;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_45-8-3;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;36;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_45-1-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;37;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_45-4-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;38;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_45-7-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;39;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2716_Treesnips_45-9-1;A;SNP;2716;TTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCG;ACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTC;1;1;40;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_40-4-3;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;1;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_40-8-3;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;2;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_40-1-2;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;3;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_40-14-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;4;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_40-15-2;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;5;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_40-20-2;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;6;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_40-25-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;7;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_41-3-3;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;8;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_41-8-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;9;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_41-1-3;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;10;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_41-2-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;11;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_41-3-2;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;12;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_41-6-2;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;13;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_41-9-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;14;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_42-1-3;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;15;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_42-8-2;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;16;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_42-1-2;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;17;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_42-2-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;18;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_42-2-2;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;19;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_42-8-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;20;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_42-9-2;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;21;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_43-4-3;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;22;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_43-5-3;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;23;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_43-1-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;24;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_43-2-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;25;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_43-7-2;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;26;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_43-9-3;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;27;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_43-10-2;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;28;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_44-3-3;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGTTTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;29;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_44-6-2;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;30;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_44-3-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGTTTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;31;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_44-5-2;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;32;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_44-7-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;33;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_44-10-2;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;34;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_45-5-3;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;35;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_45-8-3;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;36;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_45-1-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;37;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_45-4-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACA;TGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;38;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_45-7-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;39;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2720_Treesnips_45-9-1;A;SNP;2720;GCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACA;TGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGG;1;1;40;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_40-4-3;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;1;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_40-8-3;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;2;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_40-1-2;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;3;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_40-14-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;4;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_40-15-2;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;5;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_40-20-2;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;6;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_40-25-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;7;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_41-3-3;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;8;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_41-8-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;9;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_41-1-3;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;10;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_41-2-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;11;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_41-3-2;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;12;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_41-6-2;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;13;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_41-9-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;14;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_42-1-3;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;15;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_42-8-2;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;16;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_42-1-2;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;17;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_42-2-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;18;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_42-2-2;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;19;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_42-8-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;20;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_42-9-2;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;21;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_43-4-3;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;22;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_43-5-3;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;23;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_43-1-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;24;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_43-2-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;25;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_43-7-2;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;26;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_43-9-3;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;27;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_43-10-2;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;28;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_44-3-3;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGTTTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;29;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_44-6-2;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;30;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_44-3-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGTTTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;31;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_44-5-2;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;32;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_44-7-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;33;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_44-10-2;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;34;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_45-5-3;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;35;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_45-8-3;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;36;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_45-1-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;37;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_45-4-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;38;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_45-7-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;39;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2740_Treesnips_45-9-1;A;SNP;2740;TGCTGATGATGCTCCTTTGCTTCCTTCTGGGTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCT;GAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTC;1;1;40;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_40-4-3;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;1;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_40-8-3;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;2;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_40-1-2;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;3;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_40-14-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;4;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_40-15-2;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;5;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_40-20-2;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;6;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_40-25-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;7;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_41-3-3;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;8;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_41-8-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;9;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_41-1-3;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;10;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_41-2-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;11;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_41-3-2;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;12;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_41-6-2;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;13;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_41-9-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;14;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_42-1-3;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;15;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_42-8-2;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;16;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_42-1-2;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;17;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_42-2-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;18;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_42-2-2;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;19;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_42-8-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;20;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_42-9-2;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;21;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_43-4-3;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;22;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_43-5-3;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;23;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_43-1-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;24;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_43-2-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;25;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_43-7-2;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;26;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_43-9-3;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;27;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_43-10-2;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;28;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_44-3-3;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;29;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_44-6-2;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;30;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_44-3-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;31;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_44-5-2;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;32;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_44-7-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;33;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_44-10-2;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;34;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_45-5-3;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;35;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_45-8-3;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;36;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_45-1-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;37;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_45-4-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;38;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_45-7-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;39;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2775_Treesnips_45-9-1;A;SNP;2775;GGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTG;TTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATA;1;1;40;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_40-4-3;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;1;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_40-8-3;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;2;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_40-1-2;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;3;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_40-14-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;4;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_40-15-2;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;5;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_40-20-2;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;6;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_40-25-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;7;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_41-3-3;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;8;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_41-8-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;9;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_41-1-3;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;10;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_41-2-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;11;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_41-3-2;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;12;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_41-6-2;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;13;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_41-9-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;14;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_42-1-3;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;15;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_42-8-2;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;16;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_42-1-2;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;17;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_42-2-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;18;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_42-2-2;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;19;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_42-8-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;20;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_42-9-2;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;21;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_43-4-3;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;22;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_43-5-3;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;23;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_43-1-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;24;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_43-2-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;25;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_43-7-2;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;26;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_43-9-3;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;27;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_43-10-2;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;28;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_44-3-3;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGTTTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;29;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_44-6-2;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;30;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_44-3-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGTTTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;31;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_44-5-2;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;32;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_44-7-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;33;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_44-10-2;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;34;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_45-5-3;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;35;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_45-8-3;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;36;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_45-1-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;37;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_45-4-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;38;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_45-7-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;39;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_2812_Treesnips_45-9-1;A;SNP;2812;TCTGCAAACGTTTATGGCATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGCTGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGATCTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAACTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGAC;ATTGCATTCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTC;1;1;40;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_40-4-3;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;1;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_40-8-3;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;2;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_40-1-2;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;3;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_40-14-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;4;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_40-15-2;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;5;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_40-20-2;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;6;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_40-25-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCNNNNNNNNNNNNNNNN;1;1;7;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_41-3-3;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;8;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_41-8-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;9;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_41-1-3;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;10;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_41-2-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;11;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_41-3-2;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;12;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_41-6-2;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;13;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_41-9-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;14;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_42-1-3;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;15;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_42-8-2;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;16;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_42-1-2;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;17;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_42-2-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;18;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_42-2-2;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;19;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_42-8-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;20;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_42-9-2;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;21;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_43-4-3;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;22;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_43-5-3;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;23;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_43-1-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;24;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_43-2-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;25;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_43-7-2;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;26;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_43-9-3;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;27;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_43-10-2;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;28;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_44-3-3;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;29;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_44-6-2;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;30;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_44-3-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;31;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_44-5-2;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;32;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_44-7-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;33;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_44-10-2;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;34;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_45-5-3;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;35;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_45-8-3;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;36;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_45-1-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;1;37;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_45-4-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;38;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_45-7-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;39;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3124_Treesnips_45-9-1;A;SNP;3124;AATATGTGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACT;CACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTG;1;1;40;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_40-4-3;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;1;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_40-8-3;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;2;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_40-1-2;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;3;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_40-14-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;4;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_40-15-2;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;5;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_40-20-2;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;6;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_40-25-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCNNNNNNNNNNNNNNNNNNNNNNNNN;1;1;7;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_41-3-3;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;8;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_41-8-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;9;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_41-1-3;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;10;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_41-2-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;11;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_41-3-2;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;12;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_41-6-2;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;13;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_41-9-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;14;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_42-1-3;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;15;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_42-8-2;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;16;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_42-1-2;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;17;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_42-2-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;18;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_42-2-2;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;19;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_42-8-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;20;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_42-9-2;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;21;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_43-4-3;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;22;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_43-5-3;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;23;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_43-1-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;24;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_43-2-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;25;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_43-7-2;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;26;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_43-9-3;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;27;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_43-10-2;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;28;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_44-3-3;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;29;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_44-6-2;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;30;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_44-3-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;31;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_44-5-2;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;32;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_44-7-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCNN;1;1;33;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_44-10-2;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;34;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_45-5-3;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;35;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_45-8-3;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;36;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_45-1-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;1;37;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_45-4-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGG;GTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;38;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_45-7-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;39;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3133_Treesnips_45-9-1;A;SNP;3133;GTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGG;GTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTG;1;1;40;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_40-4-3;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;1;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_40-8-3;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;2;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_40-1-2;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;3;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_40-14-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;4;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_40-15-2;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;5;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_40-20-2;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;6;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_40-25-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;1;7;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_41-3-3;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;8;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_41-8-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;9;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_41-1-3;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;10;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_41-2-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;11;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_41-3-2;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;12;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_41-6-2;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;13;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_41-9-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;14;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_42-1-3;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;15;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_42-8-2;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;16;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_42-1-2;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;17;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_42-2-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;18;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_42-2-2;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;19;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_42-8-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;20;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_42-9-2;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;21;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_43-4-3;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;22;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_43-5-3;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;23;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_43-1-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;24;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_43-2-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;25;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_43-7-2;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;26;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_43-9-3;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;27;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_43-10-2;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;28;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_44-3-3;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;29;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_44-6-2;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;30;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_44-3-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;31;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_44-5-2;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;32;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_44-7-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCNNNNNNNN;1;1;33;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_44-10-2;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;34;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_45-5-3;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;35;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_45-8-3;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;36;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_45-1-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;1;37;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_45-4-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;38;Sequence;;;2
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_45-7-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;39;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_SNP_3139_Treesnips_45-9-1;A;SNP;3139;TTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGAATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGA;CTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACG;1;1;40;Sequence;;;4
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_40-4-3;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;1;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_40-8-3;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAANNNNNNNNNNNNNN;1;1;2;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_40-1-2;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;3;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_40-14-1;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAANNNNNNNNNNNNNN;1;1;4;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_40-15-2;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGTCGCAAANNNN;1;1;5;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_40-20-2;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;6;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_40-25-1;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;1;7;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_41-3-3;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;8;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_41-8-1;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAANNNNNNNNNNNNNN;1;1;9;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_41-1-3;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAANNNNNNNNNNNNNN;1;1;10;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_41-2-1;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;11;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_41-3-2;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;12;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_41-6-2;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGTCGCAAAAGTA;1;1;13;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_41-9-1;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;14;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_42-1-3;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;15;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_42-8-2;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;16;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_42-1-2;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;17;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_42-2-1;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;18;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_42-2-2;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGTCGCAAAAGTA;1;1;19;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_42-8-1;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;20;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_42-9-2;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;21;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_43-4-3;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;22;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_43-5-3;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;23;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_43-1-1;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;24;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_43-2-1;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;25;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_43-7-2;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;26;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_43-9-3;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;27;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_43-10-2;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;28;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_44-3-3;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;29;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_44-6-2;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;30;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_44-3-1;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGTCGCAAAAGTN;1;1;31;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_44-5-2;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;32;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_44-7-1;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;1;33;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_44-10-2;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGTNNNNNNNNNN;1;1;34;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_45-5-3;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAANNNNNNNNNNNNNN;1;1;35;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_45-8-3;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;36;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_45-4-1;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;1;38;Sequence;;;5
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_45-7-1;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGTCGCAAAAGTA;1;1;39;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_DEL_3245_Treesnips_45-9-1;A;DELETION;3245;CCGTTGGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA;TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;1;40;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_40-4-3;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;1;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_40-8-3;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAANNNNNNNNNNNNNN;1;1;2;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_40-1-2;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;3;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_40-14-1;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAANNNNNNNNNNNNNN;1;1;4;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_40-15-2;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGTCGCAAANNNN;1;1;5;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_40-20-2;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;6;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_40-25-1;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;1;7;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_41-3-3;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;8;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_41-8-1;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAANNNNNNNNNNNNNN;1;1;9;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_41-1-3;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAANNNNNNNNNNNNNN;1;1;10;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_41-2-1;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;11;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_41-3-2;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;12;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_41-6-2;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGTCGCAAAAGTA;1;1;13;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_41-9-1;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;14;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_42-1-3;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;15;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_42-8-2;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;16;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_42-1-2;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;17;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_42-2-1;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;18;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_42-2-2;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGTCGCAAAAGTA;1;1;19;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_42-8-1;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;20;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_42-9-2;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;21;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_43-4-3;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;22;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_43-5-3;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;23;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_43-1-1;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;24;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_43-2-1;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;25;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_43-7-2;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;26;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_43-9-3;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;27;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_43-10-2;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;28;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_44-3-3;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;29;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_44-6-2;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;30;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_44-3-1;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGTCGCAAAAGTN;1;1;31;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_44-5-2;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGNNNNNNNNNNN;1;1;32;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_44-7-1;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;1;33;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_44-10-2;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGTNNNNNNNNNN;1;1;34;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_45-5-3;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAANNNNNNNNNNNNNN;1;1;35;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_45-8-3;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGNNNNNNNNNNNN;1;1;36;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_45-4-1;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;1;38;Sequence;;;3
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_45-7-1;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTGGACAAAATTCTGGATGAAAATGGTCGCAAAAGTA;1;1;39;Sequence;;;1
+INRA_Pinus_pinaster_HDZ31-1_SNP_3291_Treesnips_45-9-1;A;SNP;3291;AGGCTCTTATGTTTTGCCATTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACAGACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGAAACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACATACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCT;GTTGTGAAGTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCAAATCAAGCAGGGTTGGACATGCTGGAAACGACANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN;1;1;40;Sequence;;;1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/real_multifasta_input.fasta	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,2419 @@
+>PpHDZ31_ref
+GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGTCGCAAAAGTA
+>Treesnips_40-4-3
+NNNNNNNNNNNNNNNNNNGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGNNNNNNNNNNN
+>Treesnips_40-8-3
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAANNNNNNNNNNNNNN
+>Treesnips_40-1-2
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGNNNNNNNNNNN
+>Treesnips_40-14-1
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAANNNNNNNNNNNNNN
+>Treesnips_40-15-2
+GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGTCGCAAANNNN
+>Treesnips_40-20-2
+GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGNNNNNNNNNNN
+>Treesnips_40-25-1
+GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+>Treesnips_41-3-3
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGNNNNNNNNNNNN
+>Treesnips_41-8-1
+GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAANNNNNNNNNNNNNN
+>Treesnips_41-1-3
+NNNNNNCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAANNNNNNNNNNNNNN
+>Treesnips_41-2-1
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGNNNNNNNNNNNN
+>Treesnips_41-3-2
+NNNNNNCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGNNNNNNNNNNN
+>Treesnips_41-6-2
+GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGTCGCAAAAGTA
+>Treesnips_41-9-1
+GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGNNNNNNNNNNN
+>Treesnips_42-1-3
+NNNAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGNNNNNNNNNNNN
+>Treesnips_42-8-2
+GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGNNNNNNNNNNN
+>Treesnips_42-1-2
+NNNNNCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGNNNNNNNNNNNN
+>Treesnips_42-2-1
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGNNNNNNNNNNNN
+>Treesnips_42-2-2
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGTCGCAAAAGTA
+>Treesnips_42-8-1
+NNNNGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGNNNNNNNNNNN
+>Treesnips_42-9-2
+NNNNNCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGNNNNNNNNNNN
+>Treesnips_43-4-3
+NNTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGATTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATCTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGNNNNNNNNNNNN
+>Treesnips_43-5-3
+GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGNNNNNNNNNNN
+>Treesnips_43-1-1
+NNNNGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGNNNNNNNNNNN
+>Treesnips_43-2-1
+NNNNGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGNNNNNNNNNNNN
+>Treesnips_43-7-2
+GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGNNNNNNNNNNNN
+>Treesnips_43-9-3
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGNNNNNNNNNNN
+>Treesnips_43-10-2
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGNNNNNNNNNNN
+>Treesnips_44-3-3
+NNNNNNNNNNNNNNNNNNNTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGTTTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGNNNNNNNNNNNN
+>Treesnips_44-6-2
+NNNNNNCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGNNNNNNNNNNN
+>Treesnips_44-3-1
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGTTTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGTCGCAAAAGTN
+>Treesnips_44-5-2
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGNNNNNNNNNNN
+>Treesnips_44-7-1
+GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACCATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+>Treesnips_44-10-2
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGTNNNNNNNNNN
+>Treesnips_45-5-3
+NNNNNNCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTTCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAANNNNNNNNNNNNNN
+>Treesnips_45-8-3
+GCTAGCCCCGCTGGGTACGTGGCATTGTTTTAGCTTTCCAAATTATGGGAAACATTATAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGNNNNNNNNNNNN
+>Treesnips_45-1-1
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTAT
+TGTTTTTGTAGCTAGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+>Treesnips_45-4-1
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACGGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTGTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTTTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATGATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAAATGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCTTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACACAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGGACATTGGACTTGGCTTCTGCTCTTGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTACACATAGGGGTGGATCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAA-TTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTAGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+>Treesnips_45-7-1
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACATTGGTTGCATTGCAAGATATATCTTTG
+GACAAAATTCTGGATGAAAATGGTCGCAAAAGTA
+>Treesnips_45-9-1
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNGGTATAAAAGGACTGTATTTTTCTATTCCAGACTCCTGTCTATAGC
+AGAGGAGACCTTGACAGAGTTCCTTTCAAAGGCTAAAGGAGCTGCTGTCGATTGGGTCCA
+GATGCCTGGGATGAAGGTTTGTGTTCCCAAGATCCTCTTCTAAAAATAGATCATGTGCTT
+GCTTGAATTATTAATCTATGGTGTATTAAGATGCCTGAGCGTGTTTTTGCAGCCTGGTCC
+GGATTCGATTGGTATTGTAGCTATTTCGAATACTTGTAATGGAGTAGCTGCACGTGCTTG
+CGGTCTTGTAGGATTAGATCCTACAAAGGTAATGAGTGCAATTATTGTGTTTTGCTATTC
+AGTAATGATTATTTTGTTTCCGAAGGAAGGGATGCTCATGCAAGTTTTCTATTCAGGTTG
+CAGAGATTCTTAAAGATCGCCCATCTTGGCTTCGTGATTGTCGTTGCCTTGATGTTTTGA
+CTGCGTTTCCTACTGGAAATGGTGGAACAATCGAGCTTTTATACATGCAGGTTTGCTATT
+CTCTCTGAAATTGATTCTGATAAGTTGCCATAAGAGGTCAAAAATTAGCAAAATCAGATT
+TATCTTTTTTTTTTTTTTTTTTGTATGATGTGGACTGCAGACATATGCCGCCACTACTTT
+AGCTTCTGCTAGAGACTTCTGGACTCTGAGATACACAACAGTGTTGGAAGATGGCAGTCT
+TGTGGTATGTGATAACTGAACAATGACACATGCTTTCATTAATCCCTTTATTTTGTGAGC
+ACAACTGGATTTTCTTCCTTGTTTTTGCAGTAGTGGGGTTTTGCTAATTATAGCTTATCT
+ATGATGTTCTGTAAGGTTTGTGAAAGGTCCTTGAGTGGTACTCAGGGTGGTCCAAGCATA
+CCGCCAGTGCAGCATTTTGTGAGAGCAGAAATGCTTCCCAGTGGATATTTGATACAACCT
+TGTGAAGGTGGTGGTTCCATAATCCGTATTGTTGATCACATGGATCTAGAGGTACATGCT
+AGTTGTTGATGGCTAGAAGCTGCAATGTAGTTTATACAATTAAATTCCCAGAGTAGCTAT
+TCTAAGATGGGCTGATCTTTTCATTGATTTGATTATTGCTATTCAGCCATGGAGTGTGCC
+TGAGGTTTTACGACCACTATATGAATCGTCCACTGTACTTGCCCAGAAAATGACAATTGC
+AGTAAGGACACCTTTAATGCCATTGTGCAGATTGTATTACAATTCTTCTAAGATTTCCAC
+TGACTGAAATCTTCATGATCAGGCATTGCGTCGATTACGCCAAATTGCACAGGAAGCCAC
+AGGTGAAGTAGTTTTTGGTTGGGGAAGACAGCCAGCTGTTCTGCGAACATTTAGCCAGAG
+GTTAAGCAGGTAATGTGACTACTGCAGGATTATATCTTCTCCCATATTTGAACCATGATG
+ATTGTGTCTAATAGACCTGTTTTTAAAAATGCAGGGGTTTCAACGAGGCCGTGAATGGAT
+TTACAGATGATGGGTGGTCATTGATGGGTAGTGATGGAGTGGAGGATGTCACTATTGCTA
+TCAATTCATCTCCAAACAAACATTTTGCCTACCAAGTTAATGCTTCTAATGGGCTAACAA
+CTCTTGGTGGTGGCATCCTTTGTGCAAAGGCATCCATGCTCTTACAGGTTCTCAAGCTAG
+TTATTTAAAAAAAA-TGTAAACAACATAATTTTATGCAATAATTTTAGAATGCATCTTGG
+GAGTCTGGAATACTTGTTTCTGAGTTCCGAGTCTTGTTTGATAGAGGAACTGATGACGTG
+TAATGTAAATACAGAATGTGCCTCCAGCATTACTTGTACGTTTCTTGCGCGAGCACCGAT
+CAGAGTGGGCAGATTCCAACATTGATGCCTATTCTGCAGCTGCTTTAAAATCAAGTCCTT
+ATAGTGTTCCAGGATCAAGAGCAGGGGGCTTTTCAGGGAGTCAAGTAATCCTTCCCTTGG
+CACATACTGTGGAACATGAGGAGGTGGGGAGTGGTTACTGAGATGCCTGGTTTTGTATTT
+TGTTGCCTTCAAACTGCATTGGGATGCTTTTCAATATTTTTCCTGGTGTTTTTGGTTCTA
+TATTTTGTTCAAATGTTTTCCTCTCTGTTGGTTTATACAATTTTGAAGCTGAAATAAATG
+TAACTGCAGTTCTTAGAGGTCATTAAGCTGGAAGGTCATGGCCTTACTCAGGAGGAAGCT
+GTCCTGTCCAGAGATATGTTTCTCTTACAGGTATCTTGTATTGCCAAAGTTACTTTCTAT
+ACCAATGATTGTGCTAGTGTATACTTTTTAAGGTTTATTGTTTAATGTTAACATTATCAA
+CAACTTTGATGGGCAGCTTTGCAGTGGAATTGATGAACATGCAGCTGGAGCATGTGCTGA
+ACTTGTTTTTGCACCAATTGATGAATCCTTTGCTGATGATGCTCCTTTGCTTCCTTCTGG
+GTTCAGGGTTATTCCTTTGGAATCAAGAACAGTTGAGTATATTCTGCAAACGTTTATGGC
+ATCTAGAATTGATTTTTCATCTATGCTAAAATATCATTCAAAACAACTGGCATCTGGTGC
+TGCATTACGTATTTATTTCTTGGAGCTTGAAGAAATGAATATATATGATGCAGGATGGAT
+CTGGGGGTCCCAACCGCACACTGGACTTGGCTTCTGCTCTGGAGGTTGGATCAACTGGAA
+CTAGAACGTCTGGTGATTCTGGCACCAACTCGAATCTGAGATCTGTGTTGACTATTGCAT
+TCCAGTTTACTTATGAGAGCCACTCGCGAGAAAATGTGGCAGCTATGGCTCGTCAATATG
+TGCGTAGTGTTGTAGCATCTGTCCAGAGGGTTGCCATGGCATTAGCTCCTTCTCGACTGA
+ATTCACATGTTGGCCCAAGGCCACCTCCTGGGACTCCAGAAGCACTTACTCTTGCCCGTT
+GGATTTGTCAGAGCTACAGGTAAATAGGAGGCTTGCATTCAAGGCTCTTATGTTTTGCCA
+TTCTTTATTTCTTAATTTTGAAATATTTTGTACTGAGAGCTGAATGCAAGTTTTTGGACA
+GACTCCACATAGGTGTGGACCTGTTTCGAGCTGATTGTGAAGCCAGTGAGTCTGTACTGA
+AACTACTTTGGCACCATTCAGATGCAATCATGTGCTGTTCTGTGAAGGTATCTATTACAT
+ACAAAATTCTGAAGAAGTATAGCACTTTGGATACCTGCCTTATATTTTTCTGGTTGTGAA
+GTTACTAAATCTGGCCTATTGCTTGTGAATATGCAGGCGTTGCCTGTTTTTACATTTGCA
+AATCAAGCAGGGTTGGACATGCTGGAAACGACANNNNNNNNNNNNNNNNNNNNNNNNNNN
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/test.wig	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,12 @@
+fixedStep  chrom=chr1  start=11  step=1
+1.1
+1.2
+fixedStep  chrom=chr1  start=14  step=1
+1.4
+1.5
+variableStep chrom=chr1
+17  1.7
+19  1.9
+variableStep chrom=chrX
+5  9.5
+6  9.6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/test1.wig	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,11 @@
+fixedStep  chrom=chr2  start=9  step=1
+0
+0
+1.1
+1.2
+fixedStep  chrom=chr2  start=14  step=1
+1.4
+1.5
+variableStep chrom=chr2
+17  1.7
+19  1.9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/test2.wig	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,3 @@
+fixedStep  chrom=chr3  start=14  step=1
+1.4
+1.5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/testBedParser1.bed	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,2 @@
+track name=reads description="Reads" useScore=0 visibility=full offset=0
+arm_X	1000	3000	test1.1	1000	+	1000	3000	0	2	100,1000,	0,1000,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/testCoordsParser.coords	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,19 @@
+/home/urgi/genome_alignment/data/banks/arabidopsis/lyrata/ara_lyra_sca1.fa /home/urgi/genome_alignment/data/banks/arabidopsis/thaliana/ara_thal_chr1.fa
+NUCMER
+
+    [S1]     [E1]  |     [S2]     [E2]  |  [LEN 1]  [LEN 2]  |  [% IDY]  | [TAGS]
+=====================================================================================
+       1     6251  |   421251   415029  |     6251     6223  |    89.03  | scaffold_1	gi|240254421:1-30427671
+    9127    11947  |   414945   412123  |     2821     2823  |    90.45  | scaffold_1	gi|240254421:1-30427671
+   12201    12953  |   411933   411173  |      753      761  |    82.56  | scaffold_1	gi|240254421:1-30427671
+   13086    20401  |   411034   403760  |     7316     7275  |    88.56  | scaffold_1	gi|240254421:1-30427671
+   20482    20686  |   403573   403369  |      205      205  |    94.66  | scaffold_1	gi|240254421:1-30427671
+   32288    32623  |   402639   402280  |      336      360  |    76.52  | scaffold_1	gi|240254421:1-30427671
+   32936    33572  |   401974   401308  |      637      667  |    79.80  | scaffold_1	gi|240254421:1-30427671
+   33748    35013  |   401256   400080  |     1266     1177  |    82.77  | scaffold_1	gi|240254421:1-30427671
+   35456    44084  |   399895   391566  |     8629     8330  |    86.23  | scaffold_1	gi|240254421:1-30427671
+   44401    45265  |   391569   390737  |      865      833  |    90.40  | scaffold_1	gi|240254421:1-30427671
+   45374    46243  |   390633   389755  |      870      879  |    71.70  | scaffold_1	gi|240254421:1-30427671
+   46366    48958  |   389607   387128  |     2593     2480  |    82.32  | scaffold_1	gi|240254421:1-30427671
+   55079    55160  |   369603   369683  |       82       81  |    93.90  | scaffold_1	gi|240254421:1-30427671
+   55407    56537  |   369910   371016  |     1131     1107  |    81.69  | scaffold_1	gi|240254421:1-30427671
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/testCoordsParser_showcoord.coords	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,5 @@
+/home/fungisex/Work2011_2012/Gnc/Compare_Genome/SLA1_SLA2/Mivi_sl_A1_scaffolds.fa /home/fungisex/Work2011_2012/Gnc/Compare_Genome/SLA1_SLA2/Mivi_sl_A2_scaffolds.fa
+NUCMER
+
+[S1]	[E1]	[S2]	[E2]	[LEN 1]	[LEN 2]	[% IDY]	[LEN R]	[LEN Q]	[COV R]	[COV Q]	[FRM]	[TAGS]
+296	2292	1	2001	1997	2001	98.30	175930	60273	1.14	3.32	1	1	mivi_sl_A1_scaffold00001	mivi_sl_A2_scaffold00003
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/testCoordsParser_showcoord_promer.coords	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,5 @@
+/home/fungisex/Work2011_2012/Gnc/Compare_Genome/SLA1_SLA2/Mivi_sl_A1_scaffolds.fa /home/fungisex/Work2011_2012/Gnc/Compare_Genome/SLA1_SLA2/Mivi_sl_A2_scaffolds.fa
+PROMER
+
+[S1]	[E1]	[S2]	[E2]	[LEN 1]	[LEN 2]	[% IDY]	[% SIM]	[% STP]	[LEN R]	[LEN Q]	[COV R]	[COV Q]	[FRM]	[TAGS]
+1229    291    939    1    939    939    94.25    97.12    3.04    175930    60273    0.53    1.56    -3    -1    mivi_sl_A1_scaffold00001    mivi_sl_A2_scaffold00003
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/parsing/test/data/testGffParser1.gff3	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,7 @@
+arm_X	test	test_transcript	1000	2000	1	+	.	ID=id1-1;Name=test1;field=value1
+arm_X	test	test_exon	1000	2000	1	+	.	ID=id1-1-exon1;Name=test1-exon1;Parent=id1-1
+arm_X	test	test_transcript	10000	20000	1	-	.	ID=id2-1;Name=test2;field=value2
+arm_X	test	test_exon	10000	10100	1	-	.	ID=id2-1-exon1;Name=test2-exon1;Parent=id2-1
+arm_X	test	test_exon	10500	20000	1	-	.	ID=id2-1-exon2;Name=test2-exon2;Parent=id2-1
+arm_X	test	test_transcript	1000	2000	1	+	.	ID=test1.1-1;Name=test1.1
+arm_X	test	test_exon	1000	2000	1	+	.	ID=test1.1-1-exon1;Name=test1.1-exon1;Parent=test1.1-1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/seq/AlignedBioseqDB.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,396 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import sys
+from commons.core.seq.BioseqDB import BioseqDB
+from commons.core.seq.Bioseq import Bioseq
+from commons.core.coord.Align import Align
+from commons.core.coord.Range import Range
+from commons.core.stat.Stat import Stat
+from math import log
+
+
+## Multiple Sequence Alignment Representation   
+#   
+#
+class AlignedBioseqDB( BioseqDB ):
+    
+    def __init__( self, name="" ):
+        BioseqDB.__init__( self, name )
+        seqLength = self.getLength()
+        if self.getSize() > 1:
+            for bs in self.db[1:]:
+                if bs.getLength() != seqLength:
+                    print "ERROR: aligned sequences have different length"
+                    
+                    
+    ## Get length of the alignment
+    # 
+    # @return length
+    # @warning name before migration was 'length'
+    #
+    def getLength( self ):
+        length = 0
+        if self.db != []:
+            length = self.db[0].getLength()
+        return length
+    
+    
+    ## Get the true length of a given sequence (without gaps)
+    #
+    # @param header string header of the sequence to analyze
+    # @return length integer
+    # @warning  name before migration was 'true_length'
+    #
+    def getSeqLengthWithoutGaps( self, header ):
+        bs = self.fetch( header )
+        count = 0
+        for pos in xrange(0,len(bs.sequence)):
+            if bs.sequence[pos] != "-":
+                count += 1
+        return count
+    
+    
+    ## Record the occurrences of symbols (A, T, G, C, N, -, ...) at each site
+    #
+    # @return: list of dico whose keys are symbols and values are their occurrences
+    #
+    def getListOccPerSite( self ):
+        lOccPerSite = []   # list of dictionaries, one per position on the sequence
+        n = 0    # nb of sequences parsed from the input file
+        firstSeq = True
+
+        # for each sequence in the bank
+        for bs in self.db:
+            if bs.sequence == None:
+                break
+            n += 1
+
+            # if it is the first to be parsed, create a dico at each site
+            if firstSeq:
+                for i in xrange(0,len(bs.sequence)):
+                    lOccPerSite.append( {} )
+                firstSeq = False
+
+            # for each site, add its nucleotide
+            for i in xrange(0,len(bs.sequence)):
+                nuc = bs.sequence[i].upper()
+                if lOccPerSite[i].has_key( nuc ):
+                    lOccPerSite[i][nuc] += 1
+                else:
+                    lOccPerSite[i][nuc] = 1
+
+        return lOccPerSite
+    
+    #TODO: review minNbNt !!! It should be at least 2 nucleotides to build a consensus...
+    ## Make a consensus from the MSA
+    #
+    # @param minNbNt: minimum nb of nucleotides to edit a consensus
+    # @param minPropNt: minimum proportion for the major nucleotide to be used, otherwise add 'N' (default=0.0)
+    # @param verbose: level of information sent to stdout (default=0/1)
+    # @return: consensus
+    #
+    def getConsensus( self, minNbNt, minPropNt=0.0, verbose=0 , isHeaderSAtannot=False):
+
+        maxPropN = 0.40  # discard consensus if more than 40% of N's
+
+        nbInSeq = self.getSize()
+        if verbose > 0:
+            print "nb of aligned sequences: %i" % ( nbInSeq ); sys.stdout.flush()
+        if nbInSeq < 2:
+            print "ERROR: can't make a consensus with less than 2 sequences"
+            sys.exit(1)
+        if minNbNt >= nbInSeq:
+            minNbNt = nbInSeq - 1
+            print "minNbNt=%i" % ( minNbNt )
+        if minPropNt >= 1.0:
+            print "ERROR: minPropNt=%.2f should be a proportion (below 1.0)" % ( minPropNt )
+            sys.exit(1)
+
+        lOccPerSite = self.getListOccPerSite()
+        nbSites = len(lOccPerSite)
+        if verbose > 0:
+            print "nb of sites: %i" % ( nbSites ); sys.stdout.flush()
+
+        seqConsensus = ""
+
+        # for each site (i.e. each column of the MSA)
+        nbRmvColumns = 0
+        countSites = 0
+        for dNt2Occ in lOccPerSite:
+            countSites += 1
+            if verbose > 1:
+                print "site %s / %i" % ( str(countSites).zfill( len(str(nbSites)) ),
+                                         nbSites )
+                sys.stdout.flush()
+            occMaxNt = 0   # occurrences of the predominant nucleotide at this site
+            lBestNt = []
+            nbNt = 0   # total nb of A, T, G and C (no gap)
+
+            # for each distinct symbol at this site (A, T, G, C, N, -,...)
+            for j in dNt2Occ.keys():
+                if j != "-":
+                    nbNt += dNt2Occ[j]
+                    if verbose > 1:
+                        print "%s: %i" % ( j, dNt2Occ[j] )
+                    if dNt2Occ[j] > occMaxNt:
+                        occMaxNt = dNt2Occ[j]
+                        lBestNt = [ j ]
+                    elif dNt2Occ[j] == occMaxNt:
+                        lBestNt.append( j )
+            if nbNt == 0:   # some MSA programs can remove some sequences (e.g. Muscle after Recon) or when using Refalign (non-alignable TE fragments put together via a refseq)
+                nbRmvColumns += 1
+
+            if len( lBestNt ) >= 1:
+                bestNt = lBestNt[0]
+            
+            # if the predominant nucleotide occurs in less than x% of the sequences, put a "N"
+            if minPropNt > 0.0 and nbNt != 0 and float(occMaxNt)/float(nbNt) < minPropNt:
+                bestNt = "N"
+
+            if int(nbNt) >= int(minNbNt):
+                seqConsensus += bestNt
+                if verbose > 1:
+                    print "-> %s" % ( bestNt )
+
+        if nbRmvColumns:
+            if nbRmvColumns == 1:
+                print "WARNING: 1 site was removed (%.2f%%)" % (nbRmvColumns / float(nbSites) * 100)
+            else:
+                print "WARNING: %i sites were removed (%.2f%%)" % ( nbRmvColumns, nbRmvColumns / float(nbSites) * 100 )
+            sys.stdout.flush()
+            if seqConsensus == "":
+                print "WARNING: no consensus can be built (no sequence left)"
+                return
+
+        propN = seqConsensus.count("N") / float(len(seqConsensus))
+        if propN >= maxPropN:
+            print "WARNING: no consensus can be built (%i%% of N's >= %i%%)" % ( propN * 100, maxPropN * 100 )
+            return
+        elif propN >= maxPropN * 0.5:
+            print "WARNING: %i%% of N's" % ( propN * 100 )
+
+        consensus = Bioseq()
+        consensus.sequence = seqConsensus
+        if isHeaderSAtannot:
+            header = self.db[0].header
+            pyramid = header.split("Gr")[1].split("Cl")[0]
+            pile = header.split("Cl")[1].split(" ")[0]
+            consensus.header = "consensus=%s length=%i nbAlign=%i pile=%s pyramid=%s" % (self.name, len(seqConsensus), self.getSize(), pile, pyramid)
+        else:
+            consensus.header = "consensus=%s length=%i nbAlign=%i" % ( self.name, len(seqConsensus), self.getSize() )
+
+        if verbose > 0:
+       
+            statEntropy = self.getEntropy( verbose - 1 )
+            print "entropy: %s" % ( statEntropy.stringQuantiles() )
+            sys.stdout.flush()
+
+        return consensus
+    
+    
+    ## Get the entropy of the whole multiple alignment (only for A, T, G and C)
+    #
+    # @param verbose level of verbosity
+    #
+    # @return statistics about the entropy of the MSA
+    #
+    def getEntropy( self, verbose=0 ):
+
+        stats = Stat()
+
+        # get the occurrences of symbols at each site
+        lOccPerSite = self.getListOccPerSite()
+
+        countSite = 0
+
+        # for each site
+        for dSymbol2Occ in lOccPerSite:
+            countSite += 1
+
+            # count the number of nucleotides (A, T, G and C, doesn't count gap '-')
+            nbNt = 0
+            dATGC2Occ = {}
+            for base in ["A","T","G","C"]:
+                dATGC2Occ[ base ] = 0.0
+            for nt in dSymbol2Occ.keys():
+                if nt != "-":
+                    nbNt += dSymbol2Occ[ nt ]
+                    checkedNt = self.getATGCNFromIUPAC( nt )
+                    if checkedNt in ["A","T","G","C"] and dSymbol2Occ.has_key( checkedNt ):
+                        dATGC2Occ[ checkedNt ] += 1 * dSymbol2Occ[ checkedNt ]
+                    else:   # for 'N'
+                        if dSymbol2Occ.has_key( checkedNt ):
+                            dATGC2Occ[ "A" ] += 0.25 * dSymbol2Occ[ checkedNt ]
+                            dATGC2Occ[ "T" ] += 0.25 * dSymbol2Occ[ checkedNt ]
+                            dATGC2Occ[ "G" ] += 0.25 * dSymbol2Occ[ checkedNt ]
+                            dATGC2Occ[ "C" ] += 0.25 * dSymbol2Occ[ checkedNt ]
+            if verbose > 2:
+                for base in dATGC2Occ.keys():
+                    print "%s: %i" % ( base, dATGC2Occ[ base ] )
+
+            # compute the entropy for the site
+            entropySite = 0.0
+            for nt in dATGC2Occ.keys():
+                entropySite += self.computeEntropy( dATGC2Occ[ nt ], nbNt )
+            if verbose > 1:
+                print "site %i (%i nt): entropy = %.3f" % ( countSite, nbNt, entropySite )
+            stats.add( entropySite )
+
+        return stats
+    
+    
+    ## Get A, T, G, C or N from an IUPAC letter
+    #  IUPAC = ['A','T','G','C','U','R','Y','M','K','W','S','B','D','H','V','N']
+    #
+    # @return A, T, G, C or N
+    #
+    def getATGCNFromIUPAC( self, nt ):
+        iBs = Bioseq()
+        return iBs.getATGCNFromIUPAC( nt )
+    
+    
+    ## Compute the entropy based on the occurrences of a certain nucleotide and the total number of nucleotides
+    #
+    def computeEntropy( self, nbOcc, nbNt ):
+        if nbOcc == 0.0:
+            return 0.0
+        else:
+            freq = nbOcc / float(nbNt)
+            return - freq * log(freq) / log(2) 
+        
+        
+    ## Save the multiple alignment as a matrix with '0' if gap, '1' otherwise
+    #
+    def saveAsBinaryMatrix( self, outFile ):
+        outFileHandler = open( outFile, "w" )
+        for bs in self.db:
+            string = "%s" % ( bs.header )
+            for nt in bs.sequence:
+                if nt != "-":
+                    string += "\t%i" % ( 1 )
+                else:
+                    string += "\t%i" % ( 0 )
+            outFileHandler.write( "%s\n" % ( string ) )
+        outFileHandler.close()
+        
+        
+    ## Return a list of Align instances corresponding to the aligned regions (without gaps)
+    #
+    # @param query string header of the sequence considered as query
+    # @param subject string header of the sequence considered as subject
+    #
+    def getAlignList( self, query, subject ):
+        lAligns = []
+        alignQ = self.fetch( query ).sequence
+        alignS = self.fetch( subject ).sequence
+        createNewAlign = True
+        indexAlign = 0
+        indexQ = 0
+        indexS = 0
+        while indexAlign < len(alignQ):
+            if alignQ[ indexAlign ] != "-" and alignS[ indexAlign ] != "-":
+                indexQ += 1
+                indexS += 1
+                if createNewAlign:
+                    iAlign = Align( Range( query, indexQ, indexQ ),
+                                    Range( subject, indexS, indexS ),
+                                    0,
+                                    int( alignQ[ indexAlign ] == alignS[ indexAlign ] ),
+                                    int( alignQ[ indexAlign ] == alignS[ indexAlign ] ) )
+                    lAligns.append( iAlign )
+                    createNewAlign = False
+                else:
+                    lAligns[-1].range_query.end += 1
+                    lAligns[-1].range_subject.end += 1
+                    lAligns[-1].score += int( alignQ[ indexAlign ] == alignS[ indexAlign ] )
+                    lAligns[-1].identity += int( alignQ[ indexAlign ] == alignS[ indexAlign ] )
+            else:
+                if not createNewAlign:
+                    lAligns[-1].identity = 100 * lAligns[-1].identity / lAligns[-1].getLengthOnQuery()
+                    createNewAlign = True
+                if alignQ[ indexAlign ] != "-":
+                    indexQ += 1
+                elif alignS[ indexAlign ] != "-":
+                    indexS += 1
+            indexAlign += 1
+        if not createNewAlign:
+            lAligns[-1].identity = 100 * lAligns[-1].identity / lAligns[-1].getLengthOnQuery()
+        return lAligns
+    
+    
+    def removeGaps(self):
+        for iBs in self.db:
+            iBs.removeSymbol( "-" )
+    
+    ## Compute mean per cent identity for MSA. 
+    # First sequence in MSA is considered as reference sequence. 
+    #
+    #        
+    def computeMeanPcentIdentity(self):
+        seqRef = self.db[0]
+        sumPcentIdentity = 0
+
+        for seq in self.db[1:]:
+            pcentIdentity = self._computePcentIdentityBetweenSeqRefAndCurrentSeq(seqRef, seq) 
+            sumPcentIdentity = sumPcentIdentity + pcentIdentity
+        
+        nbSeq = len(self.db[1:])
+        meanPcentIdentity = round (sumPcentIdentity/nbSeq)
+        
+        return meanPcentIdentity
+
+    def _computePcentIdentityBetweenSeqRefAndCurrentSeq(self, seqRef, seq):
+            indexOnSeqRef = 0
+            sumIdentity = 0
+            for nuclSeq in seq.sequence:
+                nuclRef = seqRef.sequence[indexOnSeqRef]
+            
+                if nuclRef != "-" and nuclRef == nuclSeq:
+                    sumIdentity = sumIdentity + 1
+                indexOnSeqRef = indexOnSeqRef + 1   
+            
+            return float(sumIdentity) / float(seqRef.getLength()) * 100       
+
+ 
+
+
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/seq/Bioseq.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,686 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import sys
+import string
+import re
+import random
+import cStringIO
+from commons.core.coord.Map import Map
+
+DNA_ALPHABET_WITH_N = set( ['A','T','G','C','N'] )
+IUPAC = set(['A','T','G','C','U','R','Y','M','K','W','S','B','D','H','V','N'])
+
+
+## Record a sequence with its header
+#
+class Bioseq( object ):
+    
+    header = ""
+    sequence = ""
+    
+    ## constructor
+    #
+    # @param name the header of sequence
+    # @param seq sequence (DNA, RNA, protein)
+    #
+    def __init__( self, name="", seq="" ):
+        self.header = name
+        self.sequence = seq
+        
+        
+    ## Equal operator
+    #        
+    def __eq__( self, o ):
+        if self.header==o.header and self.sequence==o.sequence:
+            return True
+        return False
+    
+    
+    ## overload __repr__
+    #
+    def __repr__( self ):
+        return "%s;%s" % ( self.header, self.sequence )
+    
+    
+    ## set attribute header
+    #
+    # @param header a string
+    #
+    def setHeader( self, header ):
+        self.header = header
+        
+        
+    ## get attribute header
+    #
+    # @return header
+    def getHeader(self):
+        return self.header
+    
+    
+    ## set attribute sequence
+    #
+    # @param sequence a string
+    #
+    def setSequence( self, sequence ):
+        self.sequence = sequence
+        
+        
+    def getSequence(self):
+        return self.sequence
+        
+    ## reset
+    #
+    def reset( self ):
+        self.setHeader( "" )
+        self.setSequence( "" )
+        
+        
+    ## Test if bioseq is empty
+    #
+    def isEmpty( self ):
+        return self.header == "" and self.sequence == ""
+    
+    
+    ## Reverse the sequence
+    #
+    def reverse( self ):
+        tmp = self.sequence
+        self.sequence = tmp[::-1]
+        
+        
+    ## Turn the sequence into its complement
+    #  Force upper case letters
+    #  @warning: old name in pyRepet.Bioseq realComplement
+    #
+    def complement( self ):
+        complement = ""
+        self.upCase()
+        for i in xrange(0,len(self.sequence),1):
+            if self.sequence[i] == "A":
+                complement += "T"
+            elif self.sequence[i] == "T":
+                complement += "A"
+            elif self.sequence[i] == "C":
+                complement += "G"
+            elif self.sequence[i] == "G":
+                complement += "C"
+            elif self.sequence[i] == "M":
+                complement += "K"
+            elif self.sequence[i] == "R":
+                complement += "Y"
+            elif self.sequence[i] == "W":
+                complement += "W"
+            elif self.sequence[i] == "S":
+                complement += "S"
+            elif self.sequence[i] == "Y":
+                complement += "R"
+            elif self.sequence[i] == "K":
+                complement += "M"
+            elif self.sequence[i] == "V":
+                complement += "B"
+            elif self.sequence[i] == "H":
+                complement += "D"
+            elif self.sequence[i] == "D":
+                complement += "H"
+            elif self.sequence[i] == "B":
+                complement += "V"
+            elif self.sequence[i] == "N":
+                complement += "N"
+            elif self.sequence[i] == "-":
+                complement += "-"
+            else:
+                print "WARNING: unknown symbol '%s', replacing it by N" % ( self.sequence[i] )
+                complement += "N"
+        self.sequence = complement
+        
+        
+    ## Reverse and complement the sequence
+    #
+    #  Force upper case letters
+    #  @warning: old name in pyRepet.Bioseq : complement  
+    # 
+    def reverseComplement( self ):
+        self.reverse()
+        self.complement()
+        
+        
+    ## Remove gap in the sequence
+    #
+    def cleanGap(self):
+        self.sequence = self.sequence.replace("-","")
+        
+        
+    ## Copy current Bioseq Instance
+    #
+    # @return: a Bioseq instance, a copy of current sequence.
+    #
+    def copyBioseqInstance(self):
+        seq = Bioseq()
+        seq.sequence = self.sequence
+        seq.header = self.header
+        return seq
+    
+    
+    ## Add phase information after the name of sequence in header
+    #
+    # @param phase integer representing phase (1, 2, 3, -1, -2, -3)
+    #
+    def setFrameInfoOnHeader(self, phase):
+        if " " in self.header:
+            name, desc = self.header.split(" ", 1)
+            name = name + "_" + str(phase)
+            self.header = name + " " + desc
+        else:
+            self.header = self.header + "_" + str(phase)
+            
+            
+    ## Fill Bioseq attributes with fasta file
+    #  
+    # @param faFileHandler file handler of a fasta file
+    #
+    def read( self, faFileHandler ):
+        line = faFileHandler.readline()
+        if line == "":
+            self.header = None
+            self.sequence = None
+            return
+        while line == "\n":
+            line = faFileHandler.readline()
+        if line[0] == '>':
+            self.header = string.rstrip(line[1:])
+        else:
+            print "error, line is",string.rstrip(line)
+            return
+        line = " "
+        seq = cStringIO.StringIO()
+        while line:
+            prev_pos = faFileHandler.tell()
+            line = faFileHandler.readline()
+            if line == "":
+                break
+            if line[0] == '>':
+                faFileHandler.seek( prev_pos )
+                break
+            seq.write( string.rstrip(line) )
+        self.sequence = seq.getvalue()
+        
+        
+    ## Create a subsequence with a modified header
+    #  
+    # @param s integer start a required subsequence
+    # @param e integer end a required subsequence
+    #
+    # @return a Bioseq instance, a subsequence of current sequence
+    #       
+    def subseq( self, s, e=0 ):
+        if e == 0 :
+            e=len( self.sequence )
+        if s > e :
+            print "error: start must be < or = to end"
+            return
+        if s <= 0 :
+            print "error: start must be > 0"
+            return
+        sub = Bioseq()
+        sub.header = self.header + " fragment " + str(s) + ".." + str(e)
+        sub.sequence = self.sequence[(s-1):e]
+        return sub
+        
+        
+    ## Get the nucleotide or aminoacid at the given position
+    #  
+    # @param pos integer nucleotide or aminoacid position
+    #
+    # @return a string
+    #       
+    def getNtFromPosition(self, pos):
+        result = None
+        if not (pos < 1 or pos > self.getLength()):
+            result = self.sequence[pos - 1]
+        return result
+    
+    
+    ## Print in stdout the Bioseq in fasta format with 60 characters lines
+    #  
+    # @param l length of required sequence default is whole sequence
+    # 
+    def view(self,l=0):
+        print '>'+self.header
+        i=0
+        if(l==0):
+            l=len(self.sequence)
+        seq=self.sequence[0:l]
+            
+        while i<len(seq):
+            print seq[i:i+60]
+            i=i+60        
+            
+            
+    ## Get length of sequence
+    #
+    # @param avoidN boolean don't count 'N' nucleotides
+    #
+    # @return length of current sequence
+    # 
+    def getLength( self, countN = True ):
+        if countN:
+            return len(self.sequence)
+        else:
+            return len(self.sequence) - self.countNt('N')
+            
+            
+    ## Return the proportion of a specific character
+    # 
+    # @param nt character that we want to count
+    #
+    def propNt( self, nt ):
+        return self.countNt( nt ) / float( self.getLength() )
+    
+    
+    ## Count occurrence of specific character
+    # 
+    # @param nt character that we want to count
+    #
+    # @return nb of occurrences
+    #
+    def countNt( self, nt ):
+        return self.sequence.count( nt )
+    
+    
+    ## Count occurrence of each nucleotide in current seq 
+    #
+    # @return a dict, keys are nucleotides, values are nb of occurrences
+    #
+    def countAllNt( self ):
+        dNt2Count = {}
+        for nt in ["A","T","G","C","N"]:
+            dNt2Count[ nt ] = self.countNt( nt )
+        return dNt2Count
+    
+    
+    ## Return a dict with the number of occurrences for each combination of ATGC of specified size and number of word found
+    #
+    # @param size integer required length word
+    #
+    def occ_word( self, size ):
+        occ = {}
+        if size == 0:
+            return occ,0
+        nbword = 0
+        srch = re.compile('[^ATGC]+')
+        wordlist = self._createWordList( size )
+        for i in wordlist:
+            occ[i] = 0
+        lenseq = len(self.sequence)
+        i = 0
+        while i < lenseq-size+1:
+            word = self.sequence[i:i+size].upper()
+            m = srch.search(word)
+            if m == None:
+                occ[word] = occ[word]+1
+                nbword = nbword + 1
+                i = i + 1
+            else:
+                i = i + m.end(0)
+        return occ, nbword
+    
+    
+    ## Return a dictionary with the frequency of occurs for each combination of ATGC of specified size
+    #
+    # @param size integer required length word
+    #
+    def freq_word( self, size ):
+        dOcc, nbWords = self.occ_word( size )
+        freq = {}
+        for word in dOcc.keys():
+            freq[word] = float(dOcc[word]) / nbWords
+        return freq
+    
+    
+    ## Find ORF in each phase
+    #
+    # @return: a dict, keys are phases, values are stop codon positions.
+    #
+    def findORF (self):
+        orf = {0:[],1:[],2:[]}
+        length = len (self.sequence)
+        for i in xrange(0,length):
+            triplet = self.sequence[i:i+3] 
+            if ( triplet == "TAA" or triplet == "TAG" or triplet == "TGA"):
+                phase = i % 3
+                orf[phase].append(i)
+        return orf
+    
+    
+    ## Convert the sequence into upper case
+    #
+    def upCase( self ):
+        self.sequence = self.sequence.upper()
+        
+        
+    ## Convert the sequence into lower case
+    #
+    def lowCase( self ):
+        self.sequence = self.sequence.lower()
+        
+        
+    ## Extract the cluster of the fragment (output from Grouper)
+    #
+    # @return cluster id (string)
+    #    
+    def getClusterID( self ):
+        data = self.header.split()
+        return data[0].split("Cl")[1]
+    
+    
+    ## Extract the group of the sequence (output from Grouper)
+    #
+    # @return group id (string)
+    #
+    def getGroupID( self ):
+        data = self.header.split()
+        return data[0].split("Gr")[1].split("Cl")[0]
+    
+    
+    ## Get the header of the full sequence (output from Grouper)
+    #
+    # @example  'Dmel_Grouper_3091_Malign_3:LARD' from '>MbS1566Gr81Cl81 Dmel_Grouper_3091_Malign_3:LARD {Fragment} 1..5203' 
+    # @return header (string)
+    #
+    def getHeaderFullSeq( self ):
+        data = self.header.split()
+        return data[1]
+    
+    
+    ## Get the strand of the fragment (output from Grouper)
+    #
+    # @return: strand (+ or -)
+    #
+    def getFragStrand( self ):
+        data = self.header.split()
+        coord = data[3].split("..")
+        if int(coord[0]) < int(coord[-1]):
+            return "+"
+        else:
+            return "-"
+        
+        
+    ## Get A, T, G, C or N from an IUPAC letter
+    #  IUPAC = ['A','T','G','C','U','R','Y','M','K','W','S','B','D','H','V','N']
+    #
+    # @return A, T, G, C or N
+    #
+    def getATGCNFromIUPAC( self, nt ):
+        subset = ["A","T","G","C","N"]
+
+        if nt in subset:
+            return nt
+        elif nt == "U":
+            return "T"
+        elif nt == "R":
+            return random.choice( "AG" )
+        elif nt == "Y":
+            return random.choice( "CT" )
+        elif nt == "M":
+            return random.choice( "CA" )
+        elif nt == "K":
+            return random.choice( "TG" )
+        elif nt == "W":
+            return random.choice( "TA" )
+        elif nt == "S":
+            return random.choice( "CG" )
+        elif nt == "B":
+            return random.choice( "CTG" )
+        elif nt == "D":
+            return random.choice( "ATG" )
+        elif nt == "H":
+            return random.choice( "ATC" )
+        elif nt == "V":
+            return random.choice( "ACG" )
+        else:
+            return "N"
+        
+        
+    def getSeqWithOnlyATGCN( self ):
+        newSeq = ""
+        for nt in self.sequence:
+            newSeq += self.getATGCNFromIUPAC( nt )
+        return newSeq
+    
+    
+    ## Replace any symbol not in (A,T,G,C,N) by another nucleotide it represents
+    #
+    def partialIUPAC( self ):
+        self.sequence = self.getSeqWithOnlyATGCN()
+    
+    
+    ## Remove non Unix end-of-line symbols, if any
+    #
+    def checkEOF( self ):
+        symbol = "\r"   # corresponds to '^M' from Windows
+        if symbol in self.sequence:
+            print "WARNING: Windows EOF removed in '%s'" % ( self.header )
+            sys.stdout.flush()
+            newSeq = self.sequence.replace( symbol, "" )
+            self.sequence = newSeq
+            
+            
+    ## Write Bioseq instance into a fasta file handler
+    #
+    # @param faFileHandler file handler of a fasta file
+    # 
+    def write( self, faFileHandler ):
+        faFileHandler.write( ">%s\n" % ( self.header ) )
+        self.writeSeqInFasta( faFileHandler )
+        
+        
+    ## Write only the sequence of Bioseq instance into a fasta file handler
+    #
+    # @param faFileHandler file handler of a fasta file
+    #
+    def writeSeqInFasta( self, faFileHandler ):
+        i = 0
+        while i < self.getLength():
+            faFileHandler.write( "%s\n" % ( self.sequence[i:i+60] ) )
+            i += 60
+            
+            
+    ## Append Bioseq instance to a fasta file
+    #
+    # @param faFile name of a fasta file as a string
+    # @param mode 'write' or 'append'
+    #
+    def save( self, faFile, mode="a" ):
+        faFileHandler = open( faFile, mode )
+        self.write( faFileHandler )
+        faFileHandler.close()
+        
+        
+    ## Append Bioseq instance to a fasta file
+    #  
+    # @param faFile name of a fasta file as a string
+    #
+    def appendBioseqInFile( self, faFile ):
+        self.save( faFile, "a" )
+        
+        
+    ## Write Bioseq instance into a fasta file handler
+    #  
+    # @param faFileHandler file handler on a file with writing right
+    #
+    def writeABioseqInAFastaFile( self, faFileHandler ):
+        self.write( faFileHandler )
+        
+        
+    ## Write Bioseq instance with other header into a fasta file handler
+    #
+    # @param faFileHandler file handler on a file with writing right
+    # @param otherHeader a string representing a new header (without the > and the \n)
+    #
+    def writeWithOtherHeader( self, faFileHandler, otherHeader ):
+        self.header = otherHeader
+        self.write( faFileHandler )
+        
+        
+    ## Append Bioseq header and Bioseq sequence in a fasta file
+    #  
+    # @param faFileHandler file handler on a file with writing right
+    # @param otherHeader a string representing a new header (without the > and the \n)
+    #
+    def writeABioseqInAFastaFileWithOtherHeader( self, faFileHandler, otherHeader ):
+        self.writeWithOtherHeader( faFileHandler, otherHeader )
+        
+        
+    ## get the list of Maps corresponding to seq without gap
+    #
+    # @warning This method was called getMap() in pyRepet.Bioseq
+    # @return a list of Map object 
+    # 
+    def getLMapWhithoutGap( self ):
+        lMaps = []
+        countSite = 1
+        countSubseq = 1
+        inGap = False
+        startMap = -1
+        endMap = -1
+
+        # initialize with the first site
+        if self.sequence[0] == "-":
+            inGap = True
+        else:
+            startMap = countSite
+
+        # for each remaining site
+        for site in self.sequence[1:]:
+            countSite += 1
+
+            # if it is a gap
+            if site == "-":
+
+                # if this is the beginning of a gap, record the previous subsequence
+                if inGap == False:
+                    inGap = True
+                    endMap = countSite - 1
+                    lMaps.append( Map( "%s_subSeq%i" % (self.header,countSubseq), self.header, startMap, endMap ) )
+                    countSubseq += 1
+
+            # if it is NOT a gap
+            if site != "-":
+
+                # if it is the end of a gap, begin the next subsequence
+                if inGap == True:
+                    inGap = False
+                    startMap = countSite
+
+                # if it is the last site
+                if countSite == self.getLength():
+                    endMap = countSite
+                    lMaps.append( Map( "%s_subSeq%i" % (self.header,countSubseq), self.header, startMap, endMap ) )
+
+        return lMaps
+    
+    
+    ## get the percentage of GC
+    #
+    # @return a percentage
+    # 
+    def getGCpercentage( self ):
+        tmpSeq = self.getSeqWithOnlyATGCN()
+        nbGC = tmpSeq.count( "G" ) + tmpSeq.count( "C" )
+        return 100 * nbGC / float( self.getLength() )
+    
+    ## get the percentage of GC of a sequence without counting N in sequence length
+    #
+    # @return a percentage
+    # 
+    def getGCpercentageInSequenceWithoutCountNInLength(self):
+        tmpSeq = self.getSeqWithOnlyATGCN()
+        nbGC = tmpSeq.count( "G" ) + tmpSeq.count( "C" )
+        return 100 * nbGC / float( self.getLength() - self.countNt("N") )
+    
+    ## get the 5 prime subsequence of a given length at the given position 
+    #
+    # @param position integer
+    # @param flankLength integer subsequence length
+    # @return a sequence string
+    # 
+    def get5PrimeFlank(self, position, flankLength):
+        if(position == 1):
+            return ""
+        else:
+            startOfFlank = 1
+            endOfFlank = position -1
+        
+            if((position - flankLength) > 0):
+                startOfFlank = position - flankLength
+            else:
+                startOfFlank = 1
+            
+            return self.subseq(startOfFlank, endOfFlank).sequence
+            
+            
+    ## get the 3 prime subsequence of a given length at the given position 
+    #  In the case of indels, the polymorphism length can be specified
+    #
+    # @param position integer
+    # @param flankLength integer subsequence length
+    # @param polymLength integer polymorphism length
+    # @return a sequence string
+    # 
+    def get3PrimeFlank(self, position, flankLength, polymLength = 1):
+        if((position + polymLength) > len( self.sequence )):
+            return ""
+        else:
+            startOfFlank = position + polymLength
+         
+            if((position+polymLength+flankLength) > len( self.sequence )):
+                endOfFlank =  len( self.sequence )
+            else:
+                endOfFlank =  position+polymLength+flankLength-1
+        
+            return self.subseq(startOfFlank, endOfFlank).sequence
+    
+    
+    def _createWordList(self,size,l=['A','T','G','C']):
+        if size == 1 :
+            return l
+        else:
+            l2 = []
+            for i in l:
+                for j in ['A','T','G','C']:
+                    l2.append( i + j )
+        return self._createWordList(size-1,l2)
+    
+    
+    def removeSymbol( self, symbol ):
+        tmp = self.sequence.replace( symbol, "" )
+        self.sequence = tmp
Binary file smart_toolShed/commons/core/seq/Bioseq.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/seq/BioseqDB.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,461 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import sys
+import re
+from commons.core.seq.Bioseq import Bioseq
+from commons.core.stat.Stat import Stat
+
+
+## Handle a collection of a Bioseq (header-sequence) 
+#
+class BioseqDB( object ):
+    
+    def __init__( self, name="" ):
+        self.idx = {}
+        self.idx_renamed = {}
+        self.db = []
+        self.name = name
+        if name != "":
+            faFile = open( name )
+            self.read( faFile )
+            faFile.close()
+        self.mean_seq_lgth = None
+        self.stat = Stat()
+        
+        
+    ## Equal operator
+    #
+    def __eq__( self, o ):
+        selfSize = self.getSize()
+        if selfSize != o.getSize():
+            return False
+        nbEqualInstances = 0
+        for i in self.db:
+            atLeastOneIsEqual = False
+            for j in o.db:
+                if i == j:
+                    atLeastOneIsEqual = True
+                    continue
+            if atLeastOneIsEqual:
+                nbEqualInstances += 1
+        if nbEqualInstances == selfSize:
+            return True
+        return False
+    
+    
+    ## Change the name of the BioseqDB
+    #
+    # @param name the BioseqDB name
+    # 
+    def setName(self, name):
+        self.name = name
+        
+        
+    ## Record each sequence of the input file as a list of Bioseq instances
+    #
+    # @param faFileHandler handler of a fasta file
+    #
+    def read( self, faFileHandler ):
+        while True:
+            seq = Bioseq()
+            seq.read( faFileHandler )
+            if seq.sequence == None:
+                break
+            self.add( seq )
+            
+            
+    ## Write all Bioseq of BioseqDB in a formatted fasta file (60 character long)
+    #
+    # @param faFileHandler file handler of a fasta file
+    #
+    def write( self, faFileHandler ):
+        for bs in self.db:
+            bs.writeABioseqInAFastaFile( faFileHandler )
+            
+            
+    ## Write all Bioseq of BioseqDB in a formatted fasta file (60 character long)
+    #
+    # @param outFaFileName file name of fasta file
+    # @param mode 'write' or 'append'
+    #
+    def save( self, outFaFileName, mode="w" ):
+        outFaFile = open( outFaFileName, mode )
+        self.write( outFaFile )
+        outFaFile.close()
+        
+        
+    ## Read a formatted fasta file and load it in the BioseqDB instance
+    #
+    # @param inFaFileName file name of fasta file
+    #    
+    def load(self, inFaFileName):
+        fichier = open(inFaFileName)
+        self.read(fichier)
+        fichier.close()
+        
+        
+    ## Reverse each sequence of the collection
+    #
+    def reverse( self ):
+        for bs in self.db:
+            bs.reverse()
+            
+            
+    ## Turn each sequence into its complement
+    #
+    def complement( self ):
+        for bs in self.db:
+            bs.complement()
+            
+            
+    ## Reverse and complement each sequence
+    #
+    def reverseComplement( self ):
+        for bs in self.db:
+            bs.reverseComplement()
+            
+            
+    ## Set the collection from a list of Bioseq instances
+    #
+    def setData( self, lBioseqs ):
+        for i in lBioseqs:
+            self.add( i )
+            
+            
+    ## Initialization of each attribute of the collection
+    #
+    def reset( self ):
+        self.db = []
+        self.idx = {}
+        self.name = None
+        self.mean_seq_lgth = None
+        self.stat.reset()
+        
+        
+    ## Remove all the gap of the sequences of the collection
+    #
+    def cleanGap(self): 
+        for iBioSeq in self.db:
+            iBioSeq.cleanGap()
+            
+            
+    ## Add a Bioseq instance and update the attributes
+    #
+    # @param bs a Bioseq instance
+    # 
+    def add( self, bs ):
+        if self.idx.has_key( bs.header ):
+            sys.stderr.write( "ERROR: two sequences with same header '%s'\n" % ( bs.header ) )
+            sys.exit(1)
+        self.db.append( bs )
+        self.idx[ bs.header ] = len(self.db) - 1
+        self.idx_renamed[ bs.header.replace("::","-").replace(":","-").replace(",","-").replace(" ","_") ] = len(self.db) - 1
+        
+        
+    ## Give the Bioseq instance corresponding to specified index
+    #
+    # @return a Bioseq instance
+    #
+    def __getitem__(self,index):
+        if index < len(self.db):
+            return self.db[index]
+        
+        
+    ## Give the number of sequences in the bank
+    #
+    # @return an integer
+    #
+    def getSize( self ):
+        return len( self.db )
+    
+    
+    ## Give the cumulative sequence length in the bank
+    #
+    # @return an integer
+    #
+    def getLength( self ):
+        cumLength = 0
+        for iBioseq in self.db:
+            cumLength += iBioseq.getLength()
+
+        return cumLength
+    
+    
+    ## Return the length of a given sequence via its header
+    #
+    # @return an integer
+    #
+    def getSeqLength( self, header ):
+        return self.fetch(header).getLength()
+    
+    
+    ## Return a list with the sequence headers
+    #
+    def getHeaderList( self ):
+        lHeaders = []
+        for bs in self.db:
+            lHeaders.append( bs.header )
+        return lHeaders
+    
+    
+    ## Return a list with the sequences
+    #
+    def getSequencesList( self ):
+        lSeqs = []
+        for bs in self.db:
+            lSeqs.append( bs.getSequence() )
+        return lSeqs
+    
+    
+    ## Give the Bioseq instance of the BioseqDB specified by its header
+    # 
+    # @warning name of this method not appropriate getBioseqByHeader is proposed
+    # @param header string
+    # @return a Bioseq instance
+    #
+    def fetch( self, header ):
+        return self.db[self.idx[header]]
+    
+    
+    ## Give the Bioseq instance of the BioseqDB specified by its renamed header
+    # In renamed header "::", ":", "," character are been replaced by "-" and " " by "_"
+    #
+    # @param renamedHeader string
+    # @return a Bioseq instance
+    #
+    def getBioseqByRenamedHeader( self, renamedHeader ):
+        return self.db[self.idx_renamed[renamedHeader]]
+    
+    
+    ## Count the number of times the given nucleotide is present in the bank.
+    #
+    # @param nt character (nt or aa)
+    # @return an integer
+    #
+    def countNt( self, nt ):
+        total = 0
+        for iBioseq in self.db:
+            total+= iBioseq.countNt( nt )
+        return total
+    
+    
+    ## Count the number of times each nucleotide (A,T,G,C,N) is present in the bank.
+    #
+    # @return a dictionary with nucleotide as key and an integer as values
+    #
+    def countAllNt( self ):
+        dNt2Count = {}
+        for nt in ["A","T","G","C","N"]:
+            dNt2Count[ nt ] = self.countNt( nt )
+        return dNt2Count
+    
+    
+    ## Extract a sub BioseqDB of specified size which beginning at specified start
+    #
+    # @param start integer index of first included Bioseq
+    # @param size integer size of expected BioseqDB 
+    # @return a BioseqDB
+    #
+    def extractPart(self, start, size):
+        iShorterBioseqDB = BioseqDB()
+        for iBioseq in self.db[start:(start + size)]:
+            iShorterBioseqDB.add(iBioseq)    
+        return iShorterBioseqDB  
+    
+    
+    ## Extract a sub BioseqDB with the specified number of best length Bioseq
+    #
+    # @param numBioseq integer the number of Bioseq searched
+    # @return a BioseqDB
+    #
+    def bestLength(self, numBioseq):
+        length_list = []
+        numseq = 0
+        for each_seq in self.db:
+            if each_seq.sequence == None:
+                l=0
+            else:
+                l = each_seq.getLength()
+            length_list.append(l)
+            numseq = numseq + 1
+
+        length_list.sort()
+        size = len(length_list)
+        if numBioseq < size:
+            len_min = length_list[size-numBioseq]
+        else:
+            len_min = length_list[0]
+
+        numseq = 0
+        nbsave = 0
+        bestSeqs = BioseqDB()
+        bestSeqs.setName(self.name)
+        for each_seq in self.db:
+            if each_seq.sequence == None:
+                l=0 
+            else :
+                l = each_seq.getLength()
+            numseq = numseq + 1
+            if l >= len_min:
+                bestSeqs.add(each_seq)
+                nbsave = nbsave + 1
+            if nbsave == numBioseq :
+                break      
+        return bestSeqs
+    
+    
+    ## Extract a sub BioseqDB from a file with Bioseq header containing the specified pattern
+    #
+    # @param pattern regular expression of wished Bioseq header
+    # @param inFileName name of fasta file in which we want extract the BioseqDB
+    #
+    def extractPatternOfFile(self, pattern, inFileName):
+        if pattern=="" :
+            return
+        srch=re.compile(pattern)
+        file_db=open(inFileName)
+        numseq=0
+        nbsave=0
+        while 1:
+            seq=Bioseq()
+            seq.read(file_db)
+            if seq.sequence==None:
+                break
+            numseq+=1
+            m=srch.search(seq.header)
+            if m:
+                self.add(seq)
+                nbsave+=1
+        file_db.close()
+        
+        
+    ## Extract a sub BioseqDB from the instance with all Bioseq header containing the specified pattern
+    #
+    # @param pattern regular expression of wished Bioseq header
+    #
+    # @return a BioseqDB
+    #
+    def getByPattern(self,pattern):
+        if pattern=="" :
+            return
+        iBioseqDB=BioseqDB()
+        srch=re.compile(pattern)
+        for iBioseq in self.db:
+            if srch.search(iBioseq.header):
+                iBioseqDB.add(iBioseq)
+        return iBioseqDB
+    
+    
+    ## Extract a sub BioseqDB from the instance with all Bioseq header not containing the specified pattern
+    #
+    # @param pattern regular expression of not wished Bioseq header
+    #
+    # @return a BioseqDB
+    #
+    def getDiffFromPattern(self,pattern):
+        if pattern=="" :
+            return
+        iBioseqDB=BioseqDB()
+        srch=re.compile(pattern)
+        for iBioseq in self.db:
+            if not srch.search(iBioseq.header):
+                iBioseqDB.add(iBioseq)
+        return iBioseqDB
+    
+    #TODO: to run several times to remove all concerned sequences when big data. How to fix it ?
+    ## Remove from the instance all Bioseq which header contains the specified pattern
+    #
+    # @param pattern regular expression of not wished Bioseq header
+    #
+    def rmByPattern(self,pattern):
+        if pattern=="" :
+            return
+        srch=re.compile(pattern)
+        for seq in self.db:
+            if srch.search(seq.header):
+                self.db.remove(seq)     
+                
+                
+    ## Copy a part from another BioseqDB in the BioseqDB if Bioseq have got header containing the specified pattern
+    # 
+    # @warning this method is called extractPattern in pyRepet.seq.BioseqDB
+    #
+    # @param pattern regular expression of wished Bioseq header
+    # @param sourceBioseqDB the BioseqDB from which we want extract Bioseq
+    #
+    def addBioseqFromABioseqDBIfHeaderContainPattern(self, pattern, sourceBioseqDB):
+        if pattern=="" :
+            return
+        srch=re.compile(pattern)
+        for seq in sourceBioseqDB.db:
+            m=srch.search(seq.header)
+            if m:
+                self.add(seq)   
+                
+                
+    ## Up-case the sequence characters in all sequences
+    # 
+    def upCase( self ):
+        for bs in self.db:
+            bs.upCase()
+            
+            
+    ## Split each gapped Bioseq in a list and store all in a dictionary
+    #
+    # @return a dict, keys are bioseq headers, values are list of Map instances 
+    #
+    def getDictOfLMapsWithoutGaps( self ):
+        dSeq2Maps = {}
+
+        for bs in self.db:
+            dSeq2Maps[ bs.header ] = bs.getLMapWhithoutGap()
+
+        return dSeq2Maps
+
+    ## Give the list of the sequence length in the bank
+    #
+    # @return an list
+    #
+    def getListOfSequencesLength( self ):
+        lLength = []
+        for iBioseq in self.db:
+            lLength.append(iBioseq.getLength())
+
+        return lLength
+    
+    ## Return sequence length for a list of sequence header
+    #
+    def getSeqLengthByListOfName( self, lHeaderName ):
+        lseqLength=[]
+        for headerName in lHeaderName: 
+            lseqLength.append(self.getSeqLength( headerName ))
+        return lseqLength
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/seq/BioseqUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,296 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import math
+import re
+from commons.core.seq.Bioseq import Bioseq
+
+## Static methods for sequences manipulation
+#
+class BioseqUtils(object):
+    
+    ## Translate a nucleotide sequence
+    #
+    # @param bioSeqInstanceToTranslate a bioseq instance to translate
+    # @param phase a integer : 1 (default), 2 or 3
+    # 
+    def translateSequence(bioSeqInstanceToTranslate, phase=1):
+        pep = ""
+        #length = math.floor((len(self.sequence)-phase-1)/3)*3
+        length = int( math.floor( ( len(bioSeqInstanceToTranslate.sequence )-( phase-1 ) )/3 )*3 )
+        #We need capital letters !
+        bioSeqInstanceToTranslate.upCase() 
+        sequence = bioSeqInstanceToTranslate.sequence                
+        for i in xrange(phase-1,length,3):
+            if (sequence[i:i+3] == "TTT" or sequence[i:i+3] == "TTC"):
+                pep = pep + "F"
+            elif ( sequence[i:i+3] == "TTA" or sequence[i:i+3] == "TTG" ):
+                pep = pep + "L"
+            elif ( sequence[i:i+2] == "CT" ):
+                pep = pep + "L"
+            elif ( sequence[i:i+3] == "ATT" or sequence[i:i+3] == "ATC" or sequence[i:i+3] == "ATA" ):
+                pep = pep + "I"
+            elif ( sequence[i:i+3] == "ATG" ):
+                pep = pep + "M"
+            elif ( sequence[i:i+2] == "GT" ):
+                pep = pep + "V"
+            elif ( sequence[i:i+2] == "TC" ) :
+                pep = pep + "S"
+            elif ( sequence[i:i+2] == "CC" ) :
+                pep = pep + "P"
+            elif ( sequence[i:i+2] == "AC" ) :
+                pep = pep + "T"
+            elif ( sequence[i:i+2] == "GC" ) :
+                pep = pep + "A"
+            elif ( sequence[i:i+3] == "TAT" or sequence[i:i+3] == "TAC" ) :
+                pep = pep + "Y"
+            elif ( sequence[i:i+3] == "TAA" or sequence[i:i+3] == "TAG" ) :
+                pep = pep + "*"
+            elif ( sequence[i:i+3] == "CAT" or sequence[i:i+3] == "CAC" ) :
+                pep = pep + "H"
+            elif ( sequence[i:i+3] == "CAA" or sequence[i:i+3] == "CAG" ) :
+                pep = pep + "Q"
+            elif ( sequence[i:i+3] == "AAT" or sequence[i:i+3] == "AAC" ) :
+                pep = pep + "N"
+            elif ( sequence[i:i+3] == "AAA" or sequence[i:i+3] == "AAG" ) :
+                pep = pep + "K"
+            elif ( sequence[i:i+3] == "GAT" or sequence[i:i+3] == "GAC" ) :
+                pep = pep + "D"
+            elif ( sequence[i:i+3] == "GAA" or sequence[i:i+3] == "GAG" ) :
+                pep = pep + "E"
+            elif ( sequence[i:i+3] == "TGT" or sequence[i:i+3] == "TGC" ) :
+                pep = pep + "C"
+            elif ( sequence[i:i+3] == "TGA" ) :
+                pep = pep + "*"
+            elif ( sequence[i:i+3] == "TGG" ) :
+                pep = pep + "W"
+            elif ( sequence[i:i+2] == "CG" ) :
+                pep = pep + "R"
+            elif ( sequence[i:i+3] == "AGT" or sequence[i:i+3] == "AGC" ) :
+                pep = pep + "S"
+            elif ( sequence[i:i+3] == "AGA" or sequence[i:i+3] == "AGG" ) :
+                pep = pep + "R"
+            elif ( sequence[i:i+2] == "GG" ):
+                pep = pep + "G"
+            #We don't know the amino acid because we don't have the nucleotide
+            #R      Purine (A or G)
+            #Y      Pyrimidine (C, T, or U)
+            #M      C or A
+            #K      T, U, or G
+            #W      T, U, or A
+            #S      C or G
+            #B      C, T, U, or G (not A)
+            #D      A, T, U, or G (not C)
+            #H      A, T, U, or C (not G)
+            #V      A, C, or G (not T, not U)
+            #N      Unknown nucleotide
+            elif ( re.search("N|R|Y|M|K|W|S|B|D|H|V", sequence[i:i+3])):
+                pep = pep + "X"                      
+        bioSeqInstanceToTranslate.sequence = pep
+        
+    translateSequence = staticmethod(translateSequence)
+    
+    ## Add the frame info in header
+    #
+    # @param bioSeqInstance a bioseq instance to translate
+    # @param phase a integer : 1 , 2 or 3
+    # 
+    def setFrameInfoOnHeader(bioSeqInstance, phase):
+        if " " in bioSeqInstance.header:
+            name, desc = bioSeqInstance.header.split(" ", 1)
+            name = name + "_" + str(phase)
+            bioSeqInstance.header = name + " " + desc
+        else:
+            bioSeqInstance.header = bioSeqInstance.header + "_" + str(phase)
+            
+    setFrameInfoOnHeader = staticmethod(setFrameInfoOnHeader)
+    
+    ## Translate a nucleotide sequence for all frames (positives and negatives)
+    #
+    # @param bioSeqInstanceToTranslate a bioseq instance to translate
+    #
+    def translateInAllFrame( bioSeqInstanceToTranslate ):
+        positives = BioseqUtils._translateInPositiveFrames( bioSeqInstanceToTranslate )        
+        negatives = BioseqUtils._translateInNegativeFrames( bioSeqInstanceToTranslate )         
+        listAll6Frames = []
+        listAll6Frames.extend(positives)
+        listAll6Frames.extend(negatives)
+        return listAll6Frames
+            
+    translateInAllFrame = staticmethod(translateInAllFrame)
+    
+    ## Replace the stop codons by X in sequence
+    #
+    # @param bioSeqInstance a bioseq instance
+    #
+    def replaceStopCodonsByX( bioSeqInstance ):
+        bioSeqInstance.sequence = bioSeqInstance.sequence.replace ("*", "X")
+            
+    replaceStopCodonsByX = staticmethod(replaceStopCodonsByX)  
+
+    ## Translate in a list all the frames of all the bioseq of bioseq list
+    #
+    # @param bioseqList a list of bioseq instances
+    # @return a list of translated bioseq instances
+    #
+    def translateBioseqListInAllFrames( bioseqList ):
+        bioseqListInAllFrames = []
+        for bioseq in bioseqList :
+            bioseqListInAllFrames.extend(BioseqUtils.translateInAllFrame(bioseq))
+        return bioseqListInAllFrames
+    
+    translateBioseqListInAllFrames = staticmethod( translateBioseqListInAllFrames )
+    
+    ## Replace the stop codons by X for each sequence of a bioseq list
+    #
+    # @param lBioseqWithStops a list of bioseq instances
+    # @return a list of bioseq instances
+    #
+    def replaceStopCodonsByXInBioseqList ( lBioseqWithStops ):
+        bioseqListWithStopsreplaced = []
+        for bioseq in lBioseqWithStops:
+            BioseqUtils.replaceStopCodonsByX(bioseq)
+            bioseqListWithStopsreplaced.append(bioseq)            
+        return bioseqListWithStopsreplaced
+    
+    replaceStopCodonsByXInBioseqList = staticmethod( replaceStopCodonsByXInBioseqList )
+    
+    ## Write a list of bioseq instances in a fasta file (60 characters per line)
+    #
+    # @param lBioseq a list of bioseq instances
+    # @param fileName string
+    #
+    def writeBioseqListIntoFastaFile( lBioseq, fileName ):
+        fout = open(fileName, "w")
+        for bioseq in lBioseq:
+                bioseq.write(fout)       
+        fout.close()
+    
+    writeBioseqListIntoFastaFile = staticmethod( writeBioseqListIntoFastaFile )
+    
+    ## read in a fasta file and create a list of bioseq instances
+    #
+    # @param fileName string
+    # @return a list of bioseq
+    #
+    def extractBioseqListFromFastaFile( fileName ):
+        file = open( fileName )
+        lBioseq = []
+        currentHeader = ""
+        while currentHeader != None:
+            bioseq = Bioseq()
+            bioseq.read(file)
+            currentHeader = bioseq.header
+            if currentHeader != None:
+                lBioseq.append(bioseq)
+        return lBioseq
+    
+    extractBioseqListFromFastaFile = staticmethod( extractBioseqListFromFastaFile )
+    
+    ## Give the length of a sequence search by name
+    #
+    # @param lBioseq a list of bioseq instances
+    # @param seqName string
+    # @return an integer
+    #
+    def getSeqLengthWithSeqName( lBioseq, seqName ):
+        length = 0
+        for bioseq in lBioseq:
+            if bioseq.header == seqName:
+                length = bioseq.getLength()
+                break        
+        return length
+
+    getSeqLengthWithSeqName = staticmethod( getSeqLengthWithSeqName )
+
+    def _translateInPositiveFrames( bioSeqInstanceToTranslate ):
+        seq1 = bioSeqInstanceToTranslate.copyBioseqInstance()
+        BioseqUtils.setFrameInfoOnHeader(seq1, 1)
+        BioseqUtils.translateSequence(seq1, 1)
+        seq2 = bioSeqInstanceToTranslate.copyBioseqInstance()
+        BioseqUtils.setFrameInfoOnHeader(seq2, 2)
+        BioseqUtils.translateSequence(seq2, 2)
+        seq3 = bioSeqInstanceToTranslate.copyBioseqInstance()
+        BioseqUtils.setFrameInfoOnHeader(seq3, 3)
+        BioseqUtils.translateSequence(seq3, 3)
+        return [seq1, seq2, seq3]
+    
+    _translateInPositiveFrames = staticmethod( _translateInPositiveFrames )
+    
+    def _translateInNegativeFrames(bioSeqInstanceToTranslate):
+        seq4 = bioSeqInstanceToTranslate.copyBioseqInstance()
+        seq4.reverseComplement()
+        BioseqUtils.setFrameInfoOnHeader(seq4, 4)
+        BioseqUtils.translateSequence(seq4, 1)
+        seq5 = bioSeqInstanceToTranslate.copyBioseqInstance()
+        seq5.reverseComplement()
+        BioseqUtils.setFrameInfoOnHeader(seq5, 5)
+        BioseqUtils.translateSequence(seq5, 2)
+        seq6 = bioSeqInstanceToTranslate.copyBioseqInstance()
+        seq6.reverseComplement()
+        BioseqUtils.setFrameInfoOnHeader(seq6, 6)
+        BioseqUtils.translateSequence(seq6, 3)
+        return [seq4, seq5, seq6]
+    
+    _translateInNegativeFrames = staticmethod( _translateInNegativeFrames )
+    
+    
+    ## Return a dictionary which keys are sequence headers and values sequence lengths.
+    #
+    def getLengthPerSeqFromFile( inFile ):
+        dHeader2Length = {}
+        inFileHandler = open( inFile, "r" )
+        while True:
+            iBs = Bioseq()
+            iBs.read( inFileHandler )
+            if iBs.sequence == None:
+                break
+            dHeader2Length[ iBs.header ] = iBs.getLength()
+        inFileHandler.close()
+        return dHeader2Length
+    
+    getLengthPerSeqFromFile = staticmethod( getLengthPerSeqFromFile )
+    
+    
+    ## Return the list of Bioseq instances, these being sorted in decreasing length
+    #
+    def getBioseqListSortedByDecreasingLength( lBioseqs ):
+        return sorted( lBioseqs, key=lambda iBs: ( iBs.getLength() ), reverse=True )
+    
+    getBioseqListSortedByDecreasingLength = staticmethod( getBioseqListSortedByDecreasingLength )
+    
+    
+    ## Return the list of Bioseq instances, these being sorted in decreasing length (without gaps)
+    #
+    def getBioseqListSortedByDecreasingLengthWithoutGaps( lBioseqs ):
+        return sorted( lBioseqs, key=lambda iBs: ( len(iBs.sequence.replace("-","")) ), reverse=True )
+    
+    getBioseqListSortedByDecreasingLengthWithoutGaps = staticmethod( getBioseqListSortedByDecreasingLengthWithoutGaps )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/seq/ClusterConsensusCollection.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,66 @@
+import re
+from commons.core.seq.BioseqDB import BioseqDB
+
+## Record a collection of bioseqDB representing cluster consensus
+#
+class ClusterConsensusCollection(object):
+
+    ## constructor
+    #
+    # @param clusterFileName string name of file containing the cluster of consensus
+    #
+    def __init__(self, clusterFileName):
+        self._clusterFileName = clusterFileName
+        self._lClusterConsensus = []
+
+    def __eq__(self, o):
+        return self._clusterFileName == o._clusterFileName and self._lClusterConsensus == o._lClusterConsensus
+
+    def getLClusterConsensus(self):
+        return self._lClusterConsensus
+    
+    def fillCollection(self):
+        iBioseqDBAllCluster = BioseqDB()
+        fClusterFile = open(self._clusterFileName, "r")
+        iBioseqDBAllCluster.read(fClusterFile)
+        fClusterFile.close()
+        lHeader = iBioseqDBAllCluster.getHeaderList()
+        firstHeader = lHeader[0]
+        previousClusterName, seqHeader = self._getClusterNameAndSeqHeader(firstHeader)
+        clusterConsensus = BioseqDB()
+        clusterConsensus.setName(previousClusterName)
+        self._addBioseqInClusterConsensus(iBioseqDBAllCluster, firstHeader, seqHeader, clusterConsensus)
+        for header in lHeader[1:]:
+            clusterName, seqHeader = self._getClusterNameAndSeqHeader(header)
+            if clusterName != previousClusterName:
+                self._lClusterConsensus.append(clusterConsensus)
+                previousClusterName = clusterName
+                clusterConsensus = BioseqDB()
+                clusterConsensus.setName(previousClusterName)
+            self._addBioseqInClusterConsensus(iBioseqDBAllCluster, header, seqHeader, clusterConsensus)
+        self._lClusterConsensus.append(clusterConsensus)
+                
+    def _getClusterNameAndSeqHeader(self, header):
+        m = re.match("(\D*)(\d+)Mb\d+\s.*", header)
+        clusterNumber = m.group(2)
+        clusterName = m.group(1) + clusterNumber
+        lPartsHeaderheader = header.split(" ")
+        seqHeader = lPartsHeaderheader[1]
+        return clusterName, seqHeader
+
+    def _addBioseqInClusterConsensus(self, iBioseqDBAllCluster, firstHeader, seqHeader, clusterConsensus):
+        ibioseq = iBioseqDBAllCluster.fetch(firstHeader)
+        ibioseq.setHeader(seqHeader)
+        clusterConsensus.add(ibioseq)
+        
+    def getNumClusterForAConsensus(self, seqName):
+        nbCluster = 1
+        for bioseqDB in self._lClusterConsensus:
+            if seqName in bioseqDB.getHeaderList():
+                return nbCluster
+            nbCluster += 1
+            
+    def getNumConsensusInCluster(self, numCluster):
+        return self._lClusterConsensus[numCluster - 1].getSize()
+
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/seq/FastaUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,1143 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import os
+import sys
+import string
+import math
+import shutil
+import re
+import glob
+from commons.core.seq.BioseqDB import BioseqDB
+from commons.core.seq.Bioseq import Bioseq
+from commons.core.coord.MapUtils import MapUtils
+from commons.core.coord.Range import Range
+from commons.core.checker.CheckerUtils import CheckerUtils
+from commons.core.launcher.LauncherUtils import LauncherUtils
+from commons.core.coord.ConvCoord import ConvCoord
+from commons.core.parsing.FastaParser import FastaParser
+
+
+## Static methods for fasta file manipulation
+#
+class FastaUtils( object ):
+    
+    ## Count the number of sequences in the input fasta file
+    #
+    # @param inFile name of the input fasta file
+    #
+    # @return integer number of sequences in the input fasta file
+    #
+    @staticmethod
+    def dbSize( inFile ):
+        nbSeq = 0
+        inFileHandler = open( inFile, "r" )
+        line = inFileHandler.readline()
+        while line:
+            if line[0] == ">":
+                nbSeq = nbSeq + 1
+            line = inFileHandler.readline()
+        inFileHandler.close()
+        
+        return nbSeq
+    
+    
+    ## Compute the cumulative sequence length in the input fasta file
+    #
+    # @param inFile handler of the input fasta file
+    #
+    @staticmethod
+    def dbCumLength( inFile ):
+        cumLength = 0
+        line = inFile.readline()
+        while line:
+            if line[0] != ">":
+                cumLength += len(string.rstrip(line))
+            line = inFile.readline()
+    
+        return cumLength
+    
+    
+    ## Return a list with the length of each sequence in the input fasta file
+    #
+    # @param inFile string name of the input fasta file
+    #
+    @staticmethod
+    def dbLengths( inFile ):
+        lLengths = []
+        inFileHandler = open( inFile, "r" )
+        currentLength = 0
+        line = inFileHandler.readline()
+        while line:
+            if line[0] == ">":
+                if currentLength != 0:
+                    lLengths.append( currentLength )
+                currentLength = 0
+            else:
+                currentLength += len(line[:-1])
+            line = inFileHandler.readline()
+        lLengths.append( currentLength )
+        inFileHandler.close()
+        return lLengths
+    
+    
+    ## Retrieve the sequence headers present in the input fasta file
+    #
+    # @param inFile string name of the input fasta file
+    # @param verbose integer level of verbosity
+    #
+    # @return list of sequence headers
+    #
+    @staticmethod
+    def dbHeaders( inFile, verbose=0 ):
+        lHeaders = []
+        
+        inFileHandler = open( inFile, "r" )
+        line = inFileHandler.readline()
+        while line:
+            if line[0] == ">":
+                lHeaders.append( string.rstrip(line[1:]) )
+                if verbose > 0:
+                    print string.rstrip(line[1:])
+            line = inFileHandler.readline()
+        inFileHandler.close()
+        
+        return lHeaders
+    
+    
+    ## Cut a data bank into chunks according to the input parameters
+    # If a sequence is shorter than the threshold, it is only renamed (not cut)
+    #
+    # @param inFileName string name of the input fasta file
+    # @param chkLgth string chunk length (in bp, default=200000)
+    # @param chkOver string chunk overlap (in bp, default=10000)
+    # @param wordN string N stretch word length (default=11, 0 for no detection)
+    # @param outFilePrefix string prefix of the output files (default=inFileName + '_chunks.fa' and '_chunks.map')
+    # @param clean boolean remove 'cut' and 'Nstretch' files
+    # @param verbose integer (default = 0)
+    #
+    @staticmethod
+    def dbChunks( inFileName, chkLgth="200000", chkOver="10000", wordN="11", outFilePrefix="", clean=False, verbose=0 ):
+        nbSeq = FastaUtils.dbSize( inFileName )
+        if verbose > 0:
+            print "cut the %i input sequences with cutterDB..." % ( nbSeq )
+            sys.stdout.flush()
+            
+        prg = "cutterDB"
+        cmd = prg
+        cmd += " -l %s" % ( chkLgth )
+        cmd += " -o %s"  %( chkOver )
+        cmd += " -w %s" % ( wordN )
+        cmd += " %s" % ( inFileName )
+        returnStatus = os.system( cmd )
+        if returnStatus != 0:
+            msg = "ERROR: '%s' returned '%i'" % ( prg, returnStatus )
+            sys.stderr.write( "%s\n" % ( msg ) )
+            sys.exit(1)
+            
+        nbChunks = FastaUtils.dbSize( "%s_cut" % ( inFileName ) )
+        if verbose > 0:
+            print "done (%i chunks)" % ( nbChunks )
+            sys.stdout.flush()
+            
+        if verbose > 0:
+            print "rename the headers..."
+            sys.stdout.flush()
+            
+        if outFilePrefix == "":
+            outFastaName = inFileName + "_chunks.fa"
+            outMapName = inFileName + "_chunks.map"
+        else:
+            outFastaName = outFilePrefix + ".fa"
+            outMapName = outFilePrefix + ".map"
+            
+        inFile = open( "%s_cut" % ( inFileName ), "r" )
+        line = inFile.readline()
+        
+        outFasta = open( outFastaName, "w" )
+        outMap = open( outMapName, "w" )
+        
+        # read line after line (no need for big RAM) and change the sequence headers
+        while line:
+            
+            if line[0] == ">":
+                if verbose > 1:
+                    print "rename '%s'" % ( line[:-1] ); sys.stdout.flush()
+                data = line[:-1].split(" ")
+                seqID = data[0].split(">")[1]
+                newHeader = "chunk%s" % ( str(seqID).zfill( len(str(nbChunks)) ) )
+                oldHeader = data[2]
+                seqStart = data[4].split("..")[0]
+                seqEnd = data[4].split("..")[1]
+                outMap.write( "%s\t%s\t%s\t%s\n" % ( newHeader, oldHeader, seqStart, seqEnd ) )
+                outFasta.write( ">%s\n" % ( newHeader ) )
+                
+            else:
+                outFasta.write( line.upper() )
+                
+            line = inFile.readline()
+            
+        inFile.close()
+        outFasta.close()
+        outMap.close()
+        
+        if clean == True:
+            os.remove(inFileName + "_cut")
+            os.remove(inFileName + ".Nstretch.map")
+            
+    
+    ## Split the input fasta file in several output files
+    #
+    # @param inFile string name of the input fasta file
+    # @param nbSeqPerBatch integer number of sequences per output file
+    # @param newDir boolean put the sequences in a new directory called 'batches'
+    # @param useSeqHeader boolean use sequence header (only if 'nbSeqPerBatch=1')
+    # @param prefix prefix in output file name 
+    # @param verbose integer verbosity level (default = 0)
+    #
+    @staticmethod
+    def dbSplit( inFile, nbSeqPerBatch, newDir, useSeqHeader=False, prefix="batch", verbose=0 ):
+        if not os.path.exists( inFile ):
+            msg = "ERROR: file '%s' doesn't exist" % ( inFile )
+            sys.stderr.write( "%s\n" % ( msg ) )
+            sys.exit(1)
+            
+        nbSeq = FastaUtils.dbSize( inFile )
+        
+        nbBatches = int( math.ceil( nbSeq / float(nbSeqPerBatch) ) )
+        if verbose > 0:
+            print "save the %i input sequences into %i batches" % ( nbSeq, nbBatches )
+            sys.stdout.flush()
+            
+        if nbSeqPerBatch > 1 and useSeqHeader:
+            useSeqHeader = False
+            
+        if newDir == True:
+            if os.path.exists( "batches" ):
+                shutil.rmtree( "batches" )
+            os.mkdir( "batches" )
+            os.chdir( "batches" )
+            os.system( "ln -s ../%s ." % ( inFile ) )
+            
+        inFileHandler = open( inFile, "r" )
+        inFileHandler.seek( 0, 0 )
+        countBatch = 0
+        countSeq = 0
+        line = inFileHandler.readline()
+        while line:
+            if line == "":
+                break
+            if line[0] == ">":
+                countSeq += 1
+                if nbSeqPerBatch == 1 or countSeq % nbSeqPerBatch == 1:
+                    if "outFile" in locals():
+                        outFile.close()
+                    countBatch += 1
+                    if nbSeqPerBatch == 1 and useSeqHeader:
+                        outFileName = "%s.fa" % ( line[1:-1].replace(" ","_") )
+                    else:
+                        outFileName = "%s_%s.fa" % ( prefix, str(countBatch).zfill( len(str(nbBatches)) ) )
+                    outFile = open( outFileName, "w" )
+                if verbose > 1:
+                    print "saving seq '%s' in file '%s'..." % ( line[1:40][:-1], outFileName )
+                    sys.stdout.flush()
+            outFile.write( line )
+            line = inFileHandler.readline()
+        inFileHandler.close()
+        
+        if newDir == True:
+            os.remove( os.path.basename( inFile ) )
+            os.chdir( ".." )
+            
+    
+    ## Split the input fasta file in several output files
+    #
+    # @param inFileName string name of the input fasta file
+    # @param maxSize integer max cumulative length for each output file
+    #
+    @staticmethod
+    def splitFastaFileInBatches(inFileName, maxSize = 200000):
+        iBioseqDB = BioseqDB(inFileName)
+        lHeadersSizeTuples = []
+        for iBioseq in iBioseqDB.db:
+            lHeadersSizeTuples.append((iBioseq.getHeader(), iBioseq.getLength()))
+            
+        lHeadersList = LauncherUtils.createHomogeneousSizeList(lHeadersSizeTuples, maxSize)
+        os.mkdir("batches")
+        os.chdir("batches")
+        
+        iterator = 0 
+        for lHeader in lHeadersList :
+            iterator += 1
+            with open("batch_%s.fa" % iterator, 'w') as f :
+                for header in lHeader :
+                    iBioseq = iBioseqDB.fetch(header)
+                    iBioseq.write(f)
+        os.chdir("..")
+        
+                    
+    ## Split the input fasta file in several output files according to their cluster identifier
+    #
+    # @param inFileName string  name of the input fasta file
+    # @param clusteringMethod string name of the clustering method (Grouper, Recon, Piler, Blastclust)
+    # @param simplifyHeader boolean simplify the headers
+    # @param createDir boolean put the sequences in different directories
+    # @param outPrefix string prefix of the output files (default='seqCluster')
+    # @param verbose integer (default = 0)
+    #
+    @staticmethod
+    def splitSeqPerCluster( inFileName, clusteringMethod, simplifyHeader, createDir, outPrefix="seqCluster", verbose=0 ):
+        if not os.path.exists( inFileName ):
+            print "ERROR: %s doesn't exist" % ( inFileName )
+            sys.exit(1)
+    
+        inFile = open( inFileName, "r" )
+    
+        line = inFile.readline()
+        if line:
+            name = line.split(" ")[0]
+            if "Cluster" in name:
+                clusterID = name.split("Cluster")[1].split("Mb")[0]
+                seqID = name.split("Mb")[1]
+            else:
+                clusterID = name.split("Cl")[0].split("Gr")[1]   # the notion of 'group' in Grouper corresponds to 'cluster' in Piler, Recon and Blastclust
+                if "Q" in name.split("Gr")[0]:
+                    seqID = name.split("Gr")[0].split("MbQ")[1]
+                elif "S" in name:
+                    seqID = name.split("Gr")[0].split("MbS")[1]
+            sClusterIDs = set( [ clusterID ] )
+            if simplifyHeader == True:
+                header = "%s_Cluster%s_Seq%s" % ( clusteringMethod, clusterID, seqID )
+            else:
+                header = line[1:-1]
+            if createDir == True:
+                if not os.path.exists( "%s_cluster_%s" % ( inFileName, clusterID )  ):
+                    os.mkdir( "%s_cluster_%s" % ( inFileName, clusterID )  )
+                os.chdir( "%s_cluster_%s" % ( inFileName, clusterID )  )
+            outFileName = "%s%s.fa" % ( outPrefix, clusterID )
+            outFile = open( outFileName, "w" )
+            outFile.write( ">%s\n" % ( header ) )
+            prevClusterID = clusterID
+        
+            line = inFile.readline()
+            while line:
+                if line[0] == ">":
+                    name = line.split(" ")[0]
+                    if "Cluster" in name:
+                        clusterID = name.split("Cluster")[1].split("Mb")[0]
+                        seqID = name.split("Mb")[1]
+                    else:
+                        clusterID = name.split("Cl")[0].split("Gr")[1]
+                        if "Q" in name.split("Gr")[0]:
+                            seqID = name.split("Gr")[0].split("MbQ")[1]
+                        elif "S" in name:
+                            seqID = name.split("Gr")[0].split("MbS")[1]
+        
+                    if clusterID != prevClusterID:
+                        outFile.close()
+        
+                    if simplifyHeader == True:
+                        header = "%s_Cluster%s_Seq%s" % ( clusteringMethod, clusterID, seqID )
+                    else:
+                        header = line[1:-1]
+        
+                    if createDir == True:
+                        os.chdir( ".." )
+                        if not os.path.exists( "%s_cluster_%s" % ( inFileName, clusterID )  ):
+                            os.mkdir( "%s_cluster_%s" % ( inFileName, clusterID )  )
+                        os.chdir( "%s_cluster_%s" % ( inFileName, clusterID )  )
+        
+                    outFileName = "%s%s.fa" % ( outPrefix, clusterID )
+                    if not os.path.exists( outFileName ):
+                        outFile = open( outFileName, "w" )
+                    else:
+                        if clusterID != prevClusterID:
+                            outFile.close()
+                            outFile = open( outFileName, "a" )
+                    outFile.write( ">%s\n" % ( header ) )
+                    prevClusterID = clusterID
+                    sClusterIDs.add( clusterID )
+        
+                else:
+                    outFile.write( line )
+        
+                line = inFile.readline()
+        
+            outFile.close()
+            if verbose > 0:
+                print "number of clusters: %i" % ( len(sClusterIDs) ); sys.stdout.flush()
+                
+            if createDir == True:
+                os.chdir("..")
+        else:
+            print "WARNING: empty input file - no cluster found"; sys.stdout.flush()
+                
+
+    ## Filter a fasta file in two fasta files using the length of each sequence as a criteron
+    #
+    # @param len_min integer    length sequence criterion to filter
+    # @param inFileName string  name of the input fasta file
+    # @param verbose integer (default = 0)      
+    #
+    @staticmethod
+    def dbLengthFilter( len_min, inFileName, verbose=0 ):
+        file_db = open( inFileName, "r" )
+        file_dbInf = open( inFileName+".Inf"+str(len_min), "w" )
+        file_dbSup = open( inFileName+".Sup"+str(len_min), "w" )
+        seq = Bioseq()
+        numseq = 0
+        nbsave = 0
+        
+        seq.read( file_db )
+        while seq.sequence:
+            l = seq.getLength()
+            numseq = numseq + 1
+            if l >= len_min:
+                seq.write( file_dbSup )
+                if verbose > 0:
+                        print 'sequence #',numseq,'=',l,'[',seq.header[0:40],'...] Sup !!'
+                        nbsave=nbsave+1
+            else:
+                seq.write( file_dbInf )
+                if verbose > 0:
+                        print 'sequence #',numseq,'=',l,'[',seq.header[0:40],'...] Inf !!'
+                        nbsave=nbsave+1
+            seq.read( file_db )
+                        
+        file_db.close()
+        file_dbInf.close()
+        file_dbSup.close()
+        if verbose > 0:
+            print nbsave,'saved sequences in ',inFileName+".Inf"+str(len_min)," and ", inFileName+".Sup"+str(len_min)
+            
+    
+    ## Extract the longest sequences from a fasta file
+    #
+    # @param num integer maximum number of sequences in the output file
+    # @param inFileName string name of the input fasta file
+    # @param outFileName string name of the output fasta file
+    # @param minThresh integer minimum length threshold (default=0)
+    # @param verbose integer (default = 0)
+    #
+    @staticmethod
+    def dbLongestSequences( num, inFileName, outFileName="", verbose=0, minThresh=0 ):
+        bsDB = BioseqDB( inFileName )
+        if verbose > 0:
+            print "nb of input sequences: %i" % ( bsDB.getSize() )
+    
+        if outFileName == "":
+            outFileName = inFileName + ".best" + str(num)
+        outFile = open( outFileName, "w" )
+        
+        if bsDB.getSize()==0:
+            return 0
+        
+        num = int(num)
+        if verbose > 0:
+            print "keep the %i longest sequences" % ( num )
+            if minThresh > 0:
+                print "with length > %i bp" % ( minThresh )
+            sys.stdout.flush()
+            
+        # retrieve the length of each input sequence
+        tmpLSeqLgth = []
+        seqNum = 0
+        for bs in bsDB.db:
+            seqNum += 1
+            tmpLSeqLgth.append( bs.getLength() )
+            if verbose > 1:
+                print "%d seq %s : %d bp" % ( seqNum, bs.header[0:40], bs.getLength() )
+            sys.stdout.flush()
+    
+        # sort the lengths
+        tmpLSeqLgth.sort()
+        tmpLSeqLgth.reverse()
+    
+        # select the longest
+        lSeqLgth = []
+        for i in xrange( 0, min(num,len(tmpLSeqLgth)) ):
+            if tmpLSeqLgth[i] >= minThresh:
+                lSeqLgth.append( tmpLSeqLgth[i] )
+        if verbose > 0:
+            print "selected max length: %i" % ( max(lSeqLgth) )
+            print "selected min length: %i" % ( min(lSeqLgth) )
+            sys.stdout.flush()
+    
+        # save the longest
+        inFile = open( inFileName )
+        seqNum = 0
+        nbSave = 0
+        for bs in bsDB.db:
+            seqNum += 1
+            if bs.getLength() >= min(lSeqLgth) and bs.getLength() >= minThresh:
+                bs.write( outFile )
+                if verbose > 1:
+                    print "%d seq %s : saved !" % ( seqNum, bs.header[0:40] )
+                    sys.stdout.flush()
+                nbSave += 1
+            if nbSave == num:
+                break
+        inFile.close()
+        outFile.close()
+        if verbose > 0:
+            print nbSave, "saved sequences in ", outFileName
+            sys.stdout.flush()
+            
+        return 0
+    
+    
+    ## Extract all the sequence headers from a fasta file and write them in a new fasta file
+    #
+    # @param inFileName string name of the input fasta file
+    # @param outFileName string name of the output file recording the headers (default = inFileName + '.headers')
+    #
+    @staticmethod
+    def dbExtractSeqHeaders( inFileName, outFileName="" ):
+        lHeaders = FastaUtils.dbHeaders( inFileName )
+        
+        if outFileName == "":
+            outFileName = inFileName + ".headers"
+            
+        outFile = open( outFileName, "w" )
+        for i in lHeaders:
+            outFile.write( i + "\n" )
+        outFile.close()
+    
+        return 0
+    
+    
+    ## Extract sequences and their headers selected by a given pattern from a fasta file and write them in a new fasta file
+    #
+    # @param pattern regular expression to search in headers
+    # @param inFileName string name of the input fasta file
+    # @param outFileName string name of the output file recording the selected bioseq (default = inFileName + '.extracted')
+    # @param verbose integer verbosity level (default = 0)
+    #
+    @staticmethod
+    def dbExtractByPattern( pattern, inFileName, outFileName="", verbose=0 ):
+        if pattern == "":
+            return
+        
+        if outFileName == "":
+            outFileName = inFileName + '.extracted'
+        outFile = open( outFileName, 'w' )
+        
+        patternTosearch = re.compile( pattern )
+        bioseq = Bioseq()
+        bioseqNb = 0
+        savedBioseqNb = 0
+        inFile = open( inFileName, "r" )
+        bioseq.read( inFile )
+        while bioseq.sequence:
+            bioseqNb = bioseqNb + 1
+            m = patternTosearch.search( bioseq.header )
+            if m:
+                bioseq.write( outFile )
+                if verbose > 1:
+                    print 'sequence num',bioseqNb,'matched on',m.group(),'[',bioseq.header[0:40],'...] saved !!'
+                savedBioseqNb = savedBioseqNb + 1
+            bioseq.read( inFile )
+        inFile.close()
+        
+        outFile.close()
+        
+        if verbose > 0:
+            print "%i sequences saved in file '%s'" % ( savedBioseqNb, outFileName )
+            
+    
+    ## Extract sequences and their headers selected by patterns contained in a file, from a fasta file and write them in a new fasta file
+    #
+    # @param patternFileName string file containing regular expression to search in headers
+    # @param inFileName string name of the input fasta file
+    # @param outFileName string name of the output file recording the selected bioseq (default = inFileName + '.extracted')
+    # @param verbose integer verbosity level (default = 0)
+    #
+    @staticmethod
+    def dbExtractByFilePattern( patternFileName, inFileName, outFileName="", verbose=0 ):
+    
+        if patternFileName == "":
+            print "ERROR: no file of pattern"
+            sys.exit(1)
+    
+        bioseq = Bioseq()
+        bioseqNb = 0
+        savedBioseqNb = 0
+        lHeaders = []
+
+        inFile = open( inFileName, "r" )
+        bioseq.read( inFile )
+        while bioseq.sequence != None:
+            lHeaders.append( bioseq.header )
+            bioseq.read( inFile )
+        inFile.close()
+    
+        lHeadersToKeep = []
+        patternFile = open( patternFileName, "r" )
+        for pattern in patternFile:
+            if verbose > 0:
+                print "pattern: ",pattern[:-1]; sys.stdout.flush()
+                
+            patternToSearch = re.compile(pattern[:-1])
+            for h in lHeaders:
+                if patternToSearch.search(h):
+                    lHeadersToKeep.append(h)
+        patternFile.close()
+    
+        if outFileName == "":
+            outFileName = inFileName + ".extracted"
+        outFile=open( outFileName, "w" )
+    
+        inFile = open( inFileName, "r" )
+        bioseq.read(inFile)
+        while bioseq.sequence:
+            bioseqNb += 1
+            if bioseq.header in lHeadersToKeep:
+                bioseq.write(outFile)
+                if verbose > 1:
+                    print 'sequence num',bioseqNb,'[',bioseq.header[0:40],'...] saved !!'; sys.stdout.flush()
+                savedBioseqNb += 1
+            bioseq.read(inFile)
+        inFile.close()
+    
+        outFile.close()
+        
+        if verbose > 0:
+            print "%i sequences saved in file '%s'" % ( savedBioseqNb, outFileName )
+            
+    
+    ## Extract sequences and their headers not selected by a given pattern from a fasta file and write them in a new fasta file
+    #
+    # @param pattern regular expression to search in headers
+    # @param inFileName string name of the input fasta file
+    # @param outFileName string name of the output file recording the selected bioseq (default = inFileName + '.extracted')
+    # @param verbose integer verbosity level (default = 0)
+    #
+    @staticmethod
+    def dbCleanByPattern( pattern, inFileName, outFileName="", verbose=0 ):
+        if pattern == "":
+            return
+        
+        patternToSearch = re.compile(pattern)
+        
+        if outFileName == "":
+            outFileName = inFileName + '.cleaned'
+        outFile = open(outFileName,'w')
+        
+        bioseq = Bioseq()
+        bioseqNb = 0
+        savedBioseqNb = 0
+        inFile = open(inFileName)
+        bioseq.read(inFile)
+        while bioseq.sequence != None:
+            bioseqNb += 1
+            if not patternToSearch.search(bioseq.header):
+                bioseq.write(outFile)
+                if verbose > 1:
+                    print 'sequence num',bioseqNb,'[',bioseq.header[0:40],'...] saved !!'
+                savedBioseqNb += 1
+            bioseq.read(inFile)
+        inFile.close()
+        
+        outFile.close()
+        
+        if verbose > 0:
+            print "%i sequences saved in file '%s'" % ( savedBioseqNb, outFileName )
+            
+    
+    ## Extract sequences and their headers not selected by patterns contained in a file, from a fasta file and write them in a new fasta file
+    #
+    # @param patternFileName string file containing regular expression to search in headers
+    # @param inFileName string name of the input fasta file
+    # @param outFileName string name of the output file recording the selected bioseq (default = inFileName + '.extracted')
+    # @param verbose integer verbosity level (default = 0)
+    #
+    @staticmethod
+    def dbCleanByFilePattern( patternFileName, inFileName, outFileName="", verbose=0 ):
+        if patternFileName == "":
+            print "ERROR: no file of pattern"
+            sys.exit(1)
+            
+        bioseq = Bioseq()
+        bioseqNb = 0
+        savedBioseqNb = 0
+        lHeaders = []
+        inFile = open( inFileName, "r" )
+        bioseq.read( inFile )
+        while bioseq.sequence != None:
+            bioseqNb += 1
+            lHeaders.append( bioseq.header )
+            bioseq.read( inFile )
+        inFile.close()
+        
+        patternFile = open( patternFileName, "r")
+        lHeadersToRemove = []
+        for pattern in patternFile:
+            if verbose > 0:
+                print "pattern: ",pattern[:-1]; sys.stdout.flush()
+                
+            patternToSearch = re.compile( pattern[:-1] )
+            for h in lHeaders:
+                if patternToSearch.search(h):
+                    lHeadersToRemove.append(h)
+        patternFile.close()
+        
+        if outFileName == "":
+            outFileName = inFileName + '.cleaned'
+        outFile = open( outFileName, 'w' )
+    
+        bioseqNum = 0
+        inFile=open( inFileName )
+        bioseq.read( inFile )
+        while bioseq.sequence != None:
+            bioseqNum += 1
+            if bioseq.header not in lHeadersToRemove:
+                bioseq.write( outFile )
+                if verbose > 1:
+                    print 'sequence num',bioseqNum,'/',bioseqNb,'[',bioseq.header[0:40],'...] saved !!'; sys.stdout.flush()
+                savedBioseqNb += 1
+            bioseq.read( inFile )
+        inFile.close()
+        
+        outFile.close()
+        
+        if verbose > 0:
+            print "%i sequences saved in file '%s'" % ( savedBioseqNb, outFileName )
+            
+    
+    ## Find sequence's ORFs from a fasta file and write them in a tab file 
+    # 
+    # @param inFileName string name of the input fasta file
+    # @param orfMaxNb integer Select orfMaxNb best ORFs
+    # @param orfMinLength integer Keep ORFs with length > orfMinLength 
+    # @param outFileName string name of the output fasta file (default = inFileName + '.orf.map')
+    # @param verbose integer verbosity level (default = 0)
+    #
+    @staticmethod
+    def dbORF( inFileName, orfMaxNb = 0, orfMinLength = 0, outFileName = "", verbose=0 ):
+        if outFileName == "":
+            outFileName = inFileName + ".ORF.map"
+        outFile = open( outFileName, "w" )
+    
+        bioseq = Bioseq()
+        bioseqNb = 0
+    
+        inFile = open( inFileName )
+        bioseq.read( inFile )
+        while bioseq.sequence != None:
+            bioseq.upCase() 
+            bioseqNb += 1
+            if verbose > 0:
+                print 'sequence num',bioseqNb,'=',bioseq.getLength(),'[',bioseq.header[0:40],'...]'
+                
+            orf = bioseq.findORF()
+            bestOrf = []
+            for i in orf.keys():
+                orfLen = len(orf[i])
+                for j in xrange(1, orfLen):
+                    start = orf[i][j-1] + 4
+                    end = orf[i][j] + 3
+                    if end - start >= orfMinLength:
+                        bestOrf.append( ( end-start, i+1, start, end ) )
+    
+            bioseq.reverseComplement()
+            
+            orf = bioseq.findORF()
+            seqLen = bioseq.getLength()
+            for i in orf.keys():
+                orfLen = len(orf[i])
+                for j in xrange(1, orfLen):
+                    start = seqLen - orf[i][j-1] - 3
+                    end = seqLen - orf[i][j] - 2
+                    if start - end >= orfMinLength:
+                        bestOrf.append( ( start-end, (i+1)*-1, start, end ) )
+    
+            bestOrf.sort()
+            bestOrf.reverse()
+            bestOrfNb = len(bestOrf)
+            if orfMaxNb != 0 and orfMaxNb < bestOrfNb:
+                bestOrfNb = orfMaxNb
+            for i in xrange(0, bestOrfNb):
+                if verbose > 0:
+                    print bestOrf[i]
+                outFile.write("%s\t%s\t%d\t%d\n"%("ORF|"+str(bestOrf[i][1])+\
+                                   "|"+str(bestOrf[i][0]),bioseq.header,
+                                   bestOrf[i][2],bestOrf[i][3]))
+            bioseq.read( inFile )
+    
+        inFile.close()
+        outFile.close()
+    
+        return 0
+
+
+    ## Sort sequences by increasing length (write a new file)
+    #
+    # @param inFileName string name of the input fasta file
+    # @param outFileName string name of the output fasta file
+    # @param verbose integer verbosity level   
+    #
+    @staticmethod
+    def sortSequencesByIncreasingLength(inFileName, outFileName, verbose=0):
+        if verbose > 0:
+            print "sort sequences by increasing length"
+            sys.stdout.flush()
+        if not os.path.exists( inFileName ):
+            print "ERROR: file '%s' doesn't exist" % ( inFileName )
+            sys.exit(1)
+            
+        # read each seq one by one
+        # save them in distinct temporary files
+        # with their length in the name
+        inFileHandler = open( inFileName, "r" )
+        countSeq = 0
+        bs = Bioseq()
+        bs.read( inFileHandler )
+        while bs.header:
+            countSeq += 1
+            tmpFile = "%ibp_%inb" % ( bs.getLength(), countSeq )
+            bs.appendBioseqInFile( tmpFile )
+            if verbose > 1:
+                print "%s (%i bp) saved in '%s'" % ( bs.header, bs.getLength(), tmpFile )
+            bs.header = ""
+            bs.sequence = ""
+            bs.read( inFileHandler )
+        inFileHandler.close()
+        
+        # sort temporary file names
+        # concatenate them into the output file
+        if os.path.exists( outFileName ):
+            os.remove( outFileName )
+        lFiles = glob.glob( "*bp_*nb" )
+        lFiles.sort( key=lambda s:int(s.split("bp_")[0]) )
+        for fileName in lFiles:
+            cmd = "cat %s >> %s" % ( fileName, outFileName )
+            returnValue = os.system( cmd )
+            if returnValue != 0:
+                print "ERROR while concatenating '%s' with '%s'" % ( fileName, outFileName )
+                sys.exit(1)
+            os.remove( fileName )
+            
+        return 0
+
+    
+    ## Sort sequences by header
+    #
+    # @param inFileName string name of the input fasta file
+    # @param outFileName string name of the output fasta file
+    # @param verbose integer verbosity level   
+    #
+    @staticmethod
+    def sortSequencesByHeader(inFileName, outFileName = "", verbose = 0):
+        if outFileName == "":
+            outFileName = "%s_sortByHeaders.fa" % os.path.splitext(inFileName)[0]
+        iBioseqDB = BioseqDB(inFileName)
+        f = open(outFileName, "w")
+        lHeaders = sorted(iBioseqDB.getHeaderList())
+        for header in lHeaders:
+            iBioseq = iBioseqDB.fetch(header)
+            iBioseq.write(f)
+        f.close()
+
+    
+    ## Return a dictionary which keys are the headers and values the length of the sequences
+    #
+    # @param inFile string name of the input fasta file
+    # @param verbose integer verbosity level   
+    #
+    @staticmethod
+    def getLengthPerHeader( inFile, verbose=0 ):
+        dHeader2Length = {}
+        
+        inFileHandler = open( inFile, "r" )
+        currentSeqHeader = ""
+        currentSeqLength = 0
+        line = inFileHandler.readline()
+        while line:
+            if line[0] == ">":
+                if currentSeqHeader != "":
+                    dHeader2Length[ currentSeqHeader ] = currentSeqLength
+                    currentSeqLength = 0
+                currentSeqHeader = line[1:-1]
+                if verbose > 0:
+                    print "current header: %s" % ( currentSeqHeader )
+                    sys.stdout.flush()
+            else:
+                currentSeqLength += len( line.replace("\n","") )
+            line = inFileHandler.readline()
+        dHeader2Length[ currentSeqHeader ] = currentSeqLength
+        inFileHandler.close()
+        
+        return dHeader2Length
+    
+    
+    ## Convert headers from a fasta file having chunk coordinates
+    #
+    # @param inFile string name of the input fasta file
+    # @param mapFile string name of the map file with the coordinates of the chunks on the chromosomes
+    # @param outFile string name of the output file
+    #
+    @staticmethod
+    def convertFastaHeadersFromChkToChr(inFile, mapFile, outFile):
+        inFileHandler = open(inFile, "r")
+        outFileHandler = open(outFile, "w")
+        dChunk2Map = MapUtils.getDictPerNameFromMapFile(mapFile)
+        iConvCoord = ConvCoord()
+        line = inFileHandler.readline()
+        while line:
+            if line[0] == ">":
+                if "{Fragment}" in line:
+                    chkName = line.split(" ")[1]
+                    chrName = dChunk2Map[chkName].seqname
+                    lCoordPairs = line.split(" ")[3].split(",")
+                    lRangesOnChk = []
+                    for i in lCoordPairs:
+                        iRange = Range(chkName, int(i.split("..")[0]), int(i.split("..")[1]))
+                        lRangesOnChk.append(iRange)
+                    lRangesOnChr = []
+                    for iRange in lRangesOnChk:
+                        lRangesOnChr.append(iConvCoord.getRangeOnChromosome(iRange, dChunk2Map))
+                    newHeader = line[1:-1].split(" ")[0]
+                    newHeader += " %s" % chrName
+                    newHeader += " {Fragment}"
+                    newHeader += " %i..%i" % (lRangesOnChr[0].start, lRangesOnChr[0].end)
+                    for iRange in lRangesOnChr[1:]:
+                        newHeader += ",%i..%i" % (iRange.start, iRange.end)
+                    outFileHandler.write(">%s\n" % newHeader)
+                else:
+                    chkName = line.split("_")[1].split(" ")[0]
+                    chrName = dChunk2Map[chkName].seqname
+                    coords = line[line.find("[")+1 : line.find("]")]
+                    start = int(coords.split(",")[0])
+                    end = int(coords.split(",")[1])
+                    iRangeOnChk = Range(chkName, start, end)
+                    iRangeOnChr = iConvCoord.getRangeOnChromosome(iRangeOnChk, dChunk2Map)
+                    newHeader = line[1:-1].split("_")[0]
+                    newHeader += " %s" % chrName
+                    newHeader += " %s" % line[line.find("(") : line.find(")")+1]
+                    newHeader += " %i..%i" % (iRangeOnChr.getStart(), iRangeOnChr.getEnd())
+                    outFileHandler.write(">%s\n" % newHeader)
+            else:
+                outFileHandler.write(line)
+            line = inFileHandler.readline()
+        inFileHandler.close()
+        outFileHandler.close()
+        
+    
+    ## Convert a fasta file to a length file
+    #
+    # @param inFile string name of the input fasta file
+    # @param outFile string name of the output file
+    #
+    @staticmethod
+    def convertFastaToLength(inFile, outFile = ""):
+        if outFile == "":
+            outFile = "%s.length" % inFile
+        
+        if inFile != "":
+            with open(inFile, "r") as inFH:
+                with open(outFile, "w") as outFH:
+                    bioseq = Bioseq()
+                    bioseq.read(inFH)
+                    while bioseq.sequence != None:
+                        seqLen = bioseq.getLength()
+                        outFH.write("%s\t%d\n" % (bioseq.header.split()[0], seqLen))
+                        bioseq.read(inFH)
+
+    
+    ## Convert a fasta file to a seq file
+    #
+    # @param inFile string name of the input fasta file
+    # @param outFile string name of the output file
+    #
+    @staticmethod
+    def convertFastaToSeq(inFile, outFile = ""):
+        if outFile == "":
+            outFile = "%s.seq" % inFile
+        
+        if inFile != "":
+            with open(inFile, "r") as inFH:
+                with open(outFile, "w") as outFH:
+                    bioseq = Bioseq()
+                    bioseq.read(inFH)
+                    while bioseq.sequence != None:
+                        seqLen = bioseq.getLength()
+                        outFH.write("%s\t%s\t%s\t%d\n" % (bioseq.header.split()[0], \
+                                                bioseq.sequence, bioseq.header, seqLen))
+                        bioseq.read(inFH)
+
+
+    ## Splice an input fasta file using coordinates in a Map file
+    #
+    # @note the coordinates should be merged beforehand!
+    #
+    @staticmethod
+    def spliceFromCoords( genomeFile, coordFile, obsFile ):
+        genomeFileHandler = open( genomeFile, "r" )
+        obsFileHandler = open( obsFile, "w" )
+        dChr2Maps = MapUtils.getDictPerSeqNameFromMapFile( coordFile )
+            
+        bs = Bioseq()
+        bs.read( genomeFileHandler )
+        while bs.sequence:
+            if dChr2Maps.has_key( bs.header ):
+                lCoords = MapUtils.getMapListSortedByIncreasingMinThenMax( dChr2Maps[ bs.header ] )
+                splicedSeq = ""
+                currentSite = 0
+                for iMap in lCoords:
+                    minSplice = iMap.getMin() - 1
+                    if minSplice > currentSite:
+                        splicedSeq += bs.sequence[ currentSite : minSplice ]
+                    currentSite = iMap.getMax()
+                splicedSeq += bs.sequence[ currentSite : ]
+                bs.sequence = splicedSeq
+            bs.write( obsFileHandler )
+            bs.read( genomeFileHandler )
+            
+        genomeFileHandler.close()
+        obsFileHandler.close()
+        
+    
+    ## Shuffle input sequences (single file or files in a directory)
+    #
+    @staticmethod
+    def dbShuffle( inData, outData, verbose=0 ):
+        if CheckerUtils.isExecutableInUserPath("esl-shuffle"):
+            prg = "esl-shuffle"
+        else : prg = "shuffle"
+        genericCmd = prg + " -d INPUT > OUTPUT"
+        if os.path.isfile( inData ):
+            if verbose > 0:
+                print "shuffle input file '%s'" % inData
+            cmd = genericCmd.replace("INPUT",inData).replace("OUTPUT",outData)
+            print cmd
+            returnStatus = os.system( cmd )
+            if returnStatus != 0:
+                sys.stderr.write( "ERROR: 'shuffle' returned '%i'\n" % returnStatus )
+                sys.exit(1)
+                
+        elif os.path.isdir( inData ):
+            if verbose > 0:
+                print "shuffle files in input directory '%s'" % inData
+            if os.path.exists( outData ):
+                shutil.rmtree( outData )
+            os.mkdir( outData )
+            lInputFiles = glob.glob( "%s/*.fa" %( inData ) )
+            nbFastaFiles = 0
+            for inputFile in lInputFiles:
+                nbFastaFiles += 1
+                if verbose > 1:
+                    print "%3i / %3i" % ( nbFastaFiles, len(lInputFiles) )
+                fastaBaseName = os.path.basename( inputFile )
+                prefix, extension = os.path.splitext( fastaBaseName )
+                cmd = genericCmd.replace("INPUT",inputFile).replace("OUTPUT","%s/%s_shuffle.fa"%(outData,prefix))
+                returnStatus = os.system( cmd )
+                if returnStatus != 0:
+                    sys.stderr.write( "ERROR: 'shuffle' returned '%i'\n" % returnStatus )
+                    sys.exit(1)
+                    
+    
+    ## Convert a cluster file (one line = one cluster = one headers list) into a fasta file with cluster info in headers
+    #
+    # @param inClusterFileName string input cluster file name
+    # @param inFastaFileName string input fasta file name
+    # @param outFileName string output file name
+    # @param verbosity integer verbosity
+    #
+    @staticmethod
+    def convertClusterFileToFastaFile(inClusterFileName, inFastaFileName, outFileName, clusteringTool = "", verbosity = 0):
+        dHeader2ClusterClusterMember, clusterIdForSingletonCluster = FastaUtils._createHeader2ClusterMemberDict(inClusterFileName, verbosity)
+        iFastaParser = FastaParser(inFastaFileName)
+        with open(outFileName, "w") as f:
+            for iSequence in iFastaParser.getIterator():
+                
+                header = iSequence.getName()
+                if dHeader2ClusterClusterMember.get(header):
+                    cluster = dHeader2ClusterClusterMember[header][0]
+                    member = dHeader2ClusterClusterMember[header][1]
+                else:
+                    clusterIdForSingletonCluster +=  1
+                    cluster = clusterIdForSingletonCluster
+                    member = 1
+                
+                newHeader = "%sCluster%sMb%s_%s" % (clusteringTool, cluster, member, header)
+                iSequence.setName(newHeader)
+                f.write(iSequence.printFasta())
+              
+    @staticmethod      
+    def _createHeader2ClusterMemberDict(inClusterFileName, verbosity = 0):
+        dHeader2ClusterClusterMember = {}
+        clusterId = 0
+        with open(inClusterFileName) as f:
+            line = f.readline()
+            while line:
+                lineWithoutLastChar = line.rstrip()
+                lHeaders = lineWithoutLastChar.split("\t")
+                clusterId += 1
+                if verbosity > 0:
+                    print "%i sequences in cluster %i" % (len(lHeaders), clusterId)
+                memberId = 0
+                for header in lHeaders:
+                    memberId += 1
+                    dHeader2ClusterClusterMember[header] = (clusterId, memberId)
+                line = f.readline()
+            if verbosity > 0:
+                print "%i clusters" % clusterId
+        return dHeader2ClusterClusterMember, clusterId
+    
+    @staticmethod     
+    def convertClusteredFastaFileToMapFile(fastaFileNameFromClustering, outMapFileName = ""):
+        """
+        Write a map file from fasta output of clustering tool.
+        Warning: only works if input fasta headers are formated like LTRharvest fasta output.
+        """
+        if not outMapFileName:
+            outMapFileName = "%s.map" % (os.path.splitext(fastaFileNameFromClustering)[0])
+        
+        fileDb = open(fastaFileNameFromClustering , "r")
+        fileMap = open(outMapFileName, "w")
+        seq = Bioseq()
+        numseq = 0
+        while 1:
+            seq.read(fileDb)
+            if seq.sequence == None:
+                break
+            numseq = numseq + 1
+            ID = seq.header.split(' ')[0].split('_')[0]
+            chunk = seq.header.split(' ')[0].split('_')[1]
+            start = seq.header.split(' ')[-1].split(',')[0][1:]
+            end = seq.header.split(' ')[-1].split(',')[1][:-1]
+            line = '%s\t%s\t%s\t%s' % (ID, chunk, start, end)
+            fileMap.write(line + "\n")
+    
+        fileDb.close()
+        fileMap.close()
+        print "saved in %s" % outMapFileName
+ 
\ No newline at end of file
Binary file smart_toolShed/commons/core/seq/__init__.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/seq/test/TestClusterConsensusCollection.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,67 @@
+import unittest
+import os
+from commons.core.seq.ClusterConsensusCollection import ClusterConsensusCollection
+from commons.core.seq.Bioseq import Bioseq
+from commons.core.seq.BioseqDB import BioseqDB
+
+class TestClusterConsensusCollection(unittest.TestCase):
+
+    def setUp(self):
+        self._clusterSequencesFileName = "clusterSequences.fa"
+        self._ClusterConsensusCollection = ClusterConsensusCollection(self._clusterSequencesFileName)
+        self._createClusterConsensusFile()
+
+    def tearDown(self):
+        os.remove(self._clusterSequencesFileName)
+        
+    def test_fillCollection(self):
+        expClusterConsensusCollection = ClusterConsensusCollection(self._clusterSequencesFileName)
+        expClusterConsensusCollection._clusterFileName = self._clusterSequencesFileName
+        bioseq1 = Bioseq("seq1", "ACCAAAGACACTAGAATAACAAGATGCGTAACGCCATACGATTTTTTGGCACACTATTTT")
+        bioseq2 = Bioseq("seq2", "ACCAAAGACACTAGAATAACAAGATGCGTAACGCCATACGATTTTTTGGCACACTATTTT")
+        bioseq3 = Bioseq("seq3", "ACCAAAGACACTAGAATAACAAGATGCGTAACGCCATACGATTTTTTGGCACACTATTTT")
+        iBioseqDB1 = BioseqDB()
+        iBioseqDB2 = BioseqDB()
+        iBioseqDB1.setData([bioseq1, bioseq2])
+        iBioseqDB2.setData([bioseq3])
+        expClusterConsensusCollection._lClusterConsensus = [iBioseqDB1, iBioseqDB2]
+        self._ClusterConsensusCollection.fillCollection()
+        self.assertEqual(expClusterConsensusCollection, self._ClusterConsensusCollection)
+        
+    def test_getNumClusterForAConsensus_for_seq2(self):
+        self._ClusterConsensusCollection.fillCollection()
+        expClusterNumber = 1
+        obsClusterNumber = self._ClusterConsensusCollection.getNumClusterForAConsensus ("seq2")
+        self.assertEqual(expClusterNumber, obsClusterNumber)
+        
+    def test_getNumClusterForAConsensus_for_seq3(self):
+        self._ClusterConsensusCollection.fillCollection()
+        expClusterNumber = 2
+        obsClusterNumber = self._ClusterConsensusCollection.getNumClusterForAConsensus ("seq3")
+        self.assertEqual(expClusterNumber, obsClusterNumber)
+        
+    def test_getNumConsensusInCluster_1(self):
+        self._ClusterConsensusCollection.fillCollection()
+        expConsensusNumber = 2
+        obsConsensusNumber = self._ClusterConsensusCollection.getNumConsensusInCluster (1)
+        self.assertEqual(expConsensusNumber, obsConsensusNumber)
+        
+    def test_getNumConsensusInCluster_2(self):
+        self._ClusterConsensusCollection.fillCollection()
+        expConsensusNumber = 1
+        obsConsensusNumber = self._ClusterConsensusCollection.getNumConsensusInCluster (2)
+        self.assertEqual(expConsensusNumber, obsConsensusNumber)
+    
+    def _createClusterConsensusFile(self):
+        fCluster = open(self._clusterSequencesFileName, "w")
+        fCluster.write(">BlastclustCluster1Mb1 seq1\n")
+        fCluster.write("ACCAAAGACACTAGAATAACAAGATGCGTAACGCCATACGATTTTTTGGCACACTATTTT\n")
+        fCluster.write(">BlastclustCluster1Mb2 seq2\n")
+        fCluster.write("ACCAAAGACACTAGAATAACAAGATGCGTAACGCCATACGATTTTTTGGCACACTATTTT\n")
+        fCluster.write(">BlasterGrouperCluster3Mb1 seq3\n")
+        fCluster.write("ACCAAAGACACTAGAATAACAAGATGCGTAACGCCATACGATTTTTTGGCACACTATTTT\n")
+        fCluster.close()
+
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/seq/test/TestSuite_seq.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import sys
+import Test_AlignedBioseqDB
+import Test_Bioseq
+import Test_BioseqDB
+import Test_BioseqUtils
+import Test_FastaUtils
+
+
+def main():
+    
+        TestSuite_seq = unittest.TestSuite()
+        
+        TestSuite_seq.addTest( unittest.makeSuite( Test_AlignedBioseqDB.Test_AlignedBioseqDB, "test" ) )
+        TestSuite_seq.addTest( unittest.makeSuite( Test_Bioseq.Test_Bioseq, "test" ) )
+        TestSuite_seq.addTest( unittest.makeSuite( Test_BioseqDB.Test_BioseqDB, "test" ) )
+        TestSuite_seq.addTest( unittest.makeSuite( Test_BioseqUtils.Test_BioseqUtils, "test" ) )
+        TestSuite_seq.addTest( unittest.makeSuite( Test_FastaUtils.Test_FastaUtils, "test" ) )
+        
+        runner = unittest.TextTestRunner( sys.stderr, 2, 2 )
+        runner.run( TestSuite_seq )
+
+      
+if __name__ == "__main__":
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/seq/test/Test_AlignedBioseqDB.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,773 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import sys
+import os
+import time
+from commons.core.seq.AlignedBioseqDB import AlignedBioseqDB
+from commons.core.seq.Bioseq import Bioseq
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.coord.Align import Align
+from commons.core.coord.Range import Range
+from commons.core.stat.Stat import Stat
+
+
+class Test_AlignedBioseqDB( unittest.TestCase ):
+    
+    def setUp( self ):
+        self._i = AlignedBioseqDB()
+        self._uniqId = "%s_%s" % ( time.strftime("%Y%m%d%H%M%S") , os.getpid() )
+        
+        
+    def tearDown( self ):
+        self._i = None
+        self._uniqId = ""
+        
+        
+    def test_getLength(self):
+        iAlignedBioseqDB = AlignedBioseqDB()
+
+        iBioseq1 = Bioseq( "seq1", "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        iAlignedBioseqDB.setData([iBioseq1])
+        
+        expLenght = 29
+        obsLength = iAlignedBioseqDB.getLength() 
+
+        self.assertEquals(expLenght, obsLength)
+        
+        
+    def test_getSeqLengthWithoutGaps( self ):
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.add( Bioseq( "seq3",
+                                      "AGCG-GACGATGCAGCAT--GCGAATGA--CGAT" ) )
+        expLenght = 29
+        obsLength = iAlignedBioseqDB.getSeqLengthWithoutGaps( "seq3" )
+        
+        self.assertEquals(expLenght, obsLength)
+        
+        
+    def test_getListOccPerSite(self):
+        iBioseq1 = Bioseq( "seq1", "AGAAA")
+        iBioseq2 = Bioseq( "seq2", "TCAAG")
+        iBioseq3 = Bioseq( "seq3", "GGTAC")
+        iBioseq4 = Bioseq( "seq4", "CCTTA")
+        
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3, iBioseq4])
+
+        expList = [
+                
+                {"A":1, "T":1, "G":1, "C":1},
+
+                {"G":2, "C":2},
+                   
+                {"A":2, "T":2 },
+                
+                {"A":3, "T":1 },   
+                
+                {"A":2, "G":1, "C":1}
+            ]
+                
+        obsList = iAlignedBioseqDB.getListOccPerSite()
+       
+        self.assertEquals(expList, obsList)
+        
+        
+    def test_getListOccPerSite_with_none_sequence(self):
+        iBioseq1 = Bioseq( "seq1", "AGAAA")
+        iBioseq2 = Bioseq( "seq2", "TCAAG")
+        iBioseq3 = Bioseq( "seq3", "GGTAC")
+        iBioseq4 = Bioseq( "seq4", None)
+        iBioseq5 = Bioseq( "seq5", "CCTTA")
+        
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3, iBioseq4, iBioseq5])
+
+        expList = [
+                {"A":1, "T":1, "G":1},
+                {"G":2, "C":1},
+                {"A":2, "T":1 },
+                {"A":3},   
+                {"A":1, "G":1, "C":1},
+            ]
+        
+        obsList = iAlignedBioseqDB.getListOccPerSite()
+        
+        self.assertEquals(expList, obsList)
+        
+        
+    def test_getListOccPerSite_on_three_sequence(self):
+        iBioseq1 = Bioseq( "seq1", "AGAAA")
+        iBioseq2 = Bioseq( "seq2", "TCAAG")
+        iBioseq3 = Bioseq( "seq3", "GGTAC")
+        
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3])
+
+        expList = [
+                {"A":1, "T":1, "G":1},
+                {"G":2, "C":1},
+                {"A":2, "T":1 },
+                {"A":3},   
+                {"A":1, "G":1, "C":1},
+            ]
+        
+        obsList = iAlignedBioseqDB.getListOccPerSite()
+        
+        self.assertEquals(expList, obsList)
+        
+        
+    def test_getConsensus_with_minNbNt_greater_than_nbInSeq(self):
+        iBioseq1 = Bioseq("seq1", "AGAT")
+        iBioseq2 = Bioseq("seq2", "TGCA")
+        iBioseq3 = Bioseq("seq3", "TACT")
+        
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3])
+        
+        expConsensus = Bioseq("consensus= length=4 nbAlign=3","TGCT")
+        obsConsensus = iAlignedBioseqDB.getConsensus(5) 
+
+        self.assertEquals(expConsensus, obsConsensus)
+        
+        
+    def test_getConsensus_with_minPropNt_greater_than_1(self):
+        isSysExitRaised = False
+        
+        iBioseq1 = Bioseq("seq1", "AGAT")
+        iBioseq2 = Bioseq("seq2", "TGCA")
+        iBioseq3 = Bioseq("seq3", "TACT")
+        
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3])
+        
+        expFileName = "expFileName"
+        expFileHandler = open(expFileName,"w")
+        expMessage = "ERROR: minPropNt=2.00 should be a proportion (below 1.0)\n"
+        expFileHandler.write(expMessage)
+        expFileHandler.close()
+        
+        obsFileName = "obsFileName"
+        obsFileHandler = open(obsFileName,"w")
+        
+        stdoutRef = sys.stdout
+        sys.stdout = obsFileHandler
+        
+        try:
+            iAlignedBioseqDB.getConsensus(2,2)
+        except SystemExit:
+            isSysExitRaised = True
+        
+        obsFileHandler.close()
+        expFileHandler.close()
+
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        self.assertTrue( isSysExitRaised )
+        
+        sys.stdout = stdoutRef
+        os.remove ( obsFileName )
+        os.remove ( expFileName )
+        stdoutRef = sys.stdout
+        
+        
+    def test_getConsensus_with_AlignBioseqInstance_size_1(self):
+        isSysExitRaised = False
+        
+        iBioseq1 = Bioseq("seq1", "AGAT")
+        
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1])
+        
+        expFileName = "expFileName"
+        expFileHandler = open(expFileName,"w")
+        expMessage = "ERROR: can't make a consensus with less than 2 sequences\n"
+        expFileHandler.write(expMessage)
+        expFileHandler.close()
+        
+        obsFileName = "obsFileName"
+        obsFileHandler = open(obsFileName,"w")
+        
+        stdoutRef = sys.stdout
+        sys.stdout = obsFileHandler
+        
+        try:
+            iAlignedBioseqDB.getConsensus(4)
+        except SystemExit:
+            isSysExitRaised = True
+        
+        obsFileHandler.close()
+        expFileHandler.close()
+
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        self.assertTrue( isSysExitRaised )
+        
+        sys.stdout = stdoutRef
+        os.remove ( obsFileName )
+        os.remove ( expFileName )
+        stdoutRef = sys.stdout
+        
+        
+    def test_getConsensus_with_gap_assertion_on_warning_msg(self):
+        iBioseq1 = Bioseq("seq1", "A-GA-T")
+        iBioseq2 = Bioseq("seq2", "T-GC-A")
+        iBioseq3 = Bioseq("seq3", "T-AC-T")
+                          
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3])
+                          
+        expFileName = "expFileName"
+        expFileHandler = open(expFileName,"w")
+        expMessage = "WARNING: 2 sites were removed (33.33%)\n"
+        expFileHandler.write(expMessage)
+        expFileHandler.close()
+        
+        obsFileName = "obsFileName"
+        obsFileHandler = open(obsFileName,"w")
+        
+        stdoutRef = sys.stdout
+        sys.stdout = obsFileHandler
+       
+        iAlignedBioseqDB.getConsensus(2)
+        
+        obsFileHandler.close()
+        expFileHandler.close()
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        
+        sys.stdout = stdoutRef
+        os.remove ( obsFileName )
+        os.remove ( expFileName )
+        stdoutRef = sys.stdout
+        
+        
+    def test_getConsensus_with_gap_assertion_on_result(self):
+        iBioseq1 = Bioseq("seq1", "A-GA-T")
+        iBioseq2 = Bioseq("seq2", "T-GC-A")
+        iBioseq3 = Bioseq("seq3", "T-AC-T")
+                          
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3])
+        
+        expConsensus = Bioseq("consensus= length=4 nbAlign=3","TGCT")
+        obsConsensus = iAlignedBioseqDB.getConsensus(2) 
+
+        self.assertEquals(expConsensus, obsConsensus)
+        
+        
+    def test_getConsensus_with_gaps_and_no_consensus_built_assertion_on_result(self):
+        iBioseq1 = Bioseq("seq1", "A--A-T")
+        iBioseq2 = Bioseq("seq2", "----A-")
+        iBioseq3 = Bioseq("seq3", "--A---")
+                          
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3])
+        
+        expConsensus = None
+        obsConsensus = iAlignedBioseqDB.getConsensus(2)
+        self.assertEquals(expConsensus, obsConsensus)
+        
+        
+    def test_getConsensus_with_gaps_and_no_consensus_built_assertion_on_warning_messages(self):
+        iBioseq1 = Bioseq("seq1", "A--A-T")
+        iBioseq2 = Bioseq("seq2", "----A-")
+        iBioseq3 = Bioseq("seq3", "--A---")
+                          
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3])
+
+        expFileName = "expFileName"
+        expFileHandler = open(expFileName,"w")
+        expMessage1 = "WARNING: 1 site was removed (16.67%)\n"
+        expMessage2 = "WARNING: no consensus can be built (no sequence left)\n"
+        expFileHandler.write(expMessage1)
+        expFileHandler.write(expMessage2)
+        expFileHandler.close()
+        
+        obsFileName = "obsFileName"
+        obsFileHandler = open(obsFileName,"w")
+        
+        stdoutRef = sys.stdout
+        sys.stdout = obsFileHandler
+       
+        iAlignedBioseqDB.getConsensus(2)
+        
+        obsFileHandler.close()
+        expFileHandler.close()
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        
+        sys.stdout = stdoutRef
+        os.remove ( obsFileName )
+        os.remove ( expFileName )
+        stdoutRef = sys.stdout
+        
+        
+    def test_getConsensus_with_unacceptable_N_proportion_assertion_on_result(self):
+        iBioseq1 = Bioseq("seq1", "AGAT")
+        iBioseq2 = Bioseq("seq2", "CCCA")
+        iBioseq3 = Bioseq("seq3", "TTCT")
+        iBioseq4 = Bioseq("seq4", "TTAT")
+            
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3, iBioseq4])
+        
+        expConsensus = None
+        obsConsensus = iAlignedBioseqDB.getConsensus(2,0.75)
+         
+        self.assertEquals(expConsensus, obsConsensus) 
+        
+        
+    def test_getConsensus_with_unacceptable_N_proportion_assertion_on_warning_msg(self):
+        iBioseq1 = Bioseq("seq1", "AGAT")
+        iBioseq2 = Bioseq("seq2", "CCCA")
+        iBioseq3 = Bioseq("seq3", "TTCT")
+        iBioseq4 = Bioseq("seq4", "TTAT")
+            
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3, iBioseq4])
+        
+        expFileName = "expFileName"
+        expFileHandler = open(expFileName,"w")
+        expMessage = "WARNING: no consensus can be built (75% of N's >= 40%)\n"
+        expFileHandler.write(expMessage)
+        expFileHandler.close()
+        
+        obsFileName = "obsFileName"
+        obsFileHandler = open(obsFileName,"w")
+        
+        stdoutRef = sys.stdout
+        sys.stdout = obsFileHandler
+       
+        iAlignedBioseqDB.getConsensus(2,0.75)
+   
+        obsFileHandler.close()
+        expFileHandler.close()
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        
+        sys.stdout = stdoutRef
+        os.remove ( obsFileName )
+        os.remove ( expFileName )
+        stdoutRef = sys.stdout
+        
+        
+    def test_getConsensus_with_acceptable_N_proportion_assertion_on_warning_msg(self):
+        iBioseq1 = Bioseq("seq1", "AGATAA")
+        iBioseq2 = Bioseq("seq2", "CTCAAA")
+        iBioseq3 = Bioseq("seq3", "TTCTAA")
+        iBioseq4 = Bioseq("seq4", "GTATCC")
+                                   
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3, iBioseq4])
+        
+        expFileName = "expFileName"
+        expFileHandler = open(expFileName,"w")
+        expMessage = "WARNING: 33% of N's\n"
+        expFileHandler.write(expMessage)
+        expFileHandler.close()
+        
+        obsFileName = "obsFileName"
+        obsFileHandler = open(obsFileName,"w")
+        
+        stdoutRef = sys.stdout
+        sys.stdout = obsFileHandler
+        
+        iAlignedBioseqDB.getConsensus(2,0.6)
+        
+        obsFileHandler.close()
+        expFileHandler.close()
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        
+        sys.stdout = stdoutRef
+        os.remove ( obsFileName )
+        os.remove ( expFileName )
+        stdoutRef = sys.stdout
+        
+        
+    def test_getConsensus_with_acceptable_N_proportion_assertion_on_result(self):
+        iBioseq1 = Bioseq("seq1", "AGATAA")
+        iBioseq2 = Bioseq("seq2", "CTCAAA")
+        iBioseq3 = Bioseq("seq3", "TTCTAA")
+        iBioseq4 = Bioseq("seq4", "GTATCC")
+                                   
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3, iBioseq4])
+        
+        expConsensus = Bioseq("consensus= length=6 nbAlign=4","NTNTAA")
+        obsConsensus = iAlignedBioseqDB.getConsensus(2,0.6)
+         
+        self.assertEquals(expConsensus, obsConsensus)
+        
+        
+    def test_getConsensus_with_chimeric_seq_in_alignment(self):
+        iBioseq1 = Bioseq("seq1", "AGAGTTGTAA")
+        iBioseq2 = Bioseq("seq2", "ATC----AAA")
+        iBioseq3 = Bioseq("seq3", "ATC----TAA")
+        iBioseq4 = Bioseq("seq4", "GTC----TAA")
+                                   
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3, iBioseq4])
+        
+        expConsensus = Bioseq("consensus= length=6 nbAlign=4","ATCTAA")
+        obsConsensus = iAlignedBioseqDB.getConsensus(2)
+         
+        self.assertEquals(expConsensus, obsConsensus) 
+        
+
+    def test_getConsensus_with_SATannot_data(self):
+        iBioseq1 = Bioseq("MbS69Gr8Cl511 chunk21 {Fragment} 165740..165916", "--TTTAGCCGAAGTCCATATGAGTCTTTGTGTTTGTATCTTCTAACAAGGAAACACTACTTAGGCTTTTAGGATAAGATTGCGGTTTAAGTTCTTATACTCAATCATACACATGACATCAAGTCATATTCGAATCCAAAACTCTAAGCAAGCTTCTTCTTGCTTCTCAAA-GCTTTGATG")
+        iBioseq2 = Bioseq("MbS68Gr8Cl511 chunk21 {Fragment} 165916..166092", "GGTCTAGCCGAAGTCCATATGAGTCTTTGTCTTTGTATCTTCTAACAAGAAAACACTACTTAGGCTTTTAGGATAAGGTTGCAGTTTAAGTTTTTATACTAAATCATACACATCACATCAAGTCATATTCGACTCCCAAACACTAACCAAGCTTCTT--TGCTTCTCAAC-GCTTTGATG")
+        iBioseq3 = Bioseq("MbS67Gr8Cl511 chunk21 {Fragment} 166093..166269", "-GTTTAGCCGAAGTCCATATGAGTCGTTGTGTTTGTATCTTCTAACAAGGAAACACTACTTACGCTTTTAGGATAAGATTGTTGTTTAAGTTCTTATACTTAATCATACACATGACATAAAGTCATATTCGACTCCAAAACACTAATCAAGCTTCTTCTTGCTTCTCAAA-GCTTTGTT-")
+        iBioseq4 = Bioseq("MbS66Gr8Cl511 chunk21 {Fragment} 173353..173529", "--TTTAGCAAAATTCTATATGAGTCTTTATCTTTGTATCTTCTAACAAGGAAACACTACTTAGGCTTTTAGGATAAGGTTGCGGGTTAAGTTCTTATACTCAATCATACACATGATATCAAGTCATATTCGACTCCAAAACACTAACCAAGCTTCTTCTTGCTTCTTAAAAGCTTTGAA-")
+                                   
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3, iBioseq4])
+        
+        expConsensus = Bioseq("consensus= length=178 nbAlign=4 pile=511 pyramid=8", "GTTTAGCCGAAGTCCATATGAGTCTTTGTNTTTGTATCTTCTAACAAGGAAACACTACTTAGGCTTTTAGGATAAGNTTGCNGTTTAAGTTCTTATACTNAATCATACACATGACATCAAGTCATATTCGACTCCAAAACACTAANCAAGCTTCTTCTTGCTTCTCAAAGCTTTGATG")
+        obsConsensus = iAlignedBioseqDB.getConsensus(2, 0.6, isHeaderSAtannot=True)
+         
+        self.assertEquals(expConsensus, obsConsensus) 
+        
+        
+    def test_getEntropy_equal_zero(self):
+        iBioseq1 = Bioseq("seq1", "AGAT")
+        iBioseq2 = Bioseq("seq2", "AGAT")
+        iBioseq3 = Bioseq("seq3", "AGAT")
+        iBioseq4 = Bioseq("seq4", "AGAT")
+                                   
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3, iBioseq4])
+        
+        expStats = Stat()
+        expStats._min = 0
+        expStats._max = 0
+        expStats._sum = 0
+        expStats._sumOfSquares = 0
+        expStats._n = 4
+        expStats._lValues = [0, 0, 0, 0]
+        
+        obsStats = iAlignedBioseqDB.getEntropy()
+        
+        self.assertEquals(expStats, obsStats) 
+        
+        
+    def test_getEntropy_different_nucl(self):
+        iBioseq1 = Bioseq("seq1", "AGAT")
+        iBioseq2 = Bioseq("seq2", "CTCA")
+        iBioseq3 = Bioseq("seq3", "TTCT")
+        iBioseq4 = Bioseq("seq4", "GTAT")
+                                   
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3, iBioseq4])
+        
+        expStats = Stat()
+        expStats._min = 0.81127812445913283
+        expStats._max = 2.0
+        expStats._sum = 4.62255624892
+        expStats._sumOfSquares = 6.31634439045
+        expStats._n = 4
+        expStats._lValues = [2.0, 0.81127812445913283, 1.0, 0.81127812445913283]
+        
+        obsStats = iAlignedBioseqDB.getEntropy()
+        
+        self.assertEquals(expStats, obsStats)
+        
+        
+    def test_getEntropy_different_nucl_with_N(self):
+        iBioseq1 = Bioseq("seq1", "AGAT")
+        iBioseq2 = Bioseq("seq2", "CNCA")
+        iBioseq3 = Bioseq("seq3", "TTNT")
+        iBioseq4 = Bioseq("seq4", "GTNT")
+                                   
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3, iBioseq4])
+        
+        expStats = Stat()
+        expStats._min = 0.811278124459
+        expStats._max = 2
+        expStats._sum = 6.11387090595
+        expStats._sumOfSquares = 10.1629200457
+        expStats._n = 4
+        expStats._lValues = [2, 1.4913146570363986, 1.8112781244591329, 0.81127812445913283]
+        
+        obsStats = iAlignedBioseqDB.getEntropy()
+        
+        self.assertEquals(expStats, obsStats)
+        
+        
+    def test_getEntropy_different_nucl_with_gap(self):
+        iBioseq1 = Bioseq("seq1", "AGAT")
+        iBioseq2 = Bioseq("seq2", "C-CA")
+        iBioseq3 = Bioseq("seq3", "T--T")
+        iBioseq4 = Bioseq("seq4", "-TNT")
+                                   
+        iAlignedBioseqDB = AlignedBioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3, iBioseq4])
+        
+        expStats = Stat()
+        expStats._min = 0.811278124459
+        expStats._max = 1.65002242165
+        expStats._sum = 5.04626304683
+        expStats._sumOfSquares = 6.89285231586
+        expStats._n = 4
+        expStats._lValues = [1.5849625007211561, 1.0, 1.6500224216483541, 0.81127812445913283]
+        
+        obsStats = iAlignedBioseqDB.getEntropy()
+        
+        self.assertEquals(expStats, obsStats)
+        
+        
+    def test_saveAsBinaryMatrix( self ):
+        iBioseq1 = Bioseq("seq1", "AGAT")
+        iBioseq2 = Bioseq("seq2", "C-CA")
+        iBioseq3 = Bioseq("seq3", "T--T")
+        iBioseq4 = Bioseq("seq4", "-TNT")
+        
+        self._i.setData( [ iBioseq1, iBioseq2, iBioseq3, iBioseq4 ] )
+        
+        expFile = "dummyExpFile_%s" % ( self._uniqId )
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "seq1\t1\t1\t1\t1\n" )
+        expFileHandler.write( "seq2\t1\t0\t1\t1\n" )
+        expFileHandler.write( "seq3\t1\t0\t0\t1\n" )
+        expFileHandler.write( "seq4\t0\t1\t1\t1\n" )
+        expFileHandler.close()
+        
+        obsFile = "dummyObsFile_%s" % ( self._uniqId )
+        self._i.saveAsBinaryMatrix( obsFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        for f in [ expFile, obsFile ]:
+            os.remove( f )
+            
+            
+    def test_getAlignList( self ):
+        iBioseq1 = Bioseq( "seq1", "AGAAT" )
+        iBioseq2 = Bioseq( "seq2", "-G-AC" )
+        self._i.setData( [ iBioseq1, iBioseq2 ] )
+        
+        iAlign1 = Align( Range( "seq1", 2, 2 ),
+                         Range( "seq2", 1, 1 ),
+                         0, 1, 100 )
+        iAlign2 = Align( Range( "seq1", 4, 5 ),
+                         Range( "seq2", 2, 3 ),
+                         0, 1, 50 )
+        lExp = [ iAlign1, iAlign2 ]
+        
+        lObs = self._i.getAlignList( "seq1", "seq2" )
+        self.assertEquals( lExp, lObs )
+    
+    
+    def test_removeGaps(self):
+        iBioseq1 = Bioseq( "seq1", "AGAAT-" )
+        iBioseq2 = Bioseq( "seq2", "AG-ACG" )
+        self._i.setData( [ iBioseq1, iBioseq2 ] )
+        
+        exp = AlignedBioseqDB()
+        exp.setData( [ Bioseq( "seq1", "AGAAT" ), 
+                      Bioseq( "seq2", "AGACG" ) ] )
+        
+        self._i.removeGaps()
+        
+        self.assertEquals(exp, self._i)
+    
+    def test_computeMeanPcentIdentity_between_two_sequences_50pcent(self): 
+        iBioseq1 = Bioseq( "seq1", "AGAAT-" )
+        iBioseq2 = Bioseq( "seq2", "AG-ACG" )
+        self._i.setData( [ iBioseq1, iBioseq2 ] )
+        expIdentity = 50.0
+        obsIdentity = self._i.computeMeanPcentIdentity()
+        self.assertEquals(expIdentity, obsIdentity)
+  
+    def test_computeMeanPcentIdentity_between_two_sequences_57pcent(self): 
+        iBioseq1 = Bioseq( "seq1", "AGAAT-T" )
+        iBioseq2 = Bioseq( "seq2", "AG-ACGT" )
+        self._i.setData( [ iBioseq1, iBioseq2 ] )
+        expIdentity = 57.0
+        obsIdentity = self._i.computeMeanPcentIdentity()
+        self.assertEquals(expIdentity, obsIdentity)
+        
+    def test_compueNeamPcentIdentity_between_two_sequences_gaps_on_same_position(self):
+        iBioseq1 = Bioseq( "seq1", "AGAAT-T" )
+        iBioseq2 = Bioseq( "seq2", "AG-AC-T" )
+        self._i.setData( [ iBioseq1, iBioseq2 ] )
+        expIdentity = 57.0
+        obsIdentity = self._i.computeMeanPcentIdentity()
+        self.assertEquals(expIdentity, obsIdentity)
+        
+    def test_computeMeanPcentIdentity_between_three_sequences_50_pcent(self):
+        iBioseqRef = Bioseq( "seqRef", "AGAAT-" )
+        iBioseq1 = Bioseq( "seq1", "AG-ACG" )
+        iBioseq2 = Bioseq( "seq2", "AG-ACG" )
+        
+        self._i.setData( [ iBioseqRef, iBioseq1, iBioseq2 ] )
+        
+        expIdentity = 50.0
+        obsIdentity = self._i.computeMeanPcentIdentity()
+        self.assertEquals(expIdentity, obsIdentity)
+        
+    def test_computeMeanPcentIdentity_between_three_sequences_42_pcent(self):
+        iBioseqRef = Bioseq( "seqRef", "AGAAT-" )
+        iBioseq1 = Bioseq( "seq1", "AG-ACG" )
+        iBioseq2 = Bioseq( "seq2", "AG-CC-" )
+
+        self._i.setData( [ iBioseqRef, iBioseq1, iBioseq2 ] )
+        
+        expIdentity = 42.0
+        obsIdentity = self._i.computeMeanPcentIdentity()
+        self.assertEquals(expIdentity, obsIdentity)
+        
+#TODO: test with tthis data:
+#>BlastclustCluster2Mb1_chunk7 (dbseq-nr 1) [101523,104351]
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#-------------------------------TAAATCCAACACTGAGAAGAATTATTTAA
+#AGAAGGTTTTTATTTAACTTCTTTATTCGGATATCAGTTTAAGACTAAAA-TTCA-AATG
+#TAAATTGGATTGAGGAGAAGCCTCAGTATTTTAACAATATTTGTATTTCGGGAGGGCCTC
+#GCTTTTGGATTCTTAAGATTAGGAAAAGATTCAAAGAGAGCAGTCAAATCTGCTTATGTC
+#AGGCTTTAGGATTTTTACAAGAACGGCTAAGTGCCGCTGCCAAAGAATTCTTTATTAGAA
+#ACGGACGCTGCGCAGCTGGGATACATTATGGAAATAACTTAAGTGCATTACTGTTTTCTT
+#TGAAATAATTGAAGTGGCCGATTTGGACCACCCAAATACGTACCTCCCCTTCCCTTAAAG
+#TGAAACCTATACTTGGGCTGGGATTGATAGATATTGTATGGAAAATGGAGTTTGTTCTAT
+#TTCTATTTGTTGTGGTATGTTTTGATTTTTTCTTATTTTAAGTTTTGCATACAGCAACAT
+#AA--ATGGCATAA--ATTATACATA-TCTTAAATATAAGTACAATAAAATTAGTCA--AT
+#TATTACAATGGTCATTAGTATG-TAAAGTGTAAT-ATTGTTCTC-TGA-AATCATCTTAA
+#CATTGGCGTTGTGTTTTACAATTTTTATTTTTGTTATATTAAGTGGTGTGTCAAGTGGTG
+#TCAAATCTATTTCTGGTTTTAACATATTTTCACTTAAAATTATACTATTGATTTCTATTT
+#TGCATTGCATTACTCCTTTCATTTTGTTTTCTTCTATTTTTATATTATTAATTGAATTTG
+#GGTAATTTTGGTTATGAATGGTTTGGGTTAAGTTCCAGTAATTTGTAATAATTTAAGTTT
+#AGTAATTTTGGGTTAAACAAGTCAAGTCTGGAAAGCTGGCATAGCCATTCTAAATCTTCT
+#ACGTATTCCGTAAACTGCATTAGCTAGAACAAAAGTGGTTATTTTCATAGTTCTGTTTTT
+#TTGGTTTCTTAAGTAAT--TAAT--TTGTATGTTTGATCAAAAAGGGTAACTATTATTTT
+#TGTAAT--TAATAACTGATTGGACATTTTTCAACAATTTTCTGTCAATTAGCAT----AT
+#CGTAATTATTAGAA-AATACTATT--TCTGGGTAA-CATAATCAAGTCGTTCAAGGTAAT
+#AGGGCCATT-TAATGTTAA-AACTTCACTTCTACTATTTTGTATGGGAAGA--CAAAATA
+#TATTTTCAT--TGATCATATTAATTGTGGAAGCCATTTGTATGTGTACCCTTTGTATACT
+#ATTTTTAAGCATTCGTGTTGTCCGGGGCTGTTGACCGAAAATTTTCGTTTAGTTCAGAAT
+#TATTTTGATTTTGTTCATTATTAATGTGTACGGGTTGGACCTGTTGTTGCCCTTCATTAA
+#TGAACCCATGATTTTGATATGGATTGTATTGATTTTGGTCATAATACTGTTGTTCGTAGG
+#TTGGGTCTGAAATAATTAGGTACGTGCCACATTGGTGGGTTGTAAGTCGTCTGCTCTGAT
+#AGCTAGGTCTAAATGGTTGAATGTATTGATTAAAATTAGGCTGGAAGGGTTGGGAATATT
+#GTGGGTAACTTGGGCGAGTTTGAACGTTTGTATTGAATTTATGTGCTTTCGAATTCTGAT
+#TAAAATTTGAATTTTTATTACGGTATTCTGGGTTTATAAAATTCAAAATTAATGAGTTTT
+#TCATAAATTCCCTCATTTTGTGCAATGGTTATTAAGGATCTTAAGTCTGTAATA-TCGTG
+#ATGAG-ATAA-AATAGTAAATATAGTAG-AGTCTTTA--ATAGCCTGAATAAAAATAAGA
+#AAATCCGATTGGTTACCTTCCAGGTGTAGTTTCGAAATTAATAATTGACGTCGTCTTTCC
+#CCTTCTTCGGAGAATGTTTTTAGGTTTCCTCTGTATGGTGTCTCCCTGAAGCTCTCCAGA
+#AGTTTGTAGTTTGGTGTTTGAGTTTTAAATTCCGCGATGAGTCTTGCTTTGAGGGTAGGC
+#CAATGCTCGGAAGTCCCAAAGATCGTATTATCCGTCCAAGTTACTTTTGATGGCTCCCAG
+#TAGAATCCTCTGTTTACGAAAATTACGTAAATCCACTCTGCTGACGACGGTGTGAAGTGT
+#TTCTGGATCACCCTTAAATGTCATAATGTCTTTAAGCTGCCGACGGGCTTCGGCAAGGTT
+#GTTGTCTCTTAGCGCAACGATTTAAGGTGCGGCAATAATTATAATAATTGGTTGAGACAT
+#TTTTATTGTAAAATTTTAAATTTTGTGTTTTATTGTTTTATTGTTTCGAATTCAATGCTA
+#TTATTTATTTTTTTTTTTGTTTTCTAGTTTCACTTTTTTTTTTATTGTATTGCTTTATTG
+#TTCTTATTTTATTTTTATATGTTGGTTTTAAAACTTAGTTGCCTTTGGACTTAATGTTTT
+#TGTTTCGTATTTCACTTCCACTTTAAATTGGATAACAGAATTGGAATTAAAATCCAAGTT
+#GAAGAGTTTCCACGAATTTATTTGGGAAATGTTTCGAGCACTGGAATCCAGTGACTGGAT
+#TATAAAATTTAACTTATTTCC-ACTCGAAGGTTCTTTTTT--CGG--------ATACTTT
+#TTGTATCAGT--TGACTAAGAGCAACACTGAGAAGAATTATTTAAAGAAGGTTTTTATTT
+#AACTTCTTTATTCGGATATCAGTTTAAGACTAAAA-TTCA-AATGTAAATTGGATTGAGG
+#AGAAGCCTCAGTATT--TCAACAATATTTGTATT--TCGGGAGGGCCTCGCTCTTGGAT-
+#-TCTTAAGATTAGGAAAAAATTCA-AAGAGAGCAGTCA-AATC-TGCTTATGTCAGGCTT
+#TAGGATTTTTACAAGAAGGGC-TAAGTGCCGCTGAAACGGATGC----------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------
+#>BlastclustCluster2Mb2_chunk7 (dbseq-nr 1) [99136,100579]
+#GTAATAATCATAATAATCATAATAATCATAATAATCATAATAATCATAATAATCATAATA
+#ATCATAATAATCATAATAATCATAATAATCATAATAATCATAATAATCATAATAATCATA
+#ATAATCATAATAATCATAATAATCATAATAATCATAATAATCATAATAATCATAATAATC
+#ATAATAATCATAATAATCATAATAATCATAATAATCATAATAATCATAATAATCATAATA
+#ATCATAATAATCATAATAATCATAATAATCATAATAATAATAATAATCATAATCATAATC
+#ATAATAAGCGATAAAAAAATTAAAAAATAAAAATTAAAACCCACTGCAATCACGTTGGAC
+#GGCGAGTCACAGACGTCAGAATAGTGGTGCGTAAATCCAACGCCGAGAAGAATTACTTCA
+#AGAAGGTTTTTATTGAACTTCTTTATTCGGATATCAGTTTAAGACTAAAAATTAATAATC
+#ATAAT---AATCATAATAATCATAATAATCATAATAATCATAATAAT-------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#-----------------------------------------------CATA-ATAATCAT
+#AATAAT--CATAATAATCATA-ATAATCATAATAATCATAATAATCATAATAATCATAAT
+#AATCATAATAATCATAATAATCATAA----TAATCATAATAATCATAATAATCATAATAA
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------TCATAA-TAATCATAATAATCGTAA---TAATCATAA----TAATCATAATAAT
+#CATAATAATCATAA-TAAT----CAT-----AATAATCAT-----AATAATCATAATAAT
+#CATAATAATCATAATAATCATAATAATCATAATAATCATAAT-AA-TCAT--AA--TAAT
+#-----CATAATAATCATAATAA--TCA----TAATAATC---AT---AATAATCATAATA
+#-AT---CATAATAATCATAATAATC-----------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#-----------------------------------ATAATAATCATAAT-AATCA-----
+#TAATAA------TCATAAT----AATCATAAT-AATCATAATAA-TCA-TAATAATCATA
+#ATAATCATAATAATCATAATAATAATAATAATCATAATCATAATCATAATAAGCATAAAA
+#AAAT--------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#------------------------------------------------------------
+#TAAAAAATAAAAATTAAAACCCACTGCAA---TCACGTTGGACGGCGAGTCACAGACGTC
+#A-GAAT-AGTGGTGCGTAAATCCAACGCCGAGAAGAATTACTTCAAGAAGGTTTTTATTG
+#AACTTCTTTATTCGGATATCAGTTTAAGACTAAAAATTAATAATCATAAT---AATCATA
+#ATAA---TCA-TAATAATCAT-AATAATCATAATAATCATAA-----TAA-TCATA-ATA
+#ATCATAATAATCATAATAA--TCATAATA-ATCA-TAATAATCATAATAATCATAATCAT
+#CATAATAATCATAATAAT--CATAA-T-------AATC--ATAATAATCATAATAATCAT
+#AATAATCATAATAATCATAATAATCATAATAATCATAATAATCATAATAATCATAATAAT
+#CATAATAATCATAATAATCATAATAATCATAATAATCATAATAATCATAATAATCATAAT
+#AATCATAATAAT
+
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_AlignedBioseqDB ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/seq/test/Test_Bioseq.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,1017 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+import sys
+from commons.core.seq.Bioseq import Bioseq 
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.coord.Map import Map
+
+
+class Test_Bioseq( unittest.TestCase ):
+    
+    def setUp(self):
+        self._bs = Bioseq()
+
+
+    def test_isEmpty_True(self):
+        self._bs.setHeader( "" )
+        self._bs.setSequence( "" )
+        exp = True
+        obs = self._bs.isEmpty()
+        self.assertEquals( exp, obs )
+
+        
+    def test_isEmpty_False(self):
+        self._bs.setHeader( "seq1" )
+        self._bs.setSequence( "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        exp = False
+        obs = self._bs.isEmpty()
+        self.assertEquals( exp, obs )
+        
+        
+    def test___eq__(self):
+        self._bs.setHeader( "seq1" )
+        self._bs.setSequence( "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        obs = Bioseq( "seq1", "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        self.assertEquals( self._bs, obs )
+        
+        
+    def test___ne__Header(self):
+        self._bs.setHeader( "seq2" )
+        self._bs.setSequence( "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        obs = Bioseq( "seq1", "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        self.assertNotEquals( self._bs, obs )
+        
+        
+    def test___ne__Sequence(self):
+        self._bs.setHeader( "seq1" )
+        self._bs.setSequence( "GGACGATGCAGCATGCGAATGACGAT" )
+        obs = Bioseq( "seq1", "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        self.assertNotEquals( self._bs, obs )
+        
+        
+    def test_reverse(self):
+        self._bs.setHeader( "seq1" )
+        self._bs.setSequence( "TGCGGA" )
+        exp = "AGGCGT"
+        self._bs.reverse()
+        obs = self._bs.sequence
+        self.assertEqual( obs, exp )
+        
+        
+    def test_complement(self):
+        self._bs.setHeader( "seq1" )
+        self._bs.setSequence( "TGCGGA" )
+        exp = "ACGCCT"
+        self._bs.complement()
+        obs = self._bs.sequence
+        self.assertEqual( obs, exp )
+        
+        
+    def test_complement_with_unknown_symbol(self):
+        self._bs.setHeader( "seq1" )
+        self._bs.setSequence( "TGCGGAFMRWTYSKVHDBN" )
+        exp = "ACGCCTNKYWARSMBDHVN"
+        self._bs.complement()
+        obs = self._bs.sequence
+        self.assertEqual( obs, exp )
+        
+        
+    def test_reverseComplement(self):
+        self._bs.setHeader( "seq1" )
+        self._bs.setSequence( "TGCGGA" )
+        exp = "TCCGCA"
+        self._bs.reverseComplement()
+        obs = self._bs.sequence
+        self.assertEqual( obs, exp )
+        
+        
+    def test_cleanGap(self):
+        self._bs.setSequence("-ATTTTGC-AGTC--TTATTCGAG-----GCCATTGCT-")
+        exp = "ATTTTGCAGTCTTATTCGAGGCCATTGCT"
+        self._bs.cleanGap()
+        obs = self._bs.sequence 
+        self.assertEquals( obs, exp )
+        
+        
+    def test_copyBioseqInstance(self):
+        self._bs.setHeader( "seq" )
+        self._bs.setSequence( "TGCGGA" )
+        obsBioseq = self._bs.copyBioseqInstance()
+        self.assertEquals(self._bs, obsBioseq)
+        
+        
+    def test_setFrameInfoOnHeader_without_description(self):
+        self._bs.setHeader( "seq" )
+        self._bs.setSequence( "TGCGGA" )
+        phase = -1
+        expHeader = "seq_-1"
+        self._bs.setFrameInfoOnHeader(phase)
+        self.assertEquals(expHeader, self._bs.header)
+        
+        
+    def test_setFrameInfoOnHeader_with_description(self):
+        self._bs.setHeader( "seq description" )
+        self._bs.setSequence( "TGCGGA" )
+        phase = -1
+        expHeader = "seq_-1 description"
+        self._bs.setFrameInfoOnHeader(phase)
+        self.assertEquals(expHeader, self._bs.header)
+        
+        
+    def test_read(self):
+        faFile = open("dummyFaFile.fa", "w")
+        faFile.write(">seq1 description1\n")
+        faFile.write("ATGCGTCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG\n")
+        faFile.write("ATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG\n")
+        faFile.close()
+        expBioseq = Bioseq()
+        expBioseq.header = "seq1 description1"
+        expBioseq.sequence = "ATGCGTCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        obsBioseq = Bioseq()
+        faFile = open("dummyFaFile.fa", "r")
+        obsBioseq.read( faFile )
+        faFile.close()
+        os.remove("dummyFaFile.fa")
+        self.assertEquals(expBioseq, obsBioseq)
+        
+        
+    def test_read_WithEmptyFile(self):
+        faFile = open("dummyFaFile.fa", "w")
+        faFile.close()
+        expBioseq = Bioseq()
+        expBioseq.header = None
+        expBioseq.sequence = None
+        obsBioseq = Bioseq()
+        faFile = open("dummyFaFile.fa", "r")
+        obsBioseq.read( faFile )
+        faFile.close()
+        os.remove("dummyFaFile.fa")
+        self.assertEquals(expBioseq, obsBioseq)
+        
+        
+    def test_read_without_header(self):
+        faFile = open("dummyFaFile.fa", "w")
+        faFile.write("seq1 description1\n")
+        faFile.write("ATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG\n")
+        faFile.close()
+        expBioseq = Bioseq()
+        expBioseq.header = ""
+        expBioseq.sequence = ""
+        obsBioseq = Bioseq()
+        faFile = open("dummyFaFile.fa", "r")
+        obsBioseq.read( faFile )
+        faFile.close()
+        os.remove("dummyFaFile.fa")
+        self.assertEquals(expBioseq, obsBioseq)
+        
+        
+    def test_read_with_two_consecutive_headers(self):
+        faFile = open("dummyFaFile.fa", "w")
+        faFile.write(">seq1 description1\n")
+        faFile.write(">ATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG\n")
+        faFile.close()
+        expBioseq = Bioseq()
+        expBioseq.header = "seq1 description1"
+        expBioseq.sequence = ""
+        obsBioseq = Bioseq()
+        faFile = open("dummyFaFile.fa", "r")
+        obsBioseq.read( faFile )
+        faFile.close()
+        os.remove("dummyFaFile.fa")
+        self.assertEquals(expBioseq, obsBioseq)
+        
+        
+    def test_read_withEmptyLines(self):
+        faFile = open("dummyFaFile.fa", "w")
+        faFile.write("\n")
+        faFile.write(">seq1 description1\n")
+        faFile.write("ATGCGTCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG\n")
+        faFile.write("ATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG\n")
+        faFile.write("\n")
+        faFile.close()
+        
+        exp = Bioseq( "seq1 description1", "ATGCGTCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG" )
+        
+        obs = Bioseq()
+        faFile = open("dummyFaFile.fa", "r")
+        obs.read( faFile )
+        faFile.close()
+        
+        os.remove("dummyFaFile.fa")
+        
+        self.assertEquals( exp, obs )
+        
+    def test_read_with_70nt_by_line(self):
+        faFile = open("dummyFaFile.fa", "w")
+        faFile.write("\n")
+        faFile.write(">seq1 description1\n")
+        faFile.write("TGTCACATCCTGATTTTCGTTTCAGGATTTATAAATTATTTAATAAATTAATAATAGAATTTATATTAAA\n")
+        faFile.write("TGTTTTTTAATTTACAAGTGAAGTTAAATGTGGGAAATAAAATTTCTTAAATCTAAAGCATGGATGGATT\n")
+        faFile.write("\n")
+        faFile.close()
+        
+        exp = Bioseq( "seq1 description1", "TGTCACATCCTGATTTTCGTTTCAGGATTTATAAATTATTTAATAAATTAATAATAGAATTTATATTAAATGTTTTTTAATTTACAAGTGAAGTTAAATGTGGGAAATAAAATTTCTTAAATCTAAAGCATGGATGGATT" )
+        
+        obs = Bioseq()
+        faFile = open("dummyFaFile.fa", "r")
+        obs.read( faFile )
+        faFile.close()
+        
+        os.remove("dummyFaFile.fa")
+        
+        self.assertEquals( exp, obs )        
+        
+    def test_appendBioseqInFile(self):
+        obsFaFileName = "dummyFaFile.fa"
+        obsFaFile = open(obsFaFileName, "w")
+        obsFaFile.write(">seq1 description1\n")
+        obsFaFile.write("ATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG\n")
+        obsFaFile.close()
+        
+        bioseq = Bioseq()
+        bioseq.header = "seq2 description2"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        
+        expFaFileName = "dummyFaFile2.fa"
+        expFaFile = open(expFaFileName, "w")
+        expFaFile.write(">seq1 description1\n")
+        expFaFile.write("ATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG\n")
+        expFaFile.write(">seq2 description2\n")
+        expFaFile.write("GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTAT\n")
+        expFaFile.write("ATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTAT\n")
+        expFaFile.write("ATAGCAGACGCATATTATATTGCGCG\n")
+        expFaFile.close()
+        
+        bioseq.appendBioseqInFile(obsFaFileName)
+        self.assertTrue(FileUtils.are2FilesIdentical(expFaFileName, obsFaFileName))
+        os.remove(obsFaFileName)
+        os.remove(expFaFileName)
+        
+        
+    def test_writeABioseqInAFastaFile(self):
+        obsFaFileName = "dummyFaFile.fa"
+        obsFaFile = open(obsFaFileName, "w")
+        obsFaFile.write(">seq1 description1\n")
+        obsFaFile.write("ATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG\n")
+        
+        bioseq = Bioseq()
+        bioseq.header = "seq2 description2"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        
+        expFaFileName = "dummyFaFile2.fa"
+        expFaFile = open(expFaFileName, "w")
+        expFaFile.write(">seq1 description1\n")
+        expFaFile.write("ATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG\n")
+        expFaFile.write(">seq2 description2\n")
+        expFaFile.write("GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTAT\n")
+        expFaFile.write("ATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTAT\n")
+        expFaFile.write("ATAGCAGACGCATATTATATTGCGCG\n")
+        expFaFile.close()
+        
+        bioseq.writeABioseqInAFastaFile(obsFaFile)
+        obsFaFile.close()
+        self.assertTrue(FileUtils.are2FilesIdentical(expFaFileName, obsFaFileName))
+        os.remove(obsFaFileName)
+        
+        
+    def test_writeABioseqInAFastaFileWithOtherHeader(self):
+        obsFaFileName = "dummyFaFile.fa"
+        obsFaFile = open(obsFaFileName, "w")
+        obsFaFile.write(">seq1 description1\n")
+        obsFaFile.write("ATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG\n")
+        
+        bioseq = Bioseq()
+        bioseq.header = "seq2 description2"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        
+        expFaFileName = "dummyFaFile2.fa"
+        newHeader = "seq2 New header2"
+        expFaFile = open(expFaFileName, "w")
+        expFaFile.write(">seq1 description1\n")
+        expFaFile.write("ATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG\n")
+        expFaFile.write(">" + newHeader + "\n")
+        expFaFile.write("GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTAT\n")
+        expFaFile.write("ATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTAT\n")
+        expFaFile.write("ATAGCAGACGCATATTATATTGCGCG\n")
+        expFaFile.close()
+        
+        bioseq.writeABioseqInAFastaFileWithOtherHeader(obsFaFile, newHeader)
+        obsFaFile.close()
+        self.assertTrue(FileUtils.are2FilesIdentical(expFaFileName, obsFaFileName))
+        os.remove(obsFaFileName)
+        os.remove(expFaFileName)
+    
+    
+    def test_writeSeqInFasta(self):
+        iBs = Bioseq()
+        iBs.header = "dummySeq"
+        iBs.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        
+        expFaFile = "dummyExpFile.fa"
+        expFaFileHandler = open(expFaFile, "w")
+        expFaFileHandler.write("GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTAT\n")
+        expFaFileHandler.write("ATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTAT\n")
+        expFaFileHandler.write("ATAGCAGACGCATATTATATTGCGCG\n")
+        expFaFileHandler.close()
+        
+        obsFaFile = "dummyObsFile.fa"
+        obsFaFileHandler = open( obsFaFile, "w" )
+        
+        iBs.writeSeqInFasta( obsFaFileHandler )
+        
+        obsFaFileHandler.close()
+
+        self.assertTrue( FileUtils.are2FilesIdentical( expFaFile, obsFaFile ) )
+        os.remove(obsFaFile)
+        os.remove(expFaFile)
+    
+        
+    def test_subseq(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        start = 10
+        end = 30
+        expSubBioseq = Bioseq()
+        expSubBioseq.header = "seq1 description1 fragment " + str(start) + ".." + str(end)
+        expSubBioseq.sequence = bioseq.sequence[(start - 1) : end]
+        obsBioseq = bioseq.subseq(start, end)
+        self.assertEquals(expSubBioseq, obsBioseq)
+        
+        
+    def test_subseq_no_end(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        start = 10
+        expSubBioseq = Bioseq()
+        expEnd = len(bioseq.sequence)
+        expSubBioseq.header = "seq1 description1 fragment " + str(start) + ".." + str(expEnd)
+        expSubBioseq.sequence = bioseq.sequence[(start - 1) : expEnd]
+        obsBioseq = bioseq.subseq(start)
+        self.assertEquals(expSubBioseq, obsBioseq)
+        
+        
+    def test_subseq_start_gt_end(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        start = 30
+        end = 10
+        expSubBioseq = None
+        obsBioseq = bioseq.subseq(start, end)
+        self.assertEquals(expSubBioseq, obsBioseq)
+        
+        
+    def test_subseq_start_eq_end(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        start = 10
+        end = 10
+        expSubBioseq = Bioseq()
+        expSubBioseq.header = "seq1 description1 fragment " + str(start) + ".." + str(end)
+        expSubBioseq.sequence = bioseq.sequence[(start - 1) : end]
+        obsBioseq = bioseq.subseq(start, end)
+        self.assertEquals(expSubBioseq, obsBioseq)
+        
+        
+    def test_subseq_negative_start(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        start = -10
+        end = 10
+        expSubBioseq = None
+        obsBioseq = bioseq.subseq(start, end)
+        self.assertEquals(expSubBioseq, obsBioseq)
+        
+        
+    def test_getNtFromPosition_1(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        expNt = "G"
+        obsNt = bioseq.getNtFromPosition(1)
+        self.assertEquals(expNt, obsNt)
+        
+        
+    def test_getNtFromPosition_10(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        expNt = "C"
+        obsNt = bioseq.getNtFromPosition(10)
+        self.assertEquals(expNt, obsNt)
+        
+        
+    def test_getNtFromPosition_last(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        expNt = "G"
+        obsNt = bioseq.getNtFromPosition(146)
+        self.assertEquals(expNt, obsNt)
+
+        
+    def test_getNtFromPosition_position_outside_range_0(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        expNt = None
+        obsNt = bioseq.getNtFromPosition(0)
+        self.assertEquals(expNt, obsNt)
+
+        
+    def test_getNtFromPosition_position_outside_range_negative(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        expNt = None
+        obsNt = bioseq.getNtFromPosition(-10)
+        self.assertEquals(expNt, obsNt)
+
+        
+    def test_getNtFromPosition_position_outside_range_positive(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        expNt = None
+        obsNt = bioseq.getNtFromPosition(147)
+        self.assertEquals(expNt, obsNt)
+        
+        
+    def test_view(self):
+        obsFileName = "obsdummy_Bioseq_view"
+        expFileName = "expDummy_Bioseq_View"
+        
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        
+        obsFile = open(obsFileName,"w")
+        expFile = open(expFileName, "w")
+        
+        expFile.write ( ">seq1 description1\n")
+        expFile.write ( "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTAT\n")
+        expFile.write ( "ATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTAT\n")
+        expFile.write ( "ATAGCAGACGCATATTATATTGCGCG\n")
+        
+        stdoutRef = sys.stdout
+        sys.stdout = obsFile
+        bioseq.view()
+        obsFile.close()
+        expFile.close()
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        sys.stdout = stdoutRef
+        os.remove ( obsFileName )
+        os.remove ( expFileName )
+        
+        
+    def test_view_with_l(self):
+        obsFileName = "obsdummy_Bioseq_view"
+        expFileName = "expDummy_Bioseq_View"
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        obsFile = open(obsFileName,"w")
+        expFile = open(expFileName, "w")
+        expFile.write ( ">seq1 description1\n")
+        expFile.write ( "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTAT\n")
+        expFile.write ( "ATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTAT\n")
+        stdoutRef = sys.stdout
+        sys.stdout = obsFile
+        bioseq.view(120)
+        obsFile.close()
+        expFile.close()
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        sys.stdout = stdoutRef
+        os.remove ( obsFileName )
+        os.remove ( expFileName )
+        
+        
+    def test_getLength(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        expLength = 146
+        obsLength = bioseq.getLength()
+        self.assertEquals(expLength, obsLength)
+        
+        
+    def test_getLength_empty_seq(self):
+        bioseq = Bioseq()
+        expLength = 0
+        obsLength = bioseq.getLength()
+        self.assertEquals(expLength, obsLength) 
+             
+             
+    def test_getLength_WithoutN(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGANCGCTGCTTTATTAAGCGCTAGATGNNNNNNNNNNNNNNNCGACGCTGCATTTATTAAGCGCTAGCGATTATANNNNNNNNNTAGCAGACGCATATTATATTGCGCGATGCGACGCTGCTTTATTANAGCGCTAGCGNNATTATATAGCANGACGCATATTATATTGCGCG"
+        expLength = 146
+        obsLength = bioseq.getLength(False)
+        self.assertEquals(expLength, obsLength)
+             
+             
+    def test_getLength_WithoutN_empty_seq(self):
+        bioseq = Bioseq()
+        expLength = 0
+        obsLength = bioseq.getLength(False)
+        self.assertEquals(expLength, obsLength) 
+        
+        
+    def test_countNt(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        expCount = 3
+        obsCount = bioseq.countNt('N')
+        self.assertEquals(expCount, obsCount)
+        
+        
+    def test_countNt_withCharacterNotExisting(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        expCount = 0
+        obsCount = bioseq.countNt('W')
+        self.assertEquals(expCount, obsCount)
+        
+        
+    def test_countAllNt(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        dExpCount = {'A': 34, 'C': 31, 'T': 43, 'G': 35, 'N': 3}
+        dObsCount = bioseq.countAllNt()
+        self.assertEquals(dExpCount, dObsCount)
+        
+        
+    def test_occ_word_size_1(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        dExpOccWord = {'A': 34, 'C': 31, 'T': 43, 'G': 35}
+        ExpNbWord = 143
+        dObsOccWord, ObsNbWord = bioseq.occ_word(1)
+        self.assertEquals(dExpOccWord, dObsOccWord)
+        self.assertEquals(ExpNbWord, ObsNbWord)
+        
+        
+    def test_occ_word_size_0(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        dExpOccWord = {}
+        ExpNbWord = 0
+        dObsOccWord, ObsNbWord = bioseq.occ_word(0)
+        self.assertEquals(dExpOccWord, dObsOccWord)
+        self.assertEquals(ExpNbWord, ObsNbWord)
+        
+        
+    def test_occ_word_size_n(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        dExpOccWord = {'ACC': 0, 'ATG': 2, 'AAG': 3, 'AAA': 0, 'ATC': 0, 'AAC': 0, 'ATA': 8, 'AGG': 0, 'CCT': 0, 'CTC': 0, 'AGC': 8, 'ACA': 0, 'AGA': 2, 'CAT': 3, 'AAT': 0, 'ATT': 9, 'CTG': 3, 'CTA': 3, 'ACT': 0, 'CAC': 0, 'ACG': 2, 'CAA': 0, 'AGT': 0, 'CAG': 2, 'CCG': 0, 'CCC': 0, 'CTT': 3, 'TAT': 13, 'GGT': 0, 'TGT': 0, 'CGA': 3, 'CCA': 0, 'TCT': 0, 'GAT': 3, 'CGG': 0, 'TTT': 3, 'TGC': 7, 'GGG': 0, 'TAG': 5, 'GGA': 0, 'TAA': 3, 'GGC': 0, 'TAC': 0, 'TTC': 0, 'TCG': 0, 'TTA': 10, 'TTG': 2, 'TCC': 0, 'GAA': 0, 'TGG': 0, 'GCA': 5, 'GTA': 0, 'GCC': 0, 'GTC': 0, 'GCG': 12, 'GTG': 0, 'GAG': 0, 'GTT': 0, 'GCT': 9, 'TGA': 0, 'GAC': 2, 'CGT': 0, 'TCA': 0, 'CGC': 10}
+        ExpNbWord = 135
+        dObsOccWord, ObsNbWord = bioseq.occ_word(3)
+        self.assertEquals(dExpOccWord, dObsOccWord)
+        self.assertEquals(ExpNbWord, ObsNbWord)
+        
+        
+    def test_freq_word_size_1(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        dExpFreqWord = {'A': 0.23776223776223776, 'C': 0.21678321678321677, 'T': 0.30069930069930068, 'G': 0.24475524475524477}
+        dObsFreqWord = bioseq.freq_word(1)
+        self.assertEquals(dExpFreqWord, dObsFreqWord)
+        
+        
+    def test_freq_word_size_0(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        dExpFreqWord = {}
+        dObsFreqWord = bioseq.freq_word(0)
+        self.assertEquals(dExpFreqWord, dObsFreqWord)
+        
+        
+    def test_freq_word_size_n(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        dExpFreqWord = {'ACC': 0.0, 'ATG': 0.014814814814814815, 'AAG': 0.022222222222222223, 'AAA': 0.0, 'ATC': 0.0, 'AAC': 0.0, 'ATA': 0.059259259259259262, 'AGG': 0.0, 'CCT': 0.0, 'CTC': 0.0, 'AGC': 0.059259259259259262, 'ACA': 0.0, 'AGA': 0.014814814814814815, 'CAT': 0.022222222222222223, 'AAT': 0.0, 'ATT': 0.066666666666666666, 'CTG': 0.022222222222222223, 'CTA': 0.022222222222222223, 'ACT': 0.0, 'CAC': 0.0, 'ACG': 0.014814814814814815, 'CAA': 0.0, 'AGT': 0.0, 'CAG': 0.014814814814814815, 'CCG': 0.0, 'CCC': 0.0, 'TAT': 0.096296296296296297, 'GGT': 0.0, 'TGT': 0.0, 'CGA': 0.022222222222222223, 'CCA': 0.0, 'TCT': 0.0, 'GAT': 0.022222222222222223, 'CGG': 0.0, 'CTT': 0.022222222222222223, 'TGC': 0.05185185185185185, 'GGG': 0.0, 'TAG': 0.037037037037037035, 'GGA': 0.0, 'TAA': 0.022222222222222223, 'GGC': 0.0, 'TAC': 0.0, 'TTC': 0.0, 'TCG': 0.0, 'TTT': 0.022222222222222223, 'TTG': 0.014814814814814815, 'TCC': 0.0, 'GAA': 0.0, 'TGG': 0.0, 'GCA': 0.037037037037037035, 'GTA': 0.0, 'GCC': 0.0, 'GTC': 0.0, 'TGA': 0.0, 'GCG': 0.088888888888888892, 'GTG': 0.0, 'GAG': 0.0, 'GTT': 0.0, 'GCT': 0.066666666666666666, 'TTA': 0.07407407407407407, 'GAC': 0.014814814814814815, 'CGT': 0.0, 'TCA': 0.0, 'CGC': 0.07407407407407407}
+        dObsFreqWord = bioseq.freq_word(3)
+        self.assertEquals(dExpFreqWord, dObsFreqWord)
+        
+        
+    def test_findORF_no_ORF_in_sequence (self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "GCGNCGCTGCTTTATT"
+        expORF = {0:[],1:[],2:[]}
+        obsORF = bioseq.findORF()
+        self.assertEquals (expORF,obsORF)
+        
+        
+    def test_findORF_one_ORF_in_first_phase(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "TAAGCGNCGCTGCTTTATT"
+        expORF = {0:[0],1:[],2:[]}
+        obsORF = bioseq.findORF()
+        self.assertEquals (expORF,obsORF)
+        
+            
+    def test_findORF_three_ORF_in_first_phase(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "TAAGCGTAGNCGTGACTGCTTTATT"
+        expORF = {0:[0,6,12],1:[],2:[]}
+        obsORF = bioseq.findORF()
+        self.assertEquals (expORF,obsORF)
+        
+             
+    def test_findORF_two_ORF_in_first_phase_one_ORF_in_second_phase(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "TAAGTAGAGNCGTGACTGCTTTATT"
+        expORF = {0:[0,12],1:[4],2:[]}
+        obsORF = bioseq.findORF()
+        self.assertEquals (expORF,obsORF)
+        
+        
+    def test_findORF_two_ORF_in_first_phase_three_ORF_in_second_phase(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "TAAGTAGAGNCGTGACTGATAGTATT"
+        expORF = {0:[0,12],1:[4,16,19],2:[]}
+        obsORF = bioseq.findORF()
+        self.assertEquals (expORF,obsORF)
+        
+        
+    def test_findORF_one_ORF_in_second_phase_three_ORF_in_third_phase(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "AATATTAGTGGAGTAGTTGATGATTTT"
+        expORF = {0:[], 1:[13], 2:[5,17,20]}
+        obsORF = bioseq.findORF()
+        self.assertEquals (expORF,obsORF)
+        
+        
+    def test_findORF_three_ORF_in_second_phase_one_ORF_in_third_phase(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq1 description1"
+        bioseq.sequence = "TTTGAAGTGGAGGAGTTGATGATTTTAAT"
+        expORF = {0:[], 1:[16, 19, 25], 2:[2]}
+        obsORF = bioseq.findORF()
+        self.assertEquals (expORF,obsORF)
+        
+        
+    def test_upCase(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq description"
+        bioseq.sequence = "taattcggcct"
+        expSeq = "TAATTCGGCCT"
+        bioseq.upCase()
+        obsSeq = bioseq.sequence
+        self.assertEquals( expSeq, obsSeq )
+        
+        
+    def test_lowCase(self):
+        bioseq = Bioseq()
+        bioseq.header = "seq description"
+        bioseq.sequence = "TAATTCGGCCT"
+        expSeq = "taattcggcct"
+        bioseq.lowCase()
+        obsSeq = bioseq.sequence
+        self.assertEquals( expSeq, obsSeq )
+        
+        
+    def test_getClusterID(self):
+        bioseq = Bioseq()
+        bioseq.header = "MbQ58Gr2Cl0 chunk1 {Fragment} 74091..74624"
+        bioseq.sequence = "TAATTCGGCCT"
+        expID = "0"
+        obsID = bioseq.getClusterID()
+        self.assertEquals( expID, obsID )
+        
+        
+    def test_getGroupID(self):
+        bioseq = Bioseq()
+        bioseq.header = "MbQ58Gr2Cl0 chunk1 {Fragment} 74091..74624"
+        bioseq.sequence = "TAATTCGGCCT"
+        expID = "2"
+        obsID = bioseq.getGroupID()
+        self.assertEquals( expID, obsID )
+        
+        
+    def test_getHeaderFullSeq(self):
+        bioseq = Bioseq()
+        bioseq.header = "MbQ58Gr2Cl0 chunk1 {Fragment} 74091..74624"
+        bioseq.sequence = "TAATTCGGCCT"
+        expHeader = "chunk1"
+        obsHeader = bioseq.getHeaderFullSeq()
+        self.assertEquals( expHeader, obsHeader )
+        
+        
+    def test_getFragStrand_plus_strand(self):
+        bioseq = Bioseq()
+        bioseq.header = "MbQ58Gr2Cl0 chunk1 {Fragment} 74091..74624"
+        bioseq.sequence = "TAATTCGGCCT"
+        expStrand = '+'
+        obsStrand = bioseq.getFragStrand()
+        self.assertEquals(expStrand, obsStrand)
+        
+        
+    def test_getFragStrand_minus_strand(self):
+        bioseq = Bioseq()
+        bioseq.header = "MbQ58Gr2Cl0 chunk1 {Fragment} 74624..74091"
+        bioseq.sequence = "TAATTCGGCCT"
+        expStrand = '-'
+        obsStrand = bioseq.getFragStrand()
+        self.assertEquals(expStrand, obsStrand)
+        
+        
+    def test_getATGCNFromIUPAC_A(self):
+        bioseq = Bioseq()
+        expNucl = 'A'
+        obsNucl = bioseq.getATGCNFromIUPAC('A')
+        self.assertEquals(expNucl, obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_T(self):
+        bioseq = Bioseq()
+        expNucl = 'T'
+        obsNucl = bioseq.getATGCNFromIUPAC('T')
+        self.assertEquals(expNucl, obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_C(self):
+        bioseq = Bioseq()
+        expNucl = 'C'
+        obsNucl = bioseq.getATGCNFromIUPAC('C')
+        self.assertEquals(expNucl, obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_G(self):
+        bioseq = Bioseq()
+        expNucl = 'G'
+        obsNucl = bioseq.getATGCNFromIUPAC('G')
+        self.assertEquals(expNucl, obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_N(self):
+        bioseq = Bioseq()
+        expNucl = 'N'
+        obsNucl = bioseq.getATGCNFromIUPAC('N')
+        self.assertEquals(expNucl, obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_U(self):
+        bioseq = Bioseq()
+        expNucl = 'T'
+        obsNucl = bioseq.getATGCNFromIUPAC('U')
+        self.assertEquals(expNucl, obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_R(self):
+        bioseq = Bioseq()
+        expNucl1 = 'A'
+        expNucl2 = 'G'
+        obsNucl = bioseq.getATGCNFromIUPAC('R')
+        self.assertTrue(expNucl1 == obsNucl or expNucl2 == obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_Y(self):
+        bioseq = Bioseq()
+        expNucl1 = 'C'
+        expNucl2 = 'T'
+        obsNucl = bioseq.getATGCNFromIUPAC('Y')
+        self.assertTrue(expNucl1 == obsNucl or expNucl2 == obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_M(self):
+        bioseq = Bioseq()
+        expNucl1 = 'C'
+        expNucl2 = 'A'
+        obsNucl = bioseq.getATGCNFromIUPAC('M')
+        self.assertTrue(expNucl1 == obsNucl or expNucl2 == obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_K(self):
+        bioseq = Bioseq()
+        expNucl1 = 'T'
+        expNucl2 = 'G'
+        obsNucl = bioseq.getATGCNFromIUPAC('K')
+        self.assertTrue(expNucl1 == obsNucl or expNucl2 == obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_W(self):
+        bioseq = Bioseq()
+        expNucl1 = 'T'
+        expNucl2 = 'A'
+        obsNucl = bioseq.getATGCNFromIUPAC('W')
+        self.assertTrue(expNucl1 == obsNucl or expNucl2 == obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_S(self):
+        bioseq = Bioseq()
+        expNucl1 = 'C'
+        expNucl2 = 'G'
+        obsNucl = bioseq.getATGCNFromIUPAC('S')
+        self.assertTrue(expNucl1 == obsNucl or expNucl2 == obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_B(self):
+        bioseq = Bioseq()
+        expNucl1 = 'C'
+        expNucl2 = 'T'
+        expNucl3 = 'G'
+        obsNucl = bioseq.getATGCNFromIUPAC('B')
+        self.assertTrue(expNucl1 == obsNucl or expNucl2 == obsNucl or expNucl3 == obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_D(self):
+        bioseq = Bioseq()
+        expNucl1 = 'A'
+        expNucl2 = 'T'
+        expNucl3 = 'G'
+        obsNucl = bioseq.getATGCNFromIUPAC('D')
+        self.assertTrue(expNucl1 == obsNucl or expNucl2 == obsNucl or expNucl3 == obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_H(self):
+        bioseq = Bioseq()
+        expNucl1 = 'C'
+        expNucl2 = 'T'
+        expNucl3 = 'A'
+        obsNucl = bioseq.getATGCNFromIUPAC('H')
+        self.assertTrue(expNucl1 == obsNucl or expNucl2 == obsNucl or expNucl3 == obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_V(self):
+        bioseq = Bioseq()
+        expNucl1 = 'C'
+        expNucl2 = 'A'
+        expNucl3 = 'G'
+        obsNucl = bioseq.getATGCNFromIUPAC('V')
+        self.assertTrue(expNucl1 == obsNucl or expNucl2 == obsNucl or expNucl3 == obsNucl)
+        
+        
+    def test_getATGCNFromIUPAC_Z(self):
+        bioseq = Bioseq()
+        expNucl = 'N'
+        obsNucl = bioseq.getATGCNFromIUPAC('Z')
+        self.assertEquals(expNucl, obsNucl)
+        
+        
+    def test_partialIUPAC(self):
+        bioseq = Bioseq()
+        bioseq.sequence = "ATGCNRATGCN"
+        expSequence1 = "ATGCNAATGCN"
+        expSequence2 = "ATGCNGATGCN"
+        bioseq.partialIUPAC()
+        obsSequence = bioseq.sequence
+        self.assertTrue(expSequence1 == obsSequence or expSequence2 == obsSequence)
+        
+        
+    def test_checkEOF(self):
+        bioseq = Bioseq()
+        bioseq.sequence = "ATGCNRATGCN\rATGCAAT\rTATA\r"
+        bioseq.checkEOF()
+        obsSequence = bioseq.sequence
+        expSequence = "ATGCNRATGCNATGCAATTATA"
+        
+        self.assertEquals(expSequence, obsSequence)
+        
+        
+    def test_getLMapWhithoutGap(self):
+        iBioseq = Bioseq()
+        iBioseq.header = "header"
+        iBioseq.sequence = "ATGC-RA-GCT"
+        obsLMap = iBioseq.getLMapWhithoutGap()
+        expLMap = [Map( "header_subSeq1", "header", 1, 4 ), Map( "header_subSeq2", "header", 6, 7 ), Map( "header_subSeq3", "header", 9, 11 )]
+        
+        self.assertEquals(expLMap, obsLMap)
+        
+        
+    def test_getLMapWhithoutGap_seqStartsWithGap(self):
+        iBioseq = Bioseq()
+        iBioseq.header = "header"
+        iBioseq.sequence = "-TGC-RA-GCT"
+        obsLMap = iBioseq.getLMapWhithoutGap()
+        expLMap = [Map( "header_subSeq1", "header", 2, 4 ), Map( "header_subSeq2", "header", 6, 7 ), Map( "header_subSeq3", "header", 9, 11 )]
+        
+        self.assertEquals(expLMap, obsLMap)
+        
+        
+    def test_getLMapWhithoutGap_seqEndsWithGap(self):
+        iBioseq = Bioseq()
+        iBioseq.header = "header"
+        iBioseq.sequence = "ATGC-RA-GC-"
+        obsLMap = iBioseq.getLMapWhithoutGap()
+        expLMap = [Map( "header_subSeq1", "header", 1, 4 ), Map( "header_subSeq2", "header", 6, 7 ), Map( "header_subSeq3", "header", 9, 10 )]
+        
+        self.assertEquals(expLMap, obsLMap)
+        
+    def test_getGCpercentage_onlyATGC( self ):
+        iBs = Bioseq( "seq", "TGCAGCT" )
+        exp = 100 * 4 / 7.0
+        obs = iBs.getGCpercentage()
+        self.assertEqual( exp, obs )
+        
+    def test_getGCpercentageInSequenceWithoutCountNInLength( self ):
+        iBs = Bioseq( "seq", "TGCAGCTNNNNN" )
+        exp = 100 * 4 / 7.0
+        obs = iBs.getGCpercentageInSequenceWithoutCountNInLength()
+        self.assertEqual( exp, obs )    
+        
+    def test_get5PrimeFlank(self):
+        bs = Bioseq( "line1", "AACTTTCCAGAA" )
+        position = 7
+        obsFlank = bs.get5PrimeFlank(position, 3)
+        expFlank = "TTT"
+        self.assertEquals(expFlank, obsFlank)
+        
+    def test_get5PrimeFlank_flank_length_truncated(self):
+        bs = Bioseq( "line1", "AACTTTCCAGAA" )
+        position = 7
+        obsFlank = bs.get5PrimeFlank(position, 15)
+        expFlank = "AACTTT"
+        self.assertEquals(expFlank, obsFlank)
+        
+    def test_get5PrimeFlank_flank_of_first_base(self):
+        bs = Bioseq( "line1", "AACTTTCCAGAA" )
+        position = 1
+        obsFlank = bs.get5PrimeFlank(position, 15)
+        expFlank = ""
+        self.assertEquals(expFlank, obsFlank)                
+   
+    def test_get3PrimeFlank(self):
+        bs = Bioseq( "line1", "AACTTTCCAGAA" )
+        position = 7
+        obsFlank = bs.get3PrimeFlank(position, 3)
+        expFlank = "CAG"
+        self.assertEquals(expFlank, obsFlank)
+        
+    def test_get3PrimeFlank_flank_length_truncated(self):
+        bs = Bioseq( "line1", "AACTTTCCAGAA" )
+        position = 7
+        obsFlank = bs.get3PrimeFlank(position, 15)
+        expFlank = "CAGAA"
+        self.assertEquals(expFlank, obsFlank)
+        
+    def test_get3PrimeFlank_flank_of_last_base(self):
+        bs = Bioseq( "line1", "AACTTTCCAGAA" )
+        position = 12
+        obsFlank = bs.get3PrimeFlank(position, 15)
+        expFlank = ""
+        self.assertEquals(expFlank, obsFlank)
+        
+    def test_get3PrimeFlank_polymLength_different_of_1(self):
+        bs = Bioseq( "line1", "AACTTTCCAGAA" )
+        position = 7
+        obsFlank = bs.get3PrimeFlank(position, 3, 2)
+        expFlank = "AGA"
+        self.assertEquals(expFlank, obsFlank) 
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_Bioseq ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/seq/test/Test_BioseqDB.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,974 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+import time
+from commons.core.seq.BioseqDB import BioseqDB
+from commons.core.seq.Bioseq import Bioseq
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.coord.Map import Map
+
+
+class Test_BioseqDB( unittest.TestCase ):
+    
+    def setUp( self ):
+        self._uniqId = "%s_%s" % ( time.strftime("%Y%m%d%H%M%S") , os.getpid() )
+        
+        
+    def tearDown( self ):
+        if os._exists("dummyBioseqDB.fa"):
+            os.remove("dummyBioseqDB.fa")
+            
+            
+    def test__eq__(self):
+        iBioseq1 = Bioseq( "seq1", "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        iBioseq2 = Bioseq( "seq2", "GCGATGCGATCGATGCGATAGCA" )
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        iBioseq3 = Bioseq( "seq1", "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        iBioseq4 = Bioseq( "seq2", "GCGATGCGATCGATGCGATAGCA" )
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq3, iBioseq4 ] )
+        
+        self.assertEquals( expBioseqDB, obsBioseqDB )
+        
+        
+    def test__eq__instances_with_different_header(self):
+        iBioseq1 = Bioseq( "seq1", "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        iBioseq2 = Bioseq( "seq2", "GCGATGCGATCGATGCGATAGCA" )
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        iBioseq3 = Bioseq( "seq3", "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        iBioseq4 = Bioseq( "seq4", "GCGATGCGATCGATGCGATAGCA" )
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq3, iBioseq4 ] )
+        
+        self.assertNotEquals( expBioseqDB, obsBioseqDB )
+        
+        
+    def test__eq__instances_with_different_sequences(self):
+        iBioseq1 = Bioseq( "seq1", "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        iBioseq2 = Bioseq( "seq2", "GCGATGCGATCGATGCGATAGCA" )
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        iBioseq3 = Bioseq( "seq1", "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        iBioseq4 = Bioseq( "seq2", "GCGATGCGATCGATGCGATAGCATATATATATATATATATATATAT" )
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq3, iBioseq4 ] )
+        
+        self.assertNotEquals( expBioseqDB, obsBioseqDB )
+        
+        
+    def test__eq__instances_with_different_sequences_and_headers(self):
+        iBioseq1 = Bioseq( "seq1", "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        iBioseq2 = Bioseq( "seq2", "GCGATGCGATCGATGCGATAGCA" )
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        iBioseq3 = Bioseq( "seq3", "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        iBioseq4 = Bioseq( "seq4", "GCGATGCGATCGATGCGATAGCATATATATATATATATATATATAT" )
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq3, iBioseq4 ] )
+        
+        self.assertNotEquals( expBioseqDB, obsBioseqDB )
+        
+        
+    def test__eq__instances_with_different_sizeOfBioseq(self):
+        iBioseq1 = Bioseq( "seq1", "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        iBioseq2 = Bioseq( "seq2", "GCGATGCGATCGATGCGATAGCA" )
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        iBioseq3 = Bioseq( "seq3", "AGCGGACGATGCAGCATGCGAATGACGAT" )
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq3 ] )
+        
+        self.assertNotEquals( expBioseqDB, obsBioseqDB )
+        
+        
+    def test_setName (self): 
+        expName = "myDataBank"
+        iBioseqDB = BioseqDB()
+        self.assertEquals (iBioseqDB.name, "")
+        
+        iBioseqDB.setName (expName)
+        obsName = iBioseqDB.name
+        self.assertEquals (expName, obsName)
+        
+        
+    def test_read(self):
+        iBioseq1 = Bioseq("consensus1","GAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq2 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGC")
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        faFN = "dummyFaFile.fa"
+        faF = open( faFN, "w" )
+        faF.write(">consensus1\n")
+        faF.write("GAGATGGCTCATGGAGTACCTGCCT\n")
+        faF.write(">consensus2\n")
+        faF.write("GAGATGGCTCATGGAGTACCGC\n")
+        faF.close()
+        
+        faF = open( faFN, "r" )
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.read( faF )
+        faF.close()
+        os.remove( faFN )
+        self.assertEquals( expBioseqDB, obsBioseqDB )
+        
+        
+    def test_write(self):
+        iBioseq1 = Bioseq("consensus1","GAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq2 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        expFaFileName = "dummyFaFile.fa"
+        expFaFile = open( expFaFileName, "w" )
+        expFaFile.write(">consensus1\n")
+        expFaFile.write("GAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCTGAGATGGCTC\n")
+        expFaFile.write("ATGGAGTACCTGCCT\n")
+        expFaFile.write(">consensus2\n")
+        expFaFile.write("GAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAG\n")
+        expFaFile.write("TACCGCGAGATGGCTCATGGAGTACCGC\n")
+        expFaFile.close()
+        
+        obsFaFileName = "obsDummyFastaFile.fa"
+        obsFaFile = open( obsFaFileName, "w" )
+        iBioseqDB.write( obsFaFile )
+        obsFaFile.close()
+        
+        self.assertTrue( FileUtils.are2FilesIdentical(expFaFileName, obsFaFileName) )
+        os.remove( expFaFileName )
+        os.remove( obsFaFileName )
+        
+        
+    def test_save(self):
+        iBioseq1 = Bioseq("consensus1","GAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq2 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        expFaFileName = "dummyFaFile.fa"
+        expFaFile = open( expFaFileName, "w" )
+        expFaFile.write(">consensus1\n")
+        expFaFile.write("GAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCTGAGATGGCTC\n")
+        expFaFile.write("ATGGAGTACCTGCCT\n")
+        expFaFile.write(">consensus2\n")
+        expFaFile.write("GAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAG\n")
+        expFaFile.write("TACCGCGAGATGGCTCATGGAGTACCGC\n")
+        expFaFile.close()
+        
+        obsFaFileName = "obsDummyFastaFile.fa"
+        iBioseqDB.save( obsFaFileName )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical(expFaFileName, obsFaFileName) )
+        os.remove( expFaFileName )
+        os.remove( obsFaFileName )
+        
+        
+    def test_load(self):
+        iBioseq1 = Bioseq("consensus1","GAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq2 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        FaFileName = "dummyFaFile.fa"
+        FaFile = open( FaFileName, "w" )
+        FaFile.write(">consensus1\n")
+        FaFile.write("GAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCTGAGATGGCTC\n")
+        FaFile.write("ATGGAGTACCTGCCT\n")
+        FaFile.write(">consensus2\n")
+        FaFile.write("GAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAG\n")
+        FaFile.write("TACCGCGAGATGGCTCATGGAGTACCGC\n")
+        FaFile.close()
+        
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.load( FaFileName )
+        
+        self.assertEquals( expBioseqDB, obsBioseqDB )
+        os.remove( FaFileName )
+        
+        
+    def test_reverse( self ):
+        iBioseq1 = Bioseq( "seq1", "ATTG" )
+        iBioseq2 = Bioseq( "seq2", "CGAAT" )
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        iBioseq3 = Bioseq( "seq1", "GTTA" )
+        iBioseq4 = Bioseq( "seq2", "TAAGC" )
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq3, iBioseq4 ] )
+        obsBioseqDB.reverse()
+        self.assertEquals( expBioseqDB, obsBioseqDB )
+        
+        
+    def test_complement( self ):
+        iBioseq1 = Bioseq( "seq1", "ATTG" )
+        iBioseq2 = Bioseq( "seq2", "CGAAT" )
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        iBioseq3 = Bioseq( "seq1", "TAAC" )
+        iBioseq4 = Bioseq( "seq2", "GCTTA" )
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq3, iBioseq4 ] )
+        
+        obsBioseqDB.complement()
+        self.assertEquals( expBioseqDB, obsBioseqDB )
+        
+        
+    def test_reverseComplement( self ):
+        iBioseq1 = Bioseq( "seq1", "ATTG" )
+        iBioseq2 = Bioseq( "seq2", "CGAAT" )
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        iBioseq3 = Bioseq( "seq1", "CAAT" )
+        iBioseq4 = Bioseq( "seq2", "ATTCG" )
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq3, iBioseq4 ] )
+        
+        obsBioseqDB.reverseComplement()
+        self.assertEquals( expBioseqDB, obsBioseqDB )
+        
+        
+    def test_setData(self):
+        iBioseq1 = Bioseq( "seq1", "ATTG" )
+        iBioseq2 = Bioseq( "seq2", "CGAAT" )
+        iBioseq3 = Bioseq( "seq3", "CAAT" )
+        iBioseq4 = Bioseq( "seq4", "ATTCG" )
+        
+        lBioseq = [iBioseq1, iBioseq2, iBioseq3, iBioseq4]
+        expBioseqDB = BioseqDB()
+        expBioseqDB.db = lBioseq
+        
+        iBioseq5 = Bioseq( "seq1", "ATTG" )
+        iBioseq6 = Bioseq( "seq2", "CGAAT" )
+        iBioseq7 = Bioseq( "seq3", "CAAT" )
+        iBioseq8 = Bioseq( "seq4", "ATTCG" )
+        
+        lBioseq2 = [iBioseq5, iBioseq6, iBioseq7, iBioseq8]
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData(lBioseq2)
+        
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_reset( self ):
+        iBioseq1 = Bioseq( "seq1", "ATTG" )
+        iBioseq2 = Bioseq( "seq2", "CGAAT" )
+        iBioseq3 = Bioseq( "seq3", "CAAT" )
+        iBioseq4 = Bioseq( "seq4", "ATTCG" )
+        
+        lBioseq = [iBioseq1, iBioseq2, iBioseq3, iBioseq4]
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData(lBioseq)
+        obsBioseqDB.reset()
+              
+        expBioseqDB = BioseqDB()
+        
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def testCleanGap(self):
+        iBioseq1 = Bioseq( "seq1", "ATTG" )
+        iBioseq2 = Bioseq( "seq2", "CGAAT" )
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData([iBioseq1, iBioseq2])
+        
+        iBioseq3 = Bioseq( "seq1", "AT-----TG" )
+        iBioseq4 = Bioseq( "seq2", "CGAA----T" )
+        
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq3, iBioseq4 ] )
+        obsBioseqDB.cleanGap()
+        
+        self.assertEquals(expBioseqDB, obsBioseqDB)          
+        
+        
+    def testCleanGap_on_empty_db(self):
+        expBioseqDB = BioseqDB()
+        
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.cleanGap()
+        
+        self.assertEquals(expBioseqDB, obsBioseqDB)          
+        
+        
+    def testCleanGap_on_size_one_db(self):
+        iBioseq1 = Bioseq( "seq1", "ATTG" )
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData([iBioseq1])
+        
+        iBioseq2 = Bioseq( "seq1", "AT-----TG" )
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData([iBioseq2])
+        
+        obsBioseqDB.cleanGap()
+         
+        self.assertEquals(expBioseqDB, obsBioseqDB)          
+        
+        
+    def test_add_to_a_empty_bioseqDB_instance (self):
+        sHeader = "embl::AF332402:AF332402 Arabidopsis thaliana clone C00024 (f)"
+        sHeader += "(At4g29080) mRNA, complete cds."
+        
+        expDictIdx = { sHeader : 0}
+        
+        sHeaderRenamed = "embl-AF332402-AF332402_Arabidopsis_thaliana_clone_C00024_(f)"
+        sHeaderRenamed += "(At4g29080)_mRNA-_complete_cds."
+        expDictIdxRenamed = {sHeaderRenamed : 0}
+        
+        iBioseq1 = Bioseq( sHeader, "ATTG" )
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.add(iBioseq1)
+        
+        obsDictIdx = obsBioseqDB.idx
+        obsDictIdxRenamed = obsBioseqDB.idx_renamed
+        
+        self.assertEquals(expDictIdx,obsDictIdx)
+        self.assertEquals(expDictIdxRenamed,obsDictIdxRenamed)
+        
+        
+    def test_add_to_a_size_one_bioseqDB_instance (self):
+        sHeader1 = "embl::AF332402:AF332402 Arabidopsis thaliana clone C00024 (f)"
+        sHeader1 += "(At4g29080) mRNA, complete cds."
+        
+        sHeader2 = "embl::AF332503:AF332402 Arabidopsis thaliana clone C00024 (f)"
+        sHeader2 += "(At4g29080) mRNA, complete cds."
+        
+        expDictIdx = { sHeader1 : 0, sHeader2 : 1}
+        
+        sHeaderRenamed1 = "embl-AF332402-AF332402_Arabidopsis_thaliana_clone_C00024_(f)"
+        sHeaderRenamed1 += "(At4g29080)_mRNA-_complete_cds."
+
+        sHeaderRenamed2 = "embl-AF332503-AF332402_Arabidopsis_thaliana_clone_C00024_(f)"
+        sHeaderRenamed2 += "(At4g29080)_mRNA-_complete_cds."
+        
+        expDictIdxRenamed = {sHeaderRenamed1 : 0, sHeaderRenamed2 : 1}
+        
+        iBioseq1 = Bioseq( sHeader1, "ATTG" )
+        iBioseq2 = Bioseq( sHeader2, "ATTG" )
+        
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData([ iBioseq1])
+        obsBioseqDB.add(iBioseq2)
+        
+        obsDictIdx = obsBioseqDB.idx
+        obsDictIdxRenamed = obsBioseqDB.idx_renamed
+        
+        self.assertEquals(expDictIdx,obsDictIdx)
+        self.assertEquals(expDictIdxRenamed,obsDictIdxRenamed)
+        
+        
+    def test_add_to_a_size_two_bioseqDB_instance (self):
+        sHeader1 = "embl::AF332402:AF332402 Arabidopsis thaliana clone C00024 (f)"
+        sHeader1 += "(At4g29080) mRNA, complete cds."
+        
+        sHeader2 = "embl::AF332503:AF332402 Arabidopsis thaliana clone C00024 (f)"
+        sHeader2 += "(At4g29080) mRNA, complete cds."
+        
+        sHeader3 = "embl::AF332604:AF332402 Arabidopsis thaliana clone C00024 (f)"
+        sHeader3 += "(At4g29080) mRNA, complete cds."
+        expDictIdx = { sHeader1 : 0, sHeader2 : 1, sHeader3 : 2}
+        
+        sHeaderRenamed1 = "embl-AF332402-AF332402_Arabidopsis_thaliana_clone_C00024_(f)"
+        sHeaderRenamed1 += "(At4g29080)_mRNA-_complete_cds."
+
+        sHeaderRenamed2 = "embl-AF332503-AF332402_Arabidopsis_thaliana_clone_C00024_(f)"
+        sHeaderRenamed2 += "(At4g29080)_mRNA-_complete_cds."
+        
+        sHeaderRenamed3 = "embl-AF332604-AF332402_Arabidopsis_thaliana_clone_C00024_(f)"
+        sHeaderRenamed3 += "(At4g29080)_mRNA-_complete_cds."
+        expDictIdxRenamed = {sHeaderRenamed1 : 0, sHeaderRenamed2 : 1, sHeaderRenamed3 :2}
+        
+        iBioseq1 = Bioseq( sHeader1, "ATTG" )
+        iBioseq2 = Bioseq( sHeader2, "ATTG" )
+        iBioseq3 = Bioseq( sHeader3, "ATTG" )
+        
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData([ iBioseq1, iBioseq2 ])
+        obsBioseqDB.add(iBioseq3)
+        
+        obsDictIdx = obsBioseqDB.idx
+        obsDictIdxRenamed = obsBioseqDB.idx_renamed
+        
+        self.assertEquals(expDictIdx,obsDictIdx)
+        self.assertEquals(expDictIdxRenamed,obsDictIdxRenamed)
+        
+        
+    def test__getitem__(self):
+        iBioseq1 = Bioseq("seq1","ATTG")
+        iBioseq2 = Bioseq("seq2","CGAAT")
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        expBioseq = Bioseq("seq2","CGAAT")
+        obsBioseq = iBioseqDB[1]
+        
+        self.assertEquals(expBioseq, obsBioseq)
+        
+        
+    def test_getSize(self):
+        expSize = 4
+        
+        iBioseq1 = Bioseq( "seq1", "ATTG" )
+        iBioseq2 = Bioseq( "seq2", "CGAAT" )
+        iBioseq3 = Bioseq( "seq3", "AT-----TG" )
+        iBioseq4 = Bioseq( "seq4", "CGAA----T" )
+        
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [iBioseq1, iBioseq2 , iBioseq3, iBioseq4 ] )
+        obsSize = obsBioseqDB.getSize()
+        
+        self.assertEquals(expSize,obsSize)
+        
+        
+    def test_getSize_emptyDB(self):
+        expSize = 0
+        
+        obsBioseqDB = BioseqDB()
+        obsSize = obsBioseqDB.getSize()
+        
+        self.assertEquals(expSize,obsSize)
+        
+        
+    def test_getLength(self):
+        iBioseq1 = Bioseq("consensus1","GAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq2 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        expLength = 163
+        obsLength = iBioseqDB.getLength()
+        
+        self.assertEquals( expLength, obsLength)
+
+    def test_getListOfSequencesLength(self):
+        iBioseq1 = Bioseq("consensus1","GAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq2 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        lLength = iBioseqDB.getListOfSequencesLength()
+        
+        expLLengh = [75, 88]
+        self.assertEquals( expLLengh, lLength )
+        
+        
+    def test_getHeaderList( self ):
+        lExpHeader = ["seq1", "seq2"]
+        
+        iBioseq1 = Bioseq( "seq1", "ATTG" )
+        iBioseq2 = Bioseq( "seq2", "CGAAT" )
+        
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        lObsHeader = obsBioseqDB.getHeaderList()
+
+        self.assertEquals( lExpHeader, lObsHeader )
+        
+        
+    def test_getSequencesList( self ):
+        lExpSeqs = ["ATGC", "AATTCCGG"]
+        
+        iBioseq1 = Bioseq("seq1", "ATGC")
+        iBioseq2 = Bioseq("seq2", "AATTCCGG")
+        
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData([iBioseq1, iBioseq2])
+        
+        lObsSeqs = obsBioseqDB.getSequencesList()
+
+        self.assertEquals(lExpSeqs, lObsSeqs)
+        
+        
+    def test_fetch( self ):
+        ibioseq1 = Bioseq( "seq1", "ATTG" )
+        ibioseq2 = Bioseq( "seq2", "CGAAT" )
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ ibioseq1, ibioseq2 ] )
+        expBioseq = ibioseq1
+        obsBioseq = iBioseqDB.fetch( "seq1" )
+        self.assertEquals( expBioseq, obsBioseq )
+        
+        
+    def test_getBioseqByRenamedHeader( self ):
+        Header1 = "embl::AF332402:AF332402 Arabidopsis thaliana clone C00024 (f)"
+        Header1 += "(At4g29080) mRNA, complete cds."
+        
+        Header2 = "embl::AF332503:AF332402 Arabidopsis thaliana clone C00024 (f)"
+        Header2 += "(At4g29080) mRNA, complete cds."
+        
+        Header3 = "embl::AF332604:AF332402 Arabidopsis thaliana clone C00024 (f)"
+        Header3 += "(At4g29080) mRNA, complete cds."
+        
+        HeaderRenamed2 = "embl-AF332503-AF332402_Arabidopsis_thaliana_clone_C00024_(f)"
+        HeaderRenamed2 += "(At4g29080)_mRNA-_complete_cds."
+        
+        ibioseq1 = Bioseq( Header1, "ATTG" )
+        ibioseq2 = Bioseq( Header2, "CGAAT" )
+        ibioseq3 = Bioseq( Header3, "TGCGAAT" )
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ ibioseq1, ibioseq2, ibioseq3 ] )
+        expBioseq = ibioseq2
+        
+        obsBioseq = iBioseqDB.getBioseqByRenamedHeader( HeaderRenamed2  )
+        
+        self.assertEquals( expBioseq, obsBioseq )
+        
+        
+    def test_init_with_the_parm_name( self ):
+        iBioseq1 = Bioseq("seq1","ATTG")
+        iBioseq2 = Bioseq("seq2","CGAAT")
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        fastaFilename = "dummyBioseqDB.fa"
+        f = open(fastaFilename, "w")
+        f.write(">seq1\n")
+        f.write("ATTG\n")
+        f.write(">seq2\n")
+        f.write("CGAAT\n")
+        f.close()
+        
+        obsBioseqDB = BioseqDB(fastaFilename)
+        os.remove(fastaFilename)
+        self.assertEquals( expBioseqDB, obsBioseqDB )
+        
+        
+    def test_countNt(self):
+        iBioseq1 = Bioseq()
+        iBioseq1.header = "seq1 description1"
+        iBioseq1.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        iBioseq2 = Bioseq()
+        iBioseq2.header = "seq2 description2"
+        iBioseq2.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        expCount = 6
+        obsCount = iBioseqDB.countNt('N')
+        self.assertEquals(expCount, obsCount)
+        
+    def test_countNt_lowercase(self):
+        iBioseq1 = Bioseq()
+        iBioseq1.header = "seq1 description1"
+        iBioseq1.sequence = "gcgncgctgctttattaagcgctagcatgcgncgctgctttattaagcgctagcgattatatagcagacgcatattatattgcgcgatgcgncgctgctttattaagcgctagcgattatatagcagacgcatattatattgcgcg"
+        iBioseq2 = Bioseq()
+        iBioseq2.header = "seq2 description2"
+        iBioseq2.sequence = "gcgncgctgctttattaagcgctagcatgcgncgctgctttattaagcgctagcgattatatagcagacgcatattatattgcgcgatgcgncgctgctttattaagcgctagcgattatatagcagacgcatattatattgcgcg"
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        expCount = 0
+        obsCount = iBioseqDB.countNt('N')
+        self.assertEquals(expCount, obsCount)
+        
+        
+    def test_countNt_withCharacterNotExisting(self):
+        iBioseq1 = Bioseq()
+        iBioseq1.header = "seq1 description1"
+        iBioseq1.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        iBioseq2 = Bioseq()
+        iBioseq2.header = "seq2 description2"
+        iBioseq2.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        expCount = 0
+        obsCount = iBioseqDB.countNt('W')
+        self.assertEquals(expCount, obsCount)
+        
+        
+    def test_countAllNt(self):
+        iBioseq1 = Bioseq()
+        iBioseq1.header = "seq1 description1"
+        iBioseq1.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        iBioseq2 = Bioseq()
+        iBioseq2.header = "seq2 description2"
+        iBioseq2.sequence = "GCGNCGCTGCTTTATTAAGCGCTAGCATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCGATGCGNCGCTGCTTTATTAAGCGCTAGCGATTATATAGCAGACGCATATTATATTGCGCG"
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        
+        dExpCount = {'A': 68, 'C': 62, 'T': 86, 'G': 70, 'N': 6}
+        
+        dObsCount = iBioseqDB.countAllNt()
+        self.assertEquals(dExpCount, dObsCount)
+        
+        
+    def test_extractPart(self):    
+        iBioseq1 = Bioseq("consensus1","GAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq2 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq3 = Bioseq("consensus3","GAGATGGCTCATGGAGTACCTGCCTTGCATGACTGCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq4 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+                    
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2, iBioseq3, iBioseq4 ] )
+
+        iBioseq5 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq6 = Bioseq("consensus3","GAGATGGCTCATGGAGTACCTGCCTTGCATGACTGCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACCTGCCT")
+                 
+        expSubBioseqDB = BioseqDB()
+        expSubBioseqDB.setData( [ iBioseq5, iBioseq6 ] )
+        
+        obsSubBioseqDB = iBioseqDB.extractPart (1, 2)
+        
+        self.assertEquals(expSubBioseqDB, obsSubBioseqDB)
+        
+        
+    def test_bestLength(self):
+        iBioseq1 = Bioseq("consensus1","GAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACC")
+        iBioseq2 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq3 = Bioseq("consensus3","GAGATGGCTCATGGAGTACC")
+        iBioseq4 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq5 = Bioseq("consensus5","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq6 = Bioseq("consensus6","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        iBioseq7 = Bioseq("consensus7","TGCCTGATGGCTCATGGAGTACCTGCCT")
+                    
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2, iBioseq3, iBioseq4, iBioseq5, iBioseq6 , iBioseq7] )
+        
+        iBioseq8 = Bioseq("consensus1","GAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACC")
+        iBioseq9 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq10 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq11 = Bioseq("consensus6","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq8, iBioseq9, iBioseq10, iBioseq11] )
+        
+        obsBioseqDB = iBioseqDB.bestLength (4)
+        
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_bestLength_with_a_none_sequence_include(self):
+        iBioseq1 = Bioseq("consensus1", None)
+        iBioseq2 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq3 = Bioseq("consensus3","GAGATGGCTCATGGAGTACC")
+                    
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2, iBioseq3] )
+        
+        iBioseq4 = Bioseq("consensus1", None)
+        iBioseq5 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq6 = Bioseq("consensus3","GAGATGGCTCATGGAGTACC")
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq4, iBioseq5, iBioseq6] )
+        
+        obsBioseqDB = iBioseqDB.bestLength (3)
+        
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_bestLength_with_a_none_sequence_not_include(self):
+        iBioseq1 = Bioseq("consensus1", None)
+        iBioseq2 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq3 = Bioseq("consensus3","GAGATGGCTCATGGAGTACC")
+                    
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2, iBioseq3] )
+        
+        iBioseq5 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq6 = Bioseq("consensus3","GAGATGGCTCATGGAGTACC")
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq5, iBioseq6] )
+        
+        obsBioseqDB = iBioseqDB.bestLength (2)
+        
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_bestLength_number_of_bioseq_requiered_gt_BioseqDB_size(self):
+        iBioseq1 = Bioseq("consensus1","GAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACC")
+        iBioseq2 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq3 = Bioseq("consensus3","GAGATGGCTCATGGAGTACC")
+                    
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2, iBioseq3] )
+        
+        iBioseq4 = Bioseq("consensus1","GAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACC")
+        iBioseq5 = Bioseq("consensus2","GAGATGGCTCATGGAGTACCGCGAGACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq6 = Bioseq("consensus3","GAGATGGCTCATGGAGTACC")
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq4, iBioseq5, iBioseq6] )
+        
+        obsBioseqDB = iBioseqDB.bestLength (15)
+        
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_extractPatternOfFile(self):
+        fastaFilename = "dummyBioseqDB.fa"
+        f = open(fastaFilename, "w")
+        f.write(">consensus1\nGAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACC\n")
+        f.write(">consensus2\nGAGATGGCTCATGGAGTACCGCGAGACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC\n")
+        f.write(">consensus3\nGAGATGGCTCATGGAGTACC\n")
+        f.write(">consensus4\nGAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC\n")
+        f.write(">consensus11\nTGCCTGAGATGGCTCATGGAGTACCTGCCTTGCCTTGCATGACTGCATGGAGTACCTGCCTGTGCCTGATGGCTCATGGAGTACCTGCCT\n")
+        f.close()
+        
+        iBioseq1 = Bioseq("consensus1","GAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACC")
+        iBioseq2 = Bioseq("consensus11","TGCCTGAGATGGCTCATGGAGTACCTGCCTTGCCTTGCATGACTGCATGGAGTACCTGCCTGTGCCTGATGGCTCATGGAGTACCTGCCT")
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq1, iBioseq2] )
+        
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.extractPatternOfFile("consensus1+" , fastaFilename)
+        os.remove(fastaFilename)
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_extractPatternOfFile_WithNoExistingPattern(self):
+        fastaFilename = "dummyBioseqDB.fa"
+        f = open(fastaFilename, "w")
+        f.write(">consensus1\nGAGATGGCTCATGGAGTACCTGCCTGAGATGGCTCATGGAGTACC\n")
+        f.write(">consensus2\nGAGATGGCTCATGGAGTACCGCGAGACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC\n")
+        f.write(">consensus3\nGAGATGGCTCATGGAGTACC\n")
+        f.write(">consensus4\nGAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC\n")
+        f.write(">consensus11\nTGCCTGAGATGGCTCATGGAGTACCTGCCTTGCCTTGCATGACTGCATGGAGTACCTGCCTGTGCCTGATGGCTCATGGAGTACCTGCCT\n")
+        f.close()
+        
+        expBioseqDB = BioseqDB()
+        
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.extractPatternOfFile("NoExistingPattern" , fastaFilename)
+        os.remove(fastaFilename)
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_getByPattern (self):
+        iBioseq1 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq2 = Bioseq("consensus1","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq3 = Bioseq("consensus6","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        iBioseq4 = Bioseq("consensus11","TGCCTGATGGCTCATGGAGTACCTGCCT")
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2, iBioseq3, iBioseq4] )
+        
+        iBioseq5 = Bioseq("consensus1","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq6 = Bioseq("consensus11","TGCCTGATGGCTCATGGAGTACCTGCCT")
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq5, iBioseq6] )
+       
+        obsBioseqDB = iBioseqDB.getByPattern("consensus1+")
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_getByPattern_with_no_existing_pattern (self):
+        iBioseq1 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq2 = Bioseq("consensus1","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq3 = Bioseq("consensus6","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        iBioseq4 = Bioseq("consensus11","TGCCTGATGGCTCATGGAGTACCTGCCT")
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2, iBioseq3, iBioseq4] )
+        
+        expBioseqDB = BioseqDB()
+       
+        obsBioseqDB = iBioseqDB.getByPattern("noExistingPattern+")
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_getDiffFromPattern (self):
+        iBioseq1 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq2 = Bioseq("consensus1","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq3 = Bioseq("consensus6","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        iBioseq4 = Bioseq("consensus11","TGCCTGATGGCTCATGGAGTACCTGCCT")
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2, iBioseq3, iBioseq4] )
+        
+        iBioseq5 = Bioseq("consensus1","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq6 = Bioseq("consensus11","TGCCTGATGGCTCATGGAGTACCTGCCT")
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq5, iBioseq6] )
+       
+        obsBioseqDB = iBioseqDB.getDiffFromPattern("consensus[4|6]")
+        
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_getDiffFromPattern_with_no_existing_pattern (self):
+        iBioseq1 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq2 = Bioseq("consensus1","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq3 = Bioseq("consensus6","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        iBioseq4 = Bioseq("consensus11","TGCCTGATGGCTCATGGAGTACCTGCCT")
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData( [ iBioseq1, iBioseq2, iBioseq3, iBioseq4] )
+        
+        iBioseq5 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq6 = Bioseq("consensus1","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq7 = Bioseq("consensus6","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        iBioseq8 = Bioseq("consensus11","TGCCTGATGGCTCATGGAGTACCTGCCT")
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq5, iBioseq6, iBioseq7, iBioseq8] )
+       
+        obsBioseqDB = iBioseqDB.getDiffFromPattern("noExistingPattern+")
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_rmByPattern (self):
+        iBioseq1 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq2 = Bioseq("consensus1","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq3 = Bioseq("consensus6","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        iBioseq4 = Bioseq("consensus11","TGCCTGATGGCTCATGGAGTACCTGCCT")
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq1, iBioseq2, iBioseq3, iBioseq4] )
+        
+        iBioseq5 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq6 = Bioseq("consensus6","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq5, iBioseq6 ] )
+       
+        obsBioseqDB.rmByPattern("consensus1+")
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_rmByPattern_with_no_existing_pattern (self):
+        iBioseq1 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq2 = Bioseq("consensus1","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq3 = Bioseq("consensus6","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        iBioseq4 = Bioseq("consensus11","TGCCTGATGGCTCATGGAGTACCTGCCT")
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq1, iBioseq2, iBioseq3, iBioseq4] )
+        
+        iBioseq5 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq6 = Bioseq("consensus1","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq7 = Bioseq("consensus6","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        iBioseq8 = Bioseq("consensus11","TGCCTGATGGCTCATGGAGTACCTGCCT")
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq5, iBioseq6, iBioseq7, iBioseq8 ] )
+        obsBioseqDB.rmByPattern("noExistingPattern+")
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_addBioseqFromABioseqDBIfHeaderContainPattern (self):
+        iBioseq1 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq2 = Bioseq("consensus1","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq3 = Bioseq("consensus7","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        iBioseq4 = Bioseq("consensus11","TGCCTGATGGCTCATGGAGTACCTGCCT")
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq1, iBioseq2, iBioseq3, iBioseq4] )
+        
+        iBioseq5 = Bioseq("Sequence4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq6 = Bioseq("consensus6","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        inBioseqDB = BioseqDB()
+        inBioseqDB.setData( [ iBioseq5, iBioseq6 ])
+
+        iBioseq7 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq8 = Bioseq("consensus1","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq9 = Bioseq("consensus7","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        iBioseq10 = Bioseq("consensus11","TGCCTGATGGCTCATGGAGTACCTGCCT")
+        iBioseq11 = Bioseq("consensus6","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq7, iBioseq8, iBioseq9, iBioseq10, iBioseq11] )
+       
+        obsBioseqDB.addBioseqFromABioseqDBIfHeaderContainPattern("consensus.*", inBioseqDB)
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_addBioseqFromABioseqDBIfHeaderContainPattern_with_no_existing_pattern (self):
+        iBioseq1 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq2 = Bioseq("consensus1","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq3 = Bioseq("consensus7","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        iBioseq4 = Bioseq("consensus11","TGCCTGATGGCTCATGGAGTACCTGCCT")
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq1, iBioseq2, iBioseq3, iBioseq4] )
+        
+        iBioseq5 = Bioseq("Sequence4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq6 = Bioseq("consensus6","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        inBioseqDB = BioseqDB()
+        inBioseqDB.setData( [ iBioseq5, iBioseq6 ])
+
+        iBioseq7 = Bioseq("consensus4","GAGATGGCTCATGGAGTACCGCGAGTGCGGTACCTATGGCCCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGCGAGATGGCTCATGGAGTACCGC")
+        iBioseq8 = Bioseq("consensus1","TGCCTGAGATGGCTCATGGAGTACCTGCCT")
+        iBioseq9 = Bioseq("consensus7","TGCCTTGCATGACTGCATGGAGTACCTGCCTG")
+        iBioseq10 = Bioseq("consensus11","TGCCTGATGGCTCATGGAGTACCTGCCT")
+        
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq7, iBioseq8, iBioseq9, iBioseq10] )
+       
+        obsBioseqDB.addBioseqFromABioseqDBIfHeaderContainPattern("noExistingPattern", inBioseqDB)
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_upCase (self):
+        iBioseq1 = Bioseq("consensus4","atgacGatgca")
+        iBioseq2 = Bioseq("consensus1","atgcgaT")
+        obsBioseqDB = BioseqDB()
+        obsBioseqDB.setData( [ iBioseq1, iBioseq2 ] )
+        iBioseq3 = Bioseq("consensus4","ATGACGATGCA")
+        iBioseq4 = Bioseq("consensus1","ATGCGAT")
+        expBioseqDB = BioseqDB()
+        expBioseqDB.setData( [ iBioseq3, iBioseq4 ] )
+        obsBioseqDB.upCase()
+        self.assertEquals(expBioseqDB, obsBioseqDB)
+        
+        
+    def test_getMap(self):
+        iBioseq1 = Bioseq("header1","ATGC-RA-GCT")
+        iBioseq2 = Bioseq("header2","-TGC-RA-GCT")
+        iBioseq3 = Bioseq("header3","ATGC-RA-GC-")
+
+        iAlignedBioseqDB = BioseqDB()
+        iAlignedBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3])
+        
+        obsDict = iAlignedBioseqDB.getDictOfLMapsWithoutGaps()
+        
+        expLMap1 = [Map( "header1_subSeq1", "header1", 1, 4 ), Map( "header1_subSeq2", "header1", 6, 7 ), Map( "header1_subSeq3", "header1", 9, 11 )]
+        expLMap2 = [Map( "header2_subSeq1", "header2", 2, 4 ), Map( "header2_subSeq2", "header2", 6, 7 ), Map( "header2_subSeq3", "header2", 9, 11 )]
+        expLMap3 = [Map( "header3_subSeq1", "header3", 1, 4 ), Map( "header3_subSeq2", "header3", 6, 7 ), Map( "header3_subSeq3", "header3", 9, 10 )]    
+        
+        expDict = {
+                   "header1": expLMap1,
+                   "header2": expLMap2,
+                   "header3": expLMap3
+                   } 
+        
+        self.assertEquals(expDict, obsDict)
+
+    def test_getSeqLengthByListOfName(self):
+        iBioseq1 = Bioseq("header1","ATGC-RA-GCT")
+        iBioseq2 = Bioseq("header2","-TGC-RAR")
+        iBioseq3 = Bioseq("header3","ATGC")
+
+        iBioseqDB = BioseqDB()
+        iBioseqDB.setData([iBioseq1, iBioseq2, iBioseq3])
+        
+        expList =  [11, 4]
+        obsList = iBioseqDB.getSeqLengthByListOfName(["header1", "header3"])
+        
+        self.assertEquals( expList, obsList )        
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_BioseqDB ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/seq/test/Test_BioseqUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,498 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+from commons.core.seq.Bioseq import Bioseq
+from commons.core.seq.BioseqUtils import BioseqUtils
+from commons.core.utils.FileUtils import FileUtils
+
+
+class Test_BioseqUtils( unittest.TestCase ):
+    
+    def test_translateSequence_one_nt( self ):
+        bioseq = Bioseq()
+        bioseq.sequence = "G"
+        BioseqUtils.translateSequence(bioseq, 1)
+        expSequence = ""
+        obsSequence = bioseq.sequence
+        self.assertEqual(expSequence, obsSequence)
+        
+        
+    def test_translateSequence_frame1( self ):
+        bioseq = Bioseq()
+        bioseq.sequence = "NGTGGCTTCTAGTTGATCAGTTTATGATCACAATGATTTCACGTAGGTGTCTCGTGGCTCCGACTAATCAACAATATAATGCGAGTAGAGCTTGA"
+        BioseqUtils.translateSequence(bioseq, 1)
+        expSequence = "XGF*LISL*SQ*FHVGVSWLRLINNIMRVEL"
+        obsSequence = bioseq.sequence
+        self.assertEqual(expSequence, obsSequence)
+        
+        
+    def test_translateSequence_frame2( self ):
+        bioseq = Bioseq()
+        bioseq.sequence = "NGTGGCTTCTAGTTGATCAGTTTATGATCACAATGATTTCACGTAGGTGTCTCGTGGCTCCGACTAATCAACAATATAATGCGAGTAGAGCTTGA"
+        BioseqUtils.translateSequence(bioseq, 2)
+        expSequence = "VASS*SVYDHNDFT*VSRGSD*STI*CE*SL"
+        obsSequence = bioseq.sequence
+        self.assertEqual(expSequence, obsSequence)
+        
+        
+    def test_translateSequence_frame3( self ):
+        bioseq = Bioseq()
+        bioseq.sequence = "NGTGGCTTCTAGTTGATCAGTTTATGATCACAATGATTTCACGTAGGTGTCTCGTGGCTCCGACTAATCAACAATATAATGCGAGTAGAGCTTGA"
+        BioseqUtils.translateSequence(bioseq, 3)
+        expSequence = "WLLVDQFMITMISRRCLVAPTNQQYNASRA*"
+        obsSequence = bioseq.sequence
+        self.assertEqual(expSequence, obsSequence)
+        
+        
+    def test_setFrameInfoOnHeader(self):
+        bioseq = Bioseq()
+        bioseq.header = "header1 description1 description2"
+        BioseqUtils.setFrameInfoOnHeader(bioseq,1)
+        expHeader = "header1_1 description1 description2"
+        obsHeader = bioseq.header
+        self.assertEquals(expHeader,obsHeader)
+        
+        
+    def test_setFrameInfoOnHeader_header_without_space(self):
+        bioseq = Bioseq()
+        bioseq.header = "header"
+        BioseqUtils.setFrameInfoOnHeader(bioseq,1)
+        expHeader = "header_1"
+        obsHeader = bioseq.header
+        self.assertEquals(expHeader, obsHeader)
+        
+        
+    def test_TranslateInAllFrame( self ):
+        bioseq = Bioseq()
+        bioseq.header = "header1"
+        bioseq.sequence = "TGTGGCTTCTAGTTGATCAGTTTATGATCACAATGATTTCACGTAGGTGTCTCGTGGCTCCGACTAATCAACAATATAATGCGAGTAGAGCTTGA"
+        
+        bioseq1 = Bioseq()
+        bioseq1.header = "header1_1"
+        bioseq1.sequence = "CGF*LISL*SQ*FHVGVSWLRLINNIMRVEL"
+        bioseq2 = Bioseq()
+        bioseq2.header = "header1_2"
+        bioseq2.sequence = "VASS*SVYDHNDFT*VSRGSD*STI*CE*SL"
+        bioseq3 = Bioseq()
+        bioseq3.header = "header1_3"
+        bioseq3.sequence = "WLLVDQFMITMISRRCLVAPTNQQYNASRA*"
+        bioseq4 = Bioseq()
+        bioseq4.header = "header1_4"
+        bioseq4.sequence = "SSSTRIILLISRSHETPT*NHCDHKLIN*KP"
+        bioseq5 = Bioseq()
+        bioseq5.header = "header1_5"
+        bioseq5.sequence = "QALLALYC*LVGATRHLREIIVIIN*STRSH"
+        bioseq6 = Bioseq()
+        bioseq6.header = "header1_6"
+        bioseq6.sequence = "KLYSHYIVD*SEPRDTYVKSL*S*TDQLEAT"
+        
+        expLBioseq = [bioseq1, bioseq2, bioseq3, bioseq4, bioseq5, bioseq6]
+        obsLBioseq = BioseqUtils.translateInAllFrame(bioseq)
+        
+        self.assertEquals(expLBioseq, obsLBioseq) 
+        
+        
+    def test_replaceStopCodonsByX( self ):
+        bioseq = Bioseq()
+        bioseq.sequence = "VASS*SVYDHNDFT*VSRGSD*STI*CE*SL"
+        BioseqUtils.replaceStopCodonsByX(bioseq)
+        expSequence = "VASSXSVYDHNDFTXVSRGSDXSTIXCEXSL"
+        obsSequence = bioseq.sequence
+        self.assertEquals(expSequence, obsSequence)
+        
+        
+    def test_translateBioseqListInAllFrames_with_empty_list( self ):
+        lBioseq = []
+        obsLBioseq = BioseqUtils.translateBioseqListInAllFrames( lBioseq )
+        expLBioseq = []
+        self.assertEquals( expLBioseq, obsLBioseq )
+        
+        
+    def test_translateBioseqListInAllFrames_with_one_item( self ):
+        bioseq1 = Bioseq()
+        bioseq1.header = "header1 description"
+        bioseq1.sequence = "TGTGGCTTCTAGTTGATCAGTTTATGATCACAATGATTTCACGTAGGTGTCTCGTGGCTCCGACTAATCAACAATATAATGCGAGTAGAGCTTGA"
+        lBioseq = [bioseq1]
+        obsLBioseq = BioseqUtils.translateBioseqListInAllFrames( lBioseq )
+       
+        expBioseq1 = Bioseq()
+        expBioseq1.header = "header1_1 description"
+        expBioseq1.sequence = "CGF*LISL*SQ*FHVGVSWLRLINNIMRVEL"
+        
+        expBioseq2 = Bioseq()
+        expBioseq2.header = "header1_2 description"
+        expBioseq2.sequence = "VASS*SVYDHNDFT*VSRGSD*STI*CE*SL"
+        
+        expBioseq3 = Bioseq()
+        expBioseq3.header = "header1_3 description"
+        expBioseq3.sequence = "WLLVDQFMITMISRRCLVAPTNQQYNASRA*"
+
+        expBioseq4 = Bioseq()
+        expBioseq4.header = "header1_4 description"
+        expBioseq4.sequence = "SSSTRIILLISRSHETPT*NHCDHKLIN*KP"        
+
+        expBioseq5 = Bioseq()
+        expBioseq5.header = "header1_5 description"
+        expBioseq5.sequence = "QALLALYC*LVGATRHLREIIVIIN*STRSH"     
+                
+        expBioseq6 = Bioseq()
+        expBioseq6.header =  "header1_6 description"
+        expBioseq6.sequence = "KLYSHYIVD*SEPRDTYVKSL*S*TDQLEAT"    
+        
+        expLBioseq = [expBioseq1, expBioseq2, expBioseq3, expBioseq4, expBioseq5, expBioseq6]
+                     
+        self.assertEquals( expLBioseq, obsLBioseq )
+        
+        
+    def test_translateBioseqListInAllFrames( self ):
+        bioseq1 = Bioseq()
+        bioseq1.header = "header1 description"
+        bioseq1.sequence = "TGTGGCTTCTAGTTGATCAGTTTATGATCACAATGATTTCACGTAGGTGTCTCGTGGCTCCGACTAATCAACAATATAATGCGAGTAGAGCTTGA"
+        bioseq2 = Bioseq()
+        bioseq2.header = "header2"
+        bioseq2.sequence = "TGTGGCTTCTAGTTGATCAGTTTATGATCACAATGATTTCACGTAGGTGTCTCGTGGCTACGACTAATCAACAATATAATGCGAGTAGAGCTTGA"
+        lBioseq = [bioseq1, bioseq2]
+        obsLBioseq = BioseqUtils.translateBioseqListInAllFrames( lBioseq )
+       
+        expBioseq1 = Bioseq()
+        expBioseq1.header = "header1_1 description"
+        expBioseq1.sequence = "CGF*LISL*SQ*FHVGVSWLRLINNIMRVEL"
+        
+        expBioseq2 = Bioseq()
+        expBioseq2.header = "header1_2 description"
+        expBioseq2.sequence = "VASS*SVYDHNDFT*VSRGSD*STI*CE*SL"
+        
+        expBioseq3 = Bioseq()
+        expBioseq3.header = "header1_3 description"
+        expBioseq3.sequence = "WLLVDQFMITMISRRCLVAPTNQQYNASRA*"
+
+        expBioseq4 = Bioseq()
+        expBioseq4.header = "header1_4 description"
+        expBioseq4.sequence = "SSSTRIILLISRSHETPT*NHCDHKLIN*KP"        
+
+        expBioseq5 = Bioseq()
+        expBioseq5.header = "header1_5 description"
+        expBioseq5.sequence = "QALLALYC*LVGATRHLREIIVIIN*STRSH"     
+                
+        expBioseq6 = Bioseq()
+        expBioseq6.header =  "header1_6 description"
+        expBioseq6.sequence = "KLYSHYIVD*SEPRDTYVKSL*S*TDQLEAT"    
+
+        expBioseq7 = Bioseq()
+        expBioseq7.header = "header2_1"
+        expBioseq7.sequence =  "CGF*LISL*SQ*FHVGVSWLRLINNIMRVEL"    
+        
+        expBioseq8 = Bioseq()
+        expBioseq8.header = "header2_2"
+        expBioseq8.sequence = "VASS*SVYDHNDFT*VSRGYD*STI*CE*SL"     
+
+        expBioseq9 = Bioseq()
+        expBioseq9.header = "header2_3"
+        expBioseq9.sequence = "WLLVDQFMITMISRRCLVATTNQQYNASRA*"     
+
+        expBioseq10 = Bioseq()
+        expBioseq10.header = "header2_4"
+        expBioseq10.sequence = "SSSTRIILLISRSHETPT*NHCDHKLIN*KP"
+             
+        expBioseq11 = Bioseq()
+        expBioseq11.header = "header2_5"
+        expBioseq11.sequence = "QALLALYC*LVVATRHLREIIVIIN*STRSH"     
+
+        expBioseq12 = Bioseq()
+        expBioseq12.header = "header2_6"
+        expBioseq12.sequence = "KLYSHYIVD*S*PRDTYVKSL*S*TDQLEAT"     
+
+        expLBioseq = [expBioseq1, expBioseq2, expBioseq3, expBioseq4, expBioseq5, expBioseq6, expBioseq7, expBioseq8, expBioseq9, expBioseq10, expBioseq11, expBioseq12]
+        self.assertEquals( expLBioseq, obsLBioseq )
+        
+        
+    def test_replaceStopCodonsByXInBioseqList_empty_list( self ):
+        lBioseq = []
+        obsLBioseq = BioseqUtils.replaceStopCodonsByXInBioseqList( lBioseq )
+        expLBioseq = []
+        self.assertEquals(obsLBioseq, expLBioseq)
+        
+        
+    def test_replaceStopCodonsByXInBioseqList_without_stop_codon( self ):
+        bioseq1 = Bioseq()
+        bioseq1.header = "header1 description"
+        bioseq1.sequence = "CGFLISLSQFHVGVSWLRLINNIMRVEL"
+        
+        lBioseq = [bioseq1]
+        
+        obsLBioseq = BioseqUtils.replaceStopCodonsByXInBioseqList( lBioseq )
+        
+        bioseq2 = Bioseq()
+        bioseq2.header = "header1 description"
+        bioseq2.sequence = "CGFLISLSQFHVGVSWLRLINNIMRVEL"
+        
+        expLBioseq = [bioseq2]
+      
+        self.assertEquals(obsLBioseq, expLBioseq)
+        
+        
+    def test_replaceStopCodonsByXInBioseqList( self ):
+        bioseq1 = Bioseq()
+        bioseq1.header = "header1 description"
+        bioseq1.sequence = "CGF*LISL*SQ*FHVGVSWLRLINNIMRVEL"
+        
+        bioseq2 = Bioseq()
+        bioseq2.header = "header2"
+        bioseq2.sequence = "VASS*SVYDHNDFT*VSRGSD*STI*CE*SL"
+        
+        lBioseq = [bioseq1, bioseq2]
+        
+        obsLBioseq = BioseqUtils.replaceStopCodonsByXInBioseqList( lBioseq )
+        
+        bioseq3 = Bioseq()
+        bioseq3.header = "header1 description"
+        bioseq3.sequence = "CGFXLISLXSQXFHVGVSWLRLINNIMRVEL"
+        
+        bioseq4 = Bioseq()
+        bioseq4.header = "header2"
+        bioseq4.sequence = "VASSXSVYDHNDFTXVSRGSDXSTIXCEXSL"
+        
+        expLBioseq = [bioseq3, bioseq4]
+      
+        self.assertEquals(obsLBioseq, expLBioseq)
+        
+        
+    def test_writeBioseqListIntoFastaFile(self):
+        obsFileName = "dummyWrittenFastaFile.fa"
+        
+        bioseq1 = Bioseq()
+        bioseq1.header = "header1 description"
+        bioseq1.sequence = "TGTGGCTTCTAGTTGATCAGTTTATGATCACAATGATTTCACGTAGGTGTCTCGTGGCTCCGACTAATCAACAATATAATGCGAGTAGAGCTTGA"
+        bioseq2 = Bioseq()
+        bioseq2.header = "header2"
+        bioseq2.sequence = "TGTGGCTTCTAGTTGATCAGTTTATGATCACAATGATTTCACGTAGGTGTCTCGTGGCTACGACTAATCAACAATATAATGCGAGTAGAGCTTGA"
+
+        lBioseq = [bioseq1, bioseq2]
+        
+        BioseqUtils.writeBioseqListIntoFastaFile( lBioseq, obsFileName )
+        
+        expFileName = "dummyFastaFile.fa"
+        f = open(expFileName, "w")
+        f.write(">header1 description\n")
+        f.write("TGTGGCTTCTAGTTGATCAGTTTATGATCACAATGATTTCACGTAGGTGTCTCGTGGCTC\n")
+        f.write("CGACTAATCAACAATATAATGCGAGTAGAGCTTGA\n")
+        f.write(">header2\n")
+        f.write("TGTGGCTTCTAGTTGATCAGTTTATGATCACAATGATTTCACGTAGGTGTCTCGTGGCTA\n")
+        f.write("CGACTAATCAACAATATAATGCGAGTAGAGCTTGA\n")
+        f.close()
+         
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+        
+    def test_extractBioseqListFromFastaFile( self ): 
+        fileName = "dummyFastaFile.fa"
+        f = open(fileName,"w")
+        f.write(">header1_1 description1\n")
+        f.write("CGF*LISL*SQ*FHVGVSWLRLINNIMRVEL\n")
+        f.write(">header1_2 description2\n")
+        f.write("VASS*SVYDHNDFT*VSRGSD*STI*CE*SL\n")
+        f.write(">header1_3 description3\n")
+        f.write("CWLLVDQFMITMISRRCLVAPTNQQYNASRA*\n")
+        f.close()
+        
+        bioseq1 = Bioseq()
+        bioseq1.header = "header1_1 description1"
+        bioseq1.sequence = "CGF*LISL*SQ*FHVGVSWLRLINNIMRVEL"
+        bioseq2 = Bioseq()
+        bioseq2.header = "header1_2 description2"
+        bioseq2.sequence = "VASS*SVYDHNDFT*VSRGSD*STI*CE*SL"
+        bioseq3 = Bioseq()
+        bioseq3.header = "header1_3 description3"
+        bioseq3.sequence = "CWLLVDQFMITMISRRCLVAPTNQQYNASRA*"
+        
+        expLBioseq = [bioseq1, bioseq2, bioseq3]
+        
+        obsLBioseq = BioseqUtils.extractBioseqListFromFastaFile( fileName )
+        self.assertEquals(expLBioseq , obsLBioseq)
+        
+        os.remove( fileName )
+        
+        
+    def test_extractBioseqListFromFastaFile_empty_seq( self ): 
+        fileName = "dummyFastaFile.fa"
+        f = open(fileName,"w")
+        f.write(">header1_1 description1\n")
+        f.close()
+        
+        bioseq1 = Bioseq()
+        bioseq1.header = "header1_1 description1"
+        bioseq1.sequence = ""
+        expLBioseq = [bioseq1]
+        
+        obsLBioseq = BioseqUtils.extractBioseqListFromFastaFile( fileName )
+        self.assertEquals(expLBioseq , obsLBioseq)
+        
+        os.remove( fileName )
+        
+        
+    def test_extractBioseqListFromFastaFile_empty_file( self ): 
+        fileName = "dummyFastaFile.fa"
+        
+        f = open(fileName,"w")
+        f.close()
+        
+        expLBioseq = []
+        
+        obsLBioseq = BioseqUtils.extractBioseqListFromFastaFile( fileName )
+        self.assertEquals(expLBioseq , obsLBioseq)
+        
+        os.remove( fileName )
+        
+        
+    def test_getSeqLengthWithSeqName ( self ):
+        bioseq1 = Bioseq()
+        bioseq1.header = "header1 description"
+        bioseq1.sequence = "CGF*LISL*SQ*FHVGVSWLRLINNIMRVEL"
+        
+        bioseq2 = Bioseq()
+        bioseq2.header = "header2"
+        bioseq2.sequence = "ATGCGTGCGTAAATGCGTATGCGTATGCGTTCGCGAATGCGTGT"
+        
+        lBioseq = [bioseq1, bioseq2]
+        
+        obsLength = BioseqUtils.getSeqLengthWithSeqName(lBioseq, "header1 description")
+        expLength = 31
+        
+        self.assertEquals( expLength, obsLength)
+        
+        
+    def test_getSeqLengthWithSeqName_second_item ( self ):
+        bioseq1 = Bioseq()
+        bioseq1.header = "header1 description"
+        bioseq1.sequence = "CGF*LISL*SQ*FHVGVSWLRLINNIMRVEL"
+        
+        bioseq2 = Bioseq()
+        bioseq2.header = "header2"
+        bioseq2.sequence = "ATGCGTGCGTAAATGCGTATGCGTATGCGTTCGCGAATGCGTGT"
+        
+        lBioseq = [bioseq1, bioseq2]
+        
+        obsLength = BioseqUtils.getSeqLengthWithSeqName(lBioseq, "header2")
+        expLength = 44
+        
+        self.assertEquals( expLength, obsLength)
+        
+        
+    def test_getSeqLengthWithSeqName_empty_list ( self ):
+        lBioseq = []
+        
+        obsLength = BioseqUtils.getSeqLengthWithSeqName(lBioseq, "header2")
+        expLength = 0
+        
+        self.assertEquals( expLength, obsLength)
+        
+        
+    def test_getSeqLengthWithSeqName_empty_sequence ( self ):
+        bioseq1 = Bioseq()
+        bioseq1.header = "header1 description"
+        bioseq1.sequence = "CGF*LISL*SQ*FHVGVSWLRLINNIMRVEL"
+        
+        bioseq2 = Bioseq()
+        bioseq2.header = "header2"
+        bioseq2.sequence = ""
+        
+        lBioseq = [bioseq1, bioseq2]
+        
+        obsLength = BioseqUtils.getSeqLengthWithSeqName(lBioseq, "header2")
+        expLength = 0
+        
+        self.assertEquals( expLength, obsLength)
+        
+        
+    def test_getSeqLengthWithSeqName_sequence_unknown ( self ):
+        bioseq1 = Bioseq()
+        bioseq1.header = "header1 description"
+        bioseq1.sequence = "CGF*LISL*SQ*FHVGVSWLRLINNIMRVEL"
+        
+        bioseq2 = Bioseq()
+        bioseq2.header = "header2"
+        bioseq2.sequence = "ATGCGTGCGTAAATGCGTATGCGTATGCGTTCGCGAATGCGTGT"
+        
+        lBioseq = [bioseq1, bioseq2]
+        
+        obsLength = BioseqUtils.getSeqLengthWithSeqName(lBioseq, "header3")
+        expLength = 0
+        
+        self.assertEquals( expLength, obsLength)
+        
+        
+    def test_getLengthPerSeqFromFile( self ):
+        inFile = "dummyInFile"
+        inFileHandler = open( inFile, "w" )
+        inFileHandler.write( ">seq1\nAGCGATGCAGCTA\n" )
+        inFileHandler.write( ">seq2\nGCGATGCGCATCGACGCGA\n" )
+        inFileHandler.close()
+        
+        dExp = { "seq1": 13, "seq2": 19 }
+        
+        dObs = BioseqUtils.getLengthPerSeqFromFile( inFile )
+        
+        self.assertEqual( dExp, dObs )
+        
+        os.remove( inFile )
+        
+        
+    def test_getBioseqListSortedByDecreasingLength( self ):
+        lBioseqs = [ Bioseq( "TE2", "ACC" ),
+                    Bioseq( "TE3", "TA" ),
+                    Bioseq( "TE1", "AGCG" ) ]
+        lExp = [ Bioseq( "TE1", "AGCG" ),
+                Bioseq( "TE2", "ACC" ),
+                Bioseq( "TE3", "TA" ) ]
+        lObs = BioseqUtils.getBioseqListSortedByDecreasingLength( lBioseqs )
+        self.assertEquals( lExp, lObs )
+        
+        
+    def test_getBioseqListSortedByDecreasingLengthWithoutGaps( self ):
+        lBioseqs = [ Bioseq( "TE2", "-ACC-" ),
+                    Bioseq( "TE3", "TA---" ),
+                    Bioseq( "TE1", "-AGCG" ) ]
+        lExp = [ Bioseq( "TE1", "-AGCG" ),
+                Bioseq( "TE2", "-ACC-" ),
+                Bioseq( "TE3", "TA---" ) ]
+        lObs = BioseqUtils.getBioseqListSortedByDecreasingLengthWithoutGaps( lBioseqs )
+        self.assertEquals( lExp, lObs )
+        
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_BioseqUtils ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/seq/test/Test_FastaUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,1506 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.seq.FastaUtils import FastaUtils
+from commons.core.seq.test.Utils_for_T_FastaUtils import Utils_for_T_FastaUtils
+from commons.core.utils.FileUtils import FileUtils
+import glob
+import os
+import shutil
+import unittest
+
+
+class Test_FastaUtils( unittest.TestCase ):
+    
+        
+    def test_dbSize_for_empty_file(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_for_empty_file(fileName)
+        
+        obsNb = FastaUtils.dbSize( fileName )
+        
+        expNb = 0
+        os.remove(fileName)
+        self.assertEquals(expNb, obsNb)
+        
+        
+    def test_dbSize_one_sequence(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_one_sequence(fileName)
+        
+        obsNb = FastaUtils.dbSize( fileName )
+        
+        expNb = 1
+        os.remove(fileName)
+        self.assertEquals(expNb, obsNb)
+        
+        
+    def test_dbSize_four_sequences(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_four_sequences(fileName)
+        
+        obsNb = FastaUtils.dbSize( fileName )
+        
+        expNb = 4
+        os.remove(fileName)
+        self.assertEquals(expNb, obsNb)
+        
+        
+    def test_dbChunks(self):
+        inFileName = "dummyBigSeqFastaFile.fa"
+        expChunksFileName = 'exp' + inFileName +'_chunks.fa'
+        expChunksMapFileName = 'exp' + inFileName +'_chunks.map'
+        expCutFileName = 'exp' + inFileName +'_cut'
+        expNStretchFileName = 'exp' + inFileName +'.Nstretch.map'
+        Utils_for_T_FastaUtils._createFastaFile_big_sequence(inFileName)
+        Utils_for_T_FastaUtils._createFastaFile_of_Chunks(expChunksFileName)
+        Utils_for_T_FastaUtils._createMapFile_of_Chunks(expChunksMapFileName)
+        Utils_for_T_FastaUtils._createFastaFile_of_cut(expCutFileName)
+        Utils_for_T_FastaUtils._createFastaFile_of_Nstretch(expNStretchFileName)
+        
+        FastaUtils.dbChunks(inFileName, '60', '10', '11', '', False, 0)
+        
+        obsChunksFileName = inFileName +'_chunks.fa'
+        obsChunksMapFileName = inFileName +'_chunks.map'
+        obsCutFileName = inFileName +'_cut'
+        obsNStretchFileName = inFileName +'.Nstretch.map'
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expChunksFileName, obsChunksFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(expChunksMapFileName, obsChunksMapFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(expCutFileName, obsCutFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(expNStretchFileName, obsNStretchFileName))
+        
+        os.remove(inFileName)
+        os.remove(expChunksFileName)
+        os.remove(expChunksMapFileName)
+        os.remove(expCutFileName)
+        os.remove(expNStretchFileName)
+        os.remove(obsChunksFileName)
+        os.remove(obsChunksMapFileName)
+        os.remove(obsCutFileName)
+        os.remove(obsNStretchFileName)
+        
+        
+    def test_dbChunks_with_clean_and_prefix(self):
+        inFileName = "dummyBigSeqFastaFile.fa"
+        expChunksFileName = 'exp' + inFileName +'_chunks.fa'
+        expChunksMapFileName = 'exp' + inFileName +'_chunks.map'
+        Utils_for_T_FastaUtils._createFastaFile_big_sequence(inFileName)
+        Utils_for_T_FastaUtils._createFastaFile_of_Chunks(expChunksFileName)
+        Utils_for_T_FastaUtils._createMapFile_of_Chunks(expChunksMapFileName)
+
+        FastaUtils.dbChunks(inFileName, '60', '10', '11', 'outFile_chunks', True, 0)
+        
+        obsChunksFileName = "outFile_chunks.fa"
+        obsChunksMapFileName = "outFile_chunks.map"
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expChunksFileName, obsChunksFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(expChunksMapFileName, obsChunksMapFileName))
+        
+        os.remove(inFileName)
+        os.remove(expChunksFileName)
+        os.remove(expChunksMapFileName)
+        os.remove(obsChunksFileName)
+        os.remove(obsChunksMapFileName)
+        
+        
+    def test_dbCumLength_with_empty_file(self):
+        inFileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_for_empty_file(inFileName)
+        
+        expCumulLength = 0
+        
+        inFileHandler = open(inFileName, "r")
+        obsCumulLength = FastaUtils.dbCumLength(inFileHandler)
+        inFileHandler.close()
+        os.remove(inFileName)
+        
+        self.assertEquals(expCumulLength, obsCumulLength)
+        
+    def test_dbCumLength_four_sequences(self):
+        inFileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_four_sequences(inFileName)
+        
+        expCumulLength = 1168
+        
+        inFileHandler = open(inFileName, "r")
+        obsCumulLength = FastaUtils.dbCumLength(inFileHandler)
+        inFileHandler.close()
+        os.remove(inFileName)
+        
+        self.assertEquals(expCumulLength, obsCumulLength)
+        
+        
+    def test_dbLengths( self ):
+        inFileName = "dummyFastaFile.fa"
+        inF = open( inFileName, "w" )
+        inF.write(">seq1\nATGACGT\n")
+        inF.write(">seq2\nATGGCGAGACGT\n")
+        inF.close()
+        lExp = [ 7, 12 ]
+        lObs = FastaUtils.dbLengths( inFileName )
+        self.assertEquals( lExp, lObs )
+        os.remove( inFileName )
+        
+        
+    def test_dbHeaders_with_empty_file(self):
+        inFile = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_for_empty_file( inFile )
+        lExp = []
+        lObs = FastaUtils.dbHeaders( inFile )
+        self.assertEquals( lExp, lObs )
+        os.remove( inFile )
+        
+        
+    def test_dbHeaders_with_one_sequence_without_header(self):
+        inFile = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_sequence_without_header( inFile )
+        lExp = []
+        lObs = FastaUtils.dbHeaders( inFile )
+        self.assertEquals( lExp, lObs )
+        os.remove( inFile )
+        
+        
+    def test_dbHeaders_four_sequences(self):
+        inFile = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_four_sequences( inFile )
+        lExp = [ "seq 1", "seq 2", "seq 3", "seq 4" ]
+        lObs = FastaUtils.dbHeaders( inFile )
+        self.assertEquals( lExp, lObs )
+        os.remove( inFile )
+        
+        
+    def test_dbSplit_no_in_file( self ):
+        inFileName = "dummyFastaFile.fa"
+        isSysExitRaised = False
+        try:
+            FastaUtils.dbSplit( inFileName, 1, False )
+        except SystemExit:
+            isSysExitRaised = True
+        self.assertTrue( isSysExitRaised )
+        
+        
+    def test_dbSplit_emptyFile( self ):
+        inFile = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_for_empty_file( inFile )
+        FastaUtils.dbSplit( inFile, 10, False, 1 )
+        self.assertTrue( not os.path.exists( "batch_1.fa" ) )
+        os.remove( inFile )
+        
+        
+    def test_dbSplit_oneSequence_tenSequencesPerBatch( self ):
+        inFile = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_one_sequence( inFile )
+        
+        expBatchFile = "dummyExpBatch_1.fa"
+        Utils_for_T_FastaUtils._createFastaFile_one_sequence( expBatchFile )
+        
+        FastaUtils.dbSplit( inFile, 10, False )
+        
+        obsBatchFile = "batch_1.fa"
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expBatchFile, obsBatchFile ) )
+        
+        for f in [ inFile, expBatchFile, obsBatchFile ]:
+            os.remove( f )
+        
+        
+    def test_dbSplit_fourSequences_threeSequencesPerBatch( self ):
+        inFile = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_four_sequences( inFile )
+        
+        expBatch1File = "dummyExpBatch_1.fa"
+        expBatch2File = "dummyExpBatch_2.fa"
+        Utils_for_T_FastaUtils._createBatch1_three_sequences( expBatch1File )
+        Utils_for_T_FastaUtils._createBatch2_one_sequence( expBatch2File )
+        
+        FastaUtils.dbSplit( inFile, 3, False )
+        
+        obsBatch1File = "batch_1.fa"
+        obsBatch2File = "batch_2.fa"
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expBatch1File, obsBatch1File ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expBatch2File, obsBatch2File ) )
+        
+        for f in [ inFile, expBatch1File, expBatch2File, obsBatch1File, obsBatch2File ]:
+            os.remove( f )
+            
+            
+    def test_dbSplit_fourSequences_twoSequencesPerBatch_inBatchDirectory( self ):
+        inFile = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_four_sequences( inFile )
+        
+        expBatch1File = "dummyExp_batch_1.fa"
+        expBatch2File = "dummyExp_batch_2.fa"
+        Utils_for_T_FastaUtils._createBatch1_two_sequences( expBatch1File )
+        Utils_for_T_FastaUtils._createBatch2_two_sequences( expBatch2File )
+        
+        FastaUtils.dbSplit( inFile, 2, True, 1 )
+        
+        obsBatch1File = "batches/batch_1.fa"
+        obsBatch2File = "batches/batch_2.fa"
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expBatch1File, obsBatch1File ) )
+        self.assertTrue( FileUtils.are2FilesIdentical( expBatch2File, obsBatch2File ) )
+        
+        for f in [ inFile, expBatch1File, expBatch2File, obsBatch1File, obsBatch2File ]:
+            os.remove( f )
+            
+            
+    def test_dbSplit_tenSequences_oneSequencePerBatch_inBatchDirectory( self ):
+        inFile = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_ten_sequences( inFile )
+        
+        FastaUtils.dbSplit( inFile, 1, True )
+        
+        nb = 1
+        for s in [ '01', '02', '03', '04', '05', '06', '07', '08', '09', '10' ]:
+            expBatchFile = "exp_batch_%s.fa" % ( s )
+            Utils_for_T_FastaUtils._createBatch_one_small_sequence( expBatchFile, "seq " + str(nb) )
+            nb += 1
+            obsBatchFile = "batches/batch_%s.fa" % ( s )
+            self.assertTrue( FileUtils.are2FilesIdentical( expBatchFile, obsBatchFile ) )
+            os.remove( expBatchFile )
+            os.remove( obsBatchFile )
+            
+        os.remove( inFile )
+        os.rmdir( "batches" )
+        
+        
+    def test_dbSplit_twoSequences_oneSequencePerBatch_useSeqHeader( self ):
+        inFile = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils.createFastaFile_twoSequences( inFile )
+        
+        lExpFileNames = [ "seq_1.fa", "seq_2.fa" ]
+        lExpFiles = [ "dummyExp_seq_1.fa", "dummyExp_seq_2.fa" ]
+        Utils_for_T_FastaUtils.createFastaFile_seq_1( lExpFiles[0] )
+        Utils_for_T_FastaUtils.createFastaFile_seq_2( lExpFiles[1] )
+        
+        FastaUtils.dbSplit( inFile, 1, False, True )
+        
+        lObsFiles = glob.glob( "seq*.fa" )
+        lObsFiles.sort()
+        for i in range( 0, len(lExpFileNames) ):
+            self.assertEqual( lExpFileNames[i], lObsFiles[i] )
+            self.assertTrue( FileUtils.are2FilesIdentical( lExpFiles[i], lObsFiles[i] ) )
+            
+        for f in [ inFile ] + lExpFiles + lObsFiles:
+            os.remove( f )
+            
+            
+    def test_dbSplit_twoSequences_otherPrefix( self ):
+        inFile = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils.createFastaFile_twoSequences( inFile )
+        
+        lExpFileNames = [ "query_1.fa", "query_2.fa" ]
+        lExpFiles = [ "dummyExp_seq_1.fa", "dummyExp_seq_2.fa" ]
+        Utils_for_T_FastaUtils.createFastaFile_seq_1( lExpFiles[0] )
+        Utils_for_T_FastaUtils.createFastaFile_seq_2( lExpFiles[1] )
+        
+        FastaUtils.dbSplit( inFile, 1, False, False, "query" )
+        
+        lObsFiles = glob.glob( "query_*.fa" )
+        lObsFiles.sort()
+        for i in range( 0, len(lExpFileNames) ):
+            self.assertEqual( lExpFileNames[i], lObsFiles[i] )
+            self.assertTrue( FileUtils.are2FilesIdentical( lExpFiles[i], lObsFiles[i] ) )
+            
+        for f in [ inFile ] + lExpFiles + lObsFiles:
+            os.remove( f )
+            
+            
+    def test_splitFastaFileInBatches(self):
+        inFileName = "dummyFastaFile.fa"
+        with open(inFileName, "w") as f:
+            f.write(">seq1\n")
+            f.write("ATCGCTAGCTAGCTCGATCTAGTCAGTCTGTTTGGATCGCTCTCTGCTCGGAAATCC\n")
+            f.write(">seq2\n")
+            f.write("ATCGCTAGCTAGCTCG\n")
+            f.write(">seq3\n")
+            f.write("GTTTGGATCGCT\n")
+            f.write(">seq6\n")
+            f.write("ATCGCTAGCTAGCTCGATCTAGTCAGTCTGTTTGGATCGCTCTCTGCTCGGAAATCCTCTGTTTGGATCGCTCTCTGCTCGGAAATCC\n")
+            f.write(">seq5\n")
+            f.write("TTGGATCGCTCTCTGCTCGGAAATCCCGTC\n")
+        expBatch1 = "expBatch_1.fa"
+        with open(expBatch1, "w") as f:
+            f.write(">seq6\n")
+            f.write("ATCGCTAGCTAGCTCGATCTAGTCAGTCTGTTTGGATCGCTCTCTGCTCGGAAATCCTCT\n")
+            f.write("GTTTGGATCGCTCTCTGCTCGGAAATCC\n")
+        expBatch2 = "expBatch_2.fa"
+        with open(expBatch2, "w") as f:
+            f.write(">seq1\n")
+            f.write("ATCGCTAGCTAGCTCGATCTAGTCAGTCTGTTTGGATCGCTCTCTGCTCGGAAATCC\n")
+        expBatch3 = "expBatch_3.fa"
+        with open(expBatch3, "w") as f:
+            f.write(">seq5\n")
+            f.write("TTGGATCGCTCTCTGCTCGGAAATCCCGTC\n")
+            f.write(">seq2\n")
+            f.write("ATCGCTAGCTAGCTCG\n")
+            f.write(">seq3\n")
+            f.write("GTTTGGATCGCT\n")
+        
+        FastaUtils.splitFastaFileInBatches(inFileName, 60)
+        
+        obsBatch1 = "batches/batch_1.fa"
+        obsBatch2 = "batches/batch_2.fa"
+        obsBatch3 = "batches/batch_3.fa"
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expBatch1, obsBatch1))
+        self.assertTrue(FileUtils.are2FilesIdentical(expBatch2, obsBatch2))
+        self.assertTrue(FileUtils.are2FilesIdentical(expBatch3, obsBatch3))
+        
+        os.remove(inFileName)
+        os.remove(expBatch1)
+        os.remove(expBatch2)
+        os.remove(expBatch3)
+        shutil.rmtree("batches")
+            
+            
+    def test_splitFastaFileInBatches_one_seq(self):
+        inFileName = "dummyFastaFile.fa"
+        with open(inFileName, "w") as f:
+            f.write(">seq2\n")
+            f.write("ATCGCTAGCTAGCTCG\n")
+        expBatch1 = "expBatch_1.fa"
+        with open(expBatch1, "w") as f:
+            f.write(">seq2\n")
+            f.write("ATCGCTAGCTAGCTCG\n")
+        
+        FastaUtils.splitFastaFileInBatches(inFileName, 60)
+        
+        obsBatch1 = "batches/batch_1.fa"
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expBatch1, obsBatch1))
+        
+        os.remove(inFileName)
+        os.remove(expBatch1)
+        shutil.rmtree("batches")
+        
+            
+    def test_splitSeqPerCluster_no_in_file(self):
+        inFileName = "dummyFastaFile.fa"
+        isSysExitRaised = False
+        try:
+            FastaUtils.splitSeqPerCluster( inFileName, "Piler", False, False, "seqCluster")
+        except SystemExit:
+            isSysExitRaised = True
+        self.assertTrue(isSysExitRaised)        
+        
+        
+    def test_splitSeqPerCluster_in_file_empty(self):
+        inFileName = "dummyFastaFile.fa"
+        with open(inFileName, 'w'):
+            pass
+        
+        FastaUtils.splitSeqPerCluster( inFileName, "Piler", False, False, "seqCluster")
+        
+        self.assertEquals(glob.glob("seqCluster*.fa"), [])
+        
+        os.remove(inFileName)
+        
+        
+    def test_splitSeqPerCluster_four_sequences_without_dir(self):
+        inFileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_of_four_sequences_with_specific_header(inFileName)
+        
+        expFirstClusterFileName = "exp_seqCluster1.fa"
+        Utils_for_T_FastaUtils._createFastaFile_of_first_cluster_result(expFirstClusterFileName)
+        expSecondClusterFileName = "exp_seqCluster2.fa"
+        Utils_for_T_FastaUtils._createFastaFile_of_second_cluster_result(expSecondClusterFileName)
+        expThirdClusterFileName = "exp_seqCluster3.574.fa"
+        Utils_for_T_FastaUtils._createFastaFile_of_third_cluster_result(expThirdClusterFileName)
+        
+        FastaUtils.splitSeqPerCluster( inFileName, "Piler", False, False, "seqCluster")
+        obsFirstClusterFileName = "seqCluster1.fa"
+        obsSecondClusterFileName = "seqCluster2.fa"
+        obsThirdClusterFileName = "seqCluster3.574.fa"
+        
+        os.remove(inFileName)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFirstClusterFileName, obsFirstClusterFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(expSecondClusterFileName, obsSecondClusterFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(expThirdClusterFileName, obsThirdClusterFileName))
+        
+        os.remove(expFirstClusterFileName)
+        os.remove(expSecondClusterFileName)
+        os.remove(expThirdClusterFileName)
+        os.remove(obsFirstClusterFileName)
+        os.remove(obsSecondClusterFileName)
+        os.remove(obsThirdClusterFileName)
+        
+        
+    def test_splitSeqPerCluster_four_sequences_without_dir_no_split(self):
+        inFileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_of_four_sequences_with_specific_header_in_same_cluster(inFileName)
+        
+        expClusterFileName = "exp_seqCluster.fa"
+        Utils_for_T_FastaUtils._createFastaFile_of_four_sequences_with_specific_header_in_same_cluster(expClusterFileName)
+        
+        FastaUtils.splitSeqPerCluster( inFileName, "Piler", False, False, "seqCluster")
+        obsClusterFileName = "seqCluster1.fa"
+        
+        os.remove(inFileName)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expClusterFileName, obsClusterFileName))
+        
+        os.remove(expClusterFileName)
+        os.remove(obsClusterFileName)
+        
+        
+    def test_splitSeqPerCluster_four_sequences_without_dir_shuffle(self):
+        inFileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_of_four_sequences_with_specific_header_shuffle(inFileName)
+        
+        expFirstClusterFileName = "exp_seqCluster1.fa"
+        Utils_for_T_FastaUtils._createFastaFile_of_first_cluster_result(expFirstClusterFileName)
+        expSecondClusterFileName = "exp_seqCluster2.fa"
+        Utils_for_T_FastaUtils._createFastaFile_of_second_cluster_result(expSecondClusterFileName)
+        expThirdClusterFileName = "exp_seqCluster3.574.fa"
+        Utils_for_T_FastaUtils._createFastaFile_of_third_cluster_result(expThirdClusterFileName)
+        
+        FastaUtils.splitSeqPerCluster( inFileName, "Piler", False, False, "seqCluster")
+        obsFirstClusterFileName = "seqCluster1.fa"
+        obsSecondClusterFileName = "seqCluster2.fa"
+        obsThirdClusterFileName = "seqCluster3.574.fa"
+        
+        os.remove(inFileName)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFirstClusterFileName, obsFirstClusterFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(expSecondClusterFileName, obsSecondClusterFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(expThirdClusterFileName, obsThirdClusterFileName))
+        
+        os.remove(expFirstClusterFileName)
+        os.remove(expSecondClusterFileName)
+        os.remove(expThirdClusterFileName)
+        os.remove(obsFirstClusterFileName)
+        os.remove(obsSecondClusterFileName)
+        os.remove(obsThirdClusterFileName)
+        
+        
+    def test_splitSeqPerCluster_four_sequences_simplify_header(self):
+        inFileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_of_four_sequences_with_specific_header(inFileName)
+        
+        expFirstClusterFileName = "exp_seqCluster1.fa"
+        Utils_for_T_FastaUtils._createFastaFile_of_first_cluster_result_with_simplify_header(expFirstClusterFileName)
+        expSecondClusterFileName = "exp_seqCluster2.fa"
+        Utils_for_T_FastaUtils._createFastaFile_of_second_cluster_result_with_simplify_header(expSecondClusterFileName)
+        expThirdClusterFileName = "exp_seqCluster3.574.fa"
+        Utils_for_T_FastaUtils._createFastaFile_of_third_cluster_result_with_simplify_header(expThirdClusterFileName)
+        
+        FastaUtils.splitSeqPerCluster( inFileName, "Piler", True, False, "seqCluster")
+        obsFirstClusterFileName = "seqCluster1.fa"
+        obsSecondClusterFileName = "seqCluster2.fa"
+        obsThirdClusterFileName = "seqCluster3.574.fa"
+        
+        os.remove(inFileName)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFirstClusterFileName, obsFirstClusterFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(expSecondClusterFileName, obsSecondClusterFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(expThirdClusterFileName, obsThirdClusterFileName))
+        
+        os.remove(expFirstClusterFileName)
+        os.remove(expSecondClusterFileName)
+        os.remove(expThirdClusterFileName)
+        os.remove(obsFirstClusterFileName)
+        os.remove(obsSecondClusterFileName)
+        os.remove(obsThirdClusterFileName)
+        
+        
+    def test_splitSeqPerCluster_four_sequences_with_dir(self):
+        inFileName = "dummyFastaFile.fa" 
+        Utils_for_T_FastaUtils._createFastaFile_of_four_sequences_with_specific_header(inFileName)
+        FastaUtils.splitSeqPerCluster( inFileName, "Piler", False, True, "seqCluster")
+        os.remove(inFileName)
+        
+        for i in ['1', '2', '3.574']:
+            expClusterFileName = "exp_cluster" + i + ".fa"
+            if i == '1':
+                Utils_for_T_FastaUtils._createFastaFile_of_first_cluster_result(expClusterFileName)
+            if i == '2':
+                Utils_for_T_FastaUtils._createFastaFile_of_second_cluster_result(expClusterFileName)
+            if i == '3.574':
+                Utils_for_T_FastaUtils._createFastaFile_of_third_cluster_result(expClusterFileName)
+               
+            obsClusterFileName= inFileName + "_cluster_" + i + "/seqCluster" + i + ".fa"
+            self.assertTrue(FileUtils.are2FilesIdentical(expClusterFileName, obsClusterFileName))
+            os.remove(expClusterFileName)
+            os.remove(obsClusterFileName)
+            os.rmdir( inFileName + "_cluster_" + i )
+            
+            
+    def test_dbLengthFilter_with_one_sequence(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_one_sequence(fileName)
+        
+        expFileNameInf = "exp_dummyFastaFile.fa.Inf12"
+        Utils_for_T_FastaUtils._createFastaFile_for_empty_file(expFileNameInf)
+        expFileNameSup = "exp_dummyFastaFile.fa.Sup12"
+        Utils_for_T_FastaUtils._createFastaFile_one_sequence(expFileNameSup)
+        
+        FastaUtils.dbLengthFilter(12, fileName, verbose=0)
+        
+        obsFileNameInf = "dummyFastaFile.fa.Inf12"
+        obsFileNameSup = "dummyFastaFile.fa.Sup12"
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileNameInf, obsFileNameInf))
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileNameSup, obsFileNameSup))
+        
+        os.remove(fileName)
+        os.remove(expFileNameInf)
+        os.remove(expFileNameSup)
+        os.remove(obsFileNameInf)
+        os.remove(obsFileNameSup)
+        
+    def test_dbLengthFilter_with_four_sequence(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_four_sequences(fileName)
+        
+        expFileNameInf = "exp_dummyFastaFile.fa.Inf130"
+        Utils_for_T_FastaUtils._createFastaFile_one_sequence(expFileNameInf)
+        expFileNameSup = "exp_dummyFastaFile.fa.Sup130"
+        Utils_for_T_FastaUtils._createResult_of_dbLengthFilter_sup(expFileNameSup) 
+        
+        FastaUtils.dbLengthFilter(130, fileName, verbose=0)
+        
+        obsFileNameInf = "dummyFastaFile.fa.Inf130"
+        obsFileNameSup = "dummyFastaFile.fa.Sup130"
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileNameInf, obsFileNameInf))
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileNameSup, obsFileNameSup)) 
+        
+        os.remove(fileName)
+        os.remove(expFileNameInf)
+        os.remove(expFileNameSup)
+        os.remove(obsFileNameInf)
+        os.remove(obsFileNameSup)
+        
+    def test_dbLongestSequences_with_empty_file(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_for_empty_file(fileName)
+      
+        expResult = 0
+        
+        obsResult = FastaUtils.dbLongestSequences( 1, fileName )
+        
+        self.assertEquals(expResult, obsResult)
+        
+        os.remove(fileName)
+        
+    def test_dbLongestSequences_with_one_longest_sequence(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_four_sequences(fileName)
+      
+        expFileName = "exp_dummyFastaFile.fa.best1"
+        f = open(expFileName, 'w')
+        f.write(">seq 3\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+        FastaUtils.dbLongestSequences( 1, fileName, outFileName="", verbose=0, minThresh=0 )
+        
+        obsFileName = "dummyFastaFile.fa.best1"
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(fileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_dbLongestSequences_with_two_longest_sequence(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_three_sequences(fileName)
+        expFileName = "exp_dummyFastaFile.fa.best1"
+        f = open(expFileName, 'w')
+        f.write(">seq 2\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq 4\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()   
+
+        FastaUtils.dbLongestSequences( 2, fileName, outFileName="", verbose=0, minThresh=0 )
+        obsFileName = "dummyFastaFile.fa.best2"
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(fileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_dbExtractSeqHeaders(self):  
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_three_sequences(fileName)
+        expFileName = "exp_dummyFastaFile.fa"
+        f = open(expFileName, 'w')
+        f.write("seq 1\n")
+        f.write("seq 2\n")
+        f.write("seq 4\n")
+        f.close()   
+        
+        FastaUtils.dbExtractSeqHeaders(fileName)  
+        obsFileName = "dummyFastaFile.fa.headers"
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(fileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_dbExtractSeqHeaders_with_empty_file(self):  
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_for_empty_file(fileName)
+        expFileName = "exp_dummyFastaFile.fa"
+        f = open(expFileName, 'w')
+        f.write("")
+        f.close()   
+        
+        FastaUtils.dbExtractSeqHeaders(fileName)  
+        obsFileName = "dummyFastaFile.fa.headers"
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(fileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_dbExtractSeqHeaders_without_header(self):  
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_sequence_without_header(fileName)
+        expFileName = "exp_dummyFastaFile.fa"
+        f = open(expFileName, 'w')
+        f.write("")
+        f.close()   
+        
+        FastaUtils.dbExtractSeqHeaders(fileName)  
+        obsFileName = "dummyFastaFile.fa.headers"
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(fileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_dbExtractByPattern_without_pattern(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_three_sequences(fileName)
+        
+        obsResult = FastaUtils.dbExtractByPattern( "", fileName)
+        
+        expResult = None
+        
+        self.assertEquals(expResult, obsResult)
+        
+        os.remove(fileName)
+
+    def test_dbExtractByPattern(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_three_sequences(fileName)
+        expFileName = "exp_dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_three_sequences(expFileName)
+        
+        FastaUtils.dbExtractByPattern( 'seq', fileName)
+        
+        obsFileName = "dummyFastaFile.fa.extracted"
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(fileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_dbExtractByPattern_with_2_as_pattern(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_three_sequences(fileName)
+        expFileName = "exp_dummyFastaFile.fa"
+        f = open(expFileName, 'w')
+        f.write(">seq 2\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()   
+        
+        FastaUtils.dbExtractByPattern( ' 2', fileName)
+        
+        obsFileName = "dummyFastaFile.fa.extracted"
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(fileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_dbExtractByPattern_with_sandie_as_pattern(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_three_sequences(fileName)
+        expFileName = "exp_dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_for_empty_file(expFileName)
+        
+        FastaUtils.dbExtractByPattern( 'sandie', fileName)
+        
+        obsFileName = "dummyFastaFile.fa.extracted"
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(fileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+    
+    def test_dbExtractByFilePattern_empty_pattern_filename(self):
+        patternFileName = ""
+        isSysExitRaised = False
+        try:
+            FastaUtils.dbExtractByFilePattern(patternFileName , None, "")
+        except SystemExit:
+            isSysExitRaised = True
+        self.assertTrue(isSysExitRaised)        
+        
+    def test_dbExtractByFilePattern(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils. _createFastaFile_ten_sequences(fileName)
+        patternFileName = "dummyPatternFile.txt"
+        Utils_for_T_FastaUtils._createPatternFile(patternFileName)
+        
+        expFileName = "exp_dummyFastaFile.fa"
+        f = open(expFileName, 'w')
+        f.write(">seq 1\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 3\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 8\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 10\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.close()
+        
+        obsFileName = "dummyFastaFile.fa.extracted"
+        
+        FastaUtils.dbExtractByFilePattern( patternFileName, fileName, "")
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(fileName)
+        os.remove(patternFileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_dbCleanByPattern_without_pattern(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils._createFastaFile_three_sequences(fileName)
+        
+        obsResult = FastaUtils.dbCleanByPattern( "", fileName)
+        
+        expResult = None
+        
+        self.assertEquals(expResult, obsResult)
+        
+        os.remove(fileName)
+        
+    def test_dbCleanByPattern(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils. _createFastaFile_ten_sequences(fileName)
+        
+        expFileName = "exp_dummyFastaFile.fa"
+        f = open(expFileName, 'w')
+        f.write(">seq 1\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 3\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 4\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 5\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 6\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 7\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 8\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 9\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 10\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.close()
+        
+        obsFileName = "dummyFastaFile.fa.cleaned"
+        FastaUtils.dbCleanByPattern( '2', fileName)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(fileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_dbCleanByPattern_with_expectedFile_empty(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils. _createFastaFile_ten_sequences(fileName)
+        
+        expFileName = "exp_dummyFastaFile.fa"
+        f = open(expFileName, 'w')
+        f.write("")
+        f.close()
+        
+        obsFileName = "dummyFastaFile.fa.cleaned"
+        FastaUtils.dbCleanByPattern( 'seq', fileName)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(fileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+    
+    def test_dbCleanByFilePattern_empty_pattern_filename(self):
+        patternFileName = ""
+        isSysExitRaised = False
+        try:
+            FastaUtils.dbCleanByFilePattern(patternFileName , None, "")
+        except SystemExit:
+            isSysExitRaised = True
+        self.assertTrue(isSysExitRaised)       
+        
+    def test_dbCleanByFilePattern(self):
+        fileName = "dummyFastaFile.fa"
+        Utils_for_T_FastaUtils. _createFastaFile_ten_sequences(fileName)
+        patternFileName = "dummyPatternFile.txt"
+        Utils_for_T_FastaUtils._createPatternFile(patternFileName)
+        
+        expFileName = "exp_dummyFastaFile.fa"
+        f = open(expFileName, 'w')
+        f.write(">seq 2\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 4\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 5\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 6\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 7\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 9\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.close()
+        
+        obsFileName = "dummyFastaFile.fa.cleaned"
+        
+        FastaUtils.dbCleanByFilePattern( patternFileName, fileName, "")
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        os.remove(fileName)
+        os.remove(patternFileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_dbORF_without_ORF(self):
+        fileName = "dummy.fa"
+        with open(fileName, "w") as f:
+            f.write(">dummy\n")
+            f.write("GGGTTGGGTTGGGTTGGGTTGGGTTGGGTTGGGTTGGGTTGGGTTGGGTT\n")
+    
+        expFileName = "exp.ORF.map"
+        with open(expFileName, "w") as f:
+            f.write("")
+        obsFileName = "%s.ORF.map" % fileName
+        
+        FastaUtils.dbORF(fileName, 0, 0)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+    
+        os.remove(fileName)
+        os.remove(obsFileName)
+        os.remove(expFileName)
+        
+    def test_dbORF_with_one_ORF(self):
+        fileName = "dummyFastaFile.fa"
+        f = open(fileName, 'w')
+        f.write(">seq1\n")
+        f.write("GAAAATATGGGGTAGATAAGGGATCTGGGTTAATTTTTT\n")
+        f.close()
+    
+        expFileName = "exp_dummyORFFile.ORF.map"
+        f = open(expFileName, 'w')
+        f.write("ORF|1|17\tseq1\t16\t33\n")
+        f.close()
+        
+        FastaUtils.dbORF(fileName, 0, 0)
+        obsFileName = fileName + ".ORF.map"
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+    
+        os.remove(fileName)
+        os.remove(obsFileName)
+        os.remove(expFileName)
+        
+    def test_dbORF_with_real_ORF(self):
+        fileName = "dummy.fa"
+        with open(fileName, "w") as f:
+            f.write(">DmelChr4_Blaster_Recon_13_Map_4\n")
+            f.write("AAGTTGGACATTGAGGGCTTTCTTCGCCGTGTTTCGTTCTTTTCGACAAACAGCAGTGCT\n")
+            f.write("TTGCGGATCATTTTGTTTGAACAACCGACAATGCGACCAATTTCAGCGTAGGTTTTACCT\n")
+            f.write("TCAGAGATCACGTTTTTAATCAAATTTCTTTTTTCGACGGTACAATGCTTTCCGCGACCC\n")
+            f.write("ATGACTAGAGAATTTTTGGTCTTCGTTTGGAAAAAATTCAATTAAAACCTTTAATACAAC\n")
+            f.write("TCCTTTTTTCAAAATTTTTCGAAAAAAACCCAAAGCAATCACTCCTATTAATTTTATTCA\n")
+            f.write("GCAAATACGTGTTCAGTGCTATTTTTGTTACCGCCTCATTTCGCGCACTTTTGCAGCAAG\n")
+            f.write("TGCCCAAAAACAAAAAGAACCGTTACATTGAGAGACTAAAAATTTCTTGCTCAGAGAGCC\n")
+            f.write("AACATATGGTACTTATTATTCATGCAATCTGACTTAAAAAAATATAAACATTTAATAATT\n")
+            f.write("TTTTTTAGGAAATCAACTTTCCACCTGCAGTAGTGCTATTATTTTAACCGCAGCTGTATA\n")
+            f.write(">DmelChr4_Blaster_Piler_3.5_Map_7\n")
+            f.write("AGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTT\n")
+            f.write("AGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTT\n")
+            f.write("AGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTT\n")
+            f.write("AGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTT\n")
+            f.write("AGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTT\n")
+            f.write("AGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTT\n")
+            f.write("AGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGGTTAGGGTTAGGGTTAGGGTTAGGGT\n")
+            f.write("TAGGGCTAGGGTTAGGGGTTAGGGTTAGGGTTAGGCTTAGGGTTAGGGTTAGGGTTAGGG\n")
+            f.write("TTAGGGTTAGGGTTAGGGTTAGGAGTTAGGGTGTAGGGTTAGGGTTAGGGTTAGGGTTAG\n")
+            f.write("GGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAG\n")
+            f.write("GGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGCTAGGGTTAGGGTTAG\n")
+            f.write("GGTTAGGGTTAGGGTTAGGGTTAGGGTTAGGGTTAG\n")
+            f.write(">DmelChr4_Blaster_Grouper_10_Map_13\n")
+            f.write("GCAAAGACACTAGAATAACAAGATGCGTAACGGCCATACATTGGTTTGGCACTATGCAGC\n")
+            f.write("CACTTTTTTGGTGACGGCCAAAATTACTCTCTTTCCGCTCACTCCCGCTGAGAGCGTAAG\n")
+            f.write("AAATCTAAAAATATAATTTGCTTGCTTGTGTGAGTAAAAACAAGAGACGAGAACGCGTAT\n")
+            f.write("AAGTGTGCGTGTTGTGCTAGAAGACGATTTTCGGGACCGAAATCAATTCTGATCGAAGAA\n")
+            f.write("ACGAATTTACATGGTACATATTAGGGTAGTTTTTGCCAATTTCCTAGCAATATGATAAAA\n")
+            f.write("TAAAAAAATTTTTAAAAATTCGCGCCCTGACTATTATAATTTTAAAGCTTTTTAAAATTT\n")
+            f.write("GTTTGTTAAAATCGCCGCTCGAATTAGCTACCGTTTACACATTTATATTTATGTTTAATT\n")
+            f.write("CTAATTTGTCTCTCATCTGACAATTTTTTAAGAAAGCGAAATATTTTTTTTTTGAAACAC\n")
+            f.write("TTTTAATGTTAATGTTACATCATATTAAGTCAAATGATTTAATAAATATACTAAATAATT\n")
+            f.write("AAATATGATAACTGTTTATTGCAAAAGTAATATCAAAGACACTAGAATTATTCTAGTGTC\n")
+            f.write("TTTGCTTTGTTCATATCTTGAGGCACGAAGTGCGGACACAAGCACTCAACAATCATTGCC\n")
+            f.write("TTATTAATTTTTCACACGCCGCAAGATGAATACTCTAATGACAAATATTCTTATATAAAG\n")
+            f.write("TCATTTTTGAAATTTATTTTTGTGATAATATGTACATAGATTTGGCTATTTCTAATCTAT\n")
+            f.write("TTTCAAATAATAATAACGTTAAGGCAATGCAAAACAAGAATTTTTTTAGTCGCATGGTGC\n")
+            f.write("CAATTGATCAAAAATAATATAGATTTAAAGTCTAAGAACTTCTAAGGTGAAGGGCATATT\n")
+            f.write("TTGTCAAATTTACAATGCATGAGCGAGCATACGTGTGCACACATACAGTTGTCTGCTATC\n")
+            f.write("ACTTTGTGCGTTGAAAA\n")
+    
+        expFileName = "exp.ORF.map"
+        with open(expFileName, "w") as f:
+            f.write("ORF|3|263\tDmelChr4_Blaster_Recon_13_Map_4\t189\t452\n")
+            f.write("ORF|2|206\tDmelChr4_Blaster_Recon_13_Map_4\t185\t391\n")
+            f.write("ORF|-3|164\tDmelChr4_Blaster_Recon_13_Map_4\t382\t218\n")
+            f.write("ORF|-1|161\tDmelChr4_Blaster_Recon_13_Map_4\t297\t136\n")
+            f.write("ORF|1|113\tDmelChr4_Blaster_Recon_13_Map_4\t400\t513\n")
+            f.write("ORF|1|113\tDmelChr4_Blaster_Recon_13_Map_4\t112\t225\n")
+            f.write("ORF|3|107\tDmelChr4_Blaster_Recon_13_Map_4\t81\t188\n")
+            f.write("ORF|1|107\tDmelChr4_Blaster_Recon_13_Map_4\t292\t399\n")
+            f.write("ORF|-1|104\tDmelChr4_Blaster_Recon_13_Map_4\t432\t328\n")
+            f.write("ORF|-2|104\tDmelChr4_Blaster_Recon_13_Map_4\t515\t411\n")
+            f.write("ORF|3|116\tDmelChr4_Blaster_Piler_3.5_Map_7\t393\t509\n")
+            f.write("ORF|-3|116\tDmelChr4_Blaster_Piler_3.5_Map_7\t505\t389\n")
+            f.write("ORF|-2|86\tDmelChr4_Blaster_Piler_3.5_Map_7\t518\t432\n")
+            f.write("ORF|1|80\tDmelChr4_Blaster_Piler_3.5_Map_7\t436\t516\n")
+            f.write("ORF|-3|170\tDmelChr4_Blaster_Grouper_10_Map_13\t222\t52\n")
+            f.write("ORF|-1|161\tDmelChr4_Blaster_Grouper_10_Map_13\t260\t99\n")
+            f.write("ORF|3|155\tDmelChr4_Blaster_Grouper_10_Map_13\t702\t857\n")
+            f.write("ORF|3|152\tDmelChr4_Blaster_Grouper_10_Map_13\t288\t440\n")
+            f.write("ORF|1|137\tDmelChr4_Blaster_Grouper_10_Map_13\t622\t759\n")
+            f.write("ORF|2|128\tDmelChr4_Blaster_Grouper_10_Map_13\t539\t667\n")
+            f.write("ORF|1|125\tDmelChr4_Blaster_Grouper_10_Map_13\t760\t885\n")
+            f.write("ORF|2|122\tDmelChr4_Blaster_Grouper_10_Map_13\t14\t136\n")
+            f.write("ORF|-2|113\tDmelChr4_Blaster_Grouper_10_Map_13\t847\t734\n")
+            f.write("ORF|1|110\tDmelChr4_Blaster_Grouper_10_Map_13\t154\t264\n")
+        obsFileName = "%s.ORF.map" % fileName
+        
+        FastaUtils.dbORF(fileName, 10, 30)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+    
+        os.remove(fileName)
+        os.remove(obsFileName)
+        os.remove(expFileName)
+        
+    def test_sortSequencesByIncreasingLength(self):
+        fileName = "dummyFastaFile.fa"
+        f = open(fileName, 'w')
+        f.write(">seq1_length_60\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq2_length_120\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq3_length_32\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATAT\n")
+        f.close()
+        
+        expFileName = "exp_dummyFastaFile.fa"
+        f = open(expFileName, 'w')
+        f.write(">seq3_length_32\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATAT\n")
+        f.write(">seq1_length_60\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq2_length_120\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        
+        f.close()
+        
+        obsFileName = "obs_dummyFastaFile.fa"
+        
+        FastaUtils.sortSequencesByIncreasingLength(fileName, obsFileName, 0)
+
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+    
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_sortSequencesByIncreasingLength_in_file_do_not_exists(self):
+        fileName = "dummyFile.fa"
+        isSysExitRaised = False
+        try:
+            FastaUtils.sortSequencesByIncreasingLength(fileName, "", 0)
+        except SystemExit:
+            isSysExitRaised = True
+        
+        self.assertTrue(isSysExitRaised)
+
+    def test_sortSequencesByHeader(self):
+        fileName = "dummyFastaFile.fa"
+        f = open(fileName, "w")
+        f.write(">seq1::test-test\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq3\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATAT\n")
+        f.write(">seq2\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.close()
+        expFileName = "expFastaFile.fa"
+        f = open(expFileName, "w")
+        f.write(">seq1::test-test\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq2\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq3\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATAT\n")
+        f.close()
+        
+        obsFileName = "obsFastaFile.fa"
+        FastaUtils.sortSequencesByHeader(fileName, obsFileName)
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+    
+        os.remove(expFileName)
+        os.remove(obsFileName)
+
+    def test_sortSequencesByHeader_no_outFileName(self):
+        fileName = "dummyFastaFile.fa"
+        f = open(fileName, "w")
+        f.write(">seq12\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq1\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATAT\n")
+        f.write(">seq2\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.close()
+        expFileName = "expFastaFile.fa"
+        f = open(expFileName, "w")
+        f.write(">seq1\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATAT\n")
+        f.write(">seq12\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq2\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.close()
+        
+        obsFileName = "dummyFastaFile_sortByHeaders.fa"
+        FastaUtils.sortSequencesByHeader(fileName)
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+    
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_getLengthPerHeader( self ):
+        inFile = "dummyFile.fa"
+        inFileHandler = open( inFile, "w" )
+        inFileHandler.write(">seq1\nAGCGATGCGT\n")
+        inFileHandler.write(">seq2\nAGCGATG\n")
+        inFileHandler.write(">seq3\nAGCGATGGTGCGTGC\n")
+        inFileHandler.write("AGCGATGGTGCGTGC\n")
+        inFileHandler.close()
+        
+        dExp = { "seq1": 10, "seq2": 7, "seq3": 30 }
+        
+        dObs = FastaUtils.getLengthPerHeader( inFile, 0 )
+        
+        self.assertEquals( dExp, dObs )
+        
+        os.remove( inFile )
+
+    def test_convertFastaHeadersFromChkToChr_grouper(self):
+        inFile = "dummyFastaFile.fa"
+        with open(inFile, "w") as f:
+            f.write(">MbQ1Gr1Cl0 chunk6 {Fragment} 95523..96053\n")
+            f.write("AGCGTGCA\n")
+            f.write(">MbQ77Gr8Cl0 chunk7 {Fragment} 123657..122568,121935..121446\n")
+            f.write("AGCATGC\n")
+            f.write(">MbS78Gr8Cl0 chunk7 {Fragment} 140078..139519,139470..138985,138651..138183\n")
+            f.write("CGTGCG\n")
+            f.write(">MbQ79Gr8Cl0 chunk7 {Fragment} 48021..48587,48669..49153,57346..57834\n")
+            f.write("AGCGTGC\n")
+        mapFile = "dummyMapFile.map"
+        with open(mapFile, "w") as f:
+            f.write("chunk5\tdmel_chr4\t760001\t960000\n")
+            f.write("chunk6\tdmel_chr4\t950001\t1150000\n")
+            f.write("chunk7\tdmel_chr4\t1140001\t1281640\n")
+        expFile = "expFile.fa"
+        with open(expFile, "w") as f:
+            f.write(">MbQ1Gr1Cl0 dmel_chr4 {Fragment} 1045523..1046053\n")
+            f.write("AGCGTGCA\n")
+            f.write(">MbQ77Gr8Cl0 dmel_chr4 {Fragment} 1263657..1262568,1261935..1261446\n")
+            f.write("AGCATGC\n")
+            f.write(">MbS78Gr8Cl0 dmel_chr4 {Fragment} 1280078..1279519,1279470..1278985,1278651..1278183\n")
+            f.write("CGTGCG\n")
+            f.write(">MbQ79Gr8Cl0 dmel_chr4 {Fragment} 1188021..1188587,1188669..1189153,1197346..1197834\n")
+            f.write("AGCGTGC\n")
+        obsFile = "obsFile.fa"
+
+        FastaUtils.convertFastaHeadersFromChkToChr(inFile, mapFile, obsFile)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFile, obsFile))
+        
+        for file in [inFile, mapFile, expFile, obsFile]:
+            os.remove(file)
+        
+    def test_convertFastaHeadersFromChkToChr_blastclust(self):
+        inFile = "dummyFastaFile.fa"
+        with open(inFile, "w") as f:
+            f.write(">BlastclustCluster12Mb63_chunk1 (dbseq-nr 0) [1,10]\n")
+            f.write("AGCGTGCA\n")
+            f.write(">BlastclustCluster12Mb53_chunk2 (dbseq-nr 2) [1,10]\n")
+            f.write("AGCATGC\n")
+            f.write(">BlastclustCluster12Mb26_chunk2 (dbseq-nr 2) [12,18]\n")
+            f.write("CGTGCG\n")
+            f.write(">BlastclustCluster12Mb35_chunk3 (dbseq-nr 0) [10,1]\n")
+            f.write("AGCGTGC\n")
+        mapFile = "dummyMapFile.map"
+        with open(mapFile, "w") as f:
+            f.write("chunk1\tchromosome1\t1\t20\n")
+            f.write("chunk2\tchromosome1\t16\t35\n")
+            f.write("chunk3\tchromosome2\t1\t20\n")
+        expFile = "expFile.fa"
+        with open(expFile, "w") as f:
+            f.write(">BlastclustCluster12Mb63 chromosome1 (dbseq-nr 0) 1..10\n")
+            f.write("AGCGTGCA\n")
+            f.write(">BlastclustCluster12Mb53 chromosome1 (dbseq-nr 2) 16..25\n")
+            f.write("AGCATGC\n")
+            f.write(">BlastclustCluster12Mb26 chromosome1 (dbseq-nr 2) 27..33\n")
+            f.write("CGTGCG\n")
+            f.write(">BlastclustCluster12Mb35 chromosome2 (dbseq-nr 0) 10..1\n")
+            f.write("AGCGTGC\n")
+        obsFile = "obsFile.fa"
+
+        FastaUtils.convertFastaHeadersFromChkToChr(inFile, mapFile, obsFile)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFile, obsFile))
+        
+        for file in [inFile, mapFile, expFile, obsFile]:
+            os.remove(file)
+            
+    def test_convertFastaToLength( self ):
+        inFile = "dummyFastaFile.fa"
+        inFileHandler = open(inFile, "w")
+        inFileHandler.write(">ReconCluster12Mb63 chunk1 {Fragment} 1..10\n")
+        inFileHandler.write("AGCGTGCA\n")
+        inFileHandler.write(">ReconCluster12Mb53 chunk2 {Fragment} 1..10\n")
+        inFileHandler.write("AGCATGCAA\n")
+        inFileHandler.write(">ReconCluster12Mb26 chunk2 {Fragment} 12..18\n")
+        inFileHandler.write("CGTGCGAAAA\n")
+        inFileHandler.write(">ReconCluster12Mb35 chunk3 {Fragment} 10..1\n")
+        inFileHandler.write("AGCGTG\n")
+        inFileHandler.close()
+
+        expFile = "expFile.length"
+        expFileHandler = open(expFile, "w")
+        expFileHandler.write("ReconCluster12Mb63\t8\n")
+        expFileHandler.write("ReconCluster12Mb53\t9\n")
+        expFileHandler.write("ReconCluster12Mb26\t10\n")
+        expFileHandler.write("ReconCluster12Mb35\t6\n")
+        expFileHandler.close()
+        
+        obsFile = "obsFile.length"
+        
+        FastaUtils.convertFastaToLength(inFile, obsFile)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFile, obsFile))
+        
+        for f in [inFile, expFile, obsFile]:
+            os.remove(f)
+            
+    def test_convertFastaToSeq( self ):
+        inFile = "dummyFastaFile.fa"
+        inFileHandler = open(inFile, "w")
+        inFileHandler.write(">ReconCluster12Mb63 chunk1 {Fragment} 1..10\n")
+        inFileHandler.write("AGCGTGCA\n")
+        inFileHandler.write(">ReconCluster12Mb53 chunk2 {Fragment} 1..10\n")
+        inFileHandler.write("AGCATGCAA\n")
+        inFileHandler.write(">ReconCluster12Mb26 chunk2 {Fragment} 12..18\n")
+        inFileHandler.write("CGTGCGAAAA\n")
+        inFileHandler.write(">ReconCluster12Mb35 chunk3 {Fragment} 10..1\n")
+        inFileHandler.write("AGCGTG\n")
+        inFileHandler.close()
+
+        expFile = "expFile.seq"
+        expFileHandler = open(expFile, "w")
+        expFileHandler.write("ReconCluster12Mb63\tAGCGTGCA\tReconCluster12Mb63 chunk1 {Fragment} 1..10\t8\n")
+        expFileHandler.write("ReconCluster12Mb53\tAGCATGCAA\tReconCluster12Mb53 chunk2 {Fragment} 1..10\t9\n")
+        expFileHandler.write("ReconCluster12Mb26\tCGTGCGAAAA\tReconCluster12Mb26 chunk2 {Fragment} 12..18\t10\n")
+        expFileHandler.write("ReconCluster12Mb35\tAGCGTG\tReconCluster12Mb35 chunk3 {Fragment} 10..1\t6\n")
+        expFileHandler.close()
+        
+        obsFile = "obsFile.seq"
+        
+        FastaUtils.convertFastaToSeq(inFile, obsFile)
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFile, obsFile))
+        
+        for f in [inFile, expFile, obsFile]:
+            os.remove(f)
+            
+    def test_spliceFromCoords( self ):
+        coordFile = "dummyCoordFile"
+        coordFileHandler = open( coordFile, "w" )
+        coordFileHandler.write("TE1\tchr1\t2\t5\n")
+        coordFileHandler.write("TE2\tchr1\t15\t11\n")
+        coordFileHandler.write("TE3\tchr2\t1\t3\n")
+        coordFileHandler.write("TE1\tchr2\t8\t10\n")
+        coordFileHandler.write("TE4\tchr3\t3\t1\n")
+        coordFileHandler.write("TE4\tchr3\t6\t4\n")
+        coordFileHandler.close()
+        
+        genomeFile = "dummyGenomeFile"
+        genomeFileHandler = open( genomeFile, "w" )
+        genomeFileHandler.write(">chr1\n")
+        genomeFileHandler.write("AGGGGAAAAACCCCCAAAAA\n")
+        genomeFileHandler.write(">chr2\n")
+        genomeFileHandler.write("GGGAAAAGGG\n")
+        genomeFileHandler.write(">chr3\n")
+        genomeFileHandler.write("GGGGGGTTTT\n")
+        genomeFileHandler.close()
+        
+        expFile = "dummyExpFile"
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write(">chr1\n")
+        expFileHandler.write("AAAAAAAAAAA\n")
+        expFileHandler.write(">chr2\n")
+        expFileHandler.write("AAAA\n")
+        expFileHandler.write(">chr3\n")
+        expFileHandler.write("TTTT\n")
+        expFileHandler.close()
+        
+        obsFile = "dummyObsFile"
+        
+        FastaUtils.spliceFromCoords( genomeFile,
+                                     coordFile,
+                                     obsFile )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        for f in [ coordFile, genomeFile, expFile, obsFile ]:
+            os.remove( f )
+            
+    def test_dbShuffle_inputFile( self ):
+        inFile = "dummyInFile.fa"
+        inFileHandler = open( inFile, "w" )
+        inFileHandler.write(">seq1\n")
+        inFileHandler.write("AGCGATCGACAGCGCATCGCGCATCGCATCGCTACGCATAC\n")
+        inFileHandler.close()
+        
+        obsFile = "dummyObsFile.fa"
+        FastaUtils.dbShuffle( inFile, obsFile, 1 )
+        
+        self.assertTrue( FastaUtils.dbSize( obsFile ) == 1 )
+        
+        for f in [ inFile, obsFile ]:
+            os.remove( f )
+            
+    def test_dbShuffle_inputDir( self ):
+        inDir = "dummyInDir"
+        if os.path.exists( inDir ):
+            shutil.rmtree( inDir )
+        os.mkdir( inDir )
+        inFile = "%s/dummyInFile.fa" % inDir
+        inFileHandler = open( inFile, "w" )
+        inFileHandler.write(">seq1\n")
+        inFileHandler.write("AGCGATCGACAGCGCATCGCGCATCGCATCGCTACGCATAC\n")
+        inFileHandler.close()
+        
+        obsDir = "dummyObsDir"
+        FastaUtils.dbShuffle( inDir, obsDir, 1 )
+        
+        obsFile = "dummyInFile_shuffle.fa"
+        self.assertTrue( len( glob.glob("%s/%s" % (obsDir,obsFile)) ) == 1 )
+        
+        for d in [ inDir, obsDir ]:
+            shutil.rmtree( d )
+            
+    def test_convertClusterFileToFastaFile(self):
+        inClusterFileName = "in.tab"
+        with open(inClusterFileName, "w") as f:
+            f.write("DTX-incomp_DmelChr4-B-R10-Map3_reversed\tDTX-incomp_DmelChr4-B-R9-Map3_reversed\tDTX-incomp_DmelChr4-B-G9-Map3\n")
+            f.write("PotentialHostGene-chim_DmelChr4-B-R5-Map5\tPotentialHostGene-chim_DmelChr4-B-R4-Map5_reversed\n")
+            f.write("RLX-incomp_DmelChr4-B-G220-Map3\n")
+        inFastaFileName = "in.fa"
+        with open(inFastaFileName, "w") as f:
+            f.write(">DTX-incomp_DmelChr4-B-R10-Map3_reversed\n")
+            f.write("ATCGCATCGATCGATC\n")
+            f.write(">DTX-incomp_DmelChr4-B-R9-Map3_reversed\n")
+            f.write("ATCGCATCGATCGATC\n")
+            f.write(">RLX-incomp_DmelChr4-B-G220-Map3\n")
+            f.write("ATCGCC\n")
+            f.write(">PotentialHostGene-chim_DmelChr4-B-R5-Map5\n")
+            f.write("ATCGCATCGATCGATCATCGCATCGATCGATC\n")
+            f.write(">PotentialHostGene-chim_DmelChr4-B-R4-Map5_reversed\n")
+            f.write("ATCGCATCGATCGATCATCGCATCGATCGATC\n")
+            f.write(">DTX-incomp_DmelChr4-B-G9-Map3\n")
+            f.write("ATCGCATCGATCGATC\n")
+        expFileName = "exp.fa"
+        with open(expFileName, "w") as f:
+            f.write(">BlastclustCluster1Mb1_DTX-incomp_DmelChr4-B-R10-Map3_reversed\n")
+            f.write("ATCGCATCGATCGATC\n")
+            f.write(">BlastclustCluster1Mb2_DTX-incomp_DmelChr4-B-R9-Map3_reversed\n")
+            f.write("ATCGCATCGATCGATC\n")
+            f.write(">BlastclustCluster3Mb1_RLX-incomp_DmelChr4-B-G220-Map3\n")
+            f.write("ATCGCC\n")
+            f.write(">BlastclustCluster2Mb1_PotentialHostGene-chim_DmelChr4-B-R5-Map5\n")
+            f.write("ATCGCATCGATCGATCATCGCATCGATCGATC\n")
+            f.write(">BlastclustCluster2Mb2_PotentialHostGene-chim_DmelChr4-B-R4-Map5_reversed\n")
+            f.write("ATCGCATCGATCGATCATCGCATCGATCGATC\n")
+            f.write(">BlastclustCluster1Mb3_DTX-incomp_DmelChr4-B-G9-Map3\n")
+            f.write("ATCGCATCGATCGATC\n")
+        obsFileName = "obs.fa"
+        
+        FastaUtils.convertClusterFileToFastaFile(inClusterFileName, inFastaFileName, obsFileName, "Blastclust")
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        os.remove(inClusterFileName)
+        os.remove(inFastaFileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+
+    
+    def test_convertClusterFileToFastaFile_withoutUnclusterizedSequences(self):
+        inClusterFileName = "in.tab"
+        with open(inClusterFileName, "w") as f:
+            f.write("DTX-incomp_DmelChr4-B-R10-Map3_reversed\tDTX-incomp_DmelChr4-B-R9-Map3_reversed\tDTX-incomp_DmelChr4-B-G9-Map3\n")
+            f.write("PotentialHostGene-chim_DmelChr4-B-R5-Map5\tPotentialHostGene-chim_DmelChr4-B-R4-Map5_reversed\n")
+        inFastaFileName = "in.fa"
+        with open(inFastaFileName, "w") as f:
+            f.write(">DTX-incomp_DmelChr4-B-R10-Map3_reversed\n")
+            f.write("ATCGCATCGATCGATC\n")
+            f.write(">DTX-incomp_DmelChr4-B-R9-Map3_reversed\n")
+            f.write("ATCGCATCGATCGATC\n")
+            f.write(">RLX-incomp_DmelChr4-B-G220-Map3\n")
+            f.write("ATCGCC\n")
+            f.write(">PotentialHostGene-chim_DmelChr4-B-R5-Map5\n")
+            f.write("ATCGCATCGATCGATCATCGCATCGATCGATC\n")
+            f.write(">PotentialHostGene-chim_DmelChr4-B-R4-Map5_reversed\n")
+            f.write("ATCGCATCGATCGATCATCGCATCGATCGATC\n")
+            f.write(">DTX-incomp_DmelChr4-B-G9-Map3\n")
+            f.write("ATCGCATCGATCGATC\n")
+        expFileName = "exp.fa"
+        with open(expFileName, "w") as f:
+            f.write(">BlastclustCluster1Mb1_DTX-incomp_DmelChr4-B-R10-Map3_reversed\n")
+            f.write("ATCGCATCGATCGATC\n")
+            f.write(">BlastclustCluster1Mb2_DTX-incomp_DmelChr4-B-R9-Map3_reversed\n")
+            f.write("ATCGCATCGATCGATC\n")
+            f.write(">BlastclustCluster3Mb1_RLX-incomp_DmelChr4-B-G220-Map3\n")
+            f.write("ATCGCC\n")
+            f.write(">BlastclustCluster2Mb1_PotentialHostGene-chim_DmelChr4-B-R5-Map5\n")
+            f.write("ATCGCATCGATCGATCATCGCATCGATCGATC\n")
+            f.write(">BlastclustCluster2Mb2_PotentialHostGene-chim_DmelChr4-B-R4-Map5_reversed\n")
+            f.write("ATCGCATCGATCGATCATCGCATCGATCGATC\n")
+            f.write(">BlastclustCluster1Mb3_DTX-incomp_DmelChr4-B-G9-Map3\n")
+            f.write("ATCGCATCGATCGATC\n")
+        obsFileName = "obs.fa"
+        
+        FastaUtils.convertClusterFileToFastaFile(inClusterFileName, inFastaFileName, obsFileName, "Blastclust")
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        os.remove(inClusterFileName)
+        os.remove(inFastaFileName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_convertClusterFileToMapFile(self):
+        for clustAlgo in ["Blastclust", "MCL"]:
+            inFileName = "dummy%sOut.fa"  % clustAlgo
+            inF = open(inFileName, "w")
+            inF.write(">%sCluster1Mb1_chunk1 (dbseq-nr 1) [1,14]\n" % clustAlgo)
+            inF.write("gaattgtttactta\n")
+            inF.write(">%sCluster3Mb1_chunk5 (dbseq-nr 8) [1000,1014]\n" % clustAlgo)
+            inF.write("gaattgtttactta\n")
+            inF.write(">%sCluster1Mb2_chunk1 (dbseq-nr 1) [30,44]\n" % clustAlgo)
+            inF.write("gaattgtttactta\n")
+            inF.write(">%sCluster2Mb1_chunk2 (dbseq-nr 1) [100,114]\n" % clustAlgo)
+            inF.write("gaattgtttactta")
+            inF.close()
+            
+            fileExp = "%sToMapExpected.map" % clustAlgo
+            outF = open(fileExp, "w")
+            outF.write("%sCluster1Mb1\tchunk1\t1\t14\n" % clustAlgo)
+            outF.write("%sCluster3Mb1\tchunk5\t1000\t1014\n" % clustAlgo)
+            outF.write("%sCluster1Mb2\tchunk1\t30\t44\n" % clustAlgo)
+            outF.write("%sCluster2Mb1\tchunk2\t100\t114\n" % clustAlgo)
+            outF.close()
+            
+            fileObs = "%s.map" % os.path.splitext(inFileName)[0]
+            FastaUtils.convertClusteredFastaFileToMapFile(inFileName, fileObs)
+            
+            self.assertTrue(FileUtils.are2FilesIdentical(fileObs, fileExp))
+            
+            os.remove(inFileName)
+            os.remove(fileObs)
+            os.remove(fileExp)
+            
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/seq/test/Utils_for_T_FastaUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,857 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+class Utils_for_T_FastaUtils( object ):
+    
+    def _createFastaFile_for_empty_file(fileName):
+        f = open(fileName, 'w')
+        f.write("")
+        f.close()
+        
+    _createFastaFile_for_empty_file = staticmethod ( _createFastaFile_for_empty_file )
+    
+    
+    def _createFastaFile_one_sequence(fileName):
+        f = open(fileName, 'w')
+        f.write(">seq 1\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_one_sequence = staticmethod ( _createFastaFile_one_sequence )
+    
+    
+    def createFastaFile_twoSequences( fileName ):
+        f = open( fileName, "w" )
+        f.write( ">seq 1\n" )
+        f.write( "ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n" )
+        f.write( "ATATTCG\n" )
+        f.write( ">seq 2\n" )
+        f.write( "ATATTCTTTCATCGATCGATCGGCGGCTATATGCTAGTGACGAAGCTAGTGTGAGTAGTA\n" )
+        f.write( "ATATTCG\n" )
+        f.close()
+        
+    createFastaFile_twoSequences = staticmethod ( createFastaFile_twoSequences )
+    
+    
+    def createFastaFile_seq_1( fileName ):
+        f = open( fileName, "w" )
+        f.write( ">seq 1\n" )
+        f.write( "ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n" )
+        f.write( "ATATTCG\n" )
+        f.close()
+        
+    createFastaFile_seq_1 = staticmethod( createFastaFile_seq_1 )
+    
+    
+    def createFastaFile_seq_2( fileName ):
+        f = open( fileName, "w" )
+        f.write( ">seq 2\n" )
+        f.write( "ATATTCTTTCATCGATCGATCGGCGGCTATATGCTAGTGACGAAGCTAGTGTGAGTAGTA\n" )
+        f.write( "ATATTCG\n" )
+        f.close()
+        
+    createFastaFile_seq_2 = staticmethod( createFastaFile_seq_2 )
+    
+    
+    def _createFastaFile_sequence_without_header(fileName):
+        f = open(fileName, 'w')
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_sequence_without_header = staticmethod ( _createFastaFile_sequence_without_header )
+    
+        
+    def _createFastaFile_four_sequences(fileName):
+        f = open(fileName, 'w')
+        f.write(">seq 1\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq 2\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq 3\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq 4\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_four_sequences = staticmethod ( _createFastaFile_four_sequences )
+    
+    
+    def _createFastaFile_three_sequences(fileName):
+        f = open(fileName, 'w')
+        f.write(">seq 1\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq 2\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq 4\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_three_sequences = staticmethod ( _createFastaFile_three_sequences )
+    
+    
+# ------------------ for dbSplit ---------------- #
+
+    def _createBatch1_two_sequences(inFileName):
+        f = open(inFileName, 'w')
+        f.write(">seq 1\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq 2\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createBatch1_two_sequences = staticmethod ( _createBatch1_two_sequences )
+    
+    
+    def _createBatch2_two_sequences(inFileName):
+        f = open(inFileName, 'w')
+        f.write(">seq 3\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq 4\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createBatch2_two_sequences = staticmethod ( _createBatch2_two_sequences )
+    
+    
+    def _createBatch1_three_sequences(inFileName):
+        f = open(inFileName, 'w')
+        f.write(">seq 1\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq 2\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq 3\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createBatch1_three_sequences = staticmethod ( _createBatch1_three_sequences )
+    
+    
+    def _createBatch2_one_sequence(inFileName):
+        f = open(inFileName, 'w')
+        f.write(">seq 4\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createBatch2_one_sequence = staticmethod ( _createBatch2_one_sequence )
+    
+    
+    def _createFastaFile_ten_sequences(fileName):
+        f = open(fileName, 'w')
+        f.write(">seq 1\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 2\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 3\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 4\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 5\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 6\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 7\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 8\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 9\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">seq 10\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.close()
+        
+    _createFastaFile_ten_sequences = staticmethod ( _createFastaFile_ten_sequences )
+    
+    
+    def _createBatch_one_small_sequence(fileName, seqName):
+        f = open(fileName, 'w')
+        f.write(">" +seqName + "\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.close()
+        
+    _createBatch_one_small_sequence = staticmethod ( _createBatch_one_small_sequence )
+    
+    
+# ------------------ for dbChunks ------------------- #
+
+    def _createFastaFile_big_sequence(fileName):
+        f = open(fileName, 'w')
+        f.write(">sequence\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_big_sequence = staticmethod ( _createFastaFile_big_sequence )
+    
+    
+    def _createFastaFile_of_Chunks(fileName):
+        f = open(fileName, 'w')
+        f.write('>chunk01\n')
+        f.write('ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n')
+        f.write('>chunk02\n')
+        f.write('GTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGT\n')
+        f.write('>chunk03\n')
+        f.write('GCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCA\n')
+        f.write('>chunk04\n')
+        f.write('ATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTAT\n')
+        f.write('>chunk05\n')
+        f.write('CGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGAT\n')
+        f.write('>chunk06\n')
+        f.write('ATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGC\n')
+        f.write('>chunk07\n')
+        f.write('ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n')
+        f.write('>chunk08\n')
+        f.write('GTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGT\n')
+        f.write('>chunk09\n')
+        f.write('GCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCA\n')
+        f.write('>chunk10\n')
+        f.write('ATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTAT\n')
+        f.write('>chunk11\n')
+        f.write('CGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGAT\n')
+        f.write('>chunk12\n')
+        f.write('ATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGC\n')
+        f.write('>chunk13\n')
+        f.write('ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n')
+        f.write('>chunk14\n')
+        f.write('GTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGT\n')
+        f.write('>chunk15\n')
+        f.write('GCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCA\n')
+        f.write('>chunk16\n')
+        f.write('ATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTAT\n')
+        f.write('>chunk17\n')
+        f.write('CGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGAT\n')
+        f.write('>chunk18\n')
+        f.write('ATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGC\n')
+        f.write('>chunk19\n')
+        f.write('ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n')
+        f.write('>chunk20\n')
+        f.write('GTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGT\n')
+        f.write('>chunk21\n')
+        f.write('GCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCA\n')
+        f.write('>chunk22\n')
+        f.write('ATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTAT\n')
+        f.write('>chunk23\n')
+        f.write('CGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCG\n')
+        f.close()
+        
+    _createFastaFile_of_Chunks = staticmethod ( _createFastaFile_of_Chunks )
+    
+    
+    def _createMapFile_of_Chunks(fileName):
+        f = open(fileName, 'w')
+        f.write("chunk01\tsequence\t1\t60\n")
+        f.write("chunk02\tsequence\t51\t110\n")
+        f.write("chunk03\tsequence\t101\t160\n")
+        f.write("chunk04\tsequence\t151\t210\n")
+        f.write("chunk05\tsequence\t201\t260\n")
+        f.write("chunk06\tsequence\t251\t310\n")
+        f.write("chunk07\tsequence\t301\t360\n")
+        f.write("chunk08\tsequence\t351\t410\n")
+        f.write("chunk09\tsequence\t401\t460\n")
+        f.write("chunk10\tsequence\t451\t510\n")
+        f.write("chunk11\tsequence\t501\t560\n")
+        f.write("chunk12\tsequence\t551\t610\n")
+        f.write("chunk13\tsequence\t601\t660\n")
+        f.write("chunk14\tsequence\t651\t710\n")
+        f.write("chunk15\tsequence\t701\t760\n")
+        f.write("chunk16\tsequence\t751\t810\n")
+        f.write("chunk17\tsequence\t801\t860\n")
+        f.write("chunk18\tsequence\t851\t910\n")
+        f.write("chunk19\tsequence\t901\t960\n")
+        f.write("chunk20\tsequence\t951\t1010\n")
+        f.write("chunk21\tsequence\t1001\t1060\n")
+        f.write("chunk22\tsequence\t1051\t1110\n")
+        f.write("chunk23\tsequence\t1101\t1147\n")
+        f.close()
+        
+    _createMapFile_of_Chunks = staticmethod ( _createMapFile_of_Chunks )
+    
+    
+    def _createFastaFile_of_cut(fileName):
+        f = open(fileName, 'w')
+        f.write(">1  sequence {Cut} 1..60\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">2  sequence {Cut} 51..110\n")
+        f.write("GTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGT\n")
+        f.write(">3  sequence {Cut} 101..160\n")
+        f.write("GCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCA\n")
+        f.write(">4  sequence {Cut} 151..210\n")
+        f.write("ATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTAT\n")
+        f.write(">5  sequence {Cut} 201..260\n")
+        f.write("CGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGAT\n")
+        f.write(">6  sequence {Cut} 251..310\n")
+        f.write("ATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGC\n")
+        f.write(">7  sequence {Cut} 301..360\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">8  sequence {Cut} 351..410\n")
+        f.write("GTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGT\n")
+        f.write(">9  sequence {Cut} 401..460\n")
+        f.write("GCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCA\n")
+        f.write(">10  sequence {Cut} 451..510\n")
+        f.write("ATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTAT\n")
+        f.write(">11  sequence {Cut} 501..560\n")
+        f.write("CGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGAT\n")
+        f.write(">12  sequence {Cut} 551..610\n")
+        f.write("ATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGC\n")
+        f.write(">13  sequence {Cut} 601..660\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">14  sequence {Cut} 651..710\n")
+        f.write("GTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGT\n")
+        f.write(">15  sequence {Cut} 701..760\n")
+        f.write("GCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCA\n")
+        f.write(">16  sequence {Cut} 751..810\n")
+        f.write("ATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTAT\n")
+        f.write(">17  sequence {Cut} 801..860\n")
+        f.write("CGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGAT\n")
+        f.write(">18  sequence {Cut} 851..910\n")
+        f.write("ATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGC\n")
+        f.write(">19  sequence {Cut} 901..960\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write(">20  sequence {Cut} 951..1010\n")
+        f.write("GTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGT\n")
+        f.write(">21  sequence {Cut} 1001..1060\n")
+        f.write("GCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCA\n")
+        f.write(">22  sequence {Cut} 1051..1110\n")
+        f.write("ATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCGCGCATCGATCGATCGGCGGCTAT\n")
+        f.write(">23  sequence {Cut} 1101..1147\n")
+        f.write("CGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTAATATTCG\n")
+        f.close()
+        
+    _createFastaFile_of_cut = staticmethod ( _createFastaFile_of_cut )
+    
+    
+    def _createFastaFile_of_Nstretch(fileName):
+        f = open(fileName, 'w')
+        f.write("")
+        f.close()
+        
+    _createFastaFile_of_Nstretch = staticmethod ( _createFastaFile_of_Nstretch )
+    
+    
+# ------------------ for splitSeqPerCluster ------------------- #
+    
+    def _createFastaFile_of_four_sequences_with_specific_header(inFileName):
+        f = open(inFileName, 'w')
+        f.write(">ReconCluster1Mb155 chunk183 {Fragment} 1..5506\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">MbQ3Gr2Cl0 chunk440 {Fragment} 2678..3645\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">MbS2Gr2Cl0 chunk622 {Fragment} 104..1078\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">PilerCluster3.574Mb796 chunk0117 {Fragment} 51582..50819\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_of_four_sequences_with_specific_header = staticmethod ( _createFastaFile_of_four_sequences_with_specific_header )
+    
+    
+    def _createFastaFile_of_four_sequences_with_specific_header_shuffle(inFileName):
+        f = open(inFileName, 'w')
+        f.write(">MbQ3Gr2Cl0 chunk440 {Fragment} 2678..3645\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">ReconCluster1Mb155 chunk183 {Fragment} 1..5506\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">MbS2Gr2Cl0 chunk622 {Fragment} 104..1078\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">PilerCluster3.574Mb796 chunk0117 {Fragment} 51582..50819\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_of_four_sequences_with_specific_header_shuffle = staticmethod ( _createFastaFile_of_four_sequences_with_specific_header_shuffle )
+    
+    
+    def _createFastaFile_of_four_sequences_with_specific_header_in_same_cluster(inFileName):
+        f = open(inFileName, 'w')
+        f.write(">ReconCluster1Mb155 chunk1 {Fragment} 1..5506\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">ReconCluster1Mb155 chunk2 {Fragment} 1..5506\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">ReconCluster1Mb155 chunk3 {Fragment} 1..5506\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">ReconCluster1Mb155 chunk4 {Fragment} 1..5506\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_of_four_sequences_with_specific_header_in_same_cluster = staticmethod ( _createFastaFile_of_four_sequences_with_specific_header_in_same_cluster )
+    
+    
+    def _createFastaFile_of_first_cluster_result(inFileName):
+        f = open(inFileName, 'w')
+        f.write(">ReconCluster1Mb155 chunk183 {Fragment} 1..5506\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_of_first_cluster_result = staticmethod ( _createFastaFile_of_first_cluster_result )
+    
+    
+    def _createFastaFile_of_second_cluster_result(inFileName):
+        f = open(inFileName, 'w')
+        f.write(">MbQ3Gr2Cl0 chunk440 {Fragment} 2678..3645\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">MbS2Gr2Cl0 chunk622 {Fragment} 104..1078\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_of_second_cluster_result = staticmethod ( _createFastaFile_of_second_cluster_result )
+    
+    
+    def _createFastaFile_of_third_cluster_result(inFileName): 
+        f = open(inFileName, 'w')
+        f.write(">PilerCluster3.574Mb796 chunk0117 {Fragment} 51582..50819\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_of_third_cluster_result = staticmethod ( _createFastaFile_of_third_cluster_result )
+    
+    
+    def _createFastaFile_of_first_cluster_result_with_simplify_header(inFileName):
+        f = open(inFileName, 'w')
+        f.write(">Piler_Cluster1_Seq155\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_of_first_cluster_result_with_simplify_header = staticmethod ( _createFastaFile_of_first_cluster_result_with_simplify_header )
+    
+    
+    def _createFastaFile_of_second_cluster_result_with_simplify_header(inFileName):
+        f = open(inFileName, 'w')
+        f.write(">Piler_Cluster2_Seq3\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">Piler_Cluster2_Seq2\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_of_second_cluster_result_with_simplify_header = staticmethod ( _createFastaFile_of_second_cluster_result_with_simplify_header )
+    
+    
+    def _createFastaFile_of_third_cluster_result_with_simplify_header(inFileName): 
+        f = open(inFileName, 'w')
+        f.write(">Piler_Cluster3.574_Seq796\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_of_third_cluster_result_with_simplify_header = staticmethod ( _createFastaFile_of_third_cluster_result_with_simplify_header )
+        
+# ---------------------------------- #
+    
+    def _createPatternFile(fileName):
+        f = open(fileName, 'w')
+        f.write('seq 3\n')
+        f.write('f\n')
+        f.write('s.q 1\n')
+        f.write('q 8\n')
+        
+    _createPatternFile = staticmethod ( _createPatternFile )
+    
+        
+    def _createResult_of_dbLengthFilter_sup(inFileName): 
+        f = open(inFileName, 'w')
+        f.write(">seq 2\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq 3\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq 4\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createResult_of_dbLengthFilter_sup = staticmethod ( _createResult_of_dbLengthFilter_sup )
+    
+        
+    def _createFastaFile_four_sequences_for_header_filtering(fileName):
+        f = open(fileName, 'w')
+        f.write(">seq1_HostGene\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq2_SSR\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq3_Map2_NoCat\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.write(">seq4_confused\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCGCGCATCGATCGATCGGCGGCTATATGCTAGTCAGCTAGCTAGTGTGAGTAGTA\n")
+        f.write("ATATTCG\n")
+        f.close()
+        
+    _createFastaFile_four_sequences_for_header_filtering = staticmethod ( _createFastaFile_four_sequences_for_header_filtering )
+    
+   
+    def _createFastaFile_three_sequences_with_ORFs(fileName):
+        f = open(fileName, 'w')
+        f.write(">Mivi_sl_Blaster_Grouper_1_Map_3\n")
+        f.write("TACAGTCAAACCTGAGAAAATTTATATCGCCCAATCTTATACCTGGCAAAATTTATGGAC\n")
+        f.write("TTTTCAATCTCCCGACTTTTTTGGCTGACAGAACCTGTCCAATCTTATACCTTATAATTT\n")
+        f.write("ATGGGTTTACAGGTCAAATTATAAGATAAGAGAGAGCCGGAAATGAGCGATTGATCAGGA\n")
+        f.write("ATTGGCCTCTCCTTCGGCGTTCTTGTTGACGAGCCGCCTGCTGGAACAGTCCGAAATGCC\n")
+        f.write("CCGAAACAGCCGAGAAGCGAGCACAGTAGAGCAAAGGCGGCGGTTGACACGTTGACAGGC\n")
+        f.write("TATTAGTCGCGACGTGCTTCTCTCTCCTCTTCCGCCGACAACGACGCCGAAATGAACATC\n")
+        f.write("TTCACAATTCGAGAAGCCCTCATCAGAAATTCCTCTTCATATCATCATGGTCTCATTCCC\n")
+        f.write("TTCCCGGAATTCAACTGCTGGCGCCACGCTCAAATCTTGTCTGATCGCAAGAACAAAGGA\n")
+        f.write("TCGACCGACCATACACCTCTTCCCAACGGTCGCGGGCCTCTCGATGGCGATCGCGGCATC\n")
+        f.write("ATCAACGCGATGAACGCTCTGAAGACGGCGAACGATGAGCTGGTCGAAAAGGGGATAGTT\n")
+        f.write("ACGAGCAACGAGAAGATGAGTATCCACTTTCTCGTCGATGTGGAGGAGGAGAACCTTGCT\n")
+        f.write("GGTGGGGCTGAAATGACCGATCAGGAGATTGTGGACCTGGTCATTGCCGAAGAGTTGGAG\n")
+        f.write("GAGAATTGCGAGGGAGAAGGAGGAGAGGAGGAAGCGGAGATAGAGCTCCGACCGGCGGAG\n")
+        f.write("CGAACGACGCTGAAGGAGGCAATCTCAGCGCTTGATGTTTTCCTTAGGTTTGCTATGAAT\n")
+        f.write("GGGTACTCAGGTCCAACGGATTTGATTTCTTTTGAGGACGAGGCTAGGAGGATTCGCAGG\n")
+        f.write("ACTCTTGTTGCCGAGCAGGATGCCGCGAGGATTCAGACGACAATGACTTCGTATTTCCAG\n")
+        f.write("CGTCAGTAG\n")
+        f.write(">Mivi_sl_Blaster_Grouper_2_Map_3\n")
+        f.write("TACAGTCAGACCTGAGAAAATTTATATCGCCCAATCTTATACCTGTCAAAATTTATGGAC\n")
+        f.write("TTTTCAATCTCCCGACTTTTTTGGCTGACAGAACCTGTCCAATCTTATACCTTATAATTT\n")
+        f.write("ATGGGTTTACAGGTCAAATTATAAGATAAGAGAGAGCCGGAAATGAGCGATTGATCAGGA\n")
+        f.write("ATTGGCCTCTCCTTCGGCGTTCTTGTTGACGAGCCGCCTGCTGGAAGAGTCCGAAATGCC\n")
+        f.write("CCGAAACAGCCAAGAAGCGAGCACAGTAGAGCAAAGGCGGCGGTTGACACGTTGACAGGC\n")
+        f.write("TAGTCGCGACGTGCTTCTCTCTCCTCTTCCGCCGACAACGACGCCGAAATGAACATCTTC\n")
+        f.write("ACAATCCGAGAAGCCCTCATCAGAAATTCCTCTTCATATCATCATGGTCTCATTCCCTTC\n")
+        f.write("CCGGAATTCAACTGCTGGCGCCACGCTCAAATCTTGTCTGATCGCAAGAACAAAGGATCG\n")
+        f.write("ACCGACCATACACCTCTTCCCAACGGTCGCGGGCCTCTCGATGGCGATCGCGGCATCATC\n")
+        f.write("AACGCGATGAACGCTCTGAAGACGGCGAACGATGAGCTGGTCGAAAAGGGGATAGTTACG\n")
+        f.write("AGCAACGAGAAGATGAGTATCCACTTTCTCGTCGATGTGGAGGAGGAGAACCTTGCTGGT\n")
+        f.write("GGGGCTGAAATGACCGATCAGGAGATTGTGGACCTGGGGTCATTGCCGAAGAGTTGGAGG\n")
+        f.write("AGAATTGCGAGGGAGAACTTGAAGGAGGAGAGGAGGAAGCGGAGATAGAGCTCCGACCGG\n")
+        f.write("CGGAGCGAACGACGCTGAAGGAGGCAATCTCAGCGCTTGGTGTTTTCCTTAGGTTTGCTA\n")
+        f.write("TGAATGGGTACTCAGGTCCAACGAATTTGATTTCTTTTGAGGACGAGGCTAGGAGGATTC\n")
+        f.write("GCAGGACTCTTGTTGCCGAGCAGGATGCCGCGAGGATTCAGACGACAATGACTTCGTATT\n")
+        f.write("TCCAGCGTCAGTAGGTCAAGATATTTTTTCTTGGAGCTTTCATAACTTGTTAGATGTCAT\n")
+        f.write("CATGCCTCAGTAGAGGCCGTACATTGGCTGCAATTCAGTAATTCGGGCCTTCTGAATTTC\n")
+        f.write("CTCCCCCTCAAAAGTCAATGTATCGACTCAAACGATGCACGAAAATTCTTGATTTGATGT\n")
+        f.write("AGGAAGCTCAAAAACGGAGTTTCAGGTCATAATGTAGTGATCTGAAGCCGAACTCTCCAA\n")
+        f.write("GCTTATACCTGTCTTAATTTATGGGAAAATCCGTCCACCGAAAATATAAATTTTCTCAGG\n")
+        f.write("TCTGACTGTA\n")
+        f.write(">Mivi_sl_Blaster_Grouper_3_Map_3\n")
+        f.write("CAACACAAAGATAAGGCACCTTCATCCAGTGGCTCGCACGAACTTTCAATTGCAAGTCGT\n")
+        f.write("TGGCGTGCGCTGGGCGGGATCAAAACCGGGTCTGGGAGTCGCGTAACCCACTGGAGCAAG\n")
+        f.write("TAGGTGGTAGCCTGGACTGACAACGTGGACGTCAGCGACTTGAAATAGGTATTCGCGGCT\n")
+        f.write("TTCGTGGTCGGTGTACCCCTGTGTGTCCGGCATCGGCTGTCCAGAGTCGCCAGCCTGCCC\n")
+        f.write("GGTGCGAATGTGGGGGGCAGTCTCGGTCGCGCACGTGCGATGTCCCTCTCCCCACACGGG\n")
+        f.write("CCTGTCGGCTGCGGCTAACGGCCCCTGCAATGAGTCCTATCGACAGAAGTCCACCCAAGC\n")
+        f.write("TCAGCCTTCCCTCCACCAACACCAACATCGCAAGCCTCTCAAAAATTCACATCTCTTACA\n")
+        f.write("TCCCCTCGAAACACCCACTAAATGGATCCCTACCCTATCACTTGGCGGCAGTACTAGTAG\n")
+        f.write("CACGGGCCCAACTTCGACGGATCTCGAACGGACTTCCCACGGGTTCTCGGTGTGCAAGCG\n")
+        f.write("TCTCAGGTCAAGGTTTTGGTTGGTGGGCTTTCTGGGTGTGCAAAGGGGATTATTATAGAG\n")
+        f.write("GGAAGAAGAAGAAGGATGGGACCAGGGAGGCAGAGACGTGCGGGGTCAGGTTGATGGGGG\n")
+        f.write("AAGGTCGTGGAAGCGAAGAACGAGAGGCGAGCTTGTCGTTTGAGGAGAAAGGGGCCTCGC\n")
+        f.write("TGCCTGCAGAGAAAGGCGGTAAGTTGACCGGCGCAAAGTTATCATGAGACCGTAGCTCAG\n")
+        f.write("TATCGTTTCCTGTCGAGGGCATGGGTTACAGTCCGTCGAACTATGCGCGAGATCATCTGG\n")
+        f.write("TAGTAAAGAATCCCGCCGCCACTGACCAGATCTCCTGTGTCCTCTCAGCTCTCACAAAAC\n")
+        f.write("CTAGAAAAGCTTCGCATGGAGCCAAACGAATACTCCAATCCGACATTGAGCAAGACCCTT\n")
+        f.write("CCCTCTCGCCTCATAGGAACGAAACGGCCCATCTTCGAAGGGACAACTCTCTGTCGGCCG\n")
+        f.write("AGGAGATGACTTTTCTGACCGAGCGTAAGAGGAGATCGCACAGAGTCAGGGGTTGGTCGA\n")
+        f.write("GCTTTTGGGATTGGAGGAAGGGGGAGAGATTGATGAACGAGACGTCCCAATAGTGAGTCG\n")
+        f.write("CTCCGCACTGGAGCAATGATGGCAAACCGTGGAGTTGAAGAGTCTTGAACGCTATCAGAT\n")
+        f.write("CGGGCTAGGAGGGTCGGGAGGCGGTTGAATGCGTGCCAACCTTGGCTTCCTGTCAACGAT\n")
+        f.write("CCTCGCCTTTCAAGAGCTCGATCTATGGCAGTTGTTGACCTACACAGCGGGGGTATCCGG\n")
+        f.write("GTCCTGTTGGGCTCTGGCGAGTTTATATACGCTACCGATCGCACGTCCGCTCACACCATC\n")
+        f.write("CATCACTCAACGCCGCTGCGGTGATTGAGCACTTTATGTCCGTCTCAGGGGATCACCGTC\n")
+        f.write("TGAGTACAAAATCGGTCAACCGAGTCAGGGAGGCACACGGAGGGTACCAATCGCTTTTCG\n")
+        f.write("GACCTTTGATTTCAAAGTCTAAGAACAGTCAAAAGATCTGTAGTGAGTACAGACCACTGA\n")
+        f.write("CCCTCACTTGAGTAGATATTGACACTGACGAAGATCGCTACACTGCGGGCCTTGACAGTG\n")
+        f.write("ATTGATCTGTACTCGACACTGGTCTCATCGTACTTCTGGATGATGCCCAGAAAAGATGGG\n")
+        f.write("AAGGATCAGGTTGATCCGTATGTACCCCTGCGTCGGCTCGTGAGGTCCAGAGAGGGTCAT\n")
+        f.write("TCCACTGACTGTCCCGAACCCCCCCTGGCTGATCGTCAGCGCCTCGATGAAATGGTCGCG\n")
+        f.write("CGCGTACGATAATGCGGGCCTGGCTCACGGATGCGCGCCTTTCCCTATCGTCAGTCACGC\n")
+        f.write("AAATGTAGGCTTCCATCTGGAACGCTGCTTGATGGCCTAAGAATGGGCCGTCACGGAACA\n")
+        f.write("GCTCACCGCCTGCAGACACGAACGGCCGTGGCGGTCATGGAAGGATCTGAACGTGTCGCC\n")
+        f.write("CCATACGATTGACGAAGAGATGTAAGCTCCCTTGGTA\n")
+        f.close()
+    
+    _createFastaFile_three_sequences_with_ORFs = staticmethod ( _createFastaFile_three_sequences_with_ORFs )
+    
+    
+    def _createFastaFile_three_sequences_with_ORFs_expected(fileName):  
+        f = open(fileName, 'w') 
+        f.write("ORF|1|662\tMivi_sl_Blaster_Grouper_1_Map_3\t307\t969\n")
+        f.write("ORF|-3|254\tMivi_sl_Blaster_Grouper_1_Map_3\t793\t539\n")
+        f.write("ORF|2|197\tMivi_sl_Blaster_Grouper_1_Map_3\t356\t553\n")
+        f.write("ORF|3|176\tMivi_sl_Blaster_Grouper_1_Map_3\t288\t464\n")
+        f.write("ORF|-1|176\tMivi_sl_Blaster_Grouper_1_Map_3\t786\t610\n")
+        f.write("ORF|3|143\tMivi_sl_Blaster_Grouper_1_Map_3\t672\t815\n")
+        f.write("ORF|1|131\tMivi_sl_Blaster_Grouper_1_Map_3\t175\t306\n")
+        f.write("ORF|-2|131\tMivi_sl_Blaster_Grouper_1_Map_3\t797\t666\n")
+        f.write("ORF|2|128\tMivi_sl_Blaster_Grouper_1_Map_3\t167\t295\n")
+        f.write("ORF|-2|119\tMivi_sl_Blaster_Grouper_1_Map_3\t242\t123\n")
+        f.write("ORF|1|464\tMivi_sl_Blaster_Grouper_2_Map_3\t304\t768\n")
+        f.write("ORF|3|305\tMivi_sl_Blaster_Grouper_2_Map_3\t669\t974\n")
+        f.write("ORF|-3|251\tMivi_sl_Blaster_Grouper_2_Map_3\t1094\t843\n")
+        f.write("ORF|-2|245\tMivi_sl_Blaster_Grouper_2_Map_3\t531\t286\n")
+        f.write("ORF|-3|224\tMivi_sl_Blaster_Grouper_2_Map_3\t791\t567\n")
+        f.write("ORF|-2|215\tMivi_sl_Blaster_Grouper_2_Map_3\t1098\t883\n")
+        f.write("ORF|2|197\tMivi_sl_Blaster_Grouper_2_Map_3\t353\t550\n")
+        f.write("ORF|3|173\tMivi_sl_Blaster_Grouper_2_Map_3\t288\t461\n")
+        f.write("ORF|-1|173\tMivi_sl_Blaster_Grouper_2_Map_3\t1087\t914\n")
+        f.write("ORF|-1|143\tMivi_sl_Blaster_Grouper_2_Map_3\t310\t167\n")
+        f.write("ORF|3|626\tMivi_sl_Blaster_Grouper_3_Map_3\t141\t767\n")
+        f.write("ORF|2|434\tMivi_sl_Blaster_Grouper_3_Map_3\t164\t598\n")
+        f.write("ORF|3|365\tMivi_sl_Blaster_Grouper_3_Map_3\t768\t1133\n")
+        f.write("ORF|-3|359\tMivi_sl_Blaster_Grouper_3_Map_3\t1514\t1155\n")
+        f.write("ORF|-1|320\tMivi_sl_Blaster_Grouper_3_Map_3\t1879\t1559\n")
+        f.write("ORF|3|272\tMivi_sl_Blaster_Grouper_3_Map_3\t1299\t1571\n")
+        f.write("ORF|-2|248\tMivi_sl_Blaster_Grouper_3_Map_3\t1503\t1255\n")
+        f.write("ORF|1|236\tMivi_sl_Blaster_Grouper_3_Map_3\t1576\t1812\n")
+        f.write("ORF|-1|227\tMivi_sl_Blaster_Grouper_3_Map_3\t1423\t1196\n")
+        f.write("ORF|-3|227\tMivi_sl_Blaster_Grouper_3_Map_3\t368\t141\n")
+        f.close()
+
+    _createFastaFile_three_sequences_with_ORFs_expected = staticmethod ( _createFastaFile_three_sequences_with_ORFs_expected )
+    
+    
+    def _createLinkFile_four_sequences_with_new_headers(fileName):
+        f = open(fileName, 'w')
+        f.write("seq 1\tReconCluster1Mb155 chunk183 {Fragment} 1..5506\t1\t127\n")
+        f.write("seq 2\tMbQ3Gr2Cl0 chunk440 {Fragment} 2678..3645\t1\t307\n")
+        f.write("seq 3\tMbS2Gr2Cl0 chunk622 {Fragment} 104..1078\t1\t427\n")
+        f.write("seq 4\tPilerCluster3.574Mb796 chunk0117 {Fragment} 51582..50819\t1\t307\n")
+        
+    _createLinkFile_four_sequences_with_new_headers = staticmethod ( _createLinkFile_four_sequences_with_new_headers )
+    
+    
+    def _createLinkFile_four_sequences_same_headers(fileName):
+        f = open(fileName, 'w')
+        f.write("seq 1\tseq 1\t1\t127\n")
+        f.write("seq 2\tseq 2\t1\t307\n")
+        f.write("seq 3\tseq 3\t1\t427\n")
+        f.write("seq 4\tseq 4\t1\t307\n")
+        
+    _createLinkFile_four_sequences_same_headers = staticmethod ( _createLinkFile_four_sequences_same_headers )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/DbFactory.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,38 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+ 
+from commons.core.sql.DbMySql import DbMySql
+
+class DbFactory (object):
+    
+    def createInstance(configFileName = "", verbosity = 1):
+        return DbMySql(cfgFileName = configFileName, verbosity = verbosity)
+    
+    createInstance = staticmethod(createInstance)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/DbMySql.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,851 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+#        Exception hierarchy:
+#
+#        StandardError
+#        |__Warning
+#        |__Error
+#           |__InterfaceError
+#           |__DatabaseError
+#              |__DataError
+#              |__OperationalError
+#              |__IntegrityError
+#              |__InternalError
+#              |__ProgrammingError
+#              |__NotSupportedError
+
+import os
+import sys
+import time
+import ConfigParser
+import MySQLdb
+from MySQLdb import InterfaceError
+from MySQLdb import OperationalError
+from MySQLdb import InternalError
+from MySQLdb import DatabaseError
+from commons.core.seq.Bioseq import Bioseq
+from commons.core.LoggerFactory import LoggerFactory
+from commons.core.checker.RepetException import RepetException
+from commons.core.sql.TablePathAdaptator import TablePathAdaptator
+from commons.core.sql.TableSetAdaptator import TableSetAdaptator
+
+LOG_DEPTH = "repet.commons"
+
+TABLE_SCHEMA_DESCRIPTOR = {"map":       [("name", "varchar(255)"), ("chr", "varchar(255)"), ("start", "int"), ("end", "int")],
+                           "set":       [("path", "int unsigned"), ("name", "varchar(255)"), ("chr", "varchar(255)"), ("start", "int"), ("end", "int")],
+                           "match":     [("query_name", "varchar(255)"), ("query_start", "int"), ("query_end", "int"), ("query_length", "int unsigned"), ("query_length_perc", "float"),
+                                         ("match_length_perc", "float"), ("subject_name", "varchar(255)"), ("subject_start", "int unsigned"), ("subject_end", "int unsigned"),
+                                         ("subject_length", "int unsigned"), ("subject_length_perc", "float"), ("E_value", "double"), ("score", "int unsigned"), ("identity", "float"),
+                                         ("path", "int unsigned")],
+                           "path":      [("path", "int unsigned"), ("query_name", "varchar(255)"), ("query_start", "int"), ("query_end", "int"), ("subject_name", "varchar(255)"),
+                                         ("subject_start", "int unsigned"), ("subject_end", "int unsigned"), ("E_value", "double"), ("score", "int unsigned"), ("identity", "float")],
+                           "align":     [("query_name", "varchar(255)"), ("query_start", "int"), ("query_end", "int"), ("subject_name", "varchar(255)"), ("subject_start", "int unsigned"),
+                                         ("subject_end", "int unsigned"), ("E_value", "double"), ("score", "int unsigned"), ("identity", "float")],
+                           "seq":       [("accession", "varchar(255)"), ("sequence", "longtext"), ("description", "varchar(255)"), ("length", "int unsigned")],
+                           "length":    [("accession", "varchar(255)"), ("length", "int unsigned")],
+                           "jobs":      [("jobid", "int unsigned"), ("jobname", "varchar(255)"), ("groupid", "varchar(255)"), ("launcher", "varchar(1024)"),
+                                         ("queue", "varchar(255)"), ("resources", "varchar(255)"), ("status", "varchar(255)"), ("time", "datetime"), ("node", "varchar(255)")],
+                           "classif":   [("seq_name", "varchar(255)"), ("length", "int unsigned"), ("strand", "char"), ("status", "varchar(255)"), ("class_classif", "varchar(255)"),
+                                         ("order_classif", "varchar(255)"), ("completeness", "varchar(255)"), ("evidence", "text")],
+                           "pathstat":  [("family", "varchar(255)"), ("maxLength", "int"), ("meanLength", "int"), ("covg", "int"), ("frags", "int"), ("fullLgthFrags", "int"), ("copies", "int"),
+                                         ("fullLgthCopies", "int"), ("meanId", "varchar(255)"), ("sdId", "varchar(255)"), ("minId", "varchar(255)"), ("q25Id", "varchar(255)"), ("medId", "varchar(255)"),
+                                         ("q75Id", "varchar(255)"), ("maxId", "varchar(255)"), ("meanLgth", "varchar(255)"), ("sdLgth", "varchar(255)"), ("minLgth", "varchar(255)"), ("q25Lgth", "varchar(255)"),
+                                         ("medLgth", "varchar(255)"), ("q75Lgth", "varchar(255)"), ("maxLgth", "varchar(255)"), ("meanLgthPerc", "varchar(255)"), ("sdLgthPerc", "varchar(255)"), 
+                                         ("minLgthPerc", "varchar(255)"), ("q25LgthPerc", "varchar(255)"), ("medLgthPerc", "varchar(255)"), ("q75LgthPerc", "varchar(255)"), ("maxLgthPerc", "varchar(255)")],
+                           "info_tables":[("name", "varchar(255)"), ("file", "varchar(255)")]
+                         }
+
+TABLE_INDEX_DESCRIPTOR = {"map":       [("iname", "name"), ("ichr", "chr"), ("istart", "start"), ("iend", "end"), ("icoord", "start, end")],
+                        "set":         [("id", "path"), ("iname", "name"), ("ichr", "chr"), ("istart", "start"), ("iend", "end"), ("icoord", "start, end")],
+                        "match":       [("id", "path"), ("qname", "query_name"), ("qstart", "query_start"), ("qend", "query_end"),
+                                       ("sname", "subject_name"), ("sstart", "subject_start"), ("send", "subject_end"), ("qcoord", "query_start, query_end")],
+                        "path":        [("id", "path"), ("qname", "query_name"), ("qstart", "query_start"), ("qend", "query_end"),
+                                       ("sname", "subject_name"), ("sstart", "subject_start"), ("send", "subject_end"), ("qcoord", "query_start, query_end")],
+                        "align":       [("qname", "query_name"), ("qstart", "query_start"), ("qend", "query_end"),
+                                       ("sname", "subject_name"), ("sstart", "subject_start"), ("send", "subject_end"), ("qcoord", "query_start, query_end")],  
+                        "seq":         [("iacc", "accession"), ("idescr", "description")],  
+                        "length":      [("iacc", "accession"), ("ilength", "length")],
+                        "jobs":        [("ijobid", "jobid"), ("ijobname", "jobname"), ("igroupid", "groupid"), ("istatus", "status")],
+                        "classif":     [("iseq_name", "seq_name"), ("istatus", "status"), ("iclass", "class_classif"), ("iorder", "order_classif"), ("icomp", "completeness")],
+                        "pathstat":    [],
+                        "info_tables": []
+                        }
+
+TABLE_TYPE_SYNONYMS = {"tab": "match",
+                       "fasta": "seq",
+                       "fa": "seq",
+                       "fsa": "seq"
+                       }
+ 
+## Handle connections to MySQL tables formatted for REPET
+#
+class DbMySql(object):
+    
+    ## Constructor
+    #
+    # @param user string db user name
+    # @param host string db host name
+    # @param passwd string db user password
+    # @param dbname string database name
+    # @param port integer database port
+    # @param cfgFileName string configuration file name
+    #
+    # @note when a parameter is left blank, the constructor is able
+    #   to set attribute values from environment variables: REPET_HOST,
+    #   REPET_USER, REPET_PW, REPET_DB, REPET_PORT
+    #
+    def __init__(self, user = "", host = "", passwd = "", dbname = "", port = "", cfgFileName = "", verbosity = 1):
+        self._log = LoggerFactory.createLogger("%s.%s" % (LOG_DEPTH, self.__class__.__name__), verbosity)
+        if cfgFileName != "":
+            self.setAttributesFromConfigFile(cfgFileName)
+            
+        elif host != "" and user != "" and passwd != "" and dbname != "":
+            self.host = host
+            self.user = user
+            self.passwd = passwd
+            self.dbname = dbname
+            
+        else:
+            for envVar in ["REPET_HOST","REPET_USER","REPET_PW","REPET_DB"]:
+                if os.environ.get( envVar ) == None:
+                    msg = "ERROR: can't find environment variable '%s'" % envVar
+                    self._log.error(msg)
+                    raise RepetException(msg)
+            self.host = os.environ.get("REPET_HOST")
+            self.user = os.environ.get("REPET_USER")
+            self.passwd = os.environ.get("REPET_PW")
+            self.dbname = os.environ.get("REPET_DB")
+        
+        if port != "" and cfgFileName == "":
+            self.port = int(port)
+        elif os.environ.get("REPET_PORT") != None:
+            self.port = int(os.environ.get("REPET_PORT"))
+        else:
+            self.port = 3306
+                    
+        maxNbTry = 10
+        for i in xrange(1,maxNbTry+1):
+            if not self.open():
+                time.sleep(2)
+                if i == maxNbTry:
+                    msg = "ERROR: failed to connect to the MySQL database"
+                    self._log.error(msg)
+                    raise DatabaseError(msg)
+            else:
+                break
+            
+        self.cursor = self.db.cursor()
+        self.execute("""use %s""" %(self.dbname))
+        
+        
+    ## Set the attributes from the configuration file
+    #
+    # @param configFileName string configuration file name
+    #
+    def setAttributesFromConfigFile(self, configFileName):
+        config = ConfigParser.ConfigParser()
+        config.readfp( open(configFileName) )
+        self.host = config.get("repet_env","repet_host")
+        self.user = config.get("repet_env","repet_user")
+        self.passwd = config.get("repet_env","repet_pw")
+        self.dbname = config.get("repet_env","repet_db")
+        self.port = int( config.get("repet_env","repet_port") )
+        
+        
+    ## Connect to the MySQL database
+    #
+    def open(self):
+        try:
+            if int(MySQLdb.get_client_info().split(".")[0]) >= 5:
+                self.db = MySQLdb.connect( user = self.user, host = self.host,\
+                                           passwd = self.passwd, db = self.dbname, \
+                                           port = self.port, \
+                                           local_infile = 1 )
+            else:
+                self.db = MySQLdb.connect( user = self.user, host = self.host,\
+                                           passwd = self.passwd, db = self.dbname, \
+                                           port = self.port )
+        except MySQLdb.Error, e:
+            msg = "ERROR %d: %s" % (e.args[0], e.args[1])
+            self._log.error(msg)
+            return False
+
+        return True
+    
+    
+    ## Execute a SQL query
+    #
+    # @param qry string SQL query to execute
+    # @param params parameters of SQL query 
+    #
+    def execute(self, qry, params = None, nbTry = 3, sleep = 5):
+        if nbTry:
+            self._log.debug("################START SQL DEBUG MODE################")
+            self._log.debug("Current directory: %s" % os.getcwd())
+            self._log.debug("Host: %s" % self.host)
+            self._log.debug("User: %s" % self.user)
+            self._log.debug("Database: %s" % self.dbname)
+            self._log.debug("SQL command: %s" % qry)
+            self._log.debug("################STOP SQL DEBUG MODE################\n")
+    
+            try:
+                if params == None:
+                    self.cursor.execute(qry)
+                else:
+                    self.cursor.execute(qry, params)
+            except (InterfaceError, OperationalError, InternalError) as iError:
+                self._log.error("FAILED to execute query '%s': %s. %s retries left." % (qry, iError.args[1], nbTry - 1))
+                self._log.debug("WAIT %is to execute '%s'" % (sleep, qry))
+                time.sleep(sleep)
+                try:
+                    self.close()
+                except:
+                    pass
+                self.open()
+                self.cursor = self.db.cursor()
+                self.execute(qry, params, nbTry - 1, sleep)
+        else:
+            msg = "ERROR: can't execute '%s' after several tries" % qry
+            self._log.error(msg)
+            raise DatabaseError(msg)
+        
+    ## Close the connection
+    #
+    def close( self ):
+        self.db.close()
+        
+        
+    ## Retrieve the results of a SQL query
+    #
+    def fetchall(self):
+        return self.cursor.fetchall()
+    
+    
+    ## Test if a table exists
+    #
+    # @param table string table name
+    # @return boolean True if the table exists, False otherwise
+    #
+    def doesTableExist( self, table ):
+        self.execute( """SHOW TABLES""" )
+        results = self.cursor.fetchall()
+        if (table,) in results:
+            return True
+        return False
+    
+    
+    ## Remove a table if it exists
+    #
+    # @param table string table name
+    #
+    def dropTable(self, table):
+        if self.doesTableExist( table ):
+            sqlCmd = "DROP TABLE %s" % table
+            self.execute( sqlCmd )
+            sqlCmd = 'DELETE FROM info_tables WHERE name = "%s"' % table
+            self.execute( sqlCmd )
+            
+            
+    ## Rename a table
+    #
+    # @param table string existing table name
+    # @param newName string new table name
+    #
+    def renameTable( self, table, newName ):
+        self.dropTable( newName )
+        self.execute( 'RENAME TABLE %s TO %s ;' % (table, newName) )
+        self.execute( 'UPDATE info_tables SET name="%s" WHERE name="%s";' % (newName, table) )
+        
+        
+    ## Duplicate a table
+    #
+    # @param tableName string source table name
+    # @param newTableName string new table name
+    #
+    def copyTable(self, sourcetableName, newTableName):
+        self.dropTable( newTableName )
+        sqlCmd = "CREATE TABLE %s LIKE %s;" % (newTableName, sourcetableName) 
+        self.execute( sqlCmd )
+        sqlCmd = "INSERT INTO %s SELECT * FROM %s;" % (newTableName, sourcetableName) 
+        self.execute( sqlCmd )
+        self._log.info("copying table data,", sourcetableName, "in", newTableName)
+        self.updateInfoTable(newTableName, "")
+        
+        
+    ## Give the rows number of the table
+    #
+    # @param tableName string table name
+    #
+    def getSize( self, tableName ):
+        qry = "SELECT count(*) FROM %s;" % (tableName)
+        self.execute(qry)
+        res = self.fetchall()
+        return int( res[0][0] )
+    
+    
+    def getTableType(self, tableName):
+        qry = "SHOW COLUMNS FROM %s;" % (tableName)
+        self.execute(qry)
+        res = self.fetchall()
+        
+        fieldNames = []
+        for row in res:
+            fieldNames.append(row[0])
+            
+        for tableType, fieldInfos in TABLE_SCHEMA_DESCRIPTOR.items():
+            refFieldsNames = [name for name,type in fieldInfos]
+            if refFieldsNames == fieldNames:
+                return tableType
+        
+        return None
+        
+    
+    ## Test if table is empty
+    #
+    # @param tableName string table name
+    # @return boolean True if the table is empty, False otherwise
+    #
+    def isEmpty(self, tableName):
+        return self.getSize(tableName) == 0
+    
+    
+    ## Record a new table in the 'info_table' table
+    #
+    # @param tableName string table name
+    # @param info string information on the table origin
+    #
+    def updateInfoTable( self, tableName, info ):
+        if not self.doesTableExist( "info_tables" ):
+            sqlCmd = "CREATE TABLE info_tables ( name varchar(255), file varchar(255) )"
+            self.execute( sqlCmd )
+        sqlCmd = 'INSERT INTO info_tables VALUES ("%s","%s")' % (tableName, info)
+        self.execute( sqlCmd )
+        
+        
+    ## Get a list with the fields
+    #
+    def getFieldList( self, table ):
+        lFields = []
+        sqlCmd = "DESCRIBE %s" % ( table )
+        self.execute( sqlCmd )
+        lResults = self.fetchall()
+        for res in lResults:
+            lFields.append( res[0] )
+        return lFields
+    
+    
+    ## Check that the input file has as many fields than it is supposed to according to its format
+    #
+    # @note fields should be separated by tab
+    #
+    def checkDataFormatting( self, dataType, fileName ):
+        dataType = dataType.lower()
+        if dataType in ["fa", "fasta", "seq", "classif", "length", "jobs", "pathstat"]:
+            return
+        dDataType2NbFields = { "map": 4, "set": 5, "align": 9, "path": 10, "match": 15, "tab": 15 }
+        fileHandler = open( fileName, "r" )
+        line = fileHandler.readline()
+        if line != "":
+            tokens = line.split("\t")
+            if len(tokens) < dDataType2NbFields[ dataType ]:
+                msg = "ERROR: '%s' file has less than %i fields" % ( dataType, dDataType2NbFields[ dataType ] )
+                self._log.error(msg)
+                raise RepetException(msg)
+            if len(tokens) > dDataType2NbFields[ dataType ]:
+                msg = "ERROR: '%s' file has more than %i fields" % ( dataType, dDataType2NbFields[ dataType ] )
+                self._log.error(msg)
+                raise RepetException(msg)
+        fileHandler.close()
+        
+
+    def createIndex(self, tableName="", tableType=""):
+        sqlCmd = "SHOW INDEX FROM %s;"% (tableName)
+        self.execute(sqlCmd)
+        res = self.fetchall()
+        lIndex = []
+        for i in res:
+            lIndex.append(i[2])
+        self._log.warning("existing indexes:", lIndex)
+        
+        for indexName, fieldNames in TABLE_INDEX_DESCRIPTOR.get(tableType):
+            if not indexName in lIndex:
+                sqlCmd = "CREATE INDEX %s ON %s ( %s );" % (indexName, tableName, fieldNames)
+                self.execute(sqlCmd)
+                
+    
+    ## Create a MySQL table of specified data type and load data
+    #
+    # @param tableName string name of the table to be created
+    # @param fileName string name of the file containing the data to be loaded in the table
+    # @param dataType string type of the data (map, set, align, path, match, seq, length, jobs)
+    # @param overwrite boolean (default = False)
+    #
+    def createTable(self, tableName, dataType, fileName = "", overwrite = False):
+        self._log.info("creating table '%s' from file '%s' of type '%s'..." % (tableName, fileName, dataType))
+            
+        if fileName != "":
+            self.checkDataFormatting(dataType, fileName)
+            
+        if overwrite:
+            self.dropTable(tableName)
+                    
+        tableType = dataType.lower()
+        if TABLE_SCHEMA_DESCRIPTOR.get(tableType,None) is None and TABLE_TYPE_SYNONYMS.get(tableType,None) is None:
+            msg = "ERROR: unknown type %s" % dataType
+            self._log.error(msg)
+            raise RepetException(msg)
+            
+        tableType = TABLE_TYPE_SYNONYMS.get(tableType,tableType)
+        
+        fields = [" ".join(fieldDescription) for fieldDescription in TABLE_SCHEMA_DESCRIPTOR.get(tableType)]
+        sqlCmd = "CREATE TABLE %s (%s)" % (tableName, ",".join(fields))
+        self.execute(sqlCmd)
+        self.createIndex(tableName, tableType)
+        
+        tmpFileName = ""
+        if fileName:
+            if tableType == "seq":
+                tmpFileName = "%s.seq" % os.path.basename(fileName)
+                self._convertFastaToSeq(fileName, tmpFileName)
+                fileName = tmpFileName
+            elif tableType == "length":
+                tmpFileName = "%s.length" % os.path.basename(fileName)
+                self._convertFastaToLength(fileName, tmpFileName)
+                fileName = tmpFileName
+        
+        hasHeaderLine = tableType == "match" or tableType == "pathstat"
+        self.loadDataFromFile(tableName, fileName, hasHeaderLine)
+        if tmpFileName:
+            os.remove(tmpFileName)
+        
+        if tableType == "path":
+            self.changePathQueryCoordinatesToDirectStrand( tableName )
+        
+        self.updateInfoTable(tableName, fileName)
+        self._log.info("creating table '%s' done!" % tableName)
+    
+
+    ## Create a bin table for fast access
+    #
+    # @param pathTableName string path table name (input table)
+    # @param idxTableName string bin path table name (output table)
+    # @param overwrite boolean default = False
+    #    
+    def createBinPathTable(self, pathTableName, overwrite = False):
+        idxTableName = "%s_idx" % pathTableName # is an attribute in TableBinPathAdaptator
+        if not self.doesTableExist(pathTableName):
+            msg = "ERROR: '%s' doesn't exist => '%s' can't be created" % (pathTableName, idxTableName)
+            self._log.error(msg)
+            raise RepetException(msg)
+        self._log.info("creating %s for fast access" % idxTableName)
+        if overwrite:
+            self.dropTable(idxTableName)
+            
+        sqlCmd = "CREATE TABLE %s ( path int unsigned, idx int unsigned, contig varchar(255), min int, max int, strand int unsigned)" % idxTableName
+        self.execute(sqlCmd)
+
+        sqlCmd = "CREATE INDEX id ON %s ( path );" % idxTableName
+        self.execute(sqlCmd)
+        sqlCmd = "CREATE INDEX ibin ON %s ( idx );" % idxTableName
+        self.execute(sqlCmd)
+        sqlCmd = "CREATE INDEX icontig ON %s ( contig );" % idxTableName
+        self.execute(sqlCmd)
+        sqlCmd = "CREATE INDEX imin ON %s ( min );" % idxTableName
+        self.execute(sqlCmd)
+        sqlCmd = "CREATE INDEX imax ON %s ( max );" % idxTableName
+        self.execute(sqlCmd)
+        sqlCmd = "CREATE INDEX istrand ON %s ( strand );" % idxTableName
+        self.execute(sqlCmd)
+
+        tmpTableName = "%s_tmp" % pathTableName
+        self._createPathTableAndGroupByIdAndOrderByStrand(pathTableName, tmpTableName)
+        iTPA = TablePathAdaptator(self, tmpTableName)
+        if not self.isEmpty(tmpTableName):
+            tmpFileName = "%s.tmp%s" % (pathTableName, str(os.getpid()))
+            with open(tmpFileName, "w") as f:
+                lQueryNames = iTPA.getQueryList()
+                for queryName in lQueryNames:
+                    lPaths = iTPA.getPathListFromQuery(queryName)
+                    for i in lPaths:
+                        idx = i.range_query.findIdx()
+                        max = i.range_query.getMax()
+                        min = i.range_query.getMin()
+                        strand = i.range_query.isOnDirectStrand()
+                        f.write("%d\t%d\t%s\t%d\t%d\t%d\n"%(i.id, idx, i.range_query.seqname, min, max, strand))
+            sqlCmd="LOAD DATA LOCAL INFILE '%s' INTO TABLE %s FIELDS ESCAPED BY '' " % (tmpFileName, idxTableName)
+            self.execute(sqlCmd)
+            self.updateInfoTable(idxTableName, "%s bin indexes" % pathTableName)
+            os.remove(tmpFileName)
+        self.dropTable(tmpTableName)
+        
+    
+    ## This table summarize the Path list information according to the identifier numbers. The min and max value is taken
+    #
+    def _createPathTableAndGroupByIdAndOrderByStrand(self, pathTableName, outTableName):
+        self.dropTable(outTableName)
+
+        sqlcmd="CREATE TABLE %s SELECT path, query_name, min(query_start) AS query_start, max(query_end) AS query_end, subject_name, min(subject_start) AS subject_start, max(subject_end) AS subject_end, min(e_value) AS e_value, sum(score) AS score, avg(identity) AS identity FROM %s WHERE query_start<query_end and subject_start<subject_end group by path;" % (outTableName, pathTableName)
+        self.execute(sqlcmd)
+
+        sqlcmd="INSERT INTO %s SELECT path, query_name, min(query_start) AS query_start, max(query_end) AS query_end, subject_name, max(subject_start) AS subject_start, min(subject_end) AS subject_end, min(e_value) AS e_value, sum(score) AS score, avg(identity) AS identity FROM %s WHERE query_start<query_end and subject_start>subject_end group by path;" % (outTableName, pathTableName)
+        self.execute(sqlcmd)
+
+        sqlcmd="INSERT INTO %s SELECT path, query_name, max(query_start) AS query_start, min(query_end) AS query_end, subject_name, min(subject_start) AS subject_start, max(subject_end) AS subject_end, min(e_value) AS e_value, sum(score) AS score, avg(identity) AS identity FROM %s WHERE query_start>query_end and subject_start<subject_end group by path;" % (outTableName, pathTableName)
+        self.execute(sqlcmd)
+
+        sqlcmd="INSERT INTO %s SELECT path, query_name, max(query_start) AS query_start, min(query_end) AS query_end, subject_name, max(subject_start) AS subject_start, min(subject_end) AS subject_end, min(e_value) AS e_value, sum(score) AS score, avg(identity) AS identity FROM %s WHERE query_start>query_end and subject_start>subject_end group by path;" % (outTableName, pathTableName)
+        self.execute(sqlcmd)
+
+        self.createIndex(outTableName, "path")
+
+
+    ## Create a bin table for fast access
+    #
+    # @param setTableName string set table name (input table)
+    # @param idxTableName string bin set table name (output table)
+    # @param overwrite boolean default = False
+    #
+    def createBinSetTable(self, setTableName, overwrite = False):
+        idxTableName = "%s_idx" % setTableName # is an attribute in TableBinSetAdaptator
+        if not self.doesTableExist(setTableName):
+            msg = "ERROR: '%s' doesn't exist => '%s' can't be created" % (setTableName, idxTableName)
+            self._log.error(msg)
+            raise RepetException(msg)
+        self._log.info("creating %s for fast access" % idxTableName)
+        if overwrite:
+            self.dropTable(idxTableName)
+        
+        sqlCmd = "CREATE TABLE %s ( path int unsigned, bin float, contig varchar(255), min int, max int, strand int unsigned)" % idxTableName
+        self.execute(sqlCmd)
+        
+        sqlCmd = "CREATE INDEX id ON %s ( path );" % idxTableName
+        self.execute(sqlCmd)
+        sqlCmd = "CREATE INDEX ibin ON %s ( bin );" % idxTableName
+        self.execute(sqlCmd)
+        sqlCmd = "CREATE INDEX icontig ON %s ( contig );" % idxTableName
+        self.execute(sqlCmd)
+        sqlCmd = "CREATE INDEX imin ON %s ( min );" % idxTableName
+        self.execute(sqlCmd)
+        sqlCmd = "CREATE INDEX imax ON %s ( max );" % idxTableName
+        self.execute(sqlCmd)
+        sqlCmd = "CREATE INDEX istrand ON %s ( strand );" % idxTableName
+        self.execute(sqlCmd)
+
+        tmpTableName = "%s_tmp" % setTableName
+        self._createSetTableAndGroupByIdAndOrderByStrand(setTableName, tmpTableName)
+        iTSA = TableSetAdaptator(self, tmpTableName)
+        if not self.isEmpty(tmpTableName):
+            tmpFileName = "%s.tmp%s" % (setTableName, str(os.getpid()))
+            with open(tmpFileName, "w") as f:
+                lSeqNames = iTSA.getSeqNameList()
+                for seqName in lSeqNames:
+                    lSets = iTSA.getSetListFromSeqName(seqName)
+                    for i in lSets:
+                        bin = i.getBin()
+                        max = i.getMax()
+                        min = i.getMin()
+                        strand = i.isOnDirectStrand()
+                        f.write("%d\t%f\t%s\t%d\t%d\t%d\n"%(i.id, bin, i.seqname, min, max, strand))
+            sqlCmd="LOAD DATA LOCAL INFILE '%s' INTO TABLE %s FIELDS ESCAPED BY '' " % (tmpFileName, idxTableName)
+            self.execute(sqlCmd)
+            self.updateInfoTable(idxTableName, "%s bin indexes" % setTableName)
+            os.remove(tmpFileName)
+        self.dropTable(tmpTableName)
+        
+        
+    ## This table summarize the Set list information according to the identifier numbers. The min and max value is taken
+    #
+    def _createSetTableAndGroupByIdAndOrderByStrand(self, setTableName, outTableName):
+        self.dropTable(outTableName)
+
+        sqlcmd="CREATE TABLE %s SELECT path, name, chr, min(start) AS start, max(end) AS end FROM %s WHERE start<end group by path;" % (outTableName, setTableName)
+        self.execute(sqlcmd)
+
+        sqlcmd="INSERT INTO %s SELECT path, name, chr, max(start) AS start, min(end) AS end FROM %s WHERE start>end group by path;" % (outTableName, setTableName)
+        self.execute(sqlcmd)
+
+        self.createIndex(outTableName, "set")
+
+                   
+    ## Load data from a file into a MySQL table
+    #
+    # @param tableName string table name
+    # @param fileName string file name
+    # @param escapeFirstLine boolean True to ignore the first line of file, False otherwise 
+    #
+    def loadDataFromFile(self, tableName, fileName, escapeFirstLine = False):
+        if fileName != "":
+            sqlCmd = "LOAD DATA LOCAL INFILE '%s' INTO TABLE %s FIELDS ESCAPED BY '' " % ( fileName, tableName )
+            if escapeFirstLine == True:
+                sqlCmd = "%s IGNORE 1 LINES" %(sqlCmd)
+            self.execute( sqlCmd )
+
+        self._log.info("%i entries in the table %s" % (self.getSize(tableName), tableName))
+        
+######################################################################################
+#TODO: remove duplication with same methods in fastautils
+    ## Convert a fasta file to a length file
+    #
+    # @param inFile string name of the input fasta file
+    # @param outFile string name of the output file
+    #
+    def _convertFastaToLength(self, inFile, outFile = ""):
+        if outFile == "":
+            outFile = "%s.length" % inFile
+        
+        if inFile != "":
+            with open(inFile, "r") as inFH:
+                with open(outFile, "w") as outFH:
+                    bioseq = Bioseq()
+                    while True:
+                        bioseq.read(inFH)
+                        if bioseq.sequence == None:
+                            break
+                        seqLen = bioseq.getLength()
+                        outFH.write("%s\t%d\n" % (bioseq.header.split()[0], seqLen))
+    
+    
+    ## Convert a fasta file to a seq file
+    #
+    # @param inFile string name of the input fasta file
+    # @param outFile string name of the output file
+    #
+    def _convertFastaToSeq(self, inFile, outFile = ""):
+        if outFile == "":
+            outFile = "%s.seq" % inFile
+        
+        if inFile != "":
+            with open(inFile, "r") as inFH:
+                with open(outFile, "w") as outFH:
+                    bioseq = Bioseq()
+                    while True:
+                        bioseq.read(inFH)
+                        if bioseq.sequence == None:
+                            break
+                        seqLen = bioseq.getLength()
+                        outFH.write("%s\t%s\t%s\t%d\n" % (bioseq.header.split()[0], \
+                                                bioseq.sequence, bioseq.header, seqLen))
+
+######################################################################################
+            
+    ## Change the coordinates such that the query is on the direct strand.
+    #
+    # @param inTable string path table name to update
+    #    
+    def changePathQueryCoordinatesToDirectStrand( self, inTable ):
+        sqlCmd = "ALTER TABLE %s ADD COLUMN tmpid INT NOT NULL AUTO_INCREMENT PRIMARY KEY" % ( inTable )
+        self.execute( sqlCmd )
+        
+        tmpTable = "%s_tmp" % ( inTable )
+        sqlCmd = "CREATE TABLE %s SELECT * FROM %s WHERE query_start > query_end" % ( tmpTable, inTable )
+        self.execute( sqlCmd )
+        
+        sqlCmd = "UPDATE %s, %s" % ( inTable, tmpTable )
+        sqlCmd += " SET %s.query_start=%s.query_end," % ( inTable, tmpTable )
+        sqlCmd += " %s.query_end=%s.query_start," % ( inTable, tmpTable )
+        sqlCmd += " %s.subject_start=%s.subject_end," % ( inTable, tmpTable )
+        sqlCmd += " %s.subject_end=%s.subject_start" % ( inTable, tmpTable )
+        sqlCmd += " WHERE %s.tmpid=%s.tmpid" % ( inTable, tmpTable )
+        self.execute( sqlCmd )
+        
+        sqlCmd = "ALTER TABLE %s DROP COLUMN tmpid" % ( inTable )
+        self.execute( sqlCmd )
+        self.dropTable( tmpTable )
+        
+        
+    ## Export data from a table in a file.
+    #
+    # @param tableName string table name 
+    # @param outFileName string output file name
+    # @param keepFirstLine boolean if you want the first line (column name) in output file
+    # @param param string sql parameters to select data expected 
+    #
+    def exportDataToFile( self, tableName, outFileName="", keepFirstLine=False, param="" ):
+        if outFileName == "": outFileName = tableName
+        prg = "mysql"
+        cmd = prg
+        cmd += " -h %s" % ( self.host )
+        cmd += " -u %s" % ( self.user )
+        cmd += " -p\"%s\"" % ( self.passwd )
+        cmd += " --database=%s" % ( self.dbname )
+        cmd += " -e\"SELECT * FROM %s" % ( tableName )
+        if param != "": cmd += " %s" % ( param )
+        cmd += ";\""
+        cmd += " > "
+        if keepFirstLine == False:
+            cmd += "%s.tmp" % ( outFileName )
+        else:
+            cmd += "%s" % ( outFileName )
+        log = os.system( cmd )
+        if log != 0: print "ERROR: mysql returned %i" % ( log ); sys.exit(1)
+    
+        if keepFirstLine == False:
+            tmpFileName = "%s.tmp" % ( outFileName )
+            tmpFile = open( tmpFileName, "r" )
+            outFile = open( outFileName, "w" )
+            i = 0
+            for line in tmpFile:
+                if i > 0:
+                    outFile.write( line )
+                i += 1
+            tmpFile.close()
+            outFile.close()
+            os.remove( tmpFileName )
+            
+            
+    ## Convert a Path table into an Align table
+    #
+    # @param inPathTable string name of the input Path table
+    # @param outAlignTable string name of the output Align table
+    #
+    def convertPathTableIntoAlignTable( self, inPathTable, outAlignTable ):
+        sqlCmd = "CREATE TABLE %s SELECT query_name,query_start,query_end,subject_name,subject_start,subject_end,E_value,score,identity FROM %s;" % ( outAlignTable, inPathTable )
+        self.execute( sqlCmd )
+        self.updateInfoTable( outAlignTable, "" )
+        
+    
+    ## Create a set table from a map table
+    #
+    # @param mapTableName string map table name
+    # @param setTableName string new set table name
+    #
+    def convertMapTableIntoSetTable( self, mapTableName, setTableName ):
+        sqlCmd = "CREATE TABLE %s (path int(10) unsigned auto_increment primary key) select name, chr, start, end from %s;" % (setTableName, mapTableName)
+        self.execute(sqlCmd)
+        self.createIndex(setTableName, "set")
+    
+    
+    ## Convert an Align table into a Path table
+    #
+    # @param inAlignTable string name of the input Align table
+    # @param outPathTable string name of the output Path table
+    #
+    def convertAlignTableIntoPathTable( self, inAlignTable, outPathTable ):
+        self.createTable( outPathTable, "path", "", True )
+        sqlCmd = "SELECT * FROM %s" % ( inAlignTable )
+        self.execute( sqlCmd )
+        lResults = self.fetchall()
+        rowIndex = 0
+        for res in lResults:
+            rowIndex += 1
+            sqlCmd = "INSERT INTO %s" % ( outPathTable )
+            sqlCmd += " (path,query_name,query_start,query_end,subject_name,subject_start,subject_end,E_value,score,identity)"
+            sqlCmd += " VALUES ( '%i'" % ( rowIndex )
+            for i in res:
+                sqlCmd += ', "%s"' % ( i )
+            sqlCmd += " )"
+            self.execute( sqlCmd )
+        self.updateInfoTable( outPathTable, "" )
+        
+        
+    ## Give a list of instances according to the SQL command
+    #
+    # @param SQLCmd string is a SQL command
+    # @param methodGetInstance2Adapt a getter method name. With this method you choose the type of intances contained in lObjs. See example in Test_DbMySql.py.
+    # @return lObjs list of instances
+    #
+    def getObjectListWithSQLCmd( self, SQLCmd,  methodGetInstance2Adapt):
+        self.execute( SQLCmd )
+        res = self.fetchall()
+        lObjs = []
+        for t in res:
+            iObj = methodGetInstance2Adapt()
+            iObj.setFromTuple( t )
+            lObjs.append( iObj )
+        return lObjs
+    
+    
+    ## Give a list of integer according to the SQL command
+    #
+    # @param sqlCmd string is a SQL command
+    # @return lInteger integer list
+    #
+    def getIntegerListWithSQLCmd( self, sqlCmd ):
+        self.execute(sqlCmd)
+        res = self.fetchall()
+        lInteger = []
+        for t in res:
+            if t[0] != None:
+                lInteger.append(int(t[0]))
+        return lInteger
+    
+    
+    ## Give a int according to the SQL command
+    #
+    # @param sqlCmd string is a SQL command
+    # @return nb integer 
+    #
+    def getIntegerWithSQLCmd( self, sqlCmd ):
+        self.execute(sqlCmd)
+        res = self.fetchall()
+        nb = res[0][0]
+        if nb == None:
+            nb = 0
+        return nb
+    
+    
+    ## Give a list of str according to the SQL command
+    #
+    # @param sqlCmd string is a SQL command
+    # @return lString str list
+    #
+    def getStringListWithSQLCmd( self, sqlCmd ):
+        self.execute(sqlCmd)
+        res = self.fetchall()
+        lString = []
+        for i in res:
+            lString.append(i[0])
+        return lString
+    
+#TODO: use API to add indexes
+    ## Remove doublons in a given table
+    #
+    # @param table string name of a MySQL table
+    #
+    def removeDoublons( self, table ):
+        tmpTable = "%s_%s" % ( table, time.strftime("%Y%m%d%H%M%S") )
+        sqlCmd = "CREATE TABLE %s SELECT DISTINCT * FROM %s" % ( tmpTable, table )
+        self.execute( sqlCmd )
+        self.dropTable( table )
+        self.renameTable(tmpTable, table)
+        
+        
+    ## Get a list of table names from a pattern
+    #
+    # @note for instance pattern = 'MyProject_%'
+    #
+    def getTableListFromPattern( self, pattern ):
+        if pattern == "*" or pattern == "%":
+            sqlCmd = "SHOW TABLES"
+        else:
+            sqlCmd = "SHOW TABLES like '%s'" % ( pattern )
+        lTables = self.getStringListWithSQLCmd( sqlCmd )
+        return lTables
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/DbSQLite.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,173 @@
+import sqlite3
+import os
+import sys
+
+#TODO: update...compare with DbMySql.py
+class DbSQLite(object):
+    
+    ## Constructor
+    #
+    # @param host string db file path
+    # @param cfgFileName string configuration file name
+    #
+    # @note when a parameter is left blank, the constructor is able
+    #   to set attribute values from environment variable: REPET_HOST,
+    #   
+    def __init__(self, host = ""):
+        if host != "":
+            self.host = host
+        else:
+            msg = "ERROR: no host specified"
+            sys.stderr.write( "%s\n" % msg )
+            sys.exit(1)
+        # remove open() and cursor from init() use directly outside this class ...
+        self.open()
+        self.cursor = self.db.cursor()
+    
+    ## Connect to the DbSQLite database
+    #
+    # @param verbose integer (default = 0)
+    #
+    def open( self, verbose = 0, nb = 0 ):
+        try:
+            #sqlite.connect(":memory:", check_same_thread = False)
+            self.db = sqlite3.connect(self.host, check_same_thread= False, isolation_level=None, detect_types=sqlite3.PARSE_DECLTYPES)
+        except sqlite3.Error, e:
+            if verbose > 0:
+                print "ERROR %s" % e
+                sys.stdout.flush()
+            return False
+        return True
+    
+    ## Execute a SQL query
+    #
+    # @param qry string SQL query to execute
+    # @param params parameters of SQL query 
+    #
+    def execute( self, qry, params=None ):
+        try : 
+            if params == None:
+                self.cursor.execute( qry )
+            else:
+                self.cursor.execute( qry, params )
+        except Exception, e:
+            #TODO Must be test 
+            try : 
+                if params == None:
+                    self.cursor.execute( qry )
+                else:
+                    self.cursor.execute( qry, params )
+            except Exception, e:
+                    print "Erreur : %s" % e
+                    
+    ## Retrieve the results of a SQL query
+    #  
+    def fetchall(self):
+        return self.cursor.fetchall()
+    
+    ## Record a new table in the 'info_table' table
+    #
+    # @param tableName string table name
+    # @param info string information on the table origin
+    #
+    def updateInfoTable( self, tableName, info ):
+        if not self.doesTableExist( "info_tables" ):
+            sqlCmd = "CREATE TABLE info_tables ( name varchar(255), file varchar(255) )"
+            self.execute( sqlCmd )
+        sqlCmd = 'INSERT INTO info_tables VALUES ("%s","%s")' % (tableName, info)
+        self.execute( sqlCmd )
+   
+    def createTable(self, tableName, dataType, overwrite=False, verbose=0):
+        if verbose > 0:
+            print "creating table '%s' from file '%s' of type '%s'..." % (tableName, dataType)
+            sys.stdout.flush()
+        if overwrite:
+            self.dropTable(tableName)   
+        if dataType.lower() in ["job", "jobs"]:
+            self.createJobTable(tableName)
+        else:
+            print "ERROR: unknown type %s" % (dataType)
+            self.close()
+            sys.exit(1)
+        if verbose > 0:
+            print "done!"; sys.stdout.flush()
+    
+    ## Create a job table
+    #
+    # @param tablename new table name
+    #
+    def createJobTable( self, tablename ):
+        sqlCmd = "CREATE TABLE %s" % ( tablename )
+        sqlCmd += " ( jobid INT UNSIGNED"
+        sqlCmd += ", jobname VARCHAR(255)"
+        sqlCmd += ", groupid VARCHAR(255)"
+        sqlCmd += ", command TEXT"
+        sqlCmd += ", launcher VARCHAR(1024)"
+        sqlCmd += ", queue VARCHAR(255)"
+        sqlCmd += ", status VARCHAR(255)"
+        sqlCmd += ", time timestamp"
+        sqlCmd += ", node VARCHAR(255) )"
+        self.execute( sqlCmd )
+        
+        self.updateInfoTable( tablename, "job table" )
+        sqlCmd = "CREATE INDEX igroupid ON " + tablename + " ( groupid )"
+        self.execute( sqlCmd )
+    
+    ## Test if a table exists
+    #
+    # @param table string table name
+    # @return boolean True if the table exists, False otherwise
+    #       
+    def doesTableExist( self, table ):
+        qry = "PRAGMA table_info(%s)" % (table)
+        self.execute( qry )
+        results = self.cursor.fetchall()
+        if results:
+            return True
+        return False
+    
+    def isEmpty( self, tableName ):
+        return self.getSize( tableName ) == 0
+    
+    ## Give the rows number of the table
+    #
+    # @param tableName string table name
+    #
+    def getSize( self, tableName ):
+        qry = "SELECT count(*) FROM %s;" % ( tableName )
+        self.execute( qry )
+        res = self.fetchall()
+        return int( res[0][0] )
+    
+    ## Remove a table if it exists
+    #
+    # @param table string table name
+    # @param verbose integer (default = 0)
+    #
+    def dropTable( self, table, verbose = 0 ):
+        if self.doesTableExist( table ):
+            sqlCmd = "DROP TABLE %s" % ( table )
+            self.execute( sqlCmd )
+            sqlCmd = 'DELETE FROM info_tables WHERE name = "%s"' % ( table )
+            self.execute( sqlCmd )
+            
+    ## Get a list with the fields
+    #                    
+    def getFieldList( self, table ):
+        lFields = []
+        sqlCmd = "PRAGMA table_info(%s)" % ( table )
+        self.execute( sqlCmd )
+        lResults = self.fetchall()
+        for res in lResults:
+            lFields.append( res[1] )
+        return lFields
+    
+    ## delete this SQLite database session
+    #
+    def delete(self):
+        os.remove(self.host)
+        
+    ## Close the connection
+    #   
+    def close( self ):
+        self.db.close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/ITableMapAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,113 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+## Interface for TableMapAdaptator 
+#
+class ITableMapAdaptator(object):
+  
+    ## Insert a map instance
+    #
+    # @param obj map or set
+    # @param delayed boolean must the insert be delayed 
+    #
+    # @warning old name was insAMap
+    #
+    def insert(self, obj, delayed=False):
+        pass
+
+        
+    ## Insert a list of Map or Set or Match instances
+    #
+    # @param l a list of object instances
+    # @param delayed boolean
+    #
+    # @warning old name was insMapList
+    #
+    def insertList(self, l, delayed = False):
+        pass
+    
+    ## Give a list of the distinct seqName/chr present in the table
+    #
+    # @return lDistinctContigNames string list
+    #
+    # @warning old name was getContig_name
+    #
+    def getSeqNameList(self):
+        pass
+    
+    
+    ## Give a list of Map instances having a given seq name
+    #
+    # @param seqName string seq name
+    # @return lMap list of instances
+    #
+    # @warning old name was get_MapList_from_contig
+    #
+    def getMapListFromSeqName(self, seqName):
+        pass
+    
+    
+    ## Return a list of Set instances from a given sequence name
+    #
+    # @param seqName string sequence name
+    # @return lSets list of Set instances
+    #
+    # @warning old name was getSetList_from_contig 
+    #
+    def getSetListFromSeqName( self, seqName ):
+        pass
+
+    
+    ## Give a map instances list overlapping a given region
+    #
+    # @param seqName string seq name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lMap list of map instances
+    #
+    # @warning old name was getMapList_from_qcoord
+    #
+    def getMapListOverlappingCoord(self, seqName, start, end):
+        pass
+    
+    
+    ## Return a list of Set instances overlapping a given region
+    #   
+    # @param seqName string sequence name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lSet list of Set instances
+    #
+    # @warning old name was getSetList_from_qcoord
+    #
+    def getSetListOverlappingCoord( self, seqName, start, end ):
+        pass
+    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/ITableMatchAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,68 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+## Interface for TableMatchAdaptator
+#
+class ITableMatchAdaptator(object):
+        
+    ## Give a list of Match instances given a query name
+    #
+    # @param query string sequence name
+    # @return lMatches list of Match instances
+    #
+    def getMatchListFromQuery( self, query ):
+        pass
+    
+    ## Give a list of Match instances having the same identifier
+    #
+    # @param id integer identifier number
+    # @return lMatch a list of Match instances
+    #
+    def getMatchListFromId( self, id ):
+        pass
+    
+    ## Insert a Match instance
+    #
+    # @param iMatch a Match instance
+    # @param delayed boolean
+    #
+    def insert(self, iMatch, delayed = False):
+        pass  
+        
+    ## Insert a list of Map or Set or Match instances
+    #
+    # @param l a list of object instances
+    # @param delayed boolean
+    #
+    # @warning old name was insMapList
+    #
+    def insertList(self, l, delayed = False):
+        pass
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/ITablePathAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,429 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+## Interface for TablePathAdaptator
+#
+class ITablePathAdaptator (object):
+
+    ## Give the data contained in the table as a list of Path instances
+    #
+    # @return lPaths list of path instances
+    #
+    def getListOfAllPaths( self ):
+        pass
+    
+    ## Give a list of Path instances having the same identifier
+    #
+    # @param id integer identifier number
+    # @return lPath a list of Path instances
+    #
+    # @warning old name was getPathList_from_num
+    #
+    def getPathListFromId( self, id ):
+        pass
+
+    ## Give a list of Path instances according to the given list of identifier numbers
+    #
+    # @param lId integer list 
+    # @return lPath a list of Path instances
+    #
+    # @warning old name was getPathList_from_numlist
+    #
+    def getPathListFromIdList( self, lId ):
+        pass
+        
+    ## Give a list of Path instances having the same given query name
+    #
+    # @param query string name of the query 
+    # @return lPath a list of Path instances
+    #
+    # @warning old name was getPathList_from_query
+    #
+    def getPathListFromQuery( self, query ):
+        pass
+    
+    ## Give a list with all the distinct identifiers corresponding to the query
+    #
+    # @param query string name of the query 
+    # @return lId a list of integer
+    #
+    # @warning old name was getPathList_from_query
+    #
+    def getIdListFromQuery( self, query ):
+        pass
+    
+    ## Give a list with all the distinct identifiers corresponding to the subject
+    #
+    # @param subject string name of the subject 
+    # @return lId a list of integer
+    #
+    # @warning old name was getPathList_from_subject
+    #
+    def getIdListFromSubject( self, subject ):
+        pass
+    
+    ## Insert a path instance
+    #
+    # @param obj a path instance
+    # @param delayed boolean indicating if the insert must be delayed
+    #
+    # @note data are inserted such that the query is always on the direct strand
+    #
+    # @warning old name was insAPath
+    #
+    def insert(self, obj, delayed = False):
+        pass
+    
+    ## Insert a list of Path instances
+    #
+    # @param l a list of Path instances
+    # @param delayed boolean
+    #
+    # @warning old name was insPathList
+    #
+    def insertList(self, l, delayed = False):
+        pass
+    
+    ## Give a list of the identifier number contained in the table
+    #
+    # @return l integer list
+    #
+    # @warning old name was getPath_num
+    #
+    def getIdList(self):
+        pass
+    
+    ## Give a list of Path instances having the same given subject name
+    #
+    # @param subject string name of the subject 
+    # @return lPath a list of Path instances
+    #
+    # @warning old name was getPath_num
+    #
+    def getPathListFromSubject( self, subject ):
+        pass
+    
+    ## Give a list of the distinct subject names present in the table
+    #
+    # @return lDistinctTypeNames string list
+    #
+    # @warning old name was getListDistinctSubjectName
+    #
+    def getSubjectList(self):
+        pass
+    
+    ## Give a list of the distinct query names present in the table
+    #
+    # @return lDistinctQueryNames string list
+    #
+    # @warning old name was getListDistinctQueryName
+    #
+    def getQueryList(self):
+        pass
+    
+    ## Give a list of Set instance list from the path contained on a query name
+    #
+    # @param queryName string query name
+    # @return lSet list of set instance 
+    #
+    def getSubjectListFromQuery (self, queryName):
+        pass
+    
+    ## Give a list of Path instances with the given query and subject, both on direct strand
+    #
+    # @param query string query name
+    # @param subject string subject name
+    # @return lPaths list of path instances
+    #
+    # @warning old name was getListPathsWithDirectQueryDirectSubjectPerQuerySubject
+    #
+    def getPathListWithDirectQueryDirectSubjectFromQuerySubject( self, query, subject ):
+        pass
+    
+    ## Give a list of Path instances with the given query on direct strand and the given subject on reverse strand
+    #
+    # @param query string query name
+    # @param subject string subject name
+    # @return lPaths list of path instances
+    #
+    # @warning old name was getListPathsWithDirectQueryReverseSubjectPerQuerySubject
+    #
+    def getPathListWithDirectQueryReverseSubjectFromQuerySubject( self, query, subject ):
+        pass
+    
+    ## Give the number of Path instances with the given query name
+    #
+    # @param query string query name
+    # @return pathNb integer the number of Path instances
+    #
+    # @warning old name was getNbPaths_from_query
+    #
+    def getNbPathsFromQuery( self, query ):
+        pass
+    
+    ## Give the number of Path instances with the given subject name
+    #
+    # @param subject string subject name
+    # @return pathNb integer the number of Path instances
+    #
+    # @warning old name was getNbPaths_from_subject
+    #
+    def getNbPathsFromSubject( self, subject ):
+        pass
+    
+    ## Give the number of distinct path identifiers
+    #
+    # @return idNb integer the number of Path instances
+    #
+    # @warning old name was getNbAllPathsnums
+    #
+    def getNbIds( self ):
+        pass
+    
+    ## Give the number of distinct path identifiers for a given subject
+    #
+    # subjectName string subject name
+    # @return idNb integer the number of Path instances
+    #
+    # @warning old name was getNbPathsnums_from_subject
+    #
+    def getNbIdsFromSubject( self, subjectName ):
+        pass
+    
+    ## Give the number of distinct path identifiers for a given query
+    #
+    # @param queryName string query name
+    # @return idNb integer the number of Path instances
+    #
+    # @warning old name was getNbPathsnums_from_query
+    #
+    def getNbIdsFromQuery( self, queryName ):
+        pass
+    
+    ## Give a list of Path instances overlapping a given region
+    #
+    # @param query string query name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lPath list of Path instances
+    #
+    def getPathListOverlappingQueryCoord( self, query, start, end ):
+        pass
+    
+    ## Give a list of Set instances overlapping a given region
+    #
+    # @param query string query name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lSet list of Set instances
+    #
+    # @warning old name was getSetList_from_qcoord
+    #
+    def getSetListOverlappingQueryCoord(self, query, start, end):
+        pass
+
+    ## Give a list of Path instances included in a given query region
+    #
+    # @param query string query name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lPaths list of Path instances
+    #
+    # @warning old name was getIncludedPathList_from_qcoord
+    #
+    def getPathListIncludedInQueryCoord( self, query, start, end ):
+        pass
+    
+    ## Give a list of Set instances included in a given region
+    #
+    # @param query string query name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lSet list of Set instances
+    #
+    # @warning old name was getInSetList_from_qcoord
+    #
+    def getSetListIncludedInQueryCoord(self, query, start, end):
+        pass
+    
+    ## Give a a list of Path instances sorted by query coordinates
+    #
+    # @return lPaths list of Path instances
+    #
+    # @warning old name was getListOfPathsSortedByQueryCoord
+    #
+    def getPathListSortedByQueryCoord( self ):
+        pass
+    
+    ## Give a a list of Path instances sorted by query coordinates for a given query
+    #
+    # @param queryName string query name
+    # @return lPaths list of Path instances
+    #
+    def getPathListSortedByQueryCoordFromQuery( self, queryName ):
+        pass
+    
+    ## Give a list of path instances sorted by increasing E-value
+    #
+    # queryName string query name
+    # @return lPaths list of path instances
+    #
+    def getPathListSortedByIncreasingEvalueFromQuery( self, queryName ):
+        pass
+
+    ## Give a cumulative length of all paths (fragments) for a given subject name
+    #
+    # @param subjectName string subject name
+    # @return nb Cumulative length for all path
+    # @warning doesn't take into account the overlaps !!
+    # @warning old name was getCumulPathLength_from_subject
+    #  
+    def getCumulLengthFromSubject( self, subjectName ):
+        pass
+    
+    ## Give a list of the length of all chains of paths for a given subject name
+    #
+    # @param subjectName string  name of the subject
+    # @return lChainLengths list of lengths per chain of paths
+    # @warning doesn't take into account the overlaps !!
+    # @warning old name was getListChainLength_from_subject
+    #
+    def getChainLengthListFromSubject( self, subjectName ):
+        pass
+
+    ## Give a list of identity of all chains of paths for a given subject name
+    #
+    # @param subjectName string name of the subject
+    # @return lChainIdentities list of identities per chain of paths
+    # @warning doesn't take into account the overlaps !!
+    # @warning old name was getListChainIdentity_from_subject
+    # 
+    def getChainIdentityListFromSubject( self, subjectName ):
+        pass
+    
+    ## Give a list of Path lists sorted by weighted identity.
+    #
+    # @param qry query name
+    # @return lChains list of chains
+    #
+    def getListOfChainsSortedByAscIdentityFromQuery( self, qry ):
+        pass
+    
+    ## Give a list of the length of all paths for a given subject name
+    #
+    # @param subjectName string name of the subject
+    # @return lPathLengths list of lengths per path
+    # @warning doesn't take into account the overlaps !!
+    # @warning old name was getListPathLength_from_subject
+    #
+    def getPathLengthListFromSubject( self, subjectName ):
+        pass
+    
+    ## Give a a list with all distinct identifiers for a given subject sorted in decreasing order according to the length of the chains
+    #    
+    # @return lPathNums a list of paths Id
+    #
+    # @warning old name was getPathNumListSortedByDecreasingChainLengthFromSubject
+    #
+    def getIdListSortedByDecreasingChainLengthFromSubject( self, subjectName ):
+        pass
+    
+    ## Give a list of Set instance list from the path contained on a query name
+    #
+    # @param query string query name
+    # @return lSet list of set instance 
+    #
+    # @warning old name was getSetList_from_contig
+    #
+    def getSetListFromQuery(self, query):
+        pass
+    
+    ## Delete path corresponding to a given identifier number
+    #
+    # @param id integer identifier number
+    #
+    # @warning old name was delPath_from_num
+    #
+    def deleteFromId(self,id):
+        pass
+    
+    ## Delete path corresponding to a given list of identifier number
+    #
+    # @param lId list of identifier number
+    #
+    # @warning old name was delPath_from_numlist
+    #
+    def deleteFromIdList(self,lId):
+        pass
+
+    ## Join two path by changing id number of id1 and id2 path to the least of id1 and id2
+    #
+    # @param id1 integer path number
+    # @param id2 integer path number
+    # @return newId integer id used to join
+    #
+    # @warning old name was joinPath
+    #
+    def joinTwoPaths(self,id1,id2):
+        pass
+    
+    ## Get a new id number
+    #
+    # @return newId integer new id
+    #
+    def getNewId(self):
+        pass
+    
+    ## Test if table is empty
+    #    
+    def isEmpty( self ):
+        pass
+    
+    ## Create a 'pathRange' table from a 'path' table. 
+    # The output table summarizes the information per identifier. 
+    # The min and max value are taken. 
+    # The identity is averaged over the fragments. 
+    # It may overwrite an existing table.
+    #
+    # @param outTable string name of the output table
+    # @return outTable string Table which summarizes the information per identifier
+    #
+    def path2PathRange( self, outTable="" ):
+        pass
+    
+    ## Return the number of times a given instance is present in the table
+    # The identifier is not considered,
+    # only coordinates, score, E-value and identity.
+    #
+    # @return nbOcc integer
+    #
+    def getNbOccurrences( self, iPath ):
+        pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/ITableSeqAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,63 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+## Interface for TableSeqAdaptator
+#
+class ITableSeqAdaptator(object):
+
+    ## Retrieve all the distinct accession names in a list.
+    #
+    # @return lAccessions list of accessions
+    #
+    # @warning old name was getListAccession
+    #
+    def getAccessionsList( self ):
+        pass
+    
+    ## Save sequences in a fasta file from a list of accession names.
+    # 
+    # @param lAccessions list of accessions
+    # @param outFileName string Fasta file
+    #
+    # @warning old name saveListAccessionInFastaFile
+    #
+    def saveAccessionsListInFastaFile( self, lAccessions, outFileName ):
+        pass
+    
+    ## insert bioseq instance
+    #
+    # @param seq bioseq 
+    # @param delayed boolean must the insert be delayed 
+    # 
+    # @warning old name was insASeq
+    #
+    def insert(self, seq, delayed = False):
+        pass
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/ITableSetAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,146 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+## Interface for TableSetAdaptator
+#
+class ITableSetAdaptator (object):
+    
+    ## Insert a set instance
+    #
+    # @param obj a set instance
+    # @param delayed boolean indicating if the insert must be delayed
+    #
+    # @warning old name was insASet
+    #
+    def insert(self, obj, delayed = False):
+        pass
+
+    ## Insert a list of Set instances
+    #
+    # @param l a list of object instances
+    # @param delayed boolean
+    #
+    # @warning old name was insSetList
+    #
+    def insertList(self, l, delayed = False):
+        pass
+    
+    ## Give a list of identifier numbers contained in the table
+    #
+    # @return l integer list
+    #
+    # @warning old name was getSet_num
+    #
+    def getIdList(self):
+        pass
+    
+    ## Give a list of Set instances having a given seq name
+    #
+    # @param seqName string seq name
+    # @return lSets list of instances
+    #
+    # @warning old name was get_SetList_from_contig
+    #
+    def getSetListFromSeqName(self, seqName):
+        pass
+        
+    ## Give a set instances list with a given identifier number
+    #
+    # @param id integer identifier number
+    # @return lSet list of set instances
+    #
+    # @warning old name was getSetList_from_num
+    #
+    def getSetListFromId(self, id):
+        pass
+    
+    ## Give a set instances list with a list of identifier numbers
+    #
+    # @param lId integers list identifiers list numbers
+    # @return lSet list of set instances
+    #
+    # @warning old name was getSetList_from_numlist
+    #   
+    def getSetListFromIdList(self,lId):
+        pass
+    
+    ## Return a list of Set instances overlapping a given sequence
+    #   
+    # @param seqName string sequence name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lSet list of Set instances
+    #
+    # @warning old name was getSetList_from_qcoord
+    #
+    def getSetListOverlappingCoord( self, seqName, start, end ):
+        pass
+    
+    ## Delete set corresponding to a given identifier number
+    #
+    # @param id integer identifier number
+    #
+    # @warning old name was delSet_from_num 
+    #  
+    def deleteFromId(self, id):
+        pass
+    
+    ## Delete set corresponding to a given list of identifier number
+    #
+    # @param lId integers list list of identifier number
+    #  
+    # @warning old name was delSet_from_listnum 
+    #
+    def deleteFromIdList(self, lId):
+        pass
+    
+    ## Join two set by changing id number of id1 and id2 set to the least of id1 and id2
+    #
+    # @param id1 integer id path number
+    # @param id2 integer id path number
+    #
+    # @warning old name was joinSet
+    #    
+    def joinTwoSets(self, id1, id2):
+        pass
+    
+    ## Get a new id number
+    #
+    # @return new_id integer max_id + 1 
+    #
+    def getNewId(self):
+        pass
+    
+    ## Give the data contained in the table as a list of Sets instances
+    #
+    # @return lSets list of set instances
+    #
+    def getListOfAllSets( self ):
+        pass
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/Job.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,74 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+## Job informations to launch a command on a cluster.
+#
+class Job(object):
+    
+    ## Constructor
+    #
+    #   @param jobid the job identifier
+    #   @param jobname the job name
+    #   @param groupid the group identifier to record related job series 
+    #   @param queue queue name of the job manager
+    #   @param command command launched
+    #   @param node cluster node name where the execution takes place
+    #   @param launcherFile file name launched as job
+    #   @param lResources resources (memory, time...) but need to conform to SGE/Torque syntax !
+    #
+    def __init__(self, jobid=0, jobname="", groupid="", queue="", command="", launcherFile="",\
+                  node="", lResources=["mem_free=1G"], parallelEnvironment="" ):
+        if str(jobid).isdigit():
+            self.jobid = int(jobid)
+            self.jobname = jobname
+        else:
+            self.jobname = jobid
+            self.jobid = 0
+        self.jobid = jobid
+        self.groupid = groupid
+        self.setQueue(queue)
+        self.command = command
+        self.launcher = launcherFile
+        self.node = node
+        self.lResources = lResources
+        self.parallelEnvironment = parallelEnvironment
+        
+    def setQueue(self, queue):
+        self.queue = ""
+        if queue != "none":
+            self.queue = queue
+    
+    def __eq__(self, o):
+        if self.jobid == o.jobid and self.jobname == o.jobname\
+         and self.groupid == o.groupid and self.queue == o.queue and self.command == o.command \
+         and self.launcher == o.launcher and self.node == o.node and self.lResources == o.lResources \
+         and self.parallelEnvironment == o.parallelEnvironment:
+            return True
+        return False
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/JobAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,271 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import os
+import time
+import sys
+import tempfile
+import subprocess
+from commons.core.sql.Job import Job
+
+## Methods for Job persistence 
+#
+class JobAdaptator(object):
+    
+    def __init__(self, lJob = [], table = "" ):
+        self._lJobID = lJob
+        self._table = table
+        self._acronym = ""
+    ## Record a job
+    #
+    # @param job Job instance with the job informations
+    #
+    def recordJob(self, job):
+        self._lJobID.append(job)
+    
+    ## Remove a job from the job table
+    #
+    #  @param job: job instance to remove
+    #
+    def removeJob(self, job):
+        pass         
+            
+    ## Set the jobid of a job with the id of SGE
+    #
+    # @param job job instance
+    # @param jobid integer
+    #
+    def updateJobIdInDB(self, job, jobid):
+        pass
+        
+    ## Get a job status
+    #
+    # @param job: a Job instance with the job informations
+    #
+    def getJobStatus(self, job):
+        pass
+    
+    
+    ## Change a job status
+    #
+    # @param job: a Job instance with the job informations
+    # @param status: the new status (waiting,finished,error)
+    #
+    def changeJobStatus(self, job, status):
+        pass
+        
+    ## Get the number of jobs belonging to the desired groupid with the desired status.
+    #
+    # @param groupid string a group identifier to record related job series 
+    # @param status string job status (waiting, running, finished, error)
+    # @return int
+    #
+    def getCountStatus(self, groupid, status):
+        pass
+        
+    ## Clean all job from a job group
+    #
+    # @param groupid: a group identifier to record related job series
+    #
+    def cleanJobGroup(self, groupid):
+        pass            
+            
+    ## Check if there is unfinished job from a job group.
+    #
+    # @param groupid string a group identifier to record related job series 
+    #        
+    def hasUnfinishedJob(self, groupid):
+        pass
+
+    def _getJobIDListFromQstat(self):
+        lJobIDFromQstat = []
+        tmp = tempfile.NamedTemporaryFile(delete=False)
+        cmd ="qstat | grep %s" % self._acronym
+        process = subprocess.Popen(cmd, shell=True,stdout=tmp)
+        process.communicate()
+        tmp.close()
+        if process.returncode == 0:
+            fileName = tmp.name
+            jobidFileHandler = open(fileName, "r")        
+            for line in jobidFileHandler:
+                line2 = line.lstrip(" ")
+                lJobIDFromQstat.append(line2.split(" ")[0])
+            jobidFileHandler.close()
+            os.remove(fileName)
+        return lJobIDFromQstat     
+     
+    def _areJobsStillRunning(self,lJobID,lJobIDFromQstat):
+        sorted(lJobID)  
+        sorted(lJobIDFromQstat)
+        for i in lJobID:
+            for j in lJobIDFromQstat:
+                if int(i)== int(j):
+                    return True
+        return False
+                
+        
+    ## Wait job finished status from a job group.
+    #  Job are re-launched if error (max. 3 times)
+    #
+    # @param groupid string a group identifier to record related job series
+    # @param checkInterval integer time laps in seconds between two checks (default = 5)
+    # @param maxRelaunch integer max nb of times a job in error is relaunch before exiting (default = 3)
+    # @param exitIfTooManyErrors boolean exit if a job is still in error above maxRelaunch (default = True)
+    # @param timeOutPerJob integer max nb of seconds after which one tests if a job is still in SGE or not (default = 60*60=1h)
+    #
+    def waitJobGroup(self, groupid, checkInterval=5, maxRelaunch=3, exitIfTooManyErrors=True, timeOutPerJob=60*60):
+        
+        while True:
+            time.sleep(checkInterval)
+            lJobIDFromQstat = self._getJobIDListFromQstat()
+            if self._areJobsStillRunning(self._lJobID, lJobIDFromQstat) == False:
+                break
+    
+    ## Submit a job to a queue and record it in job table.
+    #
+    # @param job a job instance
+    # @param maxNbWaitingJobs integer max nb of waiting jobs before submitting a new one (default = 10000)
+    # @param checkInterval integer time laps in seconds between two checks (default = 30)
+    # @param verbose integer (default = 0)
+    #               
+    def submitJob(self, job, verbose=0, maxNbWaitingJobs=10000, checkInterval=30):
+        cmd = self._getQsubCommand(job)
+        tmp = tempfile.NamedTemporaryFile(delete=False)
+        process = subprocess.Popen(cmd, shell=True,stdout=tmp)
+        process.communicate()
+        tmp.close()
+        if process.returncode == 0:
+            fileName = tmp.name
+            jobidFileHandler = open(fileName, "r")
+            jobid = self._getJobidFromJobManager(jobidFileHandler)
+            if verbose > 0:
+                print "job '%i %s' submitted" % (jobid, job.jobname)
+                sys.stdout.flush()
+            job.jobid = jobid
+            #newJob= Job(job.jobid, job.jobname, job.groupid, job.queue, job.command, job.launcher, job.node, job.lResources, job.parallelEnvironment)
+            self._acronym = job.jobname.split("_")[0][:10]
+            self.recordJob(job.jobid)
+            jobidFileHandler.close()
+            os.remove(fileName)
+        return process.returncode
+
+
+    ## Get the list of nodes where jobs of one group were executed
+    #
+    # @param groupid string a group identifier of job series 
+    # @return lNodes list of nodes names without redundancy
+    #
+    def getNodesListByGroupId(self, groupId):
+        pass
+    
+    def checkJobTable(self):
+        pass
+    
+    def close(self):
+        pass
+    
+    def _getJobidAndNbJob(self, jobid) :
+        tab = jobid.split(".")
+        jobid = tab[0]
+        tab = tab[1].split(":")
+        nbJob = tab[0]
+        return jobid, nbJob
+    
+class JobAdaptatorSGE(JobAdaptator):
+
+   ## Check if a job is still handled by SGE
+    #
+    # @param jobid string job identifier
+    # @param jobname string job name
+    #  
+    def isJobStillHandledBySge(self, jobid, jobname):
+        isJobInQstat = False
+        tmp = tempfile.NamedTemporaryFile(delete=False)
+        cmd = "qstat"
+        process = subprocess.Popen(cmd, shell=True,stdout=tmp)
+        process.communicate()
+        tmp.close()
+        qstatFile = tmp.name
+        if process.returncode  != 0:
+            msg = "ERROR while launching 'qstat'"
+            sys.stderr.write( "%s\n" % msg )
+            sys.exit(1)
+        qstatFileHandler = open(qstatFile, "r")
+        lLines = qstatFileHandler.readlines()
+        for line in lLines:
+            tokens = line.split()
+            if len(tokens) > 3 and tokens[0] == str(jobid) and tokens[2] == jobname[0:len(tokens[2])]:
+                isJobInQstat = True
+                break
+        qstatFileHandler.close()
+        os.remove(qstatFile)
+        return isJobInQstat
+    
+    def _getQsubCommand(self, job):    
+        cmd = "echo '%s' | " % job.launcher
+        prg = "qsub"
+        cmd += prg
+        cmd += " -V"
+        cmd += " -N %s" % job.jobname
+        if job.queue != "":
+            cmd += " -q %s" % job.queue
+        cmd += " -cwd"
+        if job.lResources != []:
+            cmd += " -l \""
+            cmd += " ".join(job.lResources)
+            cmd += "\""
+        if job.parallelEnvironment != "":
+            cmd += " -pe " + job.parallelEnvironment
+        return cmd
+    
+    def _getJobidFromJobManager(self, jobidFileHandler):
+        return int(jobidFileHandler.readline().split(" ")[2])
+    
+
+class JobAdaptatorTorque(JobAdaptator):  
+        
+    def _getQsubCommand(self, job):    
+        cmd = "echo '%s' | " % job.launcher
+        prg = "qsub"
+        cmd += prg
+        cmd += " -V"
+        cmd += " -d %s" % os.getcwd()
+        cmd += " -N %s" % job.jobname
+        if job.queue != "":
+            cmd += " -q %s" % job.queue
+        if job.lResources != []:
+            cmd += " -l \""
+            cmd += " ".join(job.lResources).replace("mem_free","mem")
+            cmd += "\""
+        return cmd
+
+    def _getJobidFromJobManager(self, jobidFileHandler):
+        return int(jobidFileHandler.readline().split(".")[0])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/OldRepetDB.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,27 @@
+import pyRepet.sql.RepetDBMySQL
+
+
+class RepetDB ( pyRepet.sql.RepetDBMySQL.RepetDB ):
+    
+    #TODO: try 
+    def execute( self, qry, params=None ):
+        if params == None:
+            self.cursor.execute( qry )
+        else:
+            self.cursor.execute( qry, params )
+            
+            
+    ## Record a new table in the 'info_table' table
+    #
+    # @param tablename table name
+    # @param info information on the origin of the table
+    # 
+    def updateInfoTable( self, tablename, info ):
+        self.execute( """SHOW TABLES""" )
+        results = self.fetchall()
+        if ("info_tables",) not in results:
+            sqlCmd = "CREATE TABLE info_tables ( name varchar(255), file varchar(255) )"
+            self.execute( sqlCmd )
+        qryParams = "INSERT INTO info_tables VALUES (%s, %s)"
+        params = ( tablename, info )
+        self.execute( qryParams,params )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/RepetJob.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,252 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import os
+import time
+import sys
+from commons.core.sql.DbMySql import DbMySql
+from commons.core.sql.TableJobAdaptatorFactory import TableJobAdaptatorFactory
+
+#TODO: to remove... => replace all RepetJob() by TableJobAdaptator()...
+## Methods for Job persistence 
+#
+class RepetJob( DbMySql ):
+        
+        
+    ## Record a job
+    #
+    # @param job Job instance with the job informations
+    #
+    def recordJob( self, job ):
+        self.removeJob( job )
+        sqlCmd = "INSERT INTO %s" % ( job.tablename )
+        sqlCmd += " VALUES ("
+        sqlCmd += " \"%s\"," % ( job.jobid )
+        sqlCmd += " \"%s\"," % ( job.jobname )
+        sqlCmd += " \"%s\"," % ( job.groupid )
+        sqlCmd += " \"%s\"," % ( job.command.replace("\"","\'") )
+        sqlCmd += " \"%s\"," % ( job.launcher )
+        sqlCmd += " \"%s\"," % ( job.queue )
+        sqlCmd += " \"waiting\","
+        sqlCmd += " \"%s\"," % ( time.strftime( "%Y-%m-%d %H:%M:%S" ) )
+        sqlCmd += " \"?\" );"
+        self.execute( sqlCmd )
+        
+        
+    ## Remove a job from the job table
+    #
+    #  @param job: job instance to remove
+    #
+    def removeJob( self, job ):
+        qry = "DELETE FROM %s" % ( job.tablename )
+        qry += " WHERE groupid='%s'" % ( job.groupid )
+        qry += " AND jobname='%s'" % ( job.jobname )
+        qry += " AND queue='%s';" % ( job.queue )
+        self.execute( qry )
+            
+            
+    ## Set the jobid of a job with the id of SGE
+    #
+    # @param job job instance
+    # @param jobid integer
+    #
+    def setJobIdFromSge( self, job, jobid ):
+        qry = "UPDATE %s" % ( job.tablename )
+        qry += " SET jobid='%i'" % ( int(jobid) )
+        qry += " WHERE jobname='%s'" % ( job.jobname )
+        qry += " AND groupid='%s'" % ( job.groupid )
+        qry += " AND queue='%s';" % ( job.queue )
+        self.execute( qry )
+        
+        
+    ## Get a job status
+    #
+    # @param job: a Job instance with the job informations
+    #
+    def getJobStatus( self, job ):
+        if job.jobid != 0 and job.jobname == "":
+            job.jobname = job.jobid
+            job.jobid = 0
+        qry = "SELECT status FROM %s" % ( job.tablename )
+        qry += " WHERE groupid='%s'" % ( job.groupid )
+        qry += " AND jobname='%s'" % ( job.jobname )
+        qry += " AND queue='%s';" % ( job.queue )
+        self.execute( qry )
+        res = self.fetchall()
+        if len(res) > 1:
+            msg = "ERROR while getting job status: non-unique jobs"
+            sys.stderr.write( "%s\n" % msg )
+            sys.stderr.flush()
+            sys.exit(1)
+        if res == None or len(res) == 0:
+            return "unknown"
+        return res[0][0]
+    
+    
+    ## Change a job status
+    #
+    # @param job: a Job instance with the job informations
+    # @param status: the new status (waiting,finished,error)
+    # @param method: db or file
+    #
+    def changeJobStatus( self, job, status, method=""):
+        sqlCmd = "UPDATE %s" % ( job.tablename )
+        sqlCmd += " SET status='%s'" % ( status )
+        sqlCmd += ",node='%s'" % ( job.node )
+        sqlCmd += " WHERE groupid='%s'" % ( job.groupid )
+        sqlCmd += " AND jobname='%s'" % ( job.jobname )
+        sqlCmd += " AND queue='%s';" % ( job.queue )
+        self.execute( sqlCmd )
+        
+        
+    ## Get the number of jobs belonging to the desired groupid with the desired status.
+    #
+    # @param tablename string table name to record the jobs   
+    # @param groupid string a group identifier to record related job series 
+    # @param status string job status (waiting, running, finished, error)
+    # @return int
+    #
+    def getCountStatus( self, tablename, groupid, status ):
+        qry = "SELECT count(jobname) FROM %s" % ( tablename )
+        qry += " WHERE groupid='%s'" % ( groupid )
+        qry += " AND status='%s';" % ( status )
+        self.execute( qry )
+        res = self.fetchall()
+        return int( res[0][0] )
+        
+        
+    ## Clean all job from a job group
+    #
+    # @param tablename table name to record the jobs
+    # @param groupid: a group identifier to record related job series
+    #
+    def cleanJobGroup( self, tablename, groupid ):
+        if self.doesTableExist( tablename ):
+            qry = "DELETE FROM %s WHERE groupid='%s';" % ( tablename, groupid )
+            self.execute( qry )
+            
+            
+    ## Check if there is unfinished job from a job group.
+    #
+    # @param tablename string table name to record the jobs
+    # @param groupid string a group identifier to record related job series 
+    #        
+    def hasUnfinishedJob( self, tablename, groupid ):
+        if not self.doesTableExist( tablename ):
+            return False
+        qry = "SELECT * FROM %s" % ( tablename )
+        qry += " WHERE groupid='%s'" % ( groupid )
+        qry += " and status!='finished';" 
+        self.execute( qry )
+        res = self.fetchall()
+        if len(res) == 0:
+            return False
+        return True
+    
+         
+    ## Check if a job is still handled by SGE
+    #
+    # @param jobid string job identifier
+    # @param jobname string job name
+    #  
+    def isJobStillHandledBySge( self, jobid, jobname ):
+        isJobInQstat = False
+        qstatFile = "qstat_stdout"
+        cmd = "qstat > %s" % ( qstatFile )
+        returnStatus = os.system( cmd )
+        if returnStatus != 0:
+            msg = "ERROR while launching 'qstat'"
+            sys.stderr.write( "%s\n" % msg )
+            sys.exit(1)
+        qstatFileHandler = open( qstatFile, "r" )
+        lLines = qstatFileHandler.readlines()
+        for line in lLines:
+            tokens = line.split()
+            if len(tokens) > 3 and tokens[0] == str(jobid) and tokens[2] == jobname[0:len(tokens[2])]:
+                isJobInQstat = True
+                break
+        qstatFileHandler.close()
+        os.remove( qstatFile )
+        return isJobInQstat
+    
+    
+    ## Wait job finished status from a job group.
+    #  Job are re-launched if error (max. 3 times)
+    #
+    # @param tableName string table name to record the jobs
+    # @param groupid string a group identifier to record related job series
+    # @param checkInterval integer time laps in seconds between two checks (default = 5)
+    # @param maxRelaunch integer max nb of times a job in error is relaunch before exiting (default = 3)
+    # @param exitIfTooManyErrors boolean exit if a job is still in error above maxRelaunch (default = True)
+    # @param timeOutPerJob integer max nb of seconds after which one tests if a job is still in SGE or not (default = 60*60=1h)
+    #
+    def waitJobGroup(self, tableName, groupid, checkInterval=5, maxRelaunch=3, exitIfTooManyErrors=True, timeOutPerJob=60*60):
+        iTJA = TableJobAdaptatorFactory.createInstance(self, tableName)
+        iTJA.waitJobGroup(groupid, checkInterval, maxRelaunch, exitIfTooManyErrors, timeOutPerJob)
+                        
+    ## Submit a job to a queue and record it in job table.
+    #
+    # @param job a job instance
+    # @param maxNbWaitingJobs integer max nb of waiting jobs before submitting a new one (default = 10000)
+    # @param checkInterval integer time laps in seconds between two checks (default = 30)
+    # @param verbose integer (default = 0)
+    #               
+    def submitJob( self, job, verbose=0, maxNbWaitingJobs=10000, checkInterval=30 ):
+        iTJA = TableJobAdaptatorFactory.createInstance(self, job.tablename)
+        return iTJA.submitJob(job, verbose, maxNbWaitingJobs, checkInterval)
+                        
+        
+    ## Get the list of nodes where jobs of one group were executed
+    #
+    # @param tablename string table name where jobs are recored   
+    # @param groupid string a group identifier of job series 
+    # @return lNodes list of nodes names
+    #
+    def getNodesListByGroupId( self, tableName, groupId ):
+        qry = "SELECT node FROM %s" % tableName
+        qry += " WHERE groupid='%s'" % groupId
+        self.execute( qry )
+        res = self.fetchall()
+        lNodes = []
+        for resTuple in res:
+            lNodes.append(resTuple[0])
+        return lNodes
+    
+    def getDbName(self):
+        return "DbMySql"
+    
+    def _getJobidAndNbJob(self, jobid) :
+        tab = []
+        tab = jobid.split(".")
+        jobid = tab[0]
+        tab = tab[1].split(":")
+        nbJob = tab[0]
+        return jobid, nbJob
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/TableAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,128 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+## Abstract class, Ancestor of Table*Adaptator
+#
+class TableAdaptator( object ):
+    
+    ## Constructor
+    #
+    # @param iDb DbMySql instance
+    # @param table str table name
+    #
+    def __init__( self, iDb = None, table = "" ):
+        self._iDb = iDb
+        self._table = table
+        
+    ## Set connector to database
+    #
+    # @param iDb database instance
+    #
+    def setDbConnector( self, iDb ):
+        self._iDb = iDb
+        
+    ## Set table
+    #
+    # @param table string table name
+    #
+    def setTable( self, table ):
+        self._table = table
+    
+    ## Return the table name
+    #
+    def getTable( self ):
+        return self._table
+        
+    ## Return the number of rows in the table
+    #
+    def getSize( self ):
+        return self._iDb.getSize( self._table )
+    
+    ## Test if table is empty
+    #    
+    def isEmpty( self ):
+        return self._iDb.isEmpty( self._table )
+    
+    ## Insert an instance of Map or Set or Match or Path or Seq instances
+    #
+    # @param obj a Map or Set or Match or Path or Seq instance
+    # @param delayed boolean
+    #
+    def insert(self, obj, delayed = False):
+        if obj.isEmpty():
+            return
+        self._escapeAntislash(obj)
+        sql_cmd = self._genSqlCmdForInsert(obj, delayed)
+        self._iDb.execute(sql_cmd)
+    
+    ## Insert a list of Map or Set or Match or Path instances
+    #
+    # @param l a list of object instances
+    # @param delayed boolean
+    #
+    def insertList(self, l, delayed = False):
+        for i in l:
+            self.insert(i, delayed)
+            
+    ## Give the data contained in the table as a list of coord object instances
+    #
+    # @return lObject list of coord object instances
+    #
+    def getListOfAllCoordObject( self ):
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        lObjs = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lObjs
+    
+    ## Generate sql command for GetListOverlappingCoord method 
+    #  
+    # @param obj Map, Set or Match instance
+    # @param delayed boolean
+    # @return sqlCmd string generated sql command
+    #
+    def _genSqlCmdForInsert(self, obj, delayed):
+        sqlCmd = 'INSERT '
+        if delayed :
+            sqlCmd += ' DELAYED '
+        type2Insert, attr2Insert = self._getTypeAndAttr2Insert(obj)
+        sqlCmd +=  'INTO %s VALUES (' % (self._table) 
+        sqlCmd +=  ",".join(type2Insert)
+        sqlCmd += ")" 
+        sqlCmd = sqlCmd % attr2Insert
+        return sqlCmd
+   
+    def _getTypeAndAttr2Insert(self, obj):
+        pass
+    
+    def _getInstanceToAdapt(self):
+        pass
+    
+    def _escapeAntislash(self, obj):
+        pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/TableBinPathAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,257 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+from commons.core.coord.Range import getIdx
+from commons.core.sql.TablePathAdaptator import TablePathAdaptator
+from commons.core.coord.PathUtils import PathUtils
+
+## Bin Adaptator for a path table.
+#
+class TableBinPathAdaptator(TablePathAdaptator):
+
+    
+    ## Constructor
+    #
+    # @param db db instance
+    # @param tableName string table name (default = "")
+    #
+    def __init__(self, db, tableName = ""):
+        TablePathAdaptator.__init__(self, db, tableName)
+        self._table_idx = "%s_idx" % (self._table)
+            
+    ## Insert a path instance
+    #
+    # @param path a path instance
+    # @param delayed boolean indicating if the insert must be delayed (default = false) 
+    #        
+    def insert( self, path, delayed = False ):
+        TablePathAdaptator.insert(self, path, delayed)
+        self._escapeAntislash(path)
+        idx = path.range_query.findIdx()
+        max = path.range_query.getMax()
+        min = path.range_query.getMin()
+        strand = path.range_query.isOnDirectStrand()
+        if delayed:
+            sql_cmd = 'INSERT DELAYED INTO %s VALUES (%d,%d,"%s",%d,%d,%d)'\
+                 % (self._table_idx,\
+                   path.id,\
+                   idx,\
+                   path.range_query.seqname,\
+                   min,\
+                   max,\
+                   strand)
+        else:
+            sql_cmd = 'INSERT INTO %s VALUES (%d,%d,"%s",%d,%d,%d)'\
+                 % (self._table_idx,\
+                   path.id,\
+                   idx,\
+                   path.range_query.seqname,\
+                   min,\
+                   max,\
+                   strand)
+            
+        self._iDb.execute(sql_cmd)
+    
+    ## Return a path instances list included in a given region using the bin scheme
+    #
+    # @param contig string contig name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lOutPath a path instances list
+    #
+    def getPathListIncludedInQueryCoord(self, contig, start, end):
+        min_coord = min(start, end)
+        max_coord = max(start, end)
+        lpath = self.getChainListOverlappingQueryCoord(contig, start, end)
+        lOutPath = []
+        for i in lpath:
+            if i.range_query.getMin() > min_coord and \
+               i.range_query.getMax() < max_coord:
+                lOutPath.append(i)
+                            
+        return lOutPath
+    
+    ## Return a path instances list overlapping (and included) in a given region using the bin scheme
+    #
+    # @param contig string contig name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lOutPath a path instances list
+    #
+    def getPathListOverlappingQueryCoord(self, contig, start, end):
+        min_coord = min(start, end)
+        max_coord = max(start, end)
+        lpath = self.getChainListOverlappingQueryCoord(contig, start, end)
+        lOutPath = []
+        for i in lpath:
+            if ((i.range_query.getMin() <= min_coord and i.range_query.getMax() >= min_coord) or \
+                (i.range_query.getMin() >= min_coord and i.range_query.getMin() <= max_coord) or \
+                (i.range_query.getMin() <= min_coord and i.range_query.getMax() >= max_coord) or \
+                (i.range_query.getMin() >= min_coord and i.range_query.getMax() <= max_coord)) and \
+                (i.range_query.getSeqname() == contig):
+                    lOutPath.append(i)
+                    
+        return lOutPath
+    
+    ## Return a path instances list chain (by Id and Coord in chr) list overlapping a given region using the bin scheme
+    #
+    # @param contig string contig name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lpath a path instances list
+    #    
+    def getChainListOverlappingQueryCoord(self, contig, start, end):
+        min_coord = min(start, end)
+        max_coord = max(start, end)
+        sql_cmd = 'select distinct path from %s where contig="%s" and ('\
+                 % (self._table + "_idx", contig)
+                 
+        for bin_lvl in xrange(6, 2, -1):
+            if getIdx(start,bin_lvl) == getIdx(end, bin_lvl):
+                idx = getIdx(start, bin_lvl)
+                sql_cmd += 'idx=%d' % (idx)
+            else:
+                idx1 = getIdx(min_coord, bin_lvl)
+                idx2 = getIdx(max_coord, bin_lvl)
+                sql_cmd += 'idx between %d and %d' % (idx1, idx2)
+            if bin_lvl > 3:
+                sql_cmd += " or "
+                
+        sql_cmd += ") and min<=%d and max>=%d;" % (max_coord, min_coord)
+
+        
+        self._iDb.execute(sql_cmd)
+        res = self._iDb.fetchall()
+        lnum = []
+        for i in res:
+            lnum.append( int(i[0]) )
+        lpath = self.getPathListFromIdList(lnum)
+        return lpath
+
+    ## Delete path corresponding to a given identifier number
+    #
+    # @param num integer identifier number
+    #
+    def deleteFromId(self, num):
+        TablePathAdaptator.deleteFromId(self, num)
+        sqlCmd='delete from %s where path=%d;' % (self._table_idx, num)
+        self._iDb.execute(sqlCmd)
+    
+    ## Delete path corresponding to a given list of identifier number
+    #
+    # @param lNum list list of integer identifier number
+    #
+    def deleteFromIdList(self, lNum):
+        if lNum == []:
+            return
+        TablePathAdaptator.deleteFromIdList(self, lNum)
+        sqlCmd = 'delete from %s where path=%d' % (self._table_idx, lNum[0])
+        for i in lNum[1:]:
+            sqlCmd += " or path=%d" % (i)
+        sqlCmd += ";"
+        self._iDb.execute(sqlCmd)
+             
+    ##  Join two path by changing id number of id1 and id2 path to the least of id1 and id2
+    #
+    # @param id1 integer id path number
+    # @param id2 integer id path number
+    # @return newId integer minimum of id1 id2
+    # @note this method modify the ID even if this one not existing in the path table  
+    #     
+    def joinTwoPaths(self, id1, id2):
+        TablePathAdaptator.joinTwoPaths(self, id1, id2)
+        if id1 < id2:
+            newId = id1
+            oldId = id2
+        else:
+            newId = id2
+            oldId = id1
+        sqlCmd = 'UPDATE %s SET path=%d WHERE path=%d' % (self._table_idx, newId, oldId)
+        self._iDb.execute(sqlCmd)
+        return newId
+    
+    ## Get a new id number
+    #
+    # @return newId integer max Id in path table + 1
+    #
+    def getNewId(self):
+        sqlCmd = 'select max(path) from %s;' % (self._table_idx)
+        self._iDb.execute(sqlCmd)
+        maxId = self._iDb.fetchall()[0][0]
+        if maxId == None:
+            maxId = 0
+        newId = int(maxId) + 1
+        return newId
+    
+    ## Give a list of Set instances included in a given region
+    #
+    # @param query string query name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lSet list of Set instances
+    #
+    def getSetListIncludedInQueryCoord(self, query, start, end):
+        lPath=self.getPathListIncludedInQueryCoord(query, start, end)
+        lSet = PathUtils.getSetListFromQueries(lPath) 
+        return lSet
+    
+    ## Give a list of Set instances overlapping a given region
+    #
+    # @param query string query name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lSet list of Set instances
+    #
+    def getSetListOverlappingQueryCoord(self, query, start, end):
+        lPath = self.getPathListOverlappingQueryCoord(query, start, end)
+        lSet = PathUtils.getSetListFromQueries(lPath)
+        return lSet
+    
+    ## Give a list of identifiers contained in the table
+    #
+    # @return lId integer list
+    #
+    def getIdList(self):
+        sqlCmd = "SELECT DISTINCT path from %s;" % (self._table_idx)
+        lId = self._iDb.getIntegerListWithSQLCmd( sqlCmd )
+        return lId
+        
+    ## Give a list of the distinct query names present in the table
+    #
+    # @return lDistinctQueryNames string list
+    #
+    def getQueryList(self):
+        lDistinctQueryNames = self._getDistinctTypeNamesList("query")
+        return lDistinctQueryNames
+    
+    def _getDistinctTypeNamesList( self, type ):
+        sqlCmd = "SELECT DISTINCT contig FROM %s" % ( self._table_idx )
+        lDistinctTypeNames = self._iDb.getStringListWithSQLCmd(sqlCmd)
+        return lDistinctTypeNames
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/TableBinSetAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,265 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+from commons.core.sql.TableSetAdaptator import TableSetAdaptator
+from commons.core.coord.SetUtils import SetUtils
+
+## Adaptator for Set tables with bin indexes
+#
+class TableBinSetAdaptator(TableSetAdaptator):
+   
+    ## constructor
+    #
+    # @param iDb DbMySql instance instance of DbMySql
+    # @param tableName string table name (default = "")
+    #
+    def __init__(self, iDb, tableName = ""):
+        TableSetAdaptator.__init__(self, iDb, tableName)
+        self._table_idx = "%s_idx" % (self._table)
+        
+    ## Insert a set instance in a set bin table
+    # 
+    # @param iSet set instance an instance of set object
+    # @param delayed boolean an insert delayed or not
+    #
+    def insASetInSetAndBinTable(self, iSet, delayed = False):
+        self.insert(iSet, delayed)
+        iSet.seqname = iSet.seqname.replace("\\", "\\\\")
+        iSet.name = iSet.name.replace("\\", "\\\\")
+        bin = iSet.getBin()
+        max = iSet.getMax()
+        min = iSet.getMin()
+        strand = iSet.isOnDirectStrand()
+        sql_prefix = ''
+        if delayed:
+            sql_prefix = 'INSERT DELAYED INTO '
+        else:
+            sql_prefix = 'INSERT INTO '
+        sql_cmd = sql_prefix + '%s VALUES (%d,%f,"%s",%d,%d,%d)'\
+                 %(self._table_idx,\
+                   iSet.id,\
+                   bin,\
+                   iSet.seqname,\
+                   min,\
+                   max,\
+                   strand)
+        self._iDb.execute(sql_cmd)
+
+    ## Delete set corresponding to a given identifier number in set and bin set table
+    # @param id integer identifier number
+    # @note old name was delSet_from_num
+    #
+    def deleteFromIdFromSetAndBinTable(self, id):
+        self.deleteFromId(id)
+        sql_cmd = 'delete from %s where path=%d' % (self._table_idx, id)
+        self._iDb.execute(sql_cmd)
+
+    ## Delete path corresponding to a given list of identifier number
+    #
+    # @param lId integer list list of identifier number
+    # @note old name was delSet_from_listnum
+    #
+    def deleteFromListIdFromSetAndBinTable(self, lId):
+        if lId != []:
+            self.deleteFromIdList(lId)
+            sql_cmd = 'delete from %s where path=%d' % (self._table_idx, lId[0])
+            for i in lId[1:]:
+                sql_cmd += " or path=%d" % (i)
+            self._iDb.execute(sql_cmd)
+
+    ## Join two set by changing id number of id1 and id2 path
+    # to the least of id1 and id2
+    #
+    # @param id1 integer id path number
+    # @param id2 integer id path number
+    # @return id integer new id
+    # @note old name was joinSet
+    #
+    def joinTwoSetsFromSetAndBinTable(self, id1, id2):
+        self.joinTwoSets(id1, id2)
+        if id1 < id2:
+            new_id = id1
+            old_id = id2
+        else:
+            new_id = id2
+            old_id = id1
+        sql_cmd = 'UPDATE %s SET path=%d WHERE path=%d'\
+                % (self._table_idx, new_id, old_id)
+        self._iDb.execute(sql_cmd)
+        return new_id
+    
+    ## Get a new id number from set bin table
+    #
+    def getNewId(self):
+        sql_cmd = 'select max(path) from %s;' % (self._table_idx)
+        self._iDb.execute(sql_cmd)
+        max_id = self._iDb.fetchall()[0][0]
+        if max_id != None:
+            return int(max_id)+1
+        else:
+            return 1
+        
+    ## Get a set list instance between start and end parameters
+    # using the bin scheme
+    #
+    # @param seqName reference seq name
+    # @param start start coordinate
+    # @param end end coordinate
+    # @return lSet set list
+    # @note old name was getSetList_from_qcoord
+    #
+    def getSetListFromQueryCoord(self, seqName, start, end):
+
+        min_coord = min(start,end)
+        max_coord = max(start,end)
+
+        sql_cmd = 'select path from %s where contig="%s" and ('\
+                 % (self._table + "_idx", seqName)
+        for i in xrange(8, 2, -1):
+            bin_lvl = pow(10, i)
+            if int(start/bin_lvl) == int(end/bin_lvl):       
+                bin = float(bin_lvl + (int(start / bin_lvl) / 1e10))
+                sql_cmd += 'bin=%f' % (bin)
+            else:
+                bin1 = float(bin_lvl + (int(start / bin_lvl) / 1e10))
+                bin2 = float(bin_lvl + (int(end  /bin_lvl) / 1e10))
+                sql_cmd += 'bin between %f and %f' % (bin1, bin2)
+            if bin_lvl != 1000:
+                sql_cmd += " or "
+
+        sql_cmd += ") and min<=%d and max>=%d" % (max_coord, min_coord);
+        self._iDb.execute(sql_cmd)
+        res = self._iDb.fetchall()
+        lId = []
+        for i in res:
+            lId.append(int(i[0]))
+        lSet = self.getSetListFromIdList(lId)
+        return lSet
+
+    ## Get a set list instances strictly included between start and end parameters
+    # using the bin scheme
+    #
+    # @param seqName reference seq name
+    # @param start start coordinate
+    # @param end end coordinate
+    # @return lSet set list
+    # @note old name was getInSetList_from_qcoord
+    # @warning the implementation has been changed : I added the two first lines
+    #
+    def getSetListStrictlyIncludedInQueryCoord(self, contig, start, end):
+        min_coord = min(start,end)
+        max_coord = max(start,end)
+        lSet = self.getSetListFromQueryCoord(contig, start, end)       
+        lSetStrictlyIncluded = []
+        for iSet in lSet:
+            if iSet.getMin() > min_coord and \
+               iSet.getMax() < max_coord:
+                lSetStrictlyIncluded.append(iSet)
+                            
+        return lSetStrictlyIncluded
+    
+    ## Get a list of the identifier Id contained in the table bin
+    #
+    # @return lId list of int list of identifier
+    # @note old name was getSet_num
+    #
+    def getIdList(self):
+        sql_cmd = 'select distinct path from %s;' % (self._table_idx)
+        self._iDb.execute(sql_cmd)
+        res = self._iDb.fetchall()
+        lId = []
+        for t in res:
+            lId.append(int(t[0]))
+        return lId
+    
+    ## Get a list of the query sequence name contained in the table bin
+    #
+    # @return lSeqName list of string list of query sequence name
+    # @note old name was getContig_name
+    #
+    def getSeqNameList(self):
+        sql_cmd = 'select distinct contig from %s;' % (self._table_idx)
+        self._iDb.execute(sql_cmd)
+        res = self._iDb.fetchall()
+        lSeqName = []
+        for t in res:
+            lSeqName.append(t[0])
+        return lSeqName
+    
+    ## Insert a Set list with the same new identifier in the table bin and set
+    #
+    # @note old name was insAddSetList
+    #
+    def insertListInSetAndBinTable(self, lSets, delayed = False):
+        id = self.getNewId()
+        SetUtils.changeIdInList( lSets, id )
+        for iSet in lSets:
+            self.insASetInSetAndBinTable(iSet, delayed)
+    
+    ## Insert a set list instances In table Bin and Set and merge all overlapping sets
+    #
+    # @param lSets reference seq name
+    # @note old name was insMergeSetList
+    #    
+    def insertListInSetAndBinTableAndMergeAllSets(self, lSets):
+        min, max = SetUtils.getListBoundaries(lSets)
+        oldLSet = self.getSetListFromQueryCoord(lSets[0].seqname, min, max)
+        oldQueryhash = SetUtils.getDictOfListsWithIdAsKey(oldLSet)
+        qhash = SetUtils.getDictOfListsWithIdAsKey(lSets)
+        for lNewSetById in qhash.values():
+            found = False
+            for currentId, oldLsetById in oldQueryhash.items():
+                if SetUtils.areSetsOverlappingBetweenLists(lNewSetById, oldLsetById):
+                    oldLsetById.extend(lNewSetById)
+                    oldLsetById = SetUtils.mergeSetsInList(oldLsetById)
+                    self.deleteFromIdFromSetAndBinTable(currentId)
+                    found = True
+            if not found:
+                self.insertListInSetAndBinTable(lNewSetById)
+            else:
+                id = self.getNewId()
+                SetUtils.changeIdInList(oldLsetById, id)
+                self.insertListInSetAndBinTable(oldLsetById)
+                
+    ## Insert a set list instances In table Bin and Set after removing all overlaps between database and lSets
+    #
+    # @param lSets reference seq name
+    # @note old name was insDiffSetList
+    #    
+    def insertListInSetAndBinTableAndRemoveOverlaps(self, lSets):
+        min, max = SetUtils.getListBoundaries(lSets)
+        oldLSet = self.getSetListFromQueryCoord(lSets[0].seqname, min, max)
+        oldQueryHash = SetUtils.getDictOfListsWithIdAsKey(oldLSet)
+        newQueryHash = SetUtils.getDictOfListsWithIdAsKey(lSets)
+        for lNewSetById in newQueryHash.values():
+            for lOldSetById in oldQueryHash.values():
+                if SetUtils.areSetsOverlappingBetweenLists(lNewSetById, lOldSetById):
+                    lNewSetById = SetUtils.getListOfSetWithoutOverlappingBetweenTwoListOfSet(lOldSetById, lNewSetById)
+            self.insertListInSetAndBinTable(lNewSetById)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/TableJobAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,405 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import os
+import time
+import datetime
+import sys
+from commons.core.sql.Job import Job 
+from commons.core.sql.TableAdaptator import TableAdaptator
+
+## Methods for Job persistence 
+#
+class TableJobAdaptator(TableAdaptator):
+        
+    ## Record a job
+    #
+    # @param job Job instance with the job informations
+    #
+    def recordJob(self, job):
+        self.removeJob(job)
+        sqlCmd = "INSERT INTO %s" % self._table
+        sqlCmd += " VALUES ("
+        sqlCmd += " \"%s\"," % job.jobid
+        sqlCmd += " \"%s\"," % job.jobname
+        sqlCmd += " \"%s\"," % job.groupid
+        sqlCmd += " \"%s\"," % job.launcher
+        sqlCmd += " \"%s\"," % job.queue
+        sqlCmd += " \"%s\"," % job.lResources
+        sqlCmd += " \"waiting\","
+        sqlCmd += " \"%s\"," % time.strftime("%Y-%m-%d %H:%M:%S")
+        sqlCmd += " \"?\" );"
+        self._iDb.execute(sqlCmd)
+        
+       
+    ## Remove a job from the job table
+    #
+    #  @param job: job instance to remove
+    #
+    def removeJob(self, job):
+        qry = "DELETE FROM %s" % self._table
+        qry += " WHERE groupid='%s'" % job.groupid
+        qry += " AND jobname='%s'" % job.jobname
+        qry += " AND launcher='%s';" % job.launcher
+        self._iDb.execute(qry)
+            
+            
+    ## Set the jobid of a job with the id of SGE
+    #
+    # @param job job instance
+    # @param jobid integer
+    #
+    def updateJobIdInDB(self, job, jobid):
+        #TODO: check if only one job will be updated
+        qry = "UPDATE %s" % self._table
+        qry += " SET jobid='%i'" % int(jobid)
+        qry += " WHERE jobname='%s'" % job.jobname
+        qry += " AND groupid='%s'" % job.groupid
+        qry += " AND launcher='%s';" % job.launcher
+        self._iDb.execute(qry)
+        
+        
+    ## Get a job status
+    #
+    # @param job: a Job instance with the job informations
+    #
+    def getJobStatus(self, job):
+        if job.jobid != 0 and job.jobname == "":
+            job.jobname = job.jobid
+            job.jobid = 0
+        qry = "SELECT status FROM %s" % self._table
+        qry += " WHERE groupid='%s'" % job.groupid
+        qry += " AND jobname='%s'" % job.jobname
+        qry += " AND launcher='%s';" % job.launcher
+        self._iDb.execute(qry)
+        res = self._iDb.fetchall()
+        if len(res) > 1:
+            sys.stderr.write("ERROR while getting job status: non-unique jobs\n")
+            sys.stderr.flush()
+            sys.exit(1)
+        if res == None or len(res) == 0:
+            return "unknown"
+        return res[0][0]
+    
+    
+    ## Change a job status
+    #
+    # @param job: a Job instance with the job informations
+    # @param status: the new status (waiting,finished,error)
+    #
+    def changeJobStatus(self, job, status):
+        sqlCmd = "UPDATE %s" % self._table
+        sqlCmd += " SET status='%s'" % status
+        sqlCmd += ", node='%s'" % job.node
+        sqlCmd += " WHERE groupid='%s'" % job.groupid
+        sqlCmd += " AND jobname='%s'" % job.jobname
+        sqlCmd += " AND launcher='%s';" % job.launcher
+        self._iDb.execute(sqlCmd)
+        
+        
+    ## Get the number of jobs belonging to the desired groupid with the desired status.
+    #
+    # @param groupid string a group identifier to record related job series 
+    # @param status string job status (waiting, running, finished, error)
+    # @return int
+    #
+    def getCountStatus(self, groupid, status):
+        qry = "SELECT count(jobname) FROM %s" % self._table
+        qry += " WHERE groupid='%s'" % groupid
+        qry += " AND status='%s';" % status
+        self._iDb.execute(qry)
+        res = self._iDb.fetchall()
+        return int(res[0][0])
+        
+        
+    ## Clean all job from a job group
+    #
+    # @param groupid: a group identifier to record related job series
+    #
+    def cleanJobGroup(self, groupid):
+        qry = "DELETE FROM %s WHERE groupid='%s';" % (self._table, groupid)
+        self._iDb.execute(qry)
+            
+            
+    ## Check if there is unfinished job from a job group.
+    #
+    # @param groupid string a group identifier to record related job series 
+    #        
+    def hasUnfinishedJob(self, groupid):
+        qry = "SELECT * FROM %s" % self._table
+        qry += " WHERE groupid='%s'" % groupid
+        qry += " and status!='finished';" 
+        self._iDb.execute(qry)
+        res = self._iDb.fetchall()
+        if len(res) == 0:
+            return False
+        return True
+    
+
+    ## Wait job finished status from a job group.
+    #  Job are re-launched if error (max. 3 times)
+    #
+    # @param groupid string a group identifier to record related job series
+    # @param checkInterval integer time laps in seconds between two checks (default = 5)
+    # @param maxRelaunch integer max nb of times a job in error is relaunch before exiting (default = 3)
+    # @param exitIfTooManyErrors boolean exit if a job is still in error above maxRelaunch (default = True)
+    # @param timeOutPerJob integer max nb of seconds after which one tests if a job is still in SGE or not (default = 60*60=1h)
+    #
+    def waitJobGroup(self, groupid, checkInterval=5, maxRelaunch=3, exitIfTooManyErrors=True, timeOutPerJob=60*60):
+        dJob2Err = {}
+        
+        # retrieve the total number of jobs belonging to the desired groupid
+        qry = "SELECT count(jobname) FROM %s WHERE groupid='%s';" % (self._table, groupid)
+        self._iDb.execute(qry)
+        totalNbJobs = int(self._iDb.fetchall()[0][0])
+        
+        nbTimeOuts = 0
+        
+        while True:
+            time.sleep(checkInterval)
+            # retrieve the finished jobs and stop if all jobs are finished
+            nbFinishedJobs = self.getCountStatus(groupid, "finished")
+            if nbFinishedJobs == totalNbJobs:
+                break
+
+            # retrieve the jobs in error and relaunch them if they are in error (max. 'maxRelaunch' times)
+            qry = "SELECT * FROM %s" % self._table
+            qry += " WHERE groupid='%s'" % groupid
+            qry += " AND status ='error';"
+            self._iDb.execute(qry)
+            lJobsInError = self._iDb.fetchall()
+            for job in lJobsInError:
+                jobName = job[1]
+                if not dJob2Err.has_key(jobName):
+                    dJob2Err[jobName] = 1
+                if dJob2Err[jobName] < maxRelaunch:
+                    print "job '%s' in error, re-submitting (%i)" % (job[1], dJob2Err[job[1]])
+                    sys.stdout.flush()
+                    lResources = job[5].replace("[", "").replace("]", "").replace("'", "").split(", ")
+                    newJob = Job(jobname=jobName, groupid=job[2], launcherFile=job[3], queue=job[4], lResources=lResources)
+                    self.submitJob(newJob)
+                    dJob2Err[jobName] += 1
+                else:
+                    dJob2Err[jobName] += 1
+                    cmd = "job '%s' in permanent error (>%i)" % (jobName, maxRelaunch)
+                    cmd += "\ngroupid = %s" % groupid
+                    cmd += "\nnb of jobs = %i" % totalNbJobs
+                    cmd += "\nnb of finished jobs = %i" % self.getCountStatus(groupid, "finished")
+                    cmd += "\nnb of waiting jobs = %i" % self.getCountStatus(groupid, "waiting")
+                    cmd += "\nnb of running jobs = %i" % self.getCountStatus(groupid, "running")
+                    cmd += "\nnb of jobs in error = %i" % self.getCountStatus(groupid, "error")
+                    sys.stdout.flush()
+                    if exitIfTooManyErrors:
+                        self.cleanJobGroup(groupid)
+                        sys.exit(1)
+                    else:
+                        checkInterval = 60
+            nbTimeOuts = self._checkIfJobsTableAndJobsManagerInfoAreConsistent(nbTimeOuts, timeOutPerJob, groupid)
+    
+    
+    ## Submit a job to a queue and record it in job table.
+    #
+    # @param job a job instance
+    # @param maxNbWaitingJobs integer max nb of waiting jobs before submitting a new one (default = 10000)
+    # @param checkInterval integer time laps in seconds between two checks (default = 30)
+    # @param verbose integer (default = 0)
+    #               
+    def submitJob(self, job, verbose=0, maxNbWaitingJobs=10000, checkInterval=30):
+        if self.getJobStatus(job) in ["waiting", "running", "finished"]:
+            sys.stderr.write( "WARNING: job '%s' was already submitted\n" % job.jobname)
+            sys.stderr.flush()
+            self.cleanJobGroup(job.groupid)
+            sys.exit(1)
+            
+        while self.getCountStatus(job.groupid, "waiting") > maxNbWaitingJobs:
+            time.sleep(checkInterval)
+
+        self.recordJob(job)
+        cmd = self._getQsubCommand(job)
+        returnStatus = os.system(cmd)
+
+        if returnStatus == 0:
+            fileName = "jobid.stdout"
+            jobidFileHandler = open(fileName, "r")
+            jobid = self._getJobidFromJobManager(jobidFileHandler)
+            if verbose > 0:
+                print "job '%i %s' submitted" % (jobid, job.jobname)
+                sys.stdout.flush()
+            job.jobid = jobid
+            jobidFileHandler.close()
+            self.updateJobIdInDB(job, jobid)
+            os.remove(fileName)
+        return returnStatus
+
+
+    ## Get the list of nodes where jobs of one group were executed
+    #
+    # @param groupid string a group identifier of job series 
+    # @return lNodes list of nodes names without redundancy
+    #
+    def getNodesListByGroupId(self, groupId):
+        qry = "SELECT DISTINCT node FROM %s" % self._table
+        qry += " WHERE groupid='%s'" % groupId
+        self._iDb.execute(qry)
+        res = self._iDb.fetchall()
+        lNodes = []
+        for resTuple in res:
+            lNodes.append(resTuple[0])
+        return lNodes
+    
+    def checkJobTable(self):
+        if not self._iDb.doesTableExist(self._table):
+            self._iDb.createTable(self._table, "jobs")
+        else:
+            lExpFields = sorted(["jobid", "jobname", "groupid", "launcher", "queue", "resources", "status", "time", "node"])
+            lObsFields = sorted(self._iDb.getFieldList(self._table))
+            if lExpFields != lObsFields:
+                self._iDb.createTable(self._table, "jobs", overwrite = True)
+    
+    def close(self):
+        self._iDb.close() 
+    
+    def _getJobidAndNbJob(self, jobid) :
+        tab = jobid.split(".")
+        jobid = tab[0]
+        tab = tab[1].split(":")
+        nbJob = tab[0]
+        return jobid, nbJob
+    
+class TableJobAdaptatorSGE(TableJobAdaptator):
+        
+    def _checkIfJobsTableAndJobsManagerInfoAreConsistent(self, nbTimeOuts, timeOutPerJob, groupid):
+        # retrieve the date and time at which the oldest, still-running job was submitted
+        sql = "SELECT jobid,jobname,time FROM %s WHERE groupid='%s' AND status='running' ORDER BY time DESC LIMIT 1" % (self._table, groupid)
+        self._iDb.execute( sql )
+        res = self._iDb.fetchall()
+        if len(res) > 0:
+            jobid = res[0][0]
+            jobname = res[0][1]
+            dateTimeOldestJob = res[0][2]
+            dateTimeCurrent = datetime.datetime.now()
+            # delta is time between (i) first job launched of the given groupid and still in running state and (ii) current time 
+            delta = dateTimeCurrent - dateTimeOldestJob
+            # check if delta is in an interval:  0 <= delta < 1h | 1h <= delta < 2h | 2h <= delta < 3h (timeOutPerJob = 1h)  
+            if delta.seconds >= nbTimeOuts * timeOutPerJob and delta.seconds < (nbTimeOuts+1) * timeOutPerJob:
+                return nbTimeOuts
+            # delta outside the interval: go to next interval (time out) 
+            if delta.seconds >= (nbTimeOuts+1) * timeOutPerJob:
+                nbTimeOuts += 1
+                # Job with 'running' status should be in qstat. Because status in DB is set at 'running' by the job launched.
+                if not self.isJobStillHandledBySge(jobid, jobname):
+                    # But if not, let time for the status update (in DB), if the job finished between the query execution and now.
+                    time.sleep( 5 )
+                # If no update at 'finished', exit
+                #TODO: check status in DB
+                if not self.isJobStillHandledBySge(jobid, jobname):
+                    msg = "ERROR: job '%s', supposedly still running, is not handled by SGE anymore" % ( jobid )
+                    msg += "\nit was launched the %s (> %.2f hours ago)" % ( dateTimeOldestJob, timeOutPerJob/3600.0 )
+                    msg += "\nthis problem can be due to:"
+                    msg += "\n* memory shortage, in that case, decrease the size of your jobs;"
+                    msg += "\n* timeout, in that case, decrease the size of your jobs;"
+                    msg += "\n* node failure or database error, in that case, launch the program again or ask your system administrator."
+                    sys.stderr.write("%s\n" % msg)
+                    sys.stderr.flush()
+                    self.cleanJobGroup(groupid)
+                    sys.exit(1)
+        return nbTimeOuts
+                        
+    ## Check if a job is still handled by SGE
+    #
+    # @param jobid string job identifier
+    # @param jobname string job name
+    #  
+    def isJobStillHandledBySge(self, jobid, jobname):
+        isJobInQstat = False
+        qstatFile = "qstat_stdout"
+        cmd = "qstat > %s" % qstatFile
+        returnStatus = os.system(cmd)
+        if returnStatus != 0:
+            msg = "ERROR while launching 'qstat'"
+            sys.stderr.write( "%s\n" % msg )
+            sys.exit(1)
+        qstatFileHandler = open(qstatFile, "r")
+        lLines = qstatFileHandler.readlines()
+        for line in lLines:
+            tokens = line.split()
+            if len(tokens) > 3 and tokens[0] == str(jobid) and tokens[2] == jobname[0:len(tokens[2])]:
+                isJobInQstat = True
+                break
+        qstatFileHandler.close()
+        os.remove(qstatFile)
+        return isJobInQstat
+    
+    def _getQsubCommand(self, job):    
+        cmd = "echo '%s' | " % job.launcher
+        prg = "qsub"
+        cmd += prg
+        cmd += " -V"
+        cmd += " -N %s" % job.jobname
+        if job.queue != "":
+            cmd += " -q %s" % job.queue
+        cmd += " -cwd"
+        if job.lResources != []:
+            cmd += " -l \""
+            cmd += " ".join(job.lResources)
+            cmd += "\""
+        if job.parallelEnvironment != "":
+            cmd += " -pe " + job.parallelEnvironment
+        cmd += " > jobid.stdout"
+        return cmd
+    
+    def _getJobidFromJobManager(self, jobidFileHandler):
+        return int(jobidFileHandler.readline().split(" ")[2])
+    
+
+class TableJobAdaptatorTorque(TableJobAdaptator):  
+                        
+    def _checkIfJobsTableAndJobsManagerInfoAreConsistent(self, nbTimeOuts, timeOutPerJob, groupid):
+        return nbTimeOuts
+        
+    def _getQsubCommand(self, job):    
+        cmd = "echo '%s' | " % job.launcher
+        prg = "qsub"
+        cmd += prg
+        cmd += " -V"
+        cmd += " -d %s" % os.getcwd()
+        cmd += " -N %s" % job.jobname
+        if job.queue != "":
+            cmd += " -q %s" % job.queue
+        if job.lResources != []:
+            cmd += " -l \""
+            cmd += " ".join(job.lResources).replace("mem_free","mem")
+            cmd += "\""
+        cmd += " > jobid.stdout"
+        return cmd
+
+    def _getJobidFromJobManager(self, jobidFileHandler):
+        return int(jobidFileHandler.readline().split(".")[0])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/TableJobAdaptatorFactory.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,66 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+import os
+import sys
+from commons.core.sql.TableJobAdaptator import TableJobAdaptatorSGE
+from commons.core.sql.TableJobAdaptator import TableJobAdaptatorTorque
+from commons.core.sql.JobAdaptator import JobAdaptatorSGE
+from commons.core.sql.JobAdaptator import JobAdaptatorTorque
+
+class TableJobAdaptatorFactory(object):
+
+    def createInstance(iDb, jobTableName):
+        if os.environ["REPET_JOB_MANAGER"].lower() == "sge":
+            iTJA = TableJobAdaptatorSGE(iDb, jobTableName)
+        elif os.environ["REPET_JOB_MANAGER"].lower() == "torque":
+            iTJA = TableJobAdaptatorTorque(iDb, jobTableName)
+        else:
+            print "ERROR: unknown jobs manager : $REPET_JOB_MANAGER = %s." % os.environ["REPET_JOB_MANAGER"]
+            sys.exit(1)
+            
+        return iTJA
+
+    createInstance = staticmethod(createInstance)
+       
+    def createJobInstance():
+        if os.environ["REPET_JOB_MANAGER"].lower() == "sge":
+            iJA = JobAdaptatorSGE()
+        elif os.environ["REPET_JOB_MANAGER"].lower() == "torque":
+            iJA = JobAdaptatorTorque()
+        else:
+            print "ERROR: unknown jobs manager : $REPET_JOB_MANAGER = %s." % os.environ["REPET_JOB_MANAGER"]
+            sys.exit(1)
+            
+        return iJA   
+    
+
+    createJobInstance = staticmethod(createJobInstance)
+    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/TableMapAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,193 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import sys
+from commons.core.sql.TableAdaptator import TableAdaptator
+from commons.core.sql.ITableMapAdaptator import ITableMapAdaptator
+from commons.core.coord.Map import Map
+from commons.core.coord.MapUtils import MapUtils
+
+
+## Adaptator for Map table
+#
+class TableMapAdaptator( TableAdaptator, ITableMapAdaptator ):
+            
+    ## Give a list of Map instances having a given seq name
+    #
+    # @param seqName string seq name
+    # @return lMap list of instances
+    #
+    def getListFromSeqName( self, seqName ):
+        sqlCmd = "SELECT * FROM %s" % (self._table)
+        colum2Get, type2Get, attr2Get = self._getTypeColumAttr2Get(seqName)
+        sqlCmd += " WHERE " + colum2Get
+        sqlCmd += " = "
+        sqlCmd = sqlCmd + type2Get
+        sqlCmd = sqlCmd % "'" + attr2Get + "'"
+        return self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        
+    ## Give a list of Map instances overlapping a given region
+    #
+    # @param query string query name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return list map instances
+    #
+    def getListOverlappingCoord(self, query, start, end):
+        sqlCmd = 'select * from %s where chr="%s" and ((start between least(%d,%d) and greatest(%d,%d) or end between least(%d,%d) and greatest(%d,%d)) or (least(start,end)<=least(%d,%d) and greatest(start,end)>=greatest(%d,%d)))  ;' % (self._table, query, start, end, start, end, start, end, start, end, start, end, start, end)
+        return self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+    
+    ## Give a list of Map instances having a given sequence name
+    #
+    # @param seqName string sequence name
+    # @return lMap list of instances
+    #
+    def getMapListFromSeqName(self, seqName):
+        lMap = self.getListFromSeqName( seqName )
+        return lMap
+    
+#TODO: Check getListFromSeqName method: uses name instead of seqname
+#    ## Give a list of Map instances having a given sequence name from list
+#    #
+#    # @param lSeqName string sequence name list
+#    # @return lMap list of instances
+#    #
+#    def getMapListFromSeqNameList(self, lSeqName):
+#        lMap = []
+#        [lMap.extend(self.getListFromSeqName(seqName)) for seqName in lSeqName]
+#        return lMap
+    
+    ## Give a list of Map instances having a given chromosome
+    #
+    # @param chr string chromosome
+    # @return lMap list of instances
+    #
+    def getMapListFromChr(self, chr):
+        sqlCmd = "SELECT * FROM %s WHERE chr='%s'" % (self._table, chr)
+        lMap = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lMap
+
+    ## Give a list of the distinct seqName/chr present in the table
+    #
+    # @return lDistinctContigNames string list
+    #
+    def getSeqNameList(self):
+        sqlCmd = "SELECT DISTINCT chr FROM %s" % ( self._table )
+        lDistinctContigNames = self._iDb.getStringListWithSQLCmd(sqlCmd)
+        return lDistinctContigNames
+    
+    ## Return a list of Set instances from a given sequence name
+    #
+    # @param seqName string sequence name
+    # @return lSets list of Set instances
+    # 
+    def getSetListFromSeqName( self, seqName ):
+        lMaps = self.getListFromSeqName( seqName )
+        lSets = MapUtils.mapList2SetList( lMaps )
+        return lSets
+    
+    ## Give a map instances list overlapping a given region
+    #
+    # @param seqName string seq name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lMap list of map instances
+    #
+    def getMapListOverlappingCoord(self, seqName, start, end):
+        lMap = self.getListOverlappingCoord(seqName, start, end)
+        return lMap
+    
+    ## Return a list of Set instances overlapping a given sequence
+    #   
+    # @param seqName string sequence name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lSet list of Set instances
+    #
+    def getSetListOverlappingCoord( self, seqName, start, end ):
+        lMaps = self.getListOverlappingCoord( seqName, start, end )
+        lSets = MapUtils.mapList2SetList( lMaps )
+        return lSets
+    
+    ## Give a dictionary which keys are Map names and values the corresponding Map instances
+    #
+    # @return dName2Maps dict which keys are Map names and values the corresponding Map instances
+    #
+    def getDictPerName( self ):
+        dName2Maps = {}
+        lMaps = self.getListOfAllMaps()
+        for iMap in lMaps:
+            if dName2Maps.has_key( iMap.name ):
+                if iMap == dName2Maps[ iMap.name ]:
+                    continue
+                else:
+                    msg = "ERROR: in table '%s' two different Map instances have the same name '%s'" % ( self._table, iMap.name )
+                    sys.stderr.write( "%s\n" % ( msg ) )
+                    sys.exit(1)
+            dName2Maps[ iMap.name ] = iMap
+        return dName2Maps
+    
+    ## Return a list of Map instances with all the data contained in the table
+    #
+    # @return lMaps list of Map instances
+    #
+    def getListOfAllMaps( self ):
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        lMaps = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lMaps
+    
+    ## Give the end of map as integer
+    #
+    # @return end integer the end of map 
+    #
+    def getEndFromSeqName(self, seqName):
+        sqlCmd = "SELECT end FROM %s WHERE chr = '%s'" % (self._table, seqName)
+        end = self._iDb.getIntegerWithSQLCmd(sqlCmd)
+        return end
+    
+    def _getInstanceToAdapt(self):
+        iMap = Map()
+        return iMap
+
+    def _getTypeColumAttr2Get(self, name):
+        colum2Get = 'name'
+        type2Get = '%s'
+        attr2Get = name
+        return colum2Get, type2Get, attr2Get
+    
+    def _getTypeAndAttr2Insert(self, map):
+        type2Insert = ("'%s'","'%s'","'%d'","'%d'")
+        attr2Insert = (map.name, map.seqname, map.start, map.end)
+        return type2Insert, attr2Insert
+
+    def _escapeAntislash(self, obj):
+        obj.name = obj.name.replace("\\", "\\\\")
+        obj.seqname = obj.seqname.replace("\\", "\\\\")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/TableMatchAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,100 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.sql.TableAdaptator import TableAdaptator
+from commons.core.sql.ITableMatchAdaptator import ITableMatchAdaptator
+from commons.core.coord.Match import Match
+
+## Adaptator for Match table
+#
+class TableMatchAdaptator( TableAdaptator, ITableMatchAdaptator ):
+        
+    ## Give a list of Match instances given a query name
+    #
+    # @param query string sequence name
+    # @return lMatches list of Match instances
+    #
+    def getMatchListFromQuery( self, query ):
+        sqlCmd = "SELECT * FROM %s WHERE query_name='%s';" % ( self._table, query )
+        return self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+    
+    ## Give a list of Match instances having the same identifier
+    #
+    # @param id integer identifier number
+    # @return lMatch a list of Match instances
+    #
+    def getMatchListFromId( self, id ):
+        sqlCmd = "SELECT * FROM %s WHERE path='%d';" % ( self._table, id )
+        lMatch = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lMatch
+    
+    ## Give a list of Match instances according to the given list of identifier numbers
+    #
+    # @param lId integer list 
+    # @return lMatch a list of Match instances
+    # 
+    def getMatchListFromIdList( self, lId ):
+        lMatch=[]
+        if lId == []:
+            return lMatch
+        sqlCmd = "select * from %s where path=%d" % (self._table, lId[0])
+        for i in lId[1:]:
+            sqlCmd += " or path=%d" % (i)
+        sqlCmd += ";"
+        lMatch = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lMatch
+    
+    ## Give the data contained in the table as a list of Match instances
+    #
+    # @return lMatchs list of match instances
+    #
+    def getListOfAllMatches( self ):
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        lMatches = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lMatches    
+    
+    def _getInstanceToAdapt(self):
+        iMatch = Match()
+        return iMatch
+    
+    def _getTypeAndAttr2Insert(self, match):
+        type2Insert = ("'%s'","'%d'","'%d'","'%d'","'%f'","'%f'","'%s'","'%d'","'%d'","'%d'","'%f'","'%g'","'%d'","'%f'","'%d'")
+        attr2Insert = ( match.range_query.seqname, match.range_query.start, \
+                        match.range_query.end, match.query_length, match.query_length_perc, \
+                        match.match_length_perc, match.range_subject.seqname, match.range_subject.start,\
+                        match.range_subject.end, match.subject_length, match.subject_length_perc, \
+                        match.e_value, match.score, match.identity, \
+                        match.id)
+        return type2Insert, attr2Insert
+    
+    def _escapeAntislash(self, obj):
+        obj.range_query.seqname = obj.range_query.seqname.replace("\\", "\\\\")
+        obj.range_subject.seqname = obj.range_subject.seqname.replace("\\", "\\\\")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/TablePathAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,673 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.coord.Path import Path
+from commons.core.coord.PathUtils import PathUtils
+from commons.core.sql.TableAdaptator import TableAdaptator
+from commons.core.sql.ITablePathAdaptator import ITablePathAdaptator
+
+
+## Adaptator for a Path table
+#
+class TablePathAdaptator( TableAdaptator, ITablePathAdaptator ):
+
+    ## Give a list of Path instances having the same identifier
+    #
+    # @param id integer identifier number
+    # @return lPath a list of Path instances
+    #
+    def getPathListFromId( self, id ):
+        sqlCmd = "SELECT * FROM %s WHERE path='%d';" % ( self._table, id )
+        lPath = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lPath
+    
+    ## Give a list of Path instances according to the given list of identifier numbers
+    #
+    # @param lId integer list 
+    # @return lPath a list of Path instances
+    #
+    def getPathListFromIdList( self, lId ):
+        lPath=[]
+        if lId == []:
+            return lPath
+        sqlCmd = "select * from %s where path=%d" % (self._table, lId[0])
+        for i in lId[1:]:
+            sqlCmd += " or path=%d" % (i)
+        sqlCmd += ";"
+        lPath = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lPath
+    
+    ## Give a list of Path instances having the same given query name
+    #
+    # @param query string name of the query 
+    # @return lPath a list of Path instances
+    #
+    def getPathListFromQuery( self, query ):
+        lPath = self._getPathListFromTypeName("query", query)
+        return lPath
+    
+    ## Give a list of Path instances having the same given subject name
+    #
+    # @param subject string name of the subject 
+    # @return lPath a list of Path instances
+    #
+    def getPathListFromSubject( self, subject ):
+        lPath = self._getPathListFromTypeName("subject", subject)
+        return lPath
+    
+    ## Give a list of the distinct subject names present in the table
+    #
+    # @return lDistinctSubjectNames string list
+    #
+    def getSubjectList(self):
+        lDistinctSubjectNames = self._getDistinctTypeNamesList("subject")
+        return lDistinctSubjectNames
+    
+    ## Give a list of the distinct query names present in the table
+    #
+    # @return lDistinctQueryNames string list
+    #
+    def getQueryList(self):
+        lDistinctQueryNames = self._getDistinctTypeNamesList("query")
+        return lDistinctQueryNames
+    
+    ## Give a list of the distinct query names present in the table
+    # @note method to have correspondence with getSeqNameList() in TableSetAdaptator (for srptAutoPromote.py)
+    #
+    # @return lDistinctContigNames string list
+    #
+    def getSeqNameList(self):
+        return self.getQueryList()
+    
+    ## Give a list with all the distinct identifiers corresponding to the query
+    #
+    # @param query string name of the subject 
+    # @return lId a list of integer
+    #
+    def getIdListFromQuery( self, query ):
+        lId = self._getIdListFromTypeName("query", query)
+        return lId
+    
+    ## Give a list with all the distinct identifiers corresponding to the subject
+    #
+    # @param subject string name of the subject 
+    # @return lId a list of integer
+    #
+    def getIdListFromSubject( self, subject ):
+        lId = self._getIdListFromTypeName("subject", subject)
+        return lId
+    
+    ## Give a list of identifiers contained in the table
+    #
+    # @return lId integer list
+    #
+    def getIdList(self):
+        sqlCmd = "SELECT DISTINCT path from %s;" % (self._table)
+        lId = self._iDb.getIntegerListWithSQLCmd( sqlCmd )
+        return lId
+        
+    ## Give a list of the distinct subject names present in the table given a query name
+    #
+    # @param queryName string 
+    # @return lDistinctSubjectNamesPerQuery string list
+    #
+    def getSubjectListFromQuery( self, queryName ):
+        sqlCmd = "SELECT DISTINCT subject_name FROM %s WHERE query_name='%s'" % ( self._table, queryName )
+        lDistinctSubjectNamesPerQuery = self._iDb.getStringListWithSQLCmd(sqlCmd)
+        return lDistinctSubjectNamesPerQuery
+    
+    ## Give the data contained in the table as a list of Paths instances
+    #
+    # @return lPaths list of paths instances
+    #
+    def getListOfAllPaths( self ):
+        return self.getListOfAllCoordObject()
+    
+    ## Give a list of Path instances with the given query and subject, both on direct strand
+    #
+    # @param query string query name
+    # @param subject string subject name
+    # @return lPaths list of path instances
+    #
+    def getPathListWithDirectQueryDirectSubjectFromQuerySubject( self, query, subject ):
+        sqlCmd = "SELECT * FROM %s WHERE query_name='%s' AND subject_name='%s' AND query_start<query_end AND subject_start<subject_end ORDER BY query_name, subject_name, query_start;" % ( self._table, query, subject )
+        lPaths = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lPaths
+    
+    ## Give a list of Path instances with the given query on direct strand and the given subject on reverse strand
+    #
+    # @param query string query name
+    # @param subject string subject name
+    # @return lPaths list of path instances
+    #
+    def getPathListWithDirectQueryReverseSubjectFromQuerySubject( self, query, subject ):
+        sqlCmd = "SELECT * FROM %s WHERE query_name='%s' AND subject_name='%s' AND query_start<query_end AND subject_start>subject_end ORDER BY query_name, subject_name, query_start;" % ( self._table, query, subject )
+        lPaths = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lPaths
+
+    ## Give the number of Path instances with the given query name
+    #
+    # @param query string query name
+    # @return pathNb integer the number of Path instances
+    #
+    def getNbPathsFromQuery( self, query ):
+        pathNb = self._getPathsNbFromTypeName("query", query)
+        return pathNb
+    
+    ## Give the number of Path instances with the given subject name
+    #
+    # @param subject string subject name
+    # @return pathNb integer the number of Path instances
+    #
+    def getNbPathsFromSubject( self, subject ):
+        pathNb = self._getPathsNbFromTypeName("subject", subject)
+        return pathNb
+    
+    ## Give the number of distinct path identifiers
+    #
+    # @return idNb integer the number of Path instances
+    #
+    def getNbIds( self ):
+        sqlCmd = "SELECT COUNT( DISTINCT path ) FROM %s" % ( self._table )
+        idNb = self._iDb.getIntegerWithSQLCmd( sqlCmd )
+        return idNb
+    
+    ## Give the number of distinct path identifiers for a given subject
+    #
+    # @param subjectName string subject name
+    # @return idNb integer the number of Path instances
+    #
+    def getNbIdsFromSubject( self, subjectName ):
+        idNb = self._getIdNbFromTypeName("subject", subjectName)
+        return idNb
+    
+    ## Give the number of distinct path identifiers for a given query
+    #
+    # @param queryName string query name
+    # @return idNb integer the number of Path instances
+    #
+    def getNbIdsFromQuery( self, queryName ):
+        idNb = self._getIdNbFromTypeName("query", queryName)
+        return idNb
+    
+    ## Give a list of Path instances included in a given query region
+    #
+    # @param query string query name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lPaths list of Path instances
+    #
+    def getPathListIncludedInQueryCoord( self, query, start, end ):
+        if( start > end ):
+            tmp = start
+            start = end
+            end = tmp
+        sqlCmd = "SELECT * FROM %s WHERE query_name='%s' AND query_start>=%i AND query_end<=%i" % ( self._table, query, start, end )
+        lPaths = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lPaths
+    
+    ## Give a list of Path instances overlapping a given region
+    #
+    # @param query string query name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lPath list of Path instances
+    #
+    def getPathListOverlappingQueryCoord( self, query, start, end ):
+        if( start > end ):
+            tmp = start
+            start = end
+            end = tmp
+        sqlCmd = "SELECT * FROM %s WHERE query_name='%s'" % ( self._table, query )
+        sqlCmd += " AND ( ( query_start < %i AND query_end >= %i AND query_end <= %i )" % ( start, start, end )
+        sqlCmd += " OR ( query_start >= %i AND query_end <= %i )" % ( start, end )
+        sqlCmd += " OR ( query_start >= %i AND query_start <= %i AND query_end > %i )" % ( start, end, end )
+        sqlCmd += " OR ( query_start < %i AND query_end > %i ) )" % ( start, end )
+        lPaths = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lPaths
+    
+    ## Give a list of Path instances overlapping a given region
+    #
+    # @note whole chains are returned, even if only a fragment overlap with the given region
+    # @param query string query name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lPath list of Path instances
+    #
+    def getChainListOverlappingQueryCoord( self, query, start, end ):
+        if( start > end ):
+            tmp = start
+            start = end
+            end = tmp
+        sqlCmd = "SELECT DISTINCT path FROM %s WHERE query_name='%s'" % ( self._table, query )
+        sqlCmd += " AND ( ( query_start <= %i AND query_end >= %i AND query_end <= %i )" % ( start, start, end )
+        sqlCmd += " OR ( query_start >= %i AND query_end <= %i )" % ( start, end )
+        sqlCmd += " OR ( query_start >= %i AND query_start <= %i AND query_end >= %i )" % ( start, end, end )
+        sqlCmd += " OR ( query_start <= %i AND query_end >= %i ) )" % ( start, end )
+        lIdentifiers = self._iDb.getIntegerListWithSQLCmd( sqlCmd )
+        lPaths = self.getPathListFromIdList( lIdentifiers )
+        return lPaths
+    
+    ## Give a list of Set instances overlapping a given region
+    #
+    # @param query string query name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lSet list of Set instances
+    #
+    def getSetListOverlappingQueryCoord(self, query, start, end):
+        lPath = self.getPathListOverlappingQueryCoord(query, start, end)
+        lSet = PathUtils.getSetListFromQueries(lPath)
+        return lSet
+    
+    ## Give a list of Set instances included in a given region
+    #
+    # @param query string query name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lSet list of Set instances
+    #
+    def getSetListIncludedInQueryCoord(self, query, start, end):
+        lPath=self.getPathListIncludedInQueryCoord(query, start, end)
+        lSet = PathUtils.getSetListFromQueries(lPath) 
+        return lSet
+    
+    ## Give a a list of Path instances sorted by query coordinates
+    #
+    # @return lPaths list of Path instances
+    #
+    def getPathListSortedByQueryCoord( self ):
+        sqlCmd = "SELECT * FROM %s ORDER BY query_name, LEAST(query_start,query_end)" % ( self._table )
+        lPaths = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lPaths
+    
+    ## Give a a list of Path instances sorted by query coordinates for a given query
+    #
+    # @return lPaths list of Path instances
+    #
+    def getPathListSortedByQueryCoordFromQuery( self, queryName ):
+        sqlCmd = "SELECT * FROM %s WHERE query_name='%s' ORDER BY LEAST(query_start,query_end)" % ( self._table, queryName )
+        lPaths = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lPaths
+    
+    ## Give a a list of Path instances sorted by query coordinates and score for a given query
+    #
+    # @return lPaths list of Path instances
+    #
+    def getPathListSortedByQueryCoordAndScoreFromQuery(self, queryName):
+        sqlCmd = "SELECT * FROM %s WHERE query_name='%s' ORDER BY query_start, query_end, score" % (self._table, queryName)
+        lPaths = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lPaths
+    
+    ## Give a cumulative length of all paths (fragments) for a given subject name
+    #
+    # @param subjectName string subject name
+    # @return nb Cumulative length for all path
+    #
+    # @warning doesn't take into account the overlaps !!
+    #
+    def getCumulLengthFromSubject( self, subjectName ):
+        sqlCmd = "SELECT SUM(ABS(query_end-query_start)+1) FROM %s WHERE subject_name='%s'" % ( self._table, subjectName )
+        nb = self._iDb.getIntegerWithSQLCmd(sqlCmd)
+        return nb
+    
+    ## Give a list of the length of all chains of paths for a given subject name
+    #
+    # @param subjectName string  name of the subject
+    # @return lChainLengths list of lengths per chain of paths
+    #
+    # @warning doesn't take into account the overlaps !!
+    #
+    def getChainLengthListFromSubject( self, subjectName ):
+        sqlCmd = "SELECT SUM(ABS(query_end-query_start)+1) FROM %s WHERE subject_name='%s' GROUP BY PATH" % ( self._table, subjectName )
+        lChainLengths = self._iDb.getIntegerListWithSQLCmd(sqlCmd)
+        return lChainLengths
+    
+    ## Give a list of identity of all chains of paths for a given subject name
+    #
+    # @param subjectName string name of the subject
+    # @return lChainIdentities list of identities per chain of paths
+    #
+    # @warning doesn't take into account the overlaps !!
+    #
+    def getChainIdentityListFromSubject( self, subjectName ):
+        lChainIdentities = []
+        sqlCmd = "SELECT SUM(identity*(ABS(query_start-query_end)+1)) / SUM(ABS(query_end-query_start)+1) FROM %s WHERE subject_name='%s' GROUP BY PATH" % ( self._table, subjectName )
+        self._iDb.execute( sqlCmd )
+        res = self._iDb.fetchall()
+        for i in res:
+            if i[0] != None:
+                lChainIdentities.append( round( float( i[0] ), 2 ) )
+        return lChainIdentities
+    
+    ## Give a list of the length of all paths for a given subject name
+    #
+    # @param subjectName string name of the subject
+    # @return lPathLengths list of lengths per path
+    #
+    # @warning doesn't take into account the overlaps !!
+    #
+    def getPathLengthListFromSubject( self, subjectName ):
+        sqlCmd = "SELECT ABS(query_end-query_start)+1 FROM %s WHERE subject_name='%s'" % ( self._table, subjectName )
+        lPathLengths = self._iDb.getIntegerListWithSQLCmd(sqlCmd)
+        return lPathLengths
+
+    ## Give a a list with all distinct identifiers for a given subject sorted in decreasing order according to the length of the chains
+    #    
+    # @param subjectName string subject name
+    # @return lPathNums a list of paths Id
+    #
+    def getIdListSortedByDecreasingChainLengthFromSubject( self, subjectName ):
+        sqlCmd = "SELECT DISTINCT path, SUM( ABS(query_end - query_start) + 1 ) AS length"
+        sqlCmd += " FROM %s" % ( self._table )
+        sqlCmd += " WHERE subject_name='%s'" % ( subjectName )
+        sqlCmd += " GROUP BY path"
+        sqlCmd += " ORDER BY length DESC";
+        lPathNums = self._iDb.getIntegerListWithSQLCmd(sqlCmd)
+        return lPathNums
+
+    ## Give a a list with all distinct identifiers for a given subject where the chain lengths is above a given threshold
+    #    
+    # @param subjectName string subject name
+    # @lengthThreshold length threshold below which chains are filtered
+    # @return lPathNums a list of paths Id
+    #
+    def getIdListFromSubjectWhereChainsLongerThanThreshold( self, subjectName, lengthThreshold ):
+        lPathNums = []
+        sqlCmd = "SELECT DISTINCT path, SUM( ABS(query_end - query_start) + 1 ) AS length"
+        sqlCmd += " FROM %s" % ( self._table )
+        sqlCmd += " WHERE subject_name='%s'" % ( subjectName )
+        sqlCmd += " GROUP BY path"
+        sqlCmd += " ORDER BY length DESC";
+        self._iDb.execute( sqlCmd )
+        res = self._iDb.fetchall()
+        for i in res:
+            if int(i[1]) >= int(lengthThreshold):
+                lPathNums.append( i[0] )
+        return lPathNums
+    
+    ## Give a Set instances list of a query annotation
+    #
+    # @param query string query name
+    # @return lSets list of set instance 
+    #
+    def getSetListFromQuery(self, query):
+        lpath = self.getPathListFromQuery(query)
+        lSets = PathUtils.getSetListFromQueries(lpath)
+        return lSets
+    
+    ## Give a Set instances list of a query annotation
+    # @note method to have correspondence with getSetListFromSeqName() in TableSetAdaptator (for srptAutoPromote.py)
+    #
+    # @param query string query name
+    # @return lSets list of set instance 
+    #
+    def getSetListFromSeqName(self, query):
+        return self.getSetListFromQuery(query)
+    
+    ## Delete path corresponding to a given identifier number
+    #
+    # @param id integer identifier number
+    #
+    def deleteFromId(self,id):
+        sqlCmd = "delete from %s where path=%d;" % (self._table, id)
+        self._iDb.execute(sqlCmd)
+
+    ## Delete path corresponding to a given object path line
+    #
+    # @param path object 
+    #
+    def deleteFromPath(self,path):
+        sqlCmd = "delete from %s where path=%d and query_name='%s' and query_start=%s and query_end=%s and subject_name='%s' and subject_start=%s and subject_end=%s and E_value=%s and score=%s" % (self._table, path.getIdentifier(), path.getQueryName(), path.getQueryStart(), path.getQueryEnd(), path.getSubjectName(), path.getSubjectStart(), path.getSubjectEnd(), path.getEvalue(), int(path.getScore()))
+        self._iDb.execute(sqlCmd)
+
+    ## Delete path corresponding to a given list of identifier number
+    #
+    # @param lId list of identifier number
+    #
+    def deleteFromIdList(self,lId):
+        if lId == []:
+            return        
+        sqlCmd = "delete from %s where path=%d" % (self._table, lId[0])
+        for id in lId[1:]:
+            sqlCmd += " or path=%d" %(id)
+        sqlCmd += ";"
+        self._iDb.execute(sqlCmd)
+
+    ## Get a new id number
+    #
+    # @return newId integer new id
+    #
+    def getNewId(self):
+        sqlCmd = 'select max(path) from %s;' % (self._table)
+        maxId = self._iDb.getIntegerWithSQLCmd(sqlCmd)
+        newId = int(maxId)+1
+        return newId
+    
+    ##  Join two path by changing id number of id1 and id2 path to the least of id1 and id2
+    #
+    # @param id1 integer id path number
+    # @param id2 integer id path number
+    # @return newId integer minimum of id1 id2
+    # @note this method modify the ID even if this one not existing in the path table  
+    #     
+    def joinTwoPaths(self, id1, id2):
+        if id1 < id2:
+            newId = id1
+            oldId = id2
+        else:
+            newId = id2
+            oldId = id1
+        sqlCmd = "UPDATE %s SET path=%d WHERE path=%d"\
+                % (self._table, newId, oldId)
+        self._iDb.execute(sqlCmd)
+        return newId
+    
+    ## Create a 'pathRange' table from a 'path' table. 
+    # The output table summarizes the information per identifier. 
+    # The min and max value are taken. 
+    # The identity is averaged over the fragments. 
+    # It may overwrite an existing table.
+    #
+    # @param outTable string name of the output table
+    # @return outTable string Table which summarizes the information per identifier
+    #
+    def path2PathRange( self, outTable="" ):
+        return self._path2PathRangeOrPath2PathRangeQuery(outTable)
+  
+    ## Create a 'pathrange' table from a 'path' table for the given query name
+    #  The output table summarizes the information per identifier
+    #  The min and max value are taken
+    #  The identity is averaged over the fragments, weighted by the length of the of the query
+    #  It may overwrite an existing table
+    #
+    # @param outTable string name of the output table
+    # @param query string query name
+    # @return outTable string  Table which summarizes the information per identifier
+    #
+    def _path2PathRangeFromQuery( self, queryName, outTable="" ):
+        return self._path2PathRangeOrPath2PathRangeQuery(outTable, queryName)
+    
+    def _path2PathRangeOrPath2PathRangeQuery(self, outTable, queryName=""):
+        self._iDb.createIndex( self._table, "path" )
+        if outTable == "":
+            outTable = "%s_range" % ( self._table )
+        self._iDb.dropTable( outTable )
+        
+        tmpTable = "%s_tmp" % ( self._table )
+        self._iDb.dropTable( tmpTable )
+        
+        sqlCmd = self._genSqlCmdForTmpTableAccordingToQueryName(queryName, tmpTable)
+        self._iDb.execute(sqlCmd)
+            
+        sqlCmd = "CREATE TABLE %s SELECT path, query_name, MIN(query_start) AS query_start, MAX(query_end) AS query_end, subject_name, MIN(subject_start) AS subject_start, MAX(subject_end) AS subject_end, MIN(e_value) AS e_value, SUM(score) AS score, TRUNCATE(SUM(identity)/SUM(ABS(query_end-query_start)+1),2) AS identity FROM %s WHERE query_start<query_end AND subject_start<subject_end GROUP BY path;" % ( outTable, tmpTable )
+        self._iDb.execute( sqlCmd )
+        
+        sqlCmd = "INSERT into %s SELECT path, query_name, MIN(query_start) AS query_start, MAX(query_end) AS query_end, subject_name, MAX(subject_start) AS subject_start, MIN(subject_end) AS subject_end, MIN(e_value) AS e_value, SUM(score) AS score, TRUNCATE(SUM(identity)/SUM(ABS(query_end-query_start)+1),2) AS identity FROM %s WHERE query_start<query_end AND subject_start>subject_end GROUP BY path;" % ( outTable, tmpTable )
+        self._iDb.execute( sqlCmd )
+        
+        self._iDb.createIndex( outTable, "path" )
+        self._iDb.dropTable( tmpTable )
+        return outTable
+            
+    ## Give a list of Path lists sorted by weighted identity.
+    #
+    # @return lChains list of chains
+    #
+    def getListOfChainsSortedByAscIdentityFromQuery( self, qry ):
+        lChains = []
+        tmpTable = self._path2PathRangeFromQuery( qry )
+        sqlCmd = "SELECT path FROM %s ORDER BY identity" % ( tmpTable )
+        self._iDb.execute( sqlCmd )
+        lPathnums = self._iDb.fetchall()
+        self._iDb.dropTable( tmpTable )
+        for pathnum in lPathnums:
+            lChains.append( self.getPathListFromId( int(pathnum[0]) ) )
+        return lChains
+    
+    ## Give a list of path instances sorted by increasing E-value
+    #
+    # @return lPaths list of path instances
+    #
+    def getPathListSortedByIncreasingEvalueFromQuery( self, queryName ):
+        sqlCmd = "SELECT * FROM %s WHERE query_name='%s' ORDER BY E_value ASC" % ( self._table, queryName )
+        lPaths = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lPaths
+    
+    
+    ## Return the number of times a given instance is present in the table
+    # The identifier is not considered,
+    # only coordinates, score, E-value and identity.
+    #
+    # @return nbOcc integer
+    #
+    def getNbOccurrences( self, iPath ):
+        sqlCmd = "SELECT COUNT(*) FROM %s WHERE" % ( self._table )
+        sqlCmd += " query_name='%s'" % ( iPath.range_query.seqname )
+        sqlCmd += " AND query_start='%s'" % ( iPath.range_query.start )
+        sqlCmd += " AND query_end='%s'" % ( iPath.range_query.end )
+        sqlCmd += " AND subject_name='%s'" % ( iPath.range_subject.seqname )
+        sqlCmd += " AND subject_start='%s'" % ( iPath.range_subject.start )
+        sqlCmd += " AND subject_end='%s'" % ( iPath.range_subject.end )
+        sqlCmd += " AND score='%s'" % ( iPath.score )
+        sqlCmd += " AND e_value='%s'" % ( iPath.e_value )
+        sqlCmd += " AND identity='%s'" % ( iPath.identity )
+        nbOcc = self._iDb.getIntegerWithSQLCmd( sqlCmd )
+        return nbOcc
+    
+    
+    def _getPathListFromTypeName( self, type, typeName ):
+        sqlCmd = "SELECT * FROM %s WHERE %s_name='%s';" % ( self._table, type, typeName )
+        lPath = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lPath
+    
+    def _getDistinctTypeNamesList( self, type ):
+        sqlCmd = "SELECT DISTINCT %s_name FROM %s" % ( type, self._table )
+        lDistinctTypeNames = self._iDb.getStringListWithSQLCmd(sqlCmd)
+        return lDistinctTypeNames
+    
+    def _getPathsNbFromTypeName( self, type, typeName ):
+        sqlCmd = "SELECT COUNT(*) FROM %s WHERE %s_name='%s'" % ( self._table, type, typeName )
+        pathNb = self._iDb.getIntegerWithSQLCmd( sqlCmd )
+        return pathNb
+    
+    def _getIdListFromTypeName( self, type, typeName ):
+        sqlCmd = "SELECT DISTINCT path FROM %s WHERE %s_name='%s'" % ( self._table, type, typeName )
+        lId = self._iDb.getIntegerListWithSQLCmd( sqlCmd )
+        return lId
+    
+    def _getIdNbFromTypeName( self, type, typeName ):
+        sqlCmd = "SELECT COUNT( DISTINCT path ) FROM %s WHERE %s_name='%s'" % ( self._table, type, typeName )
+        idNb = self._iDb.getIntegerWithSQLCmd( sqlCmd )
+        return idNb
+    
+    def _getTypeAndAttr2Insert(self, path):
+        type2Insert = ("'%d'", "'%s'", "'%d'", "'%d'", "'%s'", "'%d'", "'%d'", "'%g'", "'%d'", "'%f'")
+        if path.range_query.isOnDirectStrand():
+            queryStart = path.range_query.start
+            queryEnd = path.range_query.end
+            subjectStart = path.range_subject.start
+            subjectEnd = path.range_subject.end
+        else:
+            queryStart = path.range_query.end
+            queryEnd = path.range_query.start
+            subjectStart = path.range_subject.end
+            subjectEnd = path.range_subject.start
+        attr2Insert = ( path.id,\
+                     path.range_query.seqname,\
+                     queryStart,\
+                     queryEnd,\
+                     path.range_subject.seqname,\
+                     subjectStart,\
+                     subjectEnd,\
+                     path.e_value,\
+                     path.score,\
+                     path.identity\
+                     )
+        return type2Insert, attr2Insert
+    
+    def _getInstanceToAdapt(self):
+        iPath = Path()
+        return iPath
+    
+    def _escapeAntislash(self, obj):
+        obj.range_query.seqname = obj.range_query.seqname.replace("\\", "\\\\")
+        obj.range_subject.seqname = obj.range_subject.seqname.replace("\\", "\\\\")
+    
+    def _genSqlCmdForTmpTableAccordingToQueryName(self, queryName, tmpTable):
+        sqlCmd = ""
+        if queryName == "":
+            sqlCmd = "CREATE TABLE %s SELECT path, query_name, query_start, query_end, subject_name, subject_start, subject_end, e_value, score, (ABS(query_end-query_start)+1)*identity AS identity FROM %s" % (tmpTable, self._table)
+        else:
+            sqlCmd = "CREATE TABLE %s SELECT path, query_name, query_start, query_end, subject_name, subject_start, subject_end, e_value, score, (ABS(query_end-query_start)+1)*identity AS identity FROM %s WHERE query_name='%s'" % (tmpTable, self._table, queryName)
+        return sqlCmd
+        
+    ## return a filtered list with only one unique occurrence of path of a given list
+    #
+    # @param lPath a list of Path instances
+    # @return lUniquePath a list of Path instances
+    #
+    def getListOfUniqueOccPath(self, lPath):
+        if len(lPath) < 2 :
+            return lPath
+        
+        sortedListPath = sorted(lPath, key=lambda iPath: ( iPath.range_query.getSeqname(), iPath.range_query.getStart(), iPath.range_query.getEnd(), iPath.range_subject.getSeqname(), iPath.range_subject.getStart(), iPath.range_subject.getEnd()))
+        lUniquePath = []    
+        for i in xrange(1, len(sortedListPath)):
+            previousPath =  sortedListPath [i-1]
+            currentPath =  sortedListPath [i]
+            if previousPath != currentPath:
+                lUniquePath.append(previousPath)
+        
+        if previousPath != currentPath:
+            lUniquePath.append(currentPath)  
+                  
+        return lUniquePath       
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/TableSeqAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,185 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import sys
+from commons.core.sql.TableAdaptator import TableAdaptator
+from commons.core.sql.ITableSeqAdaptator import ITableSeqAdaptator
+from commons.core.coord.SetUtils import SetUtils
+from commons.core.seq.Bioseq import Bioseq
+
+
+## Adaptator for a Seq table
+#
+class TableSeqAdaptator( TableAdaptator, ITableSeqAdaptator ):
+    
+    ## Retrieve all the distinct accession names in a list.
+    #
+    # @return lAccessions list of accessions
+    #
+    def getAccessionsList( self ):
+        sqlCmd = "SELECT DISTINCT accession FROM %s;" % ( self._table )
+        lAccessions = self._getStringListWithSQLCmd(sqlCmd)
+        return lAccessions
+    
+    ## Save sequences in a fasta file from a list of accession names.
+    # 
+    # @param lAccessions list of accessions
+    # @param outFileName string Fasta file
+    #
+    def saveAccessionsListInFastaFile( self, lAccessions, outFileName ):
+        outFile = open( outFileName, "w" )
+        for ac in lAccessions:
+            bs = self.getBioseqFromHeader( ac )
+            bs.write(outFile)
+        outFile.close()
+    
+    ## Get a bioseq instance given its header
+    #
+    # @param header string name of the sequence ('accession' field in the 'seq' table) 
+    # @return bioseq instance
+    #
+    def getBioseqFromHeader( self, header ):
+        sqlCmd = "SELECT * FROM %s WHERE accession='%s';" % ( self._table, header )
+        self._iDb.execute( sqlCmd )
+        res = self._iDb.fetchall()
+        return Bioseq( res[0][0], res[0][1] )
+        
+    ## Retrieve the length of a sequence given its name.
+    #
+    # @param accession name of the sequence
+    # @return seqLength integer length of the sequence
+    # 
+    def getSeqLengthFromAccession( self, accession ):
+        sqlCmd = 'SELECT length FROM %s WHERE accession="%s"' % ( self._table, accession )
+        seqLength = self._iDb.getIntegerWithSQLCmd(sqlCmd)
+        return seqLength
+    
+    ## Retrieve the length of a sequence given its description.
+    #
+    # @param description of the sequence
+    # @return seqLength integer length of the sequence
+    # 
+    def getSeqLengthFromDescription( self, description ):
+        sqlCmd = 'SELECT length FROM %s WHERE description="%s"' % ( self._table, description )
+        seqLength = self._iDb.getIntegerWithSQLCmd(sqlCmd)
+        return seqLength
+        
+    ## Retrieve all the accessions with length in a list of tuples
+    #
+    # @return lAccessionLengthTuples list of tuples
+    # 
+    def getAccessionAndLengthList(self):
+        sqlCmd = 'SELECT accession, length FROM %s' % self._table
+        self._iDb.execute(sqlCmd)
+        res = self._iDb.fetchall()
+        lAccessionLengthTuples = []
+        for i in res:
+            lAccessionLengthTuples.append(i)
+        return lAccessionLengthTuples
+    
+    ## get subsequence according to given parameters
+    #
+    # @param accession 
+    # @param start integer 
+    # @param end integer
+    # @return bioseq.sequence string
+    #
+    def getSubSequence( self, accession, start, end ):
+        bs = Bioseq()
+        if start <= 0 or end <= 0:
+            print "ERROR with coordinates start=%i or end=%i" % ( start, end )
+            sys.exit(1)
+            
+        if accession not in self.getAccessionsList():
+            print "ERROR: accession '%s' absent from table '%s'" % ( accession, self._table )
+            sys.exit(1)
+            
+        lengthAccession = self.getSeqLengthFromAccession( accession )
+        if start > lengthAccession or end > lengthAccession:
+            print "ERROR: coordinates start=%i end=%i out of sequence '%s' range (%i bp)" % ( start, end, accession, lengthAccession )
+            sys.exit(1)
+            
+        sqlCmd = "SELECT SUBSTRING(sequence,%i,%i) FROM %s WHERE accession='%s'" % ( min(start,end), abs(end-start)+ 1, self._table, accession )
+        self._iDb.execute( sqlCmd )
+        res = self._iDb.fetchall()
+        bs.setSequence( res[0][0] )
+        if start > end:
+            bs.reverseComplement()
+        return bs.sequence
+    
+    ## get bioseq from given set list
+    #
+    # @param lSets set list of sets 
+    # @return bioseq instance
+    #
+    def getBioseqFromSetList( self, lSets ):
+        header = "%s::%i %s " % ( lSets[0].name, lSets[0].id, lSets[0].seqname )
+        sequence = ""
+        lSortedSets = SetUtils.getSetListSortedByIncreasingMinThenMax( lSets )
+        if not lSets[0].isOnDirectStrand():
+            lSortedSets.reverse()
+        for iSet in lSortedSets:
+            header += "%i..%i," % ( iSet.getStart(), iSet.getEnd() )
+            sequence += self.getSubSequence( iSet.seqname, iSet.getStart(), iSet.getEnd() )
+        return Bioseq( header[:-1], sequence )
+    
+    ## Return True if the given accession is present in the table
+    #
+    def isAccessionInTable( self, name ):
+        sqlCmd = "SELECT accession FROM %s WHERE accession='%s'" % ( self._table, name )
+        self._iDb.execute( sqlCmd )
+        res = self._iDb.fetchall()
+        return bool(res)
+    
+    ## Retrieve all the distinct accession names in a fasta file.
+    #
+    # @param outFileName string Fasta file
+    # 
+    def exportInFastaFile(self, outFileName ):
+        lAccessions = self.getAccessionsList()
+        self.saveAccessionsListInFastaFile( lAccessions, outFileName )
+        
+    def _getStringListWithSQLCmd( self, sqlCmd ):
+        self._iDb.execute(sqlCmd)
+        res = self._iDb.fetchall()
+        lString = []
+        for i in res:
+            lString.append(i[0])
+        return lString
+   
+    def _getTypeAndAttr2Insert(self, bs):
+        type2Insert =  ( "'%s'", "'%s'", "'%s'", "'%i'" ) 
+        attr2Insert =  (bs.header.split()[0], bs.sequence, bs.header, bs.getLength())
+        return type2Insert, attr2Insert
+    
+    def _escapeAntislash(self, obj):
+        pass
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/TableSetAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,215 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from commons.core.sql.ITableSetAdaptator import ITableSetAdaptator
+from commons.core.sql.TableAdaptator import TableAdaptator
+from commons.core.coord.Set import Set
+
+
+## Adaptator for a Set table
+#
+class TableSetAdaptator( TableAdaptator, ITableSetAdaptator ):
+            
+    ## Give a list of Set instances having a given seq name
+    #
+    # @param seqName string seq name
+    # @return lSet list of instances
+    #
+    def getListFromSeqName( self, seqName ):
+        sqlCmd = "SELECT * FROM %s" % (self._table)
+        colum2Get, type2Get, attr2Get = self._getTypeColumAttr2Get(seqName)
+        sqlCmd += " WHERE " + colum2Get
+        sqlCmd += " = "
+        sqlCmd = sqlCmd + type2Get
+        sqlCmd = sqlCmd % "'" + attr2Get + "'"
+        lSet = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lSet
+        
+    ## Give a list of set instances overlapping a given region
+    #
+    # @param query string query name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lSet list of set instances
+    #
+    def getListOverlappingCoord(self, query, start, end):
+        sqlCmd = 'select * from %s where chr="%s" and ((start between least(%d,%d) and greatest(%d,%d) or end between least(%d,%d) and greatest(%d,%d)) or (least(start,end)<=least(%d,%d) and greatest(start,end)>=greatest(%d,%d)))  ;' % (self._table, query, start, end, start, end, start, end, start, end, start, end, start, end)
+        lSet = self._iDb.getObjectListWithSQLCmd( sqlCmd, self._getInstanceToAdapt )
+        return lSet
+
+    #TODO: to test !!!
+    ## Give a list of Set instances overlapping a given region
+    #
+    # @note whole chains are returned, even if only a fragment overlap with the given region
+    # @param query string query name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lSets list of Path instances
+    #
+    def getChainListOverlappingCoord(self, query, start, end):
+        sqlCmd = "select distinct path from %s where chr='%s' and ((start between least(%d,%d) and greatest(%d,%d) or end between least(%d,%d) and greatest(%d,%d)) or (least(start,end)<=least(%d,%d) and greatest(start,end)>=greatest(%d,%d)));" % (self._table, query,start,end,start,end,start,end,start,end,start,end,start,end)
+        lIdentifiers = self._iDb.getIntegerListWithSQLCmd(sqlCmd)
+        lSets = self.getSetListFromIdList(lIdentifiers)
+        return lSets
+
+    ## Give a list of identifier numbers contained in the table
+    #
+    # @return lId integer list
+    #
+    def getIdList(self):
+        sqlCmd = "select distinct path from %s;" % (self._table)
+        lId = self._iDb.getIntegerListWithSQLCmd( sqlCmd )
+        return lId
+    
+    ## Give a list of the distinct seqName/chr present in the table
+    #
+    # @return lDistinctContigNames string list
+    #
+    def getSeqNameList(self):
+        sqlCmd = "SELECT DISTINCT chr FROM %s" % ( self._table )
+        lDistinctContigNames = self._iDb.getStringListWithSQLCmd(sqlCmd)
+        return lDistinctContigNames
+    
+    ## Give a list of Set instances having a given seq name
+    #
+    # @param seqName string seq name
+    # @return lSet list of instances
+    #
+    def getSetListFromSeqName( self, seqName):
+        lSets = self.getListFromSeqName(seqName)
+        return lSets
+    
+    ## Give a set instances list with a given identifier number
+    #
+    # @param id integer identifier number
+    # @return lSet list of set instances
+    #
+    def getSetListFromId(self, id):
+        SQLCmd = "select * from %s where path=%d;" % (self._table, id)
+        return self._iDb.getObjectListWithSQLCmd( SQLCmd, self._getInstanceToAdapt )
+   
+    ## Give a set instances list with a list of identifier numbers
+    #
+    # @param lId integers list identifiers list numbers
+    # @return lSet list of set instances
+    #   
+    def getSetListFromIdList(self,lId):
+        lSet = []
+        if lId == []:
+            return lSet
+        SQLCmd = "select * from %s where path=%d" % (self._table, lId[0])
+        for i in lId[1:]:
+            SQLCmd += " or path=%d" % (i)
+        SQLCmd += ";"
+        return self._iDb.getObjectListWithSQLCmd( SQLCmd, self._getInstanceToAdapt )
+    
+    ## Return a list of Set instances overlapping a given sequence
+    #   
+    # @param seqName string sequence name
+    # @param start integer start coordinate
+    # @param end integer end coordinate
+    # @return lSet list of Set instances
+    #
+    def getSetListOverlappingCoord( self, seqName, start, end ):
+        lSet = self.getListOverlappingCoord( seqName, start, end )
+        return lSet
+    
+    ## Delete set corresponding to a given identifier number
+    #
+    # @param id integer identifier number
+    #  
+    def deleteFromId(self, id):
+        sqlCmd = "delete from %s where path=%d;" % (self._table, id)
+        self._iDb.execute(sqlCmd)
+        
+    ## Delete set corresponding to a given list of identifier number
+    #
+    # @param lId integers list list of identifier number
+    #  
+    def deleteFromIdList(self, lId):
+        if lId == []:
+            return
+        sqlCmd = "delete from %s where path=%d" % ( self._table, lId[0] )
+        for i in lId[1:]:
+            sqlCmd += " or path=%d"%(i)
+        sqlCmd += ";"
+        self._iDb.execute(sqlCmd)
+        
+    ## Join two set by changing id number of id1 and id2 set to the least of id1 and id2
+    #
+    # @param id1 integer id path number
+    # @param id2 integer id path number
+    #    
+    def joinTwoSets(self, id1, id2):
+        if id1 < id2:
+            newId = id1
+            oldId = id2
+        else:
+            newId = id2
+            oldId = id1
+        sqlCmd = "UPDATE %s SET path=%d WHERE path=%d" % (self._table, newId, oldId)
+        self._iDb.execute(sqlCmd)
+    
+    ## Get a new id number
+    #
+    # @return new_id integer max_id + 1 
+    #
+    def getNewId(self):
+        sqlCmd = "select max(path) from %s;" % (self._table)
+        maxId = self._iDb.getIntegerWithSQLCmd(sqlCmd)
+        newId = int(maxId) + 1
+        return newId
+    
+    ## Give the data contained in the table as a list of Sets instances
+    #
+    # @return lSets list of set instances
+    #
+    def getListOfAllSets( self ):
+        return self.getListOfAllCoordObject()
+   
+    def _getInstanceToAdapt(self):
+            iSet = Set()
+            return iSet
+    
+    def _getTypeColumAttr2Get(self, contig):
+        colum2Get = 'chr'
+        type2Get = '%s'
+        attr2Get = contig
+        return colum2Get, type2Get, attr2Get
+    
+    def _getTypeAndAttr2Insert(self, set):
+        type2Insert = ("'%d'","'%s'","'%s'","'%d'","'%d'")
+        attr2Insert = (set.id, set.name, set.seqname, set.start, set.end)
+        return type2Insert, attr2Insert
+
+    def _escapeAntislash(self, obj):
+        obj.name = obj.name.replace("\\", "\\\\")
+        obj.seqname = obj.seqname.replace("\\", "\\\\")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/TestSuite_sql.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import sys
+import Test_DbMySql
+import Test_TableBinPathAdaptator
+import Test_TableMapAdaptator
+import Test_TableMatchAdaptator
+import Test_TablePathAdaptator
+import Test_TableSeqAdaptator
+import Test_TableSetAdaptator
+import Test_F_RepetJob
+import Test_RepetJob
+import Test_TableBinSetAdaptator
+
+def main():
+
+        TestSuite_sql = unittest.TestSuite()
+        
+        TestSuite_sql.addTest( unittest.makeSuite( Test_DbMySql.Test_DbMySql, "test" ) )
+        TestSuite_sql.addTest( unittest.makeSuite( Test_TableBinPathAdaptator.Test_TableBinPathAdaptator, "test" ) )
+        TestSuite_sql.addTest( unittest.makeSuite( Test_TableMapAdaptator.Test_TableMapAdaptator, "test" ) )
+        TestSuite_sql.addTest( unittest.makeSuite( Test_TableMatchAdaptator.Test_TableMatchAdaptator, "test" ) )
+        TestSuite_sql.addTest( unittest.makeSuite( Test_TableSetAdaptator.Test_TableSetAdaptator, "test" ) )
+        TestSuite_sql.addTest( unittest.makeSuite( Test_TableSeqAdaptator.Test_TableSeqAdaptator, "test" ) )
+        TestSuite_sql.addTest( unittest.makeSuite( Test_TableMatchAdaptator.Test_TableMatchAdaptator, "test" ) )
+        TestSuite_sql.addTest( unittest.makeSuite( Test_TablePathAdaptator.Test_TablePathAdaptator, "test" ) )
+        TestSuite_sql.addTest( unittest.makeSuite( Test_F_RepetJob.Test_F_RepetJob, "test" ) )
+        TestSuite_sql.addTest( unittest.makeSuite( Test_RepetJob.Test_RepetJob, "test" ) )
+        TestSuite_sql.addTest( unittest.makeSuite( Test_TableBinSetAdaptator.Test_TableBinSetAdaptator, "test" ) )
+        
+        runner = unittest.TextTestRunner( sys.stderr, 2, 2 )
+        runner.run( TestSuite_sql )
+        
+        
+if __name__ == "__main__":
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_DbFactory.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,63 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+import os
+import unittest
+from commons.core.sql.DbFactory import DbFactory
+
+class Test_DbFactory( unittest.TestCase ):
+
+    def test_createInstance (self):
+        dbInstance = DbFactory.createInstance()
+        expValue = None
+        obsValue = dbInstance
+        self.assertNotEquals(expValue, obsValue)
+        
+    def test_createInstance_with_config (self):
+        configFileName = "dummyConfigFileName.cfg"
+        configF = open(configFileName,"w")
+        configF.write("[repet_env]\n")
+        configF.write( "repet_host: %s\n" % ( os.environ["REPET_HOST"] ) )
+        configF.write( "repet_user: %s\n" % ( os.environ["REPET_USER"] ) )
+        configF.write( "repet_pw: %s\n" % ( os.environ["REPET_PW"] ) )
+        configF.write( "repet_db: %s\n" % ( os.environ["REPET_DB"] ) )
+        configF.write( "repet_port: %s\n" % ( os.environ["REPET_PORT"] ) )
+        configF.close()
+        
+        dbInstance = DbFactory.createInstance(configFileName)
+        expValue = None
+        obsValue = dbInstance
+        self.assertNotEquals(expValue, obsValue)
+        os.remove(configFileName)
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_DbFactory ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_DbMySql.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,1554 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+import unittest
+import time
+import os
+from MySQLdb import ProgrammingError
+from commons.core.sql.DbMySql import DbMySql
+from commons.core.sql.DbMySql import TABLE_SCHEMA_DESCRIPTOR
+from commons.core.sql.DbMySql import TABLE_TYPE_SYNONYMS
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.coord.Path import Path
+
+class Test_DbMySql( unittest.TestCase ):
+    
+    def setUp( self ):
+        self._iDb = DbMySql( )
+        self._uniqId = "%s" % time.strftime("%Y%m%d%H%M%S")
+
+    def tearDown( self ):
+        if self._iDb.db.open:
+            self._iDb.close()
+        self._iDb = None
+        
+    def test_execute_syntax_error(self):
+        expErrorMsg = "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHAUD TABLES' at line 1"
+        obsErrorMsg = ""
+        sqlCmd = "CHAUD TABLES"
+        try:
+            self._iDb.execute(sqlCmd)
+        except ProgrammingError as excep:
+            obsErrorMsg = excep.args[1]
+        
+        self.assertEquals(expErrorMsg, obsErrorMsg)
+
+    def test_execute_with_1_retry(self):
+        tableName = "dummyTable%s" % self._uniqId
+        sqlCmd = "CREATE TABLE %s (dummyColumn varchar(255))" % tableName
+        self._iDb.close()
+        self._iDb.execute(sqlCmd)
+        self.assertTrue(self._iDb.doesTableExist(tableName))
+        self._iDb.dropTable(tableName)
+
+    def test_setAttributesFromConfigFile(self):
+        expHost = "dummyHost"
+        expUser = "dummyUser"
+        expPw = "dummyPw"
+        expDb = "dummyDb"
+        expPort = 1000
+        
+        configFileName = "dummyConfigFileName.cfg"
+        f = open( configFileName, "w" )
+        f.write("[repet_env]\n")
+        f.write("repet_host: " + expHost + "\n")
+        f.write("repet_user: " + expUser + "\n")
+        f.write("repet_pw: " + expPw + "\n")
+        f.write("repet_db: " + expDb + "\n")
+        f.write("repet_port: " + str(expPort) + "\n")
+        f.close()
+        
+        self._iDb.setAttributesFromConfigFile(configFileName)
+        
+        obsHost = self._iDb.host
+        obsUser = self._iDb.user
+        obsPw = self._iDb.passwd
+        obsDb = self._iDb.dbname
+        obsPort = self._iDb.port
+        
+        os.remove(configFileName)
+        
+        self.assertEquals( expHost, obsHost )
+        self.assertEquals( expUser, obsUser )
+        self.assertEquals( expPw, obsPw )
+        self.assertEquals( expDb, obsDb )
+        self.assertEquals( expPort, obsPort )
+
+    def test_open_True(self):
+        self._iDb.close()
+        self.assertTrue(self._iDb.open())
+        self.assertEquals(1, self._iDb.db.open)
+        self._iDb.close()
+        self.assertEquals(0, self._iDb.db.open)
+        
+    def test_open_False(self):
+        self._iDb.close()
+        self._iDb.user = "dummyUser"
+        self.assertFalse( self._iDb.open() )
+        
+    def test_doesTableExist_True(self):
+        tableName = "dummyTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( dummyColumn varchar(255) )" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        self.assertTrue( self._iDb.doesTableExist(tableName) )
+        self._iDb.dropTable(tableName)
+        
+    def test_doesTableExist_False(self):
+        tableName = "dummyTable" + self._uniqId
+        self.assertFalse( self._iDb.doesTableExist(tableName) )
+        
+    def test_dropTable(self):
+        tableName = "dummyTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( dummyColumn varchar(255) )" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        self._iDb.dropTable(tableName)
+        self.assertFalse( self._iDb.doesTableExist(tableName) )
+        
+    def test_renameTable(self):
+        tableName = "dummyTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( dummyColumn varchar(255) )" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        self._iDb.updateInfoTable( tableName, "" )
+        newTableName = "newDummyTable"
+        
+        self._iDb.renameTable(tableName, newTableName)
+        
+        self.assertFalse( self._iDb.doesTableExist(tableName) )
+        self.assertTrue( self._iDb.doesTableExist(newTableName) )
+        
+        expTuple = (('newDummyTable', ''),)
+        sqlCmd = 'SELECT * FROM info_tables WHERE name = "%s"' % ( newTableName )
+        self._iDb.execute( sqlCmd )
+        obsTuple = self._iDb.cursor.fetchall()
+        self.assertEquals( expTuple, obsTuple)
+        
+        expTuple = ()
+        sqlCmd = 'SELECT * FROM info_tables WHERE name = "%s"' % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTuple = self._iDb.cursor.fetchall()
+        self.assertEquals( expTuple, obsTuple)
+        
+        self._iDb.dropTable(newTableName)
+        
+    def test_copyTable(self):
+        tableName = "dummyTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( dummyColumn varchar(255) );" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE INDEX idummyColumn ON %s ( dummyColumn );" % (tableName)
+        self._iDb.execute( sqlCmd )
+        
+        newTableName = "newDummyTable"
+        
+        self._iDb.copyTable(tableName, newTableName)
+        
+        self.assertTrue( self._iDb.doesTableExist(tableName) )
+        self.assertTrue( self._iDb.doesTableExist(newTableName) )
+        
+        expTuple = (('newDummyTable', ''),)
+        sqlCmd = 'SELECT * FROM info_tables WHERE name = "%s";' % ( newTableName )
+        self._iDb.execute( sqlCmd )
+        obsTuple = self._iDb.cursor.fetchall()
+        
+        self.assertEquals( expTuple, obsTuple)
+            
+        expTuple = (('newDummyTable', 1L, 'idummyColumn', 1L, 'dummyColumn', 'A', None, None, None, 'YES', 'BTREE', ''),)
+        sqlCmd = "SHOW INDEX FROM %s;" % ( newTableName )
+        self._iDb.execute( sqlCmd )
+        obsTuple = self._iDb.cursor.fetchall()
+        self.assertEquals( expTuple, obsTuple)
+        
+        self._iDb.dropTable(tableName)
+        self._iDb.dropTable(newTableName)
+        
+    def test_getTableType(self):
+        lTypesToTest = TABLE_SCHEMA_DESCRIPTOR.keys()
+        for tableType in lTypesToTest:
+            tableName = "dummy%sTable%s" % (tableType, self._uniqId)
+            self._iDb.createTable(tableName, tableType)
+            
+            obsType = self._iDb.getTableType(tableName)
+            self.assertEquals(tableType, obsType)
+            
+            self._iDb.dropTable(tableName)
+    
+    def test_getSize_empty_table(self):
+        tableName = "dummyPathTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( path int unsigned, query_name varchar(255), query_start int , query_end int, subject_name varchar(255), subject_start int unsigned, subject_end int unsigned, E_value double, score int unsigned, identity float)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        
+        pathFileName = "dummyPathFile.txt"
+        pathF = open( pathFileName, "w" )
+        pathF.write( "")
+        pathF.close()
+        self._iDb.loadDataFromFile(tableName, pathFileName, False)
+        expSize = 0
+        obsSize = self._iDb.getSize(tableName)
+        
+        self._iDb.dropTable(tableName)
+        os.remove(pathFileName)
+        
+        self.assertEquals( expSize, obsSize )
+        
+    def test_getSize_two_rows(self):
+        tableName = "dummyPathTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( path int unsigned, query_name varchar(255), query_start int , query_end int, subject_name varchar(255), subject_start int unsigned, subject_end int unsigned, E_value double, score int unsigned, identity float)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        
+        pathFileName = "dummyPathFile.txt"
+        pathF = open( pathFileName, "w" )
+        pathF.write( "1\tqry\t1\t100\tsbj\t1\t100\t1e-123\t136\t98.4\n" )
+        pathF.write( "2\tqry\t500\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        pathF.close()
+        self._iDb.loadDataFromFile(tableName, pathFileName, False)
+        expSize = 2
+        obsSize = self._iDb.getSize(tableName)
+        
+        self._iDb.dropTable(tableName)
+        os.remove(pathFileName)
+        
+        self.assertEquals( expSize, obsSize )
+        
+    def test_isEmpty_True(self):
+        tableName = "dummyTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( dummyColumn varchar(255) )" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        
+        fileName = "dummyTableFile.txt"
+        f = open( fileName, "w" )
+        f.write( "" )
+        f.close()
+        self._iDb.loadDataFromFile(tableName, fileName, False)
+        
+        self.assertTrue( self._iDb.isEmpty(tableName) )
+        
+        self._iDb.dropTable(tableName)
+        os.remove(fileName)
+        
+    def test_isEmpty_False(self):
+        tableName = "dummyTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( dummyColumn varchar(255) )" % tableName
+        self._iDb.execute( sqlCmd )
+        
+        fileName = "dummyTableFile.txt"
+        f = open( fileName, "w" )
+        f.write( "test" )
+        f.close()
+        self._iDb.loadDataFromFile(tableName, fileName, False)
+        
+        self.assertFalse( self._iDb.isEmpty(tableName) )
+        
+        self._iDb.dropTable(tableName)
+        os.remove(fileName)
+
+    def test_updateInfoTable(self):
+        tableName = "dummyTable" + self._uniqId
+        info = "Table_for_test"
+        
+        self._iDb.updateInfoTable(tableName, info)
+        
+        sqlCmd = 'SELECT file FROM info_tables WHERE name = "%s"' % ( tableName )
+        self._iDb.execute( sqlCmd )
+        results = self._iDb.cursor.fetchall()
+        obsResult = False
+        if (info,) in results:
+            obsResult = True
+            sqlCmd = 'DELETE FROM info_tables WHERE name = "%s"' % ( tableName )
+            self._iDb.execute( sqlCmd )
+            
+        self.assertTrue( obsResult )
+        
+    def test_loadDataFromFile_with_empty_file(self):
+        tableName = "dummyPathTable1" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( path int unsigned, query_name varchar(255), query_start int , query_end int, subject_name varchar(255), subject_start int unsigned, subject_end int unsigned, E_value double, score int unsigned, identity float)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        
+        pathFileName = "dummyPathFile.txt"
+        pathF = open( pathFileName, "w" )
+        pathF.write( "" )
+        pathF.close()
+        expTPathTuples = ()
+        
+        self._iDb.loadDataFromFile(tableName, pathFileName, False)
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTPathTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(pathFileName)
+        
+        self.assertEquals( expTPathTuples, obsTPathTuples )
+        
+    def test_loadDataFromFile_with_first_line(self):
+        tableName = "dummyPathTable2" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( path int unsigned, query_name varchar(255), query_start int , query_end int, subject_name varchar(255), subject_start int unsigned, subject_end int unsigned, E_value double, score int unsigned, identity float)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        
+        pathFileName = "dummyPathFile.txt"
+        pathF = open( pathFileName, "w" )
+        pathF.write( "1\tqry\t1\t100\tsbj\t1\t100\t1e-123\t136\t98.4\n" )
+        pathF.write( "2\tqry\t500\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        pathF.close()
+        
+        expPathTuple1 = (1L, 'qry', 1L, 100L, 'sbj', 1L, 100L, 1e-123, 136L, 98.4)
+        expPathTuple2 = (2L, 'qry', 500L, 401L, 'sbj', 1L, 100L, 1e-152, 161L, 98.7)
+        expTPathTuples = (expPathTuple1, expPathTuple2)
+        
+        self._iDb.loadDataFromFile(tableName, pathFileName, False)
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTPathTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(pathFileName)
+        
+        self.assertEquals( expTPathTuples, obsTPathTuples )
+        
+    def test_loadDataFromFile_without_first_line(self):
+        tableName = "dummyPathTable3" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( path int unsigned, query_name varchar(255), query_start int , query_end int, subject_name varchar(255), subject_start int unsigned, subject_end int unsigned, E_value double, score int unsigned, identity float)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        
+        pathFileName = "dummyPathFile.txt"
+        pathF = open( pathFileName, "w" )
+        pathF.write( "1\tqry\t1\t100\tsbj\t1\t100\t1e-123\t136\t98.4\n" )
+        pathF.write( "2\tqry\t500\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        pathF.close()
+        
+        expPathTuple = (2L, 'qry', 500L, 401L, 'sbj', 1L, 100L, 1e-152, 161L, 98.7)
+        expTPathTuples = (expPathTuple,)
+        
+        self._iDb.loadDataFromFile(tableName, pathFileName, True)
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTPathTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(pathFileName)
+        
+        self.assertEquals( expTPathTuples, obsTPathTuples )
+        
+    def test_createIndex_Map(self):
+        tableName = "dummyMapTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( name varchar(255), chr varchar(255), start int, end int)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        expLIndex = ["iname", "ichr", "istart", "iend", "icoord", "icoord"]
+        
+        self._iDb.createIndex(tableName, "map")
+        
+        sqlCmd = "SHOW INDEX FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        results = self._iDb.cursor.fetchall()
+        
+        for index in expLIndex[:-1]:
+            sqlCmd = "DROP INDEX %s ON %s" % ( index, tableName )
+            self._iDb.execute( sqlCmd )
+        self._iDb.dropTable(tableName)
+        
+        obsLIndex = []
+        for tuple in results:
+            obsLIndex.append(tuple[2])
+            
+        self.assertEquals( expLIndex, obsLIndex)
+        
+    def test_createIndex_Map_coord_index_already_exist(self):
+        tableName = "dummyMapTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( name varchar(255), chr varchar(255), start int, end int)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE INDEX icoord ON %s ( start,end );" % (tableName)
+        self._iDb.execute( sqlCmd )
+        expLIndex = ["icoord", "icoord", "iname", "ichr", "istart", "iend"]
+        
+        self._iDb.createIndex(tableName, "map")
+        
+        sqlCmd = "SHOW INDEX FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        results = self._iDb.cursor.fetchall()
+        
+        for index in expLIndex[1:]:
+            sqlCmd = "DROP INDEX %s ON %s" % ( index, tableName )
+            self._iDb.execute( sqlCmd )
+        self._iDb.dropTable(tableName)
+        
+        obsLIndex = []
+        for tuple in results:
+            obsLIndex.append(tuple[2])
+            
+        self.assertEquals( expLIndex, obsLIndex)
+
+    def test_createTable_Map( self ):
+        tableName = "dummyMapTable" + self._uniqId
+        mapFileName = "dummyMapFile.txt"
+        mapF = open( mapFileName, "w" )
+        mapF.write( "map1\tseq1\t20\t50\n" )
+        mapF.write( "map2\tseq2\t700\t760\n" )
+        mapF.close()
+        
+        expMapTuple1 = ("map1", "seq1", 20L, 50L)
+        expMapTuple2 = ("map2", "seq2", 700L, 760L)
+        expTMapTuples = (expMapTuple1, expMapTuple2)
+        
+        self._iDb.createTable(tableName, 'map', mapFileName)
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTMapTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(mapFileName)
+        
+        self.assertEquals( expTMapTuples, obsTMapTuples )
+        
+    def test_createIndex_Match(self):
+        tableName = "dummyMatchTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( query_name varchar(255), query_start int, query_end int, query_length int unsigned, query_length_perc float, match_length_perc float, subject_name varchar(255), subject_start int unsigned, subject_end int unsigned, subject_length int unsigned, subject_length_perc float, E_value double, score int unsigned, identity float, path int unsigned)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        expLIndex = ["id", "qname", "qstart", "qend", "sname", "sstart", "send", "qcoord", "qcoord"]
+        
+        self._iDb.createIndex(tableName, "match")
+        
+        sqlCmd = "SHOW INDEX FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        results = self._iDb.cursor.fetchall()
+        
+        obsLIndex = []
+        for tuple in results:
+            obsLIndex.append(tuple[2])
+        
+        self._iDb.dropTable(tableName)
+        self.assertEquals( expLIndex, obsLIndex)
+
+    def test_createIndex_Match_all_index_already_exist(self):
+        tableName = "dummyMatchTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( query_name varchar(255), query_start int, query_end int, query_length int unsigned, query_length_perc float, match_length_perc float, subject_name varchar(255), subject_start int unsigned, subject_end int unsigned, subject_length int unsigned, subject_length_perc float, E_value double, score int unsigned, identity float, path int unsigned)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE UNIQUE INDEX id ON %s ( path );" % (tableName)
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE INDEX qname ON %s ( query_name(10) );" % (tableName)
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE INDEX qstart ON %s ( query_start );" % (tableName)
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE INDEX qend ON %s ( query_end );" % (tableName)
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE INDEX sname ON %s ( subject_name(10) );" % (tableName)
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE INDEX sstart ON %s ( subject_start );" % (tableName)
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE INDEX send ON %s ( subject_end );" % (tableName)
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE INDEX qcoord ON %s ( query_start,query_end );" % (tableName)
+        self._iDb.execute( sqlCmd )
+        expLIndex = ["id", "qname", "qstart", "qend", "sname", "sstart", "send", "qcoord", "qcoord"]
+        
+        self._iDb.createIndex(tableName, "match")
+        
+        sqlCmd = "SHOW INDEX FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        results = self._iDb.cursor.fetchall()
+        
+        for index in expLIndex[:-1]:
+            sqlCmd = "DROP INDEX %s ON %s" % ( index, tableName )
+            self._iDb.execute( sqlCmd )
+        self._iDb.dropTable(tableName)
+        
+        obsLIndex = []
+        for tuple in results:
+            obsLIndex.append(tuple[2])
+            
+        self.assertEquals( expLIndex, obsLIndex)
+        
+    def test_createTable_match( self ):
+        tableName = "dummyMatchTable" + self._uniqId
+        matchFileName = "dummyMatchFile.txt"
+        matchF = open( matchFileName, "w" )
+        matchF.write( "qry1\t700\t760\t60\t100\t100\tsbj2\t500\t560\t60\t100\t1e-123\t136\t98.4\t2\n" )
+        matchF.write( "qry2\t700\t760\t60\t100\t100\tsbj2\t500\t560\t60\t100\t1e-123\t136\t98.4\t2\n" )
+        matchF.close()
+        
+        expMatchTuple = ("qry2", 700L, 760L, 60L, 100.0, 100.0, "sbj2", 500L, 560L, 60L, 100.0, 1e-123, 136L, 98.4, 2L)
+        expTMatchTuples = (expMatchTuple,)
+        
+        self._iDb.createTable(tableName, "match", matchFileName)
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTMatchTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(matchFileName)
+        
+        self.assertEquals( expTMatchTuples, obsTMatchTuples )
+        
+    def test_createIndex_Path(self):
+        tableName = "dummyPathTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( path int unsigned, query_name varchar(255), query_start int , query_end int, subject_name varchar(255), subject_start int unsigned, subject_end int unsigned, E_value double, score int unsigned, identity float)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        expLIndex = ["id", "qname", "qstart", "qend", "sname", "sstart", "send", "qcoord", "qcoord"]
+        
+        self._iDb.createIndex(tableName, "path")
+        
+        sqlCmd = "SHOW INDEX FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        results = self._iDb.cursor.fetchall()
+        
+        for index in expLIndex[:-1]:
+            sqlCmd = "DROP INDEX %s ON %s" % ( index, tableName )
+            self._iDb.execute( sqlCmd )
+        self._iDb.dropTable(tableName)
+        
+        obsLIndex = []
+        for tuple in results:
+            obsLIndex.append(tuple[2])
+            
+        self.assertEquals( expLIndex, obsLIndex)
+        
+    def test_createIndex_Path_id_and_send_index_already_exist(self):
+        tableName = "dummyPathTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( path int unsigned, query_name varchar(255), query_start int , query_end int, subject_name varchar(255), subject_start int unsigned, subject_end int unsigned, E_value double, score int unsigned, identity float)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE INDEX id ON %s ( path );" % (tableName)
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE INDEX send ON %s ( subject_end );" % (tableName)
+        self._iDb.execute( sqlCmd )
+        expLIndex = ["id", "send", "qname", "qstart", "qend", "sname", "sstart", "qcoord", "qcoord"]
+        
+        self._iDb.createIndex(tableName, "path")
+        
+        sqlCmd = "SHOW INDEX FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        results = self._iDb.cursor.fetchall()
+        
+        for index in expLIndex[:-1]:
+            sqlCmd = "DROP INDEX %s ON %s" % ( index, tableName )
+            self._iDb.execute( sqlCmd )
+        self._iDb.dropTable(tableName)
+        
+        obsLIndex = []
+        for tuple in results:
+            obsLIndex.append(tuple[2])
+            
+        self.assertEquals( expLIndex, obsLIndex)
+        
+    def test_createTable_path( self ):
+        tableName = "dummyPathTable" + self._uniqId
+        pathFileName = "dummyPathFile.txt"
+        pathF = open( pathFileName, "w" )
+        pathF.write( "1\tqry\t1\t100\tsbj\t1\t100\t1e-123\t136\t98.4\n" )
+        pathF.write( "2\tqry\t500\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        pathF.close()
+        
+        expPathTuple1 = (1L, "qry", 1L, 100L, "sbj", 1L, 100L, 1e-123, 136L, 98.4)
+        expPathTuple2 = (2L, "qry", 401L, 500L, "sbj", 100L, 1L, 1e-152, 161L, 98.7)  # change coordinates
+        expTPathTuples = (expPathTuple1, expPathTuple2)
+        
+        self._iDb.createTable( tableName, "path", pathFileName)
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTPathTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(pathFileName)
+        
+        self.assertEquals( expTPathTuples, obsTPathTuples )
+        
+    def test_createIndex_align(self):
+        tableName = "dummyAlignTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( query_name varchar(255), query_start int, query_end int,subject_name varchar(255), subject_start int unsigned, subject_end int unsigned,E_value double, score int unsigned, identity float)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        expLIndex = ["qname", "qstart", "qend", "sname", "sstart", "send", "qcoord", "qcoord"]
+        
+        self._iDb.createIndex(tableName, "align")
+        
+        sqlCmd = "SHOW INDEX FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        results = self._iDb.cursor.fetchall()
+        
+        for index in expLIndex[:-1]:
+            sqlCmd = "DROP INDEX %s ON %s" % ( index, tableName )
+            self._iDb.execute( sqlCmd )
+        self._iDb.dropTable(tableName)
+        
+        obsLIndex = []
+        for tuple in results:
+            obsLIndex.append(tuple[2])
+            
+        self.assertEquals( expLIndex, obsLIndex)
+        
+    def test_createIndex_align_qstart_index_already_exist(self):
+        tableName = "dummyAlignTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( query_name varchar(255), query_start int, query_end int,subject_name varchar(255), subject_start int unsigned, subject_end int unsigned,E_value double, score int unsigned, identity float)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE INDEX qstart ON %s ( query_start );" % (tableName)
+        self._iDb.execute( sqlCmd )
+        expLIndex = ["qstart", "qname", "qend", "sname", "sstart", "send", "qcoord", "qcoord"]
+        
+        self._iDb.createIndex(tableName, "align")
+        
+        sqlCmd = "SHOW INDEX FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        results = self._iDb.cursor.fetchall()
+        
+        for index in expLIndex[:-1]:
+            sqlCmd = "DROP INDEX %s ON %s" % ( index, tableName )
+            self._iDb.execute( sqlCmd )
+        self._iDb.dropTable(tableName)
+        
+        obsLIndex = []
+        for tuple in results:
+            obsLIndex.append(tuple[2])
+            
+        self.assertEquals( expLIndex, obsLIndex)
+        
+    def test_createTable_align( self ):
+        tableName = "dummyAlignTable" + self._uniqId
+        alignFileName = "dummyAlignFile.txt"
+        alignF = open( alignFileName, "w" )
+        alignF.write( "query1\t1\t100\tsubject1\t1\t150\t0.5\t15\t35\n" )
+        alignF.write( "query2\t1\t100\tsubject2\t1\t150\t0.5\t15\t35\n" )
+        alignF.close()
+        
+        expAlignTuple1 = ("query1", 1L, 100L, "subject1", 1L, 150L, 0.5, 15L, 35)
+        expAlignTuple2 = ("query2", 1L, 100L, "subject2", 1L, 150L, 0.5, 15L, 35)
+        expTAlignTuples = (expAlignTuple1, expAlignTuple2)
+        
+        self._iDb.createTable( tableName, "align", alignFileName )
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTAlignTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(alignFileName)
+        
+        self.assertEquals( expTAlignTuples, obsTAlignTuples )
+        
+    def test_createIndex_set(self):
+        tableName = "dummySetTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( path int unsigned, name varchar(255), chr varchar(255), start int, end int)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        expLIndex = ["id", "iname", "ichr", "istart", "iend", "icoord", "icoord"]
+        
+        self._iDb.createIndex(tableName, "set")
+        
+        sqlCmd = "SHOW INDEX FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        results = self._iDb.cursor.fetchall()
+        
+        for index in expLIndex[:-1]:
+            sqlCmd = "DROP INDEX %s ON %s" % ( index, tableName )
+            self._iDb.execute( sqlCmd )
+        self._iDb.dropTable(tableName)
+
+        obsLIndex = []
+        for tuple in results:
+            obsLIndex.append(tuple[2])
+            
+        self.assertEquals( expLIndex, obsLIndex)
+        
+    def test_createIndex_set_id_index_already_exist(self):
+        tableName = "dummySetTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( path int unsigned, name varchar(255), chr varchar(255), start int, end int)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE INDEX id ON %s ( path );" % (tableName)
+        self._iDb.execute( sqlCmd )
+        expLIndex = ["id", "iname", "ichr", "istart", "iend", "icoord", "icoord"]
+        
+        self._iDb.createIndex(tableName, 'set')
+        
+        sqlCmd = "SHOW INDEX FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        results = self._iDb.cursor.fetchall()
+        
+        for index in expLIndex[:-1]:
+            sqlCmd = "DROP INDEX %s ON %s" % ( index, tableName )
+            self._iDb.execute( sqlCmd )
+        self._iDb.dropTable(tableName)
+        
+        obsLIndex = []
+        for tuple in results:
+            obsLIndex.append(tuple[2])
+            
+        self.assertEquals( expLIndex, obsLIndex)
+        
+    def test_createTable_set( self ):
+        tableName = "dummySetTable" + self._uniqId
+        setFileName = "dummySetFile.txt"
+        setF = open( setFileName, "w" )
+        setF.write( "15\tset1\tchr1\t1\t100\n" )
+        setF.write( "15\tset2\tchr2\t1\t100\n" )
+        setF.close()
+        
+        expSetTuple1 = (15L, "set1", "chr1", 1L, 100L)
+        expSetTuple2 = (15L, "set2", "chr2", 1L, 100L)
+        expTSetTuples = (expSetTuple1, expSetTuple2)
+        
+        self._iDb.createTable( tableName, 'set', setFileName )
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTSetTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(setFileName)
+        
+        self.assertEquals( expTSetTuples, obsTSetTuples )
+     
+    def test_convertMapTableIntoSetTable( self ):
+        mapTableName = "dummyMapTable" + self._uniqId
+        mapFileName = "dummyMapFile.txt"
+        with open(mapFileName, "w") as mapFH:
+            mapFH.write("map1\tchr1\t1\t100\n")
+            mapFH.write("map2\tchr2\t1\t100\n")
+            
+        self._iDb.createTable(mapTableName, 'map', mapFileName)
+        
+        expSetTuple1 = (1, "map1", "chr1", 1, 100)
+        expSetTuple2 = (2, "map2", "chr2", 1, 100)
+        expTSetTuples = (expSetTuple1, expSetTuple2)
+        
+        setTableName = "dummySetTable" + self._uniqId
+        self._iDb.convertMapTableIntoSetTable(mapTableName, setTableName)
+        
+        sqlCmd = "SELECT * FROM %s" % setTableName
+        self._iDb.execute(sqlCmd)
+        obsTSetTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(mapTableName)
+        self._iDb.dropTable(setTableName)
+        os.remove(mapFileName)
+        
+        self.assertEquals( expTSetTuples, obsTSetTuples )
+       
+    def test_createIndex_seq(self):
+        tableName = "dummySeqTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( accession varchar(255), sequence longtext, description varchar(255), length int unsigned)" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        expLIndex = ["iacc", "idescr"]
+        
+        self._iDb.createIndex(tableName,'seq')
+        
+        sqlCmd = "SHOW INDEX FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        results = self._iDb.cursor.fetchall()
+        
+        for index in expLIndex:
+            sqlCmd = "DROP INDEX %s ON %s" % ( index, tableName )
+            self._iDb.execute( sqlCmd )
+        self._iDb.dropTable(tableName)
+        
+        obsLIndex = []
+        for tuple in results:
+            obsLIndex.append(tuple[2])
+            
+        self.assertEquals(expLIndex, obsLIndex)
+   
+    def test_createIndex_seq_idescr_index_already_exist(self):
+        tableName = "dummySeqTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( accession varchar(255), sequence longtext, description varchar(255), length int unsigned);" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE INDEX idescr ON %s ( description(10) );" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        expLIndex = ["idescr", "iacc"]
+        
+        self._iDb.createIndex(tableName,'seq')
+        
+        sqlCmd = "SHOW INDEX FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        results = self._iDb.cursor.fetchall()
+        
+        for index in expLIndex:
+            sqlCmd = "DROP INDEX %s ON %s" % ( index, tableName )
+            self._iDb.execute( sqlCmd )
+        self._iDb.dropTable(tableName)
+        
+        obsLIndex = []
+        for tuple in results:
+            obsLIndex.append(tuple[2])
+            
+        self.assertEquals(expLIndex, obsLIndex)
+        
+    def test_createTable_seq( self ):
+        tableName = "dummySeqTable" + self._uniqId
+        seqFileName = "dummySeqFile.txt"
+        seqF = open( seqFileName, "w" )
+        seqF.write( ">acc1 seq1\n" )
+        seqF.write( "ATACTTCGCTAGCTCGC\n" )
+        seqF.write( ">acc2 seq2\n" )
+        seqF.write( "ATACTTCGCTAGCTCGCATACTTCGCTAGCTCGCATACTTCGCTAGCTCGCATACTTCGCTAGCTCGC\n" )
+        seqF.close()
+        
+        expSeqTuple1 = ("acc1", "ATACTTCGCTAGCTCGC", "acc1 seq1", 17L)
+        expSeqTuple2 = ("acc2", "ATACTTCGCTAGCTCGCATACTTCGCTAGCTCGCATACTTCGCTAGCTCGCATACTTCGCTAGCTCGC", "acc2 seq2", 68L)
+        expTSeqTuples = (expSeqTuple1, expSeqTuple2)
+        
+        self._iDb.createTable( tableName,'seq', seqFileName )
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTSeqTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(seqFileName)
+        
+        self.assertEquals( expTSeqTuples, obsTSeqTuples )
+    
+    def test_createIndex_job(self):
+        tableName = "dummyTable%s" % self._uniqId
+        sqlCmd = "CREATE TABLE %s" % tableName
+        sqlCmd += " ( jobid INT UNSIGNED"
+        sqlCmd += ", jobname VARCHAR(255)"
+        sqlCmd += ", groupid VARCHAR(255)"
+        sqlCmd += ", command TEXT"
+        sqlCmd += ", launcher VARCHAR(1024)"
+        sqlCmd += ", queue VARCHAR(255)"
+        sqlCmd += ", status VARCHAR(255)"
+        sqlCmd += ", time DATETIME"
+        sqlCmd += ", node VARCHAR(255) )"
+        self._iDb.execute(sqlCmd)
+        expLIndex = ["ijobid", "ijobname", "igroupid", "istatus"]
+        
+        self._iDb.createIndex(tableName, 'jobs')
+        
+        sqlCmd = "SHOW INDEX FROM %s" % tableName
+        self._iDb.execute(sqlCmd)
+        results = self._iDb.cursor.fetchall()
+        
+        obsLIndex = []
+        for tuple in results:
+            obsLIndex.append(tuple[2])
+        
+        for index in obsLIndex:
+            sqlCmd = "DROP INDEX %s ON %s" % (index, tableName)
+            self._iDb.execute(sqlCmd)
+        self._iDb.dropTable(tableName)
+            
+        self.assertEquals(expLIndex, obsLIndex)
+ 
+    def test_createTable_job( self ):
+        tableName = "dummyTable%s" % self._uniqId
+        expTuples = ()
+        
+        self._iDb.createTable(tableName,'jobs')
+        
+        sqlCmd = "SELECT * FROM %s" % tableName
+        self._iDb.execute(sqlCmd)
+        obsTuples = self._iDb.cursor.fetchall()
+        self._iDb.dropTable(tableName)
+        
+        self.assertEquals(expTuples, obsTuples)
+      
+    def test_createIndex_length(self):
+        tableName = "dummyTable%s" % self._uniqId
+        sqlCmd = "CREATE TABLE %s (accession varchar(255), length int unsigned)" % tableName
+        self._iDb.execute(sqlCmd)
+        expLIndex = ["iacc", "ilength"]
+        
+        self._iDb.createIndex(tableName,'length')
+        
+        sqlCmd = "SHOW INDEX FROM %s" % tableName
+        self._iDb.execute(sqlCmd)
+        results = self._iDb.cursor.fetchall()
+        
+        obsLIndex = []
+        for tuple in results:
+            obsLIndex.append(tuple[2])
+        
+        for index in obsLIndex:
+            sqlCmd = "DROP INDEX %s ON %s" % (index, tableName)
+            self._iDb.execute(sqlCmd)
+        self._iDb.dropTable(tableName)
+            
+        self.assertEquals(expLIndex, obsLIndex)
+
+    def test_createTable_length( self ):
+        tableName = "dummyLengthTable%s" % self._uniqId
+        seqFileName = "dummyFile.fa"
+        seqF = open( seqFileName, "w" )
+        seqF.write(">acc1 seq1\n")
+        seqF.write("ATACTTCGCTAGCTCGC\n")
+        seqF.write(">acc2 seq2\n")
+        seqF.write("ATACTTCGCTAGCTCGCATACTTCGCTAGCTCGCATACTTCGCTAGCTCGCATACTTCGCTAGCTCGC\n")
+        seqF.close()
+        
+        expTuple1 = ("acc1", 17)
+        expTuple2 = ("acc2", 68)
+        expTTuples = (expTuple1, expTuple2)
+        
+        self._iDb.createTable(tableName, "length", seqFileName)
+        
+        sqlCmd = "SELECT * FROM %s" % tableName
+        self._iDb.execute(sqlCmd)
+        obsTTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(seqFileName)
+        
+        self.assertEquals(expTTuples, obsTTuples)
+        
+    def test_createTable_with_overwrite_Map( self ):
+        tableName = "dummyMapTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( dummyColumn varchar(255) )" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        
+        fileName = "dummyMapFile.txt"
+        mapF = open( fileName, "w" )
+        mapF.write( "map1\tseq1\t20\t50\n" )
+        mapF.write( "map2\tseq2\t700\t760\n" )
+        mapF.close()
+        
+        expMapTuple1 = ("map1", "seq1", 20L, 50L)
+        expMapTuple2 = ("map2", "seq2", 700L, 760L)
+        expTMapTuples = (expMapTuple1, expMapTuple2)
+        
+        self._iDb.createTable(tableName, "Map", fileName, True)
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTMapTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(fileName)
+        
+        self.assertEquals( expTMapTuples, obsTMapTuples )
+        
+    def test_createTable_without_overwrite_Align( self ):
+        tableName = "dummyAlignTable" + self._uniqId
+        alignFileName = "dummyAlignFile.txt"
+        alignF = open( alignFileName, "w" )
+        alignF.write( "query1\t1\t100\tsubject1\t1\t150\t0.5\t15\t35\n" )
+        alignF.write( "query2\t1\t100\tsubject2\t1\t150\t0.5\t15\t35\n" )
+        alignF.close()
+        
+        expAlignTuple1 = ("query1", 1L, 100L, "subject1", 1L, 150L, 0.5, 15L, 35)
+        expAlignTuple2 = ("query2", 1L, 100L, "subject2", 1L, 150L, 0.5, 15L, 35)
+        expTAlignTuples = (expAlignTuple1, expAlignTuple2)
+        
+        self._iDb.createTable(tableName, "align", alignFileName, False)
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTAlignTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(alignFileName)
+        
+        self.assertEquals( expTAlignTuples, obsTAlignTuples )
+        
+    def test_createTable_without_overwrite_Match( self ):
+        tableName = "dummyMatchTable" + self._uniqId
+        matchFileName = "dummyMatchFile.txt"
+        matchF = open( matchFileName, "w" )
+        matchF.write( "qry1\t700\t760\t60\t100\t100\tsbj2\t500\t560\t60\t100\t1e-123\t136\t98.4\t2\n" )
+        matchF.write( "qry2\t700\t760\t60\t100\t100\tsbj2\t500\t560\t60\t100\t1e-123\t136\t98.4\t2\n" )
+        matchF.close()
+        
+        expMatchTuple = ("qry2", 700L, 760L, 60L, 100.0, 100.0, "sbj2", 500L, 560L, 60L, 100.0, 1e-123, 136L, 98.4, 2L)
+        expTMatchTuples = (expMatchTuple,)
+        
+        self._iDb.createTable(tableName, "tab", matchFileName, False)
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTMatchTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(matchFileName)
+        
+        self.assertEquals( expTMatchTuples, obsTMatchTuples )
+        
+    def test_createTable_without_overwrite_Path( self ):
+        tableName = "dummyPathTable" + self._uniqId
+        pathFileName = "dummyPathFile.txt"
+        pathF = open( pathFileName, "w" )
+        pathF.write( "1\tqry\t1\t100\tsbj\t1\t100\t1e-123\t136\t98.4\n" )
+        pathF.write( "2\tqry\t500\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        pathF.close()
+        
+        expPathTuple1 = (1L, "qry", 1L, 100L, "sbj", 1L, 100L, 1e-123, 136L, 98.4)
+        expPathTuple2 = (2L, "qry", 401L, 500L, "sbj", 100L, 1L, 1e-152, 161L, 98.7)  # change coordinates
+        expTPathTuples = (expPathTuple1, expPathTuple2)
+        
+        self._iDb.createTable(tableName, "Path", pathFileName, False)
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTPathTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(pathFileName)
+        
+        self.assertEquals( expTPathTuples, obsTPathTuples )
+        
+    def test_createTable_without_overwrite_Set( self ):
+        tableName = "dummySetTable" + self._uniqId
+        setFileName = "dummySetFile.txt"
+        setF = open( setFileName, "w" )
+        setF.write( "15\tset1\tchr1\t1\t100\n" )
+        setF.write( "15\tset2\tchr2\t1\t100\n" )
+        setF.close()
+        
+        expSetTuple1 = (15L, "set1", "chr1", 1L, 100L)
+        expSetTuple2 = (15L, "set2", "chr2", 1L, 100L)
+        expTSetTuples = (expSetTuple1, expSetTuple2)
+        
+        self._iDb.createTable(tableName, "Set", setFileName, False)
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTSetTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(setFileName)
+        
+        self.assertEquals( expTSetTuples, obsTSetTuples )  
+        
+    def test_createTable_without_overwrite_Seq( self ):
+        tableName = "dummySeqTable" + self._uniqId
+        seqFileName = "dummySeqFile.txt"
+        seqF = open( seqFileName, "w" )
+        seqF.write( ">acc1 seq1\n" )
+        seqF.write( "ATACTTCGCTAGCTCGC\n" )
+        seqF.write( ">acc2 seq2\n" )
+        seqF.write( "ATACTTCGCTAGCTCGCATACTTCGCTAGCTCGCATACTTCGCTAGCTCGCATACTTCGCTAGCTCGC\n" )
+        seqF.close()
+        
+        expSeqTuple1 = ("acc1", "ATACTTCGCTAGCTCGC", "acc1 seq1", 17L)
+        expSeqTuple2 = ("acc2", "ATACTTCGCTAGCTCGCATACTTCGCTAGCTCGCATACTTCGCTAGCTCGCATACTTCGCTAGCTCGC", "acc2 seq2", 68L)
+        expTSeqTuples = (expSeqTuple1, expSeqTuple2)
+        
+        self._iDb.createTable(tableName, "fasta", seqFileName, False)
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTSeqTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(seqFileName)
+        
+        self.assertEquals( expTSeqTuples, obsTSeqTuples )
+        
+    def test_createTable_with_overwrite_Classif( self ):
+        tableName = "dummyClassifTable" + self._uniqId
+        classifFileName = "dummyClassifFile.txt"
+        with open( classifFileName, "w" ) as f:
+            f.write("RIX-incomp-chim_DmelCaf1_2_0-B-G1000-Map3\t3508\t-\tPotentialChimeric\tI\tLINE\tincomplete\tCI=36; coding=(TE_BLRtx: DMCR1A:ClassI:LINE:Jockey: 14.16%); struct=(TElength: >700bps)\n")
+            f.write("RLX-incomp_DmelCaf1_2_0-B-G1019-Map3\t4131\t+\tok\tI\tLTR\tincomplete\tCI=28; coding=(TE_BLRtx: ROO_I:ClassI:LTR:Bel-Pao: 43.27%, ROO_LTR:ClassI:LTR:Bel-Pao: 100.00%; TE_BLRx: BEL-6_DWil-I_2p:ClassI:LTR:Bel-Pao: 69.84%); struct=(TElength: >4000bps); other=(HG_BLRn: FBtr0087866_Dmel_r4.3: 4.72%; SSRCoverage=0.15<0.75)\n")
+        
+        self._iDb.createTable(tableName, "Classif", classifFileName, True)
+        
+        self.assertTrue(self._iDb.getSize(tableName) == 2)
+        self._iDb.dropTable(tableName)
+        os.remove(classifFileName)
+        
+    def test_createTable_no_file( self ):
+        lTypesToTest = TABLE_SCHEMA_DESCRIPTOR.keys()
+        lTypesToTest.extend(TABLE_TYPE_SYNONYMS)
+        for tableType in lTypesToTest:
+            tableName = "dummy%sTable%s" % (tableType, self._uniqId)
+            self._iDb.createTable(tableName, tableType)
+            
+            self.assertTrue(self._iDb.doesTableExist(tableName))
+            self.assertTrue(self._iDb.isEmpty(tableName))
+            
+            self._iDb.dropTable(tableName)
+        
+    def test_changePathQueryCoordinatesToDirectStrand(self):
+        tableName = "dummyPathTable" + self._uniqId
+        pathFileName = "dummyPathFile.txt"
+        pathF = open( pathFileName, "w" )
+        pathF.write( "1\tqry\t100\t1\tsbj\t1\t100\t1e-123\t136\t98.4\n" )
+        pathF.write( "2\tqry\t500\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        pathF.write( "3\tqry\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        pathF.close()
+        
+        expPathTuple1 = (1L, "qry", 1L, 100L, "sbj", 100L, 1L, 1e-123, 136L, 98.4)
+        expPathTuple2 = (2L, "qry", 401L, 500L, "sbj", 100L, 1L, 1e-152, 161L, 98.7)  
+        expPathTuple3 = (3L, "qry", 5L, 401L, "sbj", 1L, 100L, 1e-152, 161L, 98.7)  
+        expTPathTuples = (expPathTuple1, expPathTuple2, expPathTuple3)
+
+        sqlCmd = "CREATE TABLE %s ( path int unsigned, query_name varchar(255), query_start int , query_end int, subject_name varchar(255), subject_start int unsigned, subject_end int unsigned, E_value double, score int unsigned, identity float)" % tableName
+        self._iDb.execute( sqlCmd )
+        
+        self._iDb.loadDataFromFile(tableName, pathFileName, False)
+        self._iDb.changePathQueryCoordinatesToDirectStrand(tableName)
+        
+        sqlCmd = "SELECT * FROM %s" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        obsTPathTuples = self._iDb.cursor.fetchall()
+        
+        self._iDb.dropTable(tableName)
+        os.remove(pathFileName)
+        
+        self.assertEquals( expTPathTuples, obsTPathTuples )
+        
+    def test_exportDataToFile(self):
+        tableName = "dummyPathTable" + self._uniqId
+        expFileName = "dummyPathFile.txt"
+        pathF = open( expFileName, "w" )
+        pathF.write( "1\tqry\t1\t100\tsbj\t100\t1\t1e-123\t136\t98.4\n" )
+        pathF.write( "2\tqry\t401\t500\tsbj\t100\t1\t1e-152\t161\t98.7\n" )
+        pathF.write( "3\tqry\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        pathF.close()
+        self._iDb.createTable(tableName, "Path", expFileName, False)
+        obsFileName = "DummyObsFileName"
+        
+        self._iDb.exportDataToFile(tableName, obsFileName)
+        
+        self.assertTrue(FileUtils.isRessourceExists(obsFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        self._iDb.dropTable(tableName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_exportDataToFile_keepFirstLineTrue(self):
+        tableName = "dummyPathTable" + self._uniqId
+        pathFileName = "dummyPathFile.txt"
+        pathF = open( pathFileName, "w" )
+        pathF.write( "1\tqry\t1\t100\tsbj\t100\t1\t1e-123\t136\t98.4\n" )
+        pathF.write( "2\tqry\t401\t500\tsbj\t100\t1\t1e-152\t161\t98.7\n" )
+        pathF.write( "3\tqry\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        pathF.close()
+        
+        expFileName = "expPathFile.txt"
+        pathF = open( expFileName, "w" )
+        pathF.write("path\tquery_name\tquery_start\tquery_end\tsubject_name\tsubject_start\tsubject_end\tE_value\tscore\tidentity\n")
+        pathF.write( "1\tqry\t1\t100\tsbj\t100\t1\t1e-123\t136\t98.4\n" )
+        pathF.write( "2\tqry\t401\t500\tsbj\t100\t1\t1e-152\t161\t98.7\n" )
+        pathF.write( "3\tqry\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        pathF.close()
+        
+        self._iDb.createTable(tableName, "Path", pathFileName, False)
+        obsFileName = "DummyObsFileName"
+        
+        self._iDb.exportDataToFile(tableName, obsFileName, True)
+        
+        self.assertTrue(FileUtils.isRessourceExists(obsFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        self._iDb.dropTable(tableName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        os.remove(pathFileName)
+        
+    def test_exportDataToFile_with_keepFirstLineTrue_and_param(self):
+        tableName = "dummyPathTable" + self._uniqId
+        pathFileName = "dummyPathFile.txt"
+        pathF = open( pathFileName, "w" )
+        pathF.write( "1\tqry\t1\t100\tsbj\t100\t1\t1e-123\t136\t98.4\n" )
+        pathF.write( "2\tqry2\t401\t500\tsbj\t100\t1\t1e-152\t161\t98.7\n" )
+        pathF.write( "3\tqry\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        pathF.close()
+        
+        expFileName = "expPathFile.txt"
+        pathF = open( expFileName, "w" )
+        pathF.write("path\tquery_name\tquery_start\tquery_end\tsubject_name\tsubject_start\tsubject_end\tE_value\tscore\tidentity\n")
+        pathF.write( "2\tqry2\t401\t500\tsbj\t100\t1\t1e-152\t161\t98.7\n" )
+        pathF.close()
+        
+        self._iDb.createTable(tableName, "Path", pathFileName, False)
+        obsFileName = "DummyObsFileName"
+        
+        self._iDb.exportDataToFile(tableName, obsFileName, True, "where query_name = 'qry2'")
+        
+        self.assertTrue(FileUtils.isRessourceExists(obsFileName))
+        self.assertTrue(FileUtils.are2FilesIdentical(expFileName, obsFileName))
+        
+        self._iDb.dropTable(tableName)
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        os.remove(pathFileName)
+        
+        
+    def test_convertPathTableIntoAlignTable( self ):
+        inPathTable = "dummyInPathTable_%s" % ( self._uniqId )
+        inPathFile = "dummyInPathFile_%s" % ( self._uniqId )
+        inPathFileHandler = open( inPathFile, "w" )
+        inPathFileHandler.write( "1\tqry\t1\t100\tsbj\t100\t1\t1e-123\t136\t98.4\n" )
+        inPathFileHandler.write( "2\tqry2\t401\t500\tsbj\t100\t1\t1e-152\t161\t98.7\n" )
+        inPathFileHandler.write( "3\tqry\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        inPathFileHandler.close()
+        self._iDb.createTable( inPathTable, "path", inPathFile, True )
+        
+        expAlignFile = "dummyExpAlignFile_%s" % ( self._uniqId )
+        expAlignFileHandler = open( expAlignFile, "w" )
+        expAlignFileHandler.write( "qry\t1\t100\tsbj\t100\t1\t1e-123\t136\t98.4\n" )
+        expAlignFileHandler.write( "qry2\t401\t500\tsbj\t100\t1\t1e-152\t161\t98.7\n" )
+        expAlignFileHandler.write( "qry\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        expAlignFileHandler.close()
+        obsAlignTable = "dummyObsAlignTable_%s" % ( self._uniqId )
+        
+        self._iDb.convertPathTableIntoAlignTable( inPathTable, obsAlignTable )
+        
+        obsAlignFile = "dummyObsAlignFile_%s" % ( self._uniqId )
+        self._iDb.exportDataToFile( obsAlignTable, obsAlignFile, False )
+        self.assertTrue( FileUtils.are2FilesIdentical( expAlignFile, obsAlignFile ) )
+        
+        for f in [ inPathFile, expAlignFile, obsAlignFile ]:
+            os.remove( f )
+        for t in [ inPathTable, obsAlignTable ]:
+            self._iDb.dropTable( t )
+            
+    def test_convertAlignTableIntoPathTable( self ):
+        inAlignTable = "dummyInPathTable_%s" % ( self._uniqId )
+        inAlignFile = "dummyInPathFile_%s" % ( self._uniqId )
+        inAlignFileHandler = open( inAlignFile, "w" )
+        inAlignFileHandler.write( "qry\t1\t100\tsbj\t100\t1\t1e-123\t136\t98.4\n" )
+        inAlignFileHandler.write( "qry2\t401\t500\tsbj\t100\t1\t1e-152\t161\t98.7\n" )
+        inAlignFileHandler.write( "qry3\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        inAlignFileHandler.close()
+        self._iDb.createTable( inAlignTable, "align", inAlignFile, True )
+        
+        expPathFile = "dummyExpPathFile_%s" % ( self._uniqId )
+        expPathFileHandler = open( expPathFile, "w" )
+        expPathFileHandler.write( "1\tqry\t1\t100\tsbj\t100\t1\t1e-123\t136\t98.4\n" )
+        expPathFileHandler.write( "2\tqry2\t401\t500\tsbj\t100\t1\t1e-152\t161\t98.7\n" )
+        expPathFileHandler.write( "3\tqry3\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        expPathFileHandler.close()
+        obsPathTable = "dummyObsPathTable_%s" % ( self._uniqId )
+        
+        self._iDb.convertAlignTableIntoPathTable( inAlignTable, obsPathTable )
+        
+        obsPathFile = "dummyObsAlignFile_%s" % ( self._uniqId )
+        self._iDb.exportDataToFile( obsPathTable, obsPathFile, False )
+        self.assertTrue( FileUtils.are2FilesIdentical( expPathFile, obsPathFile ) )
+        
+        for f in [ inAlignFile, expPathFile, obsPathFile ]:
+            os.remove( f )
+        for t in [ inAlignTable, obsPathTable ]:
+            self._iDb.dropTable( t )
+            
+    def test_convertAlignTableIntoPathTable_with_single_quote( self ):
+        inAlignTable = "dummyInPathTable_%s" % ( self._uniqId )
+        inAlignFile = "dummyInPathFile_%s" % ( self._uniqId )
+        inAlignFileHandler = open( inAlignFile, "w" )
+        inAlignFileHandler.write( "qry\t1\t100\t'sbj\t100\t1\t1e-123\t136\t98.4\n" )
+        inAlignFileHandler.write( "qry2\t401\t500\tsbj'\t100\t1\t1e-152\t161\t98.7\n" )
+        inAlignFileHandler.write( "qry3\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        inAlignFileHandler.close()
+        self._iDb.createTable( inAlignTable, "align", inAlignFile, True )
+        
+        expPathFile = "dummyExpPathFile_%s" % ( self._uniqId )
+        expPathFileHandler = open( expPathFile, "w" )
+        expPathFileHandler.write( "1\tqry\t1\t100\t'sbj\t100\t1\t1e-123\t136\t98.4\n" )
+        expPathFileHandler.write( "2\tqry2\t401\t500\tsbj'\t100\t1\t1e-152\t161\t98.7\n" )
+        expPathFileHandler.write( "3\tqry3\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        expPathFileHandler.close()
+        obsPathTable = "dummyObsPathTable_%s" % ( self._uniqId )
+        
+        self._iDb.convertAlignTableIntoPathTable( inAlignTable, obsPathTable )
+        
+        obsPathFile = "dummyObsAlignFile_%s" % ( self._uniqId )
+        self._iDb.exportDataToFile( obsPathTable, obsPathFile, False )
+        self.assertTrue( FileUtils.are2FilesIdentical( expPathFile, obsPathFile ) )
+        
+        for f in [ inAlignFile, expPathFile, obsPathFile ]:
+            os.remove( f )
+        for t in [ inAlignTable, obsPathTable ]:
+            self._iDb.dropTable( t )
+          
+    def test_getObjectListWithSQLCmd(self):
+        inPathTable = "dummyInPathTable_%s" % ( self._uniqId )
+        inPathFile = "dummyInPathFile_%s" % ( self._uniqId )
+        inPathFileHandler = open( inPathFile, "w" )
+        inPathFileHandler.write( "1\tqry\t100\t1\tsbj\t1\t100\t1e-123\t136\t98.4\n" )
+        inPathFileHandler.write( "2\tqry\t500\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        inPathFileHandler.write( "3\tqry\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        inPathFileHandler.close()
+        self._iDb.createTable( inPathTable, "path", inPathFile, True )
+        
+        path1 = Path()
+        path1.setFromTuple((1, "qry", 1, 100, "sbj", 100, 1, 1e-123, 136, 98.4))
+        path2 = Path()
+        path2.setFromTuple((2, "qry", 401, 500, "sbj", 100, 1, 1e-152, 161, 98.7))
+        path3 = Path()  
+        path3.setFromTuple((3, "qry", 5, 401, "sbj", 1, 100, 1e-152, 161, 98.7))
+        expLPath = [path1, path2, path3]
+        sqlCmd = "SELECT * FROM %s;" % (inPathTable)
+        obsLPath = self._iDb.getObjectListWithSQLCmd(sqlCmd, self._getInstanceToAdapt)
+        
+        os.remove( inPathFile )
+        self._iDb.dropTable( inPathTable )
+        
+        self.assertEquals(expLPath, obsLPath)
+    
+    def test_getIntegerListWithSQLCmd(self):
+        inPathTable = "dummyInPathTable_%s" % ( self._uniqId )
+        inPathFile = "dummyInPathFile_%s" % ( self._uniqId )
+        inPathFileHandler = open( inPathFile, "w" )
+        inPathFileHandler.write( "1\tqry\t100\t1\tsbj\t1\t100\t1e-123\t136\t98.4\n" )
+        inPathFileHandler.write( "2\tqry\t500\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        inPathFileHandler.write( "3\tqry\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        inPathFileHandler.close()
+        self._iDb.createTable( inPathTable, "path", inPathFile, True )
+        
+        expLPath = [1, 2, 3]
+        sqlCmd = "SELECT * FROM %s;" % (inPathTable)
+        obsLPath = self._iDb.getIntegerListWithSQLCmd(sqlCmd)
+        
+        os.remove( inPathFile )
+        self._iDb.dropTable( inPathTable )
+        
+        self.assertEquals(expLPath, obsLPath)
+    
+    def test_getIntegerWithSQLCmd(self):
+        inPathTable = "dummyInPathTable_%s" % ( self._uniqId )
+        inPathFile = "dummyInPathFile_%s" % ( self._uniqId )
+        inPathFileHandler = open( inPathFile, "w" )
+        inPathFileHandler.write( "1\tqry\t100\t1\tsbj\t1\t100\t1e-123\t136\t98.4\n" )
+        inPathFileHandler.write( "2\tqry\t500\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        inPathFileHandler.write( "3\tqry\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        inPathFileHandler.close()
+        self._iDb.createTable( inPathTable, "path", inPathFile, True )
+        
+        expId = 1
+        sqlCmd = "SELECT path FROM %s where path='%d';" % (inPathTable, 1)
+        obsId = self._iDb.getIntegerWithSQLCmd(sqlCmd)
+        
+        os.remove( inPathFile )
+        self._iDb.dropTable( inPathTable )
+        
+        self.assertEquals(expId, obsId)
+    
+    def test_getStringListWithSQLCmd(self):
+        inPathTable = "dummyInPathTable_%s" % ( self._uniqId )
+        inPathFile = "dummyInPathFile_%s" % ( self._uniqId )
+        inPathFileHandler = open( inPathFile, "w" )
+        inPathFileHandler.write( "1\tqry\t100\t1\tsbj\t1\t100\t1e-123\t136\t98.4\n" )
+        inPathFileHandler.write( "2\tqry\t500\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        inPathFileHandler.write( "3\tqry\t5\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        inPathFileHandler.close()
+        self._iDb.createTable( inPathTable, "path", inPathFile, True )
+        
+        expLString = ["qry","qry","qry"]
+        sqlCmd = "SELECT query_name FROM %s;" % (inPathTable)
+        obsLString = self._iDb.getStringListWithSQLCmd(sqlCmd)
+        
+        os.remove( inPathFile )
+        self._iDb.dropTable( inPathTable )
+        
+        self.assertEquals(expLString, obsLString)
+        
+    def test_removeDoublons( self ):
+        inPathTable = "dummyInPathTable_%s" % ( self._uniqId )
+        inPathFile = "dummyInPathFile_%s" % ( self._uniqId )
+        inPathFileHandler = open( inPathFile, "w" )
+        inPathFileHandler.write( "1\tqry\t1\t100\tsbj\t1\t100\t1e-123\t136\t98.4\n" )
+        inPathFileHandler.write( "2\tqry\t401\t500\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        inPathFileHandler.write( "2\tqry\t401\t500\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        inPathFileHandler.close()
+        self._iDb.createTable( inPathTable, "path", inPathFile, True )
+        
+        expFile = "dummyExpFile_%s" % ( self._uniqId )
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "1\tqry\t1\t100\tsbj\t1\t100\t1e-123\t136\t98.4\n" )
+        expFileHandler.write( "2\tqry\t401\t500\tsbj\t1\t100\t1e-152\t161\t98.7\n" )
+        expFileHandler.close()
+        
+        self._iDb.removeDoublons( inPathTable )
+        
+        obsFile = "dummyObsFile_%s" % ( self._uniqId )
+        self._iDb.exportDataToFile(inPathTable, obsFile)
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, obsFile ) )
+        
+        self._iDb.dropTable( inPathTable )
+        for f in [ inPathFile, expFile, obsFile ]:
+            os.remove( f )
+            
+    def test_getTableListFromPattern_oneTable( self ):
+        inTable = "dummyInTable_%s" % ( self._uniqId )
+        self._iDb.createTable( inTable, "path", "", True )
+        exp = [ inTable ]
+        obs = self._iDb.getTableListFromPattern( "%s%%" % inTable )
+        self.assertEqual( exp, obs )
+        self._iDb.dropTable( inTable )
+        
+    def test_getTableListFromPattern_twoTables( self ):
+        inTable1 = "dummyInTable1_%s" % ( self._uniqId )
+        inTable2 = "dummyInTable2_%s" % ( self._uniqId )
+        inTable3 = "dummyTotoTable3_%s" % ( self._uniqId )
+        for table in [ inTable1, inTable2, inTable3 ]:
+            self._iDb.createTable( table, "path", "", True )
+        exp = [ inTable1, inTable2 ]
+        obs = self._iDb.getTableListFromPattern( "dummyInTable%%_%s" % self._uniqId )
+        self.assertEqual( exp, obs )
+        for table in [ inTable1, inTable2, inTable3 ]:
+            self._iDb.dropTable( table )
+            
+    def test_createPathStatTable(self):
+        statsFileName = "DmelCaf1_statsPerClassif.txt"
+        f = open (statsFileName, "w")
+        f.write("family\tmaxLength\tmeanLength\tcovg\tfrags\tfullLgthFrags\tcopies\tfullLgthCopies\tmeanId\tsdId\tminId\tq25Id\tmedId\tq75Id\tmaxId\tmeanLgth\tsdLgth\tminLgth\tq25Lgth\tmedLgth\tq75Lgth\tmaxLgth\tmeanLgthPerc\tsdLgthPerc\tminLgthPerc\tq25LgthPerc\tmedLgthPerc\tq75LgthPerc\tmaxLgthPerc\n")
+        f.write("Helitron\t2367\t2367\t138367\t852\t0\t803\t0\t81.20\t4.24\t68.55\t78.32\t81.03\t83.49\t100.00\t172.46\t184.92\t21\t70.00\t129.00\t216.00\t2202\t7.29\t7.81\t0.89\t2.96\t5.45\t9.13\t93.03\n")
+        f.write("LINE\t7688\t7688\t3769377\t8358\t10\t6329\t10\t85.52\t8.02\t62.80\t79.27\t83.33\t92.88\t100.00\t597.97\t980.29\t21\t117.00\t256.00\t537.00\t7726\t7.78\t12.75\t0.27\t1.52\t3.33\t6.98\t100.49\n")
+        f.write("LTR\t13754\t13754\t9146587\t20749\t0\t17868\t1\t82.69\t7.39\t58.76\t77.81\t80.82\t85.67\t100.00\t519.75\t1217.12\t20\t105.00\t183.50\t336.00\t13738\t3.78\t8.85\t0.15\t0.76\t1.33\t2.44\t99.88\n")
+        f.write("MITE\t378\t378\t2890\t10\t3\t9\t3\t98.78\t1.20\t95.80\t98.64\t99.18\t99.46\t99.73\t325.33\t47.86\t253\t290.00\t333.00\t362.00\t390\t86.07\t12.66\t66.93\t76.72\t88.10\t95.77\t103.17\n")
+        f.write("NoCat\t9999\t9999\t384076\t1297\t1\t1219\t1\t82.60\t6.73\t61.20\t78.37\t81.41\t85.29\t100.00\t323.01\t686.85\t21\t64.00\t139.00\t280.00\t10000\t3.23\t6.87\t0.21\t0.64\t1.39\t2.80\t100.01\n")
+        f.write("SSR\t680\t680\t325152\t2340\t24\t2290\t28\t79.07\t3.60\t69.19\t76.64\t79.02\t81.10\t97.83\t221.64\t139.84\t21\t121.00\t183.00\t285.00\t799\t32.59\t20.57\t3.09\t17.79\t26.91\t41.91\t117.50\n")
+        f.write("TIR\t2532\t2532\t700173\t2503\t5\t2160\t5\t84.70\t7.43\t64.03\t79.46\t82.77\t90.09\t100.00\t326.54\t405.94\t21\t90.00\t187.00\t342.00\t2758\t12.90\t16.03\t0.83\t3.55\t7.39\t13.51\t108.93\n")
+        f.write("confused\t19419\t19419\t1299224\t3903\t0\t3311\t0\t82.30\t6.34\t63.20\t78.17\t80.81\t84.58\t100.00\t408.22\t989.57\t21\t113.00\t207.00\t339.00\t17966\t2.10\t5.10\t0.11\t0.58\t1.07\t1.75\t92.52\n")
+        f.close()
+        tableName = "dummyDmelCaf1_chr_allTEs_nr_noSSR_join_path_statsPerClassif"
+        self._iDb.createTable(tableName, "pathstat", statsFileName)
+        
+        self.assertTrue(self._iDb.doesTableExist(tableName))
+        
+        expSize = 8
+        obsSize = self._iDb.getSize(tableName)
+        self.assertEquals(expSize, obsSize)
+        
+        expColumnNb = 29
+        sqlCmd = "DESC %s;" % tableName
+        self._iDb.execute(sqlCmd)
+        res = self._iDb.fetchall()
+        obsColumnNb = len(res)
+        self.assertEquals(expColumnNb, obsColumnNb)
+        
+        self._iDb.dropTable(tableName)
+        os.remove(statsFileName)
+        
+    def test_createJobTable_is_table_created(self):
+        tableName = "dummyJobTable" + self._uniqId
+        self._iDb.createTable(tableName, "jobs")
+        self.assertTrue(self._iDb.doesTableExist(tableName))
+        self._iDb.dropTable(tableName)
+        
+    def test_createClassifTable(self):
+        tableName = "dummyClassifTable"
+        self._iDb.dropTable(tableName)        
+        fileName = "test.classif"
+        
+        with open(fileName, "w") as f:
+            f.write("RIX-incomp-chim_DmelCaf1_2_0-B-G1000-Map3\t3508\t-\tPotentialChimeric\tI\tLINE\tincomplete\tCI=36; coding=(TE_BLRtx: DMCR1A:ClassI:LINE:Jockey: 14.16%, FW3_DM:ClassI:LINE:Jockey: 15.07%; TE_BLRx: CR1-1_DWil_2p:ClassI:LINE:Jockey: 18.98%, FW2_DM-ORF1p:ClassI:LINE:Jockey: 22.36%, Jockey-1_DYa_1p:ClassI:LINE:Jockey: 11.86%); struct=(TElength: >700bps); other=(TE_BLRx: Gypsy7-I_Dmoj_1p:ClassI:LTR:Gypsy: 12.58%; HG_BLRn: FBtr0089196_Dmel_r4.3: 11.74%; SSRCoverage=0.12<0.75)\n")
+            f.write("RLX-incomp_DmelCaf1_2_0-B-G1019-Map3\t4131\t+\tok\tI\tLTR\tincomplete\tCI=28; coding=(TE_BLRtx: ROO_I:ClassI:LTR:Bel-Pao: 43.27%, ROO_LTR:ClassI:LTR:Bel-Pao: 100.00%; TE_BLRx: BEL-6_DWil-I_2p:ClassI:LTR:Bel-Pao: 69.84%); struct=(TElength: >4000bps); other=(HG_BLRn: FBtr0087866_Dmel_r4.3: 4.72%; SSRCoverage=0.15<0.75)\n")
+            f.write("RLX-incomp_DmelCaf1_2_0-B-G1025-Map3\t6534\t-\tok\tI\tLTR\tincomplete\tCI=28; coding=(TE_BLRtx: Gypsy2-I_Dmoj:ClassI:LTR:Gypsy: 11.82%, MDG3_DM:ClassI:LTR:Gypsy: 17.43%, STALKER2_LTR:ClassI:LTR:Gypsy: 14.62%, STALKER4_LTR:ClassI:LTR:Gypsy: 57.21%; TE_BLRx: Gypsy-16_DWil-I_1p:ClassI:LTR:Gypsy: 32.19%; profiles: PF00665.18_rve_INT_32.0: 68.64%); struct=(TElength: >4000bps); other=(HG_BLRn: FBtr0070036_Dmel_r4.3: 3.73%; TermRepeats: non-termLTR: 1701; SSRCoverage=0.14<0.75)\n")
+      
+        self._iDb.createTable(tableName, "classif", fileName)
+        self.assertTrue(self._iDb.doesTableExist(tableName))
+        
+        expColumnNb = 8
+        sqlCmd = "DESC %s;" % tableName
+        self._iDb.execute(sqlCmd)
+        res = self._iDb.fetchall()
+        obsColumnNb = len(res)
+        self.assertEquals(expColumnNb, obsColumnNb)
+        
+        expSize = 3
+        obsSize = self._iDb.getSize(tableName)
+        self.assertEquals(expSize, obsSize)
+        
+        expLIndex = ["iseq_name", "istatus", "iclass", "iorder", "icomp"]
+        sqlCmd = "SHOW INDEX FROM %s" % tableName
+        self._iDb.execute(sqlCmd)
+        res = self._iDb.cursor.fetchall()
+        obsLIndex = []
+        for tuple in res:
+            obsLIndex.append(tuple[2])
+        self.assertEquals(expLIndex, obsLIndex)
+  
+        self._iDb.dropTable(tableName)
+        os.remove(fileName)
+        
+    def test_createClassifIndex(self):
+        tableName = "dummyclassifTable%s" % self._uniqId
+        sqlCmd = "CREATE TABLE %s (seq_name varchar(255), length int unsigned, strand char, status varchar(255), class_classif varchar(255), order_classif varchar(255), completeness varchar(255), evidences text);" % tableName
+        self._iDb.execute(sqlCmd)
+        expLIndex = ["iseq_name", "istatus", "iclass", "iorder", "icomp"]
+        
+        self._iDb.createIndex(tableName, "classif")
+        
+        sqlCmd = "SHOW INDEX FROM %s" % tableName
+        self._iDb.execute(sqlCmd)
+        res = self._iDb.cursor.fetchall()
+        
+        obsLIndex = []
+        for tuple in res:
+            obsLIndex.append(tuple[2])
+        self.assertEquals(expLIndex, obsLIndex)
+        self._iDb.dropTable(tableName)
+
+    def test_createBinPathTable(self):
+        pathFileName = "dummy.path"
+        with open(pathFileName, "w") as pathF:
+            pathF.write("1\tqry\t1\t100\tsbj\t1\t100\t1e-123\t136\t98.4\n")
+            pathF.write("2\tqry\t500\t401\tsbj\t1\t100\t1e-152\t161\t98.7\n")
+        
+        expPathTuple1 = (1, 1000000, "qry", 1, 100, 1)
+        expPathTuple2 = (2, 1000000, "qry", 401, 500, 1)  # change coordinates
+        expTPathTuples = (expPathTuple1, expPathTuple2)
+        
+        pathTableName = "dummy_path"
+        idxTableName = "dummy_path_idx"
+        self._iDb.createTable(pathTableName, "path", pathFileName)
+        self._iDb.createBinPathTable(pathTableName, True)
+        
+        sqlCmd = "SELECT * FROM %s" % idxTableName
+        self._iDb.execute(sqlCmd)
+        obsTPathTuples = self._iDb.fetchall()
+        
+        self._iDb.dropTable(pathTableName)
+        self._iDb.dropTable(idxTableName)
+        os.remove(pathFileName)
+        
+        self.assertEquals(expTPathTuples, obsTPathTuples)
+
+    def test_createBinSetTable(self):
+        setFileName = "dummy.set"
+        with open(setFileName, "w") as setF:
+            setF.write("1\tseq1\tchr1\t1900\t3900\n")
+            setF.write("2\tseq2\tchr1\t2\t9\n")
+            setF.write("3\tseq3\tchr1\t8\t13\n")
+            
+        expTuple = ((1L, 10000.0, 'chr1', 1900L, 3900L, 1L), (2L, 1000.0, 'chr1', 2L, 9L, 1L), (3L, 1000.0, 'chr1', 8L, 13L, 1L))
+        
+        setTableName = "dummy_set"
+        idxTableName = "dummy_set_idx"
+        self._iDb.createTable(setTableName, "set", setFileName)
+        self._iDb.createBinSetTable(setTableName, True)
+        
+        sqlCmd = "SELECT * FROM %s" % idxTableName
+        self._iDb.execute(sqlCmd)
+        obsTuple = self._iDb.fetchall()
+        
+        self._iDb.dropTable(setTableName)
+        self._iDb.dropTable(idxTableName)
+        os.remove(setFileName)
+        
+        self.assertEquals(expTuple, obsTuple)
+
+    def _getInstanceToAdapt(self):
+        iPath = Path()
+        return iPath
+            
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_DbSQLite.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,162 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import time
+from commons.core.sql.DbSQLite import DbSQLite
+
+class Test_DbSQLite(unittest.TestCase):
+
+    def setUp( self ):
+        self._iDb = DbSQLite("test.db")
+        self._uniqId = "%s" % time.strftime("%Y%m%d%H%M%S")
+        
+    def tearDown( self ):
+        if self._iDb.open():
+            self._iDb.close()
+        self._iDb.delete()
+        self._iDb = None
+        
+    def test_open_True(self):
+        self._iDb.close()
+        self.assertTrue( self._iDb.open(1) )
+
+    def test_open_False(self):
+        self._iDb.close()
+        self._iDb.host = "/toto/toto.db"
+        self.assertFalse( self._iDb.open(1) )
+        self._iDb.host = "test.db"
+
+    def test_updateInfoTable(self):
+        tableName = "dummyTable" + self._uniqId
+        info = "Table_for_test"
+        
+        self._iDb.updateInfoTable(tableName, info)
+        
+        sqlCmd = 'SELECT file FROM info_tables WHERE name = "%s"' % ( tableName )
+        self._iDb.execute( sqlCmd )
+        results = self._iDb.fetchall()
+        obsResult = False
+        if (info,) in results:
+            obsResult = True
+            sqlCmd = 'DELETE FROM info_tables WHERE name = "%s"' % ( tableName )
+            self._iDb.execute( sqlCmd )
+            
+        self.assertTrue( obsResult )
+        
+    def test_doesTableExist_True(self):
+        tableName = "dummyTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( dummyColumn varchar(255) )" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        self.assertTrue( self._iDb.doesTableExist(tableName) )
+
+    def test_dropTable(self):
+        tableName = "dummyTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( dummyColumn varchar(255) )" % tableName
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE TABLE info_tables ( name varchar(255), file varchar(255) )"
+        self._iDb.execute( sqlCmd )
+        sqlCmd = 'INSERT INTO info_tables VALUES ("%s","")' % tableName
+        self._iDb.execute( sqlCmd )
+        
+        self._iDb.dropTable(tableName)
+        self.assertFalse( self._iDb.doesTableExist(tableName) )
+        
+    def test_doesTableExist_False(self):
+        tableName = "dummyTable" + self._uniqId
+        self.assertFalse( self._iDb.doesTableExist(tableName) )
+        
+    def test_createJobTable_is_table_created(self):
+        self._iDb.createTable("dummyJobTable", "jobs")
+        isTableCreated = self._iDb.doesTableExist("dummyJobTable")
+        self.assertTrue(isTableCreated)
+    
+    def test_createJobTable_field_list(self):
+        self._iDb.createTable("dummyJobTable", "jobs")
+        obsLFiled = self._iDb.getFieldList("dummyJobTable")
+        expLField = ["jobid", "jobname", "groupid", "command", "launcher", "queue", "status", "time", "node"]
+        self.assertEquals(expLField, obsLFiled)
+        
+    def test_createTable(self):
+        tableName = "dummyJobTable" + self._uniqId
+        self._iDb.createTable(tableName, "job")
+        obsLFiled = self._iDb.getFieldList(tableName)
+        expLField = ["jobid", "jobname", "groupid", "command", "launcher", "queue", "status", "time", "node"]
+        self.assertEquals(expLField, obsLFiled)
+        
+    def test_createTable_with_overwrite_Job(self):
+        tableName = "dummyJobTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( dummyColumn varchar(255) )" % tableName
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "CREATE TABLE info_tables ( name varchar(255), file varchar(255) )"
+        self._iDb.execute( sqlCmd )
+        sqlCmd = 'INSERT INTO info_tables VALUES ("%s","")' % tableName
+        self._iDb.execute( sqlCmd )
+        
+        self._iDb.createTable(tableName, "job", True)
+        obsLFiled = self._iDb.getFieldList(tableName)
+        expLField = ["jobid", "jobname", "groupid", "command", "launcher", "queue", "status", "time", "node"]
+        self.assertEquals(expLField, obsLFiled)
+        
+    def test_getSize_empty_table(self):
+        tableName = "dummyJobTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( dummyColumn varchar(255) )" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        expSize = 0
+        obsSize = self._iDb.getSize(tableName)
+        self.assertEquals( expSize, obsSize )
+        
+    def test_getSize_one_rows(self):
+        tableName = "dummyJobTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( dummyColumn varchar(255) )" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        sqlCmd = "INSERT INTO %s (dummyColumn) VALUES ('toto')" % tableName
+        self._iDb.execute( sqlCmd )
+        expSize = 1
+        obsSize = self._iDb.getSize(tableName)
+        self.assertEquals( expSize, obsSize )
+        
+    def test_isEmpty_True(self):
+        tableName = "dummyTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( dummyColumn varchar(255) )" % ( tableName )
+        self._iDb.execute( sqlCmd )
+        self.assertTrue(self._iDb.isEmpty(tableName))
+        
+    def test_isEmpty_False(self):
+        tableName = "dummyTable" + self._uniqId
+        sqlCmd = "CREATE TABLE %s ( dummyColumn varchar(255) )" % (tableName)
+        self._iDb.execute(sqlCmd)
+        sqlCmd = "INSERT INTO %s (dummyColumn) VALUES ('toto')" % tableName
+        self._iDb.execute(sqlCmd)
+        self.assertFalse(self._iDb.isEmpty(tableName))
+        
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_F_JobAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,91 @@
+from commons.core.launcher.WriteScript import WriteScript
+from commons.core.sql.Job import Job
+from commons.core.sql.DbFactory import DbFactory
+from commons.core.sql.TableJobAdaptatorFactory import TableJobAdaptatorFactory
+import sys
+import stat
+import os
+import time
+import unittest
+import glob
+
+class Test_F_TableJobAdaptator(unittest.TestCase):
+
+    def setUp(self):
+        self._jobTableName = "dummyJobTable"
+        self._iJA = TableJobAdaptatorFactory.createJobInstance()
+
+    def tearDown(self):
+        pass
+    
+    def test_submitJob(self):
+        job1 = self._createJobInstance("job1")
+        self._createLauncherFile(job1, self._iJA)
+        job2 = self._createJobInstance("job2")
+        self._createLauncherFile(job2, self._iJA)
+        job3 = self._createJobInstance("job3")
+        self._createLauncherFile(job3, self._iJA)
+        
+        self._iJA.submitJob( job1, maxNbWaitingJobs=3, checkInterval=5, verbose=0 )
+        self._iJA.submitJob( job2, maxNbWaitingJobs=3, checkInterval=5, verbose=0 )
+        self._iJA.submitJob( job3, maxNbWaitingJobs=3, checkInterval=5, verbose=0 )
+
+        time.sleep(120)
+        
+        expErrorFilePrefix1 = job1.jobname + ".e" 
+        expOutputFilePrefix1 = job1.jobname + ".o"
+        expErrorFilePrefix2 = job2.jobname + ".e" 
+        expOutputFilePrefix2 = job2.jobname + ".o"
+        expErrorFilePrefix3 = job3.jobname + ".e" 
+        expOutputFilePrefix3 = job3.jobname + ".o"
+        
+        lErrorFiles1 = glob.glob(expErrorFilePrefix1 + "*")
+        lOutputFiles1 = glob.glob(expOutputFilePrefix1 + "*")
+        lErrorFiles2 = glob.glob(expErrorFilePrefix2 + "*")
+        lOutputFiles2 = glob.glob(expOutputFilePrefix2 + "*")
+        lErrorFiles3 = glob.glob(expErrorFilePrefix3 + "*")
+        lOutputFiles3 = glob.glob(expOutputFilePrefix3 + "*")
+        
+        isLErrorFileNotEmpty1 = (len(lErrorFiles1) != 0) 
+        isLOutputFileNotEmpty1 = (len(lOutputFiles1) != 0)
+        isLErrorFileNotEmpty2 = (len(lErrorFiles2) != 0) 
+        isLOutputFileNotEmpty2 = (len(lOutputFiles2) != 0)
+        isLErrorFileNotEmpty3 = (len(lErrorFiles3) != 0) 
+        isLOutputFileNotEmpty3 = (len(lOutputFiles3) != 0)
+        
+        os.system("rm launcherFileTest*.py *.e* *.o*")
+        self.assertTrue(isLErrorFileNotEmpty1 and isLOutputFileNotEmpty1)
+        self.assertTrue(isLErrorFileNotEmpty2 and isLOutputFileNotEmpty2)
+        self.assertTrue(isLErrorFileNotEmpty3 and isLOutputFileNotEmpty3)
+    
+    def test_submit_and_waitJobGroup(self):
+        iJob = self._createJobInstance("test")
+        self._createLauncherFile(iJob, self._iJA)
+        
+        self._iJA.submitJob( iJob, maxNbWaitingJobs=3, checkInterval=5, verbose=0 )
+        self._iJA.waitJobGroup(iJob.groupid, 0, 2)
+        
+        expErrorFilePrefix1 = iJob.jobname + ".e" 
+        expOutputFilePrefix1 = iJob.jobname + ".o"
+        
+        lErrorFiles1 = glob.glob(expErrorFilePrefix1 + "*")
+        lOutputFiles1 = glob.glob(expOutputFilePrefix1 + "*")
+        
+        isLErrorFileExist = (len(lErrorFiles1) != 0) 
+        isLOutputFileExist = (len(lOutputFiles1) != 0)
+        os.system("rm launcherFileTest*.py *.e* *.o*")
+        self.assertTrue(isLErrorFileExist and isLOutputFileExist)
+
+    def _createJobInstance(self, name):
+        lResources = []
+        if os.environ.get("HOSTNAME") == "compute-2-46.local":
+            lResources.append("test=TRUE")
+        return Job(0, name, "test", "", "log = os.system(\"date;sleep 5;date\")", "%s/launcherFileTest_%s.py" % (os.getcwd(), name), lResources=lResources)
+
+    def _createLauncherFile(self, iJob, iJA):
+        iWriteScript = WriteScript(iJob, iJA, os.getcwd(), os.getcwd(), False, True)
+        iWriteScript.run(iJob.command, "", iJob.launcher)
+        os.chmod(iJob.launcher, stat.S_IRWXU+stat.S_IRWXG+stat.S_IRWXO)
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_F_TableJobAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,185 @@
+from commons.core.launcher.WriteScript import WriteScript
+from commons.core.sql.Job import Job
+from commons.core.sql.DbFactory import DbFactory
+from commons.core.sql.TableJobAdaptatorFactory import TableJobAdaptatorFactory
+import sys
+import stat
+import os
+import time
+import unittest
+import glob
+
+class Test_F_TableJobAdaptator(unittest.TestCase):
+
+    def setUp(self):
+        self._jobTableName = "dummyJobTable"
+        self._db = DbFactory.createInstance()
+        self._iTJA = TableJobAdaptatorFactory.createInstance(self._db, self._jobTableName)
+
+    def tearDown(self):
+        self._db.dropTable(self._jobTableName)
+        self._db.close()
+    
+    def test_submitJob_with_multiple_jobs(self):
+        self._db.createTable(self._jobTableName, "jobs", overwrite = True)
+        job1 = _createJobInstance("job1")
+        _createLauncherFile(job1, self._iTJA)
+        job2 = _createJobInstance("job2")
+        _createLauncherFile(job2, self._iTJA)
+        job3 = _createJobInstance("job3")
+        _createLauncherFile(job3, self._iTJA)
+        
+        self._iTJA.submitJob( job1, maxNbWaitingJobs=3, checkInterval=5, verbose=0 )
+        self._iTJA.submitJob( job2, maxNbWaitingJobs=3, checkInterval=5, verbose=0 )
+        self._iTJA.submitJob( job3, maxNbWaitingJobs=3, checkInterval=5, verbose=0 )
+
+        time.sleep(120)
+        
+        expJobStatus = "finished"
+        obsJobStatus1 = self._iTJA.getJobStatus(job1)
+        obsJobStatus2 = self._iTJA.getJobStatus(job2)
+        obsJobStatus3 = self._iTJA.getJobStatus(job3)
+        
+        self.assertEquals(expJobStatus, obsJobStatus1)
+        self.assertEquals(expJobStatus, obsJobStatus2)
+        self.assertEquals(expJobStatus, obsJobStatus3)
+        
+        expErrorFilePrefix1 = job1.jobname + ".e" 
+        expOutputFilePrefix1 = job1.jobname + ".o"
+        expErrorFilePrefix2 = job2.jobname + ".e" 
+        expOutputFilePrefix2 = job2.jobname + ".o"
+        expErrorFilePrefix3 = job3.jobname + ".e" 
+        expOutputFilePrefix3 = job3.jobname + ".o"
+        
+        lErrorFiles1 = glob.glob(expErrorFilePrefix1 + "*")
+        lOutputFiles1 = glob.glob(expOutputFilePrefix1 + "*")
+        lErrorFiles2 = glob.glob(expErrorFilePrefix2 + "*")
+        lOutputFiles2 = glob.glob(expOutputFilePrefix2 + "*")
+        lErrorFiles3 = glob.glob(expErrorFilePrefix3 + "*")
+        lOutputFiles3 = glob.glob(expOutputFilePrefix3 + "*")
+        
+        isLErrorFileNotEmpty1 = (len(lErrorFiles1) != 0) 
+        isLOutputFileNotEmpty1 = (len(lOutputFiles1) != 0)
+        isLErrorFileNotEmpty2 = (len(lErrorFiles2) != 0) 
+        isLOutputFileNotEmpty2 = (len(lOutputFiles2) != 0)
+        isLErrorFileNotEmpty3 = (len(lErrorFiles3) != 0) 
+        isLOutputFileNotEmpty3 = (len(lOutputFiles3) != 0)
+        
+        os.system("rm launcherFileTest*.py *.e* *.o*")
+        self.assertTrue(isLErrorFileNotEmpty1 and isLOutputFileNotEmpty1)
+        self.assertTrue(isLErrorFileNotEmpty2 and isLOutputFileNotEmpty2)
+        self.assertTrue(isLErrorFileNotEmpty3 and isLOutputFileNotEmpty3)
+
+    def test_submitJob_job_already_submitted(self):
+        self._db.createTable(self._jobTableName, "jobs", overwrite = True)
+        iJob = _createJobInstance("job")
+        self._iTJA.recordJob(iJob)
+        
+        isSysExitRaised = False
+        try:
+            self._iTJA.submitJob(iJob)
+        except SystemExit:
+            isSysExitRaised = True
+        self.assertTrue(isSysExitRaised)
+    
+    def test_waitJobGroup_with_error_job_maxRelaunch_two(self):
+        self._db.createTable(self._jobTableName, "jobs", overwrite = True)
+        iJob = _createJobInstance("job")
+        _createLauncherFile(iJob, self._iTJA)
+        
+        self._iTJA.recordJob(iJob)
+        self._iTJA.changeJobStatus(iJob, "error")
+        
+        self._iTJA.waitJobGroup(iJob.groupid, 0, 2)
+        
+        time.sleep(120)
+        
+        expJobStatus = "finished"
+        obsJobStatus1 = self._iTJA.getJobStatus(iJob)
+        
+        self.assertEquals(expJobStatus, obsJobStatus1)
+        
+        expErrorFilePrefix1 = iJob.jobname + ".e" 
+        expOutputFilePrefix1 = iJob.jobname + ".o"
+        
+        lErrorFiles1 = glob.glob(expErrorFilePrefix1 + "*")
+        lOutputFiles1 = glob.glob(expOutputFilePrefix1 + "*")
+        
+        isLErrorFileNotEmpty1 = (len(lErrorFiles1) != 0) 
+        isLOutputFileNotEmpty1 = (len(lOutputFiles1) != 0)
+        
+        self._iTJA.removeJob(iJob) 
+        os.system("rm launcherFileTest*.py *.e* *.o*")
+        self.assertTrue(isLErrorFileNotEmpty1 and isLOutputFileNotEmpty1)
+
+class Test_F_TableJobAdaptator_SGE(unittest.TestCase):
+
+    def setUp(self):
+        if os.environ["REPET_JOB_MANAGER"].lower() != "sge":
+            print "ERROR: jobs manager is not SGE: REPET_JOB_MANAGER = %s." % os.environ["REPET_JOB_MANAGER"]
+            sys.exit(0)
+        self._jobTableName = "dummyJobTable"
+        self._db = DbFactory.createInstance()
+        self._db.createTable(self._jobTableName, "jobs", overwrite = True)
+        self._iTJA = TableJobAdaptatorFactory.createInstance(self._db, self._jobTableName)
+        self._iJob = _createJobInstance("job")
+        _createLauncherFile(self._iJob, self._iTJA)
+
+    def tearDown(self):
+        self._db.dropTable(self._jobTableName)
+        self._db.close()
+
+    def test_waitJobGroup_with_several_nbTimeOut_waiting(self):
+        self._iTJA.recordJob(self._iJob)
+        self._iTJA.changeJobStatus(self._iJob, "running")
+        
+        expMsg = "ERROR: job '%s', supposedly still running, is not handled by SGE anymore\n" % self._iJob.jobid
+        
+        obsError = "obsError.txt"
+        obsErrorHandler = open(obsError, "w")
+        stderrRef = sys.stderr
+        sys.stderr = obsErrorHandler
+        
+        isSysExitRaised = False
+        try:
+            self._iTJA.waitJobGroup(self._iJob.groupid, timeOutPerJob = 3)
+        except SystemExit:
+            isSysExitRaised = True
+           
+        obsErrorHandler.close()
+        
+        obsErrorHandler = open(obsError, "r")
+        obsMsg = obsErrorHandler.readline()
+        obsErrorHandler.close()
+       
+        sys.stderr = stderrRef
+        os.remove(obsError)
+        os.system("rm launcherFileTest*.py")
+        self.assertTrue(isSysExitRaised)
+        self.assertEquals(expMsg, obsMsg)
+         
+    def test_isJobStillHandledBySge_True(self):
+        self._iTJA.submitJob(self._iJob)
+        isJobHandledBySge = self._iTJA.isJobStillHandledBySge(self._iJob.jobid, self._iJob.jobname)
+        os.system("rm launcherFileTest*.py")
+        self.assertTrue(isJobHandledBySge)
+
+    def test_isJobStillHandledBySge_False(self):
+        self._iTJA.recordJob(self._iJob)
+        isJobHandledBySge = self._iTJA.isJobStillHandledBySge(self._iJob.jobid, self._iJob.jobname)
+        os.system("rm launcherFileTest*.py")
+        self.assertFalse(isJobHandledBySge)
+
+def _createJobInstance(name):
+    lResources = []
+    if os.environ.get("HOSTNAME") == "compute-2-46.local":
+        lResources.append("test=TRUE")
+    return Job(0, name, "test", "", "log = os.system(\"date;sleep 5;date\")", "%s/launcherFileTest_%s.py" % (os.getcwd(), name), lResources=lResources)
+
+def _createLauncherFile(iJob, iTJA):
+    iWriteScript = WriteScript(iJob, iTJA, os.getcwd(), os.getcwd())
+    iWriteScript.run(iJob.command, "", iJob.launcher)
+    os.chmod(iJob.launcher, stat.S_IRWXU+stat.S_IRWXG+stat.S_IRWXO)
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_Job.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,30 @@
+import unittest
+from commons.core.sql.Job import Job
+
+class Test_Job(unittest.TestCase):
+
+    def test__eq__(self):
+        self._job = Job(jobid=0, jobname="test", groupid="test", queue="test",command="test", launcherFile="test", node="test", lResources="mem_free=1G" )
+        o =  Job(jobid=0, jobname="test", groupid="test", queue="test",command="test", launcherFile="test", node="test", lResources="mem_free=1G" )
+        self.assertEqual( self._job, o ) # same data
+        o =  Job(jobid=1, jobname="test", groupid="test", queue="test",command="test", launcherFile="test", node="test", lResources="mem_free=1G" )
+        self.assertNotEqual( self._job, o ) # different jobid        
+        o =  Job(jobid=0, jobname="test1", groupid="test", queue="test",command="test", launcherFile="test", node="test", lResources="mem_free=1G" )
+        self.assertNotEqual( self._job, o ) # different jobname
+        o =  Job(jobid=0, jobname="test", groupid="test1", queue="test",command="test", launcherFile="test", node="test", lResources="mem_free=1G" )
+        self.assertNotEqual( self._job, o ) # different groupid
+        o =  Job(jobid=0, jobname="test", groupid="test", queue="test1",command="test", launcherFile="test", node="test", lResources="mem_free=1G" )
+        self.assertNotEqual( self._job, o ) # different queue        
+        o =  Job(jobid=0, jobname="test", groupid="test", queue="test",command="test1", launcherFile="test", node="test", lResources="mem_free=1G" )
+        self.assertNotEqual( self._job, o ) # different command
+        o =  Job(jobid=0, jobname="test", groupid="test", queue="test",command="test", launcherFile="test1", node="test", lResources="mem_free=1G" )
+        self.assertNotEqual( self._job, o ) # different launcherFile
+        o =  Job(jobid=0, jobname="test", groupid="test", queue="test",command="test", launcherFile="test", node="test1", lResources="mem_free=1G" )
+        self.assertNotEqual( self._job, o ) # different node
+        o =  Job(jobid=0, jobname="test", groupid="test", queue="test",command="test", launcherFile="test", node="test", lResources="mem_free=2G" )
+        self.assertNotEqual( self._job, o ) # different lResources
+        o =  Job(jobid=0, jobname="test", groupid="test", queue="test",command="test", launcherFile="test", node="test", lResources="mem_free=1G", parallelEnvironment="multithread 6" )
+        self.assertNotEqual( self._job, o ) # different parallelEnvironment
+                
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_TableBinPathAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,1244 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+import unittest
+import os
+import time
+from commons.core.sql.TableBinPathAdaptator import TableBinPathAdaptator
+from commons.core.coord.Path import Path
+from commons.core.coord.Set import Set
+from commons.core.sql.DbFactory import DbFactory
+
+class Test_TableBinPathAdaptator( unittest.TestCase ):
+    
+    def setUp( self ):
+        self._uniqId = "%s_%s" % (time.strftime("%Y%m%d%H%M%S") , os.getpid())
+        self._db = DbFactory.createInstance()
+        self._table = "dummyPathTable_%s" % self._uniqId
+        self._table_idx = "dummyPathTable_%s_idx" % self._uniqId
+        
+    def tearDown( self ):
+        self._db.dropTable(self._table)
+        self._db.dropTable(self._table_idx)
+        self._db.close()
+ 
+    #TODO: strand ?!? How does it work ?
+    def test_insert_QryRevSbjDir( self ):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("1", "chr1", "250", "100", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("2", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        tuple = ("4", "chr5", "140", "251", "TE5", "140", "251", "2e-14", "14", "73.1")
+        p4 = Path()
+        p4.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        self._tpA.insert(p4)
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, "chr1", 10, 25, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (1, "chr1", 100, 250, "TE1", 17, 11, 1e-18, 20, 87.4),
+                        (2, "chr1", 15, 30, "TE2", 10, 13, 5e-24, 34, 93.1),
+                        (4, "chr5", 140, 251, "TE5", 140, 251, 2e-14, 14, 73.1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+
+        sqlCmd = "SELECT * FROM %s_idx" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, 1000000, "chr1", 10, 25, 1),
+                        (1, 1000000, "chr1", 100, 250, 1),
+                        (2, 1000000, "chr1", 15, 30, 1),
+                        (4, 1000000, "chr5", 140, 251, 1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+    def test_getPathListOverlappingQueryCoord_one_included( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("6\tchr1\t950\t1010\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+
+        tuple = ("6", "chr1", "950", "1010", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        
+        lObs = self._tpA.getPathListOverlappingQueryCoord( "chr1", 900, 1010 )
+        self.assertEquals(1, len(lObs))
+        lExp = [p1]
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+        
+    def test_getPathListOverlappingQueryCoord_two_overlapped( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("6\tchr1\t950\t1500\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("7\tchr1\t750\t1000\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+
+        tuple = ("6", "chr1", "950", "1500", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("7", "chr1", "750", "1000", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        
+        lObs = self._tpA.getPathListOverlappingQueryCoord( "chr1", 900, 1010 )
+        self.assertEquals(2, len(lObs))
+        lExp = [p1, p2]
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+        
+    def test_getPathListOverlappingQueryCoord_two_not_overlapped_and_not_included( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("6\tchr1\t1050\t1500\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("7\tchr1\t750\t800\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+
+        tuple = ("6", "chr1", "1050", "1500", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("7", "chr1", "750", "800", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        
+        lObs = self._tpA.getPathListOverlappingQueryCoord( "chr1", 900, 1010 )
+        self.assertEquals(0, len(lObs))
+        lExp = []
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+        
+    def test_getPathListOverlappingQueryCoord_one_verlapping_and_others_chained( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("6\tchr1\t900\t1010\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("6\tchr1\t1020\t1030\tTE2\t10\t13\t1e-20\t30\t90.2\n")
+        pathF.write("7\tchr1\t950\t999\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("7\tchr1\t1020\t1030\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("7\tchr5\t8000\t15000\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+
+        tuple = ("6", "chr1", "900", "1010", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+        
+        tuple = ("6", "chr1", "1020", "1030", "TE2", "10", "13", "1e-20", "30", "90.2")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("7", "chr1", "850", "999", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        tuple = ("7", "chr1", "1020", "1030", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p4 = Path()
+        p4.setFromTuple(tuple)
+        
+        tuple = ("7", "chr5", "8000", "15000", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p5 = Path()
+        p5.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        
+        lObs = self._tpA.getPathListOverlappingQueryCoord( "chr1", 1000, 1010 )
+        self.assertEquals(1, len(lObs))
+        lExp = [p1]
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+        
+    def test_getChainListOverlappingQueryCoord_with_all_path_strictly_included_in_the_given_region(self):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t1\t10\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n")
+        pathF.write("3\tchr1\t8\t13\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("4\tchr1\t11\t15\tTE2\t15\t19\t1e-10\t25\t80.2\n")
+        pathF.write("5\tchr1\t14\t19\tTE1\t1\t6\t1e-15\t45\t98.4\n")
+        pathF.close()
+
+        tuple = ("1", "chr1", "1", "10", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+        
+        tuple = ("2", "chr1", "2", "9", "TE2", "10", "13", "1e-20", "30", "90.2")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+
+        tuple = ("3", "chr1", "8", "13", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        tuple = ("4", "chr1", "11", "15", "TE2", "15", "19", "1e-10", "25", "80.2")
+        p4 = Path()
+        p4.setFromTuple(tuple)
+        
+        tuple = ("5", "chr1", "14", "19", "TE1", "1", "6", "1e-15", "45", "98.4")
+        p5 = Path()
+        p5.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        lObs = self._tpA.getChainListOverlappingQueryCoord( "chr1", 1, 20 )
+        self.assertEquals(5, len(lObs))
+        
+        lExp = [p1, p2, p3, p4, p5]
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+        
+    def test_getChainListOverlappingQueryCoord_with_2_path_overlapping_the_given_region(self):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t1\t20\tTE1\t11\t17\t1e-18\t20\t87.4\n")
+        pathF.write("2\tchr1\t10\t30\tTE2\t10\t13\t5e-24\t34\t93.1\n")
+        pathF.close()
+
+        tuple = ("1", "chr1", "1", "20", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+        
+        tuple = ("2", "chr1", "10", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        lObs = self._tpA.getChainListOverlappingQueryCoord( "chr1", 12, 18 )
+        self.assertEquals(2, len(lObs))
+        
+        lExp = [p1, p2]
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+        
+    def test_getChainListOverlappingQueryCoord_without_path_overlapping_the_given_region(self):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t1\t20\tTE1\t11\t17\t1e-18\t20\t87.4\n")
+        pathF.write("2\tchr1\t10\t30\tTE2\t10\t13\t5e-24\t34\t93.1\n")
+        pathF.write("3\tchr5\t45\t50\tTE2\t10\t13\t5e-24\t34\t93.1\n")
+        pathF.close()
+
+        tuple = ("1", "chr1", "1", "20", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+        
+        tuple = ("2", "chr1", "10", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr5", "45", "50", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        lObs = self._tpA.getChainListOverlappingQueryCoord( "chr1", 40, 50 )
+        self.assertEquals(0, len(lObs))
+        
+        lExp = []
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+        
+    def test_getChainListOverlappingQueryCoord_with_inverse_coord(self):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t2000\t1010\tTE2\t17\t11\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t5000\t3030\tTE2\t13\t10\t1e-20\t30\t90.2\n")
+        pathF.close()
+        
+        tuple = ("1", "chr1", "2000", "1010", "TE2", "17", "11", "1e-20", "30", "90.2")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+        
+        tuple = ("2", "chr1", "5000", "3030", "TE2", "13", "10", "1e-20", "30", "90.2")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        
+        lObs = self._tpA.getChainListOverlappingQueryCoord( "chr1", 1000, 1500 )
+        self.assertEquals(1, len(lObs))
+        lExp = [p1]
+        self.assertEquals(lExp, lObs)
+        
+        lObs = self._tpA.getChainListOverlappingQueryCoord( "chr1", 4000, 4510 )
+        self.assertEquals(1, len(lObs))
+        lExp = [p2]
+        self.assertEquals(lExp, lObs)
+        
+        lObs = self._tpA.getChainListOverlappingQueryCoord( "chr1", 1000, 4510 )
+        self.assertEquals(2, len(lObs))
+        lExp = [p1, p2]
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+        
+    def test_getChainListOverlappingQueryCoord_with_chain_id_and_coord( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("6\tchr1\t900\t1010\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("6\tchr1\t1020\t1030\tTE2\t10\t13\t1e-20\t30\t90.2\n")
+        pathF.write("7\tchr1\t950\t999\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("7\tchr1\t1020\t1030\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("7\tchr5\t8000\t15000\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+
+        tuple = ("6", "chr1", "900", "1010", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+        
+        tuple = ("6", "chr1", "1020", "1030", "TE2", "10", "13", "1e-20", "30", "90.2")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("7", "chr1", "950", "999", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        tuple = ("7", "chr1", "1020", "1030", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p4 = Path()
+        p4.setFromTuple(tuple)
+        
+        tuple = ("7", "chr5", "8000", "15000", "TE2", "11", "17", "1e-20", "30", "90.2")
+        p5 = Path()
+        p5.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        lObs = self._tpA.getChainListOverlappingQueryCoord( "chr1", 1000, 1010 )
+        self.assertEquals(5, len(lObs))
+        lExp = [p1, p2, p3, p4, p5]
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+
+    def test_getPathListIncludedInQueryCoord_all_included(self):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t10\t20\tTE1\t11\t17\t1e-18\t20\t87.4\n")
+        pathF.write("2\tchr1\t20\t30\tTE2\t10\t13\t5e-24\t34\t93.1\n")
+        pathF.close()
+
+        tuple = ("1", "chr1", "10", "20", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+        
+        tuple = ("2", "chr1", "20", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        lObs = self._tpA.getPathListIncludedInQueryCoord( "chr1", 1, 40 )
+        self.assertEquals(2, len(lObs))
+        
+        lExp = [p1, p2]
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+
+    def test_getPathListIncludedInQueryCoord_all_not_included(self):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t10\t20\tTE1\t11\t17\t1e-18\t20\t87.4\n")
+        pathF.write("2\tchr1\t20\t30\tTE2\t10\t13\t5e-24\t34\t93.1\n")
+        pathF.write("3\tchr5\t55\t60\tTE2\t10\t13\t5e-24\t34\t93.1\n")
+        pathF.close()
+
+        tuple = ("1", "chr1", "10", "20", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+        
+        tuple = ("2", "chr1", "20", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr2", "55", "60", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        lObs = self._tpA.getPathListIncludedInQueryCoord( "chr1", 50, 70 )
+        self.assertEquals(0, len(lObs))
+        
+        lExp = []
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+
+    def test_getPathListIncludedInQueryCoord_all_overlapping(self):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t10\t25\tTE1\t11\t17\t1e-18\t20\t87.4\n")
+        pathF.write("2\tchr1\t15\t30\tTE2\t10\t13\t5e-24\t34\t93.1\n")
+        pathF.close()
+
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+        
+        tuple = ("2", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        lObs = self._tpA.getPathListIncludedInQueryCoord( "chr1", 13, 22 )
+        self.assertEquals(0, len(lObs))
+        
+        lExp = []
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+
+    def test_getPathListIncludedInQueryCoord_with_one_included_and_one_overlapping(self):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t10\t25\tTE1\t11\t17\t1e-18\t20\t87.4\n")
+        pathF.write("2\tchr1\t15\t30\tTE2\t10\t13\t5e-24\t34\t93.1\n")
+        pathF.close()
+
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+        
+        tuple = ("2", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        lObs = self._tpA.getPathListIncludedInQueryCoord( "chr1", 9, 27 )
+        self.assertEquals(1, len(lObs))
+        lExp = [p1]
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+
+    def test_getPathListIncludedInQueryCoord_with_one_included_and_two_chained(self):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t10\t25\tTE1\t11\t17\t1e-18\t20\t87.4\n")
+        pathF.write("1\tchr1\t100\t250\tTE1\t11\t17\t1e-18\t20\t87.4\n")
+        pathF.write("2\tchr1\t15\t30\tTE2\t10\t13\t5e-24\t34\t93.1\n")
+        pathF.close()
+
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("1", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("2", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        lObs = self._tpA.getPathListIncludedInQueryCoord( "chr1", 9, 27 )
+        self.assertEquals(1, len(lObs))
+        lExp = [p1]
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+        
+    def test_deleteFromId_with_correct_ID(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        self._tpA.deleteFromId(3)
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, "chr1", 10, 25, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (2, "chr1", 100, 250, "TE1", 11, 17, 1e-18, 20, 87.4),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+
+        sqlCmd = "SELECT * FROM %s_idx" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, 1000000, "chr1", 10, 25, 1),
+                        (2, 1000000, "chr1", 100, 250, 1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+    def test_deleteFromId_with_not_exist_ID(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        self._tpA.deleteFromId(4)
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, "chr1", 10, 25, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (2, "chr1", 100, 250, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (3, "chr1", 15, 30, "TE2", 10, 13, 5e-24, 34, 93.1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+
+        sqlCmd = "SELECT * FROM %s_idx" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, 1000000, "chr1", 10, 25, 1),
+                        (2, 1000000, "chr1", 100, 250, 1),
+                        (3, 1000000, "chr1", 15, 30, 1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+    def test_deleteFromId_with_multiple_ID(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("2", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        self._tpA.deleteFromId(2)
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, "chr1", 10, 25, "TE1", 11, 17, 1e-18, 20, 87.4),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+
+        sqlCmd = "SELECT * FROM %s_idx" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, 1000000, "chr1", 10, 25, 1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+    def test_deleteFromIdList(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        lNumToRemove = [2, 3]
+        self._tpA.deleteFromIdList(lNumToRemove)
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, "chr1", 10, 25, "TE1", 11, 17, 1e-18, 20, 87.4),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+
+        sqlCmd = "SELECT * FROM %s_idx" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, 1000000, "chr1", 10, 25, 1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+    def test_deleteFromIdList_with_empty_list(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        lNumToRemove = []
+        self._tpA.deleteFromIdList(lNumToRemove)
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, "chr1", 10, 25, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (2, "chr1", 100, 250, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (3, "chr1", 15, 30, "TE2", 10, 13, 5e-24, 34, 93.1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+
+        sqlCmd = "SELECT * FROM %s_idx" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, 1000000, "chr1", 10, 25, 1),
+                        (2, 1000000, "chr1", 100, 250, 1),
+                        (3, 1000000, "chr1", 15, 30, 1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+    def test_deleteFromIdList_with_list_of_existing_and_not_existing_ID(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        lNumToRemove = [3, 4]
+        self._tpA.deleteFromIdList(lNumToRemove)
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, "chr1", 10, 25, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (2, "chr1", 100, 250, "TE1", 11, 17, 1e-18, 20, 87.4),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+
+        sqlCmd = "SELECT * FROM %s_idx" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, 1000000, "chr1", 10, 25, 1),
+                        (2, 1000000, "chr1", 100, 250, 1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+    def test_deleteFromIdList_with_multiple_ID_on_BinPathTable(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("3", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        lNumToRemove = [3]
+        self._tpA.deleteFromIdList(lNumToRemove)
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, "chr1", 10, 25, "TE1", 11, 17, 1e-18, 20, 87.4),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+
+        sqlCmd = "SELECT * FROM %s_idx" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, 1000000, "chr1", 10, 25, 1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+    def test_joinTwoPaths_with_min_and_max_existing_IDs(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        expNewId = 1
+        obsNewId = self._tpA.joinTwoPaths(1, 2)
+        
+        self.assertEquals(expNewId, obsNewId)
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, "chr1", 10, 25, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (1, "chr1", 100, 250, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (3, "chr1", 15, 30, "TE2", 10, 13, 5e-24, 34, 93.1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+
+        sqlCmd = "SELECT * FROM %s_idx" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, 1000000, "chr1", 10, 25, 1),
+                        (1, 1000000, "chr1", 100, 250, 1),
+                        (3, 1000000, "chr1", 15, 30, 1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+    def test_joinTwoPaths_with_min_ID_not_existing_and_max_ID_existing(self):
+        tuple = ("4", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("5", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("6", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        expNewId = 1
+        obsNewId = self._tpA.joinTwoPaths(1, 5)
+        
+        self.assertEquals(expNewId, obsNewId)
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((4, "chr1", 10, 25, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (1, "chr1", 100, 250, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (6, "chr1", 15, 30, "TE2", 10, 13, 5e-24, 34, 93.1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+
+        sqlCmd = "SELECT * FROM %s_idx" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((4, 1000000, "chr1", 10, 25, 1),
+                        (1, 1000000, "chr1", 100, 250, 1),
+                        (6, 1000000, "chr1", 15, 30, 1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+    def test_joinTwoPaths_with_min_ID_existing_and_max_ID_not_existing(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        expNewId = 1
+        obsNewId = self._tpA.joinTwoPaths(1, 5)
+        
+        self.assertEquals(expNewId, obsNewId)
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, "chr1", 10, 25, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (2, "chr1", 100, 250, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (3, "chr1", 15, 30, "TE2", 10, 13, 5e-24, 34, 93.1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+
+        sqlCmd = "SELECT * FROM %s_idx" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, 1000000, "chr1", 10, 25, 1),
+                        (2, 1000000, "chr1", 100, 250, 1),
+                        (3, 1000000, "chr1", 15, 30, 1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+    def test_joinTwoPaths_with_min_and_max_not_existing_IDs(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        expNewId = 4
+        obsNewId = self._tpA.joinTwoPaths(4, 5)
+        
+        self.assertEquals(expNewId, obsNewId)
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, "chr1", 10, 25, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (2, "chr1", 100, 250, "TE1", 11, 17, 1e-18, 20, 87.4),
+                        (3, "chr1", 15, 30, "TE2", 10, 13, 5e-24, 34, 93.1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+
+        sqlCmd = "SELECT * FROM %s_idx" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        expPathTuple = ((1, 1000000, "chr1", 10, 25, 1),
+                        (2, 1000000, "chr1", 100, 250, 1),
+                        (3, 1000000, "chr1", 15, 30, 1),)
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+    def test_getNewId(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        expNewId = 4
+        obsNewId = self._tpA.getNewId()
+        
+        self.assertEquals(expNewId, obsNewId)
+        
+    def test_getNewId_with_empty_path_table(self):
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        
+        expNewId = 1
+        obsNewId = self._tpA.getNewId()
+        
+        self.assertEquals(expNewId, obsNewId)
+        
+    def test_getSetListIncludedInQueryCoord_one_included(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        
+        s2 = Set()
+        s2.setFromTuple(("2","TE1","chr1","100","250"))
+        expLSet = [s2]
+        obsLSet = self._tpA.getSetListIncludedInQueryCoord('chr1', 95, 300)
+        
+        self.assertEquals(expLSet, obsLSet)
+        
+    def test_getSetListIncludedInQueryCoord_one_overlapping(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        
+        expLSet = []
+        obsLSet = self._tpA.getSetListIncludedInQueryCoord('chr1', 150, 200)
+        
+        self.assertEquals(expLSet, obsLSet)
+        
+    def test_getSetListIncludedInQueryCoord_with_no_result(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        
+        expLSet = []
+        obsLSet = self._tpA.getSetListIncludedInQueryCoord('chr1', 5000, 6000)
+        
+        self.assertEquals(expLSet, obsLSet)
+        
+    def test_getSetListIncludedInQueryCoord_one_included_and_two_chain(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "1000", "2500", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+
+        tuple = ("3", "chr1", "50", "150", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p4 = Path()
+        p4.setFromTuple(tuple)
+        
+        tuple = ("4", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p5 = Path()
+        p5.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        self._tpA.insert(p4)
+        self._tpA.insert(p5)
+        
+        s2 = Set()
+        s2.setFromTuple(("2","TE1","chr1","100","250"))
+        expLSet = [s2]
+        obsLSet = self._tpA.getSetListIncludedInQueryCoord('chr1', 95, 300)
+        
+        self.assertEquals(expLSet, obsLSet)
+        
+    def test_getSetListOverlappingQueryCoord_one_included(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        
+        s2 = Set()
+        s2.setFromTuple(("2","TE1","chr1","100","250"))
+        expLSet = [s2]
+        obsLSet = self._tpA.getSetListOverlappingQueryCoord('chr1', 95, 300)
+        
+        self.assertEquals(expLSet, obsLSet)
+        
+    def test_getSetListOverlappingQueryCoord_one_overlapping(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        
+        s2 = Set()
+        s2.setFromTuple(("2","TE1","chr1","100","250"))
+        expLSet = [s2]
+        obsLSet = self._tpA.getSetListOverlappingQueryCoord('chr1', 150, 200)
+        
+        self.assertEquals(expLSet, obsLSet)
+        
+    def test_getSetListOverlappingQueryCoord_with_no_result(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        
+        expLSet = []
+        obsLSet = self._tpA.getSetListOverlappingQueryCoord('chr1', 5000, 6000)
+        
+        self.assertEquals(expLSet, obsLSet)
+        
+    def test_getSetListOverlappingQueryCoord_one_included_and_two_chain(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "1000", "2500", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+
+        tuple = ("3", "chr1", "50", "150", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p4 = Path()
+        p4.setFromTuple(tuple)
+        
+        tuple = ("4", "chr1", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p5 = Path()
+        p5.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        self._tpA.insert(p4)
+        self._tpA.insert(p5)
+        
+        s2 = Set()
+        s2.setFromTuple(("2","TE1","chr1","100","250"))
+        s4 = Set()
+        s4.setFromTuple(("3","TE1","chr1","50","150"))
+        expLSet = [s2, s4]
+        obsLSet = self._tpA.getSetListOverlappingQueryCoord('chr1', 95, 300)
+        
+        self.assertEquals(expLSet, obsLSet)
+        
+    def test_getIdList( self ):
+        p1 = Path()
+        p1.setFromString( "1\tchr1\t1\t10\tTE1\t11\t17\t1e-20\t30\t90.2\n" )
+        p2 = Path()
+        p2.setFromString( "2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n" )
+        p3 = Path()
+        p3.setFromString( "2\tchr1\t12\t19\tTE2\t15\t22\t1e-10\t40\t94.2\n" )
+        p4 = Path()
+        p4.setFromString( "3\tchr2\t8\t13\tTE1\t11\t17\t1e-20\t30\t90.2\n" )
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        
+        lPath = [ p1, p2, p3, p4]
+        self._tpA.insertList(lPath)
+        
+        expList = [ 1, 2, 3 ]
+        obsList = self._tpA.getIdList()
+        
+        self.assertEqual( expList, obsList )
+        
+    def test_getQueryList(self):
+        tuple = ("1", "chr1", "10", "25", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+
+        tuple = ("2", "chr1", "100", "250", "TE1", "11", "17", "1e-18", "20", "87.4")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+        
+        tuple = ("3", "chr2", "15", "30", "TE2", "10", "13", "5e-24", "34", "93.1")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path" )
+        self._db.createBinPathTable(self._table, True)
+        self._tpA = TableBinPathAdaptator( self._db, self._table )
+        self._tpA.insert(p1)
+        self._tpA.insert(p2)
+        self._tpA.insert(p3)
+        
+        expList = [ "chr1", "chr2" ]
+        obsList = self._tpA.getQueryList()
+        self.assertEqual( expList, obsList )
+
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_TableBinPathAdaptator ) )
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_TableBinSetAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,290 @@
+import unittest
+import os
+import time
+from commons.core.sql.TableBinSetAdaptator import TableBinSetAdaptator
+from commons.core.coord.Set import Set
+from commons.core.sql.DbFactory import DbFactory
+
+class Test_TableBinSetAdaptator(unittest.TestCase):
+
+    def setUp(self):
+        self._uniqId = "%s_%s" % (time.strftime("%Y%m%d%H%M%S") , os.getpid())
+        self._iDb = DbFactory.createInstance()
+        radicalTableName = "dummySetTable"
+        self._tableName = "%s_%s" % (radicalTableName, self._uniqId)
+        self._tableName_bin = "%s_idx" % self._tableName
+        self._setFileName = "dummySetFile_%s" % self._uniqId
+        setF = open( self._setFileName, "w" )
+        setF.write("1\tseq1\tchr1\t1900\t3900\n")
+        setF.write("2\tseq2\tchr1\t2\t9\n")
+        setF.write("3\tseq3\tchr1\t8\t13\n")
+        setF.close()
+        self._iDb.createTable(self._tableName, "set", self._setFileName)
+        self._iTableBinSetAdaptator = TableBinSetAdaptator(self._iDb, self._tableName)
+       
+    def tearDown(self):
+        self._iDb.dropTable( self._tableName )
+        self._iDb.dropTable( self._tableName_bin )
+        self._iDb.close()
+        if os.path.exists(self._setFileName):
+            os.remove(self._setFileName)
+        
+    def test_insASetInSetAndBinTable(self):
+        iSet = Set(1, "set1", "seq1", 2, 1)
+        self._iDb.createBinSetTable(self._tableName, True)
+        self._iTableBinSetAdaptator.insASetInSetAndBinTable(iSet)
+        expTupleInBinTable = ((1L, 10000.0, 'chr1', 1900L, 3900L, 1L), (2L, 1000.0, 'chr1', 2L, 9L, 1L), (3L, 1000.0, 'chr1', 8L, 13L, 1L), (1L, 1000.0, 'seq1', 1L, 2L, 0L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName_bin )
+        self._iDb.execute( sqlCmd )
+        obsTupleInBinTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInBinTable, obsTupleInBinTable)
+        expTupleInSetTable = ((1L, 'seq1', 'chr1', 1900L, 3900L), (2L, 'seq2', 'chr1', 2L, 9L), (3L, 'seq3', 'chr1', 8L, 13L), (1L, 'set1', 'seq1', 2L, 1L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName )
+        self._iDb.execute( sqlCmd )
+        obsTupleInSetTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInSetTable, obsTupleInSetTable)
+        
+    def test_insASetInSetAndBinTable_delayedCase(self):
+        iSet = Set(1, "set1", "seq1", 2, 1)
+        self._iDb.createBinSetTable(self._tableName, True)
+        self._iTableBinSetAdaptator.insASetInSetAndBinTable(iSet, True)
+        expTupleInBinTable = ((1L, 10000.0, 'chr1', 1900L, 3900L, 1L), (2L, 1000.0, 'chr1', 2L, 9L, 1L), (3L, 1000.0, 'chr1', 8L, 13L, 1L), (1L, 1000.0, 'seq1', 1L, 2L, 0L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName_bin )
+        self._iDb.execute( sqlCmd )
+        obsTupleInBinTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInBinTable, obsTupleInBinTable)
+        expTupleInSetTable = ((1L, 'seq1', 'chr1', 1900L, 3900L), (2L, 'seq2', 'chr1', 2L, 9L), (3L, 'seq3', 'chr1', 8L, 13L), (1L, 'set1', 'seq1', 2L, 1L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName )
+        self._iDb.execute( sqlCmd )
+        obsTupleInSetTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInSetTable, obsTupleInSetTable)
+        
+    def test_deleteFromIdFromSetAndBinTable(self):
+        self._iDb.createBinSetTable(self._tableName, True)
+        self._iTableBinSetAdaptator.deleteFromIdFromSetAndBinTable(2)
+        expTupleInBinTable = ((1L, 10000.0, 'chr1', 1900L, 3900L, 1L), (3L, 1000.0, 'chr1', 8L, 13L, 1L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName_bin )
+        self._iDb.execute( sqlCmd )
+        obsTupleInBinTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInBinTable, obsTupleInBinTable)
+        expTupleInSetTable = ((1L, 'seq1', 'chr1', 1900L, 3900L), (3L, 'seq3', 'chr1', 8L, 13L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName )
+        self._iDb.execute( sqlCmd )
+        obsTupleInSetTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInSetTable, obsTupleInSetTable)
+
+    def test_deleteFromListIdFromSetAndBinTable(self):
+        lSetToRemove = [1,2]
+        self._iDb.createBinSetTable(self._tableName, True)
+        self._iTableBinSetAdaptator.deleteFromListIdFromSetAndBinTable(lSetToRemove)
+        expTupleInBinTable = ((3L, 1000.0, 'chr1', 8L, 13L, 1L),)
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName_bin )
+        self._iDb.execute( sqlCmd )
+        obsTupleInBinTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInBinTable, obsTupleInBinTable)
+        expTupleInSetTable = ((3L, 'seq3', 'chr1', 8L, 13L),)
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName )
+        self._iDb.execute( sqlCmd )
+        obsTupleInSetTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInSetTable, obsTupleInSetTable)
+        os.remove(self._setFileName)
+
+    def test_joinTwoSetsFromSetAndBinTable(self):
+        id1 = 1
+        id2 = 2
+        self._iDb.createBinSetTable(self._tableName, True)
+        obsNewId = self._iTableBinSetAdaptator.joinTwoSetsFromSetAndBinTable(id1, id2)
+        expTupleInBinTable = ((1L, 10000.0, 'chr1', 1900L, 3900L, 1L), (1L, 1000.0, 'chr1', 2L, 9L, 1L), (3L, 1000.0, 'chr1', 8L, 13L, 1L))
+        expNewId = 1
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName_bin )
+        self._iDb.execute( sqlCmd )
+        obsTupleInBinTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInBinTable, obsTupleInBinTable)
+        expTupleInSetTable = ((1L, 'seq1', 'chr1', 1900L, 3900L), (1L, 'seq2', 'chr1', 2L, 9L), (3L, 'seq3', 'chr1', 8L, 13L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName )
+        self._iDb.execute( sqlCmd )
+        obsTupleInSetTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInSetTable, obsTupleInSetTable)
+        self.assertEquals(expNewId, obsNewId)
+        
+    def test_joinTwoSetsFromSetAndBinTable_with_reversed_id(self):
+        id1 = 2
+        id2 = 1
+        self._iDb.createBinSetTable(self._tableName, True)
+        obsNewId = self._iTableBinSetAdaptator.joinTwoSetsFromSetAndBinTable(id1, id2)
+        expTupleInBinTable = ((1L, 10000.0, 'chr1', 1900L, 3900L, 1L), (1L, 1000.0, 'chr1', 2L, 9L, 1L), (3L, 1000.0, 'chr1', 8L, 13L, 1L))
+        expNewId = 1
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName_bin )
+        self._iDb.execute( sqlCmd )
+        obsTupleInBinTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInBinTable, obsTupleInBinTable)
+        expTupleInSetTable = ((1L, 'seq1', 'chr1', 1900L, 3900L), (1L, 'seq2', 'chr1', 2L, 9L), (3L, 'seq3', 'chr1', 8L, 13L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName )
+        self._iDb.execute( sqlCmd )
+        obsTupleInSetTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInSetTable, obsTupleInSetTable)
+        self.assertEquals(expNewId, obsNewId)
+        
+    def test_getNewId(self):   
+        self._iDb.createBinSetTable(self._tableName, True)
+        obsNewId = self._iTableBinSetAdaptator.getNewId()
+        expNewId = 4
+        self.assertEquals(expNewId, obsNewId)
+        
+    def test_getNewId_empty_table(self):
+        self._iDb.dropTable( self._tableName )
+        self._iDb.dropTable( self._tableName_bin )
+        setF = open( self._setFileName, "w" )
+        setF.close()
+        self._iDb.createTable( self._tableName, "set", self._setFileName )
+        self._iDb.createBinSetTable(self._tableName, True)
+        obsNewId = self._iTableBinSetAdaptator.getNewId()
+        expNewId = 1
+        self.assertEquals(expNewId, obsNewId)
+        
+    def test_getSetListFromQueryCoord(self):
+        start = 10
+        end = 4000
+        seqName = 'chr1'
+        self._iDb.createBinSetTable(self._tableName, True)
+        obsLSet = self._iTableBinSetAdaptator.getSetListFromQueryCoord(seqName, start, end)
+        iSet1 = Set(1, "seq1", "chr1", 1900, 3900)
+        iSet2 = Set(3, "seq3", "chr1", 8, 13)
+        expLSet = [iSet1, iSet2]
+        self.assertEquals(expLSet, obsLSet)
+        
+    def test_getSetListFromQueryCoord_return_empty_list(self):
+        start = 4000
+        end = 40000
+        seqName = 'chr1'
+        self._iDb.createBinSetTable(self._tableName, True)
+        obsLSet = self._iTableBinSetAdaptator.getSetListFromQueryCoord(seqName, start, end)
+        expLSet = []
+        self.assertEquals(expLSet, obsLSet)
+        
+    def test_getSetListStrictlyIncludedInQueryCoord(self):
+        start = 10
+        end = 4000
+        seqName = 'chr1'
+        self._iDb.createBinSetTable(self._tableName, True)
+        obsLSet = self._iTableBinSetAdaptator.getSetListStrictlyIncludedInQueryCoord(seqName, start, end)
+        iSet1 = Set(1, "seq1", "chr1", 1900, 3900)
+        expLSet = [iSet1]
+        self.assertEquals(expLSet, obsLSet)
+        
+    def test_getSetListStrictlyIncludedInQueryCoord_return_empty_list(self):
+        start = 4000
+        end = 40000
+        seqName = 'chr1'
+        self._iDb.createBinSetTable(self._tableName, True)
+        obsLSet = self._iTableBinSetAdaptator.getSetListStrictlyIncludedInQueryCoord(seqName, start, end)
+        expLSet = []
+        self.assertEquals(expLSet, obsLSet)
+        
+    def test_getIdList(self):
+        expLId = [1,2,3]
+        self._iDb.createBinSetTable(self._tableName, True)
+        obsLId = self._iTableBinSetAdaptator.getIdList()
+        self.assertEquals(expLId, obsLId)
+        
+    def test_getSeqNameList(self):
+        self._iDb.dropTable( self._tableName )
+        self._iDb.dropTable( self._tableName_bin )
+        setF = open( self._setFileName, "w" )
+        setF.write("1\tseq1\tchr2\t1900\t3900\n")
+        setF.write("2\tseq2\tchr1\t2\t9\n")
+        setF.write("3\tseq3\tchr1\t8\t13\n")
+        setF.close()
+        self._iDb.createTable( self._tableName, "set", self._setFileName )
+        self._iDb.createBinSetTable(self._tableName, True)
+        expLSeqName = ["chr1", "chr2"]
+        obsLSeqName = self._iTableBinSetAdaptator.getSeqNameList()
+        self.assertEquals(expLSeqName, obsLSeqName)
+        
+    def test_insertListInSetAndBinTable(self):
+        iSet1 = Set(1, "seq4", "chr1", 100, 390)
+        iSet2 = Set(2, "seq5", "chr1", 1, 13)
+        lSet = [iSet1, iSet2]
+        self._iDb.createBinSetTable(self._tableName, True)
+        self._iTableBinSetAdaptator.insertListInSetAndBinTable(lSet)
+        expTupleInBinTable = ((1L, 10000.0, 'chr1', 1900L, 3900L, 1L), (2L, 1000.0, 'chr1', 2L, 9L, 1L), (3L, 1000.0, 'chr1', 8L, 13L, 1L), (4L, 1000.0, 'chr1', 100L, 390L, 1L), (4L, 1000.0, 'chr1', 1L, 13L, 1L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName_bin )
+        self._iDb.execute( sqlCmd )
+        obsTupleInBinTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInBinTable, obsTupleInBinTable)
+        expTupleInSetTable = ((1L, 'seq1', 'chr1', 1900L, 3900L), (2L, 'seq2', 'chr1', 2L, 9L), (3L, 'seq3', 'chr1', 8L, 13L), (4L, 'seq4', 'chr1', 100L, 390L), (4L, 'seq5', 'chr1', 1L, 13L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName )
+        self._iDb.execute( sqlCmd )
+        obsTupleInSetTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInSetTable, obsTupleInSetTable)
+        
+    def test_insertListInSetAndBinTableAndMergeAllSets(self):
+        iSet1 = Set(1, "seq4", "chr1", 100, 390)
+        iSet2 = Set(2, "seq5", "chr1", 1, 13)
+        lSet = [iSet1, iSet2]
+        self._iDb.createBinSetTable(self._tableName, True)
+        self._iTableBinSetAdaptator.insertListInSetAndBinTableAndMergeAllSets(lSet)
+        expTupleInBinTable = ((1L, 10000.0, 'chr1', 1900L, 3900L, 1L), (5L, 1000.0, 'chr1', 1L, 13L, 1L), (4L, 1000.0, 'chr1', 100L, 390L, 1L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName_bin )
+        self._iDb.execute( sqlCmd )
+        obsTupleInBinTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInBinTable, obsTupleInBinTable)
+        expTupleInSetTable = ((1L, 'seq1', 'chr1', 1900L, 3900L), (5L, 'seq5', 'chr1', 1L, 13L), (4L, 'seq4', 'chr1', 100L, 390L) )
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName )
+        self._iDb.execute( sqlCmd )
+        obsTupleInSetTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInSetTable, obsTupleInSetTable)
+
+    def test_insertListInSetAndBinTableAndRemoveOverlaps(self):
+        iSet1 = Set(1, "seq4", "chr1", 100, 390)
+        iSet2 = Set(2, "seq5", "chr1", 1, 13)
+        lSet = [iSet1, iSet2]
+        self._iDb.createBinSetTable(self._tableName, True)
+        self._iTableBinSetAdaptator.insertListInSetAndBinTableAndRemoveOverlaps(lSet)
+        expTupleInBinTable = ((1L, 10000.0, 'chr1', 1900L, 3900L, 1L), (2L, 1000.0, 'chr1', 2L, 9L, 1L), (3L, 1000.0, 'chr1', 8L, 13L, 1L), (4L, 1000.0, 'chr1', 100L, 390L, 1L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName_bin )
+        self._iDb.execute( sqlCmd )
+        obsTupleInBinTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInBinTable, obsTupleInBinTable)
+        expTupleInSetTable = ((1L, 'seq1', 'chr1', 1900L, 3900L), (2L, 'seq2', 'chr1', 2L, 9L), (3L, 'seq3', 'chr1', 8L, 13L), (4L, 'seq4', 'chr1', 100L, 390L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName )
+        self._iDb.execute( sqlCmd )
+        obsTupleInSetTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInSetTable, obsTupleInSetTable)
+
+    def test_insertListInSetAndBinTableAndRemoveOverlaps_Without_Overlaps(self):
+        iSet1 = Set(1, "seq4", "chr1", 100, 390)
+        iSet2 = Set(2, "seq5", "chr1", 50, 65)
+        lSet = [iSet1, iSet2]
+        self._iDb.createBinSetTable(self._tableName, True)
+        self._iTableBinSetAdaptator.insertListInSetAndBinTableAndRemoveOverlaps(lSet)
+        expTupleInBinTable = ((1L, 10000.0, 'chr1', 1900L, 3900L, 1L), (2L, 1000.0, 'chr1', 2L, 9L, 1L), (3L, 1000.0, 'chr1', 8L, 13L, 1L), (4L, 1000.0, 'chr1', 100L, 390L, 1L), (5L, 1000.0, 'chr1', 50L, 65L, 1L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName_bin )
+        self._iDb.execute( sqlCmd )
+        obsTupleInBinTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInBinTable, obsTupleInBinTable)
+        expTupleInSetTable = ((1L, 'seq1', 'chr1', 1900L, 3900L), (2L, 'seq2', 'chr1', 2L, 9L), (3L, 'seq3', 'chr1', 8L, 13L), (4L, 'seq4', 'chr1', 100L, 390L), (5L, 'seq5', 'chr1', 50L, 65L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName )
+        self._iDb.execute( sqlCmd )
+        obsTupleInSetTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInSetTable, obsTupleInSetTable)
+
+    def test_insertListInSetAndBinTableAndRemoveOverlaps_With_Only_Overlaps(self):
+        iSet1 = Set(1, "seq4", "chr1", 1, 5)
+        iSet2 = Set(2, "seq5", "chr1", 8, 13)
+        lSet = [iSet1, iSet2]
+        self._iDb.createBinSetTable(self._tableName, True)
+        self._iTableBinSetAdaptator.insertListInSetAndBinTableAndRemoveOverlaps(lSet)
+        expTupleInBinTable = ((1L, 10000.0, 'chr1', 1900L, 3900L, 1L), (2L, 1000.0, 'chr1', 2L, 9L, 1L), (3L, 1000.0, 'chr1', 8L, 13L, 1L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName_bin )
+        self._iDb.execute( sqlCmd )
+        obsTupleInBinTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInBinTable, obsTupleInBinTable)
+        expTupleInSetTable = ((1L, 'seq1', 'chr1', 1900L, 3900L), (2L, 'seq2', 'chr1', 2L, 9L), (3L, 'seq3', 'chr1', 8L, 13L))
+        sqlCmd = "SELECT * FROM %s" % ( self._tableName )
+        self._iDb.execute( sqlCmd )
+        obsTupleInSetTable = self._iDb.cursor.fetchall()
+        self.assertEquals(expTupleInSetTable, obsTupleInSetTable)
+                          
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_TableJobAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,640 @@
+import unittest
+import sys
+import os
+import time
+#import stat
+#import threading
+from commons.core.sql.DbMySql import DbMySql
+#from commons.core.sql.DbSQLite import DbSQLite
+from commons.core.sql.Job import Job
+from commons.core.utils.FileUtils import FileUtils
+from commons.core.sql.TableJobAdaptatorFactory import TableJobAdaptatorFactory
+
+#class Test_TableJobAdaptator_SQLite( unittest.TestCase ):
+#        
+#    def setUp(self):
+#        self._jobTableName = "dummyJobTable"
+#        self._dbName = "test.db"
+#        self._db = DbSQLite(self._dbName)
+#        self._iTJA = TableJobAdaptator(self._db, self._jobTableName)
+#        if not self._db.doesTableExist(self._jobTableName):
+#            self._db.createJobTable(self._jobTableName)
+#        self._iJob = self._createJobInstance()
+#        
+#    def tearDown(self):
+#        self._iTJA = None
+#        self._db.close()
+##        self._db.delete()
+#        
+##    def test_recordJob(self):
+##        self._iTJA.recordJob(self._iJob)
+##        qryParams = "SELECT jobid, groupid, command, launcher, queue, status, node FROM " + self._jobTableName + " WHERE jobid = ?" 
+##        params = (self._iJob.jobid,)
+##        self._db.execute(qryParams, params)
+##        tObs = self._db.fetchall()[0]
+##        tExp =(self._iJob.jobid, self._iJob.groupid, self._iJob.command, self._iJob.launcher, self._iJob.queue, "waiting", "?")
+##        self.assertEquals(tExp,tObs)
+##    
+##    def test_removeJob(self):
+##        self._iTJA.recordJob(self._iJob)
+##        self._iTJA.removeJob(self._iJob)
+##        self.assertTrue(self._db.isEmpty(self._jobTableName))
+##        
+##    def test_getJobStatus(self):
+##        self._iTJA.recordJob(self._iJob)
+##        expStatus = "waiting"
+##        obsStatus = self._iTJA.getJobStatus(self._iJob)
+##        self.assertEquals(expStatus, obsStatus)
+##        
+##    def test_getJobStatus_no_job(self):
+##        expStatus = "unknown"
+##        obsStatus = self._iTJA.getJobStatus(self._iJob)
+##        self.assertEquals(expStatus, obsStatus)
+##
+##    def test_getJobStatus_no_name(self):
+##        iJob = Job( self._jobTableName, 20, "", "groupid", "queue", "command", "launcherFile", "node", "lResources" ) 
+##        expStatus = "unknown"
+##        obsStatus = self._iTJA.getJobStatus(iJob)
+##        self.assertEquals(expStatus, obsStatus)
+##        
+##    def test_getJobStatus_two_jobs(self):
+##        # Warning : this case will not append, because recordJob() begin by removeJob()
+##        sqlCmd = "INSERT INTO %s" % self._iJob.tablename
+##        sqlCmd += " VALUES ("
+##        sqlCmd += " \"%s\"," % self._iJob.jobid
+##        sqlCmd += " \"%s\"," % self._iJob.jobname
+##        sqlCmd += " \"%s\"," % self._iJob.groupid
+##        sqlCmd += " \"%s\"," % self._iJob.command.replace("\"","\'")
+##        sqlCmd += " \"%s\"," % self._iJob.launcher
+##        sqlCmd += " \"%s\"," % self._iJob.queue
+##        sqlCmd += " \"waiting\","
+##        sqlCmd += " \"%s\"," % time.strftime( "%Y-%m-%d %H:%M:%S" )
+##        sqlCmd += " \"?\" );"
+##        self._db.execute(sqlCmd)
+##        self._db.execute(sqlCmd)
+##        
+##        expError = "expError.txt"
+##        expErrorHandler = open(expError, "w")
+##        expErrorHandler.write("ERROR while getting job status: non-unique jobs\n")
+##        expErrorHandler.close()
+##        obsError = "obsError.txt"
+##        obsErrorHandler = open(obsError, "w")
+##        stderrRef = sys.stderr
+##        sys.stderr = obsErrorHandler
+##        
+##        isSysExitRaised = False
+##        try:
+##            self._iTJA.getJobStatus(self._iJob)
+##        except SystemExit:
+##            isSysExitRaised = True
+##           
+##        obsErrorHandler.close()
+##        
+##        self.assertTrue(isSysExitRaised)
+##        self.assertTrue(FileUtils.are2FilesIdentical(expError, obsError))
+##        sys.stderr = stderrRef
+##        os.remove(obsError)
+##        os.remove(expError)
+##
+##    def test_changeJobStatus(self):
+##        expStatus = "finished"
+##        self._iTJA.recordJob(self._iJob)
+##        self._iTJA.changeJobStatus(self._iJob, expStatus)
+##        qryParams = "SELECT status FROM " + self._jobTableName + " WHERE jobid =? AND groupid=? AND queue=?" 
+##        params = (self._iJob.jobid, self._iJob.groupid, self._iJob.queue)
+##        self._db.execute(qryParams, params)
+##        obsStatus = self._db.fetchall()[0][0]
+##        self.assertEquals(expStatus, obsStatus)
+##        self._iTJA.removeJob(self._iJob)
+##        
+##    def test_getCountStatus(self):
+##        iJob1 = self._createJobInstance()
+##        iJob2 = Job(self._jobTableName, 1, "job2", "groupid", "queue2", "command2", "launcherFile2", "node2", "lResources2")
+##        self._iTJA.recordJob(iJob1)
+##        self._iTJA.recordJob(iJob2)
+##        expCount = 2
+##        obsCount = self._iTJA.getCountStatus(self._jobTableName, iJob1.groupid, "waiting")
+##        self.assertEquals(expCount, obsCount)
+##        
+##    def test_getCountStatus_without_res(self):
+##        expCount = 0
+##        obsCount = self._iTJA.getCountStatus(self._jobTableName, "groupid", "waiting")
+##        self.assertEquals(expCount, obsCount)
+##   
+##    def test_cleanJobGroup(self):
+##        iJob1 = self._createJobInstance()
+##        iJob2 = Job(self._jobTableName, "jobid2", iJob1.groupid, "queue2", "command2", "launcherFile2", "node2", "lResources2")
+##        iJob3 = Job(self._jobTableName, "jobid2", "groupid3", "queue2", "command2", "launcherFile2", "node2", "lResources2")
+##        self._iTJA.recordJob(iJob1)
+##        self._iTJA.recordJob(iJob2)
+##        self._iTJA.recordJob(iJob3)
+##        self._iTJA.cleanJobGroup(self._jobTableName, iJob1.groupid)
+##        qryParams = "SELECT count(*) FROM " + self._jobTableName  
+##        self._db.execute(qryParams)
+##        expCount = 1
+##        obsCount = self._db.fetchall()[0][0]
+##        self.assertEquals(expCount, obsCount)
+##                
+##    def test_hasUnfinishedJob_one_waiting_one_finished(self):
+##        iJob1 = self._createJobInstance()
+##        iJob2 = Job(self._jobTableName, 0, "jobname2", iJob1.groupid, "queue2", "command2", "launcherFile2", "node2", "lResources2")
+##        iJob3 = Job(self._jobTableName, 0, "jobname3", "groupid3", "queue2", "command2", "launcherFile2", "node2", "lResources2")
+##        self._iTJA.recordJob(iJob1)
+##        self._iTJA.recordJob(iJob2)
+##        self._iTJA.recordJob(iJob3)
+##        self._iTJA.changeJobStatus(iJob2, "finished")
+##        expHasGrpIdFinished = True
+##        obsHasGrpIdFinished = self._iTJA.hasUnfinishedJob(self._jobTableName, iJob1.groupid)
+##        self.assertEquals(expHasGrpIdFinished, obsHasGrpIdFinished)
+##        
+##    def test_hasUnfinishedJob_jobTable_doesnt_exist(self):
+##        self._db.dropTable(self._jobTableName)
+##        expHasGrpIdFinished = False
+##        obsHasGrpIdFinished = self._iTJA.hasUnfinishedJob(self._jobTableName, self._iJob.groupid)
+##        self.assertEquals(expHasGrpIdFinished, obsHasGrpIdFinished)
+##        
+##    def test_hasUnfinishedJob_all_jobs_finished_for_same_groupid(self): 
+##        iJob1 = self._createJobInstance()
+##        iJob2 = Job(self._jobTableName, "jobid2", iJob1.groupid, "queue2", "command2", "launcherFile2", "node2", "lResources2")
+##        iJob3 = Job(self._jobTableName, "jobid2", "groupid3", "queue2", "command2", "launcherFile2", "node2", "lResources2")
+##        self._iTJA.recordJob(iJob1)
+##        self._iTJA.recordJob(iJob2)
+##        self._iTJA.recordJob(iJob3)
+##        self._iTJA.changeJobStatus(iJob1, "finished")
+##        self._iTJA.changeJobStatus(iJob2, "finished")
+##        expHasGrpIdFinished = False
+##        obsHasGrpIdFinished = self._iTJA.hasUnfinishedJob(self._jobTableName, iJob1.groupid)
+##        self.assertEquals(expHasGrpIdFinished, obsHasGrpIdFinished)
+##
+##    def test_waitJobGroup_with_finished_job(self):
+##        obs = False
+##        self._iTJA.recordJob(self._iJob)
+##        self._iTJA.changeJobStatus(self._iJob, "finished")
+##        try:
+##            self._iTJA.waitJobGroup(self._jobTableName ,self._iJob.groupid, 0, 0)
+##        except SystemExit:
+##            obs = True
+##        self.assertFalse(obs)
+##        
+##    def test_waitJobGroup_with_error_job_maxRelaunch_zero(self):
+##        obs = False
+##        self._iTJA.recordJob(self._iJob)
+##        self._iTJA.changeJobStatus(self._iJob, "error")
+##        try:
+##            self._iTJA.waitJobGroup(self._jobTableName ,self._iJob.groupid, 0, 0)
+##        except SystemExit:
+##            obs = True
+##        self.assertTrue(obs)
+##        
+##    def test_setJobIdFromSge(self):
+##        self._iTJA.recordJob(self._iJob)
+##        self._iTJA.setJobIdFromSge(self._iJob, 1000)
+##        qryParams = "SELECT jobid FROM " + self._jobTableName + " WHERE jobname = ? AND queue = ? AND groupid = ?" 
+##        params = (self._iJob.jobname, self._iJob.queue, self._iJob.groupid)
+##        self._db.execute(qryParams, params)
+##        tObs = self._db.fetchall()[0]
+##        tExp =(1000,)
+##        self.assertEquals(tExp,tObs)
+##                
+##    def test_submitJob_8_fields_for_job_table(self):
+##        self._db.dropTable(self._jobTableName)
+##        sqlCmd = "CREATE TABLE " + self._jobTableName 
+##        sqlCmd += " ( jobid INT UNSIGNED"
+##        sqlCmd += ", groupid VARCHAR(255)"
+##        sqlCmd += ", command TEXT"
+##        sqlCmd += ", launcher VARCHAR(1024)"
+##        sqlCmd += ", queue VARCHAR(255)"
+##        sqlCmd += ", status VARCHAR(255)"
+##        sqlCmd += ", time DATETIME"
+##        sqlCmd += ", node VARCHAR(255) )"
+##        self._db.execute(sqlCmd)
+##        self._iTJA.submitJob(self._iJob)
+##        expFieldsNb = 9
+##        obsFieldsNb = len(self._db.getFieldList(self._jobTableName))
+##        self.assertEquals(expFieldsNb, obsFieldsNb)
+##        os.remove("jobid.stdout")
+##        
+##    def test_getNodesListByGroupId(self):
+##        iJob1 = Job( self._jobTableName, 0, "job1", "groupid", "queue", "command", "launcherFile", "node1", "lResources" )
+##        iJob2 = Job( self._jobTableName, 1, "job2", "groupid", "queue", "command", "launcherFile", "node2", "lResources" )
+##        iJob3 = Job( self._jobTableName, 2, "job3", "groupid2", "queue", "command", "launcherFile", "node3", "lResources" )
+##        self._insertJob(iJob1)
+##        self._insertJob(iJob2)
+##        self._insertJob(iJob3)
+##        expNodeList = ["node1", "node2"]
+##        obsNodeList = self._iTJA.getNodesListByGroupId(self._jobTableName, "groupid")
+##        self.assertEquals(expNodeList, obsNodeList)
+##        
+##    def test_getNodesListByGroupId_empty_list(self):
+##        iJob1 = Job( self._jobTableName, 0, "job1", "groupid", "queue", "command", "launcherFile", "node1", "lResources" )
+##        iJob2 = Job( self._jobTableName, 1, "job2", "groupid", "queue", "command", "launcherFile", "node2", "lResources" )
+##        iJob3 = Job( self._jobTableName, 2, "job3", "groupid32", "queue", "command", "launcherFile", "node3", "lResources" )
+##        self._insertJob(iJob1)
+##        self._insertJob(iJob2)
+##        self._insertJob(iJob3)
+##        expNodeList = []
+##        obsNodeList = self._iTJA.getNodesListByGroupId(self._jobTableName, "groupid3")
+##        self.assertEquals(expNodeList, obsNodeList)
+##
+##    def test_commitJob(self):
+##        iJob1 = Job( self._jobTableName, 0, "job1", "groupid", "queue", "command", "launcherFile", "node1", "lResources" )
+##        self._insertJob(iJob1)
+##        
+##        expJobStatus = "waiting"
+##        obsJobStatus = self._iTJA.getJobStatus(self._iJob)
+##        self.assertEquals(expJobStatus, obsJobStatus)
+##        expJobStatus = "waiting"
+##        obsJobStatus = self._iTJA.getJobStatus(self._iJob)
+##        self.assertEquals(expJobStatus, obsJobStatus)
+##        self._db.close()
+##        
+##        self._db = DbSQLite(self._dbName)
+##        self._iTJA = TableJobAdaptator(self._db, self._jobTableName)
+##        expJobStatus = "waiting"
+##        obsJobStatus = self._iTJA.getJobStatus(self._iJob)
+##        self.assertEquals(expJobStatus, obsJobStatus)
+##        
+##    def _insertJob(self, iJob):
+##        self._iTJA = TableJobAdaptator(self._db, self._jobTableName)        
+##        self._iTJA.removeJob( iJob )
+##        sqlCmd = "INSERT INTO %s" % ( iJob.tablename )
+##        sqlCmd += " VALUES ("
+##        sqlCmd += " \"%s\"," % ( iJob.jobid )
+##        sqlCmd += " \"%s\"," % ( iJob.jobname )
+##        sqlCmd += " \"%s\"," % ( iJob.groupid )
+##        sqlCmd += " \"%s\"," % ( iJob.command.replace("\"","\'") )
+##        sqlCmd += " \"%s\"," % ( iJob.launcher )
+##        sqlCmd += " \"%s\"," % ( iJob.queue )
+##        sqlCmd += " \"waiting\","
+##        sqlCmd += " \"%s\"," % ( time.strftime( "%Y-%m-%d %H:%M:%S" ) )
+##        sqlCmd += " \"%s\" );" % ( iJob.node )
+##        self._db.execute( sqlCmd )
+#
+##    def testRecordJob_in_parallel_with_2_thread(self) :
+##        job1 = Job(self._jobTableName, 0, "job1", "test", "", "date;sleep 5;date", "./launcherFileTest_job1.py")
+##        job2 = Job(self._jobTableName, 0, "job2", "test", "", "date;sleep 5;date", "./launcherFileTest_job2.py")
+##        
+##        db1 = DbSQLite('threadJobTable.db')
+##        db1.createJobTable(self._jobTableName)
+##        
+##        db2 = DbSQLite(self._dbName)
+##        
+##        iTJA1 = TableJobAdaptator(db1, self._jobTableName)
+##        iTJA2 = TableJobAdaptator(db2, self._jobTableName)
+##        
+##        iRJT1 = RecordJobThread(iTJA1, job1)
+##        iRJT2 = RecordJobThread(iTJA2, job2)
+##        iRJT1.start()
+##        iRJT2.start()
+##        
+##        while iRJT1.isAlive() or iRJT2.isAlive():
+##            time.sleep(5)
+##        
+##        expJobStatus = "waiting"
+##        obsJobStatus1 = iTJA1.getJobStatus(job1)
+##        obsJobStatus2 = iTJA2.getJobStatus(job2)
+##                
+##        self.assertEquals(expJobStatus, obsJobStatus1)
+##        self.assertEquals(expJobStatus, obsJobStatus2)
+##        db1.db.close()
+##        db1.delete()
+##        
+#
+#    def test_ThreadRecordJob_sqlite3_connection_object_different_instances(self):
+#        
+##        for i in range(1, 11):
+##            job = Job(self._jobTableName, 0, "job%s"% i, "test_Thread", "", "date;sleep 5;date", "./launcherFileTest_job%s.py" % i)
+##            db1 = DbSQLite(self._dbName)
+##            iTJA1 = TableJobAdaptator(db1, self._jobTableName)
+##            iRJT1 = RecordJobThread(iTJA1, job)
+#
+#        #self._db.createJobTable(self._jobTableName)
+#        
+#        for i in range(1, 30) :
+#            job = "job%s"% i
+#            db = "db%s"%i
+#            job = Job(self._jobTableName, 0, "job%s"% i, "test_Thread", "", "date;sleep 5;date", "./launcherFileTest_job%s.py" % i)
+#            db = DbSQLite(self._dbName)
+#            if i == 1 :
+#                db.createJobTable(self._jobTableName)
+#            iTJA = TableJobAdaptator(db, self._jobTableName)
+#            iRJT = RecordJobThread(iTJA, job)
+#            iRJT.start()
+#
+#            #while iRJT.isAlive() :
+#                #time.sleep(1)
+#            
+##        job1 = Job(self._jobTableName, 0, "job1", "test", "", "date;sleep 5;date", "./launcherFileTest_job1.py")
+##        self._createLauncherFile(job1)
+##        job2 = Job(self._jobTableName, 0, "job2", "test", "", "date;sleep 5;date", "./launcherFileTest_job2.py")
+##        self._createLauncherFile(job2)
+##        
+##        db1 = DbSQLite(self._dbName)
+##        db2 = DbSQLite(self._dbName)
+##        
+##        iTJA1 = TableJobAdaptator(db1, self._jobTableName)
+##        iTJA2 = TableJobAdaptator(db2, self._jobTableName)
+##        
+##        
+##        iRJT1 = RecordJobThread(iTJA1, job1)
+##        iRJT2 = RecordJobThread(iTJA2, job2)
+##        
+##        iRJT1.start()
+##        iRJT2.start()
+##    
+##        while iRJT1.isAlive() or iRJT2.isAlive():
+##            time.sleep(5)
+#
+#
+##        self.assertNotEquals(iRJT1._iTableJobAdaptator._iDb.db, iRJT2._iTableJobAdaptator._iDb.db)
+#        
+#
+#    def _createLauncherFile(self, iJob):
+#        jobFileHandler = open(iJob.launcher , "w")
+##        self.cdir
+##        self.job
+#        cDir = os.getcwd()
+#
+#        launcher = "#!/usr/bin/python\n"
+#        launcher += "import os\n"
+#        launcher += "import sys\n"
+#        
+#        launcher += "print \"system:\", os.uname()\n"
+#        launcher += "sys.stdout.flush()\n"
+#        
+#        newStatus = "running"
+#        launcher += "from commons.core.sql.Job import Job\n"
+#        launcher += "from commons.core.sql.DbSQLite import DbSQLite\n"
+#        launcher += "from commons.core.sql.TableJobAdaptator import TableJobAdaptator\n"
+#        launcher += "iJob = Job('%s', %s, '%s', '%s')\n" % (iJob.tablename, iJob.jobid, iJob.jobname, iJob.groupid)
+#        launcher += "iDb = DbSQLite('%s/%s')\n" % (cDir, self._dbName)
+#        launcher += "iTJA = TableJobAdaptator(iDb, '%s')\n" % self._jobTableName
+#        launcher += "if not iDb.doesTableExist('%s'):\n" % (iJob.tablename)
+#        launcher += "\tiDb.createJobTable('%s')\n" % self._jobTableName
+#        
+#        launcher += "iTJA.changeJobStatus(iJob, '%s')\n" % newStatus
+#        
+#        launcher += "print \"LAUNCH: " + iJob.command + "\"\n"
+#        launcher += "sys.stdout.flush()\n"
+#        launcher += "exitStatus = os.system (\"" + iJob.command + "\")\n"
+#        launcher += "if exitStatus != 0:\n"
+#        launcher += "\tprint \"ERROR: " + iJob.command + " returned exit status '%i'\" % ( exitStatus )\n"
+#        
+#        newStatus = "finished"
+#        launcher += "iTJA.changeJobStatus(iJob, '%s')\n" % newStatus
+#        launcher += "iDb.close()\n"
+#        
+#        launcher += "sys.exit(0)\n"
+#        jobFileHandler.write(launcher)
+#        jobFileHandler.close()
+#        os.chmod(iJob.launcher, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
+#         
+#    def _createJobInstance(self):
+#        return Job( self._jobTableName, 0, "job1", "groupid", "queue", "command", "launcherFile", "node", "lResources" )
+         
+
+class Test_TableJobAdaptator_MySQL( unittest.TestCase ):
+
+    def setUp(self):
+        self._jobTableName = "dummyJobTable"
+        self._db = DbMySql()
+        self._iTJA = TableJobAdaptatorFactory.createInstance(self._db, self._jobTableName)   
+        self._db.createTable(self._jobTableName, "jobs", overwrite = True)
+        self._iJob = self._createJobInstance()      
+          
+    def tearDown(self):
+        self._db.dropTable(self._jobTableName)
+        self._iTJA = None
+        self._db.close()
+                     
+    def test_recordJob(self):
+        self._iTJA.recordJob(self._iJob)
+        qryParams = "SELECT jobid, jobname, groupid, launcher, queue, resources, status, node FROM " + self._jobTableName + " WHERE jobid = %s"
+        params = (self._iJob.jobid)
+        self._db.execute(qryParams, params)
+        tObs = self._db.fetchall()[0]
+        tExp =(self._iJob.jobid, self._iJob.jobname, self._iJob.groupid, self._iJob.launcher, self._iJob.queue, "['mem_free=10M']", "waiting", "?")
+        self.assertEquals(tExp,tObs)
+
+    def test_removeJob(self):
+        self._iTJA.recordJob(self._iJob)
+        self._iTJA.removeJob(self._iJob)
+        isTableEmpty = self._db.isEmpty(self._jobTableName)
+        self.assertTrue(isTableEmpty)
+    
+    def test_getJobStatus(self):
+        self._iTJA.recordJob(self._iJob)
+        expStatus = "waiting"
+        obsStatus = self._iTJA.getJobStatus(self._iJob)
+        self.assertEquals(expStatus, obsStatus)
+    
+    def test_getJobStatus_no_job(self):
+        expStatus = "unknown"
+        obsStatus = self._iTJA.getJobStatus(self._iJob)
+        self.assertEquals(expStatus, obsStatus)
+
+    def test_getJobStatus_no_name(self):
+        iJob = Job(self._jobTableName, 20, "", "groupid", "queue", "command", "launcherFile", "node", "lResources") 
+        expStatus = "unknown"
+        obsStatus = self._iTJA.getJobStatus(iJob)
+        self.assertEquals(expStatus, obsStatus)
+            
+    def test_getJobStatus_two_jobs(self):
+        # Warning : this case will not append, because recordJob() begin by removeJob()
+        sqlCmd = "INSERT INTO %s" % self._jobTableName
+        sqlCmd += " VALUES ("
+        sqlCmd += " \"%s\"," % self._iJob.jobid
+        sqlCmd += " \"%s\"," % self._iJob.jobname
+        sqlCmd += " \"%s\"," % self._iJob.groupid
+        sqlCmd += " \"%s\"," % self._iJob.launcher
+        sqlCmd += " \"%s\"," % self._iJob.queue
+        sqlCmd += " \"%s\"," % self._iJob.lResources
+        sqlCmd += " \"waiting\","
+        sqlCmd += " \"%s\"," % time.strftime("%Y-%m-%d %H:%M:%S")
+        sqlCmd += " \"?\" );"
+        self._db.execute(sqlCmd)
+        self._db.execute(sqlCmd)
+        
+        expError = "expError.txt"
+        expErrorHandler = open(expError, "w")
+        expErrorHandler.write("ERROR while getting job status: non-unique jobs\n")
+        expErrorHandler.close()
+        obsError = "obsError.txt"
+        obsErrorHandler = open(obsError, "w")
+        stderrRef = sys.stderr
+        sys.stderr = obsErrorHandler
+        
+        isSysExitRaised = False
+        try:
+            self._iTJA.getJobStatus(self._iJob)
+        except SystemExit:
+            isSysExitRaised = True
+        obsErrorHandler.close()
+        self.assertTrue(isSysExitRaised)
+        self.assertTrue(FileUtils.are2FilesIdentical(expError, obsError))
+        sys.stderr = stderrRef
+        os.remove(obsError)
+        os.remove(expError)
+        
+    def test_changeJobStatus(self):
+        expStatus = "finished"
+        self._iTJA.recordJob(self._iJob)
+        self._iTJA.changeJobStatus(self._iJob, expStatus)
+        qryParams = "SELECT status FROM " + self._jobTableName + " WHERE jobid =%s AND groupid=%s AND queue=%s" 
+        params = (self._iJob.jobid, self._iJob.groupid, self._iJob.queue)
+        self._db.execute(qryParams, params)
+        obsStatus = self._db.fetchall()[0][0]
+        self.assertEquals(expStatus, obsStatus)
+        
+    def test_getCountStatus(self):
+        iJob1 = self._createJobInstance()
+        iJob2 = Job(1, "job2", "groupid", "queue2", "command2", "launcherFile2", "node2", "lResources2")
+        self._iTJA.recordJob(iJob1)
+        self._iTJA.recordJob(iJob2)
+        expCount = 2
+        obsCount = self._iTJA.getCountStatus(iJob1.groupid, "waiting")
+        self.assertEquals(expCount, obsCount)
+        
+    def test_getCountStatus_without_res(self):
+        expCount = 0
+        obsCount = self._iTJA.getCountStatus("groupid", "waiting")
+        self.assertEquals(expCount, obsCount)
+
+    def test_cleanJobGroup(self):
+        iJob1 = self._createJobInstance()
+        iJob2 = Job(2, "jobid2", iJob1.groupid, "queue2", "command2", "launcherFile2", "node2", "lResources2")
+        iJob3 = Job(3, "jobid2", "groupid3", "queue2", "command2", "launcherFile2", "node2", "lResources2")
+        self._iTJA.recordJob(iJob1)
+        self._iTJA.recordJob(iJob2)
+        self._iTJA.recordJob(iJob3)
+        self._iTJA.cleanJobGroup(iJob1.groupid)
+        qryParams = "SELECT count(*) FROM %s" % self._jobTableName  
+        self._db.execute(qryParams)
+        expCount = 1
+        obsCount = self._db.fetchall()[0][0]
+        self.assertEquals(expCount, obsCount)
+  
+    def test_hasUnfinishedJob_one_waiting_one_finished(self):
+        iJob1 = self._createJobInstance()
+        iJob2 = Job(0, "jobname2", iJob1.groupid, "queue2", "command2", "launcherFile2", "node2", "lResources2")
+        iJob3 = Job(0, "jobname3", "groupid3", "queue2", "command2", "launcherFile2", "node2", "lResources2")
+        self._iTJA.recordJob(iJob1)
+        self._iTJA.recordJob(iJob2)
+        self._iTJA.recordJob(iJob3)
+        self._iTJA.changeJobStatus(iJob2, "finished")
+        expHasGrpIdFinished = True
+        obsHasGrpIdFinished = self._iTJA.hasUnfinishedJob(iJob1.groupid)
+        self.assertEquals(expHasGrpIdFinished, obsHasGrpIdFinished)
+        
+    def test_hasUnfinishedJob_all_jobs_finished_for_same_groupid(self): 
+        iJob1 = self._createJobInstance()
+        iJob2 = Job(2, "jobid2", iJob1.groupid, "queue2", "command2", "launcherFile2", "node2", "lResources2")
+        iJob3 = Job(3, "jobid2", "groupid3", "queue2", "command2", "launcherFile2", "node2", "lResources2")
+        self._iTJA.recordJob(iJob1)
+        self._iTJA.recordJob(iJob2)
+        self._iTJA.recordJob(iJob3)
+        self._iTJA.changeJobStatus(iJob1, "finished")
+        self._iTJA.changeJobStatus(iJob2, "finished")
+        expHasGrpIdFinished = False
+        obsHasGrpIdFinished = self._iTJA.hasUnfinishedJob(iJob1.groupid)
+        self.assertEquals(expHasGrpIdFinished, obsHasGrpIdFinished)
+
+    def test_waitJobGroup_with_finished_job(self):
+        obs = False
+        self._iTJA.recordJob(self._iJob)
+        self._iTJA.changeJobStatus(self._iJob, "finished")
+        try:
+            self._iTJA.waitJobGroup(self._iJob.groupid, 0, 0)
+        except SystemExit:
+            obs = True
+        self.assertFalse(obs)
+        
+    def test_waitJobGroup_with_error_job_maxRelaunch_zero(self):
+        obs = False
+        self._iTJA.recordJob(self._iJob)
+        self._iTJA.changeJobStatus(self._iJob, "error")
+        try:
+            self._iTJA.waitJobGroup(self._iJob.groupid, 0, 0)
+        except SystemExit:
+            obs = True
+        self.assertTrue(obs)
+        
+    #TODO: how to test ?!?
+#    def test_waitJobGroup_with_error_relaunch(self):
+#        iJob = Job(0, "job1", "groupid", "queue.q", "command", "launcherFile", "node", ["mem_free=10M", "test=TRUE"])
+#        obs = False
+#        self._iTJA.recordJob(iJob)
+#        self._iTJA.changeJobStatus(iJob, "error")
+#        try:
+#            self._iTJA.waitJobGroup(iJob.groupid)
+#        except SystemExit:
+#            obs = True
+#        self.assertTrue(obs)
+    
+    def test_updateJobIdInDB(self):
+        self._iTJA.recordJob(self._iJob)
+        self._iTJA.updateJobIdInDB(self._iJob, 1000)
+        qryParams = "SELECT jobid FROM " + self._jobTableName + " WHERE jobname = %s AND queue = %s AND groupid = %s" 
+        params = (self._iJob.jobname, self._iJob.queue, self._iJob.groupid)
+        self._db.execute(qryParams, params)
+        tObs = self._db.fetchall()[0]
+        tExp =(1000,)
+        self.assertEquals(tExp,tObs)
+
+    def test_getNodesListByGroupId(self):
+        iJob1 = Job(0, "job1", "groupid", "queue", "command", "launcherFile", "node1", "lResources")
+        iJob2 = Job(1, "job2", "groupid", "queue", "command", "launcherFile", "node2", "lResources")
+        iJob3 = Job(2, "job3", "groupid", "queue", "command", "launcherFile", "node2", "lResources")
+        iJob4 = Job(3, "job4", "groupid2", "queue", "command", "launcherFile", "node3", "lResources")
+        self._insertJob(iJob1)
+        self._insertJob(iJob2)
+        self._insertJob(iJob3)
+        self._insertJob(iJob4)
+        expNodeList = ["node1", "node2"]
+        obsNodeList = self._iTJA.getNodesListByGroupId("groupid")
+        self.assertEquals(expNodeList, obsNodeList)
+
+    def test_getNodesListByGroupId_empty_list(self):
+        iJob1 = Job(0, "job1", "groupid", "queue", "command", "launcherFile", "node1", "lResources")
+        iJob2 = Job(1, "job2", "groupid", "queue", "command", "launcherFile", "node2", "lResources")
+        iJob3 = Job(2, "job3", "groupid32", "queue", "command", "launcherFile", "node3", "lResources")
+        self._insertJob(iJob1)
+        self._insertJob(iJob2)
+        self._insertJob(iJob3)
+        expNodeList = []
+        obsNodeList = self._iTJA.getNodesListByGroupId("groupid3")
+        self.assertEquals(expNodeList, obsNodeList)
+        
+# TODO test TableJobAdaptator._createJobInstance  TableJobAdaptator._createLauncherFile
+    def _insertJob(self, iJob):
+        self._iTJA = TableJobAdaptatorFactory.createInstance(self._db, self._jobTableName)        
+        self._iTJA.removeJob(iJob)
+        sqlCmd = "INSERT INTO %s" % self._jobTableName
+        sqlCmd += " VALUES ("
+        sqlCmd += " \"%s\"," % iJob.jobid
+        sqlCmd += " \"%s\"," % iJob.jobname
+        sqlCmd += " \"%s\"," % iJob.groupid
+        sqlCmd += " \"%s\"," % iJob.launcher
+        sqlCmd += " \"%s\"," % iJob.queue
+        sqlCmd += " \"%s\"," % iJob.lResources
+        sqlCmd += " \"waiting\","
+        sqlCmd += " \"%s\"," % time.strftime("%Y-%m-%d %H:%M:%S")
+        sqlCmd += " \"%s\" );" % iJob.node
+        self._db.execute(sqlCmd)
+
+    def _createJobInstance(self):
+        return Job(0, "job1", "groupid", "", "command", "launcherFile", "node", ["mem_free=10M"])
+
+#class RecordJobThread(threading.Thread):
+#
+#    def __init__(self, iTableJobAdaptator, iJob):
+#        threading.Thread.__init__(self)
+#        self._iTableJobAdaptator = iTableJobAdaptator
+#        self._iJob = iJob
+#        
+#    def run(self):
+#        self._iTableJobAdaptator.recordJob(self._iJob)
+#        #self._iTableJobAdaptator.submitJob(self._iJob)
+                                             
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_TableJobAdaptatorFactory.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,27 @@
+import os
+import unittest
+from commons.core.sql.TableJobAdaptatorFactory import TableJobAdaptatorFactory
+from commons.core.sql.DbFactory import DbFactory
+
+class Test_TableJobAdaptatorFactory(unittest.TestCase):
+
+    def test_createInstance_SGE(self):
+        REPET_JOB_MANAGER_Initial_Value = os.environ["REPET_JOB_MANAGER"]
+        os.environ["REPET_JOB_MANAGER"] = "SGE"
+        instance = TableJobAdaptatorFactory.createInstance(DbFactory.createInstance(), "dummyJobTable")
+        obsClassName = instance.__class__.__name__
+        expClassName = "TableJobAdaptatorSGE"
+        os.environ["REPET_JOB_MANAGER"] = REPET_JOB_MANAGER_Initial_Value
+        self.assertEquals(expClassName, obsClassName)
+
+    def test_createInstance_Torque(self):
+        REPET_JOB_MANAGER_Initial_Value = os.environ["REPET_JOB_MANAGER"]
+        os.environ["REPET_JOB_MANAGER"] = "Torque"
+        instance = TableJobAdaptatorFactory.createInstance(DbFactory.createInstance(), "dummyJobTable")
+        obsClassName = instance.__class__.__name__
+        expClassName = "TableJobAdaptatorTorque"
+        os.environ["REPET_JOB_MANAGER"] = REPET_JOB_MANAGER_Initial_Value
+        self.assertEquals(expClassName, obsClassName)
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_TableMapAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,250 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import time
+import os
+from commons.core.sql.TableMapAdaptator import TableMapAdaptator
+from commons.core.sql.DbMySql import DbMySql
+from commons.core.coord.Map import Map
+from commons.core.coord.Set import Set
+
+
+class Test_TableMapAdaptator( unittest.TestCase ):
+    
+    def setUp( self ):
+        self._uniqId = "%s_%s" % ( time.strftime("%Y%m%d%H%M%S") , os.getpid() )
+        self._configFileName = "dummyConfigFile_%s" % ( self._uniqId )
+        configF = open(self._configFileName, "w" )
+        configF.write( "[repet_env]\n" )
+        configF.write( "repet_host: %s\n" % ( os.environ["REPET_HOST"] ) )
+        configF.write( "repet_user: %s\n" % ( os.environ["REPET_USER"] ) )
+        configF.write( "repet_pw: %s\n" % ( os.environ["REPET_PW"] ) )
+        configF.write( "repet_db: %s\n" % ( os.environ["REPET_DB"] ) )
+        configF.write( "repet_port: %s\n" % ( os.environ["REPET_PORT"] ) )
+        configF.close()
+        self._iDb = DbMySql( cfgFileName=self._configFileName )
+        self._table = "dummyMapTable_%s" % ( self._uniqId )
+        self._tMapA = TableMapAdaptator( self._iDb, self._table )
+        
+        
+    def tearDown( self ):
+        self._uniqId = None
+        self._iDb.dropTable( self._table )
+        self._iDb.close()
+        self._table = None
+        self._tMapA = None
+        os.remove( self._configFileName )
+        self._configFileName = ""
+        
+##################################################################################
+################## Tests for methods in ITableMapAdaptator #######################
+##################################################################################    
+
+    def test_getEndFromSeqName(self):
+        self._iDb.createTable( self._table, "map", "" )
+        map1 = Map()
+        map1.setFromString( "name1\tdesc1\t1\t120\n" )
+        map2 = Map()
+        map2.setFromString( "name2\tdesc2\t1\t20\n" )
+        for m in [ map1, map2]:
+            self._tMapA.insert(m)
+        expEnd = 20
+        obsEnd = self._tMapA.getEndFromSeqName("desc2")
+        self.assertEqual(expEnd, obsEnd)     
+        
+
+    def test_getMapListFromSeqName( self ):
+        self._iDb.createTable( self._table, "map", "" )
+        map1 = Map()
+        map1.setFromString( "name1\tdesc1\t1\t120\n" )
+        map2 = Map()
+        map2.setFromString( "name2\tdesc2\t1\t20\n" )
+        map3 = Map()
+        map3.setFromString( "name2\tdesc2\t1\t50\n" )
+        for m in [ map1, map2, map3 ]: self._tMapA.insert( m )
+        lExp = [ map2, map3 ]
+        lObs = self._tMapA.getMapListFromSeqName("name2")
+        self.assertEqual( lObs, lExp )     
+
+    def test_getMapListFromChr( self ):
+        self._iDb.createTable( self._table, "map", "" )
+        map1 = Map()
+        map1.setFromString( "name1\tchr1\t1\t120\n" )
+        map2 = Map()
+        map2.setFromString( "name2\tchr2\t1\t20\n" )
+        map3 = Map()
+        map3.setFromString( "name2\tchr2\t1\t50\n" )
+        for m in [ map1, map2, map3 ]: self._tMapA.insert( m )
+        lExp = [ map2, map3 ]
+        lObs = self._tMapA.getMapListFromChr("chr2")
+        self.assertEqual( lObs, lExp )
+
+    def test_getSeqNameList(self):
+        self._iDb.createTable( self._table, "map", "" )
+        map1 = Map()
+        map1.setFromString( "name1\tdesc1\t1\t120\n" )
+        map2 = Map()
+        map2.setFromString( "name2\tdesc2\t1\t20\n" )
+        map3 = Map()
+        map3.setFromString( "name2\tdesc2\t1\t50\n" )
+        for m in [ map1, map2, map3 ]: self._tMapA.insert( m )
+        lExp = ["desc1", "desc2"]
+        lObs = self._tMapA.getSeqNameList()
+        self.assertEqual( lObs, lExp )
+        
+    def test_insert_one_element( self ):
+        map2Insert = Map()
+        map2Insert.name="name1"
+        map2Insert.seqname="name2"
+        map2Insert.start=1L
+        map2Insert.end=50L
+        self._iDb.createTable( self._table, "map", "" )
+        self._tMapA.insert( map2Insert )
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._iDb.execute( sqlCmd )
+        expTmapTuple = (('name1', 'name2', 1L, 50L),)
+        obsTmapTuples = self._iDb.cursor.fetchall()
+        self.assertEquals( expTmapTuple, obsTmapTuples )
+        
+    def test_insert_two_elements( self ):   
+        map1 = Map()
+        map1.setFromString( "name1\tdesc1\t1\t120\n" )
+        map2 = Map()
+        map2.setFromString( "name2\tdesc2\t1\t20\n" )
+        self._iDb.createTable( self._table, "map", "" )
+        for m in [ map1, map2 ]: self._tMapA.insert( m )
+        expTmapTuple = ( ('name1', 'desc1', 1L, 120L), ('name2', 'desc2', 1L, 20L) )
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._iDb.execute( sqlCmd )
+        obsTmapTuples = self._iDb.cursor.fetchall()
+        self.assertEquals(expTmapTuple, obsTmapTuples )
+        
+    def test_insertList( self ):
+        self._iDb.createTable( self._table, "map", "" )
+        map1 = Map()
+        map1.setFromString( "name1\tdesc1\t1\t120\n" )
+        map2 = Map()
+        map2.setFromString( "name2\tdesc2\t1\t20\n" )
+        lmap = [ map1, map2 ]
+        self._tMapA.insertList( lmap )
+        lExp = lmap
+        lObs = self._tMapA.getListOfAllMaps()
+        self.assertEqual( lObs, lExp )
+        
+    def test_getSetListFromSeqName( self ):
+        self._iDb.createTable( self._table, "map", "" )
+        map1 = Map()
+        map1.setFromString( "name1\tdesc1\t1\t120\n" )
+        map2 = Map()
+        map2.setFromString( "name2\tdesc2\t1\t20\n" )
+        map3 = Map()
+        map3.setFromString( "name2\tdesc2\t1\t50\n" )
+        for m in [ map1, map2, map3 ]: self._tMapA.insert( m )
+        explMap = [Set( 1,"name2", "desc2", 1, 20), Set( 2,"name2", "desc2", 1, 50)]
+        obslMap = self._tMapA.getSetListFromSeqName("name2")
+        self.assertEqual( explMap, obslMap )
+        
+    def test_getMapListOverlappingCoord( self ):
+        self._iDb.createTable( self._table, "map", "" )
+        map1 = Map()
+        map1.setFromString( "name1\tdesc1\t70\t120\n" )
+        map2 = Map()
+        map2.setFromString( "name2\tdesc1\t1\t20\n" )
+        map3 = Map()
+        map3.setFromString( "name3\tdesc1\t1\t50\n" ) 
+        for m in [ map1, map2, map3 ]: self._tMapA.insert( m )
+        explMap = [Map("name2", "desc1", 1, 20), Map("name3", "desc1", 1, 50)]
+        obslMap = self._tMapA.getMapListOverlappingCoord("desc1", 1, 60)
+        self.assertEqual( explMap, obslMap )
+        
+    def test_getSetListOverlappingCoord( self ):
+        self._iDb.createTable( self._table, "map", "" )
+        map1 = Map()
+        map1.setFromString( "name1\tdesc1\t70\t120\n" )
+        map2 = Map()
+        map2.setFromString( "name2\tdesc1\t1\t20\n" )
+        map3 = Map()
+        map3.setFromString( "name3\tdesc1\t1\t50\n" ) 
+        for m in [ map1, map2, map3 ]: self._tMapA.insert( m )
+        explSet = [Set(1, "name2", "desc1", 1, 20), Set(2, "name3", "desc1", 1, 50)]
+        obslSet = self._tMapA.getSetListOverlappingCoord("desc1", 1, 60)
+        self.assertEqual( explSet, obslSet )
+        
+##################################################################################
+########################### Tests for other methods ##############################
+##################################################################################
+        
+    def test_getListOfAllMaps( self ):
+        self._iDb.createTable( self._table, "map", "" )
+        map1 = Map()
+        map1.setFromString( "name1\tdesc1\t1\t120\n" )
+        map2 = Map()
+        map2.setFromString( "name2\tdesc2\t1\t20\n" )
+        for m in [ map1, map2 ]: self._tMapA.insert( m )
+        lExp = [ map1, map2 ]
+        lObs = self._tMapA.getListOfAllMaps()
+        self.assertEqual( lObs, lExp )
+        
+    def test_getDictPerNameFromMapFile( self ):
+        self._iDb.createTable( self._table, "map", "" )
+        iMap1 = Map( "chunk1", "chromosome1", 1, 100 )
+        iMap2 = Map( "chunk2", "chromosome1", 91, 190 )
+        iMap3 = Map( "chunk3", "chromosome2", 1, 100 )
+        iMap4 = Map( "chunk1", "chromosome1", 1, 100 )  # redundant with iMap1
+        for iMap in [ iMap1, iMap2, iMap3, iMap4 ]:
+            self._tMapA.insert( iMap )
+        dExp = { "chunk1": iMap1, "chunk2": iMap2, "chunk3": iMap3 }
+        dObs = self._tMapA.getDictPerName()
+        self.assertEquals( dExp, dObs )
+        
+#TODO: Check getListFromSeqName method: uses name instead of seqname
+#    def test_getMapListFromSeqNameList( self ):
+#        self._iDb.createTable( self._table, "map", "" )
+#        map1 = Map()
+#        map1.setFromString( "name1\tdesc1\t1\t120\n" )
+#        map2 = Map()
+#        map2.setFromString( "name2\tdesc2\t1\t20\n" )
+#        map3 = Map()
+#        map3.setFromString( "name3\tdesc2\t1\t10\n" )
+#        map4 = Map()
+#        map4.setFromString( "name4\tdesc3\t10\t200\n" )
+#        for m in [map1, map2, map3, map4]: self._tMapA.insert( m )
+#        
+#        lMapToRetrieve = ["name1", "desc2"]
+#        lExp = [map1, map2, map3]
+#        lObs = self._tMapA.getMapListFromSeqNameList(lMapToRetrieve)
+#        self.assertEqual( lObs, lExp )
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_TableMapAdaptator ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_TableMatchAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,264 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import time
+import os
+from commons.core.sql.DbMySql import DbMySql
+from commons.core.coord.Match import Match
+from commons.core.sql.TableMatchAdaptator import TableMatchAdaptator
+
+
+class Test_TableMatchAdaptator( unittest.TestCase ):
+    
+    def setUp( self ):
+        self._uniqId = "%s_%s" % (time.strftime("%Y%m%d%H%M%S") , os.getpid())
+        self._configFileName = "dummyConfigFile_%s" % self._uniqId
+        self._iDb = DbMySql()
+        self._table = "dummyMatchTable_%s" % self._uniqId
+        self._tMatchA = TableMatchAdaptator( self._iDb, self._table )
+        
+    def tearDown( self ):
+        self._uniqId = None
+        self._iDb.dropTable( self._table )
+        self._iDb.close()
+        self._table = None
+        self._tMatchA = None
+        
+##################################################################################
+################## Tests for methods in ITableMatchAdaptator #####################
+##################################################################################  
+    def test_insert(self):
+        match = Match()  
+
+        tuple = ("QName1", 1, 5, 5, 0.1, 0.2, "SName1", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+       
+        match.setFromTuple(tuple)
+                              
+        self._iDb.createTable( self._table, "match", "" )        
+        self._tMatchA.insert( match, False )
+        
+        expTMatchTuple = (('QName1', 1L, 5L, 5L, 0.1, 0.2, 'SName1', 5L, 25L, 20L, 0.15, 1e-20, 15L, 87.2, 1L),)
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._iDb.execute( sqlCmd )
+        obsTmatchTuple = self._iDb.cursor.fetchall()
+        
+        self.assertEquals( expTMatchTuple, obsTmatchTuple )
+        
+
+    def test_insert_empty_match(self):
+        match = Match()  
+
+        tuple = ("", -1, -1, 5, 0.1, 0.2, "SName1", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+       
+        match.setFromTuple(tuple)
+                              
+        self._iDb.createTable( self._table, "match", "" )        
+        self._tMatchA.insert( match, False )
+        
+        expTMatchTuple = ()
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._iDb.execute( sqlCmd )
+        obsTmatchTuple = self._iDb.cursor.fetchall()
+        
+        self.assertEquals( expTMatchTuple, obsTmatchTuple )  
+               
+    
+    def test_insertList(self):
+        match1 = Match() 
+        match2 = Match()   
+
+        tuple1 = ("QName1", 1, 5, 5, 0.1, 0.2, "SName1", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        tuple2 = ("QName2", 2, 5, 5, 0.1, 0.2, "SName2", 6, 25, 20, 0.15, 1e-20, 15, 87.2, 2)
+       
+        match1.setFromTuple(tuple1)
+        match2.setFromTuple(tuple2)
+                              
+        self._iDb.createTable( self._table, "match", "" )        
+        self._tMatchA.insertList( [ match1, match2 ], False )
+        
+        expTMatchTuple = (('QName1', 1L, 5L, 5L, 0.1, 0.2, 'SName1', 5L, 25L, 20L, 0.15, 1e-20, 15L, 87.2, 1L),\
+                          ('QName2', 2L, 5L, 5L, 0.1, 0.2, 'SName2', 6L, 25L, 20L, 0.15, 1e-20, 15L, 87.2, 2L))
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._iDb.execute( sqlCmd )
+        obsTmatchTuple = self._iDb.cursor.fetchall()
+        
+        self.assertEquals( expTMatchTuple, obsTmatchTuple )
+        
+        
+    def test_getMatchListFromQuery(self):
+        self._iDb.createTable( self._table, "match", "" )
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        tuple2 = ("QName", 1, 6, 6, 0.2, 0.1, "SName", 6, 26, 10, 0.18, 1e-30, 18, 85.2, 2)
+        tuple3 = ("QName", 1, 7, 8, 0.1, 0.2, "SName", 5, 20, 15, 0.20, 1e-25, 20, 89.0, 3)
+        tuple4 = ("QName", 1, 8, 8, 0.1, 0.1, "SName", 5, 15, 10, 0.17, 1e-23, 14, 89.5, 4)
+        match1 = Match()
+        match1.setFromTuple( tuple1 )
+        match2 = Match()
+        match2.setFromTuple( tuple2 )
+        match3 = Match()
+        match3.setFromTuple( tuple3 )
+        match4 = Match()
+        match4.setFromTuple( tuple4 )
+        expListMatch = [ match1, match2, match3, match4 ]
+        self._tMatchA.insertList(expListMatch)
+        
+        obsListMatch = self._tMatchA.getMatchListFromQuery("QName")
+        
+        self.assertEquals(expListMatch, obsListMatch)
+        
+        
+    def test_getMatchListFromQuery_unexisted_seq_name(self):
+        self._iDb.createTable( self._table, "match", "" )
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        tuple2 = ("QName", 1, 6, 6, 0.2, 0.1, "SName", 6, 26, 10, 0.18, 1e-30, 18, 85.2, 2)
+        tuple3 = ("QName", 1, 7, 8, 0.1, 0.2, "SName", 5, 20, 15, 0.20, 1e-25, 20, 89.0, 3)
+        tuple4 = ("QName", 1, 8, 8, 0.1, 0.1, "SName", 5, 15, 10, 0.17, 1e-23, 14, 89.5, 4)
+        match1 = Match()
+        match1.setFromTuple( tuple1 )
+        match2 = Match()
+        match2.setFromTuple( tuple2 )
+        match3 = Match()
+        match3.setFromTuple( tuple3 )
+        match4 = Match()
+        match4.setFromTuple( tuple4 )
+        lMatch = [ match1, match2, match3, match4 ]
+        self._tMatchA.insertList(lMatch)
+        
+        expListMatch = []
+        obsListMatch = self._tMatchA.getMatchListFromQuery("Dummy")
+        
+        self.assertEquals(expListMatch, obsListMatch)
+        
+
+    def test_getMatchListFromId(self):
+        self._iDb.createTable( self._table, "match", "" )
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        tuple2 = ("QName", 1, 6, 6, 0.2, 0.1, "SName", 6, 26, 10, 0.18, 1e-30, 18, 85.2, 2)
+        tuple3 = ("QName", 1, 7, 8, 0.1, 0.2, "SName", 5, 20, 15, 0.20, 1e-25, 20, 89.0, 3)
+        tuple4 = ("QName", 1, 8, 8, 0.1, 0.1, "SName", 5, 15, 10, 0.17, 1e-23, 14, 89.5, 4)
+        match1 = Match()
+        match1.setFromTuple( tuple1 )
+        match2 = Match()
+        match2.setFromTuple( tuple2 )
+        match3 = Match()
+        match3.setFromTuple( tuple3 )
+        match4 = Match()
+        match4.setFromTuple( tuple4 )
+        lMatch = [ match1, match2, match3, match4 ]
+        expListMatch = [ match1 ]
+        self._tMatchA.insertList(lMatch)
+        
+        obsListMatch = self._tMatchA.getMatchListFromId(1)
+        
+        self.assertEquals(expListMatch, obsListMatch)
+        
+        
+    def test_getMatchListFromIdList_empty_id_list( self ):
+        self._iDb.createTable( self._table, "match", "" )
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        tuple2 = ("QName", 1, 6, 6, 0.2, 0.1, "SName", 6, 26, 10, 0.18, 1e-30, 18, 85.2, 2)
+        tuple3 = ("QName", 1, 7, 8, 0.1, 0.2, "SName", 5, 20, 15, 0.20, 1e-25, 20, 89.0, 3)
+        tuple4 = ("QName", 1, 8, 8, 0.1, 0.1, "SName", 5, 15, 10, 0.17, 1e-23, 14, 89.5, 4)
+        match1 = Match()
+        match1.setFromTuple( tuple1 )
+        match2 = Match()
+        match2.setFromTuple( tuple2 )
+        match3 = Match()
+        match3.setFromTuple( tuple3 )
+        match4 = Match()
+        match4.setFromTuple( tuple4 )
+        lMatch = [ match1, match2, match3, match4 ]
+        self._tMatchA.insertList(lMatch)
+        
+        expList = []
+        obsList = self._tMatchA.getMatchListFromIdList([])
+        self.assertEquals(expList, obsList)
+        
+        
+    def test_getMatchListFromIdList( self ):
+        self._iDb.createTable( self._table, "match", "" )
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        tuple2 = ("QName", 1, 6, 6, 0.2, 0.1, "SName", 6, 26, 10, 0.18, 1e-30, 18, 85.2, 2)
+        tuple3 = ("QName", 1, 7, 8, 0.1, 0.2, "SName", 5, 20, 15, 0.20, 1e-25, 20, 89.0, 3)
+        tuple4 = ("QName", 1, 8, 8, 0.1, 0.1, "SName", 5, 15, 10, 0.17, 1e-23, 14, 89.5, 4)
+        match1 = Match()
+        match1.setFromTuple( tuple1 )
+        match2 = Match()
+        match2.setFromTuple( tuple2 )
+        match3 = Match()
+        match3.setFromTuple( tuple3 )
+        match4 = Match()
+        match4.setFromTuple( tuple4 )
+        lMatch = [ match1, match2, match3, match4 ]
+        self._tMatchA.insertList(lMatch)
+        
+        lObs = self._tMatchA.getMatchListFromIdList((1, 2, 3))
+        
+        lExp = [match1, match2, match3]
+        self.assertEquals(lExp, lObs)
+        
+    def test_getListOfAllMatches( self ):
+        self._iDb.createTable( self._table, "match", "" )
+        tuple1 = ("QName", 1, 5, 5, 0.1, 0.2, "SName", 5, 25, 20, 0.15, 1e-20, 15, 87.2, 1)
+        tuple2 = ("QName", 1, 6, 6, 0.2, 0.1, "SName", 6, 26, 10, 0.18, 1e-30, 18, 85.2, 2)
+        tuple3 = ("QName", 1, 7, 8, 0.1, 0.2, "SName", 5, 20, 15, 0.20, 1e-25, 20, 89.0, 3)
+        tuple4 = ("QName", 1, 8, 8, 0.1, 0.1, "SName", 5, 15, 10, 0.17, 1e-23, 14, 89.5, 4)
+        match1 = Match()
+        match1.setFromTuple( tuple1 )
+        match2 = Match()
+        match2.setFromTuple( tuple2 )
+        match3 = Match()
+        match3.setFromTuple( tuple3 )
+        match4 = Match()
+        match4.setFromTuple( tuple4 )
+        lMatch = [ match1, match2, match3, match4 ]
+        expList = [ match1, match2, match3, match4 ]
+        self._tMatchA.insertList(lMatch)
+
+        obsList = self._tMatchA.getListOfAllMatches()
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getListOfAllMatches_empty_table( self ):
+        self._iDb.createTable( self._table, "match", "" )
+        expList = []
+        obsList = self._tMatchA.getListOfAllMatches()
+        self.assertEqual( expList, obsList )
+        
+            
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_TableMatchAdaptator ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_TablePathAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,1376 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+import time
+from commons.core.sql.TablePathAdaptator import TablePathAdaptator
+from commons.core.coord.Path import Path
+from commons.core.coord.Set import Set
+from commons.core.sql.DbMySql import DbMySql
+from commons.core.coord.Range import Range
+from commons.core.coord.PathUtils import PathUtils
+from copy import deepcopy
+
+class Test_TablePathAdaptator( unittest.TestCase ):
+    
+    def setUp( self ):
+        self._uniqId = "%s_%s" % ( time.strftime("%Y%m%d%H%M%S") , os.getpid() )
+        self._configFileName = "dummyConfigFile_%s" % ( self._uniqId )
+        configF = open(self._configFileName, "w" )
+        configF.write( "[repet_env]\n" )
+        configF.write( "repet_host: %s\n" % ( os.environ["REPET_HOST"] ) )
+        configF.write( "repet_user: %s\n" % ( os.environ["REPET_USER"] ) )
+        configF.write( "repet_pw: %s\n" % ( os.environ["REPET_PW"] ) )
+        configF.write( "repet_db: %s\n" % ( os.environ["REPET_DB"] ) )
+        configF.write( "repet_port: %s\n" % ( os.environ["REPET_PORT"] ) )
+        configF.close()
+        self._db = DbMySql( cfgFileName = self._configFileName )
+        self._table = "dummyPathTable_%s" % ( self._uniqId )
+        self._tpA = TablePathAdaptator( self._db, self._table )
+        
+        
+    def tearDown( self ):
+        self._uniqId = None
+        self._db.dropTable( self._table )
+        self._db.close()
+        self._table = None
+        self._tMatchA = None
+        os.remove( self._configFileName )
+        self._configFileName = ""  
+        
+        
+##################################################################################
+################## Tests for methods in ITableMapAdaptator #######################
+##################################################################################       
+     
+    def test_getPathListFromId( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write( "1\tchr1\t1\t6\tTE2\t11\t16\t1e-20\t30\t90.2\n" )
+        pathF.write( "2\tchr1\t1001\t1006\tTE2\t11\t16\t1e-20\t30\t90.2\n" )
+        pathF.write( "2\tchr1\t1201\t1226\tTE2\t10\t26\t1e-40\t70\t87.2\n" )
+        pathF.close()
+        p1 = Path()
+        p1.setFromString( "2\tchr1\t1001\t1006\tTE2\t11\t16\t1e-20\t30\t90.2\n" )
+        p2 = Path()
+        p2.setFromString( "2\tchr1\t1201\t1226\tTE2\t10\t26\t1e-40\t70\t87.2\n" )
+        lExp = [ p1, p2 ]
+        self._db.createTable( self._table, "path", pathFileName )
+        lObs = self._tpA.getPathListFromId( 2 )
+        self.assertEqual( lObs, lExp )
+        os.remove( pathFileName )
+        
+        
+    def test_getPathListFromIdList_empty_id_list( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t1\t10\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n")
+        pathF.write("3\tchr1\t8\t13\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+        self._db.createTable( self._table, "path", pathFileName )
+        
+        expList = []
+        obsList = self._tpA.getPathListFromIdList([])
+        self.assertEquals(expList, obsList)
+        
+        os.remove( pathFileName )
+        
+        
+    def test_getPathListFromIdList( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t1\t10\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n")
+        pathF.write("3\tchr1\t8\t13\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+
+        tuple = ("1", "chr1","1", "10","TE2","11","17","1e-20","30","90.2")
+        p1 = Path()
+        p1.setFromTuple(tuple)
+        
+        tuple = ("2", "chr1","2", "9","TE2","10","13","1e-20","30","90.2")
+        p2 = Path()
+        p2.setFromTuple(tuple)
+
+        tuple = ("3", "chr1","8", "13","TE2","11","17","1e-20","30","90.2")
+        p3 = Path()
+        p3.setFromTuple(tuple)
+        
+        self._db.createTable( self._table, "path", pathFileName )
+        lObs = self._tpA.getPathListFromIdList((1, 2, 3))
+        self.assertEquals(3, len(lObs))
+        
+        lExp = [p1, p2, p3]
+        self.assertEquals(lExp, lObs)
+        
+        os.remove( pathFileName )
+        
+        
+    def test_getPathListFromQuery( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t1\t10\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n")
+        pathF.write("3\tchr2\t8\t13\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+        self._db.createTable( self._table, "path", pathFileName )
+        path1 = Path()
+        path1.setFromString("1\tchr1\t1\t10\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        path2 = Path()
+        path2.setFromString("2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n")
+        expList = [ path1, path2 ]
+        obsList = self._tpA.getPathListFromQuery("chr1")
+        self.assertEquals( expList, obsList )
+        
+        os.remove( pathFileName )
+        
+        
+    def test_getPathListFromQuery_unexisted_query( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t1\t10\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n")
+        pathF.write("3\tchr2\t8\t13\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+        self._db.createTable( self._table, "path", pathFileName )
+        expList = []
+        obsList = self._tpA.getPathListFromQuery("dummy")
+        self.assertEquals( expList, obsList )
+        
+        os.remove( pathFileName )
+        
+        
+    def test_getPathListFromSubject( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t1\t10\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t2\t9\tTE3\t10\t13\t1e-20\t30\t90.2\n")
+        pathF.write("3\tchr2\t8\t13\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+        self._db.createTable( self._table, "path", pathFileName )
+        path1 = Path()
+        path1.setFromString("1\tchr1\t1\t10\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        path3 = Path()
+        path3.setFromString("3\tchr2\t8\t13\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        expList = [ path1, path3 ]
+        obsList = self._tpA.getPathListFromSubject("TE2")
+        self.assertEquals( expList, obsList )
+
+        os.remove( pathFileName )
+        
+        
+    def test_getPathListFromSubject_unexisted_subject( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t1\t10\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t2\t9\tTE3\t10\t13\t1e-20\t30\t90.2\n")
+        pathF.write("3\tchr2\t8\t13\tTE2\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+        self._db.createTable( self._table, "path", pathFileName )
+        expList = []
+        obsList = self._tpA.getPathListFromSubject("dummy")
+        self.assertEquals( expList, obsList )
+
+        os.remove( pathFileName )
+        
+        
+    def test_insert_QryDirSbjDir( self ):
+        path2Insert = Path()
+        
+        rangeQuery2Insert = Range()
+        rangeQuery2Insert.seqname = "chr1"
+        rangeQuery2Insert.start = 1
+        rangeQuery2Insert.end = 10
+        
+        rangeSubject2Insert = Range()
+        rangeSubject2Insert.seqname = "TE2"
+        rangeSubject2Insert.start = 11
+        rangeSubject2Insert.end = 17
+         
+        path2Insert.range_query = rangeQuery2Insert
+        path2Insert.range_subject = rangeSubject2Insert
+        
+        path2Insert.identity = 90.2
+        path2Insert.score = 30
+        path2Insert.e_value = 1e-20
+        path2Insert.id = 1
+        
+        self._db.createTable( self._table, "path" )
+        self._tpA.insert( path2Insert )
+        
+        expPathTuple = ((1L, "chr1", 1L, 10L, "TE2", 11L, 17L, 1e-20, 30L, 90.2),)
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+        
+    def test_insert_BigEvalue( self ):
+        path2Insert = Path()
+        
+        rangeQuery2Insert =  Range()
+        rangeQuery2Insert.seqname = "chr1"
+        rangeQuery2Insert.start = 1
+        rangeQuery2Insert.end = 10
+        
+        rangeSubject2Insert =  Range()
+        rangeSubject2Insert.seqname = "TE2"
+        rangeSubject2Insert.start = 11
+        rangeSubject2Insert.end = 17
+         
+        path2Insert.range_query = rangeQuery2Insert
+        path2Insert.range_subject = rangeSubject2Insert
+        
+        path2Insert.identity = 90.2
+        path2Insert.score = 30.0
+        path2Insert.e_value = 1e-300
+        path2Insert.id = 1
+        
+        self._db.createTable( self._table, "path" )
+        self._tpA.insert( path2Insert )
+        
+        expPathTuple = ((1L, "chr1", 1L, 10L, "TE2", 11L, 17L, 1e-300, 30L, 90.2),)
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+        
+    def test_insert_QryRevSbjDir( self ):
+        path2Insert = Path()
+        
+        rangeQuery2Insert =  Range()
+        rangeQuery2Insert.seqname = "chr1"
+        rangeQuery2Insert.start = 10
+        rangeQuery2Insert.end = 1
+        
+        rangeSubject2Insert =  Range()
+        rangeSubject2Insert.seqname = "TE2"
+        rangeSubject2Insert.start = 11
+        rangeSubject2Insert.end = 17
+         
+        path2Insert.range_query = rangeQuery2Insert
+        path2Insert.range_subject = rangeSubject2Insert
+        
+        path2Insert.identity = 90.2
+        path2Insert.score = 30
+        path2Insert.e_value = 1e-216
+        path2Insert.id = 1
+        
+        self._db.createTable( self._table, "path" )
+        self._tpA.insert( path2Insert )
+        
+        expPathTuple = ((1L, "chr1", 1L, 10L, "TE2", 17L, 11L, 1e-216, 30L, 90.2),)
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+        
+    def test_insertList(self):
+        p1 = Path()
+        p1.setFromString( "1\tchr1\t1\t10\tTE1\t11\t17\t1e-20\t30\t90.2\n" )
+        p2 = Path()
+        p2.setFromString( "2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n" )
+        p3 = Path()
+        p3.setFromString( "2\tchr1\t12\t19\tTE2\t15\t22\t1e-10\t40\t94.2\n" )
+        p4 = Path()
+        p4.setFromString( "3\tchr2\t8\t13\tTE1\t11\t17\t1e-20\t30\t90.2\n" )
+        lPath = [ p1, p2, p3, p4]
+        self._db.createTable( self._table, "path" )
+        self._tpA.insertList(lPath)
+        
+        tuple1 = (1L, "chr1", 1L, 10L, "TE1", 11L, 17L, 1e-20, 30L, 90.2)
+        tuple2 = (2L, "chr1", 2L, 9L, "TE2", 10L, 13L, 1e-20, 30L, 90.2)
+        tuple3 = (2L, "chr1", 12L, 19L, "TE2", 15L, 22L, 1e-10, 40L, 94.2)
+        tuple4 = (3L, "chr2", 8L, 13L, "TE1", 11L, 17L, 1e-20, 30L, 90.2)
+        expPathTuple = ( tuple1, tuple2, tuple3, tuple4)
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsPathTuple = self._db.cursor.fetchall()
+        
+        self.assertEquals(expPathTuple, obsPathTuple)
+        
+        
+    def test_getIdListFromQuery( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromString( "1\tchr1\t1\t10\tTE1\t11\t17\t1e-20\t30\t90.2\n" )
+        p2a = Path()
+        p2a.setFromString( "2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n" )
+        p2b = Path()
+        p2b.setFromString( "2\tchr1\t12\t19\tTE2\t15\t22\t1e-10\t40\t94.2\n" )
+        p3 = Path()
+        p3.setFromString( "3\tchr2\t8\t13\tTE1\t11\t17\t1e-20\t30\t90.2\n" )
+        for p in [ p1, p2a, p2b, p3 ]: self._tpA.insert( p )
+        lExp = [ 1, 2 ]
+        lObs = self._tpA.getIdListFromQuery( "chr1" )
+        self.assertEqual( lObs, lExp )
+        
+        
+    def test_getIdListFromSubject( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromString( "1\tchr1\t1\t10\tTE1\t11\t17\t1e-20\t30\t90.2\n" )
+        p2a = Path()
+        p2a.setFromString( "2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n" )
+        p2b = Path()
+        p2b.setFromString( "2\tchr1\t12\t19\tTE2\t15\t22\t1e-10\t40\t94.2\n" )
+        p3 = Path()
+        p3.setFromString( "3\tchr2\t8\t13\tTE1\t11\t17\t1e-20\t30\t90.2\n" )
+        for p in [ p1, p2a, p2b, p3 ]: self._tpA.insert( p )
+        lExp = [ 2 ]
+        lObs = self._tpA.getIdListFromSubject( "TE2" )
+        self.assertEqual( lObs, lExp )
+        
+        
+    def test_getIdList( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromString( "1\tchr1\t1\t10\tTE1\t11\t17\t1e-20\t30\t90.2\n" )
+        p2 = Path()
+        p2.setFromString( "2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n" )
+        p3 = Path()
+        p3.setFromString( "2\tchr1\t12\t19\tTE2\t15\t22\t1e-10\t40\t94.2\n" )
+        p4 = Path()
+        p4.setFromString( "3\tchr2\t8\t13\tTE1\t11\t17\t1e-20\t30\t90.2\n" )
+        lPath = [ p1, p2, p3, p4]
+        self._tpA.insertList(lPath)
+        expList = [ 1, 2, 3 ]
+        obsList = self._tpA.getIdList()
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getSubjectList( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t1\t10\tTE3\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t12\t19\tTE2\t15\t22\t1e-10\t40\t94.2\n")
+        pathF.write("3\tchr2\t8\t13\tTE1\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+        self._db.createTable( self._table, "path", pathFileName )
+        expList = [ "TE1", "TE2", "TE3" ]
+        obsList = self._tpA.getSubjectList()
+        self.assertEqual( expList, obsList )
+        os.remove( pathFileName )
+        
+        
+    def test_getSubjectList_empty_table( self ):
+        self._db.createTable( self._table, "path" )
+        expList = []
+        obsList = self._tpA.getSubjectList()
+        self.assertEqual( obsList, expList )
+        
+        
+    def test_getQueryList( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t1\t10\tTE3\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t12\t19\tTE2\t15\t22\t1e-10\t40\t94.2\n")
+        pathF.write("3\tchr2\t8\t13\tTE1\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+        self._db.createTable( self._table, "path", pathFileName )
+        expList = [ "chr1", "chr2" ]
+        obsList = self._tpA.getQueryList()
+        self.assertEqual( expList, obsList )
+        os.remove( pathFileName )
+        
+        
+    def test_getSubjectListFromQuery( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t1\t10\tTE3\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t12\t19\tTE2\t15\t22\t1e-10\t40\t94.2\n")
+        pathF.write("3\tchr2\t8\t13\tTE1\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+        self._db.createTable( self._table, "path", pathFileName )
+        expList = [ "TE3", "TE2" ]
+        obsList = self._tpA.getSubjectListFromQuery( "chr1" )
+        self.assertEqual( expList, obsList )
+        os.remove( pathFileName )
+        
+        
+    def test_getSubjectListFromQuery_with_unexisted_query( self ):
+        pathFileName = "dummyPathFile_%s" % ( self._uniqId )
+        pathF = open( pathFileName, "w" )
+        pathF.write("1\tchr1\t1\t10\tTE3\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.2\n")
+        pathF.write("2\tchr1\t12\t19\tTE2\t15\t22\t1e-10\t40\t94.2\n")
+        pathF.write("3\tchr2\t8\t13\tTE1\t11\t17\t1e-20\t30\t90.2\n")
+        pathF.close()
+        self._db.createTable( self._table, "path", pathFileName )
+        expList = []
+        obsList = self._tpA.getSubjectListFromQuery( "chr3" )
+        self.assertEqual( expList, obsList )
+        os.remove( pathFileName )
+        
+        
+    def test_getListOfAllPaths( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromString( "1\tchr1\t1\t10\tTE3\t11\t17\t1e-20\t30\t85.2\n" )
+        p2a = Path()
+        p2a.setFromString( "2\tchr1\t2\t9\tTE2\t10\t13\t1e-20\t30\t90.5\n" )
+        p2b = Path()
+        p2b.setFromString( "2\tchr1\t12\t19\tTE2\t15\t22\t1e-10\t40\t89.5\n" )
+        lPaths = [ p1, p2a, p2b ]
+        self._tpA.insertList( lPaths )
+        expList = [ p1, p2a, p2b ]
+        obsList = self._tpA.getListOfAllPaths()
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getListOfAllPaths_empty_table( self ):
+        self._db.createTable( self._table, "path" )
+        expList = []
+        obsList = self._tpA.getListOfAllPaths()
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getPathListWithDirectQueryDirectSubjectFromQuerySubject( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromString( "1\tchr1\t1\t100\tTE1\t11\t110\t1e-20\t130\t85.2\n" )
+        p2 = Path()
+        p2.setFromString( "2\tchr2\t1\t100\tTE1\t11\t110\t1e-20\t130\t85.2\n" )  # different query
+        p3 = Path()
+        p3.setFromString( "3\tchr1\t1\t100\tTE2\t11\t110\t1e-20\t130\t85.2\n" )  # different subject
+        p4 = Path()
+        p4.setFromString( "4\tchr1\t100\t1\tTE1\t11\t110\t1e-20\t130\t85.2\n" )  # query on reverse strand
+        p5 = Path()
+        p5.setFromString( "5\tchr1\t1\t100\tTE1\t110\t11\t1e-20\t130\t85.2\n" )  # subject on reverse strand
+        p6 = Path()
+        p6.setFromString( "6\tchr1\t301\t400\tTE1\t11\t110\t1e-20\t130\t85.2\n" )  # further along the query
+        for p in [ p1, p2, p3, p4, p5, p6 ]: self._tpA.insert( p )
+        expList = [ p1, p6 ]
+        obsList = self._tpA.getPathListWithDirectQueryDirectSubjectFromQuerySubject( "chr1", "TE1" )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getPathListWithDirectQueryReverseSubjectFromQuerySubject( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromString( "1\tchr1\t1\t100\tTE1\t110\t11\t1e-20\t130\t85.2\n" )
+        p2 = Path()
+        p2.setFromString( "2\tchr2\t1\t100\tTE1\t110\t11\t1e-20\t130\t85.2\n" )  # different query
+        p3 = Path()
+        p3.setFromString( "3\tchr1\t1\t100\tTE2\t110\t11\t1e-20\t130\t85.2\n" )  # different subject
+        p4 = Path()
+        p4.setFromString( "4\tchr1\t100\t1\tTE1\t110\t11\t1e-20\t130\t85.2\n" )  # query on reverse strand
+        p5 = Path()
+        p5.setFromString( "5\tchr1\t1\t100\tTE1\t11\t110\t1e-20\t130\t85.2\n" )  # subject on direct strand
+        p6 = Path()
+        p6.setFromString( "6\tchr1\t301\t400\tTE1\t110\t11\t1e-20\t130\t85.2\n" )  # further along the query
+        for p in [ p1, p2, p3, p4, p5, p6 ]: self._tpA.insert( p )
+        lExp = [ p1, p6 ]
+        lObs = self._tpA.getPathListWithDirectQueryReverseSubjectFromQuerySubject( "chr1", "TE1" )
+        self.assertEqual( lObs, lExp )
+        
+        
+    def test_isEmpty( self ):
+        self._db.createTable( self._table, "path" )
+        obs = self._tpA.isEmpty()
+        self.assertTrue( obs )
+        p = Path()
+        p.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "1e-32", "164", "97.5" ) )
+        self._tpA.insert( p )
+        obs = self._tpA.isEmpty()
+        self.assertFalse( obs )
+        
+        
+    def test_getNbPathsFromQuery( self ):
+        self._db.createTable( self._table, "path" )
+        p1a = Path()
+        p1a.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "1e-32", "164", "97.5" ) )
+        p1b = Path()
+        p1b.setFromTuple( ( "1", "qry1", "111", "200", "sbj1", "101", "190", "1e-32", "164", "97.5" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "2001", "2200", "sbj3", "1", "200", "1e-76", "247", "96.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry2", "1", "350", "sbj1", "1", "350", "1e-43", "624", "98.1" ) )
+        lPaths = [ p1a, p1b, p2, p3 ]
+        self._tpA.insertList( lPaths )
+        expNb = 3
+        obsNb = self._tpA.getNbPathsFromQuery( "qry1" )
+        self.assertEqual( expNb, obsNb )
+        
+        
+    def test_getNbPathsFromQuery_unexisted_query( self ):
+        self._db.createTable( self._table, "path" )
+        p1a = Path()
+        p1a.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "1e-32", "164", "97.5" ) )
+        p1b = Path()
+        p1b.setFromTuple( ( "1", "qry1", "111", "200", "sbj1", "101", "190", "1e-32", "164", "97.5" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "2001", "2200", "sbj3", "1", "200", "1e-76", "247", "96.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry2", "1", "350", "sbj1", "1", "350", "1e-43", "624", "98.1" ) )
+        lPaths = [ p1a, p1b, p2, p3 ]
+        self._tpA.insertList( lPaths )
+        expNb = 0
+        obsNb = self._tpA.getNbPathsFromQuery( "qry3" )
+        self.assertEqual( expNb, obsNb )
+        
+        
+    def test_getNbPathsFromSubject( self ):
+        self._db.createTable( self._table, "path" )
+        p1a = Path()
+        p1a.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "1e-32", "164", "97.5" ) )
+        p1b = Path()
+        p1b.setFromTuple( ( "1", "qry1", "111", "200", "sbj1", "101", "190", "1e-32", "164", "97.5" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "2001", "2200", "sbj3", "1", "200", "1e-76", "247", "96.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry2", "1", "350", "sbj1", "1", "350", "1e-43", "624", "98.1" ) )
+        lPaths = [ p1a, p1b, p2, p3 ]
+        self._tpA.insertList( lPaths )
+        expNb = 3
+        obsNb = self._tpA.getNbPathsFromSubject( "sbj1" )
+        self.assertEqual( expNb, obsNb )
+        
+        
+    def test_getNbPathsFromSubject_unexisted_subject( self ):
+        self._db.createTable( self._table, "path" )
+        p1a = Path()
+        p1a.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "1e-32", "164", "97.5" ) )
+        p1b = Path()
+        p1b.setFromTuple( ( "1", "qry1", "111", "200", "sbj1", "101", "190", "1e-32", "164", "97.5" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "2001", "2200", "sbj3", "1", "200", "1e-76", "247", "96.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry2", "1", "350", "sbj1", "1", "350", "1e-43", "624", "98.1" ) )
+        lPaths = [ p1a, p1b, p2, p3 ]
+        self._tpA.insertList( lPaths )
+        expNb = 0
+        obsNb = self._tpA.getNbPathsFromSubject( "qry1" )
+        self.assertEqual( expNb, obsNb )
+        
+        
+    def test_getNbIds( self ):
+        self._db.createTable( self._table, "path" )
+        p1a = Path()
+        p1a.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "1e-32", "164", "97.5" ) )
+        p1b = Path()
+        p1b.setFromTuple( ( "1", "qry1", "111", "200", "sbj1", "101", "190", "1e-32", "164", "97.5" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "2001", "2200", "sbj3", "1", "200", "1e-76", "247", "96.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry2", "1", "350", "sbj1", "1", "350", "1e-43", "624", "98.1" ) )
+        for p in [ p1a, p1b, p2, p3 ]: self._tpA.insert( p )
+        exp = 3
+        obs = self._tpA.getNbIds()
+        self.assertEqual( obs, exp )
+        
+        
+    def test_getNbIdsFromSubject( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj1", "1", "150", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+
+        expNb = 2
+        obsNb = self._tpA.getNbIdsFromSubject( "sbj1" )
+        self.assertEqual( expNb, obsNb )
+        
+        
+    def test_getNbIdsFromSubject_unexisted_subject( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj1", "1", "150", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+
+        expNb = 0
+        obsNb = self._tpA.getNbIdsFromSubject( "sbj2" )
+        self.assertEqual( expNb, obsNb ) 
+        
+        
+    def test_getNbIdsFromQuery( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj2", "1", "150", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+
+        expNb = 2
+        obsNb = self._tpA.getNbIdsFromQuery( "qry1" )
+        self.assertEqual( expNb, obsNb )
+        
+        
+    def test_getNbIdsFromQuery_unexisted_query( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj2", "1", "150", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+
+        expNb = 0
+        obsNb = self._tpA.getNbIdsFromQuery( "qry2" )
+        self.assertEqual( expNb, obsNb )
+        
+        
+    def test_getPathListIncludedInQueryCoord_included( self ):
+        self._db.createTable( self._table, "path" )
+        p = Path()
+        p.setFromTuple( ( "1", "qry1", "123", "184", "sbj1", "1", "63", "0.0", "75", "97.5" ) )
+        self._tpA.insert( p )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj2", "1", "150", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+        expList = [ p ]
+        obsList = self._tpA.getPathListIncludedInQueryCoord( "qry1", 100, 200 )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getPathListIncludedInQueryCoord_included_start_higher_than_end( self ):
+        self._db.createTable( self._table, "path" )
+        p = Path()
+        p.setFromTuple( ( "1", "qry1", "123", "184", "sbj1", "1", "63", "0.0", "75", "97.5" ) )
+        self._tpA.insert( p )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj2", "1", "150", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+        expList = [ p ]
+        obsList = self._tpA.getPathListIncludedInQueryCoord( "qry1", 200, 100 )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getPathListIncludedInQueryCoord_overlapping( self ):
+        self._db.createTable( self._table, "path" )
+        p = Path()
+        p.setFromTuple( ( "1", "qry1", "83", "184", "sbj1", "1", "103", "0.0", "137", "96.5" ) )
+        self._tpA.insert( p )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj2", "1", "150", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+        expList = []
+        obsList = self._tpA.getPathListIncludedInQueryCoord( "qry1", 100, 200 )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getPathListOverlappingQueryCoord(self):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "83", "184", "sbj1", "1", "103", "0.0", "137", "96.5" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj2", "1", "150", "0.0", "187", "97.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry1", "1", "350", "sbj1", "1", "350", "1e-43", "624", "98.1" ) )
+        lPath = [ p1, p2, p3 ]
+        self._tpA.insertList(lPath)
+        expList = [ p1, p3 ]
+        obsList = self._tpA.getPathListOverlappingQueryCoord( "qry1", 100, 200 )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getPathListOverlappingQueryCoord_no_overlapping_and_start_higher_than_end(self):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "83", "184", "sbj1", "1", "103", "0.0", "137", "96.5" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj2", "1", "150", "0.0", "187", "97.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry2", "1", "350", "sbj1", "1", "350", "1e-43", "624", "98.1" ) )
+        lPath = [ p1, p2, p3 ]
+        self._tpA.insertList(lPath)
+        expList = []
+        obsList = self._tpA.getPathListOverlappingQueryCoord( "qry1", 80, 1 )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getPathListOverlappingQueryCoord_withChains(self):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "83", "184", "sbj1", "1", "103", "0.0", "137", "96.5" ) )
+        p2a = Path()
+        p2a.setFromTuple( ( "2", "qry1", "1", "150", "sbj2", "1", "150", "0.0", "187", "97.2" ) )
+        p2b = Path()
+        p2b.setFromTuple( ( "2", "qry1", "251", "350", "sbj1", "151", "250", "1e-43", "624", "98.1" ) )
+        lPath = [ p1, p2a, p2b ]
+        self._tpA.insertList(lPath)
+        expList = [ p1, p2a ]
+        obsList = self._tpA.getPathListOverlappingQueryCoord( "qry1", 100, 200 )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getChainListOverlappingQueryCoord(self):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "83", "184", "sbj1", "1", "103", "0.0", "137", "96.5" ) )
+        p2a = Path()
+        p2a.setFromTuple( ( "2", "qry1", "1", "150", "sbj2", "1", "150", "0.0", "187", "97.2" ) )
+        p2b = Path()
+        p2b.setFromTuple( ( "2", "qry1", "251", "350", "sbj1", "151", "250", "1e-43", "624", "98.1" ) )
+        lPath = [ p1, p2a, p2b ]
+        self._tpA.insertList(lPath)
+        expList = [ p1, p2a, p2b ]
+        obsList = self._tpA.getChainListOverlappingQueryCoord( "qry1", 100, 200 )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getSetListOverlappingQueryCoord(self):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "83", "184", "sbj1", "1", "103", "0.0", "137", "96.5" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj2", "1", "150", "0.0", "187", "97.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry1", "1", "350", "sbj2", "1", "350", "1e-43", "624", "98.1" ) )
+        lPath = [ p1, p2, p3 ]
+        self._tpA.insertList(lPath)
+        
+        set1 = Set()
+        set1.setFromTuple( ( "1", "sbj1", "qry1", "83", "184" ) )
+        set3 = Set()
+        set3.setFromTuple( ( "3", "sbj2", "qry1", "1", "350" ) )
+        expList = [ set1, set3 ]
+        obsList = self._tpA.getSetListOverlappingQueryCoord( "qry1", 100, 200 )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getSetListOverlappingQueryCoord_no_overlapping_and_start_higher_than_end(self):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "83", "184", "sbj1", "1", "103", "0.0", "137", "96.5" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj2", "1", "150", "0.0", "187", "97.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry2", "1", "350", "sbj1", "1", "350", "1e-43", "624", "98.1" ) )
+        lPath = [ p1, p2, p3 ]
+        self._tpA.insertList(lPath)
+        expList = []
+        obsList = self._tpA.getSetListOverlappingQueryCoord( "qry1", 80, 1 )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getSetListIncludedInQueryCoord(self):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "102", "184", "sbj1", "1", "103", "0.0", "137", "96.5" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj2", "1", "150", "0.0", "187", "97.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry1", "1", "350", "sbj2", "1", "350", "1e-43", "624", "98.1" ) )
+        lPath = [ p1, p2, p3 ]
+        self._tpA.insertList(lPath)
+        
+        set1 = Set()
+        set1.setFromTuple( ( "1", "sbj1", "qry1", "102", "184" ) )
+        expList = [ set1 ]
+        obsList = self._tpA.getSetListIncludedInQueryCoord( "qry1", 100, 200 )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getSetListIncludedInQueryCoord_no_including_and_start_higher_than_end(self):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "83", "184", "sbj1", "1", "103", "0.0", "137", "96.5" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj2", "1", "150", "0.0", "187", "97.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry2", "1", "350", "sbj1", "1", "350", "1e-43", "624", "98.1" ) )
+        lPath = [ p1, p2, p3 ]
+        self._tpA.insertList(lPath)
+        expList = []
+        obsList = self._tpA.getSetListIncludedInQueryCoord( "qry1", 80, 1 )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getPathListSortedByQueryCoord( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "3", "qry2", "101", "200", "sbj3", "1", "100", "0.0", "137", "96.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "151", "500", "sbj1", "1", "350", "0.0", "137", "96.5" ) )
+        self._tpA.insert( p2 )
+        p3 = Path()
+        p3.setFromTuple( ( "1", "qry1", "1", "200", "sbj3", "1", "200", "0.0", "137", "96.5" ) )
+        self._tpA.insert( p3 )
+        
+        expList = [ p3, p2, p1 ]
+        obsList = self._tpA.getPathListSortedByQueryCoord()
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getPathListSortedByQueryCoordFromQuery( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "3", "qry2", "101", "200", "sbj3", "1", "100", "0.0", "137", "96.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "151", "500", "sbj1", "1", "350", "0.0", "137", "96.5" ) )
+        self._tpA.insert( p2 )
+        p3 = Path()
+        p3.setFromTuple( ( "1", "qry1", "1", "200", "sbj3", "1", "200", "0.0", "137", "96.5" ) )
+        self._tpA.insert( p3 )
+        
+        expList = [ p3, p2 ]
+        obsList = self._tpA.getPathListSortedByQueryCoordFromQuery( "qry1" )
+        self.assertEqual( expList, obsList )
+        
+    def test_getPathListSortedByQueryCoordAndScoreFromQuery( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "3", "qry2", "101", "200", "sbj3", "1", "100", "0.0", "137", "96.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "151", "500", "sbj1", "1", "350", "0.0", "137", "96.5" ) )
+        self._tpA.insert( p2 )
+        p3 = Path()
+        p3.setFromTuple( ( "1", "qry1", "1", "200", "sbj3", "1", "200", "0.0", "137", "96.5" ) )
+        self._tpA.insert( p3 )
+        p4 = Path()
+        p4.setFromTuple( ( "4", "qry1", "1", "200", "sbj3", "1", "200", "0.0", "200", "96.5" ) )
+        self._tpA.insert( p4 )
+        
+        expList = [  p3, p4, p2 ]
+        obsList = self._tpA.getPathListSortedByQueryCoordAndScoreFromQuery( "qry1" )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getCumulLengthFromSubject( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj1", "1", "150", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+
+        exp = 250
+        obs = self._tpA.getCumulLengthFromSubject( "sbj1" )
+        self.assertEqual( obs, exp )
+        
+        
+    def test_getCumulLengthFromSubject_with_no_subject( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj1", "1", "150", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+
+        exp = 0
+        obs = self._tpA.getCumulLengthFromSubject( "sbj2" )
+        self.assertEqual( obs, exp )    
+        
+        
+    def test_getChainLengthListFromSubject( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "1", "qry1", "351", "500", "sbj1", "101", "250", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+        p3 = Path()
+        p3.setFromTuple( ( "2", "qry1", "801", "900", "sbj1", "1", "100", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p3 )
+        p4 = Path()
+        p4.setFromTuple( ( "3", "qry1", "1900", "1801", "sbj1", "1", "100", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p4 )
+        p5 = Path()
+        p5.setFromTuple( ( "4", "qry1", "1801", "1900", "sbj1", "100", "1", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p5 )
+        
+        expList = [ 250, 100, 100, 100 ]
+        obsList = self._tpA.getChainLengthListFromSubject( "sbj1" )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getChainIdentityListFromSubject( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "1", "qry1", "351", "500", "sbj1", "101", "250", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+        p3 = Path()
+        p3.setFromTuple( ( "2", "qry1", "801", "900", "sbj1", "1", "100", "0.0", "187", "94.3" ) )
+        self._tpA.insert( p3 )
+        
+        idChain1 = ( 98.5*(200-101+1) + 97.2*(500-351+1) ) / float(200-101+1+500-351+1)
+        idChain2 = 94.3*(900-801+1) / float(900-801+1)
+        expList = [ idChain1, idChain2 ]
+        obsList = self._tpA.getChainIdentityListFromSubject( "sbj1" )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getPathLengthListFromSubject( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "1", "qry1", "351", "500", "sbj1", "101", "250", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+        p3 = Path()
+        p3.setFromTuple( ( "2", "qry1", "801", "900", "sbj1", "1", "100", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p3 )
+        
+        expList = [ 100, 150, 100 ]
+        obsList = self._tpA.getPathLengthListFromSubject( "sbj1" )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getIdListSortedByDecreasingChainLengthFromSubject( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0847", "100", "97.2" ) )
+        self._tpA.insert( p1 )
+        p2a = Path()
+        p2a.setFromTuple( ( "2", "qry1", "351", "500", "sbj1", "1", "150", "0.0035", "100", "97.2" ) )
+        self._tpA.insert( p2a )
+        p2b = Path()
+        p2b.setFromTuple( ( "2", "qry1", "551", "700", "sbj1", "151", "300", "0.0098", "100", "97.2" ) )
+        self._tpA.insert( p2b )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry2", "541", "800", "sbj1", "1", "260", "0.147", "100", "97.2" ) )
+        self._tpA.insert( p3 )
+        
+        expList = [ 2, 3, 1 ]
+        obsList = self._tpA.getIdListSortedByDecreasingChainLengthFromSubject( "sbj1" )
+        
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getIdListFromSubjectWhereChainsLongerThanThreshold( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "1", "100", "sbj1", "1", "100", "0.0847", "100", "97.2" ) )  # 1-fragment copy, long enough
+        self._tpA.insert( p1 )
+        p2a = Path()
+        p2a.setFromTuple( ( "2", "qry2", "1", "50", "sbj1", "1", "50", "0.0035", "100", "97.2" ) )
+        self._tpA.insert( p2a )
+        p2b = Path()
+        p2b.setFromTuple( ( "2", "qry2", "101", "150", "sbj1", "51", "100", "0.0098", "100", "97.2" ) )  # 2-fragment copy, long enough
+        self._tpA.insert( p2b )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry3", "1", "80", "sbj1", "1", "80", "0.147", "100", "97.2" ) )  # 1-fragment copy, too short
+        self._tpA.insert( p3 )
+        p4a = Path()
+        p4a.setFromTuple( ( "4", "qry4", "1", "30", "sbj1", "1", "30", "0.0035", "100", "97.2" ) )
+        self._tpA.insert( p4a )
+        p4b = Path()
+        p4b.setFromTuple( ( "4", "qry4", "101", "150", "sbj1", "31", "80", "0.0098", "100", "97.2" ) )  # 2-fragment copy, too short
+        self._tpA.insert( p4b )
+        
+        exp = [ 1, 2 ]
+        obs = self._tpA.getIdListFromSubjectWhereChainsLongerThanThreshold( "sbj1", 90 )
+        
+        self.assertEqual( exp, obs )
+        
+        
+    def test_getSetListFromQuery(self):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "1", "qry1", "351", "500", "sbj1", "101", "250", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+        p3 = Path()
+        p3.setFromTuple( ( "2", "qry1", "801", "900", "sbj1", "1", "100", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p3 )
+        
+        set1 = Set()
+        set1.setFromTuple( ( "1", "sbj1", "qry1", "101", "200" ) )
+        set2 = Set()
+        set2.setFromTuple( ( "1", "sbj1", "qry1", "351", "500" ) )    
+        set3 = Set()
+        set3.setFromTuple( ( "2", "sbj1", "qry1", "801", "900" ) )
+        expList = [set1, set2, set3]
+        obsList =  self._tpA.getSetListFromQuery("qry1")
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_deleteFromId(self):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "1", "qry1", "351", "500", "sbj1", "101", "250", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+        p3 = Path()
+        p3.setFromTuple( ( "2", "qry1", "801", "900", "sbj1", "1", "100", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p3 )
+        
+        self._tpA.deleteFromId(2)
+        expList = [p1, p2]
+        obsList = self._tpA.getListOfAllPaths()
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_deleteFromPath(self):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "1", "qry1", "351", "500", "sbj1", "101", "250", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+        p3 = Path()
+        p3.setFromTuple( ( "2", "qry1", "801", "900", "sbj1", "1", "100", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p3 )
+        
+        self._tpA.deleteFromPath(p3)
+        expList = [p1, p2]
+        obsList = self._tpA.getListOfAllPaths()
+        self.assertEqual( expList, obsList )
+        
+    def test_deleteFromPath_two_lines_to_delete(self):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "1", "qry1", "351", "500", "sbj1", "101", "250", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+        p3 = Path()
+        p3.setFromTuple( ( "2", "qry1", "801", "900", "sbj1", "1", "100", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p3 )
+        p4 = Path()
+        p4.setFromTuple( ( "2", "qry1", "801", "900", "sbj1", "1", "100", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p4 )
+        
+        self._tpA.deleteFromPath(p3)
+        expList = [p1, p2]
+        obsList = self._tpA.getListOfAllPaths()
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_deleteFromIdList(self):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj1", "101", "250", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry1", "801", "900", "sbj1", "1", "100", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p3 )
+        lId = [ 1, 2 ]
+        self._tpA.deleteFromIdList(lId)
+        expList = [ p3 ]
+        obsList = self._tpA.getListOfAllPaths()
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_joinTwoPaths(self):
+        self._db.createTable( self._table, "path" )
+        
+        idPath1 = 5
+        p1 = Path()
+        p1.setFromTuple( ( "5", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        
+        idPath2 = 2
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj1", "101", "250", "0.0", "187", "97.2" ) )
+        
+        lPath = [ p1, p2 ]
+        self._tpA.insertList( lPath )
+
+        self._tpA.joinTwoPaths(idPath1, idPath2)
+
+        expP1 = Path()
+        expP1.setFromTuple( ( "2", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        expP2 = Path()
+        expP2.setFromTuple( ( "2", "qry1", "351", "500", "sbj1", "101", "250", "0.0", "187", "97.2" ) )
+        
+        expList = [ expP1, expP2 ]
+        obsList = self._tpA.getListOfAllPaths()
+        
+        self.assertEqual( expList, obsList)
+        self._db.dropTable(self._table)        
+        
+        
+    def test_joinTwoPaths_with_id1_inferior_at_id2(self):
+        self._db.createTable( self._table, "path" )
+        
+        idPath1 = 5
+        p1 = Path()
+        p1.setFromTuple( ( "5", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        
+        idPath2 = 2
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj1", "101", "250", "0.0", "187", "97.2" ) )
+        
+        lPath = [ p1, p2 ]
+        self._tpA.insertList( lPath )
+
+        self._tpA.joinTwoPaths(idPath2, idPath1)
+
+        expP1 = Path()
+        expP1.setFromTuple( ( "2", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        expP2 = Path()
+        expP2.setFromTuple( ( "2", "qry1", "351", "500", "sbj1", "101", "250", "0.0", "187", "97.2" ) )
+        
+        expList = [ expP1, expP2 ]
+        obsList = self._tpA.getListOfAllPaths()
+        
+        self.assertEqual( expList, obsList)
+        self._db.dropTable(self._table)       
+        
+        
+    def test_getNewId(self):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0", "137", "98.5" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj1", "101", "250", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p2 )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry1", "801", "900", "sbj1", "1", "100", "0.0", "187", "97.2" ) )
+        self._tpA.insert( p3 )
+        
+        expId = 4
+        obsId = self._tpA.getNewId()
+        self.assertEqual( expId, obsId)
+        
+        
+    def test_getNewId_path_null(self):
+        self._db.createTable( self._table, "path" )
+        expId = 1
+        obsId = self._tpA.getNewId()
+        self.assertEqual( expId, obsId)
+        
+        
+    def test_getListOfChainsSortedByAscIdentityFromQuery( self ):
+        self._db.createTable( self._table, "path" )
+        p1a = Path()
+        p1a.setFromTuple( ( "1", "qry1", "11", "100", "sbj1", "1", "90", "0.0", "132", "96.2" ) )
+        p2a = Path()
+        p2a.setFromTuple( ( "2", "qry1", "101", "120", "sbj2", "1", "20", "0.0", "36", "98.0" ) )
+        p1b = Path()
+        p1b.setFromTuple( ( "1", "qry1", "121", "200", "sbj1", "91", "170", "0.0", "117", "96.5" ) )
+        p2b = Path()
+        p2b.setFromTuple( ( "2", "qry1", "201", "800", "sbj2", "21", "620", "0.0", "856", "93.2" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry2", "1", "1000", "sbj1", "1", "1000", "1e-120", "900", "100.0" ) )
+        for p in [ p1a, p2a, p1b, p2b, p3 ]: self._tpA.insert( p )
+        lPaths1 = [ p1a, p1b ]
+        lPaths2 = [ p2a, p2b ]
+        expList = [ lPaths2, lPaths1 ]
+        obsList = self._tpA.getListOfChainsSortedByAscIdentityFromQuery( "qry1" )
+        for lPaths in expList: PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( lPaths )
+        for lPaths in obsList: PathUtils.getPathListSortedByIncreasingMinQueryThenMaxQuery( lPaths )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_getPathListSortedByIncreasingEvalueFromQuery( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "qry1", "101", "200", "sbj1", "1", "100", "0.0847", "100", "97.2" ) )
+        self._tpA.insert( p1 )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "qry1", "351", "500", "sbj2", "1", "150", "0.0035", "100", "97.2" ) )
+        self._tpA.insert( p2 )
+        p3 = Path()
+        p3.setFromTuple( ( "3", "qry2", "541", "800", "sbj3", "1", "260", "0.147", "100", "97.2" ) )
+        self._tpA.insert( p3 )
+        
+        expList = [ p2, p1 ]
+        obsList = self._tpA.getPathListSortedByIncreasingEvalueFromQuery( "qry1" )
+        self.assertEqual( expList, obsList )
+        
+        
+    def test_path2PathRange_QryDirSbjDir( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "chr1", "1", "10", "TE3", "11", "17", "1e-20", "30", "85.0" ) )
+        p2a = Path()
+        p2a.setFromTuple( ( "2", "chr2", "1", "100", "TE2", "10", "109", "1e-20", "163", "92.1" ) )
+        p2b = Path()
+        p2b.setFromTuple( ( "2", "chr2", "201", "250", "TE2", "151", "200", "1e-10", "75", "88.7" ) )
+        for p in [ p1, p2a, p2b ]: self._tpA.insert( p )
+        p2 = Path()
+        
+        p2.setFromTuple( ( "2", "chr2", "1", "250", "TE2", "10", "200", "1e-20", "238", "90.96" ) )   # 'merge' p2a and p2b
+        expList = [ p1, p2 ]
+        obsTable = self._tpA.path2PathRange()
+        self._tpA._table = obsTable
+        obsList = self._tpA.getListOfAllPaths()
+        self.assertEqual( expList, obsList )
+        self._db.dropTable( obsTable )
+        
+        
+    def test_path2PathRange_QryDirSbjRev( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "chr1", "1", "10", "TE3", "11", "17", "1e-20", "30", "85.0" ) )
+        p2a = Path()
+        p2a.setFromTuple( ( "2", "chr2", "1", "100", "TE2", "109", "10", "1e-20", "163", "92.1" ) )
+        p2b = Path()
+        p2b.setFromTuple( ( "2", "chr2", "201", "250", "TE2", "200", "151", "1e-10", "75", "88.7" ) )
+        for p in [ p1, p2a, p2b ]: self._tpA.insert( p )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "chr2", "1", "250", "TE2", "200", "10", "1e-20", "238", "90.96" ) )   # 'merge' p2a and p2b
+        expList = [ p1, p2 ]
+        obsTable = self._tpA.path2PathRange()
+        self._tpA._table = obsTable
+        obsList = self._tpA.getListOfAllPaths()
+        self.assertEqual( obsList, expList )
+        self._db.dropTable( obsTable )
+        
+        
+###################################################################################
+############################ Tests for other methods ##############################
+###################################################################################
+        
+    def test_path2PathRangeFromQuery_QryDirSbjDir( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "chr1", "1", "10", "TE3", "11", "17", "1e-20", "30", "85.0" ) )
+        p2a = Path()
+        p2a.setFromTuple( ( "2", "chr2", "1", "100", "TE2", "10", "109", "1e-20", "163", "92.1" ) )
+        p2b = Path()
+        p2b.setFromTuple( ( "2", "chr2", "201", "250", "TE2", "151", "200", "1e-10", "75", "88.7" ) )
+        for p in [ p1, p2a, p2b ]: self._tpA.insert( p )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "chr2", "1", "250", "TE2", "10", "200", "1e-20", "238", "90.96" ) )   # 'merge' p2a and p2b
+        expList = [ p2 ]
+        obsTable = self._tpA._path2PathRangeFromQuery( "chr2" )
+        self._tpA._table = obsTable
+        obsList = self._tpA.getListOfAllPaths()
+        self.assertEqual( expList, obsList )
+        self._db.dropTable( obsTable )
+        
+        
+    def test_path2PathRangeFromQuery_QryDirSbjRev( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "chr1", "1", "10", "TE3", "11", "17", "1e-20", "30", "85.0" ) )
+        p2a = Path()
+        p2a.setFromTuple( ( "2", "chr2", "1", "100", "TE2", "109", "10", "1e-20", "163", "92.1" ) )
+        p2b = Path()
+        p2b.setFromTuple( ( "2", "chr2", "201", "250", "TE2", "200", "151", "1e-10", "75", "88.7" ) )
+        for p in [ p1, p2a, p2b ]: self._tpA.insert( p )
+        p2 = Path()
+        p2.setFromTuple( ( "2", "chr2", "1", "250", "TE2", "200", "10", "1e-20", "238", "90.96" ) )   # 'merge' p2a and p2b
+        expList = [ p2 ]
+        obsTable = self._tpA._path2PathRangeFromQuery( "chr2" )
+        self._tpA._table = obsTable
+        obsList = self._tpA.getListOfAllPaths()
+        self.assertEqual( obsList, expList )
+        self._db.dropTable( obsTable )
+        
+        
+    def test_getNbOccurrences( self ):
+        self._db.createTable( self._table, "path" )
+        p1 = Path()
+        p1.setFromTuple( ( "1", "chr1", "1", "10", "TE3", "11", "17", "1e-20", "30", "85.0" ) )
+        
+        exp = 0
+        obs = self._tpA.getNbOccurrences( p1 )
+        self.assertEquals( exp, obs )
+        
+        self._tpA.insert( p1 )
+        exp = 1
+        obs = self._tpA.getNbOccurrences( p1 )
+        self.assertEquals( exp, obs )
+        
+        self._tpA.insert( p1 )
+        exp = 2
+        obs = self._tpA.getNbOccurrences( p1 )
+        self.assertEquals( exp, obs )
+        
+    def test_getListOfUniqueOccPath(self):
+        
+        p1 = Path()
+        p1.setFromTuple( ( "1", "chr1", "1", "10", "TE3", "11", "17", "1e-20", "30", "85.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "1", "chr1", "1", "10", "TE3", "11", "17", "1e-20", "30", "85.0" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "1", "chr1", "2", "10", "TE3", "11", "17", "1e-20", "30", "85.0" ) )
+        p4 = Path()
+        p4.setFromTuple( ( "2", "chr2", "2", "11", "TE4", "10", "18", "1e-30", "40", "95.0" ) )
+        lPath = [p1,p2,p3,p4]
+                
+        expListPath = deepcopy([p1,p3,p4])     
+        obsListUniquePath = self._tpA.getListOfUniqueOccPath(lPath)
+        self.assertEquals( expListPath, obsListUniquePath )
+
+    def test_getListOfUniqueOccPath_empty_list(self):
+        expListPath = []     
+        obsListUniquePath = self._tpA.getListOfUniqueOccPath([])
+        self.assertEquals( expListPath, obsListUniquePath )
+        
+    def test_getListOfUniqueOccPath_one_item(self):
+        p1 = Path()
+        p1.setFromTuple( ( "1", "chr1", "1", "10", "TE3", "11", "17", "1e-20", "30", "85.0" ) )
+        expListPath = deepcopy([p1])      
+        obsListUniquePath = self._tpA.getListOfUniqueOccPath([p1])
+        self.assertEquals( expListPath, obsListUniquePath )
+
+    def test_getListOfUniqueOccPath_unsorted_list(self):
+        
+        p1 = Path()
+        p1.setFromTuple( ( "1", "chr1", "1", "10", "TE3", "11", "17", "1e-20", "30", "85.0" ) )
+        p3 = Path()
+        p3.setFromTuple( ( "1", "chr1", "3", "10", "TE3", "11", "17", "1e-20", "30", "85.0" ) )
+        p4 = Path()
+        p4.setFromTuple( ( "2", "chr2", "2", "11", "TE4", "10", "18", "1e-30", "40", "95.0" ) )
+        p2 = Path()
+        p2.setFromTuple( ( "1", "chr1", "1", "10", "TE3", "11", "17", "1e-20", "30", "85.0" ) )
+        
+        lPath = [p1,p3,p4,p2]
+                
+        expListPath = deepcopy([p1,p3,p4])     
+        obsListUniquePath = self._tpA.getListOfUniqueOccPath(lPath)
+        self.assertEquals( expListPath, obsListUniquePath )
+
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_TablePathAdaptator ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_TableSeqAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,321 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import os
+import time
+from commons.core.sql.DbMySql import DbMySql
+from commons.core.sql.TableSeqAdaptator import TableSeqAdaptator
+from commons.core.seq.Bioseq import Bioseq
+from commons.core.coord.Set import Set
+from commons.core.utils.FileUtils import FileUtils
+
+
+class Test_TableSeqAdaptator( unittest.TestCase ):
+    
+    def setUp( self ):
+        self._uniqId = "%s_%s" % ( time.strftime("%Y%m%d%H%M%S") , os.getpid() )
+        self.fileUtils = FileUtils()
+        self._configFileName = "dummyConfigFile_%s" % ( self._uniqId )
+        configF = open(self._configFileName, "w" )
+        configF.write( "[repet_env]\n" )
+        configF.write( "repet_host: %s\n" % ( os.environ["REPET_HOST"] ) )
+        configF.write( "repet_user: %s\n" % ( os.environ["REPET_USER"] ) )
+        configF.write( "repet_pw: %s\n" % ( os.environ["REPET_PW"] ) )
+        configF.write( "repet_db: %s\n" % ( os.environ["REPET_DB"] ) )
+        configF.write( "repet_port: %s\n" % ( os.environ["REPET_PORT"] ) )
+        configF.close()
+        self._db = DbMySql( cfgFileName=self._configFileName )
+        self._table = "dummySeqTable_%s" % ( self._uniqId )
+        self._tsA = TableSeqAdaptator( self._db, self._table )
+        
+        
+    def tearDown( self ):
+        self._db.dropTable( self._table )
+        self._db.close()
+        os.remove( self._configFileName )
+        self._configFileName = ""
+        
+        
+##################################################################################
+################## Tests for methods in ITableSeqAdaptator #######################
+##################################################################################
+        
+    def test_insert( self ):
+        bs = Bioseq( "seq1", "AGCGATGACGATGCGAGT" )
+        self._db.createTable( self._table, "fasta" )
+        self._tsA.insert( bs )
+        
+        expBioseqTuple = (("seq1", "AGCGATGACGATGCGAGT", "seq1", 18L), )
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsBioseqTuple = self._db.cursor.fetchall()
+        
+        self.assertEqual( expBioseqTuple, obsBioseqTuple )
+        
+        
+    def test_insertList( self ):
+        bs1 = Bioseq( "seq1 desc", "AGCGATGACGATGCGAGT" )
+        bs2 = Bioseq( "seq2", "AGCGATGACGATGCGAGT")
+        bs3 = Bioseq( "seq3", "GCGATGCAGATGACGGCGGATGC")
+        lBioseq = [ bs1, bs2, bs3 ]
+        self._db.createTable( self._table, "fasta" )
+        self._tsA.insertList( lBioseq )
+        
+        tuple1 = ("seq1", "AGCGATGACGATGCGAGT", "seq1 desc", 18L)
+        tuple2 = ("seq2", "AGCGATGACGATGCGAGT", "seq2", 18L)
+        tuple3 = ("seq3", "GCGATGCAGATGACGGCGGATGC", "seq3", 23L)
+        expBioseqTuple = ( tuple1, tuple2, tuple3 )
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._db.execute( sqlCmd )
+        obsBioseqTuple = self._db.cursor.fetchall()
+        
+        self.assertEquals(expBioseqTuple, obsBioseqTuple)
+        
+        
+    def test_getAccessionsList(self):
+        faFileName = "dummyFaFile_%s" % ( self._uniqId )
+        faF = open( faFileName, "w" )
+        faF.write(">seq1\n")
+        faF.write("AGCGATGACGATGCGAGT\n")
+        faF.write(">seq2\n")
+        faF.write("GCGATGCAGATGACGGCGGATGC\n")
+        faF.close()
+        self._db.createTable( self._table, "fasta", faFileName )
+        lExp = [ "seq1", "seq2" ]
+        lExp.sort()
+        lObs = self._tsA.getAccessionsList()
+        lObs.sort()
+        self.assertEqual( lObs, lExp )
+        os.remove( faFileName )
+        
+        
+    def test_saveAccessionsListInFastaFile(self):
+        expFileName = "dummyFaFile_%s" % ( self._uniqId )
+        expF = open( expFileName, "w" )
+        expF.write(">seq1\n")
+        expF.write("AGCGATGACGATGCGAGT\n")
+        expF.write(">seq2\n")
+        expF.write("GCGATGCAGATGACGGCGGATGC\n")
+        expF.close()
+        self._db.createTable( self._table, "fasta", expFileName )
+        lAccessions = [ "seq1", "seq2" ]
+        obsFileName = "dummyObsFile_%s" % ( self._uniqId )
+        self._tsA.saveAccessionsListInFastaFile( lAccessions, obsFileName )
+        self.assertTrue( self.fileUtils.are2FilesIdentical( obsFileName, expFileName ) )
+        os.remove( expFileName )
+        os.remove( obsFileName )
+        
+    def test_exportInFastaFile(self):
+        expFileName = "dummyFaFile_%s" % ( self._uniqId )
+        faF = open( expFileName, "w" )
+        faF.write(">seq1\n")
+        faF.write("AGCGATGACGATGCGAGT\n")
+        faF.write(">seq2\n")
+        faF.write("GCGATGCAGATGACGGCGGATGC\n")
+        faF.close()
+        self._db.createTable( self._table, "fasta", expFileName )
+        obsFileName = "dummyFaFileObs_%s" % ( self._uniqId )
+        self._tsA.exportInFastaFile( obsFileName )
+        self.assertTrue( self.fileUtils.are2FilesIdentical( obsFileName, expFileName ) )
+        os.remove( expFileName )
+        os.remove( obsFileName )
+
+##################################################################################
+########################### Tests for other methods ##############################
+##################################################################################
+        
+    def test_insertWithBioseqEmpty( self ):
+        bs = Bioseq( "", "" )
+        self._db.createTable( self._table, "fasta" )
+        exp = None
+        obs = self._tsA.insert(bs)
+        self.assertEqual( exp, obs )
+        
+        
+    def test_getBioseqFromHeader( self ):
+        faFileName = "dummyFaFile_%s" % ( self._uniqId )
+        faF = open( faFileName, "w" )
+        faF.write(">seq1\n")
+        faF.write("AGCGATGACGATGCGAGT\n")
+        faF.write(">seq2\n")
+        faF.write("GCGATGCAGATGACGGCGGATGC\n")
+        faF.close()
+        self._db.createTable( self._table, "fasta", faFileName )
+        exp = Bioseq( "seq1", "AGCGATGACGATGCGAGT" )
+        obs = self._tsA.getBioseqFromHeader( "seq1" )
+        self.assertEqual( obs, exp )
+        exp = Bioseq( "seq2", "GCGATGCAGATGACGGCGGATGC" )
+        obs = self._tsA.getBioseqFromHeader( "seq2" )
+        self.assertEqual( obs, exp )
+        os.remove( faFileName )
+        
+        
+    def test_getSeqLengthFromAccession( self ):
+        inFileName = "dummyFaFile_%s" % ( self._uniqId )
+        inF = open( inFileName, "w" )
+        inF.write(">seq1\n")
+        inF.write("AGCGATGACGATGCGAGT\n")
+        inF.write(">seq2\n")
+        inF.write("GCGATGCAGATGACGGCGGATGC\n")
+        inF.close()
+        self._db.createTable( self._table, "fasta", inFileName )
+        exp = 18
+        obs = self._tsA.getSeqLengthFromAccession( "seq1" )
+        self.assertEqual( obs, exp )
+        os.remove( inFileName )
+
+
+    def test_getSeqLengthFromDescription( self ):
+        inFileName = "dummyFaFile_%s" % ( self._uniqId )
+        inF = open( inFileName, "w" )
+        inF.write(">seq1 descriptionfield\n")
+        inF.write("AGCGATGACGATGCGAGT\n")
+        inF.write(">seq2 descriptionfield\n")
+        inF.write("GCGATGCAGATGACGGCGGATGC\n")
+        inF.close()
+        self._db.createTable( self._table, "fasta", inFileName )
+        exp = 18
+        obs = self._tsA.getSeqLengthFromDescription( "seq1 descriptionfield" )
+        self.assertEqual( obs, exp )
+        os.remove( inFileName )
+        
+        
+    def test_getAccessionAndLengthList( self ):
+        inFileName = "dummyFaFile_%s" % ( self._uniqId )
+        inF = open( inFileName, "w" )
+        inF.write(">seq1\n")
+        inF.write("AGCGATGACGATGCGAGT\n")
+        inF.write(">seq2\n")
+        inF.write("GCGATGCAGATGACGGCGGATGC\n")
+        inF.close()
+        self._db.createTable( self._table, "fasta", inFileName )
+        lSeq1 = ("seq1", 18)
+        lSeq2 = ("seq2", 23)
+        lExp = [lSeq1,lSeq2]
+        lObs = self._tsA.getAccessionAndLengthList()
+        self.assertEqual( lObs, lExp )
+        os.remove( inFileName )
+        
+        
+    def test_getSeqLengthFromAccessionWithSingleQuote( self ):
+        inFileName = "dummyFaFile_%s" % ( self._uniqId )
+        inF = open( inFileName, "w" )
+        inF.write(">seq1'\n")
+        inF.write("AGCGATGACGATGCGAGT\n")
+        inF.write(">seq2\n")
+        inF.write("GCGATGCAGATGACGGCGGATGC\n")
+        inF.close()
+        self._db.createTable( self._table, "fasta", inFileName )
+        exp = 18
+        obs = self._tsA.getSeqLengthFromAccession( "seq1'" )
+        self.assertEqual( obs, exp )
+        os.remove( inFileName )
+        
+        
+    def test_getSubSequence_directStrand( self ):
+        self._db.createTable( self._table, "seq" )
+        chr = Bioseq()
+        chr.setHeader( "chr2" )
+        chr.setSequence( "AAAAAAAAAATTTTTGGGGGGGGGG" )
+        self._tsA.insert( chr )
+        exp = "TTTGGG"
+        obs = self._tsA.getSubSequence( "chr2", 13, 18 )
+        self.assertEqual( exp, obs )
+        
+        
+    def test_getSubSequence_reverseStrand( self ):
+        self._db.createTable( self._table, "seq" )
+        chr = Bioseq()
+        chr.setHeader( "chr2" )
+        chr.setSequence( "AAAAAAAAAATTTTTGGGGGGGGGG" )
+        self._tsA.insert( chr )
+        exp = "CCCAAA"
+        obs = self._tsA.getSubSequence( "chr2", 18, 13 )
+        self.assertEqual( exp, obs )
+        
+        
+    def test_getBioseqFromSetList_directStrand( self ):
+        self._db.createTable( self._table, "seq" )
+        chr = Bioseq()
+        chr.setHeader( "chr2" )
+        chr.setSequence( "AAAAAAAAAATTTTTGGGGGGGGGG" )
+        self._tsA.insert( chr )
+        lSets = []
+        lSets.append( Set( 3, "Dm-B-G600-Map3_classI-LTR-incomp", "chr2", 1, 10 ) )
+        lSets.append( Set( 3, "Dm-B-G600-Map3_classI-LTR-incomp", "chr2", 16, 25 ) )
+        exp = Bioseq( "Dm-B-G600-Map3_classI-LTR-incomp::3 chr2 1..10,16..25", "AAAAAAAAAAGGGGGGGGGG" )
+        obs = self._tsA.getBioseqFromSetList( lSets )
+        self.assertEqual( exp, obs )
+        
+        
+    def test_getBioseqFromSetList_reverseStrand( self ):
+        self._db.createTable( self._table, "seq" )
+        chr = Bioseq()
+        chr.setHeader( "chr2" )
+        chr.setSequence( "AAAAAAAAAATTTTTGGGGGGGGGG" )
+        self._tsA.insert( chr )
+        lSets = []
+        lSets.append( Set( 3, "Dm-B-G600-Map3_classI-LTR-incomp", "chr2", 10, 1 ) )
+        lSets.append( Set( 3, "Dm-B-G600-Map3_classI-LTR-incomp", "chr2", 25, 16 ) )
+        exp = Bioseq( "Dm-B-G600-Map3_classI-LTR-incomp::3 chr2 25..16,10..1", "CCCCCCCCCCTTTTTTTTTT" )
+        obs = self._tsA.getBioseqFromSetList( lSets )
+        self.assertEqual( exp, obs )
+        
+        
+    def test_isAccessionInTable_true( self ):
+        self._db.createTable( self._table, "seq" )
+        chr = Bioseq()
+        chr.setHeader( "chr2" )
+        chr.setSequence( "AAAAAAAAAATTTTTGGGGGGGGGG" )
+        self._tsA.insert( chr )
+        
+        obs = self._tsA.isAccessionInTable( "chr2" )
+        self.assertTrue( obs )
+        
+        
+    def test_isAccessionInTable_false( self ):
+        self._db.createTable( self._table, "seq" )
+        chr = Bioseq()
+        chr.setHeader( "chr2" )
+        chr.setSequence( "AAAAAAAAAATTTTTGGGGGGGGGG" )
+        self._tsA.insert( chr )
+        
+        obs = self._tsA.isAccessionInTable( "chr1" )
+        self.assertFalse( obs )
+        
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_TableSeqAdaptator ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Test_TableSetAdaptator.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,330 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import time
+import os
+from commons.core.sql.TableSetAdaptator import TableSetAdaptator
+from commons.core.sql.DbMySql import DbMySql
+from commons.core.coord.Set import Set
+
+
+class Test_TableSetAdaptator( unittest.TestCase ):
+
+    def setUp( self ):
+        self._uniqId = "%s_%s" % ( time.strftime("%Y%m%d%H%M%S") , os.getpid() )
+        self._configFileName = "dummyConfigFile_%s" % ( self._uniqId )
+        configF = open(self._configFileName, "w" )
+        configF.write( "[repet_env]\n" )
+        configF.write( "repet_host: %s\n" % ( os.environ["REPET_HOST"] ) )
+        configF.write( "repet_user: %s\n" % ( os.environ["REPET_USER"] ) )
+        configF.write( "repet_pw: %s\n" % ( os.environ["REPET_PW"] ) )
+        configF.write( "repet_db: %s\n" % ( os.environ["REPET_DB"] ) )
+        configF.write( "repet_port: %s\n" % ( os.environ["REPET_PORT"] ) )
+        configF.close()
+        self._iDb = DbMySql( cfgFileName=self._configFileName )
+        self._table = "dummySetTable_%s" % ( self._uniqId )
+        self._tSetA = TableSetAdaptator( self._iDb, self._table )
+                
+    def tearDown( self ):
+        self._uniqId = None
+        self._iDb.dropTable( self._table )
+        self._iDb.close()
+        self._table = None
+        self._tSetA = None
+        os.remove( self._configFileName )
+        self._configFileName = ""
+
+    def test_insert(self):
+        set2Insert = Set()
+        set2Insert.id = 1
+        set2Insert.name = "name1"
+        set2Insert.seqname = "name2"
+        set2Insert.start = 1L
+        set2Insert.end = 50L
+        self._iDb.createTable( self._table, "set", "" )
+        self._tSetA.insert( set2Insert, False )
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._iDb.execute( sqlCmd )
+        expTsetTuple = ((1, "name1", "name2", 1L, 50L),)
+        obsTsetTuples = self._iDb.cursor.fetchall()
+        self.assertEquals(expTsetTuple, obsTsetTuples )
+    
+    def test_insertList ( self ):
+        self._iDb.createTable( self._table, "set", "" )
+        set1 = Set()
+        set1.setFromString( "1\tname1\tdesc1\t1\t120\n" )
+        set2 = Set()
+        set2.setFromString( "2\tname2\tdesc2\t1\t20\n" )
+        lset = [ set1, set2 ]
+        self._tSetA.insertList( lset )
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._iDb.execute( sqlCmd )
+        expTsetTuple = ((1, "name1", "desc1", 1, 120), (2, "name2", "desc2", 1, 20))
+        obsTsetTuples = self._iDb.cursor.fetchall()
+        self.assertEqual( expTsetTuple, obsTsetTuples )
+
+    def test_getIdList(self):
+        set2Insert = Set()
+        set2Insert.id = 1
+        set2Insert.name = "name1"
+        set2Insert.seqname = "name2"
+        set2Insert.start = 1
+        set2Insert.end = 50
+        self._iDb.createTable( self._table, "set", "" )
+        self._tSetA.insert( set2Insert )
+        l = self._tSetA.getIdList()
+        self.assertEquals( set2Insert.id, l[0] )
+        
+    def test_getSeqNameList(self):
+        self._iDb.createTable( self._table, "set", "" )
+        set1 = Set()
+        set1.setFromString( "1\tname1\tdesc1\t1\t120\n" )
+        set2 = Set()
+        set2.setFromString( "2\tname2\tdesc2\t1\t20\n" )
+        set3 = Set()
+        set3.setFromString( "2\tname2\tdesc2\t1\t50\n" )
+        for m in [ set1, set2, set3 ]: self._tSetA.insert( m )
+        lExp = ["desc1", "desc2"]
+        lObs = self._tSetA.getSeqNameList()
+        self.assertEqual( lObs, lExp )
+        
+    def test_getSetListFromSeqName(self):
+        self._iDb.createTable( self._table, "set", "" )
+        set1 = Set()
+        set1.setFromString( "1\tname1\tdesc1\t1\t120\n" )
+        set2 = Set()
+        set2.setFromString( "2\tname2\tdesc2\t1\t20\n" )
+        set3 = Set()
+        set3.setFromString( "3\tname2\tdesc2\t1\t50\n" )
+        for m in [ set1, set2, set3 ]: self._tSetA.insert( m )
+        explSet = [Set( 2,"name2", "desc2", 1, 20), Set( 3,"name2", "desc2", 1, 50)]
+        obslSet = self._tSetA.getSetListFromSeqName("desc2")
+        self.assertEqual( explSet, obslSet )
+
+    def test_getSetListFromId(self):
+        self._iDb.createTable( self._table, "set", "" )
+        set1 = Set()
+        set1.setFromString( "1\tname1\tdesc1\t1\t120\n" )
+        set2 = Set()
+        set2.setFromString( "2\tname2\tdesc2\t1\t20\n" )
+        lset = [ set1, set2 ]
+        self._tSetA.insertList( lset )
+        explSet = [Set( 2,"name2", "desc2", 1, 20)]
+        obslSet = self._tSetA.getSetListFromId(2)
+        self.assertEqual( explSet, obslSet )
+      
+    def test_getSetListFromIdList(self):
+        self._iDb.createTable( self._table, "set", "" )
+        set1 = Set()
+        set1.setFromString( "1\tname1\tdesc1\t1\t120\n" )
+        set2 = Set()
+        set2.setFromString( "2\tname2\tdesc2\t1\t20\n" )
+        lset = [ set1, set2 ]
+        self._tSetA.insertList( lset )
+        explSet = [Set( 1, "name1", "desc1", 1, 120), Set( 2,"name2", "desc2", 1, 20)]
+        lId = [1, 2]
+        obslSet = self._tSetA.getSetListFromIdList(lId)
+        self.assertEqual( explSet, obslSet )
+     
+    def test_getSetListFromIdList_emptyList(self):
+        self._iDb.createTable( self._table, "set", "" )
+        set1 = Set()
+        set1.setFromString( "1\tname1\tdesc1\t1\t120\n" )
+        set2 = Set()
+        set2.setFromString( "2\tname2\tdesc2\t1\t20\n" )
+        lset = [ set1, set2 ]
+        self._tSetA.insertList( lset )
+        explSet = []
+        lId = []
+        obslSet = self._tSetA.getSetListFromIdList(lId)
+        self.assertEqual( explSet, obslSet )
+     
+    def test_getSetListOverlappingCoord(self):
+        self._iDb.createTable( self._table, "set", "" )
+        set1 = Set()
+        set1.setFromString( "1\tname1\tdesc2\t1\t120\n" )
+        set2 = Set()
+        set2.setFromString( "2\tname2\tdesc2\t1\t20\n" )
+        lset = [ set1, set2 ]
+        self._tSetA.insertList( lset )
+        explSet = [Set( 1,"name1", "desc2", 1, 120)]
+        obslSet = self._tSetA.getSetListOverlappingCoord("desc2", 30, 70)
+        self.assertEqual( explSet, obslSet )
+      
+    def test_deleteFromId(self):
+        self._iDb.createTable( self._table, "set", "" )
+        set1 = Set()
+        set1.setFromString( "1\tname1\tdesc1\t1\t120\n" )
+        set2 = Set()
+        set2.setFromString( "2\tname2\tdesc2\t1\t20\n" )
+        set3 = Set()
+        set3.setFromString( "3\tname2\tdesc3\t1\t50\n" )
+        for m in [ set1, set2, set3 ]: self._tSetA.insert( m )
+        self._tSetA.deleteFromId(1)
+        expTSetTuples = (( 2,"name2", "desc2", 1, 20), ( 3,"name2", "desc3", 1, 50))
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._iDb.execute( sqlCmd )
+        obsTsetTuples = self._iDb.cursor.fetchall()
+        
+        self.assertEqual( expTSetTuples, obsTsetTuples )
+  
+    def test_deleteFromIdList(self):
+        self._iDb.createTable( self._table, "set", "" )
+        set1 = Set()
+        set1.setFromString( "1\tname1\tdesc1\t1\t120\n" )
+        set2 = Set()
+        set2.setFromString( "2\tname2\tdesc2\t1\t20\n" )
+        set3 = Set()
+        set3.setFromString( "3\tname2\tdesc3\t1\t50\n" )
+        for m in [ set1, set2, set3 ]: self._tSetA.insert( m )
+        lId2del = [1, 2]
+        self._tSetA.deleteFromIdList(lId2del)
+        expTSetTuples = (( 3,"name2", "desc3", 1, 50),)
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._iDb.execute( sqlCmd )
+        obsTsetTuples = self._iDb.cursor.fetchall()
+        
+        self.assertEqual( expTSetTuples, obsTsetTuples )
+    
+    def test_deleteFromIdListWithEmptyList(self):
+        self._iDb.createTable( self._table, "set", "" )
+        set1 = Set()
+        set1.setFromString( "1\tname1\tdesc1\t1\t120\n" )
+        set2 = Set()
+        set2.setFromString( "2\tname2\tdesc2\t1\t20\n" )
+        set3 = Set()
+        set3.setFromString( "3\tname2\tdesc3\t1\t50\n" )
+        for m in [ set1, set2, set3 ]: self._tSetA.insert( m )
+        lId2del = []
+        self._tSetA.deleteFromIdList(lId2del)
+        expTSetTuples = ((1L, 'name1', 'desc1', 1L, 120L), (2L, 'name2', 'desc2', 1L, 20L), (3L, 'name2', 'desc3', 1L, 50L))
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._iDb.execute( sqlCmd )
+        obsTsetTuples = self._iDb.cursor.fetchall()
+        
+        self.assertEqual( expTSetTuples, obsTsetTuples )
+     
+    def test_joinTwoSets(self):
+        self._iDb.createTable( self._table, "set", "" )
+        idSet1 = 5
+        set1 = Set()
+        set1.setFromString( "5\tname1\tdesc1\t1\t120\n" ) 
+        idSet2 = 2
+        set2 = Set()
+        set2.setFromString( "2\tname2\tdesc2\t1\t20\n" )
+        lset = [ set1, set2 ]
+        self._tSetA.insertList( lset )
+        self._tSetA.joinTwoSets(idSet1, idSet2)
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._iDb.execute( sqlCmd )
+        
+        expTSetTuples = ((2L, "name1", "desc1", 1L, 120L ), (2L, "name2", "desc2", 1L, 20L ))
+        obsTSetTuples = self._iDb.cursor.fetchall()
+        
+        self.assertEqual( expTSetTuples, obsTSetTuples)
+        self._iDb.dropTable(self._table)
+     
+    def test_joinTwoSetsWhereId1InfId2(self):
+        self._iDb.createTable( self._table, "set", "" )
+        idSet1 = 2
+        set1 = Set()
+        set1.setFromString( "5\tname1\tdesc1\t1\t120\n" ) 
+        
+        idSet2 = 5
+        set2 = Set()
+        set2.setFromString( "2\tname2\tdesc2\t1\t20\n" )
+        
+        lset = [ set1, set2 ]
+        self._tSetA.insertList( lset )
+
+        self._tSetA.joinTwoSets(idSet1, idSet2)
+        
+        sqlCmd = "SELECT * FROM %s" % ( self._table )
+        self._iDb.execute( sqlCmd )
+        
+        expTSetTuples = ((2L, "name1", "desc1", 1L, 120L ), (2L, "name2", "desc2", 1L, 20L ))
+        obsTSetTuples = self._iDb.cursor.fetchall()
+        
+        self.assertEqual( expTSetTuples, obsTSetTuples)
+        self._iDb.dropTable(self._table)
+     
+    def test_getNewId(self):
+        self._iDb.createTable( self._table, "set", "" )
+        set1 = Set()
+        set1.setFromString( "1\tname1\tdesc1\t1\t120\n" ) 
+        set2 = Set()
+        set2.setFromString( "2\tname2\tdesc2\t1\t20\n" )
+        set3 = Set()
+        set3.setFromString( "5\tname1\tdesc1\t1\t120\n" ) 
+        set4 = Set()
+        set4.setFromString( "8\tname2\tdesc2\t1\t20\n" )
+        lset = [ set1, set2, set3, set4 ]
+        self._tSetA.insertList( lset )
+        expId = 9
+        obsId = self._tSetA.getNewId()
+        self.assertEqual( expId, obsId)
+        self._iDb.dropTable(self._table)
+     
+    def test_getNewId_set_null(self):
+        self._iDb.createTable( self._table, "set", "" )
+        set1 = Set()
+        lset = [ set1 ]
+        self._tSetA.insertList( lset )
+        expId = 1
+        obsId = self._tSetA.getNewId()
+        self.assertEqual( expId, obsId)
+        self._iDb.dropTable(self._table)  
+        
+    def test_getListOfAllSets( self ):
+        self._iDb.createTable( self._table, "set" )
+        s1 = Set()
+        s1.setFromString( "1\tchr1\tTE3\t1\t10\n" )
+        s2a = Set()
+        s2a.setFromString( "2\tchr1\tTE2\t2\t9\n" )
+        s2b = Set()
+        s2b.setFromString( "2\tchr1\tTE2\t12\t19\n" )
+        lSets = [ s1, s2a, s2b ]
+        self._tSetA.insertList( lSets )
+        expLSets = [ s1, s2a, s2b ]
+        obsLSets = self._tSetA.getListOfAllSets()
+        self.assertEqual( expLSets, obsLSets )
+        
+    def test_getListOfAllSets_empty_table( self ):
+        self._iDb.createTable( self._table, "set" )
+        expList = []
+        obsList = self._tSetA.getListOfAllSets()
+        self.assertEqual( expList, obsList )     
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_TableSetAdaptator ) )       
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Tst_F_RepetJob.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,236 @@
+import os
+import time
+import sys
+import stat
+import unittest
+import glob
+from commons.core.sql.DbMySql import DbMySql
+from commons.core.sql.RepetJob import RepetJob
+from commons.core.sql.Job import Job
+
+class Test_F_RepetJob(unittest.TestCase):
+
+    def setUp(self):
+        self._jobTableName = "dummyJobTable"
+        self._db = DbMySql()
+        self._iRepetJob = RepetJob()
+        self._configFileName = "dummyConfigFile"
+        configF = open(self._configFileName, "w" )
+        configF.write( "[repet_env]\n" )
+        configF.write( "repet_host: %s\n" % ( os.environ["REPET_HOST"] ) )
+        configF.write( "repet_user: %s\n" % ( os.environ["REPET_USER"] ) )
+        configF.write( "repet_pw: %s\n" % ( os.environ["REPET_PW"] ) )
+        configF.write( "repet_db: %s\n" % ( os.environ["REPET_DB"] ) )
+        configF.write( "repet_port: %s\n" % ( os.environ["REPET_PORT"] ) )
+        configF.close()
+
+    def tearDown(self):
+        self._iRepetJob = None
+        self._db.dropTable( self._jobTableName )
+        self._db.close()
+        os.remove(self._configFileName)
+    
+    def test_submitJob_with_multiple_jobs(self):
+        job1 = self._createJobInstance("job1")
+        self._createLauncherFile(job1)
+
+        job2 = self._createJobInstance("job2")
+        self._createLauncherFile(job2)
+
+        job3 = self._createJobInstance("job3")
+        self._createLauncherFile(job3)
+        
+        self._iRepetJob.submitJob( job1, maxNbWaitingJobs=3, checkInterval=5, verbose=0 )
+        self._iRepetJob.submitJob( job2, maxNbWaitingJobs=3, checkInterval=5, verbose=0 )
+        self._iRepetJob.submitJob( job3, maxNbWaitingJobs=3, checkInterval=5, verbose=0 )
+
+        time.sleep(70)
+        
+        expJobStatus = "finished"
+        obsJobStatus1 = self._iRepetJob.getJobStatus(job1)
+        obsJobStatus2 = self._iRepetJob.getJobStatus(job2)
+        obsJobStatus3 = self._iRepetJob.getJobStatus(job3)
+        
+        self.assertEquals(expJobStatus, obsJobStatus1)
+        self.assertEquals(expJobStatus, obsJobStatus2)
+        self.assertEquals(expJobStatus, obsJobStatus3)
+        
+        jobName1 = job1.jobname
+        jobName2 = job2.jobname
+        jobName3 = job3.jobname
+        
+        expErrorFilePrefix1 = jobName1+ ".e" 
+        expOutputFilePrefix1 = jobName1 + ".o"
+        expErrorFilePrefix2 = jobName2 + ".e" 
+        expOutputFilePrefix2 = jobName2 + ".o"
+        expErrorFilePrefix3 = jobName3 + ".e" 
+        expOutputFilePrefix3 = jobName3 + ".o"
+        
+        lErrorFiles1 = glob.glob(expErrorFilePrefix1 + "*")
+        lOutputFiles1 = glob.glob(expOutputFilePrefix1 + "*")
+        lErrorFiles2 = glob.glob(expErrorFilePrefix2 + "*")
+        lOutputFiles2 = glob.glob(expOutputFilePrefix2 + "*")
+        lErrorFiles3 = glob.glob(expErrorFilePrefix3 + "*")
+        lOutputFiles3 = glob.glob(expOutputFilePrefix3 + "*")
+        
+        isLErrorFileNotEmpty1 = (len(lErrorFiles1) != 0) 
+        isLOutputFileNotEmpty1 = (len(lOutputFiles1) != 0)
+        isLErrorFileNotEmpty2 = (len(lErrorFiles2) != 0) 
+        isLOutputFileNotEmpty2 = (len(lOutputFiles2) != 0)
+        isLErrorFileNotEmpty3 = (len(lErrorFiles3) != 0) 
+        isLOutputFileNotEmpty3 = (len(lOutputFiles3) != 0)
+        
+        os.system("rm launcherFileTest*.py *.e* *.o*")
+        self.assertTrue(isLErrorFileNotEmpty1 and isLOutputFileNotEmpty1)
+        self.assertTrue(isLErrorFileNotEmpty2 and isLOutputFileNotEmpty2)
+        self.assertTrue(isLErrorFileNotEmpty3 and isLOutputFileNotEmpty3)
+
+    def test_submitJob_job_already_submitted(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = self._createJobInstance("job")
+        self._iRepetJob.recordJob(iJob)
+        
+        isSysExitRaised = False
+        try:
+            self._iRepetJob.submitJob(iJob)
+        except SystemExit:
+            isSysExitRaised = True
+        self.assertTrue(isSysExitRaised)
+    
+    def test_waitJobGroup_with_several_nbTimeOut_waiting(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = self._createJobInstance("job")
+        self._createLauncherFile(iJob)
+        self._iRepetJob.recordJob(iJob)
+        self._iRepetJob.changeJobStatus(iJob, "running", "method")
+        
+        expMsg = "ERROR: job '%s', supposedly still running, is not handled by SGE anymore\n" % ( iJob.jobid )
+        
+        obsError = "obsError.txt"
+        obsErrorHandler = open(obsError, "w")
+        stderrRef = sys.stderr
+        sys.stderr = obsErrorHandler
+        
+        isSysExitRaised = False
+        try:
+            self._iRepetJob.waitJobGroup(self._jobTableName ,iJob.groupid, timeOutPerJob=3)
+        except SystemExit:
+            isSysExitRaised = True
+           
+        obsErrorHandler.close()
+        
+        obsErrorHandler = open(obsError, "r")
+        obsMsg = obsErrorHandler.readline()
+        obsErrorHandler.close()
+       
+        sys.stderr = stderrRef
+        os.remove(obsError)
+        os.system("rm launcherFileTest*.py")
+        self.assertTrue(isSysExitRaised)
+        self.assertEquals(expMsg, obsMsg)
+         
+    def test_waitJobGroup_with_error_job_maxRelaunch_two(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = self._createJobInstance("job")
+        self._createLauncherFile(iJob)
+        
+        self._iRepetJob.recordJob(iJob)
+        self._iRepetJob.changeJobStatus(iJob, "error", "method")
+        
+        self._iRepetJob.waitJobGroup(self._jobTableName ,iJob.groupid, 0, 2)
+        
+        time.sleep(10)
+        
+        expJobStatus = "finished"
+        obsJobStatus1 = self._iRepetJob.getJobStatus(iJob)
+        
+        self.assertEquals(expJobStatus, obsJobStatus1)
+        
+        jobName = iJob.jobname
+        
+        expErrorFilePrefix1 = jobName + ".e" 
+        expOutputFilePrefix1 = jobName + ".o"
+        
+        lErrorFiles1 = glob.glob(expErrorFilePrefix1 + "*")
+        lOutputFiles1 = glob.glob(expOutputFilePrefix1 + "*")
+        
+        isLErrorFileNotEmpty1 = (len(lErrorFiles1) != 0) 
+        isLOutputFileNotEmpty1 = (len(lOutputFiles1) != 0)
+        
+        self._iRepetJob.removeJob(iJob) 
+        os.system("rm launcherFileTest*.py *.e* *.o*")
+        self.assertTrue(isLErrorFileNotEmpty1 and isLOutputFileNotEmpty1)
+        
+
+    def test_isJobStillHandledBySge_True(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = self._createJobInstance("job")
+        self._createLauncherFile(iJob)
+        self._iRepetJob.submitJob(iJob)
+        
+        isJobHandledBySge = self._iRepetJob.isJobStillHandledBySge(iJob.jobid, iJob.jobname)
+        os.system("rm launcherFileTest*.py")
+        
+        self.assertTrue(isJobHandledBySge)
+
+    def test_isJobStillHandledBySge_False(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = self._createJobInstance("job")
+        self._createLauncherFile(iJob)
+        self._iRepetJob.recordJob(iJob)
+        
+        isJobHandledBySge = self._iRepetJob.isJobStillHandledBySge(iJob.jobid, iJob.jobname)
+        os.system("rm launcherFileTest*.py")
+        
+        self.assertFalse(isJobHandledBySge)
+        
+    def _createJobInstance(self, name):
+        return Job(self._jobTableName, 0, name, "test", "", "date;sleep 5;date", "./launcherFileTest_"+ name +".py")
+    
+    def _createLauncherFile(self, iJob):
+        jobFileHandler = open( iJob.launcher , "w" )
+
+        launcher = "#!/usr/bin/python\n"
+        launcher += "import os\n"
+        launcher += "import sys\n"
+        
+        launcher += "print \"system:\", os.uname()\n"
+        launcher += "sys.stdout.flush()\n"
+        newStatus = "running"
+        prg = "%s/bin/srptChangeJobStatus.py" % (os.environ["REPET_PATH"])
+        cmd = prg
+        cmd += " -t %s" % ( iJob.tablename )
+        cmd += " -n %s" % ( iJob.jobname )
+        cmd += " -g %s" % ( iJob.groupid )
+        if iJob.queue != "":
+            cmd += " -q %s" % ( iJob.queue )
+        cmd += " -s %s" % ( newStatus )
+        cmd += " -c %s"  %( self._configFileName )
+        cmd += " -v 1"
+        launcher +="os.system( \"" + cmd + "\" )\n"
+        
+        launcher += "print \"LAUNCH: "+ iJob.command + "\"\n"
+        launcher += "sys.stdout.flush()\n"
+        launcher += "exitStatus = os.system (\"" + iJob.command + "\")\n"
+        launcher += "if exitStatus != 0:\n"
+        launcher += "\tprint \"ERROR: "+  iJob.command + " returned exit status '%i'\" % ( exitStatus )\n"
+        
+        newStatus = "finished"
+        prg = os.environ["REPET_PATH"] + "/bin/srptChangeJobStatus.py"
+        cmd = prg
+        cmd += " -t %s" % ( iJob.tablename )
+        cmd += " -n %s" % ( iJob.jobname )
+        cmd += " -g %s" % ( iJob.groupid )
+        if iJob.queue != "":
+            cmd += " -q %s" % ( iJob.queue )
+        cmd += " -s %s" % ( newStatus )
+        cmd += " -c %s"  %( self._configFileName )
+        cmd += " -v 1"
+        launcher +="os.system( \"" + cmd + "\" )\n"
+        launcher += "sys.exit(0)\n"
+        jobFileHandler.write(launcher)
+        jobFileHandler.close()
+        os.chmod( iJob.launcher, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC )
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/sql/test/Tst_RepetJob.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,395 @@
+import unittest
+import sys
+import os
+import time
+from commons.core.sql.DbMySql import DbMySql
+from commons.core.sql.Job import Job
+from commons.core.sql.RepetJob import RepetJob
+from commons.core.utils.FileUtils import FileUtils
+
+#TODO: to remove... => replace all RepetJob() by TableJobAdaptator()...
+class Test_RepetJob( unittest.TestCase ):
+    
+    def setUp(self):
+        self._jobTableName = "dummyJobTable"
+        self._db = DbMySql()
+        self._iRepetJob = RepetJob()
+    
+    def tearDown(self):
+        self._iRepetJob = None
+        self._db.close()
+        
+    def _createJobInstance(self):
+        return Job( self._jobTableName, 0, "job1", "groupid", "queue", "command", "launcherFile", "node", "lResources" )
+    
+    def test_createJobTable_is_table_created(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+    
+        isTableCreated = self._db.doesTableExist(self._jobTableName)
+        self.assertTrue(isTableCreated)
+    
+        self._db.dropTable(self._jobTableName)
+    
+    def test_createJobTable_field_list(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+
+        obsLFiled = self._db.getFieldList(self._jobTableName)
+        expLField = ["jobid", "jobname", "groupid", "command", "launcher", "queue", "status", "time", "node"]
+    
+        self.assertEquals(expLField, obsLFiled)
+    
+        self._db.dropTable(self._jobTableName)
+    
+    def test_recordJob(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = self._createJobInstance()
+        self._iRepetJob.recordJob(iJob)
+    
+        qryParams = "SELECT jobid, groupid, command, launcher, queue, status, node FROM " + self._jobTableName + " WHERE jobid = %s" 
+        params = (iJob.jobid)
+        
+        self._db.execute(qryParams, params)
+        
+        tObs = self._db.fetchall()[0]
+        tExp =(iJob.jobid, iJob.groupid, iJob.command, iJob.launcher, iJob.queue, "waiting", "?")
+        
+        self.assertEquals(tExp,tObs)
+
+        self._db.dropTable(self._jobTableName)
+    
+    def test_removeJob(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = self._createJobInstance()
+        self._iRepetJob.recordJob(iJob)
+
+        self._iRepetJob.removeJob(iJob)
+        
+        isTableEmpty = self._db.isEmpty(self._jobTableName)
+        
+        self.assertTrue(isTableEmpty)
+        
+        self._db.dropTable(self._jobTableName)
+        
+    def test_getJobStatus(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = self._createJobInstance()
+        self._iRepetJob.recordJob(iJob)
+
+        expStatus = "waiting"
+        obsStatus = self._iRepetJob.getJobStatus(iJob)
+        
+        self.assertEquals(expStatus, obsStatus)
+        self._db.dropTable(self._jobTableName)
+    
+    def test_getJobStatus_unknown(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = self._createJobInstance()        
+
+        expStatus = "unknown"
+        obsStatus = self._iRepetJob.getJobStatus(iJob)
+        
+        self.assertEquals(expStatus, obsStatus)
+        self._db.dropTable(self._jobTableName)
+    
+    def test_getJobStatus_no_name(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = Job( self._jobTableName, 20, "", "groupid", "queue", "command", "launcherFile", "node", "lResources" ) 
+        
+        expStatus = "unknown"
+        obsStatus = self._iRepetJob.getJobStatus(iJob)
+        
+        self.assertEquals(expStatus, obsStatus)
+        self._db.dropTable(self._jobTableName)
+        
+    def test_getJobStatus_non_unique_job(self):
+        # Warning : this case will not append, because recordJob() begin by removeJob()
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = self._createJobInstance()
+        sqlCmd = "INSERT INTO %s" % ( iJob.tablename )
+        sqlCmd += " VALUES ("
+        sqlCmd += " \"%s\"," % ( iJob.jobid )
+        sqlCmd += " \"%s\"," % ( iJob.jobname )
+        sqlCmd += " \"%s\"," % ( iJob.groupid )
+        sqlCmd += " \"%s\"," % ( iJob.command.replace("\"","\'") )
+        sqlCmd += " \"%s\"," % ( iJob.launcher )
+        sqlCmd += " \"%s\"," % ( iJob.queue )
+        sqlCmd += " \"waiting\","
+        sqlCmd += " \"%s\"," % ( time.strftime( "%Y-%m-%d %H:%M:%S" ) )
+        sqlCmd += " \"?\" );"
+        self._db.execute( sqlCmd )
+        self._db.execute( sqlCmd )
+        
+        expError = "expError.txt"
+        expErrorHandler = open(expError, "w")
+        expErrorHandler.write("ERROR while getting job status: non-unique jobs\n")
+        expErrorHandler.close()
+        
+        obsError = "obsError.txt"
+        obsErrorHandler = open(obsError, "w")
+        stderrRef = sys.stderr
+        sys.stderr = obsErrorHandler
+        
+        isSysExitRaised = False
+        try:
+            self._iRepetJob.getJobStatus(iJob)
+        except SystemExit:
+            isSysExitRaised = True
+           
+        obsErrorHandler.close()
+        
+        self.assertTrue(isSysExitRaised)
+        self.assertTrue(FileUtils.are2FilesIdentical(expError, obsError))
+        
+        sys.stderr = stderrRef
+        os.remove(obsError)
+        os.remove(expError)
+         
+        self._db.dropTable(self._jobTableName)
+        
+    def test_updateInfoTable(self):
+        self._iRepetJob.updateInfoTable(self._jobTableName, "dummyInfo")
+        
+        qryParams = "SELECT name, file FROM  info_tables WHERE name=%s AND file=%s"
+        params = (self._jobTableName, "dummyInfo")
+        
+        self._db.execute(qryParams, params)
+        tObs = self._db.fetchall()[0]
+        tExp = (self._jobTableName, "dummyInfo")
+        
+        self.assertEquals(tExp, tObs)
+        
+        self._db.dropTable(self._jobTableName)
+        
+    def test_changeJobStatus(self):
+        expStatus = "finished"
+        
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = self._createJobInstance()
+        self._iRepetJob.recordJob(iJob)
+        self._iRepetJob.changeJobStatus(iJob, expStatus, "method")
+        
+        qryParams = "SELECT status FROM " + self._jobTableName + " WHERE jobid =%s AND groupid=%s AND queue=%s" 
+        params = (iJob.jobid, iJob.groupid, iJob.queue)
+        self._db.execute(qryParams, params)
+
+        obsStatus = self._db.fetchall()[0][0]
+        self.assertEquals(expStatus, obsStatus)
+        self._iRepetJob.removeJob(iJob)
+        self._db.dropTable(self._jobTableName)
+
+    def test_getCountStatus(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        
+        iJob1 = self._createJobInstance()
+        iJob2 = Job(self._jobTableName, 1, "job2", "groupid", "queue2", "command2", "launcherFile2", "node2", "lResources2")
+        
+        self._iRepetJob.recordJob(iJob1)
+        self._iRepetJob.recordJob(iJob2)
+
+        expCount = 2
+        obsCount = self._iRepetJob.getCountStatus(self._jobTableName, iJob1.groupid, "waiting")
+        
+        self.assertEquals(expCount, obsCount)
+        
+    def test_getCountStatus_without_res(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        expCount = 0
+        
+        obsCount = self._iRepetJob.getCountStatus(self._jobTableName, "groupid", "waiting")
+        
+        self.assertEquals(expCount, obsCount)
+   
+    def test_cleanJobGroup(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob1 = self._createJobInstance()
+        iJob2 = Job(self._jobTableName, "jobid2", iJob1.groupid, "queue2", "command2", "launcherFile2", "node2", "lResources2")
+        iJob3 = Job(self._jobTableName, "jobid2", "groupid3", "queue2", "command2", "launcherFile2", "node2", "lResources2")
+        
+        self._iRepetJob.recordJob(iJob1)
+        self._iRepetJob.recordJob(iJob2)
+        self._iRepetJob.recordJob(iJob3)
+        
+        self._iRepetJob.cleanJobGroup(self._jobTableName, iJob1.groupid)
+        
+        qryParams = "SELECT count(*) FROM " + self._jobTableName  
+        
+        self._db.execute(qryParams)
+        
+        expCount = 1
+        obsCount = self._db.fetchall()[0][0]
+        
+        self.assertEquals(expCount, obsCount)
+        
+        self._iRepetJob.removeJob(iJob3)
+        self._db.dropTable(self._jobTableName)
+
+    def test_hasUnfinishedJob(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob1 = self._createJobInstance()
+        iJob2 = Job(self._jobTableName, 0, "jobname2", iJob1.groupid, "queue2", "command2", "launcherFile2", "node2", "lResources2")
+        iJob3 = Job(self._jobTableName, 0, "jobname3", "groupid3", "queue2", "command2", "launcherFile2", "node2", "lResources2")
+        
+        self._iRepetJob.recordJob(iJob1)
+        self._iRepetJob.recordJob(iJob2)
+        self._iRepetJob.recordJob(iJob3)
+        
+        self._iRepetJob.changeJobStatus(iJob2, "finished", "method")
+        
+        expHasGrpIdFinished = True
+        obsHasGrpIdFinished = self._iRepetJob.hasUnfinishedJob(self._jobTableName, iJob1.groupid)
+        
+        self.assertEquals(expHasGrpIdFinished, obsHasGrpIdFinished)
+        
+        self._iRepetJob.removeJob(iJob1)
+        self._iRepetJob.removeJob(iJob2)
+        self._iRepetJob.removeJob(iJob3)
+        self._db.dropTable(self._jobTableName)
+        
+    def test_hasUnfinishedJob_JobTableNotExists(self):
+        iJob1 = self._createJobInstance()
+        
+        expHasGrpIdFinished = False
+        obsHasGrpIdFinished = self._iRepetJob.hasUnfinishedJob(self._jobTableName, iJob1.groupid)
+        
+        self.assertEquals(expHasGrpIdFinished, obsHasGrpIdFinished)
+        
+    def test_hasUnfinishedJob_AllJobsFinished(self): 
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob1 = self._createJobInstance()
+        iJob2 = Job(self._jobTableName, "jobid2", iJob1.groupid, "queue2", "command2", "launcherFile2", "node2", "lResources2")
+        iJob3 = Job(self._jobTableName, "jobid2", "groupid3", "queue2", "command2", "launcherFile2", "node2", "lResources2")
+        
+        self._iRepetJob.recordJob(iJob1)
+        self._iRepetJob.recordJob(iJob2)
+        self._iRepetJob.recordJob(iJob3)
+        
+        self._iRepetJob.changeJobStatus(iJob1, "finished", "method")
+        self._iRepetJob.changeJobStatus(iJob2, "finished", "method")
+        
+        expHasGrpIdFinished = False
+        obsHasGrpIdFinished = self._iRepetJob.hasUnfinishedJob(self._jobTableName, iJob1.groupid)
+        
+        self.assertEquals(expHasGrpIdFinished, obsHasGrpIdFinished)
+        
+        self._iRepetJob.removeJob(iJob1)
+        self._iRepetJob.removeJob(iJob2)
+        self._iRepetJob.removeJob(iJob3)
+        self._db.dropTable(self._jobTableName)
+        
+    def test_waitJobGroup_with_finished_job(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = self._createJobInstance()
+        self._iRepetJob.recordJob(iJob)
+        self._iRepetJob.changeJobStatus(iJob, "finished", "method")
+        
+        Obs = self._iRepetJob.waitJobGroup(self._jobTableName ,iJob.groupid, 0)
+        Exp = None
+        
+        self.assertEquals(Exp, Obs)
+        self._iRepetJob.removeJob(iJob) 
+        
+    def test_waitJobGroup_with_error_job_maxRelaunch_zero(self):
+        Obs = False
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = self._createJobInstance()
+        self._iRepetJob.recordJob(iJob)
+        self._iRepetJob.changeJobStatus(iJob, "error", "method")
+        
+        try:
+            self._iRepetJob.waitJobGroup(self._jobTableName ,iJob.groupid, 0, 0)
+        except SystemExit:
+            Obs = True
+        
+        self.assertTrue(Obs)
+        self._iRepetJob.removeJob(iJob)
+        
+    def test_setJobIdFromSge(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob = self._createJobInstance()
+        self._iRepetJob.recordJob(iJob)
+        self._iRepetJob.setJobIdFromSge(iJob, 1000)
+        
+        qryParams = "SELECT jobid FROM " + self._jobTableName + " WHERE jobname = %s AND queue = %s AND groupid = %s" 
+        params = (iJob.jobname, iJob.queue, iJob.groupid)
+        
+        self._db.execute(qryParams, params)
+        
+        tObs = self._db.fetchall()[0]
+        tExp =(1000,)
+        
+        self.assertEquals(tExp,tObs)
+        
+        self._db.dropTable(self._jobTableName)
+        
+    def test_submitJob_8_fields_for_job_table(self):
+        iJob = self._createJobInstance()
+        self._db.dropTable(self._jobTableName)
+        sqlCmd = "CREATE TABLE " + self._jobTableName 
+        sqlCmd += " ( jobid INT UNSIGNED"
+        sqlCmd += ", groupid VARCHAR(255)"
+        sqlCmd += ", command TEXT"
+        sqlCmd += ", launcher VARCHAR(1024)"
+        sqlCmd += ", queue VARCHAR(255)"
+        sqlCmd += ", status VARCHAR(255)"
+        sqlCmd += ", time DATETIME"
+        sqlCmd += ", node VARCHAR(255) )"
+        self._db.execute(sqlCmd)
+        
+        self._iRepetJob.submitJob(iJob)
+        
+        expFieldsNb = 9
+        obsFieldsNb = len(self._iRepetJob.getFieldList(self._jobTableName))
+        
+        self.assertEquals(expFieldsNb, obsFieldsNb)
+        
+        self._db.dropTable(self._jobTableName)
+        
+    def test_getNodesListByGroupId(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob1 = Job( self._jobTableName, 0, "job1", "groupid", "queue", "command", "launcherFile", "node1", "lResources" )
+        iJob2 = Job( self._jobTableName, 1, "job2", "groupid", "queue", "command", "launcherFile", "node2", "lResources" )
+        iJob3 = Job( self._jobTableName, 2, "job3", "groupid2", "queue", "command", "launcherFile", "node3", "lResources" )
+        
+        self._insertJob(iJob1)
+        self._insertJob(iJob2)
+        self._insertJob(iJob3)
+        
+        expNodeList = ["node1", "node2"]
+        obsNodeList = self._iRepetJob.getNodesListByGroupId(self._jobTableName, "groupid")
+        self.assertEquals(expNodeList, obsNodeList)
+        
+        self._db.dropTable(self._jobTableName)
+        
+    def test_getNodesListByGroupId_empty_list(self):
+        self._iRepetJob.createTable(self._jobTableName, "jobs")
+        iJob1 = Job( self._jobTableName, 0, "job1", "groupid", "queue", "command", "launcherFile", "node1", "lResources" )
+        iJob2 = Job( self._jobTableName, 1, "job2", "groupid", "queue", "command", "launcherFile", "node2", "lResources" )
+        iJob3 = Job( self._jobTableName, 2, "job3", "groupid32", "queue", "command", "launcherFile", "node3", "lResources" )
+        
+        self._insertJob(iJob1)
+        self._insertJob(iJob2)
+        self._insertJob(iJob3)
+        
+        expNodeList = []
+        obsNodeList = self._iRepetJob.getNodesListByGroupId(self._jobTableName, "groupid3")
+        self.assertEquals(expNodeList, obsNodeList)
+        
+        self._db.dropTable(self._jobTableName)
+        
+    def _insertJob(self, iJob):
+        self._iRepetJob.removeJob( iJob )
+        sqlCmd = "INSERT INTO %s" % ( iJob.tablename )
+        sqlCmd += " VALUES ("
+        sqlCmd += " \"%s\"," % ( iJob.jobid )
+        sqlCmd += " \"%s\"," % ( iJob.jobname )
+        sqlCmd += " \"%s\"," % ( iJob.groupid )
+        sqlCmd += " \"%s\"," % ( iJob.command.replace("\"","\'") )
+        sqlCmd += " \"%s\"," % ( iJob.launcher )
+        sqlCmd += " \"%s\"," % ( iJob.queue )
+        sqlCmd += " \"waiting\","
+        sqlCmd += " \"%s\"," % ( time.strftime( "%Y-%m-%d %H:%M:%S" ) )
+        sqlCmd += " \"%s\" );" % ( iJob.node )
+        self._iRepetJob.execute( sqlCmd )
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/stat/Stat.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,209 @@
+import math
+
+class Stat(object):
+
+    def __init__(self, lValues = []):
+        self.reset()
+        if lValues != []:
+            self.fill(lValues)
+    
+    def __eq__(self, o):
+        self._lValues.sort()
+        o._lValues.sort()
+        return self._lValues == o._lValues and round(self._sum, 6) == round(o._sum, 6) \
+            and round(self._sumOfSquares, 6) == round(o._sumOfSquares, 6) and self._n == self._n \
+            and round(self._min, 6) == round(o._min, 6) and round(self._max, 6) == round(o._max, 6)
+            
+    def getValuesList(self):
+        return self._lValues
+    
+    def getSum(self):
+        return self._sum
+    
+    def getSumOfSquares(self):
+        return self._sumOfSquares
+    
+    def getValuesNumber(self):
+        return self._n
+    
+    def getMin(self):
+        return self._min
+    
+    def getMax(self):
+        return self._max
+
+    ## Reset all attributes
+    #
+    def reset(self):
+        self._lValues = []
+        self._sum = 0.0
+        self._sumOfSquares = 0.0
+        self._n = 0
+        self._max = 0.0
+        self._min = 0.0
+
+    ## Add a value to Stat instance list and update attributes
+    #
+    # @param v float value to add
+    #    
+    def add(self, v):
+        self._lValues.append( float(v) )
+        self._sum += float(v)
+        self._sumOfSquares += float(v) * float(v)
+        self._n = self._n + 1
+        if v > self._max:
+            self._max = float(v)
+        if self._n == 1:
+            self._min = float(v)
+        elif v < self._min:
+            self._min = float(v)
+         
+    ## Add a list of values to Stat instance list and update attributes
+    #
+    # @param lValues list of float list to add
+    #    
+    def fill(self, lValues):
+        for v in lValues:
+            self.add(v)
+    
+    ## Get the arithmetic mean of the Stat instance list
+    #
+    # @return float
+    #
+    def mean(self):
+        if self._n == 0:
+            return 0
+        else:
+            return self._sum / float(self._n)
+    
+    ## Get the variance of the sample
+    # @note we consider a sample, not a population. So for calculation, we use n-1
+    #
+    # @return float
+    #
+    def var(self):
+        if self._n < 2 or self.mean() == 0.0:
+            return 0
+        else:
+            variance = self._sumOfSquares/float(self._n - 1) - self._n/float(self._n - 1) * self.mean()*self.mean()
+            if round(variance, 10) == 0:
+                variance = 0
+            return variance
+
+    ## Get the standard deviation of the sample
+    #
+    # @return float
+    #
+    def sd(self):
+        return math.sqrt( self.var() )
+
+    ## Get the coefficient of variation of the sample
+    #
+    # @return float
+    #
+    def cv(self):
+        if self._n < 2 or self.mean() == 0.0:
+            return 0
+        else:
+            return self.sd() / self.mean()
+
+    ## Get the median of the sample
+    #
+    # @return number or "NA" (Not available)
+    #
+    def median( self ):
+        if len(self._lValues) == 0:
+            return "NA"
+        if len(self._lValues) == 1:
+            return self._lValues[0]
+        self._lValues.sort()
+        m = int( math.ceil( len(self._lValues) / 2.0 ) )
+        if len(self._lValues) % 2:
+            return self._lValues[m-1]
+        else:
+            return ( self._lValues[m-1] + self._lValues[m] ) / 2.0
+        
+    ## Get the kurtosis (measure of whether the data are peaked or flat relative to a normal distribution, 'coef d'aplatissement ' in french)).
+    #  k = 0 -> completely flat
+    #  k = 3 -> same as normal distribution
+    #  k >> 3 -> peak
+    #
+    # @return float 
+    #
+    def kurtosis(self):
+        numerator = 0
+        for i in self._lValues:
+            numerator += math.pow( i - self.mean(), 4 )
+        return numerator / float(self._n - 1) * self.sd() 
+
+    ## Prepare a string with calculations on your values
+    #
+    # @return string 
+    #
+    def string(self):
+        msg = ""
+        msg += "n=%d" % ( self._n )
+        msg += " mean=%5.3f" % ( self.mean() )
+        msg += " var=%5.3f" % ( self.var() )
+        msg += " sd=%5.3f" % ( self.sd() )
+        msg += " min=%5.3f" % ( self.getMin() )
+        median = self.median()
+        if median == "NA":
+            msg += " med=%s" % (median)
+        else:
+            msg += " med=%5.3f" % (median)
+        msg += " max=%5.3f" % ( self.getMax() )
+        return msg
+    
+    ## Print descriptive statistics
+    #
+    def view(self):
+        print self.string()
+
+    ## Return sorted list of values, ascending (default) or descending
+    #
+    # @return list
+    #
+    def sort( self, isReverse = False ):
+        self._lValues.sort(reverse = isReverse)
+        return self._lValues
+    
+    ## Give the quantile corresponding to the chosen percentage
+    #
+    # @return number 
+    #
+    def quantile( self, percentage ):
+        if self._n == 0:
+            return 0
+        elif percentage == 1:
+            return self.getMax()
+        else:
+            return self.sort()[int(self._n * percentage)]
+        
+    ## Prepare a string with quantile values
+    #
+    # @return string
+    #    
+    def stringQuantiles( self ):
+        return "n=%d min=%5.3f Q1=%5.3f median=%5.3f Q3=%5.3f max=%5.3f" % \
+               (self._n, self.quantile(0), self.quantile(0.25), self.quantile(0.5), self.quantile(0.75), self.quantile(1))
+
+    ## Print quantiles string
+    #
+    def viewQuantiles( self ):
+        print self.stringQuantiles()
+        
+    ## Compute N50 
+    # @return number
+    def N50(self ):
+        lSorted = self.sort(True)
+        midlValues = self.getSum() / 2
+        cumul = 0
+        index = 0
+        while cumul < midlValues:
+            cumul =  cumul + lSorted[index]
+            index += 1
+        if (index == 0):
+            return lSorted[index]
+        else :
+            return lSorted[index - 1]
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/stat/test/Test_F_Stat.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,22 @@
+import unittest
+from commons.core.stat.Stat import Stat
+
+
+class Test_F_Stat(unittest.TestCase):
+
+
+    def test_output(self):
+        lValues = [0, -1, -5, 112, 10.2, 0.5, 4, -0.5]
+        iStat = Stat(lValues)
+        expString = "n=8 mean=15.025 var=1554.934 sd=39.433 min=-5.000 med=0.250 max=112.000"
+        self.assertEquals(expString, iStat.string())
+        
+    def test_outputQuantile(self):
+        lValues = [0, -1, -5, 112, 10.2, 0.5, 4, -0.5]
+        iStat = Stat(lValues)
+        expString = "n=8 min=-5.000 Q1=-0.500 median=0.500 Q3=10.200 max=112.000"
+        self.assertEquals(expString, iStat.stringQuantiles())
+        
+        
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/stat/test/Test_Stat.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,356 @@
+from commons.core.stat.Stat import Stat
+import unittest
+
+class Test_Stat(unittest.TestCase):
+    
+    def test__eq__true(self):
+        iStat1 = Stat([1, 2, 3, 46])
+        iStat2 = Stat([1, 2, 3, 46])
+        self.assertTrue(iStat1 == iStat2)
+
+    def test__eq__false(self):
+        iStat1 = Stat([1, 2, 3, 4])
+        iStat2 = Stat([1, 2, 3, 46])
+        self.assertFalse(iStat1 == iStat2)
+
+    def test__eq__disordered_list(self):
+        iStat1 = Stat([3, 2, 1, 46])
+        iStat2 = Stat([1, 2, 3, 46])
+        self.assertTrue(iStat1 == iStat2)
+
+    def test_reset(self):
+        lValues = [1, 2, 5, 9, 12, 46]
+        iStat = Stat(lValues)
+        iStat.reset()
+        expValuesList = []
+        expSum = 0
+        expSum2 = 0
+        expN = 0
+        expMin = 0
+        expMax = 0
+        obsValuesList = iStat.getValuesList()
+        obsSum = iStat.getSum()
+        obsSum2 = iStat.getSumOfSquares()
+        obsN = iStat.getValuesNumber()
+        obsMin = iStat.getMin()
+        obsMax = iStat.getMax()
+        self.assertEquals(expValuesList, obsValuesList)
+        self.assertEquals(expSum, obsSum)
+        self.assertEquals(expSum2, obsSum2)
+        self.assertEquals(expN, obsN)
+        self.assertEquals(expMin, obsMin)
+        self.assertEquals(expMax, obsMax)
+
+    def test_add_EmptyList(self):
+        lValues = []
+        iStat = Stat(lValues)
+        iStat.add(5)
+        expValuesList = [5]
+        expSum = 5
+        expSum2 = 25
+        expN = 1
+        expMin = 5
+        expMax = 5
+        obsValuesList = iStat.getValuesList()
+        obsSum = iStat.getSum()
+        obsSum2 = iStat.getSumOfSquares()
+        obsN = iStat.getValuesNumber()
+        obsMin = iStat.getMin()
+        obsMax = iStat.getMax()
+        self.assertEquals(expValuesList, obsValuesList)
+        self.assertEquals(expSum, obsSum)
+        self.assertEquals(expSum2, obsSum2)
+        self.assertEquals(expN, obsN)
+        self.assertEquals(expMin, obsMin)
+        self.assertEquals(expMax, obsMax)
+       
+    def test_add_Max(self):
+        lValues = [0,1,1]
+        iStat = Stat(lValues)
+        iStat.add(2)
+        expValuesList = [0,1,1,2]
+        expSum = 4
+        expSum2 = 6
+        expN = 4
+        expMin = 0
+        expMax = 2
+        obsValuesList = iStat.getValuesList()
+        obsSum = iStat.getSum()
+        obsSum2 = iStat.getSumOfSquares()
+        obsN = iStat.getValuesNumber()
+        obsMin = iStat.getMin()
+        obsMax = iStat.getMax()
+        self.assertEquals(expValuesList, obsValuesList)
+        self.assertEquals(expSum, obsSum)
+        self.assertEquals(expSum2, obsSum2)
+        self.assertEquals(expN, obsN)
+        self.assertEquals(expMin, obsMin)
+        self.assertEquals(expMax, obsMax)
+       
+    def test_add_Min(self):
+        lValues = [2,1,1]
+        iStat = Stat(lValues)
+        iStat.add(0)
+        expValuesList = [2,1,1,0]
+        expSum = 4
+        expSum2 = 6
+        expN = 4
+        expMin = 0
+        expMax = 2
+        obsValuesList = iStat.getValuesList()
+        obsSum = iStat.getSum()
+        obsSum2 = iStat.getSumOfSquares()
+        obsN = iStat.getValuesNumber()
+        obsMin = iStat.getMin()
+        obsMax = iStat.getMax()
+        self.assertEquals(expValuesList, obsValuesList)
+        self.assertEquals(expSum, obsSum)
+        self.assertEquals(expSum2, obsSum2)
+        self.assertEquals(expN, obsN)
+        self.assertEquals(expMin, obsMin)
+        self.assertEquals(expMax, obsMax)
+       
+    def test_fill_emptyList(self):
+        lValues = [2,1,1]
+        iStat = Stat(lValues)
+        iStat.fill([])
+        expValuesList = [2,1,1]
+        expSum = 4
+        expSum2 = 6
+        expN = 3
+        expMin = 1
+        expMax = 2
+        obsValuesList = iStat.getValuesList()
+        obsSum = iStat.getSum()
+        obsSum2 = iStat.getSumOfSquares()
+        obsN = iStat.getValuesNumber()
+        obsMin = iStat.getMin()
+        obsMax = iStat.getMax()
+        self.assertEquals(expValuesList, obsValuesList)
+        self.assertEquals(expSum, obsSum)
+        self.assertEquals(expSum2, obsSum2)
+        self.assertEquals(expN, obsN)
+        self.assertEquals(expMin, obsMin)
+        self.assertEquals(expMax, obsMax)
+       
+    def test_fill(self):
+        lValues = [2, 1, 1]
+        iStat = Stat(lValues)
+        iStat.fill([4, 0])
+        expValuesList = [2, 1, 1, 4, 0]
+        expSum = 8
+        expSum2 = 22
+        expN = 5
+        expMin = 0
+        expMax = 4
+        obsValuesList = iStat.getValuesList()
+        obsSum = iStat.getSum()
+        obsSum2 = iStat.getSumOfSquares()
+        obsN = iStat.getValuesNumber()
+        obsMin = iStat.getMin()
+        obsMax = iStat.getMax()
+        self.assertEquals(expValuesList, obsValuesList)
+        self.assertEquals(expSum, obsSum)
+        self.assertEquals(expSum2, obsSum2)
+        self.assertEquals(expN, obsN)
+        self.assertEquals(expMin, obsMin)
+        self.assertEquals(expMax, obsMax)
+        
+    def test_mean_emptyList(self):
+        lValues = []
+        iStat = Stat(lValues)
+        expMean = 0
+        obsMean = iStat.mean()
+        self.assertEquals(expMean, obsMean)
+        
+    def test_mean(self):
+        lValues = [0, 1]
+        iStat = Stat(lValues)
+        expMean = 0.5
+        obsMean = iStat.mean()
+        self.assertEquals(expMean, obsMean)
+        
+    def test_var_emptyList(self):
+        lValues = []
+        iStat = Stat(lValues)
+        expVar = 0
+        obsVar = iStat.var()
+        self.assertEquals(expVar, obsVar)
+        
+    def test_var(self):
+        lValues = [1, 1, 2]
+        iStat = Stat(lValues)
+        expVar = round(1/float(3), 5)
+        obsVar = round(iStat.var(), 5)
+        self.assertEquals(expVar, obsVar)
+        
+    def test_var2(self):
+        lValues = [1,6,3,4,9,6]
+        iStat = Stat(lValues)
+        expVar = 7.76667
+        obsVar = round(iStat.var(), 5)
+        self.assertEquals(expVar, obsVar)
+        
+    def test_var_null(self):
+        lValues = [87.340000000000003, 87.340000000000003, 87.340000000000003, 87.340000000000003, 87.340000000000003, 87.340000000000003, 87.340000000000003]
+        iStat = Stat(lValues)
+        expVar = 0
+        obsVar = round(iStat.var(),5)
+        self.assertEquals(expVar, obsVar)
+        
+    def test_sd(self):
+        lValues = [1, 1, 2]
+        iStat = Stat(lValues)
+        expSd = round(0.577350269, 5)
+        obsSd = round(iStat.sd(), 5)
+        self.assertEquals(expSd, obsSd)
+        
+    def test_sd_null(self):
+        lValues = [87.340000000000003, 87.340000000000003, 87.340000000000003, 87.340000000000003, 87.340000000000003, 87.340000000000003, 87.340000000000003]
+        iStat = Stat(lValues)
+        expSd = 0
+        obsSd = round(iStat.sd(), 5)
+        self.assertEquals(expSd, obsSd)
+
+    def test_cv(self):
+        lValues = [1, 1, 2]
+        iStat = Stat(lValues)
+        expSd = round(0.433012702, 5)
+        obsSd = round(iStat.cv(), 5)
+        self.assertEquals(expSd, obsSd)
+
+    def test_cv_mean_is_nul(self):
+        lValues = [1, -1]
+        iStat = Stat(lValues)
+        expSd = 0
+        obsSd = iStat.cv()
+        self.assertEquals(expSd, obsSd)
+        
+    def test_median_emptyList(self):
+        lValues = []
+        iStat = Stat(lValues)
+        expMedian = "NA"
+        obsMedian = iStat.median()
+        self.assertEquals(expMedian, obsMedian)
+        
+    def test_median_even(self):
+        lValues = [1, 2, 3, 4, 1, 2, 54, 6, 7]
+        iStat = Stat(lValues)
+        expMedian = 3
+        obsMedian = iStat.median()
+        self.assertEquals(expMedian, obsMedian)
+        
+    def test_median_odd(self):
+        lValues = [1, 2, 3, 4, 2, 54, 6, 7]
+        iStat = Stat(lValues)
+        expMedian = 3.5
+        obsMedian = iStat.median()
+        self.assertEquals(expMedian, obsMedian)
+        
+    def test_kurtosis_flat(self):
+        lValues = [1, 1, 1]
+        iStat = Stat(lValues)
+        expKurtosis = 0
+        obsKurtosis = iStat.kurtosis()
+        self.assertEquals(expKurtosis, obsKurtosis)
+        
+    def test_kurtosis_peak(self):
+        lValues = [1, 100, -5]
+        iStat = Stat(lValues)
+        expKurtosis = round(712872278.6609683, 2)
+        obsKurtosis = round(iStat.kurtosis(), 2)
+        self.assertEquals(expKurtosis, obsKurtosis)
+ 
+    def test_kurtosis_normal(self):
+        lValues = [-1, 0, 1.64, 1.64, 0, -1]
+        iStat = Stat(lValues)
+        expKurtosis = 3.0
+        obsKurtosis = round(iStat.kurtosis(), 1)
+        self.assertEquals(expKurtosis, obsKurtosis)
+        
+    def test_sort(self):
+        lValues = [-1, 0, 1.64, 1.64, 0, -1]
+        iStat = Stat(lValues)
+        expSort = [-1, -1, 0, 0, 1.64, 1.64]
+        obsSort = iStat.sort()
+        self.assertEquals(expSort, obsSort)
+        
+    def test_sort_reverse(self):
+        lValues = [-1, 0, 1.64, 1.64, 0, -1]
+        iStat = Stat(lValues)
+        expSort = [1.64, 1.64, 0, 0, -1, -1]
+        obsSort = iStat.sort(True)
+        self.assertEquals(expSort, obsSort)
+        
+    def test_sort_emptyList(self):
+        lValues = []
+        iStat = Stat(lValues)
+        expSort = []
+        obsSort = iStat.sort()
+        self.assertEquals(expSort, obsSort)
+        
+    def test_quantile_emptyList(self):
+        lValues = []
+        iStat = Stat(lValues)
+        expQuantile = 0
+        obsQuantile = iStat.quantile(0.25)
+        self.assertEquals(expQuantile, obsQuantile)
+        
+    def test_quantile_0perc(self):
+        lValues = [0, 2.64, 1.64, -1, 5]
+        iStat = Stat(lValues)
+        expQuantile = -1
+        obsQuantile = iStat.quantile(0)
+        self.assertEquals(expQuantile, obsQuantile)
+        
+    def test_quantile_25perc(self):
+        lValues = [0, 2.64, 1.64, -1, 5]
+        iStat = Stat(lValues)
+        expQuantile = 0
+        obsQuantile = iStat.quantile(0.25)
+        self.assertEquals(expQuantile, obsQuantile)
+        
+    def test_quantile_41perc(self):
+        lValues = [0, 2.64, 1.64, -1, 5]
+        iStat = Stat(lValues)
+        expQuantile = 1.64
+        obsQuantile = iStat.quantile(0.41)
+        self.assertEquals(expQuantile, obsQuantile)
+        
+    def test_quantile_75perc(self):
+        lValues = [0, 2.64, 1.64, -1, 5]
+        iStat = Stat(lValues)
+        expQuantile = 2.64
+        obsQuantile = iStat.quantile(0.75)
+        self.assertEquals(expQuantile, obsQuantile)
+        
+    def test_quantile_81perc(self):
+        lValues = [0, 2.64, 1.64, -1, 5]
+        iStat = Stat(lValues)
+        expQuantile = 5
+        obsQuantile = iStat.quantile(0.81)
+        self.assertEquals(expQuantile, obsQuantile)
+        
+    def test_quantile_100perc(self):
+        lValues = [0, 2.64, 1.64, -1, 5]
+        iStat = Stat(lValues)
+        expQuantile = 5
+        obsQuantile = iStat.quantile(1)
+        self.assertEquals(expQuantile, obsQuantile)
+        
+    def test_N50(self):
+        lValues = [10, 10, 2, 16, 3, 4, 5]
+        iStat = Stat(lValues)
+        expN50 = 10
+        obsN50 = iStat.N50()
+        self.assertEquals(expN50, obsN50)
+
+    def test_N50SpecialValues(self):
+        lValues = [1, 100, 2, 3]
+        iStat = Stat(lValues)
+        expN50 = 100
+        obsN50 = iStat.N50()
+        self.assertEquals(expN50, obsN50)
+        
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/tree/Tree.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,122 @@
+import os, re, sys
+
+class Tree:
+
+    def __init__( self, inFileName="" ):
+        self.tree = None
+        self.inFileName = inFileName
+        if self.inFileName != "":
+            self.loadTree()
+            
+    def loadTree( self, verbose=0 ):
+        inF = open( self.inFileName, "r" )
+        lines = inF.readlines()
+        inF.close()
+        line = "".join(lines).replace("\n","")
+        self.tree = self.parseTree( line )
+        if verbose > 0:
+            print "nb of leaves: %i" % ( self.getNbOfLeaves( self.tree ) )
+        
+    def parseTree( self, sTree ):
+        if "," not in sTree:
+            name, length = sTree.split(":")
+            return self.makeLeaf( name, float(length) )
+        
+        distPattern = re.compile(r'(?P<tree>\(.+\))\:(?P<length>[e\-\d\.]+)$')
+	m = distPattern.search( sTree )
+	length = 0
+	if m:			
+            if m.group('length'): length = float( m.group('length') )
+            sTree = m.group('tree')
+	if length == "": length = 0
+        
+        lhs, rhs = self.parseSubTree( sTree )
+        
+        return { "name": "internal",
+                       "left": self.parseTree( lhs ),
+                       "right": self.parseTree( rhs ),
+                       "length": length }
+        
+    def makeLeaf( self, name, length ):
+        return { "left":None, "right":None, "name":name, "length":length }
+    
+    def parseSubTree( self, sTree ):
+        """
+        Parse a newick-formatted string of type 'a,b' into [a,b]
+        """
+        chars = list( sTree[1:-1] )
+        count = 0
+        isLhs = True
+        leftS = ""
+	rightS = ""
+	for c in chars:
+            if c == "(":
+                count += 1
+            elif c == ")":
+                count -= 1
+            elif (c == ",") and (count == 0) and (isLhs) :
+                isLhs = False
+                continue
+            if isLhs: leftS += c
+            else: rightS += c
+	return [ leftS, rightS ]
+    
+    def toNewick( self, tree ):
+        newString = ""
+        if tree["name"] is not "internal":
+            newString += tree["name"]
+        else:
+            newString += "("
+            newString += self.toNewick( tree["left"] )
+            newString += ","
+            newString += self.toNewick( tree["right"] )
+            newString += ")"
+        if tree["length"]:
+            newString += ":"
+            newString += "%f" % ( tree["length"] )
+	return newString
+    
+    def saveTree( self, outFileName ):
+        outF = open( outFileName, "w" )
+        outF.write( self.toNewick( self.tree ) )
+        outF.close()
+        
+    def replaceHeaderViaPrefixSearch( self, tree, dNew2Init ):
+        if dNew2Init.has_key( tree["name"] ):
+            tree["name"] = dNew2Init[ tree["name"] ].replace(" ","_").replace("::","-").replace(",","-")
+        if tree["left"] != None:
+            self.replaceHeaderViaPrefixSearch( tree["left"], dNew2Init )
+        if tree["right"] != None:
+            self.replaceHeaderViaPrefixSearch( tree["right"], dNew2Init )
+            
+    def retrieveInitialSequenceHeaders( self, dNew2Init, outFileName  ):
+        tree = self.tree
+        self.replaceHeaderViaPrefixSearch( tree, dNew2Init )
+        self.tree = tree
+        self.saveTree( outFileName )
+
+    def getNbOfChildNodes( self, tree, nbNodes ):
+        if tree["left"] is not None:
+            nbNodes += 1
+            nbNodes = self.getNbOfChildNodes( tree["left"], nbNodes )
+        if tree["right"] is not None:
+            nbNodes += 1
+            nbNodes = self.getNbOfChildNodes( tree["right"], nbNodes )
+        return nbNodes
+    
+    def getNbOfNodes( self ):
+        nbNodes = 0
+        return self.getNbOfChildNodes( self.tree, nbNodes )
+    
+    def getNbOfChildLeaves( self, tree, nbLeaves ):
+        if tree["name"] != "internal":
+            nbLeaves += 1
+        if tree["left"] is not None:
+            nbLeaves = self.getNbOfChildLeaves( tree["left"], nbLeaves )
+        if tree["right"] is not None:
+            nbLeaves = self.getNbOfChildLeaves( tree["right"], nbLeaves )
+        return nbLeaves
+    
+    def getNbOfLeaves( self ):
+        nbLeaves = 0
+        return self.getNbOfChildLeaves( self.tree, nbLeaves )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/tree/test/Test_Tree.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,90 @@
+import unittest
+import os
+import time
+from commons.core.tree.Tree import Tree
+from commons.core.utils.FileUtils import FileUtils
+
+
+class Test_Tree( unittest.TestCase ):
+    
+    def setUp( self ):
+        self._tree = Tree()
+        self._uniqId = "%s_%s" % ( time.strftime("%Y%m%d%H%M%S") , os.getpid() )
+        
+        
+    def test_parseTree_oneLeaf( self ):
+        inString = "seq1:0.0023"
+        obs = self._tree.parseTree( inString )
+        exp = { "left":None, "right":None, "name":"seq1", "length":0.0023 }
+        self.assertEqual( obs, exp )
+        
+        
+    def test_parseTree_twoLeaves( self ):
+        inString = "(seq1:0.0023,seq2:0.0017)"
+        obs = self._tree.parseTree( inString )
+        exp = {'length':0, 'right':{'length':0.0016999999999999999, 'right':None, 'name':'seq2', 'left':None}, 'name':'internal', 'left':{'length':0.0023, 'right':None, 'name':'seq1', 'left':None}}
+        self.assertEqual( obs, exp )
+        
+##     def test_parseTree_threeLeaves( self ):
+##         inString = "(seq1:0.0023,(seq2:0.0017,seq3:0.0009))"
+##         obs = self._tree.parseTree( inString )
+##         print obs
+##         exp = {'length':0, 'right':{'length':0.0016999999999999999, 'right':None, 'name':'seq2', 'left':None}, 'name':'internal', 'left':{'length':0.0023, 'right':None, 'name':'seq1', 'left':None}}
+##         self.assertEqual( obs, exp )
+        
+        
+    def test_parseSubTree( self ):
+        inString = "(seq1:0.0023,seq2:0.0017)"
+        lExp = [ "seq1:0.0023", "seq2:0.0017" ]
+        lObs = self._tree.parseSubTree( inString )
+        self.assertEqual( lObs, lExp )
+        
+        
+    def test_saveTree( self ):
+        inFileName = "dummyInFile_%s" % ( self._uniqId )
+        inF = open( inFileName, "w" )
+        inF.write( "(seq4:0.012511,(seq3:0.005340,seq2:0.002201))" )
+        inF.close()
+        self._tree = Tree( inFileName )
+        obsFileName = "dummyObsFile_%s" % ( self._uniqId )
+        self._tree.saveTree( obsFileName )
+        self.assertTrue( FileUtils.are2FilesIdentical( obsFileName, inFileName ) )
+        for f in [ inFileName, obsFileName ]:
+            os.remove( f )
+            
+            
+    def test_retrieveInitialSequenceHeaders( self ):
+        inString = "(seq4:0.012511,(seq3:0.005340,seq2:0.002201))"
+        self._tree.tree = self._tree.parseTree( inString )
+        dNew2Init = { "seq2":"consensus524::215 dmel_chr4 142..765", "seq3":"DmelChr4-B-G387-MAP16", "seq4":"1360|1cl-3gr" }
+        expFileName = "dummyExpFile_%s"  % ( self._uniqId )
+        expF = open( expFileName, "w" )
+        expF.write( "(1360|1cl-3gr:0.012511,(DmelChr4-B-G387-MAP16:0.005340,consensus524-215_dmel_chr4_142..765:0.002201))" )
+        expF.close()
+        obsFileName = "dummyObsFile_%s"  % ( self._uniqId )
+        self._tree.retrieveInitialSequenceHeaders( dNew2Init, obsFileName )
+        self.assertTrue( FileUtils.are2FilesIdentical( obsFileName, expFileName ) )
+        for f in [ expFileName, obsFileName ]:
+            os.remove( f )
+            
+            
+    def test_getNbOfLeaves( self ):
+        inString = "(seq4:0.012511,(seq3:0.005340,seq2:0.002201))"
+        self._tree.tree = self._tree.parseTree( inString )
+        exp = 3
+        obs = self._tree.getNbOfLeaves()
+        self.assertEqual( obs, exp )
+        
+        
+    def test_getNbOfNodes( self ):
+        inString = "(seq4:0.012511,(seq3:0.005340,seq2:0.002201))"
+        self._tree.tree = self._tree.parseTree( inString )
+        exp = 4
+        obs = self._tree.getNbOfNodes()
+        self.assertEqual( obs, exp )
+        
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_Tree ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/tree/test/treeTestSuite.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,16 @@
+import unittest
+import sys
+import Test_Tree
+
+
+
+def main():
+
+        commonsTestSuite = unittest.TestSuite() 
+        commonsTestSuite.addTest(unittest.makeSuite(Test_Tree.Test_Tree,'test'))
+        runner = unittest.TextTestRunner(sys.stderr, 2, 2)
+        runner.run(commonsTestSuite)
+
+
+if __name__ == '__main__':
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/utils/FileUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,447 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import os
+import glob
+import shutil
+import sys
+import re
+import math
+try:
+    import hashlib
+except:
+    pass
+
+
+class FileUtils( object ):
+    
+    ## Return the number of lines in the given file
+    #
+    def getNbLinesInSingleFile( fileName ):
+        fileHandler = open( fileName, "r" )
+        lines = fileHandler.readlines()
+        fileHandler.close()
+        if (len(lines)>0 and lines[-1]== "\n"):
+            return (len(lines)-1)
+        else :
+            return len(lines)
+    
+    getNbLinesInSingleFile = staticmethod( getNbLinesInSingleFile )
+    
+    ## Return the number of lines in the files in the given list
+    #
+    def getNbLinesInFileList( lFileNames ):
+        count = 0
+        for fileName in lFileNames:
+            count += FileUtils.getNbLinesInSingleFile( fileName )
+        return count
+    
+    getNbLinesInFileList = staticmethod( getNbLinesInFileList )
+    
+    ## Return True if the given file exists, False otherwise
+    #
+    def isRessourceExists( fileName ):
+        return os.path.exists( fileName )
+    
+    isRessourceExists = staticmethod( isRessourceExists )
+    
+    ## Return True if the given file is empty, False otherwise
+    #
+    def isEmpty( fileName ):
+        return 0 == FileUtils.getNbLinesInSingleFile( fileName )
+    
+    isEmpty = staticmethod( isEmpty )
+    
+    ## Return True if both files are identical, False otherwise
+    #
+    def are2FilesIdentical( file1, file2 ):
+        tmpFile = "diff_%s_%s" % ( os.path.basename(file1), os.path.basename(file2) )
+        cmd = "diff %s %s >> %s" % ( file1, file2, tmpFile )
+        returnStatus = os.system( cmd )
+        if returnStatus != 0:
+            msg = "ERROR: 'diff' returned '%i'" % ( returnStatus )
+            sys.stderr.write( "%s\n" % msg )
+            sys.stderr.flush()
+            os.remove( tmpFile )
+            return False
+        if FileUtils.isEmpty( tmpFile ):
+            os.remove( tmpFile )
+            return True
+        else:
+            os.remove( tmpFile )
+            return False
+        
+    are2FilesIdentical = staticmethod( are2FilesIdentical )
+    
+    ## Return a string with all the content of the files in the given list
+    #
+    def getFileContent( lFiles ):
+        content = ""
+        lFiles.sort()
+        for fileName in lFiles:
+            currentFile = open( fileName, "r" )
+            content += currentFile.read()
+            currentFile.close()
+        return content
+    
+    getFileContent = staticmethod( getFileContent )
+    
+    ## Save content of the given file after having sorted it
+    #
+    def sortFileContent( inFile, outFile="" ):
+        inFileHandler = open(inFile, "r" )
+        lines = inFileHandler.readlines()
+        inFileHandler.close()
+        lines.sort()
+        if outFile == "":
+            outFile = inFile
+        outFileHandler = open( outFile, "w" )
+        outFileHandler.writelines( lines )
+        outFileHandler.close()
+        
+    sortFileContent = staticmethod( sortFileContent )
+    
+    ## Add end-of-line symbol to the given file content if necessary
+    #
+    def addNewLineAtTheEndOfFileContent( fileContent ):
+        if not fileContent.endswith('\n')  and  len(fileContent) != 0:
+            fileContent += '\n'
+        return fileContent
+    
+    addNewLineAtTheEndOfFileContent = staticmethod( addNewLineAtTheEndOfFileContent )
+    
+    ## Concatenate files in the given list
+    #
+    def catFilesFromList( lFiles, outFile, sort=True, skipHeaders = False, separator = "" ):
+        if sort:
+            lFiles.sort()
+        outFileHandler = open( outFile, "a" )
+        isFirstFile = True
+        for singleFile in lFiles:
+            if not isFirstFile:
+                outFileHandler.write(separator)
+            isFirstFile = False
+            singleFileHandler = open( singleFile, "r" )
+            if skipHeaders:
+                singleFileHandler.readline()
+            line = singleFileHandler.readline()
+            while line:
+                outFileHandler.write(line)
+                line = singleFileHandler.readline()
+            singleFileHandler.close()
+        outFileHandler.close()
+        
+    catFilesFromList = staticmethod( catFilesFromList )
+    
+    ## Concatenate files according to the given pattern
+    #
+    def catFilesByPattern( pattern, outFile, skipHeaders = False, separator = "" ):
+        lFiles = glob.glob( pattern )
+        FileUtils.catFilesFromList( lFiles, outFile, skipHeaders = skipHeaders, separator = separator )
+        
+    catFilesByPattern = staticmethod( catFilesByPattern )
+    
+    ## Remove files listed according to the given pattern
+    #
+    # @example prefix="/home/tmp/dummy*.txt"
+    #
+    def removeFilesByPattern( prefix ):
+        lFiles = glob.glob( prefix )
+        for f in lFiles:
+            os.remove( f )
+            
+    removeFilesByPattern = staticmethod( removeFilesByPattern )
+    
+    ## Remove files listed according to the suffixes in the given list
+    #
+    def removeFilesBySuffixList( targetPath, lSuffixes ):
+        if targetPath[-1] == "/":
+            targetPath = targetPath[:-1]
+        for suffix in lSuffixes:
+            pattern = "%s/*%s" % ( targetPath, suffix )
+            FileUtils.removeFilesByPattern( pattern )
+            
+    removeFilesBySuffixList = staticmethod( removeFilesBySuffixList )
+    
+    ## Remove repeated blanks in the given file
+    #
+    def removeRepeatedBlanks( inFile, outFile="" ):
+        if outFile == "":
+            outFile = inFile
+        tmpFile = "tr_%s_%s" % ( inFile, outFile )
+        cmd = "tr -s ' ' < %s > %s" % ( inFile, tmpFile )
+        os.system( cmd )
+        os.rename( tmpFile, outFile )
+        
+    removeRepeatedBlanks = staticmethod( removeRepeatedBlanks )
+    
+    ## Remove files in the given list
+    #
+    @staticmethod
+    def removeFilesFromList(lFiles):
+        for f in lFiles:
+            os.remove(f)
+    
+    ## Remove files in the given list if exist
+    #
+    @staticmethod
+    def removeFilesFromListIfExist(lFiles):
+        for fileName in lFiles:
+            if FileUtils.isRessourceExists(fileName):
+                os.remove(fileName)
+    
+    ## Append the content of a file to another file
+    #
+    # @param inFile string name of the input file
+    # @param outFile string name of the output file
+    #
+    def appendFileContent( inFile, outFile ):
+        outFileHandler = open( outFile, "a" )
+        inFileHandler = open( inFile, "r" )
+        shutil.copyfileobj( inFileHandler, outFileHandler )
+        inFileHandler.close()
+        outFileHandler.close()
+        
+    appendFileContent = staticmethod( appendFileContent )
+    
+    
+    ## Replace Windows end-of-line by Unix end-of-line
+    #
+    def fromWindowsToUnixEof( inFile ):
+        tmpFile = "%s.tmp" % ( inFile )
+        shutil.copyfile( inFile, tmpFile )
+        os.remove( inFile )
+        tmpFileHandler = open( tmpFile, "r" )
+        inFileHandler = open( inFile, "w" )
+        while True:
+            line = tmpFileHandler.readline()
+            if line == "":
+                break
+            inFileHandler.write( line.replace("\r\n","\n") )
+        tmpFileHandler.close()
+        inFileHandler.close()
+        os.remove( tmpFile )
+        
+    fromWindowsToUnixEof = staticmethod( fromWindowsToUnixEof )
+
+
+    ## Remove duplicated lines in a file
+    #
+    # @note it preserves the initial order and handles blank lines
+    #
+    def removeDuplicatedLines( inFile ):
+        tmpFile = "%s.tmp" % ( inFile )
+        shutil.copyfile( inFile, tmpFile )
+        os.remove( inFile )
+        
+        tmpFileHandler = open( tmpFile, "r" )
+        lLines = list( tmpFileHandler.read().split("\n") )
+        if lLines[-1] == "":
+            del lLines[-1]
+        sLines = set( lLines )
+        tmpFileHandler.close()
+        os.remove( tmpFile )
+        
+        inFileHandler = open( inFile, "w" )
+        for line in lLines:
+            if line in sLines:
+                inFileHandler.write( "%s\n" % ( line ) )
+                sLines.remove( line )
+        inFileHandler.close()
+        
+    removeDuplicatedLines = staticmethod( removeDuplicatedLines )
+    
+    
+    ## Write a list of lines in a given file
+    #
+    def writeLineListInFile( inFile, lLines ):
+        inFileHandler = open( inFile, "w" )
+        for line in lLines:
+            inFileHandler.write( line )
+        inFileHandler.close()
+        
+    writeLineListInFile = staticmethod( writeLineListInFile )
+    
+    
+    ## Give the list of absolute path of each directory in the given directory
+    #
+    # @param rootPath string absolute path of the given directory
+    #
+    # @return lDirPath list of absolute directory path
+    #
+    def getAbsoluteDirectoryPathList(rootPath):
+        lDirPath = []
+        lPaths = glob.glob(rootPath + "/*")
+        for ressource in lPaths:
+            if os.path.isdir(ressource) :
+                lDirPath.append(ressource)
+        return lDirPath
+    
+    getAbsoluteDirectoryPathList = staticmethod(getAbsoluteDirectoryPathList)
+    
+    
+    ## Get a sublist of which each element matches/doesn't match a pattern
+    #
+    # @param lPath string list of paths
+    #
+    # @param pattern string pattern
+    #
+    # @param match bool 
+    #
+    # @return lPathMatching list of path matching pattern
+    #
+    def getSubListAccordingToPattern(lPath, pattern, match = True):
+        lPathMatching = []
+        for path in lPath:
+            if match:
+                if re.match(".*%s.*" % pattern, path):
+                    lPathMatching.append(path)
+            else:
+                if not re.match(".*%s.*" % pattern, path):
+                    lPathMatching.append(path)
+        return lPathMatching
+    
+    getSubListAccordingToPattern = staticmethod(getSubListAccordingToPattern)
+    
+    
+    ## Give the list of file names found in the given directory
+    #
+    # @param dirPath string absolute path of the given directory
+    #
+    # @return lFilesInDir list of file names
+    #
+    def getFileNamesList( dirPath, patternFileFilter = ".*" ):
+        lFilesInDir = []
+        lPaths = glob.glob( dirPath + "/*" )
+        for ressource in lPaths:
+            if os.path.isfile( ressource ):
+                fileName = os.path.basename( ressource )
+                if re.match(patternFileFilter, fileName):
+                    lFilesInDir.append( fileName )
+        return lFilesInDir
+    
+    getFileNamesList = staticmethod( getFileNamesList )
+    
+    ## Return the MD5 sum of a file
+    #
+    def getMd5SecureHash( inFile ):
+        if "hashlib" in sys.modules:
+            md5 = hashlib.md5()
+            inFileHandler = open( inFile, "r" )
+            while True:
+                line = inFileHandler.readline()
+                if line == "":
+                    break
+                md5.update( line )
+            inFileHandler.close()
+            return md5.hexdigest()
+        else:
+            return ""
+        
+    getMd5SecureHash = staticmethod( getMd5SecureHash )
+    
+    ## Cat all files of a given directory
+    #
+    # @param dir string directory name
+    # @param outFileName string output file name
+    #
+    def catFilesOfDir(dir, outFileName):
+        lFiles = FileUtils.getFileNamesList(dir)
+        lFile2 = []
+        for file in lFiles:
+            lFile2.append(dir + "/" + file)
+        FileUtils.catFilesFromList(lFile2, outFileName)
+        
+    catFilesOfDir = staticmethod(catFilesOfDir)
+    
+    ## Return True if size file > 0 octet
+    #
+    # @param fileName string file name
+    #
+    def isSizeNotNull(fileName):
+        size = os.path.getsize(fileName)
+        if size > 0:
+            return True
+        return False
+        
+    isSizeNotNull = staticmethod(isSizeNotNull)
+    
+    ## Split one file into N Files by lines
+    #
+    # @param fileName string file name
+    # @param N int number of files to create
+    # 
+    @staticmethod
+    def splitFileIntoNFiles(fileName, N):
+        nbLine = FileUtils.getNbLinesInSingleFile(fileName)
+        nbLinesInEachFile = nbLine
+        if N > nbLine:
+            N = nbLine
+        if N != 0:
+            nbLinesInEachFile = math.ceil(float(nbLine) / N)
+        else:
+            N = 1
+        filePrefix, fileExt = os.path.splitext(os.path.basename(fileName))
+        fileHandler = open(fileName, "r")
+        for i in range(1,N+1):
+            with open("%s-%s%s" %(filePrefix, i, fileExt), "w") as f:
+                j = 0
+                while j < nbLinesInEachFile:
+                    j += 1
+                    f.write(fileHandler.readline())
+        fileHandler.close()            
+            
+    ## Split one file into files of N lines
+    #
+    # @param fileName string input file name
+    # @param N int lines number per files
+    # 
+    @staticmethod
+    def splitFileAccordingToLineNumber(fileName, N):
+        filePrefix, fileExt = os.path.splitext(os.path.basename(fileName))
+        with open(fileName) as inF:
+            fileNb = 1
+            line = inF.readline()
+            if not line or N == 0:
+                outFileName = "%s-%s%s" %(filePrefix, fileNb, fileExt)
+                f = open(outFileName, "wb")
+                shutil.copyfileobj(open(fileName, "rb"), f)
+                f.close()
+            else:
+                while line:
+                    outFileName = "%s-%s%s" %(filePrefix, fileNb, fileExt)
+                    with open(outFileName, "w") as outF:
+                        lineNb = 1
+                        while lineNb <= N and line:
+                            outF.write(line)
+                            line = inF.readline()
+                            lineNb += 1
+                    fileNb += 1
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/utils/PipelineStepFTests.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+import sys
+import os
+import shutil
+from commons.core.utils.FileUtils import FileUtils
+
+class PipelineStepFTests(object):
+    
+    def __init__(self, pipelineName, packageDir, workingDir, projectName, config = "", clean = True):
+        self._pipelineName = pipelineName
+        self._packageDir = packageDir
+        self._workingDir = workingDir
+        self._projectName = projectName
+        self._clean = clean
+        self._configFileName = config
+        
+    def run(self):
+        self.launchStep()
+        self.assertStep()
+
+#    def replaceInFile(self, fileName, oldPattern, newPattern, newFileName = ""):
+#        if newFileName == "":
+#            newFileName = "%s.new" % fileName
+#        f = open(newFileName, "w")
+#        for line in fileinput.input(fileName, inplace=1):
+#            newLine = line.replace(oldPattern, newPattern)
+#            f.write(newLine)
+#        f.close()
+#        fileinput.close()
+
+    def _checkIfFileExist(self, fileName):
+        if not FileUtils.isRessourceExists(fileName):
+            print "%s do not exists\n" % fileName
+            return False
+        return True
+        
+    def _printMessageAndClean(self, msg):
+        print "%s in %s functional test\n" % (msg, self._pipelineName)
+        sys.stdout.flush()
+        os.chdir("../")
+        if self._clean:
+            shutil.rmtree(self._workingDir)
+                
+    def _areTwoFilesIdenticalByScript( self, expFileName, obsFileName, scriptName):
+        cmd = "%s -v 1 -r %s -t %s 2>/dev/null" % (scriptName, expFileName, obsFileName)
+        log = os.system(cmd)
+        print
+        sys.stdout.flush()
+        if log != 0:
+            return False
+        else:
+            return True
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/utils/RepetConfigParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,38 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+from ConfigParser import ConfigParser
+
+
+class RepetConfigParser(ConfigParser):
+
+    def optionxform(self, optionstr):
+        return optionstr
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/utils/RepetOptionParser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+
+"""
+Class overriding optparse.OptionParser default epilog formatter.
+The resulting epilog display format is the same as if the corresponding string was printed. 
+"""
+
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+from optparse import OptionParser
+from optparse import BadOptionError
+from optparse import OptionValueError
+SUPPRESS_USAGE = "SUPPRESS"+"USAGE"
+
+class RepetOptionParser(OptionParser):
+
+    def parse_args(self, args=None, values=None):
+        rargs = self._get_args(args)
+        if not rargs:
+            rargs = ["-h"]
+        if values is None:
+            values = self.get_default_values()
+        self.rargs = rargs
+        self.largs = largs = [] 
+        self.values = values
+        try: 
+            self._process_args(largs, rargs, values)
+        except (BadOptionError, OptionValueError), err: 
+            self.error(str(err))
+        args = largs + rargs
+        return self.check_values(values, args)
+
+    def set_usage(self, usage):
+        if not usage or usage is SUPPRESS_USAGE:
+            self.usage = None
+        elif usage.lower().startswith("usage: "):
+            self.usage = usage[7:]
+        else:
+            self.usage = usage
+    
+    def format_epilog(self, formatter):
+        if self.epilog != None:
+            return self.epilog
+        else :
+            return ""
+    
+    def format_description(self, formatter):
+        if self.description != None:
+            return self.description
+        else :
+            return ""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/utils/test/TestSuite_utils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import unittest
+import sys
+import Test_FileUtils
+
+
+def main():
+    
+    TestSuite_utils = unittest.TestSuite() 
+    
+    TestSuite_utils.addTest( unittest.makeSuite( Test_FileUtils.Test_FileUtils, "test" ) )
+    
+    runner = unittest.TextTestRunner(sys.stderr, 2, 2)
+    runner.run( TestSuite_utils )
+    
+    
+if __name__ == "__main__":
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/utils/test/Test_FileUtils.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,885 @@
+# Copyright INRA (Institut National de la Recherche Agronomique)
+# http://www.inra.fr
+# http://urgi.versailles.inra.fr
+#
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software.  You can  use, 
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info". 
+#
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty  and the software's author,  the holder of the
+# economic rights,  and the successive licensors  have only  limited
+# liability. 
+#
+# In this respect, the user's attention is drawn to the risks associated
+# with loading,  using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate,  and  that  also
+# therefore means  that it is reserved for developers  and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or 
+# data to be ensured and,  more generally, to use and operate it in the 
+# same conditions as regards security. 
+#
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+
+import os
+import sys
+import unittest
+import time
+import shutil
+from commons.core.utils.FileUtils import FileUtils
+
+
+class Test_FileUtils( unittest.TestCase ):
+    
+    def setUp( self ):
+        self._uniqId = "%s_%s" % ( time.strftime("%Y%m%d%H%M%S"), os.getpid() )
+        
+    def tearDown( self ):
+        self._uniqId = ""
+        
+    def test_getNbLinesInSingleFile_non_empty( self ):
+        file = "dummyFile_%s" % ( self._uniqId )
+        f = open( file, "w" )
+        f.write( "line1\n" )
+        f.write( "line2\n" )
+        f.write( "line3" )
+        f.close()
+        exp = 3
+        obs = FileUtils.getNbLinesInSingleFile( file )
+        self.assertEquals( exp, obs )
+        os.remove( file )
+        
+    def test_getNbLinesInSingleFile_non_empty_endEmptyLine( self ):
+        file = "dummyFile_%s" % ( self._uniqId )
+        f = open( file, "w" )
+        f.write( "line1\n" )
+        f.write( "line2\n" )
+        f.write( "line3\n" )
+        f.write( "\n" )
+        f.close()
+        exp = 3
+        obs = FileUtils.getNbLinesInSingleFile( file )
+        self.assertEquals( exp, obs )
+        os.remove( file )
+        
+    def test_getNbLinesInSingleFile_empty( self ):
+        file = "dummyFile_%s" % ( self._uniqId )
+        os.system( "touch %s" % ( file ) )
+        exp = 0
+        obs = FileUtils.getNbLinesInSingleFile( file )
+        self.assertEquals( exp, obs )
+        os.remove( file )
+        
+    def test_getNbLinesInFileList_non_empty( self ):
+        f = open("dummy1.txt", "w")
+        f.write("line1\n")
+        f.write("line2\n")
+        f.write("line3")
+        f.close()
+        f = open("dummy2.txt", "w")
+        f.write("line1\n")
+        f.write("line2\n")
+        f.write("line3")
+        f.close()
+        f = open("dummy3.txt", "w")
+        f.write("line1\n")
+        f.write("line2\n")
+        f.write("line3")
+        f.close()
+        lFiles = [ "dummy1.txt", "dummy2.txt", "dummy3.txt" ]
+        exp = 9
+        obs = FileUtils.getNbLinesInFileList( lFiles )
+        self.assertEqual( exp, obs )
+        for f in lFiles:
+            os.remove( f )
+            
+    def test_catFilesByPattern( self ):
+        f = open("dummy1.txt", "w")
+        f.write("line11\n")
+        f.write("line12\n")
+        f.write("line13")
+        f.close()
+        f = open("dummy2.txt", "w")
+        f.write("line21\n")
+        f.write("line22\n")
+        f.write("line23\n")
+        f.close()
+        f = open("dummy3.txt", "w")
+        f.write("line31\n")
+        f.write("line32\n")
+        f.write("line33")
+        f.close()
+        lFiles = [ "dummy1.txt", "dummy2.txt", "dummy3.txt" ]
+        outFile = "concatFiles.txt"
+        FileUtils.catFilesByPattern( "dummy*.txt", outFile )
+        self.assertTrue( os.path.exists( outFile ) )
+        exp = "line11\nline12\nline13line21\nline22\nline23\nline31\nline32\nline33"
+        obs = FileUtils.getFileContent( [ outFile ] )
+        self.assertEqual( exp, obs )
+        for f in lFiles:
+            os.remove( f )
+        os.remove(outFile)
+            
+    def test_catFilesByPattern_with_headers( self ):
+        f = open("dummy1.txt", "w")
+        f.write("line11\n")
+        f.write("line12\n")
+        f.write("line13\n")
+        f.close()
+        f = open("dummy2.txt", "w")
+        f.write("line21\n")
+        f.write("line22\n")
+        f.write("line23\n")
+        f.close()
+        f = open("dummy3.txt", "w")
+        f.write("line31\n")
+        f.write("line32\n")
+        f.write("line33\n")
+        f.close()
+        lFiles = [ "dummy1.txt", "dummy2.txt", "dummy3.txt" ]
+        outFile = "concatFiles.txt"
+        FileUtils.catFilesByPattern( "dummy*.txt", outFile, skipHeaders = True)
+        self.assertTrue( os.path.exists( outFile ) )
+        exp = "line12\nline13\nline22\nline23\nline32\nline33\n"
+        obs = FileUtils.getFileContent( [ outFile ] )
+        self.assertEqual( exp, obs )
+        for f in lFiles:
+            os.remove( f )
+        os.remove(outFile)
+            
+    def test_catFilesByPattern_with_separator( self ):
+        f = open("dummy1.txt", "w")
+        f.write("line11\n")
+        f.write("line12\n")
+        f.write("line13")
+        f.close()
+        f = open("dummy2.txt", "w")
+        f.write("line21\n")
+        f.write("line22\n")
+        f.write("line23\n")
+        f.close()
+        f = open("dummy3.txt", "w")
+        f.write("line31\n")
+        f.write("line32\n")
+        f.write("line33")
+        f.close()
+        lFiles = [ "dummy1.txt", "dummy2.txt", "dummy3.txt" ]
+        outFile = "concatFiles.txt"
+        FileUtils.catFilesByPattern( "dummy*.txt", outFile, separator = "\n+------------+\n")
+        self.assertTrue( os.path.exists( outFile ) )
+        exp = "line11\nline12\nline13\n+------------+\nline21\nline22\nline23\n\n+------------+\nline31\nline32\nline33"
+        obs = FileUtils.getFileContent( [ outFile ] )
+        self.assertEqual( exp, obs )
+        for f in lFiles:
+            os.remove( f )
+        os.remove(outFile)
+            
+    def test_catFilesByPattern_with_headers_and_separator( self ):
+        f = open("dummy1.txt", "w")
+        f.write("line11\n")
+        f.write("line12\n")
+        f.write("line13\n")
+        f.close()
+        f = open("dummy2.txt", "w")
+        f.write("line21\n")
+        f.write("line22\n")
+        f.write("line23\n")
+        f.close()
+        f = open("dummy3.txt", "w")
+        f.write("line31\n")
+        f.write("line32\n")
+        f.write("line33\n")
+        f.close()
+        lFiles = [ "dummy1.txt", "dummy2.txt", "dummy3.txt" ]
+        outFile = "concatFiles.txt"
+        FileUtils.catFilesByPattern( "dummy*.txt", outFile, separator = "\n+------------+\n", skipHeaders = True)
+        self.assertTrue( os.path.exists( outFile ) )
+        exp = "line12\nline13\n\n+------------+\nline22\nline23\n\n+------------+\nline32\nline33\n"
+        obs = FileUtils.getFileContent( [ outFile ] )
+        self.assertEqual( exp, obs )
+        for f in lFiles:
+            os.remove( f )
+        os.remove(outFile)
+            
+    def test_isRessourceExists_exists(self): 
+        f = open("dummyFile.txt", "w")
+        f.close()
+        self.assertTrue(FileUtils.isRessourceExists("dummyFile.txt"))
+        os.system("rm dummyFile.txt")
+            
+    def test_isRessourceExists_not_exists(self):
+        self.assertFalse(FileUtils.isRessourceExists("dummyFile.txt"))
+            
+    def test_isEmpty_empty( self ):
+        file = "dummyFile_%s" % ( self._uniqId )
+        os.system( "touch %s" % ( file ) )
+        self.assertTrue( FileUtils.isEmpty( file ) )
+        os.remove( file )
+        
+    def test_isEmpty_non_empty( self ):
+        file = "dummyFile_%s" % ( self._uniqId )
+        fileHandler = open( file, "w" )
+        fileHandler.write( "line1\n" )
+        fileHandler.close()
+        self.assertFalse( FileUtils.isEmpty( file ) )
+        os.remove( file )
+        
+    def test_are2FilesIdentical_true( self ):
+        f = open("dummy1.txt", "w")
+        f.write("line11\n")
+        f.close()
+        f = open("dummy2.txt", "w")
+        f.write("line11\n")
+        f.close()
+        self.assertTrue( FileUtils.are2FilesIdentical( "dummy1.txt", "dummy2.txt" ) )
+        for f in [ "dummy1.txt", "dummy2.txt" ]:
+            os.remove( f )
+            
+    def test_are2FilesIdentical_false( self ):
+        f = open("dummy1.txt", "w")
+        f.write("line11\n")
+        f.close()
+        f = open("dummy2.txt", "w")
+        f.write("line21\n")
+        f.close()
+        self.assertFalse( FileUtils.are2FilesIdentical( "dummy1.txt", "dummy2.txt" ) )
+        for f in [ "dummy1.txt", "dummy2.txt" ]:
+            os.remove( f )
+            
+    def test_getFileContent( self ):
+        inFile = "dummyInFile_%s" % ( self._uniqId )
+        inFileHandler = open( inFile, "w" )
+        inFileHandler.write( "zgdfet\n" )
+        inFileHandler.write( "agdfet\n" )
+        inFileHandler.close()
+        exp = "zgdfet\n" + "agdfet\n"
+        obs = FileUtils.getFileContent( [ inFile ] )
+        self.assertEquals( exp, obs )
+        os.remove( inFile )
+        
+    def test_sortFileContent( self ):
+        inFile = "dummyInFile_%s" % ( self._uniqId )
+        inFileHandler = open( inFile, "w" )
+        inFileHandler.write( "zgdfet\n" )
+        inFileHandler.write( "agdfet\n" )
+        inFileHandler.close()
+        
+        expFile = "dummyExpFile_%s" % ( self._uniqId )
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "agdfet\n" )
+        expFileHandler.write( "zgdfet\n" )
+        expFileHandler.close()
+        
+        FileUtils.sortFileContent( inFile )
+        
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, inFile ) )
+        for f in [ inFile, expFile ]:
+            os.remove( f )
+            
+    def test_removeFilesByPattern_prefix( self ):
+        fileName1 = "filetest.fa"
+        fileName2 = "test.fa.Nstretch.map"
+        fileName3 = "test.fa_cut"
+        os.system("touch %s" % fileName1)
+        os.system("touch %s" % fileName2)
+        os.system("touch %s" % fileName3)
+        FileUtils.removeFilesByPattern("test*")
+        self.assertTrue(os.path.exists(fileName1))
+        self.assertFalse(os.path.exists(fileName2))
+        self.assertFalse(os.path.exists(fileName3))
+        os.remove(fileName1)
+            
+    def test_removeFilesByPattern_suffix( self ):
+        fileName1 = "filetest"
+        fileName2 = "test.fa.Nstretch.map"
+        fileName3 = "test.fa_cut"
+        os.system("touch %s" % fileName1)
+        os.system("touch %s" % fileName2)
+        os.system("touch %s" % fileName3)
+        FileUtils.removeFilesByPattern("*test")
+        self.assertFalse(os.path.exists(fileName1))
+        self.assertTrue(os.path.exists(fileName2))
+        self.assertTrue(os.path.exists(fileName3))
+        os.remove(fileName2)
+        os.remove(fileName3)
+            
+    def test_removeFilesBySuffixList( self ):
+        tmpDir = "dummyDir_%s" % ( self._uniqId )
+        if not os.path.exists( tmpDir ):
+            os.mkdir( tmpDir )
+        commonPrefix = "dummyFile_%s"  %( self._uniqId )
+        os.system( "touch %s/%s.fa" % ( tmpDir, commonPrefix ) )
+        os.system( "touch %s/%s.fa.Nstretch.map" % ( tmpDir, commonPrefix ) )
+        os.system( "touch %s/%s.fa_cut" % ( tmpDir, commonPrefix ) )
+        lSuffixes = [ ".Nstretch.map", "_cut" ]
+        FileUtils.removeFilesBySuffixList( tmpDir, lSuffixes )
+        self.assertTrue( os.path.exists( "%s/%s.fa" % ( tmpDir, commonPrefix ) ) )
+        self.assertFalse( os.path.exists( "%s/%s.fa.Nstretch.map" % ( tmpDir, commonPrefix ) ) )
+        self.assertFalse( os.path.exists( "%s/%s.fa_cut" % ( tmpDir, commonPrefix ) ) )
+        shutil.rmtree( tmpDir )
+        
+    def test_removeRepeatedBlanks( self ):
+        inFileName = "dummyWithRepeatedBlanks.dum"
+        obsFileName = "dummyWithoutRepeatedBlanks.dum"
+        expFileName = "dummyExpWithoutRepeatedBlanks.dum"
+        self._writeFileWithRepeatedBlanks( inFileName )
+        self._writeFileWithoutRepeatedBlanks( expFileName )
+        FileUtils.removeRepeatedBlanks( inFileName, obsFileName )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        for f in [ inFileName, expFileName, obsFileName ]:
+            os.remove( f )
+            
+    def test_RemoveRepeatedBlanks_without_outfileName (self):
+        inFileName = "dummyWithRepeatedBlanks.dum"
+        expFileName = "dummyExpWithoutRepeatedBlanks.dum"
+        obsFileName = inFileName
+        self._writeFileWithRepeatedBlanks( inFileName )
+        self._writeFileWithoutRepeatedBlanks( expFileName )
+        FileUtils.removeRepeatedBlanks( inFileName )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFileName, obsFileName ) )
+        for f in [ inFileName, expFileName ]:
+            os.remove( f )
+
+
+    def test_fromWindowsToUnixEof( self ):
+        inFile = "dummyInFile"
+        inFileHandler = open( inFile, "w" )
+        inFileHandler.write( "toto\r\n" )
+        inFileHandler.close()
+        expFile = "dummyExpFile"
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "toto\n" )
+        expFileHandler.close()
+        FileUtils.fromWindowsToUnixEof( inFile )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, inFile ) )
+        for f in [ inFile, expFile ]:
+            os.remove( f )
+            
+            
+    def test_removeDuplicatedLines( self ):
+        inFile = "dummyInFile"
+        inFileHandler = open( inFile, "w" )
+        inFileHandler.write( "toto\n" )
+        inFileHandler.write( "titi\n" )
+        inFileHandler.write( "toto\n" )
+        inFileHandler.close()
+        expFile = "dummyExpFile"
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "toto\n" )
+        expFileHandler.write( "titi\n" )
+        expFileHandler.close()
+        FileUtils.removeDuplicatedLines( inFile )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, inFile ) )
+        for f in [ inFile, expFile ]:
+            os.remove( f )
+            
+            
+    def test_writeLineListInFile( self ):
+        inFile = "dummyInFile"
+        lLines = [ "toto\n", "titi\n" ]
+        expFile = "dummyExpFile"
+        expFileHandler = open( expFile, "w" )
+        expFileHandler.write( "toto\n" )
+        expFileHandler.write( "titi\n" )
+        expFileHandler.close()
+        FileUtils.writeLineListInFile( inFile, lLines )
+        self.assertTrue( FileUtils.are2FilesIdentical( expFile, inFile ) )
+        for f in [ inFile, expFile ]:
+            os.remove( f )
+            
+        
+    def test_getAbsoluteDirectoryPathList(self):
+        currentDir = os.getcwd()
+        rootDir = currentDir + "/" + "dummy"
+        if os.path.exists( rootDir ):
+            shutil.rmtree(rootDir)
+        os.mkdir(rootDir)
+        
+        os.mkdir(rootDir + "/" + "dummyDir1")
+        os.mkdir(rootDir + "/" + "dummyDir2")
+        
+        expLDir = [rootDir + "/" + "dummyDir1", rootDir + "/" + "dummyDir2"]
+        obsLDir = FileUtils.getAbsoluteDirectoryPathList(rootDir)
+        
+        expLDir.sort()
+        obsLDir.sort()
+        self.assertEquals(expLDir, obsLDir)
+        
+        shutil.rmtree(rootDir + "/" + "dummyDir1")
+        shutil.rmtree(rootDir + "/" + "dummyDir2")
+        shutil.rmtree(rootDir)
+        
+        
+    def test_getAbsoluteDirectoryPathList_empty_dir(self):
+        currentDir = os.getcwd()
+        rootDir = currentDir + "/" + "dummy"
+        if os.path.exists( rootDir ):
+            shutil.rmtree(rootDir)
+        os.mkdir(rootDir)
+        
+        expLDir = []
+        obsLDir = FileUtils.getAbsoluteDirectoryPathList(rootDir)
+        
+        self.assertEquals(expLDir, obsLDir)
+        
+        shutil.rmtree(rootDir)
+        
+        
+    def test_getSubListAccordingToPattern_match(self):
+        lPath = ["/home/repet/titi", "/pattern/test", "/patter/test", "/_patternic_/test", "/home/patternic/test", "/home/pattern", "pattern", ""]
+        
+        expL = ["/pattern/test", "/_patternic_/test", "/home/patternic/test", "/home/pattern", "pattern"]
+        obsL = FileUtils.getSubListAccordingToPattern(lPath, "pattern")
+        
+        self.assertEquals(expL, obsL)
+        
+        
+    def test_getSubListAccordingToPattern_not_match(self):
+        lPath = ["/home/repet/titi", "/pattern/test", "/patter/test", "/_patternic_/test", "/home/patternic/test", "/home/pattern", "pattern", ""]
+        
+        expL = ["/home/repet/titi", "/patter/test", ""]
+        obsL = FileUtils.getSubListAccordingToPattern(lPath, "pattern", False)
+
+        self.assertEquals(expL, obsL)
+        
+        
+    def test_getFileNamesList(self):
+        currentDir = os.getcwd()
+        rootDir = currentDir + "/" + "dummy"
+        if os.path.exists( rootDir ):
+            shutil.rmtree(rootDir)
+        os.mkdir(rootDir)
+        
+        directory = "testDir"
+        os.mkdir(rootDir + "/" + directory)
+        fileName1 = "dummyFile1.gff"
+        fullFileName1 = rootDir + "/" + directory + "/" + fileName1
+        file1 = open(fullFileName1, "w")
+        file1.close()
+        fileName2 = "dummyFile2.gff"
+        fullFileName2 = rootDir + "/" + directory + "/" + fileName2
+        file2 = open(fullFileName2, "w")
+        file2.close()
+        
+        expLFiles = [fileName1, fileName2]
+        obsLFiles = FileUtils.getFileNamesList(rootDir + "/" + directory)
+        
+        self.assertEquals(expLFiles, sorted(obsLFiles))
+        
+        shutil.rmtree(rootDir)
+        
+    def test_getFileNamesList_withPattern(self):
+        currentDir = os.getcwd()
+        rootDir = currentDir + "/" + "dummy"
+        if os.path.exists( rootDir ):
+            shutil.rmtree(rootDir)
+        os.mkdir(rootDir)
+        
+        directory = "testDir"
+        os.mkdir(rootDir + "/" + directory)
+        fileName1 = "dummyFile1.gff"
+        fullFileName1 = rootDir + "/" + directory + "/" + fileName1
+        file1 = open(fullFileName1, "w")
+        file1.close()
+        fileName2 = "dummyFile2.gff"
+        fullFileName2 = rootDir + "/" + directory + "/" + fileName2
+        file2 = open(fullFileName2, "w")
+        file2.close()
+        
+        expLFiles = [fileName1]
+        obsLFiles = FileUtils.getFileNamesList(rootDir + "/" + directory, "dummyFile1.*")
+        
+        self.assertEquals(expLFiles, obsLFiles)
+        
+        shutil.rmtree(rootDir)
+        
+    def test_getFileNamesList_empty_dir(self):
+        currentDir = os.getcwd()
+        rootDir = currentDir + "/" + "dummy"
+        os.mkdir(rootDir)
+    
+        directory = "testDir"
+        os.mkdir(rootDir + "/" + directory)
+        
+        expLFiles = []
+        obsLFiles = FileUtils.getFileNamesList(rootDir + "/" + directory)
+        
+        self.assertEquals(expLFiles, obsLFiles)
+        
+        shutil.rmtree(rootDir)
+        
+    def test_getMd5SecureHash( self ):
+        if "hashlib" in sys.modules:
+            inFile = "dummyInFile"
+            inFileHandler = open( inFile, "w" )
+            inFileHandler.write( "DLZIH17T63B;?" )
+            inFileHandler.close()
+            exp = "50d1e2ded8f03881f940f70226e2b986"
+            obs = FileUtils.getMd5SecureHash( inFile )
+            self.assertEqual( exp, obs )
+            os.remove( inFile )
+            
+    def test_catFilesOfDir(self):        
+        currentDir = os.getcwd()
+        rootDir = currentDir + "/" + "dummy"
+        if os.path.exists( rootDir ):
+            shutil.rmtree(rootDir)
+        os.mkdir(rootDir)
+        
+        directory = "testDir"
+        os.mkdir(rootDir + "/" + directory)
+        fileName1 = "dummyFile1.gff"
+        fullFileName1 = rootDir + "/" + directory + "/" + fileName1
+        file1 = open(fullFileName1, "w")
+        file1.write("file1\n")
+        file1.close()
+        fileName2 = "dummyFile2.gff"
+        fullFileName2 = rootDir + "/" + directory + "/" + fileName2
+        file2 = open(fullFileName2, "w")
+        file2.write("file2\n")
+        file2.close()
+        obsFile = "obsFile"
+        expFile = "expFile"
+        expF = open(expFile, "w")
+        expF.write("file1\nfile2\n")
+        expF.close()
+        FileUtils.catFilesOfDir(rootDir + "/" + directory, obsFile)
+        self.assertTrue(FileUtils.are2FilesIdentical(expFile, obsFile))
+        
+        shutil.rmtree(rootDir)
+        os.remove(expFile)
+        os.remove(obsFile)
+        
+    def test_isSizeNotNull_True(self):
+        file = "dummyExpFile"
+        fileHandler = open( file, "w" )
+        fileHandler.write( "toto\n" )
+        fileHandler.write( "titi\n" )
+        fileHandler.close()
+        obsSize = FileUtils.isSizeNotNull(file)
+        self.assertTrue(obsSize)
+        os.remove(file)
+        
+    def test_isSizeNotNull_False(self):
+        file = "dummyExpFile"
+        fileHandler = open( file, "w" )
+        fileHandler.close()
+        obsSize = FileUtils.isSizeNotNull(file)
+        self.assertFalse(obsSize)
+        os.remove(file)
+            
+    def test_splitFileIntoNFiles_3_files(self):
+        inputFile = "dummy.txt"
+        obsFile1 = "dummy-1.txt"
+        obsFile2 = "dummy-2.txt"
+        obsFile3 = "dummy-3.txt"
+        
+        f = open(inputFile, "w")
+        f.write("line1\n")
+        f.write("line2\n")
+        f.write("line3\n")
+        f.close()
+
+        exp1 = "line1\n"
+        exp2 = "line2\n"
+        exp3 = "line3\n"
+        
+        FileUtils.splitFileIntoNFiles(inputFile, 3)
+        
+        obs1 = open(obsFile1).read()
+        obs2 = open(obsFile2).read()
+        obs3 = open(obsFile3).read()
+        
+        self.assertEqual(exp1, obs1)
+        self.assertEqual(exp2, obs2)
+        self.assertEqual(exp3, obs3)
+        self.assertFalse(FileUtils.isRessourceExists("dummy-4.txt"))
+        FileUtils.removeFilesByPattern("dummy*")
+            
+    def test_splitFileIntoNFiles_2_files(self):
+        inputFile = "dummy.txt"
+        obsFile1 = "dummy-1.txt"
+        obsFile2 = "dummy-2.txt"
+        
+        f = open(inputFile, "w")
+        f.write("line1\n")
+        f.write("line2\n")
+        f.write("line3\n")
+        f.close()
+
+        exp1 = "line1\nline2\n"
+        exp2 = "line3\n"
+        
+        FileUtils.splitFileIntoNFiles(inputFile, 2)
+        
+        obs1 = open(obsFile1).read()
+        obs2 = open(obsFile2).read()
+        
+        self.assertEqual(exp1, obs1)
+        self.assertEqual(exp2, obs2)
+        self.assertFalse(FileUtils.isRessourceExists("dummy-3.txt"))
+        FileUtils.removeFilesByPattern("dummy*")
+            
+    def test_splitFileIntoNFiles_one_file(self):
+        inputFile = "dummy.txt"
+        obsFile1 = "dummy-1.txt"
+        
+        f = open(inputFile, "w")
+        f.write("line1\n")
+        f.write("line2\n")
+        f.write("line3\n")
+        f.close()
+
+        exp1 = "line1\nline2\nline3\n"
+        
+        FileUtils.splitFileIntoNFiles(inputFile, 1)
+        
+        obs1 = open(obsFile1).read()
+        
+        self.assertEqual(exp1, obs1)
+        self.assertFalse(FileUtils.isRessourceExists("dummy-2.txt"))
+        FileUtils.removeFilesByPattern("dummy*")
+            
+    def test_splitFileIntoNFiles_more_file_than_lines(self):
+        inputFile = "dummy.txt"
+        obsFile1 = "dummy-1.txt"
+        obsFile2 = "dummy-2.txt"
+        obsFile3 = "dummy-3.txt"
+        
+        f = open(inputFile, "w")
+        f.write("line1\n")
+        f.write("line2\n")
+        f.write("line3\n")
+        f.close()
+
+        exp1 = "line1\n"
+        exp2 = "line2\n"
+        exp3 = "line3\n"
+        
+        FileUtils.splitFileIntoNFiles(inputFile, 10)
+        
+        obs1 = open(obsFile1).read()
+        obs2 = open(obsFile2).read()
+        obs3 = open(obsFile3).read()
+        
+        self.assertEqual(exp1, obs1)
+        self.assertEqual(exp2, obs2)
+        self.assertEqual(exp3, obs3)
+        self.assertFalse(FileUtils.isRessourceExists("dummy-4.txt"))
+        FileUtils.removeFilesByPattern("dummy*")
+        
+    def test_splitFileIntoNFiles_empty_file(self):
+        inputFile = "dummy.txt"
+        obsFile1 = "dummy-1.txt"
+
+        os.system( "touch %s" % ( inputFile ) )
+
+        exp1 = ""
+        
+        FileUtils.splitFileIntoNFiles(inputFile, 10)
+        
+        obs1 = open(obsFile1).read()
+        
+        self.assertEqual(exp1, obs1)
+        self.assertFalse(FileUtils.isRessourceExists("dummy-2.txt"))
+        FileUtils.removeFilesByPattern("dummy*")
+        
+    def test_splitFileIntoNFiles_0_file(self):
+        inputFile = "dummy.txt"
+        obsFile1 = "dummy-1.txt"
+        
+        f = open(inputFile, "w")
+        f.write("line1\n")
+        f.write("line2\n")
+        f.write("line3\n")
+        f.close()
+        
+        exp1 = "line1\nline2\nline3\n"
+        
+        FileUtils.splitFileIntoNFiles(inputFile, 0)
+        
+        obs1 = open(obsFile1).read()
+        
+        self.assertEqual(exp1, obs1)
+        self.assertFalse(FileUtils.isRessourceExists("dummy-2.txt"))
+        FileUtils.removeFilesByPattern("dummy*")
+        
+    def test_splitFileAccordingToLineNumber_3_files(self):
+        inputFile = "dummy.txt"
+        obsFile1 = "dummy-1.txt"
+        obsFile2 = "dummy-2.txt"
+        obsFile3 = "dummy-3.txt"
+        
+        f = open(inputFile, "w")
+        f.write("line1\n")
+        f.write("line2\n")
+        f.write("line3\n")
+        f.close()
+
+        exp1 = "line1\n"
+        exp2 = "line2\n"
+        exp3 = "line3\n"
+        
+        FileUtils.splitFileAccordingToLineNumber(inputFile, 1)
+        
+        obs1 = open(obsFile1).read()
+        obs2 = open(obsFile2).read()
+        obs3 = open(obsFile3).read()
+        
+        self.assertEqual(exp1, obs1)
+        self.assertEqual(exp2, obs2)
+        self.assertEqual(exp3, obs3)
+        self.assertFalse(FileUtils.isRessourceExists("dummy-4.txt"))
+        FileUtils.removeFilesByPattern("dummy*")
+            
+    def test_splitFileAccordingToLineNumber_2_files(self):
+        inputFile = "dummy.txt"
+        obsFile1 = "dummy-1.txt"
+        obsFile2 = "dummy-2.txt"
+        
+        f = open(inputFile, "w")
+        f.write("line1\n")
+        f.write("line2\n")
+        f.write("line3\n")
+        f.close()
+
+        exp1 = "line1\nline2\n"
+        exp2 = "line3\n"
+        
+        FileUtils.splitFileAccordingToLineNumber(inputFile, 2)
+        
+        obs1 = open(obsFile1).read()
+        obs2 = open(obsFile2).read()
+        
+        self.assertEqual(exp1, obs1)
+        self.assertEqual(exp2, obs2)
+        self.assertFalse(FileUtils.isRessourceExists("dummy-3.txt"))
+        FileUtils.removeFilesByPattern("dummy*")
+            
+    def test_splitFileAccordingToLineNumber_one_file(self):
+        inputFile = "dummy.txt"
+        obsFile1 = "dummy-1.txt"
+        
+        f = open(inputFile, "w")
+        f.write("line1\n")
+        f.write("line2\n")
+        f.write("line3\n")
+        f.close()
+
+        exp1 = "line1\nline2\nline3\n"
+        
+        FileUtils.splitFileAccordingToLineNumber(inputFile, 3)
+        
+        obs1 = open(obsFile1).read()
+        
+        self.assertEqual(exp1, obs1)
+        self.assertFalse(FileUtils.isRessourceExists("dummy-2.txt"))
+        FileUtils.removeFilesByPattern("dummy*")
+            
+    def test_splitFileAccordingToLineNumber_more_maxLines_than_lines(self):
+        inputFile = "dummy.txt"
+        obsFile1 = "dummy-1.txt"
+        
+        f = open(inputFile, "w")
+        f.write("line1\n")
+        f.write("line2\n")
+        f.write("line3\n")
+        f.close()
+
+        exp1 = "line1\nline2\nline3\n"
+        
+        FileUtils.splitFileAccordingToLineNumber(inputFile, 10)
+        
+        obs1 = open(obsFile1).read()
+
+        self.assertEqual(exp1, obs1)
+        self.assertFalse(FileUtils.isRessourceExists("dummy-2.txt"))
+        FileUtils.removeFilesByPattern("dummy*")
+            
+    def test_splitFileAccordingToLineNumber_empty_file(self):
+        inputFile = "dummy.txt"
+        obsFile1 = "dummy-1.txt"
+
+        os.system( "touch %s" % ( inputFile ) )
+
+        exp1 = ""
+        
+        FileUtils.splitFileAccordingToLineNumber(inputFile, 10)
+        
+        obs1 = open(obsFile1).read()
+        
+        self.assertEqual(exp1, obs1)
+        self.assertFalse(FileUtils.isRessourceExists("dummy-2.txt"))
+        FileUtils.removeFilesByPattern("dummy*")
+            
+    def test_splitFileAccordingToLineNumber_0_lines(self):
+        inputFile = "dummy.txt"
+        obsFile1 = "dummy-1.txt"
+        
+        f = open(inputFile, "w")
+        f.write("line1\n")
+        f.write("line2\n")
+        f.write("line3\n")
+        f.close()
+
+        exp1 = "line1\nline2\nline3\n"
+        
+        FileUtils.splitFileAccordingToLineNumber(inputFile, 0)
+        
+        obs1 = open(obsFile1).read()
+        
+        self.assertEqual(exp1, obs1)
+        self.assertFalse(FileUtils.isRessourceExists("dummy-2.txt"))
+        FileUtils.removeFilesByPattern("dummy*")
+    
+    def _writeFile( self, fileName ):
+        inFile = open(fileName, 'w')
+        inFile.write(">Sequence_de_reference\n")
+        inFile.write("ATTTTGCAGTCTTATTCGAG-----GCCATTGCT\n")
+        inFile.write(">Lignee1_mismatch\n")
+        inFile.write("ATTTTGCAGACTTATTCGAG-----GCCATTGCT\n")
+        inFile.write(">Lignee2_insertion\n")
+        inFile.write("ATTTTGCAGTCTTATTCGAGATTACGCCATTGCT\n")
+        inFile.write(">Lignee3_deletion\n")
+        inFile.write("A---TGCAGTCTTATTCGAG-----GCCATTGCT\n")
+        inFile.close()      
+        
+    def _writeFileWithEmptyLine( self, fileName ):
+        fileWithEmptyLine = open(fileName, 'w')
+        fileWithEmptyLine.write(">Sequence_de_reference\n")
+        fileWithEmptyLine.write("ATTTTGCAGTCTTATTCGAG-----GCCATTGCT\n")
+        fileWithEmptyLine.write("\n\n")
+        fileWithEmptyLine.write(">Lignee1_mismatch\n")
+        fileWithEmptyLine.write("ATTTTGCAGACTTATTCGAG-----GCCATTGCT\n")
+        fileWithEmptyLine.write("\n\n")
+        fileWithEmptyLine.write(">Lignee2_insertion\n")
+        fileWithEmptyLine.write("ATTTTGCAGTCTTATTCGAGATTACGCCATTGCT\n")
+        fileWithEmptyLine.write("\n")
+        fileWithEmptyLine.write(">Lignee3_deletion\n")
+        fileWithEmptyLine.write("A---TGCAGTCTTATTCGAG-----GCCATTGCT\n")
+        fileWithEmptyLine.close() 
+        
+    def _writeFileWithRepeatedBlanks( self, fileName ):
+        fileWithRepeatedBlanks = open(fileName, 'w')
+        fileWithRepeatedBlanks.write(">Sequ  ence_de     _reference\n")
+        fileWithRepeatedBlanks.write("ATTTT  GCAGTCTT TTCGAG-  ----GCCATT  GCT\n")
+        fileWithRepeatedBlanks.close() 
+        
+    def _writeFileWithoutRepeatedBlanks( self, fileName ):
+        fileWithoutRepeatedBlanks = open(fileName, 'w')
+        fileWithoutRepeatedBlanks.write(">Sequ ence_de _reference\n")
+        fileWithoutRepeatedBlanks.write("ATTTT GCAGTCTT TTCGAG- ----GCCATT GCT\n")
+        fileWithoutRepeatedBlanks.close()
+        
+test_suite = unittest.TestSuite()
+test_suite.addTest( unittest.makeSuite( Test_FileUtils ) )
+if __name__ == "__main__":
+    unittest.TextTestRunner(verbosity=2).run( test_suite )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/BedWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,100 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from commons.core.writer.TranscriptListWriter import TranscriptListWriter
+
+
+class BedWriter(TranscriptListWriter):
+    """
+    A class that writes a transcript list into a file with BED format
+    @ivar fileName: name of the file 
+    @type fileName: string
+    @ivar handle:     handle to the file
+    @type handle:     file handle
+    @ivar header:     first lines of the file
+    @type header:     string
+    """
+
+
+    def __init__(self, fileName, verbosity = 0):
+        """
+        Constructor
+        @param fileName:    name of the file 
+        @type    fileName:    string
+        @param verbosity: verbosity
+        @type    verbosity: int
+        """
+        self.header = "track name=reads description=\"Reads\" useScore=0 visibility=full offset=0\n"
+        super(BedWriter, self).__init__(fileName, verbosity)
+
+
+    @staticmethod
+    def getFileFormats():
+        """
+        Get the format of the file
+        """
+        return ["bed"]
+
+
+    @staticmethod
+    def getExtension():
+        """
+        Get the usual extension for the file
+        """
+        return "bed"
+        
+        
+    def setTitle(self, title):
+        """
+        Set the title of the track
+        @param title: the title of the track
+        @type    title: string
+        """
+        if title != None:
+            self.header = "track name=%s description=\"%s\" useScore=0 visibility=full offset=0\n" % (title, title)
+
+
+    def copyProperties(self, bedParser):
+        """
+        Copy the properties collected by a parser, to produce a similar output
+        @param bedParser: a BED Parser parser
+        @type    bedParser: class L{BedParser<BedParser>}
+        """
+        self.setTitle(bedParser.title)
+        
+
+    def printTranscript(self, transcript):
+        """
+        Export the given transcript with GBrowse format
+        @param transcript: transcript to be printed
+        @type    transcript: class L{Transcript<Transcript>}
+        @return:                     a string
+        """
+        return transcript.printBed()
+
Binary file smart_toolShed/commons/core/writer/BedWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/CsvWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,153 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os
+import random
+from commons.core.writer.TranscriptListWriter import TranscriptListWriter
+from SMART.Java.Python.misc.Progress import Progress
+
+class CsvWriter(TranscriptListWriter):
+    """
+    A class that writes a transcript list into a file with CSV (Excel) format
+    @ivar fileName: name of the file 
+    @type fileName: string
+    @ivar handle: handle to the file
+    @type handle: file handle
+    """
+
+
+    def __init__(self, fileName, verbosity = 0):
+        """
+        Constructor
+        @param fileName: name of the file 
+        @type fileName: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        super(CsvWriter, self).__init__(fileName, verbosity)
+        self.header   = ""
+        self.title    = "chromosome,start,end,strand,exons,tags\n"
+        self.modified = False
+            
+
+    def __del__(self):
+        """
+        Destructor
+        (Trick to write 1 tag per column)
+        """
+        if self.handle != None:
+            self.modifyCsv()
+        super(CsvWriter, self).__del__()
+
+
+    def close(self):
+        if self.handle != None:
+            self.modifyCsv()
+        super(CsvWriter, self).close()
+
+
+    def modifyCsv(self):
+        """
+        Clean CSV file so that there is one column per tag
+        """
+        if self.modified:
+            return
+
+        # read all the tags
+        self.handle.close()
+        self.handle = open(self.fileName)
+        nbFirstFields = 5
+        tags = set()
+        if self.verbosity >= 10:
+            print "Modifying CSV file..."
+        number = -1
+        for number, line in enumerate(self.handle):
+            if number != 0:
+                theseTags = line.strip().split(",")[nbFirstFields:]
+                for tag in theseTags:
+                    if tag.find("=") != -1:
+                        (key, value) = tag.split("=", 1)
+                        if value != None:
+                            tags.add(key)
+        if self.verbosity >= 10:
+            print " ...done"
+
+        # re-write the file
+        tmpFileName = "tmpFile%d.csv" % (random.randint(0, 100000))
+        tmpFile = open(tmpFileName, "w")
+        self.handle.seek(0)
+        progress = Progress(number + 1, "Re-writting CSV file", self.verbosity)
+        tmpFile.write(self.title.replace("tags", ",".join(sorted(tags))))
+        for line in self.handle:
+            tagValues = dict([(key, None) for key in tags])
+            tmpFile.write(",".join(line.strip().split(",")[:nbFirstFields]))
+            for tag in line.strip().split(",")[nbFirstFields:]:
+                if tag.find("=") != -1:
+                    key = tag.split("=", 1)[0]
+                    tagValues[key] = tag.split("=", 1)[1]
+                else:
+                    tagValues[key] += ";%s" % (tag)
+            for key in sorted(tagValues.keys()):
+                tmpFile.write(",%s" % (tagValues[key]))
+            tmpFile.write("\n")
+            progress.inc()
+        tmpFile.close()
+
+        # replace former file
+        import shutil
+        shutil.move(tmpFile.name, self.fileName)
+        progress.done()
+        self.modified = True
+
+
+    @staticmethod
+    def getFileFormats():
+        """
+        Get the format of the file
+        """
+        return ["csv", "xls", "excel"]
+
+
+    @staticmethod
+    def getExtension():
+        """
+        Get the usual extension for the file
+        """
+        return "csv"
+        
+        
+    def printTranscript(self, transcript):
+        """
+        Export the given transcript with GFF2 format
+        @param transcript: transcript to be printed
+        @type transcript: class L{Transcript<Transcript>}
+        @return: a string
+        """
+        return transcript.printCsv()
+
Binary file smart_toolShed/commons/core/writer/CsvWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/EmblWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,116 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from commons.core.writer.TranscriptListWriter import TranscriptListWriter
+
+
+class EmblWriter(TranscriptListWriter):
+    """
+    A class that writes a transcript list into several files with EMBL format
+    @ivar fileName: name of the file 
+    @type fileName: string
+    @ivar handle: handle to the file
+    @type handle: file handle
+    """
+
+
+    def __init__(self, fileName, verbosity = 0):
+        """
+        Constructor
+        @param fileName: name of the file 
+        @type fileName: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        self.fileName = fileName
+        self.verbosity = verbosity
+        self.handles = {}
+        self.handle = None
+
+
+    def __del__(self):
+        """
+        Destructor
+        Trick to append the sequences at the end of the EMBL files
+        """
+        handle                = open(self.sequenceFileName)
+        currentHandle = None
+        for line in handle:
+            if line[0] == ">":
+                chromosome = line[1:].strip()
+                if chromosome in self.handles:
+                    currentHandle = self.handles[chromosome]
+                else:
+                    currentHandle = None
+            else:
+                if currentHandle != None:
+                    currentHandle.write(line)
+        handle.close()
+        for handle in self.handles.values():
+            handle.close()
+            
+
+    @staticmethod
+    def getFileFormats():
+        """
+        Get the format of the file
+        """
+        return ["embl"]
+        
+        
+    @staticmethod
+    def getExtension():
+        """
+        Get the usual extension for the file
+        """
+        return "embl"
+
+
+    def addTranscript(self, transcript):
+        """
+        Add a transcript to the list of transcripts to be written
+        @param transcript: transcript to be written
+        @type    transcript: class L{Transcript<Transcript>}
+        """
+        chromosome = transcript.getChromosome()
+        if chromosome not in self.handles:
+            self.handles[chromosome] = open("%s%s.embl" % (self.fileName[:-len(".embl")], chromosome.title()), "w")
+        self.handles[chromosome].write(self.printTranscript(transcript))
+
+
+    def printTranscript(self, transcript):
+        """
+        Export the given transcript with GFF2 format
+        @param transcript: transcript to be printed
+        @type transcript: class L{Transcript<Transcript>}
+        @return: a string
+        """
+        return transcript.printEmbl()
+
+
Binary file smart_toolShed/commons/core/writer/EmblWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/FastaWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,77 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from commons.core.writer.SequenceListWriter import SequenceListWriter
+
+
+class FastaWriter(SequenceListWriter):
+    """
+    A class that writes a sequence list into a file with FASTA format
+    @ivar fileName: name of the file 
+    @type fileName: string
+    @ivar handle: handle to the file
+    @type handle: file handle
+    @ivar header: first lines of the file
+    @type header: string
+    """
+
+
+    def __init__(self, fileName, verbosity = 0):
+        """
+        Constructor
+        @param fileName: name of the file 
+        @type fileName: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        super(FastaWriter, self).__init__(fileName, verbosity)
+
+    @staticmethod
+    def getFileFormats():
+        """
+        Get the format of the file
+        """
+        return ["fasta", "mfa"]
+
+
+    @staticmethod
+    def getExtension():
+        """
+        Get the usual extension for the file
+        """
+        return "fasta"
+        
+        
+    def getLine(self, sequence):
+        """
+        Convert a sequence
+        @param sequence: sequence to be written
+        @type    sequence: class L{Sequence<Sequence>}
+        """
+        return sequence.printFasta()
Binary file smart_toolShed/commons/core/writer/FastaWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/FastqWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,78 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from commons.core.writer.SequenceListWriter import SequenceListWriter
+
+
+class FastqWriter(SequenceListWriter):
+    """
+    A class that writes a sequence list into a file with FASTQ format
+    @ivar fileName: name of the file 
+    @type fileName: string
+    @ivar handle: handle to the file
+    @type handle: file handle
+    @ivar header: first lines of the file
+    @type header: string
+    """
+
+
+    def __init__(self, fileName, verbosity = 0):
+        """
+        Constructor
+        @param fileName: name of the file 
+        @type fileName: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        super(FastqWriter, self).__init__(fileName, verbosity)
+        
+
+    @staticmethod
+    def getFileFormats():
+        """
+        Get the format of the file
+        """
+        return ["fastq", "mfq"]
+        
+        
+    @staticmethod
+    def getExtension():
+        """
+        Get the usual extension for the file
+        """
+        return "fastq"
+        
+        
+    def getLine(self, sequence):
+        """
+        Convert a sequence
+        @param sequence: sequence to be written
+        @type    sequence: class L{Sequence<Sequence>}
+        """
+        return sequence.printFastq()
Binary file smart_toolShed/commons/core/writer/FastqWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/GbWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,102 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from commons.core.writer.TranscriptListWriter import TranscriptListWriter
+
+
+class GbWriter(TranscriptListWriter):
+    """
+    A class that writes a transcript list into a file with GBrowse format
+    @ivar fileName: name of the file 
+    @type fileName: string
+    @ivar handle: handle to the file
+    @type handle: file handle
+    @ivar header: first lines of the file
+    @type header: string
+    """
+
+
+    def __init__(self, fileName, verbosity = 0):
+        """
+        Constructor
+        @param fileName: name of the file 
+        @type fileName: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        self.header = "[READS]\nbgcolor = red\nstrand_arrow = 1\n\n"
+        super(GbWriter, self).__init__(fileName, verbosity)
+     
+        
+    @staticmethod
+    def getFileFormats():
+        """
+        Get the format of the file
+        """
+        return ["gb", "gbrowse"]
+        
+        
+    @staticmethod
+    def getExtension():
+        """
+        Get the usual extension for the file
+        """
+        return "gb"
+        
+        
+    def setColor(self, color):
+        """
+        Set the color of the track
+        @param color: the color of the track
+        @type    color: string
+        """
+        if color != None:
+            self.header = "[READS]\nbgcolor= %s\nstrand_arrow = 1\n\n" % (color)
+        
+        
+    def copyProperties(self, gbParser):
+        """
+        Copy the properties collected by a parser, to produce a similar output
+        @param gbParser: a GBrowse parser
+        @type    gbParser: class L{GbParser<GbParser>}
+        """
+        self.setColor(gbParser.color)
+        
+
+    def printTranscript(self, transcript):
+        """
+        Export the given transcript with GBrowse format
+        Possibly skip the reference if already put
+        @param transcript: transcript to be printed
+        @type transcript: class L{Transcript<Transcript>}
+        @return: a string
+        """
+        if self.lastChromosome != None and self.lastChromosome == transcript.getChromosome():
+            return transcript.printGBrowseLine()
+        return transcript.printGBrowse()
Binary file smart_toolShed/commons/core/writer/GbWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/Gff2Writer.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,89 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from commons.core.writer.TranscriptListWriter import TranscriptListWriter
+
+
+class Gff2Writer(TranscriptListWriter):
+    """
+    A class that writes a transcript list into a file with GFF2 format
+    @ivar fileName: name of the file 
+    @type fileName: string
+    @ivar handle: handle to the file
+    @type handle: file handle
+    """
+
+
+    def __init__(self, fileName, verbosity = 0):
+        """
+        Constructor
+        @param fileName: name of the file 
+        @type fileName: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        self.header = ""
+        self.title = ""
+        super(Gff2Writer, self).__init__(fileName, verbosity)
+            
+
+    @staticmethod
+    def getFileFormats():
+        """
+        Get the format of the file
+        """
+        return ["gff2"]
+        
+        
+    @staticmethod
+    def getExtension():
+        """
+        Get the usual extension for the file
+        """
+        return "gff2"
+        
+        
+    def setTitle(self, title):
+        """
+        Set the title of the transcripts
+        @param title: the title of the transcripts
+        @type    title: string
+        """
+        self.title = title
+
+
+    def printTranscript(self, transcript):
+        """
+        Export the given transcript with GFF2 format
+        @param transcript: transcript to be printed
+        @type transcript: class L{Transcript<Transcript>}
+        @return: a string
+        """
+        return transcript.printGff2(self.title)
+
Binary file smart_toolShed/commons/core/writer/Gff2Writer.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/Gff3Writer.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,130 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from commons.core.writer.TranscriptListWriter import TranscriptListWriter
+
+
+class Gff3Writer(TranscriptListWriter):
+    """
+    A class that writes a transcript list into a file with GFF3 format
+    @ivar fileName: name of the file 
+    @type fileName: string
+    @ivar handle: handle to the file
+    @type handle: file handle
+    """
+
+
+    def __init__(self, fileName, verbosity = 0, title="S-MART", feature="transcript", featurePart="exon"):
+        """
+        Constructor
+        @param fileName: name of the file 
+        @type fileName: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        self.header = ""
+        self.title    = title
+        self.feature = feature
+        self.featurePart = featurePart
+        super(Gff3Writer, self).__init__(fileName, verbosity)
+            
+
+    @staticmethod
+    def getFileFormats():
+        """
+        Get the format of the file
+        """
+        return ["gff3", "gff"]
+        
+        
+    @staticmethod
+    def getExtension():
+        """
+        Get the usual extension for the file
+        """
+        return "gff3"
+        
+        
+    def setTitle(self, title):
+        """
+        Set the title of the transcripts
+        @param title: the title of the transcripts
+        @type    title: string
+        """
+        self.title = title
+        
+    def setFeature(self, feature):
+        """
+        Set the name of the feature
+        @param title: the title of the feature
+        @type    feature: string
+        """
+        self.feature = feature
+        
+    def setFeaturePart(self, featurePart):
+        """
+        Set the name of the feature part
+        @param title: the title of the feature part
+        @type    featurePart: string
+        """
+        self.featurePart = featurePart
+
+
+    def printTranscript(self, transcript):
+        """
+        Export the given transcript with GFF2 format
+        @param transcript: transcript to be printed
+        @type transcript: class L{Transcript<Transcript>}
+        @return: a string
+        """
+        direction = "+"
+        if transcript.getDirection() == -1:
+            direction = "-"
+        transcript.sortExonsIncreasing()
+        if "ID" not in transcript.getTagValues():
+            transcript.setTagValue("ID", transcript.getUniqueName())
+        feature = self.feature
+        tags = transcript.tags
+        if "feature" in transcript.getTagNames():
+            feature = transcript.getTagValue("feature")
+            del transcript.tags["feature"]
+        score = "."
+        if "score" in transcript.getTagNames():
+            score = "%d" % (int(transcript.getTagValue("score")))
+            del transcript.tags["score"]
+        comment = transcript.getTagValues(";", "=")
+        string = "%s\t%s\t%s\t%d\t%d\t%s\t%s\t.\t%s\n" % (transcript.getChromosome(), self.title, feature, transcript.getStart(), transcript.getEnd(), score, direction, comment)
+        if len(transcript.exons) > 1:
+            for i, exon in enumerate(transcript.getExons()):
+                if "score" in exon.getTagNames():
+                    score = "%d" % (int(exon.getTagValue("score")))
+                string += "%s\t%s\t%s\t%d\t%d\t%s\t%s\t.\tID=%s-%s%d;Name=%s-%s%d;Parent=%s\n" % (transcript.getChromosome(), self.title,self.featurePart, exon.getStart(), exon.getEnd(), score, direction, transcript.getTagValue("ID"),self.featurePart, i+1, transcript.name,self.featurePart, i+1, transcript.getTagValue("ID"))
+        self.tags = tags
+        return string
+
Binary file smart_toolShed/commons/core/writer/Gff3Writer.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/GtfWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,89 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from commons.core.writer.TranscriptListWriter import TranscriptListWriter
+
+
+class GtfWriter(TranscriptListWriter):
+    """
+    A class that writes a transcript list into a file with GTF format
+    @ivar fileName: name of the file 
+    @type fileName: string
+    @ivar handle: handle to the file
+    @type handle: file handle
+    """
+
+
+    def __init__(self, fileName, verbosity = 0):
+        """
+        Constructor
+        @param fileName: name of the file 
+        @type fileName: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        self.header = ""
+        self.title    = "S-MART"
+        super(GtfWriter, self).__init__(fileName, verbosity)
+            
+
+    @staticmethod
+    def getFileFormats():
+        """
+        Get the format of the file
+        """
+        return ["gtf", "gtf2"]
+        
+        
+    @staticmethod
+    def getExtension():
+        """
+        Get the usual extension for the file
+        """
+        return "gtf"
+        
+        
+    def setTitle(self, title):
+        """
+        Set the title of the transcripts
+        @param title: the title of the transcripts
+        @type    title: string
+        """
+        self.title = title
+
+
+    def printTranscript(self, transcript):
+        """
+        Export the given transcript with GTF format
+        @param transcript: transcript to be printed
+        @type transcript: class L{Transcript<Transcript>}
+        @return: a string
+        """
+        return transcript.printGtf(self.title)
+
Binary file smart_toolShed/commons/core/writer/GtfWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/MapWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,100 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from commons.core.writer.TranscriptListWriter import TranscriptListWriter
+
+
+class MapWriter(TranscriptListWriter):
+    """
+    A class that writes a transcript list into a file with GFF3 format
+    @ivar fileName: name of the file 
+    @type fileName: string
+    @ivar handle: handle to the file
+    @type handle: file handle
+    """
+
+
+    def __init__(self, fileName, verbosity = 0, title="S-MART"):
+        """
+        Constructor
+        @param fileName: name of the file 
+        @type fileName: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        self.header = ""
+        self.title    = title
+        TranscriptListWriter.__init__(self, fileName, verbosity)
+            
+
+    @staticmethod
+    def getFileFormats():
+        """
+        Get the format of the file
+        """
+        return ["map"]
+        
+        
+    @staticmethod
+    def getExtension():
+        """
+        Get the usual extension for the file
+        """
+        return "map"
+        
+        
+    def setTitle(self, title):
+        """
+        Set the title of the transcripts
+        @param title: the title of the transcripts
+        @type    title: string
+        """
+        self.title = title
+
+
+    def printTranscript(self, transcript):
+        """
+        Export the given transcript to map format
+        @param transcript: transcript to be printed
+        @type transcript: class L{Transcript<Transcript>}
+        @return: a string
+        """
+        name = transcript.name
+        if "nbOccurrences" in transcript.getTagNames() and transcript.getTagValue("nbOccurrences") != 1 and transcript.getTagValue("occurrences"):
+            name = "%s-%d" % (name, transcript.getTagValue("occurrence"))
+        sizes   = []
+        starts  = []
+        transcript.sortExonsIncreasing()
+        for exon in transcript.getExons():
+            sizes.append("%d" % (exon.getSize()))
+            starts.append("%d" % (exon.getStart() - transcript.getStart()))
+        return "%s\t%s\t%d\t%d\n" % (name, transcript.getChromosome(), transcript.getStart(), transcript.getEnd()+1)
+
+
+
Binary file smart_toolShed/commons/core/writer/MapWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/MySqlTranscriptWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,214 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os
+import random
+from SMART.Java.Python.mySql.MySqlTable import MySqlTable
+from SMART.Java.Python.mySql.MySqlTranscriptTable import MySqlTranscriptTable
+from SMART.Java.Python.misc.Progress import Progress
+
+class MySqlTranscriptWriter(object):
+    """
+    A class that writes a transcript list into a mySQL table
+    @ivar name:                      name of the tables 
+    @type name:                      string
+    @ivar tables:                    the tables
+    @type tables:                    dict of L{MySqlTranscriptTable<MySqlTranscriptTable>}
+    @ivar mySqlConnection:           connection to a MySQL database
+    @type mySqlConnection:           class L{MySqlConnection<MySqlConnection>}
+    @ivar tmpTranscriptFileHandles:  files where transcripts are temporary stored, before copy into database
+    @type tmpTranscriptFileHandles:  dict of file handles
+    @ivar nbTranscriptsByChromosome: number of transcripts written
+    @type nbTranscriptsByChromosome: dict of int (one for each chromosome)
+    @ivar randomNumber:              a random number, used for having a unique name for the tables
+    @type randomNumber:              int
+    @ivar toBeWritten:               there exists transcripts to be copied into database
+    @type toBeWritten:               bool                
+    @ivar verbosity:                 verbosity
+    @type verbosity:                 int        
+    """
+
+
+    def __init__(self, connection, name = None, verbosity = 0):
+        """
+        Constructor
+        @param name:      name of the file 
+        @type  name:      string
+        @param verbosity: verbosity
+        @type  verbosity: int
+        """
+        self.name                      = name
+        self.verbosity                 = verbosity
+        self.tables                    = {}
+        self.indices                   = {}
+        self.tmpTranscriptFileHandles  = {}
+        self.nbTranscriptsByChromosome = {}
+        self.toBeWritten               = False
+        self.randomNumber              = random.randint(0, 100000)
+        self.mySqlConnection           = connection
+        self.nbTmpFiles                = 100
+        self.transcriptValues          = {}
+        self.nbTranscriptValues        = 1000
+        if self.name != None:
+            pos = self.name.rfind(os.sep)
+            if pos != -1:
+                self.name = self.name[pos+1:]
+            
+
+    def __del__(self):
+        """
+        Destructor
+        Possibly write into into database the last transcripts
+        """
+        if self.toBeWritten:
+            self.write()
+
+
+    def addIndex(self, name, values):
+        """
+        Add an index to the tables
+        @param name:   name of the index
+        @type  name:   string
+        @param values: values to index
+        @type  values: list of strings
+        """
+        self.indices[name] = values
+
+
+    def createTable(self, chromosome):
+        """
+        Create a table for a chromosome
+        @param chromosome: a chromosome name
+        @type  chromosome: string
+        """
+        self.tables[chromosome] = MySqlTranscriptTable(self.mySqlConnection, self.name, chromosome, self.verbosity)
+        self.tables[chromosome].createTranscriptTable()
+        for name, values in self.indices.iteritems():
+            self.tables[chromosome].createIndex("%s_%s_%d" % (name, chromosome, self.randomNumber), values)
+
+        
+    
+    def addTranscript(self, transcript):
+        """
+        Add a transcript to the list of transcripts to be written
+        @param transcript: transcript to be written
+        @type  transcript: class L{Transcript<Transcript>}
+        """
+        chromosome = transcript.getChromosome()
+        if chromosome not in self.tables:
+            self.createTable(chromosome)
+            self.nbTranscriptsByChromosome[chromosome] = 1
+        if chromosome not in self.transcriptValues:
+            self.transcriptValues[chromosome] = []
+            
+        self.transcriptValues[chromosome].append(transcript.getSqlValues())
+
+        self.nbTranscriptsByChromosome[chromosome] += 1
+        self.toBeWritten                            = True
+        if sum([len(transcripts) for transcripts in self.transcriptValues.values()]) > self.nbTranscriptValues:
+            self.write() 
+
+
+    def addElement(self, element):
+        """
+        Same as "addTranscript"
+        @param element: transcript to be written
+        @type  element: class L{Transcript<Transcript>}
+        """
+        self.addTranscript(element)
+
+
+#   def addTranscriptList(self, transcriptListParser):
+#       """
+#       Add a list of transcripts to the transcripts to be written
+#       @param transcriptListParser: transcripts to be written
+#       @type  transcriptListParser: class L{TranscriptListParser<TranscriptListParser>}
+#       """
+#       progress = Progress(transcriptListParser.getNbTranscripts(), "Storing %s into database" % (transcriptListParser.fileName), self.verbosity)
+#       for transcript in transcriptListParser.getIterator():
+#           self.addTranscript(transcript)
+#           progress.inc()
+#       progress.done()
+            
+            
+    def addTranscriptList(self, transcriptListParser):
+        """
+        Add a list of transcripts to the transcripts to be written
+        @param transcriptListParser: transcripts to be written
+        @type  transcriptListParser: class L{TranscriptListParser<TranscriptListParser>}
+        """
+        self.transcriptListParser = transcriptListParser
+        self.mySqlConnection.executeManyQueriesIterator(self)
+            
+            
+    def getIterator(self):
+        """
+        Iterator to the SQL commands to insert the list
+        """
+        progress = Progress(self.transcriptListParser.getNbTranscripts(), "Storing %s into database" % (self.transcriptListParser.fileName), self.verbosity)
+        for transcript in self.transcriptListParser.getIterator():
+            chromosome = transcript.getChromosome()
+            if chromosome not in self.tables:
+                self.createTable(chromosome)
+            self.nbTranscriptsByChromosome[chromosome] = self.nbTranscriptsByChromosome.get(chromosome, 0) + 1
+            values = transcript.getSqlValues()
+            yield "INSERT INTO '%s' (%s) VALUES (%s)" % (self.tables[chromosome].name, ", ".join(self.tables[chromosome].variables), ", ".join([MySqlTable.formatSql(values[variable], self.tables[chromosome].types[variable], self.tables[chromosome].sizes[variable]) for variable in self.tables[chromosome].variables]))
+            progress.inc()
+        progress.done()
+            
+            
+    def write(self):
+        """
+        Copy the content of the files into the database
+        (May add transcripts to already created databases)
+        """
+        for chromosome in self.transcriptValues:
+            if chromosome in self.transcriptValues:
+                self.tables[chromosome].insertMany(self.transcriptValues[chromosome])
+        self.transcriptValues = {}
+        self.toBeWritten      = False
+            
+            
+    def getTables(self):
+        """
+        Get the tables
+        @return: the mySQL tables
+        """
+        if self.toBeWritten:
+            self.write()
+        return self.tables
+
+            
+            
+    def removeTables(self):
+        """
+        Drop the tables
+        """
+        for chromosome in self.tables:
+            self.tables[chromosome].remove()
Binary file smart_toolShed/commons/core/writer/MySqlTranscriptWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/SamWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,101 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os
+import random
+from commons.core.writer.TranscriptListWriter import TranscriptListWriter
+
+
+class SamWriter(TranscriptListWriter):
+    """
+    A class that writes a transcript list into a file with SAM format
+    @ivar sizes: estimated sizes of the chromosomes
+    @type sizes: dict of string to int
+    """
+
+
+    def __init__(self, fileName, verbosity = 0):
+        """
+        Constructor
+        @param fileName:    name of the file 
+        @type fileName:     string
+        @param verbosity: verbosity
+        @type verbosity:    int
+        """
+        super(SamWriter, self).__init__(fileName, verbosity)
+        self.sizes         = {}
+        self.headerWritten = False
+        
+        
+    def close(self):
+        """
+        Close file (trick to add header)
+        """
+        super(SamWriter, self).close()
+        if self.headerWritten:
+            return
+        tmpFileName = "tmpFile%d.sam" % (random.randint(0, 100000))
+        tmpHandle = open(tmpFileName, "w")
+        for chromosome, size in self.sizes.iteritems():
+            tmpHandle.write("@SQ\tSN:%s\tLN:%d\n" % (chromosome, size))
+        self.handle = open(self.fileName)
+        for line in self.handle:
+            tmpHandle.write(line)
+        tmpHandle.close()
+        self.handle.close()
+        os.rename(tmpFileName, self.fileName)
+        self.headerWritten = True
+
+
+    @staticmethod
+    def getFileFormats():
+        """
+        Get the format of the file
+        """
+        return ["sam"]
+        
+        
+    @staticmethod
+    def getExtension():
+        """
+        Get the usual extension for the file
+        """
+        return "sam"
+        
+        
+    def printTranscript(self, transcript):
+        """
+        Export the given transcript with GBrowse format
+        @param transcript: transcript to be printed
+        @type transcript: class L{Transcript<Transcript>}
+        @return: a string
+        """
+        self.sizes[transcript.getChromosome()] = max(transcript.getEnd(), self.sizes.get(transcript.getChromosome(), 0))
+        return transcript.printSam()
+
Binary file smart_toolShed/commons/core/writer/SamWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/SequenceListWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,94 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+
+class SequenceListWriter(object):
+    """
+    An interface that writes a list of sequences into a file
+    @ivar fileName: name of the file 
+    @type fileName: string
+    @ivar handle: handle to the file
+    @type handle: file handle
+    @ivar header: first lines of the file
+    @type header: string
+    """
+
+
+    def __init__(self, fileName, verbosity = 0):
+        """
+        Constructor
+        @param fileName: name of the file 
+        @type fileName: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        self.fileName = fileName
+        self.verbosity = verbosity
+        self.handle = open(self.fileName, "w")
+
+
+    def __del__(self):
+        """
+        Destructor
+        """
+        self.close()
+        
+
+    def write(self):
+        """
+        No-op
+        """
+        pass
+        
+        
+    def close(self):
+        """
+        Close writer
+        """
+        if self.handle != None:
+            self.handle.close()
+        
+        
+    def addSequence(self, sequence):
+        """
+        Add a sequence to the list of sequence to be written
+        @param sequence: sequence to be written
+        @type    sequence: class L{Sequence<Sequence>}
+        """
+        self.handle.write(self.getLine(sequence))
+
+
+    def addElement(self, element):
+        """
+        Same as "addSequence"
+        @param element: sequence to be written
+        @type    element: class L{Sequence<Sequence>}
+        """
+        self.addSequence(element)
+
Binary file smart_toolShed/commons/core/writer/SequenceListWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/TranscriptListWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,163 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from SMART.Java.Python.misc.Progress import Progress
+
+class TranscriptListWriter(object):
+    """
+    An interface that writes a transcript list into a file
+    @ivar fileName: name of the file 
+    @type fileName: string
+    @ivar handle: handle to the file
+    @type handle: file handle
+    @ivar header: first lines of the file
+    @type header: string
+    @ivar started: whether some transcripts have already been writted
+    @type started: boolean
+    @ivar lastChromosome: the chromosome on which the transcript which was inserted last
+    @type lastChromosome: string
+    """
+
+
+    def __init__(self, fileName, verbosity = 0):
+        """
+        Constructor
+        @param fileName: name of the file 
+        @type fileName: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        self.fileName = fileName
+        self.verbosity = verbosity
+        self.handle = open(self.fileName, "w")
+        self.started = False
+        self.lastChromosome = None
+        self.header = ""
+        self.sequenceFileName = None
+
+
+    def __del__(self):
+        """
+        Destructor
+        """
+        self.close()
+
+
+    def close(self):
+        """
+        Close writer
+        """
+        if self.handle != None and not self.handle.closed:
+            self.handle.close()
+        self.handle = None
+
+
+    def addTranscript(self, transcript):
+        """
+        Add a transcript to the list of transcripts to be written
+        @param transcript: transcript to be written
+        @type    transcript: class L{Transcript<Transcript>}
+        """
+        if not self.started:
+            self.handle.write(self.header)
+            self.started = True
+
+        self.handle.write(self.printTranscript(transcript))
+        self.lastChromosome = transcript.getChromosome()
+
+
+    def addElement(self, element):
+        """
+        Same as "addTranscript"
+        @param element: transcript to be written
+        @type    element: class L{Transcript<Transcript>}
+        """
+        self.addTranscript(element)
+
+
+    def addTranscriptList(self, transcriptList):
+        """
+        Add a list of transcripts to the transcripts to be written
+        @param transcriptList: transcripts to be written
+        @type    transcriptList: class L{TranscriptList<TranscriptList>}
+        """
+        progress = Progress(transcriptList.getNbTranscripts(), "Writing transcripts", self.verbosity)
+        for transcript in transcriptList.getIterator():
+            self.addTranscript(transcript)
+            progress.inc()
+        progress.done()
+            
+
+    def addTranscriptTable(self, transcriptTable):
+        """
+        Add a list of transcripts in a mySQL table to the transcripts to be written
+        @param transcriptTable: transcripts to be written
+        @type    transcriptTable: class L{MySqlTranscriptTable<MySqlTranscriptTable>}
+        """
+        for transcript in transcriptTable.getIterator():
+            self.addTranscript(transcript)
+            
+            
+    def setTitle(self, title):
+        """
+        Possibly write a title for the list (by default, do nothing)
+        @param title: a title for the list
+        @type title:    string
+        """
+        pass
+    
+    def setFeature(self, feature):
+        """
+        Set the name of the feature
+        @param title: the title of the feature
+        @type    feature: string
+        """
+        pass
+        
+    def setFeaturePart(self, featurePart):
+        """
+        Set the name of the feature part
+        @param title: the title of the feature part
+        @type    featurePart: string
+        """
+        pass
+
+
+    def addSequenceFile(self, fileName):
+        """
+        Get the multi-fasta file of the sequences
+        """
+        self.sequenceFileName = fileName
+        
+        
+    def write(self):
+        """
+        No-op
+        """
+        pass
Binary file smart_toolShed/commons/core/writer/TranscriptListWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/TranscriptWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,189 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import os
+import sys
+from commons.core.writer.WriterChooser import WriterChooser
+from commons.core.writer.MySqlTranscriptWriter import MySqlTranscriptWriter
+
+class TranscriptWriter(object):
+    """
+    An interface class that writes a list of transcripts, handle different formats
+    @ivar container: container of the data
+    @type container: L{TranscriptContainer<TranscriptContainer>}
+    @ivar format: format of the data to be printed
+    @type format: string     
+    @ivar file: the file where to print
+    @type file: string 
+    @ivar type: type of the data (transcripts, mappings or mySQL)
+    @type type: string
+    @ivar writer: a transcript list writer
+    @type writer: L{TranscriptListWriter<TranscriptListWriter>} or None
+    @ivar mode: use a container or enter transcript one by one
+    @type mode: string
+    @ivar verbosity: verbosity
+    @type verbosity: int        
+    """
+
+    def __init__(self, file, format, verbosity = 0):
+        """
+        Constructor
+        @param container: container of the data
+        @type container: string
+        @param format: format of the data
+        @type format: string
+        @param file: file where to print
+        @type file: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        self.container = None
+        self.format = format
+        self.file = file 
+
+        self.verbosity = verbosity
+        self.type = None
+        self.writer = None
+        self.mode = None
+        if self.format == None:
+            sys.exit("Error! Writer input format is empty!")
+
+        if self.format == "sql":
+            self.type = "sql"
+            pos = self.file.rfind(os.sep)
+            if pos > -1:
+                self.file = self.file[pos+1:]
+            self.writer = MySqlTranscriptWriter(self.file, self.verbosity)
+        else:
+            writerChooser = WriterChooser(self.verbosity)
+            writerChooser.findFormat(self.format)
+            self.writer = writerChooser.getWriter(self.file)
+            self.type = writerChooser.getType()
+            
+            
+    def close(self):
+        """
+        Close writer
+        """
+        if self.writer != None:
+            self.writer.close()
+
+
+    def setContainer(self, container):
+        """
+        Set a container for the data
+        @param container: container of the data
+        @type container: class L{TranscriptContainer<TranscriptContainer>}
+        """
+        self.container = container
+        if self.mode == "transcript":
+            raise Exception("Error! TranscriptWriter '%s' on 'transcript' mode is currently used on 'container' mode." % (self.file))
+        self.mode = "container"
+
+
+    def addTranscript(self, transcript):
+        """
+        Add a transcript to write
+        @param transcript: a transcript
+        @type transcript: class L{Transcript<Transcript>}
+        """
+        self.writer.addTranscript(transcript)
+        if self.mode == "container":
+            sys.exit("Error! TranscriptWriter '%s' on 'container' mode is currently used on 'transcript' mode." % (self.file))
+        self.mode = "transcript"
+        
+        
+    def addElement(self, transcript):
+        """
+        Same as addTranscript
+        """
+        self.addTranscript(transcript)
+    
+
+    def setTitle(self, title):
+        """
+        Possibly write a title for the list
+        @param title: a title for the list
+        @type title: string
+        """
+        if self.writer != None:
+            self.writer.setTitle(title)
+
+    def setFeature(self, feature):
+        """
+        Possibly Set the name of the feature
+        @param title: the title of the feature
+        @type    feature: string
+        """
+        if self.writer != None:
+            self.writer.setFeature(feature)
+        
+    def setFeaturePart(self, featurePart):
+        """
+        Possibly Set the name of the feature part
+        @param title: the title of the feature part
+        @type    featurePart: string
+        """
+        if self.writer != None:
+            self.writer.setFeaturePart(featurePart)    
+        
+    def setStrands(self, strands):
+        """
+        Possibly consider both strands separately
+        @param strands: whether both strands should be considered separately
+        @type  strands: boolean
+        """
+        if self.writer != None:
+            self.writer.setStrands(strands)
+            
+        
+    def write(self):
+        """
+        Write the content and possibly convert data
+        """        
+        if self.type == "transcript" or self.type == "sequence":
+            if self.mode == "container":
+                self.writer.addTranscriptList(self.container)
+            return
+
+        if self.mode == "transcript" or self.type == "sequence":
+            self.writer.write()
+            return
+
+        if self.container.format != "sql":
+            self.container.storeIntoDatabase()
+        tables = self.container.getTables()
+        for chromosome in tables:
+            tables[chromosome].rename("%s_%s" % (self.file, chromosome))
+        return
+        
+
+    def addSequenceFile(self, fileName):
+        self.writer.addSequenceFile(fileName)
+            
\ No newline at end of file
Binary file smart_toolShed/commons/core/writer/TranscriptWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/UcscWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,73 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from commons.core.writer.BedWriter import BedWriter
+
+class UcscWriter(BedWriter):
+    """
+    A class that writes a transcript list into a file with UCSC BED format (minor differences with BED format)
+    """
+
+
+    def __init__(self, fileName, verbosity = 0):
+        """
+        Constructor
+        @param fileName: name of the file 
+        @type fileName: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        super(UcscWriter, self).__init__(fileName, verbosity)
+        
+
+    @staticmethod
+    def getFileFormats():
+        """
+        Get the format of the file
+        """
+        return ["ucsc"]
+        
+        
+    @staticmethod
+    def getExtension():
+        """
+        Get the usual extension for the file
+        """
+        return "bed"
+
+        
+    def printTranscript(self, transcript):
+        """
+        Export the given transcript with GBrowse format
+        @param transcript: transcript to be printed
+        @type transcript: class L{Transcript<Transcript>}
+        @return: a string
+        """
+        return transcript.printUcsc()
+
Binary file smart_toolShed/commons/core/writer/UcscWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/WigWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,139 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+from commons.core.writer.TranscriptListWriter import TranscriptListWriter
+
+
+class WigWriter(TranscriptListWriter):
+    """
+    A class that writes a transcript list into a file with WIGGLE format
+    @ivar fileName: name of the file 
+    @type fileName: string
+    @ivar handle: handle to the file
+    @type handle: file handle
+    @ivar header: first lines of the file
+    @type header: string
+    """
+
+
+    def __init__(self, fileName, verbosity = 0):
+        """
+        Constructor
+        @param fileName: name of the file 
+        @type fileName: string
+        @param verbosity: verbosity
+        @type verbosity: int
+        """
+        self.fileName  = fileName
+        self.verbosity = verbosity
+        self.data      = {-1: {}, 0: {}, 1: {}}
+        self.title     = "Reads"
+        self.strands   = False
+        self.handle    = None
+
+
+    def __del__(self):
+        """
+        Destructor
+        Actually print the file
+        """
+        strand2string = {-1: "-", 1: "+", 0: ""}
+        self.handle   = open(self.fileName, "w")
+        self.handle.write("track type=wiggle_0 name=\"%s\"\n" % (self.title))
+        for strand in self.data:
+            for chromosome in sorted(self.data[strand]):
+                 self.handle.write("variableStep chrom=%s%s\n" % (chromosome, strand2string[strand]))
+                 for pos in sorted(self.data[strand][chromosome]):
+                     self.handle.write("%d\t%d\n" % (pos, self.data[strand][chromosome][pos]))
+        self.handle.close()
+
+        
+    @staticmethod
+    def getFileFormats():
+        """
+        Get the format of the file
+        """
+        return ["wig", "wiggle"]
+        
+        
+    @staticmethod
+    def getExtension():
+        """
+        Get the usual extension for the file
+        """
+        return "wig"
+        
+        
+    def setTitle(self, title):
+        """
+        Set the title of the track
+        @param title: the title of the track
+        @type    title: string
+        """
+        if title != None:
+            self.title = title
+
+
+    def setStrands(self, strands):
+        """
+        Consider each strand separately
+        @param boolean: whether each strand should be considered separately
+        @type  boolean: boolean
+        """
+        self.strands = strands
+
+
+    def copyProperties(self, parser):
+        """
+        Copy the properties collected by a parser, to produce a similar output
+        @param bedParser: a parser
+        @type    bedParser: class L{TranscriptListWriter<TranscriptListWriter>}
+        """
+        self.setTitle(parser.title)
+        
+
+    def addTranscript(self, transcript):
+        """
+        Export the given transcript with GBrowse format
+        @param transcript: transcript to be printed
+        @type transcript: class L{Transcript<Transcript>}
+        @return: a string
+        """
+        chromosome = transcript.getChromosome()
+        direction  = transcript.getDirection()
+        if not self.strands:
+            direction = 0
+        if chromosome not in self.data[direction]:
+            self.data[direction][chromosome] = {}
+        for exon in transcript.getExons():
+            for pos in range(exon.getStart(), exon.getEnd()+1):
+                if pos not in self.data[direction][chromosome]:
+                    self.data[direction][chromosome][pos]  = 1
+                else:
+                    self.data[direction][chromosome][pos] += 1
Binary file smart_toolShed/commons/core/writer/WigWriter.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/WriterChooser.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,127 @@
+#
+# Copyright INRA-URGI 2009-2010
+# 
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+# 
+# As a counterpart to the access to the source code and rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+# 
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using, modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+# 
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+#
+import sys
+from commons.core.writer.TranscriptListWriter import TranscriptListWriter
+from commons.core.writer.SequenceListWriter import SequenceListWriter
+from commons.core.writer.BedWriter import BedWriter
+from commons.core.writer.CsvWriter import CsvWriter
+from commons.core.writer.EmblWriter import EmblWriter
+from commons.core.writer.FastaWriter import FastaWriter
+from commons.core.writer.FastqWriter import FastqWriter
+from commons.core.writer.GbWriter import GbWriter
+from commons.core.writer.Gff2Writer import Gff2Writer
+from commons.core.writer.SamWriter import SamWriter
+from commons.core.writer.UcscWriter import UcscWriter
+from commons.core.writer.WigWriter import WigWriter
+from commons.core.writer.Gff3Writer import Gff3Writer
+from commons.core.writer.GtfWriter import GtfWriter
+from commons.core.writer.MapWriter import  MapWriter
+
+ 
+class WriterChooser(object):
+    """
+    A class that finds the correct writer
+    @ivar type: transcript / sequence writer
+    @type type: string
+    @ivar format: the format of the writer
+    @type format: string
+    @ivar writerClass: the class of the writer
+    @type writerClass: string
+    @ivar extension: default extension of the file
+    @type extension: string
+    @ivar verbosity: verbosity
+    @type verbosity: int        
+    """
+
+    def __init__(self, verbosity = 0):
+        """
+        Constructor
+        @param verbosity: verbosity
+        @type    verbosity: int
+        """
+        self.type = None
+        self.format = None
+        self.writerClass = None
+        self.extension = None
+        self.verbosity = verbosity
+    
+
+    def findFormat(self, format, type = None):
+        """
+        Find the correct parser
+        @ivar format: the format
+        @type format: string
+        @ivar type: transcript sequence parser (None is all)
+        @type type: string
+        @return: a parser
+        """
+        classes = {}
+        if (type == "transcript"):
+            classes = {TranscriptListWriter: "transcript"}
+        elif (type == "sequence"):
+            classes = {SequenceListWriter: "sequence"}
+        elif (type == None):
+            classes = {TranscriptListWriter: "transcript", SequenceListWriter: "sequence"}
+        else:
+            sys.exit("Do not understand format type '%s'" % (type))
+
+        for classType in classes:
+            for writerClass in classType.__subclasses__():
+                if format in writerClass.getFileFormats():
+                    self.writerClass = writerClass
+                    self.extension = writerClass.getExtension()
+                    self.type = classes[classType]
+                    return
+        sys.exit("Cannot get writer for format '%s'" % (format))
+
+
+    def getWriter(self, fileName):
+        """
+        Get the writer previously found
+        @return: the writer
+        """
+        return self.writerClass(fileName, self.verbosity)
+
+
+    def getType(self):
+        """
+        Get the type of writer previously found
+        @return: the type of writer
+        """
+        return self.type
+
+
+    def getExtension(self):
+        """
+        Get the default extension of writer previously found
+        @return: the extension
+        """
+        return self.extension
+
Binary file smart_toolShed/commons/core/writer/WriterChooser.pyc has changed
Binary file smart_toolShed/commons/core/writer/__init__.pyc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/test/Test_Gff3Writer.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,101 @@
+from commons.core.writer.Gff3Writer import Gff3Writer
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Interval import Interval
+import unittest
+import os
+from SMART.Java.Python.misc import Utils
+
+class Test_Gff3Writer(unittest.TestCase):
+  
+    def test_writer(self):
+        obsFileName = "testGffWriter1.gff3"
+        writer = Gff3Writer(obsFileName)
+        
+        transcript = Transcript()
+        transcript.setName("test1.1")
+        transcript.setChromosome("arm_X")
+        transcript.setStart(1000)
+        transcript.setEnd(4000)
+        transcript.setDirection("+")
+        transcript.setTagValue("ID", "test1.1-1")
+        transcript.setTagValue("occurrence", 1)
+        transcript.setTagValue("nbOccurrences", 2)
+        
+        exon1 = Interval()
+        exon1.setChromosome("arm_X")
+        exon1.setStart(1000)
+        exon1.setEnd(2000)
+        exon1.setDirection("+")
+        
+        exon2 = Interval()
+        exon2.setChromosome("arm_X")
+        exon2.setStart(3000)
+        exon2.setEnd(4000)
+        exon2.setDirection("+")
+        
+        transcript.addExon(exon1)
+        transcript.addExon(exon2)
+        
+        writer.addTranscript(transcript)
+        writer.write()
+        writer.close()
+        
+        expFileName = "expFile.gff3"
+        f = open(expFileName, "w")
+        f.write("arm_X\tS-MART\ttranscript\t1000\t4000\t.\t+\t.\tnbOccurrences=2;ID=test1.1-1;occurrence=1;Name=test1.1\n")
+        f.write("arm_X\tS-MART\texon\t1000\t2000\t.\t+\t.\tID=test1.1-1-exon1;Name=test1.1-exon1;Parent=test1.1-1\n")
+        f.write("arm_X\tS-MART\texon\t3000\t4000\t.\t+\t.\tID=test1.1-1-exon2;Name=test1.1-exon2;Parent=test1.1-1\n")
+        f.close()
+        
+        self.assertTrue(Utils.diff(expFileName, obsFileName))
+        
+        os.remove(expFileName)
+        os.remove(obsFileName)
+        
+    def test_writerAltNames(self):
+        obsFileName = "testGffWriter1.gff3"
+        writer = Gff3Writer(obsFileName,title="ALTSOURCE", feature="Match", featurePart="Match-Part")
+        
+        transcript = Transcript()
+        transcript.setName("test1.1")
+        transcript.setChromosome("arm_X")
+        transcript.setStart(1000)
+        transcript.setEnd(4000)
+        transcript.setDirection("+")
+        transcript.setTagValue("ID", "test1.1-1")
+        transcript.setTagValue("occurrence", 1)
+        transcript.setTagValue("nbOccurrences", 2)
+        
+        exon1 = Interval()
+        exon1.setChromosome("arm_X")
+        exon1.setStart(1000)
+        exon1.setEnd(2000)
+        exon1.setDirection("+")
+        
+        exon2 = Interval()
+        exon2.setChromosome("arm_X")
+        exon2.setStart(3000)
+        exon2.setEnd(4000)
+        exon2.setDirection("+")
+        
+        transcript.addExon(exon1)
+        transcript.addExon(exon2)
+        
+        writer.addTranscript(transcript)
+        writer.write()
+        writer.close()
+        
+        expFileName = "expFile.gff3"
+        f = open(expFileName, "w")
+        f.write("arm_X\tALTSOURCE\tMatch\t1000\t4000\t.\t+\t.\tnbOccurrences=2;ID=test1.1-1;occurrence=1;Name=test1.1\n")
+        f.write("arm_X\tALTSOURCE\tMatch-Part\t1000\t2000\t.\t+\t.\tID=test1.1-1-Match-Part1;Name=test1.1-Match-Part1;Parent=test1.1-1\n")
+        f.write("arm_X\tALTSOURCE\tMatch-Part\t3000\t4000\t.\t+\t.\tID=test1.1-1-Match-Part2;Name=test1.1-Match-Part2;Parent=test1.1-1\n")
+        f.close()
+        
+        self.assertTrue(Utils.diff(expFileName, obsFileName))
+        
+        os.remove(expFileName)
+        os.remove(obsFileName)
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smart_toolShed/commons/core/writer/test/Test_MapWriter.py	Thu Jan 17 10:52:14 2013 -0500
@@ -0,0 +1,61 @@
+from SMART.Java.Python.structure.Transcript import Transcript
+from SMART.Java.Python.structure.Interval import Interval
+import unittest
+import os
+from SMART.Java.Python.misc import Utils
+from commons.core.writer.MapWriter import MapWriter
+from commons.core.utils.FileUtils import FileUtils
+
+class Test_MapWriter(unittest.TestCase):
+    
+    def setUp(self):
+        self.expFileName = "expMapWriter.map"
+        self.obsFileName = "testMapWriter1.map"
+        
+    def tearDown(self):
+        os.remove(self.expFileName)
+        os.remove(self.obsFileName)
+        
+    def test_writer(self):
+        self.write_ExpMapFileName()
+        writer = MapWriter(self.obsFileName)
+        
+        transcript = Transcript()
+        transcript.setName("test1.1")
+        transcript.setChromosome("arm_X")
+        transcript.setStart(1000)
+        transcript.setEnd(4000)
+        transcript.setDirection("+")
+        transcript.setTagValue("ID", "test1.1-1")
+        transcript.setTagValue("occurrence", 1)
+        transcript.setTagValue("nbOccurrences", 2)
+        
+        exon1 = Interval()
+        exon1.setChromosome("arm_X")
+        exon1.setStart(1000)
+        exon1.setEnd(2000)
+        exon1.setDirection("+")
+        
+        exon2 = Interval()
+        exon2.setChromosome("arm_X")
+        exon2.setStart(3000)
+        exon2.setEnd(4000)
+        exon2.setDirection("+")
+        
+        transcript.addExon(exon1)
+        transcript.addExon(exon2)
+        
+        writer.addTranscript(transcript)
+        writer.write()
+        writer.close()
+        
+        self.assertTrue(FileUtils.are2FilesIdentical(self.expFileName, self.obsFileName))
+        
+
+    def write_ExpMapFileName(self):
+        f = open(self.expFileName, "w")
+        f.write("test1.1\tarm_X\t1000\t4001\n")
+        f.close()
+
+if __name__ == '__main__':
+    unittest.main()
Binary file smart_toolShed/documentation.pdf has changed