Repository: PacificBiosciences/FALCON Branch: master Commit: ab80e88e1278 Files: 165 Total size: 1.4 MB Directory structure: gitextract_zc9ere_s/ ├── .gitignore ├── .gitmodules ├── .travis.yml ├── LICENSE ├── MANIFEST.in ├── README.md ├── bamboo_build.sh ├── bamboo_wheel.sh ├── doc/ │ └── README ├── examples/ │ ├── build_env.sh │ ├── build_env2.sh │ ├── ecoli_asm_graph_exploration.ipynb │ ├── fc_run_LG.cfg │ ├── fc_run_arab.cfg │ ├── fc_run_dmel.cfg │ ├── fc_run_ecoli.cfg │ ├── fc_run_ecoli_2.cfg │ ├── logging.json │ └── run_ecoli_test.sh ├── falcon.snake ├── falcon_kit/ │ ├── FastaReader.py │ ├── __init__.py │ ├── bash.py │ ├── falcon_kit.py │ ├── fc_asm_graph.py │ ├── functional.py │ ├── gfa_graph.py │ ├── io.py │ ├── mains/ │ │ ├── LAmerge.py │ │ ├── LAsort.py │ │ ├── __init__.py │ │ ├── actg_coordinate.py │ │ ├── build_pdb.py │ │ ├── build_rdb.py │ │ ├── calc_cutoff.py │ │ ├── collect_contig_gfa.py │ │ ├── collect_pread_gfa.py │ │ ├── consensus.py │ │ ├── consensus_gather_fasta_fofn.py │ │ ├── consensus_scatter.py │ │ ├── consensus_split.py │ │ ├── consensus_task.py │ │ ├── contig_annotate.py │ │ ├── copy_fofn.py │ │ ├── copy_mapped.py │ │ ├── ctg_link_analysis.py │ │ ├── daligner.py │ │ ├── daligner_gather_las_list.py │ │ ├── daligner_scatter.py │ │ ├── daligner_split.py │ │ ├── dazzler.py │ │ ├── dedup_a_tigs.py │ │ ├── fasta2fasta.py │ │ ├── fetch_reads.py │ │ ├── gen_gfa_v1.py │ │ ├── gen_gfa_v2.py │ │ ├── generate_read_to_ctg_map.py │ │ ├── generic_gather.py │ │ ├── generic_run_units_of_work.py │ │ ├── generic_scatter_one_uow.py │ │ ├── generic_unsplit.py │ │ ├── get_read_ctg_map.py │ │ ├── graph_to_contig.py │ │ ├── graph_to_utgs.py │ │ ├── hgap4_adapt.py │ │ ├── las_merge.py │ │ ├── las_merge_gather.py │ │ ├── las_merge_scatter.py │ │ ├── las_merge_split.py │ │ ├── ovlp_filter.py │ │ ├── ovlp_stats.py │ │ ├── ovlp_to_graph.py │ │ ├── pr_ctg_track.py │ │ ├── report_pre_assembly.py │ │ ├── rr_ctg_track.py │ │ ├── run1.py │ │ ├── symlink_mapped.py │ │ ├── task_report_pre_assembly.py │ │ └── tasks.py │ ├── multiproc.py │ ├── pype.py │ ├── pype_tasks.py │ ├── run_support.py │ ├── snakemake.py │ ├── stats_preassembly.py │ ├── tiling_path.py │ └── util/ │ ├── __init__.py │ ├── io.py │ └── system.py ├── makefile ├── setup.cfg ├── setup.py ├── src/ │ ├── c/ │ │ ├── DW_banded.c │ │ ├── Makefile │ │ ├── Makefile.osx │ │ ├── common.h │ │ ├── ext_falcon.c │ │ ├── falcon.c │ │ └── kmer_lookup.c │ ├── py_scripts/ │ │ ├── fc_actg_coordinate.py │ │ ├── fc_consensus.py │ │ ├── fc_contig_annotate.py │ │ ├── fc_ctg_link_analysis.py │ │ ├── fc_dedup_a_tigs.py │ │ ├── fc_graph_to_contig.py │ │ ├── fc_graph_to_utgs.py │ │ ├── fc_ovlp_filter.py │ │ ├── fc_ovlp_stats.py │ │ ├── fc_ovlp_to_graph.py │ │ └── fc_run.py │ └── utils/ │ └── fetch_preads.py ├── test/ │ ├── HPCdaligner_synth0.sh │ ├── HPCdaligner_synth0_new.sh │ ├── HPCdaligner_synth0_preads.sh │ ├── helpers.py │ ├── se161.sh │ ├── test_actg_coordinate.py │ ├── test_calc_cutoff.py │ ├── test_collect_contig_gfa.py │ ├── test_collect_pread_gfa.py │ ├── test_consensus.py │ ├── test_contig_annotate.py │ ├── test_ctg_link_analysis.py │ ├── test_functional.py │ ├── test_gen_gfa_v1.py │ ├── test_gen_gfa_v2.py │ ├── test_gfa_graph.py │ ├── test_graph_to_contig.py │ ├── test_graph_to_utgs.py │ ├── test_ovlp_filter.py │ ├── test_ovlp_stats.py │ ├── test_ovlp_to_graph.py │ ├── test_run.py │ ├── test_run_LG.py │ ├── test_run_support.py │ ├── test_stats_preassembly.py │ ├── test_tiling_path.py │ ├── test_util_io.py │ └── test_util_system.py ├── test_data/ │ ├── calc_cutoff/ │ │ └── partial_capture.txt │ ├── gfa-1/ │ │ ├── a_ctg.fa │ │ ├── a_ctg_tiling_path │ │ ├── ctg_paths │ │ ├── expected-1-sg-r-c.gfa │ │ ├── expected-2-tiling-r-c.gfa │ │ ├── expected-3-tiling-no_r-c.gfa │ │ ├── expected-4-tiling-no_r-no_c.gfa │ │ ├── expected-5-sg-no_r-no_c.gfa │ │ ├── expected-6-tiling-no_r-no_c-minlen.gfa │ │ ├── expected-7-nx-no_r-no_c.gfa │ │ ├── expected-8-nx-tiling-no_r-no_c.gfa │ │ ├── expected-9-nx-tiling-r-c.gfa │ │ ├── p_ctg.fa │ │ ├── p_ctg_tiling_path │ │ ├── preads4falcon.fasta │ │ ├── sg.gexf │ │ ├── sg_edges_list │ │ └── utg_data │ ├── p_ctg_tiling_path_1 │ ├── p_ctg_tiling_path_2 │ ├── t1.fa │ ├── t1.fofn │ ├── t2.fa │ └── t2.fofn └── travis.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ /LOCAL/ /build/ /dist/ /.cache/ falcon_kit.egg-info/ /.coverage *.pyc *.pyo *.swp *.so *.dylib *.dll *.egg *.eggs FALCON.tar.gz *.xml *.whl .pytest_cache/ ================================================ FILE: .gitmodules ================================================ ================================================ FILE: .travis.yml ================================================ # Build matrix / environment variable are explained on: # http://about.travis-ci.org/docs/user/build-configuration/ # This file can be validated on: # http://lint.travis-ci.org/ #before_install: sudo apt-get install -y cmake # cmake is pre-installed in Travis for both linux and osx #before_install: # - sudo apt-get update -qq # - sudo apt-get install -qq valgrind #sudo: required os: - linux #language: python # This seems to cause virtualenv, which we do not want. We prefer a --user install. # But to speed-up start-up, language: c compiler: - clang # hmm. distutils uses 'gcc' anyway # - gcc script: ./travis.sh #env: # matrix: # - SHARED_LIB=ON STATIC_LIB=ON CMAKE_PKG=ON BUILD_TYPE=release VERBOSE_MAKE=false # - SHARED_LIB=OFF STATIC_LIB=ON CMAKE_PKG=OFF BUILD_TYPE=debug VERBOSE_MAKE=true VERBOSE notifications: email: false sudo: false ================================================ FILE: LICENSE ================================================ #################################################################################$$ # Copyright (c) 2011-2015, Pacific Biosciences of California, Inc. # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted (subject to the limitations in the # disclaimer below) provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # # * Neither the name of Pacific Biosciences nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE # GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY PACIFIC # BIOSCIENCES AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL PACIFIC BIOSCIENCES OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. #################################################################################$$ ================================================ FILE: MANIFEST.in ================================================ include src/c/* ================================================ FILE: README.md ================================================ Falcon =========== Falcon: a set of tools for fast aligning long reads for consensus and assembly The Falcon tool kit is a set of simple code collection which I use for studying efficient assembly algorithm for haploid and diploid genomes. It has some back-end code implemented in C for speed and some simple front-end written in Python for convenience. DOCUMENTATION ------------- The default branch is now "master" which contained the latest code. The current latest intergrated release is v0.3.0. Check [v0.3+ Integration Installation Guide](https://github.com/PacificBiosciences/FALCON-integrate/wiki/Installation) for installation. For the pre-Jun 2015 v0.2.2 version, please check [v0.2.2 release github repository](https://github.com/PacificBiosciences/FALCON/tree/v0.2.2). We will no longer address issues that are specific to that branch unless they also impact the current master branch. - [wiki pages](https://github.com/PacificBiosciences/FALCON/wiki) - [Developer Installation Guide](https://github.com/PacificBiosciences/FALCON/wiki/Setup:-Installation-and-Environment) - [v0.3+ Integration Installation Guide](https://github.com/PacificBiosciences/FALCON-integrate/wiki/Installation) - [Documentation is here.](https://github.com/PacificBiosciences/FALCON/wiki/Manual) - [FAQs](https://github.com/PacificBiosciences/FALCON/wiki/FAQs) - [v0.2.2 release github repository](https://github.com/PacificBiosciences/FALCON/tree/v0.2.2) ABOUT THE LICENSE ------------------ Standard PacBio ["Open Source License"](LICENSE). July 9th, 2015 DISCLAIMER ---------- THIS WEBSITE AND CONTENT AND ALL SITE-RELATED SERVICES, INCLUDING ANY DATA, ARE PROVIDED "AS IS," WITH ALL FAULTS, WITH NO REPRESENTATIONS OR WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY, NON-INFRINGEMENT OR FITNESS FOR A PARTICULAR PURPOSE. YOU ASSUME TOTAL RESPONSIBILITY AND RISK FOR YOUR USE OF THIS SITE, ALL SITE-RELATED SERVICES, AND ANY THIRD PARTY WEBSITES OR APPLICATIONS. NO ORAL OR WRITTEN INFORMATION OR ADVICE SHALL CREATE A WARRANTY OF ANY KIND. ANY REFERENCES TO SPECIFIC PRODUCTS OR SERVICES ON THE WEBSITES DO NOT CONSTITUTE OR IMPLY A RECOMMENDATION OR ENDORSEMENT BY PACIFIC BIOSCIENCES. ================================================ FILE: bamboo_build.sh ================================================ #!/bin/bash type module >& /dev/null || . /mnt/software/Modules/current/init/bash module purge module load git module load gcc module load ccache module load python/2 #module load make set -vex git --version which gcc which g++ gcc --version which python rm -rf LOCAL mkdir -p LOCAL export PYTHONUSERBASE=$(pwd)/LOCAL export PATH=${PYTHONUSERBASE}/bin:${PATH} # We need latest local pypeFLOW, not from PyPI. pushd ../pypeFLOW pip install --user --edit . popd # Back to FALCON. # Unfortunately, we need pypeflow for pylint. python -c 'import pypeflow as p; print p' python -c 'import pypeflow.sample_tasks as p; print p' make install-edit # Note: no --edit because we might be building artifacts. # ... Scratch that. We have trouble getting coverage for # source=falcon_kit # but maybe it will work with a --edit install. export MY_TEST_FLAGS="-v -s --durations=0 --cov=falcon_kit --cov-report=term-missing --cov-report=xml:coverage.xml --cov-branch" make test sed -i -e 's@filename="@filename="./falcon_kit/@g' coverage.xml make pylint ================================================ FILE: bamboo_wheel.sh ================================================ #!/bin/bash type module >& /dev/null || . /mnt/software/Modules/current/init/bash module purge module load gcc module load ccache set -vex ls -larth .. ls -larth pwd module load python/2-UCS2 make wheel WHEELHOUSE=artifacts/gcc-6.4.0/wheelhouse # For now, we have only "any" wheels, so we do not need to build again. module unload python module load python/2-UCS4 make wheel WHEELHOUSE=artifacts/gcc-6.4.0/wheelhouse ================================================ FILE: doc/README ================================================ The images here are used by https://github.com/PacificBiosciences/FALCON/wiki/Manual ================================================ FILE: examples/build_env.sh ================================================ virtualenv --no-site-packages --always-copy $PWD/fc_env . $PWD/fc_env/bin/activate git clone https://github.com/pb-jchin/pypeFLOW cd pypeFLOW python setup.py install cd .. git clone https://github.com/PacificBiosciences/FALCON.git cd FALCON python setup.py install cd .. git clone https://github.com/pb-jchin/DAZZ_DB.git cd DAZZ_DB/ make cp DBrm DBshow DBsplit DBstats fasta2DB ../fc_env/bin/ cd .. git clone https://github.com/pb-jchin/DALIGNER.git cd DALIGNER make cp daligner daligner_p DB2Falcon HPCdaligner LA4Falcon LAmerge LAsort ../fc_env/bin ================================================ FILE: examples/build_env2.sh ================================================ virtualenv --no-site-packages --always-copy $PWD/fc_env . $PWD/fc_env/bin/activate cd FALCON git submodule init git submodule update cd pypeFLOW python setup.py install cd .. python setup.py install cd DAZZ_DB/ make cp DBrm DBshow DBsplit DBstats fasta2DB ../../fc_env/bin/ cd .. cd DALIGNER make cp daligner daligner_p DB2Falcon HPCdaligner LA4Falcon LAmerge LAsort ../../fc_env/bin cd ../.. ================================================ FILE: examples/ecoli_asm_graph_exploration.ipynb ================================================ { "metadata": { "name": "", "signature": "sha256:585e8268126c8365dec7b581d0673bd9a5a1e83a88800e51c0f9028479318042" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "FALCON Assembly Graph Processing and Visulization Example\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook shows how to fetch the graph data from the assembler and show how to examine the bubbles in the assembly graph." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You will need to have `matplotlib`, `networkx` and `pygraphviz` as Python libraries. Of course, you will need to have `graphviz` command line tool install in your system too. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some setup to change the working directory to where the data is." ] }, { "cell_type": "code", "collapsed": false, "input": [ "%cd /mnt/projects/bifxanalysis/jchin_asm_jobs/DA_develop_test/Ecoli/2-asm-falcon/\n", "%matplotlib inline\n", "%pylab inline" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "/mnt/projects/bifxanalysis/jchin_asm_jobs/DA_develop_test/Ecoli/2-asm-falcon\n", "Populating the interactive namespace from numpy and matplotlib\n" ] } ], "prompt_number": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some boilerplate code for loading the necessary module and classes" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import networkx as nx\n", "from IPython.display import display, HTML, SVG, Image" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Load the `AsmGraph` class which parse the graph data files and load them into python objects. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "from falcon_kit.fc_asm_graph import AsmGraph" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Load data into `G_asm`. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "G_asm = AsmGraph(\"sg_edges_list\", \"utg_data\", \"ctg_paths\")" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Show all contig identifiers. The `000000R` is the dual contig of `000000F`." ] }, { "cell_type": "code", "collapsed": false, "input": [ "print G_asm.ctg_data.keys()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "['000000F', '000000R']\n" ] } ], "prompt_number": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Print out the content of the contig `000000F`. The output is a tuple of `contig identifier`, `start_utg`, `end_node`, `number of base`, `number of overlapped base`, `unitigs`." ] }, { "cell_type": "code", "collapsed": false, "input": [ "print G_asm.ctg_data[\"000000F\"]\n", "print\n", "print \"number of unitigs in the contig:\", len(G_asm.ctg_data[\"000000F\"][-1])" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "('ctg_linear', '000011445:B~NA~000003425:E', '000011445:B', 4642293, 28970832, (['000011445:B', 'NA', '000003425:E'], ['000003425:E', '000009719:E', '000006955:E'], ['000006955:E', 'NA', '000017147:B'], ['000017147:B', '000012473:B', '000010757:B'], ['000010757:B', 'NA', '000015636:E'], ['000015636:E', '000004093:E', '000015696:B'], ['000015696:B', 'NA', '000016941:B'], ['000016941:B', '000003353:B', '000008783:B'], ['000008783:B', 'NA', '000006338:B'], ['000006338:B', '000004932:B', '000010623:B'], ['000010623:B', 'NA', '000014991:B'], ['000014991:B', '000013790:E', '000002926:B'], ['000002926:B', 'NA', '000011761:B'], ['000011761:B', '000003659:E', '000014184:E'], ['000014184:E', 'NA', '000012028:E'], ['000012028:E', '000013461:E', '000011445:B']))\n", "\n", "number of unitigs in the contig: 16\n" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "If the starting node is the same of the ending node, then the contig may be circular too. (The contig type only applys to \"simple unitig\". Any contig contains more than one single unitig is classfied as `ctg_linear`. This convention may change in the futrue." ] }, { "cell_type": "code", "collapsed": false, "input": [ "utgs = G_asm.ctg_data[\"000000F\"][-1]\n", "if utgs[0][0] == utgs[-1][-1]:\n", " print \"the contig is a cirular\"\n", "else:\n", " print \"thec contig is not circular\"" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "the contig is a cirular\n" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Check the number of node in the string subgraph for this contig. We can get the full string subgraph using the method `get_sg_for_ctg()`. This is full string graph. Each node is 5' or 3' ends of a read." ] }, { "cell_type": "code", "collapsed": false, "input": [ "sg = G_asm.get_sg_for_ctg(\"000000F\")\n", "print \"number of nodes:\", len(sg.nodes())\n", "print \"number of edges:\", len(sg.edges())" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "number of nodes: 1361\n", "number of edges: 1369\n" ] } ], "prompt_number": 8 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Call `neato` layout code from Graphviz to layout the contig string graph. We can see a circle with a couple of small bubbles." ] }, { "cell_type": "code", "collapsed": false, "input": [ "position=nx.graphviz_layout(sg, prog='neato') " ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 9 }, { "cell_type": "code", "collapsed": false, "input": [ "figure(figsize=(10,10))\n", "ax=subplot(1,1,1)\n", "minx = 10\n", "miny = 10\n", "count = 0\n", "for e in sg.edges():\n", " yy, xx = zip(position[e[0]], position[e[1]]) \n", "\n", " xx = -array(xx)\n", " yy = -array(yy)\n", " ax.plot( xx, yy, \".-b\" ) \n", "\n", " if min(xx) < minx:\n", " minx = min(xx)\n", " if min(yy) < miny:\n", " miny = min(yy)\n", "\n", " #print x,y\n", "xlim(minx*1.1,-minx*0.1)\n", "ylim(miny*1.1,-miny*0.1)\n", "ax.get_xaxis().set_visible(False)\n", "ax.get_yaxis().set_visible(False)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "display_data", "png": "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\n", "text": [ "" ] } ], "prompt_number": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create the assembly graph which each edge is a simple or a compound unitig rather than a raw string graph edge. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "utgs = G_asm.ctg_data[\"000000F\"][-1]\n", "utg_g = nx.DiGraph()\n", "for s,v,t in utgs:\n", " utg_g.add_edge(s,t)\n", "position=nx.graphviz_layout(utg_g, prog='neato') \n", "figure(figsize=(10,10))\n", "ax=subplot(1,1,1)\n", "minx = 10\n", "miny = 10\n", "count = 0\n", "for e in utg_g.edges():\n", " yy, xx = zip(position[e[0]], position[e[1]]) \n", "\n", " xx = -array(xx)\n", " yy = -array(yy)\n", "\n", " ax.plot( xx, yy, \".-b\" ) \n", "\n", " if min(xx) < minx:\n", " minx = min(xx)\n", " if min(yy) < miny:\n", " miny = min(yy)\n", "\n", " #print x,y\n", "xlim(minx*1.1,-minx*0.1)\n", "ylim(miny*1.1,-miny*0.1)\n", "ax.get_xaxis().set_visible(False)\n", "ax.get_yaxis().set_visible(False)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "display_data", "png": "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\nvf8Pu2r4C/+hBTQAAAAASUVORK5CYII=\n", "text": [ "" ] } ], "prompt_number": 11 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Load sequences for each string graph edges so we can generate sequence given a path in the graph." ] }, { "cell_type": "code", "collapsed": false, "input": [ "G_asm.load_sg_seq(\"preads4falcon.fasta\")" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 12 }, { "cell_type": "markdown", "metadata": {}, "source": [ "This shows how to get sequences for each simple or compound unitigs with a contig." ] }, { "cell_type": "code", "collapsed": false, "input": [ "compound_path_seqs = {}\n", "print \"s\", \"v\", \"t\", \"type\", \"seq len\", \"path len\"\n", "for s,v,t in G_asm.ctg_data[\"000000F\"][-1]:\n", " utg_data = G_asm.utg_data[(s,t,v)]\n", " type_, length, score, path_or_edges = utg_data\n", " \n", " if type_ == \"simple\":\n", " path = path_or_edges.split(\"~\")\n", " seq = G_asm.get_seq_from_path( path )\n", " print s, v, t, utg_data[0], len(seq)\n", " else:\n", " c_graph = nx.DiGraph()\n", " simple_utgs = [ e.split(\"~\") for e in path_or_edges.split(\"|\")]\n", " \n", " for ss, tt, vv in simple_utgs:\n", " type_, length, score, sub_path = G_asm.utg_data[ (ss,vv,tt) ]\n", " sub_path = sub_path.split(\"~\")\n", " v1 = sub_path[0]\n", " for v2 in sub_path[1:]:\n", " c_graph.add_edge( v1, v2, score = 10000000 - G_asm.sg_edges[ (v1, v2) ][1] )\n", " v1 = v2\n", " seqs = []\n", " while 1:\n", " try:\n", " shortest_path = nx.shortest_path( c_graph, s, t, weight = \"score\" )\n", " except nx.exception.NetworkXNoPath:\n", " break\n", " seq = G_asm.get_seq_from_path( shortest_path )\n", " seqs.append( (seq, shortest_path) )\n", " \n", " n0 = shortest_path[0]\n", " for n1 in shortest_path[1:]:\n", " c_graph.remove_edge(n0, n1)\n", " n0 = n1\n", " \n", " compound_path_seqs[(s,v,t)] = seqs\n", " for seq, subpath in seqs: \n", " print s, v, t, utg_data[0], len(seq), len(subpath)\n" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "s v t type seq len path len\n", "000011445:B NA 000003425:E compound 2736 3\n", "000011445:B NA 000003425:E compound 2681 3\n", "000003425:E 000009719:E 000006955:E simple 84196\n", "000006955:E NA 000017147:B compound 26315 7\n", "000006955:E NA 000017147:B compound 26357 7\n", "000017147:B 000012473:B 000010757:B simple 601191\n", "000010757:B NA 000015636:E compound 16169 3\n", "000010757:B NA 000015636:E compound 16194 3\n", "000015636:E 000004093:E 000015696:B simple 1469288\n", "000015696:B NA 000016941:B compound 16458 3\n", "000015696:B NA 000016941:B compound 16438 8\n", "000016941:B 000003353:B 000008783:B simple 88381\n", "000008783:B NA 000006338:B compound 26074 3\n", "000008783:B NA 000006338:B compound 26058 10\n", "000006338:B 000004932:B 000010623:B simple 206164\n", "000010623:B NA 000014991:B compound 30158 3\n", "000010623:B NA 000014991:B compound 30148 8\n", "000014991:B 000013790:E 000002926:B simple 392373\n", "000002926:B NA 000011761:B compound 25736 3\n", "000002926:B NA 000011761:B compound 25814 12\n", "000011761:B 000003659:E 000014184:E simple 184084\n", "000014184:E NA 000012028:E compound 14792 3\n", "000014184:E NA 000012028:E compound 14895 4\n", "000012028:E 000013461:E 000011445:B simple 1447372\n" ] } ], "prompt_number": 13 }, { "cell_type": "markdown", "metadata": {}, "source": [ " Boilerplate code for using an aligner within `falcon_kit` for dot plots and alignment." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from falcon_kit import kup, falcon, DWA\n", "rcmap = dict(zip(\"ACGTacgtNn-\",\"TGCATGCANN-\"))\n", "def rc(seq):\n", " return \"\".join([rcmap[c] for c in seq[::-1]])\n", "\n", "def get_aln_data(t_seq, q_seq):\n", " aln_data = []\n", " K = 8\n", " seq0 = t_seq\n", " lk_ptr = kup.allocate_kmer_lookup( 1 << (K * 2) )\n", " sa_ptr = kup.allocate_seq( len(seq0) )\n", " sda_ptr = kup.allocate_seq_addr( len(seq0) )\n", " kup.add_sequence( 0, K, seq0, len(seq0), sda_ptr, sa_ptr, lk_ptr)\n", " q_id = \"dummy\"\n", " \n", " kmer_match_ptr = kup.find_kmer_pos_for_seq(q_seq, len(q_seq), K, sda_ptr, lk_ptr)\n", " kmer_match = kmer_match_ptr[0]\n", " aln_range_ptr = kup.find_best_aln_range(kmer_match_ptr, K, K*5, 12)\n", " aln_range = aln_range_ptr[0]\n", " x,y = zip( * [ (kmer_match.query_pos[i], kmer_match.target_pos[i]) for i in range(kmer_match.count)] )\n", " kup.free_kmer_match(kmer_match_ptr)\n", " s1, e1, s2, e2 = aln_range.s1, aln_range.e1, aln_range.s2, aln_range.e2\n", " \n", " if e1 - s1 > 100:\n", "\n", " alignment = DWA.align(q_seq[s1:e1], e1-s1,\n", " seq0[s2:e2], e2-s2,\n", " 100,1)\n", "\n", " if alignment[0].aln_str_size > 100:\n", " aln_data.append( ( q_id, 0, s1, e1, len(q_seq), s2, e2, len(seq0), alignment[0].aln_str_size, alignment[0].dist ) )\n", " aln_str1 = alignment[0].q_aln_str\n", " aln_str0 = alignment[0].t_aln_str\n", "\n", " DWA.free_alignment(alignment)\n", "\n", " kup.free_kmer_lookup(lk_ptr)\n", " kup.free_seq_array(sa_ptr)\n", " kup.free_seq_addr_array(sda_ptr)\n", " return aln_data, x, y" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 14 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plot the subgraph of each compound path and do alignment between different subpaths within the compound path. One can see 7 out of 8 compound path might caused by errors where the identity between the alternative paths are high. However, the path starts at `000006955:E` and ends at `000017147:B` shows a 2kb inversion. This appears to be realy bioligcal polymorphism in a population of E. coli cells." ] }, { "cell_type": "code", "collapsed": false, "input": [ "print \"s\", \"v\", \"t\", \"aln_identity\", \"aln_coverage\"\n", "\n", "for s,v,t in compound_path_seqs:\n", " \n", " sg = G_asm.get_sg_for_utg((s,t,v))\n", " position=nx.graphviz_layout(sg, prog='dot') \n", " figure(figsize=(10,4))\n", " ax=subplot(1,2,1)\n", " minx = 10\n", " miny = 10\n", " count = 0\n", " for e in sg.edges():\n", " yy, xx = zip(position[e[0]], position[e[1]]) \n", " col = \"k\"\n", " xx = -array(xx)\n", " yy = -array(yy)\n", " ax.plot( xx, yy, \".-\"+col ) \n", " if min(xx) < minx:\n", " minx = min(xx)\n", " if min(yy) < miny:\n", " miny = min(yy)\n", "\n", " #print x,y\n", " xlim(minx*1.1,-minx*0.1)\n", " ylim(miny*1.1,-miny*0.1)\n", " ax.get_xaxis().set_visible(False)\n", " ax.get_yaxis().set_visible(False)\n", " \n", " seqs = compound_path_seqs[(s,v,t)]\n", " seq0 = seqs[0][0]\n", " ax=subplot(1,2,2)\n", " for seq, path in seqs[1:]:\n", " aln_data, x, y = get_aln_data(seq0, seq)\n", # OUT OF DATE! " print s,v,t, 1.0-1.0*aln_data[-1][-1] / aln_data[-1][-2], 1.0*(aln_data[-1][3]-aln_data[-1][2])/aln_data[-1][4]\n", " \n", " plot(x, y,'.b', markersize=0.2)\n", " seq = rc(seq)\n", " aln_data, rx, ry = get_aln_data(seq0, seq)\n", " rx = np.array(rx)\n", " rx = len(seq) - rx\n", " plot(rx, ry,'.r', markersize=0.2)\n", " text(0, 0, \"%s %s %s\" % (s, v, t))\n", " \n", " \n", " \n" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "s v t aln_identity aln_coverage\n", "000011445:B" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " NA 000003425:E 0.97798972854 0.995151063036\n", "000010757:B" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " NA 000015636:E 0.99697456162 0.999382487341\n", "000014184:E" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " NA 000012028:E 0.98953722334 0.999261497147\n", "000006955:E" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " NA 000017147:B 0.9952 0.923473839967\n", "000015696:B" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " NA 000016941:B 0.995871782419 0.999391653486\n", "000002926:B" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " NA 000011761:B 0.990612686394 0.999612613311\n", "000008783:B" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " NA 000006338:B 0.99254387642 0.999616240694\n", "000010623:B" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " NA 000014991:B 0.992332352844 0.999601963646\n" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\nOYPd2zPyH44uswlIf0bOUUBy2L59+7j77rt59913iYuL46mnniIsLDB+LdWrV2flypV07tyZ5s2b\nM23aNE0uKRLAdDrnD545jo78mkG1shlqOQpBgfFJHKQ+//xzoqKiaNiwIRs3bqRBgwZOl3TJwsLC\nePrpp1m1ahVvv/02nTt3Jj093emyRETyzROOMjOhdkRJqte/jCYcNQEFLAUkB/z222888sgjPP30\n03zyySe88sorFC1a1OmyLkujRo3YuHEj9erVIyoqikWLFjldkohf8udWGn2Wu4bxp6S4wlH16lCx\npnZKqFJA8rG1a9cSGRlJWFgYSUlJ3HTTTU6X5DVXXHEFr732GvPmzWPIkCH069ePY8eOOV2WiMhF\nuewJICWoKCD5yIkTJxgxYgT3338/b775JpMnT6Z06dJOl1Ugbr75ZpKSksjKyiIqKor169c7XZKI\n31ArjX/SBJCSmwKSD/zwww80b96clJQUkpKS6NSpk9MlFbgrr7ySqVOn8ve//50uXbrw7LPPcuLE\nCafLEhE5iyaAlLwoIBWg06dP88Ybb9C6dWsGDx7MggULqBhiX0vuuecekpOT2bJlCzfccAMpKSlO\nlyRyfv7cSUi8zqkJIMX/aaLIAvLLL7/Qt29fTpw4wcaNG7nuuuucLskxlSpVYuHChUydOpVWrVrx\n7LPPMnjw4ICZzkBEgo9npNrBg5oAUvKmTygvs9YyZ84cmjZtSrt27fj6669DOhx5GGN49NFH+fbb\nb/noo49o27YtO3fudLoskbOpk1DQ84Sjw7syuLac5jiSvCkgedHBgwe5//77ee2111i+fDnDhw/X\nJThyqVWrFmvWrKFNmzY0adKEDz74QJNLiojPpKe7whFA3bqu02qSt1A/26yA5CVLly4lIiKCa6+9\nlvj4eKKiopwuyW8VLlyYkSNHsnTpUl566SW6d+/OoUOHnC5LRIKcpzM2uIKR5jiS81FAukwZGRkM\nGDCAxx9/nDlz5vD6669TrFgxp8sKCI0bNyYhIYEqVaoQERHB8uXLnS5JRIKUOmNfulA/26yAdBk2\nbtxIdHQ0v/32G8nJybRu3drpkgJO8eLFGT9+PDNnzuTRRx9l0KBBZGZmOl2WiAQRTziqVg0aNAjt\nD325eApI+XDy5ElGjx5Np06dePnll5k1axZlypRxuqyA1qZNG5KTkzl06BCNGzcmPj7e6ZJEJMBl\n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\nTIy703avHI+Ry+Q5TaNwJKEuIFqQcjp16hRjxozhrbfe4q233qJHjx5OlyRB5NChQ/Tv358ffviB\nOXPmEB2QhwDjAAAe6klEQVQd7XRJPleQLUjGmLlAK6A8rv5GfwM+Bz4CrgXSgPuttUfc248EHgZO\nAUOstcvc65sAM4DiwJfW2sHneD2/O4b5K09n7BIlXMFI/bDzz6l5PbNfF/+ZWNTXvHn8CriA5JGQ\nkEDPnj2Jiorivffey77ulUh+LVu2jEceeYSuXbvyyiuvULx4cadLcoRm0g5NqamuofxqObp8CkjO\nUUBy+/333xk+fDiffvop06ZNo23btk6XJAEoMzOToUOHsnDhQqZPn06bNm2cLslRCkihJT3d9cHq\nmcUgBD9TJYiEXB+kcylevDhvvfUW06ZN4+GHH2bIkCH8/vvvTpclAWTz5s00btyYI0eOsGXLlpAP\nRxJkLjD22zM7dmamwpFIbgEdkDzatm3Lli1b2L9/P40bNyYhIcHpksTPnTp1ihdeeIGOHTvywgsv\nMGfOHMqUKXPhB4oEidRU2LnTNTu2rqsmcraAPsWWl7lz5zJkyBAGDx7M8OHDKVzYr6d6Egds376d\nXr16UaZMGaZNm0bVqppjMCedYgt+nnBUrRrUrOl0NSLeo1Ns59GjRw++++47vv76a26++WZ++ukn\np0sSP2GtZcKECdx444307t2bpUuXKhxJ0LnQjMoZGa5TagpHIucXlM0r4eHhLFu2jHfffZcWLVrw\n0ksv0a9fP82AHML27NnDI488wv79+1m7di316tVzuiQRn0tNdYUjnVITubCga0HyCAsLY9CgQaxZ\ns4Z//vOfdOzYkb179zpdljhg/vz5REdH06xZM9avX69wJEEtr87WGRmu0WqZma55jhSORC4saAOS\nx/XXX8+GDRto3LgxUVFRfPrpp06XJD5y9OhRevfuzYgRI/j88895/vnnKVKkiNNlifiU59Ih+/e7\nWo50Wk3k4gR9QAIoWrQoL774Ip999hnDhg2jb9++HD161OmypADFxcURERFBqVKlSExMJCYmxumS\nRBzhaTmqUEEtRyKXIiQCkkeLFi1ITEykWLFiREVFsWbNGqdLEi87fvw4zzzzDA8++CATJ07kvffe\no6Q+FSQEeTprlyx5gdmxL9SrWyREhVRAAihVqhQTJ07knXfeoXv37gwdOpT//e9/TpclXpCUlESz\n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\nbt261UZGRtoTJ07Y1NRUW6tWLXv69GlrrbXNmjWzGzdutNZa2759e7tkyRJrrbVpaWl2y5Yttnfv\n3vaTTz45Y3+uXLnSLlq0yHbs2PGsfb1582bbq1cvW7p06TPWnzp1yrZu3dp26NDhjOerUaOGPXjw\nYF6/tmwzZsywgwYNyv75gQcesNOnTz9ru+nTp9trr73WduvWLXtdw4YN7Y4dO7J/Hjp0qL3rrrts\nnz59zvl659on7777ru3fv7+11toPP/ww+3UOHjxor7vuOnv48GF7+PBhe91119kjR45Ya63t2rWr\nnTdvnrXW2ieeeMJOmDDBWmvt4sWLbfv27a211n777bc2JiYm+/UzMjKstdaePHnSxsTE2G+++Sb7\nvl9++cXefvvtZ+y3xMREu2fPHmuttT/88IOtWrVq9vaxsbE2ISHhnO/VWmtXf/mlvevOO8+7jTjH\nm8cvtSCJSFCrXbs2NWrUoEiRInTv3p2lSz+nenX4+uuF9OnTB4A+ffqwYMECAD7//HN69OhBkSJF\nqFGjBrVr12bjxo3s2bOH3377Lbvlpnfv3tmPqV69Oo0aNSIs7OxD6q233kqpUqXOWp+VlcXQoUMZ\nO3asJ8xl+8c//sF9991HhQoVznpc7m3z4tnm1KlTZGRkULZs2bO2McbQsWNHtm7dyvbt2/N8jk8/\n/ZSJEyeyatUq/ve//521zfn2ycKFf+zfe++9l5UrVwKwbNky2rVrR5kyZShTpgxt27ZlyZIlWGtZ\nvXo19913H3D278TzXDExMRw5coR9+/YBUKJECQBOnDhBVlbWGe/16aefZuzYsWfUHBUVxTXXXANA\n/fr1+f33389oqbqU/Ss5BOFEoApIIhKwjDF3GGO2GWN+NMYMy2ubatWqAa7TaldcEc7Ro7upWBH2\n7dtHpUqVAKhUqVL2B+6vv/5KeHh49uPDw8PZvXv3WeurVq3K7t278137O++8w9133539Ye2xe/du\nPv/8c/r37+95jznfL7fddhtNmzZl8uTJ2esnTZrEpEmTANeH97x584iOjiY8PJzDhw/TsWPHPGsI\nCwtj6NChvPLKK2fdt379emrVqkWVKlWIjY1l8eLFZ22ze/fuc+6T3bt3Z+/7woULc9VVV3Hw4MFz\n7t9Dhw5RpkyZ7JCZ87l+/fXX7OfyPGbXrl2AK2hGRUVRqVIlWrduTf369QFXqAoPDyciIiLP9w4w\n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\nkVz+H2u0gdemx5O1AAAAAElFTkSuQmCC\n", "text": [ "" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\nH29rjcBSPel9AAAAAElFTkSuQmCC\n", "text": [ "" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\njUaj0Wi88H9a1PCNPEKs2gAAAABJRU5ErkJggg==\n", "text": [ "" ] }, { "metadata": {}, "output_type": "display_data", "png": "iVBORw0KGgoAAAANSUhEUgAAAksAAAEACAYAAACjyjIwAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsvX2cXkV5N/4dEgLsPJQK2WMRYrI1UAg/g5QikaKGgihP\nKolCeRNKSagVBALaKCZEWUnCawXyRN5UJLyIVBC0jWABjTSi8vKAtbzGms0PqHA2BMXMUiQyzx9n\nZs41c2bmnHuzm3v33vl+xL3vc+blmjkn9/U93+s6M0xKiYSEhISEhISEBD+2abcBCQkJCQkJCQkj\nGYksJSQkJCQkJCREkMhSQkJCQkJCQkIEiSwlJCQkJCQkJESQyFJCQkJCQkJCQgSJLCUkJCQkJCQk\nRJDIUkJCwpCCMbY9Y+xnjLHHGWNPMsYuVMd3Zozdyxh7ljH2b4yxPyZ1PscYW8sYe5oxdjg5vj9j\n7Bfq3JXk+HaMsdvU8Z8yxiZv3VEmJCSMJSSylJCQMKSQUv4PgEOklO8CMB3AIYyxgwGcC+BeKeWe\nAO5X38EYmwbgWADTAHwIwFWMMaaauxrAPCnlHgD2YIx9SB2fB+BldfxyABdvndElJCSMRSSylJCQ\nMOSQUg6ojxMAjAPwCoAjAaxUx1cCmKM+zwZwq5TyDSllH4BfAjiQMbYrgB2llA+pcjeSOrStOwAc\nOkxDSUhISEhkKSEhYejBGNuGMfY4gJcA/FBK+QSAt0opX1JFXgLwVvX5bQCeJ9WfB7Cb5/gL6jjU\n3+cAQEq5GcBvGWM7D8dYEhISEsa324CEhITOg5TyTQDvYoztBOD7jLFDnPOSMZb2WkpISBgViJKl\n9GOWkDA2IaVk9aUatfNbxtgqAPsDeIkx9idSyhdViC1XxV4AMIlU2x2FovSC+uwe13XeDuC/GWPj\nAewkpdzo9p9+wxISxh6G6veLojYMJ6VM/6X/0n9j6L8tBWNson7TjTG2A4APAHgMwHcBnKyKnQzg\nLvX5uwCOY4xNYIz1ANgDwENSyhcBvMoYO1AlfJ8E4Dukjm7raBQJ46P2N+wLX/hC221IdiZbO8HO\n4UIKwyUkJAw1dgWwkjG2DYoHspuklPczxh4D8M+MsXkA+gAcAwBSyicZY/8M4EkAmwGcLstfvdMB\n3ABgBwDfk1Leo45/DcBNjLG1AF4GcNxWGVlCQsKYRCJLCQkJQwop5S8A/Lnn+EYAhwXqLAOwzHP8\nUQDv9Bx/HYpsJSQkJAw30ttwCQkJCW3GzJkz221CIyQ7hx6jxdbRYudwgcVifIwxOZwxwISEhJEH\nxhjkMCRItgPpNywhYWxhuH6/krKUkJCQkJCQkBBBIksJCQkJCQkJCREkspSQkJCQkJCQEEEiSwkJ\nCQkJCQkJESSylJCQkJCQkJAQQSJLCQkJCQkJCQkRJLKUkJCQkJCQkBBBIksJCQkJCQkJCREkspSQ\nkJCQkJCQEEEiSwkJCQkJCQkJESSylJCQkJCQkJAQQSJLCQkJCQkJCQkRJLKUkJCQkJCQkBBBIksJ\nCQkJCQkJCREkspSQkJCQkJCQEEEiSwkJCQkJCQkJESSylJCQkJCQkJAQQSJLCQkJCQkJCQkRJLKU\nkJCQkJCQkBBBIksJCQkJCQkJCREkspSQkNDZEKL8qz/7vgeqhqoPB+r6EALI8+G3Y8RiKC/C1rig\nWxmNhjTM4162rPiv0zC+3QYkJCQkDCeEADi3vwMAR+k3OLfLuA0IAQhwcOjKocJDZLCvj8IIFJa3\nWHew5YagulvW9dMtm9CgcyGK/+OwL+4WDrtqArkffG2LvLjBeMb9ZZzJEOramrnKi/M8qzeY3svB\nMtQeYkxdP3Xzps9//OPAg/cKHHAAEL1PRyESWUpISOhs6F945RSE8igi9GNOvA4nTpZzANQhNWJa\nYfgcUF0zHKIow/mgPD8lik3sMqRD99mgAyGg5s7faKttWvZoMlFTLngSJWERwm7Lx02t4w3nuzJ/\nA/W0gZhX32jEHO+tqK+J1dGWEUdf3SOPBB55BJjSDXzoQ623OdKRyFJCQkJHgyoahujwCM+hBYX9\nxB0kWAEMyiENhvyEPL5Tzu0jz4uvWWZHZ4xi4hlvq2OqqihEPRkE54sRpkrHjpzlVRh911/3EChU\nfuX2MUIWAX3fcNNURfnxtKtDrbUc3LEtqiipolnGy+vMS6PqlKsYkcxz4KijgGcfE9hrCnDpVRzv\ne1+0uVGJRJYSEhLGDHhWKh6lOuSEP7SXouoNSB33QKuP5sZx10kZvgGQ/mpUhsGCc0dtCdjphoxg\n1XFsoo7ZzK+32SihqZsaH4QKXbptZFmgf9qeDn02DOVV7I2QzpjtA/1FvzwrGhUo+ueaSQHlPDp9\nV9q0Lmi4Tx9CY9XfH34YOO004NlngQOnA7fcAmQ99e2ORiSylJCQMCbQ5Mm7LieplRwS2kyUzOS5\nP3RVsa963m0/UNEQs3yd+t5TfKeEwfK9kfzfsk9Pvk7MloACUjsG2OeD15EUCKpF5IRPCaJlQnMe\ntcchL0IrRIpaNrlvOAdEl9Oeb24CRL0uvOuztxHZdsLTK1cCF14IvPgi8N73AqtWDQFTH8FIb8Ml\nJCQMKRhjkxhjP2SMPcEY+0/G2Fnq+PmMsecZY4+p/44gdT7HGFvLGHuaMXY4Ob4/Y+wX6tyV5Ph2\njLHb1PGfMsYmt2Skk2+kHVrIYwvfqZiXz3OjAFTq+uoN1MgVZaKNtz/jN4VQeVneYTQTwgJ9uI34\nhiHASZhMEGWlpvO6cTWxa5AohS4BLpxXDUM2x+yl91GDCfc1xbNi9vK8aMMKA/f0FP95Qnh6DNa8\nC1HmugU6Dd1ibiRTH1+2DFi2SGDTSwIf/CCwalV0WjoCSVlKSEgYarwB4Bwp5eOMsf8F4FHG2L0A\nJIAvSSm/RAszxqYBOBbANAC7AbiPMbaHlFICuBrAPCnlQ4yx7zHGPiSlvAfAPAAvSyn3YIwdC+Bi\nAMf5jLGemgMJrqVDKGJIxq84T/YVZSD0SB4I39GcFVM1y8B5mKTpF7oK2aZahuYdVeCGaajqEgun\nuWFI9dlqg6o0KNsy85kH5kavfZBl3vyjaDgOJCzmINRWMefVsJ+pIxxSR6YgZk8dD7LPt6a6VEii\nbsMxpppjVt4r5r7Q9z0x2nzNPH3lRTkzN/paq/8WLgWuvx7YbjNw9NHAFV9paWijFoksJSQkDCmk\nlC8CeFF93sQYewoFCQIA5qkyG8CtUso3APQxxn4J4EDG2HoAO0opH1LlbgQwB8A9AI4E8AV1/A4A\nKwZlbEMFIHgqdIJkTHPHsVXqURLi8cy1Cc3UmUZCeY2hSZIrEeQ5MACA91hFlZGu2c1UMlJOO3mv\nMkGJnQg3rdvRRIH4+HrUFLTMzfRbfZ4qsc5C4UBPuUyTFD1lTcbhK+CTAD2qVFGGXAdPM3OPFbj/\nfmCn7YHjTgR6e2E9AWzxvTeCkchSQkLCsIExNgXAfgB+CuAvAZzJGPtbAI8A+LSU8jcA3qbOazyP\ngly9oT5rvICSdO0G4DkAkFJuZoz9ljG2s5Ryo88O8yNOHIcJlwgU5KaOaDRK7HA7DB8ypuSlv/Em\nNNMkY49NGfezB1dR464R2sFRsuU2QAmEUZSqZkSdtAs112ZcIZs9TcXeRqw1IURUvBKWXYYKM6Fj\nMdCcrtBJn8Kn86Zo1jklaZZy5RDRjI7NIYJBXkhOuPfLUUcBP7kPeMtbgE9/Gpg7F2UOX08HsySF\nRJYSEhKGBSoEdzuA+UphuhrAF9XpCwD8E4pw2rBC9OXgUxzvUAlj+CqWjlPkAujPwbvtdqL8yRfH\nCWTfmqiXxxK7GQ+h436baoYUP+6zncT56oYUbNhRzJRgQtmQH9SBk7a1IucUs5ZCoCEqkYuCezRM\n0HdNoNMSIriWiblDhEi/+pxpUJEb6zq7YTZFlLzkWLenrlP0nqaDqoFeGuDnPwfe/naOpUuB2bPj\nHL4TkchSQkLCkIMxti2K8NjNUsq7AEBKmZPzXwXwL+rrCwAmkeq7o1CUXlCf3eO6ztsB/DdjbDyA\nnUKq0hXXXYoJfFtgwgTMnDkTM2fOLE+aOI1TieTVAJSoBCSPGLRn9SQVRbhEtQ+fCuMqGyEPpr/7\n8ohCY6gZmyYeLXlL6qxVLlGtKT4Jxyno5QDmoCIsPCvJma+yuhd88xpSl2I5VBV7Yie10snLNwtt\nZZAUFzkU44v26WNxwrn+Pk5Mqz/5ZLEq99q1wD77ACtWANOmlQUMgWwqsQ0DVq9ejdWrVw97P6zI\noQycZEzGzickJHQeGGOQUvpyi5rWZwBWokjAPocc31VK+Wv1+RwAB0gpT1AJ3t8A8G6oBG8AU6WU\nkjH2MwBnAXgIwCoAy6WU9zDGTgfwTinlaYyx4wDMkVJWErwZY1L+6ldGGfEmezseQ4ADfevAu1C8\ndYSAk2kQliscr7PtBlWsGkT2rNxcd3uNVtsW/hW2W4kwmjpNl1HwyFDmkFPXyUOuHtTwkSVSztrO\nQyFXK3ZrzlqqivbgKwnzkTCZeeNREZeK0hRRv7yDJoXKBG3n4oQy+omdIldvwGXcmmu93UkoDkcP\nrVwJLF0K/PrXwLvfDdx/f2BsetyBdbe2Nrb09yuEpCwlJCQMNf4SwIkA/oMx9pg6thDA8Yyxd6F4\nK24dgH8AACnlk4yxfwbwJIDNAE4nT2mnA7gBwA4AvqfehAOArwG4iTG2FsDLCLwJR1HxSTGSo/UH\nl0/VdRKCG8NRx7bEsXCt6tQ4wOFCy6EsX+yuUUf143Knlh6sJYLOCUOE9VthhmzY1YJh0Rh8ZFZ3\nSufFl2NGDKTqlyHN+n4QpD1LYauS/MrcqAOXXc2xfDnw298Cf/VXwHe+o23VbZULQxT9Ygv+cYwO\nJGUpISHBwnA9mbUD9Dds3briWA9ZYTikNFElqZaH1HnjgIJlhUcGoezUVfYqPw1VrYoDrjOyicpG\n7XFUicYD96g8RlVSx63QkC7rOx8bg2LWAhy5sOu4ipGr3AFE/OlxrjGZ0+iU1cy1yEsFjbZbUXdc\nUkpDwgF17pLzBW66g+PVP3D89V8DN9zgtyu6ZEUbkZSlhISEhC1AXRTDKpuRwgLR/JBYaM+rPtTF\n3GgZb3sItkfH5vWzTfdV84WG6mytg3sBeGa/499q8yakV6gpeuFFN6+Mq6zolvb1M0oPwIV/1kpF\nxXPNNgigi1fqGLUnNi51UggAeZUECfV2nEXeiPQZnTejOPnvp4+fw/HA3cC22xa5SsvOziHWAciy\nCqltd7htayORpYSEhM6G8ghmy4+8PNWYxCDihNwDTp5KKHmWHjO+zuEOpUIxBHa1UNk4xhiJadiX\nR7Apm46F8ny5QrxKW/RxI6a4iprOYyJlrG5y20CTA6bbhyckFhqvOp5NVHEyQjhrL0dEcawYTkiX\np/uyvi+PSBBGJVSOkwDO/nuBH/0IGPdHHKefBfzjaSoU6eloi5TQUYpElhISEjoaIrfDSa2EDXxv\nUPmITkkCyid8WsYNX+hISAWu9+G8SjAiyJCbT1aoC2Qz1iYObgi8YDAtKSvmtFCD4nWVuOMHIU6u\nELZhvbDnmHNvWFIIoL8f6NJ7sZHOzBQEiEm1YGuoI2mFORwD/QLdKlnbdCeEPTEBxaeO1OgcpA/M\n4fjlz4FJk4DPfU7g6KNVgSyDHjy9lyjJanJfdgISWUpISOhs1Dk7IOpVdC5HltkOwqpHO+D1r8OH\nHIx7TK8XNBgIAYh+Ad4F7/I8hkA2CbmpCnbIsZkdvrkIjkkRPKGXaXAvXYO8KU7eevSWcSaiq5vb\nxChgO7WvlnRyvV0IvCTItkcZm3FDpnXfFUXIa5SnPW4TYyEKlZJzICOK21NPA393OvBf/yWwxx7A\n8q9xHDDNDSt6hke2txkrSGQpISGho1GGYwIFImTBOCzhOeaUixsR2R6jrip5A8kHS4XhZEFCFXbS\neS5EXAujSaK2KeIoDtz+bL05RVUJUjc0Ji+ZJNfJTZbmVKZSxBawc7SKxPL6fkJES1+/8EnSoJbE\naGOkjEW4PPKMPlSMgzCepmSNjM8dk/589+3ABRdwPPsCx3umC/zgB5pU8/JaCluVLdXKSKJ8hyKR\npYSEhM4GdTCeTczKH3//Lz91WJUSrXgLJwcn1NRg86Z9x63Xu1ttYMuKRhHLs7LCTE6B3Gx03FAN\nq/RZEgFXIbRIgQf9fQJsQGDyNFvuoiTY5UxeJiZUYJfGcT1htMocRZQeCPqGXHWNAw6gR72ZJ3KB\nq64C/s/1HL/5DXDE+wS+/W2UBM+1tekcuyyzw5hUIksJCQljG1ug+lioYTnRtgmRqvinGqOsMFeN\nClULn6d2xhVT1ax8GarqmOPE4duxoWa2ceK/1XXjIrcJByUe2hbt9yHUC45VZaaOpHaVwcyyTl4Q\ncZ4pAhVSpdYVsTW9bEJhf7h8MGrnvAnnL+QfiLb1iiuAb34TEJuBD38YuO5yf7+G7NF7QpQbQ481\nJLKUkJDQ0bB9R9VDcv2kX5EL4PdKotkaQSFloFJalE442K0ny7tSluS/NLEvCrfxBqTGG7YhcJc1\nEAIQAwHzIiqfLxzmmut7I06b5Ua9KPHyQhXMpgA+plJpi6piPrUlxC7Dh8IDVchF0W6WodJnqWQK\nnHsu8J37OMaPB045Bejt1WOKdCcEIeHwhg0tmwabZDfCkchSQkLCmId50vfBQ1TCjbQOGgasbcEK\njVRVn1CoptXQXsWhB6WOcMMWiSuOGCKhNuMAn9ITF8E8ChevkA1eKlUBR00Ja5YVbEs481c7N5yX\newYqcuVTqOwxq6o9mXXYI9hZ9UJbhzS6fh7JTAjgtH/k+OEPizf/Tj0VOP/8sktvtE0IiPUC6OLg\n3SjvgxAZUmzYbCsTWe5iNCKRpYSEhI5GaAVr89cXhqOJLb42iXric3puQq1XKdJ/BYrEbE+5sm1e\nsYl+ddWcmFOtc9iFz+P2Hmo8q3XUFUWJTkKeI+PcWlfJcLA6Jue7BnruqYLEudn6hebthEKstcSj\nAcP0FtH3Uy5Ku5o2WVfAVW+06qUVJYFKXc6B448HfvQIsNtuwGc/C7M0gJcoUQI5UTVQs7WNNccd\nGqZLZCkhIWFsoRKz8TgZmjCrHQAlVe6GtmjNR5g6pp7f0YXInUGFMQU6EqQ8OWXW+skiyopjgzf8\n57RtgRI99blSUo2hshYUHV9dXlPTCxGYM2GIVkRJI9eBcyCrCd3FDnsvV0BRakKyxJN9RZlpU8wY\n+/qAo0/meOYZYNo0YMUK4IADqu3qzy7pA13YM2oAVHwVGGG7nwwZEllKSEgYk7AIC+j6PqpAwFHX\nbRki1uXAgACfkpnQjchhO3vViQ5Z6P4tBUTnikQcVEBoiILW8ZV3OUmrQgGdV3MMvJgTEsKyxqfm\nWh/XLNJSKnwhOVfxCIUMCwmrJMA+o4UABoS6VuG3IyvNKrg7t4TMsHiaE3az7HEbIce817urC2IA\nhhj/8F+BCy4A/v91Agf8f8C//ICHmvNCJ4TrAta/C8+4Oh2JLCUkJHQ0aveCM85Y/REAwIvt4PR2\nD67DIEmxFRVgAABxWj4/4vr/GCHwhnEEWQacR97mq9hNTqEkJZa6FsqDIk2WDj+iwrjo4nZfbqOc\ng2uyFO4w3L6aB/flOAM6RlclgyZekURvbUvARKuf/hzoQrnuVYiQmOvvaScCi5Bq4rhPj5nXq68G\nrrmGY+NGYNbBOW66qdp4iCzRsRVkFdb1opdiLJAkjUSWEhISOh6Wc1dwf+i1Y6CpSly/fkUctft6\nvvmu60xxWFmWgQsBQdowr5IT9YRrpxTwYkG+IMq9y7xVQ6QrlKviVomRtpCIU3wqj2W8/C4EUc88\ndX1OXTikM+Klg7aZufZUonPnIdXB0COpb3K88vJYrQrjI+G0C71Vj5uM7skh0qevvhq46ipg0ybg\nyCOBL1/CvWMOTqFrk74AZshjiCERJLKUkJDQ0ci4MHuRAah9HN7Sp2VvLkoDYaRSOeBoOQcEslLw\nikghQcVJNabnhRP1Ru+H10QZq3YWOulUpoy0xeqx8pwX11t9s8vy+BtvUbUo0KH3WoMD3T1GmRQC\n1ZwwNf6mypxL8kx0mJOlGgRw9tnAqlXAhAnFG2+LFgFUBY2OTzWsibfvvhJKaM2QK5WOvgUQarQz\nkMhSQkJCx8OXyGqt5u0kc1Clpr9PbbSqiIlRgmjDDQiC1U1PJA020JYhRipMWCkvwmschbqgeTY0\nb8aKCnK1Yva6dUWZLLPPN+uyWpbzImdLQClv8ComlurSQN2q+241QEKvQoTJVCVUFUjEjvbndF23\nCGqxSnkOM+5AHFnPw9y5wH33ATvuCHz848DChaQAyT1qAivZ3enI7HlH7wH3e2vdjQokspSQkNDZ\n4PTJOiDxBBwBALABz69/KGQVMaElOLlLIhcQG4pNcdGdubxh0I7JDQmR3OpBmBqoRBJzKmVFWYbH\n2qgLZ7VYtgztkcR+lDZQJdC1OSfpYr58OHdOfeJR5a2/UKgzsGhn2V+x8e4xs4DHHwd23x1YsEAt\nDaDb1Eb2FAsf5euK45ne/oR27TIehVxwYADIuqH+LTlqFXe+dyASWUpISOh4GOeiiRAvlATA8xtf\nSDgmTMKnqRKclPZkuTZ+oq6N92hnLqr5M1286tBoWMuxxZyvC7nU2c050NOjxTWzoLdVJ5BJr8di\nEoWL+BHAeRkyC8Uu6TkR2ESWlAvmFoXmxXws9w0MhUzdxGfOyyG3iiYhvqKT+KKdDz8MnHEGzNIA\nX/kKsM8+qklFippuT0JNsDYd1vcP5wCvhk8bK3mjHIksJSQkdDS8T84uNGEwlSKNWLGrMllZ9OUF\nmaEhNseR+5Qbd6kBo3SQcBXv4eCZvc2KsM0A+tWr+VlmRqIJQJ4X3zMuvKSKC713WbnSdDDJWwig\nXxRkk+biVFNcrLkt2/KQkWHwsDQ8ZPy7unbcXCO//ZQIuiFLygVDb1hWtlshcJUdqxMEDnnI1G23\nAV/4AvDrXwOHzqCb4TplHRusflFeX01EfQbQhw1zLkAmE1lKSEhI6ASIwBO3wxB0SA7E6Zqi6/uB\nibYz5CSvSbfha9o4Gn1wQJj1cSxfV7NqctWxZQgzlnB9KySV0/okhOQSCV9Pmmjl9vhdkipyRPNo\nfGG94hgvlTYrEdmuZ312jN0SR+6rG1OfBtO4j3AIgfKtOHWDXHkl8PUVAm9sAg77QIY7bvQ06d4/\nDdmMS/Tch41OJUN1SGQpISGho1GJWpFztWsw6Qbok3SWWU/YJbnxNEJCZDzgaIqlBuxyITv0+kp5\nzjEwAHRP4Ra50qFFq38ocYHElwwR1MgU0dJhMlKXfi5JC1cbEAvoiREOaanOu7COV0Bym3zthKCH\npbmXqwhZZfW6R55uK3lUjg1epUfDCRXyyIrodQuRe0Huv4ULC1Vp/O+BWYcILL/RVgp1ojpHw/ub\n2r8F6HQSlchSQkJC50N7U6AaB9NwPaImDk5uEkDDOB6EQioueSBtxiJSlgnkOBsQxaKZFU/emuMq\n2iVqQjUtpSVoRcIlS3aHYQN99azL4iofyvqS05YX2lW5GtnvKyrI6t+ZJ9QVqxuCpw2OKvOjytzH\nPyZw993AH7bnOGEuxxmnCG9+VdOBmXwydd5VAWk1b2iRJrDpNckCfY12JLKUkJAwNiFEobhUJBD7\nh14MqMOBZsri1ZW0jRJDw3OhlmIORtfNMuMczeaphIjRJiqqAiUp7lC1adRxekwKmRjzkXR+YnC3\nkTFzFgjX0fYt/uUhSL5Unqp9jj20vI/wEZvL+axZy0kTDj22FkjF7NnAw6uBnXYC5p0FnHZaoSK5\nq0i4gqAvYb0I7TnZ6Zx7y0aVQDVJeX9xqC5yPJqRyFJCQkLnIyhzRKqoZaMFyqTnSpPBJBMEvUzI\ngcVM960qXafQNLXHOjcISamVsWwpfOpG3bCsfLHBghdJ9n6jBPr7AdnF9dv5+nDVPjeu5xJzd0kB\nhfe+F/i//xeYPJnjwguB2Yd5VJ6Abe42NkKRej6glqLQbJoQykgk1oZm7XmsUGcgkaWEhISOhz+P\nxnFKEXLTtN2KamFt0NvQkbhvntEwoEpsNg4v0mS5knXYXjefiIYF9UaqQYes1RVnA9lgZ03hEgq6\nsFGT5kn+jpWY7mxT4+06D+QcCVEIMVwtd6BCT0WeGDAwAOzQVT80M5ec+xd+dPDEE8CpxwusXQvs\nuRfHzTcDU6YElm7w9WfK2Iy2OJ6ZQtQWqsKpoYeJkiqQ0TU5OhSJLCUkJHQ0LOWDhqFCSbrOdw6E\nPbNPUWqAqJPz9GUOBdlO9TtN/B5SqPCN8MhdoWmqVVlC7bhOPtOb5QZCpooECwH09wPd3Rye7f22\nPLXGInLAxMnlqua6cbOFTCCvrDpYe5HKf/1X4NwLOPJ1wHumC/zLD1BeVx0bJIPy3s50wMoGoslV\nTND/LnRdizQ5YdLyGnmH0nFIZCkhIaHj4cvlCMEVdoDq83KtUwg4QF+yeLWaneMkeGZSk3QhzlU7\nbtiErtbs6SPM9TxlM+JofZUDbdafqCvu1Muy8FgiXXR1OdU4j15ITUJMLpgojwtRLFtQtEeunyIW\nnBKyRqP1zC/5fPXVwDXXAL9+BfjgYcA3vuIMQ3ElLwIxNDefTiPPC2Wsu9upD8DKFwvLkkT5jA55\nVCORpYSEhI6GyP2hDhrKqvXrAanE2iNsqB6ntVMnyTZl4nCA7QibaNWRuSYKgNAqA4Q9zqz6+j3g\nzydyzaw/6J4KkSTisKlqQvmBWgqBLvBpJ207cpMHMRULgD80SO3g3FZkAnZTLFwI3Hwnx+bNwEkf\nFbhiqVMucPEGE+0UAhjoF+iC3tQX3ixtY+6A2qsusD9gJypKGoksJSQkdDQ2bEChxABlyCIXEP3C\n3j4EVpHKZ1+Z4IO0r2KtouRRQqCdbLyN0nGRc3Uhu2DHKJUVc651L9hCxLB1bHHGNsrOFbu0yIz+\nmxdkkWceVQpxohAy0eQHeUjtxz7Occ89xfczzgAWzgeAcl0sNywZHBMxwurDU6+7G9DLWBgVjTv8\nTBPGLs8qHopVAAAgAElEQVQ/jqG6FiMciSwlJCQMKRhjkwDciGJJaQngOinlcsbYzgBuAzAZQB+A\nY6SUv1F1PgdgLoA/ADhLSvlv6vj+AG4AsD2A70kp56vj26k+/hzAywCOlVKu99kzcTIvyRIBh/A7\nkBZkmcZ+voHT8vbvYRbR9CnuP+e2b4iBILZxEv4T9uKYjcyN5UYJAdGnlCcT7inHOFjiFHp7TM+x\nJiaGeHKnLjwcyA2htiCZhDgyDeuZgxlXq5kXX2fNAn78Y2DiRGD+fODMM4l1wmnQ6Wgw81c2U18p\nVlaTvjoON9qRyFJCQsJQ4w0A50gpH2eM/S8AjzLG7gVwCoB7pZSXMMY+C+BcAOcyxqYBOBbANAC7\nAbiPMbaHlFICuBrAPCnlQ4yx7zHGPiSlvAfAPAAvSyn3YIwdC+BiAMf5jNGLUwNwvEoGQRNwMUQ/\n9r4QXaScdsqVnJcaD+jNraKExcMgTGiNO2WoM3YbrknEDjlJ07Ta+851tISr1Y7P17jVt1PYbN/n\nbzpsrO5YiGCuVKWaIkLuNQiqkp5lD/TSAO94B7BiBfC+9/nNC27+7MKXM4eaOVUkOhSyRp4Xypa7\nHLhWa7dEKRwFSGQpISFhSCGlfBHAi+rzJsbYUyhI0JEA3q+KrQSwGgVhmg3gVinlGwD6GGO/BHAg\nY2w9gB2llA+pOjcCmAPgHtXWF9TxOwCsaNnQ0I88+bX3Rq6IIhF81ZxUNiEUR1EKRi9IqNB89ag8\nLZEMU9inSHB7HacmoULSHg3VhFQzMQBgonrVnnazhQ7WKB4uGdbt9pTX2KQImW1XQmymyi4aqWe6\nXAOFRbf35JPF4pJPPw3svTfwrW/BWqvJsiGyXESdkqgLhXO049KQEAAGAN5N7k1CxDqVIFFs024D\n2oF3vOMd4Jyju7sb69d7lfutgr322gt//Md/nOwYQXbsueee6OrqavtcdAoYY1MA7AfgZwDeKqV8\nSZ16CcBb1ee3AXieVHseBblyj7+gjkP9fQ4ApJSbAfxWhfkq0ISGJmKYjxk3RMf3g5/n5TI/0dQM\nV4Hh4TYNnALcbNxRbdK1h1b3Ji0367K+UI1c0KQ93pOBq1frXRtj9Q2xyfPyGvr69tiYZWqdKUJ2\nBvrDc2NNG+elekLqR8kt5+ZeqoUotk655RbgpJOAZ54BDjwQeOQRD1EinQ9KuXEMD86307gQ6t9N\nLsr7bUpWbmnSnxNiqsO2hHR1IMaksvTcc8/hjTfewMDAAKZMmdJucwAg2eGg3Xa89tprOPjgg/Hc\nc8+11Y7RDBWCuwPAfCnl7xhj5pyUUjLG5NawY+mlSwEAE/gEzJw5EzMPOKA40SD0VpePwTNur8Pk\nVgasxOFYQrC7TYc318WBz7ZC3bHLGAWoQe6TbVJxMnPLOZVCipI5r/dTy3M7kbo0sJ4F5Hkxrtiu\nsDFSV2enzw5DhJoXb2LXt1YKLP8q8NImjsMPB+64I1CP1K0Tj4xyxsuDZS5azfVuEG6kyivXBo2A\nZKXVq1dj9erVw97PmCNLTz31FDZv3gwA6OrqwpNPPonJkye3xZbu7m5s2LAh2TGC7NA2bLPNNliz\nZs1W779TwBjbFgVRuklKeZc6/BJj7E+klC8yxnZFuUnCCwAmkeq7o1CUXlCf3eO6ztsB/DdjbDyA\nnaSUG322LLt0mX2ghSff2r1BXfIhyjCPNxzlC+uZYw4BUZva0nIVkiXKoGBxvkWnVUdUGrZXy3c8\nylsjaLIClGRS9xfIy7Hquh8DhvpCljTcOlgu4FtOYf5CjnvuAN54AzhmlsB11+leAvZpshQIpepq\nFmexyHmDFxEi5LdS11Ue6fc2kKaZM2di5syZ5ntvb++w9DPmwnCf//zn8dnPfha77757W4kBADzy\nyCPJjhFmxyOPPILddtsNu+22G9atW9cWG0Y7WCEhfQ3Ak1LKK8ip7wI4WX0+GcBd5PhxjLEJjLEe\nAHsAeEjlPr3KGDtQtXkSgO942joawP2NDaQ/9NSJB2ItjXw7bUuI6vGG1Svfnc7dcq7fCglclhMl\nylWQAKqGsiwu5LQET3jLZ0hwyhxjvJcuNt95Dqxf779OHjtiCJHeuks991iB760snhFOX8AVUaq2\nbdoJ3VcO9NS66h/dviTPq+26od+gHaGDZM4a3uqjFqx44SRwkjEZOz/a8Oijj+LII4/E2rVr0dXV\nYCOfhDGLW265BVdddRXWrFkDGj4aC2CMQUo56EEzxg4G8ACA/0CxdAAAfA7AQwD+GYUi1Ad76YCF\nKJYO2IwibPd9dVwvHbADiqUDzlLHtwNwE4p8qJcBHCel7PPY4v8Ny50NzdzkH1ddqIsa+Ryvp7D5\nCrt9fVI/0YeUmpiCE1sUMmhHjVrmK9hS7ozOt1FuuQwtCpXs7YQcQeZERJLnUV5Co/4JYat6biXf\nHnMN5iOuBsaPUcw9VmDNvwn80Y7AvLM4TvtHf0GrncEqck57VHkqVyivtusSdnMqdH/rsrEXHbYy\ntvT3K9juWCJLRxxxBI488kicdtpp7TYlYYTjD3/4A971rnfhoosuwqxZs9ptzlbFcP3YtAPB37A6\n8kAdt3De8hJkU9XMV9kmRSIvyILlSHT7ulzDxGDTj4/MRby1S6SahM0oGQmNzduIa6dLllQZzj32\nEw/tdcCkbUOQOKw5MXAdurA/0Dk3XaPanncJiBYYY54XidxPPiwweTKw+CKOD37QM2Xufdawr5ph\nu9Na1snz4ruj1vnast7MtE4M4j4eZgzX79eYyVl64IEH8Mwzz2DevHntNiVhFGDcuHFYsmQJFi1a\nhCOOOALbbDPmItYdjeCChBo+dccTYyicXL3PHBgARE5CJSYfZPBxC7WHa5CwURstogJKTuw6JRFS\nNqt8F07GznUDNCHdJTEg4+QcXKs+RMmrmKyJay6gE4ViYkrleFNJw4zFo/ZpVkEYRqVZcq5OAezr\nA+bOBZ59Fth3X44vfxnYZx9Pe74tVVqVu7xjJNfLBeeVfwAhpVGo+8QoouQ+AUYGSRpujAllSUqJ\n9773vfiHf/gHnHTSSe02J2GUQEqJGTNm4JxzzsFxx3nXO+xIdKqyVBNdqiBIljzkQiPmu7xP99qe\n2P5jtH2lVIGXIawoWVKOjj75h8bj2mh9d0ldIGypCURlrJ4QYcVkJWWZMJwmlBH1y/QZUj4C9bTz\n181YY/TcIJXQGBmrVYWoUXffDfzTPwHPPw+85z3AqlUe063VLMncaEUTzkR6xh6bm4oK6ElAi6pa\nqoBZV0krk743NwE7NtomJGVpC3D33XfjlVdewQknnNBuUxJGERhjWLZsGT7xiU/gqKOOwrbbbttu\nkxK2AoJ+iHN/3kuojrC3ERnqXA47VzqcK+KSM+uLU4naadscUCZ0c+BqUUrhD/V5GKJXsROeXKYA\nKkPoJ1Kbh9AA8C6cacZJ58dli7Qzp661BlR/DnRxfOUrwM03F9XmfAC4/rbwQOiWLeX2LLaNLZFB\na4K4bX+sqLKdbpKr+3KXTjCXE5F/Lx2GjidLb775JhYtWoQlS5Zg3Lhx7TYnYZTh0EMPxdvf/nas\nXLkSp556arvNSRgMdI6KOUDzXQJP7k79MgzhB+UCpVIRhxUWC4Qxqo6Im1WpI4UqnZS5OOGqrYoX\ntKDIiw2LgYqft9twfbZPhlLI8+KQxUt9io8o5k8IrqKKpdJE2+EceG2DKFairlOtHHhDcdr8fgHe\nrchOP3D5FcDXbyuWBvjwh4FLLimHSNvT4VGh5oWSuEo+mEN2jIDj7HlYUbo0V0Km2rULiXW5+siB\ngeoYS7Lvv6CV6WujojTc6HiydPvtt2P8+PGYM2dOu01JGKVYunQpjjnmGJx44onYfvvt221OQovw\nOf0KuSGvXUcdqEeJCYVi0OKbQa6dlEdEK/jaCDnbBgbViBDeChwAJmemvsV9SGjKUsCEKJJ6urps\nNQj1/NUKUelDvCQE1hpJEEXOFOcQkZegfaEvQ8ZC4al+AF1leOqMz3A89qDAhB05TvyowGcWAN4V\nLe2pse89bm+wCzhkWggM9Av0D3Bgoq0wmvuF82KjXmW/IT5qEdXiBYWS7HAIoJuX18GQzcEy6M5D\nR5OlzZs3Y/HixVixYsWYe/07YegwY8YM7Lfffrjmmmtw9tlnt9uchMHAjbMQzyIEB2KkhISMhNmg\n1U9GuBOyCAknvnSfykmQ8J0T0quOrQaBMl7FxBc+Q8RPEpXGjBfCVj9CNnZ1VRmnghEpfPKXmlRK\nYnxkuLhOhIR1exQlESAGniLukg+8W53PBT56EsfPH+T4kx2BT3wCOPV4QAz4lbaKvSjmXbfrfQGB\n3Cjd3YBU94NZSRuwQqC++TBf9Pz0ZMb+Sn8+RSkAY5pjRyehoxO8r7/+etx88824//77E1lK2CL8\n4he/wAc+8AGsXbsWO+64Y7vNGVZ0XIL3pk0VVkITjml+TCj3SB+sKDekiC8/SYgyT8Zs+QEE+xQC\n3le6DVnStjlObKge+GlujEvOrD7IXBZv5XF7+SKElx7w2a3HF9yQ2GWcoQG7kymElRMUNCIQCqw0\n65IlDuTrBP72b4EfP84xaRLwhS8AhxxSmhAkyp6EcrrulmuWdR8FDeTx9bYC9ZrkiHm6qhwbCWQp\nJXi3iNdffx29vb345je/mYhSwhbjne98Jw477DBceeWVOO+889ptTkKroI/aQiUhh/IuInGo0kE0\nC28Vzi3WjsffO6pC0YVSrFqOkbWG2JpCMZWhyjM4Mt+msE6zvoRrt98tYoB16gidT0WsfGHEQpcs\n14rSfPGJJ4AzjhVY9yvgne8qErvN0gAiMjbXBpVY5b4tOEDziIgiVB1CSQabdOeWG0wdetAc7+Dw\nXMcqS8uXL8d9992H7373u+02JaFD8Mtf/hIzZszAs88+i5139m5w3xHoSGVJeUCzMawTKgNs52j9\n9SzaV3EaNcpEK8jzok3rbTfOK2pWS301JB4658py8k1UnFg7+phDxLx90QZ0mLQF1cNrR6CupfpR\nJZBeSq3UkIOcA8hz3HkXcMV1HK+szTF5L45v/iCz7iHRlxe2d2fxW4OQJX3RhQBEXw7eBXMspnZG\nw27OPDS9XSt1XGXLp3ampQNGFzZt2oQLL7wQ3//+99ttSkIHYerUqTj66KNxySWX4KKLLmq3OQlN\nwbkiIKg8mVPHUf7wt0hCaHiPOpgG4RBveccBFo5I2R9rI7KB76AQyZMSKhUoSEKEVwSxUKu6mPhT\n3MaysRagc7OMWlOGH6PqiTr3la8C118PvPQ74IiPZPjyDeSawb4nasE50FOV4XgXrD5t28vJr+O0\nbtW6Mr4K3KdquR0DyPuLv534UlxHkqXly5fjkEMOwfTp09ttSkKHYfHixZg+fTrmz5+PXXfdtd3m\nJDQFrypK9BQlSxpGhdI+ga51I5RSosNIRgZqMVLm8V5FezqmUh1Dpb7wn3Of+usITqVS3UAcB0p5\nYzGn9kn37bXatnU9QwwaxIqcHKUoF7O2NoGfGHqUrwWnC9x1F8dr23AcdRxw5ZV++zlXS00Mgrty\niOJtNnD7mlEVyjM4c9i5r1ohVEGbHNJv2qKhw64OZEkKHUeWNm7ciMsvvxwPPvhgu01J6EDstttu\nOOWUU7BkyRJ8+ctfbrc5CU0gBLKAutNK3obbpq4kgII0GemKm3N1sPonNlaqNvFyTRJPBHHCbhVF\naMq8nfqFLt2wy0C/KF5wG6oE374+iJcHgL2mVcOkNERHx6cK+sKrJSEiDl7AvOVII68+5euoo4Cf\n/QDYcUfg1LnAggXluUZ75dUfjpJaUyFAlHT9YFUj09nj97VT9hVozAO98oAbFuwEdBxZuvTSS/GR\nj3wEe+yxR7tNSehQnHvuufizP/szfPrTn8af/umfttuchBq4P9yWk3JCTfSH3n113SUAXDWic2/M\nca1U5SU5oQZY4bloHCsijTQo4x6m4xN6TD0uaSrJXiyMaPKNtJIjws6/FTmjUrSrC0CXt25FZOFa\nUSrKah5HSYRYn4NP5MU1cW4M/bG/3zmljJo1C3jkEWCnt3Gcuwg4+mjSriIoW0wQnPCgcMZAr7c7\nPl29Nrzp1A0RG28Totz6xEvYPGSsU9BRZOnFF1/Eddddh8cff7zdpiR0MCZOnIgzzzwTvb29WLly\nZbvNSahDE8WFlmsxVlE6Jx6Mmll5RTpxOdSt17SwLRbJQ3Ufr3K9o7IwHxBAd3UPC28ULjIfgmdm\ns10A6Oom60zRBOAWk9NNvZ4e561AMheuz3ZCje68gnPwiVW1jHNCGj2mCQHMmQM8/jjwp38KrPg6\ncMAB7hgdlYvWDxw3tjmhvmjEsSaB2laXnOtG6wq7Tu2tHgnJurdHk4jpaERHkaWlS5fi5JNPxqRJ\nk9ptSkKH41Of+hSmTp2KJ554AvtUthFPGGmgT88+Z0kjZ9y3GGKoUc95y6kTx649uVaUgv6H1BNk\nK7pqeMSvtoiBsMmWQlETKqNvPfnacV+zd1UFQ+Bi/Thtm+R2vYK0u+4SmXOac+SdS1/eTg95xbAm\nnAUhsGYNcPoCjl/9CtjnncA3v1nNxTZKYphP+Mzxg7AdEwoFUZsIQknUPsXJRaguHUOeA3wgR9ZN\nGuPFdjvB1LZOi70RdMzSAX19fdh///3x9NNPo7u7u93mJIwBXHbZZfjJT36CO+64o92mDCk6bemA\nTS9tgg6z0fCV2d4iJCdQh+rzdIFQ2FCEo2q68BcE/LlIW4CKMhQIJxqFxN0qpM4Wh2GYDXlJOz6y\nVG7cS/rXfeky2iZK1ipyk3Oc4JbrBC66CHjppUJJ+udVg5zbVq4NscuEh525r7snYkPzKVm+ukIU\n4chuKLLk2Thaq1cVEt9mDNfvV8eQpVNOOQWTJk3CF7/4xXabkjBG8Nprr2Hq1Km46667cIDR5Uc/\nOo0syV/9qpRmWiFLoCGUgOcfpPo0WESJWCNWVd+oqxoEnaLPsQtPmKgFslDnzGm54HCDsoenzUBD\ny5YB11wD/O53wJyDcnz966RuhX00GZRdJkhCG7TnM9nXnlVOhX+taxAh+I2XvRDCrsN527c6Sess\nRfDUU09h1apVWLt2bbtNSRhD2GGHHbB48WKcd955aU2vkQzqeIiHCUR3zAfqbBo7yCEiRzHS4O2i\nCYlrLElUSZN3rSPCpsp1eBxbVZJ70603OEDWagjbGx9CmawPFMqMRSbc+8EZ6/z5wK23AlICxx8P\nXHVpUSbPAQwIZFOAGNHwGFR/P3iUTE1AHVMtsVNX8fHDiiLX3w/eDZVn5l4pu6yep0pbLvG1rqvQ\nrDk+1lGKbdptwFDg85//PBYsWICddtqp3aYkjDHMmzcP//Vf/4XVq1e325SEEEhYKM9tsUFvYVF8\nEfbJGHxlfccCXj3WlbfpXJRbg8AZg/FR3OQRtTQcR6KwVCT3O5nLkls5Y3Q7JuG0SrF1eZlkM9wI\nTQgx7KijgBtvBMaPB/7+74GrrirPC3AMoPnYrXK5PU5TzWU+NWaHbjvdpnt9rH66u+1rJ4p7ymov\nQFCb3Es8a7+qNJwY9crSo48+igcffDC9lZTQFmy77bbo7e3FokWLsGbNmrQP4QhEnqN2nzL3SV0f\nCxb2faZqwBYKTIWvKt/uqrOV2gDAn7ztcYD2ac/bZEIU/ZO9V4pDOvE4Dzp8E5oLKEBCOBqEWzAk\nH6G6JYwuHwpLFZsYe5syXZ06O8fPVwNv2SXDuecCH/uYPcdFX9XFPaPXWCtutUyD2+MNzBsdnH4r\nUDjXiztGGYUtqyqq3ubV8hFU1LTIYaCN2Ft/nYBRT5bOO+88nHfeeejq6mq3KQljFMcddxwuuugi\nfO9738OsWbPabU6CC00C8ly9Pp/RUwZ6xe4eu2qwTe8xxQKMs9ZvDglbrQHCRICW6+8DZBdHT081\nHOP7HvrsIkS2jMOrCR+ZqFv/gOeE9rCwSEKeF+1nWfGluBQNwlPUDidUGKzjhLBMG/r6OPlqs2YB\nT/878Pa3A71XAe97n18kjPXpkkOrfJYVBC8PkKwIA64QwMD11yRO316hN97K+jYh09fHkGRSeLCk\nv5MwqsnSAw88gGeeeQbz5s1rtykJYxjjxo3DkiVLsGjRIhxxxBHYZpuOiG53DPSqwnVw8zKCXiri\ntXiD3R6EAMSAVmwiCgLUmowBXkaRrytschfSDCWxNE2l8SkUxh7OIbqnANrEgJOvaba5LYRMaJXH\n1BeiSC7nNjmtW+No/XrgnI/nWPtL4E/emeGSK8s1lLz2eJQb70A85KkVWAnWLkH0TJ4ALzfe5Rk9\n1bh/IQA2INQDhXPCaci1b0vGOlowasmSlBKLFi1Cb28vJkyY0G5zEsY4jjzySCxbtgzf+ta3cOyx\nx7bbnAQK7eB6skpYi/64l0RjC/pyn8SFk7SsPvOG7I2GDy2f1aon9JsZPl5HBgbRkRUKdVllk7ab\nqkwVuYyoSSR09cOHOHp7gYE+gX3fBXynboesoBxHiEMEJJLpbdqMQzjHqylEXnAIYKCYWpPUHggT\n+9rKMtJ3KwxLS1kdjlFLlu6++25s3LgRJ5xwQrtNSUgAYwzLli3Daaedho9+9KPYdttt221Sggsh\nIPoE0OUkojpO2CR8O69Pl8VqFCbarOtbCXlat64435P522mFm2Q9HgUp4tyD6kgEJZHyHLObD56L\nlfHyR2J+SCXSCpIgZyr5Obnd4Y03AitWABs3Au95b4Zv3BRKAmthYE4M1BdZC+aaOV1k9J4r2LF/\nA12aQzQls+aQK4VIrMvNd9FflKZkioYFBThyJ5fMt3p8JYSYyNLIxJtvvolFixZhyZIlGDduXLvN\nSUgAABx66KGYNGkSVq5ciVNPPbXd5iRo6F/2PDevRLt5HqZoYLVkU9Z3KuZETXIP4p6ShFNiTZVN\nVAmQWedmMCGugD21SVAtNBxduydGQAJql488ecfLOZBlZmWDhQuBG24A/ud/gCOOAK6/Hl410U0S\n95HOlsNPiqjS5OxK0yrnyroXmqidlh3+Oea+UzVbqNT1CTS0b5RjVJKl22+/HePHj8ecOXPabUpC\ngoWlS5fimGOOwYknnojtt9++3eYkKBQkg4N382oeSMDTVTbO9UkaunHYXCgYNiEnym0z9BYfUXMA\nlH7N3XLDbVt/96pbkQ7MkNTbZlaajJu/5OQFNWjeWyaUG2SNgZZzw29EKbPUKVpRVT777wXuvBPY\nvA3HSScBV145SKObwGOXjxTRg5YCRU+pMXivZ53ZPdUXGoTg5b2WC+t8Xds6ZOi7hlsYHR7RGHVk\nafPmzVi8eDFWrFiRXtNOGHGYMWMG9ttvP1xzzTU4++yz221OAmhaReEgjMNBdXuOwr3ZClBtfrfJ\nicnM20T+/OpS4YIQ1oZvyhJkNc7KDe1U2lb2lGPRDrFUDyjRCSlo5dpTXkHF3pKkISj5DJIH9efl\npwt7d9krq048nLpu6Mk3IADHzuVY831gl+0FzvhEsecbjWy5yldFpXEVmIiiREmNCETQdB/qctjE\nSPVaqEql6mjW2iJzBShCFFAn6663vidEbp927+OxjlFHlm688Ua87W1vw2GHHdZuUxISvLjgggtw\n+OGHY968edhxxx3bbU4C6lWhaNkYDBOzFaX84XV4feMAsN+U+m0+dGjG92ac462avtnXyG5q1Lp1\nxV8lWVHHapwz8ejFOHkZ2mmhq9rC/aXT317YifeayLlEV8OroAmBI48EfvgQ0N3NcfY5wNxj9fIO\nfrJojVt9KcNy4UEJmhulQ4hOzhIlRUIAfX3FW480d02H/oTgVn3rth0QxabJE20S6osiV8ZEC0VC\nab5QpI/ggvOSbKoxdxrDGlVk6fXXX0dvby9uvfXWpColjFhMnz4dhx56KK688kqcd9557TanLWCM\nXQ9gFoBcSvlOdex8AKcC6FfFFkop71bnPgdgLoA/ADhLSvlv6vj+AG4AsD2A70kp56vj2wG4EcCf\nA3gZwLFSyvU+W8IhgpCjjYeVKs6Ckgbtf7oAvOavr9/KooninBYkyhDXeTGZZ/2eUKK2cmjU19N8\nFM7hXbRSDMBaY9Icd7YsCSoUDWEpHb5scQHs0s2xiyujRZx6CHkOHHUUx2OPAX+2u8DFFwOHzVYE\nxBmGHt8TTwADA8C0aaV15no0YIYbNgA7TOamntmWMK/cgAAKohQlyYp9mKUR9H1LSLYhfpqoEFjX\nu5RZK2VccugxNTTkMYFRRZauvfZaTJ8+HQcddFC7TUlIiKK3txczZszA6aefjp133rnd5rQDXwfw\nf1AQGg0J4EtSyi/RgoyxaQCOBTANwG4A7mOM7aF28b4awDwp5UOMse8xxj4kpbwHwDwAL0sp92CM\nHQvgYgDHxQwyT8cm5aXeE7i+ukK4Am3wfXpaUFwCbSj1Rm91EluTyRF+rDa859yCPT0qHhQw1hND\naqoYtcSrOPcTOZc75AEJhZS97z5gwQLghReAffcFvvEVYMqUeqMq6xsrwvraBgE+IFC8mx+4Zhl3\n1+KscD13uDr/TIiSDAqhCa9H+dTHPPMUGlZJsClZr7+GoQcIWkCT6UwtwJrr8fprjFqMGrK0adMm\nXHjhhWnD0oRRgalTp+Loo4/GJZdcgosuuqjd5mx1SCn/nTE2xXPKJwnPBnCrlPINAH2MsV8COJAx\nth7AjlLKh1S5GwHMAXAPgCMBfEEdvwPAiiZ2efOPyEHf0zXNDxH9ArybeD5LghFFOIsHziu4SxGE\nlCH1pViSyEdieNkOzWHSaoaByQrP/EoNac7r0DNnPzQEiGMM7hxH4kSuEugtViNn3HILcNFFwK9/\nDfzFXwD//u+A1317BkFSkgDrNIcYgBUWM800SZJuQaax9iuEumd0fX09uZ04HiLMrdig9xZ0LxHp\nMtqMyAUGBsIPAKMZo4YsLV++HIcccgimT5/eblMSEhph8eLFmD59OubPn49dd9213eaMFJzJGPtb\nAOfd9lYAACAASURBVI8A+LSU8jcA3gbgp6TM8ygUpjfUZ40X1HGov88BgJRyM2Pst4yxnaWUG4M9\nx7wwih96AQADArwL4GqLEb2CjwAvjjvN0LCY2DAAPLcBfJcuYMqUcCKzFUKrUWy4ZzkAJ2GX2hQM\nGzqMp1WyI0TVlorhhIjZ4TZA9OXFGlc9ngUpPYa37PTzHEIAl67M8NWvFk3+7/9drKmk+8nzoq73\nLXka/nRUOM65Cms2IwF67FlWNxBSnhTN+tcBAwCm9PgLms80vObvyyVUNARaKlfNxuV7G5Mm7ncg\nRzIYFWTplVdeweWXX44HH6xbYjUhYeRgt912wymnnIKlS5dixYpGwken42oAX1SfLwDwTyjCacOK\n888/H7//ffH58MNnYqbaz6Ky7o/egb3LiSGomAL3EBvACadN5kB/DnSpei4vcyWawUAIiP7CUdLw\nIM2PsUAO1G52GlDVSuJmq0q6CFfZ10ECxnkxr7qCo24Fui3mlJSn4SRfxd5e4OurgDffBGbPLtZT\nisKn/IWUIX/x4rgTEhN5Tb8ILG+kya8OBXKngrrIQhR96IXQ3bftXLWxaErA7B0nhL2IuiKayLIK\nkaSXSttcCYvSedjC27tVrF69GqtXrx72fliRFhA4yZiMnd9aWLhwITZs2IDrrruu3aYkJLSEDRs2\nYK+99sLDDz+MHu/iOCMPjDFIKbf4DQoVhvsXneAdOscYOxcApJQXqXP3oAixrQfwQynl3ur48QDe\nJ6U8TZU5X0r5U8bYeAC/llJ2e/qRctMmryoSXCQx5PGdEIkVFWmiIviUF9hOyOeoKHSYUCsg+pgu\nV2xZ4ZAR0lHhZMtxm7euiEIhBMo38wJhOyssI8o300oyFpGthCi9uxqwUETVmOwseyAEIHhWmuFM\njADH3LnAg/cKTJgAnPhRgc98UoBPCecX+RC99EQlo4V8dSyCEmiwr09vklxjjPNd8MzqUwigvx/o\n7ra3VLHEOkESxHlWHUueFyHGKT3Wddcro/tE2eIZwmXNEaa5lTBUv18uRryy9OKLL+Laa6/F448/\n3m5TEhJaxsSJE3HGGWfg/PPPx8qVK9ttTlvBGNtVSvlr9fUjAH6hPn8XwDcYY19CEV7bA8BDUkrJ\nGHuVMXYggIcAnARgOalzMorw3dEA7o/1Xfx+26GKaDgpWsDXdkMM1pk4jlM/wVum6lAMLe/0xzmA\njFf8sF2ANuEPu5ncFZ0VrvoxRT3tW2qRwwqNIqFDlLzsRBCXbLVB8NEPAhseeAL77jSAjy6ahrnH\nAugfsBhD8LJW4lTVedB5PFuKkkQV5KalRg0TKk20VB1KjEAeAkR5jQwJ1XlzeisUssJ5xV6PmliS\n1tAA20uYhgMjXlk688wzse222+JLX/pSfeGEhBGIV199FVOnTsUPf/hD7LPPPu02pxZD8WTGGLsV\nwPsBTATwEgqlaCaAd6F4K24dgH+QUr6kyi9EsXTAZgDzpZTfV8f10gE7oFg64Cx1fDsANwHYD8XS\nAcdJKfs8dpS/YeFYj1XHqzhtoRMI+uOm7XolpqadeIoRNSjUt7cJ56C1rEDNGGrVllAfrkoC+xJ+\n6EPAY48B78+ewKfOAQ6dO8VuzyFL+nNFpSLzlqvcJLqulfe2afG+qBSvua6hvgPF/ZXchHBe7g1n\nQqia7DYUWYMYAWRpuJSlEU2W+vr6sP/+++Ppp59Gd3dFYU9IGDW47LLL8JOf/AR33HFHu02pxXD9\n2LQDld8wGkojP+zUeVm+07wdFFkBuQGakKWgI91Sx+MhH77QmYYbTqIhQpfoNCVeQXuaEljP4ce+\nn+NTnwYe7suwzz7AN7+pEo9r5i0QWbQKxBLBYyG5yBD80IX1fZdl1hwHpydSJtgHtVXYewkaEqX7\nie3j57Zbp9xtZYzJMFxvby8++clPJqKUMOrxyU9+EpdffjkefvhhHKASjBPahzwH2IAKhcAOj3hR\nJGh4Ec1zQdUph5xsqDGf4zLFRF4ke3dnlSUJQk6rJH3aMzYYTMBe01YorBdoQwggX1dYkJEkZQj/\nfq7uW1u3XCdw9ReLBSDfP0Ng1WrPBHu2laFFYspQkX/mP+1ePyEAsU6UbZqFhnjl2lXao+qZGV2g\nLzq0ddpOXTFC1gJxVM5VeE6/FeeNucVJ7FjCiCVLTz31FFatWoW1a9e225SEhC3GDjvsgMWLF+O8\n885La4W1E+rHXqtGxf/K1+Jtr4jKejPDhWhoJ5hg5G/DOGi19EGdSuMqSVp10eUavZfQQAkK1nPJ\nB6BTbLy47DLg2i8Br76a4S/fD3z7206fmkm0El50bYI//OeW8TVO98wLkXAfoSlvvwgrF64aqBXP\ncHm6CKWtKIUvDq+s+E1P+lnkkCuiIwwjNgz3N3/zNzjggAPwmc98pi39JyQMNX7/+99j7733xte+\n9jXMnDmz3eYE0WlhuE2bpPd32wppOHGZVn7vm+T2hMp5c1AioahY+Mi0JeIhlNjYWsmtouEo7+at\ngT7qJjf0ZiCEwMKFwPW3cWzeDPz1X9tLA1TIEmF5tM2m13ZQPj8UmnLfOkS47eB94iE/Udt8ZCkv\nlEjRlVlvQ4bsNQddaS12f4vQBdw6GFNhuEcffRQ//vGPx/zbQwmdhQkTJqC3txeLFi3CmjVr0v6G\nbUb5O9/QYw2nLTTM1GKfjcIutK/I6Uq4SceHQn0Noo86+Mgk58DZZwN33gl0jRM46e+A3stsZmaU\nkp4eRS6CESi7gxhRNvGxhgPyhSmBSpiycduCLpTJTQ5dg3x6MyZTTIUl+RQVY2w4Hu9G0DrEKEQ8\nr6mDMCKVpSOOOAIf/vCHcfrpp2/1vhMShhN/+MMfsO++++Liiy/GrFmz2m2OF52mLLX0G+aVemrK\nxuQUQRQFEUkSj/U7WCWmoYlRNEzibTxtoZAiJ4nKnuTlkz4q8LOfATtM5DhzrsD8+SgVjkpoKqLA\nuQPw5DVZRWKTG2u3ySlBVkV31RgyTzT52qv80MZjF3ido7jV3Ax1SmXL65RtJYwZZemBBx7AM888\ng+985zvtNiUhYcgxbtw4LFmyBIsWLcIRRxyBbbbZpt0mjUk0zVtxy1p5LCHHFeosGppznF0LcJOf\nY87Zq2SI8FYm7orfIZ4XzO1xy+UwbxZ6FQunPADMmgU88RCw++7A+ZcCs2c7FbTikpdvqHFts1Jl\nDHnydeSwKqr6hHKOhgSeMKulhtFJzXO1kbK6CX1LdtehhvCF7pvQ9amQJ/de7jCMqF9qKSUWLVqE\n3t5eTJgwod3mJCQMC2bPno3tttsO3/rWt9ptythGKHm1wY+9Do1o9UOIYm2edTm3uJGVX9IoduKx\nLWaTEOWyBoFzujm3Kd/wm9rl1uUo7YiRHz0flf88w3zySeA97wEefhiYPI3j5js5Zs8u28pz0p7P\nBmpkk4Qv32Q4ZETkAuKJdaXiRMsFJjZ4il67LLNW5jaVYnaFYowOGdfhMn3ONFlzr5vTDf9NdDpG\nlLJ0zz33YOPGjTjhhBPabUpCwrCBMYZly5bhtNNOw1FHHYXx40fUP8OOR62q5BSg5YwP0yEIGv4J\nEY/I039FKGhhHBWjnO4q9oRiZxm3/HIlogNR7HVG818QnseYQlH8F18bSPTl+PGPgbOv6EFfH7D/\n/sA991TL0UYKwsHNd/dc8Zo8oDfCjfp+h+hQZQoAMDBQzm1ALSzISKmi1YXJvIfp/ee7CSPtWe26\napWjLg5V1KzT+dSI+ZV+8803sXDhQixZsgTjxo1rtzkJCcOKQw89FJMmTcINN9yAU089td3mdDy8\n+RURh+NNP/LsqQaUqyFzbi9i6A2DeU+Q09zZh6suvBU7aRQXmwiZz251ml8VytUhbfqOu/3QLeBc\ndSVk+g3f4vjaV4EXfgcccgiwalVAAHSjSgF2RucxuKyCzzjzOTPfOQcwbYrf8JAdul33VA27KKrE\n9+izb9Dq/WXIHsprVpAvUh4NFrb0NN/m1KStjhFDlm6//XaMHz8ec+bMabcpCQlbBUuXLsUxxxyD\nE088Edtvv327zUnQCDz1x8rUQeQC6BfFbvLK6bmkob+/9abroktuWQtEyqLnLCLFAe2wS5JVqmq+\ntqn69j/PCbBdOIRHpfMZt3Apx/XXZxj/usDswwSuvjFSL0YUvMQpTPLsZuJrEAXJCu1Kz2uuCCMN\nt1HyNsyEo0psPOON3Tvep4aSZI0ljAiytHnzZixevBgrVqxIr1MnjBnMmDED++23H6655hqcffbZ\n7TansxHyBsQZuHk9IieLVfraI/kkJbEokK8rjmc95GAXt2UecPT3lyGerq5wuCSkdFkEyBfeEuWr\n50IAG9YLTJzo2OWr3+O8ldXAm2sixQnB2mUXAF2ozq1HXTr7bOCBb6/Dbgz4q+MznH9+3IQhJRq0\nMZeBGm7QbA6MApXnwHMbgF0mF00MFCxJoJpI72u+okI5hEVfV3NK2U63MQFg7wOXkYYdBcqdi+IN\nTk/xMaYoaYwIsnTjjTfibW97Gw477LB2m5KQsFVxwQUX4PDDD8e8efOw4447ttucjoTIBUS/AO/m\nlhMJV7AlGPfpvAkGBso6OkRHd3oXGwT4ZI7u7tIvB19WEsLaQsO1zUuwPMayAYHXNwoMdPnVEG+/\nRAUry0Xq57Yn1XNOmyxaUA5Z5RDNnctx773AuyYM4GMnAvMus+tEc5xouKoBhCgUH58aZ82lOuC+\nbRhvmHwfGADfAeBTylCg7mNYiAZNlnKOhZQy33jdAgKww8HOP4i6txo7BW1fZ+n111/HnnvuiVtv\nvRUHHXTQsPaVkDAS8bGPfQx77703zjvvvHabAqDz1lna9NKmwmGot9GCjlfYm+jGfv3r8jdcVcoO\nzagcp8xZOycWChHk9X6dd+XmFfnkGkpUnH5DTZhqPtUtJitUFJlqWdMfL5WRY44BHn0UeOtbgYXz\nBebOrbZfT5ZQqjl0QJ5y+nOUtLhKE+KkwFKUXITuOaoC0Vw6EV7KIWij7ztQzodWKEMriEcmOPbv\nhbY5UshSx66zdO2112L69OmJKCWMWfT29mLGjBk4/fTTsfPOO7fbnM6D9opNf8wDZVsJ+5RP4Z5z\nmf1WmauyVNrX9utXwCPqUdUAf1O1cAZLQzDReaAdxDriHHkOHHcc8J//CUyeDFx4IXDYYbzsJBQm\ncuzkKJZtEALwiXPuNHnnQBfSf32Z+qHpFgL9fYDs4ujJ4CcxihS5xKIg5UMTUqwQWn3Qp+w5/YRI\nctQmfX7wJo8qtJUsbdq0CcuWLUsbiyaMaUydOhVHHXUULrnkElx00UXtNqdjEUpLMXCe5GNCSexh\nHtBP28V7SO7TfKV9T32f0TzjpcMOSSMBNmSNl7bpqe6dG1oghJpJKdb7Kcji978PnHeOwPr1wL77\nctxyC3ljjo5RteN7m1GHtqxuIgsvBkON5K/o1/1UbXDvDdpmV1dhtg65WiuD63Lk8pmDlIj5lKYY\nuwleJNVWP5kzp5+YclpH3BqrfB2GtpKl5cuX45BDDsG+++7bTjMSEtqOxYsXY99998X8+fOx6667\nttucjoJFAJrmnwTaCaLCxEg9RzkKVg9Hryr9CLVGtZWLUuOhTPjNOGVPHVGuqaQ6qnCg6hd/O+a4\nnvx+Ad7Fcd99HAsWAL95AZgxA/ju/a6hvg5Dg+ImTSrzqTqw5z8YflOhMtFFQqNCvXRfxwo4L8hV\nyFzSYaUl1Q7nHKIvh3h5AHwvGvb0d+k7UFlRux9AV82bfdRG53Nj4tPJDImgbWTplVdeweWXX44f\n//jH7TIhIWHEYPfdd8ff/d3fYenSpVixYkW7zelI6OgaJSYAwj/2otzsw1JlBIjz83tI68k94PTN\nm2Oi5q07aqZefiCSk+MTeFzbBQAo4cMVKbQKUmnctVGrF10cvMfv4K2hdHMsvYLjK98Afvc7YOaH\nOO64I1DYGXt4a40AifOEntxlEnzqiqsihpS60KUyc6+kKd80huoLcGCXQlVyUo38nXkTzcrzfIrH\nblRJsqs6clXfzIEz2ZxOqDqW9wPo5rVb6I1mtI0sXXrppZgzZw723HPPdpmQkDCicO6552LvvffG\npz/9afTozS4TthzEAUAniIRCGDUxBh0mKY+p4trBiXIhaQNXVSDevfjIgQG1IE9PVu2aOie1/ABV\nyNx0mwoJpO0IUThyrR6Qt9e0LZXFHlXdcg7VXxUGq2UOvMjVWbAAuP12QMpiY9ylSwu1J0gIPJvc\n+mA5aOW8rdfnibqlVRZ3rtw9ZmNhKjMmXxhQwXcb5XmxllZ3NyGvpBDvrtrmC/3SQmaDZjfxXpBA\nMFFUffeWcIhZngMgXCy69aE20POGZaehLWTpxRdfxLXXXovHH3+8Hd0nJIxIdHd344wzzkBvby9u\nuOGGdpvTUXDzjywEnGJ1N/WybOmMw07CJTHa+ZgXtlw1ZsD2SjQUJNSKijE1zBF9zId8vQCfqCqr\ntX7KnBibQxpCRfa0ixFIkw9DFQfqddXnvz8BeGi1wOTtBD5wQoazPy6wYT2ww2R7xXLt2M2xDQOF\nvXSu/GKP3bfwHPJwx8CwWoervgQa7upSxIXYYt6cHFCqobY/NlBNlgSADTn4RFRvACGwYYMiYpPL\n9ijJq8wBlV99NtA2oJUqjqzyhNB5aAtZWrZsGU4++WRMmjSpHd0nJIxYfOpTn8Iee+yBJ598EtOm\nTWu3OZ0BoizQH3+vsww4J0t1IQyHFi8VDk2oim8D/ZotEVXGNbGbbHDqGkbjYoGQkCFWHNWyAzDq\nDrqywk7qHN2PPiUh4LjrQm8A8DezBB55GHjLW4BPHDeAD59CmYInvKdP8QxiYvP1k0p7eDRBW98G\nZimFHg5LyA0xaxob0yqVVoUcG43wRpSnilJDDRqo2mmK+OaIqJViAyAG1DXQIV21Dc8OEKXqY+wn\nSh3nlWFmsfwrF87AOzl9aauTpb6+Ptxyyy14+umnt3bXCQkjHn/0R3+EBQsWYPHixbgjmtCR0AqM\nQ/D9iLuSQ90vPa868EDaSPHXqe7fP85xOv0kdwRlGKWpjbZSoJ2lUHvA8jC5UeW5e4wQiHKsnsGS\n8gIcx/2VwNqfC+w8JcPnL+Y47D3O3ndmwCplPeMQKvoGDmtNKF8IybKv+OJpvDpEWrTSnBAQ6/uB\niTB7yMVCbpYNlB25JgSYhBZz6LWqJRu0HO8p3zS0rnumSJvWJkkozjOnsVyuSsiwA8lQHbb6opSn\nnHIKJk2ahC9+8YtD2m5CQqfgtddew9SpU3HnnXfi3e9+91bvv9MWpTS/YUQZCD4BE0WhlafkYL4Q\nVbGEsNuKKFwml4gWbRSHqtqlo2Fmw9+sJBeVUGNoTOQLfY3fJTy6zLNrcpx9DtC3DthrL+Dam4vV\nyk17rv1kMUnvpsc++2g5d74btuG2Z7iO+qDHGAzhhuxBlTuZ6x8hIk3vObdc8FqtywvVaUokFy6m\ntIY6HMHoiEUpJ02ahOeffx4777wz5s2bh8mTJ2/N7hMSRgV22GEHvPbaazjwwAMxceJEPPLII+nf\nynBiEA7AdU5GGdDnPCpEkFCBG0Kj306jXrDiYJVTFbmwHbhPJiB7h3GiGJVkrOHYfeE6BzqZ+F9v\nA265HPj9f/fjXX/eje/cy4E8hxA87Jhp+00JjmdOyhys+jboauLmGhaNlXvjka5CRLgxjITktEFs\nHyxCpliKag3ri47Pp5yNMWxVsvTqq68CADZu3IiDDz4Yzz333NbsPiFhVEBKid/+9rcAgA0bNqR/\nK0MFrVq44QoKlxTQfJHAk7h5Ecm3hpPyyDzLSM6Sqma2H3EcFd0HjjpYx1a9/1yQvKhQlu91bi8h\ncUJXTdbnocqGEMCXvwzcdBPABjhmv1/g2pvKgjTHp0IMopJNOHxVZ1dL4HofODVxWn1r2JjvVhoM\nn3IR5C55VSmsdKouviGStF2zMIbTF7k2jRSukGLWYdiqZGnChAkACpls9erVW7PrhIRRA7qifVdX\nF9asWdNGazoH1oNxRB1oKhwM9JdESgggg4g6yMpxcoAm/xoloI4M6HV06nyUN8xDlAJ/0cbhJ41l\ny4A77wQ2bwYOPZzjSzf22EoKUSWi4Ur3vChXQY8SpAaLT5pQGVfcVU92SDnxhlP9duROv9E5c4kf\nXQqiQQjRmOq+WbdOkXOqjFHCr8Yp8mJOvTZGbuCSdJEHg1EUotsSbFWy9Mgjj+Dggw/Gbrvthh/9\n6Ed4xzvesTW7T0gY8XjzzTexcOFCrFixAsuWLcOaNWtSCG4IUa5iHXF8lFzQdWycgl1ddnFaX4fS\n3A1SLVt4uVp0vk4RLbI1BX1qr5AFEvpz+9dlyvCLx0anferd3bJ6tW9O3uZz527BAuCuu4Bx44BT\njhFYsACgLC7vB14bACbyQfhUMxDXeM+gFTSR1QnaUdC2KMsJEOmB/uBpb7O+zYcreV9kLst6nn70\nSUPKipO53lcwukiqrRz5CJ1LUi0iaVlFytdtzdIh2KpkafLkyXjuuefw4IMP4vjjj8fHPvYxbLfd\ndlvThISEEY1vf/vb2GabbfCJT3wCp512WrvN6QzoZF36G+78oFtRDM0uBH3H3gbnKNf+yYX16rf1\nJO/rw+M8hxw+pcQNl5i/ti2aaGQ9iszlqDh0itmzgQceAHbZBZg/HzhzLsp2Nbo49KtClk+tC63x\nSNKzI4OVXwVEF6qoCxc57KFoz/Mqv76CznxkznIFJgtKXwe1uKY39YeTNhuFSJ0Peuw9vphrlRFF\n5zKC8nRlUvyMvIPQlnWWDjroIEyfPh3XXnstzjrrrHaYkJAw4rB582YsXrwYV1xxBRjriJfRRjR8\nYZviO4CBkkPol665OQnLqXAOCP1KPg0zOT4kFErSxEvDUny048y1wy1jPGbF8AZbTPh8YIg4dHXZ\nh60NfJ32PnCQwOOPA299O0dvL3DssQA8BNOEphDZ2sVFQM0A7LkU4CY3zBwfzCKJ69YViWD6tT13\nIS0yDr24eDQs6CMW+ohnSQQ3BEqXdSqb8ncYvQfIm4aN90Z0iaMnv8lbp4OxTbs6XrJkCZYtW4ZN\nmza1y4SEhBGFm2++GVmW4fDDD2+3KVsMxtj1jLGXGGO/IMd2Zozdyxh7ljH2b4yxPybnPscYW8sY\ne5oxdjg5vj9j7Bfq3JXk+HaMsdvU8Z8yxsKxygY/4pZv4BzotlUAgzwvNjwVdmXzarb2opE+CvJV\nekixLkf+RG4tF+BJJyrUK0/7pmyel45RdajfULPmQVeg/5EiWQ83ScP0dXo6jU88ARy8n8CzjwlM\nnQrccYcmSrZRZTSHqFsoz8XgEcb8E6o+80y96q/GnOcF/7HGTxW3GlgqI502RVw5h7+tUHyLEmnP\neHzVTL+B9aPoJczz0rY8L0K7TcZpDSE0Nw3nrGGxUYm2kaV9990XhxxyCJYvX94uExISRgxef/11\nnH/++Vi6dGmnqEpfB/Ah59i5AO6VUu4J4H71HYyxaQCOBTBN1bmKlZNwNYB5Uso9AOzBGNNtzgPw\nsjp+OYCLB2uo60O10w0W7rIdv1FNaqI7sTKV8plNdHhWEDLaQJYRRUFvPOagqfNyy1FS4OK224CP\nfAR45hlg77/g+Ml/cOyzT4MxtRp+JGTPtc/iSSI3OWV1cyxygbzPIWq6QpYB++zj34uOEMdKm5E5\nHix54Ly8vqHxBPhutQxVyDyhxkpdNVbKy2m1LeRToxZbfVFKimeffRZ/+Zd/iWeffRZvectbhq2f\nhISRjhUrVuDuu+/GqlWr2m3KkC3qxhibAuBfpJTvVN+fBvB+KeVLjLE/AbBaSrkXY+xzAN6UUl6s\nyt0D4HwA6wH8QEq5tzp+HICZUspPqDJfkFL+jDE2HsCvpZTdjgnR3zDfIoJA1ak3yplpctwtUpND\n0zCNpJQVtIclx7WqU9eG1ZeV/2MbcNllwPLlwCuvAAcdBJAXN6uN6a8mhOMMqIF9VlOh+SJhprrD\n9HV7S+ERTiJ9ja1uyIwW1f3Qg61EHa2y7kHyXdutv/vuTzukm7lNBPvUJMtHPkNv6zW+X4cZHbEo\npYs999wTc+bMwaWXXoply5a105SEhLZB/L/2zj7Oqqre/+/Fo8xCRWQOGBAzAiIiAvmYImIGaCWC\npqikpHVNTLGb2BVEhQKyK/0yzdS8miimopBSmqESApUPGF5voIQ5oKJyBsKHWWMgsH5/7Iez9tpr\n73MGgTMz7M/rNXrO3uvhu9Y+nO/nfL7ftZZSzJgxgyeffLLcpuxudNZab/BfbwA6+68/BzxvlHsH\n6Ap86r8OsN6/jv//twG01tuEEB8KITpqrf+V1Hnsyzzi3YyNJVVKHRNW/fCleeJ9CXA624Y6Hhms\n3DMcfVDf1YYqwZkbyTJKwQ03wNy58O9/w8iR8KtfNcBYpQp2mLG1FJuKNVly3yaS1KdgrEbYMPI8\n8O6bAk3Qf/C5cZlSCNWVYGMDxhL/LEdveHlcVt6bAxFF1fh3EU6Hfc9hXmMhSbsbZSVLANdffz0D\nBw5kwoQJdOnSpdzmZMiwx3HrrbcyZMgQBg0aVG5T9hi01loIsftkawNTp04FYOtWOPHoYzlt+JCC\nMwwcmYmGspzgdUKoI1Y+6FsmrIxqKELVIeF6KXDFWwx873swfz60beu9njw5rQmbhEaJklJAzkuG\ndzpeW+Uxya01YV55twMPh9IAb56q6rhglTHDpqGpRfosmZBDuJVFOGhzToLGIp/DeBufmdQE/SXE\nCPc0eVq8ePEe2bex7GSpe/fuXHjhhcyYMYNbb7213OZkyLBHsXnzZn7605/uLRtPbhBCdNFavy+E\nOAgIspHXA92Nct3wFKX1/mv7elDn88C7fhhu/yRV6eqrpwJRx1kIuflIIjelKAJBfUOlifh005H5\nBez8m+B2TLloAAoqUnplr28ZtS1qnpHYLDnrQsmiRdCuHfzH+YrJV1p9OMiac36TyKXdjpmkxxog\n4QAAIABJREFUbl53jcWXe2IkJ+G5OZUURxkAZa5GK/EjEPbvXUm030koLJKZGKK0wpHRkJ8srNo0\nlMGS7HbY5lTGamu9VYN+WK/citLQoUMZOnRo+H7atGm7pZ+yJXibmDRpEr/5zW9Yu3ZtuU3JkGGP\nYtasWYwcOZI+ffqU25Q9gQXAOP/1OOAx4/q5Qog2QohqoDfwotb6feAjIcSxfsL3BcDjjra+jpcw\nXhx+uCpMXi3BEyYmrgZ17TYakOmaJkKZHMtuLq0L+16qOaqwm7OpdAV/I0fCwoXeHkpTp8IPfuDf\n85O/zbaTwlthoroycqFQkX7CpfgUiIBLOCn6vPzCkWKOOs45sScdoqsJjTLBHHg8wlKVAo4UbDph\nr1I0m8oXFgmUAimJbFwa2mj87XZUVkKnTs5bDfjoNzmUXVkCyOVyXHbZZUybNo1f//rX5TYnQ4Y9\ngg0bNnDHHXewYsWKcpuyyyGEeBA4CegkhHgbuB64EZgrhPgWsBY4B0BrvUoIMRdYBWwDLjOysi8D\n7gXaAU9qrZ/yr98N3C+EWANsAs5NssXliEpSC8JQnf/eIQckJbsWVB4iSlLwS11a7XzmPJAGNJAW\nIQxQWwvTRr9O/s12dD/kaO64A4YMAQzikxSCCl67iJOrr6i9OMino7w1FvMYk7SHWyhXivoW58Bh\nyE8pqM17KyOtcKq9zF/i7WAOhWTzggqV0D8FVSg4MLkQlgwOUo6Sy6BLhUSWsPdWEmJqkj1X4WnP\nexfKuhrOxIcffkjv3r157rnn6Nu37x7pM0OGcuLKK69ECMHNN99cblMi2F2rScoBIYSuq9OFDShJ\nPjcs4vHMsJGMOj+kjG2CGIbgHLs3BsqJlIUT7gPFxQ6pmIpG0OxO5YC4KgXyjZlrYioovsqx4h+S\nq6+Gdq+/TGVVO2544DAOOyxqU9gexFZZBbekjG+WaE9xzOnacTKbaCYMNVRocq4Ha9hVo6BekauS\nkTmwQ142uQ3mKHLNYIRmfdeQvA1Elff80+TE+MvItJjtKSQ56SBLaUpfGowxhW0kJYen/dsoM5rl\najgT+++/PxMnTuT666/nkUceKbc5GTLsVqxbt445c+awatWqcpuyVyB0IkUiOElHegBulcbadsB8\nbRYv5h/tezGhyD+fLSRlLqJHVH1IhO1NVUA04L7b4aZfwlubJIOHDeHhudbEuTyxg2ykdW/yofBY\nMWuH6GK+194WQOaMXJ2EiraNTjjG4rIbM1fKYjau9nM5PKXGIcgESl10FaP14cEg4r4yKY25k9Gi\nhT2hcu6cp8iAXEaXQnoaEUHaE2g0ZAng8ssvp1evXrz88ssceeSR5TYnQ4bdhh/+8IeMHz+ezp07\nFy+c4TPB9gmpZEgWwh+pUoZ/P+4vvM7Uujx0kshqY6m6mQ+jFLK6GiUlSilkotwVhJbiNoTqQuCI\nvRvJtgcKUF55ycvWcKfeJPnVryQVKs/ZQxX/83guEopJdIlmyAYgn0cqnLKSDOYtSEousCVq13pn\nuuWqZWS5e+Lz8vstEAt3wTBsiFc2KF94dgahyFtjIU7kYrAMTOUQaazZZECuMsYH2UXSI13koh+3\nRHsSbHMVjbTTkDE3EzQqslRRUcGUKVOYMmUKf/jDH8ptToYMuwWrV69mwYIFrFmzptym7DUI0l+V\nyoWb7UWOrTCcaBLMtJqCA46THCkB4yDXSD5N5IXx0hXqMe23wyG2k/SJm1R5v24RacccT05y2WUQ\nCPpnjob/vqEQkgnOoIu064e9fI3Dy5ExxlLMBJtHSUnh8FsrpytUXgwnHSWIGOUSHHZtHlkB5KqT\njfL7lCqPlxAUNTKNEJREEhIakJICOSylIUsR9C/GyIzBXaNNmxJZiewmUnxvYEYONCqyBPDtb3+b\nm266iSVLljDEyyjMkKFZ4frrr+eqq66iQ4cOxQtn2DXYlV/sgRwTOvD4fdmv4JRj+R82WZLSGZ4p\nBo9w2I5LetdMR2gSMVVYKab8emPGeCveOrZVXHwxXDsz552Bl1fJGxrGlJCYYXE4Qktme7kcoeqk\nlMdVUh+beTNQt5KKVSYodq6LFpmwpjGdK1hEr3iHxj1XHhREdxO3xxwccZPS9q766BcU0vgc7NTB\nxU0MjSbB28R9993HXXfdxZIlS5rLOVkZMgCwYsUKvvrVr7JmzZqiSka50NwSvD/Td5jDM5pKh71U\n25Ufkpo8bLVnxwxdOdmRdoMq5jEdZkjPyPiNJSgDX70ox7Jl3mrwyVd6ZAkpUTV5VD3ISom01TOl\noklDlqNPUseSWIY9fmUNoSQUUTtc6lTkfl5RWwu6wgtrJp1jV9S2UlWXlGcSFglVPG+uZXWxbPlk\nE3ZWDEqqZ19POHGmLNhd31+NYp8lG2PHjmXTpk089dRTxQtnyNCEMGXKFCZPntxoiVKzROBU/D+l\nCiG43dqfjwjPyKtCvs5nQdCoS20I7ltlzWXmCsmwUZLnnoMePeCee+DiK6KH97rG4h6Uv1dTraOs\nWd9uy3xvtCdl+gGyqfNRxGwXgrKfbFJ8srFAYpL2LEolcbK0OXTal9RwQ68HfeQV+Rr34b87BcPo\nBhHZZoJGF4YDaNmyJdOnT+faa69lxIgRtGjRKDldhgwNwrJly1i5ciXz588vtyl7Fxrys9r+tS4L\nOTuRPXKC5OJi4Qc/rBSqGp7M5IhjeFqGykOQcByYEf5aN+o4qgcdJtoRjO2lVZL/vATWrIEjD1XM\nng1VVfjhFUl9raKywlOVwrq2LGYd2FuYL8MWO6wUbNugogpYkgIV2T4hYT+roLz3OBLOfQvmx1bA\nzLCalHz+0OhUJU2jq3/TXuuye5WeQQxjzdlqpWPMkTy4hP6L2u2yy3pfKiHaG4hToyRLAKNHj2bm\nzJnMmzePs88+u9zmZMjwmaC1ZvLkyUydOpW2bduW25y9C7aDUspfxZ2wwisS31JQq7zNB/2dvwFy\nxfJPkm7lJEpJamtVYlHPERZ21Y6QjyLtF7v3wAMwbRZ89B4ceywsWOCoHoQNDScdS1K37HGJW35S\nVEFFtW1rgDwRIR6Oe14IzUUeo+VUPt5toY6MXYsZELxOsT3CO6zcLucjTHiuCfzF3ZldzifnkWf4\nmUNxcYN2lzjbGNFoyZIQgpkzZzJhwgRGjx5Nq1aN1tQMGYpi4cKF1NbW8o1vfKPcpux9SPKcGL/G\nVZBULFF4S+YD7SRXScxLO5eTm96opsZ7XV3tXMmmK2RY2VQycjnPoRdWdamQvJgO1xBsUpNUTDtn\n/lzyy19CXR2cMlwyb168ulTKX9mWoJKkKGmxCJw5R8pfNxfW9/5fIJ+mOlQ49T5AqoInJRWQxl8i\nZa19RBsEjwBZdf0HKK0bsTJAJAk9gWmkqVch4Q+3XDAIa1A/3NCphAHGyJa1d5T54XQYFpDoXHXz\nl5YaNQMZNmwYBx10EPfddx8XX3xxuc3JkGGnsGPHDiZPnsz06dMz0l8uuMILMuq7wHPen2w0jr4K\nPLDPUHI56a8UI3Lsg1KgapWXEG1zIzsCQ7AizSHHBIqOy4+6HG7CUAMFJSh6ww3wyL0KvQ1GjZLc\ndhvhMRqlOFUnWSmirACFPZ2AjesU7ToVInjmburgqUO19V4OVdhGTQ2qHqiqTiQ3riihXTbYQVva\nJMIR0kzM+4p0WESpyee9+4XBJpK5YopPKnlylfPJtTI/4EEY2Lhvt+ftveXejNPuN2g7IFZh3bR9\nvpo4GvU3txCCGTNmcN555zF27NgsfJGhSWL+/PkIITjzzDPLbUqGAL7nClSPIFRSv1bRqcInRQlQ\nZgjN9FkVhjesju7nY6dCme9LDrMYeTtO1SI2Pm9YF18MzzwD+7WEs8+GGTfHiwY5WDHjUrpwmmq0\nE5C1ICeo/hOFeDsfhhcDLhEQtopK6GSrNgZKCiMFUlV1rmiFhiaA22Qn0rx9I8hNw3hutvoS1Fm1\n0vt/rl+yEU72R/g5i45Fxj+b9oAcbQY/IMAgslik3jbLJ/Z7QziuUZMlgOOPP54jjjiCO++8kwkT\nJpTbnAwZGoRt27Zx3XXXcfPNN2fbYJQTkZyR5KTiykrfObh+XgdOsDJnhGMKSlXMpYQrh8y+DV9q\nt1+MADmQlJ8bCBpjx8LTT0P79vDdCZKJE42KtpPfxQhIUqioHSojqkaw3kzlg/CbY+l5dTWS6LF2\nzn6wyIxF+Lx6Xr6Y33kIc2PHsKFSxpZWNJfznrsVt3OKVp0qYtWdkVUzyd1qz1W58ENAOvfLKuSB\nGe0WscEMORaUQfPfU/NTlAI0erIEMH36dEaMGMHFF19M+/bty21OhgwlY86cOeRyOYYPH15uU/Z6\nOAQTD6HzJnIzKTwjczn/WIwUGYQEJ+7fMPsK76VsVlPI5yltfErBl74Er70GhxwCV18NX/tacl07\nzOTMzSkFDrWiwBn8vakCh9vAtpPCWBGEYa/kuJdpSyRWWWK/SUpTpIL5NuVwXy9UVx37fDhDZSaM\n8J7dZRqxjBQ2xp0UeSyqfO5FaBJkacCAAZx88snccsstTJ48udzmZMhQErZs2cLUqVOZM2dOpio1\nEsQcQIk5Fp6DLCQel+Q4kkJa4U7eDbc/YhDxEImU8PLLcPnl8MYbMKCX4sHZUNXPkp5MZcIkDiX0\nWSpjMxW1fB5kvVHVUNKcqpzVX8zxmzleDZjHAvEtvU7YX/gcg89BnNTEtjhwhbpKtdMWNw3lJyBE\nTsIm0z9f8cfo/mzY/1bs9vc27tQkyBLAtGnTOOGEExg/fjwHHHBAuc3JkKEo7rrrLvr168fgwYPL\nbUoGoqGq0O+lEIBoSMe7oMBTXIxbsbL+BZMrRdtMcDMJUkAYWpOFcFGSEvDww3DddfDuu/DFL8Kz\n1tYApSIWmiqCAvlMaE/6xK4UdShoLy1/KSkPqFjyTKDqGQfRqrUKWeFoK8GekghXiXJMojJlkWxX\nc6Le3Yf5OUmFg3DGwrr5woUiQmqzR5MhS4cccgijRo3ipptuYubMmeU2J0OGVCilmDFjBk8++WS5\nTcmQz0eISNQhlPbtn/gru5SKvuPL+8pUjtLPhkgNHSp/N3Df2c2aBbfcAh99BCNG4G0NoKzxWgzO\nNQUuopKY6xWp4287YI1rp9WcRMnJb64+aqdpt3NrB7+QUl4oMHUsWHMefADsaw1A6saapRgRU9pU\n+FzM29jP26pfTMVL/Mzt5WgyZAm8A0gHDhzIhAkT6NKlS7nNyZAhEbfeeitDhgxh0KBB5TYlg4Xo\nr+jkZO9COMMIoQVcIwjFhB5KWgX862ZTyls+LytU6MxzOas/ZZ0l5ysh0orLSAn5tYpP6qHTYV7i\n9pw5sG0bjBoF997b8HmJEMEEohJx+EVCYZEQn7ECzrUxpF0xvOXI3THnJ/KoTIefj5YP+zOeT5hU\nXiUjZZNURyeJMifNzDWyB6cU1OahopBknhrN9PcmkGmsRVq5ZQ4DI8pQsXk3qoZNhc9ZFforYntz\nRZMiS927d+fCCy9k5syZ3HLLLeU2J0MGJz744AN++tOfsmzZsnKbkgFQMhfbPDKmtqTVV9aLhngK\nw1NLCaIeqMyRJJkohbdfk99P6ATzhXZCeyok7Srgu9+F3/0OWreGSy4BW3gPeZbD+ZtEQhkbRPoF\no21Yc2GqWmGhZL8eC0k2ZDoj9dbmkcEulDaZUN6eP0F+mcsQmfOnwx6cOYxIgRJs9gcn/b0QIsRT\n+SfNVRYIo1UtTmJcxksjDByoZ/V5b2WayoXVlPLP6au0FKfg+YRKXyw+XCDnOUNhihgbty0Wumum\nhKpJkSWASZMm0bdvX6666ip69OhRbnMyZIhh1qxZjBw5kj59+pTblAwpsENr4WsrtBPxxyqaDG0r\nGyof9XzSiEh5l+O7U0e8ipTRBPKgH8dxI7lqyVe/CkuXQocOMGECha0BGgrfSdobRdoIQkgqHygz\nyR7RRURNUhCSp7zn8MNNlxJlKq8BWRGQBas9I/QWmSc72lmo4LbZ8SbYSNQ8fy2mTEbYgjUG8zMR\nDp54ObMpx2fMDgObcxF+sPJ5qPdsMDc4jU1rmmLmKBd89n3B0Oao6W00AwitdfJNIXTa/XLhuuuu\nY/369dxzzz3lNiVDhgg2bNjAYYcdxooVK/j85z9fbnN2CkIItNbNYvleKd9hcbJUOLoi74dMws26\nbbJkhKVU3v9FX1FQkkySFYSPgv7ss2gB5+o8pQh32w7zXfJ5zhgFT7+So0sXmPKfytsawO7XHqgl\nY9j9muMtdc6c91RpK+xU3gtPyQpPAYwoVUSPQ4nAcOBJ85oUoitlDLFCdr+u+okykaPNYuWsHCKz\nH2e/qQWczRZMMT9btvoYHALt2NupsZKl3fX91eSUJYCJEyfSu3dvXn/9dQ499NBym5MhQ4gf//jH\nXHDBBU2WKDVrJHyjx3yM+WvctWGhF+eJO3cZVVqCl/nIWW9+R/X+pn4YuTdKIaVb1jH96sqV8JMz\nXmdLzSf07zuYm34pObR78bF6IT5LeSnE1bz/1Xq2IXOpns8ZhnLeMGDsIxUcP5KTCqr80JU/T2a5\n2lqoqKCwqaJNXhwmpJpjKlQNcewJzyTxYpo8F5QrRqgcnai8Rw7r60FVGGeymeQqKbl9J02x23eV\nLYGnNXk0SbK0//77M3HiRK677joeeeSRcpuTIQMA69at4/7772fVqlXlNiVDAtIUnAjCkEla4oqz\nSmJ7QUhOSi/WZ4Z0IqGcFDL3zDMwaRK0eetABvStZ96iwA7Libk4hSf1ROwO2/b5iYxvJp0OO/8r\n7EZGVYkSENpS678n2FHd6M4mAobzDhUkV3jLVqJIeF7KSrAvEhKMvLYZQ9GBWn0FVVV009Kk6uYF\nO3xcrOvIe+n4QARvc/5nZmeTzZoRmiRZArj88svp1asXL7/8MkceeWS5zcmQgR/+8IeMHz+ezp07\nl9uUDC4UiRsUjZzko6GlpObsjbiTFAiZK5wUHzjNNDng4Ydh5s+9A2cHD+vH7CcM29JCTirIdzII\nle3wfWdfzP/F+gnyc4rYDhQmJJ8nB/75bYXbYd9VOS+PSeW9hOkS4a0stNqysYtjR84mihGsBsJ8\nZsHnL2zFGVczHksaUW2ITWnhQvvzk5AI3tTRZMlSRUUFU6ZMYcqUKfzhD38otzkZ9nKsXr2aBQsW\nsGbNmnKbkiEFhe/vnfgiDzYBLEEpiSWGmzeihpSEG26A3/wGPtgKp54KkXTNUE1J6KoE4wLRKbmR\nNAWuRAWkhEJFc6GKtVtCpwXy4UhJ8u/7Ak9xAl3kCJrUysTJjAx3PHU3mpTu5FRAi/Rtv7XHkTjf\nVmjXM7n5q01NMsE7wNatW+nTpw+zZ89myJAh5TYnw16MMWPGMGjQIK655ppym/KZ0ewSvOvqvDcu\nVSFAypd8oBQlHTjqQik5M6VW/O43FX/9XZ4tLSVf+bpk6lScYwmjQjK+B1Gi8mSFglKThxMUqzA0\nltB2uCdVCX60hO7c7xuQ1Oy6F0BSgs3WuMK6DSF4+bx3L5ezwqcq0ge5XISI2GQpbF+VvtFpLIk7\nCP1ZIblEEpV3fN4aEVnKErwdaNOmDdOmTePaa69lyZIl2flbGcqCFStWsHTp0mx1ZmOFSyKwY2UJ\nCdEmSs29sZop8YYbZ50Ff30Guuwrufx7kvHjg3aK8C4778UYTMHBpShgDbA3Enpx1FXBwa7GirZg\ntaHNipzEwS9TCD0RthsJ/bjste2SMuLspVEvSLgP0rqKzYmkQK6cClnaA0pV6oh/+IzbSWHdNKTl\n6iWR0eDRhKb4hCqWpmUoYc05nalJkyWAsWPHcuONN/LUU09x2mmnlducDHshpkyZwuTJk0nbcyZD\nGeF/qzsdRhHnBMaP9YZ4gmKySGKVgvMfORIWvyTp0kVy5bWScePiw/IqGtcSwjGBk8vn4ZONinad\n8M5Ck1EFxXSQaeGXxLFY16Q0tl1oAEoJDUUigE6S5JOi8FJUjUvqo5THa859UiTSFS4zG/CIlr9f\nlU1icuZGqskG2URxp8lKAyrIpDlv5mjyZKlly5ZMnz6da6+9lhEjRtCiRYtym5RhL8KyZctYuXIl\n8+fPL7cpGZKQ5NRdRCnwcCphk8ZSYzrFEl5SkM/D2V+BVaugZx/41a/g6KPdZSMEy4SLAfj2tetk\nrSBztKlUYY/IVBTxzvka7763xN1U7QrqTLrK4jM8/3kFgmC1bVsxpQbCRKRga4hQEQrmImlIO6EQ\nSYkzty0WOrRUKWdXu0CuKVRNJ14hUQ5Czo44Y1p+VHPmT82CWYwePZoWLVowb968cpuSYS+C1prJ\nkyczdepU2rZtW25zmgyEEGuFEK8KIVYIIV70r3UUQjwthPiHEGKhEKKDUX6SEGKNEOJ1IcRw4/qR\nQoj/8+/9PLFDI6cnzMvYmW91Q6GylZLYNauP2H1HI1LCX59RnP4lxcuvSw7uL/njHx1EyaobvA3y\naNIceC6XTILsfJjPAqW83JZPNio2bnQoSxGj4843xmMTyiUiGKzRULALd3Bf5qzVgUEuUt54XWKX\nYVlT0bLm0Ww7ZkMQBlybL4SI/UrB3kqJnRodBS/TbFfKI7HhuXENxa74gDRBNAuyJIRg5syZXHfd\ndWzbtq3c5mTYS7Bw4UJqa2v5xje+UW5Tmho0MFRrPUhrfYx/7Rrgaa31IcCz/nuEEIcBY4DDgFOB\nX4pCcuLtwLe01r2B3kKIU0vpPEYqgi9/Ox5VTJGy2w1zXooQJeuGUqBW1vDIrBquvBJqauCEE+CF\nRf6mjUkN+AQgaCp5sPGwY5ozldLLL0pdYVUik+jUQ9KpR3S+IuHQYm0EpMevGJC9nYHC25F9Z0KC\ntmjY0DYCRD4aAUEyw6gVCeFPGZ/DCPEqYnMpCMheJJ9sVzXeDNDkw3ABhg0bxkEHHcT999/PRRdd\nVG5zMjRzBKrS9OnTadWq2fwz2pOwV2OMBE7yX88GFuMRpjOAB7XWnwJrhRBvAMcKIdYB+2qtX/Tr\n3AeMAp6K9RT7eU/6L2NH2CN0JNIPTVjtFG1Oysg5cXaFX9wG8+fBB1tg6FD49dyU6IsluySG1PJB\nZnXO8m2F0JOrWaf9jvupISNjhZxTxTJX0BnjCYisa8xFo5y2QTZJVJDI/8IQE2H4zG4mpgya9RLC\nXA6e6oZSXrJ57FgR43MTmYCgU+WcjMQocfCZyaVseWAToRTDzX8XzV1tajbf8kIIZsyYwXnnncf5\n55+fhUUy7FbMnz8fIQRnnnlmuU1pitDAM0KI7cCdWuu7gM5a6w3+/Q1AsLPn54DnjbrvAF2BT/3X\nAdb719OhUnZHLiUcFBQNVlRVu9sJCRKK+lrQFaYDDFsH4Oqr4dFHq9mxA8aMUtx2m3dL2ck0CcaF\n6S8uAhEhCoVC5hlzYJCX4HoxxxfJZQmHTZjwbBtk9h2EMg1SFNQNYROfEhxxIrk0ui8FkdwdWZgT\newFlrA/jnMBCp3GD8nnAihKSjz/AtPGE5ES5CwdjyOcpqI/IxI+S2WZw7EwyObbGt5eg2ZAlgOOP\nP54jjjiCX/3qV1xxxRXlNidDM8X27duZMmUKN998c7Zdxc7hBK31e0KISuBpIcTr5k2ttRZC7J4N\n3or9SobIFgERH+RSLMz3CUuiWmxS6HrpKxbRFUuXn5Nn6TJos2+OCy+Ea68tqAVpqytjjtkFw6sH\nztN+bR9950JAfiJL9cEI00WVkIBpmIev5vNAvZHz7Joz6SVwi3qFrFCRvkI70mAXSAmF7sy+QNK2\nvYgU5ywm3apeLAzsaj6iOBHZ9iAtHEe9HyCuzIWfl0RybXbs+qHgUtSauaIUoFmRJYDp06dz6qmn\nctFFF9G+fftym5OhGeL+++8nl8sxfPjw4oUzxKC1fs//f60Q4rfAMcAGIUQXrfX7QoiDgCDLdT1g\nHhPbDU9RWu+/Nq+vd/U3dfJk70WbNgwdOpShQ4dGC4S7TsYlgyQFySQC4TUzFOP/rFfAPgfK8Mw1\ns8oFZypW/1nRsZPk25PhkrE7/zO9oOYQcZ6xcFfgrIPkXp9QlZaflCCzmTaAR6rqLU4QEgFf7qgH\nKqShbEXnvrZeopFUFx96tH9L7VAGkRP1ispKnM49TciKhZrM9g3SKu3DfmONEKqN/puYnaZlxThZ\ntJx9ILOnAHlHwMjETcFdalnss2Rcj5Cs2IXyYPHixSxevHi399Okd/BOwnnnnUf//v2ZHHxJZsiw\ni7Blyxb69OnDnDlzGDx4cLnN2S3YnTt4CyEqgJZa64+FEBJYCEwDvgxs0lr/RAhxDdBBa32Nn+D9\nGzxC1RV4Bujlq08vABOAF4EngFu01k9Z/bl38DYROGyZi+Vf5FfmoV6ROyy6hKyouGAk3yqiK69U\nXnHu6YpXX/WW1E//mWTQIYXVWkGSeKL64SArMXt8B2aSpYi6EjjUQGnIRxuIKFG2HZEYVQLxsObR\nbEvlFconS8GY/dPifOeuvHQrZDRUVUoujVXGJEsoL0HcNZ9h2DSpyQhZKsyHSZbSUqbMOSuqYFKY\ng3BOUsZqP+PQ1qDRXC6Sv2a2lRhaTHjGsc9EgEakLmU7eDcA06ZN44QTTmD8+PEccMAB5TYnQzPC\nXXfdRb9+/ZotUdoD6Az81g9ftgIe0FovFEIsB+YKIb4FrAXOAdBarxJCzAVWAduAy4xfcJcB9wLt\ngCdtohTCcNhOHx8e8GoUCBJhK6NKQqEhIl5R5VVIioI+vf18/LJ+ey+tknz/AsX7/1R06ZPjnocl\nVZWKjesUuFZCJSDiFMHrIzhJ1hikNFQhlYf6+iB/yiIGwZjX1niKT7U/J2troAKoro6WdRqEk3Ao\nBetWKcQnis8fKr0NFwuMASQFXcmfS5lAXFwIHb40GEfw/EylqCbv6ZXVcb3KpfaE92wVJXYzOtbw\nufhESnlsp2CLI3TqGmtJq/7yeT8p3ejDJrUBGbTVPgpzls/LaJ9SRgmWfy3yeUsyvJn8jUE+AAAg\nAElEQVSiWZKlQw45hFGjRnHTTTcxc+bMcpuToZlAKcWMGTN48skny21Kk4XWugYY6Lj+Lzx1yVVn\nJhD7h6y1fhnoX3LnSkGtH04q4vDDvBtA+QqNzS0imdWOdiKXa/MseBhuuDXHO+9IDhsgeeRJGfIb\nguX1fvjE41gJhMFWaww78n5IJpfgkCN255XH+XJe0rXXaOG+BI8oORAmn4dKgzV8KzJTUVFY/hge\nFlvE0cZIlxlSTEGs/yQlzlK/EuXCUhQt87KtMFkFElVJ80axz6dZLml8MiDPGITH3WyDI2l7EUkK\n0CzJEsD111/PwIEDmTBhAl26dCm3ORmaAW699VaGDBnCoEGDym1Khp2BCkJd0u0sXU6yvt4jDNJc\nui6N//pOPCdjGzabPuzXv4bf37eRrfVw/LBqHn/cKNgAFSVxaPWFtmprgbwRvglst3ywUn49Mwcl\nUF0CwidzUJtHBrto+33ExhlRHYzwkPLIkawC01O7Qlaew5ZI6bMdg4dKn8XFQk6YCoxJ+GScGDgU\npYg9wTw42ExSmC6RzBpqlLSZY5IBDWAsheI5V6pd7LOauA5AFu7HujYUpQzNmCx1796dCy+8kJkz\nZ3LLLbeU25wMTRwffPABP/3pT1m2bFm5TcmwszB/sTt+jcfCI0HOj5QR52xWd65YC5Qhn4zNmAGP\nPyjZd0s9J50EN93lrSwzHX+kmUDVKUF5CflLpXQ6cxeUAvI+UUw6SNgcg+N+Wj8xRcWu7siBcTYQ\n3PdXx9nPJyS8Vk5PzDaHomPbEVMVE+xpCAICBlC7VlFR4eWopTWXqDolXUyoEPuYm3lWjqHKQIEy\n24kz2b2aODVbsgQwadIk+vbty1VXXUWPHj3KbU6GJoxZs2YxcuRI+vTpU25TMuwMVCF5WkW8ZkL5\nwDE4joQw81uUKhxdZlYNcNV4xaJFsK2N5IxvSq691ndSfrv1gbJjrrYLD0BLVkIioaxAvfDvBAfX\nmkJF0ZQbw6nmgy0CCJLAcxFnGbZtxJsSOGNoE9ZLF2cNfbGRDxNEkoKbZjcN9dtpRCRCxBwF0nKa\nkvox26pf56ttji0fvPlM2AMpgah4H93ggbptMqumkjADxfaSiqiGJbTXnNCsyVIul+Oyyy5j2rRp\n3HPPPeU2J0MTxYYNG7j99ttZsWJFuU3JsCtQUtKLXzQhhOIpE0lqk/d3zuWS5c9B5/aKb02AK68s\nVPbzmosqK6UgDCG5Vq3Z7QWhx2rLG6YobpFB7SRiVcME7ILqU1A5rHoJ/abdi8FS62JT4wot2pcD\nVuwzibS9rmx+0+MwS6WxVRy/s11FPmLEOGHcMUKb8Hls0GesmaJZbh1g4sMPP6R3794sWbKEQw89\ntNzmZGiC+N73vgfAzTffXGZL9gx259YBexolfYdZBKGYIw0LWR7RvDRyJLzwAnTpAlddqjjrLN/H\n+g5XyVwYmgmcbRKhsEMnCWaX5MhUjScdSJssmRJZQAZK9YOB2mDbk7ZhZtL85f28spxMVi8c8kdR\nW1eu9PKzDuvnVFrSOGKImhqvjarqiDqYRJaC+jHbkoxtKPFQyjt4t0LGnmdkPI52G9CFB3/OZcDw\nczk/J63xHXWSbR2wk9h///2ZOHEi119/PXPnzi23ORmaGN566y3uv/9+Vq1aVW5TMuwsbDJULIQQ\n/uxOuB8sqXbkiaxaBZdcAv/4BxxyCMyZA5WV0fby6xSqk3E4ni1PWQQiaUzBjtrxBOed+7Wv6kFt\nVNTXKioq/XCef+K9c8PF4HVopKVeOGyO1LXmMFDrdssRGhXRZX2pU5NEAHK5iG1JJCkxvSftufgV\ng4N1CyHJInUS7oWX/M+q8rPAneNOYo7ms3ER371IVYK9gCwBXH755fTu3Zu//e1vfOELXyi3ORma\nEH74wx8yfvx4OnfuXLxwhkaLhiTOlvTVbygwAR5/HCZNgrfeggED4LHHHOGOXM7LUwKq+vnkwpEX\nZduVmBPkUJrS7E9SexQSVVntNVLvLOKoFJ3UyPYDjvuRegYjMIUimSsMKmkcoeM3rjlFGoP0qFx1\noZyD0ZTk760wWalcoaAoWXWcMTFZGlkMwphVuZIMSFX50qsGr2IXIxtT7gXEqdmH4QL88pe/5Pe/\n/322R06GkrF69WoGDx7MmjVr6NChQ7nN2WNojmG4kkMhDYXfzq33SG66CTZvhiFD4IknrDwcQ2ko\n+kPeERJrgCk7NaSdiAB5/6m1wkAp8acCmYuWce7WnWBXqnJj18vnvTK5XHRKpbsRVePt1p5GQNJ2\n7C4FEfvzNd7FlET+xPks9iEqwbhdym8aEVnaXd9fLXZ1g40V3/72t3nttddYunRpuU3J0ERwww03\ncNVVV+1VRKm5ophz/SyYMQNunqFo82Ge07+kmDvXcIqo6C9w/NCWoSbZREopvGVyYTJwIdwVhMVs\nlOKr7H5NJM6P1X+kcymhQqLqC5HJkgwKrvmVij2bfB7yNX6YyhHJc5kMFM7vU6rwHAKm4mJmxaAU\nqtaYf1WwKcmOWB6XOdakgSc1mNjQZ0eky4BZpoxtd9vTGLFXhOEA2rRpw7Rp05g8eTJLlizJTovP\nkIoVK1awZMkS7r777nKbkmF3wPHF7lQ+XDA89mVXS+bN8+qMOQdm3gzIQg5ySndO5cXz5RJ/F8cG\no5TIV1KdmK0plcJL1TlvJ3C/XCkcKX5RRjb0ttU4L2SV0kYSjAZD4lpfC/nKmGKnlBfe8/Zssm8U\n5iDYzyp1Qo2qLpsLZKkE1dCsnDb4hE7C9LpwG4j00K6nGCaHQIuiESlMuxp7DVkCGDt2LDfeeCNP\nPfUUp512WrnNydCIMWXKFCZPnoxz08EMTRsq5eDU0Fs4nruZ2C0lZ50FixbB/vvDZZdLJk50OaJ4\nO7nq6KaVJgo/0N1swyYUwZswN6cUFSAJhqMrTIMM3yvl9S8thxjYrABVG8o6BVutVWPBiryAsLj2\nMDK7CI+EoTTuIPEVEfusNEDVqwIZKNWxB5+XXA4pPWKogvFIt83muJSSkevOriOfyag9JfOPz0BU\nIp8raaxETBpDWkiwmWKvIkstW7Zk+vTpXHvttYwYMYIWLfaaKGSGBmDZsmWsXLmS+fPnl9uUDLsK\nCV/o7pyigtrhhJSMOFPy/PNw0EFeUve4cbEixbsPJBP/pvSvOcuWmKyTSCBk0EHcKCllNF8n0eBo\nXdu552tAIKmstMrWBuQoJTfHMQaV91iNlMHrnd+HKCST0m1D4rQGbC0fJD1BaFTCfJokEigpXzut\nncRiJWxdEApoKn7Pzh3zXspImVS7XIWaMWHaaxK8A2itadeuHS1atEBKyfLly8u2u/fBBx9MPp+n\nVatWzJkzh+rqavbZZx/atm1L27Ztw9etW7du8mHDHTt2sGXLFrZs2cK///1v5+vzzz+fDz/8kDZt\n2pTtuRx66KGsWbOGiooK/v73v++VO783xwRv84veXH3lKShePktwtEmAJHHp9NPh73+Hvn3hvtsV\nh/WwlCi7Yj5PvhaozMXzta08nJLJUk0JycEmampg40bo1KmQr2P0rdZ5idq5fqWTpby1dUHi7s/+\njbDJ6pyz+ZgvNvKrlMI/8Le04SaYHOuz5IKlkFVHvSR+kSrIpLQTICCQqlYhK2Us4Tx8FkEye3BD\nSi//C+OkG6S3v5UfpivZrrSYr7OBPYNsn6VdBCEELVu2pL6+nk8++YSqqqpymwTA6NGj6d27t5NI\nbN++nTZt2jiJlP067V5SuSuuuIKPP/6YVq1acf3119O+fXsnmUkjOsXKbdu2rait7777Ltu3bwco\n+3Opq6tj8ODBvP3222W1I8MuQpqDU9EkjRhJ8S8uWQLf/z6sXg2HHw6/e0h5zqiU7itwJ4JESFaK\nqdYv/rBIimNy+nz74Fy/oOxkkYBijk5KZH2Nt82An3uTS1qeHnjlmrz7foLhYdjO5CgNCJ0B0T21\nXNdKRRhrTMlVSmiwwdyhxIJpZ+WZoTxTAbSJuVcAt1JWzK5mrCK5sNcpSwCVlZVs3LiRiooKVq1a\nVTb1oFQ7tm/fztatWxtEThpS7tFHHyV4zhUVFVxwwQWfiZS57pWijjWG59IYbCg3mp2yVFfnvXH8\nAk7aARko5Cjlcjz8e8kNN8D778NJJ3l7KqFU6hJ/W4xIdZquPCrDuQdJukEDUvorxOoVuUoiB/5G\n+iaaF5VIFEqRemwE6pa/ND/s/zMoCyofVUJiIaYG5hkFeUs2WSohounsLhL6KjVcFpAY6S4bU5tS\nyhYlx4665vW8n3sUkvyIDJWL2wLxZ1pk3OVOYcqUpV2I5cuXM3jwYJYtW1ZWZ1iqHS1btqRdu3a0\na9dut9jRWAhCY3gujcGGDLsYCWENlQdZkbxhn1dNcvvtkltuge0fKUaeAvfNMySgnfUIDfQoARmJ\ncbIKXxFISh+xhJDQ8QVqQqRwaTbnlfQ5pBECTKnuDA8lLAQL5tx7A7afNtWdGPFzJKBFeINxraEI\nCEfYTprCFBtPCcJmqZG9YqG+Ivak3TZtidiVz0NtLWEymlmoWKPNCHulspQhinXr1mUEIUOI5qws\nmbkfxVQfpeDqq2HePNi+Hc4cofjVz1IkiQY4j0BBsVdUJTVVsvBjXUwqY+cblTKOQFUJlBmzbpqi\n1GCyZCpLrmdjkLZIW0bBhuQDmbeSFKeYauN6QI7KaUqRq0rScw8Qrk4ziKLZh0s5LIRu059P8CZC\nlnISqQoKa8GQxkuWMmUpw25Djx49stycDM0XF18M3bvDtGkoY7dob0m6r7I49AYpvbPeWraEb30L\nZs6UcQXHwb6SfIjKK6jN+3v1+CEPFScaLrUhTVlw2iPjTtNsTIFTjXJ1YW9kma4Kxfs03zeoroxf\nM8NgMqgYqGSysOVBYifWMwque30kPLt83usrxg4N21X8E1QK4Y1wK2MsSVysEOp0mhLvHMJVls55\n8fsMt1nA+OzV5iEvvb20ktovgeg3F2RkKUOGDM0b//gHPPOMl2Mz6z4+2aiorQeqCtsDSJQz/+j8\n873/jx0bOJGEn/xgyFTRy0lF8fNeQgJg7DcUOtEUz+MMqZXooYqdohIhcv6FQLlIDBsZZKWoAtYA\nJKljPr9xYmf6sh59oWP7ATqJbVxRCucp/Mwk910gXNYeUSWOJx6SJC7jueQypYgkgxvtyMqdfGDN\nFBlZypAhQ/PG2LFwyy3w9NPIS8+B//dr/4apRihkcMKtgUsu8f7vIjxeEwkkxlU05+3zo5RCGk5K\nqWgl1yaNRRsv9X5KsVi4JlBapOm4k9u3yVtszuycH+N1qH4UszvIL0tgYM5NFFPyfHK5wvWYeQHZ\nKcIspfT7NZ5jYrgxTZEx5jYtNBe7ZhFm5SulIQlKmFezXKyEpZgWXUFohk7TPr9NGBlZypAhQ/PG\nhReiKrvDT36EXLYYefHp8Lvfhd/lSgG1CllREfVugeojHUngDZAuYqGUSAgoUB8MBx86fO9dalcJ\nak4EKrrSLpGz2Cu9TAkpCOsVG2ugjCgX+YuYZDZrXZPRuU9QsaBIDlQ44cZ7W/1LMkQZKpq1otBM\n6pEJzbhChzFil6aKOUSgSJ1wXO6wLYCS3kZisqbGIZv55Mwn7rGwbVLILsXw8EdH6oex6SIjSxky\nZGjWyJNj42Ffo9MdhyO/P87bUfLLX0bd9AsYPMR35gVHWlBYQNV7Z9pG9qv0CzRkGb4zLOOCUuQt\nNadoGKuEOFdtLahaCLcvKyTBxB2lJ5VEr5UaS0u7X8qAEiW8EuEKeQXXws1BjcT2hO6c0VYr/BaU\nU8pLNg+nTSlCbm3Udz57g/QY0+60JfGaZaxzF24Ho0oNlVphRWk3YRtl2mDVbS7IyFKGDBn2DnSv\nguXL4ZRT4IUX4Lvfhut+hPz61/B38ouWlxJZVVAhTBJVMkxniCPcZDkvpTxypin4nGKbdUu8nZwV\nOfc2CFJSUQk6pk5EVYzIIatJG0yaY3KSQRmeD1sYerwtl3piE4Bi/tZUfVznr8Wcdi5H/drCPLjg\nKVUy3OTcqx5nTjZR9oajLNUwUOqKH5gbco189H3Qjv25sZ+Pi2gVSE21k4RGSI+htMXCwjL6Ionr\nSj/L3VOsmh9fyshShgwZmjVyUiF7UPj2fvZZ1BlnwXOL4NqrUTX/RE6dDBihBN9JxnJHPA8dDeUY\nSAqdSWnscVkdqxCJ3zQ4rzawRSnP2TqIRjAOiVEmjRC50EDVJ9FZJqkSjntJjjkkZ66ymKGlaNuV\nVfF2gvbDCJ1Njg2y4Ap5BvNqKnVpdkeHnjBJVgORz6UtCfnhSlzP0+owkeiYSliCcupU28yGzRvN\njSmRkaUMGTLsJYg4it/MQ13yH/DEPORtN8PWOrj22sSwTFivoUghAi67XM41KaphKl3m0SCxcnlP\nLWgwOUpA4UT6AoraaN8rJf+lCLw+47YE9b0xF3kEljpWID7xewnVIgW8/CRVOH+v2JSbJMMksMo8\nMzCNpRicMGFO04hbsAC0QIgKyqDL1FSYz6L5cSValNuADBkyZNideGrpUgYNPpLjjuvN/7vxR2HC\n7ZYbf8K5+7Zn0OZ/MXzWLD745jdDx/HjWbPo3bs3hx56KAsXLgzbevn11+l/3HH07t2byVdfFiYv\nb9myhTFjxjBwYG9OOeU41q1bF9Z56623GD58OEOHHsbJJ/fjrbfeAmDRokUMGjyEo046ju9855vh\nuYiLFy9m//33Z9CgQRx//CBuvfVHoTOrqqriiCOOYNCgQZx00jHRgfrO9pFH7qWyspJBgwYxYMAg\njjv5eNb8/ZUwGzo4kLZFixZMnDgxrD5r1iymTZsWafKIIwZy9tnn+cpFPFS5ZcsWzjprDL169ea4\n46Ljnj17NgMHHsLAgYdw3333hddXrqzh6BOH0nvAAM4991w+/fTT8N6ECRPo3bs3xxwzgOefXxE+\nj4svvpjOnTvTr1//MKlbSjj33HMZNGgQgwYN4vDDqxk8eBBIyaaWLTnj/K/RufO+XHHFFRFOErwe\nOXIkxx3XPxzSNdd8n+OPH8TxJx7FgKMOp1u3A5wKTL9+hWdwxBFHsGDBgijjqFfxpHCjvvkXMchV\n0CziCAcGzyWvCgdEp3UYVcGiUPlCUn1YNkHRS+3HtrG5QGud+OfdzpAhw94E/9996ndDU/kDdM+e\nPfXKlTX6nXe26v79+uvlS5frujqtr776av2Tn/xE65tu0jd26KD/q21bXfeVkfqlPy7RA/r101s3\nb9Y1K1fqnj176h07dmittT766KP1Cy+8oLXW+rThw/UffvtbrbXWt912mx4/frzWWuuHHnpIjxkz\nJpzPk046ST/zzDNaa62VUrq+vl5v375dd+3aXS9atEZv2KD1Nddcr++++26ttdZ/+tOf9Omnn+58\nNlVVVXrTpk3em7o678/Cvffeq6+44gqttdYbNnh/dRvqdN2bGyLl27Ztqw8++GC9ceNGrbXWs2bN\n0lOnTg3vr1q1Sh999LG6qqpaK6WiXfovbrvtNv3tb4/XdXXRcW/atElXVx+s33lns968ebM++OCD\n9Qdr1mi9YYMePfpsPXv2w1prrS+99FJ988236w0btJ437wl92mmn+XPwvD766GNDW5YsWaL/9re/\n6cMOO9wbjz3sujp91YQJ+kc/+lE4z08/vUz//Od36Msvv9wzd4Nnc12d1g88ME+fc875ul+//vFJ\nfvNNPWvyVD1u3LeKPoPVq1frHj166Lo6rTe8WRf2ETMw4VkVvecj8hw3xMsG9833b77pbtZuI+je\n1bZtWszUho51D2B3fX9lylKGDBmaNXr16kWPHlW0bt2ar59zPk8sehqABQsWMG7cOJg4kXE/+xnz\nd2jUomd44lvf4LzRo2ndujVVPXrQq1cvXnjhBd775z/5+MMPOeaYY0ApLjzvPB576qloW8BZZ53F\ns88+C0qxavlytm/fzimnnAJAhdbs+HgHr7++iRYt2lBV1Qsp4eSTv8y8efNQCj75hPBgaxfS7pll\nIuG9nCxsvOmjdevWXHLJJfzsJz8pKAFbt6JW1qBq8jz44IOMHXseI0YM5/HHH4+rCkqx4Le/ZexY\na9zAH//4R4YMGU7r1h3o0KEDw4YN4w/PPovWmqVLFvGN0acBMG7cOH7/+8dAKX7/2KOMGTMOpWDo\n0GP56KMPeP/99wE48cQTOeCAA2jRwilwobVm7vz5nHfeeaAUuk7zxS+ewH77tS3Mga+oaF3H7bf/\njB/8YIp7LqurmfenP3LBBeeZQ40c8hvUq6n5kP3ad/DmtX4XqSn+RJvzHYw5ODDZRi4HOfKR51tf\nX0QFMvoC/zNihWpdqUhh9/k8+VX5uKKVFJNt4sjIUoYMGZoshBCnCiFeF0KsEUL8l6tM9+7dwyjS\nwQd3Y9269SgFGzZsoHPnzgB0HjeO2jZtkNXVbHz/XbrNmQNr14KUdOvWjfXr1/Pue+/RrWtXr1Gl\n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\nQ4YU/H88r/wMVhtTOwAAAABJRU5ErkJggg==\n", "text": [ "" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\n8Jo9e7bMnj1bRIzVcImJidKmTRtp3bq13H333XLq1Cm/5+y7am7mzJlSoUIFOXDggIwYMULeeOMN\nr/zLli2Txo0b+8lx90lKipe88+fPy4ABAyQ1NVU6deokOTk5XisBU1NTJTU1VebNm+cu8/3330vH\n9u0lNSVFBg4cKE8//bSIiBw7dkySk5OlWrVqkpCQIPWSk+Wn48cD9omrv2bMmCFpaWmSlpYmkyZN\n8qu3iMjUqVPlpZdecl936dJFkpOTJS4uTpKTkuTZyZPdbX/mmWdExFgNV716dWnTpo2kp6dLt27d\nZO/27aFXh4VYPTZl0qToV5aZcq0uTisoEJk0aUp0uqLEtVKwpLDr/aXE51uIJ0qp4Dc1Gk25RUQC\nBJGULZRSNwFTReRO83oScFlE/uKRR7/DNJqrDDveXyGNJY1GoymrKKUqAnuAHsBRYBPwoIjsLtWK\naTSacof+uRONRnNFIiKXlFKjgRVAHPCWNpQ0Go0daM+SRqPRaDQaTQj0ajiNRlPusLJZpUU59ZRS\nq5VSu5RS/1FKjTXTayqlPlNKfaeUWqmUSvAoM8nU+61SqpdHejul1E7z3owweuOUUluVUh/brU8p\nlaCU+lAptVsp9Y1SqpPN+iaZ/blTKfWuUuraWOpTSs1VSp1QSu30SIul/GuVUovM9A1KqfpBdL5g\n9ul2pdRipVT1GOpc5KvPI+8flVKXlVI17danlBpjtvE/Sqm/2KlPKdVRKbVJGX8Xm5VSHWL5DH37\n0Q87osb1oQ996KO0DowpuX1AA6ASsA1oFqWsOkAb87wKRoxUM+CvwAQzfSIw3TxvbuqrZOrfR5EH\nfxPQ0Tz/BLgzhN5xwP8Ay8xr2/QB84GHzfOKQHW79JllvgeuNa8XAcNiqQ/oCmQAOz30xlL+KOB1\n8/wBjP29AunsCVQwz6fHWOfnvvrMe/WAT4EcoKad+oBbgc+ASuZ1os36MoE7zPO7gNWxfIbh3gXa\ns6TRaMobljartIKIHBeRbeZ5AbAbYy+nezGMDMz/+5rnfYD3ROSiiBzAeHF3UkrVBaqKyCYz3zse\nZbxQSiUD/w38A3Ct6rFFn+nt6Coic802XhKRsza270fgIhCvjAD9eIzg/JjpE5G1QJ6P3li2x1PW\nR0CPQDpF5DMRuWxebgRcv/ESC53pAdoI8Ddggk+aXfp+B/zZ/BtDRE7ZrO8YhiEPkAC4fmsoJs+Q\nMGhjSaPRlDcsbVYZKUqpBhjfdjcC14vICfPWCeB68/wGU5+vbt/0IyHq9HfgCeCyR5pd+hoCp5RS\nbyulspVSc5RSDrv0icgZ4CXgEIaRlC8in9nYPhexlO/+fInIJeCs55RXEB7G8GzETCdFhgMASqk+\nQK6I7PDRbYs+oDFwizmNlamUam+zvieBl5RSh4AXgEmx1BfuGWpjSaPRlDdivmpFKVUF4xvoYyLy\nk5cyw5cfE51KqXuAkyKylSKvkhex1Icx7dYWY0qiLeDEGJRs0aeUSgEex5guuQGoopQaYpe+QNgt\n3xel1GSgUETetVFHPPAUMMUz2S59JhWBGiJyE4Zx/77N+t4CxorIjcAfgLk26/NCG0sajaa8cQQj\ndsNFPby/YUaEUqoShqG0QESWmMknlFJ1zPt1gZNBdCebuo9QNA3jSj+CP12Ae5VSOcB7wG1KqQU2\n6svF8EZsNq8/xDCejtukrz3wlYicNr/RLwY626jPRSz6L9ejzI2mrIpAddNj5odSajjGlOpgj+SY\n6MTwvrhIwTBAt5ufnWQgSyl1vU36MPMuBjA/P5eVUv/PRn0dReRf5vmHGNPtrrK2PUMX2ljSaDTl\njS1AY6VUA6XUNRgBnMuiEaSUUhjfaL8RkZc9bi3DCEzG/H+JR/ogpdQ1SqmGGFMVm0TkOPCjMlaa\nKeBXHmXciMhTIlJPRBoCg4AvRORXNuo7DhxWSqWZSbcDu4CP7dAHfAvcpJS6zsx3O/CNjfrwkFNc\n+UsDyOoPrAqkUCl1J4bHpY+InPepS0x1ishOEbleRBqan51coK059WhXG5cAt5ltTQOuEZEfbNS3\nTynVzTy/DfjOrv4MSLgIcH3oQx/6uNIOjNUyezCCPScVQ87NGLFD24Ct5nEnUBNjxc53wEogwaPM\nU6bebzFX75jp7YCd5r2ZFnR3o2g1nG36MIJpNwPbMTwF1W3WNwHDINuJEWRbKZb6MDxyR4FCjLiU\nETGWfy3GlNNeYAOGR8dX58Pm/YMen5vXY6hzmanvgquNPn38PeZqOLv0mc9tgVk+C+hugz7PZ9ge\nI15wG/A1kBHLZxju71FvSqnRaDQajUYTAj0Np9FoNBqNRhMCbSxpNBqNRqPRhEAbSxqNRqPRaDQh\n0MaSRqPRaDQaTQi0saTRaDQajUYTAm0saTQajUaj0YRAG0sajUaj0Wg0IdDGkkaj0Wg0Gk0I/g9T\nvNhAQiy1fgAAAABJRU5ErkJggg==\n", "text": [ "" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\n+xc3Fh+zP53t5vIIwaPPPsspJ54Y1FkjJTNmzOBvf/sbM6ZN45nnn+cf736INDZG0s0+8oQTuO6m\nm4J7++67L++88x8+ef9jzjzlFC677LLCkxJj8+zZ9jmVMr/Ksah2faP1ATRYjtJM9F74ZP+Nl15o\nUDvNDSlZSpEixeaKPYHPlVLVSqk1wGPAaLPQO+98xTcroO9+PTjs9NX07NkTgG7duvGdqgchWLp0\nKZlMBomgvEfv0MHaixYvpqKigp49e7Jo6dIgMXfx4kVsvXUF2Sz03G47FuZyIARr167l22+/ZZst\ntgApWbluHUeceCI3XnMNew4cGDijvQYP5o0XXmDm9OkopejXr3/Q59y5czn7V79i2nPPsXWPHiAE\nFRUVVFRUMOzAA6FrOUcffTzvz54drFrSfbAfhgM44ogjeOONN0JzIgRssYX7unXr1vz617/m5ptv\nDu6v23JLpv5jGtfddBOVAwdywQUX8OKLL/LSSy8BeYfas29fFi1din9x0eefU9GrV6C8LVzoJnV/\n+607J126dKFnz57B/AoB2W9q6N6rkm222YYVK1awfv16AD77fDHbdusRIhhr1mhkKUHWmPnfmYjK\nDGu32IKnn32OI487Lbi3Xdeu7LPnPmyxxTa079WL/x09mv+++06ExBRSYPzujzzsMN54440g6TwW\nUuZ399b6ePNNgyz5481koHdlItnxiwYr24yyUrp7bkmRCVROnz+Zn5lsFrJVMhTC1DuZ+e6bkcTz\nloSULKVIkWJzRU/gK+39Iu9aCKtWfcbuxzjc9NIQHn32Hxx88FHIrOSwgw/job//HYTgvvse4vDD\njwbgf//3KB577DFWr15NVXU1n33xRZDL0rFjR959dyb19YrHHnuEIw85FKTkqEMP5aGJEwF48skn\nOejgg0EIVq9ezTHHHMOYMadz6MGjQ06mdsECkJJVbdrw71mz+OW4MxBIFi5cyDGjj+G+2++jb9++\nQShk2223ZbvttuPTFSsQlRn+/e9XGOjl3djylYR33OyMGTPcdiBEMHRCdeaZZ/Lyy6+QzdailOKd\nd15l8OAhfDz/K6qqq6murubYY4/l448/DupICR07dqdjx47MnDkTpRSPPPYYo0e7fPWoo47ioYce\nAuCZZ57koIMOAuAnP/kJL730EosXr2DRom+YPv1l9tl1BLXzatl3n3155JG/g5RMfmIyRxx2RGhs\n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\n+P8Bk38bBJ6K5/sAAAAASUVORK5CYII=\n", "text": [ "" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\nofhiw/eJLmlPy6jim6RKLd+rpLkNGx6klLEv57SBgcHOBPf/feJ3Q315AbJDhw5y0aJyuXbtJtmz\nZ0950UWLZdu2Uu6++xWyV69bZXW1lLdcf7380x//KCsrpfzP7Pdkz+7d5aZNm2T5okWyQ/v2sra2\nVkopZZ8+feQ777wjq6ulPPYXx8sZj82QUkp5zz33yAvPO0/K6mr5+OOPy+HDh0sppXzppbny8MOP\nlLW1tXLr1q3y8L59ZdmMGbK6slpWV2fW/LTTTpMPP/ywlFLKiRMnyssuu0pWV0tZUVEl99qrpVy3\nbrOUUkrbtmV1tZTr1m2Wffv2lW+8/LKU1dWB17S775YXjx7tyx45cqS8994H/fG8pg8++KA84IAD\nHF2rq6WsrJTdunSRX375pd/oyiuvlIMHD5Znn3124B7xZKhrIqWUJ510kpw5Y4aU1dXOmlx4oZRS\nOmty2mlSVlfLNWvWyPbt28u1a9fKtWvXyvbt28t169ZJKaUcOnSofGL6dCmrq+Xoc8+V/7jzTiml\nlE8//aI8/viTpJRSzn1pruzz8z7K/M6Sf//7/VJKKTdv3uzL2rBhgz+v22+6XZ599rlSSilramrk\n1q1bpZRSfv3117Jly73l+lXr5Q/ffitbtmwp16xZI6WU8sorr5STrrhCVn9RGVi7l16aKwcPHuyv\nwfjx4+X48RNlZaUMXFOvgbpWce8ja1vp6O01qK6sdo5J6RyvrIx21FybuIO+PI2OWWXlOmaBsKO+\nv4xnycDAoEGjtLQjXbq0o0WLJjRufAbTpj1HbS1Yuz/LrKdPx7Lg7N/8hmf//W8sC157/UVGDB1K\nkyZNaNe2LR3bt+edd97h66+/5rvvvuPQQw/FsuC3o37Hv1+ZBcDzzz/PsN+ch43FaaedxquvvgpA\ncXGKTZs28cMPP7Bx40Z++GEzezZzPQHuz/Gvv97Aa6+9ximnnAJA69at2bhxA5YF333nbOTdvLmT\nMVFUVIRtw9q1m9i6dStN92rjJ1Cr2LRJYtuwZcsWbNtmr71aRtoIIRg0aBCLFi1iydKlkfNSSp55\n5hnuvfdeXnv1VX749tuA3kBmTbp2BdvmrLPO4tkZM8C2ef755zn77LMBnDV5/XWwLGY/9xzHH3MM\nLVq0oEWLFgwYMICZM2cipWTu3LmcfuqpAJx93nk8O3MmALNnP8fIkWdjp236HNyHdd9toLKykvXr\n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\n3n77bVq0aEGrVq3Yd9992X///VmyZAkAc+bMoWvXrmzaBMuWLVVCnc/5a7V4cQXr12/BsmDNmi9Z\nunQpnXr0oH3Xrnz66aesXr0agFdeeSVwrVSozjNvfT3esc2hq9D18d4meYB0/cAN5bmlK+x09Hzc\nw3F+f28O2SazUzwG5yIp+xvzNJyBwU4H6snTcMBpwH8rn38L/DXURl577UuyU6fOskP79nLKpEn+\nPNesWSOPPfZY2alTJzlgwAC5du1a/9zEiTfJ9u07yJ/97Gdy1rPP+o/6zH/jDdntwANlh/bt5cUX\nXyyldE6t+WqNHHrqqbJjx46yb9++sry83Jd16aWXyq5du8ouXbrIyy67LLDW/fv3l7Nnz5bjx0/0\nnyiqqKiSgwYNkj169JDdunWTjz76qJRSyo/mzpW9u3aVPbt3l927d5e33XabL+fee++V9957r5RS\nymnTpsni4mLZq1cv2aNHD/mrX/1KVlVUyPDjWtOmTZMXX3yx/3DV3XffLRs1aiQXL66QZ55xprzv\n7rsDuj7//POyU6dOMoz58+fLbt26yQ4dOgTXZM33cujQodo1eeCBB2THjh1lx44d5bRp0/zjX3zx\nhezd+1BZWtpRDhs2TG7atMk/N2bMGNmhQwfZo0cP+f777/vHFyxYIA855BDZo0cPeergwXLdypVy\n/PiJ8uSTT5PdunWTPXv2lL/+9a9lpfsE2dSpD8uDDuoqe/XqJfv06SNnzpzpy5o+fbrs1q2b7NGj\nhxwyZIj89ttv/blfd911Ukop586dK5s3by579eole/bsKX/xi1/IpUuXRtYlV0ycOFH6i6Y+sZbr\nE2a6hupTbpXR8+EuuYzl65lt7AJjR31/CRn6FaJCCBF/0sDAoMFCSplDAk9hIYQ4DJgkpTzR/Twe\nqJVS3qq0Md9hBgY7GXbE91ciWTIwMDCoqxBC7AJ8BhwLrALeBUZIKT9J7GhgYGCQJ8x2JwYGBvUS\nUsotQog/ALOBxsD9higZGBjsCBjPkoGBgYGBgYFBAszTcAYGBg0OuRSr/Al0qBBCfCSE+FAI8a57\nrKUQ4hUhxBIhxMtCiBZK+/Guvp8KIY5Xjh8shPjYPXfXdtDrASFEpRDiY+XYdtNLCLGbEOIJ9/jb\nQoi221HPSUKIFe6afiiEOKkO6Lm/EGKuEGKREOL/hBBj3eN1cU3jdK1T6yqEaCqEeEcIsUAIsVgI\ncbN7vHBruiOyxs3LvMzLvAr1wgnJLQPaAU2ABcBBBdCjHGgZOnYbcKX7/k/ALbolk0IAAAN5SURB\nVO77Lq6eTVy9l5Hx/L8LHOq+fwk48UfqdRTQG/h4R+gFXAT83X0/HHh8O+o5Efijpm0h9dwX6OW+\n3wMnj+6gOrqmcbrWxXUtcv/uArwN9CvkmhrPkoGBQUNDTsUqfyKEn8oZAkx3308HTnHfnww8JqXc\nLKWswPmy7yuEaA00k1K+67Z7SOmzTZBSvgGs3YF6qbKexknA3156QnRNC63nN1LKBe77auATnHpf\ndXFN43SFureu3r41u+L8AFpLAdfUkCUDA4OGhpyKVf4EkMAcIcR8IcT57rFWUspK930l0Mp9vx+O\nnh48ncPHV7Jj5rI99fLXX0q5BVgvhIju5LvtuFgIsVAIcb8ShqkTegoh2uF4w96hjq+pouvb7qE6\nta5CiEZCiAU4azdXSrmIAq6pIUsGBgYNDXXlqZUjpZS9gZOAMUKIo9ST0vH/1xVdfdRVvVz8AygF\negFfA3cUVp0MhLMT8tPAJVLK79RzdW1NXV2fwtG1mjq4rlLKWillL6AEOFoIcUzo/E+6poYsGRgY\nNDSsBPZXPu9P8NflTwIp5dfu3ypgBk54sFIIsS+AGyJIu83DOpfg6LzSfa8eX7kD1N0eeq1Q+hzg\nytoFaC6l/HZ7KCmlTEsXwFScNS24nkKIJjhE6WEp5bPu4Tq5poquj3i61tV1dXVbD7wIHEwB19SQ\nJQMDg4aG+UAnIUQ7IcSuOMmbz/+UCgghioQQzdz3FnA88LGrx9lus7MBz7A+D5whhNhVCFEKdALe\nlVJ+A2wQQvQVQgjgTKXP9sT20Os5jazTgVe3l5KugfRwKs6aFlRPV+79wGIp5Z3KqTq3pnG61rV1\nFULs44UChRC7AwOADynkmm5Llrp5mZd5mVddfuGEvj7DSfQcX4DxS3GezlkA/J+nA9ASmAMsAV4G\nWih9rnb1/RQ4QTl+MI7xWgbcvR10ewyn4vkmnJyN321PvYDdgCeBpTj5MO22k57n4CTofgQsdA1l\nqzqgZz+g1r3WH7qvE+vomup0PamurSvQHfjA1fMj4Irt/f8nXz1NUUoDAwMDAwMDgwSYMJyBgYGB\ngYGBQQIMWTIwMDAwMDAwSIAhSwYGBgYGBgYGCTBkycDAwMDAwMAgAYYsGRgYGBgYGBgkwJAlAwMD\nAwMDA4MEGLJkYGBgYGBgYJAAQ5YMDAwMDAwMDBLw/8CdJ7uR+xIZAAAAAElFTkSuQmCC\n", "text": [ "" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\n", "text": [ "" ] } ], "prompt_number": 15 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Author: Jason Chin, Dec. 5, 2014" ] } ], "metadata": {} } ] } ================================================ FILE: examples/fc_run_LG.cfg ================================================ [General] # list of files of the initial bas.h5 files input_fofn = input.fofn #input_fofn = preads.fofn input_type = raw #input_type = preads # The length cutoff used for seed reads used for initial mapping length_cutoff = 10000 # The length cutoff used for seed reads usef for pre-assembly length_cutoff_pr = 7000 jobqueue = bigmem sge_option_da = -pe smp 4 -q %(jobqueue)s sge_option_la = -pe smp 16 -q %(jobqueue)s sge_option_pda = -pe smp 8 -q %(jobqueue)s sge_option_pla = -pe smp 16 -q %(jobqueue)s sge_option_fc = -pe smp 24 -q %(jobqueue)s sge_option_cns = -pe smp 16 -q %(jobqueue)s da_concurrent_jobs = 96 cns_concurrent_jobs = 96 pda_concurrent_jobs = 96 pa_HPCdaligner_option = -v -dal128 -t16 -e.70 -l1000 -s1000 ovlp_HPCdaligner_option = -v -dal128 -t32 -h60 -e.96 -l500 -s1000 pa_DBsplit_option = -x500 -s400 ovlp_DBsplit_option = -x500 -s400 falcon_sense_option = --output-multi --min-idt 0.70 --min-cov 4 --max-n-read 200 --n-core 16 overlap_filtering_setting = --max-diff 60 --max-cov 60 --min-cov 2 --n-core 24 ================================================ FILE: examples/fc_run_arab.cfg ================================================ [General] # list of files of the initial bas.h5 files input_fofn = input.fofn #input_fofn = preads.fofn input_type = raw #input_type = preads # The length cutoff used for seed reads used for initial mapping length_cutoff = 15000 # The length cutoff used for seed reads usef for pre-assembly length_cutoff_pr = 15000 jobqueue = your_queue sge_option_da = -pe smp 8 -q %(jobqueue)s sge_option_la = -pe smp 2 -q %(jobqueue)s # 6 seems to small... 8 might be better for Dmel sge_option_pda = -pe smp 8 -q %(jobqueue)s sge_option_pla = -pe smp 2 -q %(jobqueue)s sge_option_fc = -pe smp 24 -q %(jobqueue)s sge_option_cns = -pe smp 8 -q %(jobqueue)s da_concurrent_jobs = 32 pda_concurrent_jobs = 32 pa_HPCdaligner_option = -v -dal128 -t16 -e.70 -l1000 -s1000 ovlp_HPCdaligner_option = -v -dal128 -t32 -h60 -e.96 -l500 -s1000 pa_DBsplit_option = -x500 -s400 ovlp_DBsplit_option = -x500 -s400 falcon_sense_option = --output-multi --min-idt 0.70 --min-cov 4 --max-n-read 200 --n-core 6 overlap_filtering_setting = --max-diff 100 --max-cov 100 --min-cov 1 --bestn 10 --n-core 24 ================================================ FILE: examples/fc_run_dmel.cfg ================================================ [General] # list of files of the initial bas.h5 files input_fofn = input.fofn #input_fofn = preads.fofn input_type = raw #input_type = preads # The length cutoff used for seed reads used for initial mapping length_cutoff = 12000 # The length cutoff used for seed reads usef for pre-assembly length_cutoff_pr = 12000 jobqueue = your_queue sge_option_da = -pe smp 8 -q %(jobqueue)s sge_option_la = -pe smp 2 -q %(jobqueue)s # 6 seems to small... 8 might be better for Dmel sge_option_pda = -pe smp 8 -q %(jobqueue)s sge_option_pla = -pe smp 2 -q %(jobqueue)s sge_option_fc = -pe smp 24 -q %(jobqueue)s sge_option_cns = -pe smp 8 -q %(jobqueue)s da_concurrent_jobs = 32 pda_concurrent_jobs = 32 pa_HPCdaligner_option = -v -dal128 -t16 -e.70 -l1000 -s1000 ovlp_HPCdaligner_option = -v -dal128 -t32 -h60 -e.96 -l500 -s1000 pa_DBsplit_option = -x500 -s400 ovlp_DBsplit_option = -x500 -s400 falcon_sense_option = --output-multi --min-idt 0.70 --min-cov 4 --max-n-read 200 --n-core 6 overlap_filtering_setting = --max-diff 30 --max-cov 60 --min-cov 5 --n-core 24 ================================================ FILE: examples/fc_run_ecoli.cfg ================================================ [General] # list of files of the initial bas.h5 files input_fofn = input.fofn #input_fofn = preads.fofn input_type = raw #input_type = preads # The length cutoff used for seed reads used for initial mapping length_cutoff = 12000 # The length cutoff used for seed reads usef for pre-assembly length_cutoff_pr = 12000 jobqueue = your_queue sge_option_da = -pe smp 8 -q %(jobqueue)s sge_option_la = -pe smp 2 -q %(jobqueue)s sge_option_pda = -pe smp 8 -q %(jobqueue)s sge_option_pla = -pe smp 2 -q %(jobqueue)s sge_option_fc = -pe smp 24 -q %(jobqueue)s sge_option_cns = -pe smp 8 -q %(jobqueue)s da_concurrent_jobs = 32 pda_concurrent_jobs = 32 pa_HPCdaligner_option = -v -dal4 -t16 -e.70 -l1000 -s1000 ovlp_HPCdaligner_option = -v -dal4 -t32 -h60 -e.96 -l500 -s1000 pa_DBsplit_option = -x500 -s50 ovlp_DBsplit_option = -x500 -s50 falcon_sense_option = --output-multi --min-idt 0.70 --min-cov 4 --max-n-read 200 --n-core 6 overlap_filtering_setting = --max-diff 100 --max-cov 100 --min-cov 20 --bestn 10 --n-core 24 ================================================ FILE: examples/fc_run_ecoli_2.cfg ================================================ [General] # list of files of the initial bas.h5 files input_fofn = input.fofn #input_fofn = preads.fofn input_type = raw #input_type = preads # The length cutoff used for seed reads used for initial mapping length_cutoff = 12000 # The length cutoff used for seed reads usef for pre-assembly length_cutoff_pr = 12000 jobqueue = your_queue sge_option_da = -pe smp 8 -q %(jobqueue)s sge_option_la = -pe smp 2 -q %(jobqueue)s sge_option_pda = -pe smp 8 -q %(jobqueue)s sge_option_pla = -pe smp 2 -q %(jobqueue)s sge_option_fc = -pe smp 24 -q %(jobqueue)s sge_option_cns = -pe smp 8 -q %(jobqueue)s da_concurrent_jobs = 32 pda_concurrent_jobs = 32 pa_HPCdaligner_option = -v -dal24 -t16 -e.70 -l1000 -s1000 ovlp_HPCdaligner_option = -v -dal24 -t32 -h60 -e.96 -l500 -s1000 pa_DBsplit_option = -x500 -s200 ovlp_DBsplit_option = -x500 -s200 falcon_sense_option = --output-multi --min-idt 0.70 --min-cov 4 --max-n-read 200 --n-core 6 overlap_filtering_setting = --max-diff 100 --max-cov 100 --min-cov 20 --bestn 10 --n-core 24 ================================================ FILE: examples/logging.json ================================================ { "version": 1, "formatters": { "format_full": { "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s" }, "format_brief": { "format": "%(levelname)s: %(message)s" } }, "filters": { }, "handlers": { "handler_file_all": { "class": "logging.FileHandler", "level": "DEBUG", "formatter": "format_full", "filename": "all.log", "mode": "w" }, "handler_stream": { "class": "logging.StreamHandler", "level": "INFO", "formatter": "format_brief", "stream": "ext://sys.stderr" } }, "loggers": { }, "root": { "handlers": ["handler_stream", "handler_file_all"], "level": "NOTSET" }, "disable_existing_loggers": false } ================================================ FILE: examples/run_ecoli_test.sh ================================================ mkdir ecoli_test/ cd ecoli_test/ mkdir data cd data wget https://www.dropbox.com/s/tb78i5i3nrvm6rg/m140913_050931_42139_c100713652400000001823152404301535_s1_p0.1.subreads.fasta wget https://www.dropbox.com/s/v6wwpn40gedj470/m140913_050931_42139_c100713652400000001823152404301535_s1_p0.2.subreads.fasta wget https://www.dropbox.com/s/j61j2cvdxn4dx4g/m140913_050931_42139_c100713652400000001823152404301535_s1_p0.3.subreads.fasta cd .. find $PWD/data -name "*.fasta" > input.fofn cp ../FALCON/examples/fc_run_ecoli_2.cfg . fc_run.py fc_run_ecoli_2.cfg ================================================ FILE: falcon.snake ================================================ import json import os #import snakemake.utils def snake_merge_dynamic_dict(reldir, input_fns, pattern, wildcards): '''Assume each wildcard appears at most once in the pattern. ''' for k in wildcards: pattern = pattern.replace('{%s}' %k, '(?P<%s>\w+)' %k) re_dynamic = re.compile(pattern) mapped = list() for fn in input_fns: mo = re_dynamic.search(fn) assert mo, '{!r} did not match {!r}'.format(fn, re_dynamic.pattern) file_description = dict() file_description['wildcards'] = dict(mo.groupdict()) file_description['fn'] = os.path.relpath(fn, reldir) mapped.append(file_description) return mapped def snake_merge_multi_dynamic(output_fn, dict_of_input_fns, dict_of_patterns, wildcards): outdir = os.path.normpath(os.path.dirname(output_fn)) if not os.path.isdir(outdir): os.makedirs(outdir) assert list(sorted(dict_of_input_fns.keys())) == list(sorted(dict_of_patterns.keys())) all_mapped = dict() for i in dict_of_patterns.keys(): input_fns = dict_of_input_fns[i] pattern = dict_of_patterns[i] mapped = snake_merge_dynamic_dict(outdir, input_fns, pattern, wildcards) all_mapped[i] = mapped all_grouped = dict() for i, mapped in all_mapped.items(): #print(i, mapped) for file_description in mapped: #print(file_description) #print(file_description['wildcards']) #print(list(sorted(file_description['wildcards'].items()))) wildkey = ','.join('{}={}'.format(k,v) for k,v in sorted(file_description['wildcards'].items())) if wildkey not in all_grouped: new_group = dict( wildcards=dict(file_description['wildcards']), fns=dict(), ) all_grouped[wildkey] = new_group group = all_grouped[wildkey] wildcards = file_description['wildcards'] assert wildcards == group['wildcards'], '{!r} should match {!r} by snakemake convention'.format( wildcards, group['wildcards']) fn = file_description['fn'] group['fns'][i] = fn ser = json.dumps(all_grouped, indent=2, separators=(',', ': ')) + '\n' with open(output_fn, 'w') as out: out.write(ser) shell.prefix(''' # Add -e vs. in falcon_unzip. set -vex hostname pwd ''') rule static_0_rawreads: input: config='config.json', raw_reads_fofn='input.fofn' output: db_build_done='0-rawreads/rdb_build_done', length_cutoff='0-rawreads/length_cutoff', raw_reads_db='0-rawreads/raw_reads.db', run_jobs='0-rawreads/run_jobs.sh' params: topdir=".." shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date python -m falcon_kit.mains.build_rdb --input-fofn-fn=../{input.raw_reads_fofn} --config-fn=../{input.config} --run-jobs-fn=../{output.run_jobs} --length-cutoff-fn=../{output.length_cutoff} --job-done-fn=../{output.db_build_done} touch ../{output.db_build_done} date ''' rule static_0_rawreads_daligner_scatter: input: db='0-rawreads/raw_reads.db', run_jobs='0-rawreads/run_jobs.sh' output: scattered='0-rawreads/daligner-scatter/scattered.json' params: wildcards="dal0_id", pread_aln="0", topdir="../..", db_prefix="raw_reads", skip_checks="0", stage="0-rawreads" shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date python -m falcon_kit.mains.daligner_scatter --run-jobs-fn=../../{input.run_jobs} --db-prefix={params.db_prefix} --db-fn=../../{input.db} --skip-checks={params.skip_checks} --pread-aln={params.pread_aln} --stage={params.stage} --wildcards={params.wildcards} --scattered-fn=../../{output.scattered} date ''' rule dynamic_foo_split: input: '0-rawreads/daligner-scatter/scattered.json' output: daligner_settings=dynamic('0-rawreads/daligner-scripts/{dal0_id}.symlink/settings.json'), daligner_script=dynamic('0-rawreads/daligner-scripts/{dal0_id}.symlink/daligner-script.sh') shell: 'python -m falcon_kit.mains.copy_mapped --special-split={input} daligner_settings="0-rawreads/daligner-scripts/{{dal0_id}}.symlink/settings.json" daligner_script="0-rawreads/daligner-scripts/{{dal0_id}}.symlink/daligner-script.sh"' rule static_0_rawreads__dal0_id_: input: daligner_script='0-rawreads/daligner-scripts/{dal0_id}.symlink/daligner-script.sh', daligner_settings='0-rawreads/daligner-scripts/{dal0_id}.symlink/settings.json' output: job_done='0-rawreads/{dal0_id}/daligner.done' params: dal0_id="{dal0_id}" shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date # Note: HPC.daligner chooses a merged filename in its generated script, so we will symlink to it. python -m falcon_kit.mains.daligner --daligner-settings-fn=../../{input.daligner_settings} --daligner-script-fn=../../{input.daligner_script} --job-done-fn=../../{output.job_done} date ''' rule dynamic_foo_merge: input: job_done=ancient(dynamic('0-rawreads/{dal0_id}/daligner.done')) output: '0-rawreads/daligner-gathered/gathered.json' run: snake_merge_multi_dynamic(output[0], dict( job_done=[str(i) for i in input.job_done] ), dict( job_done="0-rawreads/{dal0_id}/daligner.done" ), ["dal0_id"] # all wildcards ) rule static_0_rawreads_daligner_intermediate_gathered_las: input: gathered='0-rawreads/daligner-gathered/gathered.json' output: las_paths='0-rawreads/daligner-intermediate-gathered-las/gathered-las.txt' params: topdir="../.." shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date python -m falcon_kit.mains.daligner_gather --gathered-fn=../../{input.gathered} --las-paths-fn=../../{output.las_paths} date ''' rule static_0_rawreads_merge_scatter: input: gathered_las='0-rawreads/daligner-intermediate-gathered-las/gathered-las.txt', run_jobs='0-rawreads/run_jobs.sh' output: scattered='0-rawreads/merge-scatter/scattered.json' params: db_prefix="raw_reads", wildcards="mer0_id", topdir="../..", stage="0-rawreads" shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date python -m falcon_kit.mains.las_merge_scatter --db-prefix={params.db_prefix} --stage={params.stage} --run-jobs-fn=../../{input.run_jobs} --gathered-las-fn=../../{input.gathered_las} --wildcards={params.wildcards} --scattered-fn=../../{output.scattered} date ''' rule dynamic_foo1_split: input: '0-rawreads/merge-scatter/scattered.json' output: las_paths=dynamic('0-rawreads/merge-scripts/{mer0_id}.symlink/las_paths.json'), merged_las_json=dynamic('0-rawreads/merge-scripts/{mer0_id}.symlink/merged_las.json'), merge_script=dynamic('0-rawreads/merge-scripts/{mer0_id}.symlink/merge-script.sh') shell: 'python -m falcon_kit.mains.copy_mapped --special-split={input} las_paths="0-rawreads/merge-scripts/{{mer0_id}}.symlink/las_paths.json" merged_las_json="0-rawreads/merge-scripts/{{mer0_id}}.symlink/merged_las.json" merge_script="0-rawreads/merge-scripts/{{mer0_id}}.symlink/merge-script.sh"' rule static_0_rawreads__mer0_id_: input: las_paths='0-rawreads/merge-scripts/{mer0_id}.symlink/las_paths.json', merge_script='0-rawreads/merge-scripts/{mer0_id}.symlink/merge-script.sh', merged_las_json='0-rawreads/merge-scripts/{mer0_id}.symlink/merged_las.json' output: job_done='0-rawreads/{mer0_id}/merge.done', merged_las='0-rawreads/{mer0_id}/merged.las' params: mer0_id="{mer0_id}" shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date # Note: HPC.daligner chooses a merged filename in its generated script, so we will symlink to it. python -m falcon_kit.mains.las_merge --las-paths-fn=../../{input.las_paths} --merge-script-fn=../../{input.merge_script} --las-merged-fn-fn=../../{input.merged_las_json} --las-merged-symlink-fn=../../{output.merged_las} --job-done-fn=../../{output.job_done} date ''' rule dynamic_foo1_merge: input: job_done=ancient(dynamic('0-rawreads/{mer0_id}/merge.done')), merged_las=ancient(dynamic('0-rawreads/{mer0_id}/merged.las')) output: '0-rawreads/merge-gathered/gathered.json' run: snake_merge_multi_dynamic(output[0], dict( job_done=[str(i) for i in input.job_done], merged_las=[str(i) for i in input.merged_las] ), dict( job_done="0-rawreads/{mer0_id}/merge.done", merged_las="0-rawreads/{mer0_id}/merged.las" ), ["mer0_id"] # all wildcards ) rule static_0_rawreads_merged_las_fofn: input: gathered='0-rawreads/merge-gathered/gathered.json' output: las_fofn='0-rawreads/merged-las-fofn/las.fofn', las_fopfn='0-rawreads/merged-las-fofn/las.fopfn' params: topdir="../.." shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date python -m falcon_kit.mains.las_merge_gather --gathered-fn=../../{input.gathered} --las-fofn-fn=../../{output.las_fofn} --las-fopfn-fn=../../{output.las_fopfn} date ''' rule static_0_rawreads_cns_scatter: input: config='config.json', las_fopfn='0-rawreads/merged-las-fofn/las.fopfn', length_cutoff='0-rawreads/length_cutoff', raw_reads_db='0-rawreads/raw_reads.db' output: scattered='0-rawreads/cns-scatter/scattered.json' params: wildcards="cns0_id,cns0_id2", topdir="../.." shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date python -m falcon_kit.mains.consensus_scatter --las-fopfn-fn=../../{input.las_fopfn} --db-fn=../../{input.raw_reads_db} --length-cutoff-fn=../../{input.length_cutoff} --config-fn=../../{input.config} --wildcards={params.wildcards} --scattered-fn=../../{output.scattered} date ''' rule dynamic_foo2_split: input: '0-rawreads/cns-scatter/scattered.json' output: las=dynamic('0-rawreads/cns-scatter/{cns0_id}.symlink/merged.{cns0_id2}.las') shell: 'python -m falcon_kit.mains.copy_mapped --special-split={input} las="0-rawreads/cns-scatter/{{cns0_id}}.symlink/merged.{{cns0_id2}}.las"' rule static_0_rawreads_consensus__cns0_id_: input: config='config.json', db='0-rawreads/raw_reads.db', las='0-rawreads/cns-scatter/{cns0_id}.symlink/merged.{cns0_id2}.las', length_cutoff='0-rawreads/length_cutoff' output: fasta='0-rawreads/consensus/{cns0_id}/consensus.{cns0_id2}.fasta' params: cns0_id2="{cns0_id2}", cns0_id="{cns0_id}" shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date python -m falcon_kit.mains.consensus_task --las-fn=../../../{input.las} --db-fn=../../../{input.db} --length-cutoff-fn=../../../{input.length_cutoff} --config-fn=../../../{input.config} --fasta-fn=../../../{output.fasta} date ''' rule dynamic_foo2_merge: input: fasta=ancient(dynamic('0-rawreads/consensus/{cns0_id}/consensus.{cns0_id2}.fasta')) output: '0-rawreads/cns-gather/gathered.json' run: snake_merge_multi_dynamic(output[0], dict( fasta=[str(i) for i in input.fasta] ), dict( fasta="0-rawreads/consensus/{cns0_id}/consensus.{cns0_id2}.fasta" ), ["cns0_id", "cns0_id2"] # all wildcards ) rule static_0_rawreads_preads: input: gathered='0-rawreads/cns-gather/gathered.json' output: preads_fofn='0-rawreads/preads/input_preads.fofn' params: topdir="../.." shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date python -m falcon_kit.mains.consensus_gather --gathered-fn=../../{input.gathered} --preads-fofn-fn=../../{output.preads_fofn} date ''' rule static_0_rawreads_report: input: config='config.json', length_cutoff='0-rawreads/length_cutoff', preads_fofn='0-rawreads/preads/input_preads.fofn', raw_reads_db='0-rawreads/raw_reads.db' output: pre_assembly_report='0-rawreads/report/pre_assembly_stats.json' params: length_cutoff_user="-1", topdir="../..", genome_length="5000" shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date python -m falcon_kit.mains.task_report_pre_assembly --config-fn=../../{input.config} --length-cutoff-fn=../../{input.length_cutoff} --raw-reads-db-fn=../../{input.raw_reads_db} --preads-fofn-fn=../../{input.preads_fofn} --pre-assembly-report-fn=../../{output.pre_assembly_report} date ''' rule static_1_preads_ovl: input: config='config.json', preads_fofn='0-rawreads/preads/input_preads.fofn' output: db_build_done='1-preads_ovl/pdb_build_done', preads_db='1-preads_ovl/preads.db', run_jobs='1-preads_ovl/run_jobs.sh' params: topdir=".." shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date python -m falcon_kit.mains.build_pdb --input-fofn-fn=../{input.preads_fofn} --config-fn=../{input.config} --run-jobs-fn=../{output.run_jobs} --job-done-fn=../{output.db_build_done} # TODO: Verify that input.preads_db exists. touch ../{output.db_build_done} date ''' rule static_1_preads_ovl_daligner_scatter: input: db='1-preads_ovl/preads.db', run_jobs='1-preads_ovl/run_jobs.sh' output: scattered='1-preads_ovl/daligner-scatter/scattered.json' params: wildcards="dal1_id", pread_aln="1", topdir="../..", db_prefix="preads", skip_checks="0", stage="1-preads_ovl" shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date python -m falcon_kit.mains.daligner_scatter --run-jobs-fn=../../{input.run_jobs} --db-prefix={params.db_prefix} --db-fn=../../{input.db} --skip-checks={params.skip_checks} --pread-aln={params.pread_aln} --stage={params.stage} --wildcards={params.wildcards} --scattered-fn=../../{output.scattered} date ''' rule dynamic_foo3_split: input: '1-preads_ovl/daligner-scatter/scattered.json' output: daligner_settings=dynamic('1-preads_ovl/daligner-scripts/{dal1_id}.symlink/settings.json'), daligner_script=dynamic('1-preads_ovl/daligner-scripts/{dal1_id}.symlink/daligner-script.sh') shell: 'python -m falcon_kit.mains.copy_mapped --special-split={input} daligner_settings="1-preads_ovl/daligner-scripts/{{dal1_id}}.symlink/settings.json" daligner_script="1-preads_ovl/daligner-scripts/{{dal1_id}}.symlink/daligner-script.sh"' rule static_1_preads_ovl__dal1_id_: input: daligner_script='1-preads_ovl/daligner-scripts/{dal1_id}.symlink/daligner-script.sh', daligner_settings='1-preads_ovl/daligner-scripts/{dal1_id}.symlink/settings.json' output: job_done='1-preads_ovl/{dal1_id}/daligner.done' params: dal1_id="{dal1_id}" shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date # Note: HPC.daligner chooses a merged filename in its generated script, so we will symlink to it. python -m falcon_kit.mains.daligner --daligner-settings-fn=../../{input.daligner_settings} --daligner-script-fn=../../{input.daligner_script} --job-done-fn=../../{output.job_done} date ''' rule dynamic_foo3_merge: input: job_done=ancient(dynamic('1-preads_ovl/{dal1_id}/daligner.done')) output: '1-preads_ovl/daligner-gathered/gathered.json' run: snake_merge_multi_dynamic(output[0], dict( job_done=[str(i) for i in input.job_done] ), dict( job_done="1-preads_ovl/{dal1_id}/daligner.done" ), ["dal1_id"] # all wildcards ) rule static_1_preads_ovl_daligner_intermediate_gathered_las: input: gathered='1-preads_ovl/daligner-gathered/gathered.json' output: las_paths='1-preads_ovl/daligner-intermediate-gathered-las/gathered-las.txt' params: topdir="../.." shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date python -m falcon_kit.mains.daligner_gather --gathered-fn=../../{input.gathered} --las-paths-fn=../../{output.las_paths} date ''' rule static_1_preads_ovl_merge_scatter: input: gathered_las='1-preads_ovl/daligner-intermediate-gathered-las/gathered-las.txt', run_jobs='1-preads_ovl/run_jobs.sh' output: scattered='1-preads_ovl/merge-scatter/scattered.json' params: db_prefix="preads", wildcards="mer1_id", topdir="../..", stage="1-preads_ovl" shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date python -m falcon_kit.mains.las_merge_scatter --db-prefix={params.db_prefix} --stage={params.stage} --run-jobs-fn=../../{input.run_jobs} --gathered-las-fn=../../{input.gathered_las} --wildcards={params.wildcards} --scattered-fn=../../{output.scattered} date ''' rule dynamic_foo4_split: input: '1-preads_ovl/merge-scatter/scattered.json' output: las_paths=dynamic('1-preads_ovl/merge-scripts/{mer1_id}.symlink/las_paths.json'), merged_las_json=dynamic('1-preads_ovl/merge-scripts/{mer1_id}.symlink/merged_las.json'), merge_script=dynamic('1-preads_ovl/merge-scripts/{mer1_id}.symlink/merge-script.sh') shell: 'python -m falcon_kit.mains.copy_mapped --special-split={input} las_paths="1-preads_ovl/merge-scripts/{{mer1_id}}.symlink/las_paths.json" merged_las_json="1-preads_ovl/merge-scripts/{{mer1_id}}.symlink/merged_las.json" merge_script="1-preads_ovl/merge-scripts/{{mer1_id}}.symlink/merge-script.sh"' rule static_1_preads_ovl__mer1_id_: input: las_paths='1-preads_ovl/merge-scripts/{mer1_id}.symlink/las_paths.json', merge_script='1-preads_ovl/merge-scripts/{mer1_id}.symlink/merge-script.sh', merged_las_json='1-preads_ovl/merge-scripts/{mer1_id}.symlink/merged_las.json' output: job_done='1-preads_ovl/{mer1_id}/merge.done', merged_las='1-preads_ovl/{mer1_id}/merged.las' params: mer1_id="{mer1_id}" shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date # Note: HPC.daligner chooses a merged filename in its generated script, so we will symlink to it. python -m falcon_kit.mains.las_merge --las-paths-fn=../../{input.las_paths} --merge-script-fn=../../{input.merge_script} --las-merged-fn-fn=../../{input.merged_las_json} --las-merged-symlink-fn=../../{output.merged_las} --job-done-fn=../../{output.job_done} date ''' rule dynamic_foo4_merge: input: job_done=ancient(dynamic('1-preads_ovl/{mer1_id}/merge.done')), merged_las=ancient(dynamic('1-preads_ovl/{mer1_id}/merged.las')) output: '1-preads_ovl/merge-gathered/gathered.json' run: snake_merge_multi_dynamic(output[0], dict( job_done=[str(i) for i in input.job_done], merged_las=[str(i) for i in input.merged_las] ), dict( job_done="1-preads_ovl/{mer1_id}/merge.done", merged_las="1-preads_ovl/{mer1_id}/merged.las" ), ["mer1_id"] # all wildcards ) rule static_1_preads_ovl_merged_las_fofn: input: gathered='1-preads_ovl/merge-gathered/gathered.json' output: las_fofn='1-preads_ovl/merged-las-fofn/las.fofn', las_fopfn='1-preads_ovl/merged-las-fofn/las.fopfn' params: topdir="../.." shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date python -m falcon_kit.mains.las_merge_gather --gathered-fn=../../{input.gathered} --las-fofn-fn=../../{output.las_fofn} --las-fopfn-fn=../../{output.las_fopfn} date ''' rule static_1_preads_ovl_db2falcon: input: las_fofn='1-preads_ovl/merged-las-fofn/las.fofn', preads_db='1-preads_ovl/preads.db' output: job_done='1-preads_ovl/db2falcon/db2falcon_done', preads4falcon='1-preads_ovl/db2falcon/preads4falcon.fasta' params: topdir="../.." shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date # Given preads.db, # write preads4falcon.fasta (implicitly) in CWD. time DB2Falcon -U ../../{input.preads_db} [ -f ../../{output.preads4falcon} ] || exit 1 touch ../../{output.job_done} date ''' rule static_2_asm_falcon: input: config='config.json', db2falcon_done='1-preads_ovl/db2falcon/db2falcon_done', db_file='1-preads_ovl/preads.db', las_fofn='1-preads_ovl/merged-las-fofn/las.fofn', preads4falcon_fasta='1-preads_ovl/db2falcon/preads4falcon.fasta' output: falcon_asm_done='2-asm-falcon/falcon_asm_done' params: topdir="..", length_cutoff_pr="1", overlap_filtering_setting="--max_diff 10000 --max_cov 100000 --min_cov 1 --min_len 1 --bestn 1000 --n_core 0", fc_ovlp_to_graph_option=" --min_len 1" shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date # Given, las.fofn, # write preads.ovl: # mobs uses binwrappers, so it does not see our "entry-points". # So, after dropping "src/py_scripts/*.py", we can call these via python -m: time python -m falcon_kit.mains.ovlp_filter --db ../{input.db_file} --fofn ../{input.las_fofn} {params.overlap_filtering_setting} --min_len {params.length_cutoff_pr} --out-fn preads.ovl ln -sf ../{input.preads4falcon_fasta} ./preads4falcon.fasta # Given preads.ovl, # write sg_edges_list, c_path, utg_data, ctg_paths. time python -m falcon_kit.mains.ovlp_to_graph {params.fc_ovlp_to_graph_option} --overlap-file preads.ovl >| fc_ovlp_to_graph.log # Given sg_edges_list, utg_data, ctg_paths, preads4falcon.fasta, # write p_ctg.fa and a_ctg_all.fa, # plus a_ctg_base.fa, p_ctg_tiling_path, a_ctg_tiling_path, a_ctg_base_tiling_path: time python -m falcon_kit.mains.graph_to_contig # Given a_ctg_all.fa, write a_ctg.fa: time python -m falcon_kit.mains.dedup_a_tigs # Generate a GFA of all assembly graph edges. This GFA can contain # edges and nodes which are not part of primary and associate contigs. time python -m falcon_kit.mains.gen_gfa_v1 >| asm.gfa # Generate a GFA of all assembly graph edges. This GFA can contain # edges and nodes which are not part of primary and associate contigs. time python -m falcon_kit.mains.gen_gfa_v1 --add-string-graph >| sg.gfa #rm -f ./preads4falcon.fasta touch ../{output.falcon_asm_done} date ''' ================================================ FILE: falcon_kit/FastaReader.py ================================================ from __future__ import absolute_import from builtins import next from builtins import range from builtins import object from os.path import abspath, expanduser from .io import NativeIO as StringIO import contextlib import gzip import md5 import re import subprocess ## # Utility functions for FastaReader ## def wrap(s, columns): return "\n".join(s[start:start + columns] for start in range(0, len(s), columns)) def splitFastaHeader(name): """ Split a FASTA/FASTQ header into its id and metadata components """ nameParts = re.split('\s', name, maxsplit=1) id_ = nameParts[0] if len(nameParts) > 1: metadata = nameParts[1].strip() else: metadata = None return (id_, metadata) def splitFileContents(f, delimiter, BLOCKSIZE=8192): """ Same semantics as f.read().split(delimiter), but with memory usage determined by largest chunk rather than entire file size """ remainder = StringIO() while True: block = f.read(BLOCKSIZE) if not block: break parts = block.split(delimiter) remainder.write(parts[0]) for part in parts[1:]: yield remainder.getvalue() remainder = StringIO() remainder.write(part) yield remainder.getvalue() class FastaRecord(object): """ A FastaRecord object models a named sequence in a FASTA file. """ DELIMITER = ">" COLUMNS = 60 def __init__(self, name, sequence): try: assert "\n" not in name assert "\n" not in sequence assert self.DELIMITER not in sequence self._name = name self._sequence = sequence self._md5 = md5.md5(self.sequence).hexdigest() self._id, self._metadata = splitFastaHeader(name) except AssertionError: raise ValueError("Invalid FASTA record data") @property def name(self): """ The name of the sequence in the FASTA file, equal to the entire FASTA header following the '>' character """ return self._name @property def id(self): """ The id of the sequence in the FASTA file, equal to the FASTA header up to the first whitespace. """ return self._id @property def metadata(self): """ The metadata associated with the sequence in the FASTA file, equal to the contents of the FASTA header following the first whitespace """ return self._metadata @property def sequence(self): """ The sequence for the record as present in the FASTA file. (Newlines are removed but otherwise no sequence normalization is performed). """ return self._sequence @property def length(self): """ Get the length of the FASTA sequence """ return len(self._sequence) @property def md5(self): """ The MD5 checksum (hex digest) of `sequence` """ return self._md5 @classmethod def fromString(cls, s): """ Interprets a string as a FASTA record. Does not make any assumptions about wrapping of the sequence string. """ try: lines = s.splitlines() assert len(lines) > 1 assert lines[0][0] == cls.DELIMITER name = lines[0][1:] sequence = "".join(lines[1:]) return FastaRecord(name, sequence) except AssertionError: raise ValueError("String not recognized as a valid FASTA record") def __eq__(self, other): if isinstance(other, self.__class__): return (self.name == other.name and self.sequence == other.sequence) else: return False def __ne__(self, other): return not self.__eq__(other) def __str__(self): """ Output a string representation of this FASTA record, observing standard conventions about sequence wrapping. """ return (">%s\n" % self.name) + \ wrap(self.sequence, self.COLUMNS) # These are refactored from ReaderBase/FastaReader. def yield_fasta_records(f, fn): """ f: fileobj fn: str - filename (for exceptions) """ try: parts = splitFileContents(f, ">") assert "" == next(parts) for part in parts: yield FastaRecord.fromString(">" + part) except AssertionError: raise Exception("Invalid FASTA file {!r}".format(fn)) def stream_stdout(call, fn): args = call.split() proc = subprocess.Popen(args, stdin=open(fn), stdout=subprocess.PIPE) return proc.stdout @contextlib.contextmanager def open_fasta_reader(fn): """ fn: str - filename Note: If you already have a fileobj, you can iterate over yield_fasta_records() directly. Streaming reader for FASTA files, useable as a one-shot iterator over FastaRecord objects. Agnostic about line wrapping. Example: .. doctest:: TODO: Get data. > from pbcore import data > filename = data.getTinyFasta() > r = FastaReader(filename) > with open_fasta_reader(filename) as r: ... for record in r: ... print record.name, len(record.sequence), record.md5 ref000001|EGFR_Exon_2 183 e3912e9ceacd6538ede8c1b2adda7423 ref000002|EGFR_Exon_3 203 4bf218da37175a91869033024ac8f9e9 ref000003|EGFR_Exon_4 215 245bc7a046aad0788c22b071ed210f4d ref000004|EGFR_Exon_5 157 c368b8191164a9d6ab76fd328e2803ca """ filename = abspath(expanduser(fn)) mode = 'r' if filename.endswith(".gz"): ofs = gzip.open(filename, mode) elif filename.endswith(".dexta"): ofs = stream_stdout("undexta -vkU -w60 -i", filename) else: ofs = open(filename, mode) yield yield_fasta_records(ofs, filename) ofs.close() class FastaReader(object): """Deprecated, but should still work (with filenames). """ def __iter__(self): with open_fasta_reader(self.filename) as reader: for rec in reader: yield rec def __init__(self, f): self.filename = f ================================================ FILE: falcon_kit/__init__.py ================================================ from __future__ import absolute_import from .falcon_kit import * try: import sys, pkg_resources sys.stderr.write('{}\n'.format(pkg_resources.get_distribution('falcon-kit'))) except Exception: pass ================================================ FILE: falcon_kit/bash.py ================================================ """Most bash-scripting is generated here. """ from __future__ import absolute_import from future.utils import viewitems from . import functional import functools import getpass import logging import md5 import os import tempfile import traceback LOG = logging.getLogger(__name__) BASH = '/bin/bash' BUG_avoid_Text_file_busy = True # http://stackoverflow.com/questions/1384398/usr-bin-perl-bad-interpreter-text-file-busy/ def mkdir(d): if not os.path.isdir(d): os.makedirs(d) def make_executable(path): """http://stackoverflow.com/questions/12791997/how-do-you-do-a-simple-chmod-x-from-within-python """ mode = os.stat(path).st_mode mode |= (mode & 0o444) >> 2 # copy R bits to X os.chmod(path, mode) def write_sub_script(ofs, script): # We use shebang + chmod so we can see the sub-script in 'top'. # In order to avoid '/bin/bash: bad interpreter: Text file busy', # we 'touch' the sub-script after chmod. # http://superuser.com/questions/934300/bin-bash-bad-interpreter-text-file-busy-even-though-the-file-editor-closed ofs.write('#!{}\n'.format(BASH)) ofs.write('set -vex\n') ofs.write(script) if BUG_avoid_Text_file_busy: exe = BASH else: # We prefer to run via shebang b/c we want the script-name to appear to 'top', # but some users have a problem with that, e.g. # https://github.com/PacificBiosciences/FALCON/issues/269 # Another idea never worked reliably: # chmod +x {sub_script_bfn} # touch {sub_script_bfn} # We are trying to avoid this problem: # /bin/bash: bad interpreter: Text file busy exe = '' return exe def write_script(script, script_fn, job_done_fn=None): if job_done_fn: script += '\ntouch {}\n'.format(job_done_fn) with open(script_fn, 'w') as ofs: exe = write_sub_script(ofs, script) def write_script_and_wrapper_top(script, wrapper_fn, job_done): """NOT USED. Write script to a filename based on wrapper_fn, in same directory. Write wrapper to call it, and to write job_done on success and job_done.exit on any exit. 'job_done' should be either abspath or relative to dir of wrapper_fn. """ job_exit = job_done + '.exit' wdir = os.path.abspath(os.path.dirname(wrapper_fn)) # mkdir(wdir) # To avoid races, callers must do this. root, ext = os.path.splitext(os.path.basename(wrapper_fn)) sub_script_bfn = root + '.sub' + ext with open(os.path.join(wdir, sub_script_bfn), 'w') as ofs: exe = write_sub_script(ofs, script) make_executable(os.path.join(wdir, sub_script_bfn)) wrapper = """ set -vex cd {wdir} trap 'touch {job_exit}' EXIT ls -il {sub_script_bfn} hostname ls -il {sub_script_bfn} time {exe} ./{sub_script_bfn} touch {job_done} """ wrapper = wrapper.format(**locals()) with open(wrapper_fn, 'w') as ofs: ofs.write(wrapper) return job_done, job_exit def select_rundir(tmpdir, wdir, script): user = getpass.getuser() digest = md5.md5(script).hexdigest() return '{}/{}/falcontmp/{}/{}'.format(tmpdir, user, wdir, digest) def write_script_and_wrapper_for_tmp(tmpdir, script, wrapper_fn, job_done): """NOT USED. This will be done in pypeFLOW. """ wdir = os.path.dirname(os.path.abspath(wrapper_fn)) root, ext = os.path.splitext(os.path.basename(wrapper_fn)) sub_script_bfn = root + '.xsub' + ext with open(os.path.join(wdir, sub_script_bfn), 'w') as ofs: exe = write_sub_script(ofs, script) make_executable(os.path.join(wdir, sub_script_bfn)) rdir = select_rundir(tmpdir, wdir, script) tmp_wrapper_script = """ shopt -s dotglob rm -rf {rdir} mkdir -p {rdir} cd {rdir} for target in {wdir}/* ; do ln -s $target . ; done time {exe} ./{sub_script_bfn} shopt -s dotglob for x in ./* ; do if [ -f $x -a ! -f {wdir}/$x ] ; then mv -f $x {wdir} ; fi ; done cd {wdir} rm -rf {rdir} # Presumably, the parent directories might be used by other jobs. """ tmp_wrapper_script = tmp_wrapper_script.format(**locals()) return write_script_and_wrapper_top(tmp_wrapper_script, wrapper_fn, job_done) def filter_DBsplit_option(opt): """We want -a by default, but if we see --no-a[ll], we will not add -a. """ flags = opt.split() if '-x' not in opt: flags.append('-x70') # daligner belches on any read < kmer length return ' '.join(flags) def update_dict_entry(d, key, func): d[key] = func(d[key]) def get_last_block(fn): """From existing db, e.g. 'raw_reads.db', return (bool, int) Related to 'openending'. Not currently used. """ last_block = 1 new_db = True if os.path.exists(fn): with open(fn) as f: for l in f: l = l.strip().split() if l[0] == "blocks" and l[1] == "=": last_block = int(l[2]) new_db = False break return (new_db, last_block) def script_build_rdb(config, input_fofn_fn, run_jobs_bfn, length_cutoff_fn='length_cutoff'): """ raw_reads.db will be output into CWD, should not already exist. run_jobs_bfn will be output into CWD. """ last_block = 1 config = dict(config) # copy update_dict_entry(config, 'pa_DBsplit_option', filter_DBsplit_option) DBsplit = 'DBsplit {pa_DBsplit_option} raw_reads'.format(**config) # if openending == True: # count = """$(cat raw_reads.db | LD_LIBRARY_PATH= awk '$1 == "blocks" {print $3-1}')""" count = """$(cat raw_reads.db | LD_LIBRARY_PATH= awk '$1 == "blocks" {print $3}')""" params = dict(config) length_cutoff = params.get('length_cutoff') if int(length_cutoff) < 0: bash_cutoff = '$(python2.7 -m falcon_kit.mains.calc_cutoff --coverage {} {} <(DBstats -b1 {}))'.format( params['seed_coverage'], params['genome_size'], 'raw_reads') else: bash_cutoff = '{}'.format(length_cutoff) try: cat_fasta = functional.choose_cat_fasta(open(input_fofn_fn).read()) except Exception: LOG.exception('Using "cat" by default.') cat_fasta = 'cat ' DBdust = 'DBdust {} raw_reads'.format(params.get('pa_DBdust_option', '')) params.update(locals()) script = """\ echo "PBFALCON_ERRFILE=$PBFALCON_ERRFILE" set -o pipefail rm -f raw_reads.db .raw_reads.* # in case of re-run #fc_fasta2fasta < {input_fofn_fn} >| fc.fofn while read fn; do {cat_fasta} $fn | fasta2DB -v raw_reads -i${{fn##*/}}; done < {input_fofn_fn} #cat fc.fofn | xargs rm -f {DBsplit} {DBdust} LB={count} rm -f {run_jobs_bfn} CUTOFF={bash_cutoff} echo -n $CUTOFF >| {length_cutoff_fn} echo "SMRT_PYTHON_PATH_PREPEND=$SMRT_PYTHON_PATH_PREPEND" echo "PATH=$PATH" which HPC.daligner HPC.daligner -P. {pa_HPCdaligner_option} -mdust -H$CUTOFF raw_reads {last_block}-$LB >| {run_jobs_bfn} """.format(**params) return script # Note: We dump the 'length_cutoff' file for later reference within the preassembly report # of pbsmrtpipe HGAP. # However, it is not a true dependency because we still have a workflow that starts # from 'corrected reads' (preads), in which case build_rdb is not run. def script_build_pdb(config, input_fofn_bfn, run_jobs_bfn): # "bfn" used to mean base-file-name, but I do not remember why. ~cd last_block = 1 count = """$(cat preads.db | LD_LIBRARY_PATH= awk '$1 == "blocks" {print $3}')""" params = dict(config) update_dict_entry(params, 'ovlp_DBsplit_option', filter_DBsplit_option) # We need to run DBdust for preads too, for consistency. # We will always use defaults for preads, since they should be small and clean. DBdust = 'DBdust preads' params.update(locals()) script = """\ python -m falcon_kit.mains.copy_fofn --in={input_fofn_bfn} --out=preads.fofn --abs rm -f preads.db .preads.* # in case of re-run while read fn; do fasta2DB -v preads $fn; done < preads.fofn DBsplit {ovlp_DBsplit_option} preads {DBdust} LB={count} which HPC.daligner HPC.daligner -P. {ovlp_HPCdaligner_option} -mdust -H{length_cutoff_pr} preads {last_block}-$LB >| {run_jobs_bfn} """.format(**params) return script def script_run_DB2Falcon(config, preads4falcon_fn, preads_db): """Run in pread_dir. """ params = dict(config) params.update(locals()) script = """\ # Given preads.db, # write preads4falcon.fasta (implicitly) in CWD. time DB2Falcon -U {preads_db} [ -f preads4falcon.fasta ] || exit 1 """.format(**params) return script def scripts_daligner(run_jobs_fn, db_prefix, rdb_build_done, nblock, pread_aln=False, skip_check=False): """Yield job_uid, bash """ scripts = {} xform_script = functional.get_script_xformer(pread_aln) db_dir = os.path.dirname(run_jobs_fn) get_daligner_job_descriptions = ( functional.get_daligner_job_descriptions_sans_LAcheck if skip_check else functional.get_daligner_job_descriptions) single = (nblock == 1) try: job_descs = get_daligner_job_descriptions( open(run_jobs_fn), db_prefix, single) except Exception: raise Exception('Could not parse job descriptions from file "{}":\n{}'.format( run_jobs_fn, traceback.format_exc())) for i, (desc, bash) in enumerate(viewitems(job_descs)): job_uid = '%04x' % i daligner_cmd = xform_script(bash) bash = """ db_dir={db_dir} ln -sf ${{db_dir}}/.{db_prefix}.bps . ln -sf ${{db_dir}}/.{db_prefix}.idx . ln -sf ${{db_dir}}/{db_prefix}.db . ln -sf ${{db_dir}}/.{db_prefix}.dust.anno . ln -sf ${{db_dir}}/.{db_prefix}.dust.data . rm -f *.las {daligner_cmd} rm -f *.C?.las *.C?.S.las *.C??.las *.C??.S.las *.C???.las *.C???.S.las rm -f *.N?.las *.N?.S.las *.N??.las *.N??.S.las *.N???.las *.N???.S.las """.format(db_dir=db_dir, db_prefix=db_prefix, daligner_cmd=daligner_cmd) yield job_uid, bash def scripts_merge(config, db_prefix, run_jobs_fn): """Yield p_id, bash p_id can be '.123' or just '' """ with open(run_jobs_fn) as f: mjob_data = functional.get_mjob_data(f) bash_funcs = """ # Get the real path of a link, following all links (since 'readlink -f' is not on OSX). # http://stackoverflow.com/questions/7665/how-to-resolve-symbolic-links-in-a-shell-script/697552 realpath() { local r=$1; local t=$(readlink $r) while [ $t ]; do r=$(cd $(dirname $r) && cd $(dirname $t) && pwd -P)/$(basename $t) t=$(readlink $r) done echo $r } rmfollow() { local path=$(realpath $1) rm -f "${path}" } """ # las_fns = functional.get_las_filenames(mjob_data, db_prefix) # ok, but tricky for p_id in mjob_data: #las_fn = las_fns[p_id] # We already know the output .las filename by convention. las_fn = '%s.%s.las' % (db_prefix, p_id) bash_lines = mjob_data[p_id] script = [] for line in bash_lines: script.append(line) # Assume we no longer have "&& rm". for line in bash_lines: if not line.startswith('LAmerge'): continue las_files = [ word + '.las' for word in functional.yield_args_from_line(line)] #las_fn = os.path.basename(las_files[0]) #assert las_fn == os.path.basename(las_files[0]) script.extend('# rmfollow {}'.format(fn) for fn in las_files[1:]) break content = bash_funcs + '\n'.join(script + ['']) yield p_id, content, las_fn def script_run_consensus(config, db_fn, las_fn, out_file_bfn): """config: falcon_sense_option, length_cutoff TODO: Delete this version. Should not be used anywhere. """ params = dict(config) # We calculate length_cutoff again! This is because we do not want # to create yet another task in pbsmrtpipe. length_cutoff = params.get('length_cutoff') if int(length_cutoff) < 0: bash_cutoff = '$(python2.7 -m falcon_kit.mains.calc_cutoff --coverage {} {} <(DBstats -b1 {}))'.format( params['seed_coverage'], params['genome_size'], db_fn) else: bash_cutoff = '{}'.format(length_cutoff) params.update(locals()) LA4Falcon_flags = 'P' if params.get('LA4Falcon_preload') else '' if config["falcon_sense_skip_contained"]: LA4Falcon_flags += 'fso' elif config["falcon_sense_greedy"]: LA4Falcon_flags += 'fog' else: LA4Falcon_flags += 'fo' if LA4Falcon_flags: LA4Falcon_flags = '-' + ''.join(set(LA4Falcon_flags)) run_consensus = "LA4Falcon -H$CUTOFF %s {db_fn} {las_fn} | python -m falcon_kit.mains.consensus {falcon_sense_option} >| {out_file_bfn}" % LA4Falcon_flags if config.get('dazcon', False): run_consensus = """ which dazcon dazcon {pa_dazcon_option} -s {db_fn} -a {las_fn} >| {out_file_bfn} """ script = """ set -o pipefail CUTOFF=%(bash_cutoff)s %(run_consensus)s """ % (locals()) return script.format(**params) def script_run_falcon_asm(config, las_fofn_fn, preads4falcon_fasta_fn, db_file_fn): params = dict(config) params.update(locals()) script = """\ # Given, las.fofn, # write preads.ovl: # mobs uses binwrappers, so it does not see our "entry-points". # So, after dropping "src/py_scripts/*.py", we can call these via python -m: time python -m falcon_kit.mains.ovlp_filter --db {db_file_fn} --las-fofn {las_fofn_fn} {overlap_filtering_setting} --min_len {length_cutoff_pr} --out-fn preads.ovl ln -sf {preads4falcon_fasta_fn} ./preads4falcon.fasta # Given preads.ovl, # write sg_edges_list, c_path, utg_data, ctg_paths. time python -m falcon_kit.mains.ovlp_to_graph {fc_ovlp_to_graph_option} --overlap-file preads.ovl >| fc_ovlp_to_graph.log # Given sg_edges_list, utg_data, ctg_paths, preads4falcon.fasta, # write p_ctg.fa and a_ctg_all.fa, # plus a_ctg_base.fa, p_ctg_tiling_path, a_ctg_tiling_path, a_ctg_base_tiling_path: time python -m falcon_kit.mains.graph_to_contig # Given a_ctg_all.fa, write a_ctg.fa: time python -m falcon_kit.mains.dedup_a_tigs # Collect all info needed to format the GFA-1 and GFA-2 representations of # the assembly graphs. time python -m falcon_kit.mains.collect_pread_gfa >| asm.gfa.json time python -m falcon_kit.mains.collect_pread_gfa --add-string-graph >| sg.gfa.json time python -m falcon_kit.mains.collect_contig_gfa >| contig.gfa.json # Output the assembly pread graph. time python -m falcon_kit.mains.gen_gfa_v1 asm.gfa.json >| asm.gfa time python -m falcon_kit.mains.gen_gfa_v2 asm.gfa.json >| asm.gfa2 # Output the string graph. time python -m falcon_kit.mains.gen_gfa_v1 sg.gfa.json >| sg.gfa time python -m falcon_kit.mains.gen_gfa_v2 sg.gfa.json >| sg.gfa2 # Output the contig graph with associate contigs attached to each primary contig. time python -m falcon_kit.mains.gen_gfa_v2 contig.gfa.json >| contig.gfa2 #rm -f ./preads4falcon.fasta """ return script.format(**params) def script_run_report_pre_assembly(i_raw_reads_db_fn, i_preads_fofn_fn, genome_length, length_cutoff, o_json_fn): params = dict() params.update(locals()) script = """\ python2.7 -m falcon_kit.mains.report_pre_assembly --genome-length {genome_length} --length-cutoff {length_cutoff} --db {i_raw_reads_db_fn} --preads-fofn {i_preads_fofn_fn} --out {o_json_fn} """ return script.format(**params) ================================================ FILE: falcon_kit/falcon_kit.py ================================================ from __future__ import absolute_import __all__ = [ 'kup', 'DWA', 'falcon', 'KmerLookup', 'KmerMatch', 'AlnRange', 'ConsensusData', 'Alignment', 'get_alignment', ] from ctypes import * import os import ext_falcon #module_path = os.path.split(__file__)[0] seq_coor_t = c_int base_t = c_uint8 class KmerLookup(Structure): _fields_ = [("start", seq_coor_t), ("last", seq_coor_t), ("count", seq_coor_t)] class KmerMatch(Structure): _fields_ = [("count", seq_coor_t), ("query_pos", POINTER(seq_coor_t)), ("target_pos", POINTER(seq_coor_t))] class AlnRange(Structure): _fields_ = [("s1", seq_coor_t), ("e1", seq_coor_t), ("s2", seq_coor_t), ("e2", seq_coor_t), ("score", c_long)] class ConsensusData(Structure): _fields_ = [("sequence", c_char_p), ("eff_cov", POINTER(c_uint))] try: falcon_dll = CDLL(ext_falcon.__file__) except OSError: # It seems that setup.py has changed the __file__ it attaches to an extension module. # I have no idea why or why, but this works around it. falcon_dll = CDLL(os.path.join(os.path.dirname(__file__), '..', os.path.basename(ext_falcon.__file__))) kup = falcon_dll kup.allocate_kmer_lookup.argtypes = [seq_coor_t] kup.allocate_kmer_lookup.restype = POINTER(KmerLookup) kup.init_kmer_lookup.argtypes = [POINTER(KmerLookup), seq_coor_t] kup.free_kmer_lookup.argtypes = [POINTER(KmerLookup)] kup.allocate_seq.argtypes = [seq_coor_t] kup.allocate_seq.restype = POINTER(base_t) kup.init_seq_array.argtypes = [POINTER(base_t), seq_coor_t] kup.free_seq_array.argtypes = [POINTER(base_t)] kup.allocate_seq_addr.argtypes = [seq_coor_t] kup.allocate_seq_addr.restype = POINTER(seq_coor_t) kup.free_seq_addr_array.argtypes = [POINTER(seq_coor_t)] kup.add_sequence.argtypes = [seq_coor_t, c_uint, POINTER(c_char), seq_coor_t, POINTER(seq_coor_t), POINTER(c_uint8), POINTER(KmerLookup)] kup.mask_k_mer.argtypes = [c_long, POINTER(KmerLookup), c_long] kup.find_kmer_pos_for_seq.argtypes = [POINTER(c_char), seq_coor_t, c_uint, POINTER(seq_coor_t), POINTER(KmerLookup)] kup.find_kmer_pos_for_seq.restype = POINTER(KmerMatch) kup.free_kmer_match.argtypes = [POINTER(KmerMatch)] kup.find_best_aln_range.argtypes = [ POINTER(KmerMatch), seq_coor_t, seq_coor_t, seq_coor_t] kup.find_best_aln_range.restype = POINTER(AlnRange) kup.find_best_aln_range2.argtypes = [ POINTER(KmerMatch), seq_coor_t, seq_coor_t, seq_coor_t] kup.find_best_aln_range2.restype = POINTER(AlnRange) kup.free_aln_range.argtypes = [POINTER(AlnRange)] class Alignment(Structure): """ typedef struct { seq_coor_t aln_str_size ; seq_coor_t dist ; seq_coor_t aln_q_s; seq_coor_t aln_q_e; seq_coor_t aln_t_s; seq_coor_t aln_t_e; char * q_aln_str; char * t_aln_str; } alignment; """ _fields_ = [("aln_str_size", seq_coor_t), ("dist", seq_coor_t), ("aln_q_s", seq_coor_t), ("aln_q_e", seq_coor_t), ("aln_t_s", seq_coor_t), ("aln_t_e", seq_coor_t), ("q_aln_str", c_char_p), ("t_aln_str", c_char_p)] DWA = falcon_dll DWA.align.argtypes = [POINTER(c_char), c_long, POINTER( c_char), c_long, c_long, c_int] DWA.align.restype = POINTER(Alignment) DWA.free_alignment.argtypes = [POINTER(Alignment)] falcon = falcon_dll falcon.generate_consensus.argtypes = [ POINTER(c_char_p), c_uint, c_uint, c_uint, c_uint, c_uint, c_double] falcon.generate_consensus.restype = POINTER(ConsensusData) falcon.free_consensus_data.argtypes = [POINTER(ConsensusData)] def get_alignment(seq1, seq0): K = 8 lk_ptr = kup.allocate_kmer_lookup(1 << (K * 2)) sa_ptr = kup.allocate_seq(len(seq0)) sda_ptr = kup.allocate_seq_addr(len(seq0)) kup.add_sequence(0, K, seq0, len(seq0), sda_ptr, sa_ptr, lk_ptr) kmer_match_ptr = kup.find_kmer_pos_for_seq( seq1, len(seq1), K, sda_ptr, lk_ptr) kmer_match = kmer_match_ptr[0] aln_range_ptr = kup.find_best_aln_range(kmer_match_ptr, K, K * 10, 50) #x,y = zip( * [ (kmer_match.query_pos[i], kmer_match.target_pos[i]) for i in range(kmer_match.count )] ) kup.free_kmer_match(kmer_match_ptr) aln_range = aln_range_ptr[0] s1, e1, s2, e2 = aln_range.s1, aln_range.e1, aln_range.s2, aln_range.e2 kup.free_aln_range(aln_range_ptr) if e1 - s1 > 500: #s1 = 0 if s1 < 14 else s1 - 14 #s2 = 0 if s2 < 14 else s2 - 14 e1 = len(seq1) if e1 >= len(seq1) - 2 * K else e1 + K * 2 e2 = len(seq0) if e2 >= len(seq0) - 2 * K else e2 + K * 2 alignment = DWA.align(seq1[s1:e1], e1 - s1, seq0[s2:e2], e2 - s2, 100, 0) # print seq1[s1:e1] # print seq0[s2:e2] # if alignment[0].aln_str_size > 500: #aln_str1 = alignment[0].q_aln_str #aln_str0 = alignment[0].t_aln_str aln_size = alignment[0].aln_str_size aln_dist = alignment[0].dist aln_q_s = alignment[0].aln_q_s aln_q_e = alignment[0].aln_q_e aln_t_s = alignment[0].aln_t_s aln_t_e = alignment[0].aln_t_e # print "X,",alignment[0].aln_q_s, alignment[0].aln_q_e # print "Y,",alignment[0].aln_t_s, alignment[0].aln_t_e # print aln_str1 # print aln_str0 DWA.free_alignment(alignment) kup.free_seq_addr_array(sda_ptr) kup.free_seq_array(sa_ptr) kup.free_kmer_lookup(lk_ptr) if e1 - s1 > 500 and aln_size > 500: return s1, s1 + aln_q_e - aln_q_s, s2, s2 + aln_t_e - aln_t_s, aln_size, aln_dist else: return None ================================================ FILE: falcon_kit/fc_asm_graph.py ================================================ from __future__ import absolute_import from builtins import zip from builtins import object from .FastaReader import open_fasta_reader import networkx as nx RCMAP = dict(zip("ACGTacgtNn-", "TGCAtgcaNn-")) def reverse_end(node_id): node_id, end = node_id.split(":") new_end = "B" if end == "E" else "E" return node_id + ":" + new_end class AsmGraph(object): def __init__(self, sg_file, utg_file, ctg_file): self.sg_edges = {} self.sg_edge_seqs = {} self.utg_data = {} self.ctg_data = {} self.utg_to_ctg = {} self.node_to_ctg = {} self.node_to_utg = {} self.load_sg_data(sg_file) self.load_utg_data(utg_file) self.load_ctg_data(ctg_file) self.build_node_map() def load_sg_data(self, sg_file): with open(sg_file) as f: for l in f: l = l.strip().split() v, w = l[0:2] seq_id, b, e = l[2:5] b, e = int(b), int(e) score, idt = l[5:7] score, idt = int(score), float(idt) type_ = l[7] self.sg_edges[(v, w)] = ((seq_id, b, e), score, idt, type_) def load_sg_seq(self, fasta_fn): all_read_ids = set() # read ids in the graph for v, w in self.sg_edges: type_ = self.sg_edges[(v, w)][-1] if type_ != "G": continue v = v.split(":")[0] w = w.split(":")[0] all_read_ids.add(v) all_read_ids.add(w) seqs = {} # load all p-read name into memory with open_fasta_reader(fasta_fn) as f: for r in f: if r.name not in all_read_ids: continue seqs[r.name] = r.sequence.upper() for v, w in self.sg_edges: seq_id, s, t = self.sg_edges[(v, w)][0] type_ = self.sg_edges[(v, w)][-1] if type_ != "G": continue if s < t: e_seq = seqs[seq_id][s:t] else: e_seq = "".join([RCMAP[c] for c in seqs[seq_id][t:s][::-1]]) self.sg_edge_seqs[(v, w)] = e_seq def get_seq_from_path(self, path): if len(self.sg_edge_seqs) == 0: return "" v = path[0] seqs = [] for w in path[1:]: seqs.append(self.sg_edge_seqs[(v, w)]) v = w return "".join(seqs) def load_utg_data(self, utg_file): with open(utg_file) as f: for l in f: l = l.strip().split() s, v, t = l[0:3] type_, length, score = l[3:6] length, score = int(length), int(score) path_or_edges = l[6] self.utg_data[(s, t, v)] = ( type_, length, score, path_or_edges) def load_ctg_data(self, ctg_file): with open(ctg_file) as f: for l in f: l = l.strip().split() ctg_id, ctg_type = l[0:2] start_edge = l[2] end_node = l[3] length = int(l[4]) score = int(l[5]) path = tuple((e.split("~") for e in l[6].split("|"))) self.ctg_data[ctg_id] = ( ctg_type, start_edge, end_node, length, score, path) for u in path: s, v, t = u # rint s,v,t type_, length, score, path_or_edges = self.utg_data[( s, t, v)] if type_ != "compound": self.utg_to_ctg[(s, t, v)] = ctg_id else: for svt in path_or_edges.split("|"): s, v, t = svt.split("~") self.utg_to_ctg[(s, t, v)] = ctg_id def get_sg_for_utg(self, utg_id): sg = nx.DiGraph() type_, length, score, path_or_edges = self.utg_data[utg_id] if type_ == "compound": for svt in path_or_edges.split("|"): s, v, t = svt.split("~") type_, length, score, one_path = self.utg_data[(s, t, v)] one_path = one_path.split("~") sg.add_path(one_path) else: one_path = path_or_edges.split("~") sg.add_path(one_path) return sg def get_sg_for_ctg(self, ctg_id): sg = nx.DiGraph() utgs = [] path = self.ctg_data[ctg_id][-1] for s, v, t in path: type_, length, score, path_or_edges = self.utg_data[(s, t, v)] utgs.append((type_, path_or_edges)) for t, utg in utgs: if t == "simple": one_path = utg.split("~") sg.add_path(one_path) elif t == "compound": for svt in utg.split("|"): s, v, t = svt.split("~") type_, length, score, one_path = self.utg_data[(s, t, v)] one_path = one_path.split("~") sg.add_path(one_path) return sg def build_node_map(self): for ctg_id in self.ctg_data: sg = self.get_sg_for_ctg(ctg_id) for n in sg.nodes(): self.node_to_ctg.setdefault(n, set()) self.node_to_ctg[n].add(ctg_id) for u_id in self.utg_data: if self.utg_data[u_id][0] == "compound": continue sg = self.get_sg_for_utg(u_id) for n in sg.nodes(): self.node_to_utg.setdefault(n, set()) self.node_to_utg[n].add(u_id) ================================================ FILE: falcon_kit/functional.py ================================================ """Purely functional code. """ from __future__ import absolute_import from __future__ import division from __future__ import print_function from future.utils import viewitems from .io import NativeIO as StringIO import collections import logging import re #LOG = logging.getLogger(__name__) def _verify_pairs(pairs1, pairs2): if pairs1 != pairs2: # pragma: no cover print('pair2dali:', pairs1) print('pair2sort:', pairs2) print('dali-sort:', set(pairs1) - set(pairs2)) print('sort-dali:', set(pairs2) - set(pairs1)) print('pair2dali:', len(pairs1)) print('pair2sort:', len(pairs2)) assert pairs1 == pairs2 def skip_LAcheck(bash): def lines(): for line in StringIO(bash): if 'LAcheck' in line: yield 'set +e\n' yield line yield 'set -e\n' else: yield line return ''.join(lines()) def get_daligner_job_descriptions_sans_LAcheck(run_jobs_stream, db_prefix, single=False): """Strip LAcheck (somehow) from each bash script. (For now, we will run it but not fail on error.) """ descs = get_daligner_job_descriptions(run_jobs_stream, db_prefix, single) result = {} for (k, v) in viewitems(descs): bash = skip_LAcheck(v) bash = bash.replace( 'LAsort', 'python2.7 -m falcon_kit.mains.LAsort {}'.format(db_prefix)) bash = bash.replace( 'LAmerge', 'python2.7 -m falcon_kit.mains.LAmerge {}'.format(db_prefix)) result[k] = bash return result def get_daligner_job_descriptions(run_jobs_stream, db_prefix, single=False): """Return a dict of job-desc-tuple -> HPCdaligner bash-job. Comments are ignored. E.g., each item will look like: ('.2', '.1', '.2', '.3'): 'daligner Rationale --------- For i/o efficiency, we want to daligner calls with LAsort/LAmerge lines. But Gene has done this himself too. So now, we only want the daligner calls here. Later, we will do the extra LAmerge lines, grouped by A-read. """ re_block_dali = re.compile(r'%s(\.\d+|)' % db_prefix) def blocks_dali(line): """Return ['.1', '.2', ...] Can return [''] if only 1 block. """ return [mo.group(1) for mo in re_block_dali.finditer(line)] # X == blocks[0]; A/B/C = blocks[...] lines = [line.strip() for line in run_jobs_stream] # in case caller passed filename, not stream assert any(len(l) > 1 for l in lines), repr('\n'.join(lines)) lines_dali = [l for l in lines if l.startswith( 'daligner')] # could be daligner_p result = {} for dali in lines_dali: id = tuple(blocks_dali(dali)) early_checks = [ "LAcheck -v {db_prefix} *.las".format(db_prefix=db_prefix)] script = '\n'.join([dali] + early_checks) + '\n' result[id] = script return result re_first_block_las = re.compile(r'^(?:\S+)(?:\s+-\S+)*\s+[^\.]+\.(\d+|)') def first_block_las(line): """ >>> first_block_las('LAsort -v -a foo.1.foo.1.C0') 1 """ mo = re_first_block_las.search(line) try: return int(mo.group(1)) except Exception as e: raise Exception('Pattern {!r} does not match line {!r}: {}'.format( re_first_block_las.pattern, line, e)) def get_las_filenames(mjob_data, db_prefix): """Given result of get_mjob_data(), return {int: final_las_filename} """ # This is our best guess. # (We might not even need this, since we know the output filename of each merge-task by convention.) # Eventually, we need to re-write HPC.daligner. result = {} re_LAmerge = re.compile(r'^LAmerge\s+(?:\-\S+\s+)(\S+)') re_LAcheck = re.compile(r'^LAcheck\s+(?:\-\S+\s+)\S+\s+(\S+)') for (p_id, bash_lines) in viewitems(mjob_data): if not bash_lines: # The daligner+LAsort+LAmerge job produced the final .las # for this block. We will symlink it later. las_fn = '{}.{}.las'.format(db_prefix, p_id) result[p_id] = las_fn continue # Find the last line which can tell us the final .las name. i = len(bash_lines) - 1 while bash_lines[i].split()[0] not in ('LAmerge', 'LAcheck'): i -= 1 # Now we will raise an exception if there were none. But in theory, there # must be at least an LAsort. first_word = bash_lines[i].split()[0] if first_word == 'LAmerge': regex = re_LAmerge elif first_word == 'LAcheck': regex = re_LAcheck else: raise Exception('first_word={!r} in line#{} of {!r}'.format( first_word, i, bash_lines)) mo = regex.search(bash_lines[i]) if not mo: raise Exception('Regex {!r} failed on {!r}'.format( regex.pattern, bash_lines[i])) las_fn = mo.group(1) + '.las' result[p_id] = las_fn return result def get_mjob_data(run_jobs_stream): """Given output of HPC.daligner, return {int: [bash-lines]} """ f = run_jobs_stream # Strip either '&& rm ...' or '; rm ...' ? #re_strip_rm = re.compile(r'^(.*) ((\&\&)|;) .*$') # Copied from scripts_merge() mjob_data = {} for l in f: l = l.strip() first_word = l.split()[0] if first_word not in ("LAsort", "LAmerge", "rm"): continue if first_word in ["LAsort"]: # We now run this part w/ daligner, but we still need # a small script for some book-keeping. p_id = first_block_las(l) mjob_data.setdefault(p_id, []) # mjob_data[p_id].append( " ".join(l) ) # Already done w/ daligner! raise Exception('We do not expect to see LAsort at all anymore.') elif first_word in ["LAmerge"]: p_id = first_block_las(l) mjob_data.setdefault(p_id, []) # l = re_strip_rm.sub(r'\1', l) # (LAmerge && rm) rm is very safe if we run in /tmp mjob_data[p_id].append(l) #LOG.info('{}: {}'.format(p_id, l)) elif first_word in ["rm"]: p_id = first_block_las(l) mjob_data.setdefault(p_id, []) mjob_data[p_id].append(l) #LOG.info('rm{}: {}'.format(p_id, l)) #for key, data in mjob_data.items(): # mjob_data[key] = '\n'.join(data) return mjob_data def yield_args_from_line(bash_line): """Given a line of LAmerge, etc., return [output_las_fn, input_las_fn0, input_las_fn1, ...] """ for word in bash_line.split(): if word.startswith('-') or word in ('LAcheck', 'LAmerge', 'LAsort'): continue yield word _re_sub_daligner = re.compile(r'^daligner\b', re.MULTILINE) def xform_script_for_preads(script): daligner_exe = 'daligner_p' # , flags=re.MULTILINE) # flags in py2.7 return _re_sub_daligner.sub(daligner_exe, script) def xform_script_for_raw_reads(script): return script def get_script_xformer(pread_aln): if pread_aln: return xform_script_for_preads else: return xform_script_for_raw_reads class GenomeCoverageError(Exception): pass def calc_cutoff_from_reverse_sorted_readlength_counts(rl_counts, target): """Return first read_len which gives at least 'target' bases. """ total = sum(pair[0] * pair[1] for pair in rl_counts) subtotal = 0 if target > total: msg = 'Not enough reads available for desired genome coverage (bases needed={} > actual={})'.format( target, total) raise GenomeCoverageError(msg) cutoff = 0 for (rl, count) in rl_counts: subtotal += rl * count if subtotal >= target: cutoff = rl break else: # pragma: no cover msg = 'Impossible target (probably a bug): target={target}, subtotal={subtotal}, total={total}'.format( locals()) raise Exception(msg) return cutoff def num2int(num): """ >>> num2int('1,000,000') 1000000 """ return int(num.replace(',', '')) def get_reverse_sorted_readlength_counts_from_DBstats(DBstats_output): """Return pairs of (readlength, count). Bin: Count % Reads % Bases Average 169,514: 1 0.0 0.0 169514 ... -> [(169514, 1), ...] """ rl_counts = list() lines = DBstats_output.splitlines() re_stat = re.compile( r'^\s*(?P\S+):\s+(?P\S+)\s+\S+\s+\S+\s+\S+\s*$') for line in lines: match = re_stat.search(line) if not match: continue rl = num2int(match.group('bin')) count = num2int(match.group('count')) rl_counts.append((rl, count)) return rl_counts def calc_cutoff(target, DBstats_output): """Calculate the length_cutoff needed for at least 'target' bases. DBstats_output: ASCII output of 'DBstats -b1 DB', """ rl_counts = get_reverse_sorted_readlength_counts_from_DBstats( DBstats_output) return calc_cutoff_from_reverse_sorted_readlength_counts(rl_counts, target) def parse_2columns_of_ints(data): r"""Given 2 columns of integers, space- and line-delimited, yield tuples. >>> tuple(parse_2columns_of_ints("1 2\n3 4")) ((1, 2), (3, 4)) """ for line in data.splitlines(): line = line.strip() if not line: continue yield tuple(int(x) for x in line.split()) def weighted_average(cols): """Given tuples of (weight, value), return weighted average. >>> weighted_average(((100, 1), (200, 2), (100, 5))) 2.5 """ return sum(w * v for (w, v) in cols) / sum(w for (w, v) in cols) def parsed_readlengths_from_dbdump_output(output): """Given output text from the DBump command, yield all read-lengths. """ re_length = re.compile('^L\s+\d+\s+(\d+)\s+(\d+)$') for line in output.splitlines(): mo = re_length.search(line) if mo: beg, end = mo.group(1, 2) beg = int(beg) end = int(end) yield end - beg def mapped_readlengths_from_dbdump_output(output): """Given output text from the DBump command, return dict of (id => read-length). There will be alternate lines like these: R # L # # # https://dazzlerblog.wordpress.com/command-guides/dazz_db-command-guide/ """ lengths = dict() re_rid = re.compile('^R\s+(\d+)$') re_length = re.compile('^L\s+(\d+)\s+(\d+)\s+(\d+)$') for line in output.splitlines(): mo = re_rid.search(line) if mo: idx = int(mo.group(1)) continue mo = re_length.search(line) if mo: well, beg, end = mo.group(1, 2, 3) well = int(idx) beg = int(beg) end = int(end) lengths[idx] = (end - beg) continue return lengths def average_difference(dictA, dictB): """Return the average difference of values in dictA minus dictB, only using values in dictA. If a value is missing from dictB, raise Exception. """ total_diff = 0.0 for (k, va) in viewitems(dictA): vb = dictB[k] total_diff += (va - vb) return total_diff / len(dictA) def calc_metric_fragmentation(perl_counts_output): # """perl -e 'while (<>) { if ( m{>[^/]+/(\d+)\d/} ) { $id{$1}++; } }; while (my ($k, $v) = each %%id) { $counts{$v}++; }; while (my ($k, $v) = each %%counts) { print "$v $k\n"; };' %s""" %(fastas) cols = tuple(parse_2columns_of_ints(perl_counts_output)) avg = weighted_average(cols) return avg def calc_metric_truncation(dbdump_output, length_pairs_output): # """perl -e 'while (<>) { if ( m{>[^/]+/0*(\d+)\d/(\d+)_(\d+)} ) { $lengths{$1} += ($3 - $2); } }; while (my ($k, $v) = each %%lengths) { print "$k $v\n"; };' %s""" %(fastas) cols = tuple(parse_2columns_of_ints(length_pairs_output)) pread_lengths = dict((k, v) for (k, v) in cols) orig_lengths = mapped_readlengths_from_dbdump_output(dbdump_output) avg = -average_difference(pread_lengths, orig_lengths) return avg def choose_cat_fasta(fofn): """Given the contents of a fasta FOFN, return a command to write the contents of a fasta to stdout, keeping the original file. Raise Exception on error. >>> choose_cat_fasta('abc.gz') 'zcat ' >>> choose_cat_fasta('abc.dexta') 'undexta -vkU -w60 -i < ' >>> choose_cat_fasta('abc') 'cat ' """ first_line = fofn.splitlines()[0] if first_line.endswith('.gz'): return 'zcat ' elif first_line.endswith('.dexta'): return 'undexta -vkU -w60 -i < ' else: return 'cat ' re_underscore_flag = re.compile(r'(--[\w-]+)(_)') def dash_flags(val): """ >>> dash_flags('--foo_bar --one_two_three') '--foo-bar --one-two-three' >>> dash_flags('') '' """ while True: # Repeat until settled, as there might be multiple _ in the same flag. new_val = re_underscore_flag.sub(r'\1-', val) if new_val == val: return new_val val = new_val def cfg_tobool(v): """ >>> cfg_tobool('yes') True >>> cfg_tobool('true') True >>> cfg_tobool('T') True >>> cfg_tobool('1') True >>> cfg_tobool('no') False >>> cfg_tobool('false') False >>> cfg_tobool('F') False >>> cfg_tobool('0') False >>> cfg_tobool('') False """ if v in (True, False, None): return v if not v: return False if v.upper()[0] in ('T', 'Y'): return True if v.upper()[0] in ('F', 'N'): return False return bool(int(v)) # https://stackoverflow.com/questions/3387691/how-to-perfectly-override-a-dict # We derived from dict instead of from MutableMapping to json.dumps() works. _RaiseKeyError = object() # singleton for no-default behavior class LowerDict(dict): # dicts take a mapping or iterable as their optional first argument __slots__ = () # no __dict__ - that would be redundant def __init__(self): # No args allowed, to keep it simple. super(LowerDict, self).__init__(self) def __getitem__(self, k): return super(LowerDict, self).__getitem__(k.lower()) def __setitem__(self, k, v): return super(LowerDict, self).__setitem__(k.lower(), v) def __delitem__(self, k): return super(LowerDict, self).__delitem__(k.lower()) def get(self, k, default=None): return super(LowerDict, self).get(k.lower(), default) def setdefault(self, k, default=None): return super(LowerDict, self).setdefault(k.lower(), default) def pop(self, k, v=_RaiseKeyError): if v is _RaiseKeyError: return super(LowerDict, self).pop(k.lower()) return super(LowerDict, self).pop(k.lower(), v) #def update(self, mapping=(), **kwargs): # super(LowerDict, self).update(self._process_args(mapping, **kwargs)) def __contains__(self, k): return super(LowerDict, self).__contains__(k.lower()) #def copy(self): # don't delegate w/ super - dict.copy() -> dict :( # return type(self)(self) @classmethod def fromkeys(cls, keys, v=None): return super(LowerDict, cls).fromkeys((k.lower() for k in keys), v) def __repr__(self): return '{0}({1})'.format(type(self).__name__, super(LowerDict, self).__repr__()) __loop_set = set() def toLowerDict(cfg): """Change key-names to be lower-case, at all levels of dict cfg. Then, return the case-insensitive LowerDict, substituted recursively. """ if isinstance(cfg, LowerDict): return cfg if id(cfg) in __loop_set: # Prevent infinite loop. raise Exception('Already ran update_lowercase({}) (len(set)=={}):\n {}'.format( id(cfg), len(__loop_set), cfg)) __loop_set.add(id(cfg)) low = LowerDict() for k,v in list(cfg.items()): if isinstance(v, dict): v = toLowerDict(v) # RECURSION if k in low: msg = 'Collision for "{}" in dict:\n{}'.format(k, cfg) if v != low[k]: raise Exception(msg) low[k] = v return low ================================================ FILE: falcon_kit/gfa_graph.py ================================================ from __future__ import absolute_import import os import sys import json GFA_H_TAG = 'H' GFA_S_TAG = 'S' GFA_L_TAG = 'L' GFA_P_TAG = 'P' GFA_ORIENT_FWD = '+' GFA_ORIENT_REV = '-' GFA_SEQ_UNKNOWN = '*' GFA_LINK_CIGAR_UNKNOWN = '*' GFA2_E_TAG = 'E' KW_NAME = 'name' KW_TAGS = 'tags' KW_LABELS = 'labels' KW_NODE_SEQ = 'seq' KW_NODE_LEN = 'len' KW_EDGE_SOURCE = 'v' KW_EDGE_SOURCE_ORIENT = 'v_orient' KW_EDGE_SINK = 'w' KW_EDGE_SINK_ORIENT = 'w_orient' KW_EDGE_CIGAR = 'cigar' KW_EDGE_SOURCE_START = 'v_start' KW_EDGE_SOURCE_END = 'v_end' KW_EDGE_SINK_START = 'w_start' KW_EDGE_SINK_END = 'w_end' KW_PATH_NODES = 'nodes' KW_PATH_CIGARS = 'cigars' """ GFA-1: - H line: line = '\t'.join([GFA_H_TAG, '\tVN:Z:1.0']) - S line: line = '\t'.join([GFA_S_TAG, rname, GFA_SEQ_UNKNOWN if (not write_reads) else r.sequence, 'LN:i:%s' % len(r.sequence)]) - L line: line = '\t'.join([GFA_L_TAG, edge.sg_edge.v_name, edge.sg_edge.v_orient, edge.sg_edge.w_name, edge.sg_edge.w_orient, cig_str]) - P line: line = '\t'.join([GFA_P_TAG, ctg_name, ','.join(segs), ','.join(segs_cigar)] GFA-2: - H line: line = '\t'.join([GFA_H_TAG, '\tVN:Z:2.0']) - S line: line = '\t'.join([GFA_S_TAG, rname, str(len(r.sequence)), GFA_SEQ_UNKNOWN if (not write_reads) else r.sequence]) - E line: line = '\t'.join([GFA2_E_TAG, edge_name, source_node, sink_node, source_start, source_end, sink_start, sink_end, cig_str]) """ class GFAGraph: def __init__(self): self.nodes = {} self.edges = {} self.paths = {} """ Node: {KW_NAME: '01234', KW_NODE_SEQ: 'ACTG', 'len': 4} Node: {'name': '56789', KW_NODE_SEQ: 'CAGT', 'len': 4} Edge: {KW_NAME: 'edge1', 'source': '01234', 'sink': '56789', 'cigar': '*', 'source_start': 3, 'source_end': 4, 'sink_start': 0, 'sink_end': 1} Path: {KW_NAME: '000000F', 'nodes': ['01234', '56789'], ' """ def add_node(self, node_name, node_len, node_seq='*', tags={}, labels={}): if len(node_name) == 0: raise 'Node name should be a non-empty string.\n' if node_len < 0: raise 'Node length should be >= 0.\n' if len(node_seq) == 0: raise 'Node sequence should be a non-empty string. Use "*" instead.\n' if isinstance(tags, dict) == False: raise 'The tags object must be a dict.\n' if isinstance(labels, dict) == False: raise 'The labels object must be a dict.\n' self.nodes[node_name] = { KW_NAME: node_name, KW_NODE_LEN: node_len, KW_NODE_SEQ: node_seq, KW_TAGS: tags, KW_LABELS: labels } def add_edge(self, edge_name, source, source_orient, sink, sink_orient, source_start, source_end, sink_start, sink_end, cigar, tags={}, labels={}): """ source_orient + if fwd, - otherwise. sink_orient + if fwd, - otherwise. """ if len(edge_name) == 0: raise 'Edge name should be a non-empty string.\n' if len(source) == 0: raise 'Source node not specified.\n' if len(sink) == 0: raise 'Sink node not specified.\n' if source_orient not in '+-': raise 'Source orientation should be either "+" or "-".\n' if sink_orient not in '+-': raise 'Sink orientation should be either "+" or "-".\n' if source_start < 0 or source_end < 0: raise 'Source coordinates should be >= 0.\n' if sink_start < 0 or sink_end < 0: raise 'Sink coordinates should be >= 0.\n' if len(cigar) == 0: raise 'Cigar string should not be empty. Use "*" instead.\n' if source_end < source_start: sys.stderr.write('ERROR with: source = %s, source_start = %s, source_end = %s, sink = %s, sink_start = %s, sink_end = %s\n' % (source, source_start, source_end, sink, sink_start, sink_end)) raise 'Source end coordinate should be >= source start coordinate.\n' if sink_end < sink_start: raise 'Sink end coordinate should be >= sink start coordinate.\n' if isinstance(tags, dict) == False: raise 'The tags object must be a dict.\n' if isinstance(labels, dict) == False: raise 'The labels object must be a dict.\n' self.edges[str((source, sink))] = { KW_NAME: edge_name, KW_EDGE_SOURCE: source, KW_EDGE_SOURCE_ORIENT: source_orient, KW_EDGE_SINK: sink, KW_EDGE_SINK_ORIENT: sink_orient, KW_EDGE_SOURCE_START: source_start, KW_EDGE_SOURCE_END: source_end, KW_EDGE_SINK_START: sink_start, KW_EDGE_SINK_END: sink_end, KW_EDGE_CIGAR: cigar, KW_TAGS: tags, KW_LABELS: labels } def add_path(self, path_name, path_nodes, path_cigars, tags={}, labels={}): """ path_nodes is a list of nodes which should be joined consecutively in a path. path_cigars is a list of CIGAR strings describing how the two neighboring nodes are joined. len(path_nodes) == len(path_cigars) """ if len(path_name) == 0: raise 'Path name should be a non-empty string.\n' if len(path_nodes) == 0: raise 'Path nodes should be a non-empty list.\n' if len(path_cigars) == 0: raise 'Path cigars should be a non-empty list.\n' if isinstance(tags, dict) == False: raise 'The tags object must be a dict.\n' if isinstance(labels, dict) == False: raise 'The labels object must be a dict.\n' if len(path_nodes) != len(path_cigars): raise 'The path_nodes and path_cigars should have the same length.\n' self.paths[path_name] = { KW_NAME: path_name, KW_PATH_NODES: path_nodes, KW_PATH_CIGARS: path_cigars, KW_TAGS: tags, KW_LABELS: labels } def write_gfa_v1(self, fp_out): # Header line = '\t'.join([GFA_H_TAG, 'VN:Z:1.0']) fp_out.write(line + '\n') # Sequences. for node_name, node_data in self.nodes.iteritems(): line = '\t'.join([ GFA_S_TAG, node_data[KW_NAME], node_data[KW_NODE_SEQ], 'LN:i:%d' % node_data[KW_NODE_LEN]]) fp_out.write(line + '\n') for edge, edge_data in self.edges.iteritems(): cigar = edge_data[KW_EDGE_CIGAR] if edge_data[KW_EDGE_CIGAR] != '*' else '%dM' % (abs(edge_data[KW_EDGE_SINK_END] - edge_data[KW_EDGE_SINK_START])) line = '\t'.join([str(val) for val in [ GFA_L_TAG, edge_data[KW_EDGE_SOURCE], edge_data[KW_EDGE_SOURCE_ORIENT], edge_data[KW_EDGE_SINK], edge_data[KW_EDGE_SINK_ORIENT], cigar ] ]) fp_out.write(line + '\n') for path_name, path_data in self.paths.iteritems(): line = '\t'.join([GFA_P_TAG, path_data[KW_NAME], ','.join(path_data[KW_PATH_NODES]), ','.join(path_data[KW_PATH_CIGARS])]) fp_out.write(line + '\n') def write_gfa_v2(self, fp_out): # Header line = '\t'.join([GFA_H_TAG, 'VN:Z:2.0']) fp_out.write(line + '\n') # Sequences. for node_name, node_data in self.nodes.iteritems(): line = '\t'.join([ GFA_S_TAG, node_data[KW_NAME], str(node_data[KW_NODE_LEN]), node_data[KW_NODE_SEQ]]) fp_out.write(line + '\n') for edge, edge_data in self.edges.iteritems(): v = edge_data[KW_EDGE_SOURCE] w = edge_data[KW_EDGE_SINK] v_len = self.nodes[v][KW_NODE_LEN] w_len = self.nodes[w][KW_NODE_LEN] # GFA-2 specifies a special char '$' when a coordinate is the same as the sequence length. v_start = str(edge_data[KW_EDGE_SOURCE_START]) + ('$' if edge_data[KW_EDGE_SOURCE_START] == v_len else '') v_end = str(edge_data[KW_EDGE_SOURCE_END]) + ('$' if edge_data[KW_EDGE_SOURCE_END] == v_len else '') w_start = str(edge_data[KW_EDGE_SINK_START]) + ('$' if edge_data[KW_EDGE_SINK_START] == w_len else '') w_end = str(edge_data[KW_EDGE_SINK_END]) + ('$' if edge_data[KW_EDGE_SINK_END] == w_len else '') line = '\t'.join([str(val) for val in [ GFA2_E_TAG, edge_data[KW_NAME], edge_data[KW_EDGE_SOURCE] + edge_data[KW_EDGE_SOURCE_ORIENT], edge_data[KW_EDGE_SINK] + edge_data[KW_EDGE_SINK_ORIENT], v_start, v_end, w_start, w_end, edge_data[KW_EDGE_CIGAR], ] ]) fp_out.write(line + '\n') def serialize_gfa(gfa_graph): gfa_dict = {} gfa_dict['nodes'] = gfa_graph.nodes gfa_dict['edges'] = gfa_graph.edges gfa_dict['paths'] = gfa_graph.paths return json.dumps(gfa_dict) def deserialize_gfa(fp_in): gfa_dict = json.load(fp_in) gfa = GFAGraph() gfa.nodes = gfa_dict['nodes'] gfa.edges = gfa_dict['edges'] gfa.paths = gfa_dict['paths'] return gfa ================================================ FILE: falcon_kit/io.py ================================================ from __future__ import absolute_import from __future__ import division from pypeflow.io import ( syscall, capture, cd, mkdirs, symlink, rm, touch, filesize, exists_and_not_empty) # needed? import io import logging import os import pprint import sys if sys.version_info >= (3, 0): NativeIO = io.StringIO else: NativeIO = io.BytesIO LOG = logging.getLogger() def log(*msgs): LOG.debug(' '.join(repr(m) for m in msgs)) def validate_config(config): # This simple and quick check catches common problems early. # This code might go somewhere else someday. smrt_bin_cmds = [ 'blasr', 'samtools', 'pbalign', 'variantCaller', ] path_cmds = [ 'nucmer', 'show-coords', 'fc_rr_hctg_track2.exe', ] LOG.info('PATH={}'.format(os.environ['PATH'])) try: capture('which which') except Exception: LOG.warning('Could not find "which" command. Skipping checks for "blasr", etc.') return for cmd in smrt_bin_cmds + path_cmds: syscall('which ' + cmd) syscall('show-coords -h') syscall('nucmer --version') def update_env_from_config(config, fn): LOG.info('From {!r}, config={}'.format(fn, pprint.pformat(config))) smrt_bin = config.get('smrt_bin') if smrt_bin: PATH = '{}:{}'.format(os.environ['PATH'], smrt_bin) os.environ['PATH'] = PATH validate_config(config) def eng(number): return '{:.1f}MB'.format(number / 2**20) def read_as_msgpack(stream): import msgpack content = stream.read() log(' Read {} as msgpack'.format(eng(len(content)))) return msgpack.loads(content) def read_as_json(stream): import json content = stream.read() log(' Read {} as json'.format(eng(len(content)))) return json.loads(content) def write_as_msgpack(stream, val): import msgpack content = msgpack.dumps(val) log(' Serialized to {} as msgpack'.format(eng(len(content)))) stream.write(content) def write_as_json(stream, val): import json content = json.dumps(val, indent=2, separators=(',', ': ')) log(' Serialized to {} as json'.format(eng(len(content)))) stream.write(content) def deserialize(fn): log('Deserializing from {!r}'.format(fn)) with open(fn) as ifs: log(' Opened for read: {!r}'.format(fn)) if fn.endswith('.msgpack'): val = read_as_msgpack(ifs) elif fn.endswith('.json'): val = read_as_json(ifs) else: raise Exception('Unknown extension for {!r}'.format(fn)) log(' Deserialized {} records'.format(len(val))) return val def serialize(fn, val): """Assume dirname exists. """ log('Serializing {} records'.format(len(val))) mkdirs(os.path.dirname(fn)) with open(fn, 'w') as ofs: log(' Opened for write: {!r}'.format(fn)) if fn.endswith('.msgpack'): write_as_msgpack(ofs, val) elif fn.endswith('.json'): write_as_json(ofs, val) ofs.write('\n') # for vim else: raise Exception('Unknown extension for {!r}'.format(fn)) def yield_bam_fn(input_bam_fofn_fn): LOG.info('Reading BAM names from FOFN {!r}'.format(input_bam_fofn_fn)) fofn_basedir = os.path.normpath(os.path.dirname(input_bam_fofn_fn)) def abs_fn(maybe_rel_fn): if os.path.isabs(maybe_rel_fn): return maybe_rel_fn else: return os.path.join(fofn_basedir, maybe_rel_fn) for row in open(input_bam_fofn_fn): yield abs_fn(row.strip()) def yield_abspath_from_fofn(fofn_fn): """Yield each filename. Relative paths are resolved from the FOFN directory. """ try: basedir = os.path.dirname(fofn_fn) for line in open(fofn_fn): fn = line.strip() if not os.path.isabs(fn): fn = os.path.abspath(os.path.join(basedir, fn)) yield fn except Exception: LOG.error('Problem resolving paths in FOFN {!r}'.format(fofn_fn)) raise def rmdirs(*dirnames): for d in dirnames: assert os.path.normpath(d.strip()) not in ['.', '', '/'] syscall('rm -rf {}'.format(' '.join(dirnames))) def rmdir(d): rmdirs(d) def rm_force(*fns): for fn in fns: if os.path.exists(fn): os.unlink(fn) ================================================ FILE: falcon_kit/mains/LAmerge.py ================================================ #!/usr/bin/env python """Usage: LAmerge.py DB Run LAcheck on each input in args. Exclude any failures from the arglist. Then run LAmerge on the remaining arglist. This differs from LAsort.py in that the first las file is actually an *explicit* output, whereas LAsort relies on *implicit* outputs. """ from __future__ import absolute_import import sys import os def log(msg): sys.stderr.write(msg + '\n') def system(call, checked=False): log('!{}'.format(call)) rc = os.system(call) if rc: msg = '{} <- {!r}'.format(rc, call) if checked: raise Exception(msg) log(msg) return rc def main(argv=sys.argv): db = argv[1] args = argv[2:] # Skip program name lass = list() new_args = list() new_args.append('LAmerge') for arg in args: if arg.startswith('-'): new_args.append(arg) else: lass.append(arg) outlas = lass[0] new_args.append(outlas) # This is the output las. for las in lass[1:]: rc = system('LAcheck -vS {} {}.las'.format(db, las)) # Assume sorted. if rc: log('Skipping {}.las'.format(las)) else: new_args.append(las) system(' '.join(new_args)) system('LAcheck -vS {} {}.las'.format(db, outlas)) # Assume sorted. if __name__ == "__main__": main() ================================================ FILE: falcon_kit/mains/LAsort.py ================================================ #!/usr/bin/env python """Usage: LAsort.py DB Run LAcheck on each input in args. Exclude any failures from the arglist. Then run LAsort on the remaining arglist. """ from __future__ import absolute_import import sys import os def log(msg): sys.stderr.write(msg + '\n') def system(call, checked=False): log('!{}'.format(call)) rc = os.system(call) if rc: msg = '{} <- {!r}'.format(rc, call) if checked: raise Exception(msg) log(msg) return rc def main(argv=sys.argv): log('argv:{!r}'.format(argv)) db = argv[1] args = argv[2:] # Skip program name lass = list() new_args = list() new_args.append('LAsort') for arg in args: if arg.startswith('-'): new_args.append(arg) else: lass.append(arg) for las in lass: rc = system('LAcheck -v {} {}.las'.format(db, las)) if rc: log('Skipping {}.las'.format(las)) else: new_args.append(las) system(' '.join(new_args)) if __name__ == "__main__": main() ================================================ FILE: falcon_kit/mains/__init__.py ================================================ ================================================ FILE: falcon_kit/mains/actg_coordinate.py ================================================ from __future__ import absolute_import from __future__ import print_function from falcon_kit.FastaReader import open_fasta_reader import sys def main(argv=sys.argv): p_ctg_coor_map = {} with open("p_ctg_tiling_path") as f: for row in f: row = row.strip().split() ctg_id, v, w, edge_rid, b, e = row[:6] if ctg_id not in p_ctg_coor_map: coor = 0 # the p_ctg_tiling_path should be sorted by contig the order of the edges in the tiling path p_ctg_coor_map[ctg_id] = {} p_ctg_coor_map[ctg_id][v] = 0 coor += abs(int(b) - int(e)) p_ctg_coor_map[ctg_id][w] = coor continue else: coor += abs(int(b) - int(e)) p_ctg_coor_map[ctg_id][w] = coor with open_fasta_reader("a_ctg.fa") as a_ctg_fasta: for r in a_ctg_fasta: rid = r.name.split() rid, v, w = rid[:3] pid = rid.split("-")[0] print(rid, p_ctg_coor_map[pid][v], p_ctg_coor_map[pid][w]) if __name__ == "__main__": main(sys.argv) ================================================ FILE: falcon_kit/mains/build_pdb.py ================================================ from __future__ import absolute_import import argparse import logging import os import sys from .. import io from .. import bash # for write_script LOG = logging.getLogger() def run(config_fn, input_fofn_fn, job_done_fn, run_jobs_fn): LOG.info('Building pdb from {!r} ({!r}), to write {!r}'.format( input_fofn_fn, config_fn, run_jobs_fn)) config = io.deserialize(config_fn) run_jobs_fn = os.path.basename(run_jobs_fn) script = bash.script_build_pdb(config, input_fofn_fn, run_jobs_fn) script_fn = 'build_pdb.sh' bash.write_script(script, script_fn, job_done_fn) io.syscall('bash -vex {}'.format(script_fn)) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Build Dazzler DB for preads, and run HPC.daligner to generate run-script.' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--input-fofn-fn', help='Input. (Basename only.) User-provided file of fasta filename.', ) parser.add_argument( '--config-fn', help='Input. JSON of relevant configuration (currently from General section of full-prog config).', ) parser.add_argument( '--job-done-fn', help='Output. (Basename only.) Sentinel (to be dropped someday).', ) parser.add_argument( '--run-jobs-fn', help='Output. (Basename only.) Produced by HPC.daligner.', ) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/build_rdb.py ================================================ from __future__ import absolute_import import argparse import logging import os import sys from ..util.io import yield_validated_fns from .. import io from .. import bash # for write_script LOG = logging.getLogger() def run(config_fn, length_cutoff_fn, input_fofn_fn, job_done_fn, run_jobs_fn): LOG.info('Building rdb from {!r} ({!r}), to write {!r}'.format( input_fofn_fn, config_fn, run_jobs_fn)) # First, make FOFN relative to thisdir. my_input_fofn_fn = 'my.' + os.path.basename(input_fofn_fn) with open(my_input_fofn_fn, 'w') as stream: for fn in yield_validated_fns(input_fofn_fn): stream.write(fn) stream.write('\n') config = io.deserialize(config_fn) run_jobs_fn = os.path.basename(run_jobs_fn) script = bash.script_build_rdb(config, my_input_fofn_fn, run_jobs_fn, length_cutoff_fn) script_fn = 'build_rdb.sh' bash.write_script(script, script_fn, job_done_fn) io.syscall('bash -vex {}'.format(script_fn)) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Build Dazzler DB for raw_reads, and run HPC.daligner to generate run-script.' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--input-fofn-fn', help='Input. (Basename only.) User-provided file of fasta filename.', ) parser.add_argument( '--config-fn', help='Input. JSON of relevant configuration (currently from General section of full-prog config).', ) parser.add_argument( '--length-cutoff-fn', help='Output. The read-length lower-bound for seed-reads. Might be calculated or specified.', ) parser.add_argument( '--job-done-fn', help='Output. (Basename only.) Sentinel (to be dropped someday).', ) parser.add_argument( '--run-jobs-fn', help='Output. (Basename only.) Produced by HPC.daligner.', ) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/calc_cutoff.py ================================================ from __future__ import absolute_import from .. import functional as f import argparse import os import sys import traceback def main(argv=sys.argv): import argparse description = """ Given the result of 'DBstats -u -b1' on stdin, print the lowest read-length required for sufficient coverage of the genome (i.e. 'length_cutoff'). """ epilog = """ This is useful when length_cutoff is not provided but the genome-size can be estimated. The purpose is to *reduce* the amount of data seen by DALIGNER, since otherwise it will miss many alignments when it encounters resource limits. Note: If PBFALCON_ERRFILE is defined (and its directory is writable), we will write errors there in addition to stderr. """ parser = argparse.ArgumentParser(description=description, epilog=epilog, formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--coverage', type=float, default=20, help='Desired coverage ratio (i.e. over-sampling)') parser.add_argument('genome_size', type=int, help='Estimated number of bases in genome. (haploid?)') parser.add_argument('capture', # default='-', # I guess default is not allowed for required args. help='File with captured output of DBstats. (Otherwise, stdin.)') args = parser.parse_args(argv[1:]) target = int(args.genome_size * args.coverage) capture = open(args.capture) if args.capture != '-' else sys.stdin stats = capture.read() try: cutoff = f.calc_cutoff(target, stats) except Exception: msg = traceback.format_exc() msg += 'User-provided genome_size: {}\nDesired coverage: {}\n'.format( args.genome_size, args.coverage) # pbfalcon wants us to write errs here. errfile = os.environ.get('PBFALCON_ERRFILE') if errfile: with open(errfile, 'w') as ofs: ofs.write(msg) raise Exception(msg) sys.stdout.write(str(cutoff)) if __name__ == "__main__": main(sys.argv) ================================================ FILE: falcon_kit/mains/collect_contig_gfa.py ================================================ import argparse import os import sys import json from falcon_kit.gfa_graph import GFAGraph, serialize_gfa, deserialize_gfa import falcon_kit.mains.collect_pread_gfa import falcon_kit.tiling_path def run(fp_out, p_ctg_tiling_path, a_ctg_tiling_path, p_ctg_fasta, a_ctg_fasta, write_contigs, min_p_len, min_a_len, only_these_contigs): gfa_graph = GFAGraph() # Load the primary and associate contig files. p_ctg_dict = falcon_kit.mains.collect_pread_gfa.load_seqs(p_ctg_fasta, (not write_contigs)) p_ctg_lens = {key: val[0] for key, val in p_ctg_dict.iteritems()} p_ctg_seqs = {key: val[1] for key, val in p_ctg_dict.iteritems()} a_ctg_dict = falcon_kit.mains.collect_pread_gfa.load_seqs(a_ctg_fasta, (not write_contigs)) a_ctg_lens = {key: val[0] for key, val in a_ctg_dict.iteritems()} a_ctg_seqs = {key: val[1] for key, val in a_ctg_dict.iteritems()} # Create whitelists for filtering contigs. p_ctg_whitelist = set(p_ctg_seqs.keys()) a_ctg_whitelist = set([key for key in a_ctg_seqs.keys()]) if only_these_contigs: p_ctg_whitelist = set(open(only_these_contigs).read().splitlines()) & set(p_ctg_whitelist) a_ctg_whitelist = set([key for key in a_ctg_seqs.keys() if key.split('-')[0].split('_')[0] in p_ctg_whitelist]) # Load the tiling paths and assign coordinates. p_paths = falcon_kit.tiling_path.load_tiling_paths(p_ctg_tiling_path, whitelist_seqs=p_ctg_whitelist, contig_lens=p_ctg_lens) a_paths = falcon_kit.tiling_path.load_tiling_paths(a_ctg_tiling_path, whitelist_seqs=a_ctg_whitelist, contig_lens=a_ctg_lens) # Find the associate contig placement. `a_placement` is a dict: # placement[p_ctg_id][a_ctg_id] = (start, end, p_ctg_id, a_ctg_id, first_node, last_node) a_placement = falcon_kit.tiling_path.find_a_ctg_placement(p_paths, a_paths) # Add the nodes. for ctg_id, tiling_path in p_paths.iteritems(): gfa_graph.add_node(ctg_id, p_ctg_lens[ctg_id], p_ctg_seqs[ctg_id]) for ctg_id, tiling_path in a_paths.iteritems(): gfa_graph.add_node(ctg_id, a_ctg_lens[ctg_id], a_ctg_seqs[ctg_id]) for p_ctg_id, a_dict in a_placement.iteritems(): for a_ctg_id, placement in a_dict.iteritems(): start, end, p_ctg_id, a_ctg_id, first_node, last_node = placement a_ctg_len = a_ctg_lens[a_ctg_id] # edge_name = 'edge-%d-out-%s-to-%s' % (len(gfa_graph.edges), a_ctg_id, p_ctg_id) edge_name = 'edge-%d' % (len(gfa_graph.edges)) gfa_graph.add_edge(edge_name, p_ctg_id, '+', a_ctg_id, '+', start, start, 0, 0, '*', tags = {}, labels = {}) # edge_name = 'edge-%d-in-%s-to-%s' % (len(gfa_graph.edges), a_ctg_id, p_ctg_id) edge_name = 'edge-%d' % (len(gfa_graph.edges)) gfa_graph.add_edge(edge_name, a_ctg_id, '+', p_ctg_id, '+', a_ctg_len, a_ctg_len, end, end, '*', tags = {}, labels = {}) fp_out.write(serialize_gfa(gfa_graph)) fp_out.write('\n') def parse_args(argv): parser = argparse.ArgumentParser(description="Generates GFA output (on stdout) from FALCON's assembly.", formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--p-ctg-tiling-path', type=str, default='p_ctg_tiling_path', help='location of the p_ctg tiling path file') parser.add_argument('--a-ctg-tiling-path', type=str, default='a_ctg_tiling_path', help='location of the a_ctg tiling path file') parser.add_argument('--p-ctg-fasta', type=str, default='p_ctg.fa', help='path to the primary contigs file') parser.add_argument('--a-ctg-fasta', type=str, default='a_ctg.fa', help='path to the associate contigs file') parser.add_argument('--write-contigs', '-c', action='store_true', help="output contig sequences as S lines") parser.add_argument('--min-p-len', type=int, default=0, help='primary contig paths with length smaller than this will not be reported') parser.add_argument('--min-a-len', type=int, default=0, help='associate contig paths with length smaller than this will not be reported') parser.add_argument('--only-these-contigs', type=str, default='', help='limit output to specified contigs listed in file (one per line)') args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) run(sys.stdout, **vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/collect_pread_gfa.py ================================================ import argparse import os import sys import json from falcon_kit.fc_asm_graph import AsmGraph from falcon_kit.FastaReader import FastaReader from falcon_kit.gfa_graph import * import falcon_kit.tiling_path def load_seqs(fasta_fn, store_only_seq_len): """ If store_only_seq_len is True, then the seq is discarded and only it's length stored. """ seqs = {} f = FastaReader(fasta_fn) if store_only_seq_len == False: for r in f: seqs[r.name.split()[0]] = (len(r.sequence), r.sequence.upper()) else: for r in f: seqs[r.name.split()[0]] = (len(r.sequence), '*') return seqs def load_pread_overlaps(fp_in): preads_overlap_dict = {} for line in fp_in: sl = line.strip().split() if len(sl) < 13: continue # Example line: 000000009 000000082 -3004 99.90 0 4038 7043 7043 1 6488 9492 9492 overlap 000000F.5000003.0 000000F.5000003.0 preads_overlap_dict[(sl[0], sl[1])] = sl[0:4] + [int(val) for val in sl[4:12]] + sl[12:] # Overlaps are not always symmetrically represented in the preads.ovl for some reason, so add the # reverse overlap here as well, but do not overwrite existing (just to be safe). if (sl[1], sl[0]) not in preads_overlap_dict: preads_overlap_dict[(sl[1], sl[0])] = [sl[1], sl[0], sl[2], sl[3]] + [int(val) for val in sl[8:12]] + [int(val) for val in sl[4:8]] + sl[12:] return preads_overlap_dict def load_sg_edges(fp_in): """ Loads all sg_edges_list so that haplotig paths can be reversed if needed. with open(os.path.join(fc_asm_path, "sg_edges_list"), 'r') as fp: sg_edges_dict = load_sg_edges(fp) """ sg_edges_dict = {} for line in fp_in: sl = line.strip().split() if len(sl) < 8: continue # Example line: 000000512:B 000000679:E 000000679 4290 7984 4290 99.95 TR sg_edges_dict[(sl[0], sl[1])] = sl[0:3] + [int(val) for val in sl[3:6]] + [float(sl[6])] + sl[7:] return sg_edges_dict def add_node(gfa_graph, v, preads_dict): v_name, v_orient = v.split(':') v_len, v_seq = preads_dict[v_name] gfa_graph.add_node(v_name, v_len, v_seq) def add_edge(gfa_graph, v, w, edge_split_line, preads_overlap_dict, sg_edges_dict): edge_name = 'edge-%d' % (len(gfa_graph.edges)) v_name, v_orient = v.split(':') w_name, w_orient = w.split(':') v_orient = '+' if v_orient == 'E' else '-' w_orient = '+' if w_orient == 'E' else '-' cigar = '*' # Get the SG edge and the overlap, and set the tags and labels. sg_edge = sg_edges_dict[(v, w)] overlap = preads_overlap_dict[(v_name, w_name)] labels = {'tp': edge_split_line, 'sg_edge': sg_edge, 'overlap': overlap} tags = {} # Example overlap: # 000000001 000000170 -6104 99.75 0 1909 8010 8010 1 1250 7354 7354 overlap 000000F.5000003.0 000000F.5000003.0 # Handle the overlap coordinates - GFA format requires the coordinates to be with # respect to the fwd strand, and the M4 format reports overlaps on the # strand of the alignment. _, _, score, idt, v_rev, v_start, v_end, v_len, w_rev, w_start, w_end, w_len = overlap[0:12] if v_rev == 1: v_start, v_end = v_end, v_start v_start = v_len - v_start v_end = v_len - v_end if w_rev == 1: w_start, w_end = w_end, w_start w_start = w_len - w_start w_end = w_len - w_end gfa_graph.add_edge(edge_name, v_name, v_orient, w_name, w_orient, v_start, v_end, w_start, w_end, cigar, tags = tags, labels = labels) def add_tiling_paths_to_gfa(gfa_graph, tiling_paths, preads_dict, preads_overlap_dict, sg_edges_dict): # Add nodes. for ctg_id, tiling_path in tiling_paths.iteritems(): for edge in tiling_path.edges: add_node(gfa_graph, edge.v, preads_dict) add_node(gfa_graph, edge.w, preads_dict) # Add edges. for ctg_id, tiling_path in tiling_paths.iteritems(): for edge in tiling_path.edges: add_edge(gfa_graph, edge.v, edge.w, edge.get_split_line(), preads_overlap_dict, sg_edges_dict) # Add path. for ctg_id, tiling_path in tiling_paths.iteritems(): path_nodes = [] path_cigars = [] if len(tiling_path.edges) == 0: continue # Add the first node to the path. v = tiling_path.edges[0].v v_name, v_orient = v.split(':') cigar = '%dM' % (tiling_path.coords[v]) # This will be 0 if the contig is improper, and length of v otherwise. path_nodes.append(v_name) path_cigars.append(cigar) # Add the rest of the nodes. for edge in tiling_path.edges: w_name, w_orient = edge.w.split(':') cigar = '%dM' % (abs(edge.e - edge.b)) path_nodes.append(w_name) path_cigars.append(cigar) gfa_graph.add_path(ctg_id, path_nodes, path_cigars) def add_string_graph_to_gfa(gfa_graph, sg_edges_list, utg_data, ctg_paths, preads_dict, preads_overlap_dict, sg_edges_dict): asm_graph = AsmGraph(sg_edges_list, utg_data, ctg_paths) for v, w in asm_graph.sg_edges: add_node(gfa_graph, v, preads_dict) add_node(gfa_graph, w, preads_dict) for v, w in asm_graph.sg_edges: edge_data = asm_graph.sg_edges[(v, w)] if edge_data[-1] != 'G': continue add_edge(gfa_graph, v, w, edge_data, preads_overlap_dict, sg_edges_dict) def run(fp_out, p_ctg_tiling_path, a_ctg_tiling_path, preads_fasta, p_ctg_fasta, a_ctg_fasta, sg_edges_list, preads_ovl, utg_data, ctg_paths, add_string_graph, write_reads, min_p_len, min_a_len, only_these_contigs): """ This method produces a GFAGraph object containing info required to write both the GFA-1 and GFA-2 formatted assemblies. However, it does not write the GFA formats directly, but instead dumps a JSON file to disk. The JSON file is converted to a GFA-1 or a GFA-2 with outside scripts. The graphical output is produced from either the entire string graph (only the non-filtered edges are considered) or from only the tiling paths. String graph can show the neighborhood of contig breaks, whereas the tiling path output is more sparse. Output is written to stdout. """ gfa_graph = GFAGraph() # Load preads. preads_dict = load_seqs(preads_fasta, (not write_reads)) # Load the pread overlaps with open(preads_ovl, 'r') as fp: preads_overlap_dict = load_pread_overlaps(fp) # Load the SG edges. with open(sg_edges_list, 'r') as fp: sg_edges_dict = load_sg_edges(fp) # Load the primary and associate contig files. p_ctg_seqs = load_seqs(p_ctg_fasta, True) a_ctg_seqs = load_seqs(a_ctg_fasta, True) # Collect the sequence lengths from the above dicts. p_ctg_lens = {key: val[0] for key, val in p_ctg_seqs.iteritems()} a_ctg_lens = {key: val[0] for key, val in a_ctg_seqs.iteritems()} # Create whitelists for filtering contigs. p_ctg_whitelist = set(p_ctg_seqs.keys()) a_ctg_whitelist = set([key for key in a_ctg_seqs.keys()]) if only_these_contigs: p_ctg_whitelist = set(open(only_these_contigs).read().splitlines()) & set(p_ctg_whitelist) a_ctg_whitelist = set([key for key in a_ctg_seqs.keys() if key.split('-')[0].split('_')[0] in p_ctg_whitelist]) # Load the tiling paths and assign coordinates. p_paths = falcon_kit.tiling_path.load_tiling_paths(p_ctg_tiling_path, whitelist_seqs=p_ctg_whitelist, contig_lens=p_ctg_lens) a_paths = falcon_kit.tiling_path.load_tiling_paths(a_ctg_tiling_path, whitelist_seqs=a_ctg_whitelist, contig_lens=a_ctg_lens) add_tiling_paths_to_gfa(gfa_graph, p_paths, preads_dict, preads_overlap_dict, sg_edges_dict) add_tiling_paths_to_gfa(gfa_graph, a_paths, preads_dict, preads_overlap_dict, sg_edges_dict) if add_string_graph: add_string_graph_to_gfa(gfa_graph, sg_edges_list, utg_data, ctg_paths, preads_dict, preads_overlap_dict, sg_edges_dict) fp_out.write(serialize_gfa(gfa_graph)) fp_out.write('\n') def parse_args(argv): parser = argparse.ArgumentParser(description="Generates GFA output (on stdout) from FALCON's assembly.", formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--p-ctg-tiling-path', type=str, default='p_ctg_tiling_path', help='location of the p_ctg tiling path file') parser.add_argument('--a-ctg-tiling-path', type=str, default='a_ctg_tiling_path', help='location of the a_ctg tiling path file') parser.add_argument('--preads-fasta', type=str, default='preads4falcon.fasta', help='path to the preads4falcon.fasta file') parser.add_argument('--p-ctg-fasta', type=str, default='p_ctg.fa', help='path to the primary contigs file') parser.add_argument('--a-ctg-fasta', type=str, default='a_ctg.fa', help='path to the associate contigs file') parser.add_argument('--sg-edges-list', type=str, default='sg_edges_list', help='string graph edges file from Falcon assembly') parser.add_argument('--preads-ovl', type=str, default='preads.ovl', help='the preads overlap file') parser.add_argument('--utg-data', type=str, default='utg_data', help='unitig data file from Falcon') parser.add_argument('--ctg-paths', type=str, default='ctg_paths', help='contig paths file from Falcon assembly') parser.add_argument('--add-string-graph', action='store_true', help="in addition to tiling paths, output other edges and nodes from the final string graph") parser.add_argument('--write-reads', '-r', action='store_true', help="output read sequences in S lines") # parser.add_argument('--write-contigs', '-c', action='store_true', # help="output contig sequences as S lines") parser.add_argument('--min-p-len', type=int, default=0, help='primary contig paths with length smaller than this will not be reported') parser.add_argument('--min-a-len', type=int, default=0, help='associate contig paths with length smaller than this will not be reported') parser.add_argument('--only-these-contigs', type=str, default='', help='limit output to specified contigs listed in file (one per line)') args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) run(sys.stdout, **vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/consensus.py ================================================ from __future__ import absolute_import from __future__ import print_function from __future__ import division from builtins import range from ctypes import (POINTER, c_char_p, c_uint, c_uint, c_uint, c_uint, c_uint, c_double, string_at) from falcon_kit.multiproc import Pool from falcon_kit import falcon import argparse import logging import multiprocessing import os import re import sys import falcon_kit LOG = logging.getLogger() falcon.generate_consensus.argtypes = [ POINTER(c_char_p), c_uint, c_uint, c_uint, c_double] falcon.generate_consensus.restype = POINTER(falcon_kit.ConsensusData) falcon.free_consensus_data.argtypes = [POINTER(falcon_kit.ConsensusData)] def get_longest_reads(seqs, max_n_read, max_cov_aln, sort=True): # including the sort kwarg allows us to avoid a redundant sort # in get_consensus_trimmed() if sort: seqs = seqs[:1] + sorted(seqs[1:], key=lambda x: -len(x)) longest_n_reads = max_n_read if max_cov_aln > 0: longest_n_reads = 1 seed_len = len(seqs[0]) read_cov = 0 for seq in seqs[1:]: if read_cov // seed_len > max_cov_aln: break longest_n_reads += 1 read_cov += len(seq) longest_n_reads = min(longest_n_reads, max_n_read) return(seqs[:longest_n_reads]) def get_alignment(seq1, seq0, edge_tolerance=1000): kup = falcon_kit.kup K = 8 lk_ptr = kup.allocate_kmer_lookup(1 << (K * 2)) sa_ptr = kup.allocate_seq(len(seq0)) sda_ptr = kup.allocate_seq_addr(len(seq0)) kup.add_sequence(0, K, seq0, len(seq0), sda_ptr, sa_ptr, lk_ptr) kup.mask_k_mer(1 << (K * 2), lk_ptr, 16) kmer_match_ptr = kup.find_kmer_pos_for_seq( seq1, len(seq1), K, sda_ptr, lk_ptr) kmer_match = kmer_match_ptr[0] aln_range_ptr = kup.find_best_aln_range2(kmer_match_ptr, K, K * 50, 25) #x,y = zip( * [ (kmer_match.query_pos[i], kmer_match.target_pos[i]) for i in range(kmer_match.count )] ) aln_range = aln_range_ptr[0] kup.free_kmer_match(kmer_match_ptr) s1, e1, s0, e0, km_score = aln_range.s1, aln_range.e1, aln_range.s2, aln_range.e2, aln_range.score e1 += K + K // 2 e0 += K + K // 2 kup.free_aln_range(aln_range) len_1 = len(seq1) len_0 = len(seq0) if e1 > len_1: e1 = len_1 if e0 > len_0: e0 = len_0 aln_size = 1 if e1 - s1 > 500: aln_size = max(e1 - s1, e0 - s0) aln_score = int(km_score * 48) aln_q_s = s1 aln_q_e = e1 aln_t_s = s0 aln_t_e = e0 kup.free_seq_addr_array(sda_ptr) kup.free_seq_array(sa_ptr) kup.free_kmer_lookup(lk_ptr) if s1 > edge_tolerance and s0 > edge_tolerance: return 0, 0, 0, 0, 0, 0, "none" if len_1 - e1 > edge_tolerance and len_0 - e0 > edge_tolerance: return 0, 0, 0, 0, 0, 0, "none" if e1 - s1 > 500 and aln_size > 500: return s1, s1 + aln_q_e - aln_q_s, s0, s0 + aln_t_e - aln_t_s, aln_size, aln_score, "aln" else: return 0, 0, 0, 0, 0, 0, "none" def get_consensus_without_trim(c_input): seqs, seed_id, config = c_input LOG.debug('Starting get_consensus_without_trim(len(seqs)=={}, seed_id={})'.format( len(seqs), seed_id)) min_cov, K, max_n_read, min_idt, edge_tolerance, trim_size, min_cov_aln, max_cov_aln = config if len(seqs) > max_n_read: seqs = get_longest_reads(seqs, max_n_read, max_cov_aln, sort=True) seqs_ptr = (c_char_p * len(seqs))() seqs_ptr[:] = seqs consensus_data_ptr = falcon.generate_consensus( seqs_ptr, len(seqs), min_cov, K, min_idt) consensus = string_at(consensus_data_ptr[0].sequence)[:] eff_cov = consensus_data_ptr[0].eff_cov[:len(consensus)] LOG.debug(' Freeing1') falcon.free_consensus_data(consensus_data_ptr) del seqs_ptr LOG.debug(' Finishing get_consensus_without_trim(seed_id={})'.format(seed_id)) return consensus, seed_id def get_consensus_with_trim(c_input): seqs, seed_id, config = c_input LOG.debug('Starting get_consensus_with_trim(len(seqs)=={}, seed_id={})'.format( len(seqs), seed_id)) min_cov, K, max_n_read, min_idt, edge_tolerance, trim_size, min_cov_aln, max_cov_aln = config trim_seqs = [] seed = seqs[0] for seq in seqs[1:]: aln_data = get_alignment(seq, seed, edge_tolerance) s1, e1, s2, e2, aln_size, aln_score, c_status = aln_data if c_status == "none": continue if aln_score > 1000 and e1 - s1 > 500: e1 -= trim_size s1 += trim_size trim_seqs.append((e1 - s1, seq[s1:e1])) trim_seqs.sort(key=lambda x: -x[0]) # use longest alignment first trim_seqs = [x[1] for x in trim_seqs] trim_seqs = [seed] + trim_seqs if len(trim_seqs[1:]) > max_n_read: # seqs already sorted, dont' sort again trim_seqs = get_longest_reads( trim_seqs, max_n_read, max_cov_aln, sort=False) seqs_ptr = (c_char_p * len(trim_seqs))() seqs_ptr[:] = trim_seqs consensus_data_ptr = falcon.generate_consensus( seqs_ptr, len(trim_seqs), min_cov, K, min_idt) consensus = string_at(consensus_data_ptr[0].sequence)[:] eff_cov = consensus_data_ptr[0].eff_cov[:len(consensus)] LOG.debug(' Freeing2') falcon.free_consensus_data(consensus_data_ptr) del seqs_ptr LOG.debug(' Finishing get_consensus_with_trim(seed_id={})'.format(seed_id)) return consensus, seed_id def get_seq_data(config, min_n_read, min_len_aln): max_len = 100000 min_cov, K, max_n_read, min_idt, edge_tolerance, trim_size, min_cov_aln, max_cov_aln = config seqs = [] seed_id = None seed_len = 0 seqs_data = [] read_cov = 0 read_ids = set() with sys.stdin as f: for l in f: l = l.strip().split() if len(l) != 2: continue read_id = l[0] seq = l[1] if len(seq) > max_len: seq = seq[:max_len - 1] if read_id not in ("+", "-", "*"): if len(seq) >= min_len_aln: if len(seqs) == 0: seqs.append(seq) # the "seed" seed_len = len(seq) seed_id = read_id if read_id not in read_ids: # avoidng using the same read twice. seed is used again here by design seqs.append(seq) read_ids.add(read_id) read_cov += len(seq) elif l[0] == "+": if len(seqs) >= min_n_read and read_cov // seed_len >= min_cov_aln: seqs = get_longest_reads( seqs, max_n_read, max_cov_aln, sort=True) yield (seqs, seed_id, config) #seqs_data.append( (seqs, seed_id) ) seqs = [] read_ids = set() seed_id = None read_cov = 0 elif l[0] == "*": seqs = [] read_ids = set() seed_id = None read_cov = 0 elif l[0] == "-": # yield (seqs, seed_id) #seqs_data.append( (seqs, seed_id) ) break def format_seq(seq, col): return "\n".join([seq[i:(i + col)] for i in range(0, len(seq), col)]) def parse_args(argv): parser = argparse.ArgumentParser(description='a simple multi-processor consensus sequence generator', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--n-core', type=int, default=24, help='number of processes used for generating consensus; ' '0 for main process only') parser.add_argument('--min-cov', type=int, default=6, help='minimum coverage to break the consensus') parser.add_argument('--min-cov-aln', type=int, default=10, help='minimum coverage of alignment data; a seed read with less than MIN_COV_ALN average depth' + ' of coverage will be completely ignored') parser.add_argument('--max-cov-aln', type=int, default=0, # 0 to emulate previous behavior help='maximum coverage of alignment data; a seed read with more than MAX_COV_ALN average depth' + \ ' of coverage of the longest alignments will be capped, excess shorter alignments will be ignored') parser.add_argument('--min-len-aln', type=int, default=0, # 0 to emulate previous behavior help='minimum length of a sequence in an alignment to be used in consensus; any shorter sequence will be completely ignored') parser.add_argument('--min-n-read', type=int, default=10, help='1 + minimum number of reads used in generating the consensus; a seed read with fewer alignments will ' + 'be completely ignored') parser.add_argument('--max-n-read', type=int, default=500, help='1 + maximum number of reads used in generating the consensus') parser.add_argument('--trim', action="store_true", default=False, help='trim the input sequence with k-mer spare dynamic programming to find the mapped range') parser.add_argument('--output-full', action="store_true", default=False, help='output uncorrected regions too') parser.add_argument('--output-multi', action="store_true", default=False, help='output multi correct regions') parser.add_argument('--min-idt', type=float, default=0.70, help='minimum identity of the alignments used for correction') parser.add_argument('--edge-tolerance', type=int, default=1000, help='for trimming, the there is unaligned edge leng > edge_tolerance, ignore the read') parser.add_argument('--trim-size', type=int, default=50, help='the size for triming both ends from initial sparse aligned region') parser.add_argument('-v', '--verbose-level', type=float, default=2.0, help='logging level (WARNING=3, INFO=2, DEBUG=1)') return parser.parse_args(argv[1:]) def run(args): logging.basicConfig(level=int(round(10*args.verbose_level))) good_region = re.compile("[ACGT]+") assert args.n_core <= multiprocessing.cpu_count(), 'Requested n_core={} > cpu_count={}'.format( args.n_core, multiprocessing.cpu_count()) def Start(): LOG.info('Started a worker in {} from parent {}'.format( os.getpid(), os.getppid())) exe_pool = Pool(args.n_core, initializer=Start) if args.trim: get_consensus = get_consensus_with_trim else: get_consensus = get_consensus_without_trim K = 8 config = args.min_cov, K, \ args.max_n_read, args.min_idt, args.edge_tolerance, args.trim_size, args.min_cov_aln, args.max_cov_aln # TODO: pass config object, not tuple, so we can add fields for res in exe_pool.imap(get_consensus, get_seq_data(config, args.min_n_read, args.min_len_aln)): cns, seed_id = res if len(cns) < 500: continue if args.output_full: print(">" + seed_id + "_f") print(cns) else: cns = good_region.findall(cns) if len(cns) == 0: continue if args.output_multi: seq_i = 0 for cns_seq in cns: if len(cns_seq) < 500: continue if seq_i >= 10: break print(">prolog/%s%01d/%d_%d" % (seed_id, seq_i, 0, len(cns_seq))) print(format_seq(cns_seq, 80)) seq_i += 1 else: cns.sort(key=lambda x: len(x)) print(">" + seed_id) print(cns[-1]) def main(argv=sys.argv): args = parse_args(argv) run(args) if __name__ == "__main__": main(sys.argv) ================================================ FILE: falcon_kit/mains/consensus_gather_fasta_fofn.py ================================================ """ """ from __future__ import absolute_import from __future__ import print_function from future.utils import viewitems import argparse import logging import os import sys from .. import io LOG = logging.getLogger() def run(gathered_fn, preads_fofn_fn): gathered = io.deserialize(gathered_fn) d = os.path.abspath(os.path.realpath(os.path.dirname(gathered_fn))) def abspath(fn): if os.path.isabs(fn): return fn # I expect this never to happen though. return os.path.join(d, fn) fasta_fns = list() for desc in gathered: fasta_fns.append(abspath(desc['fasta'])) with open(preads_fofn_fn, 'w') as f: for filename in sorted(fasta_fns): print(filename, file=f) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Turn gathered file into FOFN of fasta files.' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--gathered-fn', help='Input. JSON list of output dicts.') parser.add_argument( '--preads-fofn-fn', help='Output. FOFN of preads (fasta files).', ) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/consensus_scatter.py ================================================ from __future__ import absolute_import from future.utils import viewitems import argparse import collections import logging import os import sys from .. import io from .. import bash LOG = logging.getLogger() def corrected_relpath(p, was_rel_to): if os.path.isabs(p): return p #LOG.warning('{},{},{}'.format(p, was_rel_to, os.path.relpath(os.path.join(was_rel_to, p)))) return os.path.normpath(os.path.relpath(os.path.join(was_rel_to, p))) def read_gathered_las(path): """Return dict of block->[las_paths]. For now, these are ws separated on each line of input. """ result = collections.defaultdict(list) dn = os.path.normpath(os.path.dirname(path)) with open(path) as ifs: for line in ifs: block, las_path = line.split() result[int(block)].append(corrected_relpath(las_path, dn)) #import pprint #LOG.warning('path={!r}, result={}'.format( # path, pprint.pformat(result))) return result def run(las_fopfn_fn, db_fn, length_cutoff_fn, config_fn, wildcards, scattered_fn): LOG.info('Scattering las from {!r} (based on {!r}) into {!r}.'.format( las_fopfn_fn, db_fn, scattered_fn)) wildcards = wildcards.split(',') basedir = os.path.dirname(os.path.abspath(scattered_fn)) rootdir = os.path.dirname(os.path.dirname(basedir)) # for now jobs = list() p_ids_merge_las = read_gathered_las(las_fopfn_fn) tasks = [] for (p_id, las_fns) in viewitems(p_ids_merge_las): assert len(las_fns) == 1, repr(las_fns) # since we know each merge-task is for a single block las_fn = las_fns[0] cns_id = 'cns_%05d' % int(p_id) cns_id2 = cns_id ##out_done_fn = '%s_done' % cns_label #out_file_fn = '%s.fasta' % cns_label symlinked_las_fn = '{rootdir}/0-rawreads/cns-scatter/{cns_id}/merged.{cns_id2}.las'.format(**locals()) io.mkdirs(os.path.normpath(os.path.dirname(symlinked_las_fn))) src = os.path.relpath(las_fn, os.path.normpath(os.path.dirname(symlinked_las_fn))) io.symlink(src, symlinked_las_fn) # Record in a job-dict. job = dict() job['input'] = dict( las = symlinked_las_fn, db = db_fn, length_cutoff = length_cutoff_fn, config = config_fn, ) job['output'] = dict( fasta = '{rootdir}/0-rawreads/consensus/{cns_id}/consensus.{cns_id2}.fasta'.format(**locals()), ) job['params'] = dict( ) job['wildcards'] = {wildcards[0]: cns_id, wildcards[1]: cns_id} jobs.append(job) io.serialize(scattered_fn, jobs) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Prepare for parallel consensus jobs.' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--las-fopfn-fn', help='Input. FOFN for las files.)', ) parser.add_argument( '--db-fn', help='Input. Dazzler DB of raw_reads.', ) parser.add_argument( '--length-cutoff-fn', help='Input. Contains a single integer, the length-cutoff.', ) parser.add_argument( '--config-fn', help='Input. JSON of relevant configuration (currently from General section of full-prog config).', ) parser.add_argument( '--wildcards', help='To be used in substitutions', ) parser.add_argument( '--scattered-fn', help='Output. JSON list of jobs, where each is a dict of input/output/params/wildcards.', ) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/consensus_split.py ================================================ from __future__ import absolute_import from future.utils import viewitems import argparse import collections import logging import os import sys from .. import io from .. import bash from .. import pype_tasks LOG = logging.getLogger() def corrected_relpath(p, was_rel_to): if os.path.isabs(p): return p #LOG.warning('{},{},{}'.format(p, was_rel_to, os.path.relpath(os.path.join(was_rel_to, p)))) return os.path.normpath(os.path.relpath(os.path.join(was_rel_to, p))) def read_gathered_las(path): """Return dict of block->[las_paths]. For now, these are ws separated on each line of input. """ result = collections.defaultdict(list) dn = os.path.normpath(os.path.dirname(path)) p_id2las = io.deserialize(path) for block, las_path in p_id2las.items(): result[int(block)].append(corrected_relpath(las_path, dn)) #import pprint #LOG.warning('path={!r}, result={}'.format( # path, pprint.pformat(result))) return result def run(p_id2las_fn, db_fn, length_cutoff_fn, config_fn, wildcards, bash_template_fn, split_fn): with open(bash_template_fn, 'w') as stream: stream.write(pype_tasks.TASK_CONSENSUS_TASK_SCRIPT) db_fn = os.path.realpath(db_fn) # Because DazzlerDB is not a "FileType" in pbcommand, # it might be a symlink with a weird extension. LOG.info('Scattering las from {!r} (based on {!r}) into {!r}.'.format( p_id2las_fn, db_fn, split_fn)) wildcards = wildcards.split(',') #basedir = os.path.dirname(os.path.abspath(split_fn)) #rootdir = os.path.dirname(os.path.dirname(basedir)) # for now outdir = os.path.abspath(os.path.dirname(split_fn)) jobs = list() p_ids_merge_las = read_gathered_las(p_id2las_fn) tasks = [] for (p_id, las_fns) in viewitems(p_ids_merge_las): assert len(las_fns) == 1, repr(las_fns) # since we know each merge-task is for a single block las_fn = las_fns[0] cns_id = 'cns_%05d' % int(p_id) cns_id2 = cns_id ##out_done_fn = '%s_done' % cns_label #out_file_fn = '%s.fasta' % cns_label #symlinked_las_fn = '{rootdir}/0-rawreads/cns-split/{cns_id}/merged.{cns_id2}.las'.format(**locals()) symlinked_las_fn = '{outdir}/cns-symlinks/{cns_id}/merged.{cns_id2}.las'.format(**locals()) io.mkdirs(os.path.normpath(os.path.dirname(symlinked_las_fn))) src = os.path.relpath(las_fn, os.path.normpath(os.path.dirname(symlinked_las_fn))) io.symlink(src, symlinked_las_fn) # Record in a job-dict. job = dict() job['input'] = dict( las = symlinked_las_fn, db = db_fn, length_cutoff = length_cutoff_fn, config = config_fn, ) job['output'] = dict( fasta = 'consensus.{cns_id2}.fasta'.format(**locals()), #'{rootdir}/0-rawreads/consensus/{cns_id}/consensus.{cns_id2}.fasta'.format(**locals()), ) job['params'] = dict( ) job['wildcards'] = {wildcards[0]: cns_id, wildcards[1]: cns_id} jobs.append(job) io.serialize(split_fn, jobs) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Prepare for parallel consensus jobs.' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--p-id2las-fn', help='Input. JSON dict of p-id to las.)') parser.add_argument( '--db-fn', help='Input. Dazzler DB of raw_reads.') parser.add_argument( '--length-cutoff-fn', help='Input. Contains a single integer, the length-cutoff.') parser.add_argument( '--config-fn', help='Input. JSON of relevant configuration (currently from General section of full-prog config).') parser.add_argument( '--wildcards', help='Input. Comma-separated wildcard names. Might be needed downstream.') parser.add_argument( '--split-fn', help='Output. JSON list of jobs, where each is a dict of input/output/params/wildcards.') parser.add_argument( '--bash-template-fn', help='Output. Copy of known daligner bash template, for use later.') args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/consensus_task.py ================================================ from __future__ import absolute_import import argparse import logging import multiprocessing import os import re import sys from .. import io from .. import bash LOG = logging.getLogger() def get_option_with_proper_nproc(regexp, opt, opt_name, nproc, cpu_count=multiprocessing.cpu_count()): """Return opts sans the regexp match, and proper nproc. >>> regexp = re.compile(r'-j[^\d]*(\d+)') >>> get_option_with_proper_nproc(regexp, 'foo -j 5', 'baz', nproc=7, cpu_count=6) ('foo ', 5) >>> get_option_with_proper_nproc(regexp, 'foo -j 5', 'baz', nproc=3, cpu_count=4) ('foo ', 3) >>> get_option_with_proper_nproc(regexp, 'foo -j 5', 'baz', nproc=3, cpu_count=2) ('foo ', 2) """ job_nproc = int(nproc) mo = regexp.search(opt) if mo: opt_nproc = int(mo.group(1)) if job_nproc < opt_nproc: LOG.warning('NPROC={}, but falcon_sense_option="{}", so we will ignore that option and use {}'.format( job_nproc, opt, job_nproc)) elif job_nproc > opt_nproc: LOG.warning('NPROC={}, but falcon_sense_option="{}", so we will override NPROC and use {}'.format( job_nproc, opt, opt_nproc)) nproc = min(job_nproc, opt_nproc) opt = regexp.sub('', opt) # remove --n_core, for now else: nproc = job_nproc if nproc > cpu_count: LOG.warning('Requested nproc={} > cpu_count={}; using {}'.format( nproc, cpu_count, cpu_count)) nproc = cpu_count return opt, nproc def get_falcon_sense_option(opt, nproc): """ >>> get_falcon_sense_option('', 11) ' --n-core=11' >>> get_falcon_sense_option('--n-core=24', 10) ' --n-core=10' """ re_n_core = re.compile(r'--n-core[^\d]+(\d+)') opt, nproc = get_option_with_proper_nproc(re_n_core, opt, 'falcon_sense_option', nproc) opt += ' --n-core={}'.format(nproc) return opt def get_pa_dazcon_option(opt, nproc): """ >>> get_pa_dazcon_option('', 12) ' -j 12' >>> get_pa_dazcon_option('-j 48', 13) ' -j 13' """ re_j = re.compile(r'-j[^\d]+(\d+)') opt, nproc = get_option_with_proper_nproc(re_j, opt, 'pa_dazcon_option', nproc) opt += ' -j {}'.format(nproc) return opt # This function was copied from bash.py and modified. def script_run_consensus(config, db_fn, las_fn, out_file_fn, nproc): """config: dazcon, falcon_sense_greedy, falcon_sense_skip_contained, LA4Falcon_preload """ io.rm(out_file_fn) # in case of resume out_file_bfn = out_file_fn + '.tmp' params = dict(config) length_cutoff = params['length_cutoff'] bash_cutoff = '{}'.format(length_cutoff) params['falcon_sense_option'] = get_falcon_sense_option(params.get('falcon_sense_option', ''), nproc) params['pa_dazcon_option'] = get_pa_dazcon_option(params.get('pa_dazcon_option', ''), nproc) params.update(locals()) # not needed LA4Falcon_flags = 'P' if params.get('LA4Falcon_preload') else '' if config["falcon_sense_skip_contained"]: LA4Falcon_flags += 'fso' elif config["falcon_sense_greedy"]: LA4Falcon_flags += 'fog' else: LA4Falcon_flags += 'fo' if LA4Falcon_flags: LA4Falcon_flags = '-' + ''.join(set(LA4Falcon_flags)) run_consensus = "LA4Falcon -H$CUTOFF %s {db_fn} {las_fn} | python -m falcon_kit.mains.consensus {falcon_sense_option} >| {out_file_bfn}" % LA4Falcon_flags if config.get('dazcon', False): run_consensus = """ which dazcon dazcon {pa_dazcon_option} -s {db_fn} -a {las_fn} >| {out_file_bfn} """ script = """ set -o pipefail CUTOFF=%(bash_cutoff)s %(run_consensus)s mv -f {out_file_bfn} {out_file_fn} """ % (locals()) return script.format(**params) def run(config_fn, length_cutoff_fn, las_fn, db_fn, nproc, fasta_fn): job_done_fn = 'job.done' length_cutoff = int(open(length_cutoff_fn).read()) config = io.deserialize(config_fn) config['length_cutoff'] = length_cutoff script = script_run_consensus( config, db_fn, las_fn, os.path.basename(fasta_fn), # not sure basename is really needed here nproc=nproc, ) script_fn = 'run_consensus.sh' bash.write_script(script, script_fn, job_done_fn) io.syscall('bash -vex {}'.format(script_fn)) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Run consensus on a merged .las file, to produce a fasta file of preads.' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--nproc', help='Number of processors to be used.') parser.add_argument( '--las-fn', help='Input. Merged .las file.', ) parser.add_argument( '--db-fn', help='Input. Dazzler DB of raw-reads.', ) parser.add_argument( '--length-cutoff-fn', help='Input. Contains a single integer, the length-cutoff.', ) parser.add_argument( '--config-fn', help='Input. JSON of relevant configuration (currently from General section of full-prog config).', ) parser.add_argument( '--fasta-fn', help='Output. Consensus fasta file.', ) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/contig_annotate.py ================================================ from __future__ import absolute_import from __future__ import print_function from falcon_kit.fc_asm_graph import AsmGraph import sys def main(argv=sys.argv): G_asm = AsmGraph("sg_edges_list", "utg_data", "ctg_paths") p_ctg_coor_map = {} for fn in ("p_ctg_tiling_path", "a_ctg_tiling_path"): f = open(fn) for row in f: row = row.strip().split() ctg_id, v, w, edge_rid, b, e = row[:6] if ctg_id not in p_ctg_coor_map: coor = 0 # the p_ctg_tiling_path should be sorted by contig the order of the edges in the tiling path p_ctg_coor_map[ctg_id] = {} p_ctg_coor_map[ctg_id][v] = 0 coor += abs(int(b) - int(e)) p_ctg_coor_map[ctg_id][w] = coor G_asm.node_to_ctg[w] print(ctg_id, v, 0, " ".join(list(G_asm.node_to_ctg[v]))) print(ctg_id, w, coor, " ".join(list(G_asm.node_to_ctg[w]))) continue else: coor += abs(int(b) - int(e)) p_ctg_coor_map[ctg_id][w] = coor print(ctg_id, w, coor, " ".join(list(G_asm.node_to_ctg[w]))) f.close() if __name__ == "__main__": main(sys.argv) ================================================ FILE: falcon_kit/mains/copy_fofn.py ================================================ from __future__ import absolute_import import argparse import logging import os import sys from .. import io LOG = logging.getLogger() def run(abs, in_fn, out_fn): out_dir = os.path.normpath(os.path.dirname(out_fn)) io.mkdirs(out_dir) def identity(fn): return fn def relative(fn): return os.path.relpath(fn, out_dir) adjusted_fn = identity if abs else relative with open(out_fn, 'w') as stream: for abs_fn in io.yield_abspath_from_fofn(in_fn): fn = adjusted_fn(abs_fn) stream.write('{}\n'.format(fn)) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Copy FOFN. If directory changes, then relative paths must change too.' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--in-fn', help='Input. FOFN of paths relative to its own directory.' ) parser.add_argument( '--abs', action='store_true', help='Store absolute paths. (Otherwise, paths will be relative to directory of output FOFN.)' ) parser.add_argument( '--out-fn', help='Output. FOFN of paths relative to its own directory.' ) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/copy_mapped.py ================================================ #!/bin/env python2.7 from __future__ import absolute_import from future.utils import viewitems import argparse import json import logging import os import shutil import sys LOG = logging.getLogger(__name__) def deserialize(fn): with open(fn) as ifs: return json.loads(ifs.read()) def assert_exists(fn): if not os.path.isfile(fn): raise Exception('Does not exist: {!r}'.format(fn)) def mkdir(dirname): if not os.path.isdir(dirname): # Possible race-condition, so dirs must be created serially. os.makedirs(dirname) #def symlink(name, src): # msg = '{} -> {}'.format(name, src) # assert not os.path.lexists(name), msg # #print msg # os.symlink(src, name) def copy(name, rel_src): try: if not os.path.isabs(rel_src): dn = os.path.normpath(os.path.dirname(name)) src = os.path.join(dn, rel_src) else: src = rel_src shutil.copy2(src, name) except Exception: msg = '{} -> {}'.format(name, rel_src) LOG.error(msg) raise def run(special_split_fn, fn_patterns): """ Symlink targets will be relative to cwd. For each pattern, each wildcard will be substituted everywhere, e.g. fn_pattern == 'top/{key}/input_{key}.txt' """ fnkeypattdict = dict(fnkeypatt.split('=') for fnkeypatt in fn_patterns) jobs = deserialize(special_split_fn) mapdir = os.path.normpath(os.path.dirname(os.path.normpath(special_split_fn))) for job in jobs: inputs = job['input'] wildcards = job['wildcards'] for (fnkey, fn_pattern) in viewitems(fnkeypattdict): val = inputs[fnkey] # val should be relative to the location of the special_split_fn. #assert not os.path.isabs(val), 'mapped input (dynamic output) filename {!r} must be relative (to serialzed file location {!r})'.format( # val, special_split_fn) if not os.path.isabs(val): mapped_input_fn = os.path.join(mapdir, val) else: mapped_input_fn = val assert_exists(mapped_input_fn) try: symlink_name = fn_pattern.format(**wildcards) except Exception as err: import pprint msg = str(err) + ': for pattern {!r} and wildcards\n{!r}'.format( fn_pattern, pprint.pformat(wildcards)) raise Exception(msg) outdir = os.path.normpath(os.path.dirname(symlink_name)) mkdir(outdir) target_name = os.path.relpath(mapped_input_fn, outdir) copy(symlink_name, target_name) def parse_args(argv): description = 'Create copies called "fn_pattern", of files named by values in "mapped_fn".' parser = argparse.ArgumentParser( description=description, ) parser.add_argument( '--special-split-fn', required=True, help='Serialized split-file (in our special format), where "mapped_inputs" has a map with key to filename, relative to the directory of this file.') parser.add_argument( 'fn_patterns', nargs='+', help='"fnkey=pattern" Can appear multiple times. Each is a pattern for output filename, to be substituted with keys in special_split_fn. Each fnkey=filename must appear in the input section of each job listed in special-split.') return parser.parse_args(argv[1:]) def main(argv=sys.argv): args = parse_args(argv) run(**vars(args)) if __name__ == "__main__": logging.basicConfig() main() ================================================ FILE: falcon_kit/mains/ctg_link_analysis.py ================================================ from __future__ import absolute_import from __future__ import print_function from falcon_kit import fc_asm_graph import sys def main(argv=sys.argv): AsmGraph = fc_asm_graph.AsmGraph G_asm = AsmGraph("sg_edges_list", "utg_data", "ctg_paths") sg_edges = G_asm.sg_edges node_to_ctg = G_asm.node_to_ctg node_to_utg = G_asm.node_to_utg ctg_data = G_asm.ctg_data utg_data = G_asm.utg_data ctg_pair_links = {} for (v, w) in list(sg_edges.keys()): if v in node_to_ctg and w in node_to_ctg: for ctg1 in list(node_to_ctg[v]): for ctg2 in list(node_to_ctg[w]): if ctg1 == ctg2: continue ctg_pair_links.setdefault((ctg1, ctg2), set()) ctg_pair_links[(ctg1, ctg2)].add((v, w)) utg_pair_links = {} for (v, w) in list(sg_edges.keys()): if v in node_to_utg and w in node_to_utg: for u1 in list(node_to_utg[v]): for u2 in list(node_to_utg[w]): if u1 == u2: continue utg_pair_links.setdefault((u1, u2), set()) utg_pair_links[(u1, u2)].add((v, w)) for ctg1, ctg2 in ctg_pair_links: links = ctg_pair_links[(ctg1, ctg2)] count = len(links) if count > 0: path1 = ctg_data[ctg1][-1][-5:] path2 = ctg_data[ctg2][-1][:5] utg1 = [] utg2 = [] for s1, v1, t1 in path1: u1 = (s1, t1, v1) type_, length, score, path_or_edges = utg_data[u1] if type_ == "compound": for u in path_or_edges.split("|"): ss, vv, tt = u.split("~") utg1.append((ss, tt, vv)) else: utg1.append(u1) for s2, v2, t2 in path2: u2 = (s2, t2, v2) type_, length, score, path_or_edges = utg_data[u2] if type_ == "compound": for u in path_or_edges.split("|"): ss, vv, tt = u.split("~") utg2.append((ss, tt, vv)) else: utg2.append(u2) # print path1 # print path2 # print len(utg1), len(utg2) for u1 in utg1: for u2 in utg2: u1 = tuple(u1) u2 = tuple(u2) c = utg_pair_links.get((u1, u2), set()) if len(c) == 0: continue s1, t1, v1 = u1 s2, t2, v2 = u2 len_1 = ctg_data[ctg1][3] len_2 = ctg_data[ctg2][3] print('{} {} {:7d}\t{:7d}\t{}\t{}\t{}\t{} {} {}'.format( ctg1, ctg2, len_1, len_2, len(utg1), len(utg2), len(links), "~".join((s1, v1, t1)), "~".join((s2, v2, t2)), len(c))) if __name__ == "__main__": main(sys.argv) ================================================ FILE: falcon_kit/mains/daligner.py ================================================ from __future__ import absolute_import import argparse import logging import os import sys from .. import io from .. import bash # for write_script LOG = logging.getLogger() def run(daligner_settings_fn, daligner_script_fn, job_done_fn): cwd = os.getcwd() LOG.info('Running daligner from {!r} (using {!r}) to write {!r}'.format( daligner_script_fn, daligner_settings_fn, job_done_fn)) script = open(daligner_script_fn).read() #daligner_settings = io.deserialize(daligner_settings_fn) # not used script_fn = 'run_daligner.sh' bash.write_script(script, script_fn, job_done_fn) io.syscall('bash -vex {}'.format(script_fn)) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Run daligner (including LAsort and first-level LAmerge) using the script generated by HPC.daligner.' epilog = 'The real .las output will be next to the job-done sentinel file, but we would have to parse HPD.daligner to learn the actual filename.' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--daligner-settings-fn', help='Input. Any extra settings for daligner.', ) parser.add_argument( '--daligner-script-fn', help='Input. Part of the output of HPC.daligner.', ) parser.add_argument( '--job-done-fn', help='Output. Just a sentinel. The real .las output is next to this file, implicitly.', ) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/daligner_gather_las_list.py ================================================ """Not sure anything uses the fopfn anymore. """ from __future__ import absolute_import #from future.utils import viewitems #from future.utils import itervalues import argparse import glob import logging import os import sys from .. import io #, run_support LOG = logging.getLogger() def run(gathered_fn, las_paths_fn): gathered = io.deserialize(gathered_fn) d = os.path.abspath(os.path.realpath(os.path.dirname(gathered_fn))) def abspath(fn): if os.path.isabs(fn): return fn # I expect this never to happen though. return os.path.join(d, fn) job_done_fns = list() for job_output in gathered: for fn in job_output.values(): abs_fn = abspath(fn) job_done_fns.append(abs_fn) import pprint LOG.info('job_done_fns: {}'.format(pprint.pformat(job_done_fns))) job_rundirs = sorted(os.path.dirname(fn) for fn in job_done_fns) # Find all .las leaves so far. #[block, las_path in run_support.daligner_gather_las(job_rundirs)] las_paths = list() for uow_dir in job_rundirs: # We could assert the existence of a job_done file here. d = os.path.abspath(uow_dir) las_path_glob = glob.glob(os.path.join(d, '*.las')) LOG.debug('dir={!r}, glob={!r}'.format(d, las_path_glob)) las_paths.extend(las_path_glob) io.serialize(las_paths_fn, las_paths) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Turn gathered file into .las paths.' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--gathered-fn', help='Input. (From generic pypeflow gen_parallel.)', ) parser.add_argument( '--las-paths-fn', help='Output. JSON of las files.', ) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/daligner_scatter.py ================================================ from __future__ import absolute_import import argparse import collections import logging import os import sys from .. import io from .. import bash from .. import run_support LOG = logging.getLogger() def run(db_prefix, pread_aln, skip_checks, run_jobs_fn, db_fn, stage, wildcards, scattered_fn): nblock = run_support.get_nblock(db_fn) db_build_done_fn = None daligner_scripts = bash.scripts_daligner(run_jobs_fn, db_prefix, db_build_done_fn, nblock=nblock, pread_aln=bool(pread_aln), skip_check=skip_checks) basedir = os.path.dirname(os.path.abspath(scattered_fn)) rootdir = os.path.dirname(os.path.dirname(basedir)) # for now jobs = list() for job_uid, script in daligner_scripts: job_id = 'j_{}'.format(job_uid) daligner_settings = dict(db_prefix=db_prefix) # Write the scattered inputs. daligner_script_fn = '{rootdir}/{stage}/daligner-scripts/{job_id}/daligner-script.sh'.format(**locals()) daligner_settings_fn = '{rootdir}/{stage}/daligner-scripts/{job_id}/settings.json'.format(**locals()) io.mkdirs(os.path.dirname(daligner_script_fn)) with open(daligner_script_fn, 'w') as stream: stream.write(script) io.serialize(daligner_settings_fn, daligner_settings) # Record in a job-dict. job = dict() job['input'] = dict( daligner_script = daligner_script_fn, daligner_settings = daligner_settings_fn, # not used today, but maybe someday ) job['output'] = dict( job_done = '{rootdir}/{stage}/daligner/{job_id}/daligner.done'.format(**locals()), ) job['params'] = dict( ) job['wildcards'] = {wildcards: job_id} jobs.append(job) io.serialize(scattered_fn, jobs) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Prepare for parallel daligner jobs.' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--run-jobs-fn', help='Input. Result of HPC.daligner.', ) parser.add_argument( '--db-prefix', default='raw_reads', help='Either preads or raw_reads.', ) parser.add_argument( '--skip-checks', default=0, type=int, help='Skip LAcheck calls after daligner. (0 => do not skip)', ) parser.add_argument( '--db-fn', help='Dazzler DB of reads. (Used to calculate number of blocks.)', ) parser.add_argument( '--pread-aln', default=0, type=int, help='If non-zero, use pread alignment mode. (Run daligner_p instead of daligner.)', ) parser.add_argument( '--stage', default='0-rawreads', help='Either 0-rawreads or 1-preads_ovl, for now.', ) parser.add_argument( '--wildcards', help='To be used in substitutions', ) parser.add_argument( '--scattered-fn', help='Output. JSON list of jobs, where each is a dict of input/output/params/wildcards.', ) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/daligner_split.py ================================================ from __future__ import absolute_import import argparse import collections import logging import os import sys from .. import io from .. import bash from .. import run_support from .. import pype_tasks LOG = logging.getLogger() def run(bash_template_fn, db_prefix, pread_aln, skip_checks, run_jobs_fn, db_fn, wildcards, nproc, split_fn): with open(bash_template_fn, 'w') as stream: stream.write(pype_tasks.TASK_DALIGNER_SCRIPT) nblock = run_support.get_nblock(db_fn) # TODO: nproc can restrict -T => 1 or 2 (never 3) if 4 != nproc: LOG.warning('Currently ignoring nproc={} in daligner_split.'.format(nproc)) db_build_done_fn = None assert isinstance(pread_aln, int) daligner_scripts = bash.scripts_daligner(run_jobs_fn, db_prefix, db_build_done_fn, nblock=nblock, pread_aln=bool(pread_aln), skip_check=skip_checks) #basedir = os.path.dirname(os.path.abspath(split_fn)) #rootdir = os.path.dirname(os.path.dirname(basedir)) # for now cwd = os.getcwd() jobs = list() for job_uid, script in daligner_scripts: job_id = 'j_{}'.format(job_uid) daligner_settings = dict(db_prefix=db_prefix) # Write script/settings for a unit-of-work. daligner_script_fn = '{cwd}/daligner-scripts/{job_id}/daligner-script.sh'.format(**locals()) daligner_settings_fn = '{cwd}/daligner-scripts/{job_id}/settings.json'.format(**locals()) io.mkdirs(os.path.dirname(daligner_script_fn)) with open(daligner_script_fn, 'w') as stream: stream.write(script) io.serialize(daligner_settings_fn, daligner_settings) # Record in a job-dict. job = dict() job['input'] = dict( daligner_script = daligner_script_fn, daligner_settings = daligner_settings_fn, # not used today, but maybe someday ) job['output'] = dict( job_done = 'daligner.done' ) job['params'] = dict( ) job['wildcards'] = {wildcards: job_id} jobs.append(job) io.serialize(split_fn, jobs) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Split HPC.daligner output into multiple daligner jobs (possible in parallel).' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--run-jobs-fn', help='Input. Result of HPC.daligner.') parser.add_argument( '--db-prefix', default='raw_reads', help='Either preads or raw_reads.') parser.add_argument( '--skip-checks', default=0, type=int, help='Skip LAcheck calls after daligner. (0 => do not skip)') parser.add_argument( '--db-fn', help='Dazzler DB of reads. (Used to calculate number of blocks.)') parser.add_argument( '--pread-aln', default=0, type=int, help='If non-zero, use pread alignment mode. (Run daligner_p instead of daligner.)') parser.add_argument( '--wildcards', help='Input. Comma-separated wildcard names. Might be needed downstream.') parser.add_argument( '--nproc', type=int, default=4, help='(Ignored for now.) Number of processors available to this run. Should restrict -T if < 4.', ) parser.add_argument( '--split-fn', help='Output. JSON list of units of work.') parser.add_argument( '--bash-template-fn', help='Output. Copy of known daligner bash template, for use later.') args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/dazzler.py ================================================ ''' # DAMASKER options """ Example config usage: pa_use_tanmask = true pa_use_repmask = true pa_HPCtanmask_option = pa_repmask_levels = 2 pa_HPCrepmask_1_option = -g1 -c20 -mtan pa_HPCrepmask_2_option = -g10 -c15 -mtan -mrep1 pa_damasker_HPCdaligner_option = -mtan -mrep1 -mrep10 """ pa_use_tanmask = False if config.has_option(section, 'pa_use_tanmask'): pa_use_tanmask = config.getboolean(section, 'pa_use_tanmask') pa_HPCtanmask_option = "" if config.has_option(section, 'pa_HPCtanmask_option'): pa_HPCtanmask_option = config.get(section, 'pa_HPCtanmask_option') pa_use_repmask = False if config.has_option(section, 'pa_use_repmask'): pa_use_repmask = config.getboolean(section, 'pa_use_repmask') pa_repmask_levels = 0 # REPmask tool can be used multiple times. if config.has_option(section, 'pa_repmask_levels'): pa_repmask_levels = config.getint(section, 'pa_repmask_levels') pa_HPCrepmask_1_option = """ -g1 -c20 -mtan""" if config.has_option(section, 'pa_HPCrepmask_1_option'): pa_HPCrepmask_1_option = config.get(section, 'pa_HPCrepmask_1_option') pa_HPCrepmask_2_option = """ -g10 -c15 -mtan -mrep1""" if config.has_option(section, 'pa_HPCrepmask_2_option'): pa_HPCrepmask_2_option = config.get(section, 'pa_HPCrepmask_2_option') pa_damasker_HPCdaligner_option = """ -mtan -mrep1 -mrep10""" # Repeat masks need to be passed to Daligner. if config.has_option(section, 'pa_damasker_HPCdaligner_option'): pa_damasker_HPCdaligner_option = config.get( section, 'pa_damasker_HPCdaligner_option') # End of DAMASKER options. # Note: We dump the 'length_cutoff' file for later reference within the preassembly report # of pbsmrtpipe HGAP. # However, it is not a true dependency because we still have a workflow that starts # from 'corrected reads' (preads), in which case build_db is not run. Catrack -dfv raw_reads.db tan ''' from __future__ import absolute_import import argparse import collections import glob import logging import os import re import sys from ..util.io import yield_validated_fns from .. import io, functional from .. import( bash, # for write_sub_script pype_tasks, # for TASKS ) LOG = logging.getLogger() WAIT = 20 # seconds to wait for file to exist def filter_DBsplit_option(opt): """We want -a by default, but if we see --no-a[ll], we will not add -a. """ flags = opt.split() if '-x' not in opt: flags.append('-x70') # daligner belches on any read < kmer length return ' '.join(flags) def script_build_db(config, input_fofn_fn, db): """ db (e.g. 'raw_reads.db') will be output into CWD, should not already exist. 'dust' track will also be generated. """ params = dict(config) try: cat_fasta = functional.choose_cat_fasta(open(input_fofn_fn).read()) except Exception: LOG.exception('Using "cat" by default.') cat_fasta = 'cat ' DBdust = 'DBdust {} {}'.format(config.get('pa_DBdust_option', ''), db) params.update(locals()) script = """\ echo "PBFALCON_ERRFILE=$PBFALCON_ERRFILE" set -o pipefail rm -f {db}.db .{db}.* # in case of re-run #fc_fasta2fasta < {input_fofn_fn} >| fc.fofn while read fn; do {cat_fasta} $fn | fasta2DB -v {db} -i${{fn##*/}}; done < {input_fofn_fn} #cat fc.fofn | xargs rm -f {DBdust} """.format(**params) return script def script_length_cutoff(config, db, length_cutoff_fn='length_cutoff'): params = dict(config) length_cutoff = config['user_length_cutoff'] if int(length_cutoff) < 0: bash_cutoff = '$(python2.7 -m falcon_kit.mains.calc_cutoff --coverage {} {} <(DBstats -b1 {}))'.format( params['seed_coverage'], params['genome_size'], db) else: bash_cutoff = '{}'.format(length_cutoff) params.update(locals()) return """ CUTOFF={bash_cutoff} echo -n $CUTOFF >| {length_cutoff_fn} """.format(**params) def script_DBsplit(config, db): params = dict(config) params.update(locals()) DBsplit_opt = filter_DBsplit_option(config['DBsplit_opt']) params.update(locals()) return """ DBsplit -f {DBsplit_opt} {db} #LB=$(cat {db}.db | LD_LIBRARY_PATH= awk '$1 == "blocks" {{print $3}}') #echo -n $LB >| db_block_count """.format(**params) def build_db(config, input_fofn_fn, db_fn, length_cutoff_fn): LOG.info('Building rdb from {!r}, to write {!r}'.format( input_fofn_fn, db_fn)) db = os.path.splitext(db_fn)[0] # First, make FOFN relative to thisdir. my_input_fofn_fn = 'my.' + os.path.basename(input_fofn_fn) with open(my_input_fofn_fn, 'w') as stream: for fn in yield_validated_fns(input_fofn_fn): stream.write(fn) stream.write('\n') script = ''.join([ script_build_db(config, my_input_fofn_fn, db), script_length_cutoff(config, db, length_cutoff_fn), script_DBsplit(config, db), ]) script_fn = 'build_db.sh' with open(script_fn, 'w') as ofs: exe = bash.write_sub_script(ofs, script) io.syscall('bash -vex {}'.format(script_fn)) def script_HPC_daligner(config, db, length_cutoff_fn, tracks, prefix='daligner-jobs'): params = dict(config) masks = ' '.join('-m{}'.format(track) for track in tracks) params.update(locals()) symlink(length_cutoff_fn, 'CUTOFF') return """ #LB=$(cat db_block_count) CUTOFF=$(cat CUTOFF) rm -f daligner-jobs.* echo "SMRT_PYTHON_PATH_PREPEND=$SMRT_PYTHON_PATH_PREPEND" echo "PATH=$PATH" which HPC.daligner HPC.daligner -P. {daligner_opt} {masks} -H$CUTOFF -f{prefix} {db} >| run_jobs.sh """.format(**params) def script_HPC_TANmask(db, prefix): assert prefix and '/' not in prefix params = dict() #dict(config) params.update(locals()) return """ rm -f {prefix}.* rm -f .{db}.*.tan.anno rm -f .{db}.*.tan.data echo "SMRT_PYTHON_PATH_PREPEND=$SMRT_PYTHON_PATH_PREPEND" echo "PATH=$PATH" which HPC.TANmask HPC.TANmask -P. -f{prefix} {db} """.format(**params) def symlink(actual, symbolic=None, force=True): """Symlink into cwd, relatively. symbolic name is basename(actual) if not provided. If not force, raise when already exists and does not match. But ignore symlink to self. """ symbolic = os.path.basename(actual) if not symbolic else symbolic if os.path.abspath(actual) == os.path.abspath(symbolic): LOG.warning('Cannot symlink {!r} as {!r}, itself.'.format(actual, symbolic)) return rel = os.path.relpath(actual) if force: LOG.info('ln -sf {} {}'.format(rel, symbolic)) if os.path.lexists(symbolic): if os.readlink(symbolic) == rel: return else: os.unlink(symbolic) else: LOG.info('ln -s {} {}'.format(rel, symbolic)) if os.path.lexists(symbolic): if os.readlink(symbolic) != rel: msg = '{!r} already exists as {!r}, not {!r}'.format( symbolic, os.readlink(symbolic), rel) raise Exception(msg) else: LOG.info('{!r} already points to {!r}'.format(symbolic, rel)) return os.symlink(rel, symbolic) def symlink_db(db_fn): """Symlink everything that could be related to this Dazzler DB. """ db_dirname, db_basename = os.path.split(db_fn) dbname = os.path.splitext(db_basename)[0] fn = os.path.join(db_dirname, dbname + '.db') symlink(fn) possible_suffixes = ( '.idx', '.bps', '.dust.data', '.dust.anno', '.tan.data', '.tan.anno', ) for suffix in possible_suffixes: fn = os.path.join(db_dirname, '.' + dbname + suffix) if os.path.exists(fn): symlink(fn) return dbname def tan_split(config_fn, db_fn, uows_fn, bash_template_fn): with open(bash_template_fn, 'w') as stream: stream.write(pype_tasks.TASK_DB_TAN_APPLY_SCRIPT) # TANmask would put track-files in the DB-directory, not '.', # so we need to symlink everything first. db = symlink_db(db_fn) script = ''.join([ script_HPC_TANmask(db, prefix='tan-jobs'), ]) script_fn = 'split_db.sh' with open(script_fn, 'w') as ofs: exe = bash.write_sub_script(ofs, script) io.syscall('bash -vex {}'.format(script_fn)) # We now have files like tan-jobs.01.OVL # We need to parse that one. (We ignore the others.) lines = open('tan-jobs.01.OVL').readlines() re_block = re.compile(r'{}(\.\d+|)'.format(db)) def get_blocks(line): """Return ['.1', '.2', ...] """ return [mo.group(1) for mo in re_block.finditer(line)] scripts = list() for line in lines: if line.startswith('#'): continue if not line.strip(): continue blocks = get_blocks(line) assert blocks, 'No blocks found in {!r} from {!r}'.format(line, 'tan-jobs.01.OVL') las_files = ' '.join('TAN.{db}{block}.las'.format(db=db, block=block) for block in blocks) script_lines = [ line, 'LAcheck {} {}\n'.format(db, las_files), 'TANmask {} {}\n'.format(db, las_files), 'rm -f {}\n'.format(las_files), ] if len(blocks) == 1: # special case assert blocks == [''], "{!r} != ['']".format(blocks) script_lines.append('mv .{db}.tan.data .{db}.1.tan.data\n'.format(db=db)) script_lines.append('mv .{db}.tan.anno .{db}.1.tan.anno\n'.format(db=db)) scripts.append(''.join(script_lines)) jobs = list() for i, script in enumerate(scripts): job_id = 'tan_{:03d}'.format(i) script_dir = os.path.join('tan-scripts', job_id) script_fn = os.path.join(script_dir, 'run_datander.sh') io.mkdirs(script_dir) with open(script_fn, 'w') as stream: stream.write('{}\n'.format(script)) # Record in a job-dict. job = dict() job['input'] = dict( config=config_fn, db=db_fn, script=os.path.abspath(script_fn), ) job['output'] = dict( job_done = 'job.done' ) job['params'] = dict( ) job['wildcards'] = dict( tan0_id=job_id, ) jobs.append(job) io.serialize(uows_fn, jobs) def tan_apply(db_fn, script_fn, job_done_fn): # datander would put track-files in the DB-directory, not '.', # so we need to symlink everything first. db = symlink_db(db_fn) symlink(script_fn) io.syscall('bash -vex {}'.format(os.path.basename(script_fn))) io.touch(job_done_fn) def tan_combine(db_fn, gathered_fn, new_db_fn): new_db = os.path.splitext(new_db_fn)[0] db = symlink_db(db_fn) assert db == new_db, 'basename({!r})!={!r}, but old and new DB names must match.'.format(db_fn, new_db_fn) # Remove old, in case of resume. io.syscall('rm -f .{db}.*.tan.anno .{db}.*.tan.data'.format(db=db)) gathered = io.deserialize(gathered_fn) gathered_dn = os.path.dirname(gathered_fn) # Create symlinks for all track-files. for job in gathered: done_fn = job['job_done'] done_dn = os.path.dirname(done_fn) if not os.path.isabs(done_dn): LOG.info('Found relative done-file: {!r}'.format(done_fn)) done_dn = os.path.join(gathered_dn, done_dn) annos = glob.glob('{}/.{}.*.tan.anno'.format(done_dn, db)) datas = glob.glob('{}/.{}.*.tan.data'.format(done_dn, db)) assert len(annos) == len(datas), 'Mismatched globs:\n{!r}\n{!r}'.format(annos, datas) for fn in annos + datas: symlink(fn, force=False) cmd = 'Catrack -vdf {} tan'.format(db) io.syscall(cmd) def split_db(config_fn, daligner_uows_fn, db_fn): raise NotImplementedError('Who dey?') def get_tracks(db_fn): db_dirname, db_basename = os.path.split(db_fn) dbname = os.path.splitext(db_basename)[0] fns = glob.glob('{}/.{}.*.anno'.format(db_dirname, dbname)) re_anno = re.compile(r'\.{}\.([^\.]+)\.anno'.format(dbname)) tracks = [re_anno.search(fn).group(1) for fn in fns] return tracks def daligner_split(config, config_fn, db_fn, nproc, wildcards, length_cutoff_fn, split_fn, bash_template_fn): with open(bash_template_fn, 'w') as stream: stream.write(pype_tasks.TASK_DB_DALIGNER_APPLY_SCRIPT) db = os.path.splitext(db_fn)[0] dbname = os.path.basename(db) tracks = get_tracks(db_fn) script = ''.join([ script_HPC_daligner(config, db, length_cutoff_fn, tracks, 'daligner-jobs'), ]) script_fn = 'split_db.sh' with open(script_fn, 'w') as ofs: exe = bash.write_sub_script(ofs, script) io.syscall('bash -vex {}'.format(script_fn)) # We now have files like tan-jobs.01.OVL # We need to parse that one. (We ignore the others.) lines = open('daligner-jobs.01.OVL').readlines() preads_aln = True if dbname == 'preads' else False xformer = functional.get_script_xformer(preads_aln) LOG.debug('preads_aln={!r} (True => use daligner_p)'.format(preads_aln)) scripts = list() for line in lines: if line.startswith('#'): continue if not line.strip(): continue line = xformer(line) # Use daligner_p for preads. scripts.append(line) """ Special case: # Daligner jobs (1) daligner raw_reads raw_reads && mv raw_reads.raw_reads.las raw_reads.las In that case, the "block" name is empty. (See functional.py) We will rename the file. (LAmerge on a single input is a no-op, which is fine.) """ if len(scripts) == 1: script = scripts[0] re_script = re.compile(r'(mv\b.*\S+\s+)(\S+)$') # no trailing newline, for now mo = re_script.search(script) if not mo: msg = 'Only 1 line in daligner-jobs.01.OVL, but {!r} did not match {!r}.'.format( script, re_script.pattern) LOG.warning(msg) else: new_script = re_script.sub(r'\1{dbname}.1.{dbname}.1.las'.format(dbname=dbname), script, 1) msg = 'Only 1 line in daligner-jobs.01.OVL; {!r} matches\n {!r}. Replacing with\n {!r}.'.format( script, re_script.pattern, new_script) LOG.warning(msg) scripts = [new_script] for i, script in enumerate(scripts): LAcheck = 'LAcheck -vS {} *.las'.format(db) script += '\n' + LAcheck + '\n' scripts[i] = script jobs = list() for i, script in enumerate(scripts): job_id = 'j_{:04d}'.format(i) script_dir = os.path.join('daligner-scripts', job_id) script_fn = os.path.join(script_dir, 'run_daligner.sh') io.mkdirs(script_dir) with open(script_fn, 'w') as stream: stream.write(script) # Record in a job-dict. job = dict() job['input'] = dict( config=config_fn, db=db_fn, script=os.path.abspath(script_fn), ) job['output'] = dict( job_done = 'daligner.done' ) job['params'] = dict( ) job['wildcards'] = {wildcards: job_id} jobs.append(job) io.serialize(split_fn, jobs) def daligner_apply(db_fn, script_fn, job_done_fn): symlink(script_fn) io.syscall('bash -vex {}'.format(os.path.basename(script_fn))) io.touch(job_done_fn) class MissingLas(Exception): pass def is_perfect_square(n): import math root = round(math.sqrt(n)) return n == root*root def daligner_combine(db_fn, gathered_fn, las_paths_fn): """Merge all .las pair-files from gathered daligner runs. Write simple las_paths_fn and archaic p_id2las_fn. """ gathered = io.deserialize(gathered_fn) d = os.path.abspath(os.path.realpath(os.path.dirname(gathered_fn))) def abspath(fn): if os.path.isabs(fn): return fn # I expect this never to happen though. return os.path.join(d, fn) job_done_fns = list() for job_output in gathered: for fn in job_output.values(): abs_fn = abspath(fn) job_done_fns.append(abs_fn) #import pprint #LOG.info('job_done_fns: {}'.format(pprint.pformat(job_done_fns))) job_rundirs = sorted(os.path.dirname(fn) for fn in job_done_fns) import time def find_las_paths(): las_paths = list() for uow_dir in job_rundirs: # We could assert the existence of a job_done file here. d = os.path.abspath(uow_dir) las_path_glob = glob.glob(os.path.join(d, '*.las')) LOG.debug('dir={!r}, glob={!r}'.format(d, las_path_glob)) if not las_path_glob: LOG.info('No .las found in {!r}. Sleeping {} seconds before retrying.'.format(d, WAIT)) time.sleep(WAIT) las_path_glob = glob.glob(os.path.join(d, '*.las')) LOG.debug('dir={!r}, glob={!r}'.format(d, las_path_glob)) if not las_path_glob: msg = 'No .las files found in daligner dir {!r}.'.format(d) raise MissingLas(msg) las_paths.extend(las_path_glob) n = len(las_paths) if not is_perfect_square(n): msg = '{} is not a perfect square. We must be missing some .las files.'.format(n) raise MissingLas(msg) return las_paths try: las_paths = sorted(find_las_paths(), key=lambda fn: os.path.basename(fn)) except MissingLas: LOG.info('Not enough .las found from {!r}. Sleeping {} seconds before retrying.'.format(gathered_fn, WAIT)) time.sleep(WAIT) las_paths = find_las_paths() io.serialize(las_paths_fn, las_paths) def merge_split(config_fn, dbname, las_paths_fn, split_fn, bash_template_fn): with open(bash_template_fn, 'w') as stream: stream.write(pype_tasks.TASK_DB_LAMERGE_APPLY_SCRIPT) las_paths = io.deserialize(las_paths_fn) re_las_pair = re.compile(r'{db}\.(\d+)\.{db}\.(\d+)\.las$'.format(db=dbname)) las_map = collections.defaultdict(list) for path in las_paths: mo = re_las_pair.search(path) if not mo: msg = '{!r} does not match regex {!r}'.format( path, re_las_pair.pattern) raise Exception(msg) a, b = int(mo.group(1)), int(mo.group(2)) las_map[a].append(path) jobs = list() for i, block in enumerate(las_map): job_id = 'm_{:05d}'.format(i) # Write the las files for this job. input_dir = os.path.join('merge-scripts', job_id) las_paths_fn = os.path.join('.', input_dir, 'las-paths.json') io.mkdirs(input_dir) las_paths = las_map[block] io.serialize(las_paths_fn, las_paths) # Record in a job-dict. las_fn = '{}.{}.las'.format(dbname, block) job = dict() job['input'] = dict( config=config_fn, #db=db_fn, #script=os.path.abspath(script_fn), las_paths=las_paths_fn, ) job['output'] = dict( #job_done = 'daligner.done' las_fn=las_fn ) job['params'] = dict( ) job['wildcards'] = dict( mer0_id=job_id, ) jobs.append(job) io.serialize(split_fn, jobs) def ichunked(seq, chunksize): """Yields items from an iterator in iterable chunks. https://stackoverflow.com/a/1335572 """ from itertools import chain, islice it = iter(seq) while True: yield chain([it.next()], islice(it, chunksize-1)) def merge_apply(las_paths_fn, las_fn): """Merge the las files into one, a few at a time. This replaces the logic of HPC.daligner. """ io.rm_force(las_fn) #all_las_paths = rel_to(io.deserialize(las_paths_fn), os.path.dirname(las_paths_fn)) all_las_paths = io.deserialize(las_paths_fn) # Create symlinks, so system calls will be shorter. all_syms = list() for fn in all_las_paths: symlink(fn) all_syms.append(os.path.basename(fn)) curr_paths = sorted(all_syms) # Merge a few at-a-time. at_a_time = 250 # max is 252 for LAmerge level = 1 while len(curr_paths) > 1: level += 1 next_paths = list() for i, paths in enumerate(ichunked(curr_paths, at_a_time)): tmp_las = 'L{}.{}.las'.format(level, i+1) paths_arg = ' '.join(paths) cmd = 'LAmerge -v {} {}'.format(tmp_las, paths_arg) io.syscall(cmd) next_paths.append(tmp_las) curr_paths = next_paths io.syscall('mv -f {} {}'.format(curr_paths[0], 'keep-this')) io.syscall('#rm -f *.las') io.syscall('mv -f {} {}'.format('keep-this', las_fn)) def merge_combine(gathered_fn, las_paths_fn, block2las_fn): gathered = io.deserialize(gathered_fn) d = os.path.abspath(os.path.realpath(os.path.dirname(gathered_fn))) def abspath(fn): if os.path.isabs(fn): return fn # I expect this never to happen though. return os.path.join(d, fn) las_fns = list() for job_output in gathered: assert len(job_output) == 1, 'len(job_output) == {} != 1'.format(len(job_output)) for fn in job_output.values(): abs_fn = abspath(fn) las_fns.append(abs_fn) #import pprint #LOG.info('job_done_fns: {}'.format(pprint.pformat(job_done_fns))) import time #job_rundirs = sorted(os.path.dirname(fn) for fn in job_done_fns) #las_paths = list() #for uow_dir in job_rundirs: # # We could assert the existence of a job_done file here. # d = os.path.abspath(uow_dir) # las_path_glob = glob.glob(os.path.join(d, '*.las')) # LOG.debug('dir={!r}, glob={!r}'.format(d, las_path_glob)) # if not las_path_glob: # time.sleep(WAIT) # las_path_glob = glob.glob(os.path.join(d, '*.las')) # LOG.debug('dir={!r}, glob={!r}'.format(d, las_path_glob)) # if not las_path_glob: # msg = 'Missing .las file. Skipping block for dir {}'.format(d) # LOG.error(msg) # if len(las_path_glob) > 1: # msg = 'Expected exactly 1 .las in {!r}, but found {}:\n {!r}'.format( # d, len(las_path_glob), las_path_glob) # LOG.warning(mgs) # las_paths.extend(las_path_glob) las_paths = list() for las_fn in sorted(las_fns): if not os.path.exists(las_fn): msg = 'Did not find las-file {!r}. Waiting {} seconds.'.format(las_fn, WAIT) LOG.info(las_fn) time.sleep(WAIT) if not os.path.exists(las_fn): msg = 'Did not find las-file {!r}, even after waiting {} seconds. Maybe retry later?'.format(las_fn, WAIT) raise Exception(msg) #LOG.warning(las_fn) #continue las_paths.append(las_fn) # Map block nums to .las files. re_block = re.compile(r'\.(\d+)\.las$') block2las = dict() for fn in las_paths: mo = re_block.search(fn) if not mo: msg = 'Las file {!r} did not match regex {!r}.'.format( fn, re_block.pattern) raise Exception(msg) block = int(mo.group(1)) block2las[block] = fn # Verify sequential block nums. blocks = sorted(block2las.keys()) expected = list(range(1, len(blocks)+1)) if blocks != expected: msg = '{!r} has {} .las files, but their block-numbers are not sequential: {!r}'.format( gathered_fn, len(blocks), blocks) raise Exception(msg) # Serialize result, plus an archaric file. io.serialize(las_paths_fn, sorted(block2las.values())) io.serialize(block2las_fn, block2las) def setup_logging(log_level): hdlr = logging.StreamHandler(sys.stderr) hdlr.setLevel(log_level) hdlr.setFormatter(logging.Formatter('[%(levelname)s]%(message)s')) LOG.addHandler(hdlr) LOG.setLevel(logging.NOTSET) LOG.info('Log-level: {}'.format(log_level)) def cmd_build(args): ours = get_ours(args.config_fn, args.db_fn) build_db(ours, args.input_fofn_fn, args.db_fn, args.length_cutoff_fn) def cmd_tan_split(args): tan_split(args.config_fn, args.db_fn, args.split_fn, args.bash_template_fn) def cmd_tan_apply(args): tan_apply(args.db_fn, args.script_fn, args.job_done_fn) def cmd_tan_combine(args): tan_combine(args.db_fn, args.gathered_fn, args.new_db_fn) def cmd_daligner_split(args): ours = get_ours(args.config_fn, args.db_fn) daligner_split(ours, args.config_fn, args.db_fn, args.nproc, args.wildcards, args.length_cutoff_fn, args.split_fn, args.bash_template_fn) def cmd_daligner_apply(args): daligner_apply(args.db_fn, args.script_fn, args.job_done_fn) def cmd_daligner_combine(args): daligner_combine(args.db_fn, args.gathered_fn, args.las_paths_fn) def cmd_merge_split(args): merge_split(args.config_fn, args.db_prefix, args.las_paths_fn, args.split_fn, args.bash_template_fn) def cmd_merge_apply(args): merge_apply(args.las_paths_fn, args.las_fn) def cmd_merge_combine(args): merge_combine(args.gathered_fn, args.las_paths_fn, args.block2las_fn) options_note = """ For raw_reads.db, we also look for the following config keys: - pa_DBsplit_option - pa_HPCdaligner_option - length_cutoff: -1 => calculate based on "genome_size" and "seed_coverage" config. - seed_coverage - genome_size For preads.db, these are named: - ovlp_DBsplit_option - ovlp_HPCdaligner_option - length_cutoff_pr """ def get_ours(config_fn, db_fn): ours = dict() config = io.deserialize(config_fn) ours['genome_size'] = int(config['genome_size']) ours['seed_coverage'] = float(config['seed_coverage']) if os.path.basename(db_fn).startswith('preads'): ours['DBsplit_opt'] = config.get('ovlp_DBsplit_option', '') ours['daligner_opt'] = config.get('ovlp_HPCdaligner_option', '') ours['user_length_cutoff'] = int(config.get('length_cutoff_pr', '0')) else: ours['DBsplit_opt'] = config.get('pa_DBsplit_option', '') ours['daligner_opt'] = config.get('pa_HPCdaligner_option', '') ours['user_length_cutoff'] = int(config.get('length_cutoff', '0')) # TODO: TEMP -- Delete asserts! assert ours['DBsplit_opt'] assert ours['daligner_opt'] assert ours['user_length_cutoff'] LOG.info('config({!r}):\n{}'.format(config_fn, config)) LOG.info('our subset of config:\n{}'.format(ours)) return ours def add_build_arguments(parser): parser.add_argument( '--input-fofn-fn', required=True, help='input. User-provided file of fasta filename. Relative paths are relative to directory of FOFN.', ) parser.add_argument( '--length-cutoff-fn', required=True, help='output. Simple file of a single integer, either calculated or specified by --user-length-cutoff.' ) def add_tan_split_arguments(parser): parser.add_argument( '--split-fn', default='tan-mask-uows.json', help='output. Units-of-work from TANmask, for datander.', ) parser.add_argument( '--bash-template-fn', default='bash-template.sh', help='output. Script to apply later.', ) def add_tan_apply_arguments(parser): parser.add_argument( '--script-fn', required=True, help='input. Script to run datander.', ) parser.add_argument( '--job-done-fn', default='job.done', help='output. Sentinel.', ) def add_tan_combine_arguments(parser): parser.add_argument( '--gathered-fn', required=True, help='input. List of sentinels. Produced by gen_parallel_tasks() gathering. The tan-track files are next to these.', ) parser.add_argument( '--new-db-fn', required=True, help='output. This must match the input DB name. It will be symlinked, except the new track files.', ) def add_daligner_split_arguments(parser): parser.add_argument( '--wildcards', default='dummy_wildcard', help='Comma-separated string of keys to be subtituted into output paths for each job, if any. (Helps with snakemake and pypeflow; not needed in pbsmrtpipe, since outputs are pre-determined.)', ) parser.add_argument( '--length-cutoff-fn', required=True, help='input. Simple file of a single integer, either calculated or specified by --user-length-cutoff.' ) parser.add_argument( '--split-fn', default='daligner-mask-uows.json', help='output. Units-of-work from TANmask, for dadalignerder.', ) parser.add_argument( '--bash-template-fn', default='bash-template.sh', help='output. Script to apply later.', ) def add_daligner_apply_arguments(parser): parser.add_argument( '--script-fn', required=True, help='input. Script to run dadalignerder.', ) parser.add_argument( '--job-done-fn', default='job.done', help='output. Sentinel.', ) def add_daligner_combine_arguments(parser): parser.add_argument( '--gathered-fn', required=True, help='input. List of sentinels. Produced by gen_parallel_tasks() gathering. The .las files are next to these.', ) parser.add_argument( '--las-paths-fn', required=True, help='output. JSON list of las paths.') def add_merge_split_arguments(parser): parser.add_argument( '--db-prefix', required=True, help='DB is named "prefix.db", and the prefix is expected to match .las files', ) parser.add_argument( '--las-paths-fn', help='input. foo.a.foo.b.las files from daligner.', ) parser.add_argument( '--split-fn', default='merge-mask-uows.json', help='output. Units-of-work from TANmask, for damergeder.', ) parser.add_argument( '--bash-template-fn', default='bash-template.sh', help='output. Script to apply later.', ) def add_merge_apply_arguments(parser): parser.add_argument( '--las-paths-fn', required=True, help='input. JSON list of las paths to merge. These must be .las "pairs" (foo.a.foo.b.las). The a-blocks must all be the same. Ultimately, we will generate a single .las from these, named after the a-block.') parser.add_argument( '--las-fn', required=True, help='output. The merged las-file.', ) def add_merge_combine_arguments(parser): parser.add_argument( '--gathered-fn', required=True, help='input. List of sentinels. Produced by gen_parallel_tasks() gathering. The .las files are next to these.', ) parser.add_argument( '--las-paths-fn', required=True, help='output. JSON list of las paths.') parser.add_argument( '--block2las-fn', required=True, help='output. JSON dict of block (int) to las.') def add_split_arguments(parser): parser.add_argument( '--run-jobs-fn', help='Output. Produced by HPC.daligner.', ) parser.add_argument( '--rep-mask-uows-fn', default='rep-mask-uows.json', help='output. Units-of-work for REPmask.', ) parser.add_argument( '--daligner-uows-fn', default='daligner-uows.json', help='output. Units-of-work for daligner.', ) parser.add_argument( '--las-merge-uows-fn', default='las-merge-uows.json', help='output. Units-of-work for LAmerge.', ) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Basic daligner steps: build; split into units-of-work; combine results and prepare for next step.' epilog = 'These tasks perform the split/apply/combine strategy (of which map/reduce is a special case).' + options_note parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--log-level', default='INFO', help='Python logging level.', ) parser.add_argument( '--nproc', type=int, default=0, help='ignored for now, but non-zero will mean "No more than this."', ) parser.add_argument( '--config-fn', required=True, help='Input. JSON of user-configuration. (This is probably the [General] section.)', ) parser.add_argument( '--db-fn', default='raw_reads.db', help='Input or Output. Dazzler DB. (Dot-files are implicit.)', ) help_build = 'build Dazzler DB for raw_reads; calculate length-cutoff for HGAP seed reads; split Dazzler DB into blocks; run DBdust to mask low-complexity regions' help_tan_split = 'generate units-of-work for datander, via HPC.TANmask' help_tan_apply = 'run datander and TANmask as a unit-of-work (according to output of HPC.TANmask), and remove .las files' help_tan_combine = 'run Catrack on partial track-files, to produce a "tan" mask' help_daligner_split = 'generate units-of-work for daligner, via HPC.daligner' help_daligner_apply = 'run daligner as a unit-of-work (according to output of HPC.TANmask)' help_daligner_combine = 'generate a file of .las files, plus units-of-work for LAmerge (alias for merge-split)' help_merge_split = 'generate a file of .las files, plus units-of-work for LAmerge (alias for daligner-combine)' help_merge_apply = 'run merge as a unit-of-work, and (possibly) remove .las files' help_merge_combine = 'generate a file of .las files' subparsers = parser.add_subparsers(help='sub-command help') parser_build = subparsers.add_parser('build', formatter_class=HelpF, description=help_build, help=help_build) add_build_arguments(parser_build) parser_build.set_defaults(func=cmd_build) parser_tan_split = subparsers.add_parser('tan-split', formatter_class=HelpF, description=help_tan_split, epilog='', help=help_tan_split) add_tan_split_arguments(parser_tan_split) parser_tan_split.set_defaults(func=cmd_tan_split) parser_tan_apply = subparsers.add_parser('tan-apply', formatter_class=HelpF, description=help_tan_apply, epilog='', help=help_tan_apply) add_tan_apply_arguments(parser_tan_apply) parser_tan_apply.set_defaults(func=cmd_tan_apply) parser_tan_combine = subparsers.add_parser('tan-combine', formatter_class=HelpF, description=help_tan_combine, epilog='The result will be mostly symlinks, plus new tan-track files. To use these as a mask, subsequent steps will need to add "-mtan".', help=help_tan_combine) add_tan_combine_arguments(parser_tan_combine) parser_tan_combine.set_defaults(func=cmd_tan_combine) parser_daligner_split = subparsers.add_parser('daligner-split', formatter_class=HelpF, description=help_daligner_split, epilog='HPC.daligner will be passed mask flags for any mask tracks which we glob. Note: if db is named "preads.db", we run daligner_p instead of daligner.', help=help_daligner_split) add_daligner_split_arguments(parser_daligner_split) parser_daligner_split.set_defaults(func=cmd_daligner_split) parser_daligner_apply = subparsers.add_parser('daligner-apply', formatter_class=HelpF, description=help_daligner_apply, epilog='', help=help_daligner_apply) add_daligner_apply_arguments(parser_daligner_apply) parser_daligner_apply.set_defaults(func=cmd_daligner_apply) parser_daligner_combine = subparsers.add_parser('daligner-combine', formatter_class=HelpF, description=help_daligner_combine, epilog='', help=help_daligner_combine) add_daligner_combine_arguments(parser_daligner_combine) parser_daligner_combine.set_defaults(func=cmd_daligner_combine) parser_merge_split = subparsers.add_parser('merge-split', formatter_class=HelpF, description=help_merge_split, epilog='HPC.merge will be passed mask flags for any mask tracks which we glob.', help=help_merge_split) add_merge_split_arguments(parser_merge_split) parser_merge_split.set_defaults(func=cmd_merge_split) parser_merge_apply = subparsers.add_parser('merge-apply', formatter_class=HelpF, description=help_merge_apply, epilog='Ultimately, there will be 1 .las per block.', help=help_merge_apply) add_merge_apply_arguments(parser_merge_apply) parser_merge_apply.set_defaults(func=cmd_merge_apply) parser_merge_combine = subparsers.add_parser('merge-combine', formatter_class=HelpF, description=help_merge_combine, epilog='', help=help_merge_combine) add_merge_combine_arguments(parser_merge_combine) parser_merge_combine.set_defaults(func=cmd_merge_combine) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) setup_logging(args.log_level) args.func(args) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/dedup_a_tigs.py ================================================ from __future__ import absolute_import from __future__ import print_function from falcon_kit.FastaReader import open_fasta_reader import argparse import sys def parse_args(argv): parser = argparse.ArgumentParser(description='Removes duplicate a-tig, iff *all* conditions are violated. Assumes the working directory has the a_ctg_all.fa file, and produces a_ctg.fa', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--max_idt', type=int, help="keep a-tig if the identity (in %) to the primary contig is <= max_idt", default=96) parser.add_argument('--max_aln_cov', type=int, help="keep a-tig if the alignment coverage (in %) on the a-tig is <= max_aln_cov", default=97) parser.add_argument('--min_len_diff', type=int, help="keep a-tig if the length different > min_len_diff", default=500) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) with open_fasta_reader("a_ctg_all.fa") as reads: with open("a_ctg.fa", "w") as f: for r in reads: tig_id, v, w, len_, ovl, ne, delta_l, idt, cov = r.name.split() if 100 * float(idt) > args.max_idt and 100 * float(cov) > args.max_aln_cov and\ abs(int(delta_l)) < args.min_len_diff: continue print(">" + r.name, file=f) print(r.sequence, file=f) if __name__ == "__main__": main(sys.argv) ================================================ FILE: falcon_kit/mains/fasta2fasta.py ================================================ #!/usr/bin/env python2.7 """A pre-processor for DAZZ_DB/fasta2DB. Since fasta2DB has several constraints (a single movie per fasta, limited line-width, actual filenames), we write intermediate fasta files to disk. To reduce disk I/O, we can also compress them. Currently, we ignore zmw numbers and instead use a global counter. Inputs may be compressed, and may be either fasta or fastq. (For now, we ignore QVs.) """ from __future__ import absolute_import from future.utils import itervalues from builtins import object from ..util.system import abs_fns import argparse import glob import gzip import logging import os import re import sys log = logging.getLogger() DNA_BASES = ['A', 'C', 'G', 'T'] COMPLEMENT = { 'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A', } def complement(x): return (COMPLEMENT[base] for base in x) zmw_counter = None def WriteSplit(write, seq, split=8000): i = 0 while i < len(seq): slice = seq[i:i + split] write(slice) write('\n') i += split def parse_header(header, zmw_counter=None): """ >>> parse_header('>mine foo bar', 1) ('mine', 1, 'foo bar', 2) >>> parse_header('>mine/123/5_75 foo bar') ('mine', 123, '5_75 foo bar', None) For now, ignore the zmw and instead use a global counter. """ if '/' in header: parts = header[1:].split('/') else: parts = header[1:].split(None, 1) movie = parts[0] if zmw_counter is None: zmw = int(parts[1]) else: zmw = zmw_counter zmw_counter += 1 if len(parts) > 1: extra = parts[-1] else: extra = '' return movie, zmw, extra, zmw_counter re_range = re.compile('^(\d+)_(\d+)\s*(.*)$') def process_fasta(ifs, movie2write): header = ifs.readline().strip() if header[0] != '>': raise Exception('{!r} is not a fasta file.'.format(ifs.name)) while header: global zmw_counter movie, zmw, extra, zmw_counter = parse_header(header, zmw_counter) write = movie2write[movie] # log.info('header={!r}'.format(header)) seq = '' line = ifs.readline().strip() while line and not line.startswith('>'): seq += line.strip() line = ifs.readline().strip() length = len(seq) #log.info('seq:{!r}...({})'.format(seq[:5], length)) beg, end = 0, length mo = re_range.search(extra) if mo: beg, end, extra = mo.groups() beg = int(beg) end = int(end) if (end - beg) != length: end = beg + length # Probably never happens tho. if extra: extra = ' ' + extra new_header = '>{movie}/{zmw}/{beg}_{end}{extra}\n'.format(**locals()) write(new_header) WriteSplit(write, seq) header = line def process_fastq(ifs, movie2write): header = ifs.readline().strip() if header[0] != '@': raise Exception('{!r} is not a fastq file.'.format(ifs.name)) while header: global zmw_counter movie, zmw, extra, zmw_counter = parse_header(header, zmw_counter) write = movie2write[movie] # log.info('header={!r}'.format(header)) seq = ifs.readline().strip() header2 = ifs.readline().strip() quals = ifs.readline().strip() length = len(seq) #log.info('seq:{!r}...({})'.format(seq[:5], length)) new_header = '>{movie}/{zmw}/0_{length} {extra}\n'.format(**locals()) write(new_header) WriteSplit(write, seq) header = ifs.readline().strip() def process_try_both(ifs, movie2write): try: process_fasta(ifs, movie2write) except Exception: log.exception('bad fasta: {!r}; trying as fastq...'.format(ifs.name)) process_fastq(ifs, movie2write) def process(ifn, movie2write): root, ext = os.path.splitext(ifn) if ifn.endswith('.gz'): Open = gzip.GzipFile ext = os.path.splitext(root)[1] elif ifn.endswith('.bz2'): import bz2 Open = bz2.BZ2File ext = os.path.splitext(root)[1] else: Open = open log.info('ext={!r}'.format(ext)) if ext in ('.fasta', '.fa'): func = process_fasta elif ext in ('.fastq', '.fq'): func = process_fastq else: func = process_try_both with Open(ifn) as ifs: func(ifs, movie2write) class WriterMap(object): def basenames(self): return list(self.__obn2movie.keys()) def close(self): for ofs in itervalues(self.__movie2ofs): ofs.close() def __getitem__(self, movie): """Get or create a 'write' function. """ ofs = self.__movie2ofs.get(movie) if ofs is None: obn = self.__basename(movie) self.__obn2movie[obn] = movie if os.path.exists(obn): log.info('Over-writing {!r}'.format(obn)) else: log.info('Creating {!r}'.format(obn)) ofs = self.__open(obn, mode='w') self.__movie2ofs[movie] = ofs return ofs.write def __init__(self, Basename, Open): self.__obn2movie = dict() self.__movie2ofs = dict() self.__basename = Basename self.__open = Open def get_writer(Gzip=False): if Gzip: def Basename(movie): return movie + '.fasta.gz' import functools Open = functools.partial(gzip.GzipFile, compresslevel=1) # A little better, a little slower: #import bz2 #Open = bz2.BZ2File #Basename = lambda movie: movie + '.fasta.bz2' else: def Basename(movie): return movie + '.fasta' Open = open movie2write = WriterMap(Basename, Open) return movie2write def fixall(ifns, Gzip=False): """Given an iterator of input absolute filenames (fasta or fastq), return a list of output basenames of resulting .fasta(.gz) files, relative to CWD. """ if Gzip: open = gzip.GzipFile movie2write = get_writer(Gzip) for ifn in ifns: process(ifn, movie2write) movie2write.close() return movie2write.basenames() def main(): parser = argparse.ArgumentParser() parser.add_argument('--gzip', action='store_true', help='Compress intermediate fasta with gzip. (Not currently implemented.)') parser.add_argument('--zmw-start', type=int, help='Ignore the zmw number in the fasta header. Instead, use a global counter, starting at this numer.') # parser.add_argument('--clean', # action='store_true', # help='Remove intermediate fasta when done.') # parser.add_argument('--fofn', # help='Dump intermediate FOFN. This can be used directly by "fasta2DB foo -ffofn" if fasta are uncompressed.') # parser.add_argument('--fasta2DB', # help='Pass these arguments along to fasta2DB. These should exclude fasta inputs.') #global ARGS ARGS = parser.parse_args() global zmw_counter zmw_counter = ARGS.zmw_start for obn in fixall(abs_fns(sys.stdin, os.getcwd()), Gzip=ARGS.gzip): sys.stdout.write('{}\n'.format(os.path.abspath(obn))) if __name__ == "__main__": logging.basicConfig() log.setLevel(logging.DEBUG) main() ================================================ FILE: falcon_kit/mains/fetch_reads.py ================================================ from __future__ import absolute_import from __future__ import print_function from __future__ import division from falcon_kit.FastaReader import open_fasta_reader import argparse import contextlib import os import glob import sys import re def fetch_ref_and_reads(base_dir, fofn, ctg_id, out_dir, min_ctg_lenth): read_fofn = fofn if out_dir == None: out_dir = os.path.join(base_dir, '3-unzip/reads') ctg_fa = os.path.join(base_dir, '2-asm-falcon/p_ctg.fa') read_map_dir = os.path.join(base_dir, '2-asm-falcon/read_maps') rawread_id_file = os.path.join( read_map_dir, 'dump_rawread_ids', 'rawread_ids') pread_id_file = os.path.join(read_map_dir, 'dump_pread_ids', 'pread_ids') rid_to_oid = open(rawread_id_file).read().split( '\n') # daligner raw read id to the original ids pid_to_fid = open(pread_id_file).read().split( '\n') # daligner pread id to the fake ids assert rid_to_oid, 'Empty rid_to_oid. Maybe empty {!r}?'.format( rawread_id_file) assert pid_to_fid, 'Empty pid_to_fid. Maybe empty {!r}?'.format( pread_id_file) def pid_to_oid(pid): fid = pid_to_fid[int(pid)] rid = int(fid.split('/')[1]) // 10 return rid_to_oid[int(rid)] with open_fasta_reader(ctg_fa) as ref_fasta: all_ctg_ids = set() for s in ref_fasta: s_id = s.name.split()[0] if ctg_id != 'all' and s_id != ctg_id: continue if len(s.sequence) < min_ctg_lenth: continue if ctg_id != 'all': ref_out = open(os.path.join( out_dir, '%s_ref.fa' % ctg_id), 'w') else: ref_out = open(os.path.join(out_dir, '%s_ref.fa' % s_id), 'w') print('>%s' % s_id, file=ref_out) print(s.sequence, file=ref_out) all_ctg_ids.add(s_id) ref_out.close() read_set = {} ctg_id_hits = {} map_fn = os.path.join(read_map_dir, 'rawread_to_contigs') with open(map_fn, 'r') as f: for row in f: row = row.strip().split() hit_ctg = row[1] hit_ctg = hit_ctg.split('-')[0] if int(row[3]) == 0: o_id = rid_to_oid[int(row[0])] read_set[o_id] = hit_ctg ctg_id_hits[hit_ctg] = ctg_id_hits.get(hit_ctg, 0) + 1 assert read_set, 'Empty read_set. Maybe empty {!r}?'.format(map_fn) map_fn = os.path.join(read_map_dir, 'pread_to_contigs') with open(map_fn, 'r') as f: for row in f: row = row.strip().split() hit_ctg = row[1] hit_ctg = hit_ctg.split('-')[0] if hit_ctg not in read_set and int(row[3]) == 0: o_id = pid_to_oid(row[0]) read_set[o_id] = hit_ctg ctg_id_hits[hit_ctg] = ctg_id_hits.get(hit_ctg, 0) + 1 with open(os.path.join(out_dir, 'ctg_list'), 'w') as f: for ctg_id in sorted(list(all_ctg_ids)): if ctg_id_hits.get(ctg_id, 0) < 5: continue # ignore small circle contigs, they need different approach if ctg_id[-1] not in ['F', 'R']: continue print(ctg_id, file=f) read_out_files = {} @contextlib.contextmanager def reopened_fasta_out(ctg_id): # A convenient closure, with a contextmanager. if ctg_id not in read_out_files: read_out = open(os.path.join(out_dir, '%s_reads.fa' % ctg_id), 'w') read_out_files[ctg_id] = 1 else: read_out = open(os.path.join(out_dir, '%s_reads.fa' % ctg_id), 'a') yield read_out read_out.close() with open(read_fofn, 'r') as f: for r_fn in f: r_fn = r_fn.strip() # will soon handle .dexta too with open_fasta_reader(r_fn) as read_fa_file: for r in read_fa_file: rid = r.name.split()[0] if rid not in read_set: ctg_id = 'unassigned' else: ctg_id = read_set[rid] if ctg_id == 'NA' or ctg_id not in all_ctg_ids: ctg_id = 'unassigned' with reopened_fasta_out(ctg_id) as read_out: print('>' + rid, file=read_out) print(r.sequence, file=read_out) def parse_args(argv): parser = argparse.ArgumentParser( description='using the read to contig mapping data to partition the reads grouped by contigs') parser.add_argument('--base_dir', type=str, default='./', help='the base working dir of a falcon assembly') parser.add_argument('--fofn', type=str, default='./input.fofn', help='path to the file of the list of raw read fasta files') parser.add_argument('--ctg_id', type=str, default='all', help='contig identifier in the contig fasta file') parser.add_argument('--out_dir', default=None, type=str, help='the output base_dir, default to `base_dir/3-unzip/reads` directory') parser.add_argument('--min_ctg_lenth', default=20000, type=int, help='the minimum length of the contig for the outputs, default=20000') #parser.add_argument('--ctg_fa', type=str, default='./2-asm-falcon/p_ctg.fa', help='path to the contig fasta file') #parser.add_argument('--read_map_dir', type=str, default='./2-asm-falcon/read_maps', help='path to the read-contig map directory') # we can run this in parallel mode in the furture # parser.add_argument('--n_core', type=int, default=4, # help='number of processes used for generating consensus') args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) fetch_ref_and_reads(**vars(args)) if __name__ == '__main__': main() ================================================ FILE: falcon_kit/mains/gen_gfa_v1.py ================================================ import argparse import os import sys from falcon_kit.fc_asm_graph import AsmGraph from falcon_kit.FastaReader import FastaReader from falcon_kit.gfa_graph import * def run(fp_out, collected_gfa): with open(collected_gfa, 'r') as fp_in: gfa_graph = deserialize_gfa(fp_in) gfa_graph.write_gfa_v1(fp_out) def parse_args(argv): parser = argparse.ArgumentParser(description="Generates GFA output (on stdout) from FALCON's assembly.", formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('collected_gfa', type=str, default='asm.gfa.json', help='Path to the file with collected and formatted data for generating the GFA') args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) run(sys.stdout, **vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/gen_gfa_v2.py ================================================ import argparse import os import sys from falcon_kit.fc_asm_graph import AsmGraph from falcon_kit.FastaReader import FastaReader from falcon_kit.gfa_graph import * def run(fp_out, collected_gfa): with open(collected_gfa, 'r') as fp_in: gfa_graph = deserialize_gfa(fp_in) gfa_graph.write_gfa_v2(fp_out) def parse_args(argv): parser = argparse.ArgumentParser(description="Generates GFA output (on stdout) from FALCON's assembly.", formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('collected_gfa', type=str, default='asm.gfa.json', help='Path to the file with collected and formatted data for generating the GFA') args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) run(sys.stdout, **vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/generate_read_to_ctg_map.py ================================================ from __future__ import absolute_import from __future__ import print_function from __future__ import division import argparse import logging import sys from ..util import io from ..fc_asm_graph import AsmGraph def run(rawread_id_fn, pread_id_fn, sg_edges_list_fn, utg_data_fn, ctg_paths_fn, output_fn): read_to_contig_map = output_fn pread_did_to_rid = open(pread_id_fn).read().split('\n') rid_to_oid = open(rawread_id_fn).read().split('\n') asm_G = AsmGraph(sg_edges_list_fn, utg_data_fn, ctg_paths_fn) pread_to_contigs = {} with open(read_to_contig_map, 'w') as f: for ctg in asm_G.ctg_data: if ctg[-1] == 'R': continue ctg_g = asm_G.get_sg_for_ctg(ctg) for n in ctg_g.nodes(): pid = int(n.split(':')[0]) rid = pread_did_to_rid[pid].split('/')[1] rid = int(int(rid) // 10) oid = rid_to_oid[rid] k = (pid, rid, oid) pread_to_contigs.setdefault(k, set()) pread_to_contigs[k].add(ctg) for k in pread_to_contigs: pid, rid, oid = k for ctg in list(pread_to_contigs[k]): print('%09d %09d %s %s' % (pid, rid, oid, ctg), file=f) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Generate read_to_ctg_map from rawread_id file and pread_id file' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--rawread-id-fn', required=True, help='From TASK_DUMP_RAWREAD_IDS_SCRIPT', ) parser.add_argument( '--pread-id-fn', required=True, help='From TASK_DUMP_PREAD_IDS_SCRIPT', ) parser.add_argument( '--sg-edges-list-fn', required=True, help='From Falcon stage 2-asm-falcon', ) parser.add_argument( '--utg-data-fn', required=True, help='From Falcon stage 2-asm-falcon', ) parser.add_argument( '--ctg-paths-fn', required=True, help='From Falcon stage 2-asm-falcon', ) parser.add_argument( '--output-fn', required=True, help='read-to-ctg-map', ) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/generic_gather.py ================================================ from __future__ import absolute_import import argparse import logging import os import sys from .. import io LOG = logging.getLogger() def run(gathered_fn, scattered_fn): thatdir = os.path.dirname(scattered_fn) thisdir = os.path.dirname(gathered_fn) scattered = io.deserialize(scattered_fn) gathered = dict() for job in scattered: job_output = dict() #job_output['wildcards'] = dict() fn_dict = dict(job['output']) for key in list(fn_dict.keys()): # Fix path to be relative to gathered_fn. fn = fn_dict[key] if not os.path.isabs(fn): thatfn = os.path.join(thatdir, fn) else: thatfn = fn thisfn = os.path.relpath(thatfn, thisdir) fn_dict[key] = thisfn job_output['fns'] = fn_dict wildcards = job['wildcards'] wildkey = ','.join('{}={}'.format(k,v) for k,v in sorted(wildcards.items())) gathered[wildkey] = job_output io.serialize(gathered_fn, gathered) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Gather generic filenames into ... something. For now, just serialize.' epilog = 'We expect the scattered file to have a specific format.' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--scattered-fn', help='Input: result of scattering', ) parser.add_argument( '--gathered-fn', help='Output: serialized something-or-other', ) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/generic_run_units_of_work.py ================================================ from __future__ import absolute_import import argparse import collections import glob import logging import os import sys import pypeflow.do_task from .. import io LOG = logging.getLogger() # Here is some stuff basically copied from pypeflow.sample_tasks.py. def validate(bash_template, inputs, outputs, parameterss): LOG.info('bash_script_from_template({}\n\tinputs={!r},\n\toutputs={!r})'.format( bash_template, inputs, outputs)) def validate_dict(mydict): "Python identifiers are illegal as keys." try: collections.namedtuple('validate', mydict.keys()) except ValueError as exc: LOG.exception('Bad key name in task definition dict {!r}'.format(mydict)) raise validate_dict(inputs) validate_dict(outputs) validate_dict(parameterss) def update_values_rel_to(things, dn): for key, val in things.items(): try: if not os.path.isabs(val): things[key] = os.path.normpath(os.path.join(dn, val)) except Exception: # Probably just not a string. But could be str, unicode, ... pass def run(bash_template_fn, units_of_work_fn, nproc, results_fn): uows = io.deserialize(units_of_work_fn) uow_dirs = list() results = list() for i, uow in enumerate(uows): job = uow inputs = job['input'] update_values_rel_to(inputs, os.path.normpath(os.path.dirname(units_of_work_fn))) outputs = job['output'] # assumed to be relative to run-dir params = dict(job['params']) params['pypeflow_nproc'] = nproc # We could also verify that any nproc from a splitter (which was a hint for splitting) # matches pypeflow_nproc. #params.update({k: v for (k, v) in viewitems(job['wildcards'])}) # include expanded wildcards LOG.info('INPUT:{}'.format(inputs)) LOG.info('OUTPUT:{}'.format(outputs)) LOG.info('PARAMS:{}'.format(params)) uow_dir = 'uow-{:02d}'.format(i) uow_dirs.append(uow_dir) io.rmdir(uow_dir) io.mkdirs(uow_dir) script = open(bash_template_fn).read() with io.cd(uow_dir): pypeflow.do_task.run_bash(script, inputs, outputs, params) resolved_outputs = {k: os.path.abspath(v) for k,v in outputs.items()} results.append({k: os.path.join('.', os.path.relpath(v)) for k,v in resolved_outputs.items()}) # Must be relative to this dir. # (We assume outputs are under the current directory.) # The reason for the './' prefix? So we can substitute in CWD later, # in case we ran in /tmp. This also helps the pbsmrtpipe "gatherer". #wildcards_str = '_'.join(w for w in itervalues(job['wildcards'])) #job_name = 'job{}'.format(wildcards_str) #for (output_name, output_fn) in viewitems(outputs): # giname = '{}_{}'.format(job_name, output_name) # gather_inputs[giname] = output_fn io.serialize(results_fn, results) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Run a bash script once for each unit-of-work, in its own sub-dir.' epilog = 'For now, runs will be in series, since we do not know how many processors we can use.' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--nproc', help='Number of processors to be used.') parser.add_argument( '--bash-template-fn', help='Input. Template of bash script to run on each unit-of-work, with snakemake-style substitutions.') parser.add_argument( '--units-of-work-fn', help='Input. JSON list of records of unit-of-work. Each record is a dict of input, output, and params (snakemake-style).') parser.add_argument( '--results-fn', help='Output. JSON list of result records.') args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/generic_scatter_one_uow.py ================================================ from __future__ import absolute_import import argparse import collections import glob import logging import os import sys import pypeflow.do_task from .. import io LOG = logging.getLogger() # Here is some stuff basically copied from pypeflow.sample_tasks.py. def validate(bash_template, inputs, outputs, parameterss): LOG.info('bash_script_from_template({}\n\tinputs={!r},\n\toutputs={!r})'.format( bash_template, inputs, outputs)) def validate_dict(mydict): "Python identifiers are illegal as keys." try: collections.namedtuple('validate', mydict.keys()) except ValueError as exc: LOG.exception('Bad key name in task definition dict {!r}'.format(mydict)) raise validate_dict(inputs) validate_dict(outputs) validate_dict(parameterss) def run(all_uow_list_fn, split_idx, one_uow_list_fn): all_uows = io.deserialize(all_uow_list_fn) dn = os.path.abspath(os.path.dirname(all_uow_list_fn)) one_uow = all_uows[split_idx] def fixpath(rel): try: if rel.startswith('./'): return os.path.join(dn, rel) except Exception: pass return rel if isinstance(one_uow, dict): input_dict = one_uow['input'] for k, v in input_dict.items(): input_dict[k] = fixpath(v) io.serialize(one_uow_list_fn, [one_uow]) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Scatter a single unit-of-work from many units-of-work.' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--all-uow-list-fn', help='Input. JSON list of all units of work.') parser.add_argument( '--split-idx', type=int, help='Input. Index into the all-uow-list for our single unit-of-work.') parser.add_argument( '--one-uow-list-fn', help='Output. JSON list of a single unit-of-work.') args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/generic_unsplit.py ================================================ from __future__ import absolute_import import argparse import logging import os import sys from .. import io LOG = logging.getLogger() def run(result_fn_list_fn, gathered_fn): thatdir = os.path.dirname(result_fn_list_fn) thisdir = os.path.dirname(gathered_fn) result_fn_list = io.deserialize(result_fn_list_fn) io.serialize(gathered_fn, result_fn_list) gathered = list() for result_fn in result_fn_list: some_results = io.deserialize(result_fn) d = os.path.abspath(os.path.dirname(result_fn)) def abspath(v): if v.startswith('.'): return os.path.normpath(os.path.join(d, v)) else: return v # apparently not a path # By construction, this is a list of dicts of k:output, # where outputs are relative to the location of result_fn. some_abs_results = list() for one in some_results: for v in one.itervalues(): assert not v.startswith('/'), '{!r} was expected to be relative'.format(v) abs_one = {k: abspath(v) for k,v in one.items()} some_abs_results.append(abs_one) gathered.extend(some_abs_results) io.serialize(gathered_fn, gathered) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Gather the contents of contents of result-lists into a single gathered-list.' epilog = 'results-list is known already, so that is a pseudo output. Its filenames point to the actual, unknown results.' # Question: Do we need to know the wildcards for each result? parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--result-fn-list-fn', help='Input: Combined list of filenames of results (pseudo output, expected to exist already in our run-dir)') parser.add_argument( '--gathered-fn', help='Output: serialized something-or-other') args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/get_read_ctg_map.py ================================================ from __future__ import absolute_import from .. import pype_tasks # pylint: disable=no-name-in-module, import-error, fixme, line-too-long from pypeflow.simple_pwatcher_bridge import (PypeProcWatcherWorkflow, MyFakePypeThreadTaskBase, makePypeLocalFile, fn, PypeTask) PypeThreadTaskBase = MyFakePypeThreadTaskBase import argparse import glob import logging import sys import subprocess as sp import shlex import os LOG = logging.getLogger(__name__) def make_dirs(d): if not os.path.isdir(d): LOG.debug('mkdirs {}'.format(d)) os.makedirs(d) def get_read_ctg_map(rawread_dir, pread_dir, asm_dir): read_map_dir = os.path.abspath(os.path.join(asm_dir, 'read_maps')) make_dirs(read_map_dir) wf = PypeProcWatcherWorkflow( max_jobs=12, ) """ job_type=config['job_type'], job_queue=config['job_queue'], sge_option=config.get('sge_option', ''), watcher_type=config['pwatcher_type'], watcher_directory=config['pwatcher_directory']) """ rawread_db = makePypeLocalFile(os.path.join(rawread_dir, 'raw_reads.db')) rawread_id_file = makePypeLocalFile(os.path.join( read_map_dir, 'dump_rawread_ids', 'rawread_ids')) task = PypeTask( inputs={'rawread_db': rawread_db}, outputs={'rawread_id_file': rawread_id_file}, ) wf.addTask(task(pype_tasks.task_dump_rawread_ids)) pread_db = makePypeLocalFile(os.path.join(pread_dir, 'preads.db')) pread_id_file = makePypeLocalFile(os.path.join( read_map_dir, 'dump_pread_ids', 'pread_ids')) task = PypeTask( inputs={'pread_db': pread_db}, outputs={'pread_id_file': pread_id_file}, ) wf.addTask(task(pype_tasks.task_dump_pread_ids)) wf.refreshTargets() # block sg_edges_list = makePypeLocalFile(os.path.join(asm_dir, 'sg_edges_list')) utg_data = makePypeLocalFile(os.path.join(asm_dir, 'utg_data')) ctg_paths = makePypeLocalFile(os.path.join(asm_dir, 'ctg_paths')) inputs = {'rawread_id_file': rawread_id_file, 'pread_id_file': pread_id_file, 'sg_edges_list': sg_edges_list, 'utg_data': utg_data, 'ctg_paths': ctg_paths} read_to_contig_map = makePypeLocalFile(os.path.join( read_map_dir, 'get_ctg_read_map', 'read_to_contig_map')) task = PypeTask( inputs=inputs, outputs={'read_to_contig_map': read_to_contig_map}, ) wf.addTask(task(pype_tasks.task_generate_read_to_ctg_map)) wf.refreshTargets() # block def parse_args(argv): parser = argparse.ArgumentParser(description='generate `2-asm-falcon/read_maps/read_to_contig_map` that contains the \ information from the chain of mapping: (contig id) -> (internal p-read id) -> (internal raw-read id) -> (original read id)', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--basedir', type=str, default='./', help='the base working dir of a FALCON assembly') args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): logging.basicConfig() args = parse_args(argv) basedir = args.basedir rawread_dir = os.path.abspath(os.path.join(basedir, '0-rawreads')) pread_dir = os.path.abspath(os.path.join(basedir, '1-preads_ovl')) asm_dir = os.path.abspath(os.path.join(basedir, '2-asm-falcon')) get_read_ctg_map(rawread_dir=rawread_dir, pread_dir=pread_dir, asm_dir=asm_dir) if __name__ == '__main__': main() ================================================ FILE: falcon_kit/mains/graph_to_contig.py ================================================ """ TODO: (from convo w/ Ivan) the issue with this script (but would still like to re-read it to refresh my memory). The script loads all edge sequences and tries to do two things at once: create p_ctg and a_ctg sequences, and align the bubbles using those sequences If we generate: 1. All paths first (as tiling paths) for all p_ctg and all a_ctg without loading sequences - this should not consume much space (take a look at *_tiling_paths files). 2. Load the first read of each tiling path fully, and only edge sequences for every transition, we can generate the output sequences with the same memory/disk consumption. 3. Align bubbles after that. Our resource consumption should be same Bubbles? It aligns them to produce the identity score After that the dedup_a_tigs.py script is used to deduplicate fake a_ctg. But that script is simple, and only depends on the alignment info that the previous script stored in the a_ctg header. """ from __future__ import absolute_import from __future__ import print_function from builtins import zip from builtins import range import argparse import sys import networkx as nx #from pbcore.io import FastaReader from falcon_kit.FastaReader import open_fasta_reader from falcon_kit import kup, falcon, DWA read_fasta = "preads4falcon.fasta" edge_data_file = "sg_edges_list" utg_data_file = "utg_data" ctg_data_file = "ctg_paths" RCMAP = dict(zip("ACGTacgtNn-", "TGCAtgcaNn-")) class TooLongError(Exception): pass def log(msg): sys.stderr.write(msg) sys.stderr.write('\n') def rc(seq): return "".join([RCMAP[c] for c in seq[::-1]]) def get_aln_data(t_seq, q_seq): aln_data = [] #x = [] #y = [] K = 8 seq0 = t_seq lk_ptr = kup.allocate_kmer_lookup(1 << (K * 2)) sa_ptr = kup.allocate_seq(len(seq0)) sda_ptr = kup.allocate_seq_addr(len(seq0)) kup.add_sequence(0, K, seq0, len(seq0), sda_ptr, sa_ptr, lk_ptr) q_id = "dummy" kmer_match_ptr = kup.find_kmer_pos_for_seq( q_seq, len(q_seq), K, sda_ptr, lk_ptr) kmer_match = kmer_match_ptr[0] if kmer_match.count != 0: aln_range_ptr = kup.find_best_aln_range(kmer_match_ptr, K, K * 5, 12) aln_range = aln_range_ptr[0] #x, y = list(zip(* [(kmer_match.query_pos[i], kmer_match.target_pos[i]) # for i in range(kmer_match.count)])) s1, e1, s2, e2 = aln_range.s1, aln_range.e1, aln_range.s2, aln_range.e2 max_len = 250000 # to keep allocations < 16GB, given band_tol=1500 if (e1 - s1) >= max_len or (e2 - s2) >= max_len: # DW.align() would crash, so raise here. # (500000 is the approx. upper bound for int overflow, # but some users run out of memory anyway.) raise TooLongError('q_len={} or t_len={} are too big, over 500k'.format( (e1-s1), (e2-s2))) if e1 - s1 > 100: log('Calling DW_banded.align(q, {}, t, {}, 1500, 1)'.format( e1-s1, e2-s2)) alignment = DWA.align(q_seq[s1:e1], e1 - s1, seq0[s2:e2], e2 - s2, 1500, 1) if alignment[0].aln_str_size > 100: aln_data.append((q_id, 0, s1, e1, len(q_seq), s2, e2, len( seq0), alignment[0].aln_str_size, alignment[0].dist)) aln_str1 = alignment[0].q_aln_str aln_str0 = alignment[0].t_aln_str DWA.free_alignment(alignment) kup.free_aln_range(aln_range_ptr) kup.free_kmer_match(kmer_match_ptr) kup.free_kmer_lookup(lk_ptr) kup.free_seq_array(sa_ptr) kup.free_seq_addr_array(sda_ptr) return aln_data #, x, y def reverse_end(node_id): node_id, end = node_id.split(":") new_end = "B" if end == "E" else "E" return node_id + ":" + new_end def yield_first_seq(one_path_edges, seqs): if one_path_edges and one_path_edges[0][0] != one_path_edges[-1][1]: # If non-empty, and non-circular, # prepend the entire first read. (vv, ww) = one_path_edges[0] (vv_rid, vv_letter) = vv.split(":") if vv_letter == 'E': first_seq = seqs[vv_rid] else: assert vv_letter == 'B' first_seq = "".join([RCMAP[c] for c in seqs[vv_rid][::-1]]) yield first_seq def run(improper_p_ctg, proper_a_ctg): """improper==True => Neglect the initial read. We used to need that for unzip. """ reads_in_layout = set() with open(edge_data_file) as f: for l in f: l = l.strip().split() """001039799:E 000333411:E 000333411 17524 20167 17524 99.62 G""" v, w, rid, s, t, aln_score, idt, type_ = l if type_ != "G": continue r1 = v.split(":")[0] reads_in_layout.add(r1) r2 = w.split(":")[0] reads_in_layout.add(r2) seqs = {} # load all p-read name into memory with open_fasta_reader(read_fasta) as f: for r in f: if r.name not in reads_in_layout: continue seqs[r.name] = r.sequence.upper() # name == rid-string edge_data = {} with open(edge_data_file) as f: for l in f: l = l.strip().split() """001039799:E 000333411:E 000333411 17524 20167 17524 99.62 G""" v, w, rid, s, t, aln_score, idt, type_ = l if type_ != "G": continue r1, dir1 = v.split(":") reads_in_layout.add(r1) # redundant, but harmless r2, dir2 = w.split(":") reads_in_layout.add(r2) # redundant, but harmless s = int(s) t = int(t) aln_score = int(aln_score) idt = float(idt) if s < t: e_seq = seqs[rid][s:t] assert 'E' == dir2 else: # t and s were swapped for 'c' alignments in ovlp_to_graph.generate_string_graph():702 # They were translated from reverse-dir to forward-dir coordinate system in LA4Falcon. e_seq = "".join([RCMAP[c] for c in seqs[rid][t:s][::-1]]) assert 'B' == dir2 edge_data[(v, w)] = (rid, s, t, aln_score, idt, e_seq) utg_data = {} with open(utg_data_file) as f: for l in f: l = l.strip().split() s, v, t, type_, length, score, path_or_edges = l if type_ not in ["compound", "simple", "contained"]: continue length = int(length) score = int(score) if type_ in ("simple", "contained"): path_or_edges = path_or_edges.split("~") else: path_or_edges = [tuple(e.split("~")) for e in path_or_edges.split("|")] utg_data[(s, v, t)] = type_, length, score, path_or_edges p_ctg_out = open("p_ctg.fa", "w") a_ctg_out = open("a_ctg_all.fa", "w") a_ctg_base_out = open("a_ctg_base.fa", "w") p_ctg_t_out = open("p_ctg_tiling_path", "w") a_ctg_t_out = open("a_ctg_tiling_path", "w") a_ctg_base_t_out = open("a_ctg_base_tiling_path", "w") layout_ctg = set() with open(ctg_data_file) as f: for l in f: l = l.strip().split() ctg_id, c_type_, i_utig, t0, length, score, utgs = l ctg_id = ctg_id s0 = i_utig.split("~")[0] if (reverse_end(t0), reverse_end(s0)) in layout_ctg: continue else: layout_ctg.add((s0, t0)) ctg_label = i_utig + "~" + t0 length = int(length) utgs = utgs.split("|") one_path = [] total_score = 0 total_length = 0 #a_ctg_data = [] a_ctg_group = {} for utg in utgs: s, v, t = utg.split("~") type_, length, score, path_or_edges = utg_data[(s, v, t)] total_score += score total_length += length if type_ == "simple": if len(one_path) != 0: one_path.extend(path_or_edges[1:]) else: one_path.extend(path_or_edges) if type_ == "compound": c_graph = nx.DiGraph() all_alt_path = [] for ss, vv, tt in path_or_edges: type_, length, score, sub_path = utg_data[(ss, vv, tt)] v1 = sub_path[0] for v2 in sub_path[1:]: c_graph.add_edge( v1, v2, e_score=edge_data[(v1, v2)][3]) v1 = v2 shortest_path = nx.shortest_path(c_graph, s, t, "e_score") score = nx.shortest_path_length(c_graph, s, t, "e_score") all_alt_path.append((score, shortest_path)) # a_ctg_data.append( (s, t, shortest_path) ) #first path is the same as the one used in the primary contig while 1: n0 = shortest_path[0] for n1 in shortest_path[1:]: c_graph.remove_edge(n0, n1) n0 = n1 try: shortest_path = nx.shortest_path( c_graph, s, t, "e_score") score = nx.shortest_path_length( c_graph, s, t, "e_score") #a_ctg_data.append( (s, t, shortest_path) ) all_alt_path.append((score, shortest_path)) except nx.exception.NetworkXNoPath: break # if len(shortest_path) < 2: # break all_alt_path.sort() all_alt_path.reverse() shortest_path = all_alt_path[0][1] if len(one_path) != 0: one_path.extend(shortest_path[1:]) else: one_path.extend(shortest_path) a_ctg_group[(s, t)] = all_alt_path if len(one_path) == 0: continue one_path_edges = list(zip(one_path[:-1], one_path[1:])) if improper_p_ctg: sub_seqs = [] else: sub_seqs = list(yield_first_seq(one_path_edges, seqs)) for vv, ww in one_path_edges: rid, s, t, aln_score, idt, e_seq = edge_data[(vv, ww)] sub_seqs.append(e_seq) print("%s %s %s %s %d %d %d %0.2f" % ( ctg_id, vv, ww, rid, s, t, aln_score, idt), file=p_ctg_t_out) print(">%s %s %s %d %d" % ( ctg_id, ctg_label, c_type_, total_length, total_score), file=p_ctg_out) print("".join(sub_seqs), file=p_ctg_out) a_id = 1 for v, w, in a_ctg_group: # get the base sequence used in the primary contig atig_output = [] score, atig_path = a_ctg_group[(v, w)][0] atig_path_edges = list(zip(atig_path[:-1], atig_path[1:])) if not proper_a_ctg: sub_seqs = [] else: sub_seqs = list(yield_first_seq(atig_path_edges, seqs)) total_length = 0 total_score = 0 for vv, ww in atig_path_edges: rid, s, t, aln_score, idt, e_seq = edge_data[(vv, ww)] sub_seqs.append(e_seq) total_length += abs(s - t) total_score += aln_score base_seq = "".join(sub_seqs) atig_output.append( (v, w, atig_path, total_length, total_score, base_seq, atig_path_edges, 0, 1, 1)) for score, atig_path in a_ctg_group[(v, w)][1:]: atig_path_edges = list(zip(atig_path[:-1], atig_path[1:])) if not proper_a_ctg: sub_seqs = [] else: sub_seqs = list(yield_first_seq(atig_path_edges, seqs)) total_length = 0 total_score = 0 for vv, ww in atig_path_edges: rid, s, t, aln_score, idt, e_seq = edge_data[(vv, ww)] sub_seqs.append(e_seq) total_length += abs(s - t) total_score += aln_score seq = "".join(sub_seqs) delta_len = len(seq) - len(base_seq) idt = 0.0 cov = 0.0 if len(base_seq) > 2000 and len(seq) > 2000: try: aln_data = get_aln_data(base_seq, seq) if len(aln_data) != 0: idt = 1.0 - 1.0 * \ aln_data[-1][-1] / aln_data[-1][-2] cov = 1.0 * \ (aln_data[-1][3] - aln_data[-1] [2]) / aln_data[-1][4] except TooLongError: log('WARNING: Seqs were too long for get_aln_data(), so we set idt/cov low enough to prevent filtering by dedup_a_tigs, at atig_path[:-1] == {}'.format(atig_path[:-1])) idt = -1.0 cov = -1.0 atig_output.append( (v, w, atig_path, total_length, total_score, seq, atig_path_edges, delta_len, idt, cov)) if len(atig_output) == 1: continue sub_id = 0 for data in atig_output: v0, w0, tig_path, total_length, total_score, seq, atig_path_edges, delta_len, a_idt, cov = data for vv, ww in atig_path_edges: rid, s, t, aln_score, idt, e_seq = edge_data[(vv, ww)] if sub_id != 0: print("%s-%03d-%02d %s %s %s %d %d %d %0.2f" % ( ctg_id, a_id, sub_id, vv, ww, rid, s, t, aln_score, idt), file=a_ctg_t_out) else: print("%s-%03d-%02d %s %s %s %d %d %d %0.2f" % ( ctg_id, a_id, sub_id, vv, ww, rid, s, t, aln_score, idt), file=a_ctg_base_t_out) if sub_id != 0: print(">%s-%03d-%02d %s %s %d %d %d %d %0.2f %0.2f" % ( ctg_id, a_id, sub_id, v0, w0, total_length, total_score, len(atig_path_edges), delta_len, a_idt, cov), file=a_ctg_out) print(seq, file=a_ctg_out) else: print(">%s-%03d-%02d %s %s %d %d %d %d %0.2f %0.2f" % ( ctg_id, a_id, sub_id, v0, w0, total_length, total_score, len(atig_path_edges), delta_len, a_idt, cov), file=a_ctg_base_out) print(seq, file=a_ctg_base_out) sub_id += 1 a_id += 1 a_ctg_out.close() a_ctg_base_out.close() p_ctg_out.close() a_ctg_t_out.close() a_ctg_base_t_out.close() a_ctg_t_out.close() p_ctg_t_out.close() def main(argv=sys.argv): description = 'Generate the primary and alternate contig fasta files and tiling paths, given the string graph.' epilog = """ We assume these input files, in cwd: read_fasta = "preads4falcon.fasta" edge_data_file = "sg_edges_list" utg_data_file = "utg_data" ctg_data_file = "ctg_paths" We write these: p_ctg_out = open("p_ctg.fa", "w") a_ctg_out = open("a_ctg_all.fa", "w") a_ctg_base_out = open("a_ctg_base.fa", "w") p_ctg_t_out = open("p_ctg_tiling_path", "w") a_ctg_t_out = open("a_ctg_tiling_path", "w") a_ctg_base_t_out = open("a_ctg_base_tiling_path", "w") """ parser = argparse.ArgumentParser( description=description, formatter_class=argparse.RawDescriptionHelpFormatter, epilog=epilog) parser.add_argument('--improper-p-ctg', action='store_true', help='Skip the initial read in each p_ctg path.') parser.add_argument('--proper-a-ctg', action='store_true', help='Skip the initial read in each a_ctg path.') args = parser.parse_args(argv[1:]) run(**vars(args)) if __name__ == "__main__": main(sys.argv) ================================================ FILE: falcon_kit/mains/graph_to_utgs.py ================================================ from __future__ import absolute_import from __future__ import print_function from builtins import zip from builtins import range from falcon_kit import kup, falcon, DWA from falcon_kit.fc_asm_graph import AsmGraph import networkx as nx import sys RCMAP = dict(zip("ACGTacgtNn-", "TGCAtgcaNn-")) def rc(seq): return "".join([RCMAP[c] for c in seq[::-1]]) def get_aln_data(t_seq, q_seq): aln_data = [] K = 8 seq0 = t_seq lk_ptr = kup.allocate_kmer_lookup(1 << (K * 2)) sa_ptr = kup.allocate_seq(len(seq0)) sda_ptr = kup.allocate_seq_addr(len(seq0)) kup.add_sequence(0, K, seq0, len(seq0), sda_ptr, sa_ptr, lk_ptr) q_id = "dummy" kmer_match_ptr = kup.find_kmer_pos_for_seq( q_seq, len(q_seq), K, sda_ptr, lk_ptr) kmer_match = kmer_match_ptr[0] aln_range_ptr = kup.find_best_aln_range(kmer_match_ptr, K, K * 5, 12) aln_range = aln_range_ptr[0] x, y = list(zip(* [(kmer_match.query_pos[i], kmer_match.target_pos[i]) for i in range(kmer_match.count)])) kup.free_kmer_match(kmer_match_ptr) s1, e1, s2, e2 = aln_range.s1, aln_range.e1, aln_range.s2, aln_range.e2 if e1 - s1 > 100: alignment = DWA.align(q_seq[s1:e1], e1 - s1, seq0[s2:e2], e2 - s2, 1500, 1) if alignment[0].aln_str_size > 100: aln_data.append((q_id, 0, s1, e1, len(q_seq), s2, e2, len( seq0), alignment[0].aln_str_size, alignment[0].dist)) aln_str1 = alignment[0].q_aln_str aln_str0 = alignment[0].t_aln_str DWA.free_alignment(alignment) kup.free_kmer_lookup(lk_ptr) kup.free_seq_array(sa_ptr) kup.free_seq_addr_array(sda_ptr) return aln_data, x, y def main(argv=sys.argv): G_asm = AsmGraph("sg_edges_list", "utg_data", "ctg_paths") G_asm.load_sg_seq("preads4falcon.fasta") utg_out = open("utgs.fa", "w") for utg in G_asm.utg_data: s, t, v = utg type_, length, score, path_or_edges = G_asm.utg_data[(s, t, v)] if type_ == "simple": path_or_edges = path_or_edges.split("~") seq = G_asm.get_seq_from_path(path_or_edges) print(">%s~%s~%s-%d %d %d" % ( s, v, t, 0, length, score), file=utg_out) print(seq, file=utg_out) if type_ == "compound": c_graph = nx.DiGraph() all_alt_path = [] path_or_edges = [c.split("~") for c in path_or_edges.split("|")] for ss, vv, tt in path_or_edges: type_, length, score, sub_path = G_asm.utg_data[(ss, tt, vv)] sub_path = sub_path.split("~") v1 = sub_path[0] for v2 in sub_path[1:]: c_graph.add_edge( v1, v2, e_score=G_asm.sg_edges[(v1, v2)][1]) v1 = v2 shortest_path = nx.shortest_path(c_graph, s, t, "e_score") score = nx.shortest_path_length(c_graph, s, t, "e_score") all_alt_path.append((score, shortest_path)) # a_ctg_data.append( (s, t, shortest_path) ) #first path is the same as the one used in the primary contig while 1: if s == t: break n0 = shortest_path[0] for n1 in shortest_path[1:]: c_graph.remove_edge(n0, n1) n0 = n1 try: shortest_path = nx.shortest_path(c_graph, s, t, "e_score") score = nx.shortest_path_length(c_graph, s, t, "e_score") #a_ctg_data.append( (s, t, shortest_path) ) all_alt_path.append((score, shortest_path)) except nx.exception.NetworkXNoPath: break # if len(shortest_path) < 2: # break all_alt_path.sort() all_alt_path.reverse() shortest_path = all_alt_path[0][1] score, atig_path = all_alt_path[0] atig_output = [] atig_path_edges = list(zip(atig_path[:-1], atig_path[1:])) sub_seqs = [] total_length = 0 total_score = 0 for vv, ww in atig_path_edges: r, aln_score, idt, typs_ = G_asm.sg_edges[(vv, ww)] e_seq = G_asm.sg_edge_seqs[(vv, ww)] rid, ss, tt = r sub_seqs.append(e_seq) total_length += abs(ss - tt) total_score += aln_score base_seq = "".join(sub_seqs) atig_output.append( (s, t, atig_path, total_length, total_score, base_seq, atig_path_edges, 1, 1)) duplicated = True for score, atig_path in all_alt_path[1:]: atig_path_edges = list(zip(atig_path[:-1], atig_path[1:])) sub_seqs = [] total_length = 0 total_score = 0 for vv, ww in atig_path_edges: r, aln_score, idt, type_ = G_asm.sg_edges[(vv, ww)] e_seq = G_asm.sg_edge_seqs[(vv, ww)] rid, ss, tt = r sub_seqs.append(e_seq) total_length += abs(ss - tt) total_score += aln_score seq = "".join(sub_seqs) aln_data, x, y = get_aln_data(base_seq, seq) if len(aln_data) != 0: idt = 1.0 - 1.0 * aln_data[-1][-1] / aln_data[-1][-2] cov = 1.0 * (aln_data[-1][3] - aln_data[-1][2]) / aln_data[-1][4] if idt < 0.96 or cov < 0.98: duplicated = False atig_output.append( (s, t, atig_path, total_length, total_score, seq, atig_path_edges, idt, cov)) else: duplicated = False atig_output.append( (s, t, atig_path, total_length, total_score, seq, atig_path_edges, 0, 0)) # if len(atig_output) == 1: # continue sub_id = 0 for data in atig_output: v0, w0, tig_path, total_length, total_score, seq, atig_path_edges, a_idt, cov = data print(">%s~%s~%s-%d %d %d" % ( v0, "NA", w0, sub_id, total_length, total_score), file=utg_out) print(seq, file=utg_out) sub_id += 1 if __name__ == "__main__": main(sys.argv) ================================================ FILE: falcon_kit/mains/hgap4_adapt.py ================================================ """Given a full HGAP4 run, generate directories and symlinks to make it look like a pypeflow run. Then, fc_run/fc_unzip/fc_quiver can operate on it. In fact, fc_run should be already satisfied. One caveat: At the moment, parts of falcon-unzip actually write into the falcon dirs. We should fix that. But for now, we create writable run-dirs. We do *not* write into the HGAP4 run-dir. """ from __future__ import absolute_import from future.utils import viewitems from ..util.system import (cd, touch, make_dirs) import argparse import contextlib import glob import json import logging import os import sys LOG = logging.getLogger(__name__) """ Note that, even though this program is designed to let unzip run, it has nothing to do with unzip. It merely mimics falcon, so that the falcon jobs appear as fully satisfied to pypeflow. That is why this program is in this repo rather than in FALCON_unzip. However, if HGAP4/pbsmrtpipe-tasks change, then this would need to be updated. """ """HGAP4 with --force-chunk-mode pbcoretools.tasks.filterdataset-0 pbcoretools.tasks.subreadset_zmw_scatter-1 pbcoretools.tasks.bam2fasta-2 pbcoretools.tasks.bam2fasta-1 .pbcoretools.tasks.subreadset_zmw_scatter-f87695df-095d-44f0-958c-380106fc60 pbcoretools.tasks.gather_fasta-1 pbcoretools.tasks.fasta2fofn-0 falcon_ns.tasks.task_falcon_gen_config-0 falcon_ns.tasks.task_falcon_config-0 falcon_ns.tasks.task_falcon_make_fofn_abs-0 falcon_ns.tasks.task_falcon0_build_rdb-0 pbfalcon.tasks.scatter0_run_daligner_jobs-1 .pbfalcon.tasks.scatter0_run_daligner_jobs-c71da9cc-ee0e-41ca-93b3-63b5d3f14857-gathered-pipeline.chunks.json falcon_ns.tasks.task_falcon0_run_daligner_jobs-1 pbfalcon.tasks.gather0_run_daligner_jobs-1 falcon_ns.tasks.task_falcon0_rm_las-0 falcon_ns.tasks.task_falcon0_run_merge_consensus_jobs-0 pbfalcon.tasks.scatter_run_scripts_in_json-1 falcon_ns.tasks.task_falcon0_merge-1 .pbfalcon.tasks.scatter_run_scripts_in_json-94c652c2-e483-4cc3-81e8-264e5de74da3-gathered-pipeline.chunks.json pbcoretools.tasks.gather_txt-1 pbfalcon.tasks.scatter_run_scripts_in_json_2-1 .pbfalcon.tasks.scatter_run_scripts_in_json_2-23ee9e9f-415d-4312-90ba-5744320f4f7b-gathered-pipeline.chunks.json falcon_ns.tasks.task_falcon0_cons-1 pbcoretools.tasks.gather_txt-2 falcon_ns.tasks.task_report_preassembly_yield-0 falcon_ns.tasks.task_falcon1_rm_las-0 falcon_ns.tasks.task_falcon1_build_pdb-0 pbfalcon.tasks.scatter1_run_daligner_jobs-1 .pbfalcon.tasks.scatter1_run_daligner_jobs-53468780-ee9d-44e9-a9cb-60676f3ae7b4-gathered-pipeline.chunks.json pbfalcon.tasks.gather1_run_daligner_jobs-1 falcon_ns.tasks.task_falcon1_merge-0 falcon_ns.tasks.task_falcon1_run_merge_consensus_jobs-0 falcon_ns.tasks.task_falcon1_db2falcon-0 falcon_ns.tasks.task_falcon2_rm_las-0 falcon_ns.tasks.task_falcon2_run_asm-0 """ """Post-FALCON steps: pbcoretools.tasks.fasta2referenceset-0 pbalign.tasks.pbalign-0 ******* pbreports.tasks.summarize_coverage-0 genomic_consensus.tasks.variantcaller-0 ******* pbreports.tasks.coverage_report_hgap-0 genomic_consensus.tasks.gff2bed-0 pbcoretools.tasks.contigset2fasta-0 pbreports.tasks.polished_assembly-0 pbreports.tasks.mapping_stats_hgap-0 falcon_ns.tasks.task_report_preassembly_yield-0 Or with chunking: pbcoretools.tasks.fasta2referenceset-0 pbcoretools.tasks.subreadset_align_scatter-1 pbalign.tasks.pbalign-2 pbalign.tasks.pbalign-1 .pbcoretools.tasks.subreadset_align_scatter-b473df0f-c3d5-46ab-8c45-be5054ea0dbd-gathered-pipeline.chunks.json pbcoretools.tasks.gather_alignmentset-1 pbreports.tasks.summarize_coverage-0 pbcoretools.tasks.alignment_contig_scatter-1 pbreports.tasks.coverage_report_hgap-0 genomic_consensus.tasks.variantcaller-2 genomic_consensus.tasks.variantcaller-1 .pbcoretools.tasks.alignment_contig_scatter-7eda161b-3ed9-4891-97f3-300dd975407a-gathered-pipeline.chunks.json pbcoretools.tasks.gather_gff-1 pbreports.tasks.mapping_stats_hgap-0 pbcoretools.tasks.gather_fastq-1 pbcoretools.tasks.gather_contigset-1 pbcoretools.tasks.gather_vcf-1 genomic_consensus.tasks.gff2bed-0 pbreports.tasks.polished_assembly-0 pbcoretools.tasks.contigset2fasta-0 """ """In job_output/tasks/ dir, without chunking: pbcoretools.tasks.filterdataset-0 pbcoretools.tasks.bam2fasta-0 ******* pbcoretools.tasks.fasta2fofn-0 falcon_ns.tasks.task_falcon_gen_config-0 falcon_ns.tasks.task_falcon_config-0 falcon_ns.tasks.task_falcon_make_fofn_abs-0 falcon_ns.tasks.task_falcon0_build_rdb-0 falcon_ns.tasks.task_falcon0_run_daligner_jobs-0 ******* falcon_ns.tasks.task_falcon0_run_merge_consensus_jobs-0 falcon_ns.tasks.task_falcon0_rm_las-0 falcon_ns.tasks.task_falcon0_merge-0 falcon_ns.tasks.task_falcon0_cons-0 falcon_ns.tasks.task_falcon1_rm_las-0 falcon_ns.tasks.task_falcon1_build_pdb-0 falcon_ns.tasks.task_falcon1_run_daligner_jobs-0 ******* falcon_ns.tasks.task_falcon1_merge-0 falcon_ns.tasks.task_falcon1_run_merge_consensus_jobs-0 falcon_ns.tasks.task_falcon1_db2falcon-0 falcon_ns.tasks.task_falcon2_rm_las-0 falcon_ns.tasks.task_falcon2_run_asm-0 0-rawreads/ 0-rawreads/raw-fofn-abs 0-rawreads/daligner-scatter 0-rawreads/job_0000 0-rawreads/raw-gather 0-rawreads/merge-scatter 0-rawreads/m_00001 0-rawreads/merge-gather 0-rawreads/cns-scatter 0-rawreads/preads 0-rawreads/preads/cns_00001 0-rawreads/report 1-preads_ovl/ 1-preads_ovl/daligner-scatter 1-preads_ovl/job_0000 1-preads_ovl/gathered-las 1-preads_ovl/merge-scatter 1-preads_ovl/m_00001 1-preads_ovl/merge-gather 1-preads_ovl/db2falcon 2-asm-falcon/ """ @contextlib.contextmanager def mkcd(newdir): make_dirs(newdir) with cd(newdir): yield def symlink(jo): """Caller should first cd into link-dir. """ def assert_exists(path): assert os.path.exists(path), 'File does not exist: {!r}'.format(path) def assert_dir(path): assert os.path.isdir(path), 'Not a directory: {!r}'.format(path) assert_dir(jo) taskdir = os.path.join(jo, 'tasks') assert_dir(taskdir) def touch_done(): """Standard pypeflow convention. """ touch('run.sh.done') def abstdir(basetdir): return os.path.abspath(os.path.join(jo, 'tasks', basetdir)) def link(targetdir, basename, linkname=None): if not linkname: linkname = basename reldir = os.path.relpath(targetdir) target = os.path.join(reldir, basename) assert_exists(os.path.abspath(target)) if os.path.lexists(linkname): if os.readlink(linkname) == target: return os.unlink(linkname) LOG.info('link {!r} to {}/{}'.format(linkname, reldir, basename)) os.symlink(target, linkname) # Define task symlinkers def task_make_fofn_abs_raw(): """ "input_fofn" from cfg """ with mkcd('0-rawreads/raw-fofn-abs/'): # touch('input.fofn') touch_done() def task_build_rdb(): rdir = abstdir('falcon_ns.tasks.task_falcon0_build_rdb-0') with mkcd('0-rawreads/'): #touch('length_cutoff', 'rdb_build_done', 'run_jobs.sh', 'raw_reads.db') link(rdir, 'raw_reads.db') link(rdir, '.raw_reads.bps') link(rdir, '.raw_reads.idx') link(rdir, '.raw_reads.dust.data') link(rdir, '.raw_reads.dust.anno') touch_done() def task_daligner_scatter(): """ """ with mkcd('0-rawreads/daligner-scatter/'): data = dict() with open('scattered.json', 'w') as stream: stream.write(json.dumps(data)) touch_done() def create_daligner_tasks(): """ 0-rawreads/job_0000 *** """ #create_daligner_tasks('0-rawreads', '0-rawreads/daligner-scatter/scattered.json') def task_daligner_gather(): """ """ with mkcd('0-rawreads/raw-gather/'): # touch('gathered_las.txt') touch_done() def task_merge_scatter(): """ """ with mkcd('0-rawreads/merge-scatter/'): data = dict() with open('scattered.json', 'w') as stream: stream.write(json.dumps(data)) touch_done() def create_merge_tasks(): """ 0-rawreads/m_00001 *** """ #create_merge_tasks('0-rawreads', '0-rawreads/merge-scatter/scattered.json') def task_merge_gather(): # falcon_unzip/rr_hctg_track.py expects files under 0-rawreads/m*/raw_reads.*.las dn2fn = dict() rdir = abstdir( 'falcon_ns.tasks.task_falcon0_run_merge_consensus_jobs-0/') with cd(rdir): for path in glob.glob(os.path.join('m*/raw_reads.*.las')): dn, fn = os.path.split(path) dn2fn[dn] = fn with mkcd('0-rawreads/'): for (dn, fn) in viewitems(dn2fn): with mkcd(dn): link(os.path.join(rdir, dn), fn) with mkcd('0-rawreads/merge-gather/'): #touch('las.fofn', 'las.fopfn') touch_done() def task_consensus_scatter(): """ """ with mkcd('0-rawreads/cns-scatter/'): data = dict() with open('scattered.json', 'w') as stream: stream.write(json.dumps(data)) touch_done() def create_consensus_tasks(): """ 0-rawreads/preads/cns_00001 *** """ #create_consensus_tasks('0-rawreads', '0-rawreads/cns-scatter/scattered.json') def task_consensus_gather(): """ """ with mkcd('0-rawreads/preads'): # touch('input_preads.fofn') touch_done() def task_report_pre_assembly(): """ """ with mkcd('0-rawreads/report/'): # touch('pre_assembly_stats.json') touch_done() def task_build_pdb(): """ """ rdir = abstdir('falcon_ns.tasks.task_falcon1_build_pdb-0') with mkcd('1-preads_ovl/'): #touch('pdb_build_done', 'run_jobs.sh', 'preads.db') link(rdir, 'preads.db') link(rdir, '.preads.bps') link(rdir, '.preads.idx') link(rdir, '.preads.dust.data') link(rdir, '.preads.dust.anno') touch_done() def task_daligner_scatter1(): """ """ with mkcd('1-preads_ovl/daligner-scatter/'): data = dict() with open('scattered.json', 'w') as stream: stream.write(json.dumps(data)) touch_done() def create_daligner_tasks1(): """ 1-preads_ovl/job_0000 *** """ #create_daligner_tasks('1-preads', '1-preads/daligner-scatter/scattered.json') def task_daligner_gather1(): """ """ with mkcd('1-preads_ovl/gathered-las/'): # touch('gathered_las.txt') touch_done() def task_merge_scatter1(): """ """ with mkcd('1-preads_ovl/merge-scatter/'): data = dict() with open('scattered.json', 'w') as stream: stream.write(json.dumps(data)) touch_done() def create_merge_tasks1(): """ 1-preads_ovl/m_00001 *** """ #create_merge_tasks('1-preads_ovl', '1-preads_ovl/merge-scatter/scattered.json') def task_merge_gather1(): # falcon/pr_ctg_track.py expects files under 1-preads_ovl/m*/preads.*.las dn2fn = dict() rdir = abstdir( 'falcon_ns.tasks.task_falcon1_run_merge_consensus_jobs-0/') with cd(rdir): for path in glob.glob(os.path.join('m*/preads.*.las')): dn, fn = os.path.split(path) dn2fn[dn] = fn with mkcd('1-preads_ovl/'): for (dn, fn) in viewitems(dn2fn): with mkcd(dn): link(os.path.join(rdir, dn), fn) #rdir = abstdir('falcon_ns.tasks.task_falcon1_merge-0') rdir = abstdir( 'falcon_ns.tasks.task_falcon1_run_merge_consensus_jobs-0') with mkcd('1-preads_ovl/merge-gather/'): #touch('las.fofn', 'las.fopfn') link(rdir, 'file.fofn', 'las.fofn') touch_done() def task_run_db2falcon(): rdir = abstdir('falcon_ns.tasks.task_falcon1_db2falcon-0') rdirx = abstdir( 'falcon_ns.tasks.task_falcon1_run_merge_consensus_jobs-0') with mkcd('1-preads_ovl/db2falcon/'): #touch('db2falcon', 'preads4falcon.fasta') link(rdirx, 'preads4falcon.fasta') touch_done() def task_run_falcon_asm(): """falcon_ns.tasks.task_falcon2_run_asm-0 (falcon_ns.tasks.task_falcon2_rm_las-0) """ rdir = abstdir('falcon_ns.tasks.task_falcon2_run_asm-0') with mkcd('2-asm-falcon/'): # workflow depends on: touch('falcon_asm_done') # get_read_ctg_map needs: link(rdir, 'sg_edges_list') link(rdir, 'utg_data') link(rdir, 'ctg_paths') # fetch_reads needs: link(rdir, 'p_ctg.fa') touch_done() task_make_fofn_abs_raw() task_build_rdb() task_daligner_scatter() create_daligner_tasks() task_daligner_gather() task_merge_scatter() create_merge_tasks() task_merge_gather() task_consensus_scatter() create_consensus_tasks() task_consensus_gather() task_report_pre_assembly() task_build_pdb() task_daligner_scatter1() create_daligner_tasks1() task_daligner_gather1() task_merge_scatter1() create_merge_tasks1() task_merge_gather1() task_run_db2falcon() task_run_falcon_asm() def get_parser(): class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass description = 'Given a full HGAP4 run, generate directories and symlinks to make it look like a pypeflow run.' epilog = """ Typically: mkdir mydir/ cd mydir/ python -m falcon_kit.mains.hgap4_adapt --job-output-dir=../job_output/ fc_run fc_run.cfg -- (A) fc_unzip.py fc_unzip.cfg -- (B) fc_quiver.py fc_unzip.cfg -- (C) You need to create/modify the .cfg files. (A) This should be a no-op, and you do not need to run this at all. Just a sanity check. It will tell you that everything is already satisfied. But it cannot work unless you provide `input.fofn` (which can be empty) and set it to `input_fofn` in your .cfg. (B)/(C) These will need both `input_fofn` and `input_bam_fofn`. The latter should name actual BAM files to use for Quiver (also for partitioning for pbalign). For more help on .cfg files, see * https://github.com/PacificBiosciences/FALCON/wiki * https://github.com/PacificBiosciences/FALCON_unzip/wiki * https://github.com/PacificBiosciences/FALCON-integrate/wiki """ parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF) parser.add_argument('--job-output-dir', default='job_output', help='Directory of HGAP4 job_output. (A symlink or relative path is fine.) Task-dirs are under here in "tasks/"') return parser def main(argv=sys.argv): args = get_parser().parse_args(argv[1:]) symlink(args.job_output_dir) if __name__ == '__main__': logging.basicConfig(level=logging.INFO) main() ================================================ FILE: falcon_kit/mains/las_merge.py ================================================ from __future__ import absolute_import import argparse import logging import os import sys from .. import io from .. import bash # for write_script LOG = logging.getLogger() def run(p_id_num, las_paths_fn, merge_script_fn, las_merged_fn_fn, las_merged_symlink_fn, job_done_fn, p_id_fn): with open(p_id_fn, 'w') as stream: stream.write(p_id_num) cwd = os.getcwd() LOG.info('Merging las files from {!r} using {!r} to write {!r} (symlink to name from {!r}) (and {!r})'.format( las_paths_fn, merge_script_fn, las_merged_symlink_fn, las_merged_fn_fn, job_done_fn)) if os.path.lexists(las_merged_symlink_fn): os.unlink(las_merged_symlink_fn) las_merged_name_fn = io.deserialize(las_merged_fn_fn) script = open(merge_script_fn).read() las_paths = io.deserialize(las_paths_fn) src_dir = os.path.normpath(os.path.dirname(las_paths_fn)) for las_path in las_paths: if not os.path.isabs(las_path): las_path = os.path.abspath(os.path.join(src_dir, las_path)) if os.path.commonprefix([las_path, cwd]) == '/': src = las_path else: src = os.path.relpath(las_path, cwd) name = os.path.join(cwd, os.path.basename(las_path)) LOG.info('symlink {!r} <- {!r}'.format(src, name)) if os.path.lexists(name): os.unlink(name) os.symlink(src, name) script_fn = 'run_las_merge.sh' bash.write_script(script, script_fn, job_done_fn) io.syscall('bash -vex {}'.format(script_fn)) os.symlink(las_merged_name_fn, las_merged_symlink_fn) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Merge several .las files into one, using the script generated by HPC.daligner.' epilog = 'The name of the merged .las file is not known to this program. It was selected by HPC.daligner. The input .las files will be symlinked into CWD so that the HPC.daligner script can find what it expects.' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--las-paths-fn', help='Input. JSON list of las filenames to merge.') parser.add_argument( '--merge-script-fn', help='Input. Part of the output of HPC.daligner.') parser.add_argument( '--las-merged-fn-fn', help='Input. File which contains the file-name of the merged .las file to be generated (presumably in CWD) by the script.') parser.add_argument( '--p-id-num', help='Input. Just an integer, which is sort of the block number for consensus. This will go into p-id-fn.') parser.add_argument( '--las-merged-symlink-fn', help='Output. Symlink to the result of the script.') parser.add_argument( '--p-id-fn', help='Output. File containing just a single integer, the p-id-num.') parser.add_argument( '--job-done-fn', help='Output. Just a sentinel. (TODO: Drop.)') args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/las_merge_gather.py ================================================ """Not sure anything uses the fopfn anymore. """ from __future__ import absolute_import from __future__ import print_function #from future.utils import viewitems import argparse import logging import os import sys from .. import io LOG = logging.getLogger() def run(gathered_fn, las_fn, p_id2las_fn): gathered = io.deserialize(gathered_fn) d = os.path.abspath(os.path.realpath(os.path.dirname(gathered_fn))) def abspath(fn): if os.path.isabs(fn): return fn # I expect this never to happen though. return os.path.join(d, fn) p_id2las = dict() for desc in gathered: p_id_fn = abspath(desc['p_id']) p_id = int(open(p_id_fn).read()) #io.deserialize(p_id_fn) # someday? requires file-extension p_id2las[p_id] = abspath(desc['merged_las']) io.serialize(p_id2las_fn, p_id2las) io.serialize(las_fn, list(p_id2las.values())) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Turn gathered file into .las FOFN (and FOPFN).' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--gathered-fn', help='Input. JSON list of output dicts.') parser.add_argument( '--las-fn', help='Output. JSON list of las paths.') parser.add_argument( '--p-id2las-fn', help='Output. JSON dict of p_id to las.') args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/las_merge_scatter.py ================================================ from __future__ import absolute_import import argparse import collections import logging import os import sys from .. import io from .. import bash LOG = logging.getLogger() def read_gathered_las(path): """Return dict of block->[las_paths]. For now, these are ws separated on each line of input. """ result = collections.defaultdict(list) with open(path) as ifs: for line in ifs: block, las_path = line.split() result[int(block)].append(las_path) # LOG.warning('path={!r}, result={}'.format( # path, pprint.pformat(result))) return result def run(run_jobs_fn, gathered_las_fn, db_prefix, stage, wildcards, scattered_fn): LOG.info('Scattering las from {!r} (based on {!r}) into {!r}.'.format( gathered_las_fn, run_jobs_fn, scattered_fn)) config = dict() # not used anyway merge_scripts = list(bash.scripts_merge(config, db_prefix, run_jobs_fn)) gathered_dict = read_gathered_las(gathered_las_fn) gathered_dict_dir = os.path.normpath(os.path.dirname(gathered_las_fn)) basedir = os.path.dirname(os.path.abspath(scattered_fn)) rootdir = os.path.dirname(os.path.dirname(basedir)) # for now jobs = list() for p_id, merge_script, merged_las_fn in merge_scripts: job_id = 'm_%05d' %p_id # Write the scattered inputs. merge_script_fn = '{rootdir}/{stage}/merge-scripts/{job_id}/merge-script.sh'.format(**locals()) las_paths_fn = '{rootdir}/{stage}/merge-scripts/{job_id}/las_paths.json'.format(**locals()) merged_las_json_fn = '{rootdir}/{stage}/merge-scripts/{job_id}/merged_las.json'.format(**locals()) io.mkdirs(os.path.dirname(merge_script_fn), os.path.dirname(las_paths_fn), os.path.dirname(merged_las_json_fn)) with open(merge_script_fn, 'w') as stream: stream.write(merge_script) # las_paths must be updated for new relative paths las_paths_dir = os.path.normpath(os.path.dirname(las_paths_fn)) las_paths = list() for p in gathered_dict[p_id]: updated_relative_path = os.path.relpath(os.path.join(gathered_dict_dir, p), las_paths_dir) las_paths.append(updated_relative_path) io.serialize(las_paths_fn, las_paths) io.serialize(merged_las_json_fn, merged_las_fn) # Record in a job-dict. job = dict() job['input'] = dict( las_paths = las_paths_fn, merge_script = merge_script_fn, merged_las_json = merged_las_json_fn, ) job['output'] = dict( merged_las = '{rootdir}/{stage}/{job_id}/merged.las'.format(**locals()), job_done = '{rootdir}/{stage}/{job_id}/merge.done'.format(**locals()), ) job['params'] = dict( actual_merged_las = merged_las_fn, ) job['wildcards'] = {wildcards: job_id} jobs.append(job) io.serialize(scattered_fn, jobs) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Prepare for parallel las-merge jobs.' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--run-jobs-fn', help='Input. Result of HPC.daligner.', ) parser.add_argument( '--gathered-las-fn', help='Input. (Not sure of content yet.)', ) parser.add_argument( '--db-prefix', default='raw_reads', help='Either preads or raw_reads.', ) parser.add_argument( '--stage', default='0-rawreads', help='Either 0-rawreads or 1-preads_ovl, for now.', ) parser.add_argument( '--wildcards', help='To be used in substitutions', ) # Do we need config too? parser.add_argument( '--scattered-fn', help='Output. JSON list of jobs, where each is a dict of input/output/params/wildcards.', ) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/las_merge_split.py ================================================ from __future__ import absolute_import import argparse import collections import logging import os import re import sys from .. import io from .. import bash from .. import pype_tasks LOG = logging.getLogger() # Could be L1.* or preads.* or raw_reads.* re_las = re.compile(r'\.(\d*)(?:\.[^\.]+\.\d*)?\.las$') # see daligner_gather_las() in run_support.py def get_block(las_fn): """ >>> get_block('foo.42.las') 42 >>> get_block('foo.12.foo.34.las') 12 """ mo = re_las.search(las_fn) if not mo: msg = 'No match of las file {!r} with {}'.format(las_fn, re_las.pattern) raise Exception(msg) block = int(mo.group(1)) return block def read_gathered_las(las_fns): """Return dict of block->[las_paths]. The input is one .las file per line. """ result = collections.defaultdict(list) for las_fn in las_fns: block = get_block(las_fn) result[block].append(las_fn) return result def run(run_jobs_fn, gathered_las_fn, db_prefix, wildcards, split_fn, bash_template_fn): with open(bash_template_fn, 'w') as stream: stream.write(pype_tasks.TASK_LAS_MERGE_SCRIPT) LOG.info('Splitting las file-list from {!r} (based on {!r}) into {!r}.'.format( gathered_las_fn, run_jobs_fn, split_fn)) config = dict() # not used anyway merge_scripts = list(bash.scripts_merge(config, db_prefix, run_jobs_fn)) gathered_las = io.deserialize(gathered_las_fn) gathered_dict = read_gathered_las(gathered_las) LOG.info('Gathered {} las files.'.format(len(gathered_dict))) gathered_dict_dir = os.path.normpath(os.path.dirname(gathered_las_fn)) if 0 == len(gathered_dict): raise Exception('No .las files. There must have been some kind of error.\n gathered_las_fn={!r},\n run_jobs_fn={!r}'.format( gathered_las_fn, run_jobs_fn)) if 1 == len(gathered_dict) and 1 == len(gathered_dict.values()[0]): LOG.warning('There is only 1 .las file in {!r}.\n The las-merge step will be a no-op.'.format(gathered_las_fn)) assert len(merge_scripts) == 0, 'Expected more than 1 .las file. merge_scripts={}. See {!r} and {!r}'.format( merge_scripts, run_jobs_fn, gathered_las_fn) solo_block, solo_las_fns = gathered_dict.items()[0] merge_scripts = [(solo_block, '# no-op', os.path.basename(solo_las_fns[0]))] cwd = os.getcwd() jobs = list() for p_id, merge_script, merged_las_fn in merge_scripts: job_id = 'm_%05d' %p_id # Write the split inputs. merge_script_fn = '{cwd}/las-merge-scripts/{job_id}/merge-script.sh'.format(**locals()) las_paths_fn = '{cwd}/las-merge-scripts/{job_id}/las_paths.json'.format(**locals()) merged_las_json_fn = '{cwd}/las-merge-scripts/{job_id}/merged_las.json'.format(**locals()) io.mkdirs(os.path.dirname(merge_script_fn), os.path.dirname(las_paths_fn), os.path.dirname(merged_las_json_fn)) with open(merge_script_fn, 'w') as stream: stream.write(merge_script) # las_paths must be updated for new relative paths las_paths_dir = os.path.normpath(os.path.dirname(las_paths_fn)) las_paths = list() for p in gathered_dict[p_id]: updated_relative_path = os.path.relpath(os.path.join(gathered_dict_dir, p), las_paths_dir) las_paths.append(updated_relative_path) io.serialize(las_paths_fn, las_paths) io.serialize(merged_las_json_fn, merged_las_fn) # Record in a job-dict. job = dict() job['input'] = dict( las_paths = las_paths_fn, merge_script = merge_script_fn, merged_las_json = merged_las_json_fn, ) job['output'] = dict( merged_las = 'merged.las', job_done = 'merge.done', p_id = 'p_id' ) job['params'] = dict( actual_merged_las = merged_las_fn, p_id_num = p_id, ) job['wildcards'] = {wildcards: job_id} jobs.append(job) io.serialize(split_fn, jobs) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Prepare for parallel las-merge jobs.' epilog = '' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--run-jobs-fn', help='Input. Result of HPC.daligner.') parser.add_argument( '--gathered-las-fn', help='Input. (Not sure of content yet.)') parser.add_argument( '--db-prefix', default='raw_reads', help='Either preads or raw_reads.') parser.add_argument( '--wildcards', help='Input. Comma-separated wildcard names. Might be needed downstream.') parser.add_argument( '--split-fn', help='Output. JSON list of jobs, where each is a dict of input/output/params/wildcards.') parser.add_argument( '--bash-template-fn', help='Output. Known template of bash for running las-merge.') args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/ovlp_filter.py ================================================ from __future__ import absolute_import from builtins import range from falcon_kit.multiproc import Pool import falcon_kit.util.io as io import argparse import os import sys Reader = io.CapturedProcessReaderContext def run_filter_stage1(db_fn, fn, max_diff, max_ovlp, min_ovlp, min_len): cmd = "LA4Falcon -mo %s %s" % (db_fn, fn) reader = Reader(cmd) with reader: return fn, filter_stage1(reader.readlines, max_diff, max_ovlp, min_ovlp, min_len) def filter_stage1(readlines, max_diff, max_ovlp, min_ovlp, min_len): def ignore(overlap_data): left_count = overlap_data["5p"] right_count = overlap_data["3p"] if (abs(left_count - right_count) > max_diff) or \ (left_count > max_ovlp) or (right_count > max_ovlp) or \ (left_count < min_ovlp) or (right_count < min_ovlp): return True ignore_rtn = [] current_q_id = None ave_idt = 0.0 all_over_len = 0.0 overlap_data = {"5p": 0, "3p": 0} q_id = None for l in readlines(): l = l.strip().split() q_id, t_id = l[:2] if q_id != current_q_id: if current_q_id is not None: if ignore(overlap_data): ignore_rtn.append(current_q_id) overlap_data = {"5p": 0, "3p": 0} current_q_id = q_id ave_idt = 0.0 all_over_len = 0.0 overlap_len = -int(l[2]) idt = float(l[3]) q_s, q_e, q_l = int(l[5]), int(l[6]), int(l[7]) t_s, t_e, t_l = int(l[9]), int(l[10]), int(l[11]) if idt < 90.0: continue if q_l < min_len or t_l < min_len: continue if l[-1] in ("contains", "overlap"): ave_idt += idt * overlap_len all_over_len += overlap_len if q_s == 0: overlap_data["5p"] += 1 if q_e == q_l: overlap_data["3p"] += 1 if q_id is not None: if ignore(overlap_data): ignore_rtn.append(current_q_id) return ignore_rtn def run_filter_stage2(db_fn, fn, max_diff, max_ovlp, min_ovlp, min_len, ignore_set): cmd = "LA4Falcon -mo %s %s" % (db_fn, fn) reader = Reader(cmd) with reader: return fn, filter_stage2(reader.readlines, max_diff, max_ovlp, min_ovlp, min_len, ignore_set) def filter_stage2(readlines, max_diff, max_ovlp, min_ovlp, min_len, ignore_set): contained_id = set() for l in readlines(): l = l.strip().split() q_id, t_id = l[:2] q_s, q_e, q_l = int(l[5]), int(l[6]), int(l[7]) t_s, t_e, t_l = int(l[9]), int(l[10]), int(l[11]) idt = float(l[3]) if idt < 90: continue if q_l < min_len or t_l < min_len: continue if q_id in ignore_set: continue if t_id in ignore_set: continue if l[-1] == "contained": contained_id.add(q_id) if l[-1] == "contains": contained_id.add(t_id) return contained_id def run_filter_stage3(db_fn, fn, max_diff, max_ovlp, min_ovlp, min_len, ignore_set, contained_set, bestn): cmd = "LA4Falcon -mo %s %s" % (db_fn, fn) reader = Reader(cmd) with reader: return fn, filter_stage3(reader.readlines, max_diff, max_ovlp, min_ovlp, min_len, ignore_set, contained_set, bestn) def filter_stage3(readlines, max_diff, max_ovlp, min_ovlp, min_len, ignore_set, contained_set, bestn): ovlp_output = [] overlap_data = {"5p": [], "3p": []} current_q_id = None for l in readlines(): l = l.strip().split() q_id, t_id = l[:2] if current_q_id == None: current_q_id = q_id overlap_data = {"5p": [], "3p": []} elif q_id != current_q_id: left = overlap_data["5p"] right = overlap_data["3p"] left.sort() right.sort() for i in range(len(left)): score, m_range, ovlp = left[i] ovlp_output.append(ovlp) # print " ".join(ovlp), read_end_data[current_q_id] if i >= bestn and m_range > 1000: break for i in range(len(right)): score, m_range, ovlp = right[i] ovlp_output.append(ovlp) # print " ".join(ovlp), read_end_data[current_q_id] if i >= bestn and m_range > 1000: break overlap_data = {"5p": [], "3p": []} current_q_id = q_id if q_id in contained_set: continue if t_id in contained_set: continue if q_id in ignore_set: continue if t_id in ignore_set: continue overlap_len = -int(l[2]) idt = float(l[3]) q_s, q_e, q_l = int(l[5]), int(l[6]), int(l[7]) t_s, t_e, t_l = int(l[9]), int(l[10]), int(l[11]) if idt < 90: continue if q_l < min_len or t_l < min_len: continue if q_s == 0: overlap_data["5p"].append((-overlap_len, t_l - (t_e - t_s), l)) elif q_e == q_l: overlap_data["3p"].append((-overlap_len, t_l - (t_e - t_s), l)) left = overlap_data["5p"] right = overlap_data["3p"] left.sort() right.sort() for i in range(len(left)): score, m_range, ovlp = left[i] ovlp_output.append(ovlp) # print " ".join(ovlp), read_end_data[current_q_id] if i >= bestn and m_range > 1000: break for i in range(len(right)): score, m_range, ovlp = right[i] ovlp_output.append(ovlp) # print " ".join(ovlp), read_end_data[current_q_id] if i >= bestn and m_range > 1000: break return ovlp_output def run_ovlp_filter(outs, exe_pool, file_list, max_diff, max_cov, min_cov, min_len, bestn, db_fn): io.LOG('preparing filter_stage1') io.logstats() inputs = [] for fn in file_list: if len(fn) != 0: inputs.append((run_filter_stage1, db_fn, fn, max_diff, max_cov, min_cov, min_len)) ignore_all = [] for res in exe_pool.imap(io.run_func, inputs): ignore_all.extend(res[1]) io.LOG('preparing filter_stage2') io.logstats() inputs = [] ignore_all = set(ignore_all) for fn in file_list: if len(fn) != 0: inputs.append((run_filter_stage2, db_fn, fn, max_diff, max_cov, min_cov, min_len, ignore_all)) contained = set() for res in exe_pool.imap(io.run_func, inputs): contained.update(res[1]) # print res[0], len(res[1]), len(contained) # print "all", len(contained) io.LOG('preparing filter_stage3') io.logstats() inputs = [] ignore_all = set(ignore_all) for fn in file_list: if len(fn) != 0: inputs.append((run_filter_stage3, db_fn, fn, max_diff, max_cov, min_cov, min_len, ignore_all, contained, bestn)) for res in exe_pool.imap(io.run_func, inputs): for l in res[1]: outs.write(" ".join(l) + "\n") io.logstats() def try_run_ovlp_filter(out_fn, n_core, fofn, max_diff, max_cov, min_cov, min_len, bestn, db_fn): io.LOG('starting ovlp_filter') file_list = io.validated_fns(fofn) io.LOG('fofn %r: %r' % (fofn, file_list)) n_core = min(n_core, len(file_list)) exe_pool = Pool(n_core) tmp_out_fn = out_fn + '.tmp' try: with open(tmp_out_fn, 'w') as outs: run_ovlp_filter(outs, exe_pool, file_list, max_diff, max_cov, min_cov, min_len, bestn, db_fn) outs.write('---\n') os.rename(tmp_out_fn, out_fn) io.LOG('finished ovlp_filter') except: io.LOG('terminating ovlp_filter workers...') exe_pool.terminate() raise def ovlp_filter(out_fn, n_core, las_fofn, max_diff, max_cov, min_cov, min_len, bestn, db_fn, debug, silent, stream): if debug: n_core = 0 silent = False if silent: io.LOG = io.write_nothing if stream: global Reader Reader = io.StreamedProcessReaderContext try_run_ovlp_filter(out_fn, n_core, las_fofn, max_diff, max_cov, min_cov, min_len, bestn, db_fn) def parse_args(argv): epilog = """Output consists of selected lines from LA4Falcon -mo, e.g. 000000047 000000550 -206 100.00 0 0 206 603 1 0 206 741 overlap """ class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass parser = argparse.ArgumentParser( description='a simple multi-processes LAS ovelap data filter', epilog=epilog, formatter_class=HelpF) parser.add_argument( '--out-fn', default='preads.ovl', help='Output filename') parser.add_argument( '--n-core', type=int, default=4, help='number of processes used for generating consensus; 0 for main process only') parser.add_argument( '--las-fofn', type=str, help='file contains the paths of all LAS files to be processed in parallel') parser.add_argument( '--db', type=str, dest='db_fn', help='read db file path') parser.add_argument( '--max-diff', type=int, help="max difference of 5' and 3' coverage") parser.add_argument( '--max-cov', type=int, help="max coverage of 5' or 3' coverage") parser.add_argument( '--min-cov', type=int, help="min coverage of 5' or 3' coverage") parser.add_argument( '--min-len', type=int, default=2500, help="min length of the reads") parser.add_argument( '--bestn', type=int, default=10, help="output at least best n overlaps on 5' or 3' ends if possible") parser.add_argument( '--stream', action='store_true', help='stream from LA4Falcon, instead of slurping all at once; can save memory for large data') parser.add_argument( '--debug', '-g', action='store_true', help="single-threaded, plus other aids to debugging") parser.add_argument( '--silent', action='store_true', help="suppress cmd reporting on stderr") args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) ovlp_filter(**vars(args)) if __name__ == "__main__": main(sys.argv) ================================================ FILE: falcon_kit/mains/ovlp_stats.py ================================================ from __future__ import absolute_import from __future__ import print_function from falcon_kit.multiproc import Pool import falcon_kit.util.io as io import argparse import shlex import subprocess as sp import sys import traceback Reader = io.CapturedProcessReaderContext def filter_stats(readlines, min_len): current_q_id = None ave_idt = 0.0 all_over_len = 0.0 overlap_data = {"5p": 0, "3p": 0} q_id = None rtn_data = [] q_l = 0 for l in readlines(): l = l.strip().split() q_id, t_id = l[:2] if q_id != current_q_id: left_count = overlap_data["5p"] right_count = overlap_data["3p"] if (current_q_id != None and (left_count > 0 or right_count > 0)): rtn_data.append((current_q_id, q_l, left_count, right_count)) overlap_data = {"5p": 0, "3p": 0} current_q_id = q_id ave_idt = 0.0 all_over_len = 0.0 overlap_len = -int(l[2]) idt = float(l[3]) q_s, q_e, q_l = int(l[5]), int(l[6]), int(l[7]) t_s, t_e, t_l = int(l[9]), int(l[10]), int(l[11]) if q_l < min_len or t_l < min_len: continue if idt < 90: continue if l[-1] in ("contains", "overlap"): ave_idt += idt * overlap_len all_over_len += overlap_len if q_s == 0: overlap_data["5p"] += 1 if q_e == q_l: overlap_data["3p"] += 1 if q_id != None: left_count = overlap_data["5p"] right_count = overlap_data["3p"] if (left_count > 0 or right_count > 0): rtn_data.append((q_id, q_l, left_count, right_count)) return rtn_data def run_filter_stats(db_fn, fn, min_len): try: cmd = "LA4Falcon -mo {} {}".format(db_fn, fn) reader = Reader(cmd) with reader: return fn, filter_stats(reader.readlines, min_len) except Exception: stack = traceback.format_exc() io.LOG(stack) raise def run_ovlp_stats(exe_pool, db_fn, file_list, min_len): inputs = [] for fn in file_list: if len(fn) != 0: inputs.append((run_filter_stats, db_fn, fn, min_len)) for res in exe_pool.imap(io.run_func, inputs): for l in res[1]: print(" ".join([str(c) for c in l])) def try_run_ovlp_stats(n_core, db_fn, fofn, min_len): io.LOG('starting ovlp_stats') file_list = io.validated_fns(fofn) io.LOG('fofn {!r}: {}'.format(fofn, file_list)) io.LOG('db {!r}; n_core={}'.format(db_fn, n_core)) n_core = min(n_core, len(file_list)) exe_pool = Pool(n_core) try: run_ovlp_stats(exe_pool, db_fn, file_list, min_len) io.LOG('finished ovlp_stats') except KeyboardInterrupt: io.LOG('terminating ovlp_stats workers...') exe_pool.terminate() def ovlp_stats(db_fn, fofn, min_len, n_core, stream, debug, silent): if debug: n_core = 0 silent = False if silent: io.LOG = io.write_nothing if stream: global Reader Reader = io.StreamedProcessReaderContext try_run_ovlp_stats(n_core, db_fn, fofn, min_len) def parse_args(argv): parser = argparse.ArgumentParser(description='a simple multi-processes LAS ovelap data filter', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--n-core', type=int, default=4, help='number of processes used for generating consensus; ' '0 for main process only') parser.add_argument('--fofn', type=str, required=True, help='file contains the path of all LAS file to be processed in parallel') parser.add_argument('--min-len', type=int, default=2500, help="min length of the reads") parser.add_argument('--db-fn', default='./1-preads_ovl/preads.db', help="DAZZLER DB of preads") parser.add_argument('--stream', action='store_true', help='stream from LA4Falcon, instead of slurping all at once; can save memory for large data') parser.add_argument('--debug', '-g', action='store_true', help="single-threaded, plus other aids to debugging") parser.add_argument('--silent', action='store_true', help="suppress cmd reporting on stderr") return parser.parse_args(argv[1:]) def main(argv=sys.argv): args = parse_args(argv) ovlp_stats(**vars(args)) if __name__ == "__main__": main(sys.argv) ================================================ FILE: falcon_kit/mains/ovlp_to_graph.py ================================================ from __future__ import absolute_import from __future__ import print_function from future.utils import viewitems from future.utils import itervalues from builtins import object import networkx as nx import os import shlex import subprocess import sys DEBUG_LOG_LEVEL = 0 class SGNode(object): """ class representing a node in the string graph """ def __init__(self, node_name): self.name = node_name self.out_edges = [] self.in_edges = [] def add_out_edge(self, out_edge): self.out_edges.append(out_edge) def add_in_edge(self, in_edge): self.in_edges.append(in_edge) class SGEdge(object): """ class representing an edge in the string graph """ def __init__(self, in_node, out_node): self.in_node = in_node self.out_node = out_node self.attr = {} def set_attribute(self, attr, value): self.attr[attr] = value def reverse_end(node_name): if (node_name == 'NA'): return node_name if (len(node_name) < 2 or (node_name[-2:] not in [':B', ':E'])): raise Exception( 'Invalid node name. Node name passed to method: "{node_name}", expected format: "(%d)+:[BE]" or "NA".'.format(node_name=node_name)) node_id, end = node_name.split(":") new_end = "B" if end == "E" else "E" return node_id + ":" + new_end class StringGraph(object): """ class representing the string graph """ def __init__(self): self.nodes = {} self.edges = {} self.n_mark = {} self.e_reduce = {} self.repeat_overlap = {} self.best_out = {} self.best_in = {} def add_node(self, node_name): """ add a node into the graph by given a node name """ if node_name not in self.nodes: self.nodes[node_name] = SGNode(node_name) def add_edge(self, in_node_name, out_node_name, **attributes): """ add an edge into the graph by given a pair of nodes """ if (in_node_name, out_node_name) not in self.edges: self.add_node(in_node_name) self.add_node(out_node_name) in_node = self.nodes[in_node_name] out_node = self.nodes[out_node_name] edge = SGEdge(in_node, out_node) self.edges[(in_node_name, out_node_name)] = edge in_node.add_out_edge(edge) out_node.add_in_edge(edge) edge = self.edges[(in_node_name, out_node_name)] for (k, v) in viewitems(attributes): edge.attr[k] = v def init_reduce_dict(self): for e in self.edges: self.e_reduce[e] = False def bfs_nodes(self, n, exclude=None, depth=5): all_nodes = set() all_nodes.add(n) candidate_nodes = set() candidate_nodes.add(n) dp = 1 while dp < depth and len(candidate_nodes) > 0: v = candidate_nodes.pop() for e in v.out_edges: w = e.out_node if w == exclude: continue if w not in all_nodes: all_nodes.add(w) if len(w.out_edges) > 0: candidate_nodes.add(w) dp += 1 return all_nodes def mark_chimer_edges(self): multi_in_nodes = {} multi_out_nodes = {} for n_name in self.nodes: n = self.nodes[n_name] out_nodes = [e.out_node for e in n.out_edges if self.e_reduce[( e.in_node.name, e.out_node.name)] == False] in_nodes = [e.in_node for e in n.in_edges if self.e_reduce[( e.in_node.name, e.out_node.name)] == False] if len(out_nodes) >= 2: multi_out_nodes[n_name] = out_nodes if len(in_nodes) >= 2: multi_in_nodes[n_name] = in_nodes chimer_candidates = set() out_set = set() in_set = set() for n_name in multi_out_nodes: out_nodes = set(multi_out_nodes[n_name]) out_set |= out_nodes for n_name in multi_in_nodes: in_nodes = set(multi_in_nodes[n_name]) in_set |= in_nodes chimer_candidates = out_set & in_set chimer_nodes = [] chimer_edges = set() for n in chimer_candidates: out_nodes = set([e.out_node for e in n.out_edges]) test_set = set() for in_node in [e.in_node for e in n.in_edges]: test_set = test_set | set( [e.out_node for e in in_node.out_edges]) test_set -= set([n]) if len(out_nodes & test_set) == 0: flow_node1 = set() flow_node2 = set() for v in list(out_nodes): flow_node1 |= self.bfs_nodes(v, exclude=n) for v in list(test_set): flow_node2 |= self.bfs_nodes(v, exclude=n) if len(flow_node1 & flow_node2) == 0: for e in n.out_edges: v, w = e.in_node.name, e.out_node.name if self.e_reduce[(v, w)] != True: self.e_reduce[(v, w)] = True chimer_edges.add((v, w)) rv = reverse_end(w) rw = reverse_end(v) self.e_reduce[(rv, rw)] = True chimer_edges.add((rv, rw)) for e in n.in_edges: v, w = e.in_node.name, e.out_node.name if self.e_reduce[(v, w)] != True: self.e_reduce[(v, w)] = True chimer_edges.add((v, w)) rv = reverse_end(w) rw = reverse_end(v) self.e_reduce[(rv, rw)] = True chimer_edges.add((rv, rw)) chimer_nodes.append(n.name) chimer_nodes.append(reverse_end(n.name)) return chimer_nodes, chimer_edges def mark_spur_edge(self): removed_edges = set() for v in self.nodes: if len([e for e in self.nodes[v].out_edges if self.e_reduce[(e.in_node.name, e.out_node.name)] != True]) > 1: for out_edge in self.nodes[v].out_edges: w = out_edge.out_node.name if len(self.nodes[w].out_edges) == 0 and self.e_reduce[(v, w)] != True: self.e_reduce[(v, w)] = True removed_edges.add((v, w)) v2, w2 = reverse_end(w), reverse_end(v) self.e_reduce[(v2, w2)] = True removed_edges.add((v2, w2)) if len([e for e in self.nodes[v].in_edges if self.e_reduce[(e.in_node.name, e.out_node.name)] != True]) > 1: for in_edge in self.nodes[v].in_edges: w = in_edge.in_node.name if len(self.nodes[w].in_edges) == 0 and self.e_reduce[(w, v)] != True: self.e_reduce[(w, v)] = True removed_edges.add((w, v)) v2, w2 = reverse_end(w), reverse_end(v) self.e_reduce[(w2, v2)] = True removed_edges.add((w2, v2)) return removed_edges def mark_tr_edges(self): """ transitive reduction """ n_mark = self.n_mark e_reduce = self.e_reduce FUZZ = 500 for n in self.nodes: n_mark[n] = "vacant" for (n_name, node) in viewitems(self.nodes): out_edges = node.out_edges if len(out_edges) == 0: continue out_edges.sort(key=lambda x: x.attr["length"]) for e in out_edges: w = e.out_node n_mark[w.name] = "inplay" max_len = out_edges[-1].attr["length"] max_len += FUZZ for e in out_edges: e_len = e.attr["length"] w = e.out_node if n_mark[w.name] == "inplay": w.out_edges.sort(key=lambda x: x.attr["length"]) for e2 in w.out_edges: if e2.attr["length"] + e_len < max_len: x = e2.out_node if n_mark[x.name] == "inplay": n_mark[x.name] = "eliminated" for e in out_edges: e_len = e.attr["length"] w = e.out_node w.out_edges.sort(key=lambda x: x.attr["length"]) if len(w.out_edges) > 0: x = w.out_edges[0].out_node if n_mark[x.name] == "inplay": n_mark[x.name] = "eliminated" for e2 in w.out_edges: if e2.attr["length"] < FUZZ: x = e2.out_node if n_mark[x.name] == "inplay": n_mark[x.name] = "eliminated" for out_edge in out_edges: v = out_edge.in_node w = out_edge.out_node if n_mark[w.name] == "eliminated": e_reduce[(v.name, w.name)] = True v_name, w_name = reverse_end(w.name), reverse_end(v.name) e_reduce[(v_name, w_name)] = True n_mark[w.name] = "vacant" def mark_best_overlap(self): """ find the best overlapped edges """ best_edges = set() removed_edges = set() for v in self.nodes: out_edges = self.nodes[v].out_edges if len(out_edges) > 0: out_edges.sort(key=lambda e: -e.attr["score"]) for e in out_edges: if self.e_reduce[(e.in_node.name, e.out_node.name)] != True: best_edges.add((e.in_node.name, e.out_node.name)) self.best_out[v] = e.out_node.name break in_edges = self.nodes[v].in_edges if len(in_edges) > 0: in_edges.sort(key=lambda e: -e.attr["score"]) for e in in_edges: if self.e_reduce[(e.in_node.name, e.out_node.name)] != True: best_edges.add((e.in_node.name, e.out_node.name)) self.best_in[v] = e.in_node.name break if DEBUG_LOG_LEVEL > 1: print("X", len(best_edges)) for (e_n, e) in viewitems(self.edges): v = e_n[0] w = e_n[1] if self.e_reduce[(v, w)] != True: if (v, w) not in best_edges: self.e_reduce[(v, w)] = True removed_edges.add((v, w)) v2, w2 = reverse_end(w), reverse_end(v) self.e_reduce[(v2, w2)] = True removed_edges.add((v2, w2)) return removed_edges def resolve_repeat_edges(self): edges_to_reduce = [] nodes_to_test = set() for (v_n, v) in viewitems(self.nodes): out_nodes = [] for e in v.out_edges: if self.e_reduce[(e.in_node.name, e.out_node.name)] == False: out_nodes.append(e.out_node.name) in_nodes = [] for e in v.in_edges: if self.e_reduce[(e.in_node.name, e.out_node.name)] == False: in_nodes.append(e.in_node.name) if len(out_nodes) == 1 and len(in_nodes) == 1: nodes_to_test.add(v_n) for v_n in list(nodes_to_test): v = self.nodes[v_n] out_nodes = [] for e in v.out_edges: if self.e_reduce[(e.in_node.name, e.out_node.name)] == False: out_nodes.append(e.out_node.name) in_nodes = [] for e in v.in_edges: if self.e_reduce[(e.in_node.name, e.out_node.name)] == False: in_nodes.append(e.in_node.name) in_node_name = in_nodes[0] for out_edge in self.nodes[in_node_name].out_edges: vv = out_edge.in_node.name ww = out_edge.out_node.name ww_out = self.nodes[ww].out_edges v_out = self.nodes[v_n].out_edges ww_out_nodes = set([n.out_node.name for n in ww_out]) v_out_nodes = set([n.out_node.name for n in v_out]) o_overlap = len(ww_out_nodes & v_out_nodes) ww_in_count = 0 for e in self.nodes[ww].in_edges: if self.e_reduce[(e.in_node.name, e.out_node.name)] == False: ww_in_count += 1 if ww != v_n and\ self.e_reduce[(vv, ww)] == False and\ ww_in_count > 1 and\ ww not in nodes_to_test and\ o_overlap == 0: edges_to_reduce.append((vv, ww)) out_node_name = out_nodes[0] for in_edge in self.nodes[out_node_name].in_edges: vv = in_edge.in_node.name ww = in_edge.out_node.name vv_in = self.nodes[vv].in_edges v_in = self.nodes[v_n].in_edges vv_in_nodes = set([n.in_node.name for n in vv_in]) v_in_nodes = set([n.in_node.name for n in v_in]) i_overlap = len(vv_in_nodes & v_in_nodes) vv_out_count = 0 for e in self.nodes[vv].out_edges: if self.e_reduce[(e.in_node.name, e.out_node.name)] == False: vv_out_count += 1 if vv != v_n and\ self.e_reduce[(vv, ww)] == False and\ vv_out_count > 1 and\ vv not in nodes_to_test and\ i_overlap == 0: edges_to_reduce.append((vv, ww)) removed_edges = set() for e in edges_to_reduce: self.e_reduce[e] = True removed_edges.add(e) return removed_edges def get_out_edges_for_node(self, name, mask=True): rtn = [] for e in self.nodes[name].out_edges: v = e.in_node w = e.out_node if self.e_reduce[(v.name, w.name)] == False: rtn.append(e) return rtn def get_in_edges_for_node(self, name, mask=True): rtn = [] for e in self.nodes[name].in_edges: v = e.in_node w = e.out_node if self.e_reduce[(v.name, w.name)] == False: rtn.append(e) return rtn def get_best_out_edge_for_node(self, name, mask=True): rtn = [] for e in self.nodes[name].out_edges: v = e.in_node w = e.out_node if self.e_reduce[(v.name, w.name)] == False: rtn.append(e) rtn.sort(key=lambda e: e.attr["score"]) return rtn[-1] def get_best_in_edge_for_node(self, name, mask=True): rtn = [] for e in self.nodes[name].in_edges: v = e.in_node w = e.out_node if self.e_reduce[(v.name, w.name)] == False: rtn.append(e) rtn.sort(key=lambda e: e.attr["score"]) return rtn[-1] def reverse_edge(e): e1, e2 = e return reverse_end(e2), reverse_end(e1) def reverse_path(p): p = p[::-1] return [reverse_end(n) for n in p] def find_bundle(ug, u_edge_data, start_node, depth_cutoff, width_cutoff, length_cutoff): tips = set() bundle_edges = set() bundle_nodes = set() local_graph = nx.ego_graph(ug, start_node, depth_cutoff, undirected=False) length_to_node = {start_node: 0} score_to_node = {start_node: 0} v = start_node end_node = start_node if DEBUG_LOG_LEVEL > 1: print() print() print("start", start_node) bundle_nodes.add(v) for vv, ww, kk in local_graph.out_edges(v, keys=True): max_score = 0 max_length = 0 if (vv, ww, kk) not in bundle_edges and\ reverse_end(ww) not in bundle_nodes: bundle_edges.add((vv, ww, kk)) tips.add(ww) for v in list(tips): bundle_nodes.add(v) depth = 1 width = 1.0 converage = False while 1: if DEBUG_LOG_LEVEL > 1: print("# of tips", len(tips)) if len(tips) > 4: converage = False break if len(tips) == 1: end_node = tips.pop() if DEBUG_LOG_LEVEL > 1: print("end", end_node) if end_node not in length_to_node: v = end_node max_score_edge = None max_score = 0 for uu, vv, kk in local_graph.in_edges(v, keys=True): if uu not in length_to_node: continue score = u_edge_data[(uu, vv, kk)][1] if score > max_score: max_score = score max_score_edge = (uu, vv, kk) length_to_node[v] = length_to_node[max_score_edge[0] ] + u_edge_data[max_score_edge][0] score_to_node[v] = score_to_node[max_score_edge[0] ] + u_edge_data[max_score_edge][1] converage = True break depth += 1 width = 1.0 * len(bundle_edges) / depth if depth > 10 and width > width_cutoff: converage = False break if depth > depth_cutoff: converage = False break tips_list = list(tips) tip_updated = False loop_detect = False length_limit_reached = False for v in tips_list: if DEBUG_LOG_LEVEL > 1: print("process", v) if len(local_graph.out_edges(v, keys=True)) == 0: # dead end route print("no out edge", v) continue max_score_edge = None max_score = 0 extend_tip = True for uu, vv, kk in local_graph.in_edges(v, keys=True): if DEBUG_LOG_LEVEL > 1: print("in_edges", uu, vv, kk) print(uu, "in length_to_node", uu in length_to_node) if uu not in length_to_node: extend_tip = False break score = u_edge_data[(uu, vv, kk)][1] if score > max_score: max_score = score max_score_edge = (uu, vv, kk) if extend_tip: length_to_node[v] = length_to_node[max_score_edge[0] ] + u_edge_data[max_score_edge][0] score_to_node[v] = score_to_node[max_score_edge[0] ] + u_edge_data[max_score_edge][1] if length_to_node[v] > length_cutoff: length_limit_reached = True converage = False break v_updated = False for vv, ww, kk in local_graph.out_edges(v, keys=True): if DEBUG_LOG_LEVEL > 1: print("test", vv, ww, kk) if ww in length_to_node: loop_detect = True if DEBUG_LOG_LEVEL > 1: print("loop_detect", ww) break if (vv, ww, kk) not in bundle_edges and\ reverse_end(ww) not in bundle_nodes: if DEBUG_LOG_LEVEL > 1: print("add", ww) tips.add(ww) bundle_edges.add((vv, ww, kk)) tip_updated = True v_updated = True if v_updated: if DEBUG_LOG_LEVEL > 1: print("remove", v) tips.remove(v) if len(tips) == 1: break if loop_detect: converage = False break if length_limit_reached: converage = False break if loop_detect: converage = False break if not tip_updated: converage = False break for v in list(tips): bundle_nodes.add(v) data = start_node, end_node, bundle_edges, length_to_node[ end_node], score_to_node[end_node], depth data_r = None if DEBUG_LOG_LEVEL > 1: print(converage, data, data_r) return converage, data, data_r def generate_string_graph(args): overlap_file = args.overlap_file contained_reads = set() chimer_ids = set() filter_reads = False seqs = set() G = nx.Graph() edges = set() overlap_data = [] contained_reads = set() overlap_count = {} # loop through the overlapping data to load the data in the a python array # contained reads are identified def process_fields(l): # work around for some ill formed data recored # if len(l) != 13: # continue f_id, g_id, score, identity = l[:4] if f_id == g_id: # don't need self-self overlapping return if filter_reads: if g_id not in seqs: return if f_id not in seqs: return score = int(score) identity = float(identity) contained = l[12] if contained == "contained": contained_reads.add(f_id) return if contained == "contains": contained_reads.add(g_id) return if contained == "none": return if identity < args.min_idt: # only take record with >96% identity as overlapped reads return f_strain, f_start, f_end, f_len = (int(c) for c in l[4:8]) g_strain, g_start, g_end, g_len = (int(c) for c in l[8:12]) # only used reads longer than the 4kb for assembly if f_len < args.min_len: return if g_len < args.min_len: return """ # double check for proper overlap # this is not necessary when using DALIGNER for overlapper # it may be useful if other overlappers give fuzzier alignment boundary if f_start > 24 and f_len - f_end > 24: # allow 24 base tolerance on both sides of the overlapping return if g_start > 24 and g_len - g_end > 24: return if g_strain == 0: if f_start < 24 and g_len - g_end > 24: return if g_start < 24 and f_len - f_end > 24: return else: if f_start < 24 and g_start > 24: return if g_start < 24 and f_start > 24: return """ overlap_data.append((f_id, g_id, score, identity, f_strain, f_start, f_end, f_len, g_strain, g_start, g_end, g_len)) overlap_count[f_id] = overlap_count.get(f_id, 0) + 1 overlap_count[g_id] = overlap_count.get(g_id, 0) + 1 with open(overlap_file) as f: n = 0 for line in f: if line.startswith('-'): break l = line.strip().split() process_fields(l) n += 1 else: # This happens only if we did not 'break' from the for-loop. msg = 'No end-of-file marker for overlap_file {!r} after {} lines.'.format( overlap_file, n) raise Exception(msg) overlap_set = set() sg = StringGraph() for od in overlap_data: f_id, g_id, score, identity = od[:4] if f_id in contained_reads: continue if g_id in contained_reads: continue f_s, f_b, f_e, f_l = od[4:8] g_s, g_b, g_e, g_l = od[8:12] overlap_pair = [f_id, g_id] overlap_pair.sort() overlap_pair = tuple(overlap_pair) if overlap_pair in overlap_set: # don't allow duplicated records continue else: overlap_set.add(overlap_pair) if g_s == 1: # revered alignment, swapping the begin and end coordinates g_b, g_e = g_e, g_b # build the string graph edges for each overlap if f_b > 0: if g_b < g_e: """ f.B f.E f -----------> g -------------> g.B g.E """ if f_b == 0 or g_e - g_l == 0: continue sg.add_edge("%s:B" % g_id, "%s:B" % f_id, label=(f_id, f_b, 0), length=abs(f_b - 0), score=-score, identity=identity) sg.add_edge("%s:E" % f_id, "%s:E" % g_id, label=(g_id, g_e, g_l), length=abs(g_e - g_l), score=-score, identity=identity) else: """ f.B f.E f -----------> g <------------- g.E g.B """ if f_b == 0 or g_e == 0: continue sg.add_edge("%s:E" % g_id, "%s:B" % f_id, label=(f_id, f_b, 0), length=abs(f_b - 0), score=-score, identity=identity) sg.add_edge("%s:E" % f_id, "%s:B" % g_id, label=(g_id, g_e, 0), length=abs(g_e - 0), score=-score, identity=identity) else: if g_b < g_e: """ f.B f.E f -----------> g -------------> g.B g.E """ if g_b == 0 or f_e - f_l == 0: continue sg.add_edge("%s:B" % f_id, "%s:B" % g_id, label=(g_id, g_b, 0), length=abs(g_b - 0), score=-score, identity=identity) sg.add_edge("%s:E" % g_id, "%s:E" % f_id, label=(f_id, f_e, f_l), length=abs(f_e - f_l), score=-score, identity=identity) else: """ f.B f.E f -----------> g <------------- g.E g.B """ if g_b - g_l == 0 or f_e - f_l == 0: continue sg.add_edge("%s:B" % f_id, "%s:E" % g_id, label=(g_id, g_b, g_l), length=abs(g_b - g_l), score=-score, identity=identity) sg.add_edge("%s:B" % g_id, "%s:E" % f_id, label=(f_id, f_e, f_l), length=abs(f_e - f_l), score=-score, identity=identity) sg.init_reduce_dict() sg.mark_tr_edges() # mark those edges that transitive redundant if DEBUG_LOG_LEVEL > 1: print(sum([1 for c in itervalues(sg.e_reduce) if c == True])) print(sum([1 for c in itervalues(sg.e_reduce) if c == False])) if not args.disable_chimer_bridge_removal: chimer_nodes, chimer_edges = sg.mark_chimer_edges() with open("chimers_nodes", "w") as f: for n in chimer_nodes: print(n, file=f) del chimer_nodes else: chimer_edges = set() # empty set spur_edges = sg.mark_spur_edge() removed_edges = set() if args.lfc == True: removed_edges = sg.resolve_repeat_edges() else: # mark those edges that are best overlap edges removed_edges = sg.mark_best_overlap() spur_edges.update(sg.mark_spur_edge()) if DEBUG_LOG_LEVEL > 1: print(sum([1 for c in itervalues(sg.e_reduce) if c == False])) out_f = open("sg_edges_list", "w") nxsg = nx.DiGraph() edge_data = {} for v, w in sg.edges: e = sg.edges[(v, w)] rid, sp, tp = e.attr["label"] score = e.attr["score"] identity = e.attr["identity"] length = abs(sp - tp) if sg.e_reduce[(v, w)] != True: type_ = "G" label = "%s:%d-%d" % (rid, sp, tp) nxsg.add_edge(v, w, label=label, length=length, score=score) edge_data[(v, w)] = (rid, sp, tp, length, score, identity, type_) if w in sg.best_in: nxsg.node[w]["best_in"] = v elif (v, w) in chimer_edges: type_ = "C" elif (v, w) in removed_edges: type_ = "R" elif (v, w) in spur_edges: type_ = "S" elif sg.e_reduce[(v, w)] == True: type_ = "TR" line = '%s %s %s %5d %5d %5d %5.2f %s' % ( v, w, rid, sp, tp, score, identity, type_) print(line, file=out_f) out_f.close() nxsg_r = nxsg.reverse() return nxsg, nxsg_r, edge_data def construct_compound_paths(ug, u_edge_data): source_nodes = set() sink_nodes = set() simple_nodes = set() branch_nodes = set() all_nodes = ug.nodes() for n in all_nodes: in_degree = len(ug.in_edges(n)) out_degree = len(ug.out_edges(n)) if in_degree == 0: source_nodes.add(n) if out_degree == 0: sink_nodes.add(n) if in_degree == 1 and out_degree == 1: simple_nodes.add(n) if in_degree > 1 or out_degree > 1: branch_nodes.add(n) # print "#", len(all_nodes),len(source_nodes), len(sink_nodes), len(simple_nodes), len(branch_nodes) compound_paths_0 = [] for p in list(branch_nodes): if ug.out_degree(p) > 1: coverage, data, data_r = find_bundle( ug, u_edge_data, p, 48, 16, 500000) if coverage == True: start_node, end_node, bundle_edges, length, score, depth = data compound_paths_0.append( (start_node, "NA", end_node, 1.0 * len(bundle_edges) / depth, length, score, bundle_edges)) compound_paths_0.sort(key=lambda x: -len(x[6])) edge_to_cpath = {} compound_paths_1 = {} for s, v, t, width, length, score, bundle_edges in compound_paths_0: if DEBUG_LOG_LEVEL > 1: print("constructing utg, test ", s, v, t) overlapped = False for vv, ww, kk in list(bundle_edges): if (vv, ww, kk) in edge_to_cpath: if DEBUG_LOG_LEVEL > 1: print("remove overlapped utg", (s, v, t), (vv, ww, kk)) overlapped = True break rvv = reverse_end(vv) rww = reverse_end(ww) rkk = reverse_end(kk) if (rww, rvv, rkk) in edge_to_cpath: if DEBUG_LOG_LEVEL > 1: print("remove overlapped r utg", (s, v, t), (rww, rvv, rkk)) overlapped = True break if not overlapped: if DEBUG_LOG_LEVEL > 1: print("constructing", s, v, t) bundle_edges_r = [] rs = reverse_end(t) rt = reverse_end(s) for vv, ww, kk in list(bundle_edges): edge_to_cpath.setdefault((vv, ww, kk), set()) edge_to_cpath[(vv, ww, kk)].add((s, t, v)) rvv = reverse_end(ww) rww = reverse_end(vv) rkk = reverse_end(kk) edge_to_cpath.setdefault((rvv, rww, rkk), set()) edge_to_cpath[(rvv, rww, rkk)].add( (rs, rt, v)) # assert v == "NA" bundle_edges_r.append((rvv, rww, rkk)) compound_paths_1[(s, v, t)] = width, length, score, bundle_edges compound_paths_1[(rs, v, rt) ] = width, length, score, bundle_edges_r compound_paths_2 = {} edge_to_cpath = {} for s, v, t in compound_paths_1: rs = reverse_end(t) rt = reverse_end(s) if (rs, "NA", rt) not in compound_paths_1: if DEBUG_LOG_LEVEL > 1: print("non_compliment bundle", s, v, t, len(compound_paths_1[(s, v, t)][-1])) continue width, length, score, bundle_edges = compound_paths_1[(s, v, t)] compound_paths_2[(s, v, t)] = width, length, score, bundle_edges for vv, ww, kk in list(bundle_edges): edge_to_cpath.setdefault((vv, ww, kk), set()) edge_to_cpath[(vv, ww, kk)].add((s, t, v)) compound_paths_3 = {} for (k, val) in viewitems(compound_paths_2): start_node, NA, end_node = k rs = reverse_end(end_node) rt = reverse_end(start_node) assert (rs, "NA", rt) in compound_paths_2 contained = False for vv, ww, kk in ug.out_edges(start_node, keys=True): if len(edge_to_cpath.get((vv, ww, kk), [])) > 1: contained = True if not contained: compound_paths_3[k] = val if DEBUG_LOG_LEVEL > 1: print("compound", k) compound_paths = {} for s, v, t in compound_paths_3: rs = reverse_end(t) rt = reverse_end(s) if (rs, "NA", rt) not in compound_paths_3: continue compound_paths[(s, v, t)] = compound_paths_3[(s, v, t)] return compound_paths def identify_simple_paths(sg2, edge_data): # utg construction phase 1, identify all simple paths simple_paths = dict() s_nodes = set() t_nodes = set() simple_nodes = set() all_nodes = sg2.nodes() for n in all_nodes: in_degree = len(sg2.in_edges(n)) out_degree = len(sg2.out_edges(n)) if in_degree == 1 and out_degree == 1: simple_nodes.add(n) else: if out_degree != 0: s_nodes.add(n) if in_degree != 0: t_nodes.add(n) free_edges = set(sg2.edges()) if DEBUG_LOG_LEVEL > 1: for s in list(simple_nodes): print("simple_node", s) for s in list(s_nodes): print("s_node", s) for s in list(t_nodes): print("t_node", s) for v, w in free_edges: if (reverse_end(w), reverse_end(v)) not in free_edges: print("bug", v, w) print(reverse_end(w), reverse_end(v)) while free_edges: if s_nodes: n = s_nodes.pop() if DEBUG_LOG_LEVEL > 1: print("initial utg 1", n) else: e = free_edges.pop() free_edges.add(e) n = e[0] if DEBUG_LOG_LEVEL > 1: print("initial utg 2", n) path = [] path_length = 0 path_score = 0 for v, w in sg2.out_edges(n): if (v, w) not in free_edges: continue rv = reverse_end(v) rw = reverse_end(w) path_length = 0 path_score = 0 v0 = v w0 = w path = [v, w] path_edges = set() path_edges.add((v, w)) path_length += edge_data[(v, w)][3] path_score += edge_data[(v, w)][4] free_edges.remove((v, w)) r_path_length = 0 r_path_score = 0 rv0 = rv rw0 = rw r_path = [rv, rw] # need to reverse again r_path_edges = set() r_path_edges.add((rw, rv)) r_path_length += edge_data[(rw, rv)][3] r_path_score += edge_data[(rw, rv)][4] free_edges.remove((rw, rv)) while w in simple_nodes: w, w_ = sg2.out_edges(w)[0] if (w, w_) not in free_edges: break rw_, rw = reverse_end(w_), reverse_end(w) if (rw_, rw) in path_edges: break path.append(w_) path_edges.add((w, w_)) path_length += edge_data[(w, w_)][3] path_score += edge_data[(w, w_)][4] free_edges.remove((w, w_)) r_path.append(rw_) r_path_edges.add((rw_, rw)) r_path_length += edge_data[(rw_, rw)][3] r_path_score += edge_data[(rw_, rw)][4] free_edges.remove((rw_, rw)) w = w_ simple_paths[(v0, w0, path[-1])] = path_length, path_score, path r_path.reverse() assert r_path[0] == reverse_end(path[-1]) simple_paths[(r_path[0], rw0, rv0) ] = r_path_length, r_path_score, r_path if DEBUG_LOG_LEVEL > 1: print(path_length, path_score, path) #dual_path[ (r_path[0], rw0, rv0) ] = (v0, w0, path[-1]) #dual_path[ (v0, w0, path[-1]) ] = (r_path[0], rw0, rv0) return simple_paths def identify_spurs(ug, u_edge_data, spur_len): # identify spurs in the utg graph # Currently, we use ad-hoc logic filtering out shorter utg, but we can # add proper alignment comparison later to remove redundant utgs # Side-effect: Modifies u_edge_data ug2 = ug.copy() s_candidates = set() for v in ug2.nodes(): if ug2.in_degree(v) == 0: s_candidates.add(v) while len(s_candidates) > 0: n = s_candidates.pop() if ug2.in_degree(n) != 0: continue n_ego_graph = nx.ego_graph(ug2, n, radius=10) n_ego_node_set = set(n_ego_graph.nodes()) for b_node in n_ego_graph.nodes(): if ug2.in_degree(b_node) <= 1: continue with_extern_node = False b_in_nodes = [e[0] for e in ug2.in_edges(b_node)] if len(b_in_nodes) == 1: continue for v in b_in_nodes: if v not in n_ego_node_set: with_extern_node = True break if not with_extern_node: continue s_path = nx.shortest_path(ug2, n, b_node) v1 = s_path[0] total_length = 0 for v2 in s_path[1:]: for s, t, v in ug2.out_edges(v1, keys=True): if t != v2: continue length, score, edges, type_ = u_edge_data[(s, t, v)] total_length += length v1 = v2 if total_length >= spur_len: continue v1 = s_path[0] for v2 in s_path[1:]: for s, t, v in ug2.out_edges(v1, keys=True): if t != v2: continue length, score, edges, type_ = u_edge_data[(s, t, v)] rs = reverse_end(t) rt = reverse_end(s) rv = reverse_end(v) try: ug2.remove_edge(s, t, key=v) ug2.remove_edge(rs, rt, key=rv) u_edge_data[(s, t, v)] = length, score, edges, "spur:2" u_edge_data[(rs, rt, rv) ] = length, score, edges, "spur:2" except Exception: pass if ug2.in_degree(v2) == 0: s_candidates.add(v2) v1 = v2 break return ug2 def remove_dup_simple_path(ug, u_edge_data): # identify simple dup path # if there are many multiple simple path of length connect s and t, e.g. s->v1->t, and s->v2->t, we will only keep one # Side-effect: Modifies u_edge_data ug2 = ug.copy() simple_edges = set() dup_edges = {} for s, t, v in u_edge_data: length, score, edges, type_ = u_edge_data[(s, t, v)] if len(edges) > 3: continue if type_ == "simple": if (s, t) in simple_edges: dup_edges[(s, t)].append(v) else: simple_edges.add((s, t)) dup_edges[(s, t)] = [v] for s, t in dup_edges: vl = dup_edges[(s, t)] vl.sort() for v in vl[1:]: ug2.remove_edge(s, t, key=v) length, score, edges, type_ = u_edge_data[(s, t, v)] u_edge_data[(s, t, v)] = length, score, edges, "simple_dup" return ug2 def construct_c_path_from_utgs(ug, u_edge_data, sg): # Side-effects: None, I think. s_nodes = set() #t_nodes = set() simple_nodes = set() simple_out = set() #simple_in = set() all_nodes = ug.nodes() for n in all_nodes: in_degree = len(ug.in_edges(n)) out_degree = len(ug.out_edges(n)) if in_degree == 1 and out_degree == 1: simple_nodes.add(n) else: if out_degree != 0: s_nodes.add(n) # if in_degree != 0: # t_nodes.add(n) if out_degree == 1: simple_out.add(n) # if in_degree == 1: # simple_in.add(n) c_path = [] free_edges = set() for s, t, v in ug.edges(keys=True): free_edges.add((s, t, v)) while free_edges: if s_nodes: n = s_nodes.pop() else: e = free_edges.pop() n = e[0] for s, t, v in ug.out_edges(n, keys=True): path_start = n path_end = None path_key = None path = [] path_length = 0 path_score = 0 path_nodes = set() path_nodes.add(s) if DEBUG_LOG_LEVEL > 1: print("check 1", s, t, v) path_key = t t0 = s while t in simple_out: if t in path_nodes: break rt = reverse_end(t) if rt in path_nodes: break length, score, path_or_edges, type_ = u_edge_data[(t0, t, v)] """ If the next node has two in-edges and the current path has the best overlap, we will extend the contigs. Otherwise, we will terminate the contig extension. This can help reduce some mis-assemblies but it can still construct long contigs when there is an oppertunity (assuming the best overlap has the highest likelihood to be correct.) """ if len(ug.in_edges(t, keys=True)) > 1: best_in_node = sg.node[t]["best_in"] if type_ == "simple" and best_in_node != path_or_edges[-2]: break if type_ == "compound": t_in_nodes = set() for ss, vv, tt in path_or_edges: if tt != t: continue length, score, path_or_edges, type_ = u_edge_data[( ss, vv, tt)] if path_or_edges[-1] == tt: t_in_nodes.add(path_or_edges[-2]) if best_in_node not in t_in_nodes: break # ---------------- path.append((t0, t, v)) path_nodes.add(t) path_length += length path_score += score # t is "simple_out" node assert len(ug.out_edges(t, keys=True)) == 1 t0, t, v = ug.out_edges(t, keys=True)[0] path.append((t0, t, v)) length, score, path_or_edges, type_ = u_edge_data[(t0, t, v)] path_length += length path_score += score path_nodes.add(t) path_end = t c_path.append((path_start, path_key, path_end, path_length, path_score, path, len(path))) if DEBUG_LOG_LEVEL > 1: print("c_path", path_start, path_key, path_end, path_length, path_score, len(path)) for e in path: if e in free_edges: free_edges.remove(e) if DEBUG_LOG_LEVEL > 1: print("left over edges:", len(free_edges)) return c_path def ovlp_to_graph(args): # transitivity reduction, remove spurs, remove putative edges caused by repeats sg, sg_r, edge_data = generate_string_graph(args) #dual_path = {} sg2 = nx.DiGraph() for v, w in edge_data: assert (reverse_end(w), reverse_end(v)) in edge_data # if (v, w) in masked_edges: # continue rid, sp, tp, length, score, identity, type_ = edge_data[(v, w)] if type_ != "G": continue label = "%s:%d-%d" % (rid, sp, tp) sg2.add_edge(v, w, label=label, length=length, score=score) simple_paths = identify_simple_paths(sg2, edge_data) ug = nx.MultiDiGraph() u_edge_data = {} circular_path = set() for s, v, t in simple_paths: length, score, path = simple_paths[(s, v, t)] u_edge_data[(s, t, v)] = (length, score, path, "simple") if s != t: ug.add_edge(s, t, key=v, type_="simple", via=v, length=length, score=score) else: circular_path.add((s, t, v)) if DEBUG_LOG_LEVEL > 1: with open("utg_data0", "w") as f: for s, t, v in u_edge_data: rs = reverse_end(t) rt = reverse_end(s) rv = reverse_end(v) assert (rs, rt, rv) in u_edge_data length, score, path_or_edges, type_ = u_edge_data[(s, t, v)] if type_ == "compound": path_or_edges = "|".join( [ss + "~" + vv + "~" + tt for ss, tt, vv in path_or_edges]) else: path_or_edges = "~".join(path_or_edges) print(s, v, t, type_, length, score, path_or_edges, file=f) ug2 = identify_spurs(ug, u_edge_data, 50000) ug2 = remove_dup_simple_path(ug2, u_edge_data) # phase 2, finding all "consistent" compound paths compound_paths = construct_compound_paths(ug2, u_edge_data) compound_path_file = open("c_path", "w") ug2_edges = set(ug2.edges(keys=True)) edges_to_remove = set() for s, v, t in compound_paths: width, length, score, bundle_edges = compound_paths[(s, v, t)] print(s, v, t, width, length, score, "|".join( [e[0] + "~" + e[2] + "~" + e[1] for e in bundle_edges]), file=compound_path_file) for ss, tt, vv in bundle_edges: if (ss, tt, vv) in ug2_edges: edges_to_remove.add((ss, tt, vv)) for s, t, v in edges_to_remove: ug2.remove_edge(s, t, v) length, score, edges, type_ = u_edge_data[(s, t, v)] if type_ != "spur": u_edge_data[(s, t, v)] = length, score, edges, "contained" for s, v, t in compound_paths: width, length, score, bundle_edges = compound_paths[(s, v, t)] u_edge_data[(s, t, v)] = (length, score, bundle_edges, "compound") ug2.add_edge(s, t, key=v, via=v, type_="compound", length=length, score=score) assert v == "NA" rs = reverse_end(t) rt = reverse_end(s) assert (rs, v, rt) in compound_paths #dual_path[ (s, v, t) ] = (rs, v, rt) #dual_path[ (rs, v, rt) ] = (s, v, t) compound_path_file.close() # remove short utg using local flow consistent rule """ short UTG like this can be removed, this kind of utg are likely artifects of repeats >____ _____> \__UTG_>__/ <____/ \_____< """ ug_edge_to_remove = set() for s, t, v in ug2.edges(keys=True): if ug2.in_degree(s) == 1 and ug2.out_degree(s) == 2 and \ ug2.in_degree(t) == 2 and ug2.out_degree(t) == 1: length, score, path_or_edges, type_ = u_edge_data[(s, t, v)] if length < 60000: rs = reverse_end(t) rt = reverse_end(s) rv = reverse_end(v) ug_edge_to_remove.add((s, t, v)) ug_edge_to_remove.add((rs, rt, rv)) for s, t, v in list(ug_edge_to_remove): ug2.remove_edge(s, t, key=v) length, score, edges, type_ = u_edge_data[(s, t, v)] u_edge_data[(s, t, v)] = length, score, edges, "repeat_bridge" ug = ug2 # Repeat the aggresive spur filtering with slightly larger spur length. ug2 = identify_spurs(ug, u_edge_data, 80000) ug = ug2 with open("utg_data", "w") as f: for s, t, v in u_edge_data: length, score, path_or_edges, type_ = u_edge_data[(s, t, v)] if v == "NA": path_or_edges = "|".join( [ss + "~" + vv + "~" + tt for ss, tt, vv in path_or_edges]) else: path_or_edges = "~".join(path_or_edges) print(s, v, t, type_, length, score, path_or_edges, file=f) # contig construction from utgs c_path = construct_c_path_from_utgs(ug, u_edge_data, sg) free_edges = set() for s, t, v in ug.edges(keys=True): free_edges.add((s, t, v)) ctg_id = 0 ctg_paths = open("ctg_paths", "w") c_path.sort(key=lambda x: -x[3]) for path_start, path_key, path_end, p_len, p_score, path, n_edges in c_path: length = 0 score = 0 length_r = 0 score_r = 0 non_overlapped_path = [] non_overlapped_path_r = [] for s, t, v in path: if v != "NA": rs, rt, rv = reverse_end(t), reverse_end(s), reverse_end(v) else: rs, rt, rv = reverse_end(t), reverse_end(s), "NA" if (s, t, v) in free_edges and (rs, rt, rv) in free_edges: non_overlapped_path.append((s, t, v)) non_overlapped_path_r.append((rs, rt, rv)) length += u_edge_data[(s, t, v)][0] score += u_edge_data[(s, t, v)][1] length_r += u_edge_data[(rs, rt, rv)][0] score_r += u_edge_data[(rs, rt, rv)][1] else: break if len(non_overlapped_path) == 0: continue s0, t0, v0 = non_overlapped_path[0] end_node = non_overlapped_path[-1][1] c_type_ = "ctg_linear" if (end_node != s0) else "ctg_circular" print("%06dF" % ctg_id, c_type_, s0 + "~" + v0 + "~" + \ t0, end_node, length, score, "|".join( [c[0] + "~" + c[2] + "~" + c[1] for c in non_overlapped_path]), file=ctg_paths) non_overlapped_path_r.reverse() s0, t0, v0 = non_overlapped_path_r[0] end_node = non_overlapped_path_r[-1][1] print("%06dR" % ctg_id, c_type_, s0 + "~" + v0 + "~" + \ t0, end_node, length_r, score_r, "|".join( [c[0] + "~" + c[2] + "~" + c[1] for c in non_overlapped_path_r]), file=ctg_paths) ctg_id += 1 for e in non_overlapped_path: if e in free_edges: free_edges.remove(e) for e in non_overlapped_path_r: if e in free_edges: free_edges.remove(e) for s, t, v in list(circular_path): length, score, path, type_ = u_edge_data[(s, t, v)] print("%6d" % ctg_id, "ctg_circular", s + \ "~" + v + "~" + t, t, length, score, s + "~" + v + "~" + t, file=ctg_paths) ctg_id += 1 ctg_paths.close() def main(argv=sys.argv): import argparse parser = argparse.ArgumentParser(description='a example string graph assembler that is desinged for handling diploid genomes', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument( '--overlap-file', default='preads.ovl', help='a file that contains the overlap information.') parser.add_argument( '--min_len', type=int, default=4000, help='minimum length of the reads to be considered for assembling') parser.add_argument( '--min_idt', type=float, default=96, help='minimum alignment identity of the reads to be considered for assembling') parser.add_argument( '--lfc', action="store_true", default=False, help='use local flow constraint method rather than best overlap method to resolve knots in string graph') parser.add_argument( '--disable_chimer_bridge_removal', action="store_true", default=False, help='disable chimer induced bridge removal') args = parser.parse_args(argv[1:]) ovlp_to_graph(args) if __name__ == "__main__": main(sys.argv) ================================================ FILE: falcon_kit/mains/pr_ctg_track.py ================================================ from __future__ import absolute_import from __future__ import print_function from falcon_kit.multiproc import Pool import falcon_kit.util.io as io import argparse import sys import glob import os from heapq import heappush, heappop, heappushpop Reader = io.CapturedProcessReaderContext def get_pid_to_ctg(fn): pid_to_ctg = {} with open(fn) as f: for row in f: row = row.strip().split() pid, rid, oid, ctg = row pid_to_ctg.setdefault(pid, set()) pid_to_ctg[pid].add(ctg) return pid_to_ctg def run_tr_stage1(db_fn, fn, min_len, bestn, pid_to_ctg): cmd = "LA4Falcon -mo %s %s" % (db_fn, fn) reader = Reader(cmd) with reader: return fn, tr_stage1(reader.readlines, min_len, bestn, pid_to_ctg) def tr_stage1(readlines, min_len, bestn, pid_to_ctg): """ for each read in the b-read column inside the LAS files, we keep top `bestn` hits with a priority queue through all overlaps """ rtn = {} for l in readlines(): l = l.strip().split() q_id, t_id = l[:2] overlap_len = -int(l[2]) idt = float(l[3]) q_s, q_e, q_l = int(l[5]), int(l[6]), int(l[7]) t_s, t_e, t_l = int(l[9]), int(l[10]), int(l[11]) if t_l < min_len: continue if q_id not in pid_to_ctg: continue rtn.setdefault(t_id, []) if len(rtn[t_id]) < bestn: heappush(rtn[t_id], (overlap_len, q_id)) else: heappushpop(rtn[t_id], (overlap_len, q_id)) return rtn def run_track_reads(exe_pool, base_dir, file_list, min_len, bestn, db_fn): io.LOG('preparing tr_stage1') io.logstats() asm_dir = os.path.abspath(os.path.join(base_dir, '2-asm-falcon')) pid_to_ctg = get_pid_to_ctg(os.path.join( asm_dir, 'read_maps', 'get_ctg_read_map', 'read_to_contig_map')) io.LOG('len(pid_to_ctg) == {}'.format(len(pid_to_ctg))) assert pid_to_ctg, 'Empty pid_to_ctg. Maybe empty {!r}?'.format(file_list) inputs = [] for fn in file_list: inputs.append((run_tr_stage1, db_fn, fn, min_len, bestn, pid_to_ctg)) """ Aggregate hits from each individual LAS and keep the best n hit. Note that this does not guarantee that the final results is globally the best n hits espcially when the number of `bestn` is too small. In those case, if there is more hits from single LAS file, then we will miss some good hits. """ bread_to_areads = {} for fn, res in exe_pool.imap(io.run_func, inputs): for k in res: bread_to_areads.setdefault(k, []) for item in res[k]: if len(bread_to_areads[k]) < bestn: heappush(bread_to_areads[k], item) else: heappushpop(bread_to_areads[k], item) assert bread_to_areads, 'No bread_to_areads found. Is there any point in continuing?' with open(os.path.join(asm_dir, "read_maps/pread_to_contigs"), "w") as out_f: for bread in bread_to_areads: ctg_score = {} for s, pid in bread_to_areads[bread]: if pid not in pid_to_ctg: continue ctgs = pid_to_ctg[pid] for ctg in ctgs: ctg_score.setdefault(ctg, [0, 0]) ctg_score[ctg][0] += -s ctg_score[ctg][1] += 1 ctg_score = list(ctg_score.items()) ctg_score.sort(key=lambda k: k[1][0]) rank = 0 for ctg, score_count in ctg_score: if bread in pid_to_ctg and ctg in pid_to_ctg[bread]: in_ctg = 1 else: in_ctg = 0 score, count = score_count print(bread, ctg, count, rank, score, in_ctg, file=out_f) rank += 1 def try_run_track_reads(n_core, base_dir, min_len, bestn): io.LOG('starting track_reads') pread_dir = os.path.abspath(os.path.join(base_dir, "1-preads_ovl")) file_list = glob.glob(os.path.join(pread_dir, "m*/preads.*.las")) io.LOG('file list: %r' % file_list) db_fn = os.path.join(pread_dir, "preads.db") n_core = min(n_core, len(file_list)) exe_pool = Pool(n_core) try: run_track_reads(exe_pool, base_dir, file_list, min_len, bestn, db_fn) io.LOG('finished track_reads') except: io.LOG('terminating track_reads workers...') exe_pool.terminate() raise def track_reads(n_core, base_dir, min_len, bestn, debug, silent, stream): if debug: n_core = 0 silent = False if silent: io.LOG = io.write_nothing if stream: global Reader Reader = io.StreamedProcessReaderContext try_run_track_reads(n_core, base_dir, min_len, bestn) def parse_args(argv): parser = argparse.ArgumentParser(description='scan the pread overlap information to identify the best hit from the preads \ to the contigs with read_to_contig_map generated by `fc_get_read_ctg_map` in `2-asm-falcon/read_maps/get_ctg_read_map/read_to_contig_map`', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--n_core', type=int, default=4, help='number of processes used for for tracking reads; ' '0 for main process only') #parser.add_argument('--fofn', type=str, help='file contains the path of all LAS file to be processed in parallel') #parser.add_argument('--db', type=str, dest='db_fn', help='read db file path') parser.add_argument('--base_dir', type=str, default="./", help='the base working dir of a FALCON assembly') parser.add_argument('--min_len', type=int, default=2500, help="min length of the reads") parser.add_argument('--stream', action='store_true', help='stream from LA4Falcon, instead of slurping all at once; can save memory for large data') parser.add_argument('--debug', '-g', action='store_true', help="single-threaded, plus other aids to debugging") parser.add_argument('--silent', action='store_true', help="suppress cmd reporting on stderr") parser.add_argument('--bestn', type=int, default=40, help="keep best n hits") args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) track_reads(**vars(args)) if __name__ == "__main__": main() ================================================ FILE: falcon_kit/mains/report_pre_assembly.py ================================================ #!/usr/bin/env python2.7 from __future__ import absolute_import from .. import stats_preassembly import argparse import json import logging log = logging.getLogger() def do_report(db, preads_fofn, genome_length, length_cutoff, out): kwds = dict( i_preads_fofn_fn=preads_fofn, i_raw_reads_db_fn=db, genome_length=genome_length, length_cutoff=length_cutoff, ) report_dict = stats_preassembly.calc_dict(**kwds) content = json.dumps(report_dict, sort_keys=True, indent=4, separators=(',', ': ')) open(out, 'w').write(content) def main(): parser = argparse.ArgumentParser() parser.add_argument('--genome-length', type=int, required=True, help='Estimated number of bases in the full genome haplotype.') parser.add_argument('--length-cutoff', type=int, required=True, help='Minimum length of any seed read.') parser.add_argument('--db', required=True, help='Path to raw_reads.db (dazzler DB)') parser.add_argument('--preads-fofn', required=True, help='Path to FOFN of preads fasta files.') parser.add_argument('--out', required=True, help='Path to JSON output file.') ARGS = parser.parse_args() do_report(**vars(ARGS)) if __name__ == "__main__": logging.basicConfig() log.setLevel(logging.DEBUG) main() ================================================ FILE: falcon_kit/mains/rr_ctg_track.py ================================================ from __future__ import absolute_import from __future__ import print_function from falcon_kit.multiproc import Pool import falcon_kit.util.io as io import argparse import sys import glob import os from heapq import heappush, heappop, heappushpop Reader = io.CapturedProcessReaderContext def get_rid_to_ctg(fn): rid_to_ctg = {} with open(fn) as f: for row in f: row = row.strip().split() pid, rid, oid, ctg = row rid_to_ctg.setdefault(rid, set()) rid_to_ctg[rid].add(ctg) return rid_to_ctg def run_tr_stage1(db_fn, fn, min_len, bestn, rid_to_ctg): cmd = "LA4Falcon -m %s %s" % (db_fn, fn) reader = Reader(cmd) with reader: return fn, tr_stage1(reader.readlines, min_len, bestn, rid_to_ctg) def tr_stage1(readlines, min_len, bestn, rid_to_ctg): """ for each read in the b-read column inside the LAS files, we keep top `bestn` hits with a priority queue through all overlaps """ rtn = {} for l in readlines(): l = l.strip().split() q_id, t_id = l[:2] overlap_len = -int(l[2]) idt = float(l[3]) q_s, q_e, q_l = int(l[5]), int(l[6]), int(l[7]) t_s, t_e, t_l = int(l[9]), int(l[10]), int(l[11]) if t_l < min_len: continue if q_id not in rid_to_ctg: continue rtn.setdefault(t_id, []) if len(rtn[t_id]) < bestn: heappush(rtn[t_id], (overlap_len, q_id)) else: heappushpop(rtn[t_id], (overlap_len, q_id)) return rtn def run_track_reads(exe_pool, base_dir, file_list, min_len, bestn, db_fn): io.LOG('preparing tr_stage1') io.logstats() asm_dir = os.path.abspath(os.path.join(base_dir, '2-asm-falcon')) rid_to_ctg = get_rid_to_ctg(os.path.join( asm_dir, 'read_maps', 'get_ctg_read_map', 'read_to_contig_map')) inputs = [] for fn in file_list: inputs.append((run_tr_stage1, db_fn, fn, min_len, bestn, rid_to_ctg)) """ Aggregate hits from each individual LAS and keep the best n hit. Note that this does not guarantee that the final results is globally the best n hits espcially when the number of `bestn` is too small. In those case, if there is more hits from single LAS file, then we will miss some good hits. """ bread_to_areads = {} for fn, res in exe_pool.imap(io.run_func, inputs): for k in res: bread_to_areads.setdefault(k, []) for item in res[k]: if len(bread_to_areads[k]) < bestn: heappush(bread_to_areads[k], item) else: heappushpop(bread_to_areads[k], item) #rid_to_oid = open(os.path.join(rawread_dir, 'dump_rawread_ids', 'raw_read_ids')).read().split('\n') """ For each b-read, we find the best contig map throgh the b->a->contig map. """ with open(os.path.join(asm_dir, 'read_maps/rawread_to_contigs'), 'w') as out_f: for bread in bread_to_areads: ctg_score = {} for s, rid in bread_to_areads[bread]: if rid not in rid_to_ctg: continue ctgs = rid_to_ctg[rid] for ctg in ctgs: ctg_score.setdefault(ctg, [0, 0]) ctg_score[ctg][0] += -s ctg_score[ctg][1] += 1 #oid = rid_to_oid[int(bread)] ctg_score = list(ctg_score.items()) ctg_score.sort(key=lambda k: k[1][0]) rank = 0 for ctg, score_count in ctg_score: if bread in rid_to_ctg and ctg in rid_to_ctg[bread]: in_ctg = 1 else: in_ctg = 0 score, count = score_count #print(bread, oid, ctg, count, rank, score, in_ctg, file=out_f) print(bread, ctg, count, rank, score, in_ctg, file=out_f) rank += 1 def try_run_track_reads(n_core, base_dir, min_len, bestn): io.LOG('starting track_reads') rawread_dir = os.path.abspath(os.path.join(base_dir, "0-rawreads")) # better logic for finding the las files path or move the logic to extern (taking the --fofn option?) file_list = glob.glob(os.path.join(rawread_dir, "m*/raw_reads.*.las")) io.LOG('file list: %r' % file_list) # same, shoud we decide this as a parameter db_fn = os.path.join(rawread_dir, "raw_reads.db") n_core = min(n_core, len(file_list)) exe_pool = Pool(n_core) try: run_track_reads(exe_pool, base_dir, file_list, min_len, bestn, db_fn) io.LOG('finished track_reads') except: io.LOG('terminating track_reads workers...') exe_pool.terminate() raise def track_reads(n_core, base_dir, min_len, bestn, debug, silent, stream): if debug: n_core = 0 silent = False if silent: io.LOG = io.write_nothing if stream: global Reader Reader = io.StreamedProcessReaderContext try_run_track_reads(n_core, base_dir, min_len, bestn) def parse_args(argv): parser = argparse.ArgumentParser(description='scan the raw read overlap information to identify the best hit from the reads \ to the contigs with read_to_contig_map generated by `fc_get_read_ctg_map` in `2-asm-falcon/read_maps/get_ctg_read_map/read_to_contig_map`', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--n_core', type=int, default=4, help='number of processes used for for tracking reads; ' '0 for main process only') #parser.add_argument('--fofn', type=str, help='file contains the path of all LAS file to be processed in parallel') #parser.add_argument('--db', type=str, dest='db_fn', help='read db file path') parser.add_argument('--base_dir', type=str, default="./", help='the base working dir of a FALCON assembly') parser.add_argument('--min_len', type=int, default=2500, help="min length of the reads") parser.add_argument('--stream', action='store_true', help='stream from LA4Falcon, instead of slurping all at once; can save memory for large data') parser.add_argument('--debug', '-g', action='store_true', help="single-threaded, plus other aids to debugging") parser.add_argument('--silent', action='store_true', help="suppress cmd reporting on stderr") parser.add_argument('--bestn', type=int, default=40, help="keep best n hits") args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) track_reads(**vars(args)) if __name__ == "__main__": main() ================================================ FILE: falcon_kit/mains/run1.py ================================================ from __future__ import absolute_import from ..pype import (wrap_gen_task as gen_task, gen_parallel_tasks, Dist) from .. import run_support as support from .. import bash, pype_tasks, snakemake from ..util.system import (only_these_symlinks, lfs_setstripe_maybe) from .. import io # pylint: disable=no-name-in-module, import-error, fixme, line-too-long from pypeflow.simple_pwatcher_bridge import (PypeProcWatcherWorkflow, MyFakePypeThreadTaskBase, makePypeLocalFile, fn, PypeTask) import argparse import glob import json import logging import os import re import sys import time LOG = logging.getLogger(__name__) # default, for remote tasks def create_daligner_tasks(basedir, scatter_fn): tasks = [] tasks_out = {} try: content = json.loads(open(scatter_fn).read()) # array of descriptions except Exception: msg = 'Failed to read JSON from {!r}'.format(scatter_fn) LOG.exception(msg) raise Exception(msg) for section in content: parameters = section['parameters'] inputs = section['inputs'] inputs['scatter_fn'] = os.path.abspath(scatter_fn) outputs = section['outputs'] URL = section['URL'] job_uid = parameters['job_uid'] wdir = os.path.join(basedir, 'job_%s' % job_uid) make_daligner_task = PypeTask(inputs=inputs, outputs=outputs, parameters=parameters, wdir=wdir, ) daligner_task = make_daligner_task(pype_tasks.task_run_daligner) tasks.append(daligner_task) # these are relative, so we need the PypeLocalFiles tasks_out['ajob_%s' % job_uid] = daligner_task.outputs['job_done'] return tasks, tasks_out def create_merge_tasks(basedir, scatter_fn): tasks = [] p_ids_merged_las = {} # for consensus content = json.loads(open(scatter_fn).read()) # array of descriptions for section in content: parameters = section['parameters'] inputs = section['inputs'] inputs['scatter_fn'] = os.path.abspath(scatter_fn) outputs = section['outputs'] URL = section['URL'] p_id = parameters['job_id'] wdir = os.path.join(basedir, 'm_%05d' % p_id) make_task = PypeTask(inputs=inputs, outputs=outputs, parameters=parameters, wdir=wdir, ) task = make_task(pype_tasks.task_run_las_merge) tasks.append(task) # these are relative, so we need the PypeLocalFiles las_fn = task.outputs['merged_las'] p_ids_merged_las[p_id] = las_fn return tasks, p_ids_merged_las def create_consensus_tasks(basedir, scatter_fn): consensus_tasks = [] consensus_out = {} content = json.loads(open(scatter_fn).read()) # array of descriptions for section in content: parameters = section['parameters'] inputs = section['inputs'] inputs['scatter_fn'] = scatter_fn outputs = section['outputs'] URL = section['URL'] p_id = int(parameters['job_id']) cns_label = 'cns_%05d' % int(p_id) wdir = os.path.join(basedir, 'preads', cns_label) make_c_task = PypeTask(inputs=inputs, outputs=outputs, parameters=parameters, wdir=wdir, ) c_task = make_c_task(pype_tasks.task_run_consensus) consensus_tasks.append(c_task) consensus_out['cjob_%d' % p_id] = outputs['out_file'] return consensus_tasks, consensus_out def create_merge_gather_task(wd, inputs): las_fofn_plf = makePypeLocalFile(os.path.join(wd, 'las.fofn')) las_fopfn_plf = makePypeLocalFile(os.path.join(wd, 'las.fopfn')) make_task = PypeTask(inputs=inputs, # p_ids_merged_las outputs={'las_fofn': las_fofn_plf, 'las_fopfn': las_fopfn_plf, }, ) task = make_task(pype_tasks.task_merge_gather) return task, las_fofn_plf, las_fopfn_plf def create_consensus_gather_task(wd, inputs): # Happens only in stage-0. preads_fofn_plf = makePypeLocalFile(os.path.join(wd, 'input_preads.fofn')) make_cns_gather_task = PypeTask( inputs=inputs, # consensus_out outputs={'preads_fofn': preads_fofn_plf}, ) task = make_cns_gather_task(pype_tasks.task_cns_gather) return task, preads_fofn_plf def main1(prog_name, input_config_fn, logger_config_fn=None): global LOG LOG = support.setup_logger(logger_config_fn) lfs_setstripe_maybe(path='.', stripe=12) LOG.info('fc_run started with configuration %s', input_config_fn) try: config = support.parse_cfg_file(input_config_fn) import json dumped = json.dumps(config, indent=2, separators=(',', ': '), sort_keys=True) LOG.info('cfg=\n{}'.format(dumped)) except Exception: LOG.exception('Failed to parse config "{}".'.format(input_config_fn)) raise general_config = config['General'] assert 'input_fofn' in general_config, 'Missing "input_fofn" in {}.'.format(input_config_fn) input_fofn_plf = makePypeLocalFile(general_config['input_fofn']) genome_size = int(general_config.get('genome_size', '0')) squash = True if 0 < genome_size < 1000000 else False wf = PypeProcWatcherWorkflow(job_defaults=config['job.defaults'], squash=squash, ) general_config['ver'] = '100' config_fn = './config.json' # must not be in a task-dir io.serialize(config_fn, config) with open('foo.snake', 'w') as snakemake_writer: rule_writer = snakemake.SnakemakeRuleWriter(snakemake_writer) run(wf, config, rule_writer, os.path.abspath(config_fn), input_fofn_plf=input_fofn_plf, ) def run(wf, config, rule_writer, config_fn, input_fofn_plf, ): """ Preconditions (for now): * LOG * run_support.logger """ parsed_config = io.deserialize(config_fn) if parsed_config != config: msg = 'Config from {!r} != passed config'.format(config_fn) raise Exception(msg) general_config = config['General'] general_config_fn = os.path.join(os.path.dirname(config_fn), 'General_config.json') io.serialize(general_config_fn, general_config) # Some tasks use this. rawread_dir = '0-rawreads' pread_dir = '1-preads_ovl' falcon_asm_dir = '2-asm-falcon' for d in (rawread_dir, pread_dir, falcon_asm_dir): support.make_dirs(d) # only matter for parallel jobs job_defaults = config['job.defaults'] exitOnFailure = bool(job_defaults.get('stop_all_jobs_on_failure', False)) default_njobs = int(job_defaults.get('njobs', 7)) wf.max_jobs = default_njobs assert general_config['input_type'] in ( 'raw', 'preads'), 'Invalid input_type=={!r}'.format(general_config['input_type']) # Store config as JSON, available to many tasks. if general_config['input_type'] == 'raw': parameters = {} # import sequences into daligner DB # calculate length_cutoff (if specified as -1) # split DB # run DBdust r_db_dust_fn = os.path.join(rawread_dir, 'build', 'raw_reads.db') length_cutoff_fn = os.path.join(rawread_dir, 'build', 'length_cutoff') wf.addTask(gen_task( script=pype_tasks.TASK_DB_BUILD_SCRIPT, inputs={ 'config': general_config_fn, 'input_fofn': fn(input_fofn_plf), }, outputs={ 'length_cutoff': length_cutoff_fn, 'db': r_db_dust_fn, # Also .raw_reads.*, of course. And dust track. }, parameters=dict( ), rule_writer=rule_writer, dist=Dist(NPROC=1), )) # run TANmask tan_uows_fn = os.path.join( rawread_dir, 'tan-split', 'tan-uows.json') tan_bash_template_fn = os.path.join( rawread_dir, 'tan-split', 'bash_template.sh') wf.addTask(gen_task( script=pype_tasks.TASK_DB_TAN_SPLIT_SCRIPT, inputs={ 'config': general_config_fn, 'db': r_db_dust_fn, }, outputs={ 'split': tan_uows_fn, 'bash_template': tan_bash_template_fn, }, parameters={}, rule_writer=rule_writer, dist=Dist(NPROC=1), )) gathered_fn = os.path.join(rawread_dir, 'tan-gathered', 'gathered-done-files.json') gen_parallel_tasks( wf, rule_writer, tan_uows_fn, gathered_fn, run_dict=dict( bash_template_fn=tan_bash_template_fn, script='fubar-TODO', #pype_tasks.TASK_DB_TAN_APPLY_SCRIPT, # for snakemake stuff inputs={ 'units_of_work': '0-rawreads/tan-chunks/{tan0_id}/some-units-of-work.json', }, outputs={ #'job_done': '0-rawreads/{dal0_id}/daligner.done', 'results': '0-rawreads/tan-runs/{tan0_id}/some-done-files.json', }, parameters={}, ), dist=Dist(NPROC=4, MB=4000, job_dict=config['job.step.da']), ) r_db_tan_fn = os.path.join(rawread_dir, 'tan-combine', 'raw_reads.db') wf.addTask(gen_task( script=pype_tasks.TASK_DB_TAN_COMBINE_SCRIPT, inputs={ 'config': general_config_fn, 'db': r_db_dust_fn, 'gathered': gathered_fn, }, outputs={ 'new_db': r_db_tan_fn, }, parameters={}, rule_writer=rule_writer, dist=Dist(local=True), )) # run daligner wf.max_jobs = config['job.step.da'].get('njobs', default_njobs) #rawreads_db_fn = os.path.join(rawread_dir, 'raw_reads.db') daligner_all_units_fn = os.path.join( rawread_dir, 'daligner-split', 'all-units-of-work.json') daligner_bash_template_fn = os.path.join( rawread_dir, 'daligner-split', 'daligner_bash_template.sh') params = dict(parameters) #params['db_prefix'] = 'raw_reads' #params['pread_aln'] = 0 params['skip_checks'] = int(general_config.get('skip_checks', 0)) params['wildcards'] = 'dal0_id' wf.addTask(gen_task( script=pype_tasks.TASK_DB_DALIGNER_SPLIT_SCRIPT, inputs={ 'config': general_config_fn, 'db': r_db_tan_fn, 'length_cutoff': length_cutoff_fn, }, outputs={ 'split': daligner_all_units_fn, 'bash_template': daligner_bash_template_fn }, parameters=params, rule_writer=rule_writer, dist=Dist(local=True, NPROC=4), # really, NPROC=1, but we need to know the max )) gathered_fn = os.path.join(rawread_dir, 'daligner-gathered', 'gathered-done-files.json') gen_parallel_tasks( wf, rule_writer, daligner_all_units_fn, gathered_fn, run_dict=dict( bash_template_fn=daligner_bash_template_fn, script=pype_tasks.TASK_DB_DALIGNER_APPLY_SCRIPT, # for snakemake stuff inputs={ 'units_of_work': os.path.join(rawread_dir, 'daligner-chunks/{dal0_id}/some-units-of-work.json'), }, outputs={ 'results': os.path.join(rawread_dir, 'daligner-runs/{dal0_id}/some-done-files.json'), }, parameters={}, ), dist=Dist(NPROC=4, MB=4000, job_dict=config['job.step.da']), ) r_gathered_las_fn = os.path.join(rawread_dir, 'daligner-combine', 'gathered-las.json') wf.addTask(gen_task( script=pype_tasks.TASK_DB_DALIGNER_COMBINE_SCRIPT, inputs={ 'config': general_config_fn, 'db': r_db_tan_fn, 'gathered': gathered_fn, }, outputs={ 'las_paths': r_gathered_las_fn, }, parameters={}, rule_writer=rule_writer, #dist=Dist(NPROC=1, MB=4000, job_dict=config['job.step.da']) dist=Dist(local=True), )) # Merge .las files. wf.max_jobs = config['job.step.la'].get('njobs', default_njobs) las_merge_all_units_fn = os.path.join(rawread_dir, 'las-merge-split', 'all-units-of-work.json') bash_template_fn = os.path.join(rawread_dir, 'las-merge-split', 'las-merge-bash-template.sh') params = dict(parameters) params['db_prefix'] = 'raw_reads' params['wildcards'] = 'mer0_id' wf.addTask(gen_task( script=pype_tasks.TASK_DB_LAMERGE_SPLIT_SCRIPT, inputs={ 'config': general_config_fn, 'las_paths': r_gathered_las_fn, }, outputs={ 'split': las_merge_all_units_fn, 'bash_template': bash_template_fn, }, parameters=params, rule_writer=rule_writer, dist=Dist(local=True), )) gathered_fn = os.path.join(rawread_dir, 'las-merge-gathered', 'gathered.json') gen_parallel_tasks( wf, rule_writer, las_merge_all_units_fn, gathered_fn, run_dict=dict( bash_template_fn=bash_template_fn, script=pype_tasks.TASK_DB_LAMERGE_APPLY_SCRIPT, # for snakemake inputs={ #'las_paths': './0-rawreads/merge-scripts/{mer0_id}/las_paths.json', #'merge_script': './0-rawreads/merge-scripts/{mer0_id}/merge-script.sh', #'merged_las_json': './0-rawreads/merge-scripts/{mer0_id}/merged_las.json', 'units_of_work': '0-rawreads/las-merge-chunks/{mer0_id}/some-units-of-work.json', }, outputs={ #'merged_las': './0-rawreads/{mer0_id}/merged.las', #'job_done': './0-rawreads/{mer0_id}/merge.done', 'results': '0-rawreads/las-merge-runs/{mer0_id}/some-las-paths.json', }, parameters={}, ), dist=Dist(NPROC=1, job_dict=config['job.step.la']), ) p_id2las_fn = os.path.join(rawread_dir, 'las-merge-combine', 'p_id2las.json') las_fofn_fn = os.path.join(rawread_dir, 'las-merge-combine', 'las_fofn.json') wf.addTask(gen_task( script=pype_tasks.TASK_DB_LAMERGE_COMBINE_SCRIPT, inputs={ 'config': general_config_fn, 'gathered': gathered_fn, }, outputs={ 'block2las': p_id2las_fn, 'las_paths': las_fofn_fn, }, parameters={}, rule_writer=rule_writer, dist=Dist(local=True), )) if general_config['target'] == 'overlapping': sys.exit(0) # Produce new FOFN of preads fasta, based on consensus of overlaps. wf.max_jobs = config['job.step.cns'].get('njobs', default_njobs) split_fn = os.path.join( rawread_dir, 'cns-split', 'split.json') bash_template_fn = os.path.join( rawread_dir, 'cns-split', 'consensus-bash-template.sh') params = dict(parameters) params['wildcards'] = 'cns0_id,cns0_id2' wf.addTask(gen_task( script=pype_tasks.TASK_CONSENSUS_SPLIT_SCRIPT, inputs={ 'p_id2las': p_id2las_fn, 'raw_reads_db': r_db_tan_fn, 'length_cutoff': length_cutoff_fn, 'config': general_config_fn, }, outputs={ 'split': split_fn, 'bash_template': bash_template_fn, }, parameters=params, rule_writer=rule_writer, dist=Dist(local=True), )) gathered_fn = os.path.join(rawread_dir, 'cns-gather', 'gathered.json') gen_parallel_tasks( wf, rule_writer, split_fn, gathered_fn, run_dict=dict( bash_template_fn=bash_template_fn, script=pype_tasks.TASK_CONSENSUS_TASK_SCRIPT, # for snakemake only inputs = { #'las': '0-rawreads/cns-split/{cns0_id}/merged.{cns0_id2}.las', #'db': r_db_tan_fn, #'length_cutoff': length_cutoff_fn, #'config': general_config_fn, 'units_of_work': '0-rawreads/cns-chunks/{cns0_id}/some-units-of-work.json', }, outputs = { #'fasta': '0-rawreads/consensus/{cns0_id}/consensus.{cns0_id2}.fasta', 'results': '0-rawreads/cns-runs/{cns0_id}/some-done-files.json', }, parameters={}, ), dist=Dist(NPROC=6, job_dict=config['job.step.cns']), ) preads_fofn_fn = os.path.join(rawread_dir, 'preads', 'input_preads.fofn') wf.addTask(gen_task( script=pype_tasks.TASK_CONSENSUS_GATHER_SCRIPT, inputs={ 'gathered': gathered_fn, }, outputs={ 'preads_fofn': preads_fofn_fn, }, parameters=parameters, #{}, rule_writer=rule_writer, dist=Dist(local=True), )) rdir = os.path.join(rawread_dir, 'report') pre_assembly_report_fn = os.path.join(rdir, 'pre_assembly_stats.json') params = dict(parameters) params['length_cutoff_user'] = general_config['length_cutoff'] params['genome_length'] = general_config['genome_size'] # note different name; historical wf.addTask(gen_task( script=pype_tasks.TASK_REPORT_PRE_ASSEMBLY_SCRIPT, inputs={'length_cutoff': length_cutoff_fn, 'raw_reads_db': r_db_tan_fn, 'preads_fofn': preads_fofn_fn, 'config': general_config_fn, }, outputs={'pre_assembly_report': pre_assembly_report_fn, }, parameters=params, rule_writer=rule_writer, dist=Dist(local=True), )) if general_config['target'] == 'pre-assembly': LOG.info('Quitting after stage-0 for "pre-assembly" target.') sys.exit(0) # build pread database if general_config['input_type'] == 'preads': """ preads_fofn_plf = makePypeLocalFile(os.path.join( pread_dir, 'preads-fofn-abs', os.path.basename(general_config['input_fofn']))) make_fofn_abs_task = PypeTask(inputs={'i_fofn': input_fofn_plf}, outputs={'o_fofn': preads_fofn_plf}, parameters={}, ) fofn_abs_task = make_fofn_abs_task( pype_tasks.task_make_fofn_abs_preads) wf.addTasks([fofn_abs_task]) wf.refreshTargets([fofn_abs_task]) """ raise Exception('TODO') pdb_build_done = os.path.join(pread_dir, 'pdb_build_done') run_jobs_fn = os.path.join(pread_dir, 'run_jobs.sh') preads_db_fn = os.path.join(pread_dir, 'build', 'preads.db') length_cutoff_pr_fn = os.path.join(pread_dir, 'build', 'length_cutoff') wf.addTask(gen_task( script=pype_tasks.TASK_DB_BUILD_SCRIPT, inputs={ 'config': general_config_fn, 'input_fofn': preads_fofn_fn, }, outputs={ 'length_cutoff': length_cutoff_pr_fn, 'db': preads_db_fn, # Also .preads.*, of course. }, parameters=dict( ), rule_writer=rule_writer, dist=Dist(NPROC=1), )) # run daligner wf.max_jobs = config['job.step.pda'].get('njobs', default_njobs) daligner_all_units_fn = os.path.join( pread_dir, 'daligner-split', 'all-units-of-work.json') daligner_bash_template_fn = os.path.join( pread_dir, 'daligner-split', 'daligner_bash_template.sh') params = dict(parameters) params['skip_checks'] = int(general_config.get('skip_checks', 0)) params['wildcards'] = 'dal1_id' wf.addTask(gen_task( script=pype_tasks.TASK_DB_DALIGNER_SPLIT_SCRIPT, inputs={ 'config': general_config_fn, 'db': preads_db_fn, #not tan, yet 'length_cutoff': length_cutoff_pr_fn, }, outputs={ 'split': daligner_all_units_fn, 'bash_template': daligner_bash_template_fn }, parameters=params, rule_writer=rule_writer, dist=Dist(local=True, NPROC=4), # really, NPROC=1, but we need to know the max )) gathered_fn = os.path.join(pread_dir, 'daligner-gathered', 'gathered-done-files.json') gen_parallel_tasks( wf, rule_writer, daligner_all_units_fn, gathered_fn, run_dict=dict( bash_template_fn=daligner_bash_template_fn, script=pype_tasks.TASK_DB_DALIGNER_APPLY_SCRIPT, # for snakemake stuff inputs={ 'units_of_work': os.path.join(pread_dir, 'daligner-chunks/{dal1_id}/some-units-of-work.json'), }, outputs={ 'results': os.path.join(pread_dir, 'daligner-runs/{dal1_id}/some-done-files.json'), }, parameters={}, ), dist=Dist(NPROC=4, MB=4000, job_dict=config['job.step.pda']), ) gathered_las_fn = os.path.join(pread_dir, 'daligner-combine', 'gathered-las.json') wf.addTask(gen_task( script=pype_tasks.TASK_DB_DALIGNER_COMBINE_SCRIPT, inputs={ 'config': general_config_fn, 'db': preads_db_fn, #r_db_tan_fn, 'gathered': gathered_fn, }, outputs={ 'las_paths': gathered_las_fn, }, parameters={}, rule_writer=rule_writer, #dist=Dist(NPROC=1, MB=4000, job_dict=config['job.step.pda']) dist=Dist(local=True), )) # Merge .las files. wf.max_jobs = config['job.step.pla'].get('njobs', default_njobs) las_merge_all_units_fn = os.path.join(pread_dir, 'las-merge-split', 'all-units-of-work.json') bash_template_fn = os.path.join(pread_dir, 'las-merge-split', 'las-merge-bash-template.sh') params = dict(parameters) params['db_prefix'] = 'preads' params['wildcards'] = 'mer1_id' wf.addTask(gen_task( script=pype_tasks.TASK_DB_LAMERGE_SPLIT_SCRIPT, inputs={ 'config': general_config_fn, 'las_paths': gathered_las_fn, }, outputs={ 'split': las_merge_all_units_fn, 'bash_template': bash_template_fn, }, parameters=params, rule_writer=rule_writer, dist=Dist(local=True), )) gathered_fn = os.path.join(pread_dir, 'las-merge-gathered', 'gathered.json') gen_parallel_tasks( wf, rule_writer, las_merge_all_units_fn, gathered_fn, run_dict=dict( bash_template_fn=bash_template_fn, script=pype_tasks.TASK_DB_LAMERGE_APPLY_SCRIPT, # for snakemake inputs={ 'units_of_work': os.path.join(pread_dir, 'las-merge-chunks/{mer0_id}/some-units-of-work.json'), }, outputs={ 'results': os.path.join(pread_dir, 'las-merge-runs/{mer0_id}/some-las-paths.json'), }, parameters={}, ), dist=Dist(NPROC=1, job_dict=config['job.step.la']), ) p_id2las_fn = os.path.join(pread_dir, 'las-merge-combine', 'block2las.json') las_fofn_fn = os.path.join(pread_dir, 'las-merge-combine', 'las_fofn.json') wf.addTask(gen_task( script=pype_tasks.TASK_DB_LAMERGE_COMBINE_SCRIPT, inputs={ 'config': general_config_fn, 'gathered': gathered_fn, }, outputs={ 'block2las': p_id2las_fn, 'las_paths': las_fofn_fn, }, parameters={}, rule_writer=rule_writer, dist=Dist(local=True), )) wf.max_jobs = config['job.step.asm'].get('njobs', default_njobs) db2falcon_dir = os.path.join(pread_dir, 'db2falcon') db2falcon_done_fn = os.path.join(db2falcon_dir, 'db2falcon_done') preads4falcon_fn = os.path.join(db2falcon_dir, 'preads4falcon.fasta') wf.addTask(gen_task( script=pype_tasks.TASK_RUN_DB_TO_FALCON_SCRIPT, inputs={'p_id2las': p_id2las_fn, 'preads_db': preads_db_fn, }, outputs={'job_done': db2falcon_done_fn, 'preads4falcon': preads4falcon_fn, }, parameters={}, rule_writer=rule_writer, dist=Dist(NPROC=4, job_dict=config['job.step.asm']), )) falcon_asm_done_fn = os.path.join(falcon_asm_dir, 'falcon_asm_done') for key in ('overlap_filtering_setting', 'length_cutoff_pr', 'fc_ovlp_to_graph_option'): parameters[key] = general_config[key] wf.addTask(gen_task( script=pype_tasks.TASK_RUN_FALCON_ASM_SCRIPT, inputs={'db2falcon_done': db2falcon_done_fn, 'db_file': preads_db_fn, 'preads4falcon_fasta': preads4falcon_fn, 'las_fofn': las_fofn_fn, 'config': general_config_fn, }, outputs={'falcon_asm_done': falcon_asm_done_fn}, parameters=parameters, rule_writer=rule_writer, dist=Dist(NPROC=4, job_dict=config['job.step.asm']), )) wf.refreshTargets() with io.cd('0-rawreads'): # for backwards-compatibility io.symlink('las-merge-combine', 'las-gather') #return falcon_asm_done def main(argv=sys.argv): parser = argparse.ArgumentParser() parser.add_argument('config', help='.cfg/.ini/.json') parser.add_argument('logger', nargs='?', help='(Optional)JSON config for standard Python logging module') args = parser.parse_args(argv[1:]) main1(argv[0], args.config, args.logger) if __name__ == '__main__': main() ================================================ FILE: falcon_kit/mains/symlink_mapped.py ================================================ #!/bin/env python2.7 from __future__ import absolute_import from future.utils import viewitems import argparse import json import os import sys def deserialize(fn): with open(fn) as ifs: return json.loads(ifs.read()) def assert_exists(fn): if not os.path.isfile(fn): raise Exception('Does not exist: {!r}'.format(fn)) def mkdir(dirname): if not os.path.isdir(dirname): # Possible race-condition, so dirs must be created serially. os.makedirs(dirname) def symlink(name, target): msg = '{} -> {}'.format(name, target) assert not os.path.lexists(name), msg #print msg os.symlink(target, name) def run(special_split_fn, fn_patterns): """ Symlink targets will be relative to cwd. For each pattern, each wildcard will be substituted everywhere, e.g. fn_pattern == 'top/{key}/input_{key}.txt' """ fnkeypattdict = dict(fnkeypatt.split('=') for fnkeypatt in fn_patterns) jobs = deserialize(special_split_fn) mapdir = os.path.normpath(os.path.dirname(os.path.normpath(special_split_fn))) for job in jobs: inputs = job['input'] wildcards = job['wildcards'] for (fnkey, fn_pattern) in viewitems(fnkeypattdict): val = inputs[fnkey] # val should be relative to the location of the special_split_fn. #assert not os.path.isabs(val), 'mapped input (dynamic output) filename {!r} must be relative (to serialzed file location {!r})'.format( # val, special_split_fn) if not os.path.isabs(val): mapped_input_fn = os.path.join(mapdir, val) else: mapped_input_fn = val assert_exists(mapped_input_fn) try: symlink_name = fn_pattern.format(**wildcards) except Exception as err: import pprint msg = str(err) + ': for pattern {!r} and wildcards\n{!r}'.format( fn_pattern, pprint.pformat(wildcards)) raise Exception(msg) outdir = os.path.normpath(os.path.dirname(symlink_name)) mkdir(outdir) target_name = os.path.relpath(mapped_input_fn, outdir) symlink(symlink_name, target_name) def parse_args(argv): description = 'Create symlinks named after "fn_pattern", targeting values in "mapped_fn".' parser = argparse.ArgumentParser( description=description, ) parser.add_argument( '--special-split-fn', required=True, help='Serialized split-file (in our special format), where "mapped_inputs" has a map with key to filename, relative to the directory of this file.') parser.add_argument( 'fn_patterns', nargs='+', help='"fnkey=pattern" Can appear multiple times. Each is a pattern for symlinks, to be substituted with keys in special_split_fn. Each fnkey=filename must appear in the input section of each job listed in special-split.') return parser.parse_args(argv[1:]) def main(argv=sys.argv): args = parse_args(argv) run(**vars(args)) if __name__ == "__main__": main() ================================================ FILE: falcon_kit/mains/task_report_pre_assembly.py ================================================ from __future__ import absolute_import import argparse import logging import os import sys from .. import io from .. import bash from .. import run_support LOG = logging.getLogger() def run(config_fn, length_cutoff_fn, raw_reads_db_fn, preads_fofn_fn, pre_assembly_report_fn): config = io.deserialize(config_fn) genome_length = int(config['genome_size']) length_cutoff_user = int(config['length_cutoff']) # Update length_cutoff if auto-calc (when length_cutoff is negative). # length_cutoff_fn was created long ago, so no filesystem issues. length_cutoff = run_support.get_length_cutoff( length_cutoff_user, length_cutoff_fn) # Hmmm. Actually, I think we now write the user length_cutoff into the length_cutoff file, # if not -1. TODO(CD): Check on that, and simplify here if so. script = bash.script_run_report_pre_assembly( raw_reads_db_fn, preads_fofn_fn, genome_length, length_cutoff, pre_assembly_report_fn) script_fn = 'run-report-pre-assembly.sh' job_done_fn = 'job.done' bash.write_script(script, script_fn, job_done_fn) io.syscall('bash -vex {}'.format(script_fn)) class HelpF(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass def parse_args(argv): description = 'Prepare to run the pre-assembly report generator, and run it.' epilog = 'length_cutoff might be cleaned up someday. For now, yeah, it is confusing.' parser = argparse.ArgumentParser( description=description, epilog=epilog, formatter_class=HelpF, ) parser.add_argument( '--config-fn', help='Input. JSON configuration. We use "length_cutoff" (if positive) and "genome_size".', ) parser.add_argument( '--length-cutoff-fn', help='Input. File of a single number: the length-cutoff for raw reads.', ) parser.add_argument( '--raw-reads-db-fn', help='Input. Dazzler DB of raw reads.', ) parser.add_argument( '--preads-fofn-fn', help='Input. FOFN of preads las files.', ) parser.add_argument( '--pre-assembly-report-fn', help='Output. In JSON format.', ) args = parser.parse_args(argv[1:]) return args def main(argv=sys.argv): args = parse_args(argv) logging.basicConfig(level=logging.INFO) run(**vars(args)) if __name__ == '__main__': # pragma: no cover main() ================================================ FILE: falcon_kit/mains/tasks.py ================================================ """Executable tasks. To be called by pbsmrtpipe. pypeFLOW uses its own adaptors instead. """ from __future__ import absolute_import from __future__ import print_function from .. import run_support as support import sys def help(): print(""" Usage: falcon-task [task] <[task-args]> tasks: make-fofn-abs """) sys.exit(2) def main_make_fofn_abs(i_fofn_fn, o_fofn_fn): support.make_fofn_abs(i_fofn_fn, o_fofn_fn) def main(argv=sys.argv): if len(argv) < 2 or argv[1].startswith('-'): help() task = argv[1] tasks = { 'make-fofn-abs': main_make_fofn_abs, } return tasks[task](*argv[2:]) if __name__ == "__main__": main(sys.argv) ================================================ FILE: falcon_kit/multiproc.py ================================================ """Job pools for multiprocessing. """ from __future__ import absolute_import from builtins import map from builtins import object import multiprocessing class FakePool(object): """Fake version of multiprocessing.Pool """ def map(self, func, iterable, chunksize=None): return list(map(func, iterable)) def imap(self, func, iterable, chunksize=None): return map(func, iterable) def terminate(self): pass def __init__(self, initializer=None, initargs=[], *args, **kwds): if initializer: initializer(*initargs) def Pool(processes, *args, **kwds): """Pool factory. If 'not processes', return our FakePool; otherwise, a multiprocessing.Pool. """ if processes: return multiprocessing.Pool(processes, *args, **kwds) else: return FakePool(*args, **kwds) ================================================ FILE: falcon_kit/pype.py ================================================ """This was copied from falcon_unzip, but we needed to modify the TASK SCRIPT to use our copy of generic_gather.py (not used now). """ from __future__ import absolute_import import logging import os from pypeflow.simple_pwatcher_bridge import (PypeTask, Dist) from pypeflow.tasks import gen_task as pype_gen_task from pypeflow.do_task import wait_for from . import io LOG = logging.getLogger(__name__) TASK_GENERIC_RUN_UNITS_SCRIPT = """\ python -m falcon_kit.mains.generic_run_units_of_work --nproc={params.pypeflow_nproc} --units-of-work-fn={input.units_of_work} --bash-template-fn={input.bash_template} --results-fn={output.results} """ TASK_GENERIC_SCATTER_ONE_UOW_SCRIPT = """\ python -m falcon_kit.mains.generic_scatter_one_uow --all-uow-list-fn={input.all} --one-uow-list-fn={output.one} --split-idx={params.split_idx} """ TASK_GENERIC_UNSPLIT_SCRIPT = """ python -m falcon_kit.mains.generic_unsplit --result-fn-list-fn={output.result_fn_list} --gathered-fn={output.gathered} """ #TASK_GENERIC_CHUNKING_SCRIPT = """\ # This is done via pbtag now, I think. #python -m falcon_kit.mains.generic_chunking split-fn={input.split} --bash-template-temp-fn={input.bash_template_temp} --units-of-work-fn={output.units_of_work} --uow-template-fn={output.uow_template} --split-idx={params.split_idx} #""" def wrap_gen_task(rule_writer, script, inputs, outputs, parameters=None, dist=None): if parameters is None: parameters = dict() if dist is None: dist = Dist() from future.utils import viewitems rel_inputs = dict() rel_outputs = dict() # Make relative to CWD. (But better if caller does this.) def get_rel(maybe_abs): rel = dict() for (k, v) in viewitems(maybe_abs): if os.path.isabs(v): v = os.path.relpath(v) rel[k] = v return rel inputs = get_rel(inputs) outputs = get_rel(outputs) first_output_dir = os.path.normpath(os.path.dirname(outputs.values()[0])) rel_topdir = os.path.relpath('.', first_output_dir) # redundant for rel-inputs, but fine params = dict(parameters) params['topdir'] = rel_topdir pt = pype_gen_task(script, inputs, outputs, params, dist) # Run pype_gen_task first because it can valid some stuff. rule_writer(inputs, outputs, params, script) return pt def gen_parallel_tasks( wf, rule_writer, split_fn, gathered_fn, run_dict, dist=None, run_script=TASK_GENERIC_RUN_UNITS_SCRIPT, ): """ By convention, the first (wildcard) output in run_dict['outputs'] must be the gatherable list, in the same format as the gathered_fn to be generated from them. For now, we require a single such output, since we do not yet test for wildcards. """ assert 'dist' not in run_dict, 'dist should be a parameter of gen_parallel_tasks(), not of its run_dict' if dist is None: dist = Dist() from future.utils import itervalues #from future.utils import viewitems # run_dict['inputs'] should be patterns to match the inputs in split_fn, by convention. # Write 3 wildcard rules for snakemake, 2 with dynamic. rule_writer.write_dynamic_rules( rule_name="foo", input_json=split_fn, inputs=dict_rel_paths(run_dict['inputs']), shell_template=run_dict['script'], parameters=run_dict['parameters'], wildcard_outputs=dict_rel_paths(run_dict['outputs']), output_json=gathered_fn, ) #outputs = {k:patt.format(**jobkv) for k,patt in output_patterns} #inputs = {k:patt.format(**jobkv) for k,patt in input_patterns} #inputs['SPLIT'] = split_fn # presumably ignored by script; might not be needed at all #split_fn = scatter_dict['outputs']['split'] # by convention wf.refreshTargets() wait_for(split_fn) split = io.deserialize(split_fn) bash_template_fn = run_dict['bash_template_fn'] def find_wildcard_input(inputs): for k,v in inputs.items(): if '{' in v: return v else: raise Exception('No wildcard inputs among {!r}'.format(inputs)) LOG.debug('PARALLEL OUTPUTS:{}'.format(run_dict['outputs'])) task_results = dict() for split_idx, job in enumerate(split): #inputs = job['input'] #outputs = job['output'] #params = job['params'] #wildcards = job['wildcards'] #params.update({k: v for (k, v) in viewitems(job['wildcards'])}) # include expanded wildcards #LOG.warning('OUT:{}'.format(outputs)) wildcards = job['wildcards'] def resolved(v): return v.format(**wildcards) def resolved_dict(d): result = dict(d) LOG.debug(' wildcards={!r}'.format(wildcards)) for k,v in d.items(): LOG.debug(' k={}, v={!r}'.format(k, v)) result[k] = v.format(**wildcards) return result #task_inputs = resolved_dict(run_dict['inputs']) task_outputs = resolved_dict(run_dict['outputs']) task_parameters = resolved_dict(run_dict['parameters']) wild_input = find_wildcard_input(run_dict['inputs']) one_uow_fn = os.path.abspath(wild_input.format(**wildcards)) wf.addTask(pype_gen_task( script=TASK_GENERIC_SCATTER_ONE_UOW_SCRIPT, inputs={ 'all': split_fn, }, outputs={ 'one': one_uow_fn, }, parameters={ 'split_idx': split_idx, }, dist=Dist(local=True), )) wf.addTask(pype_gen_task( script=run_script, # usually TASK_GENERIC_RUN_UNITS_SCRIPT, unless individual load-time is slow inputs={ 'units_of_work': one_uow_fn, 'bash_template': bash_template_fn, }, outputs=task_outputs, parameters=task_parameters, dist=dist, )) wildcards_str = '_'.join(w for w in itervalues(job['wildcards'])) job_name = 'job{}'.format(wildcards_str) task_results[job_name] = os.path.abspath(task_outputs.values()[0]) gather_inputs = dict(task_results) ## An implicit "gatherer" simply takes the output filenames and combines their contents. result_fn_list_fn = os.path.join(os.path.dirname(gathered_fn), 'result-fn-list.json') io.serialize(result_fn_list_fn, list(task_results.values())) # dump into next task-dir before next task starts #assert 'result_fn_list' not in gather_inputs #gather_inputs['result_fn_list'] = result_fn_list_fn # No! pseudo output, since it must exist in a known directory LOG.debug('gather_inputs:{!r}'.format(gather_inputs)) wf.addTask(pype_gen_task( script=TASK_GENERIC_UNSPLIT_SCRIPT, inputs=gather_inputs, outputs={ 'gathered': gathered_fn, 'result_fn_list': result_fn_list_fn, }, parameters={}, dist=Dist(local=True), )) def dict_rel_paths(dict_paths): from future.utils import viewitems return {k: os.path.relpath(v) for (k, v) in viewitems(dict_paths)} ================================================ FILE: falcon_kit/pype_tasks.py ================================================ from __future__ import absolute_import from __future__ import print_function from future.utils import viewitems from future.utils import itervalues # PypeTask functions now need to be module-level. from . import run_support as support from . import bash # for scattering # from pypeflow.simple_pwatcher_bridge import fn # not really needed import collections import json import logging import os.path LOG = logging.getLogger(__name__) #TASK_LAS_MERGE_SCATTER_SCRIPT = """\ #python -m falcon_kit.mains.las_merge_scatter --db-prefix={params.db_prefix} --stage={params.stage} --run-jobs-fn={input.run_jobs} --gathered-las-fn={input.gathered_las} --wildcards={params.wildcards} --scattered-fn={output.scattered} #""" TASK_LAS_MERGE_SPLIT_SCRIPT = """\ python -m falcon_kit.mains.las_merge_split --wildcards={params.wildcards} --db-prefix={params.db_prefix} --run-jobs-fn={input.run_jobs} --gathered-las-fn={input.gathered_las} --split-fn={output.split} --bash-template-fn={output.bash_template} """ TASK_LAS_MERGE_SCRIPT = """\ # Note: HPC.daligner chooses a merged filename in its generated script, so we will symlink to it. python -m falcon_kit.mains.las_merge --las-paths-fn={input.las_paths} --merge-script-fn={input.merge_script} --las-merged-fn-fn={input.merged_las_json} --las-merged-symlink-fn={output.merged_las} --job-done-fn={output.job_done} --p-id-fn={output.p_id} --p-id-num={params.p_id_num} """ TASK_LAS_MERGE_GATHER_SCRIPT = """\ python -m falcon_kit.mains.las_merge_gather --gathered-fn={input.gathered} --p-id2las-fn={output.p_id2las} --las-fn={output.las} """ #TASK_CONSENSUS_SCATTER_SCRIPT = """\ #python -m falcon_kit.mains.consensus_scatter --las-fopfn-fn={input.las_fopfn} --db-fn={input.raw_reads_db} --length-cutoff-fn={input.length_cutoff} --config-fn={input.config} --wildcards={params.wildcards} --scattered-fn={output.scattered} #""" TASK_CONSENSUS_SPLIT_SCRIPT = """\ python -m falcon_kit.mains.consensus_split --wildcards={params.wildcards} --p-id2las-fn={input.p_id2las} --db-fn={input.raw_reads_db} --length-cutoff-fn={input.length_cutoff} --config-fn={input.config} --split-fn={output.split} --bash-template-fn={output.bash_template} """ TASK_CONSENSUS_TASK_SCRIPT = """\ python -m falcon_kit.mains.consensus_task --nproc={params.pypeflow_nproc} --las-fn={input.las} --db-fn={input.db} --length-cutoff-fn={input.length_cutoff} --config-fn={input.config} --fasta-fn={output.fasta} """ TASK_CONSENSUS_GATHER_SCRIPT = """\ python -m falcon_kit.mains.consensus_gather_fasta_fofn --gathered-fn={input.gathered} --preads-fofn-fn={output.preads_fofn} """ TASK_REPORT_PRE_ASSEMBLY_SCRIPT = """\ python -m falcon_kit.mains.task_report_pre_assembly --config-fn={input.config} --length-cutoff-fn={input.length_cutoff} --raw-reads-db-fn={input.raw_reads_db} --preads-fofn-fn={input.preads_fofn} --pre-assembly-report-fn={output.pre_assembly_report} """ # Old TASK_BUILD_RDB_SCRIPT = """\ python -m falcon_kit.mains.build_rdb --input-fofn-fn={input.raw_reads_fofn} --config-fn={input.config} --run-jobs-fn={output.run_jobs} --job-done-fn={output.db_build_done} touch {output.db_build_done} """ # Old TASK_BUILD_PDB_SCRIPT = """\ python -m falcon_kit.mains.build_pdb --input-fofn-fn={input.preads_fofn} --config-fn={input.config} --run-jobs-fn={output.run_jobs} --job-done-fn={output.db_build_done} # TODO: Verify that input.preads_db exists. touch {output.db_build_done} """ TASK_DB_BUILD_SCRIPT = """\ python -m falcon_kit.mains.dazzler --config-fn={input.config} --db-fn={output.db} build --input-fofn-fn={input.input_fofn} --length-cutoff-fn={output.length_cutoff} # TODO: Verify that db exists. #ln -sf {output.length_cutoff} length_cutoff """ TASK_DB_TAN_SPLIT_SCRIPT = """\ python -m falcon_kit.mains.dazzler --config={input.config} --db={input.db} tan-split --split={output.split} --bash-template={output.bash_template} """ TASK_DB_TAN_APPLY_SCRIPT = """\ python -m falcon_kit.mains.dazzler --config={input.config} --db={input.db} tan-apply --script={input.script} --job-done={output.job_done} """ TASK_DB_TAN_COMBINE_SCRIPT = """\ python -m falcon_kit.mains.dazzler --config={input.config} --db={input.db} tan-combine --gathered={input.gathered} --new-db={output.new_db} """ TASK_DB_DALIGNER_SPLIT_SCRIPT = """\ python -m falcon_kit.mains.dazzler --config={input.config} --db={input.db} --nproc={params.pypeflow_nproc} daligner-split --wildcards={params.wildcards} --length-cutoff-fn={input.length_cutoff} --split-fn={output.split} --bash-template-fn={output.bash_template} """ TASK_DB_DALIGNER_APPLY_SCRIPT = """\ python -m falcon_kit.mains.dazzler --config={input.config} --db={input.db} daligner-apply --script={input.script} --job-done={output.job_done} """ TASK_DB_DALIGNER_COMBINE_SCRIPT = """\ python -m falcon_kit.mains.dazzler --config={input.config} --db={input.db} daligner-combine --gathered={input.gathered} --las-paths-fn={output.las_paths} """ TASK_DB_LAMERGE_SPLIT_SCRIPT = """\ python -m falcon_kit.mains.dazzler --config={input.config} merge-split --db-prefix={params.db_prefix} --las-paths={input.las_paths} --split-fn={output.split} --bash-template-fn={output.bash_template} """ TASK_DB_LAMERGE_APPLY_SCRIPT = """\ python -m falcon_kit.mains.dazzler --config={input.config} merge-apply --las-paths={input.las_paths} --las-fn={output.las_fn} """ TASK_DB_LAMERGE_COMBINE_SCRIPT = """\ python -m falcon_kit.mains.dazzler --config={input.config} merge-combine --gathered={input.gathered} --las-paths-fn={output.las_paths} --block2las-fn={output.block2las} """ #TASK_DALIGNER_SCATTER_SCRIPT = """\ #python -m falcon_kit.mains.daligner_scatter --run-jobs-fn={input.run_jobs} --db-prefix={params.db_prefix} --db-fn={input.db} --skip-checks={params.skip_checks} --pread-aln={params.pread_aln} --stage={params.stage} --wildcards={params.wildcards} --scattered-fn={output.scattered} #""" TASK_DALIGNER_SPLIT_SCRIPT = """\ python -m falcon_kit.mains.daligner_split --nproc={params.pypeflow_nproc} --wildcards={params.wildcards} --db-prefix={params.db_prefix} --skip-checks={params.skip_checks} --pread-aln={params.pread_aln} --run-jobs-fn={input.run_jobs} --db-fn={input.db} --split-fn={output.split} --bash-template-fn={output.bash_template} """ TASK_DALIGNER_SCRIPT = """\ # Note: HPC.daligner chooses a merged filename in its generated script, so we will symlink to it. python -m falcon_kit.mains.daligner --daligner-settings-fn={input.daligner_settings} --daligner-script-fn={input.daligner_script} --job-done-fn={output.job_done} """ TASK_DALIGNER_FIND_LAS_SCRIPT = """\ python -m falcon_kit.mains.daligner_gather_las_list --gathered-fn={input.gathered} --las-paths-fn={output.las_paths} """ TASK_DUMP_RAWREAD_IDS_SCRIPT = """\ DBshow -n {input.rawread_db} | tr -d '>' | LD_LIBRARY_PATH= awk '{{print $1}}' > {output.rawread_id_file} """ TASK_DUMP_PREAD_IDS_SCRIPT = """\ DBshow -n {input.pread_db} | tr -d '>' | LD_LIBRARY_PATH= awk '{{print $1}}' > {output.pread_id_file} """ TASK_GENERATE_READ_TO_CTG_MAP_SCRIPT = """\ python -m falcon_kit.mains.generate_read_to_ctg_map --rawread-id={input.rawread_id_file} --pread-id={input.pread_id_file} --sg-edges-list={input.sg_edges_list} --utg-data={input.utg_data} --ctg-paths={input.ctg_paths} --output={output.read_to_contig_map} """ TASK_RUN_DB_TO_FALCON_SCRIPT = """\ # Given preads.db, # write preads4falcon.fasta (implicitly) in CWD. time DB2Falcon -U {input.preads_db} [ -f {output.preads4falcon} ] || exit 1 touch {output.job_done} """ TASK_RUN_FALCON_ASM_SCRIPT = """\ # Given, las_fofn.json, # write preads.ovl: # mobs uses binwrappers, so it does not see our "entry-points". # So, after dropping "src/py_scripts/*.py", we can call these via python -m: time python -m falcon_kit.mains.ovlp_filter --db {input.db_file} --las-fofn {input.las_fofn} {params.overlap_filtering_setting} --min-len {params.length_cutoff_pr} --out-fn preads.ovl ln -sf {input.preads4falcon_fasta} ./preads4falcon.fasta # Given preads.ovl, # write sg_edges_list, c_path, utg_data, ctg_paths. time python -m falcon_kit.mains.ovlp_to_graph {params.fc_ovlp_to_graph_option} --overlap-file preads.ovl >| fc_ovlp_to_graph.log # Given sg_edges_list, utg_data, ctg_paths, preads4falcon.fasta, # write p_ctg.fa and a_ctg_all.fa, # plus a_ctg_base.fa, p_ctg_tiling_path, a_ctg_tiling_path, a_ctg_base_tiling_path: time python -m falcon_kit.mains.graph_to_contig # Given a_ctg_all.fa, write a_ctg.fa: time python -m falcon_kit.mains.dedup_a_tigs # Collect all info needed to format the GFA-1 and GFA-2 representations of # the assembly graphs. time python -m falcon_kit.mains.collect_pread_gfa >| asm.gfa.json time python -m falcon_kit.mains.collect_pread_gfa --add-string-graph >| sg.gfa.json time python -m falcon_kit.mains.collect_contig_gfa >| contig.gfa.json # Output the assembly pread graph. time python -m falcon_kit.mains.gen_gfa_v1 asm.gfa.json >| asm.gfa time python -m falcon_kit.mains.gen_gfa_v2 asm.gfa.json >| asm.gfa2 # Output the string graph. time python -m falcon_kit.mains.gen_gfa_v1 sg.gfa.json >| sg.gfa time python -m falcon_kit.mains.gen_gfa_v2 sg.gfa.json >| sg.gfa2 # Output the contig graph with associate contigs attached to each primary contig. time python -m falcon_kit.mains.gen_gfa_v2 contig.gfa.json >| contig.gfa2 #rm -f ./preads4falcon.fasta touch {output.falcon_asm_done} """ def fn(p): return p def system(call, check=False): LOG.debug('$(%s)' % repr(call)) rc = os.system(call) msg = 'Call %r returned %d.' % (call, rc) if rc: LOG.warning(msg) if check: raise Exception(msg) else: LOG.debug(msg) return rc def remove(*fns): for fn in fns: if os.path.exists(fn): os.remove(fn) assert not os.path.exists(fn) # Someday, we can drop mkdir() in these. def mkdir(d): if not os.path.isdir(d): os.makedirs(d) def task_make_fofn_abs_raw(self): script_fn = 'noop.sh' open(script_fn, 'w').write('echo NOOP raw') self.generated_script_fn = script_fn support.make_fofn_abs(fn(self.i_fofn), fn(self.o_fofn)) def task_make_fofn_abs_preads(self): script_fn = 'noop.sh' open(script_fn, 'w').write('echo NOOP preads') self.generated_script_fn = script_fn support.make_fofn_abs(fn(self.i_fofn), fn(self.o_fofn)) def task_build_rdb(self): input_fofn_fn = fn(self.input_fofn) job_done = fn(self.rdb_build_done) db = fn(self.raw_reads_db) run_jobs = fn(self.run_jobs) remove(job_done, db, run_jobs) work_dir = self.parameters['work_dir'] config = self.parameters['config'] script_fn = os.path.join(work_dir, 'prepare_rdb.sh') args = { 'input_fofn_fn': input_fofn_fn, 'config': config, 'job_done': job_done, 'script_fn': script_fn, 'run_jobs_fn': run_jobs, } support.build_rdb(**args) self.generated_script_fn = script_fn # essential the same as build_rdb() but the subtle differences are tricky to consolidate to one function def task_build_pdb(self): input_fofn_fn = fn(self.preads_fofn) job_done = fn(self.pdb_build_done) db = fn(self.preads_db) run_jobs = fn(self.run_jobs) remove(job_done, db, run_jobs) work_dir = self.parameters['work_dir'] config = self.parameters['config'] script_fn = os.path.join(work_dir, 'prepare_pdb.sh') args = { 'input_fofn_fn': input_fofn_fn, 'config': config, 'job_done': job_done, 'script_fn': script_fn, 'run_jobs_fn': run_jobs, } support.build_pdb(**args) self.generated_script_fn = script_fn def task_run_db2falcon(self): wd = self.parameters['wd'] # self.las_fofn # TODO: Are there any implicit dependencies, or can we drop this? job_done = fn(self.db2falcon_done) preads4falcon_fn = fn(self.preads4falcon) preads_db = fn(self.preads_db) config = self.parameters['config'] script_dir = os.path.join(wd) script_fn = os.path.join(script_dir, 'run_db2falcon.sh') args = { 'config': config, 'job_done': job_done, 'script_fn': script_fn, 'preads4falcon_fn': preads4falcon_fn, 'preads_db': preads_db, } support.run_db2falcon(**args) self.generated_script_fn = script_fn def task_run_falcon_asm(self): wd = self.parameters['wd'] # self.db2falcon_done db_file = fn(self.db_file) job_done = fn(self.falcon_asm_done) config = self.parameters['config'] pread_dir = self.parameters['pread_dir'] preads4falcon_fn = fn(self.preads4falcon) las_fofn_fn = fn(self.las_fofn) script_dir = os.path.join(wd) script_fn = os.path.join(script_dir, 'run_falcon_asm.sh') args = { 'las_fofn_fn': las_fofn_fn, 'preads4falcon_fasta_fn': preads4falcon_fn, 'db_file_fn': db_file, 'config': config, 'job_done': job_done, 'script_fn': script_fn, } support.run_falcon_asm(**args) self.generated_script_fn = script_fn def task_report_pre_assembly(self): i_raw_reads_db_fn = fn(self.raw_reads_db) i_preads_fofn_fn = fn(self.preads_fofn) i_length_cutoff_fn = fn(self.length_cutoff_fn) o_json_fn = fn(self.pre_assembly_report) cfg = self.parameters genome_length = int(cfg.get('genome_size', 0)) # different name in falcon length_cutoff = int(cfg['length_cutoff']) # Update length_cutoff if auto-calc (when length_cutoff is negative). # i_length_cutoff_fn was created long ago, so no filesystem issues. length_cutoff = support.get_length_cutoff( length_cutoff, i_length_cutoff_fn) cwd = self.parameters['cwd'] script_fn = os.path.join(cwd, 'run_report_pre_assembly.sh') job_done = os.path.join(cwd, 'report_pa_done') kwds = { 'i_raw_reads_db_fn': i_raw_reads_db_fn, 'i_preads_fofn_fn': i_preads_fofn_fn, 'genome_length': genome_length, 'length_cutoff': length_cutoff, 'o_json_fn': o_json_fn, 'job_done': job_done, 'script_fn': script_fn, } LOG.info('Report inputs: {}'.format(repr(kwds))) support.run_report_pre_assembly(**kwds) self.generated_script_fn = script_fn def task_run_daligner(self): job_done = fn(self.job_done) daligner_script = self.parameters['daligner_script'] job_uid = self.parameters['job_uid'] cwd = self.parameters['cwd'] db_prefix = self.parameters['db_prefix'] config = self.parameters['config'] script_dir = os.path.join(cwd) script_fn = os.path.join(script_dir, 'rj_%s.sh' % (job_uid)) args = { 'daligner_script': daligner_script, 'db_prefix': db_prefix, 'config': config, 'job_done': job_done, 'script_fn': script_fn, } support.run_daligner(**args) self.generated_script_fn = script_fn def read_gathered_las(path): """Return dict of block->[las_paths]. For now, these are ws separated on each line of input. """ result = collections.defaultdict(list) with open(path) as ifs: for line in ifs: block, las_path = line.split() result[int(block)].append(las_path) # LOG.warning('path={!r}, result={}'.format( # path, pprint.pformat(result))) return result def task_run_las_merge(self): job_done = fn(self.job_done) gathered_las_fn = fn(self.gathered_las) script = self.parameters['merge_script'] job_id = self.parameters['job_id'] # aka 'block' cwd = self.parameters['cwd'] gathered_dict = read_gathered_las(gathered_las_fn) las_paths = gathered_dict[job_id] for las_path in las_paths: assert os.path.isabs(las_path) if os.path.commonprefix([las_path, cwd]) == '/': src = las_path else: src = os.path.relpath(las_path, cwd) tgt = os.path.join(cwd, os.path.basename(las_path)) LOG.debug('symlink {!r} <- {!r}'.format(src, tgt)) if os.path.lexists(tgt): os.unlink(tgt) os.symlink(src, tgt) config = self.parameters['config'] script_dir = os.path.join(cwd) script_fn = os.path.join(script_dir, 'rp_%05d.sh' % (job_id)) args = { 'script': script, 'config': config, 'job_done': job_done, 'script_fn': script_fn, } support.run_las_merge(**args) self.generated_script_fn = script_fn def task_run_consensus(self): las_fn = fn(self.las) db_fn = fn(self.db) out_file_fn = fn(self.out_file) out_done = 'out.done' # fn(self.out_done) job_id = self.parameters['job_id'] cwd = self.parameters['cwd'] config = self.parameters['config'] prefix = self.parameters['prefix'] p_id = int(job_id) script_dir = os.path.join(cwd) script_fn = os.path.join(script_dir, 'c_%05d.sh' % (p_id)) #merge_job_dir = os.path.dirname(merged_las_fn) #las_fn = os.path.abspath('{merge_job_dir}/{prefix}.{job_id}.las'.format(**locals())) args = { 'db_fn': db_fn, 'las_fn': las_fn, 'out_file_fn': out_file_fn, 'config': config, 'job_done': out_done, 'script_fn': script_fn, } support.run_consensus(**args) self.generated_script_fn = script_fn def task_daligner_scatter(self): run_jobs_fn = self.run_jobs_fn db_build_done = self.db_build_done scatter_fn = self.scatter_fn par = self.parameters db_prefix = par['db_prefix'] nblock = par['nblock'] config = par['config'] pread_aln = par['pread_aln'] # False for raw_reads skip_checks = config.get('skip_checks') tasks = [] LOG.info('Skip LAcheck after daligner? {}'.format(skip_checks)) func = task_run_daligner func_name = '{}.{}'.format(func.__module__, func.__name__) for job_uid, script in bash.scripts_daligner(run_jobs_fn, db_prefix, db_build_done, nblock, pread_aln, skip_check=skip_checks): job_done_fn = 'job_%s_done' % job_uid parameters = {'daligner_script': script, 'job_uid': job_uid, 'config': config, 'sge_option': config['sge_option_da'], 'db_prefix': db_prefix} inputs = {'db_build_done': db_build_done} outputs = {'job_done': job_done_fn} python_function = func_name, URL = 'task://localhost/d_%s_%s' % (job_uid, db_prefix) daligner_task = { 'inputs': inputs, 'outputs': outputs, 'parameters': parameters, 'python_function': python_function, 'URL': URL, } tasks.append(daligner_task) content = json.dumps(tasks, sort_keys=True, indent=4, separators=(',', ': ')) open(scatter_fn, 'w').write(content) def task_merge_scatter(self): run_jobs_fn = self.run_jobs gathered_las_fn = self.gathered_las scatter_fn = self.scattered par = self.parameters db_prefix = par['db_prefix'] config = par['config'] func = task_run_las_merge func_name = '{}.{}'.format(func.__module__, func.__name__) merge_scripts = bash.scripts_merge(config, db_prefix, run_jobs_fn) tasks = [] for p_id, merge_script, merged_las_fn in merge_scripts: parameters = {'merge_script': merge_script, 'job_id': p_id, 'config': config, 'sge_option': config['sge_option_la'], } job_done_fn = 'm_%05d_done' % p_id inputs = {'gathered_las': gathered_las_fn} outputs = {'job_done': job_done_fn, # probably not needed anymore 'merged_las': merged_las_fn, } python_function = func_name, URL = 'task://localhost/m_%05d_%s' % (p_id, db_prefix) task_desc = { 'inputs': inputs, 'outputs': outputs, 'parameters': parameters, 'python_function': python_function, 'URL': URL, } tasks.append(task_desc) content = json.dumps(tasks, sort_keys=True, indent=4, separators=(',', ': ')) open(scatter_fn, 'w').write(content) def task_consensus_scatter(self): scattered_fn = self.scattered gathered_fn = self.gathered db_fn = self.db wd = os.path.dirname(scattered_fn) par = self.parameters db_prefix = par['db_prefix'] config = par['config'] func = task_run_consensus func_name = '{}.{}'.format(func.__module__, func.__name__) # by convention, since we want to preseve some old paths for now basedir = os.path.dirname(wd) p_ids_merge_las = read_gathered_las(gathered_fn) tasks = [] for (p_id, las_fns) in viewitems(p_ids_merge_las): assert len(las_fns) == 1, repr(las_fns) # since we know each merge-task is for a single block las_fn = las_fns[0] cns_label = 'cns_%05d' % int(p_id) #out_done_fn = '%s_done' % cns_label out_file_fn = '%s.fasta' % cns_label parameters = { # 'cwd': rdir, 'job_id': p_id, 'prefix': db_prefix, 'config': config, 'sge_option': config['sge_option_cns'], } inputs = {'las': las_fn, 'db': db_fn, } outputs = {'out_file': out_file_fn, #'out_done': out_done_fn, } python_function = func_name, URL = 'task://localhost/%s' % cns_label task_desc = { 'inputs': inputs, 'outputs': outputs, 'parameters': parameters, 'python_function': python_function, 'URL': URL, } tasks.append(task_desc) content = json.dumps(tasks, sort_keys=True, indent=4, separators=(',', ': ')) open(scattered_fn, 'w').write(content) def task_daligner_gather(self): """Find all .las leaves so far. """ out_dict = self.inputs gathered_fn = fn(self.gathered) nblock = self.parameters['nblock'] LOG.debug('nblock=%d, out_dir:\n%s' % (nblock, out_dict)) job_rundirs = [os.path.dirname(fn(dal_done)) for dal_done in itervalues(out_dict)] with open(gathered_fn, 'w') as ofs: for block, las_path in support.daligner_gather_las(job_rundirs): ofs.write('{} {}\n'.format(block, las_path)) def task_cns_gather(self): fofn_fn = fn(self.preads_fofn) with open(fofn_fn, 'w') as f: for filename in sorted(fn(plf) for plf in itervalues(self.inputs)): print(filename, file=f) def task_merge_gather(self): fofn_fn = fn(self.las_fofn) with open(fofn_fn, 'w') as f: # The keys are p_ids. for filename in sorted(fn(plf) for plf in itervalues(self.inputs)): print(filename, file=f) fopfn_fn = fn(self.las_fopfn) with open(fopfn_fn, 'w') as f: # The keys are p_ids. for (filename, p_id) in sorted((fn(plf), p_id) for (p_id, plf) in viewitems(self.inputs)): print(p_id, filename, file=f) #wdir = os.path.dirname(las_fofn_fn) # pread_dir = os.path.dirname(wdir) # by convention, for now # Generate las.fofn in run-dir. # No longer needed! #system('find {}/m_*/ -name "preads.*.las" >| {}'.format(pread_dir, las_fofn_fn)) def task_dump_rawread_ids(self): rawread_db = fn(self.rawread_db) rawread_id_file = fn(self.rawread_id_file) input = object() input.rawread_db = rawread_db output = object() output.rawread_id_file = rawread_id_file system(TASK_DUMP_RAWREAD_IDS_SCRIPT.format(**locals())) def task_dump_pread_ids(self): pread_db = fn(self.pread_db) pread_id_file = fn(self.pread_id_file) input = object() input.pread_db = pread_db output = object() output.pread_id_file = pread_id_file system(TASK_DUMP_PREAD_IDS_SCRIPT.format(**locals())) def task_generate_read_to_ctg_map(self): input = object() input.rawread_id_file = fn(self.rawread_id_file) input.pread_id_file = fn(self.pread_id_file) input.sg_edges_list = fn(self.sg_edges_list) input.utg_data = fn(self.utg_data) input.ctg_paths = fn(self.ctg_paths) output = object() output.read_to_contig_map = fn(self.read_to_contig_map) system(TASK_GENERATE_READ_TO_CTG_MAP_SCRIPT.format(**locals())) ================================================ FILE: falcon_kit/run_support.py ================================================ from __future__ import absolute_import from future.utils import viewitems from . import bash, functional from .functional import cfg_tobool from .io import NativeIO from .util.system import (make_fofn_abs, make_dirs, cd) import json import logging import logging.config import os import re import io import sys import tempfile import time import uuid logger = logging.getLogger(__name__) from ConfigParser import SafeConfigParser as ConfigParser def _prepend_env_paths(content, names): """ E.g. names = ['PATH', 'PYTYHONPATH'] content = echo hi => export PATH=current:path:${PATH} export PYTHON=current:path:${PYTHONPATH} echo hi """ export_env_vars = ['export %(k)s=%(v)s:${%(k)s}' % dict( k=name, v=os.environ.get(name, '')) for name in names] return '\n'.join(export_env_vars + [content]) def update_env_in_script(fn, names): """Modify fn using on prepend_env_paths(). """ with open(fn) as ifs: content = ifs.read() content = _prepend_env_paths(content, names) with open(fn, 'w') as ofs: ofs.write(content) def use_tmpdir_for_files(basenames, src_dir, link_dir): """NOT USED. Kept only for reference. This will be done in pypeFLOW. Generate script to copy db files to tmpdir (for speed). - Choose tmp_dir, based on src_dir name. - rsync basenames into tmp_dir # after 'flock', per file - symlink from link_dir into tmp_dir. Return list of script lines, sans linefeed. """ script = list() unique = os.path.abspath(src_dir).replace('/', '_') root = tempfile.gettempdir() tmp_dir = os.path.join(root, 'falcon', unique) script.append('mkdir -p %s' % tmp_dir) for basename in basenames: src = os.path.join(src_dir, basename) dst = os.path.join(tmp_dir, basename) rm_cmd = 'rm -f %s' % basename # Wait on lock for up to 10 minutes, in case of very large files. rsync_cmd = "flock -w 600 %s.lock -c 'rsync -av %s %s'" % ( dst, src, dst) ln_cmd = 'ln -sf %s %s' % (dst, basename) script.extend([rm_cmd, rsync_cmd, ln_cmd]) return script def make_job_data(url, script_fn): """Choose defaults. Run in same directory as script_fn. Base job_name on script_fn. """ wd = os.path.dirname(script_fn) job_name = '{0}-{1}-{2}'.format( os.path.basename(script_fn), url.split("/")[-1], str(uuid.uuid4())[:8], ) job_data = {"job_name": job_name, "cwd": wd, "script_fn": script_fn} return job_data def update_HPCdaligner_option(option): if '-dal' in option: logger.warning( 'HPC.daligner option "-dal" has changed to "-B". Correcting this for you.') option = option.replace('-dal', '-B') if '-deg' in option: logger.warning( 'HPC.daligner option "-deg" has changed to "-D". Correcting this for you.') option = option.replace('-deg', '-D') return option def clean_falcon_options(fc): """Update some values in fc. Replace _ with - in a couple places. """ keys = ('falcon_sense_option', 'overlap_filtering_setting', 'fc_ovlp_to_graph_option', ) for key in keys: update_dash_flags(fc, key) for dk in ('pa_HPCdaligner_option', 'ovlp_HPCdaligner_option'): if dk in fc: fc[dk] = update_HPCdaligner_option(fc[dk]) def get_config(config): """ This is only for the call from pbsmrtpipe: upport.get_config(support.parse_config(fn)) We have changed parse_config() to return a dict. So this is a no-op. """ cfg = dict(config) # already a dict now return cfg def dict2config(jdict, section): config = ConfigParser() if not config.has_section(section): config.add_section(section) for (k, v) in viewitems(jdict): config.set(section, k, str(v)) return config def parse_config(config_fn): """Deprecated. Called from pbsmrtpipe, for now. """ return parse_cfg_file(config_fn) def parse_cfg_file(config_fn): """Return as dict. """ with open(config_fn) as stream: ext = os.path.splitext(config_fn)[1] if ext in ('.json', '.js'): config = json.loads(stream.read()) else: # Parse sections (and case-sensitively), into sub-dicts. config = parse_cfg_with_sections(stream) update_defaults(config['General']) # Copy General section to top, for now. #for key, val in config['General'].items(): # config[key] = val ##cfg.update(config.get('General', {})) check_config_sections(config) # Ensure that the right sections exist. update_job_sections(config) return config def process_job_defaults(job_defaults): key = 'use_tmpdir' use_tmpdir = job_defaults.get(key, '') if '/' in use_tmpdir: tempfile.tempdir = use_tmpdir else: if use_tmpdir.lower().startswith('t'): use_tmpdir = tempfile.gettempdir() else: use_tmpdir = False job_defaults[key] = use_tmpdir def update_job_defaults_section(config): """For backwards compatibility with stuff from 'General' section. """ General = config['General'] job_defaults = config['job.defaults'] if 'njobs' in General: logger.warning('"njobs" belongs in the [job.defaults] section.') if 'pwatcher_type' in General: logger.warning('Please specify "pwatcher_type" only in the [job.defaults] section, not in [General].') if 'job_type' in General: logger.warning('Please specify "job_type" only in the [job.defaults] section, not in [General].') if 'stop_all_jobs_on_failure' in General: logger.warning('Please specify "stop_all_jobs_on_failure" only in the [job.defaults] section, not in [General].') if 'use_tmpdir' in General: logger.warning('Please specify "use_tmpdir" only in the [job.defaults] section, not in [General].') if 'job_name_style' in General: logger.warning('Please specify "job_name_style" only in the [job.defaults] section, not in [General].') if 'job_queue' in General: logger.warning('Please specify "JOB_QUEUE" only in the [job.defaults] section, not as "job_queue" in [General].') if 'sge_option' in General: logger.warning('Please specify "JOB_OPTS" in the [job.defaults] section, not as "sge_option" in [General].') pwatcher_type = General.get('pwatcher_type', 'fs_based') #, config.get('pwatcher_type'))) job_type = job_defaults.get('job_type', General.get('job_type', '')).lower() job_queue = General.get('job_queue', '') sge_option = General.get('sge_option', '') if 'pwatcher_type' not in job_defaults: job_defaults['pwatcher_type'] = pwatcher_type else: pwatcher_type = job_defaults['pwatcher_type'] if 'submit' not in config['job.defaults']: if 'blocking' == pwatcher_type: if not job_queue or ' ' not in job_queue: raise Exception('pwatcher_type=blocking, but "submit" is not in [job.defaults] section.') config['job.defaults']['submit'] = job_queue logger.warning('Please set "submit" in [job.defaults] section. (For now, we will use "job_queue" from [General], which was a hack.)') elif 'fs_based' == pwatcher_type or 'network_based' == pwatcher_type: if not job_type: logger.error('job.defaults.submit is not set; pwatcher_type={}; but job_type is not set. Maybe try "job_type=local" first.'.format(pwatcher_type)) job_type = 'local' job_defaults['job_type'] = job_type allowed_job_types = ['sge', 'pbs', 'torque', 'slurm', 'lsf', 'local'] assert job_type in allowed_job_types, 'job_type={} not in {}'.format( job_type, allowed_job_types) if job_queue and 'JOB_QUEUE' not in config['job.defaults']: job_defaults['JOB_QUEUE'] = job_queue else: raise Exception('Unknown pwatcher_type={}'.format(pwatcher_type)) #assert 'submit' in config['job.defaults'], repr(config) if sge_option and 'JOB_OPTS' not in config['job.defaults']: job_defaults['JOB_OPTS'] = sge_option if 'njobs' not in job_defaults: config['job.defaults']['njobs'] = int(General.get('default_concurrent_jobs', 8)) # GLOBAL DEFAULT CONCURRENCY msg = 'Please supply a default for "njobs" (aka concurrency) in section [job.defaults]. For now, we will use {}'.format( config['job.defaults']['njobs']) logger.warning(msg) def update_if_if(key): if key not in job_defaults: if key in General: job_defaults[key] = General[key] logger.warning('Found "{}" from [General] section; should be in [job.defaults] instead.'.format(key)) update_if_if('job_name_style') update_if_if('stop_all_jobs_on_failure') update_if_if('use_tmpdir') legacy_names = [ 'pwatcher_type', 'pwatcher_directory', 'job_type', 'job_queue', 'job_name_style', 'use_tmpdir', ] def update_if_missing(name, sub_dict): if General.get(name) and name not in sub_dict: sub_dict[name] = General[name] for name in legacy_names: update_if_missing(name, config['job.defaults']) process_job_defaults(job_defaults) def update_job_sections(config): """More for backwards compatibility with stuff from 'General' section. """ update_job_defaults_section(config) General = config['General'] # Update a few where the names change and the section is non-default. def update_step_job_opts(name): if General.get('sge_option_'+name) and 'JOB_OPTS' not in config['job.step.'+name]: config['job.step.'+name]['JOB_OPTS'] = General['sge_option_'+name] def update_step_njobs(name): if General.get(name+'_concurrent_jobs') and 'njobs' not in config['job.step.'+name]: config['job.step.'+name]['njobs'] = int(General[name+'_concurrent_jobs']) for name in ['da', 'la', 'pda', 'pla', 'cns', 'fc', 'asm']: update_step_job_opts(name) update_step_njobs(name) # Prefer 'asm' to 'fc'. asm = dict(config['job.step.asm']) config['job.step.asm'] = config['job.step.fc'] del config['job.step.fc'] config['job.step.asm'].update(asm) def parse_cfg_with_sections(stream): """Return as dict of dict of ... """ #Experimental: """ ConfigParser sections become sub-sub sections when separated by dots. [foo.bar] baz = 42 is equivalent to JSON {"foo": {"bar": {"baz": 42}}} """ content = stream.read() result = dict() try: jdict = json.loads(NativeIO(content).read()) return jdict except ValueError: pass #logger.exception('Could not parse stream as JSON.') try: config = ConfigParser() #strict=False? config.optionxform = str config.readfp(NativeIO(content)) sections = config.sections() for sec in sections: result[sec] = dict(config.items(sec)) return result except: raise def check_config_sections(cfg): """And ensure these all exist. """ allowed_sections = set(['General', 'job.step.da', 'job.step.pda', 'job.step.la', 'job.step.pla', 'job.step.cns', 'job.step.fc', 'job.step.asm', 'job.defaults', ]) all_sections = set(k for k,v in cfg.items() if isinstance(v, dict)) unexpected = all_sections - allowed_sections if unexpected: msg = 'You have {} unexpected cfg sections: {}'.format( len(unexpected), unexpected) raise Exception(msg) # Guarantee they all exist. for sec in allowed_sections: if sec not in cfg: cfg[sec] = dict() def update_dash_flags(cfg, key): if key not in cfg: return val = cfg[key] cfg[key] = new_val = functional.dash_flags(cfg[key]) if val != new_val: msg = '''\ Option contains flags with "_": "{key}={val}". Those should be "-", as in "{key}={new_val}". Auto-replaced.'''.format(**locals()) logger.warning(msg) TEXT_FILE_BUSY = 'avoid_text_file_busy' def update_defaults(cfg): """cfg is probably the General sub-dict. """ def set_default(key, val): if key not in cfg: cfg[key] = val set_default('input_type', 'raw') set_default('overlap_filtering_setting', '--max-diff 1000 --max-cov 1000 --min-cov 2') set_default('pa_HPCdaligner_option', '-v -D24 -t16 -e.70 -l1000 -s100') set_default('ovlp_HPCdaligner_option', '-v -D24 -t32 -h60 -e.96 -l500 -s1000') set_default('pa_DBsplit_option', '-x500 -s200') set_default('skip_checks', False) set_default('pa_DBdust_option', '') # Gene recommends the defaults. I have tried -w128 -t2.5 -m20 set_default('dazcon', False) set_default('pa_dazcon_option', '-j 4 -x -l 500') set_default('ovlp_DBsplit_option', '-x500 -s200') set_default('falcon_sense_option', '--output-multi --min-idt 0.70 --min-cov 2 --max-n-read 1800') set_default('falcon_sense_skip_contained', False) set_default('falcon_sense_greedy', False) set_default('LA4Falcon_preload', '') set_default('fc_ovlp_to_graph_option', '') set_default('genome_size', 0) set_default('seed_coverage', 20) set_default('length_cutoff', -1) set_default('length_cutoff_pr', 0) set_default('bestn', 12) set_default('target', 'assembly') set_default(TEXT_FILE_BUSY, bash.BUG_avoid_Text_file_busy) for bool_key in ('skip_checks', 'dazcon', 'falcon_sense_skip_contained', 'falcon_sense_greedy', 'LA4Falcon_preload', TEXT_FILE_BUSY): cfg[bool_key] = functional.cfg_tobool(cfg.get(bool_key, False)) if 'dust' in cfg: logger.warning( "The 'dust' option is deprecated and ignored. We always run DBdust now. Use pa_DBdust_option to override its default arguments.") bash.BUG_avoid_Text_file_busy = cfg[TEXT_FILE_BUSY] clean_falcon_options(cfg) falcon_sense_option = cfg['falcon_sense_option'] if 'local_match_count' in falcon_sense_option or 'output_dformat' in falcon_sense_option: raise Exception('Please remove obsolete "--local_match_count_*" or "--output_dformat"' + ' from "falcon_sense_option" in your cfg: %s' % repr(falcon_sense_option)) length_cutoff = int(cfg['length_cutoff']) if length_cutoff < 0: genome_size = int(cfg['genome_size']) if genome_size < 1: raise Exception( 'Must specify either length_cutoff>0 or genome_size>0') # This one depends on length_cutoff_pr for its default. fc_ovlp_to_graph_option = cfg['fc_ovlp_to_graph_option'] if '--min_len' not in fc_ovlp_to_graph_option and '--min-len' not in fc_ovlp_to_graph_option: length_cutoff_pr = cfg['length_cutoff_pr'] fc_ovlp_to_graph_option += ' --min_len {}'.format(length_cutoff_pr) cfg['fc_ovlp_to_graph_option'] = fc_ovlp_to_graph_option target = cfg['target'] if target not in ["overlapping", "pre-assembly", "assembly"]: msg = """ Target has to be "overlapping", "pre-assembly" or "assembly" in this verison. You have an unknown target {!r} in the configuration file. """.format(target) raise Exception(msg) possible_extra_keys = [ 'sge_option', 'default_concurrent_jobs', 'pwatcher_type', 'pwatcher_directory', 'job_type', 'job_queue', 'job_name_style', 'use_tmpdir', ] for step in ['da', 'la', 'pda', 'pla', 'fc', 'cns', 'asm']: sge_option_key = 'sge_option_' + step possible_extra_keys.append(sge_option_key) concurrent_jobs_key = step + '_concurrent_jobs' possible_extra_keys.append(concurrent_jobs_key) extra = list() for key in possible_extra_keys: if key in cfg: extra.append(key) if extra: extra.sort() msg = 'You have several old-style options. These should be provided in the `[job.defaults]` or `[job.step.*]` sections, and possibly renamed. See https://github.com/PacificBiosciences/FALCON/wiki/Configuration\n {}'.format(extra) logger.warning(msg) check_unexpected_keys(cfg) def check_unexpected_keys(cfg): # Warn on unused variables. expected = (TEXT_FILE_BUSY, 'input_fofn', 'input_type', 'overlap_filtering_setting', 'pa_HPCdaligner_option', 'ovlp_HPCdaligner_option', 'pa_DBsplit_option', 'skip_checks', 'pa_DBdust_option', 'dazcon', 'pa_dazcon_option', 'ovlp_DBsplit_option', 'falcon_sense_option', 'falcon_sense_skip_contained', 'falcon_sense_greedy', 'LA4Falcon_preload', 'fc_ovlp_to_graph_option', 'genome_size', 'seed_coverage', 'length_cutoff', 'length_cutoff_pr', 'bestn', 'target', ) unused = set(cfg.keys()) - set(expected) if unused: logger.warning("Unexpected keys in input config: {}".format(unused)) default_logging_config = """ [loggers] keys=root [handlers] keys=stream,file_all [formatters] keys=form01,form02 [logger_root] level=NOTSET handlers=stream,file_all [handler_stream] class=StreamHandler level=INFO formatter=form02 args=(sys.stderr,) [handler_file_all] class=FileHandler level=DEBUG formatter=form01 args=('all.log', 'w') [formatter_form01] format=%(asctime)s - %(name)s:%(lineno)d - %(levelname)s - %(message)s [formatter_form02] format=[%(levelname)s]%(message)s """ def _setup_logging(logging_config_fn): """See https://docs.python.org/2/library/logging.config.html """ logging.Formatter.converter = time.gmtime # cannot be done in .ini if logging_config_fn: if logging_config_fn.endswith('.json'): logging.config.dictConfig( json.loads(open(logging_config_fn).read())) # print repr(logging.Logger.manager.loggerDict) # to debug return logger_fileobj = open(logging_config_fn) else: logger_fileobj = NativeIO(default_logging_config) defaults = { } logging.config.fileConfig( logger_fileobj, defaults=defaults, disable_existing_loggers=False) def setup_logger(logging_config_fn): global logger try: _setup_logging(logging_config_fn) logger = logging.getLogger("fc_run") logger.info('Setup logging from file "{}".'.format(logging_config_fn)) except Exception: logging.basicConfig() logger = logging.getLogger() logger.exception( 'Failed to setup logging from file "{}". Using basicConfig().'.format(logging_config_fn)) try: import logging_tree logger.info(logging_tree.format.build_description()) except ImportError: pass return logger def get_nblock(db_file): """Return #blocks in dazzler-db. """ nblock = 1 new_db = True if os.path.exists(db_file): with open(db_file) as f: for l in f: l = l.strip().split() if l[0] == "blocks" and l[1] == "=": nblock = int(l[2]) new_db = False break # Ignore new_db for now. return nblock def daligner_gather_las(job_rundirs): """Return list of (block, las_fn). """ # Could be L1.* or preads.* re_las = re.compile(r'\.(\d*)(\.\d*)?\.las$') for job_rundir in job_rundirs: # 'out' sub-dir by convention. See run_daligner() above. (Improve that someday.) for las_fn in os.listdir(job_rundir): mo = re_las.search(las_fn) if not mo: continue # We will merge in the m_* dir of the left block. block = int(mo.group(1)) yield block, os.path.join(job_rundir, las_fn) def get_length_cutoff(length_cutoff, fn): if length_cutoff < 0: length_cutoff = int(open(fn).read().strip()) logger.info('length_cutoff=%d from %r' % (length_cutoff, fn)) return length_cutoff # possibly updated def build_rdb(input_fofn_fn, config, job_done, script_fn, run_jobs_fn): run_jobs_fn = os.path.basename(run_jobs_fn) script = bash.script_build_rdb(config, input_fofn_fn, run_jobs_fn) bash.write_script(script, script_fn, job_done) def build_pdb(input_fofn_fn, config, job_done, script_fn, run_jobs_fn): run_jobs_fn = os.path.basename(run_jobs_fn) script = bash.script_build_pdb(config, input_fofn_fn, run_jobs_fn) bash.write_script(script, script_fn, job_done) def run_db2falcon(config, preads4falcon_fn, preads_db, job_done, script_fn): script = bash.script_run_DB2Falcon(config, preads4falcon_fn, preads_db) bash.write_script(script, script_fn, job_done) def run_falcon_asm(config, las_fofn_fn, preads4falcon_fasta_fn, db_file_fn, job_done, script_fn): script = bash.script_run_falcon_asm( config, las_fofn_fn, preads4falcon_fasta_fn, db_file_fn) bash.write_script(script, script_fn, job_done) def run_report_pre_assembly(i_raw_reads_db_fn, i_preads_fofn_fn, genome_length, length_cutoff, o_json_fn, job_done, script_fn): script = bash.script_run_report_pre_assembly( i_raw_reads_db_fn, i_preads_fofn_fn, genome_length, length_cutoff, o_json_fn) bash.write_script(script, script_fn, job_done) def run_daligner(daligner_script, db_prefix, config, job_done, script_fn): bash.write_script(daligner_script, script_fn, job_done) def run_las_merge(script, job_done, config, script_fn): bash.write_script(script, script_fn, job_done) def run_consensus(db_fn, las_fn, out_file_fn, config, job_done, script_fn): script = bash.script_run_consensus( config, db_fn, las_fn, os.path.basename(out_file_fn)) bash.write_script(script, script_fn, job_done) ================================================ FILE: falcon_kit/snakemake.py ================================================ """Exact copy of falcon_unzip/tasks/snakemake.py TODO: Consolidate. """ from __future__ import absolute_import from future.utils import viewitems from future.utils import itervalues from builtins import object import json import os import re def find_wildcards(pattern): """ >>> find_wildcards('{foo}/{bar}') ['bar', 'foo'] """ re_wildcard = re.compile(r'\{(\w+)\}') found = [mo.group(1) for mo in re_wildcard.finditer(pattern)] return list(sorted(found)) class SnakemakeRuleWriter(object): def legalize(self, rule_name): return self.re_bad_char.sub('_', rule_name, count=0) def unique_rule_name(self, basename): rule_name = basename if rule_name in self.rule_names: i = 1 while rule_name in self.rule_names: rule_name = basename + str(i) i += 1 self.rule_names.add(rule_name) return rule_name def write_dynamic_rules(self, rule_name, input_json, inputs, shell_template, parameters, wildcard_outputs, output_json): """Lots of conventions. input_json: should have a key 'mapped_inputs', which is a map of key->filename Those filenames will be symlinked here, according to the patterns in wildcard_inputs. shell_template: for the parallel task output_json: This will contain only key->filename, based on wildcard_outputs. inputs: These include non-wildcards too. (For now, we assume inputs/outputs is just one per parallel task.) """ # snakemake does not like paths starting with './'; they can lead to mismatches. # So we run normpath everywhere. input_json = os.path.normpath(input_json) output_json = os.path.normpath(output_json) # snakemake cannot use already-generated files as dynamic outputs (the wildcard_inputs for the parallel task), # so we rename them and plan to symlink. wildcard_inputs = dict(inputs) nonwildcard_inputs = dict() for (key, fn) in list(viewitems(wildcard_inputs)): if '{' not in fn: del wildcard_inputs[key] nonwildcard_inputs[key] = fn continue dn, bn = os.path.split(wildcard_inputs[key]) wildcard_inputs[key] = os.path.join(dn + '.symlink', bn) rule_name = self.unique_rule_name(rule_name) dynamic_output_kvs = ', '.join("%s=dynamic('%s')"%(k, os.path.normpath(v)) for (k, v) in viewitems(wildcard_inputs)) dynamic_input_kvs = ', '.join("%s=ancient(dynamic('%s'))"%(k, os.path.normpath(v)) for (k, v) in viewitems(wildcard_outputs)) rule_parameters = {k: v for (k, v) in viewitems(parameters) if not k.startswith('_')} params = ','.join('\n %s="%s"'%(k,v) for (k, v) in viewitems(rule_parameters)) pattern_kv_list = list() for (name, wi) in viewitems(wildcard_inputs): fn_pattern = wi fn_pattern = fn_pattern.replace('{', '{{') fn_pattern = fn_pattern.replace('}', '}}') pattern_kv_list.append('%s="%s"' %(name, fn_pattern)) wi_pattern_kvs = ' '.join(pattern_kv_list) rule = """ rule dynamic_%(rule_name)s_split: input: %(input_json)r output: %(dynamic_output_kvs)s shell: 'python -m falcon_kit.mains.copy_mapped --special-split={input} %(wi_pattern_kvs)s' """%(locals()) self.write(rule) input_wildcards = set() # Not sure yet whether input must match output wildcards. for wi_fn in itervalues(wildcard_inputs): found = find_wildcards(wi_fn) input_wildcards.update(found) wildcards = list(sorted(input_wildcards)) params_plus_wildcards = {k: '{%s}'%k for k in wildcards} params_plus_wildcards.update(parameters) # The parallel script uses all inputs, not just wildcards. all_inputs = dict(wildcard_inputs) all_inputs.update(nonwildcard_inputs) self.write_script_rule(all_inputs, wildcard_outputs, params_plus_wildcards, shell_template, rule_name=None) wo_str_lists_list = ['%s=[str(i) for i in input.%s]' %(name, name) for name in list(wildcard_outputs.keys())] wo_pattern_kv_list = ['%s="%s"' %(name, os.path.normpath(patt)) for (name, patt) in viewitems(wildcard_outputs)] wo_str_lists_kvs = ',\n '.join(wo_str_lists_list) wo_pattern_kvs = ',\n '.join(wo_pattern_kv_list) wildcards = list() for wi_fn in itervalues(wildcard_outputs): found = find_wildcards(wi_fn) if wildcards: assert wildcards == found, 'snakemake requires all outputs (and inputs?) to have the same wildcards' else: wildcards = found wildcards_comma_sep = ', '.join('"%s"' %k for k in wildcards) rule = ''' rule dynamic_%(rule_name)s_merge: input: %(dynamic_input_kvs)s output: %(output_json)r run: snake_merge_multi_dynamic(output[0], dict( %(wo_str_lists_kvs)s ), dict( %(wo_pattern_kvs)s ), [%(wildcards_comma_sep)s] # all wildcards ) '''%(locals()) self.write(rule) def write_script_rule(self, inputs, outputs, parameters, shell_template, rule_name): assert '_bash_' not in parameters first_output_name, first_output_fn = outputs.items()[0] # for rundir, since we cannot sub wildcards in shell if not rule_name: rule_name = os.path.dirname(first_output_fn) rule_name = self.unique_rule_name(self.legalize(rule_name)) wildcard_rundir = os.path.normpath(os.path.dirname(first_output_fn)) # unsubstituted # We use snake_string_path b/c normpath drops leading ./, but we do NOT want abspath. input_kvs = ', '.join('%s=%s'%(k, snake_string_path(v)) for k,v in sorted(viewitems(inputs))) output_kvs = ', '.join('%s=%s'%(k, snake_string_path(v)) for k,v in sorted(viewitems(outputs))) rule_parameters = {k: v for (k, v) in viewitems(parameters) if not k.startswith('_')} #rule_parameters['reltopdir'] = os.path.relpath('.', wildcard_rundir) # in case we need this later params = ','.join('\n %s="%s"'%(k,v) for (k, v) in viewitems(rule_parameters)) shell = snake_shell(shell_template, wildcard_rundir) # cd $(dirname '{output.%(first_output_name)s}') rule = """ rule static_%(rule_name)s: input: %(input_kvs)s output: %(output_kvs)s params:%(params)s shell: ''' outdir=$(dirname {output[0]}) #mkdir -p ${{outdir}} cd ${{outdir}} date %(shell)s date ''' """%(locals()) self.write(rule) def __call__(self, inputs, outputs, parameters, shell_template, rule_name=None): self.write_script_rule(inputs, outputs, parameters, shell_template, rule_name) def __init__(self, writer): self.write = writer.write self.rule_names = set() # to ensure uniqueness self.re_bad_char = re.compile(r'\W') self.write(""" # THIS IS CURRENTLY BROKEN. import json import os #import snakemake.utils def snake_merge_dynamic_dict(reldir, input_fns, pattern, wildcards): '''Assume each wildcard appears at most once in the pattern. ''' for k in wildcards: pattern = pattern.replace('{%s}' %k, '(?P<%s>\w+)' %k) re_dynamic = re.compile(pattern) mapped = list() for fn in input_fns: mo = re_dynamic.search(fn) assert mo, '{!r} did not match {!r}'.format(fn, re_dynamic.pattern) file_description = dict() file_description['wildcards'] = dict(mo.groupdict()) file_description['fn'] = os.path.relpath(fn, reldir) mapped.append(file_description) return mapped def snake_merge_multi_dynamic(output_fn, dict_of_input_fns, dict_of_patterns, wildcards): outdir = os.path.normpath(os.path.dirname(output_fn)) if not os.path.isdir(outdir): os.makedirs(outdir) assert list(sorted(dict_of_input_fns.keys())) == list(sorted(dict_of_patterns.keys())) all_mapped = dict() for i in dict_of_patterns.keys(): input_fns = dict_of_input_fns[i] pattern = dict_of_patterns[i] mapped = snake_merge_dynamic_dict(outdir, input_fns, pattern, wildcards) all_mapped[i] = mapped all_grouped = dict() for i, mapped in all_mapped.items(): #print(i, mapped) for file_description in mapped: #print(file_description) #print(file_description['wildcards']) #print(list(sorted(file_description['wildcards'].items()))) wildkey = ','.join('{}={}'.format(k,v) for k,v in sorted(file_description['wildcards'].items())) if wildkey not in all_grouped: new_group = dict( wildcards=dict(file_description['wildcards']), fns=dict(), ) all_grouped[wildkey] = new_group group = all_grouped[wildkey] wildcards = file_description['wildcards'] assert wildcards == group['wildcards'], '{!r} should match {!r} by snakemake convention'.format( wildcards, group['wildcards']) fn = file_description['fn'] group['fns'][i] = fn ser = json.dumps(all_grouped, indent=2, separators=(',', ': ')) + '\\n' with open(output_fn, 'w') as out: out.write(ser) """) prefix = """ shell.prefix(''' # Add -e vs. in falcon_unzip. set -vex hostname pwd ''') """ self.write(prefix) class SnakemakeDynamic(object): """Not currently used.""" def __init__(self, path): self.path = path def snake_string_path(p): """normpath drops leading ./ """ if isinstance(p, SnakemakeDynamic): return "dynamic('{}')".format( os.path.normpath(p.path)) else: return "'{}'".format( os.path.normpath(p)) def snake_shell(template, rundir): reltopdir = os.path.relpath('.', rundir) def makerel(mo): return os.path.join(reltopdir, mo.group(0)) re_inout = re.compile(r'{(?:input|output)') return re_inout.sub(makerel, template, count =0) ================================================ FILE: falcon_kit/stats_preassembly.py ================================================ #!/usr/bin/env python2.7 """ PreAssembly Report. See FALCON-pbsmrtpipe/pbfalcon/report_preassembly.py for XML version. """ # Copied from # http://swarm/files/depot/branches/springfield/S2.3/software/smrtanalysis/bioinformatics/tools/pbreports/pbreports/report/preassembly.py from __future__ import absolute_import from __future__ import division from future.utils import viewitems from builtins import object from .FastaReader import open_fasta_reader from .util.io import syscall from . import functional import collections import glob import itertools import logging import os import pprint import re log = logging.getLogger(__name__) __version__ = '0.1' Stats = collections.namedtuple( 'FastaStats', ['nreads', 'total', 'n50', 'p95', 'esize']) # Copied from pbreports/util.py # We want to avoid a dependency on pbreports b/c it needs matplotlib. def get_fasta_readlengths(fasta_file): """ Get a sorted list of contig lengths :return: (tuple) """ lens = [] with open_fasta_reader(fasta_file) as f: for record in f: lens.append(len(record.sequence)) lens.sort() return lens def get_db_readlengths(fn): """Use DBdump on a DAZZ_DB. If DBsplit was run, then we see the filtered reads only, since we do not provide '-u' to DBdump. """ call = 'DBdump -h {}'.format(fn) return list(functional.parsed_readlengths_from_dbdump_output(syscall(call))) class FastaContainer(object): def __init__(self, nreads, total, file_name): self.nreads = nreads self.total = total self.file_name = file_name @staticmethod def from_file(file_name): # nreads, total = _compute_values(file_name) read_lens = get_fasta_readlengths(file_name) nreads = len(read_lens) total = sum(read_lens) return FastaContainer(nreads, total, file_name) def __str__(self): return "N {n} Total {t} File: {f}".format(n=self.nreads, t=self.total, f=self.file_name) def _validate_file(file_name): if os.path.isfile(file_name): return os.path.abspath(file_name) else: msg = "Unable to find {f}".format(f=file_name) log.error(msg) raise IOError(msg) def cutoff_reads(read_lens, min_read_len): return [rl for rl in read_lens if rl >= min_read_len] def read_len_above(read_lens, threshold): subtotal = 0 # Reverse-order calculation is faster. for irev, rl in enumerate(reversed(read_lens)): subtotal += rl if subtotal >= threshold: return rl def percentile(read_lens, p): # TODO: Fix this when p=1.0 return read_lens[int(len(read_lens) * p)] def stats_from_sorted_readlengths(read_lens): nreads = len(read_lens) total = sum(read_lens) sum_squares = sum(r * r for r in read_lens) n50 = read_len_above(read_lens, int(total * 0.50)) p95 = percentile(read_lens, 0.95) esize = sum_squares / total #alt_n50 = pbreports.util.compute_n50(read_lens) # log.info('our n50=%s, pbreports=%s' %(n50, alt_n50)) # Ours is more correct when median is between 2 reads. return Stats(nreads=nreads, total=total, n50=n50, p95=p95, esize=esize) def read_lens_from_fofn(fofn_fn): """Return sorted list. """ fns = [fn.strip() for fn in open(fofn_fn) if fn.strip()] # get_fasta_readlengths() returns sorted, so sorting the chain is roughly linear. return list(sorted(itertools.chain.from_iterable(get_fasta_readlengths(fn) for fn in fns))) def read_lens_from_db(db_fn): """Return sorted read-lengths from a DAZZ_DB. """ return list(sorted(get_db_readlengths(db_fn))) def abs_filenames(fofn_fn): fofn_dir = os.path.dirname(fofn_fn) def abs_fn(fn): if os.path.isabs(fn): return fn return os.path.join(fofn_dir, fn) fns = [abs_fn(fn.strip()) for fn in open(fofn_fn) if fn.strip()] return fns def metric_fragmentation(preads_fofn): # https://jira.pacificbiosciences.com/browse/SAT-105 # sed -nr 's;>prolog/([0-9]*)[0-9]/.*;\1;p' %s/*.fasta | sort | uniq -c | awk '{print $1}' | sort | uniq -c fastas = abs_filenames(preads_fofn) assert fastas, 'No fasta found in {!r}'.format(preads_fofn) call = """perl -e 'while (<>) { if ( m{>[^/]+/(\d+)\d/} ) { $id{$1}++; } }; while (my ($k, $v) = each %%id) { $counts{$v}++; }; while (my ($k, $v) = each %%counts) { print "$v $k\n"; };' %s""" % (' '.join(fastas)) counts = syscall(call) return functional.calc_metric_fragmentation(counts) def metric_truncation(db, preads_fofn): # https://jira.pacificbiosciences.com/browse/SAT-105 fastas = abs_filenames(preads_fofn) assert fastas, 'No fasta found in {!r}'.format(preads_fofn) call = """perl -e 'while (<>) { if ( m{>[^/]+/0*(\d+)\d/(\d+)_(\d+)} ) { $lengths{(1 + $1)} += ($3 - $2); } }; while (my ($k, $v) = each %%lengths) { print "$k $v\n"; };' %s""" % (' '.join(fastas)) # The +1 is because of the DBdump readids start at 1, but these start at 0. length_pairs_output = syscall(call) call = 'DBdump -rh {}'.format(db) dbdump_output = syscall(call) return functional.calc_metric_truncation(dbdump_output, length_pairs_output) def stats_dict(stats_raw_reads, stats_seed_reads, stats_corrected_reads, genome_length, length_cutoff, fragmentation, truncation): """All inputs are paths to fasta files. genome_length and length_cutoff can be None. """ log.info('stats for raw reads: %s' % repr(stats_raw_reads)) log.info('stats for seed reads: %s' % repr(stats_seed_reads)) log.info('stats for corrected reads: %s' % repr(stats_corrected_reads)) kwds = {} genome_length = -1 if not genome_length else genome_length kwds['genome_length'] = genome_length kwds['length_cutoff'] = 0 if length_cutoff is None else length_cutoff kwds['raw_reads'] = stats_raw_reads.nreads kwds['raw_bases'] = stats_raw_reads.total kwds['raw_mean'] = stats_raw_reads.total / stats_raw_reads.nreads kwds['raw_n50'] = stats_raw_reads.n50 kwds['raw_p95'] = stats_raw_reads.p95 kwds['raw_coverage'] = stats_raw_reads.total / genome_length kwds['raw_esize'] = stats_raw_reads.esize kwds['seed_reads'] = stats_seed_reads.nreads kwds['seed_bases'] = stats_seed_reads.total kwds['seed_mean'] = stats_seed_reads.total / stats_seed_reads.nreads kwds['seed_n50'] = stats_seed_reads.n50 kwds['seed_p95'] = stats_seed_reads.p95 kwds['seed_coverage'] = stats_seed_reads.total / genome_length kwds['seed_esize'] = stats_seed_reads.esize kwds['preassembled_reads'] = stats_corrected_reads.nreads kwds['preassembled_bases'] = stats_corrected_reads.total kwds['preassembled_mean'] = stats_corrected_reads.total / \ stats_corrected_reads.nreads kwds['preassembled_n50'] = stats_corrected_reads.n50 kwds['preassembled_p95'] = stats_corrected_reads.p95 kwds['preassembled_coverage'] = stats_corrected_reads.total / genome_length kwds['preassembled_esize'] = stats_corrected_reads.esize kwds['preassembled_yield'] = stats_corrected_reads.total / \ stats_seed_reads.total kwds['preassembled_seed_fragmentation'] = fragmentation kwds['preassembled_seed_truncation'] = truncation def round_if_float(v): return v if type(v) is not float else round(v, 3) result = {k: round_if_float(v) for (k, v) in viewitems(kwds)} return result # DEPRECATED def make_dict( i_preads_fofn_fn, i_raw_reads_fofn_fn, genome_length, length_cutoff, fragmentation=-1, truncation=-1, ): raw_reads = read_lens_from_fofn(i_raw_reads_fofn_fn) stats_raw_reads = stats_from_sorted_readlengths(raw_reads) seed_reads = cutoff_reads(raw_reads, length_cutoff) stats_seed_reads = stats_from_sorted_readlengths(seed_reads) preads = read_lens_from_fofn(i_preads_fofn_fn) stats_preads = stats_from_sorted_readlengths(preads) report_dict = stats_dict( stats_raw_reads=stats_raw_reads, stats_seed_reads=stats_seed_reads, stats_corrected_reads=stats_preads, genome_length=genome_length, length_cutoff=length_cutoff, fragmentation=fragmentation, truncation=truncation, ) return report_dict def calc_dict( i_preads_fofn_fn, i_raw_reads_db_fn, genome_length, length_cutoff, ): try: frag = metric_fragmentation(i_preads_fofn_fn) except: frag = -1.0 log.exception('Using arbitrary fragmentation metric: {}'.format(frag)) try: trunc = metric_truncation(i_raw_reads_db_fn, i_preads_fofn_fn) except: trunc = -1.0 log.exception('Using arbitrary truncation metric: {}'.format(trunc)) raw_reads = read_lens_from_db(i_raw_reads_db_fn) stats_raw_reads = stats_from_sorted_readlengths(raw_reads) seed_reads = cutoff_reads(raw_reads, length_cutoff) stats_seed_reads = stats_from_sorted_readlengths(seed_reads) preads = read_lens_from_fofn(i_preads_fofn_fn) stats_preads = stats_from_sorted_readlengths(preads) report_dict = stats_dict( stats_raw_reads=stats_raw_reads, stats_seed_reads=stats_seed_reads, stats_corrected_reads=stats_preads, genome_length=genome_length, length_cutoff=length_cutoff, fragmentation=frag, truncation=trunc, ) log.info('Calculated pre-assembly stats:\n{}'.format( pprint.pformat(report_dict))) return report_dict ================================================ FILE: falcon_kit/tiling_path.py ================================================ class TilingPathEdge: def __init__(self, split_line = None): self.ctg_id, self.v, self.w, self.wrid, self.b, self.e, self.score, self.identity = \ None, None, None, None, None, None, None, None self.parsed = False if split_line: # pragma: no cover self.set_from(split_line) def set_from(self, split_line): assert(len(split_line) >= 8) self.parsed = False self.ctg_id = split_line[0] self.v = split_line[1] self.w = split_line[2] self.wrid = split_line[3] self.b = int(split_line[4]) self.e = int(split_line[5]) self.score = int(split_line[6]) self.identity = float(split_line[7]) self.parsed = True def get_split_line(self): return [str(val) for val in [self.ctg_id, self.v, self.w, self.wrid, self.b, self.e, self.score, self.identity]] # def __str__(self): # return ' '.join(self.get_split_line()) class TilingPath: def __init__(self, tiling_edge_list, contig_sequence_len = None): self.edges = tiling_edge_list # These are TilingPathEdge objects. self.v_to_edge = {} self.w_to_edge = {} self.coords = {} self.contig_len = 0 self.first_node_offset = 0 for i in xrange(1, len(tiling_edge_list)): assert(tiling_edge_list[i-1].w == tiling_edge_list[i].v) # If the total contig sequence len is known, use that to # calculate the length of the first read (in case proper # contigs are specified). This is needed to offset the coordinates # which can be calculated from the tiling path. if contig_sequence_len != None: _, tiling_len = calc_node_coords(tiling_edge_list) assert(contig_sequence_len >= tiling_len) self.first_node_offset = contig_sequence_len - tiling_len # This is the length of the first node. # The self.coords is a dict: self.coords[v] = coordinate_on_contig self.coords, self.contig_len = calc_node_coords(tiling_edge_list, self.first_node_offset) # Sanity check. assert(contig_sequence_len == None or self.contig_len == contig_sequence_len) # Create a lookup of node to edge. self.v_to_edge = {} self.w_to_edge = {} for i in xrange(len(self.edges)): e = self.edges[i] self.v_to_edge[e.v] = i self.w_to_edge[e.w] = i def dump_as_split_lines(self): return [e.get_split_line() for e in self.edges] def get_subpath(self, start_coord, end_coord): """ Given a TilingPath object, the method called `TilingPath.get_subpath() will attempt to extract a part of the tiling path which covers the specified coordinates. For example, user could specify alignment start and end positions, and provide the coordinates to this method, and the result would be a list of tiling path edges which correspond to the tiling in between the two coordinates (most likely slightly longer on both ends). Both start and end coordinates can be < 0 if the input contig was improper. Returns a list of split_line tiling path edges (not TilingEdge objects). """ assert(self.edges) assert(start_coord <= end_coord) # end_coord -= 1 # Make the end inclusive. # start_node = None # end_node = None start_edge = None end_edge = None if start_coord < self.coords[self.edges[0].v]: start_edge = 0 if end_coord <= self.coords[self.edges[0].v]: end_edge = 1 for i in xrange(len(self.edges)): e = self.edges[i] if start_coord >= self.coords[e.v] and start_coord < self.coords[e.w]: start_edge = i if end_coord > self.coords[e.v] and end_coord <= self.coords[e.w]: end_edge = i + 1 if end_coord >= self.coords[self.edges[-1].w]: end_edge = len(self.edges) assert(start_edge != None and end_edge != None) # Since the start_coord and end_coord can end within an edge, # we return the position in the final contigas. new_start_coord = start_coord - self.coords[self.edges[start_edge].v] new_end_coord = end_coord - self.coords[self.edges[start_edge].v] new_path = self.edges[start_edge:end_edge] new_path = [val.get_split_line() for val in new_path] return new_path, new_start_coord, new_end_coord def calc_node_coords(tiling_edge_list, first_node_offset=0): """ For a single tiling path (tiling_edge_list is a list of edges for a particular contig) calculates the genomic coordinate of every node in the path. In case there are cycles in the tiling path, the existing node's coordinate will be overwritten. `first_node_offset` refers to the length of the first node. If not specified, the contig length should not consider the length of the first node. """ if not tiling_edge_list: return {}, 0 coord_map = {} contig_len = 0 edge0 = tiling_edge_list[0] coord_map[edge0.v] = first_node_offset for edge in tiling_edge_list: if edge.v not in coord_map: raise Exception( 'Tiling path is not in sorted order. Node "{v!r}" does not yet have an assigned coordinate.'.format(v=edge.v)) coord = coord_map[edge.v] coord += abs(int(edge.b) - int(edge.e)) coord_map[edge.w] = coord contig_len = max(contig_len, coord) return coord_map, contig_len def yield_split_line(fp_in): for line in fp_in: # Example row: "0 000000007:B 000000005:B 000000005 9 0 1980 99.95" line = line.strip() if len(line) == 0: continue sl = line.split() yield sl def load_tiling_paths(tp_file, contig_lens=None, whitelist_seqs=None): with open(tp_file) as fp_in: ret = load_tiling_paths_from_stream(fp_in, contig_lens=contig_lens, whitelist_seqs=whitelist_seqs) return ret def load_tiling_paths_from_stream(fp_in, contig_lens=None, whitelist_seqs=None): split_lines = list(yield_split_line(fp_in)) return load_tiling_paths_from_split_lines(split_lines, contig_lens=contig_lens, whitelist_seqs=whitelist_seqs) def load_tiling_paths_from_split_lines(split_lines, contig_lens=None, whitelist_seqs=None): """ Parameters: contig_lens - if a dict with contig sequence lengths is specified, the difference between the contig len and the length obtained from the tiling path will be used to offset the tiling path coordinates. whitelist_seqs - a dict or a set object containing contig IDs to load. If None, no filter will be applied. """ tiling_path_edges = {} for sl in split_lines: # Example row: "0 000000007:B 000000005:B 000000005 9 0 1980 99.95" new_edge = TilingPathEdge(sl) ctg_id = new_edge.ctg_id if whitelist_seqs != None and (ctg_id in whitelist_seqs) == False: continue tiling_path_edges.setdefault(ctg_id, []) tiling_path_edges[ctg_id].append(new_edge) # Convert the flat lists to TilingPath objects. # These keep track of tiling_paths = {} for ctg_id, edges in tiling_path_edges.iteritems(): ctg_len = None if contig_lens != None and ctg_id in contig_lens: ctg_len = contig_lens[ctg_id] tiling_paths[ctg_id] = TilingPath(edges, ctg_len) return tiling_paths def find_a_ctg_placement(p_paths, a_paths): """ Determines placement coordinates for each a_ctg in a given a_paths dict of TilingPaths, and returns a dict of: placement[p_ctg_id][a_ctg_id] = (start, end, p_ctg_id, a_ctg_id, first_node, last_node) """ placement = {} for a_ctg_id, a_tp in a_paths.iteritems(): if len(a_tp.edges) == 0: continue # pragma: no cover first_node = a_tp.edges[0].v last_node = a_tp.edges[-1].w p_ctg_id = a_ctg_id.split('-')[0].split('_')[0] p_tp = p_paths[p_ctg_id] start, end = p_tp.coords[first_node], p_tp.coords[last_node] placement.setdefault(p_ctg_id, {}) placement[p_ctg_id][a_ctg_id] = (start, end, p_ctg_id, a_ctg_id, first_node, last_node) return placement ================================================ FILE: falcon_kit/util/__init__.py ================================================ ================================================ FILE: falcon_kit/util/io.py ================================================ """I/O utilities Not specific to FALCON. """ from __future__ import absolute_import #from builtins import str from builtins import object import os import resource import shlex import subprocess as sp import sys import traceback from ..io import deserialize def write_nothing(*args): """ To use, LOG = noop """ def write_with_pid(*args): msg = '[%d]%s\n' % (os.getpid(), ' '.join(args)) sys.stderr.write(msg) LOG = write_with_pid def logstats(): """This is useful 'atexit'. """ LOG('maxrss:%9d' % (resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)) def reprarg(arg): if (isinstance(arg, set) or isinstance(arg, list) or isinstance(arg, tuple) or isinstance(arg, dict)): if len(arg) > 9: return '%s(%d elem)' % (type(arg).__name__, len(arg)) return repr(arg) def run_func(args): """Wrap multiprocessing.Pool calls. Usage: pool.imap(run_func, [func, arg0, arg1, ...]) """ func = args[0] try: func_name = func.__name__ except: # but since it must be pickle-able, this should never happen. func_name = repr(func) args = args[1:] try: LOG('starting %s(%s)' % (func_name, ', '.join(reprarg(a) for a in args))) logstats() ret = func(*args) logstats() LOG('finished %s(%s)' % (func_name, ', '.join(reprarg(a) for a in args))) return ret except Exception: raise Exception(traceback.format_exc()) except: # KeyboardInterrupt, SystemExit LOG('interrupted %s(%s)' % (func_name, ', '.join(reprarg(a) for a in args))) return def system(call, check=False): LOG('$(%s)' % repr(call)) rc = os.system(call) msg = "Call %r returned %d." % (call, rc) if rc: LOG("WARNING: " + msg) if check: raise Exception(msg) else: LOG(msg) return rc def syscall(cmd): """Return stdout, fully captured. Wait for subproc to finish. Raise if empty. Raise on non-zero exit-code. """ LOG('$ {!r} >'.format(cmd)) output = sp.check_output(shlex.split(cmd)) if not output: msg = '%r failed to produce any output.' % cmd LOG('WARNING: %s' % msg) return output def slurplines(cmd): return syscall(cmd).splitlines() def streamlines(cmd): """Stream stdout from cmd. Let stderr fall through. The returned reader will stop yielding when the subproc exits. Note: We do not detect a failure in the underlying process. """ LOG('$ %s |' % cmd) proc = sp.Popen(shlex.split(cmd), stdout=sp.PIPE) return proc.stdout class DataReaderContext(object): def readlines(self): output = self.data.strip() for line in output.splitlines(): yield line def __enter__(self): pass def __exit__(self, *args): self.returncode = 0 def __init__(self, data): self.data = data class ProcessReaderContext(object): """Prefer this to slurplines() or streamlines(). """ def readlines(self): """Generate lines of native str. """ # In py2, not unicode. raise NotImplementedError() def __enter__(self): LOG('{!r}'.format(self.cmd)) self.proc = sp.Popen(shlex.split(self.cmd), stdout=sp.PIPE, universal_newlines=True) def __exit__(self, etype, evalue, etb): if etype is None: self.proc.wait() else: # Exception was raised in "with-block". # We cannot wait on proc b/c it might never finish! pass self.returncode = self.proc.returncode if self.returncode: msg = "%r <- %r" % (self.returncode, self.cmd) raise Exception(msg) del self.proc def __init__(self, cmd): self.cmd = cmd def splitlines_iter(text): """This is the same as splitlines, but with a generator. """ # https://stackoverflow.com/questions/3054604/iterate-over-the-lines-of-a-string assert isinstance(text, str) prevnl = -1 while True: nextnl = text.find('\n', prevnl + 1) # u'\n' would force unicode if nextnl < 0: break yield text[prevnl + 1:nextnl] prevnl = nextnl if (prevnl + 1) != len(text): yield text[prevnl + 1:] class CapturedProcessReaderContext(ProcessReaderContext): def readlines(self): """Usage: cmd = 'ls -l' reader = CapturedProcessReaderContext(cmd) with reader: for line in reader.readlines(): print line Any exception within the 'with-block' is propagated. Otherwise, after all lines are read, if 'cmd' failed, Exception is raised. """ output, _ = self.proc.communicate() # Process has terminated by now, so we can iterate without keeping it alive. #for line in splitlines_iter(str(output, 'utf-8')): for line in splitlines_iter(output): yield line class StreamedProcessReaderContext(ProcessReaderContext): def readlines(self): """Usage: cmd = 'ls -l' reader = StreamedProcessReaderContext(cmd) with reader: for line in reader.readlines(): print line Any exception within the 'with-block' is propagated. Otherwise, after all lines are read, if 'cmd' failed, Exception is raised. """ for line in self.proc.stdout: # We expect unicode from py3 but raw-str from py2, given # universal_newlines=True. # Based on source-code in 'future/types/newstr.py', # it seems that str(str(x)) has no extra penalty, # and it should not crash either. Anyway, # our tests would catch it. #yield str(line, 'utf-8').rstrip() yield line.rstrip() def filesize(fn): """In bytes. Raise if fn does not exist. """ statinfo = os.stat(fn) return statinfo.st_size def validated_fns(fofn): return list(yield_validated_fns(fofn)) def yield_validated_fns(fofn): """Return list of filenames from fofn, either abs or relative to CWD instead of dir of fofn. Assert none are empty/non-existent. """ dirname = os.path.normpath(os.path.dirname(fofn)) # normpath makes '' become '.' try: fns = deserialize(fofn) except: #LOG('las fofn {!r} does not seem to be JSON or msgpack; try to switch, so we can detect truncated files.'.format(fofn)) fns = open(fofn).read().strip().split() try: for fn in fns: assert fn if not os.path.isabs(fn): fn = os.path.normpath(os.path.join(dirname, fn)) assert os.path.isfile(fn), 'File {!r} is not a file.'.format(fn) assert filesize(fn), '{!r} has size {}'.format(fn, filesize(fn)) yield fn except Exception: sys.stderr.write('Failed to validate FOFN {!r}\n'.format(fofn)) raise ================================================ FILE: falcon_kit/util/system.py ================================================ from __future__ import absolute_import from future.utils import viewitems from pypeflow.io import cd, capture import logging import os import pprint import fnmatch log = logging.getLogger(__name__) def only_these_symlinks(dir2paths): """Create symlinks, and delete all other symlinks for each directory. dir2paths := {dir: [paths]} ('paths' is usually a list of 1.) Use relative symlink targets. Possibly, log everything we do, as one log statement to avoid user complaints. """ log.info('Symlink .las files for further merging:\n{}'.format( pprint.pformat(dict(dir2paths)))) for (d, paths) in viewitems(dir2paths): bases = [os.path.basename(path) for path in paths] base2rel = {os.path.basename(path): os.path.relpath( path, d) for path in paths} assert len(base2rel) == len( bases), 'Non-unique basename in {}'.format(repr(paths)) for existing_base in os.listdir(d): existing_path = os.path.join(d, existing_base) if os.path.islink(existing_path): if existing_base in base2rel: if os.readlink(existing_path) != base2rel[existing_base]: # Wrong target (or non-relative) so remove it. os.unlink(existing_path) else: del base2rel[existing_base] # Just keep it. else: os.unlink(existing_path) # Old? Remove it for safety. for (base, rel) in viewitems(base2rel): path = os.path.join(d, base) os.symlink(rel, path) def lfs_setstripe_maybe(path='.', stripe=12): path = os.path.abspath(path) cmd = 'lfs setstripe -c {:d} {!s}'.format(stripe, path) try: capture(cmd) log.info('Lustre filesystem detected. This lfs stripe ({}) should propagate to subdirs of {!r}.'.format( stripe, path)) except Exception as exc: log.info('Apparently {!r} is not in lustre filesystem, which is fine.'.format( path)) def find_files(root_path, pattern): """ Finds all files with filenames formatted as the given pattern, descending down from root_path. raise Exception if root_path is not a directory. """ if not os.path.isdir(root_path): raise Exception('Not a directory: {!r}'.format(root_path)) for root, dirs, files in os.walk(root_path): dirs.sort() for filename in sorted(fnmatch.filter(files, pattern)): yield os.path.join(root, filename) def abs_fns(ifofns, idir=None): """Yield absolute filenames from a streamed file-of-filenames. """ log.info('Absolutizing FOFN in dir={!r}'.format(os.path.abspath(idir))) for line in ifofns.read().split(): ifn = line.strip() if not ifn: continue if not os.path.isabs(ifn): ifn = os.path.abspath(os.path.join(idir, ifn)) yield ifn def make_fofn_abs(i_fofn_fn, o_fofn_fn): """Copy i_fofn to o_fofn, but with relative filenames expanded for the dir of i_fofn. """ assert os.path.abspath(o_fofn_fn) != os.path.abspath( i_fofn_fn), '{!r} != {!r}'.format(o_fofn_fn, i_fofn_fn) with open(i_fofn_fn) as ifs, open(o_fofn_fn, 'w') as ofs: for fn in abs_fns(ifs, os.path.dirname(os.path.realpath(i_fofn_fn))): ofs.write(fn + '\n') # return o_fofn_fn def make_dirs(d): if not os.path.isdir(d): log.debug('mkdir -p {!r}'.format(d)) os.makedirs(d) def touch(*paths): """touch a file. """ msg = 'touch {!r}'.format(paths) log.debug(msg) for path in paths: if os.path.exists(path): os.utime(path, None) else: open(path, 'a').close() ================================================ FILE: makefile ================================================ # Feel free to override this. ifndef PYTHONUSERBASE PYTHONUSERBASE:=LOCAL PATH:=${PYTHONUSERBASE}/bin:${PATH} export PYTHONUSERBASE export PATH endif WHEELHOUSE?=wheelhouse PIP=pip wheel --wheel-dir ${WHEELHOUSE} MY_TEST_FLAGS?=-v -s --durations=0 DOCTEST_MODULES= falcon_kit/functional.py falcon_kit/mains/consensus_task.py falcon_kit/mains/las_merge_split.py install-edit: pip -v install --user --edit . install: wheel pip -v install --user --use-wheel --find-links=dist/ . pylint: pylint --errors-only falcon_kit/ test: python -c 'import falcon_kit; print falcon_kit.falcon' which py.test || pip install --user pytest py.test ${MY_TEST_FLAGS} --junit-xml=test.xml --doctest-modules ${DOCTEST_MODULES} test/ autopep8: autopep8 --max-line-length=120 -ir -j0 falcon_kit/ examples/ test/ setup.py old-wheel: pip install --upgrade --user pip python setup.py bdist_wheel # Look for dist/*.whl wheel: which pip ${PIP} --no-deps . ls -larth ${WHEELHOUSE} tar: rm -f FALCON.tar.gz tar cvzf FALCON.tar.gz -C ${PYTHONUSERBASE} . # Much smaller than the wheel, and includes all necessary dependencies, # but also includes anything already in the user-site. clean: \rm -f *.xml .PHONY: install test install-no-edit wheel tar clean ================================================ FILE: setup.cfg ================================================ [tool:pytest] doctest_optionflags = ALLOW_UNICODE ================================================ FILE: setup.py ================================================ #!/usr/bin/env python2.7 from setuptools import setup, Extension import subprocess import sys import glob install_requires = [ "networkx >=1.7, <=1.11", "msgpack", "future >= 0.16.0", #"logging_tree", #"pbcore >= 0.6.3", "pypeFLOW >= 2.0.0", ] scripts = [] try: local_version = '+git.{}'.format( subprocess.check_output('git rev-parse HEAD', shell=True)) except Exception: local_version = '' setup(name='falcon_kit', version='1.1.1' + local_version, description='a small toolkit for DNA seqeucne alignment, overlapping, and assembly', author='Jason Chin', author_email='jchin@pacificbiosciences.com', packages=['falcon_kit', 'falcon_kit.mains', 'falcon_kit.util', ], package_dir={'falcon_kit': 'falcon_kit/'}, ext_modules=[ Extension('ext_falcon', ['src/c/ext_falcon.c', 'src/c/DW_banded.c', 'src/c/kmer_lookup.c', 'src/c/falcon.c'], extra_link_args=[], extra_compile_args=['-fPIC', '-O3', '-fno-omit-frame-pointer'], # '-fno-omit-frame-pointer' can help with gperftools. # libraries=['profiler'], # include_dirs=['/home/cdunn/local/include'], # library_dirs=['/home/cdunn/local/lib'], # language="c++", # c for now # export_symbols=['generate_consensus'], # for windows? ), ], entry_points={'console_scripts': [ 'falcon-task=falcon_kit.mains.tasks:main', 'fc_actg_coordinate=falcon_kit.mains.actg_coordinate:main', 'fc_consensus=falcon_kit.mains.consensus:main', 'fc_contig_annotate=falcon_kit.mains.contig_annotate:main', 'fc_ctg_link_analysis=falcon_kit.mains.ctg_link_analysis:main', 'fc_dedup_a_tigs=falcon_kit.mains.dedup_a_tigs:main', 'fc_graph_to_contig=falcon_kit.mains.graph_to_contig:main', 'fc_graph_to_utgs=falcon_kit.mains.graph_to_utgs:main', 'fc_ovlp_filter=falcon_kit.mains.ovlp_filter:main', 'fc_ovlp_stats=falcon_kit.mains.ovlp_stats:main', 'fc_ovlp_to_graph=falcon_kit.mains.ovlp_to_graph:main', 'fc_calc_cutoff=falcon_kit.mains.calc_cutoff:main', 'fc_run=falcon_kit.mains.run1:main', 'fc_run1=falcon_kit.mains.run1:main', 'fc_fasta2fasta=falcon_kit.mains.fasta2fasta:main', 'fc_fetch_reads=falcon_kit.mains.fetch_reads:main', 'fc_get_read_ctg_map=falcon_kit.mains.get_read_ctg_map:main', 'fc_pr_ctg_track=falcon_kit.mains.pr_ctg_track:main', 'fc_rr_ctg_track=falcon_kit.mains.rr_ctg_track:main', 'fc_gen_gfa_v1 = falcon_kit.mains.gen_gfa_v1:main', # Some scripts still use old .py scripts, which need shebang lines. # (I guess pip does not add shebang to scripts.) 'fc_run.py=falcon_kit.mains.run1:main', ], }, extras_require={ 'falcon-task': ['falcon_kit'], }, scripts=scripts, zip_safe=False, install_requires=install_requires, ) ================================================ FILE: src/c/DW_banded.c ================================================ /* * ===================================================================================== * * Filename: DW_banded.c * * Description: A banded version for the O(ND) greedy sequence alignment algorithm * * Version: 0.1 * Created: 07/20/2013 17:00:00 * Revision: none * Compiler: gcc * * Author: Jason Chin, * Company: * * ===================================================================================== #################################################################################$$ # Copyright (c) 2011-2014, Pacific Biosciences of California, Inc. # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted (subject to the limitations in the # disclaimer below) provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # # * Neither the name of Pacific Biosciences nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE # GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY PACIFIC # BIOSCIENCES AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL PACIFIC BIOSCIENCES OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. #################################################################################$$ */ #include #include #include #include #include "common.h" int compare_d_path(const void * a, const void * b) { const d_path_data2 * arg1 = a; const d_path_data2 * arg2 = b; if (arg1->d - arg2->d == 0) { return arg1->k - arg2->k; } else { return arg1->d - arg2->d; } } void d_path_sort( d_path_data2 * base, unsigned long max_idx) { qsort(base, max_idx, sizeof(d_path_data2), compare_d_path); } d_path_data2 * get_dpath_idx( seq_coor_t d, seq_coor_t k, unsigned long max_idx, d_path_data2 * base) { d_path_data2 d_tmp; d_path_data2 *rtn; d_tmp.d = d; d_tmp.k = k; rtn = (d_path_data2 *) bsearch( &d_tmp, base, max_idx, sizeof(d_path_data2), compare_d_path); //printf("dp %ld %ld %ld %ld %ld %ld %ld\n", (rtn)->d, (rtn)->k, (rtn)->x1, (rtn)->y1, (rtn)->x2, (rtn)->y2, (rtn)->pre_k); return rtn; } void print_d_path( d_path_data2 * base, unsigned long max_idx) { unsigned long idx; for (idx = 0; idx < max_idx; idx++){ printf("dp %ld %d %d %d %d %d %d %d\n",idx, (base+idx)->d, (base+idx)->k, (base+idx)->x1, (base+idx)->y1, (base+idx)->x2, (base+idx)->y2, (base+idx)->pre_k); } } void* my_calloc(int nitems, size_t size, char const* msg, int lineno) { if (nitems < 0) { fprintf(stderr, "CRITICAL ERROR: %s=calloc(%d, %zu) cannot take a negative value at line %d.\n", msg, nitems, size, lineno); abort(); } void* result = calloc((size_t)nitems, size); if (NULL == result) { fprintf(stderr, "CRITICAL ERROR: %s=calloc(%d, %zu) returned 0.\n", msg, nitems, size, lineno); abort(); } return result; } alignment * align(char * query_seq, seq_coor_t q_len, char * target_seq, seq_coor_t t_len, seq_coor_t band_tolerance, int get_aln_str) { seq_coor_t * V; seq_coor_t * U; // array of matched bases for each "k" seq_coor_t k_offset; seq_coor_t d; seq_coor_t k, k2; seq_coor_t best_m; // the best "matches" for each d seq_coor_t min_k, new_min_k; seq_coor_t max_k, new_max_k; seq_coor_t pre_k; seq_coor_t x, y; seq_coor_t cd; seq_coor_t ck; seq_coor_t cx, cy, nx, ny; seq_coor_t max_d; seq_coor_t band_size; unsigned long d_path_idx = 0; unsigned long max_idx = 0; d_path_data2 * d_path; d_path_data2 * d_path_aux; path_point * aln_path; seq_coor_t aln_path_idx; alignment * align_rtn; seq_coor_t aln_pos; seq_coor_t i; bool aligned = false; //printf("debug: %ld %ld\n", q_len, t_len); //printf("%s\n", query_seq); max_d = (int) (0.3*(q_len + t_len)); band_size = band_tolerance * 2; V = my_calloc(max_d * 2 + 1, sizeof(seq_coor_t), "V", __LINE__); U = my_calloc(max_d * 2 + 1, sizeof(seq_coor_t), "U", __LINE__); k_offset = max_d; if ((size_t)INT_MAX < ((size_t)max_d * (size_t)(band_size + 1) * 2ULL)) { fprintf(stderr, "CRITICAL ERROR: q_len=%d and t_len=%d => max_d=%d, and band_size=%d. Those lens are too big.\n", q_len, t_len, max_d, band_size); abort(); } // We should probably use hashmap to store the backtracing information to save memory allocation time // This O(MN) block allocation scheme is convient for now but it is slower for very long sequences d_path = my_calloc(max_d * (band_size + 1 ) * 2 + 1, sizeof(d_path_data2), "d_path", __LINE__); aln_path = my_calloc(q_len + t_len + 1, sizeof(path_point), "aln_path", __LINE__); align_rtn = my_calloc(1, sizeof(alignment), "align_rtn", __LINE__); align_rtn->t_aln_str = my_calloc(q_len + t_len + 1, sizeof(char), "align_rtn->t_aln_str", __LINE__); align_rtn->q_aln_str = my_calloc(q_len + t_len + 1, sizeof(char), "align_rtn->q_aln_str", __LINE__); align_rtn->aln_str_size = 0; align_rtn->aln_q_s = 0; align_rtn->aln_q_e = 0; align_rtn->aln_t_s = 0; align_rtn->aln_t_e = 0; //printf("max_d: %lu, band_size: %lu\n", max_d, band_size); best_m = -1; min_k = 0; max_k = 0; d_path_idx = 0; max_idx = 0; for (d = 0; d < max_d; d ++ ) { if (max_k - min_k > band_size) { break; } for (k = min_k; k <= max_k; k += 2) { if ( (k == min_k) || ((k != max_k) && (V[ k - 1 + k_offset ] < V[ k + 1 + k_offset])) ) { pre_k = k + 1; x = V[ k + 1 + k_offset]; } else { pre_k = k - 1; x = V[ k - 1 + k_offset] + 1; } y = x - k; d_path[d_path_idx].d = d; d_path[d_path_idx].k = k; d_path[d_path_idx].x1 = x; d_path[d_path_idx].y1 = y; while ( x < q_len && y < t_len && query_seq[x] == target_seq[y] ){ x++; y++; } d_path[d_path_idx].x2 = x; d_path[d_path_idx].y2 = y; d_path[d_path_idx].pre_k = pre_k; d_path_idx ++; V[ k + k_offset ] = x; U[ k + k_offset ] = x + y; if ( x + y > best_m) { best_m = x + y; } if ( x >= q_len || y >= t_len) { aligned = true; max_idx = d_path_idx; break; } } // For banding new_min_k = max_k; new_max_k = min_k; for (k2 = min_k; k2 <= max_k; k2 += 2) { if (U[ k2 + k_offset] >= best_m - band_tolerance ) { if ( k2 < new_min_k ) { new_min_k = k2; } if ( k2 > new_max_k ) { new_max_k = k2; } } } max_k = new_max_k + 1; min_k = new_min_k - 1; // For no banding // max_k ++; // min_k --; // For debuging // printf("min_max_k,d, %ld %ld %ld\n", min_k, max_k, d); if (aligned == true) { align_rtn->aln_q_e = x; align_rtn->aln_t_e = y; align_rtn->dist = d; align_rtn->aln_str_size = (x + y + d) / 2; align_rtn->aln_q_s = 0; align_rtn->aln_t_s = 0; d_path_sort(d_path, max_idx); //print_d_path(d_path, max_idx); if (get_aln_str > 0) { cd = d; ck = k; aln_path_idx = 0; while (cd >= 0 && aln_path_idx < q_len + t_len + 1) { d_path_aux = (d_path_data2 *) get_dpath_idx( cd, ck, max_idx, d_path); aln_path[aln_path_idx].x = d_path_aux -> x2; aln_path[aln_path_idx].y = d_path_aux -> y2; aln_path_idx ++; aln_path[aln_path_idx].x = d_path_aux -> x1; aln_path[aln_path_idx].y = d_path_aux -> y1; aln_path_idx ++; ck = d_path_aux -> pre_k; cd -= 1; } aln_path_idx --; cx = aln_path[aln_path_idx].x; cy = aln_path[aln_path_idx].y; align_rtn->aln_q_s = cx; align_rtn->aln_t_s = cy; aln_pos = 0; while ( aln_path_idx > 0 ) { aln_path_idx --; nx = aln_path[aln_path_idx].x; ny = aln_path[aln_path_idx].y; if (cx == nx && cy == ny){ continue; } if (nx == cx && ny != cy){ //advance in y for (i = 0; i < ny - cy; i++) { align_rtn->q_aln_str[aln_pos + i] = '-'; } for (i = 0; i < ny - cy; i++) { align_rtn->t_aln_str[aln_pos + i] = target_seq[cy + i]; } aln_pos += ny - cy; } else if (nx != cx && ny == cy){ //advance in x for (i = 0; i < nx - cx; i++) { align_rtn->q_aln_str[aln_pos + i] = query_seq[cx + i]; } for (i = 0; i < nx - cx; i++) { align_rtn->t_aln_str[aln_pos + i] = '-'; } aln_pos += nx - cx; } else { for (i = 0; i < nx - cx; i++) { align_rtn->q_aln_str[aln_pos + i] = query_seq[cx + i]; } for (i = 0; i < ny - cy; i++) { align_rtn->t_aln_str[aln_pos + i] = target_seq[cy + i]; } aln_pos += ny - cy; } cx = nx; cy = ny; } align_rtn->aln_str_size = aln_pos; } break; } } free(V); free(U); free(d_path); free(aln_path); return align_rtn; } void free_alignment(alignment * aln) { free(aln->q_aln_str); free(aln->t_aln_str); free(aln); } ================================================ FILE: src/c/Makefile ================================================ DW_align.so: DW_banded.c common.h gcc DW_banded.c -O3 -shared -fPIC -o DW_align.so kmer_lookup.so: kmer_lookup.c common.h gcc kmer_lookup.c -O3 -shared -fPIC -o kmer_lookup.so #falcon: DW_banded.c common.h kmer_lookup.c falcon.c # gcc DW_banded.c kmer_lookup.c falcon.c -O4 -o falcon -fPIC falcon.so: falcon.c common.h DW_banded.c kmer_lookup.c gcc DW_banded.c kmer_lookup.c falcon.c -O3 -shared -fPIC -o falcon.so #falcon2.so: falcon.c common.h DW_banded_2.c kmer_lookup.c # gcc DW_banded_2.c kmer_lookup.c falcon.c -O3 -shared -fPIC -o falcon2.so clean: rm *.so all: DW_align.so kmer_lookup.so falcon.so ================================================ FILE: src/c/Makefile.osx ================================================ DW_align.so: DW_banded.c common.h gcc DW_banded.c -O3 -shared -fPIC -o DW_align.so -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/include/ -L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/lib kmer_lookup.so: kmer_lookup.c common.h gcc kmer_lookup.c -O3 -shared -fPIC -o kmer_lookup.so -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/include/ -L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/lib falcon: DW_banded.c common.h kmer_lookup.c falcon.c gcc DW_banded.c kmer_lookup.c falcon.c -O4 -o falcon -fPIC -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/include/ -L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/lib falcon.so: falcon.c common.h DW_banded.c kmer_lookup.c gcc DW_banded.c kmer_lookup.c falcon.c -O3 -shared -fPIC -o falcon.so -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/include/ -L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/lib all: DW_align.so kmer_lookup.so falcon.so falcon ================================================ FILE: src/c/common.h ================================================ /* * ===================================================================================== * * Filename: common.h * * Description: Common delclaration for the code base * * Version: 0.1 * Created: 07/16/2013 07:46:23 AM * Revision: none * Compiler: gcc * * Author: Jason Chin, * Company: * * ===================================================================================== #################################################################################$$ # Copyright (c) 2011-2014, Pacific Biosciences of California, Inc. # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted (subject to the limitations in the # disclaimer below) provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # # * Neither the name of Pacific Biosciences nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE # GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY PACIFIC # BIOSCIENCES AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL PACIFIC BIOSCIENCES OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. #################################################################################$$ */ typedef int seq_coor_t; typedef struct { seq_coor_t aln_str_size ; seq_coor_t dist ; seq_coor_t aln_q_s; seq_coor_t aln_q_e; seq_coor_t aln_t_s; seq_coor_t aln_t_e; char * q_aln_str; char * t_aln_str; } alignment; typedef struct { seq_coor_t pre_k; seq_coor_t x1; seq_coor_t y1; seq_coor_t x2; seq_coor_t y2; } d_path_data; typedef struct { seq_coor_t d; seq_coor_t k; seq_coor_t pre_k; seq_coor_t x1; seq_coor_t y1; seq_coor_t x2; seq_coor_t y2; } d_path_data2; typedef struct { seq_coor_t x; seq_coor_t y; } path_point; typedef struct { seq_coor_t start; seq_coor_t last; seq_coor_t count; } kmer_lookup; typedef unsigned char base; typedef base * seq_array; typedef seq_coor_t seq_addr; typedef seq_addr * seq_addr_array; typedef struct { seq_coor_t count; seq_coor_t * query_pos; seq_coor_t * target_pos; } kmer_match; typedef struct { seq_coor_t s1; seq_coor_t e1; seq_coor_t s2; seq_coor_t e2; long int score; } aln_range; typedef struct { char * sequence; int * eqv; } consensus_data; kmer_lookup * allocate_kmer_lookup (seq_coor_t); void init_kmer_lookup ( kmer_lookup *, seq_coor_t ); void free_kmer_lookup(kmer_lookup *); seq_array allocate_seq(seq_coor_t); void init_seq_array( seq_array, seq_coor_t); void free_seq_array(seq_array); seq_addr_array allocate_seq_addr(seq_coor_t size); void free_seq_addr_array(seq_addr_array); aln_range * find_best_aln_range(kmer_match *, seq_coor_t, seq_coor_t, seq_coor_t); void free_aln_range( aln_range *); kmer_match * find_kmer_pos_for_seq( char *, seq_coor_t, unsigned int K, seq_addr_array, kmer_lookup * ); void free_kmer_match( kmer_match * ptr); void free_kmer_lookup(kmer_lookup * ); void add_sequence ( seq_coor_t, unsigned int, char *, seq_coor_t, seq_addr_array, seq_array, kmer_lookup *); void mask_k_mer(seq_coor_t, kmer_lookup *, seq_coor_t); alignment * align(char *, seq_coor_t, char *, seq_coor_t, seq_coor_t, int); void free_alignment(alignment *); void free_consensus_data(consensus_data *); ================================================ FILE: src/c/ext_falcon.c ================================================ #include "Python.h" static PyMethodDef SpamMethods[] = { {NULL, NULL, 0, NULL} /* Sentinel */ }; PyMODINIT_FUNC initext_falcon(void) { PyObject *m; m = Py_InitModule("ext_falcon", SpamMethods); if (m == NULL) return; } ================================================ FILE: src/c/falcon.c ================================================ /* * ===================================================================================== * * Filename: fastcon.c * * Description: * * Version: 0.1 * Created: 07/20/2013 17:00:00 * Revision: none * Compiler: gcc * * Author: Jason Chin, * Company: * * ===================================================================================== #################################################################################$$ # Copyright (c) 2011-2014, Pacific Biosciences of California, Inc. # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted (subject to the limitations in the # disclaimer below) provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # # * Neither the name of Pacific Biosciences nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE # GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY PACIFIC # BIOSCIENCES AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL PACIFIC BIOSCIENCES OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. #################################################################################$$ */ #include #include #include #include #include #include #include "common.h" typedef struct { seq_coor_t t_pos; uint8_t delta; char q_base; seq_coor_t p_t_pos; // the tag position of the previous base uint8_t p_delta; // the tag delta of the previous base char p_q_base; // the previous base unsigned q_id; } align_tag_t; typedef struct { seq_coor_t len; align_tag_t * align_tags; } align_tags_t; typedef struct { uint16_t size; uint16_t n_link; seq_coor_t * p_t_pos; // the tag position of the previous base uint8_t * p_delta; // the tag delta of the previous base char * p_q_base; // the previous base uint16_t * link_count; uint16_t count; seq_coor_t best_p_t_pos; uint8_t best_p_delta; uint8_t best_p_q_base; // encoded base double score; } align_tag_col_t; typedef struct { align_tag_col_t * base; } msa_base_group_t; typedef struct { uint8_t size; uint8_t max_delta; msa_base_group_t * delta; } msa_delta_group_t; typedef msa_delta_group_t * msa_pos_t; align_tags_t * get_align_tags( char * aln_q_seq, char * aln_t_seq, seq_coor_t aln_seq_len, aln_range * range, unsigned q_id, seq_coor_t t_offset) { char p_q_base; align_tags_t * tags; seq_coor_t i, j, jj, k, p_j, p_jj; tags = calloc( 1, sizeof(align_tags_t) ); tags->len = aln_seq_len; tags->align_tags = calloc( aln_seq_len + 1, sizeof(align_tag_t) ); i = range->s1 - 1; j = range->s2 - 1; jj = 0; p_j = -1; p_jj = 0; p_q_base = '.'; for (k = 0; k < aln_seq_len; k++) { if (aln_q_seq[k] != '-') { i ++; jj ++; } if (aln_t_seq[k] != '-') { j ++; jj = 0; } //printf("t %d %d %d %c %c\n", q_id, j, jj, aln_t_seq[k], aln_q_seq[k]); if ( j + t_offset >= 0 && jj < UINT8_MAX && p_jj < UINT8_MAX) { (tags->align_tags[k]).t_pos = j + t_offset; (tags->align_tags[k]).delta = jj; (tags->align_tags[k]).p_t_pos = p_j + t_offset; (tags->align_tags[k]).p_delta = p_jj; (tags->align_tags[k]).p_q_base = p_q_base; (tags->align_tags[k]).q_base = aln_q_seq[k]; (tags->align_tags[k]).q_id = q_id; p_j = j; p_jj = jj; p_q_base = aln_q_seq[k]; } else { break; // when there is a big alignment gap > UINT8_MAX, stop to extned the tagging string } } // sentinal at the end //k = aln_seq_len; tags->len = k; (tags->align_tags[k]).t_pos = UINT_MAX; (tags->align_tags[k]).delta = UINT8_MAX; (tags->align_tags[k]).q_base = '.'; (tags->align_tags[k]).q_id = UINT_MAX; return tags; } void free_align_tags( align_tags_t * tags) { free( tags->align_tags ); free( tags ); } void allocate_aln_col( align_tag_col_t * col) { col->p_t_pos = ( seq_coor_t * ) calloc(col->size, sizeof( seq_coor_t )); col->p_delta = ( uint8_t * ) calloc(col->size, sizeof( uint8_t )); col->p_q_base = ( char * )calloc(col->size, sizeof( char )); col->link_count = ( uint16_t * ) calloc(col->size, sizeof( uint16_t )); } void realloc_aln_col( align_tag_col_t * col ) { col->p_t_pos = (seq_coor_t *) realloc( col->p_t_pos, (col->size) * sizeof( seq_coor_t )); col->p_delta = ( uint8_t *) realloc( col->p_delta, (col->size) * sizeof( uint8_t )); col->p_q_base = (char *) realloc( col->p_q_base, (col->size) * sizeof( char )); col->link_count = ( uint16_t *) realloc( col->link_count, (col->size) * sizeof( uint16_t )); } void free_aln_col( align_tag_col_t * col) { free(col->p_t_pos); free(col->p_delta); free(col->p_q_base); free(col->link_count); } void allocate_delta_group( msa_delta_group_t * g) { int i,j; g->max_delta = 0; g->delta = (msa_base_group_t *) calloc( g->size, sizeof(msa_base_group_t)); for (i = 0; i< g->size; i++) { g->delta[i].base = ( align_tag_col_t * ) calloc( 5, sizeof(align_tag_col_t ) ); for (j = 0; j < 5; j++ ) { g->delta[i].base[j].size = 8; allocate_aln_col(&(g->delta[i].base[j])); } } } void realloc_delta_group( msa_delta_group_t * g, uint16_t new_size ) { int i, j, bs, es; bs = g->size; es = new_size; g->delta = (msa_base_group_t *) realloc(g->delta, new_size * sizeof(msa_base_group_t)); for (i=bs; i < es; i++) { g->delta[i].base = ( align_tag_col_t *) calloc( 5, sizeof(align_tag_col_t ) ); for (j = 0; j < 5; j++ ) { g->delta[i].base[j].size = 8; allocate_aln_col(&(g->delta[i].base[j])); } } g->size = new_size; } void free_delta_group( msa_delta_group_t * g) { //manything to do here int i, j; for (i = 0; i < g->size; i++) { for (j = 0; j < 5; j++) { free_aln_col( &(g->delta[i].base[j]) ); } free(g->delta[i].base); } free(g->delta); } void update_col( align_tag_col_t * col, seq_coor_t p_t_pos, uint8_t p_delta, char p_q_base) { int updated = 0; int kk; col->count += 1; for (kk = 0; kk < col->n_link; kk++) { if ( p_t_pos == col->p_t_pos[kk] && p_delta == col->p_delta[kk] && p_q_base == col->p_q_base[kk] ) { col->link_count[kk] ++; updated = 1; break; } } if (updated == 0) { if (col->n_link + 1 > col->size) { if (col->size < (UINT16_MAX >> 1)-1) { col->size *= 2; } else { col->size += 256; } assert( col->size < UINT16_MAX-1 ); realloc_aln_col(col); } kk = col->n_link; col->p_t_pos[kk] = p_t_pos; col->p_delta[kk] = p_delta; col->p_q_base[kk] = p_q_base; col->link_count[kk] = 1; col->n_link++; } } msa_pos_t * get_msa_working_sapce(unsigned int max_t_len) { msa_pos_t * msa_array; unsigned int i; msa_array = calloc(max_t_len, sizeof(msa_pos_t *)); for (i = 0; i < max_t_len; i++) { msa_array[i] = calloc(1, sizeof(msa_delta_group_t)); msa_array[i]->size = 8; allocate_delta_group(msa_array[i]); } return msa_array; } void clean_msa_working_space( msa_pos_t * msa_array, unsigned int max_t_len) { unsigned int i,j,k; align_tag_col_t * col; for (i = 0; i < max_t_len; i++) { for (j =0; j < msa_array[i]->max_delta + 1; j++) { for (k = 0; k < 5; k++ ) { col = msa_array[i]->delta[j].base + k; /* for (c =0; c < col->size; c++) { col->p_t_pos[c] = 0; col->p_delta[c] = 0; col->p_q_base[c] = 0; col->link_count[c] =0; } */ col->n_link = 0; col->count = 0; col->best_p_t_pos = 0; col->best_p_delta = 0; col->best_p_q_base = 0; col->score = 0; } } msa_array[i]->max_delta = 0; } } #define STATIC_ALLOCATE //#undef STATIC_ALLOCATE consensus_data * get_cns_from_align_tags( align_tags_t ** tag_seqs, unsigned n_tag_seqs, unsigned t_len, unsigned min_cov ) { seq_coor_t i, j; seq_coor_t t_pos = 0; unsigned int * coverage; unsigned int * local_nbase; consensus_data * consensus; //char * consensus; align_tag_t * c_tag; coverage = calloc( t_len, sizeof(unsigned int) ); local_nbase = calloc( t_len, sizeof(unsigned int) ); #ifndef STATIC_ALLOCATE msa_pos_t * msa_array = NULL; // For more efficiency, this should be injected. msa_array = calloc(t_len, sizeof(msa_pos_t *)); for (i = 0; i < t_len; i++) { msa_array[i] = calloc(1, sizeof(msa_delta_group_t)); msa_array[i]->size = 8; allocate_delta_group(msa_array[i]); } #else static msa_pos_t * msa_array = NULL; if ( msa_array == NULL) { msa_array = get_msa_working_sapce( 100000 ); } assert(t_len < 100000); #endif // loop through every alignment //printf("XX %d\n", n_tag_seqs); for (i = 0; i < n_tag_seqs; i++) { // for each alignment position, insert the alignment tag to msa_array for (j = 0; j < tag_seqs[i]->len; j++) { c_tag = tag_seqs[i]->align_tags + j; unsigned int delta; delta = c_tag->delta; if (delta == 0) { t_pos = c_tag->t_pos; coverage[ t_pos ] ++; } // Assume t_pos was set on earlier iteration. // (Otherwise, use its initial value, which might be an error. ~cd) if (delta > msa_array[t_pos]->max_delta) { msa_array[t_pos]->max_delta = delta; if (msa_array[t_pos]->max_delta + 4 > msa_array[t_pos]->size ) { realloc_delta_group(msa_array[t_pos], msa_array[t_pos]->max_delta + 8); } } unsigned int base = -1; switch (c_tag->q_base) { case 'A': base = 0; break; case 'C': base = 1; break; case 'G': base = 2; break; case 'T': base = 3; break; case '-': base = 4; break; } // Note: On bad input, base may be -1. update_col( &(msa_array[t_pos]->delta[delta].base[base]), c_tag->p_t_pos, c_tag->p_delta, c_tag->p_q_base); local_nbase[ t_pos ] ++; } } // propogate score throught the alignment links, setup backtracking information align_tag_col_t * g_best_aln_col = 0; unsigned int g_best_ck = 0; seq_coor_t g_best_t_pos = 0; { int kk; int ck; // char base; int best_i; int best_j; int best_b; int best_ck = -1; double score; double best_score; double g_best_score; // char best_mark; align_tag_col_t * aln_col; g_best_score = -1; for (i = 0; i < t_len; i++) { //loop through every template base //printf("max delta: %d %d\n", i, msa_array[i]->max_delta); for (j = 0; j <= msa_array[i]->max_delta; j++) { // loop through every delta position for (kk = 0; kk < 5; kk++) { // loop through diff bases of the same delta posiiton /* switch (kk) { case 0: base = 'A'; break; case 1: base = 'C'; break; case 2: base = 'G'; break; case 3: base = 'T'; break; case 4: base = '-'; break; } */ aln_col = msa_array[i]->delta[j].base + kk; if (aln_col->count >= 0) { best_score = -1; best_i = -1; best_j = -1; best_b = -1; for (ck = 0; ck < aln_col->n_link; ck++) { // loop through differnt link to previous column int pi; int pj; int pkk; pi = aln_col->p_t_pos[ck]; pj = aln_col->p_delta[ck]; switch (aln_col->p_q_base[ck]) { case 'A': pkk = 0; break; case 'C': pkk = 1; break; case 'G': pkk = 2; break; case 'T': pkk = 3; break; case '-': pkk = 4; break; default: pkk = 4; } if (aln_col->p_t_pos[ck] == -1) { score = (double) aln_col->link_count[ck] - (double) coverage[i] * 0.5; } else { score = msa_array[pi]->delta[pj].base[pkk].score + (double) aln_col->link_count[ck] - (double) coverage[i] * 0.5; } // best_mark = ' '; if (score > best_score) { best_score = score; aln_col->best_p_t_pos = best_i = pi; aln_col->best_p_delta = best_j = pj; aln_col->best_p_q_base = best_b = pkk; best_ck = ck; // best_mark = '*'; } /* printf("X %d %d %d %c %d %d %d %c %d %lf %c\n", coverage[i], i, j, base, aln_col->count, aln_col->p_t_pos[ck], aln_col->p_delta[ck], aln_col->p_q_base[ck], aln_col->link_count[ck], score, best_mark); */ } aln_col->score = best_score; if (best_score > g_best_score) { g_best_score = best_score; g_best_aln_col = aln_col; g_best_ck = best_ck; g_best_t_pos = i; //printf("GB %d %d %d %d\n", i, j, ck, g_best_aln_col); } } } } } assert(g_best_score != -1); } // reconstruct the sequences unsigned int index; char bb = '$'; int ck; char * cns_str; int * eqv; double score0; consensus = calloc( 1, sizeof(consensus_data) ); consensus->sequence = calloc( t_len * 2 + 1, sizeof(char) ); consensus->eqv = calloc( t_len * 2 + 1, sizeof(unsigned int) ); cns_str = consensus->sequence; eqv = consensus->eqv; index = 0; ck = g_best_ck; i = g_best_t_pos; while (1) { if (coverage[i] > min_cov) { switch (ck) { case 0: bb = 'A'; break; case 1: bb = 'C'; break; case 2: bb = 'G'; break; case 3: bb = 'T'; break; case 4: bb = '-'; break; } } else { switch (ck) { case 0: bb = 'a'; break; case 1: bb = 'c'; break; case 2: bb = 'g'; break; case 3: bb = 't'; break; case 4: bb = '-'; break; } } // Note: On bad input, bb will keep previous value, possibly '$'. score0 = g_best_aln_col->score; i = g_best_aln_col->best_p_t_pos; if (i == -1 || index >= t_len * 2) break; j = g_best_aln_col->best_p_delta; ck = g_best_aln_col->best_p_q_base; g_best_aln_col = msa_array[i]->delta[j].base + ck; if (bb != '-') { cns_str[index] = bb; eqv[index] = (int) score0 - (int) g_best_aln_col->score; //printf("C %d %d %c %lf %d %d\n", i, index, bb, g_best_aln_col->score, coverage[i], eqv[index] ); index ++; } } // reverse the sequence for (i = 0; i < index/2; i++) { cns_str[i] = cns_str[i] ^ cns_str[index-i-1]; cns_str[index-i-1] = cns_str[i] ^ cns_str[index-i-1]; cns_str[i] = cns_str[i] ^ cns_str[index-i-1]; eqv[i] = eqv[i] ^ eqv[index-i-1]; eqv[index-i-1] = eqv[i] ^ eqv[index-i-1]; eqv[i] = eqv[i] ^ eqv[index-i-1]; } cns_str[index] = 0; //printf("%s\n", cns_str); #ifndef STATIC_ALLOCATE for (i = 0; i < t_len; i++) { free_delta_group(msa_array[i]); free(msa_array[i]); } free(msa_array); #else clean_msa_working_space(msa_array, t_len+1); #endif free(coverage); free(local_nbase); return consensus; } //const unsigned int K = 8; consensus_data * generate_consensus( char ** input_seq, unsigned int n_seq, unsigned min_cov, unsigned K, double min_idt) { unsigned int j; unsigned int seq_count; unsigned int aligned_seq_count; kmer_lookup * lk_ptr; seq_array sa_ptr; seq_addr_array sda_ptr; kmer_match * kmer_match_ptr; aln_range * arange; alignment * aln; align_tags_t ** tags_list; //char * consensus; consensus_data * consensus; double max_diff; max_diff = 1.0 - min_idt; seq_count = n_seq; //printf("XX n_seq %d\n", n_seq); //for (j=0; j < seq_count; j++) { // printf("seq_len: %u %u\n", j, strlen(input_seq[j])); //}; fflush(stdout); tags_list = calloc( seq_count, sizeof(align_tags_t *) ); lk_ptr = allocate_kmer_lookup( 1 << (K * 2) ); sa_ptr = allocate_seq( (seq_coor_t) strlen( input_seq[0]) ); sda_ptr = allocate_seq_addr( (seq_coor_t) strlen( input_seq[0]) ); add_sequence( 0, K, input_seq[0], strlen(input_seq[0]), sda_ptr, sa_ptr, lk_ptr); //mask_k_mer(1 << (K * 2), lk_ptr, 16); aligned_seq_count = 0; for (j=1; j < seq_count; j++) { //printf("seq_len: %ld %u\n", j, strlen(input_seq[j])); kmer_match_ptr = find_kmer_pos_for_seq(input_seq[j], strlen(input_seq[j]), K, sda_ptr, lk_ptr); #define INDEL_ALLOWENCE_0 6 arange = find_best_aln_range(kmer_match_ptr, K, K * INDEL_ALLOWENCE_0, 5); // narrow band to avoid aligning through big indels //printf("1:%ld %ld %ld %ld\n", arange_->s1, arange_->e1, arange_->s2, arange_->e2); //arange = find_best_aln_range2(kmer_match_ptr, K, K * INDEL_ALLOWENCE_0, 5); // narrow band to avoid aligning through big indels //printf("2:%ld %ld %ld %ld\n\n", arange->s1, arange->e1, arange->s2, arange->e2); #define INDEL_ALLOWENCE_1 0.10 if (arange->e1 - arange->s1 < 100 || arange->e2 - arange->s2 < 100 || abs( (arange->e1 - arange->s1 ) - (arange->e2 - arange->s2) ) > (int) (0.5 * INDEL_ALLOWENCE_1 * (arange->e1 - arange->s1 + arange->e2 - arange->s2))) { free_kmer_match( kmer_match_ptr); free_aln_range(arange); continue; } //printf("%ld %s\n", strlen(input_seq[j]), input_seq[j]); //printf("%ld %s\n\n", strlen(input_seq[0]), input_seq[0]); #define INDEL_ALLOWENCE_2 150 aln = align(input_seq[j]+arange->s1, arange->e1 - arange->s1 , input_seq[0]+arange->s2, arange->e2 - arange->s2 , INDEL_ALLOWENCE_2, 1); if (aln->aln_str_size > 500 && ((double) aln->dist / (double) aln->aln_str_size) < max_diff) { tags_list[aligned_seq_count] = get_align_tags( aln->q_aln_str, aln->t_aln_str, aln->aln_str_size, arange, j, 0); aligned_seq_count ++; } /*** for (k = 0; k < tags_list[j]->len; k++) { printf("%ld %d %c\n", tags_list[j]->align_tags[k].t_pos, tags_list[j]->align_tags[k].delta, tags_list[j]->align_tags[k].q_base); } ***/ free_aln_range(arange); free_alignment(aln); free_kmer_match( kmer_match_ptr); } if (aligned_seq_count > 0) { consensus = get_cns_from_align_tags( tags_list, aligned_seq_count, strlen(input_seq[0]), min_cov ); } else { // allocate an empty consensus sequence consensus = calloc( 1, sizeof(consensus_data) ); consensus->sequence = calloc( 1, sizeof(char) ); consensus->eqv = calloc( 1, sizeof(unsigned int) ); } //free(consensus); free_seq_addr_array(sda_ptr); free_seq_array(sa_ptr); free_kmer_lookup(lk_ptr); for (j=0; j < aligned_seq_count; j++) { free_align_tags(tags_list[j]); } free(tags_list); return consensus; } consensus_data * generate_utg_consensus( char ** input_seq, seq_coor_t *offset, unsigned int n_seq, unsigned min_cov, unsigned K, double min_idt) { unsigned int j; unsigned int seq_count; unsigned int aligned_seq_count; aln_range * arange; alignment * aln; align_tags_t ** tags_list; //char * consensus; consensus_data * consensus; double max_diff; seq_coor_t utg_len; seq_coor_t r_len; max_diff = 1.0 - min_idt; seq_count = n_seq; /*** for (j=0; j < seq_count; j++) { printf("seq_len: %u %u\n", j, strlen(input_seq[j])); }; fflush(stdout); ***/ tags_list = calloc( seq_count+1, sizeof(align_tags_t *) ); utg_len = strlen(input_seq[0]); aligned_seq_count = 0; arange = calloc( 1, sizeof(aln_range) ); arange->s1 = 0; arange->e1 = strlen(input_seq[0]); arange->s2 = 0; arange->e2 = strlen(input_seq[0]); tags_list[aligned_seq_count] = get_align_tags( input_seq[0], input_seq[0], strlen(input_seq[0]), arange, 0, 0); aligned_seq_count += 1; for (j=1; j < seq_count; j++) { arange->s1 = 0; arange->e1 = strlen(input_seq[j])-1; arange->s2 = 0; arange->e2 = strlen(input_seq[j])-1; r_len = strlen(input_seq[j]); //printf("seq_len: %u %u\n", j, r_len); if ( offset[j] < 0) { if ((r_len + offset[j]) < 128) { continue; } if ( r_len + offset[j] < utg_len ) { //printf("1: %ld %u %u\n", offset[j], r_len, utg_len); aln = align(input_seq[j] - offset[j], r_len + offset[j] , input_seq[0], r_len + offset[j] , 500, 1); } else { //printf("2: %ld %u %u\n", offset[j], r_len, utg_len); aln = align(input_seq[j] - offset[j], utg_len , input_seq[0], utg_len , 500, 1); } offset[j] = 0; } else { if ( offset[j] > utg_len - 128) { continue; } if ( offset[j] + r_len > utg_len ) { //printf("3: %ld %u %u\n", offset[j], r_len, utg_len); aln = align(input_seq[j], utg_len - offset[j] , input_seq[0]+offset[j], utg_len - offset[j], 500, 1); } else { //printf("4: %ld %u %u\n", offset[j], r_len, utg_len); aln = align(input_seq[j], r_len , input_seq[0]+offset[j], r_len , 500, 1); } } if (aln->aln_str_size > 500 && ((double) aln->dist / (double) aln->aln_str_size) < max_diff) { tags_list[aligned_seq_count] = get_align_tags( aln->q_aln_str, aln->t_aln_str, aln->aln_str_size, arange, j, offset[j]); aligned_seq_count ++; } free_alignment(aln); } free_aln_range(arange); if (aligned_seq_count > 0) { consensus = get_cns_from_align_tags( tags_list, aligned_seq_count, utg_len, 0 ); } else { // allocate an empty consensus sequence consensus = calloc( 1, sizeof(consensus_data) ); consensus->sequence = calloc( 1, sizeof(char) ); consensus->eqv = calloc( 1, sizeof(unsigned int) ); } //free(consensus); for (j=0; j < aligned_seq_count; j++) { free_align_tags(tags_list[j]); } free(tags_list); return consensus; } void free_consensus_data( consensus_data * consensus ){ free(consensus->sequence); free(consensus->eqv); free(consensus); } /*** void main() { unsigned int j; char small_buffer[1024]; char big_buffer[65536]; char ** input_seq; char ** seq_id; int seq_count; char * consensus; input_seq = calloc( 501, sizeof(char *)); seq_id = calloc( 501, sizeof(char *)); while(1) { seq_count = 0; while (1) { scanf("%s", small_buffer); seq_id[seq_count] = calloc( strlen(small_buffer) + 1, sizeof(char)); strcpy(seq_id[seq_count], small_buffer); scanf("%s", big_buffer); input_seq[seq_count] = calloc( strlen(big_buffer) + 1 , sizeof(char)); strcpy(input_seq[seq_count], big_buffer); if (strcmp(seq_id[seq_count], "+") == 0) { break; } if (strcmp(seq_id[seq_count], "-") == 0) { break; } //printf("%s\n", seq_id[seq_count]); seq_count += 1; if (seq_count > 500) break; } //printf("sc: %d\n", seq_count); if (seq_count < 10 && strcmp(seq_id[seq_count], "-") != 0 ) continue; if (seq_count < 10 && strcmp(seq_id[seq_count], "-") == 0 ) break; consensus = generate_consensus(input_seq, seq_count, 8, 8); if (strlen(consensus) > 500) { printf(">%s\n%s\n", seq_id[0], consensus); } fflush(stdout); free(consensus); for (j=0; j < seq_count; j++) { free(seq_id[j]); free(input_seq[j]); }; } for (j=0; j < seq_count; j++) { free(seq_id[j]); free(input_seq[j]); }; free(seq_id); free(input_seq); } ***/ ================================================ FILE: src/c/kmer_lookup.c ================================================ /* * ===================================================================================== * * Filename: kmer_count.c * * Description: * * Version: 0.1 * Created: 07/20/2013 17:00:00 * Revision: none * Compiler: gcc * * Author: Jason Chin, * Company: * * ===================================================================================== #################################################################################$$ # Copyright (c) 2011-2014, Pacific Biosciences of California, Inc. # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted (subject to the limitations in the # disclaimer below) provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # # * Neither the name of Pacific Biosciences nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE # GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY PACIFIC # BIOSCIENCES AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL PACIFIC BIOSCIENCES OR ITS # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. #################################################################################$$ */ #include #include #include #include "common.h" const unsigned int KMERMATCHINC = 10000; int compare_seq_coor(const void * a, const void * b) { const seq_coor_t * arg1 = a; const seq_coor_t * arg2 = b; return (* arg1) - (* arg2); } kmer_lookup * allocate_kmer_lookup ( seq_coor_t size ) { kmer_lookup * kl; //printf("%lu is allocated for kmer lookup\n", size); kl = (kmer_lookup *) malloc( size * sizeof(kmer_lookup) ); init_kmer_lookup( kl, size); return kl; } void init_kmer_lookup ( kmer_lookup * kl, seq_coor_t size ) { seq_coor_t i; //printf("%lu is allocated for kmer lookup\n", size); for (i=0; i threshold) { kl[i].start = INT_MAX; kl[i].last = INT_MAX; //kl[i].count = 0; } } } kmer_match * find_kmer_pos_for_seq( char * seq, seq_coor_t seq_len, unsigned int K, seq_addr_array sda, kmer_lookup * lk) { seq_coor_t i; seq_coor_t kmer_bv; seq_coor_t kmer_mask; seq_coor_t kmer_pos; seq_coor_t next_kmer_pos; unsigned int half_K; seq_coor_t kmer_match_rtn_allocation_size = KMERMATCHINC; kmer_match * kmer_match_rtn; base * sa; kmer_match_rtn = (kmer_match *) malloc( sizeof(kmer_match) ); kmer_match_rtn->count = 0; kmer_match_rtn->query_pos = (seq_coor_t *) calloc( kmer_match_rtn_allocation_size, sizeof( seq_coor_t ) ); kmer_match_rtn->target_pos = (seq_coor_t *) calloc( kmer_match_rtn_allocation_size, sizeof( seq_coor_t ) ); sa = calloc( seq_len, sizeof(base) ); kmer_mask = 0; for (i = 0; i < K; i++) { kmer_mask <<= 2; kmer_mask |= 0x00000003; } for (i = 0; i < seq_len; i++) { switch ( seq[i] ) { case 'A': sa[ i ] = 0; break; case 'C': sa[ i ] = 1; break; case 'G': sa[ i ] = 2; break; case 'T': sa[ i ] = 3; } } kmer_bv = get_kmer_bitvector(sa, K); half_K = K >> 1; for (i = 0; i < seq_len - K; i += half_K) { kmer_bv = get_kmer_bitvector(sa + i, K); if (lk[kmer_bv].start == INT_MAX) { //for high count k-mers continue; } kmer_pos = lk[ kmer_bv ].start; next_kmer_pos = sda[ kmer_pos ]; kmer_match_rtn->query_pos[ kmer_match_rtn->count ] = i; kmer_match_rtn->target_pos[ kmer_match_rtn->count ] = kmer_pos; kmer_match_rtn->count += 1; if (kmer_match_rtn->count > kmer_match_rtn_allocation_size - 1000) { kmer_match_rtn_allocation_size += KMERMATCHINC; kmer_match_rtn->query_pos = (seq_coor_t *) realloc( kmer_match_rtn->query_pos, kmer_match_rtn_allocation_size * sizeof(seq_coor_t) ); kmer_match_rtn->target_pos = (seq_coor_t *) realloc( kmer_match_rtn->target_pos, kmer_match_rtn_allocation_size * sizeof(seq_coor_t) ); } while ( next_kmer_pos > kmer_pos ){ kmer_pos = next_kmer_pos; next_kmer_pos = sda[ kmer_pos ]; kmer_match_rtn->query_pos[ kmer_match_rtn->count ] = i; kmer_match_rtn->target_pos[ kmer_match_rtn->count ] = kmer_pos; kmer_match_rtn->count += 1; if (kmer_match_rtn->count > kmer_match_rtn_allocation_size - 1000) { kmer_match_rtn_allocation_size += KMERMATCHINC; kmer_match_rtn->query_pos = (seq_coor_t *) realloc( kmer_match_rtn->query_pos, kmer_match_rtn_allocation_size * sizeof(seq_coor_t) ); kmer_match_rtn->target_pos = (seq_coor_t *) realloc( kmer_match_rtn->target_pos, kmer_match_rtn_allocation_size * sizeof(seq_coor_t) ); } } } free(sa); return kmer_match_rtn; } void free_kmer_match( kmer_match * ptr) { free(ptr->query_pos); free(ptr->target_pos); free(ptr); } aln_range* find_best_aln_range(kmer_match * km_ptr, seq_coor_t K, seq_coor_t bin_size, seq_coor_t count_th) { seq_coor_t i; seq_coor_t j; seq_coor_t q_min, q_max, t_min, t_max; seq_coor_t * d_count; seq_coor_t * q_coor; seq_coor_t * t_coor; aln_range * arange; long int d, d_min, d_max; long int cur_score; long int max_score; long int max_k_mer_count; long int max_k_mer_bin; seq_coor_t cur_start; arange = calloc(1 , sizeof(aln_range)); q_min = INT_MAX; q_max = 0; t_min = INT_MAX; t_max = 0; d_min = INT_MAX; d_max = LONG_MIN; for (i = 0; i < km_ptr->count; i++ ) { if ( km_ptr -> query_pos[i] < q_min) { q_min = km_ptr->query_pos[i]; } if ( km_ptr -> query_pos[i] > q_max) { q_max = km_ptr->query_pos[i]; } if ( km_ptr -> target_pos[i] < t_min) { t_min = km_ptr->target_pos[i]; } if ( km_ptr -> query_pos[i] > t_max) { t_max = km_ptr->target_pos[i]; } d = (long int) km_ptr->query_pos[i] - (long int) km_ptr->target_pos[i]; if ( d < d_min ) { d_min = d; } if ( d > d_max ) { d_max = d; } } //printf("%lu %ld %ld\n" , km_ptr->count, d_min, d_max); d_count = calloc( (d_max - d_min)/bin_size + 1, sizeof(seq_coor_t) ); q_coor = calloc( km_ptr->count, sizeof(seq_coor_t) ); t_coor = calloc( km_ptr->count, sizeof(seq_coor_t) ); for (i = 0; i < km_ptr->count; i++ ) { d = (long int) (km_ptr->query_pos[i]) - (long int) (km_ptr->target_pos[i]); d_count[ (d - d_min)/ (long int) bin_size ] += 1; q_coor[i] = INT_MAX; t_coor[i] = INT_MAX; } j = 0; max_k_mer_count = 0; max_k_mer_bin = INT_MAX; for (i = 0; i < km_ptr->count; i++ ) { d = (long int) (km_ptr->query_pos[i]) - (long int) (km_ptr->target_pos[i]); if ( d_count[ (d - d_min)/ (long int) bin_size ] > max_k_mer_count) { max_k_mer_count = d_count[ (d - d_min)/ (long int) bin_size ]; max_k_mer_bin = (d - d_min)/ (long int) bin_size; } } //printf("k_mer: %lu %lu\n" , max_k_mer_count, max_k_mer_bin); if ( max_k_mer_bin != INT_MAX && max_k_mer_count > count_th ) { for (i = 0; i < km_ptr->count; i++ ) { d = (long int) (km_ptr->query_pos[i]) - (long int) (km_ptr->target_pos[i]); if ( labs( ( (d - d_min)/ (long int) bin_size ) - max_k_mer_bin ) > 5 ) { continue; } if (d_count[ (d - d_min)/ (long int) bin_size ] > count_th) { q_coor[j] = km_ptr->query_pos[i]; t_coor[j] = km_ptr->target_pos[i]; //printf("d_count: %lu %lu\n" ,i, d_count[(d - d_min)/ (long int) bin_size]); //printf("coor: %lu %lu\n" , q_coor[j], t_coor[j]); j ++; } } } if (j > 1) { arange->s1 = q_coor[0]; arange->e1 = q_coor[0]; arange->s2 = t_coor[0]; arange->e2 = t_coor[0]; arange->score = 0; max_score = 0; cur_score = 0; cur_start = 0; for (i = 1; i < j; i++) { cur_score += 32 - (q_coor[i] - q_coor[i-1]); //printf("deltaD, %lu %ld\n", q_coor[i] - q_coor[i-1], cur_score); if (cur_score < 0) { cur_score = 0; cur_start = i; } else if (cur_score > max_score) { arange->s1 = q_coor[cur_start]; arange->s2 = t_coor[cur_start]; arange->e1 = q_coor[i]; arange->e2 = t_coor[i]; max_score = cur_score; arange->score = max_score; //printf("%lu %lu %lu %lu\n", arange.s1, arange.e1, arange.s2, arange.e2); } } } else { arange->s1 = 0; arange->e1 = 0; arange->s2 = 0; arange->e2 = 0; arange->score = 0; } // printf("free\n"); free(d_count); free(q_coor); free(t_coor); return arange; } aln_range* find_best_aln_range2(kmer_match * km_ptr, seq_coor_t K, seq_coor_t bin_width, seq_coor_t count_th) { seq_coor_t * d_coor; seq_coor_t * hit_score; seq_coor_t * hit_count; seq_coor_t * last_hit; seq_coor_t max_q, max_t; seq_coor_t s, e, max_s, max_e, max_span, d_s, d_e, delta, d_len; seq_coor_t px, py, cx, cy; seq_coor_t max_hit_idx; seq_coor_t max_hit_score, max_hit_count; seq_coor_t i, j; seq_coor_t candidate_idx, max_d, d; aln_range * arange; arange = calloc(1 , sizeof(aln_range)); d_coor = calloc( km_ptr->count, sizeof(seq_coor_t) ); max_q = -1; max_t = -1; for (i = 0; i < km_ptr->count; i++ ) { d_coor[i] = km_ptr->query_pos[i] - km_ptr->target_pos[i]; max_q = max_q > km_ptr->query_pos[i] ? max_q : km_ptr->query_pos[i]; max_t = max_t > km_ptr->target_pos[i] ? max_q : km_ptr->target_pos[i]; } qsort(d_coor, km_ptr->count, sizeof(seq_coor_t), compare_seq_coor); s = 0; e = 0; max_s = -1; max_e = -1; max_span = -1; delta = (long int) ( 0.05 * ( max_q + max_t ) ); d_len = km_ptr->count; d_s = -1; d_e = -1; while (1) { d_s = d_coor[s]; d_e = d_coor[e]; while (d_e < d_s + delta && e < d_len-1) { e += 1; d_e = d_coor[e]; } if ( max_span == -1 || e - s > max_span ) { max_span = e - s; max_s = s; max_e = e; } s += 1; if (s == d_len || e == d_len) { break; } } if (max_s == -1 || max_e == -1 || max_e - max_s < 32) { arange->s1 = 0; arange->e1 = 0; arange->s2 = 0; arange->e2 = 0; arange->score = 0; free(d_coor); return arange; } last_hit = calloc( km_ptr->count, sizeof(seq_coor_t) ); hit_score = calloc( km_ptr->count, sizeof(seq_coor_t) ); hit_count = calloc( km_ptr->count, sizeof(seq_coor_t) ); for (i = 0; i < km_ptr->count; i++ ) { last_hit[i] = -1; hit_score[i] = 0; hit_count[i] = 0; } max_hit_idx = -1; max_hit_score = 0; for (i = 0; i < km_ptr->count; i ++) { cx = km_ptr->query_pos[i]; cy = km_ptr->target_pos[i]; d = cx - cy; if ( d < d_coor[max_s] || d > d_coor[max_e] ) continue; j = i - 1; candidate_idx = -1; max_d = 65535; while (1) { if ( j < 0 ) break; px = km_ptr->query_pos[j]; py = km_ptr->target_pos[j]; d = px - py; if ( d < d_coor[max_s] || d > d_coor[max_e] ) { j--; continue; } if (cx - px > 320) break; //the number here controling how big alignment gap to be considered if (cy > py && cx - px + cy - py < max_d && cy - py <= 320 ) { max_d = cx - px + cy - py; candidate_idx = j; } j--; } if (candidate_idx != -1) { last_hit[i] = candidate_idx; hit_score[i] = hit_score[candidate_idx] + (64 - max_d); hit_count[i] = hit_count[candidate_idx] + 1; if (hit_score[i] < 0) { hit_score[i] = 0; hit_count[i] = 0; } } else { hit_score[i] = 0; hit_count[i] = 0; } if (hit_score[i] > max_hit_score) { max_hit_score = hit_score[i]; max_hit_count = hit_count[i]; max_hit_idx = i; } } if (max_hit_idx == -1) { arange->s1 = 0; arange->e1 = 0; arange->s2 = 0; arange->e2 = 0; arange->score = 0; free(d_coor); free(last_hit); free(hit_score); free(hit_count); return arange; } arange->score = max_hit_count + 1; arange->e1 = km_ptr->query_pos[max_hit_idx]; arange->e2 = km_ptr->target_pos[max_hit_idx]; i = max_hit_idx; while (last_hit[i] != -1) { i = last_hit[i]; } arange->s1 = km_ptr->query_pos[i]; arange->s2 = km_ptr->target_pos[i]; free(d_coor); free(last_hit); free(hit_score); free(hit_count); return arange; } void free_aln_range( aln_range * arange) { free(arange); } ================================================ FILE: src/py_scripts/fc_actg_coordinate.py ================================================ from __future__ import absolute_import from falcon_kit.mains.actg_coordinate import main import sys if __name__ == "__main__": main(sys.argv) ================================================ FILE: src/py_scripts/fc_consensus.py ================================================ from __future__ import absolute_import from falcon_kit.mains.consensus import main import sys if __name__ == "__main__": main(sys.argv) ================================================ FILE: src/py_scripts/fc_contig_annotate.py ================================================ from __future__ import absolute_import from falcon_kit.mains.contig_annotate import main import sys if __name__ == "__main__": main(sys.argv) ================================================ FILE: src/py_scripts/fc_ctg_link_analysis.py ================================================ from __future__ import absolute_import from falcon_kit.mains.ctg_link_analysis import main import sys if __name__ == "__main__": main(sys.argv) ================================================ FILE: src/py_scripts/fc_dedup_a_tigs.py ================================================ from __future__ import absolute_import from falcon_kit.mains.dedup_a_tigs import main import sys if __name__ == "__main__": main(sys.argv) ================================================ FILE: src/py_scripts/fc_graph_to_contig.py ================================================ from __future__ import absolute_import from falcon_kit.mains.graph_to_contig import main import sys if __name__ == "__main__": main(sys.argv) ================================================ FILE: src/py_scripts/fc_graph_to_utgs.py ================================================ from __future__ import absolute_import from falcon_kit.mains.graph_to_utgs import main import sys if __name__ == "__main__": main(sys.argv) ================================================ FILE: src/py_scripts/fc_ovlp_filter.py ================================================ from __future__ import absolute_import from falcon_kit.mains.ovlp_filter import main import sys if __name__ == "__main__": main(sys.argv) ================================================ FILE: src/py_scripts/fc_ovlp_stats.py ================================================ from __future__ import absolute_import from falcon_kit.mains.ovlp_stats import main import sys if __name__ == "__main__": main(sys.argv) ================================================ FILE: src/py_scripts/fc_ovlp_to_graph.py ================================================ from __future__ import absolute_import from falcon_kit.mains.ovlp_to_graph import main import sys if __name__ == "__main__": main(sys.argv) ================================================ FILE: src/py_scripts/fc_run.py ================================================ from __future__ import absolute_import from falcon_kit.mains.run1 import main import sys if __name__ == "__main__": main(sys.argv) ================================================ FILE: src/utils/fetch_preads.py ================================================ from __future__ import absolute_import from __future__ import print_function from pbcore.io import FastaReader import networkx as nx import sys u_graph = nx.DiGraph() u_edges = {} with open("./unit_edges.dat") as f: for l in f: v, w, path, seq = l.strip().split() u_edges.setdefault((v, w), []) u_edges[(v, w)].append((path, seq)) u_graph.add_edge(v, w) len(u_edges) u_graph_r = u_graph.reverse() p_tig_path = {} a_tig_path = {} with open("primary_tigs_paths_c") as f: for l in f: l = l.strip().split() id_ = l[0][1:] path = l[1:] p_tig_path[id_] = path with open("all_tigs_paths") as f: for l in f: l = l.strip().split() id_ = l[0][1:] path = l[1:] a_tig_path[id_] = path p_ugraph = nx.DiGraph() p_sgraph = nx.DiGraph() p_tig_id = sys.argv[1] main_path = p_tig_path["%s_00" % p_tig_id] all_nodes = set(main_path[:]) main_path_nodes = set(main_path[:]) p_ugraph.add_path(main_path) for id_ in a_tig_path: if id_[:4] == p_tig_id: a_path = a_tig_path[id_] if a_path[0] in main_path_nodes and a_path[-1] in main_path_nodes: p_ugraph.add_path(a_path) for pp in a_path: all_nodes.add(pp) for v, w in u_edges: if v in all_nodes and w in all_nodes: for p, s in u_edges[(v, w)]: p = p.split("-") p_sgraph.add_path(p) # print p for pp in p: all_nodes.add(pp) nx.write_gexf(p_ugraph, "p_ugraph.gexf") nx.write_gexf(p_sgraph, "p_sgraph.gexf") preads = FastaReader(sys.argv[2]) all_nodes_ids = set([s.split(":")[0] for s in list(all_nodes)]) with open("p_sgraph_nodes.fa", "w") as f: for r in preads: if r.name in all_nodes_ids: print(">" + r.name, file=f) print(r.sequence, file=f) ================================================ FILE: test/HPCdaligner_synth0.sh ================================================ # Daligner jobs (2) daligner -v -h1 -t16 -H1 -e0.7 -l1 -s1000 raw_reads.1 raw_reads.1 daligner -v -h1 -t16 -H1 -e0.7 -l1 -s1000 raw_reads.2 raw_reads.1 raw_reads.2 # Initial sort jobs (4) LAsort -v raw_reads.1.raw_reads.1.C0 raw_reads.1.raw_reads.1.N0 && LAmerge -v L1.1.1 raw_reads.1.raw_reads.1.C0.S raw_reads.1.raw_reads.1.N0.S && rm raw_reads.1.raw_reads.1.C0.S.las raw_reads.1.raw_reads.1.N0.S.las LAsort -v raw_reads.1.raw_reads.2.C0 raw_reads.1.raw_reads.2.N0 && LAmerge -v L1.1.2 raw_reads.1.raw_reads.2.C0.S raw_reads.1.raw_reads.2.N0.S && rm raw_reads.1.raw_reads.2.C0.S.las raw_reads.1.raw_reads.2.N0.S.las LAsort -v raw_reads.2.raw_reads.1.C0 raw_reads.2.raw_reads.1.N0 && LAmerge -v L1.2.1 raw_reads.2.raw_reads.1.C0.S raw_reads.2.raw_reads.1.N0.S && rm raw_reads.2.raw_reads.1.C0.S.las raw_reads.2.raw_reads.1.N0.S.las LAsort -v raw_reads.2.raw_reads.2.C0 raw_reads.2.raw_reads.2.N0 && LAmerge -v L1.2.2 raw_reads.2.raw_reads.2.C0.S raw_reads.2.raw_reads.2.N0.S && rm raw_reads.2.raw_reads.2.C0.S.las raw_reads.2.raw_reads.2.N0.S.las # Level 1 jobs (2) LAmerge -v raw_reads.1 L1.1.1 L1.1.2 && rm L1.1.1.las L1.1.2.las LAmerge -v raw_reads.2 L1.2.1 L1.2.2 ; rm L1.2.1.las L1.2.2.las ================================================ FILE: test/HPCdaligner_synth0_new.sh ================================================ # Daligner jobs (2) daligner -v -w1 -h1 -t50 -H2000 -e0.99 -l1 -s1000 -P=. -mdust raw_reads.1 raw_reads.1 daligner -v -w1 -h1 -t50 -H2000 -e0.99 -l1 -s1000 -P=. -mdust raw_reads.2 raw_reads.1 raw_reads.2 # Check initial .las files jobs (2) (optional but recommended) LAcheck -vS raw_reads raw_reads.1.raw_reads.1 raw_reads.1.raw_reads.2 LAcheck -vS raw_reads raw_reads.2.raw_reads.1 raw_reads.2.raw_reads.2 # Level 1 merge jobs (2) LAmerge -v raw_reads.1 raw_reads.1.raw_reads.1 raw_reads.1.raw_reads.2 LAmerge -v raw_reads.2 raw_reads.2.raw_reads.1 raw_reads.2.raw_reads.2 # Check level 2 .las files jobs (2) (optional but recommended) LAcheck -vS raw_reads raw_reads.1 LAcheck -vS raw_reads raw_reads.2 # Remove level 1 .las files (optional) rm raw_reads.1.raw_reads.1.las raw_reads.1.raw_reads.2.las rm raw_reads.2.raw_reads.1.las raw_reads.2.raw_reads.2.las ================================================ FILE: test/HPCdaligner_synth0_preads.sh ================================================ # Daligner jobs (1) daligner -v -h1 -t50 -H1 -e0.99 -l1 -s1000 preads.1 preads.1 # Initial sort jobs (1) LAsort -v preads.1.preads.1.C0 preads.1.preads.1.N0 preads.1.preads.1.C1 preads.1.preads.1.N1 preads.1.preads.1.C2 preads.1.preads.1.N2 preads.1.preads.1.C3 preads.1.preads.1.N3 && LAmerge -v preads.1 preads.1.preads.1.C0.S preads.1.preads.1.N0.S preads.1.preads.1.C1.S preads.1.preads.1.N1.S preads.1.preads.1.C2.S preads.1.preads.1.N2.S preads.1.preads.1.C3.S preads.1.preads.1.N3.S # Check all level 1 .las files (optional but recommended) LAcheck -vS preads preads.1 # Remove initial .las files (optional) rm preads.1.preads.1.C0.las preads.1.preads.1.N0.las preads.1.preads.1.C1.las preads.1.preads.1.N1.las preads.1.preads.1.C2.las preads.1.preads.1.N2.las preads.1.preads.1.C3.las preads.1.preads.1.N3.las rm preads.1.preads.1.C0.S.las preads.1.preads.1.N0.S.las preads.1.preads.1.C1.S.las preads.1.preads.1.N1.S.las preads.1.preads.1.C2.S.las preads.1.preads.1.N2.S.las preads.1.preads.1.C3.S.las preads.1.preads.1.N3.S.las ================================================ FILE: test/helpers.py ================================================ """ The equal_*() funcs are not really needed with pytest, but they do not hurt. """ from builtins import bytes from falcon_kit.io import NativeIO as StringIO import difflib import os.path def equal_list(a, b): assert set(a) ^ set(b) == set() def equal_dict(a, b): equal_list(sorted(a.keys()), sorted(b.keys())) for k in list(a.keys()): assert \ a[k] == b[k], 'Inequal at k={!r} ({!r}!={!r})'.format(k, a[k], b[k]) def equal_multiline(a, b): alines = a.splitlines() blines = b.splitlines() equal_list(alines, blines) def get_test_data_dir(): return os.path.join(os.path.dirname(__file__), '..', 'test_data') def assert_filecmp(got, expected_path): #result = [line.strip() for line in StringIO(got)] # fails on unicode #result = [line.strip() for line in io.TextIOWrapper(io.StringIO(got))] # for unicode result = [line.strip() for line in StringIO(bytes(got, 'utf-8'))] expected = [line.strip() for line in open(expected_path)] diffs = list(difflib.context_diff(result, expected, fromfile='got', tofile='expected')) if diffs: assert False, 'context_diff:\n' + '\n'.join(diffs[:30]) ================================================ FILE: test/se161.sh ================================================ daligner -v -k18 -h70 -t14 -H7000 -e0.75 raw_reads.92 raw_reads.1 raw_reads.2 raw_reads.3 raw_reads.4 raw_reads.5 raw_reads.6 raw_reads.7 raw_reads.8 raw_reads.9 raw_reads.10 raw_reads.11 raw_reads.12 raw_reads.13 raw_reads.14 raw_reads.15 raw_reads.16 raw_reads.17 raw_reads.18 raw_reads.19 raw_reads.20 raw_reads.21 raw_reads.22 raw_reads.23 LAcheck -v raw_reads *.las LAsort -v raw_reads.1.raw_reads.92.C0 raw_reads.1.raw_reads.92.N0 raw_reads.1.raw_reads.92.C1 raw_reads.1.raw_reads.92.N1 raw_reads.1.raw_reads.92.C2 raw_reads.1.raw_reads.92.N2 raw_reads.1.raw_reads.92.C3 raw_reads.1.raw_reads.92.N3 && LAmerge -v L1.1.92 raw_reads.1.raw_reads.92.C0.S raw_reads.1.raw_reads.92.N0.S raw_reads.1.raw_reads.92.C1.S raw_reads.1.raw_reads.92.N1.S raw_reads.1.raw_reads.92.C2.S raw_reads.1.raw_reads.92.N2.S raw_reads.1.raw_reads.92.C3.S raw_reads.1.raw_reads.92.N3.S LAsort -v raw_reads.2.raw_reads.92.C0 raw_reads.2.raw_reads.92.N0 raw_reads.2.raw_reads.92.C1 raw_reads.2.raw_reads.92.N1 raw_reads.2.raw_reads.92.C2 raw_reads.2.raw_reads.92.N2 raw_reads.2.raw_reads.92.C3 raw_reads.2.raw_reads.92.N3 && LAmerge -v L1.2.92 raw_reads.2.raw_reads.92.C0.S raw_reads.2.raw_reads.92.N0.S raw_reads.2.raw_reads.92.C1.S raw_reads.2.raw_reads.92.N1.S raw_reads.2.raw_reads.92.C2.S raw_reads.2.raw_reads.92.N2.S raw_reads.2.raw_reads.92.C3.S raw_reads.2.raw_reads.92.N3.S LAsort -v raw_reads.3.raw_reads.92.C0 raw_reads.3.raw_reads.92.N0 raw_reads.3.raw_reads.92.C1 raw_reads.3.raw_reads.92.N1 raw_reads.3.raw_reads.92.C2 raw_reads.3.raw_reads.92.N2 raw_reads.3.raw_reads.92.C3 raw_reads.3.raw_reads.92.N3 && LAmerge -v L1.3.92 raw_reads.3.raw_reads.92.C0.S raw_reads.3.raw_reads.92.N0.S raw_reads.3.raw_reads.92.C1.S raw_reads.3.raw_reads.92.N1.S raw_reads.3.raw_reads.92.C2.S raw_reads.3.raw_reads.92.N2.S raw_reads.3.raw_reads.92.C3.S raw_reads.3.raw_reads.92.N3.S LAsort -v raw_reads.4.raw_reads.92.C0 raw_reads.4.raw_reads.92.N0 raw_reads.4.raw_reads.92.C1 raw_reads.4.raw_reads.92.N1 raw_reads.4.raw_reads.92.C2 raw_reads.4.raw_reads.92.N2 raw_reads.4.raw_reads.92.C3 raw_reads.4.raw_reads.92.N3 && LAmerge -v L1.4.92 raw_reads.4.raw_reads.92.C0.S raw_reads.4.raw_reads.92.N0.S raw_reads.4.raw_reads.92.C1.S raw_reads.4.raw_reads.92.N1.S raw_reads.4.raw_reads.92.C2.S raw_reads.4.raw_reads.92.N2.S raw_reads.4.raw_reads.92.C3.S raw_reads.4.raw_reads.92.N3.S LAsort -v raw_reads.5.raw_reads.92.C0 raw_reads.5.raw_reads.92.N0 raw_reads.5.raw_reads.92.C1 raw_reads.5.raw_reads.92.N1 raw_reads.5.raw_reads.92.C2 raw_reads.5.raw_reads.92.N2 raw_reads.5.raw_reads.92.C3 raw_reads.5.raw_reads.92.N3 && LAmerge -v L1.5.92 raw_reads.5.raw_reads.92.C0.S raw_reads.5.raw_reads.92.N0.S raw_reads.5.raw_reads.92.C1.S raw_reads.5.raw_reads.92.N1.S raw_reads.5.raw_reads.92.C2.S raw_reads.5.raw_reads.92.N2.S raw_reads.5.raw_reads.92.C3.S raw_reads.5.raw_reads.92.N3.S LAsort -v raw_reads.6.raw_reads.92.C0 raw_reads.6.raw_reads.92.N0 raw_reads.6.raw_reads.92.C1 raw_reads.6.raw_reads.92.N1 raw_reads.6.raw_reads.92.C2 raw_reads.6.raw_reads.92.N2 raw_reads.6.raw_reads.92.C3 raw_reads.6.raw_reads.92.N3 && LAmerge -v L1.6.92 raw_reads.6.raw_reads.92.C0.S raw_reads.6.raw_reads.92.N0.S raw_reads.6.raw_reads.92.C1.S raw_reads.6.raw_reads.92.N1.S raw_reads.6.raw_reads.92.C2.S raw_reads.6.raw_reads.92.N2.S raw_reads.6.raw_reads.92.C3.S raw_reads.6.raw_reads.92.N3.S LAsort -v raw_reads.7.raw_reads.92.C0 raw_reads.7.raw_reads.92.N0 raw_reads.7.raw_reads.92.C1 raw_reads.7.raw_reads.92.N1 raw_reads.7.raw_reads.92.C2 raw_reads.7.raw_reads.92.N2 raw_reads.7.raw_reads.92.C3 raw_reads.7.raw_reads.92.N3 && LAmerge -v L1.7.92 raw_reads.7.raw_reads.92.C0.S raw_reads.7.raw_reads.92.N0.S raw_reads.7.raw_reads.92.C1.S raw_reads.7.raw_reads.92.N1.S raw_reads.7.raw_reads.92.C2.S raw_reads.7.raw_reads.92.N2.S raw_reads.7.raw_reads.92.C3.S raw_reads.7.raw_reads.92.N3.S LAsort -v raw_reads.8.raw_reads.92.C0 raw_reads.8.raw_reads.92.N0 raw_reads.8.raw_reads.92.C1 raw_reads.8.raw_reads.92.N1 raw_reads.8.raw_reads.92.C2 raw_reads.8.raw_reads.92.N2 raw_reads.8.raw_reads.92.C3 raw_reads.8.raw_reads.92.N3 && LAmerge -v L1.8.92 raw_reads.8.raw_reads.92.C0.S raw_reads.8.raw_reads.92.N0.S raw_reads.8.raw_reads.92.C1.S raw_reads.8.raw_reads.92.N1.S raw_reads.8.raw_reads.92.C2.S raw_reads.8.raw_reads.92.N2.S raw_reads.8.raw_reads.92.C3.S raw_reads.8.raw_reads.92.N3.S LAsort -v raw_reads.9.raw_reads.92.C0 raw_reads.9.raw_reads.92.N0 raw_reads.9.raw_reads.92.C1 raw_reads.9.raw_reads.92.N1 raw_reads.9.raw_reads.92.C2 raw_reads.9.raw_reads.92.N2 raw_reads.9.raw_reads.92.C3 raw_reads.9.raw_reads.92.N3 && LAmerge -v L1.9.92 raw_reads.9.raw_reads.92.C0.S raw_reads.9.raw_reads.92.N0.S raw_reads.9.raw_reads.92.C1.S raw_reads.9.raw_reads.92.N1.S raw_reads.9.raw_reads.92.C2.S raw_reads.9.raw_reads.92.N2.S raw_reads.9.raw_reads.92.C3.S raw_reads.9.raw_reads.92.N3.S LAsort -v raw_reads.10.raw_reads.92.C0 raw_reads.10.raw_reads.92.N0 raw_reads.10.raw_reads.92.C1 raw_reads.10.raw_reads.92.N1 raw_reads.10.raw_reads.92.C2 raw_reads.10.raw_reads.92.N2 raw_reads.10.raw_reads.92.C3 raw_reads.10.raw_reads.92.N3 && LAmerge -v L1.10.92 raw_reads.10.raw_reads.92.C0.S raw_reads.10.raw_reads.92.N0.S raw_reads.10.raw_reads.92.C1.S raw_reads.10.raw_reads.92.N1.S raw_reads.10.raw_reads.92.C2.S raw_reads.10.raw_reads.92.N2.S raw_reads.10.raw_reads.92.C3.S raw_reads.10.raw_reads.92.N3.S LAsort -v raw_reads.11.raw_reads.92.C0 raw_reads.11.raw_reads.92.N0 raw_reads.11.raw_reads.92.C1 raw_reads.11.raw_reads.92.N1 raw_reads.11.raw_reads.92.C2 raw_reads.11.raw_reads.92.N2 raw_reads.11.raw_reads.92.C3 raw_reads.11.raw_reads.92.N3 && LAmerge -v L1.11.92 raw_reads.11.raw_reads.92.C0.S raw_reads.11.raw_reads.92.N0.S raw_reads.11.raw_reads.92.C1.S raw_reads.11.raw_reads.92.N1.S raw_reads.11.raw_reads.92.C2.S raw_reads.11.raw_reads.92.N2.S raw_reads.11.raw_reads.92.C3.S raw_reads.11.raw_reads.92.N3.S LAsort -v raw_reads.12.raw_reads.92.C0 raw_reads.12.raw_reads.92.N0 raw_reads.12.raw_reads.92.C1 raw_reads.12.raw_reads.92.N1 raw_reads.12.raw_reads.92.C2 raw_reads.12.raw_reads.92.N2 raw_reads.12.raw_reads.92.C3 raw_reads.12.raw_reads.92.N3 && LAmerge -v L1.12.92 raw_reads.12.raw_reads.92.C0.S raw_reads.12.raw_reads.92.N0.S raw_reads.12.raw_reads.92.C1.S raw_reads.12.raw_reads.92.N1.S raw_reads.12.raw_reads.92.C2.S raw_reads.12.raw_reads.92.N2.S raw_reads.12.raw_reads.92.C3.S raw_reads.12.raw_reads.92.N3.S LAsort -v raw_reads.13.raw_reads.92.C0 raw_reads.13.raw_reads.92.N0 raw_reads.13.raw_reads.92.C1 raw_reads.13.raw_reads.92.N1 raw_reads.13.raw_reads.92.C2 raw_reads.13.raw_reads.92.N2 raw_reads.13.raw_reads.92.C3 raw_reads.13.raw_reads.92.N3 && LAmerge -v L1.13.92 raw_reads.13.raw_reads.92.C0.S raw_reads.13.raw_reads.92.N0.S raw_reads.13.raw_reads.92.C1.S raw_reads.13.raw_reads.92.N1.S raw_reads.13.raw_reads.92.C2.S raw_reads.13.raw_reads.92.N2.S raw_reads.13.raw_reads.92.C3.S raw_reads.13.raw_reads.92.N3.S LAsort -v raw_reads.14.raw_reads.92.C0 raw_reads.14.raw_reads.92.N0 raw_reads.14.raw_reads.92.C1 raw_reads.14.raw_reads.92.N1 raw_reads.14.raw_reads.92.C2 raw_reads.14.raw_reads.92.N2 raw_reads.14.raw_reads.92.C3 raw_reads.14.raw_reads.92.N3 && LAmerge -v L1.14.92 raw_reads.14.raw_reads.92.C0.S raw_reads.14.raw_reads.92.N0.S raw_reads.14.raw_reads.92.C1.S raw_reads.14.raw_reads.92.N1.S raw_reads.14.raw_reads.92.C2.S raw_reads.14.raw_reads.92.N2.S raw_reads.14.raw_reads.92.C3.S raw_reads.14.raw_reads.92.N3.S LAsort -v raw_reads.15.raw_reads.92.C0 raw_reads.15.raw_reads.92.N0 raw_reads.15.raw_reads.92.C1 raw_reads.15.raw_reads.92.N1 raw_reads.15.raw_reads.92.C2 raw_reads.15.raw_reads.92.N2 raw_reads.15.raw_reads.92.C3 raw_reads.15.raw_reads.92.N3 && LAmerge -v L1.15.92 raw_reads.15.raw_reads.92.C0.S raw_reads.15.raw_reads.92.N0.S raw_reads.15.raw_reads.92.C1.S raw_reads.15.raw_reads.92.N1.S raw_reads.15.raw_reads.92.C2.S raw_reads.15.raw_reads.92.N2.S raw_reads.15.raw_reads.92.C3.S raw_reads.15.raw_reads.92.N3.S LAsort -v raw_reads.16.raw_reads.92.C0 raw_reads.16.raw_reads.92.N0 raw_reads.16.raw_reads.92.C1 raw_reads.16.raw_reads.92.N1 raw_reads.16.raw_reads.92.C2 raw_reads.16.raw_reads.92.N2 raw_reads.16.raw_reads.92.C3 raw_reads.16.raw_reads.92.N3 && LAmerge -v L1.16.92 raw_reads.16.raw_reads.92.C0.S raw_reads.16.raw_reads.92.N0.S raw_reads.16.raw_reads.92.C1.S raw_reads.16.raw_reads.92.N1.S raw_reads.16.raw_reads.92.C2.S raw_reads.16.raw_reads.92.N2.S raw_reads.16.raw_reads.92.C3.S raw_reads.16.raw_reads.92.N3.S LAsort -v raw_reads.17.raw_reads.92.C0 raw_reads.17.raw_reads.92.N0 raw_reads.17.raw_reads.92.C1 raw_reads.17.raw_reads.92.N1 raw_reads.17.raw_reads.92.C2 raw_reads.17.raw_reads.92.N2 raw_reads.17.raw_reads.92.C3 raw_reads.17.raw_reads.92.N3 && LAmerge -v L1.17.92 raw_reads.17.raw_reads.92.C0.S raw_reads.17.raw_reads.92.N0.S raw_reads.17.raw_reads.92.C1.S raw_reads.17.raw_reads.92.N1.S raw_reads.17.raw_reads.92.C2.S raw_reads.17.raw_reads.92.N2.S raw_reads.17.raw_reads.92.C3.S raw_reads.17.raw_reads.92.N3.S LAsort -v raw_reads.18.raw_reads.92.C0 raw_reads.18.raw_reads.92.N0 raw_reads.18.raw_reads.92.C1 raw_reads.18.raw_reads.92.N1 raw_reads.18.raw_reads.92.C2 raw_reads.18.raw_reads.92.N2 raw_reads.18.raw_reads.92.C3 raw_reads.18.raw_reads.92.N3 && LAmerge -v L1.18.92 raw_reads.18.raw_reads.92.C0.S raw_reads.18.raw_reads.92.N0.S raw_reads.18.raw_reads.92.C1.S raw_reads.18.raw_reads.92.N1.S raw_reads.18.raw_reads.92.C2.S raw_reads.18.raw_reads.92.N2.S raw_reads.18.raw_reads.92.C3.S raw_reads.18.raw_reads.92.N3.S LAsort -v raw_reads.19.raw_reads.92.C0 raw_reads.19.raw_reads.92.N0 raw_reads.19.raw_reads.92.C1 raw_reads.19.raw_reads.92.N1 raw_reads.19.raw_reads.92.C2 raw_reads.19.raw_reads.92.N2 raw_reads.19.raw_reads.92.C3 raw_reads.19.raw_reads.92.N3 && LAmerge -v L1.19.92 raw_reads.19.raw_reads.92.C0.S raw_reads.19.raw_reads.92.N0.S raw_reads.19.raw_reads.92.C1.S raw_reads.19.raw_reads.92.N1.S raw_reads.19.raw_reads.92.C2.S raw_reads.19.raw_reads.92.N2.S raw_reads.19.raw_reads.92.C3.S raw_reads.19.raw_reads.92.N3.S LAsort -v raw_reads.20.raw_reads.92.C0 raw_reads.20.raw_reads.92.N0 raw_reads.20.raw_reads.92.C1 raw_reads.20.raw_reads.92.N1 raw_reads.20.raw_reads.92.C2 raw_reads.20.raw_reads.92.N2 raw_reads.20.raw_reads.92.C3 raw_reads.20.raw_reads.92.N3 && LAmerge -v L1.20.92 raw_reads.20.raw_reads.92.C0.S raw_reads.20.raw_reads.92.N0.S raw_reads.20.raw_reads.92.C1.S raw_reads.20.raw_reads.92.N1.S raw_reads.20.raw_reads.92.C2.S raw_reads.20.raw_reads.92.N2.S raw_reads.20.raw_reads.92.C3.S raw_reads.20.raw_reads.92.N3.S LAsort -v raw_reads.21.raw_reads.92.C0 raw_reads.21.raw_reads.92.N0 raw_reads.21.raw_reads.92.C1 raw_reads.21.raw_reads.92.N1 raw_reads.21.raw_reads.92.C2 raw_reads.21.raw_reads.92.N2 raw_reads.21.raw_reads.92.C3 raw_reads.21.raw_reads.92.N3 && LAmerge -v L1.21.92 raw_reads.21.raw_reads.92.C0.S raw_reads.21.raw_reads.92.N0.S raw_reads.21.raw_reads.92.C1.S raw_reads.21.raw_reads.92.N1.S raw_reads.21.raw_reads.92.C2.S raw_reads.21.raw_reads.92.N2.S raw_reads.21.raw_reads.92.C3.S raw_reads.21.raw_reads.92.N3.S LAsort -v raw_reads.22.raw_reads.92.C0 raw_reads.22.raw_reads.92.N0 raw_reads.22.raw_reads.92.C1 raw_reads.22.raw_reads.92.N1 raw_reads.22.raw_reads.92.C2 raw_reads.22.raw_reads.92.N2 raw_reads.22.raw_reads.92.C3 raw_reads.22.raw_reads.92.N3 && LAmerge -v L1.22.92 raw_reads.22.raw_reads.92.C0.S raw_reads.22.raw_reads.92.N0.S raw_reads.22.raw_reads.92.C1.S raw_reads.22.raw_reads.92.N1.S raw_reads.22.raw_reads.92.C2.S raw_reads.22.raw_reads.92.N2.S raw_reads.22.raw_reads.92.C3.S raw_reads.22.raw_reads.92.N3.S LAsort -v raw_reads.23.raw_reads.92.C0 raw_reads.23.raw_reads.92.N0 raw_reads.23.raw_reads.92.C1 raw_reads.23.raw_reads.92.N1 raw_reads.23.raw_reads.92.C2 raw_reads.23.raw_reads.92.N2 raw_reads.23.raw_reads.92.C3 raw_reads.23.raw_reads.92.N3 && LAmerge -v L1.23.92 raw_reads.23.raw_reads.92.C0.S raw_reads.23.raw_reads.92.N0.S raw_reads.23.raw_reads.92.C1.S raw_reads.23.raw_reads.92.N1.S raw_reads.23.raw_reads.92.C2.S raw_reads.23.raw_reads.92.N2.S raw_reads.23.raw_reads.92.C3.S raw_reads.23.raw_reads.92.N3.S LAsort -v raw_reads.92.raw_reads.1.C0 raw_reads.92.raw_reads.1.N0 raw_reads.92.raw_reads.1.C1 raw_reads.92.raw_reads.1.N1 raw_reads.92.raw_reads.1.C2 raw_reads.92.raw_reads.1.N2 raw_reads.92.raw_reads.1.C3 raw_reads.92.raw_reads.1.N3 && LAmerge -v L1.92.1 raw_reads.92.raw_reads.1.C0.S raw_reads.92.raw_reads.1.N0.S raw_reads.92.raw_reads.1.C1.S raw_reads.92.raw_reads.1.N1.S raw_reads.92.raw_reads.1.C2.S raw_reads.92.raw_reads.1.N2.S raw_reads.92.raw_reads.1.C3.S raw_reads.92.raw_reads.1.N3.S LAsort -v raw_reads.92.raw_reads.2.C0 raw_reads.92.raw_reads.2.N0 raw_reads.92.raw_reads.2.C1 raw_reads.92.raw_reads.2.N1 raw_reads.92.raw_reads.2.C2 raw_reads.92.raw_reads.2.N2 raw_reads.92.raw_reads.2.C3 raw_reads.92.raw_reads.2.N3 && LAmerge -v L1.92.2 raw_reads.92.raw_reads.2.C0.S raw_reads.92.raw_reads.2.N0.S raw_reads.92.raw_reads.2.C1.S raw_reads.92.raw_reads.2.N1.S raw_reads.92.raw_reads.2.C2.S raw_reads.92.raw_reads.2.N2.S raw_reads.92.raw_reads.2.C3.S raw_reads.92.raw_reads.2.N3.S LAsort -v raw_reads.92.raw_reads.3.C0 raw_reads.92.raw_reads.3.N0 raw_reads.92.raw_reads.3.C1 raw_reads.92.raw_reads.3.N1 raw_reads.92.raw_reads.3.C2 raw_reads.92.raw_reads.3.N2 raw_reads.92.raw_reads.3.C3 raw_reads.92.raw_reads.3.N3 && LAmerge -v L1.92.3 raw_reads.92.raw_reads.3.C0.S raw_reads.92.raw_reads.3.N0.S raw_reads.92.raw_reads.3.C1.S raw_reads.92.raw_reads.3.N1.S raw_reads.92.raw_reads.3.C2.S raw_reads.92.raw_reads.3.N2.S raw_reads.92.raw_reads.3.C3.S raw_reads.92.raw_reads.3.N3.S LAsort -v raw_reads.92.raw_reads.4.C0 raw_reads.92.raw_reads.4.N0 raw_reads.92.raw_reads.4.C1 raw_reads.92.raw_reads.4.N1 raw_reads.92.raw_reads.4.C2 raw_reads.92.raw_reads.4.N2 raw_reads.92.raw_reads.4.C3 raw_reads.92.raw_reads.4.N3 && LAmerge -v L1.92.4 raw_reads.92.raw_reads.4.C0.S raw_reads.92.raw_reads.4.N0.S raw_reads.92.raw_reads.4.C1.S raw_reads.92.raw_reads.4.N1.S raw_reads.92.raw_reads.4.C2.S raw_reads.92.raw_reads.4.N2.S raw_reads.92.raw_reads.4.C3.S raw_reads.92.raw_reads.4.N3.S LAsort -v raw_reads.92.raw_reads.5.C0 raw_reads.92.raw_reads.5.N0 raw_reads.92.raw_reads.5.C1 raw_reads.92.raw_reads.5.N1 raw_reads.92.raw_reads.5.C2 raw_reads.92.raw_reads.5.N2 raw_reads.92.raw_reads.5.C3 raw_reads.92.raw_reads.5.N3 && LAmerge -v L1.92.5 raw_reads.92.raw_reads.5.C0.S raw_reads.92.raw_reads.5.N0.S raw_reads.92.raw_reads.5.C1.S raw_reads.92.raw_reads.5.N1.S raw_reads.92.raw_reads.5.C2.S raw_reads.92.raw_reads.5.N2.S raw_reads.92.raw_reads.5.C3.S raw_reads.92.raw_reads.5.N3.S LAsort -v raw_reads.92.raw_reads.6.C0 raw_reads.92.raw_reads.6.N0 raw_reads.92.raw_reads.6.C1 raw_reads.92.raw_reads.6.N1 raw_reads.92.raw_reads.6.C2 raw_reads.92.raw_reads.6.N2 raw_reads.92.raw_reads.6.C3 raw_reads.92.raw_reads.6.N3 && LAmerge -v L1.92.6 raw_reads.92.raw_reads.6.C0.S raw_reads.92.raw_reads.6.N0.S raw_reads.92.raw_reads.6.C1.S raw_reads.92.raw_reads.6.N1.S raw_reads.92.raw_reads.6.C2.S raw_reads.92.raw_reads.6.N2.S raw_reads.92.raw_reads.6.C3.S raw_reads.92.raw_reads.6.N3.S LAsort -v raw_reads.92.raw_reads.7.C0 raw_reads.92.raw_reads.7.N0 raw_reads.92.raw_reads.7.C1 raw_reads.92.raw_reads.7.N1 raw_reads.92.raw_reads.7.C2 raw_reads.92.raw_reads.7.N2 raw_reads.92.raw_reads.7.C3 raw_reads.92.raw_reads.7.N3 && LAmerge -v L1.92.7 raw_reads.92.raw_reads.7.C0.S raw_reads.92.raw_reads.7.N0.S raw_reads.92.raw_reads.7.C1.S raw_reads.92.raw_reads.7.N1.S raw_reads.92.raw_reads.7.C2.S raw_reads.92.raw_reads.7.N2.S raw_reads.92.raw_reads.7.C3.S raw_reads.92.raw_reads.7.N3.S LAsort -v raw_reads.92.raw_reads.8.C0 raw_reads.92.raw_reads.8.N0 raw_reads.92.raw_reads.8.C1 raw_reads.92.raw_reads.8.N1 raw_reads.92.raw_reads.8.C2 raw_reads.92.raw_reads.8.N2 raw_reads.92.raw_reads.8.C3 raw_reads.92.raw_reads.8.N3 && LAmerge -v L1.92.8 raw_reads.92.raw_reads.8.C0.S raw_reads.92.raw_reads.8.N0.S raw_reads.92.raw_reads.8.C1.S raw_reads.92.raw_reads.8.N1.S raw_reads.92.raw_reads.8.C2.S raw_reads.92.raw_reads.8.N2.S raw_reads.92.raw_reads.8.C3.S raw_reads.92.raw_reads.8.N3.S LAsort -v raw_reads.92.raw_reads.9.C0 raw_reads.92.raw_reads.9.N0 raw_reads.92.raw_reads.9.C1 raw_reads.92.raw_reads.9.N1 raw_reads.92.raw_reads.9.C2 raw_reads.92.raw_reads.9.N2 raw_reads.92.raw_reads.9.C3 raw_reads.92.raw_reads.9.N3 && LAmerge -v L1.92.9 raw_reads.92.raw_reads.9.C0.S raw_reads.92.raw_reads.9.N0.S raw_reads.92.raw_reads.9.C1.S raw_reads.92.raw_reads.9.N1.S raw_reads.92.raw_reads.9.C2.S raw_reads.92.raw_reads.9.N2.S raw_reads.92.raw_reads.9.C3.S raw_reads.92.raw_reads.9.N3.S LAsort -v raw_reads.92.raw_reads.10.C0 raw_reads.92.raw_reads.10.N0 raw_reads.92.raw_reads.10.C1 raw_reads.92.raw_reads.10.N1 raw_reads.92.raw_reads.10.C2 raw_reads.92.raw_reads.10.N2 raw_reads.92.raw_reads.10.C3 raw_reads.92.raw_reads.10.N3 && LAmerge -v L1.92.10 raw_reads.92.raw_reads.10.C0.S raw_reads.92.raw_reads.10.N0.S raw_reads.92.raw_reads.10.C1.S raw_reads.92.raw_reads.10.N1.S raw_reads.92.raw_reads.10.C2.S raw_reads.92.raw_reads.10.N2.S raw_reads.92.raw_reads.10.C3.S raw_reads.92.raw_reads.10.N3.S LAsort -v raw_reads.92.raw_reads.11.C0 raw_reads.92.raw_reads.11.N0 raw_reads.92.raw_reads.11.C1 raw_reads.92.raw_reads.11.N1 raw_reads.92.raw_reads.11.C2 raw_reads.92.raw_reads.11.N2 raw_reads.92.raw_reads.11.C3 raw_reads.92.raw_reads.11.N3 && LAmerge -v L1.92.11 raw_reads.92.raw_reads.11.C0.S raw_reads.92.raw_reads.11.N0.S raw_reads.92.raw_reads.11.C1.S raw_reads.92.raw_reads.11.N1.S raw_reads.92.raw_reads.11.C2.S raw_reads.92.raw_reads.11.N2.S raw_reads.92.raw_reads.11.C3.S raw_reads.92.raw_reads.11.N3.S LAsort -v raw_reads.92.raw_reads.12.C0 raw_reads.92.raw_reads.12.N0 raw_reads.92.raw_reads.12.C1 raw_reads.92.raw_reads.12.N1 raw_reads.92.raw_reads.12.C2 raw_reads.92.raw_reads.12.N2 raw_reads.92.raw_reads.12.C3 raw_reads.92.raw_reads.12.N3 && LAmerge -v L1.92.12 raw_reads.92.raw_reads.12.C0.S raw_reads.92.raw_reads.12.N0.S raw_reads.92.raw_reads.12.C1.S raw_reads.92.raw_reads.12.N1.S raw_reads.92.raw_reads.12.C2.S raw_reads.92.raw_reads.12.N2.S raw_reads.92.raw_reads.12.C3.S raw_reads.92.raw_reads.12.N3.S LAsort -v raw_reads.92.raw_reads.13.C0 raw_reads.92.raw_reads.13.N0 raw_reads.92.raw_reads.13.C1 raw_reads.92.raw_reads.13.N1 raw_reads.92.raw_reads.13.C2 raw_reads.92.raw_reads.13.N2 raw_reads.92.raw_reads.13.C3 raw_reads.92.raw_reads.13.N3 && LAmerge -v L1.92.13 raw_reads.92.raw_reads.13.C0.S raw_reads.92.raw_reads.13.N0.S raw_reads.92.raw_reads.13.C1.S raw_reads.92.raw_reads.13.N1.S raw_reads.92.raw_reads.13.C2.S raw_reads.92.raw_reads.13.N2.S raw_reads.92.raw_reads.13.C3.S raw_reads.92.raw_reads.13.N3.S LAsort -v raw_reads.92.raw_reads.14.C0 raw_reads.92.raw_reads.14.N0 raw_reads.92.raw_reads.14.C1 raw_reads.92.raw_reads.14.N1 raw_reads.92.raw_reads.14.C2 raw_reads.92.raw_reads.14.N2 raw_reads.92.raw_reads.14.C3 raw_reads.92.raw_reads.14.N3 && LAmerge -v L1.92.14 raw_reads.92.raw_reads.14.C0.S raw_reads.92.raw_reads.14.N0.S raw_reads.92.raw_reads.14.C1.S raw_reads.92.raw_reads.14.N1.S raw_reads.92.raw_reads.14.C2.S raw_reads.92.raw_reads.14.N2.S raw_reads.92.raw_reads.14.C3.S raw_reads.92.raw_reads.14.N3.S LAsort -v raw_reads.92.raw_reads.15.C0 raw_reads.92.raw_reads.15.N0 raw_reads.92.raw_reads.15.C1 raw_reads.92.raw_reads.15.N1 raw_reads.92.raw_reads.15.C2 raw_reads.92.raw_reads.15.N2 raw_reads.92.raw_reads.15.C3 raw_reads.92.raw_reads.15.N3 && LAmerge -v L1.92.15 raw_reads.92.raw_reads.15.C0.S raw_reads.92.raw_reads.15.N0.S raw_reads.92.raw_reads.15.C1.S raw_reads.92.raw_reads.15.N1.S raw_reads.92.raw_reads.15.C2.S raw_reads.92.raw_reads.15.N2.S raw_reads.92.raw_reads.15.C3.S raw_reads.92.raw_reads.15.N3.S LAsort -v raw_reads.92.raw_reads.16.C0 raw_reads.92.raw_reads.16.N0 raw_reads.92.raw_reads.16.C1 raw_reads.92.raw_reads.16.N1 raw_reads.92.raw_reads.16.C2 raw_reads.92.raw_reads.16.N2 raw_reads.92.raw_reads.16.C3 raw_reads.92.raw_reads.16.N3 && LAmerge -v L1.92.16 raw_reads.92.raw_reads.16.C0.S raw_reads.92.raw_reads.16.N0.S raw_reads.92.raw_reads.16.C1.S raw_reads.92.raw_reads.16.N1.S raw_reads.92.raw_reads.16.C2.S raw_reads.92.raw_reads.16.N2.S raw_reads.92.raw_reads.16.C3.S raw_reads.92.raw_reads.16.N3.S LAsort -v raw_reads.92.raw_reads.17.C0 raw_reads.92.raw_reads.17.N0 raw_reads.92.raw_reads.17.C1 raw_reads.92.raw_reads.17.N1 raw_reads.92.raw_reads.17.C2 raw_reads.92.raw_reads.17.N2 raw_reads.92.raw_reads.17.C3 raw_reads.92.raw_reads.17.N3 && LAmerge -v L1.92.17 raw_reads.92.raw_reads.17.C0.S raw_reads.92.raw_reads.17.N0.S raw_reads.92.raw_reads.17.C1.S raw_reads.92.raw_reads.17.N1.S raw_reads.92.raw_reads.17.C2.S raw_reads.92.raw_reads.17.N2.S raw_reads.92.raw_reads.17.C3.S raw_reads.92.raw_reads.17.N3.S LAsort -v raw_reads.92.raw_reads.18.C0 raw_reads.92.raw_reads.18.N0 raw_reads.92.raw_reads.18.C1 raw_reads.92.raw_reads.18.N1 raw_reads.92.raw_reads.18.C2 raw_reads.92.raw_reads.18.N2 raw_reads.92.raw_reads.18.C3 raw_reads.92.raw_reads.18.N3 && LAmerge -v L1.92.18 raw_reads.92.raw_reads.18.C0.S raw_reads.92.raw_reads.18.N0.S raw_reads.92.raw_reads.18.C1.S raw_reads.92.raw_reads.18.N1.S raw_reads.92.raw_reads.18.C2.S raw_reads.92.raw_reads.18.N2.S raw_reads.92.raw_reads.18.C3.S raw_reads.92.raw_reads.18.N3.S LAsort -v raw_reads.92.raw_reads.19.C0 raw_reads.92.raw_reads.19.N0 raw_reads.92.raw_reads.19.C1 raw_reads.92.raw_reads.19.N1 raw_reads.92.raw_reads.19.C2 raw_reads.92.raw_reads.19.N2 raw_reads.92.raw_reads.19.C3 raw_reads.92.raw_reads.19.N3 && LAmerge -v L1.92.19 raw_reads.92.raw_reads.19.C0.S raw_reads.92.raw_reads.19.N0.S raw_reads.92.raw_reads.19.C1.S raw_reads.92.raw_reads.19.N1.S raw_reads.92.raw_reads.19.C2.S raw_reads.92.raw_reads.19.N2.S raw_reads.92.raw_reads.19.C3.S raw_reads.92.raw_reads.19.N3.S LAsort -v raw_reads.92.raw_reads.20.C0 raw_reads.92.raw_reads.20.N0 raw_reads.92.raw_reads.20.C1 raw_reads.92.raw_reads.20.N1 raw_reads.92.raw_reads.20.C2 raw_reads.92.raw_reads.20.N2 raw_reads.92.raw_reads.20.C3 raw_reads.92.raw_reads.20.N3 && LAmerge -v L1.92.20 raw_reads.92.raw_reads.20.C0.S raw_reads.92.raw_reads.20.N0.S raw_reads.92.raw_reads.20.C1.S raw_reads.92.raw_reads.20.N1.S raw_reads.92.raw_reads.20.C2.S raw_reads.92.raw_reads.20.N2.S raw_reads.92.raw_reads.20.C3.S raw_reads.92.raw_reads.20.N3.S LAsort -v raw_reads.92.raw_reads.21.C0 raw_reads.92.raw_reads.21.N0 raw_reads.92.raw_reads.21.C1 raw_reads.92.raw_reads.21.N1 raw_reads.92.raw_reads.21.C2 raw_reads.92.raw_reads.21.N2 raw_reads.92.raw_reads.21.C3 raw_reads.92.raw_reads.21.N3 && LAmerge -v L1.92.21 raw_reads.92.raw_reads.21.C0.S raw_reads.92.raw_reads.21.N0.S raw_reads.92.raw_reads.21.C1.S raw_reads.92.raw_reads.21.N1.S raw_reads.92.raw_reads.21.C2.S raw_reads.92.raw_reads.21.N2.S raw_reads.92.raw_reads.21.C3.S raw_reads.92.raw_reads.21.N3.S LAsort -v raw_reads.92.raw_reads.22.C0 raw_reads.92.raw_reads.22.N0 raw_reads.92.raw_reads.22.C1 raw_reads.92.raw_reads.22.N1 raw_reads.92.raw_reads.22.C2 raw_reads.92.raw_reads.22.N2 raw_reads.92.raw_reads.22.C3 raw_reads.92.raw_reads.22.N3 && LAmerge -v L1.92.22 raw_reads.92.raw_reads.22.C0.S raw_reads.92.raw_reads.22.N0.S raw_reads.92.raw_reads.22.C1.S raw_reads.92.raw_reads.22.N1.S raw_reads.92.raw_reads.22.C2.S raw_reads.92.raw_reads.22.N2.S raw_reads.92.raw_reads.22.C3.S raw_reads.92.raw_reads.22.N3.S LAsort -v raw_reads.92.raw_reads.23.C0 raw_reads.92.raw_reads.23.N0 raw_reads.92.raw_reads.23.C1 raw_reads.92.raw_reads.23.N1 raw_reads.92.raw_reads.23.C2 raw_reads.92.raw_reads.23.N2 raw_reads.92.raw_reads.23.C3 raw_reads.92.raw_reads.23.N3 && LAmerge -v L1.92.23 raw_reads.92.raw_reads.23.C0.S raw_reads.92.raw_reads.23.N0.S raw_reads.92.raw_reads.23.C1.S raw_reads.92.raw_reads.23.N1.S raw_reads.92.raw_reads.23.C2.S raw_reads.92.raw_reads.23.N2.S raw_reads.92.raw_reads.23.C3.S raw_reads.92.raw_reads.23.N3.S LAcheck -vS raw_reads L1.1.92 LAcheck -vS raw_reads L1.2.92 LAcheck -vS raw_reads L1.3.92 LAcheck -vS raw_reads L1.4.92 LAcheck -vS raw_reads L1.5.92 LAcheck -vS raw_reads L1.6.92 LAcheck -vS raw_reads L1.7.92 LAcheck -vS raw_reads L1.8.92 LAcheck -vS raw_reads L1.9.92 LAcheck -vS raw_reads L1.10.92 LAcheck -vS raw_reads L1.11.92 LAcheck -vS raw_reads L1.12.92 LAcheck -vS raw_reads L1.13.92 LAcheck -vS raw_reads L1.14.92 LAcheck -vS raw_reads L1.15.92 LAcheck -vS raw_reads L1.16.92 LAcheck -vS raw_reads L1.17.92 LAcheck -vS raw_reads L1.18.92 LAcheck -vS raw_reads L1.19.92 LAcheck -vS raw_reads L1.20.92 LAcheck -vS raw_reads L1.21.92 LAcheck -vS raw_reads L1.22.92 LAcheck -vS raw_reads L1.23.92 LAcheck -vS raw_reads L1.92.1 LAcheck -vS raw_reads L1.92.2 LAcheck -vS raw_reads L1.92.3 LAcheck -vS raw_reads L1.92.4 LAcheck -vS raw_reads L1.92.5 LAcheck -vS raw_reads L1.92.6 LAcheck -vS raw_reads L1.92.7 LAcheck -vS raw_reads L1.92.8 LAcheck -vS raw_reads L1.92.9 LAcheck -vS raw_reads L1.92.10 LAcheck -vS raw_reads L1.92.11 LAcheck -vS raw_reads L1.92.12 LAcheck -vS raw_reads L1.92.13 LAcheck -vS raw_reads L1.92.14 LAcheck -vS raw_reads L1.92.15 LAcheck -vS raw_reads L1.92.16 LAcheck -vS raw_reads L1.92.17 LAcheck -vS raw_reads L1.92.18 LAcheck -vS raw_reads L1.92.19 LAcheck -vS raw_reads L1.92.20 LAcheck -vS raw_reads L1.92.21 LAcheck -vS raw_reads L1.92.22 LAcheck -vS raw_reads L1.92.23 daligner -v -k18 -h70 -t14 -H7000 -e0.75 raw_reads.91 raw_reads.46 raw_reads.47 raw_reads.48 raw_reads.49 raw_reads.50 raw_reads.51 raw_reads.52 raw_reads.53 raw_reads.54 raw_reads.55 raw_reads.56 raw_reads.57 raw_reads.58 raw_reads.59 raw_reads.60 raw_reads.61 raw_reads.62 raw_reads.63 raw_reads.64 raw_reads.65 raw_reads.66 raw_reads.67 raw_reads.68 LAcheck -v raw_reads *.las LAsort -v raw_reads.46.raw_reads.91.C0 raw_reads.46.raw_reads.91.N0 raw_reads.46.raw_reads.91.C1 raw_reads.46.raw_reads.91.N1 raw_reads.46.raw_reads.91.C2 raw_reads.46.raw_reads.91.N2 raw_reads.46.raw_reads.91.C3 raw_reads.46.raw_reads.91.N3 && LAmerge -v L1.46.91 raw_reads.46.raw_reads.91.C0.S raw_reads.46.raw_reads.91.N0.S raw_reads.46.raw_reads.91.C1.S raw_reads.46.raw_reads.91.N1.S raw_reads.46.raw_reads.91.C2.S raw_reads.46.raw_reads.91.N2.S raw_reads.46.raw_reads.91.C3.S raw_reads.46.raw_reads.91.N3.S LAsort -v raw_reads.47.raw_reads.91.C0 raw_reads.47.raw_reads.91.N0 raw_reads.47.raw_reads.91.C1 raw_reads.47.raw_reads.91.N1 raw_reads.47.raw_reads.91.C2 raw_reads.47.raw_reads.91.N2 raw_reads.47.raw_reads.91.C3 raw_reads.47.raw_reads.91.N3 && LAmerge -v L1.47.91 raw_reads.47.raw_reads.91.C0.S raw_reads.47.raw_reads.91.N0.S raw_reads.47.raw_reads.91.C1.S raw_reads.47.raw_reads.91.N1.S raw_reads.47.raw_reads.91.C2.S raw_reads.47.raw_reads.91.N2.S raw_reads.47.raw_reads.91.C3.S raw_reads.47.raw_reads.91.N3.S LAsort -v raw_reads.48.raw_reads.91.C0 raw_reads.48.raw_reads.91.N0 raw_reads.48.raw_reads.91.C1 raw_reads.48.raw_reads.91.N1 raw_reads.48.raw_reads.91.C2 raw_reads.48.raw_reads.91.N2 raw_reads.48.raw_reads.91.C3 raw_reads.48.raw_reads.91.N3 && LAmerge -v L1.48.91 raw_reads.48.raw_reads.91.C0.S raw_reads.48.raw_reads.91.N0.S raw_reads.48.raw_reads.91.C1.S raw_reads.48.raw_reads.91.N1.S raw_reads.48.raw_reads.91.C2.S raw_reads.48.raw_reads.91.N2.S raw_reads.48.raw_reads.91.C3.S raw_reads.48.raw_reads.91.N3.S LAsort -v raw_reads.49.raw_reads.91.C0 raw_reads.49.raw_reads.91.N0 raw_reads.49.raw_reads.91.C1 raw_reads.49.raw_reads.91.N1 raw_reads.49.raw_reads.91.C2 raw_reads.49.raw_reads.91.N2 raw_reads.49.raw_reads.91.C3 raw_reads.49.raw_reads.91.N3 && LAmerge -v L1.49.91 raw_reads.49.raw_reads.91.C0.S raw_reads.49.raw_reads.91.N0.S raw_reads.49.raw_reads.91.C1.S raw_reads.49.raw_reads.91.N1.S raw_reads.49.raw_reads.91.C2.S raw_reads.49.raw_reads.91.N2.S raw_reads.49.raw_reads.91.C3.S raw_reads.49.raw_reads.91.N3.S LAsort -v raw_reads.50.raw_reads.91.C0 raw_reads.50.raw_reads.91.N0 raw_reads.50.raw_reads.91.C1 raw_reads.50.raw_reads.91.N1 raw_reads.50.raw_reads.91.C2 raw_reads.50.raw_reads.91.N2 raw_reads.50.raw_reads.91.C3 raw_reads.50.raw_reads.91.N3 && LAmerge -v L1.50.91 raw_reads.50.raw_reads.91.C0.S raw_reads.50.raw_reads.91.N0.S raw_reads.50.raw_reads.91.C1.S raw_reads.50.raw_reads.91.N1.S raw_reads.50.raw_reads.91.C2.S raw_reads.50.raw_reads.91.N2.S raw_reads.50.raw_reads.91.C3.S raw_reads.50.raw_reads.91.N3.S LAsort -v raw_reads.51.raw_reads.91.C0 raw_reads.51.raw_reads.91.N0 raw_reads.51.raw_reads.91.C1 raw_reads.51.raw_reads.91.N1 raw_reads.51.raw_reads.91.C2 raw_reads.51.raw_reads.91.N2 raw_reads.51.raw_reads.91.C3 raw_reads.51.raw_reads.91.N3 && LAmerge -v L1.51.91 raw_reads.51.raw_reads.91.C0.S raw_reads.51.raw_reads.91.N0.S raw_reads.51.raw_reads.91.C1.S raw_reads.51.raw_reads.91.N1.S raw_reads.51.raw_reads.91.C2.S raw_reads.51.raw_reads.91.N2.S raw_reads.51.raw_reads.91.C3.S raw_reads.51.raw_reads.91.N3.S LAsort -v raw_reads.52.raw_reads.91.C0 raw_reads.52.raw_reads.91.N0 raw_reads.52.raw_reads.91.C1 raw_reads.52.raw_reads.91.N1 raw_reads.52.raw_reads.91.C2 raw_reads.52.raw_reads.91.N2 raw_reads.52.raw_reads.91.C3 raw_reads.52.raw_reads.91.N3 && LAmerge -v L1.52.91 raw_reads.52.raw_reads.91.C0.S raw_reads.52.raw_reads.91.N0.S raw_reads.52.raw_reads.91.C1.S raw_reads.52.raw_reads.91.N1.S raw_reads.52.raw_reads.91.C2.S raw_reads.52.raw_reads.91.N2.S raw_reads.52.raw_reads.91.C3.S raw_reads.52.raw_reads.91.N3.S LAsort -v raw_reads.53.raw_reads.91.C0 raw_reads.53.raw_reads.91.N0 raw_reads.53.raw_reads.91.C1 raw_reads.53.raw_reads.91.N1 raw_reads.53.raw_reads.91.C2 raw_reads.53.raw_reads.91.N2 raw_reads.53.raw_reads.91.C3 raw_reads.53.raw_reads.91.N3 && LAmerge -v L1.53.91 raw_reads.53.raw_reads.91.C0.S raw_reads.53.raw_reads.91.N0.S raw_reads.53.raw_reads.91.C1.S raw_reads.53.raw_reads.91.N1.S raw_reads.53.raw_reads.91.C2.S raw_reads.53.raw_reads.91.N2.S raw_reads.53.raw_reads.91.C3.S raw_reads.53.raw_reads.91.N3.S LAsort -v raw_reads.54.raw_reads.91.C0 raw_reads.54.raw_reads.91.N0 raw_reads.54.raw_reads.91.C1 raw_reads.54.raw_reads.91.N1 raw_reads.54.raw_reads.91.C2 raw_reads.54.raw_reads.91.N2 raw_reads.54.raw_reads.91.C3 raw_reads.54.raw_reads.91.N3 && LAmerge -v L1.54.91 raw_reads.54.raw_reads.91.C0.S raw_reads.54.raw_reads.91.N0.S raw_reads.54.raw_reads.91.C1.S raw_reads.54.raw_reads.91.N1.S raw_reads.54.raw_reads.91.C2.S raw_reads.54.raw_reads.91.N2.S raw_reads.54.raw_reads.91.C3.S raw_reads.54.raw_reads.91.N3.S LAsort -v raw_reads.55.raw_reads.91.C0 raw_reads.55.raw_reads.91.N0 raw_reads.55.raw_reads.91.C1 raw_reads.55.raw_reads.91.N1 raw_reads.55.raw_reads.91.C2 raw_reads.55.raw_reads.91.N2 raw_reads.55.raw_reads.91.C3 raw_reads.55.raw_reads.91.N3 && LAmerge -v L1.55.91 raw_reads.55.raw_reads.91.C0.S raw_reads.55.raw_reads.91.N0.S raw_reads.55.raw_reads.91.C1.S raw_reads.55.raw_reads.91.N1.S raw_reads.55.raw_reads.91.C2.S raw_reads.55.raw_reads.91.N2.S raw_reads.55.raw_reads.91.C3.S raw_reads.55.raw_reads.91.N3.S LAsort -v raw_reads.56.raw_reads.91.C0 raw_reads.56.raw_reads.91.N0 raw_reads.56.raw_reads.91.C1 raw_reads.56.raw_reads.91.N1 raw_reads.56.raw_reads.91.C2 raw_reads.56.raw_reads.91.N2 raw_reads.56.raw_reads.91.C3 raw_reads.56.raw_reads.91.N3 && LAmerge -v L1.56.91 raw_reads.56.raw_reads.91.C0.S raw_reads.56.raw_reads.91.N0.S raw_reads.56.raw_reads.91.C1.S raw_reads.56.raw_reads.91.N1.S raw_reads.56.raw_reads.91.C2.S raw_reads.56.raw_reads.91.N2.S raw_reads.56.raw_reads.91.C3.S raw_reads.56.raw_reads.91.N3.S LAsort -v raw_reads.57.raw_reads.91.C0 raw_reads.57.raw_reads.91.N0 raw_reads.57.raw_reads.91.C1 raw_reads.57.raw_reads.91.N1 raw_reads.57.raw_reads.91.C2 raw_reads.57.raw_reads.91.N2 raw_reads.57.raw_reads.91.C3 raw_reads.57.raw_reads.91.N3 && LAmerge -v L1.57.91 raw_reads.57.raw_reads.91.C0.S raw_reads.57.raw_reads.91.N0.S raw_reads.57.raw_reads.91.C1.S raw_reads.57.raw_reads.91.N1.S raw_reads.57.raw_reads.91.C2.S raw_reads.57.raw_reads.91.N2.S raw_reads.57.raw_reads.91.C3.S raw_reads.57.raw_reads.91.N3.S LAsort -v raw_reads.58.raw_reads.91.C0 raw_reads.58.raw_reads.91.N0 raw_reads.58.raw_reads.91.C1 raw_reads.58.raw_reads.91.N1 raw_reads.58.raw_reads.91.C2 raw_reads.58.raw_reads.91.N2 raw_reads.58.raw_reads.91.C3 raw_reads.58.raw_reads.91.N3 && LAmerge -v L1.58.91 raw_reads.58.raw_reads.91.C0.S raw_reads.58.raw_reads.91.N0.S raw_reads.58.raw_reads.91.C1.S raw_reads.58.raw_reads.91.N1.S raw_reads.58.raw_reads.91.C2.S raw_reads.58.raw_reads.91.N2.S raw_reads.58.raw_reads.91.C3.S raw_reads.58.raw_reads.91.N3.S LAsort -v raw_reads.59.raw_reads.91.C0 raw_reads.59.raw_reads.91.N0 raw_reads.59.raw_reads.91.C1 raw_reads.59.raw_reads.91.N1 raw_reads.59.raw_reads.91.C2 raw_reads.59.raw_reads.91.N2 raw_reads.59.raw_reads.91.C3 raw_reads.59.raw_reads.91.N3 && LAmerge -v L1.59.91 raw_reads.59.raw_reads.91.C0.S raw_reads.59.raw_reads.91.N0.S raw_reads.59.raw_reads.91.C1.S raw_reads.59.raw_reads.91.N1.S raw_reads.59.raw_reads.91.C2.S raw_reads.59.raw_reads.91.N2.S raw_reads.59.raw_reads.91.C3.S raw_reads.59.raw_reads.91.N3.S LAsort -v raw_reads.60.raw_reads.91.C0 raw_reads.60.raw_reads.91.N0 raw_reads.60.raw_reads.91.C1 raw_reads.60.raw_reads.91.N1 raw_reads.60.raw_reads.91.C2 raw_reads.60.raw_reads.91.N2 raw_reads.60.raw_reads.91.C3 raw_reads.60.raw_reads.91.N3 && LAmerge -v L1.60.91 raw_reads.60.raw_reads.91.C0.S raw_reads.60.raw_reads.91.N0.S raw_reads.60.raw_reads.91.C1.S raw_reads.60.raw_reads.91.N1.S raw_reads.60.raw_reads.91.C2.S raw_reads.60.raw_reads.91.N2.S raw_reads.60.raw_reads.91.C3.S raw_reads.60.raw_reads.91.N3.S LAsort -v raw_reads.61.raw_reads.91.C0 raw_reads.61.raw_reads.91.N0 raw_reads.61.raw_reads.91.C1 raw_reads.61.raw_reads.91.N1 raw_reads.61.raw_reads.91.C2 raw_reads.61.raw_reads.91.N2 raw_reads.61.raw_reads.91.C3 raw_reads.61.raw_reads.91.N3 && LAmerge -v L1.61.91 raw_reads.61.raw_reads.91.C0.S raw_reads.61.raw_reads.91.N0.S raw_reads.61.raw_reads.91.C1.S raw_reads.61.raw_reads.91.N1.S raw_reads.61.raw_reads.91.C2.S raw_reads.61.raw_reads.91.N2.S raw_reads.61.raw_reads.91.C3.S raw_reads.61.raw_reads.91.N3.S LAsort -v raw_reads.62.raw_reads.91.C0 raw_reads.62.raw_reads.91.N0 raw_reads.62.raw_reads.91.C1 raw_reads.62.raw_reads.91.N1 raw_reads.62.raw_reads.91.C2 raw_reads.62.raw_reads.91.N2 raw_reads.62.raw_reads.91.C3 raw_reads.62.raw_reads.91.N3 && LAmerge -v L1.62.91 raw_reads.62.raw_reads.91.C0.S raw_reads.62.raw_reads.91.N0.S raw_reads.62.raw_reads.91.C1.S raw_reads.62.raw_reads.91.N1.S raw_reads.62.raw_reads.91.C2.S raw_reads.62.raw_reads.91.N2.S raw_reads.62.raw_reads.91.C3.S raw_reads.62.raw_reads.91.N3.S LAsort -v raw_reads.63.raw_reads.91.C0 raw_reads.63.raw_reads.91.N0 raw_reads.63.raw_reads.91.C1 raw_reads.63.raw_reads.91.N1 raw_reads.63.raw_reads.91.C2 raw_reads.63.raw_reads.91.N2 raw_reads.63.raw_reads.91.C3 raw_reads.63.raw_reads.91.N3 && LAmerge -v L1.63.91 raw_reads.63.raw_reads.91.C0.S raw_reads.63.raw_reads.91.N0.S raw_reads.63.raw_reads.91.C1.S raw_reads.63.raw_reads.91.N1.S raw_reads.63.raw_reads.91.C2.S raw_reads.63.raw_reads.91.N2.S raw_reads.63.raw_reads.91.C3.S raw_reads.63.raw_reads.91.N3.S LAsort -v raw_reads.64.raw_reads.91.C0 raw_reads.64.raw_reads.91.N0 raw_reads.64.raw_reads.91.C1 raw_reads.64.raw_reads.91.N1 raw_reads.64.raw_reads.91.C2 raw_reads.64.raw_reads.91.N2 raw_reads.64.raw_reads.91.C3 raw_reads.64.raw_reads.91.N3 && LAmerge -v L1.64.91 raw_reads.64.raw_reads.91.C0.S raw_reads.64.raw_reads.91.N0.S raw_reads.64.raw_reads.91.C1.S raw_reads.64.raw_reads.91.N1.S raw_reads.64.raw_reads.91.C2.S raw_reads.64.raw_reads.91.N2.S raw_reads.64.raw_reads.91.C3.S raw_reads.64.raw_reads.91.N3.S LAsort -v raw_reads.65.raw_reads.91.C0 raw_reads.65.raw_reads.91.N0 raw_reads.65.raw_reads.91.C1 raw_reads.65.raw_reads.91.N1 raw_reads.65.raw_reads.91.C2 raw_reads.65.raw_reads.91.N2 raw_reads.65.raw_reads.91.C3 raw_reads.65.raw_reads.91.N3 && LAmerge -v L1.65.91 raw_reads.65.raw_reads.91.C0.S raw_reads.65.raw_reads.91.N0.S raw_reads.65.raw_reads.91.C1.S raw_reads.65.raw_reads.91.N1.S raw_reads.65.raw_reads.91.C2.S raw_reads.65.raw_reads.91.N2.S raw_reads.65.raw_reads.91.C3.S raw_reads.65.raw_reads.91.N3.S LAsort -v raw_reads.66.raw_reads.91.C0 raw_reads.66.raw_reads.91.N0 raw_reads.66.raw_reads.91.C1 raw_reads.66.raw_reads.91.N1 raw_reads.66.raw_reads.91.C2 raw_reads.66.raw_reads.91.N2 raw_reads.66.raw_reads.91.C3 raw_reads.66.raw_reads.91.N3 && LAmerge -v L1.66.91 raw_reads.66.raw_reads.91.C0.S raw_reads.66.raw_reads.91.N0.S raw_reads.66.raw_reads.91.C1.S raw_reads.66.raw_reads.91.N1.S raw_reads.66.raw_reads.91.C2.S raw_reads.66.raw_reads.91.N2.S raw_reads.66.raw_reads.91.C3.S raw_reads.66.raw_reads.91.N3.S LAsort -v raw_reads.67.raw_reads.91.C0 raw_reads.67.raw_reads.91.N0 raw_reads.67.raw_reads.91.C1 raw_reads.67.raw_reads.91.N1 raw_reads.67.raw_reads.91.C2 raw_reads.67.raw_reads.91.N2 raw_reads.67.raw_reads.91.C3 raw_reads.67.raw_reads.91.N3 && LAmerge -v L1.67.91 raw_reads.67.raw_reads.91.C0.S raw_reads.67.raw_reads.91.N0.S raw_reads.67.raw_reads.91.C1.S raw_reads.67.raw_reads.91.N1.S raw_reads.67.raw_reads.91.C2.S raw_reads.67.raw_reads.91.N2.S raw_reads.67.raw_reads.91.C3.S raw_reads.67.raw_reads.91.N3.S LAsort -v raw_reads.68.raw_reads.91.C0 raw_reads.68.raw_reads.91.N0 raw_reads.68.raw_reads.91.C1 raw_reads.68.raw_reads.91.N1 raw_reads.68.raw_reads.91.C2 raw_reads.68.raw_reads.91.N2 raw_reads.68.raw_reads.91.C3 raw_reads.68.raw_reads.91.N3 && LAmerge -v L1.68.91 raw_reads.68.raw_reads.91.C0.S raw_reads.68.raw_reads.91.N0.S raw_reads.68.raw_reads.91.C1.S raw_reads.68.raw_reads.91.N1.S raw_reads.68.raw_reads.91.C2.S raw_reads.68.raw_reads.91.N2.S raw_reads.68.raw_reads.91.C3.S raw_reads.68.raw_reads.91.N3.S LAsort -v raw_reads.91.raw_reads.46.C0 raw_reads.91.raw_reads.46.N0 raw_reads.91.raw_reads.46.C1 raw_reads.91.raw_reads.46.N1 raw_reads.91.raw_reads.46.C2 raw_reads.91.raw_reads.46.N2 raw_reads.91.raw_reads.46.C3 raw_reads.91.raw_reads.46.N3 && LAmerge -v L1.91.46 raw_reads.91.raw_reads.46.C0.S raw_reads.91.raw_reads.46.N0.S raw_reads.91.raw_reads.46.C1.S raw_reads.91.raw_reads.46.N1.S raw_reads.91.raw_reads.46.C2.S raw_reads.91.raw_reads.46.N2.S raw_reads.91.raw_reads.46.C3.S raw_reads.91.raw_reads.46.N3.S LAsort -v raw_reads.91.raw_reads.47.C0 raw_reads.91.raw_reads.47.N0 raw_reads.91.raw_reads.47.C1 raw_reads.91.raw_reads.47.N1 raw_reads.91.raw_reads.47.C2 raw_reads.91.raw_reads.47.N2 raw_reads.91.raw_reads.47.C3 raw_reads.91.raw_reads.47.N3 && LAmerge -v L1.91.47 raw_reads.91.raw_reads.47.C0.S raw_reads.91.raw_reads.47.N0.S raw_reads.91.raw_reads.47.C1.S raw_reads.91.raw_reads.47.N1.S raw_reads.91.raw_reads.47.C2.S raw_reads.91.raw_reads.47.N2.S raw_reads.91.raw_reads.47.C3.S raw_reads.91.raw_reads.47.N3.S LAsort -v raw_reads.91.raw_reads.48.C0 raw_reads.91.raw_reads.48.N0 raw_reads.91.raw_reads.48.C1 raw_reads.91.raw_reads.48.N1 raw_reads.91.raw_reads.48.C2 raw_reads.91.raw_reads.48.N2 raw_reads.91.raw_reads.48.C3 raw_reads.91.raw_reads.48.N3 && LAmerge -v L1.91.48 raw_reads.91.raw_reads.48.C0.S raw_reads.91.raw_reads.48.N0.S raw_reads.91.raw_reads.48.C1.S raw_reads.91.raw_reads.48.N1.S raw_reads.91.raw_reads.48.C2.S raw_reads.91.raw_reads.48.N2.S raw_reads.91.raw_reads.48.C3.S raw_reads.91.raw_reads.48.N3.S LAsort -v raw_reads.91.raw_reads.49.C0 raw_reads.91.raw_reads.49.N0 raw_reads.91.raw_reads.49.C1 raw_reads.91.raw_reads.49.N1 raw_reads.91.raw_reads.49.C2 raw_reads.91.raw_reads.49.N2 raw_reads.91.raw_reads.49.C3 raw_reads.91.raw_reads.49.N3 && LAmerge -v L1.91.49 raw_reads.91.raw_reads.49.C0.S raw_reads.91.raw_reads.49.N0.S raw_reads.91.raw_reads.49.C1.S raw_reads.91.raw_reads.49.N1.S raw_reads.91.raw_reads.49.C2.S raw_reads.91.raw_reads.49.N2.S raw_reads.91.raw_reads.49.C3.S raw_reads.91.raw_reads.49.N3.S LAsort -v raw_reads.91.raw_reads.50.C0 raw_reads.91.raw_reads.50.N0 raw_reads.91.raw_reads.50.C1 raw_reads.91.raw_reads.50.N1 raw_reads.91.raw_reads.50.C2 raw_reads.91.raw_reads.50.N2 raw_reads.91.raw_reads.50.C3 raw_reads.91.raw_reads.50.N3 && LAmerge -v L1.91.50 raw_reads.91.raw_reads.50.C0.S raw_reads.91.raw_reads.50.N0.S raw_reads.91.raw_reads.50.C1.S raw_reads.91.raw_reads.50.N1.S raw_reads.91.raw_reads.50.C2.S raw_reads.91.raw_reads.50.N2.S raw_reads.91.raw_reads.50.C3.S raw_reads.91.raw_reads.50.N3.S LAsort -v raw_reads.91.raw_reads.51.C0 raw_reads.91.raw_reads.51.N0 raw_reads.91.raw_reads.51.C1 raw_reads.91.raw_reads.51.N1 raw_reads.91.raw_reads.51.C2 raw_reads.91.raw_reads.51.N2 raw_reads.91.raw_reads.51.C3 raw_reads.91.raw_reads.51.N3 && LAmerge -v L1.91.51 raw_reads.91.raw_reads.51.C0.S raw_reads.91.raw_reads.51.N0.S raw_reads.91.raw_reads.51.C1.S raw_reads.91.raw_reads.51.N1.S raw_reads.91.raw_reads.51.C2.S raw_reads.91.raw_reads.51.N2.S raw_reads.91.raw_reads.51.C3.S raw_reads.91.raw_reads.51.N3.S LAsort -v raw_reads.91.raw_reads.52.C0 raw_reads.91.raw_reads.52.N0 raw_reads.91.raw_reads.52.C1 raw_reads.91.raw_reads.52.N1 raw_reads.91.raw_reads.52.C2 raw_reads.91.raw_reads.52.N2 raw_reads.91.raw_reads.52.C3 raw_reads.91.raw_reads.52.N3 && LAmerge -v L1.91.52 raw_reads.91.raw_reads.52.C0.S raw_reads.91.raw_reads.52.N0.S raw_reads.91.raw_reads.52.C1.S raw_reads.91.raw_reads.52.N1.S raw_reads.91.raw_reads.52.C2.S raw_reads.91.raw_reads.52.N2.S raw_reads.91.raw_reads.52.C3.S raw_reads.91.raw_reads.52.N3.S LAsort -v raw_reads.91.raw_reads.53.C0 raw_reads.91.raw_reads.53.N0 raw_reads.91.raw_reads.53.C1 raw_reads.91.raw_reads.53.N1 raw_reads.91.raw_reads.53.C2 raw_reads.91.raw_reads.53.N2 raw_reads.91.raw_reads.53.C3 raw_reads.91.raw_reads.53.N3 && LAmerge -v L1.91.53 raw_reads.91.raw_reads.53.C0.S raw_reads.91.raw_reads.53.N0.S raw_reads.91.raw_reads.53.C1.S raw_reads.91.raw_reads.53.N1.S raw_reads.91.raw_reads.53.C2.S raw_reads.91.raw_reads.53.N2.S raw_reads.91.raw_reads.53.C3.S raw_reads.91.raw_reads.53.N3.S LAsort -v raw_reads.91.raw_reads.54.C0 raw_reads.91.raw_reads.54.N0 raw_reads.91.raw_reads.54.C1 raw_reads.91.raw_reads.54.N1 raw_reads.91.raw_reads.54.C2 raw_reads.91.raw_reads.54.N2 raw_reads.91.raw_reads.54.C3 raw_reads.91.raw_reads.54.N3 && LAmerge -v L1.91.54 raw_reads.91.raw_reads.54.C0.S raw_reads.91.raw_reads.54.N0.S raw_reads.91.raw_reads.54.C1.S raw_reads.91.raw_reads.54.N1.S raw_reads.91.raw_reads.54.C2.S raw_reads.91.raw_reads.54.N2.S raw_reads.91.raw_reads.54.C3.S raw_reads.91.raw_reads.54.N3.S LAsort -v raw_reads.91.raw_reads.55.C0 raw_reads.91.raw_reads.55.N0 raw_reads.91.raw_reads.55.C1 raw_reads.91.raw_reads.55.N1 raw_reads.91.raw_reads.55.C2 raw_reads.91.raw_reads.55.N2 raw_reads.91.raw_reads.55.C3 raw_reads.91.raw_reads.55.N3 && LAmerge -v L1.91.55 raw_reads.91.raw_reads.55.C0.S raw_reads.91.raw_reads.55.N0.S raw_reads.91.raw_reads.55.C1.S raw_reads.91.raw_reads.55.N1.S raw_reads.91.raw_reads.55.C2.S raw_reads.91.raw_reads.55.N2.S raw_reads.91.raw_reads.55.C3.S raw_reads.91.raw_reads.55.N3.S LAsort -v raw_reads.91.raw_reads.56.C0 raw_reads.91.raw_reads.56.N0 raw_reads.91.raw_reads.56.C1 raw_reads.91.raw_reads.56.N1 raw_reads.91.raw_reads.56.C2 raw_reads.91.raw_reads.56.N2 raw_reads.91.raw_reads.56.C3 raw_reads.91.raw_reads.56.N3 && LAmerge -v L1.91.56 raw_reads.91.raw_reads.56.C0.S raw_reads.91.raw_reads.56.N0.S raw_reads.91.raw_reads.56.C1.S raw_reads.91.raw_reads.56.N1.S raw_reads.91.raw_reads.56.C2.S raw_reads.91.raw_reads.56.N2.S raw_reads.91.raw_reads.56.C3.S raw_reads.91.raw_reads.56.N3.S LAsort -v raw_reads.91.raw_reads.57.C0 raw_reads.91.raw_reads.57.N0 raw_reads.91.raw_reads.57.C1 raw_reads.91.raw_reads.57.N1 raw_reads.91.raw_reads.57.C2 raw_reads.91.raw_reads.57.N2 raw_reads.91.raw_reads.57.C3 raw_reads.91.raw_reads.57.N3 && LAmerge -v L1.91.57 raw_reads.91.raw_reads.57.C0.S raw_reads.91.raw_reads.57.N0.S raw_reads.91.raw_reads.57.C1.S raw_reads.91.raw_reads.57.N1.S raw_reads.91.raw_reads.57.C2.S raw_reads.91.raw_reads.57.N2.S raw_reads.91.raw_reads.57.C3.S raw_reads.91.raw_reads.57.N3.S LAsort -v raw_reads.91.raw_reads.58.C0 raw_reads.91.raw_reads.58.N0 raw_reads.91.raw_reads.58.C1 raw_reads.91.raw_reads.58.N1 raw_reads.91.raw_reads.58.C2 raw_reads.91.raw_reads.58.N2 raw_reads.91.raw_reads.58.C3 raw_reads.91.raw_reads.58.N3 && LAmerge -v L1.91.58 raw_reads.91.raw_reads.58.C0.S raw_reads.91.raw_reads.58.N0.S raw_reads.91.raw_reads.58.C1.S raw_reads.91.raw_reads.58.N1.S raw_reads.91.raw_reads.58.C2.S raw_reads.91.raw_reads.58.N2.S raw_reads.91.raw_reads.58.C3.S raw_reads.91.raw_reads.58.N3.S LAsort -v raw_reads.91.raw_reads.59.C0 raw_reads.91.raw_reads.59.N0 raw_reads.91.raw_reads.59.C1 raw_reads.91.raw_reads.59.N1 raw_reads.91.raw_reads.59.C2 raw_reads.91.raw_reads.59.N2 raw_reads.91.raw_reads.59.C3 raw_reads.91.raw_reads.59.N3 && LAmerge -v L1.91.59 raw_reads.91.raw_reads.59.C0.S raw_reads.91.raw_reads.59.N0.S raw_reads.91.raw_reads.59.C1.S raw_reads.91.raw_reads.59.N1.S raw_reads.91.raw_reads.59.C2.S raw_reads.91.raw_reads.59.N2.S raw_reads.91.raw_reads.59.C3.S raw_reads.91.raw_reads.59.N3.S LAsort -v raw_reads.91.raw_reads.60.C0 raw_reads.91.raw_reads.60.N0 raw_reads.91.raw_reads.60.C1 raw_reads.91.raw_reads.60.N1 raw_reads.91.raw_reads.60.C2 raw_reads.91.raw_reads.60.N2 raw_reads.91.raw_reads.60.C3 raw_reads.91.raw_reads.60.N3 && LAmerge -v L1.91.60 raw_reads.91.raw_reads.60.C0.S raw_reads.91.raw_reads.60.N0.S raw_reads.91.raw_reads.60.C1.S raw_reads.91.raw_reads.60.N1.S raw_reads.91.raw_reads.60.C2.S raw_reads.91.raw_reads.60.N2.S raw_reads.91.raw_reads.60.C3.S raw_reads.91.raw_reads.60.N3.S LAsort -v raw_reads.91.raw_reads.61.C0 raw_reads.91.raw_reads.61.N0 raw_reads.91.raw_reads.61.C1 raw_reads.91.raw_reads.61.N1 raw_reads.91.raw_reads.61.C2 raw_reads.91.raw_reads.61.N2 raw_reads.91.raw_reads.61.C3 raw_reads.91.raw_reads.61.N3 && LAmerge -v L1.91.61 raw_reads.91.raw_reads.61.C0.S raw_reads.91.raw_reads.61.N0.S raw_reads.91.raw_reads.61.C1.S raw_reads.91.raw_reads.61.N1.S raw_reads.91.raw_reads.61.C2.S raw_reads.91.raw_reads.61.N2.S raw_reads.91.raw_reads.61.C3.S raw_reads.91.raw_reads.61.N3.S LAsort -v raw_reads.91.raw_reads.62.C0 raw_reads.91.raw_reads.62.N0 raw_reads.91.raw_reads.62.C1 raw_reads.91.raw_reads.62.N1 raw_reads.91.raw_reads.62.C2 raw_reads.91.raw_reads.62.N2 raw_reads.91.raw_reads.62.C3 raw_reads.91.raw_reads.62.N3 && LAmerge -v L1.91.62 raw_reads.91.raw_reads.62.C0.S raw_reads.91.raw_reads.62.N0.S raw_reads.91.raw_reads.62.C1.S raw_reads.91.raw_reads.62.N1.S raw_reads.91.raw_reads.62.C2.S raw_reads.91.raw_reads.62.N2.S raw_reads.91.raw_reads.62.C3.S raw_reads.91.raw_reads.62.N3.S LAsort -v raw_reads.91.raw_reads.63.C0 raw_reads.91.raw_reads.63.N0 raw_reads.91.raw_reads.63.C1 raw_reads.91.raw_reads.63.N1 raw_reads.91.raw_reads.63.C2 raw_reads.91.raw_reads.63.N2 raw_reads.91.raw_reads.63.C3 raw_reads.91.raw_reads.63.N3 && LAmerge -v L1.91.63 raw_reads.91.raw_reads.63.C0.S raw_reads.91.raw_reads.63.N0.S raw_reads.91.raw_reads.63.C1.S raw_reads.91.raw_reads.63.N1.S raw_reads.91.raw_reads.63.C2.S raw_reads.91.raw_reads.63.N2.S raw_reads.91.raw_reads.63.C3.S raw_reads.91.raw_reads.63.N3.S LAsort -v raw_reads.91.raw_reads.64.C0 raw_reads.91.raw_reads.64.N0 raw_reads.91.raw_reads.64.C1 raw_reads.91.raw_reads.64.N1 raw_reads.91.raw_reads.64.C2 raw_reads.91.raw_reads.64.N2 raw_reads.91.raw_reads.64.C3 raw_reads.91.raw_reads.64.N3 && LAmerge -v L1.91.64 raw_reads.91.raw_reads.64.C0.S raw_reads.91.raw_reads.64.N0.S raw_reads.91.raw_reads.64.C1.S raw_reads.91.raw_reads.64.N1.S raw_reads.91.raw_reads.64.C2.S raw_reads.91.raw_reads.64.N2.S raw_reads.91.raw_reads.64.C3.S raw_reads.91.raw_reads.64.N3.S LAsort -v raw_reads.91.raw_reads.65.C0 raw_reads.91.raw_reads.65.N0 raw_reads.91.raw_reads.65.C1 raw_reads.91.raw_reads.65.N1 raw_reads.91.raw_reads.65.C2 raw_reads.91.raw_reads.65.N2 raw_reads.91.raw_reads.65.C3 raw_reads.91.raw_reads.65.N3 && LAmerge -v L1.91.65 raw_reads.91.raw_reads.65.C0.S raw_reads.91.raw_reads.65.N0.S raw_reads.91.raw_reads.65.C1.S raw_reads.91.raw_reads.65.N1.S raw_reads.91.raw_reads.65.C2.S raw_reads.91.raw_reads.65.N2.S raw_reads.91.raw_reads.65.C3.S raw_reads.91.raw_reads.65.N3.S LAsort -v raw_reads.91.raw_reads.66.C0 raw_reads.91.raw_reads.66.N0 raw_reads.91.raw_reads.66.C1 raw_reads.91.raw_reads.66.N1 raw_reads.91.raw_reads.66.C2 raw_reads.91.raw_reads.66.N2 raw_reads.91.raw_reads.66.C3 raw_reads.91.raw_reads.66.N3 && LAmerge -v L1.91.66 raw_reads.91.raw_reads.66.C0.S raw_reads.91.raw_reads.66.N0.S raw_reads.91.raw_reads.66.C1.S raw_reads.91.raw_reads.66.N1.S raw_reads.91.raw_reads.66.C2.S raw_reads.91.raw_reads.66.N2.S raw_reads.91.raw_reads.66.C3.S raw_reads.91.raw_reads.66.N3.S LAsort -v raw_reads.91.raw_reads.67.C0 raw_reads.91.raw_reads.67.N0 raw_reads.91.raw_reads.67.C1 raw_reads.91.raw_reads.67.N1 raw_reads.91.raw_reads.67.C2 raw_reads.91.raw_reads.67.N2 raw_reads.91.raw_reads.67.C3 raw_reads.91.raw_reads.67.N3 && LAmerge -v L1.91.67 raw_reads.91.raw_reads.67.C0.S raw_reads.91.raw_reads.67.N0.S raw_reads.91.raw_reads.67.C1.S raw_reads.91.raw_reads.67.N1.S raw_reads.91.raw_reads.67.C2.S raw_reads.91.raw_reads.67.N2.S raw_reads.91.raw_reads.67.C3.S raw_reads.91.raw_reads.67.N3.S LAsort -v raw_reads.91.raw_reads.68.C0 raw_reads.91.raw_reads.68.N0 raw_reads.91.raw_reads.68.C1 raw_reads.91.raw_reads.68.N1 raw_reads.91.raw_reads.68.C2 raw_reads.91.raw_reads.68.N2 raw_reads.91.raw_reads.68.C3 raw_reads.91.raw_reads.68.N3 && LAmerge -v L1.91.68 raw_reads.91.raw_reads.68.C0.S raw_reads.91.raw_reads.68.N0.S raw_reads.91.raw_reads.68.C1.S raw_reads.91.raw_reads.68.N1.S raw_reads.91.raw_reads.68.C2.S raw_reads.91.raw_reads.68.N2.S raw_reads.91.raw_reads.68.C3.S raw_reads.91.raw_reads.68.N3.S LAcheck -vS raw_reads L1.46.91 LAcheck -vS raw_reads L1.47.91 LAcheck -vS raw_reads L1.48.91 LAcheck -vS raw_reads L1.49.91 LAcheck -vS raw_reads L1.50.91 LAcheck -vS raw_reads L1.51.91 LAcheck -vS raw_reads L1.52.91 LAcheck -vS raw_reads L1.53.91 LAcheck -vS raw_reads L1.54.91 LAcheck -vS raw_reads L1.55.91 LAcheck -vS raw_reads L1.56.91 LAcheck -vS raw_reads L1.57.91 LAcheck -vS raw_reads L1.58.91 LAcheck -vS raw_reads L1.59.91 LAcheck -vS raw_reads L1.60.91 LAcheck -vS raw_reads L1.61.91 LAcheck -vS raw_reads L1.62.91 LAcheck -vS raw_reads L1.63.91 LAcheck -vS raw_reads L1.64.91 LAcheck -vS raw_reads L1.65.91 LAcheck -vS raw_reads L1.66.91 LAcheck -vS raw_reads L1.67.91 LAcheck -vS raw_reads L1.68.91 LAcheck -vS raw_reads L1.91.46 LAcheck -vS raw_reads L1.91.47 LAcheck -vS raw_reads L1.91.48 LAcheck -vS raw_reads L1.91.49 LAcheck -vS raw_reads L1.91.50 LAcheck -vS raw_reads L1.91.51 LAcheck -vS raw_reads L1.91.52 LAcheck -vS raw_reads L1.91.53 LAcheck -vS raw_reads L1.91.54 LAcheck -vS raw_reads L1.91.55 LAcheck -vS raw_reads L1.91.56 LAcheck -vS raw_reads L1.91.57 LAcheck -vS raw_reads L1.91.58 LAcheck -vS raw_reads L1.91.59 LAcheck -vS raw_reads L1.91.60 LAcheck -vS raw_reads L1.91.61 LAcheck -vS raw_reads L1.91.62 LAcheck -vS raw_reads L1.91.63 LAcheck -vS raw_reads L1.91.64 LAcheck -vS raw_reads L1.91.65 LAcheck -vS raw_reads L1.91.66 LAcheck -vS raw_reads L1.91.67 LAcheck -vS raw_reads L1.91.68 daligner -v -k18 -h70 -t14 -H7000 -e0.75 raw_reads.27 raw_reads.14 raw_reads.15 raw_reads.16 raw_reads.17 raw_reads.18 raw_reads.19 raw_reads.20 raw_reads.21 raw_reads.22 raw_reads.23 raw_reads.24 raw_reads.25 raw_reads.26 raw_reads.27 LAcheck -v raw_reads *.las LAsort -v raw_reads.14.raw_reads.27.C0 raw_reads.14.raw_reads.27.N0 raw_reads.14.raw_reads.27.C1 raw_reads.14.raw_reads.27.N1 raw_reads.14.raw_reads.27.C2 raw_reads.14.raw_reads.27.N2 raw_reads.14.raw_reads.27.C3 raw_reads.14.raw_reads.27.N3 && LAmerge -v L1.14.27 raw_reads.14.raw_reads.27.C0.S raw_reads.14.raw_reads.27.N0.S raw_reads.14.raw_reads.27.C1.S raw_reads.14.raw_reads.27.N1.S raw_reads.14.raw_reads.27.C2.S raw_reads.14.raw_reads.27.N2.S raw_reads.14.raw_reads.27.C3.S raw_reads.14.raw_reads.27.N3.S LAsort -v raw_reads.15.raw_reads.27.C0 raw_reads.15.raw_reads.27.N0 raw_reads.15.raw_reads.27.C1 raw_reads.15.raw_reads.27.N1 raw_reads.15.raw_reads.27.C2 raw_reads.15.raw_reads.27.N2 raw_reads.15.raw_reads.27.C3 raw_reads.15.raw_reads.27.N3 && LAmerge -v L1.15.27 raw_reads.15.raw_reads.27.C0.S raw_reads.15.raw_reads.27.N0.S raw_reads.15.raw_reads.27.C1.S raw_reads.15.raw_reads.27.N1.S raw_reads.15.raw_reads.27.C2.S raw_reads.15.raw_reads.27.N2.S raw_reads.15.raw_reads.27.C3.S raw_reads.15.raw_reads.27.N3.S LAsort -v raw_reads.16.raw_reads.27.C0 raw_reads.16.raw_reads.27.N0 raw_reads.16.raw_reads.27.C1 raw_reads.16.raw_reads.27.N1 raw_reads.16.raw_reads.27.C2 raw_reads.16.raw_reads.27.N2 raw_reads.16.raw_reads.27.C3 raw_reads.16.raw_reads.27.N3 && LAmerge -v L1.16.27 raw_reads.16.raw_reads.27.C0.S raw_reads.16.raw_reads.27.N0.S raw_reads.16.raw_reads.27.C1.S raw_reads.16.raw_reads.27.N1.S raw_reads.16.raw_reads.27.C2.S raw_reads.16.raw_reads.27.N2.S raw_reads.16.raw_reads.27.C3.S raw_reads.16.raw_reads.27.N3.S LAsort -v raw_reads.17.raw_reads.27.C0 raw_reads.17.raw_reads.27.N0 raw_reads.17.raw_reads.27.C1 raw_reads.17.raw_reads.27.N1 raw_reads.17.raw_reads.27.C2 raw_reads.17.raw_reads.27.N2 raw_reads.17.raw_reads.27.C3 raw_reads.17.raw_reads.27.N3 && LAmerge -v L1.17.27 raw_reads.17.raw_reads.27.C0.S raw_reads.17.raw_reads.27.N0.S raw_reads.17.raw_reads.27.C1.S raw_reads.17.raw_reads.27.N1.S raw_reads.17.raw_reads.27.C2.S raw_reads.17.raw_reads.27.N2.S raw_reads.17.raw_reads.27.C3.S raw_reads.17.raw_reads.27.N3.S LAsort -v raw_reads.18.raw_reads.27.C0 raw_reads.18.raw_reads.27.N0 raw_reads.18.raw_reads.27.C1 raw_reads.18.raw_reads.27.N1 raw_reads.18.raw_reads.27.C2 raw_reads.18.raw_reads.27.N2 raw_reads.18.raw_reads.27.C3 raw_reads.18.raw_reads.27.N3 && LAmerge -v L1.18.27 raw_reads.18.raw_reads.27.C0.S raw_reads.18.raw_reads.27.N0.S raw_reads.18.raw_reads.27.C1.S raw_reads.18.raw_reads.27.N1.S raw_reads.18.raw_reads.27.C2.S raw_reads.18.raw_reads.27.N2.S raw_reads.18.raw_reads.27.C3.S raw_reads.18.raw_reads.27.N3.S LAsort -v raw_reads.19.raw_reads.27.C0 raw_reads.19.raw_reads.27.N0 raw_reads.19.raw_reads.27.C1 raw_reads.19.raw_reads.27.N1 raw_reads.19.raw_reads.27.C2 raw_reads.19.raw_reads.27.N2 raw_reads.19.raw_reads.27.C3 raw_reads.19.raw_reads.27.N3 && LAmerge -v L1.19.27 raw_reads.19.raw_reads.27.C0.S raw_reads.19.raw_reads.27.N0.S raw_reads.19.raw_reads.27.C1.S raw_reads.19.raw_reads.27.N1.S raw_reads.19.raw_reads.27.C2.S raw_reads.19.raw_reads.27.N2.S raw_reads.19.raw_reads.27.C3.S raw_reads.19.raw_reads.27.N3.S LAsort -v raw_reads.20.raw_reads.27.C0 raw_reads.20.raw_reads.27.N0 raw_reads.20.raw_reads.27.C1 raw_reads.20.raw_reads.27.N1 raw_reads.20.raw_reads.27.C2 raw_reads.20.raw_reads.27.N2 raw_reads.20.raw_reads.27.C3 raw_reads.20.raw_reads.27.N3 && LAmerge -v L1.20.27 raw_reads.20.raw_reads.27.C0.S raw_reads.20.raw_reads.27.N0.S raw_reads.20.raw_reads.27.C1.S raw_reads.20.raw_reads.27.N1.S raw_reads.20.raw_reads.27.C2.S raw_reads.20.raw_reads.27.N2.S raw_reads.20.raw_reads.27.C3.S raw_reads.20.raw_reads.27.N3.S LAsort -v raw_reads.21.raw_reads.27.C0 raw_reads.21.raw_reads.27.N0 raw_reads.21.raw_reads.27.C1 raw_reads.21.raw_reads.27.N1 raw_reads.21.raw_reads.27.C2 raw_reads.21.raw_reads.27.N2 raw_reads.21.raw_reads.27.C3 raw_reads.21.raw_reads.27.N3 && LAmerge -v L1.21.27 raw_reads.21.raw_reads.27.C0.S raw_reads.21.raw_reads.27.N0.S raw_reads.21.raw_reads.27.C1.S raw_reads.21.raw_reads.27.N1.S raw_reads.21.raw_reads.27.C2.S raw_reads.21.raw_reads.27.N2.S raw_reads.21.raw_reads.27.C3.S raw_reads.21.raw_reads.27.N3.S LAsort -v raw_reads.22.raw_reads.27.C0 raw_reads.22.raw_reads.27.N0 raw_reads.22.raw_reads.27.C1 raw_reads.22.raw_reads.27.N1 raw_reads.22.raw_reads.27.C2 raw_reads.22.raw_reads.27.N2 raw_reads.22.raw_reads.27.C3 raw_reads.22.raw_reads.27.N3 && LAmerge -v L1.22.27 raw_reads.22.raw_reads.27.C0.S raw_reads.22.raw_reads.27.N0.S raw_reads.22.raw_reads.27.C1.S raw_reads.22.raw_reads.27.N1.S raw_reads.22.raw_reads.27.C2.S raw_reads.22.raw_reads.27.N2.S raw_reads.22.raw_reads.27.C3.S raw_reads.22.raw_reads.27.N3.S LAsort -v raw_reads.23.raw_reads.27.C0 raw_reads.23.raw_reads.27.N0 raw_reads.23.raw_reads.27.C1 raw_reads.23.raw_reads.27.N1 raw_reads.23.raw_reads.27.C2 raw_reads.23.raw_reads.27.N2 raw_reads.23.raw_reads.27.C3 raw_reads.23.raw_reads.27.N3 && LAmerge -v L1.23.27 raw_reads.23.raw_reads.27.C0.S raw_reads.23.raw_reads.27.N0.S raw_reads.23.raw_reads.27.C1.S raw_reads.23.raw_reads.27.N1.S raw_reads.23.raw_reads.27.C2.S raw_reads.23.raw_reads.27.N2.S raw_reads.23.raw_reads.27.C3.S raw_reads.23.raw_reads.27.N3.S LAsort -v raw_reads.24.raw_reads.27.C0 raw_reads.24.raw_reads.27.N0 raw_reads.24.raw_reads.27.C1 raw_reads.24.raw_reads.27.N1 raw_reads.24.raw_reads.27.C2 raw_reads.24.raw_reads.27.N2 raw_reads.24.raw_reads.27.C3 raw_reads.24.raw_reads.27.N3 && LAmerge -v L1.24.27 raw_reads.24.raw_reads.27.C0.S raw_reads.24.raw_reads.27.N0.S raw_reads.24.raw_reads.27.C1.S raw_reads.24.raw_reads.27.N1.S raw_reads.24.raw_reads.27.C2.S raw_reads.24.raw_reads.27.N2.S raw_reads.24.raw_reads.27.C3.S raw_reads.24.raw_reads.27.N3.S LAsort -v raw_reads.25.raw_reads.27.C0 raw_reads.25.raw_reads.27.N0 raw_reads.25.raw_reads.27.C1 raw_reads.25.raw_reads.27.N1 raw_reads.25.raw_reads.27.C2 raw_reads.25.raw_reads.27.N2 raw_reads.25.raw_reads.27.C3 raw_reads.25.raw_reads.27.N3 && LAmerge -v L1.25.27 raw_reads.25.raw_reads.27.C0.S raw_reads.25.raw_reads.27.N0.S raw_reads.25.raw_reads.27.C1.S raw_reads.25.raw_reads.27.N1.S raw_reads.25.raw_reads.27.C2.S raw_reads.25.raw_reads.27.N2.S raw_reads.25.raw_reads.27.C3.S raw_reads.25.raw_reads.27.N3.S LAsort -v raw_reads.26.raw_reads.27.C0 raw_reads.26.raw_reads.27.N0 raw_reads.26.raw_reads.27.C1 raw_reads.26.raw_reads.27.N1 raw_reads.26.raw_reads.27.C2 raw_reads.26.raw_reads.27.N2 raw_reads.26.raw_reads.27.C3 raw_reads.26.raw_reads.27.N3 && LAmerge -v L1.26.27 raw_reads.26.raw_reads.27.C0.S raw_reads.26.raw_reads.27.N0.S raw_reads.26.raw_reads.27.C1.S raw_reads.26.raw_reads.27.N1.S raw_reads.26.raw_reads.27.C2.S raw_reads.26.raw_reads.27.N2.S raw_reads.26.raw_reads.27.C3.S raw_reads.26.raw_reads.27.N3.S LAsort -v raw_reads.27.raw_reads.14.C0 raw_reads.27.raw_reads.14.N0 raw_reads.27.raw_reads.14.C1 raw_reads.27.raw_reads.14.N1 raw_reads.27.raw_reads.14.C2 raw_reads.27.raw_reads.14.N2 raw_reads.27.raw_reads.14.C3 raw_reads.27.raw_reads.14.N3 && LAmerge -v L1.27.14 raw_reads.27.raw_reads.14.C0.S raw_reads.27.raw_reads.14.N0.S raw_reads.27.raw_reads.14.C1.S raw_reads.27.raw_reads.14.N1.S raw_reads.27.raw_reads.14.C2.S raw_reads.27.raw_reads.14.N2.S raw_reads.27.raw_reads.14.C3.S raw_reads.27.raw_reads.14.N3.S LAsort -v raw_reads.27.raw_reads.15.C0 raw_reads.27.raw_reads.15.N0 raw_reads.27.raw_reads.15.C1 raw_reads.27.raw_reads.15.N1 raw_reads.27.raw_reads.15.C2 raw_reads.27.raw_reads.15.N2 raw_reads.27.raw_reads.15.C3 raw_reads.27.raw_reads.15.N3 && LAmerge -v L1.27.15 raw_reads.27.raw_reads.15.C0.S raw_reads.27.raw_reads.15.N0.S raw_reads.27.raw_reads.15.C1.S raw_reads.27.raw_reads.15.N1.S raw_reads.27.raw_reads.15.C2.S raw_reads.27.raw_reads.15.N2.S raw_reads.27.raw_reads.15.C3.S raw_reads.27.raw_reads.15.N3.S LAsort -v raw_reads.27.raw_reads.16.C0 raw_reads.27.raw_reads.16.N0 raw_reads.27.raw_reads.16.C1 raw_reads.27.raw_reads.16.N1 raw_reads.27.raw_reads.16.C2 raw_reads.27.raw_reads.16.N2 raw_reads.27.raw_reads.16.C3 raw_reads.27.raw_reads.16.N3 && LAmerge -v L1.27.16 raw_reads.27.raw_reads.16.C0.S raw_reads.27.raw_reads.16.N0.S raw_reads.27.raw_reads.16.C1.S raw_reads.27.raw_reads.16.N1.S raw_reads.27.raw_reads.16.C2.S raw_reads.27.raw_reads.16.N2.S raw_reads.27.raw_reads.16.C3.S raw_reads.27.raw_reads.16.N3.S LAsort -v raw_reads.27.raw_reads.17.C0 raw_reads.27.raw_reads.17.N0 raw_reads.27.raw_reads.17.C1 raw_reads.27.raw_reads.17.N1 raw_reads.27.raw_reads.17.C2 raw_reads.27.raw_reads.17.N2 raw_reads.27.raw_reads.17.C3 raw_reads.27.raw_reads.17.N3 && LAmerge -v L1.27.17 raw_reads.27.raw_reads.17.C0.S raw_reads.27.raw_reads.17.N0.S raw_reads.27.raw_reads.17.C1.S raw_reads.27.raw_reads.17.N1.S raw_reads.27.raw_reads.17.C2.S raw_reads.27.raw_reads.17.N2.S raw_reads.27.raw_reads.17.C3.S raw_reads.27.raw_reads.17.N3.S LAsort -v raw_reads.27.raw_reads.18.C0 raw_reads.27.raw_reads.18.N0 raw_reads.27.raw_reads.18.C1 raw_reads.27.raw_reads.18.N1 raw_reads.27.raw_reads.18.C2 raw_reads.27.raw_reads.18.N2 raw_reads.27.raw_reads.18.C3 raw_reads.27.raw_reads.18.N3 && LAmerge -v L1.27.18 raw_reads.27.raw_reads.18.C0.S raw_reads.27.raw_reads.18.N0.S raw_reads.27.raw_reads.18.C1.S raw_reads.27.raw_reads.18.N1.S raw_reads.27.raw_reads.18.C2.S raw_reads.27.raw_reads.18.N2.S raw_reads.27.raw_reads.18.C3.S raw_reads.27.raw_reads.18.N3.S LAsort -v raw_reads.27.raw_reads.19.C0 raw_reads.27.raw_reads.19.N0 raw_reads.27.raw_reads.19.C1 raw_reads.27.raw_reads.19.N1 raw_reads.27.raw_reads.19.C2 raw_reads.27.raw_reads.19.N2 raw_reads.27.raw_reads.19.C3 raw_reads.27.raw_reads.19.N3 && LAmerge -v L1.27.19 raw_reads.27.raw_reads.19.C0.S raw_reads.27.raw_reads.19.N0.S raw_reads.27.raw_reads.19.C1.S raw_reads.27.raw_reads.19.N1.S raw_reads.27.raw_reads.19.C2.S raw_reads.27.raw_reads.19.N2.S raw_reads.27.raw_reads.19.C3.S raw_reads.27.raw_reads.19.N3.S LAsort -v raw_reads.27.raw_reads.20.C0 raw_reads.27.raw_reads.20.N0 raw_reads.27.raw_reads.20.C1 raw_reads.27.raw_reads.20.N1 raw_reads.27.raw_reads.20.C2 raw_reads.27.raw_reads.20.N2 raw_reads.27.raw_reads.20.C3 raw_reads.27.raw_reads.20.N3 && LAmerge -v L1.27.20 raw_reads.27.raw_reads.20.C0.S raw_reads.27.raw_reads.20.N0.S raw_reads.27.raw_reads.20.C1.S raw_reads.27.raw_reads.20.N1.S raw_reads.27.raw_reads.20.C2.S raw_reads.27.raw_reads.20.N2.S raw_reads.27.raw_reads.20.C3.S raw_reads.27.raw_reads.20.N3.S LAsort -v raw_reads.27.raw_reads.21.C0 raw_reads.27.raw_reads.21.N0 raw_reads.27.raw_reads.21.C1 raw_reads.27.raw_reads.21.N1 raw_reads.27.raw_reads.21.C2 raw_reads.27.raw_reads.21.N2 raw_reads.27.raw_reads.21.C3 raw_reads.27.raw_reads.21.N3 && LAmerge -v L1.27.21 raw_reads.27.raw_reads.21.C0.S raw_reads.27.raw_reads.21.N0.S raw_reads.27.raw_reads.21.C1.S raw_reads.27.raw_reads.21.N1.S raw_reads.27.raw_reads.21.C2.S raw_reads.27.raw_reads.21.N2.S raw_reads.27.raw_reads.21.C3.S raw_reads.27.raw_reads.21.N3.S LAsort -v raw_reads.27.raw_reads.22.C0 raw_reads.27.raw_reads.22.N0 raw_reads.27.raw_reads.22.C1 raw_reads.27.raw_reads.22.N1 raw_reads.27.raw_reads.22.C2 raw_reads.27.raw_reads.22.N2 raw_reads.27.raw_reads.22.C3 raw_reads.27.raw_reads.22.N3 && LAmerge -v L1.27.22 raw_reads.27.raw_reads.22.C0.S raw_reads.27.raw_reads.22.N0.S raw_reads.27.raw_reads.22.C1.S raw_reads.27.raw_reads.22.N1.S raw_reads.27.raw_reads.22.C2.S raw_reads.27.raw_reads.22.N2.S raw_reads.27.raw_reads.22.C3.S raw_reads.27.raw_reads.22.N3.S LAsort -v raw_reads.27.raw_reads.23.C0 raw_reads.27.raw_reads.23.N0 raw_reads.27.raw_reads.23.C1 raw_reads.27.raw_reads.23.N1 raw_reads.27.raw_reads.23.C2 raw_reads.27.raw_reads.23.N2 raw_reads.27.raw_reads.23.C3 raw_reads.27.raw_reads.23.N3 && LAmerge -v L1.27.23 raw_reads.27.raw_reads.23.C0.S raw_reads.27.raw_reads.23.N0.S raw_reads.27.raw_reads.23.C1.S raw_reads.27.raw_reads.23.N1.S raw_reads.27.raw_reads.23.C2.S raw_reads.27.raw_reads.23.N2.S raw_reads.27.raw_reads.23.C3.S raw_reads.27.raw_reads.23.N3.S LAsort -v raw_reads.27.raw_reads.24.C0 raw_reads.27.raw_reads.24.N0 raw_reads.27.raw_reads.24.C1 raw_reads.27.raw_reads.24.N1 raw_reads.27.raw_reads.24.C2 raw_reads.27.raw_reads.24.N2 raw_reads.27.raw_reads.24.C3 raw_reads.27.raw_reads.24.N3 && LAmerge -v L1.27.24 raw_reads.27.raw_reads.24.C0.S raw_reads.27.raw_reads.24.N0.S raw_reads.27.raw_reads.24.C1.S raw_reads.27.raw_reads.24.N1.S raw_reads.27.raw_reads.24.C2.S raw_reads.27.raw_reads.24.N2.S raw_reads.27.raw_reads.24.C3.S raw_reads.27.raw_reads.24.N3.S LAsort -v raw_reads.27.raw_reads.25.C0 raw_reads.27.raw_reads.25.N0 raw_reads.27.raw_reads.25.C1 raw_reads.27.raw_reads.25.N1 raw_reads.27.raw_reads.25.C2 raw_reads.27.raw_reads.25.N2 raw_reads.27.raw_reads.25.C3 raw_reads.27.raw_reads.25.N3 && LAmerge -v L1.27.25 raw_reads.27.raw_reads.25.C0.S raw_reads.27.raw_reads.25.N0.S raw_reads.27.raw_reads.25.C1.S raw_reads.27.raw_reads.25.N1.S raw_reads.27.raw_reads.25.C2.S raw_reads.27.raw_reads.25.N2.S raw_reads.27.raw_reads.25.C3.S raw_reads.27.raw_reads.25.N3.S LAsort -v raw_reads.27.raw_reads.26.C0 raw_reads.27.raw_reads.26.N0 raw_reads.27.raw_reads.26.C1 raw_reads.27.raw_reads.26.N1 raw_reads.27.raw_reads.26.C2 raw_reads.27.raw_reads.26.N2 raw_reads.27.raw_reads.26.C3 raw_reads.27.raw_reads.26.N3 && LAmerge -v L1.27.26 raw_reads.27.raw_reads.26.C0.S raw_reads.27.raw_reads.26.N0.S raw_reads.27.raw_reads.26.C1.S raw_reads.27.raw_reads.26.N1.S raw_reads.27.raw_reads.26.C2.S raw_reads.27.raw_reads.26.N2.S raw_reads.27.raw_reads.26.C3.S raw_reads.27.raw_reads.26.N3.S LAsort -v raw_reads.27.raw_reads.27.C0 raw_reads.27.raw_reads.27.N0 raw_reads.27.raw_reads.27.C1 raw_reads.27.raw_reads.27.N1 raw_reads.27.raw_reads.27.C2 raw_reads.27.raw_reads.27.N2 raw_reads.27.raw_reads.27.C3 raw_reads.27.raw_reads.27.N3 && LAmerge -v L1.27.27 raw_reads.27.raw_reads.27.C0.S raw_reads.27.raw_reads.27.N0.S raw_reads.27.raw_reads.27.C1.S raw_reads.27.raw_reads.27.N1.S raw_reads.27.raw_reads.27.C2.S raw_reads.27.raw_reads.27.N2.S raw_reads.27.raw_reads.27.C3.S raw_reads.27.raw_reads.27.N3.S LAcheck -vS raw_reads L1.14.27 LAcheck -vS raw_reads L1.15.27 LAcheck -vS raw_reads L1.16.27 LAcheck -vS raw_reads L1.17.27 LAcheck -vS raw_reads L1.18.27 LAcheck -vS raw_reads L1.19.27 LAcheck -vS raw_reads L1.20.27 LAcheck -vS raw_reads L1.21.27 LAcheck -vS raw_reads L1.22.27 LAcheck -vS raw_reads L1.23.27 LAcheck -vS raw_reads L1.24.27 LAcheck -vS raw_reads L1.25.27 LAcheck -vS raw_reads L1.26.27 LAcheck -vS raw_reads L1.27.14 LAcheck -vS raw_reads L1.27.15 LAcheck -vS raw_reads L1.27.16 LAcheck -vS raw_reads L1.27.17 LAcheck -vS raw_reads L1.27.18 LAcheck -vS raw_reads L1.27.19 LAcheck -vS raw_reads L1.27.20 LAcheck -vS raw_reads L1.27.21 LAcheck -vS raw_reads L1.27.22 LAcheck -vS raw_reads L1.27.23 LAcheck -vS raw_reads L1.27.24 LAcheck -vS raw_reads L1.27.25 LAcheck -vS raw_reads L1.27.26 LAcheck -vS raw_reads L1.27.27 daligner -v -k18 -h70 -t14 -H7000 -e0.75 raw_reads.73 raw_reads.19 raw_reads.20 raw_reads.21 raw_reads.22 raw_reads.23 raw_reads.24 raw_reads.25 raw_reads.26 raw_reads.27 raw_reads.28 raw_reads.29 raw_reads.30 raw_reads.31 raw_reads.32 raw_reads.33 raw_reads.34 raw_reads.35 raw_reads.36 LAcheck -v raw_reads *.las LAsort -v raw_reads.19.raw_reads.73.C0 raw_reads.19.raw_reads.73.N0 raw_reads.19.raw_reads.73.C1 raw_reads.19.raw_reads.73.N1 raw_reads.19.raw_reads.73.C2 raw_reads.19.raw_reads.73.N2 raw_reads.19.raw_reads.73.C3 raw_reads.19.raw_reads.73.N3 && LAmerge -v L1.19.73 raw_reads.19.raw_reads.73.C0.S raw_reads.19.raw_reads.73.N0.S raw_reads.19.raw_reads.73.C1.S raw_reads.19.raw_reads.73.N1.S raw_reads.19.raw_reads.73.C2.S raw_reads.19.raw_reads.73.N2.S raw_reads.19.raw_reads.73.C3.S raw_reads.19.raw_reads.73.N3.S LAsort -v raw_reads.20.raw_reads.73.C0 raw_reads.20.raw_reads.73.N0 raw_reads.20.raw_reads.73.C1 raw_reads.20.raw_reads.73.N1 raw_reads.20.raw_reads.73.C2 raw_reads.20.raw_reads.73.N2 raw_reads.20.raw_reads.73.C3 raw_reads.20.raw_reads.73.N3 && LAmerge -v L1.20.73 raw_reads.20.raw_reads.73.C0.S raw_reads.20.raw_reads.73.N0.S raw_reads.20.raw_reads.73.C1.S raw_reads.20.raw_reads.73.N1.S raw_reads.20.raw_reads.73.C2.S raw_reads.20.raw_reads.73.N2.S raw_reads.20.raw_reads.73.C3.S raw_reads.20.raw_reads.73.N3.S LAsort -v raw_reads.21.raw_reads.73.C0 raw_reads.21.raw_reads.73.N0 raw_reads.21.raw_reads.73.C1 raw_reads.21.raw_reads.73.N1 raw_reads.21.raw_reads.73.C2 raw_reads.21.raw_reads.73.N2 raw_reads.21.raw_reads.73.C3 raw_reads.21.raw_reads.73.N3 && LAmerge -v L1.21.73 raw_reads.21.raw_reads.73.C0.S raw_reads.21.raw_reads.73.N0.S raw_reads.21.raw_reads.73.C1.S raw_reads.21.raw_reads.73.N1.S raw_reads.21.raw_reads.73.C2.S raw_reads.21.raw_reads.73.N2.S raw_reads.21.raw_reads.73.C3.S raw_reads.21.raw_reads.73.N3.S LAsort -v raw_reads.22.raw_reads.73.C0 raw_reads.22.raw_reads.73.N0 raw_reads.22.raw_reads.73.C1 raw_reads.22.raw_reads.73.N1 raw_reads.22.raw_reads.73.C2 raw_reads.22.raw_reads.73.N2 raw_reads.22.raw_reads.73.C3 raw_reads.22.raw_reads.73.N3 && LAmerge -v L1.22.73 raw_reads.22.raw_reads.73.C0.S raw_reads.22.raw_reads.73.N0.S raw_reads.22.raw_reads.73.C1.S raw_reads.22.raw_reads.73.N1.S raw_reads.22.raw_reads.73.C2.S raw_reads.22.raw_reads.73.N2.S raw_reads.22.raw_reads.73.C3.S raw_reads.22.raw_reads.73.N3.S LAsort -v raw_reads.23.raw_reads.73.C0 raw_reads.23.raw_reads.73.N0 raw_reads.23.raw_reads.73.C1 raw_reads.23.raw_reads.73.N1 raw_reads.23.raw_reads.73.C2 raw_reads.23.raw_reads.73.N2 raw_reads.23.raw_reads.73.C3 raw_reads.23.raw_reads.73.N3 && LAmerge -v L1.23.73 raw_reads.23.raw_reads.73.C0.S raw_reads.23.raw_reads.73.N0.S raw_reads.23.raw_reads.73.C1.S raw_reads.23.raw_reads.73.N1.S raw_reads.23.raw_reads.73.C2.S raw_reads.23.raw_reads.73.N2.S raw_reads.23.raw_reads.73.C3.S raw_reads.23.raw_reads.73.N3.S LAsort -v raw_reads.24.raw_reads.73.C0 raw_reads.24.raw_reads.73.N0 raw_reads.24.raw_reads.73.C1 raw_reads.24.raw_reads.73.N1 raw_reads.24.raw_reads.73.C2 raw_reads.24.raw_reads.73.N2 raw_reads.24.raw_reads.73.C3 raw_reads.24.raw_reads.73.N3 && LAmerge -v L1.24.73 raw_reads.24.raw_reads.73.C0.S raw_reads.24.raw_reads.73.N0.S raw_reads.24.raw_reads.73.C1.S raw_reads.24.raw_reads.73.N1.S raw_reads.24.raw_reads.73.C2.S raw_reads.24.raw_reads.73.N2.S raw_reads.24.raw_reads.73.C3.S raw_reads.24.raw_reads.73.N3.S LAsort -v raw_reads.25.raw_reads.73.C0 raw_reads.25.raw_reads.73.N0 raw_reads.25.raw_reads.73.C1 raw_reads.25.raw_reads.73.N1 raw_reads.25.raw_reads.73.C2 raw_reads.25.raw_reads.73.N2 raw_reads.25.raw_reads.73.C3 raw_reads.25.raw_reads.73.N3 && LAmerge -v L1.25.73 raw_reads.25.raw_reads.73.C0.S raw_reads.25.raw_reads.73.N0.S raw_reads.25.raw_reads.73.C1.S raw_reads.25.raw_reads.73.N1.S raw_reads.25.raw_reads.73.C2.S raw_reads.25.raw_reads.73.N2.S raw_reads.25.raw_reads.73.C3.S raw_reads.25.raw_reads.73.N3.S LAsort -v raw_reads.26.raw_reads.73.C0 raw_reads.26.raw_reads.73.N0 raw_reads.26.raw_reads.73.C1 raw_reads.26.raw_reads.73.N1 raw_reads.26.raw_reads.73.C2 raw_reads.26.raw_reads.73.N2 raw_reads.26.raw_reads.73.C3 raw_reads.26.raw_reads.73.N3 && LAmerge -v L1.26.73 raw_reads.26.raw_reads.73.C0.S raw_reads.26.raw_reads.73.N0.S raw_reads.26.raw_reads.73.C1.S raw_reads.26.raw_reads.73.N1.S raw_reads.26.raw_reads.73.C2.S raw_reads.26.raw_reads.73.N2.S raw_reads.26.raw_reads.73.C3.S raw_reads.26.raw_reads.73.N3.S LAsort -v raw_reads.27.raw_reads.73.C0 raw_reads.27.raw_reads.73.N0 raw_reads.27.raw_reads.73.C1 raw_reads.27.raw_reads.73.N1 raw_reads.27.raw_reads.73.C2 raw_reads.27.raw_reads.73.N2 raw_reads.27.raw_reads.73.C3 raw_reads.27.raw_reads.73.N3 && LAmerge -v L1.27.73 raw_reads.27.raw_reads.73.C0.S raw_reads.27.raw_reads.73.N0.S raw_reads.27.raw_reads.73.C1.S raw_reads.27.raw_reads.73.N1.S raw_reads.27.raw_reads.73.C2.S raw_reads.27.raw_reads.73.N2.S raw_reads.27.raw_reads.73.C3.S raw_reads.27.raw_reads.73.N3.S LAsort -v raw_reads.28.raw_reads.73.C0 raw_reads.28.raw_reads.73.N0 raw_reads.28.raw_reads.73.C1 raw_reads.28.raw_reads.73.N1 raw_reads.28.raw_reads.73.C2 raw_reads.28.raw_reads.73.N2 raw_reads.28.raw_reads.73.C3 raw_reads.28.raw_reads.73.N3 && LAmerge -v L1.28.73 raw_reads.28.raw_reads.73.C0.S raw_reads.28.raw_reads.73.N0.S raw_reads.28.raw_reads.73.C1.S raw_reads.28.raw_reads.73.N1.S raw_reads.28.raw_reads.73.C2.S raw_reads.28.raw_reads.73.N2.S raw_reads.28.raw_reads.73.C3.S raw_reads.28.raw_reads.73.N3.S LAsort -v raw_reads.29.raw_reads.73.C0 raw_reads.29.raw_reads.73.N0 raw_reads.29.raw_reads.73.C1 raw_reads.29.raw_reads.73.N1 raw_reads.29.raw_reads.73.C2 raw_reads.29.raw_reads.73.N2 raw_reads.29.raw_reads.73.C3 raw_reads.29.raw_reads.73.N3 && LAmerge -v L1.29.73 raw_reads.29.raw_reads.73.C0.S raw_reads.29.raw_reads.73.N0.S raw_reads.29.raw_reads.73.C1.S raw_reads.29.raw_reads.73.N1.S raw_reads.29.raw_reads.73.C2.S raw_reads.29.raw_reads.73.N2.S raw_reads.29.raw_reads.73.C3.S raw_reads.29.raw_reads.73.N3.S LAsort -v raw_reads.30.raw_reads.73.C0 raw_reads.30.raw_reads.73.N0 raw_reads.30.raw_reads.73.C1 raw_reads.30.raw_reads.73.N1 raw_reads.30.raw_reads.73.C2 raw_reads.30.raw_reads.73.N2 raw_reads.30.raw_reads.73.C3 raw_reads.30.raw_reads.73.N3 && LAmerge -v L1.30.73 raw_reads.30.raw_reads.73.C0.S raw_reads.30.raw_reads.73.N0.S raw_reads.30.raw_reads.73.C1.S raw_reads.30.raw_reads.73.N1.S raw_reads.30.raw_reads.73.C2.S raw_reads.30.raw_reads.73.N2.S raw_reads.30.raw_reads.73.C3.S raw_reads.30.raw_reads.73.N3.S LAsort -v raw_reads.31.raw_reads.73.C0 raw_reads.31.raw_reads.73.N0 raw_reads.31.raw_reads.73.C1 raw_reads.31.raw_reads.73.N1 raw_reads.31.raw_reads.73.C2 raw_reads.31.raw_reads.73.N2 raw_reads.31.raw_reads.73.C3 raw_reads.31.raw_reads.73.N3 && LAmerge -v L1.31.73 raw_reads.31.raw_reads.73.C0.S raw_reads.31.raw_reads.73.N0.S raw_reads.31.raw_reads.73.C1.S raw_reads.31.raw_reads.73.N1.S raw_reads.31.raw_reads.73.C2.S raw_reads.31.raw_reads.73.N2.S raw_reads.31.raw_reads.73.C3.S raw_reads.31.raw_reads.73.N3.S LAsort -v raw_reads.32.raw_reads.73.C0 raw_reads.32.raw_reads.73.N0 raw_reads.32.raw_reads.73.C1 raw_reads.32.raw_reads.73.N1 raw_reads.32.raw_reads.73.C2 raw_reads.32.raw_reads.73.N2 raw_reads.32.raw_reads.73.C3 raw_reads.32.raw_reads.73.N3 && LAmerge -v L1.32.73 raw_reads.32.raw_reads.73.C0.S raw_reads.32.raw_reads.73.N0.S raw_reads.32.raw_reads.73.C1.S raw_reads.32.raw_reads.73.N1.S raw_reads.32.raw_reads.73.C2.S raw_reads.32.raw_reads.73.N2.S raw_reads.32.raw_reads.73.C3.S raw_reads.32.raw_reads.73.N3.S LAsort -v raw_reads.33.raw_reads.73.C0 raw_reads.33.raw_reads.73.N0 raw_reads.33.raw_reads.73.C1 raw_reads.33.raw_reads.73.N1 raw_reads.33.raw_reads.73.C2 raw_reads.33.raw_reads.73.N2 raw_reads.33.raw_reads.73.C3 raw_reads.33.raw_reads.73.N3 && LAmerge -v L1.33.73 raw_reads.33.raw_reads.73.C0.S raw_reads.33.raw_reads.73.N0.S raw_reads.33.raw_reads.73.C1.S raw_reads.33.raw_reads.73.N1.S raw_reads.33.raw_reads.73.C2.S raw_reads.33.raw_reads.73.N2.S raw_reads.33.raw_reads.73.C3.S raw_reads.33.raw_reads.73.N3.S LAsort -v raw_reads.34.raw_reads.73.C0 raw_reads.34.raw_reads.73.N0 raw_reads.34.raw_reads.73.C1 raw_reads.34.raw_reads.73.N1 raw_reads.34.raw_reads.73.C2 raw_reads.34.raw_reads.73.N2 raw_reads.34.raw_reads.73.C3 raw_reads.34.raw_reads.73.N3 && LAmerge -v L1.34.73 raw_reads.34.raw_reads.73.C0.S raw_reads.34.raw_reads.73.N0.S raw_reads.34.raw_reads.73.C1.S raw_reads.34.raw_reads.73.N1.S raw_reads.34.raw_reads.73.C2.S raw_reads.34.raw_reads.73.N2.S raw_reads.34.raw_reads.73.C3.S raw_reads.34.raw_reads.73.N3.S LAsort -v raw_reads.35.raw_reads.73.C0 raw_reads.35.raw_reads.73.N0 raw_reads.35.raw_reads.73.C1 raw_reads.35.raw_reads.73.N1 raw_reads.35.raw_reads.73.C2 raw_reads.35.raw_reads.73.N2 raw_reads.35.raw_reads.73.C3 raw_reads.35.raw_reads.73.N3 && LAmerge -v L1.35.73 raw_reads.35.raw_reads.73.C0.S raw_reads.35.raw_reads.73.N0.S raw_reads.35.raw_reads.73.C1.S raw_reads.35.raw_reads.73.N1.S raw_reads.35.raw_reads.73.C2.S raw_reads.35.raw_reads.73.N2.S raw_reads.35.raw_reads.73.C3.S raw_reads.35.raw_reads.73.N3.S LAsort -v raw_reads.36.raw_reads.73.C0 raw_reads.36.raw_reads.73.N0 raw_reads.36.raw_reads.73.C1 raw_reads.36.raw_reads.73.N1 raw_reads.36.raw_reads.73.C2 raw_reads.36.raw_reads.73.N2 raw_reads.36.raw_reads.73.C3 raw_reads.36.raw_reads.73.N3 && LAmerge -v L1.36.73 raw_reads.36.raw_reads.73.C0.S raw_reads.36.raw_reads.73.N0.S raw_reads.36.raw_reads.73.C1.S raw_reads.36.raw_reads.73.N1.S raw_reads.36.raw_reads.73.C2.S raw_reads.36.raw_reads.73.N2.S raw_reads.36.raw_reads.73.C3.S raw_reads.36.raw_reads.73.N3.S LAsort -v raw_reads.73.raw_reads.19.C0 raw_reads.73.raw_reads.19.N0 raw_reads.73.raw_reads.19.C1 raw_reads.73.raw_reads.19.N1 raw_reads.73.raw_reads.19.C2 raw_reads.73.raw_reads.19.N2 raw_reads.73.raw_reads.19.C3 raw_reads.73.raw_reads.19.N3 && LAmerge -v L1.73.19 raw_reads.73.raw_reads.19.C0.S raw_reads.73.raw_reads.19.N0.S raw_reads.73.raw_reads.19.C1.S raw_reads.73.raw_reads.19.N1.S raw_reads.73.raw_reads.19.C2.S raw_reads.73.raw_reads.19.N2.S raw_reads.73.raw_reads.19.C3.S raw_reads.73.raw_reads.19.N3.S LAsort -v raw_reads.73.raw_reads.20.C0 raw_reads.73.raw_reads.20.N0 raw_reads.73.raw_reads.20.C1 raw_reads.73.raw_reads.20.N1 raw_reads.73.raw_reads.20.C2 raw_reads.73.raw_reads.20.N2 raw_reads.73.raw_reads.20.C3 raw_reads.73.raw_reads.20.N3 && LAmerge -v L1.73.20 raw_reads.73.raw_reads.20.C0.S raw_reads.73.raw_reads.20.N0.S raw_reads.73.raw_reads.20.C1.S raw_reads.73.raw_reads.20.N1.S raw_reads.73.raw_reads.20.C2.S raw_reads.73.raw_reads.20.N2.S raw_reads.73.raw_reads.20.C3.S raw_reads.73.raw_reads.20.N3.S LAsort -v raw_reads.73.raw_reads.21.C0 raw_reads.73.raw_reads.21.N0 raw_reads.73.raw_reads.21.C1 raw_reads.73.raw_reads.21.N1 raw_reads.73.raw_reads.21.C2 raw_reads.73.raw_reads.21.N2 raw_reads.73.raw_reads.21.C3 raw_reads.73.raw_reads.21.N3 && LAmerge -v L1.73.21 raw_reads.73.raw_reads.21.C0.S raw_reads.73.raw_reads.21.N0.S raw_reads.73.raw_reads.21.C1.S raw_reads.73.raw_reads.21.N1.S raw_reads.73.raw_reads.21.C2.S raw_reads.73.raw_reads.21.N2.S raw_reads.73.raw_reads.21.C3.S raw_reads.73.raw_reads.21.N3.S LAsort -v raw_reads.73.raw_reads.22.C0 raw_reads.73.raw_reads.22.N0 raw_reads.73.raw_reads.22.C1 raw_reads.73.raw_reads.22.N1 raw_reads.73.raw_reads.22.C2 raw_reads.73.raw_reads.22.N2 raw_reads.73.raw_reads.22.C3 raw_reads.73.raw_reads.22.N3 && LAmerge -v L1.73.22 raw_reads.73.raw_reads.22.C0.S raw_reads.73.raw_reads.22.N0.S raw_reads.73.raw_reads.22.C1.S raw_reads.73.raw_reads.22.N1.S raw_reads.73.raw_reads.22.C2.S raw_reads.73.raw_reads.22.N2.S raw_reads.73.raw_reads.22.C3.S raw_reads.73.raw_reads.22.N3.S LAsort -v raw_reads.73.raw_reads.23.C0 raw_reads.73.raw_reads.23.N0 raw_reads.73.raw_reads.23.C1 raw_reads.73.raw_reads.23.N1 raw_reads.73.raw_reads.23.C2 raw_reads.73.raw_reads.23.N2 raw_reads.73.raw_reads.23.C3 raw_reads.73.raw_reads.23.N3 && LAmerge -v L1.73.23 raw_reads.73.raw_reads.23.C0.S raw_reads.73.raw_reads.23.N0.S raw_reads.73.raw_reads.23.C1.S raw_reads.73.raw_reads.23.N1.S raw_reads.73.raw_reads.23.C2.S raw_reads.73.raw_reads.23.N2.S raw_reads.73.raw_reads.23.C3.S raw_reads.73.raw_reads.23.N3.S LAsort -v raw_reads.73.raw_reads.24.C0 raw_reads.73.raw_reads.24.N0 raw_reads.73.raw_reads.24.C1 raw_reads.73.raw_reads.24.N1 raw_reads.73.raw_reads.24.C2 raw_reads.73.raw_reads.24.N2 raw_reads.73.raw_reads.24.C3 raw_reads.73.raw_reads.24.N3 && LAmerge -v L1.73.24 raw_reads.73.raw_reads.24.C0.S raw_reads.73.raw_reads.24.N0.S raw_reads.73.raw_reads.24.C1.S raw_reads.73.raw_reads.24.N1.S raw_reads.73.raw_reads.24.C2.S raw_reads.73.raw_reads.24.N2.S raw_reads.73.raw_reads.24.C3.S raw_reads.73.raw_reads.24.N3.S LAsort -v raw_reads.73.raw_reads.25.C0 raw_reads.73.raw_reads.25.N0 raw_reads.73.raw_reads.25.C1 raw_reads.73.raw_reads.25.N1 raw_reads.73.raw_reads.25.C2 raw_reads.73.raw_reads.25.N2 raw_reads.73.raw_reads.25.C3 raw_reads.73.raw_reads.25.N3 && LAmerge -v L1.73.25 raw_reads.73.raw_reads.25.C0.S raw_reads.73.raw_reads.25.N0.S raw_reads.73.raw_reads.25.C1.S raw_reads.73.raw_reads.25.N1.S raw_reads.73.raw_reads.25.C2.S raw_reads.73.raw_reads.25.N2.S raw_reads.73.raw_reads.25.C3.S raw_reads.73.raw_reads.25.N3.S LAsort -v raw_reads.73.raw_reads.26.C0 raw_reads.73.raw_reads.26.N0 raw_reads.73.raw_reads.26.C1 raw_reads.73.raw_reads.26.N1 raw_reads.73.raw_reads.26.C2 raw_reads.73.raw_reads.26.N2 raw_reads.73.raw_reads.26.C3 raw_reads.73.raw_reads.26.N3 && LAmerge -v L1.73.26 raw_reads.73.raw_reads.26.C0.S raw_reads.73.raw_reads.26.N0.S raw_reads.73.raw_reads.26.C1.S raw_reads.73.raw_reads.26.N1.S raw_reads.73.raw_reads.26.C2.S raw_reads.73.raw_reads.26.N2.S raw_reads.73.raw_reads.26.C3.S raw_reads.73.raw_reads.26.N3.S LAsort -v raw_reads.73.raw_reads.27.C0 raw_reads.73.raw_reads.27.N0 raw_reads.73.raw_reads.27.C1 raw_reads.73.raw_reads.27.N1 raw_reads.73.raw_reads.27.C2 raw_reads.73.raw_reads.27.N2 raw_reads.73.raw_reads.27.C3 raw_reads.73.raw_reads.27.N3 && LAmerge -v L1.73.27 raw_reads.73.raw_reads.27.C0.S raw_reads.73.raw_reads.27.N0.S raw_reads.73.raw_reads.27.C1.S raw_reads.73.raw_reads.27.N1.S raw_reads.73.raw_reads.27.C2.S raw_reads.73.raw_reads.27.N2.S raw_reads.73.raw_reads.27.C3.S raw_reads.73.raw_reads.27.N3.S LAsort -v raw_reads.73.raw_reads.28.C0 raw_reads.73.raw_reads.28.N0 raw_reads.73.raw_reads.28.C1 raw_reads.73.raw_reads.28.N1 raw_reads.73.raw_reads.28.C2 raw_reads.73.raw_reads.28.N2 raw_reads.73.raw_reads.28.C3 raw_reads.73.raw_reads.28.N3 && LAmerge -v L1.73.28 raw_reads.73.raw_reads.28.C0.S raw_reads.73.raw_reads.28.N0.S raw_reads.73.raw_reads.28.C1.S raw_reads.73.raw_reads.28.N1.S raw_reads.73.raw_reads.28.C2.S raw_reads.73.raw_reads.28.N2.S raw_reads.73.raw_reads.28.C3.S raw_reads.73.raw_reads.28.N3.S LAsort -v raw_reads.73.raw_reads.29.C0 raw_reads.73.raw_reads.29.N0 raw_reads.73.raw_reads.29.C1 raw_reads.73.raw_reads.29.N1 raw_reads.73.raw_reads.29.C2 raw_reads.73.raw_reads.29.N2 raw_reads.73.raw_reads.29.C3 raw_reads.73.raw_reads.29.N3 && LAmerge -v L1.73.29 raw_reads.73.raw_reads.29.C0.S raw_reads.73.raw_reads.29.N0.S raw_reads.73.raw_reads.29.C1.S raw_reads.73.raw_reads.29.N1.S raw_reads.73.raw_reads.29.C2.S raw_reads.73.raw_reads.29.N2.S raw_reads.73.raw_reads.29.C3.S raw_reads.73.raw_reads.29.N3.S LAsort -v raw_reads.73.raw_reads.30.C0 raw_reads.73.raw_reads.30.N0 raw_reads.73.raw_reads.30.C1 raw_reads.73.raw_reads.30.N1 raw_reads.73.raw_reads.30.C2 raw_reads.73.raw_reads.30.N2 raw_reads.73.raw_reads.30.C3 raw_reads.73.raw_reads.30.N3 && LAmerge -v L1.73.30 raw_reads.73.raw_reads.30.C0.S raw_reads.73.raw_reads.30.N0.S raw_reads.73.raw_reads.30.C1.S raw_reads.73.raw_reads.30.N1.S raw_reads.73.raw_reads.30.C2.S raw_reads.73.raw_reads.30.N2.S raw_reads.73.raw_reads.30.C3.S raw_reads.73.raw_reads.30.N3.S LAsort -v raw_reads.73.raw_reads.31.C0 raw_reads.73.raw_reads.31.N0 raw_reads.73.raw_reads.31.C1 raw_reads.73.raw_reads.31.N1 raw_reads.73.raw_reads.31.C2 raw_reads.73.raw_reads.31.N2 raw_reads.73.raw_reads.31.C3 raw_reads.73.raw_reads.31.N3 && LAmerge -v L1.73.31 raw_reads.73.raw_reads.31.C0.S raw_reads.73.raw_reads.31.N0.S raw_reads.73.raw_reads.31.C1.S raw_reads.73.raw_reads.31.N1.S raw_reads.73.raw_reads.31.C2.S raw_reads.73.raw_reads.31.N2.S raw_reads.73.raw_reads.31.C3.S raw_reads.73.raw_reads.31.N3.S LAsort -v raw_reads.73.raw_reads.32.C0 raw_reads.73.raw_reads.32.N0 raw_reads.73.raw_reads.32.C1 raw_reads.73.raw_reads.32.N1 raw_reads.73.raw_reads.32.C2 raw_reads.73.raw_reads.32.N2 raw_reads.73.raw_reads.32.C3 raw_reads.73.raw_reads.32.N3 && LAmerge -v L1.73.32 raw_reads.73.raw_reads.32.C0.S raw_reads.73.raw_reads.32.N0.S raw_reads.73.raw_reads.32.C1.S raw_reads.73.raw_reads.32.N1.S raw_reads.73.raw_reads.32.C2.S raw_reads.73.raw_reads.32.N2.S raw_reads.73.raw_reads.32.C3.S raw_reads.73.raw_reads.32.N3.S LAsort -v raw_reads.73.raw_reads.33.C0 raw_reads.73.raw_reads.33.N0 raw_reads.73.raw_reads.33.C1 raw_reads.73.raw_reads.33.N1 raw_reads.73.raw_reads.33.C2 raw_reads.73.raw_reads.33.N2 raw_reads.73.raw_reads.33.C3 raw_reads.73.raw_reads.33.N3 && LAmerge -v L1.73.33 raw_reads.73.raw_reads.33.C0.S raw_reads.73.raw_reads.33.N0.S raw_reads.73.raw_reads.33.C1.S raw_reads.73.raw_reads.33.N1.S raw_reads.73.raw_reads.33.C2.S raw_reads.73.raw_reads.33.N2.S raw_reads.73.raw_reads.33.C3.S raw_reads.73.raw_reads.33.N3.S LAsort -v raw_reads.73.raw_reads.34.C0 raw_reads.73.raw_reads.34.N0 raw_reads.73.raw_reads.34.C1 raw_reads.73.raw_reads.34.N1 raw_reads.73.raw_reads.34.C2 raw_reads.73.raw_reads.34.N2 raw_reads.73.raw_reads.34.C3 raw_reads.73.raw_reads.34.N3 && LAmerge -v L1.73.34 raw_reads.73.raw_reads.34.C0.S raw_reads.73.raw_reads.34.N0.S raw_reads.73.raw_reads.34.C1.S raw_reads.73.raw_reads.34.N1.S raw_reads.73.raw_reads.34.C2.S raw_reads.73.raw_reads.34.N2.S raw_reads.73.raw_reads.34.C3.S raw_reads.73.raw_reads.34.N3.S LAsort -v raw_reads.73.raw_reads.35.C0 raw_reads.73.raw_reads.35.N0 raw_reads.73.raw_reads.35.C1 raw_reads.73.raw_reads.35.N1 raw_reads.73.raw_reads.35.C2 raw_reads.73.raw_reads.35.N2 raw_reads.73.raw_reads.35.C3 raw_reads.73.raw_reads.35.N3 && LAmerge -v L1.73.35 raw_reads.73.raw_reads.35.C0.S raw_reads.73.raw_reads.35.N0.S raw_reads.73.raw_reads.35.C1.S raw_reads.73.raw_reads.35.N1.S raw_reads.73.raw_reads.35.C2.S raw_reads.73.raw_reads.35.N2.S raw_reads.73.raw_reads.35.C3.S raw_reads.73.raw_reads.35.N3.S LAsort -v raw_reads.73.raw_reads.36.C0 raw_reads.73.raw_reads.36.N0 raw_reads.73.raw_reads.36.C1 raw_reads.73.raw_reads.36.N1 raw_reads.73.raw_reads.36.C2 raw_reads.73.raw_reads.36.N2 raw_reads.73.raw_reads.36.C3 raw_reads.73.raw_reads.36.N3 && LAmerge -v L1.73.36 raw_reads.73.raw_reads.36.C0.S raw_reads.73.raw_reads.36.N0.S raw_reads.73.raw_reads.36.C1.S raw_reads.73.raw_reads.36.N1.S raw_reads.73.raw_reads.36.C2.S raw_reads.73.raw_reads.36.N2.S raw_reads.73.raw_reads.36.C3.S raw_reads.73.raw_reads.36.N3.S LAcheck -vS raw_reads L1.19.73 LAcheck -vS raw_reads L1.20.73 LAcheck -vS raw_reads L1.21.73 LAcheck -vS raw_reads L1.22.73 LAcheck -vS raw_reads L1.23.73 LAcheck -vS raw_reads L1.24.73 LAcheck -vS raw_reads L1.25.73 LAcheck -vS raw_reads L1.26.73 LAcheck -vS raw_reads L1.27.73 LAcheck -vS raw_reads L1.28.73 LAcheck -vS raw_reads L1.29.73 LAcheck -vS raw_reads L1.30.73 LAcheck -vS raw_reads L1.31.73 LAcheck -vS raw_reads L1.32.73 LAcheck -vS raw_reads L1.33.73 LAcheck -vS raw_reads L1.34.73 LAcheck -vS raw_reads L1.35.73 LAcheck -vS raw_reads L1.36.73 LAcheck -vS raw_reads L1.73.19 LAcheck -vS raw_reads L1.73.20 LAcheck -vS raw_reads L1.73.21 LAcheck -vS raw_reads L1.73.22 LAcheck -vS raw_reads L1.73.23 LAcheck -vS raw_reads L1.73.24 LAcheck -vS raw_reads L1.73.25 LAcheck -vS raw_reads L1.73.26 LAcheck -vS raw_reads L1.73.27 LAcheck -vS raw_reads L1.73.28 LAcheck -vS raw_reads L1.73.29 LAcheck -vS raw_reads L1.73.30 LAcheck -vS raw_reads L1.73.31 LAcheck -vS raw_reads L1.73.32 LAcheck -vS raw_reads L1.73.33 LAcheck -vS raw_reads L1.73.34 LAcheck -vS raw_reads L1.73.35 LAcheck -vS raw_reads L1.73.36 daligner -v -k18 -h70 -t14 -H7000 -e0.75 raw_reads.37 raw_reads.19 raw_reads.20 raw_reads.21 raw_reads.22 raw_reads.23 raw_reads.24 raw_reads.25 raw_reads.26 raw_reads.27 raw_reads.28 raw_reads.29 raw_reads.30 raw_reads.31 raw_reads.32 raw_reads.33 raw_reads.34 raw_reads.35 raw_reads.36 raw_reads.37 LAcheck -v raw_reads *.las LAsort -v raw_reads.19.raw_reads.37.C0 raw_reads.19.raw_reads.37.N0 raw_reads.19.raw_reads.37.C1 raw_reads.19.raw_reads.37.N1 raw_reads.19.raw_reads.37.C2 raw_reads.19.raw_reads.37.N2 raw_reads.19.raw_reads.37.C3 raw_reads.19.raw_reads.37.N3 && LAmerge -v L1.19.37 raw_reads.19.raw_reads.37.C0.S raw_reads.19.raw_reads.37.N0.S raw_reads.19.raw_reads.37.C1.S raw_reads.19.raw_reads.37.N1.S raw_reads.19.raw_reads.37.C2.S raw_reads.19.raw_reads.37.N2.S raw_reads.19.raw_reads.37.C3.S raw_reads.19.raw_reads.37.N3.S LAsort -v raw_reads.20.raw_reads.37.C0 raw_reads.20.raw_reads.37.N0 raw_reads.20.raw_reads.37.C1 raw_reads.20.raw_reads.37.N1 raw_reads.20.raw_reads.37.C2 raw_reads.20.raw_reads.37.N2 raw_reads.20.raw_reads.37.C3 raw_reads.20.raw_reads.37.N3 && LAmerge -v L1.20.37 raw_reads.20.raw_reads.37.C0.S raw_reads.20.raw_reads.37.N0.S raw_reads.20.raw_reads.37.C1.S raw_reads.20.raw_reads.37.N1.S raw_reads.20.raw_reads.37.C2.S raw_reads.20.raw_reads.37.N2.S raw_reads.20.raw_reads.37.C3.S raw_reads.20.raw_reads.37.N3.S LAsort -v raw_reads.21.raw_reads.37.C0 raw_reads.21.raw_reads.37.N0 raw_reads.21.raw_reads.37.C1 raw_reads.21.raw_reads.37.N1 raw_reads.21.raw_reads.37.C2 raw_reads.21.raw_reads.37.N2 raw_reads.21.raw_reads.37.C3 raw_reads.21.raw_reads.37.N3 && LAmerge -v L1.21.37 raw_reads.21.raw_reads.37.C0.S raw_reads.21.raw_reads.37.N0.S raw_reads.21.raw_reads.37.C1.S raw_reads.21.raw_reads.37.N1.S raw_reads.21.raw_reads.37.C2.S raw_reads.21.raw_reads.37.N2.S raw_reads.21.raw_reads.37.C3.S raw_reads.21.raw_reads.37.N3.S LAsort -v raw_reads.22.raw_reads.37.C0 raw_reads.22.raw_reads.37.N0 raw_reads.22.raw_reads.37.C1 raw_reads.22.raw_reads.37.N1 raw_reads.22.raw_reads.37.C2 raw_reads.22.raw_reads.37.N2 raw_reads.22.raw_reads.37.C3 raw_reads.22.raw_reads.37.N3 && LAmerge -v L1.22.37 raw_reads.22.raw_reads.37.C0.S raw_reads.22.raw_reads.37.N0.S raw_reads.22.raw_reads.37.C1.S raw_reads.22.raw_reads.37.N1.S raw_reads.22.raw_reads.37.C2.S raw_reads.22.raw_reads.37.N2.S raw_reads.22.raw_reads.37.C3.S raw_reads.22.raw_reads.37.N3.S LAsort -v raw_reads.23.raw_reads.37.C0 raw_reads.23.raw_reads.37.N0 raw_reads.23.raw_reads.37.C1 raw_reads.23.raw_reads.37.N1 raw_reads.23.raw_reads.37.C2 raw_reads.23.raw_reads.37.N2 raw_reads.23.raw_reads.37.C3 raw_reads.23.raw_reads.37.N3 && LAmerge -v L1.23.37 raw_reads.23.raw_reads.37.C0.S raw_reads.23.raw_reads.37.N0.S raw_reads.23.raw_reads.37.C1.S raw_reads.23.raw_reads.37.N1.S raw_reads.23.raw_reads.37.C2.S raw_reads.23.raw_reads.37.N2.S raw_reads.23.raw_reads.37.C3.S raw_reads.23.raw_reads.37.N3.S LAsort -v raw_reads.24.raw_reads.37.C0 raw_reads.24.raw_reads.37.N0 raw_reads.24.raw_reads.37.C1 raw_reads.24.raw_reads.37.N1 raw_reads.24.raw_reads.37.C2 raw_reads.24.raw_reads.37.N2 raw_reads.24.raw_reads.37.C3 raw_reads.24.raw_reads.37.N3 && LAmerge -v L1.24.37 raw_reads.24.raw_reads.37.C0.S raw_reads.24.raw_reads.37.N0.S raw_reads.24.raw_reads.37.C1.S raw_reads.24.raw_reads.37.N1.S raw_reads.24.raw_reads.37.C2.S raw_reads.24.raw_reads.37.N2.S raw_reads.24.raw_reads.37.C3.S raw_reads.24.raw_reads.37.N3.S LAsort -v raw_reads.25.raw_reads.37.C0 raw_reads.25.raw_reads.37.N0 raw_reads.25.raw_reads.37.C1 raw_reads.25.raw_reads.37.N1 raw_reads.25.raw_reads.37.C2 raw_reads.25.raw_reads.37.N2 raw_reads.25.raw_reads.37.C3 raw_reads.25.raw_reads.37.N3 && LAmerge -v L1.25.37 raw_reads.25.raw_reads.37.C0.S raw_reads.25.raw_reads.37.N0.S raw_reads.25.raw_reads.37.C1.S raw_reads.25.raw_reads.37.N1.S raw_reads.25.raw_reads.37.C2.S raw_reads.25.raw_reads.37.N2.S raw_reads.25.raw_reads.37.C3.S raw_reads.25.raw_reads.37.N3.S LAsort -v raw_reads.26.raw_reads.37.C0 raw_reads.26.raw_reads.37.N0 raw_reads.26.raw_reads.37.C1 raw_reads.26.raw_reads.37.N1 raw_reads.26.raw_reads.37.C2 raw_reads.26.raw_reads.37.N2 raw_reads.26.raw_reads.37.C3 raw_reads.26.raw_reads.37.N3 && LAmerge -v L1.26.37 raw_reads.26.raw_reads.37.C0.S raw_reads.26.raw_reads.37.N0.S raw_reads.26.raw_reads.37.C1.S raw_reads.26.raw_reads.37.N1.S raw_reads.26.raw_reads.37.C2.S raw_reads.26.raw_reads.37.N2.S raw_reads.26.raw_reads.37.C3.S raw_reads.26.raw_reads.37.N3.S LAsort -v raw_reads.27.raw_reads.37.C0 raw_reads.27.raw_reads.37.N0 raw_reads.27.raw_reads.37.C1 raw_reads.27.raw_reads.37.N1 raw_reads.27.raw_reads.37.C2 raw_reads.27.raw_reads.37.N2 raw_reads.27.raw_reads.37.C3 raw_reads.27.raw_reads.37.N3 && LAmerge -v L1.27.37 raw_reads.27.raw_reads.37.C0.S raw_reads.27.raw_reads.37.N0.S raw_reads.27.raw_reads.37.C1.S raw_reads.27.raw_reads.37.N1.S raw_reads.27.raw_reads.37.C2.S raw_reads.27.raw_reads.37.N2.S raw_reads.27.raw_reads.37.C3.S raw_reads.27.raw_reads.37.N3.S LAsort -v raw_reads.28.raw_reads.37.C0 raw_reads.28.raw_reads.37.N0 raw_reads.28.raw_reads.37.C1 raw_reads.28.raw_reads.37.N1 raw_reads.28.raw_reads.37.C2 raw_reads.28.raw_reads.37.N2 raw_reads.28.raw_reads.37.C3 raw_reads.28.raw_reads.37.N3 && LAmerge -v L1.28.37 raw_reads.28.raw_reads.37.C0.S raw_reads.28.raw_reads.37.N0.S raw_reads.28.raw_reads.37.C1.S raw_reads.28.raw_reads.37.N1.S raw_reads.28.raw_reads.37.C2.S raw_reads.28.raw_reads.37.N2.S raw_reads.28.raw_reads.37.C3.S raw_reads.28.raw_reads.37.N3.S LAsort -v raw_reads.29.raw_reads.37.C0 raw_reads.29.raw_reads.37.N0 raw_reads.29.raw_reads.37.C1 raw_reads.29.raw_reads.37.N1 raw_reads.29.raw_reads.37.C2 raw_reads.29.raw_reads.37.N2 raw_reads.29.raw_reads.37.C3 raw_reads.29.raw_reads.37.N3 && LAmerge -v L1.29.37 raw_reads.29.raw_reads.37.C0.S raw_reads.29.raw_reads.37.N0.S raw_reads.29.raw_reads.37.C1.S raw_reads.29.raw_reads.37.N1.S raw_reads.29.raw_reads.37.C2.S raw_reads.29.raw_reads.37.N2.S raw_reads.29.raw_reads.37.C3.S raw_reads.29.raw_reads.37.N3.S LAsort -v raw_reads.30.raw_reads.37.C0 raw_reads.30.raw_reads.37.N0 raw_reads.30.raw_reads.37.C1 raw_reads.30.raw_reads.37.N1 raw_reads.30.raw_reads.37.C2 raw_reads.30.raw_reads.37.N2 raw_reads.30.raw_reads.37.C3 raw_reads.30.raw_reads.37.N3 && LAmerge -v L1.30.37 raw_reads.30.raw_reads.37.C0.S raw_reads.30.raw_reads.37.N0.S raw_reads.30.raw_reads.37.C1.S raw_reads.30.raw_reads.37.N1.S raw_reads.30.raw_reads.37.C2.S raw_reads.30.raw_reads.37.N2.S raw_reads.30.raw_reads.37.C3.S raw_reads.30.raw_reads.37.N3.S LAsort -v raw_reads.31.raw_reads.37.C0 raw_reads.31.raw_reads.37.N0 raw_reads.31.raw_reads.37.C1 raw_reads.31.raw_reads.37.N1 raw_reads.31.raw_reads.37.C2 raw_reads.31.raw_reads.37.N2 raw_reads.31.raw_reads.37.C3 raw_reads.31.raw_reads.37.N3 && LAmerge -v L1.31.37 raw_reads.31.raw_reads.37.C0.S raw_reads.31.raw_reads.37.N0.S raw_reads.31.raw_reads.37.C1.S raw_reads.31.raw_reads.37.N1.S raw_reads.31.raw_reads.37.C2.S raw_reads.31.raw_reads.37.N2.S raw_reads.31.raw_reads.37.C3.S raw_reads.31.raw_reads.37.N3.S LAsort -v raw_reads.32.raw_reads.37.C0 raw_reads.32.raw_reads.37.N0 raw_reads.32.raw_reads.37.C1 raw_reads.32.raw_reads.37.N1 raw_reads.32.raw_reads.37.C2 raw_reads.32.raw_reads.37.N2 raw_reads.32.raw_reads.37.C3 raw_reads.32.raw_reads.37.N3 && LAmerge -v L1.32.37 raw_reads.32.raw_reads.37.C0.S raw_reads.32.raw_reads.37.N0.S raw_reads.32.raw_reads.37.C1.S raw_reads.32.raw_reads.37.N1.S raw_reads.32.raw_reads.37.C2.S raw_reads.32.raw_reads.37.N2.S raw_reads.32.raw_reads.37.C3.S raw_reads.32.raw_reads.37.N3.S LAsort -v raw_reads.33.raw_reads.37.C0 raw_reads.33.raw_reads.37.N0 raw_reads.33.raw_reads.37.C1 raw_reads.33.raw_reads.37.N1 raw_reads.33.raw_reads.37.C2 raw_reads.33.raw_reads.37.N2 raw_reads.33.raw_reads.37.C3 raw_reads.33.raw_reads.37.N3 && LAmerge -v L1.33.37 raw_reads.33.raw_reads.37.C0.S raw_reads.33.raw_reads.37.N0.S raw_reads.33.raw_reads.37.C1.S raw_reads.33.raw_reads.37.N1.S raw_reads.33.raw_reads.37.C2.S raw_reads.33.raw_reads.37.N2.S raw_reads.33.raw_reads.37.C3.S raw_reads.33.raw_reads.37.N3.S LAsort -v raw_reads.34.raw_reads.37.C0 raw_reads.34.raw_reads.37.N0 raw_reads.34.raw_reads.37.C1 raw_reads.34.raw_reads.37.N1 raw_reads.34.raw_reads.37.C2 raw_reads.34.raw_reads.37.N2 raw_reads.34.raw_reads.37.C3 raw_reads.34.raw_reads.37.N3 && LAmerge -v L1.34.37 raw_reads.34.raw_reads.37.C0.S raw_reads.34.raw_reads.37.N0.S raw_reads.34.raw_reads.37.C1.S raw_reads.34.raw_reads.37.N1.S raw_reads.34.raw_reads.37.C2.S raw_reads.34.raw_reads.37.N2.S raw_reads.34.raw_reads.37.C3.S raw_reads.34.raw_reads.37.N3.S LAsort -v raw_reads.35.raw_reads.37.C0 raw_reads.35.raw_reads.37.N0 raw_reads.35.raw_reads.37.C1 raw_reads.35.raw_reads.37.N1 raw_reads.35.raw_reads.37.C2 raw_reads.35.raw_reads.37.N2 raw_reads.35.raw_reads.37.C3 raw_reads.35.raw_reads.37.N3 && LAmerge -v L1.35.37 raw_reads.35.raw_reads.37.C0.S raw_reads.35.raw_reads.37.N0.S raw_reads.35.raw_reads.37.C1.S raw_reads.35.raw_reads.37.N1.S raw_reads.35.raw_reads.37.C2.S raw_reads.35.raw_reads.37.N2.S raw_reads.35.raw_reads.37.C3.S raw_reads.35.raw_reads.37.N3.S LAsort -v raw_reads.36.raw_reads.37.C0 raw_reads.36.raw_reads.37.N0 raw_reads.36.raw_reads.37.C1 raw_reads.36.raw_reads.37.N1 raw_reads.36.raw_reads.37.C2 raw_reads.36.raw_reads.37.N2 raw_reads.36.raw_reads.37.C3 raw_reads.36.raw_reads.37.N3 && LAmerge -v L1.36.37 raw_reads.36.raw_reads.37.C0.S raw_reads.36.raw_reads.37.N0.S raw_reads.36.raw_reads.37.C1.S raw_reads.36.raw_reads.37.N1.S raw_reads.36.raw_reads.37.C2.S raw_reads.36.raw_reads.37.N2.S raw_reads.36.raw_reads.37.C3.S raw_reads.36.raw_reads.37.N3.S LAsort -v raw_reads.37.raw_reads.19.C0 raw_reads.37.raw_reads.19.N0 raw_reads.37.raw_reads.19.C1 raw_reads.37.raw_reads.19.N1 raw_reads.37.raw_reads.19.C2 raw_reads.37.raw_reads.19.N2 raw_reads.37.raw_reads.19.C3 raw_reads.37.raw_reads.19.N3 && LAmerge -v L1.37.19 raw_reads.37.raw_reads.19.C0.S raw_reads.37.raw_reads.19.N0.S raw_reads.37.raw_reads.19.C1.S raw_reads.37.raw_reads.19.N1.S raw_reads.37.raw_reads.19.C2.S raw_reads.37.raw_reads.19.N2.S raw_reads.37.raw_reads.19.C3.S raw_reads.37.raw_reads.19.N3.S LAsort -v raw_reads.37.raw_reads.20.C0 raw_reads.37.raw_reads.20.N0 raw_reads.37.raw_reads.20.C1 raw_reads.37.raw_reads.20.N1 raw_reads.37.raw_reads.20.C2 raw_reads.37.raw_reads.20.N2 raw_reads.37.raw_reads.20.C3 raw_reads.37.raw_reads.20.N3 && LAmerge -v L1.37.20 raw_reads.37.raw_reads.20.C0.S raw_reads.37.raw_reads.20.N0.S raw_reads.37.raw_reads.20.C1.S raw_reads.37.raw_reads.20.N1.S raw_reads.37.raw_reads.20.C2.S raw_reads.37.raw_reads.20.N2.S raw_reads.37.raw_reads.20.C3.S raw_reads.37.raw_reads.20.N3.S LAsort -v raw_reads.37.raw_reads.21.C0 raw_reads.37.raw_reads.21.N0 raw_reads.37.raw_reads.21.C1 raw_reads.37.raw_reads.21.N1 raw_reads.37.raw_reads.21.C2 raw_reads.37.raw_reads.21.N2 raw_reads.37.raw_reads.21.C3 raw_reads.37.raw_reads.21.N3 && LAmerge -v L1.37.21 raw_reads.37.raw_reads.21.C0.S raw_reads.37.raw_reads.21.N0.S raw_reads.37.raw_reads.21.C1.S raw_reads.37.raw_reads.21.N1.S raw_reads.37.raw_reads.21.C2.S raw_reads.37.raw_reads.21.N2.S raw_reads.37.raw_reads.21.C3.S raw_reads.37.raw_reads.21.N3.S LAsort -v raw_reads.37.raw_reads.22.C0 raw_reads.37.raw_reads.22.N0 raw_reads.37.raw_reads.22.C1 raw_reads.37.raw_reads.22.N1 raw_reads.37.raw_reads.22.C2 raw_reads.37.raw_reads.22.N2 raw_reads.37.raw_reads.22.C3 raw_reads.37.raw_reads.22.N3 && LAmerge -v L1.37.22 raw_reads.37.raw_reads.22.C0.S raw_reads.37.raw_reads.22.N0.S raw_reads.37.raw_reads.22.C1.S raw_reads.37.raw_reads.22.N1.S raw_reads.37.raw_reads.22.C2.S raw_reads.37.raw_reads.22.N2.S raw_reads.37.raw_reads.22.C3.S raw_reads.37.raw_reads.22.N3.S LAsort -v raw_reads.37.raw_reads.23.C0 raw_reads.37.raw_reads.23.N0 raw_reads.37.raw_reads.23.C1 raw_reads.37.raw_reads.23.N1 raw_reads.37.raw_reads.23.C2 raw_reads.37.raw_reads.23.N2 raw_reads.37.raw_reads.23.C3 raw_reads.37.raw_reads.23.N3 && LAmerge -v L1.37.23 raw_reads.37.raw_reads.23.C0.S raw_reads.37.raw_reads.23.N0.S raw_reads.37.raw_reads.23.C1.S raw_reads.37.raw_reads.23.N1.S raw_reads.37.raw_reads.23.C2.S raw_reads.37.raw_reads.23.N2.S raw_reads.37.raw_reads.23.C3.S raw_reads.37.raw_reads.23.N3.S LAsort -v raw_reads.37.raw_reads.24.C0 raw_reads.37.raw_reads.24.N0 raw_reads.37.raw_reads.24.C1 raw_reads.37.raw_reads.24.N1 raw_reads.37.raw_reads.24.C2 raw_reads.37.raw_reads.24.N2 raw_reads.37.raw_reads.24.C3 raw_reads.37.raw_reads.24.N3 && LAmerge -v L1.37.24 raw_reads.37.raw_reads.24.C0.S raw_reads.37.raw_reads.24.N0.S raw_reads.37.raw_reads.24.C1.S raw_reads.37.raw_reads.24.N1.S raw_reads.37.raw_reads.24.C2.S raw_reads.37.raw_reads.24.N2.S raw_reads.37.raw_reads.24.C3.S raw_reads.37.raw_reads.24.N3.S LAsort -v raw_reads.37.raw_reads.25.C0 raw_reads.37.raw_reads.25.N0 raw_reads.37.raw_reads.25.C1 raw_reads.37.raw_reads.25.N1 raw_reads.37.raw_reads.25.C2 raw_reads.37.raw_reads.25.N2 raw_reads.37.raw_reads.25.C3 raw_reads.37.raw_reads.25.N3 && LAmerge -v L1.37.25 raw_reads.37.raw_reads.25.C0.S raw_reads.37.raw_reads.25.N0.S raw_reads.37.raw_reads.25.C1.S raw_reads.37.raw_reads.25.N1.S raw_reads.37.raw_reads.25.C2.S raw_reads.37.raw_reads.25.N2.S raw_reads.37.raw_reads.25.C3.S raw_reads.37.raw_reads.25.N3.S LAsort -v raw_reads.37.raw_reads.26.C0 raw_reads.37.raw_reads.26.N0 raw_reads.37.raw_reads.26.C1 raw_reads.37.raw_reads.26.N1 raw_reads.37.raw_reads.26.C2 raw_reads.37.raw_reads.26.N2 raw_reads.37.raw_reads.26.C3 raw_reads.37.raw_reads.26.N3 && LAmerge -v L1.37.26 raw_reads.37.raw_reads.26.C0.S raw_reads.37.raw_reads.26.N0.S raw_reads.37.raw_reads.26.C1.S raw_reads.37.raw_reads.26.N1.S raw_reads.37.raw_reads.26.C2.S raw_reads.37.raw_reads.26.N2.S raw_reads.37.raw_reads.26.C3.S raw_reads.37.raw_reads.26.N3.S LAsort -v raw_reads.37.raw_reads.27.C0 raw_reads.37.raw_reads.27.N0 raw_reads.37.raw_reads.27.C1 raw_reads.37.raw_reads.27.N1 raw_reads.37.raw_reads.27.C2 raw_reads.37.raw_reads.27.N2 raw_reads.37.raw_reads.27.C3 raw_reads.37.raw_reads.27.N3 && LAmerge -v L1.37.27 raw_reads.37.raw_reads.27.C0.S raw_reads.37.raw_reads.27.N0.S raw_reads.37.raw_reads.27.C1.S raw_reads.37.raw_reads.27.N1.S raw_reads.37.raw_reads.27.C2.S raw_reads.37.raw_reads.27.N2.S raw_reads.37.raw_reads.27.C3.S raw_reads.37.raw_reads.27.N3.S LAsort -v raw_reads.37.raw_reads.28.C0 raw_reads.37.raw_reads.28.N0 raw_reads.37.raw_reads.28.C1 raw_reads.37.raw_reads.28.N1 raw_reads.37.raw_reads.28.C2 raw_reads.37.raw_reads.28.N2 raw_reads.37.raw_reads.28.C3 raw_reads.37.raw_reads.28.N3 && LAmerge -v L1.37.28 raw_reads.37.raw_reads.28.C0.S raw_reads.37.raw_reads.28.N0.S raw_reads.37.raw_reads.28.C1.S raw_reads.37.raw_reads.28.N1.S raw_reads.37.raw_reads.28.C2.S raw_reads.37.raw_reads.28.N2.S raw_reads.37.raw_reads.28.C3.S raw_reads.37.raw_reads.28.N3.S LAsort -v raw_reads.37.raw_reads.29.C0 raw_reads.37.raw_reads.29.N0 raw_reads.37.raw_reads.29.C1 raw_reads.37.raw_reads.29.N1 raw_reads.37.raw_reads.29.C2 raw_reads.37.raw_reads.29.N2 raw_reads.37.raw_reads.29.C3 raw_reads.37.raw_reads.29.N3 && LAmerge -v L1.37.29 raw_reads.37.raw_reads.29.C0.S raw_reads.37.raw_reads.29.N0.S raw_reads.37.raw_reads.29.C1.S raw_reads.37.raw_reads.29.N1.S raw_reads.37.raw_reads.29.C2.S raw_reads.37.raw_reads.29.N2.S raw_reads.37.raw_reads.29.C3.S raw_reads.37.raw_reads.29.N3.S LAsort -v raw_reads.37.raw_reads.30.C0 raw_reads.37.raw_reads.30.N0 raw_reads.37.raw_reads.30.C1 raw_reads.37.raw_reads.30.N1 raw_reads.37.raw_reads.30.C2 raw_reads.37.raw_reads.30.N2 raw_reads.37.raw_reads.30.C3 raw_reads.37.raw_reads.30.N3 && LAmerge -v L1.37.30 raw_reads.37.raw_reads.30.C0.S raw_reads.37.raw_reads.30.N0.S raw_reads.37.raw_reads.30.C1.S raw_reads.37.raw_reads.30.N1.S raw_reads.37.raw_reads.30.C2.S raw_reads.37.raw_reads.30.N2.S raw_reads.37.raw_reads.30.C3.S raw_reads.37.raw_reads.30.N3.S LAsort -v raw_reads.37.raw_reads.31.C0 raw_reads.37.raw_reads.31.N0 raw_reads.37.raw_reads.31.C1 raw_reads.37.raw_reads.31.N1 raw_reads.37.raw_reads.31.C2 raw_reads.37.raw_reads.31.N2 raw_reads.37.raw_reads.31.C3 raw_reads.37.raw_reads.31.N3 && LAmerge -v L1.37.31 raw_reads.37.raw_reads.31.C0.S raw_reads.37.raw_reads.31.N0.S raw_reads.37.raw_reads.31.C1.S raw_reads.37.raw_reads.31.N1.S raw_reads.37.raw_reads.31.C2.S raw_reads.37.raw_reads.31.N2.S raw_reads.37.raw_reads.31.C3.S raw_reads.37.raw_reads.31.N3.S LAsort -v raw_reads.37.raw_reads.32.C0 raw_reads.37.raw_reads.32.N0 raw_reads.37.raw_reads.32.C1 raw_reads.37.raw_reads.32.N1 raw_reads.37.raw_reads.32.C2 raw_reads.37.raw_reads.32.N2 raw_reads.37.raw_reads.32.C3 raw_reads.37.raw_reads.32.N3 && LAmerge -v L1.37.32 raw_reads.37.raw_reads.32.C0.S raw_reads.37.raw_reads.32.N0.S raw_reads.37.raw_reads.32.C1.S raw_reads.37.raw_reads.32.N1.S raw_reads.37.raw_reads.32.C2.S raw_reads.37.raw_reads.32.N2.S raw_reads.37.raw_reads.32.C3.S raw_reads.37.raw_reads.32.N3.S LAsort -v raw_reads.37.raw_reads.33.C0 raw_reads.37.raw_reads.33.N0 raw_reads.37.raw_reads.33.C1 raw_reads.37.raw_reads.33.N1 raw_reads.37.raw_reads.33.C2 raw_reads.37.raw_reads.33.N2 raw_reads.37.raw_reads.33.C3 raw_reads.37.raw_reads.33.N3 && LAmerge -v L1.37.33 raw_reads.37.raw_reads.33.C0.S raw_reads.37.raw_reads.33.N0.S raw_reads.37.raw_reads.33.C1.S raw_reads.37.raw_reads.33.N1.S raw_reads.37.raw_reads.33.C2.S raw_reads.37.raw_reads.33.N2.S raw_reads.37.raw_reads.33.C3.S raw_reads.37.raw_reads.33.N3.S LAsort -v raw_reads.37.raw_reads.34.C0 raw_reads.37.raw_reads.34.N0 raw_reads.37.raw_reads.34.C1 raw_reads.37.raw_reads.34.N1 raw_reads.37.raw_reads.34.C2 raw_reads.37.raw_reads.34.N2 raw_reads.37.raw_reads.34.C3 raw_reads.37.raw_reads.34.N3 && LAmerge -v L1.37.34 raw_reads.37.raw_reads.34.C0.S raw_reads.37.raw_reads.34.N0.S raw_reads.37.raw_reads.34.C1.S raw_reads.37.raw_reads.34.N1.S raw_reads.37.raw_reads.34.C2.S raw_reads.37.raw_reads.34.N2.S raw_reads.37.raw_reads.34.C3.S raw_reads.37.raw_reads.34.N3.S LAsort -v raw_reads.37.raw_reads.35.C0 raw_reads.37.raw_reads.35.N0 raw_reads.37.raw_reads.35.C1 raw_reads.37.raw_reads.35.N1 raw_reads.37.raw_reads.35.C2 raw_reads.37.raw_reads.35.N2 raw_reads.37.raw_reads.35.C3 raw_reads.37.raw_reads.35.N3 && LAmerge -v L1.37.35 raw_reads.37.raw_reads.35.C0.S raw_reads.37.raw_reads.35.N0.S raw_reads.37.raw_reads.35.C1.S raw_reads.37.raw_reads.35.N1.S raw_reads.37.raw_reads.35.C2.S raw_reads.37.raw_reads.35.N2.S raw_reads.37.raw_reads.35.C3.S raw_reads.37.raw_reads.35.N3.S LAsort -v raw_reads.37.raw_reads.36.C0 raw_reads.37.raw_reads.36.N0 raw_reads.37.raw_reads.36.C1 raw_reads.37.raw_reads.36.N1 raw_reads.37.raw_reads.36.C2 raw_reads.37.raw_reads.36.N2 raw_reads.37.raw_reads.36.C3 raw_reads.37.raw_reads.36.N3 && LAmerge -v L1.37.36 raw_reads.37.raw_reads.36.C0.S raw_reads.37.raw_reads.36.N0.S raw_reads.37.raw_reads.36.C1.S raw_reads.37.raw_reads.36.N1.S raw_reads.37.raw_reads.36.C2.S raw_reads.37.raw_reads.36.N2.S raw_reads.37.raw_reads.36.C3.S raw_reads.37.raw_reads.36.N3.S LAsort -v raw_reads.37.raw_reads.37.C0 raw_reads.37.raw_reads.37.N0 raw_reads.37.raw_reads.37.C1 raw_reads.37.raw_reads.37.N1 raw_reads.37.raw_reads.37.C2 raw_reads.37.raw_reads.37.N2 raw_reads.37.raw_reads.37.C3 raw_reads.37.raw_reads.37.N3 && LAmerge -v L1.37.37 raw_reads.37.raw_reads.37.C0.S raw_reads.37.raw_reads.37.N0.S raw_reads.37.raw_reads.37.C1.S raw_reads.37.raw_reads.37.N1.S raw_reads.37.raw_reads.37.C2.S raw_reads.37.raw_reads.37.N2.S raw_reads.37.raw_reads.37.C3.S raw_reads.37.raw_reads.37.N3.S LAcheck -vS raw_reads L1.19.37 LAcheck -vS raw_reads L1.20.37 LAcheck -vS raw_reads L1.21.37 LAcheck -vS raw_reads L1.22.37 LAcheck -vS raw_reads L1.23.37 LAcheck -vS raw_reads L1.24.37 LAcheck -vS raw_reads L1.25.37 LAcheck -vS raw_reads L1.26.37 LAcheck -vS raw_reads L1.27.37 LAcheck -vS raw_reads L1.28.37 LAcheck -vS raw_reads L1.29.37 LAcheck -vS raw_reads L1.30.37 LAcheck -vS raw_reads L1.31.37 LAcheck -vS raw_reads L1.32.37 LAcheck -vS raw_reads L1.33.37 LAcheck -vS raw_reads L1.34.37 LAcheck -vS raw_reads L1.35.37 LAcheck -vS raw_reads L1.36.37 LAcheck -vS raw_reads L1.37.19 LAcheck -vS raw_reads L1.37.20 LAcheck -vS raw_reads L1.37.21 LAcheck -vS raw_reads L1.37.22 LAcheck -vS raw_reads L1.37.23 LAcheck -vS raw_reads L1.37.24 LAcheck -vS raw_reads L1.37.25 LAcheck -vS raw_reads L1.37.26 LAcheck -vS raw_reads L1.37.27 LAcheck -vS raw_reads L1.37.28 LAcheck -vS raw_reads L1.37.29 LAcheck -vS raw_reads L1.37.30 LAcheck -vS raw_reads L1.37.31 LAcheck -vS raw_reads L1.37.32 LAcheck -vS raw_reads L1.37.33 LAcheck -vS raw_reads L1.37.34 LAcheck -vS raw_reads L1.37.35 LAcheck -vS raw_reads L1.37.36 LAcheck -vS raw_reads L1.37.37 daligner -v -k18 -h70 -t14 -H7000 -e0.75 raw_reads.25 raw_reads.1 raw_reads.2 raw_reads.3 raw_reads.4 raw_reads.5 raw_reads.6 raw_reads.7 raw_reads.8 raw_reads.9 raw_reads.10 raw_reads.11 raw_reads.12 LAcheck -v raw_reads *.las LAsort -v raw_reads.1.raw_reads.25.C0 raw_reads.1.raw_reads.25.N0 raw_reads.1.raw_reads.25.C1 raw_reads.1.raw_reads.25.N1 raw_reads.1.raw_reads.25.C2 raw_reads.1.raw_reads.25.N2 raw_reads.1.raw_reads.25.C3 raw_reads.1.raw_reads.25.N3 && LAmerge -v L1.1.25 raw_reads.1.raw_reads.25.C0.S raw_reads.1.raw_reads.25.N0.S raw_reads.1.raw_reads.25.C1.S raw_reads.1.raw_reads.25.N1.S raw_reads.1.raw_reads.25.C2.S raw_reads.1.raw_reads.25.N2.S raw_reads.1.raw_reads.25.C3.S raw_reads.1.raw_reads.25.N3.S LAsort -v raw_reads.2.raw_reads.25.C0 raw_reads.2.raw_reads.25.N0 raw_reads.2.raw_reads.25.C1 raw_reads.2.raw_reads.25.N1 raw_reads.2.raw_reads.25.C2 raw_reads.2.raw_reads.25.N2 raw_reads.2.raw_reads.25.C3 raw_reads.2.raw_reads.25.N3 && LAmerge -v L1.2.25 raw_reads.2.raw_reads.25.C0.S raw_reads.2.raw_reads.25.N0.S raw_reads.2.raw_reads.25.C1.S raw_reads.2.raw_reads.25.N1.S raw_reads.2.raw_reads.25.C2.S raw_reads.2.raw_reads.25.N2.S raw_reads.2.raw_reads.25.C3.S raw_reads.2.raw_reads.25.N3.S LAsort -v raw_reads.3.raw_reads.25.C0 raw_reads.3.raw_reads.25.N0 raw_reads.3.raw_reads.25.C1 raw_reads.3.raw_reads.25.N1 raw_reads.3.raw_reads.25.C2 raw_reads.3.raw_reads.25.N2 raw_reads.3.raw_reads.25.C3 raw_reads.3.raw_reads.25.N3 && LAmerge -v L1.3.25 raw_reads.3.raw_reads.25.C0.S raw_reads.3.raw_reads.25.N0.S raw_reads.3.raw_reads.25.C1.S raw_reads.3.raw_reads.25.N1.S raw_reads.3.raw_reads.25.C2.S raw_reads.3.raw_reads.25.N2.S raw_reads.3.raw_reads.25.C3.S raw_reads.3.raw_reads.25.N3.S LAsort -v raw_reads.4.raw_reads.25.C0 raw_reads.4.raw_reads.25.N0 raw_reads.4.raw_reads.25.C1 raw_reads.4.raw_reads.25.N1 raw_reads.4.raw_reads.25.C2 raw_reads.4.raw_reads.25.N2 raw_reads.4.raw_reads.25.C3 raw_reads.4.raw_reads.25.N3 && LAmerge -v L1.4.25 raw_reads.4.raw_reads.25.C0.S raw_reads.4.raw_reads.25.N0.S raw_reads.4.raw_reads.25.C1.S raw_reads.4.raw_reads.25.N1.S raw_reads.4.raw_reads.25.C2.S raw_reads.4.raw_reads.25.N2.S raw_reads.4.raw_reads.25.C3.S raw_reads.4.raw_reads.25.N3.S LAsort -v raw_reads.5.raw_reads.25.C0 raw_reads.5.raw_reads.25.N0 raw_reads.5.raw_reads.25.C1 raw_reads.5.raw_reads.25.N1 raw_reads.5.raw_reads.25.C2 raw_reads.5.raw_reads.25.N2 raw_reads.5.raw_reads.25.C3 raw_reads.5.raw_reads.25.N3 && LAmerge -v L1.5.25 raw_reads.5.raw_reads.25.C0.S raw_reads.5.raw_reads.25.N0.S raw_reads.5.raw_reads.25.C1.S raw_reads.5.raw_reads.25.N1.S raw_reads.5.raw_reads.25.C2.S raw_reads.5.raw_reads.25.N2.S raw_reads.5.raw_reads.25.C3.S raw_reads.5.raw_reads.25.N3.S LAsort -v raw_reads.6.raw_reads.25.C0 raw_reads.6.raw_reads.25.N0 raw_reads.6.raw_reads.25.C1 raw_reads.6.raw_reads.25.N1 raw_reads.6.raw_reads.25.C2 raw_reads.6.raw_reads.25.N2 raw_reads.6.raw_reads.25.C3 raw_reads.6.raw_reads.25.N3 && LAmerge -v L1.6.25 raw_reads.6.raw_reads.25.C0.S raw_reads.6.raw_reads.25.N0.S raw_reads.6.raw_reads.25.C1.S raw_reads.6.raw_reads.25.N1.S raw_reads.6.raw_reads.25.C2.S raw_reads.6.raw_reads.25.N2.S raw_reads.6.raw_reads.25.C3.S raw_reads.6.raw_reads.25.N3.S LAsort -v raw_reads.7.raw_reads.25.C0 raw_reads.7.raw_reads.25.N0 raw_reads.7.raw_reads.25.C1 raw_reads.7.raw_reads.25.N1 raw_reads.7.raw_reads.25.C2 raw_reads.7.raw_reads.25.N2 raw_reads.7.raw_reads.25.C3 raw_reads.7.raw_reads.25.N3 && LAmerge -v L1.7.25 raw_reads.7.raw_reads.25.C0.S raw_reads.7.raw_reads.25.N0.S raw_reads.7.raw_reads.25.C1.S raw_reads.7.raw_reads.25.N1.S raw_reads.7.raw_reads.25.C2.S raw_reads.7.raw_reads.25.N2.S raw_reads.7.raw_reads.25.C3.S raw_reads.7.raw_reads.25.N3.S LAsort -v raw_reads.8.raw_reads.25.C0 raw_reads.8.raw_reads.25.N0 raw_reads.8.raw_reads.25.C1 raw_reads.8.raw_reads.25.N1 raw_reads.8.raw_reads.25.C2 raw_reads.8.raw_reads.25.N2 raw_reads.8.raw_reads.25.C3 raw_reads.8.raw_reads.25.N3 && LAmerge -v L1.8.25 raw_reads.8.raw_reads.25.C0.S raw_reads.8.raw_reads.25.N0.S raw_reads.8.raw_reads.25.C1.S raw_reads.8.raw_reads.25.N1.S raw_reads.8.raw_reads.25.C2.S raw_reads.8.raw_reads.25.N2.S raw_reads.8.raw_reads.25.C3.S raw_reads.8.raw_reads.25.N3.S LAsort -v raw_reads.9.raw_reads.25.C0 raw_reads.9.raw_reads.25.N0 raw_reads.9.raw_reads.25.C1 raw_reads.9.raw_reads.25.N1 raw_reads.9.raw_reads.25.C2 raw_reads.9.raw_reads.25.N2 raw_reads.9.raw_reads.25.C3 raw_reads.9.raw_reads.25.N3 && LAmerge -v L1.9.25 raw_reads.9.raw_reads.25.C0.S raw_reads.9.raw_reads.25.N0.S raw_reads.9.raw_reads.25.C1.S raw_reads.9.raw_reads.25.N1.S raw_reads.9.raw_reads.25.C2.S raw_reads.9.raw_reads.25.N2.S raw_reads.9.raw_reads.25.C3.S raw_reads.9.raw_reads.25.N3.S LAsort -v raw_reads.10.raw_reads.25.C0 raw_reads.10.raw_reads.25.N0 raw_reads.10.raw_reads.25.C1 raw_reads.10.raw_reads.25.N1 raw_reads.10.raw_reads.25.C2 raw_reads.10.raw_reads.25.N2 raw_reads.10.raw_reads.25.C3 raw_reads.10.raw_reads.25.N3 && LAmerge -v L1.10.25 raw_reads.10.raw_reads.25.C0.S raw_reads.10.raw_reads.25.N0.S raw_reads.10.raw_reads.25.C1.S raw_reads.10.raw_reads.25.N1.S raw_reads.10.raw_reads.25.C2.S raw_reads.10.raw_reads.25.N2.S raw_reads.10.raw_reads.25.C3.S raw_reads.10.raw_reads.25.N3.S LAsort -v raw_reads.11.raw_reads.25.C0 raw_reads.11.raw_reads.25.N0 raw_reads.11.raw_reads.25.C1 raw_reads.11.raw_reads.25.N1 raw_reads.11.raw_reads.25.C2 raw_reads.11.raw_reads.25.N2 raw_reads.11.raw_reads.25.C3 raw_reads.11.raw_reads.25.N3 && LAmerge -v L1.11.25 raw_reads.11.raw_reads.25.C0.S raw_reads.11.raw_reads.25.N0.S raw_reads.11.raw_reads.25.C1.S raw_reads.11.raw_reads.25.N1.S raw_reads.11.raw_reads.25.C2.S raw_reads.11.raw_reads.25.N2.S raw_reads.11.raw_reads.25.C3.S raw_reads.11.raw_reads.25.N3.S LAsort -v raw_reads.12.raw_reads.25.C0 raw_reads.12.raw_reads.25.N0 raw_reads.12.raw_reads.25.C1 raw_reads.12.raw_reads.25.N1 raw_reads.12.raw_reads.25.C2 raw_reads.12.raw_reads.25.N2 raw_reads.12.raw_reads.25.C3 raw_reads.12.raw_reads.25.N3 && LAmerge -v L1.12.25 raw_reads.12.raw_reads.25.C0.S raw_reads.12.raw_reads.25.N0.S raw_reads.12.raw_reads.25.C1.S raw_reads.12.raw_reads.25.N1.S raw_reads.12.raw_reads.25.C2.S raw_reads.12.raw_reads.25.N2.S raw_reads.12.raw_reads.25.C3.S raw_reads.12.raw_reads.25.N3.S LAsort -v raw_reads.25.raw_reads.1.C0 raw_reads.25.raw_reads.1.N0 raw_reads.25.raw_reads.1.C1 raw_reads.25.raw_reads.1.N1 raw_reads.25.raw_reads.1.C2 raw_reads.25.raw_reads.1.N2 raw_reads.25.raw_reads.1.C3 raw_reads.25.raw_reads.1.N3 && LAmerge -v L1.25.1 raw_reads.25.raw_reads.1.C0.S raw_reads.25.raw_reads.1.N0.S raw_reads.25.raw_reads.1.C1.S raw_reads.25.raw_reads.1.N1.S raw_reads.25.raw_reads.1.C2.S raw_reads.25.raw_reads.1.N2.S raw_reads.25.raw_reads.1.C3.S raw_reads.25.raw_reads.1.N3.S LAsort -v raw_reads.25.raw_reads.2.C0 raw_reads.25.raw_reads.2.N0 raw_reads.25.raw_reads.2.C1 raw_reads.25.raw_reads.2.N1 raw_reads.25.raw_reads.2.C2 raw_reads.25.raw_reads.2.N2 raw_reads.25.raw_reads.2.C3 raw_reads.25.raw_reads.2.N3 && LAmerge -v L1.25.2 raw_reads.25.raw_reads.2.C0.S raw_reads.25.raw_reads.2.N0.S raw_reads.25.raw_reads.2.C1.S raw_reads.25.raw_reads.2.N1.S raw_reads.25.raw_reads.2.C2.S raw_reads.25.raw_reads.2.N2.S raw_reads.25.raw_reads.2.C3.S raw_reads.25.raw_reads.2.N3.S LAsort -v raw_reads.25.raw_reads.3.C0 raw_reads.25.raw_reads.3.N0 raw_reads.25.raw_reads.3.C1 raw_reads.25.raw_reads.3.N1 raw_reads.25.raw_reads.3.C2 raw_reads.25.raw_reads.3.N2 raw_reads.25.raw_reads.3.C3 raw_reads.25.raw_reads.3.N3 && LAmerge -v L1.25.3 raw_reads.25.raw_reads.3.C0.S raw_reads.25.raw_reads.3.N0.S raw_reads.25.raw_reads.3.C1.S raw_reads.25.raw_reads.3.N1.S raw_reads.25.raw_reads.3.C2.S raw_reads.25.raw_reads.3.N2.S raw_reads.25.raw_reads.3.C3.S raw_reads.25.raw_reads.3.N3.S LAsort -v raw_reads.25.raw_reads.4.C0 raw_reads.25.raw_reads.4.N0 raw_reads.25.raw_reads.4.C1 raw_reads.25.raw_reads.4.N1 raw_reads.25.raw_reads.4.C2 raw_reads.25.raw_reads.4.N2 raw_reads.25.raw_reads.4.C3 raw_reads.25.raw_reads.4.N3 && LAmerge -v L1.25.4 raw_reads.25.raw_reads.4.C0.S raw_reads.25.raw_reads.4.N0.S raw_reads.25.raw_reads.4.C1.S raw_reads.25.raw_reads.4.N1.S raw_reads.25.raw_reads.4.C2.S raw_reads.25.raw_reads.4.N2.S raw_reads.25.raw_reads.4.C3.S raw_reads.25.raw_reads.4.N3.S LAsort -v raw_reads.25.raw_reads.5.C0 raw_reads.25.raw_reads.5.N0 raw_reads.25.raw_reads.5.C1 raw_reads.25.raw_reads.5.N1 raw_reads.25.raw_reads.5.C2 raw_reads.25.raw_reads.5.N2 raw_reads.25.raw_reads.5.C3 raw_reads.25.raw_reads.5.N3 && LAmerge -v L1.25.5 raw_reads.25.raw_reads.5.C0.S raw_reads.25.raw_reads.5.N0.S raw_reads.25.raw_reads.5.C1.S raw_reads.25.raw_reads.5.N1.S raw_reads.25.raw_reads.5.C2.S raw_reads.25.raw_reads.5.N2.S raw_reads.25.raw_reads.5.C3.S raw_reads.25.raw_reads.5.N3.S LAsort -v raw_reads.25.raw_reads.6.C0 raw_reads.25.raw_reads.6.N0 raw_reads.25.raw_reads.6.C1 raw_reads.25.raw_reads.6.N1 raw_reads.25.raw_reads.6.C2 raw_reads.25.raw_reads.6.N2 raw_reads.25.raw_reads.6.C3 raw_reads.25.raw_reads.6.N3 && LAmerge -v L1.25.6 raw_reads.25.raw_reads.6.C0.S raw_reads.25.raw_reads.6.N0.S raw_reads.25.raw_reads.6.C1.S raw_reads.25.raw_reads.6.N1.S raw_reads.25.raw_reads.6.C2.S raw_reads.25.raw_reads.6.N2.S raw_reads.25.raw_reads.6.C3.S raw_reads.25.raw_reads.6.N3.S LAsort -v raw_reads.25.raw_reads.7.C0 raw_reads.25.raw_reads.7.N0 raw_reads.25.raw_reads.7.C1 raw_reads.25.raw_reads.7.N1 raw_reads.25.raw_reads.7.C2 raw_reads.25.raw_reads.7.N2 raw_reads.25.raw_reads.7.C3 raw_reads.25.raw_reads.7.N3 && LAmerge -v L1.25.7 raw_reads.25.raw_reads.7.C0.S raw_reads.25.raw_reads.7.N0.S raw_reads.25.raw_reads.7.C1.S raw_reads.25.raw_reads.7.N1.S raw_reads.25.raw_reads.7.C2.S raw_reads.25.raw_reads.7.N2.S raw_reads.25.raw_reads.7.C3.S raw_reads.25.raw_reads.7.N3.S LAsort -v raw_reads.25.raw_reads.8.C0 raw_reads.25.raw_reads.8.N0 raw_reads.25.raw_reads.8.C1 raw_reads.25.raw_reads.8.N1 raw_reads.25.raw_reads.8.C2 raw_reads.25.raw_reads.8.N2 raw_reads.25.raw_reads.8.C3 raw_reads.25.raw_reads.8.N3 && LAmerge -v L1.25.8 raw_reads.25.raw_reads.8.C0.S raw_reads.25.raw_reads.8.N0.S raw_reads.25.raw_reads.8.C1.S raw_reads.25.raw_reads.8.N1.S raw_reads.25.raw_reads.8.C2.S raw_reads.25.raw_reads.8.N2.S raw_reads.25.raw_reads.8.C3.S raw_reads.25.raw_reads.8.N3.S LAsort -v raw_reads.25.raw_reads.9.C0 raw_reads.25.raw_reads.9.N0 raw_reads.25.raw_reads.9.C1 raw_reads.25.raw_reads.9.N1 raw_reads.25.raw_reads.9.C2 raw_reads.25.raw_reads.9.N2 raw_reads.25.raw_reads.9.C3 raw_reads.25.raw_reads.9.N3 && LAmerge -v L1.25.9 raw_reads.25.raw_reads.9.C0.S raw_reads.25.raw_reads.9.N0.S raw_reads.25.raw_reads.9.C1.S raw_reads.25.raw_reads.9.N1.S raw_reads.25.raw_reads.9.C2.S raw_reads.25.raw_reads.9.N2.S raw_reads.25.raw_reads.9.C3.S raw_reads.25.raw_reads.9.N3.S LAsort -v raw_reads.25.raw_reads.10.C0 raw_reads.25.raw_reads.10.N0 raw_reads.25.raw_reads.10.C1 raw_reads.25.raw_reads.10.N1 raw_reads.25.raw_reads.10.C2 raw_reads.25.raw_reads.10.N2 raw_reads.25.raw_reads.10.C3 raw_reads.25.raw_reads.10.N3 && LAmerge -v L1.25.10 raw_reads.25.raw_reads.10.C0.S raw_reads.25.raw_reads.10.N0.S raw_reads.25.raw_reads.10.C1.S raw_reads.25.raw_reads.10.N1.S raw_reads.25.raw_reads.10.C2.S raw_reads.25.raw_reads.10.N2.S raw_reads.25.raw_reads.10.C3.S raw_reads.25.raw_reads.10.N3.S LAsort -v raw_reads.25.raw_reads.11.C0 raw_reads.25.raw_reads.11.N0 raw_reads.25.raw_reads.11.C1 raw_reads.25.raw_reads.11.N1 raw_reads.25.raw_reads.11.C2 raw_reads.25.raw_reads.11.N2 raw_reads.25.raw_reads.11.C3 raw_reads.25.raw_reads.11.N3 && LAmerge -v L1.25.11 raw_reads.25.raw_reads.11.C0.S raw_reads.25.raw_reads.11.N0.S raw_reads.25.raw_reads.11.C1.S raw_reads.25.raw_reads.11.N1.S raw_reads.25.raw_reads.11.C2.S raw_reads.25.raw_reads.11.N2.S raw_reads.25.raw_reads.11.C3.S raw_reads.25.raw_reads.11.N3.S LAsort -v raw_reads.25.raw_reads.12.C0 raw_reads.25.raw_reads.12.N0 raw_reads.25.raw_reads.12.C1 raw_reads.25.raw_reads.12.N1 raw_reads.25.raw_reads.12.C2 raw_reads.25.raw_reads.12.N2 raw_reads.25.raw_reads.12.C3 raw_reads.25.raw_reads.12.N3 && LAmerge -v L1.25.12 raw_reads.25.raw_reads.12.C0.S raw_reads.25.raw_reads.12.N0.S raw_reads.25.raw_reads.12.C1.S raw_reads.25.raw_reads.12.N1.S raw_reads.25.raw_reads.12.C2.S raw_reads.25.raw_reads.12.N2.S raw_reads.25.raw_reads.12.C3.S raw_reads.25.raw_reads.12.N3.S LAcheck -vS raw_reads L1.1.25 LAcheck -vS raw_reads L1.2.25 LAcheck -vS raw_reads L1.3.25 LAcheck -vS raw_reads L1.4.25 LAcheck -vS raw_reads L1.5.25 LAcheck -vS raw_reads L1.6.25 LAcheck -vS raw_reads L1.7.25 LAcheck -vS raw_reads L1.8.25 LAcheck -vS raw_reads L1.9.25 LAcheck -vS raw_reads L1.10.25 LAcheck -vS raw_reads L1.11.25 LAcheck -vS raw_reads L1.12.25 LAcheck -vS raw_reads L1.25.1 LAcheck -vS raw_reads L1.25.2 LAcheck -vS raw_reads L1.25.3 LAcheck -vS raw_reads L1.25.4 LAcheck -vS raw_reads L1.25.5 LAcheck -vS raw_reads L1.25.6 LAcheck -vS raw_reads L1.25.7 LAcheck -vS raw_reads L1.25.8 LAcheck -vS raw_reads L1.25.9 LAcheck -vS raw_reads L1.25.10 LAcheck -vS raw_reads L1.25.11 LAcheck -vS raw_reads L1.25.12 daligner -v -k18 -h70 -t14 -H7000 -e0.75 raw_reads.99 raw_reads.60 raw_reads.61 raw_reads.62 raw_reads.63 raw_reads.64 raw_reads.65 raw_reads.66 raw_reads.67 raw_reads.68 raw_reads.69 raw_reads.70 raw_reads.71 raw_reads.72 raw_reads.73 raw_reads.74 raw_reads.75 raw_reads.76 raw_reads.77 raw_reads.78 raw_reads.79 LAcheck -v raw_reads *.las LAsort -v raw_reads.60.raw_reads.99.C0 raw_reads.60.raw_reads.99.N0 raw_reads.60.raw_reads.99.C1 raw_reads.60.raw_reads.99.N1 raw_reads.60.raw_reads.99.C2 raw_reads.60.raw_reads.99.N2 raw_reads.60.raw_reads.99.C3 raw_reads.60.raw_reads.99.N3 && LAmerge -v L1.60.99 raw_reads.60.raw_reads.99.C0.S raw_reads.60.raw_reads.99.N0.S raw_reads.60.raw_reads.99.C1.S raw_reads.60.raw_reads.99.N1.S raw_reads.60.raw_reads.99.C2.S raw_reads.60.raw_reads.99.N2.S raw_reads.60.raw_reads.99.C3.S raw_reads.60.raw_reads.99.N3.S LAsort -v raw_reads.61.raw_reads.99.C0 raw_reads.61.raw_reads.99.N0 raw_reads.61.raw_reads.99.C1 raw_reads.61.raw_reads.99.N1 raw_reads.61.raw_reads.99.C2 raw_reads.61.raw_reads.99.N2 raw_reads.61.raw_reads.99.C3 raw_reads.61.raw_reads.99.N3 && LAmerge -v L1.61.99 raw_reads.61.raw_reads.99.C0.S raw_reads.61.raw_reads.99.N0.S raw_reads.61.raw_reads.99.C1.S raw_reads.61.raw_reads.99.N1.S raw_reads.61.raw_reads.99.C2.S raw_reads.61.raw_reads.99.N2.S raw_reads.61.raw_reads.99.C3.S raw_reads.61.raw_reads.99.N3.S LAsort -v raw_reads.62.raw_reads.99.C0 raw_reads.62.raw_reads.99.N0 raw_reads.62.raw_reads.99.C1 raw_reads.62.raw_reads.99.N1 raw_reads.62.raw_reads.99.C2 raw_reads.62.raw_reads.99.N2 raw_reads.62.raw_reads.99.C3 raw_reads.62.raw_reads.99.N3 && LAmerge -v L1.62.99 raw_reads.62.raw_reads.99.C0.S raw_reads.62.raw_reads.99.N0.S raw_reads.62.raw_reads.99.C1.S raw_reads.62.raw_reads.99.N1.S raw_reads.62.raw_reads.99.C2.S raw_reads.62.raw_reads.99.N2.S raw_reads.62.raw_reads.99.C3.S raw_reads.62.raw_reads.99.N3.S LAsort -v raw_reads.63.raw_reads.99.C0 raw_reads.63.raw_reads.99.N0 raw_reads.63.raw_reads.99.C1 raw_reads.63.raw_reads.99.N1 raw_reads.63.raw_reads.99.C2 raw_reads.63.raw_reads.99.N2 raw_reads.63.raw_reads.99.C3 raw_reads.63.raw_reads.99.N3 && LAmerge -v L1.63.99 raw_reads.63.raw_reads.99.C0.S raw_reads.63.raw_reads.99.N0.S raw_reads.63.raw_reads.99.C1.S raw_reads.63.raw_reads.99.N1.S raw_reads.63.raw_reads.99.C2.S raw_reads.63.raw_reads.99.N2.S raw_reads.63.raw_reads.99.C3.S raw_reads.63.raw_reads.99.N3.S LAsort -v raw_reads.64.raw_reads.99.C0 raw_reads.64.raw_reads.99.N0 raw_reads.64.raw_reads.99.C1 raw_reads.64.raw_reads.99.N1 raw_reads.64.raw_reads.99.C2 raw_reads.64.raw_reads.99.N2 raw_reads.64.raw_reads.99.C3 raw_reads.64.raw_reads.99.N3 && LAmerge -v L1.64.99 raw_reads.64.raw_reads.99.C0.S raw_reads.64.raw_reads.99.N0.S raw_reads.64.raw_reads.99.C1.S raw_reads.64.raw_reads.99.N1.S raw_reads.64.raw_reads.99.C2.S raw_reads.64.raw_reads.99.N2.S raw_reads.64.raw_reads.99.C3.S raw_reads.64.raw_reads.99.N3.S LAsort -v raw_reads.65.raw_reads.99.C0 raw_reads.65.raw_reads.99.N0 raw_reads.65.raw_reads.99.C1 raw_reads.65.raw_reads.99.N1 raw_reads.65.raw_reads.99.C2 raw_reads.65.raw_reads.99.N2 raw_reads.65.raw_reads.99.C3 raw_reads.65.raw_reads.99.N3 && LAmerge -v L1.65.99 raw_reads.65.raw_reads.99.C0.S raw_reads.65.raw_reads.99.N0.S raw_reads.65.raw_reads.99.C1.S raw_reads.65.raw_reads.99.N1.S raw_reads.65.raw_reads.99.C2.S raw_reads.65.raw_reads.99.N2.S raw_reads.65.raw_reads.99.C3.S raw_reads.65.raw_reads.99.N3.S LAsort -v raw_reads.66.raw_reads.99.C0 raw_reads.66.raw_reads.99.N0 raw_reads.66.raw_reads.99.C1 raw_reads.66.raw_reads.99.N1 raw_reads.66.raw_reads.99.C2 raw_reads.66.raw_reads.99.N2 raw_reads.66.raw_reads.99.C3 raw_reads.66.raw_reads.99.N3 && LAmerge -v L1.66.99 raw_reads.66.raw_reads.99.C0.S raw_reads.66.raw_reads.99.N0.S raw_reads.66.raw_reads.99.C1.S raw_reads.66.raw_reads.99.N1.S raw_reads.66.raw_reads.99.C2.S raw_reads.66.raw_reads.99.N2.S raw_reads.66.raw_reads.99.C3.S raw_reads.66.raw_reads.99.N3.S LAsort -v raw_reads.67.raw_reads.99.C0 raw_reads.67.raw_reads.99.N0 raw_reads.67.raw_reads.99.C1 raw_reads.67.raw_reads.99.N1 raw_reads.67.raw_reads.99.C2 raw_reads.67.raw_reads.99.N2 raw_reads.67.raw_reads.99.C3 raw_reads.67.raw_reads.99.N3 && LAmerge -v L1.67.99 raw_reads.67.raw_reads.99.C0.S raw_reads.67.raw_reads.99.N0.S raw_reads.67.raw_reads.99.C1.S raw_reads.67.raw_reads.99.N1.S raw_reads.67.raw_reads.99.C2.S raw_reads.67.raw_reads.99.N2.S raw_reads.67.raw_reads.99.C3.S raw_reads.67.raw_reads.99.N3.S LAsort -v raw_reads.68.raw_reads.99.C0 raw_reads.68.raw_reads.99.N0 raw_reads.68.raw_reads.99.C1 raw_reads.68.raw_reads.99.N1 raw_reads.68.raw_reads.99.C2 raw_reads.68.raw_reads.99.N2 raw_reads.68.raw_reads.99.C3 raw_reads.68.raw_reads.99.N3 && LAmerge -v L1.68.99 raw_reads.68.raw_reads.99.C0.S raw_reads.68.raw_reads.99.N0.S raw_reads.68.raw_reads.99.C1.S raw_reads.68.raw_reads.99.N1.S raw_reads.68.raw_reads.99.C2.S raw_reads.68.raw_reads.99.N2.S raw_reads.68.raw_reads.99.C3.S raw_reads.68.raw_reads.99.N3.S LAsort -v raw_reads.69.raw_reads.99.C0 raw_reads.69.raw_reads.99.N0 raw_reads.69.raw_reads.99.C1 raw_reads.69.raw_reads.99.N1 raw_reads.69.raw_reads.99.C2 raw_reads.69.raw_reads.99.N2 raw_reads.69.raw_reads.99.C3 raw_reads.69.raw_reads.99.N3 && LAmerge -v L1.69.99 raw_reads.69.raw_reads.99.C0.S raw_reads.69.raw_reads.99.N0.S raw_reads.69.raw_reads.99.C1.S raw_reads.69.raw_reads.99.N1.S raw_reads.69.raw_reads.99.C2.S raw_reads.69.raw_reads.99.N2.S raw_reads.69.raw_reads.99.C3.S raw_reads.69.raw_reads.99.N3.S LAsort -v raw_reads.70.raw_reads.99.C0 raw_reads.70.raw_reads.99.N0 raw_reads.70.raw_reads.99.C1 raw_reads.70.raw_reads.99.N1 raw_reads.70.raw_reads.99.C2 raw_reads.70.raw_reads.99.N2 raw_reads.70.raw_reads.99.C3 raw_reads.70.raw_reads.99.N3 && LAmerge -v L1.70.99 raw_reads.70.raw_reads.99.C0.S raw_reads.70.raw_reads.99.N0.S raw_reads.70.raw_reads.99.C1.S raw_reads.70.raw_reads.99.N1.S raw_reads.70.raw_reads.99.C2.S raw_reads.70.raw_reads.99.N2.S raw_reads.70.raw_reads.99.C3.S raw_reads.70.raw_reads.99.N3.S LAsort -v raw_reads.71.raw_reads.99.C0 raw_reads.71.raw_reads.99.N0 raw_reads.71.raw_reads.99.C1 raw_reads.71.raw_reads.99.N1 raw_reads.71.raw_reads.99.C2 raw_reads.71.raw_reads.99.N2 raw_reads.71.raw_reads.99.C3 raw_reads.71.raw_reads.99.N3 && LAmerge -v L1.71.99 raw_reads.71.raw_reads.99.C0.S raw_reads.71.raw_reads.99.N0.S raw_reads.71.raw_reads.99.C1.S raw_reads.71.raw_reads.99.N1.S raw_reads.71.raw_reads.99.C2.S raw_reads.71.raw_reads.99.N2.S raw_reads.71.raw_reads.99.C3.S raw_reads.71.raw_reads.99.N3.S LAsort -v raw_reads.72.raw_reads.99.C0 raw_reads.72.raw_reads.99.N0 raw_reads.72.raw_reads.99.C1 raw_reads.72.raw_reads.99.N1 raw_reads.72.raw_reads.99.C2 raw_reads.72.raw_reads.99.N2 raw_reads.72.raw_reads.99.C3 raw_reads.72.raw_reads.99.N3 && LAmerge -v L1.72.99 raw_reads.72.raw_reads.99.C0.S raw_reads.72.raw_reads.99.N0.S raw_reads.72.raw_reads.99.C1.S raw_reads.72.raw_reads.99.N1.S raw_reads.72.raw_reads.99.C2.S raw_reads.72.raw_reads.99.N2.S raw_reads.72.raw_reads.99.C3.S raw_reads.72.raw_reads.99.N3.S LAsort -v raw_reads.73.raw_reads.99.C0 raw_reads.73.raw_reads.99.N0 raw_reads.73.raw_reads.99.C1 raw_reads.73.raw_reads.99.N1 raw_reads.73.raw_reads.99.C2 raw_reads.73.raw_reads.99.N2 raw_reads.73.raw_reads.99.C3 raw_reads.73.raw_reads.99.N3 && LAmerge -v L1.73.99 raw_reads.73.raw_reads.99.C0.S raw_reads.73.raw_reads.99.N0.S raw_reads.73.raw_reads.99.C1.S raw_reads.73.raw_reads.99.N1.S raw_reads.73.raw_reads.99.C2.S raw_reads.73.raw_reads.99.N2.S raw_reads.73.raw_reads.99.C3.S raw_reads.73.raw_reads.99.N3.S LAsort -v raw_reads.74.raw_reads.99.C0 raw_reads.74.raw_reads.99.N0 raw_reads.74.raw_reads.99.C1 raw_reads.74.raw_reads.99.N1 raw_reads.74.raw_reads.99.C2 raw_reads.74.raw_reads.99.N2 raw_reads.74.raw_reads.99.C3 raw_reads.74.raw_reads.99.N3 && LAmerge -v L1.74.99 raw_reads.74.raw_reads.99.C0.S raw_reads.74.raw_reads.99.N0.S raw_reads.74.raw_reads.99.C1.S raw_reads.74.raw_reads.99.N1.S raw_reads.74.raw_reads.99.C2.S raw_reads.74.raw_reads.99.N2.S raw_reads.74.raw_reads.99.C3.S raw_reads.74.raw_reads.99.N3.S LAsort -v raw_reads.75.raw_reads.99.C0 raw_reads.75.raw_reads.99.N0 raw_reads.75.raw_reads.99.C1 raw_reads.75.raw_reads.99.N1 raw_reads.75.raw_reads.99.C2 raw_reads.75.raw_reads.99.N2 raw_reads.75.raw_reads.99.C3 raw_reads.75.raw_reads.99.N3 && LAmerge -v L1.75.99 raw_reads.75.raw_reads.99.C0.S raw_reads.75.raw_reads.99.N0.S raw_reads.75.raw_reads.99.C1.S raw_reads.75.raw_reads.99.N1.S raw_reads.75.raw_reads.99.C2.S raw_reads.75.raw_reads.99.N2.S raw_reads.75.raw_reads.99.C3.S raw_reads.75.raw_reads.99.N3.S LAsort -v raw_reads.76.raw_reads.99.C0 raw_reads.76.raw_reads.99.N0 raw_reads.76.raw_reads.99.C1 raw_reads.76.raw_reads.99.N1 raw_reads.76.raw_reads.99.C2 raw_reads.76.raw_reads.99.N2 raw_reads.76.raw_reads.99.C3 raw_reads.76.raw_reads.99.N3 && LAmerge -v L1.76.99 raw_reads.76.raw_reads.99.C0.S raw_reads.76.raw_reads.99.N0.S raw_reads.76.raw_reads.99.C1.S raw_reads.76.raw_reads.99.N1.S raw_reads.76.raw_reads.99.C2.S raw_reads.76.raw_reads.99.N2.S raw_reads.76.raw_reads.99.C3.S raw_reads.76.raw_reads.99.N3.S LAsort -v raw_reads.77.raw_reads.99.C0 raw_reads.77.raw_reads.99.N0 raw_reads.77.raw_reads.99.C1 raw_reads.77.raw_reads.99.N1 raw_reads.77.raw_reads.99.C2 raw_reads.77.raw_reads.99.N2 raw_reads.77.raw_reads.99.C3 raw_reads.77.raw_reads.99.N3 && LAmerge -v L1.77.99 raw_reads.77.raw_reads.99.C0.S raw_reads.77.raw_reads.99.N0.S raw_reads.77.raw_reads.99.C1.S raw_reads.77.raw_reads.99.N1.S raw_reads.77.raw_reads.99.C2.S raw_reads.77.raw_reads.99.N2.S raw_reads.77.raw_reads.99.C3.S raw_reads.77.raw_reads.99.N3.S LAsort -v raw_reads.78.raw_reads.99.C0 raw_reads.78.raw_reads.99.N0 raw_reads.78.raw_reads.99.C1 raw_reads.78.raw_reads.99.N1 raw_reads.78.raw_reads.99.C2 raw_reads.78.raw_reads.99.N2 raw_reads.78.raw_reads.99.C3 raw_reads.78.raw_reads.99.N3 && LAmerge -v L1.78.99 raw_reads.78.raw_reads.99.C0.S raw_reads.78.raw_reads.99.N0.S raw_reads.78.raw_reads.99.C1.S raw_reads.78.raw_reads.99.N1.S raw_reads.78.raw_reads.99.C2.S raw_reads.78.raw_reads.99.N2.S raw_reads.78.raw_reads.99.C3.S raw_reads.78.raw_reads.99.N3.S LAsort -v raw_reads.79.raw_reads.99.C0 raw_reads.79.raw_reads.99.N0 raw_reads.79.raw_reads.99.C1 raw_reads.79.raw_reads.99.N1 raw_reads.79.raw_reads.99.C2 raw_reads.79.raw_reads.99.N2 raw_reads.79.raw_reads.99.C3 raw_reads.79.raw_reads.99.N3 && LAmerge -v L1.79.99 raw_reads.79.raw_reads.99.C0.S raw_reads.79.raw_reads.99.N0.S raw_reads.79.raw_reads.99.C1.S raw_reads.79.raw_reads.99.N1.S raw_reads.79.raw_reads.99.C2.S raw_reads.79.raw_reads.99.N2.S raw_reads.79.raw_reads.99.C3.S raw_reads.79.raw_reads.99.N3.S LAsort -v raw_reads.99.raw_reads.60.C0 raw_reads.99.raw_reads.60.N0 raw_reads.99.raw_reads.60.C1 raw_reads.99.raw_reads.60.N1 raw_reads.99.raw_reads.60.C2 raw_reads.99.raw_reads.60.N2 raw_reads.99.raw_reads.60.C3 raw_reads.99.raw_reads.60.N3 && LAmerge -v L1.99.60 raw_reads.99.raw_reads.60.C0.S raw_reads.99.raw_reads.60.N0.S raw_reads.99.raw_reads.60.C1.S raw_reads.99.raw_reads.60.N1.S raw_reads.99.raw_reads.60.C2.S raw_reads.99.raw_reads.60.N2.S raw_reads.99.raw_reads.60.C3.S raw_reads.99.raw_reads.60.N3.S LAsort -v raw_reads.99.raw_reads.61.C0 raw_reads.99.raw_reads.61.N0 raw_reads.99.raw_reads.61.C1 raw_reads.99.raw_reads.61.N1 raw_reads.99.raw_reads.61.C2 raw_reads.99.raw_reads.61.N2 raw_reads.99.raw_reads.61.C3 raw_reads.99.raw_reads.61.N3 && LAmerge -v L1.99.61 raw_reads.99.raw_reads.61.C0.S raw_reads.99.raw_reads.61.N0.S raw_reads.99.raw_reads.61.C1.S raw_reads.99.raw_reads.61.N1.S raw_reads.99.raw_reads.61.C2.S raw_reads.99.raw_reads.61.N2.S raw_reads.99.raw_reads.61.C3.S raw_reads.99.raw_reads.61.N3.S LAsort -v raw_reads.99.raw_reads.62.C0 raw_reads.99.raw_reads.62.N0 raw_reads.99.raw_reads.62.C1 raw_reads.99.raw_reads.62.N1 raw_reads.99.raw_reads.62.C2 raw_reads.99.raw_reads.62.N2 raw_reads.99.raw_reads.62.C3 raw_reads.99.raw_reads.62.N3 && LAmerge -v L1.99.62 raw_reads.99.raw_reads.62.C0.S raw_reads.99.raw_reads.62.N0.S raw_reads.99.raw_reads.62.C1.S raw_reads.99.raw_reads.62.N1.S raw_reads.99.raw_reads.62.C2.S raw_reads.99.raw_reads.62.N2.S raw_reads.99.raw_reads.62.C3.S raw_reads.99.raw_reads.62.N3.S LAsort -v raw_reads.99.raw_reads.63.C0 raw_reads.99.raw_reads.63.N0 raw_reads.99.raw_reads.63.C1 raw_reads.99.raw_reads.63.N1 raw_reads.99.raw_reads.63.C2 raw_reads.99.raw_reads.63.N2 raw_reads.99.raw_reads.63.C3 raw_reads.99.raw_reads.63.N3 && LAmerge -v L1.99.63 raw_reads.99.raw_reads.63.C0.S raw_reads.99.raw_reads.63.N0.S raw_reads.99.raw_reads.63.C1.S raw_reads.99.raw_reads.63.N1.S raw_reads.99.raw_reads.63.C2.S raw_reads.99.raw_reads.63.N2.S raw_reads.99.raw_reads.63.C3.S raw_reads.99.raw_reads.63.N3.S LAsort -v raw_reads.99.raw_reads.64.C0 raw_reads.99.raw_reads.64.N0 raw_reads.99.raw_reads.64.C1 raw_reads.99.raw_reads.64.N1 raw_reads.99.raw_reads.64.C2 raw_reads.99.raw_reads.64.N2 raw_reads.99.raw_reads.64.C3 raw_reads.99.raw_reads.64.N3 && LAmerge -v L1.99.64 raw_reads.99.raw_reads.64.C0.S raw_reads.99.raw_reads.64.N0.S raw_reads.99.raw_reads.64.C1.S raw_reads.99.raw_reads.64.N1.S raw_reads.99.raw_reads.64.C2.S raw_reads.99.raw_reads.64.N2.S raw_reads.99.raw_reads.64.C3.S raw_reads.99.raw_reads.64.N3.S LAsort -v raw_reads.99.raw_reads.65.C0 raw_reads.99.raw_reads.65.N0 raw_reads.99.raw_reads.65.C1 raw_reads.99.raw_reads.65.N1 raw_reads.99.raw_reads.65.C2 raw_reads.99.raw_reads.65.N2 raw_reads.99.raw_reads.65.C3 raw_reads.99.raw_reads.65.N3 && LAmerge -v L1.99.65 raw_reads.99.raw_reads.65.C0.S raw_reads.99.raw_reads.65.N0.S raw_reads.99.raw_reads.65.C1.S raw_reads.99.raw_reads.65.N1.S raw_reads.99.raw_reads.65.C2.S raw_reads.99.raw_reads.65.N2.S raw_reads.99.raw_reads.65.C3.S raw_reads.99.raw_reads.65.N3.S LAsort -v raw_reads.99.raw_reads.66.C0 raw_reads.99.raw_reads.66.N0 raw_reads.99.raw_reads.66.C1 raw_reads.99.raw_reads.66.N1 raw_reads.99.raw_reads.66.C2 raw_reads.99.raw_reads.66.N2 raw_reads.99.raw_reads.66.C3 raw_reads.99.raw_reads.66.N3 && LAmerge -v L1.99.66 raw_reads.99.raw_reads.66.C0.S raw_reads.99.raw_reads.66.N0.S raw_reads.99.raw_reads.66.C1.S raw_reads.99.raw_reads.66.N1.S raw_reads.99.raw_reads.66.C2.S raw_reads.99.raw_reads.66.N2.S raw_reads.99.raw_reads.66.C3.S raw_reads.99.raw_reads.66.N3.S LAsort -v raw_reads.99.raw_reads.67.C0 raw_reads.99.raw_reads.67.N0 raw_reads.99.raw_reads.67.C1 raw_reads.99.raw_reads.67.N1 raw_reads.99.raw_reads.67.C2 raw_reads.99.raw_reads.67.N2 raw_reads.99.raw_reads.67.C3 raw_reads.99.raw_reads.67.N3 && LAmerge -v L1.99.67 raw_reads.99.raw_reads.67.C0.S raw_reads.99.raw_reads.67.N0.S raw_reads.99.raw_reads.67.C1.S raw_reads.99.raw_reads.67.N1.S raw_reads.99.raw_reads.67.C2.S raw_reads.99.raw_reads.67.N2.S raw_reads.99.raw_reads.67.C3.S raw_reads.99.raw_reads.67.N3.S LAsort -v raw_reads.99.raw_reads.68.C0 raw_reads.99.raw_reads.68.N0 raw_reads.99.raw_reads.68.C1 raw_reads.99.raw_reads.68.N1 raw_reads.99.raw_reads.68.C2 raw_reads.99.raw_reads.68.N2 raw_reads.99.raw_reads.68.C3 raw_reads.99.raw_reads.68.N3 && LAmerge -v L1.99.68 raw_reads.99.raw_reads.68.C0.S raw_reads.99.raw_reads.68.N0.S raw_reads.99.raw_reads.68.C1.S raw_reads.99.raw_reads.68.N1.S raw_reads.99.raw_reads.68.C2.S raw_reads.99.raw_reads.68.N2.S raw_reads.99.raw_reads.68.C3.S raw_reads.99.raw_reads.68.N3.S LAsort -v raw_reads.99.raw_reads.69.C0 raw_reads.99.raw_reads.69.N0 raw_reads.99.raw_reads.69.C1 raw_reads.99.raw_reads.69.N1 raw_reads.99.raw_reads.69.C2 raw_reads.99.raw_reads.69.N2 raw_reads.99.raw_reads.69.C3 raw_reads.99.raw_reads.69.N3 && LAmerge -v L1.99.69 raw_reads.99.raw_reads.69.C0.S raw_reads.99.raw_reads.69.N0.S raw_reads.99.raw_reads.69.C1.S raw_reads.99.raw_reads.69.N1.S raw_reads.99.raw_reads.69.C2.S raw_reads.99.raw_reads.69.N2.S raw_reads.99.raw_reads.69.C3.S raw_reads.99.raw_reads.69.N3.S LAsort -v raw_reads.99.raw_reads.70.C0 raw_reads.99.raw_reads.70.N0 raw_reads.99.raw_reads.70.C1 raw_reads.99.raw_reads.70.N1 raw_reads.99.raw_reads.70.C2 raw_reads.99.raw_reads.70.N2 raw_reads.99.raw_reads.70.C3 raw_reads.99.raw_reads.70.N3 && LAmerge -v L1.99.70 raw_reads.99.raw_reads.70.C0.S raw_reads.99.raw_reads.70.N0.S raw_reads.99.raw_reads.70.C1.S raw_reads.99.raw_reads.70.N1.S raw_reads.99.raw_reads.70.C2.S raw_reads.99.raw_reads.70.N2.S raw_reads.99.raw_reads.70.C3.S raw_reads.99.raw_reads.70.N3.S LAsort -v raw_reads.99.raw_reads.71.C0 raw_reads.99.raw_reads.71.N0 raw_reads.99.raw_reads.71.C1 raw_reads.99.raw_reads.71.N1 raw_reads.99.raw_reads.71.C2 raw_reads.99.raw_reads.71.N2 raw_reads.99.raw_reads.71.C3 raw_reads.99.raw_reads.71.N3 && LAmerge -v L1.99.71 raw_reads.99.raw_reads.71.C0.S raw_reads.99.raw_reads.71.N0.S raw_reads.99.raw_reads.71.C1.S raw_reads.99.raw_reads.71.N1.S raw_reads.99.raw_reads.71.C2.S raw_reads.99.raw_reads.71.N2.S raw_reads.99.raw_reads.71.C3.S raw_reads.99.raw_reads.71.N3.S LAsort -v raw_reads.99.raw_reads.72.C0 raw_reads.99.raw_reads.72.N0 raw_reads.99.raw_reads.72.C1 raw_reads.99.raw_reads.72.N1 raw_reads.99.raw_reads.72.C2 raw_reads.99.raw_reads.72.N2 raw_reads.99.raw_reads.72.C3 raw_reads.99.raw_reads.72.N3 && LAmerge -v L1.99.72 raw_reads.99.raw_reads.72.C0.S raw_reads.99.raw_reads.72.N0.S raw_reads.99.raw_reads.72.C1.S raw_reads.99.raw_reads.72.N1.S raw_reads.99.raw_reads.72.C2.S raw_reads.99.raw_reads.72.N2.S raw_reads.99.raw_reads.72.C3.S raw_reads.99.raw_reads.72.N3.S LAsort -v raw_reads.99.raw_reads.73.C0 raw_reads.99.raw_reads.73.N0 raw_reads.99.raw_reads.73.C1 raw_reads.99.raw_reads.73.N1 raw_reads.99.raw_reads.73.C2 raw_reads.99.raw_reads.73.N2 raw_reads.99.raw_reads.73.C3 raw_reads.99.raw_reads.73.N3 && LAmerge -v L1.99.73 raw_reads.99.raw_reads.73.C0.S raw_reads.99.raw_reads.73.N0.S raw_reads.99.raw_reads.73.C1.S raw_reads.99.raw_reads.73.N1.S raw_reads.99.raw_reads.73.C2.S raw_reads.99.raw_reads.73.N2.S raw_reads.99.raw_reads.73.C3.S raw_reads.99.raw_reads.73.N3.S LAsort -v raw_reads.99.raw_reads.74.C0 raw_reads.99.raw_reads.74.N0 raw_reads.99.raw_reads.74.C1 raw_reads.99.raw_reads.74.N1 raw_reads.99.raw_reads.74.C2 raw_reads.99.raw_reads.74.N2 raw_reads.99.raw_reads.74.C3 raw_reads.99.raw_reads.74.N3 && LAmerge -v L1.99.74 raw_reads.99.raw_reads.74.C0.S raw_reads.99.raw_reads.74.N0.S raw_reads.99.raw_reads.74.C1.S raw_reads.99.raw_reads.74.N1.S raw_reads.99.raw_reads.74.C2.S raw_reads.99.raw_reads.74.N2.S raw_reads.99.raw_reads.74.C3.S raw_reads.99.raw_reads.74.N3.S LAsort -v raw_reads.99.raw_reads.75.C0 raw_reads.99.raw_reads.75.N0 raw_reads.99.raw_reads.75.C1 raw_reads.99.raw_reads.75.N1 raw_reads.99.raw_reads.75.C2 raw_reads.99.raw_reads.75.N2 raw_reads.99.raw_reads.75.C3 raw_reads.99.raw_reads.75.N3 && LAmerge -v L1.99.75 raw_reads.99.raw_reads.75.C0.S raw_reads.99.raw_reads.75.N0.S raw_reads.99.raw_reads.75.C1.S raw_reads.99.raw_reads.75.N1.S raw_reads.99.raw_reads.75.C2.S raw_reads.99.raw_reads.75.N2.S raw_reads.99.raw_reads.75.C3.S raw_reads.99.raw_reads.75.N3.S LAsort -v raw_reads.99.raw_reads.76.C0 raw_reads.99.raw_reads.76.N0 raw_reads.99.raw_reads.76.C1 raw_reads.99.raw_reads.76.N1 raw_reads.99.raw_reads.76.C2 raw_reads.99.raw_reads.76.N2 raw_reads.99.raw_reads.76.C3 raw_reads.99.raw_reads.76.N3 && LAmerge -v L1.99.76 raw_reads.99.raw_reads.76.C0.S raw_reads.99.raw_reads.76.N0.S raw_reads.99.raw_reads.76.C1.S raw_reads.99.raw_reads.76.N1.S raw_reads.99.raw_reads.76.C2.S raw_reads.99.raw_reads.76.N2.S raw_reads.99.raw_reads.76.C3.S raw_reads.99.raw_reads.76.N3.S LAsort -v raw_reads.99.raw_reads.77.C0 raw_reads.99.raw_reads.77.N0 raw_reads.99.raw_reads.77.C1 raw_reads.99.raw_reads.77.N1 raw_reads.99.raw_reads.77.C2 raw_reads.99.raw_reads.77.N2 raw_reads.99.raw_reads.77.C3 raw_reads.99.raw_reads.77.N3 && LAmerge -v L1.99.77 raw_reads.99.raw_reads.77.C0.S raw_reads.99.raw_reads.77.N0.S raw_reads.99.raw_reads.77.C1.S raw_reads.99.raw_reads.77.N1.S raw_reads.99.raw_reads.77.C2.S raw_reads.99.raw_reads.77.N2.S raw_reads.99.raw_reads.77.C3.S raw_reads.99.raw_reads.77.N3.S LAsort -v raw_reads.99.raw_reads.78.C0 raw_reads.99.raw_reads.78.N0 raw_reads.99.raw_reads.78.C1 raw_reads.99.raw_reads.78.N1 raw_reads.99.raw_reads.78.C2 raw_reads.99.raw_reads.78.N2 raw_reads.99.raw_reads.78.C3 raw_reads.99.raw_reads.78.N3 && LAmerge -v L1.99.78 raw_reads.99.raw_reads.78.C0.S raw_reads.99.raw_reads.78.N0.S raw_reads.99.raw_reads.78.C1.S raw_reads.99.raw_reads.78.N1.S raw_reads.99.raw_reads.78.C2.S raw_reads.99.raw_reads.78.N2.S raw_reads.99.raw_reads.78.C3.S raw_reads.99.raw_reads.78.N3.S LAsort -v raw_reads.99.raw_reads.79.C0 raw_reads.99.raw_reads.79.N0 raw_reads.99.raw_reads.79.C1 raw_reads.99.raw_reads.79.N1 raw_reads.99.raw_reads.79.C2 raw_reads.99.raw_reads.79.N2 raw_reads.99.raw_reads.79.C3 raw_reads.99.raw_reads.79.N3 && LAmerge -v L1.99.79 raw_reads.99.raw_reads.79.C0.S raw_reads.99.raw_reads.79.N0.S raw_reads.99.raw_reads.79.C1.S raw_reads.99.raw_reads.79.N1.S raw_reads.99.raw_reads.79.C2.S raw_reads.99.raw_reads.79.N2.S raw_reads.99.raw_reads.79.C3.S raw_reads.99.raw_reads.79.N3.S LAcheck -vS raw_reads L1.60.99 LAcheck -vS raw_reads L1.61.99 LAcheck -vS raw_reads L1.62.99 LAcheck -vS raw_reads L1.63.99 LAcheck -vS raw_reads L1.64.99 LAcheck -vS raw_reads L1.65.99 LAcheck -vS raw_reads L1.66.99 LAcheck -vS raw_reads L1.67.99 LAcheck -vS raw_reads L1.68.99 LAcheck -vS raw_reads L1.69.99 LAcheck -vS raw_reads L1.70.99 LAcheck -vS raw_reads L1.71.99 LAcheck -vS raw_reads L1.72.99 LAcheck -vS raw_reads L1.73.99 LAcheck -vS raw_reads L1.74.99 LAcheck -vS raw_reads L1.75.99 LAcheck -vS raw_reads L1.76.99 LAcheck -vS raw_reads L1.77.99 LAcheck -vS raw_reads L1.78.99 LAcheck -vS raw_reads L1.79.99 LAcheck -vS raw_reads L1.99.60 LAcheck -vS raw_reads L1.99.61 LAcheck -vS raw_reads L1.99.62 LAcheck -vS raw_reads L1.99.63 LAcheck -vS raw_reads L1.99.64 LAcheck -vS raw_reads L1.99.65 LAcheck -vS raw_reads L1.99.66 LAcheck -vS raw_reads L1.99.67 LAcheck -vS raw_reads L1.99.68 LAcheck -vS raw_reads L1.99.69 LAcheck -vS raw_reads L1.99.70 LAcheck -vS raw_reads L1.99.71 LAcheck -vS raw_reads L1.99.72 LAcheck -vS raw_reads L1.99.73 LAcheck -vS raw_reads L1.99.74 LAcheck -vS raw_reads L1.99.75 LAcheck -vS raw_reads L1.99.76 LAcheck -vS raw_reads L1.99.77 LAcheck -vS raw_reads L1.99.78 LAcheck -vS raw_reads L1.99.79 daligner -v -k18 -h70 -t14 -H7000 -e0.75 raw_reads.40 raw_reads.21 raw_reads.22 raw_reads.23 raw_reads.24 raw_reads.25 raw_reads.26 raw_reads.27 raw_reads.28 raw_reads.29 raw_reads.30 raw_reads.31 raw_reads.32 raw_reads.33 raw_reads.34 raw_reads.35 raw_reads.36 raw_reads.37 raw_reads.38 raw_reads.39 raw_reads.40 LAcheck -v raw_reads *.las LAsort -v raw_reads.21.raw_reads.40.C0 raw_reads.21.raw_reads.40.N0 raw_reads.21.raw_reads.40.C1 raw_reads.21.raw_reads.40.N1 raw_reads.21.raw_reads.40.C2 raw_reads.21.raw_reads.40.N2 raw_reads.21.raw_reads.40.C3 raw_reads.21.raw_reads.40.N3 && LAmerge -v L1.21.40 raw_reads.21.raw_reads.40.C0.S raw_reads.21.raw_reads.40.N0.S raw_reads.21.raw_reads.40.C1.S raw_reads.21.raw_reads.40.N1.S raw_reads.21.raw_reads.40.C2.S raw_reads.21.raw_reads.40.N2.S raw_reads.21.raw_reads.40.C3.S raw_reads.21.raw_reads.40.N3.S LAsort -v raw_reads.22.raw_reads.40.C0 raw_reads.22.raw_reads.40.N0 raw_reads.22.raw_reads.40.C1 raw_reads.22.raw_reads.40.N1 raw_reads.22.raw_reads.40.C2 raw_reads.22.raw_reads.40.N2 raw_reads.22.raw_reads.40.C3 raw_reads.22.raw_reads.40.N3 && LAmerge -v L1.22.40 raw_reads.22.raw_reads.40.C0.S raw_reads.22.raw_reads.40.N0.S raw_reads.22.raw_reads.40.C1.S raw_reads.22.raw_reads.40.N1.S raw_reads.22.raw_reads.40.C2.S raw_reads.22.raw_reads.40.N2.S raw_reads.22.raw_reads.40.C3.S raw_reads.22.raw_reads.40.N3.S LAsort -v raw_reads.23.raw_reads.40.C0 raw_reads.23.raw_reads.40.N0 raw_reads.23.raw_reads.40.C1 raw_reads.23.raw_reads.40.N1 raw_reads.23.raw_reads.40.C2 raw_reads.23.raw_reads.40.N2 raw_reads.23.raw_reads.40.C3 raw_reads.23.raw_reads.40.N3 && LAmerge -v L1.23.40 raw_reads.23.raw_reads.40.C0.S raw_reads.23.raw_reads.40.N0.S raw_reads.23.raw_reads.40.C1.S raw_reads.23.raw_reads.40.N1.S raw_reads.23.raw_reads.40.C2.S raw_reads.23.raw_reads.40.N2.S raw_reads.23.raw_reads.40.C3.S raw_reads.23.raw_reads.40.N3.S LAsort -v raw_reads.24.raw_reads.40.C0 raw_reads.24.raw_reads.40.N0 raw_reads.24.raw_reads.40.C1 raw_reads.24.raw_reads.40.N1 raw_reads.24.raw_reads.40.C2 raw_reads.24.raw_reads.40.N2 raw_reads.24.raw_reads.40.C3 raw_reads.24.raw_reads.40.N3 && LAmerge -v L1.24.40 raw_reads.24.raw_reads.40.C0.S raw_reads.24.raw_reads.40.N0.S raw_reads.24.raw_reads.40.C1.S raw_reads.24.raw_reads.40.N1.S raw_reads.24.raw_reads.40.C2.S raw_reads.24.raw_reads.40.N2.S raw_reads.24.raw_reads.40.C3.S raw_reads.24.raw_reads.40.N3.S LAsort -v raw_reads.25.raw_reads.40.C0 raw_reads.25.raw_reads.40.N0 raw_reads.25.raw_reads.40.C1 raw_reads.25.raw_reads.40.N1 raw_reads.25.raw_reads.40.C2 raw_reads.25.raw_reads.40.N2 raw_reads.25.raw_reads.40.C3 raw_reads.25.raw_reads.40.N3 && LAmerge -v L1.25.40 raw_reads.25.raw_reads.40.C0.S raw_reads.25.raw_reads.40.N0.S raw_reads.25.raw_reads.40.C1.S raw_reads.25.raw_reads.40.N1.S raw_reads.25.raw_reads.40.C2.S raw_reads.25.raw_reads.40.N2.S raw_reads.25.raw_reads.40.C3.S raw_reads.25.raw_reads.40.N3.S LAsort -v raw_reads.26.raw_reads.40.C0 raw_reads.26.raw_reads.40.N0 raw_reads.26.raw_reads.40.C1 raw_reads.26.raw_reads.40.N1 raw_reads.26.raw_reads.40.C2 raw_reads.26.raw_reads.40.N2 raw_reads.26.raw_reads.40.C3 raw_reads.26.raw_reads.40.N3 && LAmerge -v L1.26.40 raw_reads.26.raw_reads.40.C0.S raw_reads.26.raw_reads.40.N0.S raw_reads.26.raw_reads.40.C1.S raw_reads.26.raw_reads.40.N1.S raw_reads.26.raw_reads.40.C2.S raw_reads.26.raw_reads.40.N2.S raw_reads.26.raw_reads.40.C3.S raw_reads.26.raw_reads.40.N3.S LAsort -v raw_reads.27.raw_reads.40.C0 raw_reads.27.raw_reads.40.N0 raw_reads.27.raw_reads.40.C1 raw_reads.27.raw_reads.40.N1 raw_reads.27.raw_reads.40.C2 raw_reads.27.raw_reads.40.N2 raw_reads.27.raw_reads.40.C3 raw_reads.27.raw_reads.40.N3 && LAmerge -v L1.27.40 raw_reads.27.raw_reads.40.C0.S raw_reads.27.raw_reads.40.N0.S raw_reads.27.raw_reads.40.C1.S raw_reads.27.raw_reads.40.N1.S raw_reads.27.raw_reads.40.C2.S raw_reads.27.raw_reads.40.N2.S raw_reads.27.raw_reads.40.C3.S raw_reads.27.raw_reads.40.N3.S LAsort -v raw_reads.28.raw_reads.40.C0 raw_reads.28.raw_reads.40.N0 raw_reads.28.raw_reads.40.C1 raw_reads.28.raw_reads.40.N1 raw_reads.28.raw_reads.40.C2 raw_reads.28.raw_reads.40.N2 raw_reads.28.raw_reads.40.C3 raw_reads.28.raw_reads.40.N3 && LAmerge -v L1.28.40 raw_reads.28.raw_reads.40.C0.S raw_reads.28.raw_reads.40.N0.S raw_reads.28.raw_reads.40.C1.S raw_reads.28.raw_reads.40.N1.S raw_reads.28.raw_reads.40.C2.S raw_reads.28.raw_reads.40.N2.S raw_reads.28.raw_reads.40.C3.S raw_reads.28.raw_reads.40.N3.S LAsort -v raw_reads.29.raw_reads.40.C0 raw_reads.29.raw_reads.40.N0 raw_reads.29.raw_reads.40.C1 raw_reads.29.raw_reads.40.N1 raw_reads.29.raw_reads.40.C2 raw_reads.29.raw_reads.40.N2 raw_reads.29.raw_reads.40.C3 raw_reads.29.raw_reads.40.N3 && LAmerge -v L1.29.40 raw_reads.29.raw_reads.40.C0.S raw_reads.29.raw_reads.40.N0.S raw_reads.29.raw_reads.40.C1.S raw_reads.29.raw_reads.40.N1.S raw_reads.29.raw_reads.40.C2.S raw_reads.29.raw_reads.40.N2.S raw_reads.29.raw_reads.40.C3.S raw_reads.29.raw_reads.40.N3.S LAsort -v raw_reads.30.raw_reads.40.C0 raw_reads.30.raw_reads.40.N0 raw_reads.30.raw_reads.40.C1 raw_reads.30.raw_reads.40.N1 raw_reads.30.raw_reads.40.C2 raw_reads.30.raw_reads.40.N2 raw_reads.30.raw_reads.40.C3 raw_reads.30.raw_reads.40.N3 && LAmerge -v L1.30.40 raw_reads.30.raw_reads.40.C0.S raw_reads.30.raw_reads.40.N0.S raw_reads.30.raw_reads.40.C1.S raw_reads.30.raw_reads.40.N1.S raw_reads.30.raw_reads.40.C2.S raw_reads.30.raw_reads.40.N2.S raw_reads.30.raw_reads.40.C3.S raw_reads.30.raw_reads.40.N3.S LAsort -v raw_reads.31.raw_reads.40.C0 raw_reads.31.raw_reads.40.N0 raw_reads.31.raw_reads.40.C1 raw_reads.31.raw_reads.40.N1 raw_reads.31.raw_reads.40.C2 raw_reads.31.raw_reads.40.N2 raw_reads.31.raw_reads.40.C3 raw_reads.31.raw_reads.40.N3 && LAmerge -v L1.31.40 raw_reads.31.raw_reads.40.C0.S raw_reads.31.raw_reads.40.N0.S raw_reads.31.raw_reads.40.C1.S raw_reads.31.raw_reads.40.N1.S raw_reads.31.raw_reads.40.C2.S raw_reads.31.raw_reads.40.N2.S raw_reads.31.raw_reads.40.C3.S raw_reads.31.raw_reads.40.N3.S LAsort -v raw_reads.32.raw_reads.40.C0 raw_reads.32.raw_reads.40.N0 raw_reads.32.raw_reads.40.C1 raw_reads.32.raw_reads.40.N1 raw_reads.32.raw_reads.40.C2 raw_reads.32.raw_reads.40.N2 raw_reads.32.raw_reads.40.C3 raw_reads.32.raw_reads.40.N3 && LAmerge -v L1.32.40 raw_reads.32.raw_reads.40.C0.S raw_reads.32.raw_reads.40.N0.S raw_reads.32.raw_reads.40.C1.S raw_reads.32.raw_reads.40.N1.S raw_reads.32.raw_reads.40.C2.S raw_reads.32.raw_reads.40.N2.S raw_reads.32.raw_reads.40.C3.S raw_reads.32.raw_reads.40.N3.S LAsort -v raw_reads.33.raw_reads.40.C0 raw_reads.33.raw_reads.40.N0 raw_reads.33.raw_reads.40.C1 raw_reads.33.raw_reads.40.N1 raw_reads.33.raw_reads.40.C2 raw_reads.33.raw_reads.40.N2 raw_reads.33.raw_reads.40.C3 raw_reads.33.raw_reads.40.N3 && LAmerge -v L1.33.40 raw_reads.33.raw_reads.40.C0.S raw_reads.33.raw_reads.40.N0.S raw_reads.33.raw_reads.40.C1.S raw_reads.33.raw_reads.40.N1.S raw_reads.33.raw_reads.40.C2.S raw_reads.33.raw_reads.40.N2.S raw_reads.33.raw_reads.40.C3.S raw_reads.33.raw_reads.40.N3.S LAsort -v raw_reads.34.raw_reads.40.C0 raw_reads.34.raw_reads.40.N0 raw_reads.34.raw_reads.40.C1 raw_reads.34.raw_reads.40.N1 raw_reads.34.raw_reads.40.C2 raw_reads.34.raw_reads.40.N2 raw_reads.34.raw_reads.40.C3 raw_reads.34.raw_reads.40.N3 && LAmerge -v L1.34.40 raw_reads.34.raw_reads.40.C0.S raw_reads.34.raw_reads.40.N0.S raw_reads.34.raw_reads.40.C1.S raw_reads.34.raw_reads.40.N1.S raw_reads.34.raw_reads.40.C2.S raw_reads.34.raw_reads.40.N2.S raw_reads.34.raw_reads.40.C3.S raw_reads.34.raw_reads.40.N3.S LAsort -v raw_reads.35.raw_reads.40.C0 raw_reads.35.raw_reads.40.N0 raw_reads.35.raw_reads.40.C1 raw_reads.35.raw_reads.40.N1 raw_reads.35.raw_reads.40.C2 raw_reads.35.raw_reads.40.N2 raw_reads.35.raw_reads.40.C3 raw_reads.35.raw_reads.40.N3 && LAmerge -v L1.35.40 raw_reads.35.raw_reads.40.C0.S raw_reads.35.raw_reads.40.N0.S raw_reads.35.raw_reads.40.C1.S raw_reads.35.raw_reads.40.N1.S raw_reads.35.raw_reads.40.C2.S raw_reads.35.raw_reads.40.N2.S raw_reads.35.raw_reads.40.C3.S raw_reads.35.raw_reads.40.N3.S LAsort -v raw_reads.36.raw_reads.40.C0 raw_reads.36.raw_reads.40.N0 raw_reads.36.raw_reads.40.C1 raw_reads.36.raw_reads.40.N1 raw_reads.36.raw_reads.40.C2 raw_reads.36.raw_reads.40.N2 raw_reads.36.raw_reads.40.C3 raw_reads.36.raw_reads.40.N3 && LAmerge -v L1.36.40 raw_reads.36.raw_reads.40.C0.S raw_reads.36.raw_reads.40.N0.S raw_reads.36.raw_reads.40.C1.S raw_reads.36.raw_reads.40.N1.S raw_reads.36.raw_reads.40.C2.S raw_reads.36.raw_reads.40.N2.S raw_reads.36.raw_reads.40.C3.S raw_reads.36.raw_reads.40.N3.S LAsort -v raw_reads.37.raw_reads.40.C0 raw_reads.37.raw_reads.40.N0 raw_reads.37.raw_reads.40.C1 raw_reads.37.raw_reads.40.N1 raw_reads.37.raw_reads.40.C2 raw_reads.37.raw_reads.40.N2 raw_reads.37.raw_reads.40.C3 raw_reads.37.raw_reads.40.N3 && LAmerge -v L1.37.40 raw_reads.37.raw_reads.40.C0.S raw_reads.37.raw_reads.40.N0.S raw_reads.37.raw_reads.40.C1.S raw_reads.37.raw_reads.40.N1.S raw_reads.37.raw_reads.40.C2.S raw_reads.37.raw_reads.40.N2.S raw_reads.37.raw_reads.40.C3.S raw_reads.37.raw_reads.40.N3.S LAsort -v raw_reads.38.raw_reads.40.C0 raw_reads.38.raw_reads.40.N0 raw_reads.38.raw_reads.40.C1 raw_reads.38.raw_reads.40.N1 raw_reads.38.raw_reads.40.C2 raw_reads.38.raw_reads.40.N2 raw_reads.38.raw_reads.40.C3 raw_reads.38.raw_reads.40.N3 && LAmerge -v L1.38.40 raw_reads.38.raw_reads.40.C0.S raw_reads.38.raw_reads.40.N0.S raw_reads.38.raw_reads.40.C1.S raw_reads.38.raw_reads.40.N1.S raw_reads.38.raw_reads.40.C2.S raw_reads.38.raw_reads.40.N2.S raw_reads.38.raw_reads.40.C3.S raw_reads.38.raw_reads.40.N3.S LAsort -v raw_reads.39.raw_reads.40.C0 raw_reads.39.raw_reads.40.N0 raw_reads.39.raw_reads.40.C1 raw_reads.39.raw_reads.40.N1 raw_reads.39.raw_reads.40.C2 raw_reads.39.raw_reads.40.N2 raw_reads.39.raw_reads.40.C3 raw_reads.39.raw_reads.40.N3 && LAmerge -v L1.39.40 raw_reads.39.raw_reads.40.C0.S raw_reads.39.raw_reads.40.N0.S raw_reads.39.raw_reads.40.C1.S raw_reads.39.raw_reads.40.N1.S raw_reads.39.raw_reads.40.C2.S raw_reads.39.raw_reads.40.N2.S raw_reads.39.raw_reads.40.C3.S raw_reads.39.raw_reads.40.N3.S LAsort -v raw_reads.40.raw_reads.21.C0 raw_reads.40.raw_reads.21.N0 raw_reads.40.raw_reads.21.C1 raw_reads.40.raw_reads.21.N1 raw_reads.40.raw_reads.21.C2 raw_reads.40.raw_reads.21.N2 raw_reads.40.raw_reads.21.C3 raw_reads.40.raw_reads.21.N3 && LAmerge -v L1.40.21 raw_reads.40.raw_reads.21.C0.S raw_reads.40.raw_reads.21.N0.S raw_reads.40.raw_reads.21.C1.S raw_reads.40.raw_reads.21.N1.S raw_reads.40.raw_reads.21.C2.S raw_reads.40.raw_reads.21.N2.S raw_reads.40.raw_reads.21.C3.S raw_reads.40.raw_reads.21.N3.S LAsort -v raw_reads.40.raw_reads.22.C0 raw_reads.40.raw_reads.22.N0 raw_reads.40.raw_reads.22.C1 raw_reads.40.raw_reads.22.N1 raw_reads.40.raw_reads.22.C2 raw_reads.40.raw_reads.22.N2 raw_reads.40.raw_reads.22.C3 raw_reads.40.raw_reads.22.N3 && LAmerge -v L1.40.22 raw_reads.40.raw_reads.22.C0.S raw_reads.40.raw_reads.22.N0.S raw_reads.40.raw_reads.22.C1.S raw_reads.40.raw_reads.22.N1.S raw_reads.40.raw_reads.22.C2.S raw_reads.40.raw_reads.22.N2.S raw_reads.40.raw_reads.22.C3.S raw_reads.40.raw_reads.22.N3.S LAsort -v raw_reads.40.raw_reads.23.C0 raw_reads.40.raw_reads.23.N0 raw_reads.40.raw_reads.23.C1 raw_reads.40.raw_reads.23.N1 raw_reads.40.raw_reads.23.C2 raw_reads.40.raw_reads.23.N2 raw_reads.40.raw_reads.23.C3 raw_reads.40.raw_reads.23.N3 && LAmerge -v L1.40.23 raw_reads.40.raw_reads.23.C0.S raw_reads.40.raw_reads.23.N0.S raw_reads.40.raw_reads.23.C1.S raw_reads.40.raw_reads.23.N1.S raw_reads.40.raw_reads.23.C2.S raw_reads.40.raw_reads.23.N2.S raw_reads.40.raw_reads.23.C3.S raw_reads.40.raw_reads.23.N3.S LAsort -v raw_reads.40.raw_reads.24.C0 raw_reads.40.raw_reads.24.N0 raw_reads.40.raw_reads.24.C1 raw_reads.40.raw_reads.24.N1 raw_reads.40.raw_reads.24.C2 raw_reads.40.raw_reads.24.N2 raw_reads.40.raw_reads.24.C3 raw_reads.40.raw_reads.24.N3 && LAmerge -v L1.40.24 raw_reads.40.raw_reads.24.C0.S raw_reads.40.raw_reads.24.N0.S raw_reads.40.raw_reads.24.C1.S raw_reads.40.raw_reads.24.N1.S raw_reads.40.raw_reads.24.C2.S raw_reads.40.raw_reads.24.N2.S raw_reads.40.raw_reads.24.C3.S raw_reads.40.raw_reads.24.N3.S LAsort -v raw_reads.40.raw_reads.25.C0 raw_reads.40.raw_reads.25.N0 raw_reads.40.raw_reads.25.C1 raw_reads.40.raw_reads.25.N1 raw_reads.40.raw_reads.25.C2 raw_reads.40.raw_reads.25.N2 raw_reads.40.raw_reads.25.C3 raw_reads.40.raw_reads.25.N3 && LAmerge -v L1.40.25 raw_reads.40.raw_reads.25.C0.S raw_reads.40.raw_reads.25.N0.S raw_reads.40.raw_reads.25.C1.S raw_reads.40.raw_reads.25.N1.S raw_reads.40.raw_reads.25.C2.S raw_reads.40.raw_reads.25.N2.S raw_reads.40.raw_reads.25.C3.S raw_reads.40.raw_reads.25.N3.S LAsort -v raw_reads.40.raw_reads.26.C0 raw_reads.40.raw_reads.26.N0 raw_reads.40.raw_reads.26.C1 raw_reads.40.raw_reads.26.N1 raw_reads.40.raw_reads.26.C2 raw_reads.40.raw_reads.26.N2 raw_reads.40.raw_reads.26.C3 raw_reads.40.raw_reads.26.N3 && LAmerge -v L1.40.26 raw_reads.40.raw_reads.26.C0.S raw_reads.40.raw_reads.26.N0.S raw_reads.40.raw_reads.26.C1.S raw_reads.40.raw_reads.26.N1.S raw_reads.40.raw_reads.26.C2.S raw_reads.40.raw_reads.26.N2.S raw_reads.40.raw_reads.26.C3.S raw_reads.40.raw_reads.26.N3.S LAsort -v raw_reads.40.raw_reads.27.C0 raw_reads.40.raw_reads.27.N0 raw_reads.40.raw_reads.27.C1 raw_reads.40.raw_reads.27.N1 raw_reads.40.raw_reads.27.C2 raw_reads.40.raw_reads.27.N2 raw_reads.40.raw_reads.27.C3 raw_reads.40.raw_reads.27.N3 && LAmerge -v L1.40.27 raw_reads.40.raw_reads.27.C0.S raw_reads.40.raw_reads.27.N0.S raw_reads.40.raw_reads.27.C1.S raw_reads.40.raw_reads.27.N1.S raw_reads.40.raw_reads.27.C2.S raw_reads.40.raw_reads.27.N2.S raw_reads.40.raw_reads.27.C3.S raw_reads.40.raw_reads.27.N3.S LAsort -v raw_reads.40.raw_reads.28.C0 raw_reads.40.raw_reads.28.N0 raw_reads.40.raw_reads.28.C1 raw_reads.40.raw_reads.28.N1 raw_reads.40.raw_reads.28.C2 raw_reads.40.raw_reads.28.N2 raw_reads.40.raw_reads.28.C3 raw_reads.40.raw_reads.28.N3 && LAmerge -v L1.40.28 raw_reads.40.raw_reads.28.C0.S raw_reads.40.raw_reads.28.N0.S raw_reads.40.raw_reads.28.C1.S raw_reads.40.raw_reads.28.N1.S raw_reads.40.raw_reads.28.C2.S raw_reads.40.raw_reads.28.N2.S raw_reads.40.raw_reads.28.C3.S raw_reads.40.raw_reads.28.N3.S LAsort -v raw_reads.40.raw_reads.29.C0 raw_reads.40.raw_reads.29.N0 raw_reads.40.raw_reads.29.C1 raw_reads.40.raw_reads.29.N1 raw_reads.40.raw_reads.29.C2 raw_reads.40.raw_reads.29.N2 raw_reads.40.raw_reads.29.C3 raw_reads.40.raw_reads.29.N3 && LAmerge -v L1.40.29 raw_reads.40.raw_reads.29.C0.S raw_reads.40.raw_reads.29.N0.S raw_reads.40.raw_reads.29.C1.S raw_reads.40.raw_reads.29.N1.S raw_reads.40.raw_reads.29.C2.S raw_reads.40.raw_reads.29.N2.S raw_reads.40.raw_reads.29.C3.S raw_reads.40.raw_reads.29.N3.S LAsort -v raw_reads.40.raw_reads.30.C0 raw_reads.40.raw_reads.30.N0 raw_reads.40.raw_reads.30.C1 raw_reads.40.raw_reads.30.N1 raw_reads.40.raw_reads.30.C2 raw_reads.40.raw_reads.30.N2 raw_reads.40.raw_reads.30.C3 raw_reads.40.raw_reads.30.N3 && LAmerge -v L1.40.30 raw_reads.40.raw_reads.30.C0.S raw_reads.40.raw_reads.30.N0.S raw_reads.40.raw_reads.30.C1.S raw_reads.40.raw_reads.30.N1.S raw_reads.40.raw_reads.30.C2.S raw_reads.40.raw_reads.30.N2.S raw_reads.40.raw_reads.30.C3.S raw_reads.40.raw_reads.30.N3.S LAsort -v raw_reads.40.raw_reads.31.C0 raw_reads.40.raw_reads.31.N0 raw_reads.40.raw_reads.31.C1 raw_reads.40.raw_reads.31.N1 raw_reads.40.raw_reads.31.C2 raw_reads.40.raw_reads.31.N2 raw_reads.40.raw_reads.31.C3 raw_reads.40.raw_reads.31.N3 && LAmerge -v L1.40.31 raw_reads.40.raw_reads.31.C0.S raw_reads.40.raw_reads.31.N0.S raw_reads.40.raw_reads.31.C1.S raw_reads.40.raw_reads.31.N1.S raw_reads.40.raw_reads.31.C2.S raw_reads.40.raw_reads.31.N2.S raw_reads.40.raw_reads.31.C3.S raw_reads.40.raw_reads.31.N3.S LAsort -v raw_reads.40.raw_reads.32.C0 raw_reads.40.raw_reads.32.N0 raw_reads.40.raw_reads.32.C1 raw_reads.40.raw_reads.32.N1 raw_reads.40.raw_reads.32.C2 raw_reads.40.raw_reads.32.N2 raw_reads.40.raw_reads.32.C3 raw_reads.40.raw_reads.32.N3 && LAmerge -v L1.40.32 raw_reads.40.raw_reads.32.C0.S raw_reads.40.raw_reads.32.N0.S raw_reads.40.raw_reads.32.C1.S raw_reads.40.raw_reads.32.N1.S raw_reads.40.raw_reads.32.C2.S raw_reads.40.raw_reads.32.N2.S raw_reads.40.raw_reads.32.C3.S raw_reads.40.raw_reads.32.N3.S LAsort -v raw_reads.40.raw_reads.33.C0 raw_reads.40.raw_reads.33.N0 raw_reads.40.raw_reads.33.C1 raw_reads.40.raw_reads.33.N1 raw_reads.40.raw_reads.33.C2 raw_reads.40.raw_reads.33.N2 raw_reads.40.raw_reads.33.C3 raw_reads.40.raw_reads.33.N3 && LAmerge -v L1.40.33 raw_reads.40.raw_reads.33.C0.S raw_reads.40.raw_reads.33.N0.S raw_reads.40.raw_reads.33.C1.S raw_reads.40.raw_reads.33.N1.S raw_reads.40.raw_reads.33.C2.S raw_reads.40.raw_reads.33.N2.S raw_reads.40.raw_reads.33.C3.S raw_reads.40.raw_reads.33.N3.S LAsort -v raw_reads.40.raw_reads.34.C0 raw_reads.40.raw_reads.34.N0 raw_reads.40.raw_reads.34.C1 raw_reads.40.raw_reads.34.N1 raw_reads.40.raw_reads.34.C2 raw_reads.40.raw_reads.34.N2 raw_reads.40.raw_reads.34.C3 raw_reads.40.raw_reads.34.N3 && LAmerge -v L1.40.34 raw_reads.40.raw_reads.34.C0.S raw_reads.40.raw_reads.34.N0.S raw_reads.40.raw_reads.34.C1.S raw_reads.40.raw_reads.34.N1.S raw_reads.40.raw_reads.34.C2.S raw_reads.40.raw_reads.34.N2.S raw_reads.40.raw_reads.34.C3.S raw_reads.40.raw_reads.34.N3.S LAsort -v raw_reads.40.raw_reads.35.C0 raw_reads.40.raw_reads.35.N0 raw_reads.40.raw_reads.35.C1 raw_reads.40.raw_reads.35.N1 raw_reads.40.raw_reads.35.C2 raw_reads.40.raw_reads.35.N2 raw_reads.40.raw_reads.35.C3 raw_reads.40.raw_reads.35.N3 && LAmerge -v L1.40.35 raw_reads.40.raw_reads.35.C0.S raw_reads.40.raw_reads.35.N0.S raw_reads.40.raw_reads.35.C1.S raw_reads.40.raw_reads.35.N1.S raw_reads.40.raw_reads.35.C2.S raw_reads.40.raw_reads.35.N2.S raw_reads.40.raw_reads.35.C3.S raw_reads.40.raw_reads.35.N3.S LAsort -v raw_reads.40.raw_reads.36.C0 raw_reads.40.raw_reads.36.N0 raw_reads.40.raw_reads.36.C1 raw_reads.40.raw_reads.36.N1 raw_reads.40.raw_reads.36.C2 raw_reads.40.raw_reads.36.N2 raw_reads.40.raw_reads.36.C3 raw_reads.40.raw_reads.36.N3 && LAmerge -v L1.40.36 raw_reads.40.raw_reads.36.C0.S raw_reads.40.raw_reads.36.N0.S raw_reads.40.raw_reads.36.C1.S raw_reads.40.raw_reads.36.N1.S raw_reads.40.raw_reads.36.C2.S raw_reads.40.raw_reads.36.N2.S raw_reads.40.raw_reads.36.C3.S raw_reads.40.raw_reads.36.N3.S LAsort -v raw_reads.40.raw_reads.37.C0 raw_reads.40.raw_reads.37.N0 raw_reads.40.raw_reads.37.C1 raw_reads.40.raw_reads.37.N1 raw_reads.40.raw_reads.37.C2 raw_reads.40.raw_reads.37.N2 raw_reads.40.raw_reads.37.C3 raw_reads.40.raw_reads.37.N3 && LAmerge -v L1.40.37 raw_reads.40.raw_reads.37.C0.S raw_reads.40.raw_reads.37.N0.S raw_reads.40.raw_reads.37.C1.S raw_reads.40.raw_reads.37.N1.S raw_reads.40.raw_reads.37.C2.S raw_reads.40.raw_reads.37.N2.S raw_reads.40.raw_reads.37.C3.S raw_reads.40.raw_reads.37.N3.S LAsort -v raw_reads.40.raw_reads.38.C0 raw_reads.40.raw_reads.38.N0 raw_reads.40.raw_reads.38.C1 raw_reads.40.raw_reads.38.N1 raw_reads.40.raw_reads.38.C2 raw_reads.40.raw_reads.38.N2 raw_reads.40.raw_reads.38.C3 raw_reads.40.raw_reads.38.N3 && LAmerge -v L1.40.38 raw_reads.40.raw_reads.38.C0.S raw_reads.40.raw_reads.38.N0.S raw_reads.40.raw_reads.38.C1.S raw_reads.40.raw_reads.38.N1.S raw_reads.40.raw_reads.38.C2.S raw_reads.40.raw_reads.38.N2.S raw_reads.40.raw_reads.38.C3.S raw_reads.40.raw_reads.38.N3.S LAsort -v raw_reads.40.raw_reads.39.C0 raw_reads.40.raw_reads.39.N0 raw_reads.40.raw_reads.39.C1 raw_reads.40.raw_reads.39.N1 raw_reads.40.raw_reads.39.C2 raw_reads.40.raw_reads.39.N2 raw_reads.40.raw_reads.39.C3 raw_reads.40.raw_reads.39.N3 && LAmerge -v L1.40.39 raw_reads.40.raw_reads.39.C0.S raw_reads.40.raw_reads.39.N0.S raw_reads.40.raw_reads.39.C1.S raw_reads.40.raw_reads.39.N1.S raw_reads.40.raw_reads.39.C2.S raw_reads.40.raw_reads.39.N2.S raw_reads.40.raw_reads.39.C3.S raw_reads.40.raw_reads.39.N3.S LAsort -v raw_reads.40.raw_reads.40.C0 raw_reads.40.raw_reads.40.N0 raw_reads.40.raw_reads.40.C1 raw_reads.40.raw_reads.40.N1 raw_reads.40.raw_reads.40.C2 raw_reads.40.raw_reads.40.N2 raw_reads.40.raw_reads.40.C3 raw_reads.40.raw_reads.40.N3 && LAmerge -v L1.40.40 raw_reads.40.raw_reads.40.C0.S raw_reads.40.raw_reads.40.N0.S raw_reads.40.raw_reads.40.C1.S raw_reads.40.raw_reads.40.N1.S raw_reads.40.raw_reads.40.C2.S raw_reads.40.raw_reads.40.N2.S raw_reads.40.raw_reads.40.C3.S raw_reads.40.raw_reads.40.N3.S LAcheck -vS raw_reads L1.21.40 LAcheck -vS raw_reads L1.22.40 LAcheck -vS raw_reads L1.23.40 LAcheck -vS raw_reads L1.24.40 LAcheck -vS raw_reads L1.25.40 LAcheck -vS raw_reads L1.26.40 LAcheck -vS raw_reads L1.27.40 LAcheck -vS raw_reads L1.28.40 LAcheck -vS raw_reads L1.29.40 LAcheck -vS raw_reads L1.30.40 LAcheck -vS raw_reads L1.31.40 LAcheck -vS raw_reads L1.32.40 LAcheck -vS raw_reads L1.33.40 LAcheck -vS raw_reads L1.34.40 LAcheck -vS raw_reads L1.35.40 LAcheck -vS raw_reads L1.36.40 LAcheck -vS raw_reads L1.37.40 LAcheck -vS raw_reads L1.38.40 LAcheck -vS raw_reads L1.39.40 LAcheck -vS raw_reads L1.40.21 LAcheck -vS raw_reads L1.40.22 LAcheck -vS raw_reads L1.40.23 LAcheck -vS raw_reads L1.40.24 LAcheck -vS raw_reads L1.40.25 LAcheck -vS raw_reads L1.40.26 LAcheck -vS raw_reads L1.40.27 LAcheck -vS raw_reads L1.40.28 LAcheck -vS raw_reads L1.40.29 LAcheck -vS raw_reads L1.40.30 LAcheck -vS raw_reads L1.40.31 LAcheck -vS raw_reads L1.40.32 LAcheck -vS raw_reads L1.40.33 LAcheck -vS raw_reads L1.40.34 LAcheck -vS raw_reads L1.40.35 LAcheck -vS raw_reads L1.40.36 LAcheck -vS raw_reads L1.40.37 LAcheck -vS raw_reads L1.40.38 LAcheck -vS raw_reads L1.40.39 LAcheck -vS raw_reads L1.40.40 daligner -v -k18 -h70 -t14 -H7000 -e0.75 raw_reads.63 raw_reads.1 raw_reads.2 raw_reads.3 raw_reads.4 raw_reads.5 raw_reads.6 raw_reads.7 raw_reads.8 raw_reads.9 raw_reads.10 raw_reads.11 raw_reads.12 raw_reads.13 raw_reads.14 raw_reads.15 raw_reads.16 raw_reads.17 raw_reads.18 raw_reads.19 raw_reads.20 raw_reads.21 LAcheck -v raw_reads *.las LAsort -v raw_reads.1.raw_reads.63.C0 raw_reads.1.raw_reads.63.N0 raw_reads.1.raw_reads.63.C1 raw_reads.1.raw_reads.63.N1 raw_reads.1.raw_reads.63.C2 raw_reads.1.raw_reads.63.N2 raw_reads.1.raw_reads.63.C3 raw_reads.1.raw_reads.63.N3 && LAmerge -v L1.1.63 raw_reads.1.raw_reads.63.C0.S raw_reads.1.raw_reads.63.N0.S raw_reads.1.raw_reads.63.C1.S raw_reads.1.raw_reads.63.N1.S raw_reads.1.raw_reads.63.C2.S raw_reads.1.raw_reads.63.N2.S raw_reads.1.raw_reads.63.C3.S raw_reads.1.raw_reads.63.N3.S LAsort -v raw_reads.2.raw_reads.63.C0 raw_reads.2.raw_reads.63.N0 raw_reads.2.raw_reads.63.C1 raw_reads.2.raw_reads.63.N1 raw_reads.2.raw_reads.63.C2 raw_reads.2.raw_reads.63.N2 raw_reads.2.raw_reads.63.C3 raw_reads.2.raw_reads.63.N3 && LAmerge -v L1.2.63 raw_reads.2.raw_reads.63.C0.S raw_reads.2.raw_reads.63.N0.S raw_reads.2.raw_reads.63.C1.S raw_reads.2.raw_reads.63.N1.S raw_reads.2.raw_reads.63.C2.S raw_reads.2.raw_reads.63.N2.S raw_reads.2.raw_reads.63.C3.S raw_reads.2.raw_reads.63.N3.S LAsort -v raw_reads.3.raw_reads.63.C0 raw_reads.3.raw_reads.63.N0 raw_reads.3.raw_reads.63.C1 raw_reads.3.raw_reads.63.N1 raw_reads.3.raw_reads.63.C2 raw_reads.3.raw_reads.63.N2 raw_reads.3.raw_reads.63.C3 raw_reads.3.raw_reads.63.N3 && LAmerge -v L1.3.63 raw_reads.3.raw_reads.63.C0.S raw_reads.3.raw_reads.63.N0.S raw_reads.3.raw_reads.63.C1.S raw_reads.3.raw_reads.63.N1.S raw_reads.3.raw_reads.63.C2.S raw_reads.3.raw_reads.63.N2.S raw_reads.3.raw_reads.63.C3.S raw_reads.3.raw_reads.63.N3.S LAsort -v raw_reads.4.raw_reads.63.C0 raw_reads.4.raw_reads.63.N0 raw_reads.4.raw_reads.63.C1 raw_reads.4.raw_reads.63.N1 raw_reads.4.raw_reads.63.C2 raw_reads.4.raw_reads.63.N2 raw_reads.4.raw_reads.63.C3 raw_reads.4.raw_reads.63.N3 && LAmerge -v L1.4.63 raw_reads.4.raw_reads.63.C0.S raw_reads.4.raw_reads.63.N0.S raw_reads.4.raw_reads.63.C1.S raw_reads.4.raw_reads.63.N1.S raw_reads.4.raw_reads.63.C2.S raw_reads.4.raw_reads.63.N2.S raw_reads.4.raw_reads.63.C3.S raw_reads.4.raw_reads.63.N3.S LAsort -v raw_reads.5.raw_reads.63.C0 raw_reads.5.raw_reads.63.N0 raw_reads.5.raw_reads.63.C1 raw_reads.5.raw_reads.63.N1 raw_reads.5.raw_reads.63.C2 raw_reads.5.raw_reads.63.N2 raw_reads.5.raw_reads.63.C3 raw_reads.5.raw_reads.63.N3 && LAmerge -v L1.5.63 raw_reads.5.raw_reads.63.C0.S raw_reads.5.raw_reads.63.N0.S raw_reads.5.raw_reads.63.C1.S raw_reads.5.raw_reads.63.N1.S raw_reads.5.raw_reads.63.C2.S raw_reads.5.raw_reads.63.N2.S raw_reads.5.raw_reads.63.C3.S raw_reads.5.raw_reads.63.N3.S LAsort -v raw_reads.6.raw_reads.63.C0 raw_reads.6.raw_reads.63.N0 raw_reads.6.raw_reads.63.C1 raw_reads.6.raw_reads.63.N1 raw_reads.6.raw_reads.63.C2 raw_reads.6.raw_reads.63.N2 raw_reads.6.raw_reads.63.C3 raw_reads.6.raw_reads.63.N3 && LAmerge -v L1.6.63 raw_reads.6.raw_reads.63.C0.S raw_reads.6.raw_reads.63.N0.S raw_reads.6.raw_reads.63.C1.S raw_reads.6.raw_reads.63.N1.S raw_reads.6.raw_reads.63.C2.S raw_reads.6.raw_reads.63.N2.S raw_reads.6.raw_reads.63.C3.S raw_reads.6.raw_reads.63.N3.S LAsort -v raw_reads.7.raw_reads.63.C0 raw_reads.7.raw_reads.63.N0 raw_reads.7.raw_reads.63.C1 raw_reads.7.raw_reads.63.N1 raw_reads.7.raw_reads.63.C2 raw_reads.7.raw_reads.63.N2 raw_reads.7.raw_reads.63.C3 raw_reads.7.raw_reads.63.N3 && LAmerge -v L1.7.63 raw_reads.7.raw_reads.63.C0.S raw_reads.7.raw_reads.63.N0.S raw_reads.7.raw_reads.63.C1.S raw_reads.7.raw_reads.63.N1.S raw_reads.7.raw_reads.63.C2.S raw_reads.7.raw_reads.63.N2.S raw_reads.7.raw_reads.63.C3.S raw_reads.7.raw_reads.63.N3.S LAsort -v raw_reads.8.raw_reads.63.C0 raw_reads.8.raw_reads.63.N0 raw_reads.8.raw_reads.63.C1 raw_reads.8.raw_reads.63.N1 raw_reads.8.raw_reads.63.C2 raw_reads.8.raw_reads.63.N2 raw_reads.8.raw_reads.63.C3 raw_reads.8.raw_reads.63.N3 && LAmerge -v L1.8.63 raw_reads.8.raw_reads.63.C0.S raw_reads.8.raw_reads.63.N0.S raw_reads.8.raw_reads.63.C1.S raw_reads.8.raw_reads.63.N1.S raw_reads.8.raw_reads.63.C2.S raw_reads.8.raw_reads.63.N2.S raw_reads.8.raw_reads.63.C3.S raw_reads.8.raw_reads.63.N3.S LAsort -v raw_reads.9.raw_reads.63.C0 raw_reads.9.raw_reads.63.N0 raw_reads.9.raw_reads.63.C1 raw_reads.9.raw_reads.63.N1 raw_reads.9.raw_reads.63.C2 raw_reads.9.raw_reads.63.N2 raw_reads.9.raw_reads.63.C3 raw_reads.9.raw_reads.63.N3 && LAmerge -v L1.9.63 raw_reads.9.raw_reads.63.C0.S raw_reads.9.raw_reads.63.N0.S raw_reads.9.raw_reads.63.C1.S raw_reads.9.raw_reads.63.N1.S raw_reads.9.raw_reads.63.C2.S raw_reads.9.raw_reads.63.N2.S raw_reads.9.raw_reads.63.C3.S raw_reads.9.raw_reads.63.N3.S LAsort -v raw_reads.10.raw_reads.63.C0 raw_reads.10.raw_reads.63.N0 raw_reads.10.raw_reads.63.C1 raw_reads.10.raw_reads.63.N1 raw_reads.10.raw_reads.63.C2 raw_reads.10.raw_reads.63.N2 raw_reads.10.raw_reads.63.C3 raw_reads.10.raw_reads.63.N3 && LAmerge -v L1.10.63 raw_reads.10.raw_reads.63.C0.S raw_reads.10.raw_reads.63.N0.S raw_reads.10.raw_reads.63.C1.S raw_reads.10.raw_reads.63.N1.S raw_reads.10.raw_reads.63.C2.S raw_reads.10.raw_reads.63.N2.S raw_reads.10.raw_reads.63.C3.S raw_reads.10.raw_reads.63.N3.S LAsort -v raw_reads.11.raw_reads.63.C0 raw_reads.11.raw_reads.63.N0 raw_reads.11.raw_reads.63.C1 raw_reads.11.raw_reads.63.N1 raw_reads.11.raw_reads.63.C2 raw_reads.11.raw_reads.63.N2 raw_reads.11.raw_reads.63.C3 raw_reads.11.raw_reads.63.N3 && LAmerge -v L1.11.63 raw_reads.11.raw_reads.63.C0.S raw_reads.11.raw_reads.63.N0.S raw_reads.11.raw_reads.63.C1.S raw_reads.11.raw_reads.63.N1.S raw_reads.11.raw_reads.63.C2.S raw_reads.11.raw_reads.63.N2.S raw_reads.11.raw_reads.63.C3.S raw_reads.11.raw_reads.63.N3.S LAsort -v raw_reads.12.raw_reads.63.C0 raw_reads.12.raw_reads.63.N0 raw_reads.12.raw_reads.63.C1 raw_reads.12.raw_reads.63.N1 raw_reads.12.raw_reads.63.C2 raw_reads.12.raw_reads.63.N2 raw_reads.12.raw_reads.63.C3 raw_reads.12.raw_reads.63.N3 && LAmerge -v L1.12.63 raw_reads.12.raw_reads.63.C0.S raw_reads.12.raw_reads.63.N0.S raw_reads.12.raw_reads.63.C1.S raw_reads.12.raw_reads.63.N1.S raw_reads.12.raw_reads.63.C2.S raw_reads.12.raw_reads.63.N2.S raw_reads.12.raw_reads.63.C3.S raw_reads.12.raw_reads.63.N3.S LAsort -v raw_reads.13.raw_reads.63.C0 raw_reads.13.raw_reads.63.N0 raw_reads.13.raw_reads.63.C1 raw_reads.13.raw_reads.63.N1 raw_reads.13.raw_reads.63.C2 raw_reads.13.raw_reads.63.N2 raw_reads.13.raw_reads.63.C3 raw_reads.13.raw_reads.63.N3 && LAmerge -v L1.13.63 raw_reads.13.raw_reads.63.C0.S raw_reads.13.raw_reads.63.N0.S raw_reads.13.raw_reads.63.C1.S raw_reads.13.raw_reads.63.N1.S raw_reads.13.raw_reads.63.C2.S raw_reads.13.raw_reads.63.N2.S raw_reads.13.raw_reads.63.C3.S raw_reads.13.raw_reads.63.N3.S LAsort -v raw_reads.14.raw_reads.63.C0 raw_reads.14.raw_reads.63.N0 raw_reads.14.raw_reads.63.C1 raw_reads.14.raw_reads.63.N1 raw_reads.14.raw_reads.63.C2 raw_reads.14.raw_reads.63.N2 raw_reads.14.raw_reads.63.C3 raw_reads.14.raw_reads.63.N3 && LAmerge -v L1.14.63 raw_reads.14.raw_reads.63.C0.S raw_reads.14.raw_reads.63.N0.S raw_reads.14.raw_reads.63.C1.S raw_reads.14.raw_reads.63.N1.S raw_reads.14.raw_reads.63.C2.S raw_reads.14.raw_reads.63.N2.S raw_reads.14.raw_reads.63.C3.S raw_reads.14.raw_reads.63.N3.S LAsort -v raw_reads.15.raw_reads.63.C0 raw_reads.15.raw_reads.63.N0 raw_reads.15.raw_reads.63.C1 raw_reads.15.raw_reads.63.N1 raw_reads.15.raw_reads.63.C2 raw_reads.15.raw_reads.63.N2 raw_reads.15.raw_reads.63.C3 raw_reads.15.raw_reads.63.N3 && LAmerge -v L1.15.63 raw_reads.15.raw_reads.63.C0.S raw_reads.15.raw_reads.63.N0.S raw_reads.15.raw_reads.63.C1.S raw_reads.15.raw_reads.63.N1.S raw_reads.15.raw_reads.63.C2.S raw_reads.15.raw_reads.63.N2.S raw_reads.15.raw_reads.63.C3.S raw_reads.15.raw_reads.63.N3.S LAsort -v raw_reads.16.raw_reads.63.C0 raw_reads.16.raw_reads.63.N0 raw_reads.16.raw_reads.63.C1 raw_reads.16.raw_reads.63.N1 raw_reads.16.raw_reads.63.C2 raw_reads.16.raw_reads.63.N2 raw_reads.16.raw_reads.63.C3 raw_reads.16.raw_reads.63.N3 && LAmerge -v L1.16.63 raw_reads.16.raw_reads.63.C0.S raw_reads.16.raw_reads.63.N0.S raw_reads.16.raw_reads.63.C1.S raw_reads.16.raw_reads.63.N1.S raw_reads.16.raw_reads.63.C2.S raw_reads.16.raw_reads.63.N2.S raw_reads.16.raw_reads.63.C3.S raw_reads.16.raw_reads.63.N3.S LAsort -v raw_reads.17.raw_reads.63.C0 raw_reads.17.raw_reads.63.N0 raw_reads.17.raw_reads.63.C1 raw_reads.17.raw_reads.63.N1 raw_reads.17.raw_reads.63.C2 raw_reads.17.raw_reads.63.N2 raw_reads.17.raw_reads.63.C3 raw_reads.17.raw_reads.63.N3 && LAmerge -v L1.17.63 raw_reads.17.raw_reads.63.C0.S raw_reads.17.raw_reads.63.N0.S raw_reads.17.raw_reads.63.C1.S raw_reads.17.raw_reads.63.N1.S raw_reads.17.raw_reads.63.C2.S raw_reads.17.raw_reads.63.N2.S raw_reads.17.raw_reads.63.C3.S raw_reads.17.raw_reads.63.N3.S LAsort -v raw_reads.18.raw_reads.63.C0 raw_reads.18.raw_reads.63.N0 raw_reads.18.raw_reads.63.C1 raw_reads.18.raw_reads.63.N1 raw_reads.18.raw_reads.63.C2 raw_reads.18.raw_reads.63.N2 raw_reads.18.raw_reads.63.C3 raw_reads.18.raw_reads.63.N3 && LAmerge -v L1.18.63 raw_reads.18.raw_reads.63.C0.S raw_reads.18.raw_reads.63.N0.S raw_reads.18.raw_reads.63.C1.S raw_reads.18.raw_reads.63.N1.S raw_reads.18.raw_reads.63.C2.S raw_reads.18.raw_reads.63.N2.S raw_reads.18.raw_reads.63.C3.S raw_reads.18.raw_reads.63.N3.S LAsort -v raw_reads.19.raw_reads.63.C0 raw_reads.19.raw_reads.63.N0 raw_reads.19.raw_reads.63.C1 raw_reads.19.raw_reads.63.N1 raw_reads.19.raw_reads.63.C2 raw_reads.19.raw_reads.63.N2 raw_reads.19.raw_reads.63.C3 raw_reads.19.raw_reads.63.N3 && LAmerge -v L1.19.63 raw_reads.19.raw_reads.63.C0.S raw_reads.19.raw_reads.63.N0.S raw_reads.19.raw_reads.63.C1.S raw_reads.19.raw_reads.63.N1.S raw_reads.19.raw_reads.63.C2.S raw_reads.19.raw_reads.63.N2.S raw_reads.19.raw_reads.63.C3.S raw_reads.19.raw_reads.63.N3.S LAsort -v raw_reads.20.raw_reads.63.C0 raw_reads.20.raw_reads.63.N0 raw_reads.20.raw_reads.63.C1 raw_reads.20.raw_reads.63.N1 raw_reads.20.raw_reads.63.C2 raw_reads.20.raw_reads.63.N2 raw_reads.20.raw_reads.63.C3 raw_reads.20.raw_reads.63.N3 && LAmerge -v L1.20.63 raw_reads.20.raw_reads.63.C0.S raw_reads.20.raw_reads.63.N0.S raw_reads.20.raw_reads.63.C1.S raw_reads.20.raw_reads.63.N1.S raw_reads.20.raw_reads.63.C2.S raw_reads.20.raw_reads.63.N2.S raw_reads.20.raw_reads.63.C3.S raw_reads.20.raw_reads.63.N3.S LAsort -v raw_reads.21.raw_reads.63.C0 raw_reads.21.raw_reads.63.N0 raw_reads.21.raw_reads.63.C1 raw_reads.21.raw_reads.63.N1 raw_reads.21.raw_reads.63.C2 raw_reads.21.raw_reads.63.N2 raw_reads.21.raw_reads.63.C3 raw_reads.21.raw_reads.63.N3 && LAmerge -v L1.21.63 raw_reads.21.raw_reads.63.C0.S raw_reads.21.raw_reads.63.N0.S raw_reads.21.raw_reads.63.C1.S raw_reads.21.raw_reads.63.N1.S raw_reads.21.raw_reads.63.C2.S raw_reads.21.raw_reads.63.N2.S raw_reads.21.raw_reads.63.C3.S raw_reads.21.raw_reads.63.N3.S LAsort -v raw_reads.63.raw_reads.1.C0 raw_reads.63.raw_reads.1.N0 raw_reads.63.raw_reads.1.C1 raw_reads.63.raw_reads.1.N1 raw_reads.63.raw_reads.1.C2 raw_reads.63.raw_reads.1.N2 raw_reads.63.raw_reads.1.C3 raw_reads.63.raw_reads.1.N3 && LAmerge -v L1.63.1 raw_reads.63.raw_reads.1.C0.S raw_reads.63.raw_reads.1.N0.S raw_reads.63.raw_reads.1.C1.S raw_reads.63.raw_reads.1.N1.S raw_reads.63.raw_reads.1.C2.S raw_reads.63.raw_reads.1.N2.S raw_reads.63.raw_reads.1.C3.S raw_reads.63.raw_reads.1.N3.S LAsort -v raw_reads.63.raw_reads.2.C0 raw_reads.63.raw_reads.2.N0 raw_reads.63.raw_reads.2.C1 raw_reads.63.raw_reads.2.N1 raw_reads.63.raw_reads.2.C2 raw_reads.63.raw_reads.2.N2 raw_reads.63.raw_reads.2.C3 raw_reads.63.raw_reads.2.N3 && LAmerge -v L1.63.2 raw_reads.63.raw_reads.2.C0.S raw_reads.63.raw_reads.2.N0.S raw_reads.63.raw_reads.2.C1.S raw_reads.63.raw_reads.2.N1.S raw_reads.63.raw_reads.2.C2.S raw_reads.63.raw_reads.2.N2.S raw_reads.63.raw_reads.2.C3.S raw_reads.63.raw_reads.2.N3.S LAsort -v raw_reads.63.raw_reads.3.C0 raw_reads.63.raw_reads.3.N0 raw_reads.63.raw_reads.3.C1 raw_reads.63.raw_reads.3.N1 raw_reads.63.raw_reads.3.C2 raw_reads.63.raw_reads.3.N2 raw_reads.63.raw_reads.3.C3 raw_reads.63.raw_reads.3.N3 && LAmerge -v L1.63.3 raw_reads.63.raw_reads.3.C0.S raw_reads.63.raw_reads.3.N0.S raw_reads.63.raw_reads.3.C1.S raw_reads.63.raw_reads.3.N1.S raw_reads.63.raw_reads.3.C2.S raw_reads.63.raw_reads.3.N2.S raw_reads.63.raw_reads.3.C3.S raw_reads.63.raw_reads.3.N3.S LAsort -v raw_reads.63.raw_reads.4.C0 raw_reads.63.raw_reads.4.N0 raw_reads.63.raw_reads.4.C1 raw_reads.63.raw_reads.4.N1 raw_reads.63.raw_reads.4.C2 raw_reads.63.raw_reads.4.N2 raw_reads.63.raw_reads.4.C3 raw_reads.63.raw_reads.4.N3 && LAmerge -v L1.63.4 raw_reads.63.raw_reads.4.C0.S raw_reads.63.raw_reads.4.N0.S raw_reads.63.raw_reads.4.C1.S raw_reads.63.raw_reads.4.N1.S raw_reads.63.raw_reads.4.C2.S raw_reads.63.raw_reads.4.N2.S raw_reads.63.raw_reads.4.C3.S raw_reads.63.raw_reads.4.N3.S LAsort -v raw_reads.63.raw_reads.5.C0 raw_reads.63.raw_reads.5.N0 raw_reads.63.raw_reads.5.C1 raw_reads.63.raw_reads.5.N1 raw_reads.63.raw_reads.5.C2 raw_reads.63.raw_reads.5.N2 raw_reads.63.raw_reads.5.C3 raw_reads.63.raw_reads.5.N3 && LAmerge -v L1.63.5 raw_reads.63.raw_reads.5.C0.S raw_reads.63.raw_reads.5.N0.S raw_reads.63.raw_reads.5.C1.S raw_reads.63.raw_reads.5.N1.S raw_reads.63.raw_reads.5.C2.S raw_reads.63.raw_reads.5.N2.S raw_reads.63.raw_reads.5.C3.S raw_reads.63.raw_reads.5.N3.S LAsort -v raw_reads.63.raw_reads.6.C0 raw_reads.63.raw_reads.6.N0 raw_reads.63.raw_reads.6.C1 raw_reads.63.raw_reads.6.N1 raw_reads.63.raw_reads.6.C2 raw_reads.63.raw_reads.6.N2 raw_reads.63.raw_reads.6.C3 raw_reads.63.raw_reads.6.N3 && LAmerge -v L1.63.6 raw_reads.63.raw_reads.6.C0.S raw_reads.63.raw_reads.6.N0.S raw_reads.63.raw_reads.6.C1.S raw_reads.63.raw_reads.6.N1.S raw_reads.63.raw_reads.6.C2.S raw_reads.63.raw_reads.6.N2.S raw_reads.63.raw_reads.6.C3.S raw_reads.63.raw_reads.6.N3.S LAsort -v raw_reads.63.raw_reads.7.C0 raw_reads.63.raw_reads.7.N0 raw_reads.63.raw_reads.7.C1 raw_reads.63.raw_reads.7.N1 raw_reads.63.raw_reads.7.C2 raw_reads.63.raw_reads.7.N2 raw_reads.63.raw_reads.7.C3 raw_reads.63.raw_reads.7.N3 && LAmerge -v L1.63.7 raw_reads.63.raw_reads.7.C0.S raw_reads.63.raw_reads.7.N0.S raw_reads.63.raw_reads.7.C1.S raw_reads.63.raw_reads.7.N1.S raw_reads.63.raw_reads.7.C2.S raw_reads.63.raw_reads.7.N2.S raw_reads.63.raw_reads.7.C3.S raw_reads.63.raw_reads.7.N3.S LAsort -v raw_reads.63.raw_reads.8.C0 raw_reads.63.raw_reads.8.N0 raw_reads.63.raw_reads.8.C1 raw_reads.63.raw_reads.8.N1 raw_reads.63.raw_reads.8.C2 raw_reads.63.raw_reads.8.N2 raw_reads.63.raw_reads.8.C3 raw_reads.63.raw_reads.8.N3 && LAmerge -v L1.63.8 raw_reads.63.raw_reads.8.C0.S raw_reads.63.raw_reads.8.N0.S raw_reads.63.raw_reads.8.C1.S raw_reads.63.raw_reads.8.N1.S raw_reads.63.raw_reads.8.C2.S raw_reads.63.raw_reads.8.N2.S raw_reads.63.raw_reads.8.C3.S raw_reads.63.raw_reads.8.N3.S LAsort -v raw_reads.63.raw_reads.9.C0 raw_reads.63.raw_reads.9.N0 raw_reads.63.raw_reads.9.C1 raw_reads.63.raw_reads.9.N1 raw_reads.63.raw_reads.9.C2 raw_reads.63.raw_reads.9.N2 raw_reads.63.raw_reads.9.C3 raw_reads.63.raw_reads.9.N3 && LAmerge -v L1.63.9 raw_reads.63.raw_reads.9.C0.S raw_reads.63.raw_reads.9.N0.S raw_reads.63.raw_reads.9.C1.S raw_reads.63.raw_reads.9.N1.S raw_reads.63.raw_reads.9.C2.S raw_reads.63.raw_reads.9.N2.S raw_reads.63.raw_reads.9.C3.S raw_reads.63.raw_reads.9.N3.S LAsort -v raw_reads.63.raw_reads.10.C0 raw_reads.63.raw_reads.10.N0 raw_reads.63.raw_reads.10.C1 raw_reads.63.raw_reads.10.N1 raw_reads.63.raw_reads.10.C2 raw_reads.63.raw_reads.10.N2 raw_reads.63.raw_reads.10.C3 raw_reads.63.raw_reads.10.N3 && LAmerge -v L1.63.10 raw_reads.63.raw_reads.10.C0.S raw_reads.63.raw_reads.10.N0.S raw_reads.63.raw_reads.10.C1.S raw_reads.63.raw_reads.10.N1.S raw_reads.63.raw_reads.10.C2.S raw_reads.63.raw_reads.10.N2.S raw_reads.63.raw_reads.10.C3.S raw_reads.63.raw_reads.10.N3.S LAsort -v raw_reads.63.raw_reads.11.C0 raw_reads.63.raw_reads.11.N0 raw_reads.63.raw_reads.11.C1 raw_reads.63.raw_reads.11.N1 raw_reads.63.raw_reads.11.C2 raw_reads.63.raw_reads.11.N2 raw_reads.63.raw_reads.11.C3 raw_reads.63.raw_reads.11.N3 && LAmerge -v L1.63.11 raw_reads.63.raw_reads.11.C0.S raw_reads.63.raw_reads.11.N0.S raw_reads.63.raw_reads.11.C1.S raw_reads.63.raw_reads.11.N1.S raw_reads.63.raw_reads.11.C2.S raw_reads.63.raw_reads.11.N2.S raw_reads.63.raw_reads.11.C3.S raw_reads.63.raw_reads.11.N3.S LAsort -v raw_reads.63.raw_reads.12.C0 raw_reads.63.raw_reads.12.N0 raw_reads.63.raw_reads.12.C1 raw_reads.63.raw_reads.12.N1 raw_reads.63.raw_reads.12.C2 raw_reads.63.raw_reads.12.N2 raw_reads.63.raw_reads.12.C3 raw_reads.63.raw_reads.12.N3 && LAmerge -v L1.63.12 raw_reads.63.raw_reads.12.C0.S raw_reads.63.raw_reads.12.N0.S raw_reads.63.raw_reads.12.C1.S raw_reads.63.raw_reads.12.N1.S raw_reads.63.raw_reads.12.C2.S raw_reads.63.raw_reads.12.N2.S raw_reads.63.raw_reads.12.C3.S raw_reads.63.raw_reads.12.N3.S LAsort -v raw_reads.63.raw_reads.13.C0 raw_reads.63.raw_reads.13.N0 raw_reads.63.raw_reads.13.C1 raw_reads.63.raw_reads.13.N1 raw_reads.63.raw_reads.13.C2 raw_reads.63.raw_reads.13.N2 raw_reads.63.raw_reads.13.C3 raw_reads.63.raw_reads.13.N3 && LAmerge -v L1.63.13 raw_reads.63.raw_reads.13.C0.S raw_reads.63.raw_reads.13.N0.S raw_reads.63.raw_reads.13.C1.S raw_reads.63.raw_reads.13.N1.S raw_reads.63.raw_reads.13.C2.S raw_reads.63.raw_reads.13.N2.S raw_reads.63.raw_reads.13.C3.S raw_reads.63.raw_reads.13.N3.S LAsort -v raw_reads.63.raw_reads.14.C0 raw_reads.63.raw_reads.14.N0 raw_reads.63.raw_reads.14.C1 raw_reads.63.raw_reads.14.N1 raw_reads.63.raw_reads.14.C2 raw_reads.63.raw_reads.14.N2 raw_reads.63.raw_reads.14.C3 raw_reads.63.raw_reads.14.N3 && LAmerge -v L1.63.14 raw_reads.63.raw_reads.14.C0.S raw_reads.63.raw_reads.14.N0.S raw_reads.63.raw_reads.14.C1.S raw_reads.63.raw_reads.14.N1.S raw_reads.63.raw_reads.14.C2.S raw_reads.63.raw_reads.14.N2.S raw_reads.63.raw_reads.14.C3.S raw_reads.63.raw_reads.14.N3.S LAsort -v raw_reads.63.raw_reads.15.C0 raw_reads.63.raw_reads.15.N0 raw_reads.63.raw_reads.15.C1 raw_reads.63.raw_reads.15.N1 raw_reads.63.raw_reads.15.C2 raw_reads.63.raw_reads.15.N2 raw_reads.63.raw_reads.15.C3 raw_reads.63.raw_reads.15.N3 && LAmerge -v L1.63.15 raw_reads.63.raw_reads.15.C0.S raw_reads.63.raw_reads.15.N0.S raw_reads.63.raw_reads.15.C1.S raw_reads.63.raw_reads.15.N1.S raw_reads.63.raw_reads.15.C2.S raw_reads.63.raw_reads.15.N2.S raw_reads.63.raw_reads.15.C3.S raw_reads.63.raw_reads.15.N3.S LAsort -v raw_reads.63.raw_reads.16.C0 raw_reads.63.raw_reads.16.N0 raw_reads.63.raw_reads.16.C1 raw_reads.63.raw_reads.16.N1 raw_reads.63.raw_reads.16.C2 raw_reads.63.raw_reads.16.N2 raw_reads.63.raw_reads.16.C3 raw_reads.63.raw_reads.16.N3 && LAmerge -v L1.63.16 raw_reads.63.raw_reads.16.C0.S raw_reads.63.raw_reads.16.N0.S raw_reads.63.raw_reads.16.C1.S raw_reads.63.raw_reads.16.N1.S raw_reads.63.raw_reads.16.C2.S raw_reads.63.raw_reads.16.N2.S raw_reads.63.raw_reads.16.C3.S raw_reads.63.raw_reads.16.N3.S LAsort -v raw_reads.63.raw_reads.17.C0 raw_reads.63.raw_reads.17.N0 raw_reads.63.raw_reads.17.C1 raw_reads.63.raw_reads.17.N1 raw_reads.63.raw_reads.17.C2 raw_reads.63.raw_reads.17.N2 raw_reads.63.raw_reads.17.C3 raw_reads.63.raw_reads.17.N3 && LAmerge -v L1.63.17 raw_reads.63.raw_reads.17.C0.S raw_reads.63.raw_reads.17.N0.S raw_reads.63.raw_reads.17.C1.S raw_reads.63.raw_reads.17.N1.S raw_reads.63.raw_reads.17.C2.S raw_reads.63.raw_reads.17.N2.S raw_reads.63.raw_reads.17.C3.S raw_reads.63.raw_reads.17.N3.S LAsort -v raw_reads.63.raw_reads.18.C0 raw_reads.63.raw_reads.18.N0 raw_reads.63.raw_reads.18.C1 raw_reads.63.raw_reads.18.N1 raw_reads.63.raw_reads.18.C2 raw_reads.63.raw_reads.18.N2 raw_reads.63.raw_reads.18.C3 raw_reads.63.raw_reads.18.N3 && LAmerge -v L1.63.18 raw_reads.63.raw_reads.18.C0.S raw_reads.63.raw_reads.18.N0.S raw_reads.63.raw_reads.18.C1.S raw_reads.63.raw_reads.18.N1.S raw_reads.63.raw_reads.18.C2.S raw_reads.63.raw_reads.18.N2.S raw_reads.63.raw_reads.18.C3.S raw_reads.63.raw_reads.18.N3.S LAsort -v raw_reads.63.raw_reads.19.C0 raw_reads.63.raw_reads.19.N0 raw_reads.63.raw_reads.19.C1 raw_reads.63.raw_reads.19.N1 raw_reads.63.raw_reads.19.C2 raw_reads.63.raw_reads.19.N2 raw_reads.63.raw_reads.19.C3 raw_reads.63.raw_reads.19.N3 && LAmerge -v L1.63.19 raw_reads.63.raw_reads.19.C0.S raw_reads.63.raw_reads.19.N0.S raw_reads.63.raw_reads.19.C1.S raw_reads.63.raw_reads.19.N1.S raw_reads.63.raw_reads.19.C2.S raw_reads.63.raw_reads.19.N2.S raw_reads.63.raw_reads.19.C3.S raw_reads.63.raw_reads.19.N3.S LAsort -v raw_reads.63.raw_reads.20.C0 raw_reads.63.raw_reads.20.N0 raw_reads.63.raw_reads.20.C1 raw_reads.63.raw_reads.20.N1 raw_reads.63.raw_reads.20.C2 raw_reads.63.raw_reads.20.N2 raw_reads.63.raw_reads.20.C3 raw_reads.63.raw_reads.20.N3 && LAmerge -v L1.63.20 raw_reads.63.raw_reads.20.C0.S raw_reads.63.raw_reads.20.N0.S raw_reads.63.raw_reads.20.C1.S raw_reads.63.raw_reads.20.N1.S raw_reads.63.raw_reads.20.C2.S raw_reads.63.raw_reads.20.N2.S raw_reads.63.raw_reads.20.C3.S raw_reads.63.raw_reads.20.N3.S LAsort -v raw_reads.63.raw_reads.21.C0 raw_reads.63.raw_reads.21.N0 raw_reads.63.raw_reads.21.C1 raw_reads.63.raw_reads.21.N1 raw_reads.63.raw_reads.21.C2 raw_reads.63.raw_reads.21.N2 raw_reads.63.raw_reads.21.C3 raw_reads.63.raw_reads.21.N3 && LAmerge -v L1.63.21 raw_reads.63.raw_reads.21.C0.S raw_reads.63.raw_reads.21.N0.S raw_reads.63.raw_reads.21.C1.S raw_reads.63.raw_reads.21.N1.S raw_reads.63.raw_reads.21.C2.S raw_reads.63.raw_reads.21.N2.S raw_reads.63.raw_reads.21.C3.S raw_reads.63.raw_reads.21.N3.S LAcheck -vS raw_reads L1.1.63 LAcheck -vS raw_reads L1.2.63 LAcheck -vS raw_reads L1.3.63 LAcheck -vS raw_reads L1.4.63 LAcheck -vS raw_reads L1.5.63 LAcheck -vS raw_reads L1.6.63 LAcheck -vS raw_reads L1.7.63 LAcheck -vS raw_reads L1.8.63 LAcheck -vS raw_reads L1.9.63 LAcheck -vS raw_reads L1.10.63 LAcheck -vS raw_reads L1.11.63 LAcheck -vS raw_reads L1.12.63 LAcheck -vS raw_reads L1.13.63 LAcheck -vS raw_reads L1.14.63 LAcheck -vS raw_reads L1.15.63 LAcheck -vS raw_reads L1.16.63 LAcheck -vS raw_reads L1.17.63 LAcheck -vS raw_reads L1.18.63 LAcheck -vS raw_reads L1.19.63 LAcheck -vS raw_reads L1.20.63 LAcheck -vS raw_reads L1.21.63 LAcheck -vS raw_reads L1.63.1 LAcheck -vS raw_reads L1.63.2 LAcheck -vS raw_reads L1.63.3 LAcheck -vS raw_reads L1.63.4 LAcheck -vS raw_reads L1.63.5 LAcheck -vS raw_reads L1.63.6 LAcheck -vS raw_reads L1.63.7 LAcheck -vS raw_reads L1.63.8 LAcheck -vS raw_reads L1.63.9 LAcheck -vS raw_reads L1.63.10 LAcheck -vS raw_reads L1.63.11 LAcheck -vS raw_reads L1.63.12 LAcheck -vS raw_reads L1.63.13 LAcheck -vS raw_reads L1.63.14 LAcheck -vS raw_reads L1.63.15 LAcheck -vS raw_reads L1.63.16 LAcheck -vS raw_reads L1.63.17 LAcheck -vS raw_reads L1.63.18 LAcheck -vS raw_reads L1.63.19 LAcheck -vS raw_reads L1.63.20 LAcheck -vS raw_reads L1.63.21 daligner -v -k18 -h70 -t14 -H7000 -e0.75 raw_reads.50 raw_reads.34 raw_reads.35 raw_reads.36 raw_reads.37 raw_reads.38 raw_reads.39 raw_reads.40 raw_reads.41 raw_reads.42 raw_reads.43 raw_reads.44 raw_reads.45 raw_reads.46 raw_reads.47 raw_reads.48 raw_reads.49 raw_reads.50 LAcheck -v raw_reads *.las LAsort -v raw_reads.34.raw_reads.50.C0 raw_reads.34.raw_reads.50.N0 raw_reads.34.raw_reads.50.C1 raw_reads.34.raw_reads.50.N1 raw_reads.34.raw_reads.50.C2 raw_reads.34.raw_reads.50.N2 raw_reads.34.raw_reads.50.C3 raw_reads.34.raw_reads.50.N3 && LAmerge -v L1.34.50 raw_reads.34.raw_reads.50.C0.S raw_reads.34.raw_reads.50.N0.S raw_reads.34.raw_reads.50.C1.S raw_reads.34.raw_reads.50.N1.S raw_reads.34.raw_reads.50.C2.S raw_reads.34.raw_reads.50.N2.S raw_reads.34.raw_reads.50.C3.S raw_reads.34.raw_reads.50.N3.S LAsort -v raw_reads.35.raw_reads.50.C0 raw_reads.35.raw_reads.50.N0 raw_reads.35.raw_reads.50.C1 raw_reads.35.raw_reads.50.N1 raw_reads.35.raw_reads.50.C2 raw_reads.35.raw_reads.50.N2 raw_reads.35.raw_reads.50.C3 raw_reads.35.raw_reads.50.N3 && LAmerge -v L1.35.50 raw_reads.35.raw_reads.50.C0.S raw_reads.35.raw_reads.50.N0.S raw_reads.35.raw_reads.50.C1.S raw_reads.35.raw_reads.50.N1.S raw_reads.35.raw_reads.50.C2.S raw_reads.35.raw_reads.50.N2.S raw_reads.35.raw_reads.50.C3.S raw_reads.35.raw_reads.50.N3.S LAsort -v raw_reads.36.raw_reads.50.C0 raw_reads.36.raw_reads.50.N0 raw_reads.36.raw_reads.50.C1 raw_reads.36.raw_reads.50.N1 raw_reads.36.raw_reads.50.C2 raw_reads.36.raw_reads.50.N2 raw_reads.36.raw_reads.50.C3 raw_reads.36.raw_reads.50.N3 && LAmerge -v L1.36.50 raw_reads.36.raw_reads.50.C0.S raw_reads.36.raw_reads.50.N0.S raw_reads.36.raw_reads.50.C1.S raw_reads.36.raw_reads.50.N1.S raw_reads.36.raw_reads.50.C2.S raw_reads.36.raw_reads.50.N2.S raw_reads.36.raw_reads.50.C3.S raw_reads.36.raw_reads.50.N3.S LAsort -v raw_reads.37.raw_reads.50.C0 raw_reads.37.raw_reads.50.N0 raw_reads.37.raw_reads.50.C1 raw_reads.37.raw_reads.50.N1 raw_reads.37.raw_reads.50.C2 raw_reads.37.raw_reads.50.N2 raw_reads.37.raw_reads.50.C3 raw_reads.37.raw_reads.50.N3 && LAmerge -v L1.37.50 raw_reads.37.raw_reads.50.C0.S raw_reads.37.raw_reads.50.N0.S raw_reads.37.raw_reads.50.C1.S raw_reads.37.raw_reads.50.N1.S raw_reads.37.raw_reads.50.C2.S raw_reads.37.raw_reads.50.N2.S raw_reads.37.raw_reads.50.C3.S raw_reads.37.raw_reads.50.N3.S LAsort -v raw_reads.38.raw_reads.50.C0 raw_reads.38.raw_reads.50.N0 raw_reads.38.raw_reads.50.C1 raw_reads.38.raw_reads.50.N1 raw_reads.38.raw_reads.50.C2 raw_reads.38.raw_reads.50.N2 raw_reads.38.raw_reads.50.C3 raw_reads.38.raw_reads.50.N3 && LAmerge -v L1.38.50 raw_reads.38.raw_reads.50.C0.S raw_reads.38.raw_reads.50.N0.S raw_reads.38.raw_reads.50.C1.S raw_reads.38.raw_reads.50.N1.S raw_reads.38.raw_reads.50.C2.S raw_reads.38.raw_reads.50.N2.S raw_reads.38.raw_reads.50.C3.S raw_reads.38.raw_reads.50.N3.S LAsort -v raw_reads.39.raw_reads.50.C0 raw_reads.39.raw_reads.50.N0 raw_reads.39.raw_reads.50.C1 raw_reads.39.raw_reads.50.N1 raw_reads.39.raw_reads.50.C2 raw_reads.39.raw_reads.50.N2 raw_reads.39.raw_reads.50.C3 raw_reads.39.raw_reads.50.N3 && LAmerge -v L1.39.50 raw_reads.39.raw_reads.50.C0.S raw_reads.39.raw_reads.50.N0.S raw_reads.39.raw_reads.50.C1.S raw_reads.39.raw_reads.50.N1.S raw_reads.39.raw_reads.50.C2.S raw_reads.39.raw_reads.50.N2.S raw_reads.39.raw_reads.50.C3.S raw_reads.39.raw_reads.50.N3.S LAsort -v raw_reads.40.raw_reads.50.C0 raw_reads.40.raw_reads.50.N0 raw_reads.40.raw_reads.50.C1 raw_reads.40.raw_reads.50.N1 raw_reads.40.raw_reads.50.C2 raw_reads.40.raw_reads.50.N2 raw_reads.40.raw_reads.50.C3 raw_reads.40.raw_reads.50.N3 && LAmerge -v L1.40.50 raw_reads.40.raw_reads.50.C0.S raw_reads.40.raw_reads.50.N0.S raw_reads.40.raw_reads.50.C1.S raw_reads.40.raw_reads.50.N1.S raw_reads.40.raw_reads.50.C2.S raw_reads.40.raw_reads.50.N2.S raw_reads.40.raw_reads.50.C3.S raw_reads.40.raw_reads.50.N3.S LAsort -v raw_reads.41.raw_reads.50.C0 raw_reads.41.raw_reads.50.N0 raw_reads.41.raw_reads.50.C1 raw_reads.41.raw_reads.50.N1 raw_reads.41.raw_reads.50.C2 raw_reads.41.raw_reads.50.N2 raw_reads.41.raw_reads.50.C3 raw_reads.41.raw_reads.50.N3 && LAmerge -v L1.41.50 raw_reads.41.raw_reads.50.C0.S raw_reads.41.raw_reads.50.N0.S raw_reads.41.raw_reads.50.C1.S raw_reads.41.raw_reads.50.N1.S raw_reads.41.raw_reads.50.C2.S raw_reads.41.raw_reads.50.N2.S raw_reads.41.raw_reads.50.C3.S raw_reads.41.raw_reads.50.N3.S LAsort -v raw_reads.42.raw_reads.50.C0 raw_reads.42.raw_reads.50.N0 raw_reads.42.raw_reads.50.C1 raw_reads.42.raw_reads.50.N1 raw_reads.42.raw_reads.50.C2 raw_reads.42.raw_reads.50.N2 raw_reads.42.raw_reads.50.C3 raw_reads.42.raw_reads.50.N3 && LAmerge -v L1.42.50 raw_reads.42.raw_reads.50.C0.S raw_reads.42.raw_reads.50.N0.S raw_reads.42.raw_reads.50.C1.S raw_reads.42.raw_reads.50.N1.S raw_reads.42.raw_reads.50.C2.S raw_reads.42.raw_reads.50.N2.S raw_reads.42.raw_reads.50.C3.S raw_reads.42.raw_reads.50.N3.S LAsort -v raw_reads.43.raw_reads.50.C0 raw_reads.43.raw_reads.50.N0 raw_reads.43.raw_reads.50.C1 raw_reads.43.raw_reads.50.N1 raw_reads.43.raw_reads.50.C2 raw_reads.43.raw_reads.50.N2 raw_reads.43.raw_reads.50.C3 raw_reads.43.raw_reads.50.N3 && LAmerge -v L1.43.50 raw_reads.43.raw_reads.50.C0.S raw_reads.43.raw_reads.50.N0.S raw_reads.43.raw_reads.50.C1.S raw_reads.43.raw_reads.50.N1.S raw_reads.43.raw_reads.50.C2.S raw_reads.43.raw_reads.50.N2.S raw_reads.43.raw_reads.50.C3.S raw_reads.43.raw_reads.50.N3.S LAsort -v raw_reads.44.raw_reads.50.C0 raw_reads.44.raw_reads.50.N0 raw_reads.44.raw_reads.50.C1 raw_reads.44.raw_reads.50.N1 raw_reads.44.raw_reads.50.C2 raw_reads.44.raw_reads.50.N2 raw_reads.44.raw_reads.50.C3 raw_reads.44.raw_reads.50.N3 && LAmerge -v L1.44.50 raw_reads.44.raw_reads.50.C0.S raw_reads.44.raw_reads.50.N0.S raw_reads.44.raw_reads.50.C1.S raw_reads.44.raw_reads.50.N1.S raw_reads.44.raw_reads.50.C2.S raw_reads.44.raw_reads.50.N2.S raw_reads.44.raw_reads.50.C3.S raw_reads.44.raw_reads.50.N3.S LAsort -v raw_reads.45.raw_reads.50.C0 raw_reads.45.raw_reads.50.N0 raw_reads.45.raw_reads.50.C1 raw_reads.45.raw_reads.50.N1 raw_reads.45.raw_reads.50.C2 raw_reads.45.raw_reads.50.N2 raw_reads.45.raw_reads.50.C3 raw_reads.45.raw_reads.50.N3 && LAmerge -v L1.45.50 raw_reads.45.raw_reads.50.C0.S raw_reads.45.raw_reads.50.N0.S raw_reads.45.raw_reads.50.C1.S raw_reads.45.raw_reads.50.N1.S raw_reads.45.raw_reads.50.C2.S raw_reads.45.raw_reads.50.N2.S raw_reads.45.raw_reads.50.C3.S raw_reads.45.raw_reads.50.N3.S LAsort -v raw_reads.46.raw_reads.50.C0 raw_reads.46.raw_reads.50.N0 raw_reads.46.raw_reads.50.C1 raw_reads.46.raw_reads.50.N1 raw_reads.46.raw_reads.50.C2 raw_reads.46.raw_reads.50.N2 raw_reads.46.raw_reads.50.C3 raw_reads.46.raw_reads.50.N3 && LAmerge -v L1.46.50 raw_reads.46.raw_reads.50.C0.S raw_reads.46.raw_reads.50.N0.S raw_reads.46.raw_reads.50.C1.S raw_reads.46.raw_reads.50.N1.S raw_reads.46.raw_reads.50.C2.S raw_reads.46.raw_reads.50.N2.S raw_reads.46.raw_reads.50.C3.S raw_reads.46.raw_reads.50.N3.S LAsort -v raw_reads.47.raw_reads.50.C0 raw_reads.47.raw_reads.50.N0 raw_reads.47.raw_reads.50.C1 raw_reads.47.raw_reads.50.N1 raw_reads.47.raw_reads.50.C2 raw_reads.47.raw_reads.50.N2 raw_reads.47.raw_reads.50.C3 raw_reads.47.raw_reads.50.N3 && LAmerge -v L1.47.50 raw_reads.47.raw_reads.50.C0.S raw_reads.47.raw_reads.50.N0.S raw_reads.47.raw_reads.50.C1.S raw_reads.47.raw_reads.50.N1.S raw_reads.47.raw_reads.50.C2.S raw_reads.47.raw_reads.50.N2.S raw_reads.47.raw_reads.50.C3.S raw_reads.47.raw_reads.50.N3.S LAsort -v raw_reads.48.raw_reads.50.C0 raw_reads.48.raw_reads.50.N0 raw_reads.48.raw_reads.50.C1 raw_reads.48.raw_reads.50.N1 raw_reads.48.raw_reads.50.C2 raw_reads.48.raw_reads.50.N2 raw_reads.48.raw_reads.50.C3 raw_reads.48.raw_reads.50.N3 && LAmerge -v L1.48.50 raw_reads.48.raw_reads.50.C0.S raw_reads.48.raw_reads.50.N0.S raw_reads.48.raw_reads.50.C1.S raw_reads.48.raw_reads.50.N1.S raw_reads.48.raw_reads.50.C2.S raw_reads.48.raw_reads.50.N2.S raw_reads.48.raw_reads.50.C3.S raw_reads.48.raw_reads.50.N3.S LAsort -v raw_reads.49.raw_reads.50.C0 raw_reads.49.raw_reads.50.N0 raw_reads.49.raw_reads.50.C1 raw_reads.49.raw_reads.50.N1 raw_reads.49.raw_reads.50.C2 raw_reads.49.raw_reads.50.N2 raw_reads.49.raw_reads.50.C3 raw_reads.49.raw_reads.50.N3 && LAmerge -v L1.49.50 raw_reads.49.raw_reads.50.C0.S raw_reads.49.raw_reads.50.N0.S raw_reads.49.raw_reads.50.C1.S raw_reads.49.raw_reads.50.N1.S raw_reads.49.raw_reads.50.C2.S raw_reads.49.raw_reads.50.N2.S raw_reads.49.raw_reads.50.C3.S raw_reads.49.raw_reads.50.N3.S LAsort -v raw_reads.50.raw_reads.34.C0 raw_reads.50.raw_reads.34.N0 raw_reads.50.raw_reads.34.C1 raw_reads.50.raw_reads.34.N1 raw_reads.50.raw_reads.34.C2 raw_reads.50.raw_reads.34.N2 raw_reads.50.raw_reads.34.C3 raw_reads.50.raw_reads.34.N3 && LAmerge -v L1.50.34 raw_reads.50.raw_reads.34.C0.S raw_reads.50.raw_reads.34.N0.S raw_reads.50.raw_reads.34.C1.S raw_reads.50.raw_reads.34.N1.S raw_reads.50.raw_reads.34.C2.S raw_reads.50.raw_reads.34.N2.S raw_reads.50.raw_reads.34.C3.S raw_reads.50.raw_reads.34.N3.S LAsort -v raw_reads.50.raw_reads.35.C0 raw_reads.50.raw_reads.35.N0 raw_reads.50.raw_reads.35.C1 raw_reads.50.raw_reads.35.N1 raw_reads.50.raw_reads.35.C2 raw_reads.50.raw_reads.35.N2 raw_reads.50.raw_reads.35.C3 raw_reads.50.raw_reads.35.N3 && LAmerge -v L1.50.35 raw_reads.50.raw_reads.35.C0.S raw_reads.50.raw_reads.35.N0.S raw_reads.50.raw_reads.35.C1.S raw_reads.50.raw_reads.35.N1.S raw_reads.50.raw_reads.35.C2.S raw_reads.50.raw_reads.35.N2.S raw_reads.50.raw_reads.35.C3.S raw_reads.50.raw_reads.35.N3.S LAsort -v raw_reads.50.raw_reads.36.C0 raw_reads.50.raw_reads.36.N0 raw_reads.50.raw_reads.36.C1 raw_reads.50.raw_reads.36.N1 raw_reads.50.raw_reads.36.C2 raw_reads.50.raw_reads.36.N2 raw_reads.50.raw_reads.36.C3 raw_reads.50.raw_reads.36.N3 && LAmerge -v L1.50.36 raw_reads.50.raw_reads.36.C0.S raw_reads.50.raw_reads.36.N0.S raw_reads.50.raw_reads.36.C1.S raw_reads.50.raw_reads.36.N1.S raw_reads.50.raw_reads.36.C2.S raw_reads.50.raw_reads.36.N2.S raw_reads.50.raw_reads.36.C3.S raw_reads.50.raw_reads.36.N3.S LAsort -v raw_reads.50.raw_reads.37.C0 raw_reads.50.raw_reads.37.N0 raw_reads.50.raw_reads.37.C1 raw_reads.50.raw_reads.37.N1 raw_reads.50.raw_reads.37.C2 raw_reads.50.raw_reads.37.N2 raw_reads.50.raw_reads.37.C3 raw_reads.50.raw_reads.37.N3 && LAmerge -v L1.50.37 raw_reads.50.raw_reads.37.C0.S raw_reads.50.raw_reads.37.N0.S raw_reads.50.raw_reads.37.C1.S raw_reads.50.raw_reads.37.N1.S raw_reads.50.raw_reads.37.C2.S raw_reads.50.raw_reads.37.N2.S raw_reads.50.raw_reads.37.C3.S raw_reads.50.raw_reads.37.N3.S LAsort -v raw_reads.50.raw_reads.38.C0 raw_reads.50.raw_reads.38.N0 raw_reads.50.raw_reads.38.C1 raw_reads.50.raw_reads.38.N1 raw_reads.50.raw_reads.38.C2 raw_reads.50.raw_reads.38.N2 raw_reads.50.raw_reads.38.C3 raw_reads.50.raw_reads.38.N3 && LAmerge -v L1.50.38 raw_reads.50.raw_reads.38.C0.S raw_reads.50.raw_reads.38.N0.S raw_reads.50.raw_reads.38.C1.S raw_reads.50.raw_reads.38.N1.S raw_reads.50.raw_reads.38.C2.S raw_reads.50.raw_reads.38.N2.S raw_reads.50.raw_reads.38.C3.S raw_reads.50.raw_reads.38.N3.S LAsort -v raw_reads.50.raw_reads.39.C0 raw_reads.50.raw_reads.39.N0 raw_reads.50.raw_reads.39.C1 raw_reads.50.raw_reads.39.N1 raw_reads.50.raw_reads.39.C2 raw_reads.50.raw_reads.39.N2 raw_reads.50.raw_reads.39.C3 raw_reads.50.raw_reads.39.N3 && LAmerge -v L1.50.39 raw_reads.50.raw_reads.39.C0.S raw_reads.50.raw_reads.39.N0.S raw_reads.50.raw_reads.39.C1.S raw_reads.50.raw_reads.39.N1.S raw_reads.50.raw_reads.39.C2.S raw_reads.50.raw_reads.39.N2.S raw_reads.50.raw_reads.39.C3.S raw_reads.50.raw_reads.39.N3.S LAsort -v raw_reads.50.raw_reads.40.C0 raw_reads.50.raw_reads.40.N0 raw_reads.50.raw_reads.40.C1 raw_reads.50.raw_reads.40.N1 raw_reads.50.raw_reads.40.C2 raw_reads.50.raw_reads.40.N2 raw_reads.50.raw_reads.40.C3 raw_reads.50.raw_reads.40.N3 && LAmerge -v L1.50.40 raw_reads.50.raw_reads.40.C0.S raw_reads.50.raw_reads.40.N0.S raw_reads.50.raw_reads.40.C1.S raw_reads.50.raw_reads.40.N1.S raw_reads.50.raw_reads.40.C2.S raw_reads.50.raw_reads.40.N2.S raw_reads.50.raw_reads.40.C3.S raw_reads.50.raw_reads.40.N3.S LAsort -v raw_reads.50.raw_reads.41.C0 raw_reads.50.raw_reads.41.N0 raw_reads.50.raw_reads.41.C1 raw_reads.50.raw_reads.41.N1 raw_reads.50.raw_reads.41.C2 raw_reads.50.raw_reads.41.N2 raw_reads.50.raw_reads.41.C3 raw_reads.50.raw_reads.41.N3 && LAmerge -v L1.50.41 raw_reads.50.raw_reads.41.C0.S raw_reads.50.raw_reads.41.N0.S raw_reads.50.raw_reads.41.C1.S raw_reads.50.raw_reads.41.N1.S raw_reads.50.raw_reads.41.C2.S raw_reads.50.raw_reads.41.N2.S raw_reads.50.raw_reads.41.C3.S raw_reads.50.raw_reads.41.N3.S LAsort -v raw_reads.50.raw_reads.42.C0 raw_reads.50.raw_reads.42.N0 raw_reads.50.raw_reads.42.C1 raw_reads.50.raw_reads.42.N1 raw_reads.50.raw_reads.42.C2 raw_reads.50.raw_reads.42.N2 raw_reads.50.raw_reads.42.C3 raw_reads.50.raw_reads.42.N3 && LAmerge -v L1.50.42 raw_reads.50.raw_reads.42.C0.S raw_reads.50.raw_reads.42.N0.S raw_reads.50.raw_reads.42.C1.S raw_reads.50.raw_reads.42.N1.S raw_reads.50.raw_reads.42.C2.S raw_reads.50.raw_reads.42.N2.S raw_reads.50.raw_reads.42.C3.S raw_reads.50.raw_reads.42.N3.S LAsort -v raw_reads.50.raw_reads.43.C0 raw_reads.50.raw_reads.43.N0 raw_reads.50.raw_reads.43.C1 raw_reads.50.raw_reads.43.N1 raw_reads.50.raw_reads.43.C2 raw_reads.50.raw_reads.43.N2 raw_reads.50.raw_reads.43.C3 raw_reads.50.raw_reads.43.N3 && LAmerge -v L1.50.43 raw_reads.50.raw_reads.43.C0.S raw_reads.50.raw_reads.43.N0.S raw_reads.50.raw_reads.43.C1.S raw_reads.50.raw_reads.43.N1.S raw_reads.50.raw_reads.43.C2.S raw_reads.50.raw_reads.43.N2.S raw_reads.50.raw_reads.43.C3.S raw_reads.50.raw_reads.43.N3.S LAsort -v raw_reads.50.raw_reads.44.C0 raw_reads.50.raw_reads.44.N0 raw_reads.50.raw_reads.44.C1 raw_reads.50.raw_reads.44.N1 raw_reads.50.raw_reads.44.C2 raw_reads.50.raw_reads.44.N2 raw_reads.50.raw_reads.44.C3 raw_reads.50.raw_reads.44.N3 && LAmerge -v L1.50.44 raw_reads.50.raw_reads.44.C0.S raw_reads.50.raw_reads.44.N0.S raw_reads.50.raw_reads.44.C1.S raw_reads.50.raw_reads.44.N1.S raw_reads.50.raw_reads.44.C2.S raw_reads.50.raw_reads.44.N2.S raw_reads.50.raw_reads.44.C3.S raw_reads.50.raw_reads.44.N3.S LAsort -v raw_reads.50.raw_reads.45.C0 raw_reads.50.raw_reads.45.N0 raw_reads.50.raw_reads.45.C1 raw_reads.50.raw_reads.45.N1 raw_reads.50.raw_reads.45.C2 raw_reads.50.raw_reads.45.N2 raw_reads.50.raw_reads.45.C3 raw_reads.50.raw_reads.45.N3 && LAmerge -v L1.50.45 raw_reads.50.raw_reads.45.C0.S raw_reads.50.raw_reads.45.N0.S raw_reads.50.raw_reads.45.C1.S raw_reads.50.raw_reads.45.N1.S raw_reads.50.raw_reads.45.C2.S raw_reads.50.raw_reads.45.N2.S raw_reads.50.raw_reads.45.C3.S raw_reads.50.raw_reads.45.N3.S LAsort -v raw_reads.50.raw_reads.46.C0 raw_reads.50.raw_reads.46.N0 raw_reads.50.raw_reads.46.C1 raw_reads.50.raw_reads.46.N1 raw_reads.50.raw_reads.46.C2 raw_reads.50.raw_reads.46.N2 raw_reads.50.raw_reads.46.C3 raw_reads.50.raw_reads.46.N3 && LAmerge -v L1.50.46 raw_reads.50.raw_reads.46.C0.S raw_reads.50.raw_reads.46.N0.S raw_reads.50.raw_reads.46.C1.S raw_reads.50.raw_reads.46.N1.S raw_reads.50.raw_reads.46.C2.S raw_reads.50.raw_reads.46.N2.S raw_reads.50.raw_reads.46.C3.S raw_reads.50.raw_reads.46.N3.S LAsort -v raw_reads.50.raw_reads.47.C0 raw_reads.50.raw_reads.47.N0 raw_reads.50.raw_reads.47.C1 raw_reads.50.raw_reads.47.N1 raw_reads.50.raw_reads.47.C2 raw_reads.50.raw_reads.47.N2 raw_reads.50.raw_reads.47.C3 raw_reads.50.raw_reads.47.N3 && LAmerge -v L1.50.47 raw_reads.50.raw_reads.47.C0.S raw_reads.50.raw_reads.47.N0.S raw_reads.50.raw_reads.47.C1.S raw_reads.50.raw_reads.47.N1.S raw_reads.50.raw_reads.47.C2.S raw_reads.50.raw_reads.47.N2.S raw_reads.50.raw_reads.47.C3.S raw_reads.50.raw_reads.47.N3.S LAsort -v raw_reads.50.raw_reads.48.C0 raw_reads.50.raw_reads.48.N0 raw_reads.50.raw_reads.48.C1 raw_reads.50.raw_reads.48.N1 raw_reads.50.raw_reads.48.C2 raw_reads.50.raw_reads.48.N2 raw_reads.50.raw_reads.48.C3 raw_reads.50.raw_reads.48.N3 && LAmerge -v L1.50.48 raw_reads.50.raw_reads.48.C0.S raw_reads.50.raw_reads.48.N0.S raw_reads.50.raw_reads.48.C1.S raw_reads.50.raw_reads.48.N1.S raw_reads.50.raw_reads.48.C2.S raw_reads.50.raw_reads.48.N2.S raw_reads.50.raw_reads.48.C3.S raw_reads.50.raw_reads.48.N3.S LAsort -v raw_reads.50.raw_reads.49.C0 raw_reads.50.raw_reads.49.N0 raw_reads.50.raw_reads.49.C1 raw_reads.50.raw_reads.49.N1 raw_reads.50.raw_reads.49.C2 raw_reads.50.raw_reads.49.N2 raw_reads.50.raw_reads.49.C3 raw_reads.50.raw_reads.49.N3 && LAmerge -v L1.50.49 raw_reads.50.raw_reads.49.C0.S raw_reads.50.raw_reads.49.N0.S raw_reads.50.raw_reads.49.C1.S raw_reads.50.raw_reads.49.N1.S raw_reads.50.raw_reads.49.C2.S raw_reads.50.raw_reads.49.N2.S raw_reads.50.raw_reads.49.C3.S raw_reads.50.raw_reads.49.N3.S LAsort -v raw_reads.50.raw_reads.50.C0 raw_reads.50.raw_reads.50.N0 raw_reads.50.raw_reads.50.C1 raw_reads.50.raw_reads.50.N1 raw_reads.50.raw_reads.50.C2 raw_reads.50.raw_reads.50.N2 raw_reads.50.raw_reads.50.C3 raw_reads.50.raw_reads.50.N3 && LAmerge -v L1.50.50 raw_reads.50.raw_reads.50.C0.S raw_reads.50.raw_reads.50.N0.S raw_reads.50.raw_reads.50.C1.S raw_reads.50.raw_reads.50.N1.S raw_reads.50.raw_reads.50.C2.S raw_reads.50.raw_reads.50.N2.S raw_reads.50.raw_reads.50.C3.S raw_reads.50.raw_reads.50.N3.S LAcheck -vS raw_reads L1.34.50 LAcheck -vS raw_reads L1.35.50 LAcheck -vS raw_reads L1.36.50 LAcheck -vS raw_reads L1.37.50 LAcheck -vS raw_reads L1.38.50 LAcheck -vS raw_reads L1.39.50 LAcheck -vS raw_reads L1.40.50 LAcheck -vS raw_reads L1.41.50 LAcheck -vS raw_reads L1.42.50 LAcheck -vS raw_reads L1.43.50 LAcheck -vS raw_reads L1.44.50 LAcheck -vS raw_reads L1.45.50 LAcheck -vS raw_reads L1.46.50 LAcheck -vS raw_reads L1.47.50 LAcheck -vS raw_reads L1.48.50 LAcheck -vS raw_reads L1.49.50 LAcheck -vS raw_reads L1.50.34 LAcheck -vS raw_reads L1.50.35 LAcheck -vS raw_reads L1.50.36 LAcheck -vS raw_reads L1.50.37 LAcheck -vS raw_reads L1.50.38 LAcheck -vS raw_reads L1.50.39 LAcheck -vS raw_reads L1.50.40 LAcheck -vS raw_reads L1.50.41 LAcheck -vS raw_reads L1.50.42 LAcheck -vS raw_reads L1.50.43 LAcheck -vS raw_reads L1.50.44 LAcheck -vS raw_reads L1.50.45 LAcheck -vS raw_reads L1.50.46 LAcheck -vS raw_reads L1.50.47 LAcheck -vS raw_reads L1.50.48 LAcheck -vS raw_reads L1.50.49 LAcheck -vS raw_reads L1.50.50 daligner -v -k18 -h70 -t14 -H7000 -e0.75 raw_reads.73 raw_reads.55 raw_reads.56 raw_reads.57 raw_reads.58 raw_reads.59 raw_reads.60 raw_reads.61 raw_reads.62 raw_reads.63 raw_reads.64 raw_reads.65 raw_reads.66 raw_reads.67 raw_reads.68 raw_reads.69 raw_reads.70 raw_reads.71 raw_reads.72 raw_reads.73 LAcheck -v raw_reads *.las LAsort -v raw_reads.55.raw_reads.73.C0 raw_reads.55.raw_reads.73.N0 raw_reads.55.raw_reads.73.C1 raw_reads.55.raw_reads.73.N1 raw_reads.55.raw_reads.73.C2 raw_reads.55.raw_reads.73.N2 raw_reads.55.raw_reads.73.C3 raw_reads.55.raw_reads.73.N3 && LAmerge -v L1.55.73 raw_reads.55.raw_reads.73.C0.S raw_reads.55.raw_reads.73.N0.S raw_reads.55.raw_reads.73.C1.S raw_reads.55.raw_reads.73.N1.S raw_reads.55.raw_reads.73.C2.S raw_reads.55.raw_reads.73.N2.S raw_reads.55.raw_reads.73.C3.S raw_reads.55.raw_reads.73.N3.S LAsort -v raw_reads.56.raw_reads.73.C0 raw_reads.56.raw_reads.73.N0 raw_reads.56.raw_reads.73.C1 raw_reads.56.raw_reads.73.N1 raw_reads.56.raw_reads.73.C2 raw_reads.56.raw_reads.73.N2 raw_reads.56.raw_reads.73.C3 raw_reads.56.raw_reads.73.N3 && LAmerge -v L1.56.73 raw_reads.56.raw_reads.73.C0.S raw_reads.56.raw_reads.73.N0.S raw_reads.56.raw_reads.73.C1.S raw_reads.56.raw_reads.73.N1.S raw_reads.56.raw_reads.73.C2.S raw_reads.56.raw_reads.73.N2.S raw_reads.56.raw_reads.73.C3.S raw_reads.56.raw_reads.73.N3.S LAsort -v raw_reads.57.raw_reads.73.C0 raw_reads.57.raw_reads.73.N0 raw_reads.57.raw_reads.73.C1 raw_reads.57.raw_reads.73.N1 raw_reads.57.raw_reads.73.C2 raw_reads.57.raw_reads.73.N2 raw_reads.57.raw_reads.73.C3 raw_reads.57.raw_reads.73.N3 && LAmerge -v L1.57.73 raw_reads.57.raw_reads.73.C0.S raw_reads.57.raw_reads.73.N0.S raw_reads.57.raw_reads.73.C1.S raw_reads.57.raw_reads.73.N1.S raw_reads.57.raw_reads.73.C2.S raw_reads.57.raw_reads.73.N2.S raw_reads.57.raw_reads.73.C3.S raw_reads.57.raw_reads.73.N3.S LAsort -v raw_reads.58.raw_reads.73.C0 raw_reads.58.raw_reads.73.N0 raw_reads.58.raw_reads.73.C1 raw_reads.58.raw_reads.73.N1 raw_reads.58.raw_reads.73.C2 raw_reads.58.raw_reads.73.N2 raw_reads.58.raw_reads.73.C3 raw_reads.58.raw_reads.73.N3 && LAmerge -v L1.58.73 raw_reads.58.raw_reads.73.C0.S raw_reads.58.raw_reads.73.N0.S raw_reads.58.raw_reads.73.C1.S raw_reads.58.raw_reads.73.N1.S raw_reads.58.raw_reads.73.C2.S raw_reads.58.raw_reads.73.N2.S raw_reads.58.raw_reads.73.C3.S raw_reads.58.raw_reads.73.N3.S LAsort -v raw_reads.59.raw_reads.73.C0 raw_reads.59.raw_reads.73.N0 raw_reads.59.raw_reads.73.C1 raw_reads.59.raw_reads.73.N1 raw_reads.59.raw_reads.73.C2 raw_reads.59.raw_reads.73.N2 raw_reads.59.raw_reads.73.C3 raw_reads.59.raw_reads.73.N3 && LAmerge -v L1.59.73 raw_reads.59.raw_reads.73.C0.S raw_reads.59.raw_reads.73.N0.S raw_reads.59.raw_reads.73.C1.S raw_reads.59.raw_reads.73.N1.S raw_reads.59.raw_reads.73.C2.S raw_reads.59.raw_reads.73.N2.S raw_reads.59.raw_reads.73.C3.S raw_reads.59.raw_reads.73.N3.S LAsort -v raw_reads.60.raw_reads.73.C0 raw_reads.60.raw_reads.73.N0 raw_reads.60.raw_reads.73.C1 raw_reads.60.raw_reads.73.N1 raw_reads.60.raw_reads.73.C2 raw_reads.60.raw_reads.73.N2 raw_reads.60.raw_reads.73.C3 raw_reads.60.raw_reads.73.N3 && LAmerge -v L1.60.73 raw_reads.60.raw_reads.73.C0.S raw_reads.60.raw_reads.73.N0.S raw_reads.60.raw_reads.73.C1.S raw_reads.60.raw_reads.73.N1.S raw_reads.60.raw_reads.73.C2.S raw_reads.60.raw_reads.73.N2.S raw_reads.60.raw_reads.73.C3.S raw_reads.60.raw_reads.73.N3.S LAsort -v raw_reads.61.raw_reads.73.C0 raw_reads.61.raw_reads.73.N0 raw_reads.61.raw_reads.73.C1 raw_reads.61.raw_reads.73.N1 raw_reads.61.raw_reads.73.C2 raw_reads.61.raw_reads.73.N2 raw_reads.61.raw_reads.73.C3 raw_reads.61.raw_reads.73.N3 && LAmerge -v L1.61.73 raw_reads.61.raw_reads.73.C0.S raw_reads.61.raw_reads.73.N0.S raw_reads.61.raw_reads.73.C1.S raw_reads.61.raw_reads.73.N1.S raw_reads.61.raw_reads.73.C2.S raw_reads.61.raw_reads.73.N2.S raw_reads.61.raw_reads.73.C3.S raw_reads.61.raw_reads.73.N3.S LAsort -v raw_reads.62.raw_reads.73.C0 raw_reads.62.raw_reads.73.N0 raw_reads.62.raw_reads.73.C1 raw_reads.62.raw_reads.73.N1 raw_reads.62.raw_reads.73.C2 raw_reads.62.raw_reads.73.N2 raw_reads.62.raw_reads.73.C3 raw_reads.62.raw_reads.73.N3 && LAmerge -v L1.62.73 raw_reads.62.raw_reads.73.C0.S raw_reads.62.raw_reads.73.N0.S raw_reads.62.raw_reads.73.C1.S raw_reads.62.raw_reads.73.N1.S raw_reads.62.raw_reads.73.C2.S raw_reads.62.raw_reads.73.N2.S raw_reads.62.raw_reads.73.C3.S raw_reads.62.raw_reads.73.N3.S LAsort -v raw_reads.63.raw_reads.73.C0 raw_reads.63.raw_reads.73.N0 raw_reads.63.raw_reads.73.C1 raw_reads.63.raw_reads.73.N1 raw_reads.63.raw_reads.73.C2 raw_reads.63.raw_reads.73.N2 raw_reads.63.raw_reads.73.C3 raw_reads.63.raw_reads.73.N3 && LAmerge -v L1.63.73 raw_reads.63.raw_reads.73.C0.S raw_reads.63.raw_reads.73.N0.S raw_reads.63.raw_reads.73.C1.S raw_reads.63.raw_reads.73.N1.S raw_reads.63.raw_reads.73.C2.S raw_reads.63.raw_reads.73.N2.S raw_reads.63.raw_reads.73.C3.S raw_reads.63.raw_reads.73.N3.S LAsort -v raw_reads.64.raw_reads.73.C0 raw_reads.64.raw_reads.73.N0 raw_reads.64.raw_reads.73.C1 raw_reads.64.raw_reads.73.N1 raw_reads.64.raw_reads.73.C2 raw_reads.64.raw_reads.73.N2 raw_reads.64.raw_reads.73.C3 raw_reads.64.raw_reads.73.N3 && LAmerge -v L1.64.73 raw_reads.64.raw_reads.73.C0.S raw_reads.64.raw_reads.73.N0.S raw_reads.64.raw_reads.73.C1.S raw_reads.64.raw_reads.73.N1.S raw_reads.64.raw_reads.73.C2.S raw_reads.64.raw_reads.73.N2.S raw_reads.64.raw_reads.73.C3.S raw_reads.64.raw_reads.73.N3.S LAsort -v raw_reads.65.raw_reads.73.C0 raw_reads.65.raw_reads.73.N0 raw_reads.65.raw_reads.73.C1 raw_reads.65.raw_reads.73.N1 raw_reads.65.raw_reads.73.C2 raw_reads.65.raw_reads.73.N2 raw_reads.65.raw_reads.73.C3 raw_reads.65.raw_reads.73.N3 && LAmerge -v L1.65.73 raw_reads.65.raw_reads.73.C0.S raw_reads.65.raw_reads.73.N0.S raw_reads.65.raw_reads.73.C1.S raw_reads.65.raw_reads.73.N1.S raw_reads.65.raw_reads.73.C2.S raw_reads.65.raw_reads.73.N2.S raw_reads.65.raw_reads.73.C3.S raw_reads.65.raw_reads.73.N3.S LAsort -v raw_reads.66.raw_reads.73.C0 raw_reads.66.raw_reads.73.N0 raw_reads.66.raw_reads.73.C1 raw_reads.66.raw_reads.73.N1 raw_reads.66.raw_reads.73.C2 raw_reads.66.raw_reads.73.N2 raw_reads.66.raw_reads.73.C3 raw_reads.66.raw_reads.73.N3 && LAmerge -v L1.66.73 raw_reads.66.raw_reads.73.C0.S raw_reads.66.raw_reads.73.N0.S raw_reads.66.raw_reads.73.C1.S raw_reads.66.raw_reads.73.N1.S raw_reads.66.raw_reads.73.C2.S raw_reads.66.raw_reads.73.N2.S raw_reads.66.raw_reads.73.C3.S raw_reads.66.raw_reads.73.N3.S LAsort -v raw_reads.67.raw_reads.73.C0 raw_reads.67.raw_reads.73.N0 raw_reads.67.raw_reads.73.C1 raw_reads.67.raw_reads.73.N1 raw_reads.67.raw_reads.73.C2 raw_reads.67.raw_reads.73.N2 raw_reads.67.raw_reads.73.C3 raw_reads.67.raw_reads.73.N3 && LAmerge -v L1.67.73 raw_reads.67.raw_reads.73.C0.S raw_reads.67.raw_reads.73.N0.S raw_reads.67.raw_reads.73.C1.S raw_reads.67.raw_reads.73.N1.S raw_reads.67.raw_reads.73.C2.S raw_reads.67.raw_reads.73.N2.S raw_reads.67.raw_reads.73.C3.S raw_reads.67.raw_reads.73.N3.S LAsort -v raw_reads.68.raw_reads.73.C0 raw_reads.68.raw_reads.73.N0 raw_reads.68.raw_reads.73.C1 raw_reads.68.raw_reads.73.N1 raw_reads.68.raw_reads.73.C2 raw_reads.68.raw_reads.73.N2 raw_reads.68.raw_reads.73.C3 raw_reads.68.raw_reads.73.N3 && LAmerge -v L1.68.73 raw_reads.68.raw_reads.73.C0.S raw_reads.68.raw_reads.73.N0.S raw_reads.68.raw_reads.73.C1.S raw_reads.68.raw_reads.73.N1.S raw_reads.68.raw_reads.73.C2.S raw_reads.68.raw_reads.73.N2.S raw_reads.68.raw_reads.73.C3.S raw_reads.68.raw_reads.73.N3.S LAsort -v raw_reads.69.raw_reads.73.C0 raw_reads.69.raw_reads.73.N0 raw_reads.69.raw_reads.73.C1 raw_reads.69.raw_reads.73.N1 raw_reads.69.raw_reads.73.C2 raw_reads.69.raw_reads.73.N2 raw_reads.69.raw_reads.73.C3 raw_reads.69.raw_reads.73.N3 && LAmerge -v L1.69.73 raw_reads.69.raw_reads.73.C0.S raw_reads.69.raw_reads.73.N0.S raw_reads.69.raw_reads.73.C1.S raw_reads.69.raw_reads.73.N1.S raw_reads.69.raw_reads.73.C2.S raw_reads.69.raw_reads.73.N2.S raw_reads.69.raw_reads.73.C3.S raw_reads.69.raw_reads.73.N3.S LAsort -v raw_reads.70.raw_reads.73.C0 raw_reads.70.raw_reads.73.N0 raw_reads.70.raw_reads.73.C1 raw_reads.70.raw_reads.73.N1 raw_reads.70.raw_reads.73.C2 raw_reads.70.raw_reads.73.N2 raw_reads.70.raw_reads.73.C3 raw_reads.70.raw_reads.73.N3 && LAmerge -v L1.70.73 raw_reads.70.raw_reads.73.C0.S raw_reads.70.raw_reads.73.N0.S raw_reads.70.raw_reads.73.C1.S raw_reads.70.raw_reads.73.N1.S raw_reads.70.raw_reads.73.C2.S raw_reads.70.raw_reads.73.N2.S raw_reads.70.raw_reads.73.C3.S raw_reads.70.raw_reads.73.N3.S LAsort -v raw_reads.71.raw_reads.73.C0 raw_reads.71.raw_reads.73.N0 raw_reads.71.raw_reads.73.C1 raw_reads.71.raw_reads.73.N1 raw_reads.71.raw_reads.73.C2 raw_reads.71.raw_reads.73.N2 raw_reads.71.raw_reads.73.C3 raw_reads.71.raw_reads.73.N3 && LAmerge -v L1.71.73 raw_reads.71.raw_reads.73.C0.S raw_reads.71.raw_reads.73.N0.S raw_reads.71.raw_reads.73.C1.S raw_reads.71.raw_reads.73.N1.S raw_reads.71.raw_reads.73.C2.S raw_reads.71.raw_reads.73.N2.S raw_reads.71.raw_reads.73.C3.S raw_reads.71.raw_reads.73.N3.S LAsort -v raw_reads.72.raw_reads.73.C0 raw_reads.72.raw_reads.73.N0 raw_reads.72.raw_reads.73.C1 raw_reads.72.raw_reads.73.N1 raw_reads.72.raw_reads.73.C2 raw_reads.72.raw_reads.73.N2 raw_reads.72.raw_reads.73.C3 raw_reads.72.raw_reads.73.N3 && LAmerge -v L1.72.73 raw_reads.72.raw_reads.73.C0.S raw_reads.72.raw_reads.73.N0.S raw_reads.72.raw_reads.73.C1.S raw_reads.72.raw_reads.73.N1.S raw_reads.72.raw_reads.73.C2.S raw_reads.72.raw_reads.73.N2.S raw_reads.72.raw_reads.73.C3.S raw_reads.72.raw_reads.73.N3.S LAsort -v raw_reads.73.raw_reads.55.C0 raw_reads.73.raw_reads.55.N0 raw_reads.73.raw_reads.55.C1 raw_reads.73.raw_reads.55.N1 raw_reads.73.raw_reads.55.C2 raw_reads.73.raw_reads.55.N2 raw_reads.73.raw_reads.55.C3 raw_reads.73.raw_reads.55.N3 && LAmerge -v L1.73.55 raw_reads.73.raw_reads.55.C0.S raw_reads.73.raw_reads.55.N0.S raw_reads.73.raw_reads.55.C1.S raw_reads.73.raw_reads.55.N1.S raw_reads.73.raw_reads.55.C2.S raw_reads.73.raw_reads.55.N2.S raw_reads.73.raw_reads.55.C3.S raw_reads.73.raw_reads.55.N3.S LAsort -v raw_reads.73.raw_reads.56.C0 raw_reads.73.raw_reads.56.N0 raw_reads.73.raw_reads.56.C1 raw_reads.73.raw_reads.56.N1 raw_reads.73.raw_reads.56.C2 raw_reads.73.raw_reads.56.N2 raw_reads.73.raw_reads.56.C3 raw_reads.73.raw_reads.56.N3 && LAmerge -v L1.73.56 raw_reads.73.raw_reads.56.C0.S raw_reads.73.raw_reads.56.N0.S raw_reads.73.raw_reads.56.C1.S raw_reads.73.raw_reads.56.N1.S raw_reads.73.raw_reads.56.C2.S raw_reads.73.raw_reads.56.N2.S raw_reads.73.raw_reads.56.C3.S raw_reads.73.raw_reads.56.N3.S LAsort -v raw_reads.73.raw_reads.57.C0 raw_reads.73.raw_reads.57.N0 raw_reads.73.raw_reads.57.C1 raw_reads.73.raw_reads.57.N1 raw_reads.73.raw_reads.57.C2 raw_reads.73.raw_reads.57.N2 raw_reads.73.raw_reads.57.C3 raw_reads.73.raw_reads.57.N3 && LAmerge -v L1.73.57 raw_reads.73.raw_reads.57.C0.S raw_reads.73.raw_reads.57.N0.S raw_reads.73.raw_reads.57.C1.S raw_reads.73.raw_reads.57.N1.S raw_reads.73.raw_reads.57.C2.S raw_reads.73.raw_reads.57.N2.S raw_reads.73.raw_reads.57.C3.S raw_reads.73.raw_reads.57.N3.S LAsort -v raw_reads.73.raw_reads.58.C0 raw_reads.73.raw_reads.58.N0 raw_reads.73.raw_reads.58.C1 raw_reads.73.raw_reads.58.N1 raw_reads.73.raw_reads.58.C2 raw_reads.73.raw_reads.58.N2 raw_reads.73.raw_reads.58.C3 raw_reads.73.raw_reads.58.N3 && LAmerge -v L1.73.58 raw_reads.73.raw_reads.58.C0.S raw_reads.73.raw_reads.58.N0.S raw_reads.73.raw_reads.58.C1.S raw_reads.73.raw_reads.58.N1.S raw_reads.73.raw_reads.58.C2.S raw_reads.73.raw_reads.58.N2.S raw_reads.73.raw_reads.58.C3.S raw_reads.73.raw_reads.58.N3.S LAsort -v raw_reads.73.raw_reads.59.C0 raw_reads.73.raw_reads.59.N0 raw_reads.73.raw_reads.59.C1 raw_reads.73.raw_reads.59.N1 raw_reads.73.raw_reads.59.C2 raw_reads.73.raw_reads.59.N2 raw_reads.73.raw_reads.59.C3 raw_reads.73.raw_reads.59.N3 && LAmerge -v L1.73.59 raw_reads.73.raw_reads.59.C0.S raw_reads.73.raw_reads.59.N0.S raw_reads.73.raw_reads.59.C1.S raw_reads.73.raw_reads.59.N1.S raw_reads.73.raw_reads.59.C2.S raw_reads.73.raw_reads.59.N2.S raw_reads.73.raw_reads.59.C3.S raw_reads.73.raw_reads.59.N3.S LAsort -v raw_reads.73.raw_reads.60.C0 raw_reads.73.raw_reads.60.N0 raw_reads.73.raw_reads.60.C1 raw_reads.73.raw_reads.60.N1 raw_reads.73.raw_reads.60.C2 raw_reads.73.raw_reads.60.N2 raw_reads.73.raw_reads.60.C3 raw_reads.73.raw_reads.60.N3 && LAmerge -v L1.73.60 raw_reads.73.raw_reads.60.C0.S raw_reads.73.raw_reads.60.N0.S raw_reads.73.raw_reads.60.C1.S raw_reads.73.raw_reads.60.N1.S raw_reads.73.raw_reads.60.C2.S raw_reads.73.raw_reads.60.N2.S raw_reads.73.raw_reads.60.C3.S raw_reads.73.raw_reads.60.N3.S LAsort -v raw_reads.73.raw_reads.61.C0 raw_reads.73.raw_reads.61.N0 raw_reads.73.raw_reads.61.C1 raw_reads.73.raw_reads.61.N1 raw_reads.73.raw_reads.61.C2 raw_reads.73.raw_reads.61.N2 raw_reads.73.raw_reads.61.C3 raw_reads.73.raw_reads.61.N3 && LAmerge -v L1.73.61 raw_reads.73.raw_reads.61.C0.S raw_reads.73.raw_reads.61.N0.S raw_reads.73.raw_reads.61.C1.S raw_reads.73.raw_reads.61.N1.S raw_reads.73.raw_reads.61.C2.S raw_reads.73.raw_reads.61.N2.S raw_reads.73.raw_reads.61.C3.S raw_reads.73.raw_reads.61.N3.S LAsort -v raw_reads.73.raw_reads.62.C0 raw_reads.73.raw_reads.62.N0 raw_reads.73.raw_reads.62.C1 raw_reads.73.raw_reads.62.N1 raw_reads.73.raw_reads.62.C2 raw_reads.73.raw_reads.62.N2 raw_reads.73.raw_reads.62.C3 raw_reads.73.raw_reads.62.N3 && LAmerge -v L1.73.62 raw_reads.73.raw_reads.62.C0.S raw_reads.73.raw_reads.62.N0.S raw_reads.73.raw_reads.62.C1.S raw_reads.73.raw_reads.62.N1.S raw_reads.73.raw_reads.62.C2.S raw_reads.73.raw_reads.62.N2.S raw_reads.73.raw_reads.62.C3.S raw_reads.73.raw_reads.62.N3.S LAsort -v raw_reads.73.raw_reads.63.C0 raw_reads.73.raw_reads.63.N0 raw_reads.73.raw_reads.63.C1 raw_reads.73.raw_reads.63.N1 raw_reads.73.raw_reads.63.C2 raw_reads.73.raw_reads.63.N2 raw_reads.73.raw_reads.63.C3 raw_reads.73.raw_reads.63.N3 && LAmerge -v L1.73.63 raw_reads.73.raw_reads.63.C0.S raw_reads.73.raw_reads.63.N0.S raw_reads.73.raw_reads.63.C1.S raw_reads.73.raw_reads.63.N1.S raw_reads.73.raw_reads.63.C2.S raw_reads.73.raw_reads.63.N2.S raw_reads.73.raw_reads.63.C3.S raw_reads.73.raw_reads.63.N3.S LAsort -v raw_reads.73.raw_reads.64.C0 raw_reads.73.raw_reads.64.N0 raw_reads.73.raw_reads.64.C1 raw_reads.73.raw_reads.64.N1 raw_reads.73.raw_reads.64.C2 raw_reads.73.raw_reads.64.N2 raw_reads.73.raw_reads.64.C3 raw_reads.73.raw_reads.64.N3 && LAmerge -v L1.73.64 raw_reads.73.raw_reads.64.C0.S raw_reads.73.raw_reads.64.N0.S raw_reads.73.raw_reads.64.C1.S raw_reads.73.raw_reads.64.N1.S raw_reads.73.raw_reads.64.C2.S raw_reads.73.raw_reads.64.N2.S raw_reads.73.raw_reads.64.C3.S raw_reads.73.raw_reads.64.N3.S LAsort -v raw_reads.73.raw_reads.65.C0 raw_reads.73.raw_reads.65.N0 raw_reads.73.raw_reads.65.C1 raw_reads.73.raw_reads.65.N1 raw_reads.73.raw_reads.65.C2 raw_reads.73.raw_reads.65.N2 raw_reads.73.raw_reads.65.C3 raw_reads.73.raw_reads.65.N3 && LAmerge -v L1.73.65 raw_reads.73.raw_reads.65.C0.S raw_reads.73.raw_reads.65.N0.S raw_reads.73.raw_reads.65.C1.S raw_reads.73.raw_reads.65.N1.S raw_reads.73.raw_reads.65.C2.S raw_reads.73.raw_reads.65.N2.S raw_reads.73.raw_reads.65.C3.S raw_reads.73.raw_reads.65.N3.S LAsort -v raw_reads.73.raw_reads.66.C0 raw_reads.73.raw_reads.66.N0 raw_reads.73.raw_reads.66.C1 raw_reads.73.raw_reads.66.N1 raw_reads.73.raw_reads.66.C2 raw_reads.73.raw_reads.66.N2 raw_reads.73.raw_reads.66.C3 raw_reads.73.raw_reads.66.N3 && LAmerge -v L1.73.66 raw_reads.73.raw_reads.66.C0.S raw_reads.73.raw_reads.66.N0.S raw_reads.73.raw_reads.66.C1.S raw_reads.73.raw_reads.66.N1.S raw_reads.73.raw_reads.66.C2.S raw_reads.73.raw_reads.66.N2.S raw_reads.73.raw_reads.66.C3.S raw_reads.73.raw_reads.66.N3.S LAsort -v raw_reads.73.raw_reads.67.C0 raw_reads.73.raw_reads.67.N0 raw_reads.73.raw_reads.67.C1 raw_reads.73.raw_reads.67.N1 raw_reads.73.raw_reads.67.C2 raw_reads.73.raw_reads.67.N2 raw_reads.73.raw_reads.67.C3 raw_reads.73.raw_reads.67.N3 && LAmerge -v L1.73.67 raw_reads.73.raw_reads.67.C0.S raw_reads.73.raw_reads.67.N0.S raw_reads.73.raw_reads.67.C1.S raw_reads.73.raw_reads.67.N1.S raw_reads.73.raw_reads.67.C2.S raw_reads.73.raw_reads.67.N2.S raw_reads.73.raw_reads.67.C3.S raw_reads.73.raw_reads.67.N3.S LAsort -v raw_reads.73.raw_reads.68.C0 raw_reads.73.raw_reads.68.N0 raw_reads.73.raw_reads.68.C1 raw_reads.73.raw_reads.68.N1 raw_reads.73.raw_reads.68.C2 raw_reads.73.raw_reads.68.N2 raw_reads.73.raw_reads.68.C3 raw_reads.73.raw_reads.68.N3 && LAmerge -v L1.73.68 raw_reads.73.raw_reads.68.C0.S raw_reads.73.raw_reads.68.N0.S raw_reads.73.raw_reads.68.C1.S raw_reads.73.raw_reads.68.N1.S raw_reads.73.raw_reads.68.C2.S raw_reads.73.raw_reads.68.N2.S raw_reads.73.raw_reads.68.C3.S raw_reads.73.raw_reads.68.N3.S LAsort -v raw_reads.73.raw_reads.69.C0 raw_reads.73.raw_reads.69.N0 raw_reads.73.raw_reads.69.C1 raw_reads.73.raw_reads.69.N1 raw_reads.73.raw_reads.69.C2 raw_reads.73.raw_reads.69.N2 raw_reads.73.raw_reads.69.C3 raw_reads.73.raw_reads.69.N3 && LAmerge -v L1.73.69 raw_reads.73.raw_reads.69.C0.S raw_reads.73.raw_reads.69.N0.S raw_reads.73.raw_reads.69.C1.S raw_reads.73.raw_reads.69.N1.S raw_reads.73.raw_reads.69.C2.S raw_reads.73.raw_reads.69.N2.S raw_reads.73.raw_reads.69.C3.S raw_reads.73.raw_reads.69.N3.S LAsort -v raw_reads.73.raw_reads.70.C0 raw_reads.73.raw_reads.70.N0 raw_reads.73.raw_reads.70.C1 raw_reads.73.raw_reads.70.N1 raw_reads.73.raw_reads.70.C2 raw_reads.73.raw_reads.70.N2 raw_reads.73.raw_reads.70.C3 raw_reads.73.raw_reads.70.N3 && LAmerge -v L1.73.70 raw_reads.73.raw_reads.70.C0.S raw_reads.73.raw_reads.70.N0.S raw_reads.73.raw_reads.70.C1.S raw_reads.73.raw_reads.70.N1.S raw_reads.73.raw_reads.70.C2.S raw_reads.73.raw_reads.70.N2.S raw_reads.73.raw_reads.70.C3.S raw_reads.73.raw_reads.70.N3.S LAsort -v raw_reads.73.raw_reads.71.C0 raw_reads.73.raw_reads.71.N0 raw_reads.73.raw_reads.71.C1 raw_reads.73.raw_reads.71.N1 raw_reads.73.raw_reads.71.C2 raw_reads.73.raw_reads.71.N2 raw_reads.73.raw_reads.71.C3 raw_reads.73.raw_reads.71.N3 && LAmerge -v L1.73.71 raw_reads.73.raw_reads.71.C0.S raw_reads.73.raw_reads.71.N0.S raw_reads.73.raw_reads.71.C1.S raw_reads.73.raw_reads.71.N1.S raw_reads.73.raw_reads.71.C2.S raw_reads.73.raw_reads.71.N2.S raw_reads.73.raw_reads.71.C3.S raw_reads.73.raw_reads.71.N3.S LAsort -v raw_reads.73.raw_reads.72.C0 raw_reads.73.raw_reads.72.N0 raw_reads.73.raw_reads.72.C1 raw_reads.73.raw_reads.72.N1 raw_reads.73.raw_reads.72.C2 raw_reads.73.raw_reads.72.N2 raw_reads.73.raw_reads.72.C3 raw_reads.73.raw_reads.72.N3 && LAmerge -v L1.73.72 raw_reads.73.raw_reads.72.C0.S raw_reads.73.raw_reads.72.N0.S raw_reads.73.raw_reads.72.C1.S raw_reads.73.raw_reads.72.N1.S raw_reads.73.raw_reads.72.C2.S raw_reads.73.raw_reads.72.N2.S raw_reads.73.raw_reads.72.C3.S raw_reads.73.raw_reads.72.N3.S LAsort -v raw_reads.73.raw_reads.73.C0 raw_reads.73.raw_reads.73.N0 raw_reads.73.raw_reads.73.C1 raw_reads.73.raw_reads.73.N1 raw_reads.73.raw_reads.73.C2 raw_reads.73.raw_reads.73.N2 raw_reads.73.raw_reads.73.C3 raw_reads.73.raw_reads.73.N3 && LAmerge -v L1.73.73 raw_reads.73.raw_reads.73.C0.S raw_reads.73.raw_reads.73.N0.S raw_reads.73.raw_reads.73.C1.S raw_reads.73.raw_reads.73.N1.S raw_reads.73.raw_reads.73.C2.S raw_reads.73.raw_reads.73.N2.S raw_reads.73.raw_reads.73.C3.S raw_reads.73.raw_reads.73.N3.S LAcheck -vS raw_reads L1.55.73 LAcheck -vS raw_reads L1.56.73 LAcheck -vS raw_reads L1.57.73 LAcheck -vS raw_reads L1.58.73 LAcheck -vS raw_reads L1.59.73 LAcheck -vS raw_reads L1.60.73 LAcheck -vS raw_reads L1.61.73 LAcheck -vS raw_reads L1.62.73 LAcheck -vS raw_reads L1.63.73 LAcheck -vS raw_reads L1.64.73 LAcheck -vS raw_reads L1.65.73 LAcheck -vS raw_reads L1.66.73 LAcheck -vS raw_reads L1.67.73 LAcheck -vS raw_reads L1.68.73 LAcheck -vS raw_reads L1.69.73 LAcheck -vS raw_reads L1.70.73 LAcheck -vS raw_reads L1.71.73 LAcheck -vS raw_reads L1.72.73 LAcheck -vS raw_reads L1.73.55 LAcheck -vS raw_reads L1.73.56 LAcheck -vS raw_reads L1.73.57 LAcheck -vS raw_reads L1.73.58 LAcheck -vS raw_reads L1.73.59 LAcheck -vS raw_reads L1.73.60 LAcheck -vS raw_reads L1.73.61 LAcheck -vS raw_reads L1.73.62 LAcheck -vS raw_reads L1.73.63 LAcheck -vS raw_reads L1.73.64 LAcheck -vS raw_reads L1.73.65 LAcheck -vS raw_reads L1.73.66 LAcheck -vS raw_reads L1.73.67 LAcheck -vS raw_reads L1.73.68 LAcheck -vS raw_reads L1.73.69 LAcheck -vS raw_reads L1.73.70 LAcheck -vS raw_reads L1.73.71 LAcheck -vS raw_reads L1.73.72 LAcheck -vS raw_reads L1.73.73 ================================================ FILE: test/test_actg_coordinate.py ================================================ import falcon_kit.mains.actg_coordinate as mod ''' def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass ''' ================================================ FILE: test/test_calc_cutoff.py ================================================ import falcon_kit.mains.calc_cutoff as mod import helpers import os.path import pytest def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass # Note: genome_size==1 makes math easy. def test_calc_cutoff(capsys): partial_capture_fn = os.path.join( helpers.get_test_data_dir(), 'calc_cutoff/partial_capture.txt') assert os.path.exists(partial_capture_fn) mod.main('prog --coverage 14 1 {}'.format(partial_capture_fn).split()) out, err = capsys.readouterr() assert out == '2' assert not err expected_err = """ GenomeCoverageError: Not enough reads available for desired genome coverage (bases needed=23 > actual=22) User-provided genome_size: 1 Desired coverage: 23.0 """ def test_calc_cutoff_err(): partial_capture_fn = os.path.join( helpers.get_test_data_dir(), 'calc_cutoff/partial_capture.txt') assert os.path.exists(partial_capture_fn) with pytest.raises(Exception) as excinfo: mod.main('prog --coverage 23 1 {}'.format(partial_capture_fn).split()) assert expected_err in str(excinfo.value) def test_calc_cutoff_errfile(monkeypatch, tmpdir): fn = str(tmpdir.mkdir('tmp').join('errfile')) monkeypatch.setenv('PBFALCON_ERRFILE', fn) partial_capture_fn = os.path.join( helpers.get_test_data_dir(), 'calc_cutoff/partial_capture.txt') assert os.path.exists(partial_capture_fn) with pytest.raises(Exception) as excinfo: mod.main('prog --coverage 23 1 {}'.format(partial_capture_fn).split()) assert expected_err in str(excinfo.value) assert expected_err in open(fn).read() ================================================ FILE: test/test_collect_contig_gfa.py ================================================ import falcon_kit.mains.collect_contig_gfa as mod import helpers import pytest import os import falcon_kit.tiling_path from falcon_kit.FastaReader import FastaReader from test_tiling_path import test_placement_1_p_path_as_text, test_placement_1_a_path_as_text import json import random random.seed(1234567) def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass # def load_seq(fasta_fn): # return {r.name.split()[0]: r.sequence.upper() for r in FastaReader(fasta_fn)} # def path_to_seq(preads, path_as_split_lines, with_first_read): # ret = '' # if len(path_as_split_lines) == 0: # return ret # if with_first_read: # ctg_id, v, w, wrid, sp, tp = path_as_split_lines[0][0:6] # vrid, vorient = v.split(':') # ret += preads[vrid] if vorient == 'E' else "".join([RCMAP[c] for c in preads[vrid][::-1]]) # for edge in path_as_split_lines: # ctg_id, v, w, wrid, sp, tp = edge[0:6] # sp, tp = int(sp), int(tp) # ret += preads[wrid][sp:tp] if sp < tp else "".join([RCMAP[c] for c in preads[wrid][sp:tp:-1]]) # ret = ''.join([str(val) for val in ret]) # return ret def generate_seq(seq_len): return ''.join([random.choice(['A', 'C', 'T', 'G']) for i in xrange(seq_len)]) def setup_test(fp_p_ctg, fp_p_tp, fp_a_ctg, fp_a_tp): """ Configures test files with predefined values. This includes p and a tiling paths and contig sequences, and also returns the values as dicts. Expected value is returned, for the case where sequences should be omitted. """ p_tp_as_text = test_placement_1_p_path_as_text a_tp_as_text = test_placement_1_a_path_as_text all_seqs = {} # Write sample p_ctg_tiling_path. fp_p_tp.write(p_tp_as_text) # Load and parse the tiling path. Validity is tested in test_tiling_path. p_ctg_tps = falcon_kit.tiling_path.load_tiling_paths(str(fp_p_tp), contig_lens=None, whitelist_seqs=None) # Generate random p_ctg sequences write to file. p_ctg_fasta_text = '' for key, tp in p_ctg_tps.iteritems(): all_seqs[key] = generate_seq(tp.contig_len) p_ctg_fasta_text += '>%s\n%s\n' % (key, all_seqs[key]) fp_p_ctg.write(p_ctg_fasta_text) # Write sample p_ctg_tiling_path. fp_a_tp.write(a_tp_as_text) # Load and parse the tiling path. Validity is tested in test_tiling_path. a_ctg_tps = falcon_kit.tiling_path.load_tiling_paths(str(fp_a_tp), contig_lens=None, whitelist_seqs=None) # Generate random p_ctg sequences write to file. a_ctg_fasta_text = '' for key, tp in a_ctg_tps.iteritems(): all_seqs[key] = generate_seq(tp.contig_len) a_ctg_fasta_text += '>%s\n%s\n' % (key, all_seqs[key]) fp_a_ctg.write(a_ctg_fasta_text) expected = \ { "nodes": { "000000F": { "labels": {}, "seq": "*", "name": "000000F", "len": 71411, "tags": {} }, "000001F": { "labels": {}, "seq": "*", "name": "000001F", "len": 33726, "tags": {} }, "000002F": { "labels": {}, "seq": "*", "name": "000002F", "len": 8473, "tags": {} }, "000000F-1": { "labels": {}, "seq": "*", "name": "000000F-1", "len": 29405, "tags": {} } }, "edges": { "('000000F', '000000F-1')": { "labels": {}, "tags": {}, "v": "000000F", "v_orient": "+", "w": "000000F-1", "w_orient": "+", "v_start": 43849, "v_end": 43849, "w_start": 0, "w_end": 0, "cigar": "*", "name": "edge-0"}, "('000000F-1', '000000F')": { "labels": {}, "tags": {}, "v": "000000F-1", "v_orient": "+", "w": "000000F", "w_orient": "+", "v_start": 29405, "v_end": 29405, "w_start": 67383, "w_end": 67383, "cigar": "*", "name": "edge-1"}, }, "paths": {}, } return all_seqs, p_ctg_tps, a_ctg_tps, expected def test_main_1(tmpdir, capsys): """ Test without writing contig sequences. """ p_ctg_file = tmpdir.join('p_ctg.fa') p_tp_file = tmpdir.join('p_ctg_tiling_path') a_tp_file = tmpdir.join('a_ctg_tiling_path') a_ctg_file = tmpdir.join('a_ctg.fa') all_seqs, p_ctg_tps, a_ctg_tps, expected = setup_test(p_ctg_file, p_tp_file, a_ctg_file, a_tp_file) argv = ['prog', '--p-ctg-tiling-path', str(p_tp_file), '--a-ctg-tiling-path', str(a_tp_file), '--p-ctg-fasta', str(p_ctg_file), '--a-ctg-fasta', str(a_ctg_file), # '--write-contigs', '--min-p-len', '0', '--min-a-len', '0', # '--only-these-contigs' ] mod.main(argv) out, err = capsys.readouterr() result = json.loads(out) assert(result == expected) def test_main_2(tmpdir, capsys): """ Test output with sequences. """ p_ctg_file = tmpdir.join('p_ctg.fa') p_tp_file = tmpdir.join('p_ctg_tiling_path') a_tp_file = tmpdir.join('a_ctg_tiling_path') a_ctg_file = tmpdir.join('a_ctg.fa') all_seqs, p_ctg_tps, a_ctg_tps, expected = setup_test(p_ctg_file, p_tp_file, a_ctg_file, a_tp_file) # This test expects that the nodes are initialized with sequences, so # set the reference to the generated sequences here. for key, node in expected['nodes'].iteritems(): node['seq'] = all_seqs[key] argv = ['prog', '--p-ctg-tiling-path', str(p_tp_file), '--a-ctg-tiling-path', str(a_tp_file), '--p-ctg-fasta', str(p_ctg_file), '--a-ctg-fasta', str(a_ctg_file), '--write-contigs', '--min-p-len', '0', '--min-a-len', '0', # '--only-these-contigs' ] mod.main(argv) out, err = capsys.readouterr() result = json.loads(out) assert(result == expected) def test_main_3(tmpdir, capsys): """ Test the whitelist. """ p_ctg_file = tmpdir.join('p_ctg.fa') p_tp_file = tmpdir.join('p_ctg_tiling_path') a_tp_file = tmpdir.join('a_ctg_tiling_path') a_ctg_file = tmpdir.join('a_ctg.fa') all_seqs, p_ctg_tps, a_ctg_tps, expected = setup_test(p_ctg_file, p_tp_file, a_ctg_file, a_tp_file) only_these_contigs = set(['000002F']) whitelist_file = tmpdir.join('only_these_contigs') whitelist_file.write('\n'.join(only_these_contigs) + '\n') # Adjust the expected results. # Remove any node not in the whitelist. blacklist_nodes = [key for key in (p_ctg_tps.keys() + a_ctg_tps.keys()) if key not in only_these_contigs] for key in blacklist_nodes: expected['nodes'].pop(key, None) # Remove any edge not in the whitelist. blacklist_edges = [key for key, edge in expected['edges'].iteritems() if edge['v'] not in only_these_contigs or edge['w'] not in only_these_contigs] for key in blacklist_edges: expected['edges'].pop(key, None) argv = ['prog', '--p-ctg-tiling-path', str(p_tp_file), '--a-ctg-tiling-path', str(a_tp_file), '--p-ctg-fasta', str(p_ctg_file), '--a-ctg-fasta', str(a_ctg_file), # '--write-contigs', '--min-p-len', '0', '--min-a-len', '0', '--only-these-contigs', str(whitelist_file), ] mod.main(argv) out, err = capsys.readouterr() result = json.loads(out) assert(result == expected) def test_main_4(tmpdir, capsys): """ Test for an empty input. """ p_ctg_file = tmpdir.join('p_ctg.fa') p_tp_file = tmpdir.join('p_ctg_tiling_path') a_tp_file = tmpdir.join('a_ctg_tiling_path') a_ctg_file = tmpdir.join('a_ctg.fa') p_ctg_file.write('') p_tp_file.write('') a_tp_file.write('') a_ctg_file.write('') expected = {'nodes': {}, 'edges': {}, 'paths': {}} argv = ['prog', '--p-ctg-tiling-path', str(p_tp_file), '--a-ctg-tiling-path', str(a_tp_file), '--p-ctg-fasta', str(p_ctg_file), '--a-ctg-fasta', str(a_ctg_file), # '--write-contigs', '--min-p-len', '0', '--min-a-len', '0', # '--only-these-contigs' ] mod.main(argv) out, err = capsys.readouterr() result = json.loads(out) assert(result == expected) ================================================ FILE: test/test_collect_pread_gfa.py ================================================ import falcon_kit.mains.collect_pread_gfa as mod import helpers import pytest import os def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass def test_load_seqs(): # load_seqs(fasta_fn, store_only_seq_len) pass def test_load_pread_overlaps(): # load_pread_overlaps(fp_in) pass def test_load_sg_edges(): # load_sg_edges(fp_in) pass def test_add_node(): # add_node(gfa_graph, v, preads_dict) pass def test_add_edge(): # add_edge(gfa_graph, v, w, edge_split_line, preads_overlap_dict, sg_edges_dict) pass def test_add_tiling_paths_to_gfa(): # add_tiling_paths_to_gfa(gfa_graph, tiling_paths, preads_dict, preads_overlap_dict, sg_edges_dict) pass def test_add_string_graph_to_gfa(): # add_string_graph_to_gfa(gfa_graph, sg_edges_list, utg_data, ctg_paths, preads_dict, preads_overlap_dict, sg_edges_dict) pass def test_main_1(): pass ================================================ FILE: test/test_consensus.py ================================================ import falcon_kit.mains.consensus as mod def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass ================================================ FILE: test/test_contig_annotate.py ================================================ import falcon_kit.mains.contig_annotate as mod ''' def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass ''' ================================================ FILE: test/test_ctg_link_analysis.py ================================================ import falcon_kit.mains.ctg_link_analysis as mod ''' def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass ''' ================================================ FILE: test/test_functional.py ================================================ import helpers import pytest import falcon_kit.functional as f import collections import os import re thisdir = os.path.dirname(os.path.abspath(__file__)) example_HPCdaligner_fn = os.path.join(thisdir, 'HPCdaligner_synth0_new.sh') example_HPCdaligner_small_fn = os.path.join( thisdir, 'HPCdaligner_synth0_preads.sh') def eq_(a, b): assert a == b def test_get_daligner_job_descriptions(): example_HPCdaligner = open(example_HPCdaligner_fn) result = f.get_daligner_job_descriptions( example_HPCdaligner, 'raw_reads') assert result import sys, pprint sys.stderr.write(pprint.pformat(result)) helpers.equal_multiline(result[('.1', '.1')], 'daligner -v -w1 -h1 -t50 -H2000 -e0.99 -l1 -s1000 -P=. -mdust raw_reads.1 raw_reads.1\nLAcheck -v raw_reads *.las\n') helpers.equal_multiline(result[('.2', '.1', '.2')], 'daligner -v -w1 -h1 -t50 -H2000 -e0.99 -l1 -s1000 -P=. -mdust raw_reads.2 raw_reads.1 raw_reads.2\nLAcheck -v raw_reads *.las\n') eq_(len(result), 2) def test_get_daligner_job_descriptions_with_bad_arg(): with pytest.raises(AssertionError) as excinfo: f.get_daligner_job_descriptions( 'fake_filename.txt', 'raw_reads') assert r"f\na\nk\ne" in str(excinfo.value) def test_get_daligner_job_descriptions_small(): # when there is only 1 block, a special case example_HPCdaligner = open(example_HPCdaligner_small_fn) result = f.get_daligner_job_descriptions( example_HPCdaligner, 'preads', single=True) assert result helpers.equal_multiline(result[('.1', '.1')], 'daligner -v -h1 -t50 -H1 -e0.99 -l1 -s1000 preads.1 preads.1\nLAcheck -v preads *.las\n') eq_(len(result), 1) example_se161 = os.path.join(thisdir, 'se161.sh') def test_get_daligner_job_descriptions_se161(): example_HPCdaligner = open(example_se161) result = f.get_daligner_job_descriptions( example_HPCdaligner, 'raw_reads', single=False) assert result def test_get_mjob_data(): example_HPCdaligner = open(example_HPCdaligner_fn) result = f.get_mjob_data( example_HPCdaligner) assert result eq_(result[1], [ 'LAmerge -v raw_reads.1 raw_reads.1.raw_reads.1 raw_reads.1.raw_reads.2', 'rm raw_reads.1.raw_reads.1.las raw_reads.1.raw_reads.2.las']) eq_(result[2], [ 'LAmerge -v raw_reads.2 raw_reads.2.raw_reads.1 raw_reads.2.raw_reads.2', 'rm raw_reads.2.raw_reads.1.las raw_reads.2.raw_reads.2.las']) def test_skip_LAcheck(): orig = """set -e hello there LAcheck foo bar middle LAcheck -vS foo bar goodbye """ got = f.skip_LAcheck(orig) expected = """set -e hello there set +e LAcheck foo bar set -e middle set +e LAcheck -vS foo bar set -e goodbye """ eq_(got, expected) def test_first_block_las(): line = 'LAsort -v -a -q foo.1.foo.1.C0' result = f.first_block_las(line) eq_(result, 1) line = 'LAsort foo.1.foo.1.C0' result = f.first_block_las(line) eq_(result, 1) # We expect HPC.daligner to use block numbers always. line = 'LAsort -v -a -q foo.foo.C0' with pytest.raises(Exception): f.first_block_las(line) line = 'LAsort foo.foo.C0' with pytest.raises(Exception): f.first_block_las(line) def test_xform_script_for_preads(): # Technically, we never have more than one daligner in a script, but that # could change in pbsmrtpipe, since it limits the number of chunks. script = 'daligner x y\nLAsort a b\ndaligner x1 y1\n' expected = 'daligner_p x y\nLAsort a b\ndaligner_p x1 y1\n' result = f.xform_script_for_preads(script) eq_(result, expected) script = 'daligner x y\nLAsort a b\ndaligner x1 y1\n' expected = script # no-op result = f.xform_script_for_raw_reads(script) eq_(result, expected) eq_(f.get_script_xformer(True), f.xform_script_for_preads) eq_(f.get_script_xformer(False), f.xform_script_for_raw_reads) read_lens = [1, 2, 2, 3] rs_rl_counts = [(3, 1), (2, 2), (1, 1)] assert collections.Counter(read_lens) == dict(rs_rl_counts) def check(target, expected): got = f.calc_cutoff_from_reverse_sorted_readlength_counts( rs_rl_counts, target) eq_(expected, got) @pytest.mark.parametrize("n_target, n_expected", [ (8, 1), (7, 2), (4, 2), (3, 3), (1, 3), (0, 3), ]) def test_calc_cutoff_from_reverse_sorted_readlength_counts(n_target, n_expected): check(n_target, n_expected) def test_calc_cutoff_from_reverse_sorted_readlength_counts_raises(): with pytest.raises(Exception): check(9, None) capture = """ Statistics for all reads of length 500 bases or more 240,548 reads out of 309,410 ( 77.7%) 1,117,649,525 base pairs out of 1,320,493,403 ( 84.6%) 4,646 average read length 6,418 standard deviation Base composition: 0.264(A) 0.247(C) 0.279(G) 0.211(T) Distribution of Read Lengths (Bin size = 1) Bin: Count % Reads % Bases Average 169,514: 1 0.0 0.0 169514 169,513: 0 0.0 0.0 169514 """ def test_get_reverse_sorted_readlength_counts_from_DBstats(): got = f.get_reverse_sorted_readlength_counts_from_DBstats(capture) expected = [(169514, 1), (169513, 0)] eq_(expected, got) def test_num2int(): eq_(5, f.num2int('5')) eq_(1000, f.num2int('1,000')) eq_(1000000, f.num2int('1,000,000')) partial_capture = """ Bin: Count % Reads % Bases Average 4: 2 0.0 0.0 xxx 3: 0 0.0 0.0 xxx 2: 3 0.0 0.0 xxx 1: 8 0.0 0.0 xxx """ def test_calc_cutoff(): target = 14 expected = 2 got = f.calc_cutoff(target, partial_capture) eq_(expected, got) def test_calc_cutoff_bad_coverage(): target = 23 # > 22 available expected_message = 'Not enough reads available for desired genome coverage (bases needed=23 > actual=22)' with pytest.raises(f.GenomeCoverageError) as ctx: f.calc_cutoff(target, partial_capture) assert expected_message == str(ctx.value) sample_DBdump_output = """+ R 2 + M 0 + H 400 @ H 8 R 0 H 8 m000_000 L 10 1899 3899 R 1 H 8 m000_000 L 11 2080 4080 R 2 H 8 m000_000 L 12 0 2500 """ def test_parsed_readlengths_from_dbdump_output(): lengths = list(f.parsed_readlengths_from_dbdump_output( sample_DBdump_output)) helpers.equal_list(lengths, [2000, 2000, 2500]) def test_mapped_readlengths_from_dbdump_output(): mapped = f.mapped_readlengths_from_dbdump_output(sample_DBdump_output) helpers.equal_dict(mapped, {0: 2000, 1: 2000, 2: 2500}) def test_average_difference(): dictA = {1: 50, 2: 60} dictB = {1: 55, 2: 65, 3: 70} avg = f.average_difference(dictA, dictB) eq_(avg, -5.0) dictB = {1: 55} with pytest.raises(Exception): f.average_difference(dictA, dictB) sample_perl_output = """ 0 1900 1 1950 """ def test_calc_metric_truncation(): # and prove that dbdump can have extra reads, ignored. trunc = f.calc_metric_truncation(sample_DBdump_output, sample_perl_output) eq_(trunc, 75.0) sample_perl_counts_output = """ 100 1 200 2 100 5 """ def test_calc_metric_fragmentation(): frag = f.calc_metric_fragmentation(sample_perl_counts_output) eq_(frag, 2.5) def test_args_from_line(): line = 'LAmerge -v preads.1 preads.1.preads.1.C0.S preads.1.preads.1.N0.S' expected = ['preads.1', 'preads.1.preads.1.C0.S', 'preads.1.preads.1.N0.S'] result = list(f.yield_args_from_line(line)) helpers.equal_list(result, expected) bash_lines = [line] las_files = [word + '.las' for word in f.yield_args_from_line( line) for line in bash_lines if line.startswith('LAmerge')][1:] from falcon_kit.util import io def test_splitlines_iter(): for text in ['', 'a', 'a\n', 'a\nb', 'a\nb\nc', 'a\nb\nc\n', '\n', '\na', '\na\n']: assert list(io.splitlines_iter(text)) == list(text.splitlines()) def test_Readers(): reader = io.CapturedProcessReaderContext('echo "hi\nthere"') with reader: assert ['hi', 'there'] == list(reader.readlines()) reader = io.StreamedProcessReaderContext('echo "hi\nthere"') with reader: assert ['hi', 'there'] == list(reader.readlines()) from falcon_kit.mains import consensus_task # These are now redudant with the doctests, but I guess they don't hurt anything. # And I'm not sure whether SonarQube sees doctest results. (I think so.) ~cd def test_get_falcon_sense_option(): assert consensus_task.get_falcon_sense_option('', 11) == ' --n-core=11' assert consensus_task.get_falcon_sense_option('--n-core=24', 10) == ' --n-core=10' def test_get_pa_dazcon_option(): assert consensus_task.get_pa_dazcon_option('', 12) == ' -j 12' assert consensus_task.get_pa_dazcon_option('-j 48', 13) == ' -j 13' def test_get_option_with_proper_nproc(): regexp = re.compile(r'-j[^\d]*(\d+)') assert consensus_task.get_option_with_proper_nproc(regexp, 'foo -j 5', 'baz', nproc=7, cpu_count=6) == ('foo ', 5) assert consensus_task.get_option_with_proper_nproc(regexp, 'foo -j 5', 'baz', nproc=3, cpu_count=4) == ('foo ', 3) assert consensus_task.get_option_with_proper_nproc(regexp, 'foo -j 5', 'baz', nproc=3, cpu_count=2) == ('foo ', 2) assert consensus_task.get_option_with_proper_nproc(regexp, 'foo', 'baz', nproc=3, cpu_count=3) == ('foo', 3) ================================================ FILE: test/test_gen_gfa_v1.py ================================================ import falcon_kit.mains.gen_gfa_v1 as mod import helpers import pytest import os def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass def test_main_1(tmpdir, capsys): # test_dir = os.path.join(helpers.get_test_data_dir(), 'gfa-1') gfa_graph = mod.GFAGraph() gfa_graph.add_node('node1', 7, 'ACTGAAA', tags={}, labels={}) gfa_graph.add_node('node2', 10, 'AAACCCGGGT', tags={}, labels={}) gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', 4, 7, 0, 3, '*', tags={}, labels={}) gfa_graph.add_path('000000F', ['node1', 'node2'], ['4M', '7M'], tags={}, labels={}) gfa_json_file = tmpdir.join('graph.gfa.json') gfa_json_file.write(mod.serialize_gfa(gfa_graph)) argv = ['prog', str(gfa_json_file), ] mod.main(argv) out, err = capsys.readouterr() expected = """H VN:Z:1.0 S node1 ACTGAAA LN:i:7 S node2 AAACCCGGGT LN:i:10 L node1 + node2 + 3M P 000000F node1,node2 4M,7M """ # Custom tags can be in an arbitrary order and hard to compare. # They might also change between versions, so just remove # them manually here and compare only the important fields. result = [] for line in out.splitlines(): line = line.strip() sl = line.split() if len(line) == 0: continue if line[0] == 'H': result.append('\t'.join(sl[0:2])) elif line[0] == 'S': result.append('\t'.join(sl[0:4])) elif line[0] == 'L': result.append('\t'.join(sl[0:6])) elif line[0] == 'P': result.append('\t'.join(sl[0:4])) result_str = '\n'.join(result) + '\n' assert(result_str == expected) ================================================ FILE: test/test_gen_gfa_v2.py ================================================ import falcon_kit.mains.gen_gfa_v2 as mod import helpers import pytest import os def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass def test_main_1(tmpdir, capsys): # test_dir = os.path.join(helpers.get_test_data_dir(), 'gfa-1') gfa_graph = mod.GFAGraph() gfa_graph.add_node('node1', 7, 'ACTGAAA', tags={}, labels={}) gfa_graph.add_node('node2', 10, 'AAACCCGGGT', tags={}, labels={}) gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', 4, 7, 0, 3, '*', tags={}, labels={}) gfa_graph.add_path('000000F', ['node1', 'node2'], ['4M', '7M'], tags={}, labels={}) gfa_json_file = tmpdir.join('graph.gfa.json') gfa_json_file.write(mod.serialize_gfa(gfa_graph)) argv = ['prog', str(gfa_json_file), ] mod.main(argv) out, err = capsys.readouterr() expected = """H VN:Z:2.0 S node1 7 ACTGAAA S node2 10 AAACCCGGGT E edge1 node1+ node2+ 4 7$ 0 3 * """ # Custom tags can be in an arbitrary order and hard to compare. # They might also change between versions, so just remove # them manually here and compare only the important fields. result = [] for line in out.splitlines(): line = line.strip() sl = line.split() if len(line) == 0: continue if line[0] == 'H': result.append('\t'.join(sl[0:2])) elif line[0] == 'S': result.append('\t'.join(sl[0:4])) elif line[0] == 'E': result.append('\t'.join(sl[0:9])) result_str = '\n'.join(result) + '\n' assert(result_str == expected) ================================================ FILE: test/test_gfa_graph.py ================================================ from StringIO import StringIO import os import pytest import networkx as nx from falcon_kit.fc_asm_graph import AsmGraph from falcon_kit.mains.ovlp_to_graph import reverse_end from falcon_kit.util import system import falcon_kit.gfa_graph as mod import falcon_kit.mains.gen_gfa_v1 as gen_gfa_v1 import helpers def test_gfa_graph(): gfa_graph = mod.GFAGraph() def test_add_node_1(): """ Test normal usage. """ gfa_graph = mod.GFAGraph() gfa_graph.add_node('node1', 4, 'ACTG', tags={}, labels={}) gfa_graph.add_node('node2', 1000, '*', tags={}, labels={}) assert(len(gfa_graph.nodes) == 2) def test_add_node_2(): """ Tests that exceptions get raised if parameters are not correct. """ gfa_graph = mod.GFAGraph() with pytest.raises(Exception): gfa_graph.add_node('', 4, 'ACTG', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_node('node1', -1, 'ACTG', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_node('node1', 4, '', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_node('node1', 4, 'ACTG', tags=[], labels={}) with pytest.raises(Exception): gfa_graph.add_node('node1', 4, 'ACTG', tags={}, labels=[]) def test_add_edge_1(): """ Test normal usage. """ gfa_graph = mod.GFAGraph() gfa_graph.add_node('node1', 4, 'ACTG', tags={}, labels={}) gfa_graph.add_node('node2', 1000, '*', tags={}, labels={}) edge_name = 'edge1' source, source_orient = 'node1', '+' sink, sink_orient = 'node2', '+' source_start, source_end = 4, 4 sink_start, sink_end = 0, 0 cigar = '*' gfa_graph.add_edge(edge_name, source, source_orient, sink, sink_orient, source_start, source_end, sink_start, sink_end, cigar, tags={}, labels={}) assert(len(gfa_graph.edges.keys()) == 1) def test_add_edge_2(): """ Tests that exceptions get raised if parameters are not correct. """ gfa_graph = mod.GFAGraph() with pytest.raises(Exception): gfa_graph.add_edge('', 'node1', '+', 'node2', '+', 4, 4, 0, 0, '*', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_edge('edge1', '', '+', 'node2', '+', 4, 4, 0, 0, '*', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_edge('edge1', 'node1', '+', '', '+', 4, 4, 0, 0, '*', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_edge('edge1', 'node1', '1', 'node2', '+', 4, 4, 0, 0, '*', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_edge('edge1', 'node1', '+', 'node2', 'z', 4, 4, 0, 0, '*', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', -1, 4, 0, 0, '*', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', 4, -1, 0, 0, '*', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', 4, 4, -1, 0, '*', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', 4, 4, 0, -1, '*', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', 4, 4, 0, 0, '', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', 4, 3, 0, 0, '*', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', 4, 4, 5, 0, '*', tags={}, labels={}) with pytest.raises(Exception): gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', 4, 4, 0, 0, '*', tags=[], labels={}) with pytest.raises(Exception): gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', 4, 4, 0, 0, '*', tags={}, labels=[]) def test_add_path_1(): """ Test normal usage. """ gfa_graph = mod.GFAGraph() path_nodes = ['node1', 'node2', 'node3', 'node4', 'node5'] path_cigars = ['500M', '400M', '300M', '200M', '100M'] gfa_graph.add_path('000000F', path_nodes, path_cigars) assert(len(gfa_graph.paths.keys()) == 1) def test_add_path_2(): """ Tests that exceptions get raised if parameters are not correct. """ gfa_graph = mod.GFAGraph() with pytest.raises(Exception): path_nodes = ['node1', 'node2', 'node3', 'node4', 'node5'] path_cigars = ['500M', '400M', '300M', '200M', '100M'] gfa_graph.add_path('', path_nodes, path_cigars) with pytest.raises(Exception): path_nodes = ['node1'] path_cigars = ['500M', '400M', '300M', '200M', '100M'] gfa_graph.add_path('000000F', path_nodes, path_cigars) with pytest.raises(Exception): path_nodes = ['node1', 'node2', 'node3', 'node4', 'node5'] path_cigars = ['500M'] gfa_graph.add_path('000000F', path_nodes, path_cigars) with pytest.raises(Exception): path_nodes = [] path_cigars = ['500M'] gfa_graph.add_path('000000F', path_nodes, path_cigars) with pytest.raises(Exception): path_nodes = ['node1'] path_cigars = [] gfa_graph.add_path('000000F', path_nodes, path_cigars) with pytest.raises(Exception): path_nodes = ['node1', 'node2', 'node3', 'node4', 'node5'] path_cigars = ['500M', '400M', '300M', '200M', '100M'] gfa_graph.add_path('000000F', path_nodes, path_cigars, tags=[], labels={}) with pytest.raises(Exception): path_nodes = ['node1', 'node2', 'node3', 'node4', 'node5'] path_cigars = ['500M', '400M', '300M', '200M', '100M'] gfa_graph.add_path('000000F', path_nodes, path_cigars, tags={}, labels=[]) def test_write_gfa_v1(): gfa_graph = mod.GFAGraph() gfa_graph.add_node('node1', 7, 'ACTGAAA', tags={}, labels={}) gfa_graph.add_node('node2', 10, 'AAACCCGGGT', tags={}, labels={}) gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', 4, 7, 0, 3, '*', tags={}, labels={}) gfa_graph.add_path('000000F', ['node1', 'node2'], ['4M', '7M'], tags={}, labels={}) fp_out = StringIO() gfa_graph.write_gfa_v1(fp_out) result = fp_out.getvalue() expected = """H VN:Z:1.0 S node1 ACTGAAA LN:i:7 S node2 AAACCCGGGT LN:i:10 L node1 + node2 + 3M P 000000F node1,node2 4M,7M """ assert(result == expected) def test_write_gfa_v2(): gfa_graph = mod.GFAGraph() gfa_graph.add_node('node1', 7, 'ACTGAAA', tags={}, labels={}) gfa_graph.add_node('node2', 10, 'AAACCCGGGT', tags={}, labels={}) gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', 4, 7, 0, 3, '*', tags={}, labels={}) gfa_graph.add_path('000000F', ['node1', 'node2'], ['4M', '7M'], tags={}, labels={}) fp_out = StringIO() gfa_graph.write_gfa_v2(fp_out) result = fp_out.getvalue() expected = """H VN:Z:2.0 S node1 7 ACTGAAA S node2 10 AAACCCGGGT E edge1 node1+ node2+ 4 7$ 0 3 * """ assert(result == expected) def test_serialize(): gfa_graph = mod.GFAGraph() gfa_graph.add_node('node1', 7, 'ACTGAAA', tags={}, labels={}) gfa_graph.add_node('node2', 10, 'AAACCCGGGT', tags={}, labels={}) gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', 4, 7, 0, 3, '*', tags={}, labels={}) gfa_graph.add_path('000000F', ['node1', 'node2'], ['4M', '7M'], tags={}, labels={'label1': 'test'}) result = mod.serialize_gfa(gfa_graph) expected = '{"paths": {"000000F": {"labels": {"label1": "test"}, "nodes": ["node1", "node2"], "tags": {}, "name": "000000F", "cigars": ["4M", "7M"]}}, "nodes": {"node1": {"labels": {}, "seq": "ACTGAAA", "name": "node1", "len": 7, "tags": {}}, "node2": {"labels": {}, "seq": "AAACCCGGGT", "name": "node2", "len": 10, "tags": {}}}, "edges": {"(\'node1\', \'node2\')": {"labels": {}, "v_orient": "+", "tags": {}, "v_start": 4, "cigar": "*", "w_end": 3, "w_start": 0, "w_orient": "+", "name": "edge1", "v_end": 7, "w": "node2", "v": "node1"}}}' assert(result == expected) def test_deserialize(): gfa_graph = mod.GFAGraph() gfa_graph.add_node('node1', 7, 'ACTGAAA', tags={}, labels={}) gfa_graph.add_node('node2', 10, 'AAACCCGGGT', tags={}, labels={}) gfa_graph.add_edge('edge1', 'node1', '+', 'node2', '+', 4, 7, 0, 3, '*', tags={}, labels={}) gfa_graph.add_path('000000F', ['node1', 'node2'], ['4M', '7M'], tags={}, labels={'label1': 'test'}) dump = mod.serialize_gfa(gfa_graph) fp_in = StringIO(dump) result = mod.deserialize_gfa(fp_in) assert (result.nodes == gfa_graph.nodes) assert (result.edges == gfa_graph.edges) assert (result.paths == gfa_graph.paths) ================================================ FILE: test/test_graph_to_contig.py ================================================ import falcon_kit.mains.graph_to_contig as mod ''' def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass ''' ================================================ FILE: test/test_graph_to_utgs.py ================================================ import falcon_kit.mains.graph_to_utgs as mod ''' def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass ''' ================================================ FILE: test/test_ovlp_filter.py ================================================ import falcon_kit.mains.ovlp_filter as mod def assert_equal(expected, got): assert expected == got def test_help(): """Can be called 'pytest' or something, but reports proper help message otherwise. """ try: mod.main(['prog', '--help']) except SystemExit: pass def test_several(): expected = ['000000001', '000000002', '000000017', '000000028'] data = """\ 000000000 000000001 -1807 100.00 0 181 1988 1988 0 0 1807 1989 overlap 000000000 000000002 -823 99.88 0 0 823 1988 0 1166 1989 1989 overlap 000000000 000000003 -50 99.94 0 0 50 1988 0 0 50 50 overlap 000000000 000000017 -61 98.36 0 0 61 1988 0 1928 1989 1989 overlap 000000000 000000028 -1952 79.95 0 0 1952 1988 0 37 1989 1989 overlap 000000001 000000000 -1807 100.00 0 0 1807 1989 0 181 1988 1988 overlap 000000001 000000002 -642 99.84 0 0 642 1989 0 1347 1989 1989 overlap 000000002 000000000 -823 99.88 0 1166 1989 1989 0 0 823 1988 overlap 000000002 000000001 -642 99.84 0 1347 1989 1989 0 0 642 1989 overlap 000000003 000000000 -50 99.94 0 0 50 50 0 0 50 1988 overlap 000000017 000000000 -61 98.36 0 1928 1989 1989 0 0 61 1988 overlap 000000028 000000000 -1952 79.95 0 37 1989 1989 0 0 1952 1988 overlap """ readlines = data.strip().splitlines max_diff, max_ovlp, min_ovlp, min_len = 1000, 1000, 1, 1 got = mod.filter_stage1(readlines, max_diff, max_ovlp, min_ovlp, min_len) assert_equal(expected, got) def test_one_not_ignored(): """This is the same as a line dropped in the earlier test. """ expected = [] data = """\ 000000003 000000000 -50 99.94 0 0 50 50 0 0 50 1988 overlap """ readlines = data.strip().splitlines max_diff, max_ovlp, min_ovlp, min_len = 1000, 1000, 1, 1 got = mod.filter_stage1(readlines, max_diff, max_ovlp, min_ovlp, min_len) assert_equal(expected, got) def test_one_line_ignored(): """This is the same as a line kept in the earlier test. """ expected = ['000000017'] data = """\ 000000017 000000000 -61 98.36 0 1928 1989 1989 0 0 61 1988 overlap """ readlines = data.strip().splitlines max_diff, max_ovlp, min_ovlp, min_len = 1000, 1000, 1, 1 got = mod.filter_stage1(readlines, max_diff, max_ovlp, min_ovlp, min_len) assert_equal(expected, got) def test_empty(): expected = [] data = """\ """ readlines = data.strip().splitlines max_diff, max_ovlp, min_ovlp, min_len = 1000, 1000, 1, 1 got = mod.filter_stage1(readlines, max_diff, max_ovlp, min_ovlp, min_len) assert_equal(expected, got) ================================================ FILE: test/test_ovlp_stats.py ================================================ import falcon_kit.mains.ovlp_stats as mod def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass def test(): readlines = data.strip().splitlines stats = mod.filter_stats(readlines, min_len=62) # print stats assert expected == stats expected = [('000000000', 1988, 2, 1), ('000000001', 1989, 2, 0), ('000000002', 1989, 0, 2), ('000000017', 1989, 0, 1)] data = """ 000000000 000000001 -1807 100.00 0 181 1988 1988 0 0 1807 1989 overlap 000000000 000000002 -823 99.88 0 0 823 1988 0 1166 1989 1989 overlap 000000000 000000003 -50 99.94 0 0 50 1988 0 0 50 50 overlap 000000000 000000017 -61 98.36 0 0 61 1988 0 1928 1989 1989 overlap 000000000 000000028 -1952 79.95 0 0 1952 1988 0 37 1989 1989 overlap 000000001 000000000 -1807 100.00 0 0 1807 1989 0 181 1988 1988 overlap 000000001 000000002 -642 99.84 0 0 642 1989 0 1347 1989 1989 overlap 000000002 000000000 -823 99.88 0 1166 1989 1989 0 0 823 1988 overlap 000000002 000000001 -642 99.84 0 1347 1989 1989 0 0 642 1989 overlap 000000003 000000000 -50 99.94 0 0 50 50 0 0 50 1988 overlap 000000017 000000000 -61 98.36 0 1928 1989 1989 0 0 61 1988 overlap 000000028 000000000 -1952 79.95 0 37 1989 1989 0 0 1952 1988 overlap """ ================================================ FILE: test/test_ovlp_to_graph.py ================================================ import falcon_kit.mains.ovlp_to_graph as mod import pytest def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass def test_reverse_end(): ret = mod.reverse_end('123:B') expected = '123:E' assert(expected == ret) ret = mod.reverse_end('456:E') expected = '456:B' assert(expected == ret) ret = mod.reverse_end(':B') expected = ':E' assert(expected == ret) ret = mod.reverse_end(':E') expected = ':B' assert(expected == ret) with pytest.raises(Exception) as e_info: ret = mod.reverse_end(':') with pytest.raises(Exception) as e_info: ret = mod.reverse_end('') with pytest.raises(Exception) as e_info: ret = mod.reverse_end('12345:C') with pytest.raises(Exception) as e_info: ret = mod.reverse_end(':::') ================================================ FILE: test/test_run.py ================================================ #import falcon_kit.mains.run as mod ''' def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass ''' ================================================ FILE: test/test_run_LG.py ================================================ #import falcon_kit.mains.run_LG as mod ''' def test_help(): try: mod.main(['prog', '--help']) except SystemExit: pass ''' ================================================ FILE: test/test_run_support.py ================================================ import pytest import StringIO import falcon_kit.run_support as mod def parse_config(content): """Used by tests. (Clean this code up later.) """ stream = StringIO.StringIO config = mod.parse_cfg_with_sections(stream(content)) mod.update_defaults(config['General']) mod.check_config_sections(config) mod.update_job_sections(config) return config FC_RUN_CFG = """\ [General] input_fofn = input.fofn genome_size = 100 job_name_style = 1 #use_tmpdir = true #job_type = local #job_type = sge stop_all_jobs_on_failure = true #skip_checks = true #use_tmpdir = /scratch pwatcher_type = blocking job_type = string job_queue = bash -C ${CMD} >| ${STDOUT_FILE} 2>| ${STDERR_FILE} job_queue = bash -C ${CMD} # By dropping STD*_FILE, we see all output on the console. # That helps debugging in TravisCI/Bamboo. # list of files of the initial bas.h5 files input_fofn = input.fofn #input_fofn = preads.fofn input_type = raw #input_type = preads # The length cutoff used for seed reads used for initial mapping #length_cutoff = 1 genome_size = 5000 seed_coverage = 20 # The length cutoff used for seed reads usef for pre-assembly length_cutoff_pr = 1 #job_queue = production sge_option_da = -pe smp 8 -q %(job_queue)s sge_option_la = -pe smp 2 -q %(job_queue)s sge_option_pda = -pe smp 8 -q %(job_queue)s sge_option_pla = -pe smp 2 -q %(job_queue)s sge_option_fc = -pe smp 24 -q %(job_queue)s sge_option_cns = -pe smp 8 -q %(job_queue)s default_concurrent_jobs = 64 da_concurrent_jobs = 32 la_concurrent_jobs = 32 cns_concurrent_jobs = 32 pda_concurrent_jobs = 32 pla_concurrent_jobs = 32 pa_HPCdaligner_option = -v -B4 -t50 -h1 -e.99 -w1 -l1 -s1000 ovlp_HPCdaligner_option = -v -B4 -t50 -h1 -e.99 -l1 -s1000 #pa_DBsplit_option = -a -x5 -s.00065536 pa_DBsplit_option = -a -x5 -s.065536 #pa_DBsplit_option = -a -x5 -s1 ovlp_DBsplit_option = -a -x5 -s50 LA4Falcon_preload = true falcon_sense_option = --output_multi --min_idt 0.70 --min_cov 1 --max_n_read 20000 --n_core 0 #--min_cov_aln 1 --min_len_aln 40 overlap_filtering_setting = --max_diff 10000 --max_cov 100000 --min_cov 1 --min_len 1 --bestn 1000 --n_core 0 #dazcon = 1 [job.defaults] submit = bash -C ${CMD} 2> ${STDERR_FILE}.${NPROC}.txt [job.step.da] NPROC = 256 [job.step.pda] njobs = 42 """ def test_check_config_sections(): # called implicitly config = parse_config(FC_RUN_CFG) assert int(config['General']['default_concurrent_jobs']) == 64 assert int(config['General']['da_concurrent_jobs']) == 32 assert int(config['job.defaults']['njobs']) == 64 assert int(config['job.step.da']['njobs']) == 32 assert int(config['job.step.da']['NPROC']) == 256 assert int(config['job.step.pda']['njobs']) == 42 def test_check_config_sections_foo(): config = mod.parse_cfg_with_sections(StringIO.StringIO(FC_RUN_CFG)) import collections config['foo'] = collections.defaultdict(list) with pytest.raises(Exception) as excinfo: mod.check_config_sections(config) assert 'You have 1 unexpected cfg sections' in str(excinfo.value) CFG_SANS_SUBMIT_LOCAL = """\ [General] input_fofn = input.fofn genome_size = 100 pwatcher_type = fs_based job_type = local [job.defaults] # empty """ def test_update_job_sections0(): config = parse_config(CFG_SANS_SUBMIT_LOCAL) assert 'submit' not in config['job.defaults'] #assert config['job.defaults']['submit'] == 'bash -C ${CMD}' CFG_SANS_SUBMIT_SANS_JOB_TYPE = """\ [General] input_fofn = input.fofn genome_size = 100 pwatcher_type = fs_based #job_type = sge [job.defaults] # empty """ @pytest.mark.skip def test_update_job_sections1(): """For now, we do not raise anything, since pbsmrtpipe examples do not set this. """ with pytest.raises(Exception) as excinfo: parse_config(CFG_SANS_SUBMIT_SANS_JOB_TYPE) assert 'but job_type is not set' in str(excinfo.value) CFG_SANS_SUBMIT_UNKNOWN_JOB_TYPE = """\ [General] input_fofn = input.fofn genome_size = 100 [job.defaults] pwatcher_type = fs_based #submit = 'bar' job_type = foo # empty """ def test_update_job_sections2(): with pytest.raises(Exception) as excinfo: config = parse_config(CFG_SANS_SUBMIT_UNKNOWN_JOB_TYPE) assert 'job_type=foo not in ' in str(excinfo.value) CFG_SANS_SUBMIT_UNKNOWN_PWATCHER_TYPE = """\ [General] input_fofn = input.fofn genome_size = 100 [job.defaults] pwatcher_type = foo job_type = sge # empty """ def test_update_job_sections3(): with pytest.raises(Exception) as excinfo: config = parse_config(CFG_SANS_SUBMIT_UNKNOWN_PWATCHER_TYPE) assert 'Unknown pwatcher_type' in str(excinfo.value) def test_clean_falcon_options(): fc = dict( falcon_sense_option='foo --opt_one --opt-two --opt_three_x', overlap_filtering_setting='bar --Opt_one --Opt-two --Opt_three_x', ) expected = dict( falcon_sense_option='foo --opt-one --opt-two --opt-three-x', overlap_filtering_setting='bar --Opt-one --Opt-two --Opt-three-x', ) mod.clean_falcon_options(fc) assert fc == expected ================================================ FILE: test/test_stats_preassembly.py ================================================ import falcon_kit.stats_preassembly as M import helpers def test_stats_from_sorted_readlengths(): stats = M.stats_from_sorted_readlengths([1, 2, 3, 4]) expected = M.Stats(nreads=4, total=10, n50=3, p95=4, esize=3.0) assert stats == expected def test_stats_dict(): #Stats = collections.namedtuple('FastaStats', ['nreads', 'total', 'n50', 'p95']) stats_raw_reads = M.Stats(100, 1000, 50, 95, 0.0) stats_seed_reads = M.Stats(50, 500, 25, 40, 0.0) stats_corrected_reads = M.Stats(10, 100, 5, 9, 0.0) genome_length = 19 length_cutoff = 10 frag = 1.0 trunc = 2.5 result = M.stats_dict(stats_raw_reads, stats_seed_reads, stats_corrected_reads, genome_length, length_cutoff, frag, trunc) expected = { 'genome_length': 19, 'length_cutoff': 10, 'preassembled_bases': 100, 'preassembled_coverage': 5.263, 'preassembled_mean': 10.0, 'preassembled_n50': 5, 'preassembled_p95': 9, 'preassembled_reads': 10, 'preassembled_seed_fragmentation': 1.0, 'preassembled_seed_truncation': 2.5, 'preassembled_yield': 0.2, 'preassembled_esize': 0.0, 'raw_bases': 1000, 'raw_coverage': 52.632, 'raw_mean': 10.0, 'raw_n50': 50, 'raw_p95': 95, 'raw_reads': 100, 'raw_esize': 0.0, 'seed_bases': 500, 'seed_coverage': 26.316, 'seed_mean': 10.0, 'seed_n50': 25, 'seed_p95': 40, 'seed_reads': 50, 'seed_esize': 0.0, } helpers.equal_dict(result, expected) ================================================ FILE: test/test_tiling_path.py ================================================ import falcon_kit.tiling_path as mod import helpers import pytest import os from StringIO import StringIO ###################################################### # Define an example input test dataset which will be reused. ###################################################### test_1_lines = { '000000F': """000000F 000092122:B 000081654:B 000081654 33726 0 16258 99.45 000000F 000081654:B 000034462:B 000034462 10123 0 25619 99.85 000000F 000034462:B 000061403:B 000061403 1352 0 24447 99.96""", '000001F': """000001F 000092122:B 000081654:B 000081654 33726 0 16258 99.45""", '000002F': """000002F 000014727:E 000024020:E 000024020 15242 20480 15242 99.48 000002F 000024020:E 000060868:E 000060868 19975 23210 19975 99.76""" } test_1_expected_coord_map = { '000000F': {'000092122:B': 0, '000081654:B': 33726, '000034462:B': 43849, '000061403:B': 45201}, '000001F': {'000092122:B': 0, '000081654:B': 33726}, '000002F': {'000014727:E': 0, '000024020:E': 5238, '000060868:E': 8473}, } test_1_expected_contig_len = { '000000F': 45201, '000001F': 33726, '000002F': 8473 } test_1_input_tp_as_text = '\n'.join([val for key, val in test_1_lines.iteritems()]) ###################################################### # Define a new dest dataset for testing placement, # and also extracting the subpaths. ###################################################### test_placement_1_p_path_as_text = """ 000000F 000092122:B 000081654:B 000081654 33726 0 16258 99.45 000000F 000081654:B 000034462:B 000034462 10123 0 25619 99.85 000000F 000034462:B 000061403:B 000061403 1352 0 24447 99.96 000000F 000061403:B 000021348:B 000021348 9924 0 20804 99.74 000000F 000021348:B 000062240:B 000062240 5834 0 27313 99.67 000000F 000062240:B 000083779:B 000083779 862 0 30696 99.79 000000F 000083779:B 000019819:E 000019819 31327 36889 31331 99.94 000000F 000019819:E 000063672:E 000063672 29861 31245 29861 99.96 000000F 000063672:E 000026565:E 000026565 28347 28820 28363 99.87 000000F 000026565:E 000050047:B 000050047 2171 0 23431 99.62 000001F 000092122:B 000081654:B 000081654 33726 0 16258 99.45 000002F 000014727:E 000024020:E 000024020 15242 20480 15242 99.48 000002F 000024020:E 000060868:E 000060868 19975 23210 19975 99.76 """ test_placement_1_a_path_as_text = """ 000000F-1 000034462:B 000070651:E 000070651 0 10000 10000 99.80 000000F-1 000070651:E 000018109:E 000018109 16449 26526 16471 99.68 000000F-1 000018109:E 000068978:E 000068978 24989 28755 24989 99.65 000000F-1 000068978:E 000019819:E 000019819 31327 36889 31331 99.94 """ test_placement_1_expected = { '000000F': {'000000F-1': (43849, 67383, '000000F', '000000F-1', '000034462:B', '000019819:E')}, } test_placement_1_expected_coords = { '000092122:B': 0, '000081654:B': 33726, '000034462:B': 43849, '000061403:B': 45201, '000021348:B': 55125, '000062240:B': 60959, '000083779:B': 61821, '000019819:E': 67383, '000063672:E': 68767, '000026565:E': 69240, '000050047:B': 71411, } def test_tiling_path_1(): """ This is a normal test case. """ fp_in = StringIO(test_1_input_tp_as_text) # Run test. contig_lens = None whitelist_seqs = None result = mod.load_tiling_paths_from_stream(fp_in, contig_lens=contig_lens, whitelist_seqs=whitelist_seqs) # Validate. assert(sorted(result.keys()) == ['000000F', '000001F', '000002F']) # This checks several methods: # - The entire TilingPathEdge: the values are directly parsed via constructor # called from the TilingPath class. The correctness is tested by callin # the dump_as_split_lines() which should reconstruct the original input line. # - TilingPath has a method `dump_as_split_lines` which returns all such # split lines. for key, lines in test_1_lines.iteritems(): sl = [line.strip().split() for line in lines.splitlines()] assert(result[key].dump_as_split_lines() == sl) # Check the coordinates. assert(result['000000F'].coords == {'000092122:B': 0, '000081654:B': 33726, '000034462:B': 43849, '000061403:B': 45201}) assert(result['000001F'].coords == {'000092122:B': 0, '000081654:B': 33726}) assert(result['000002F'].coords == {'000014727:E': 0, '000024020:E': 5238, '000060868:E': 8473}) assert(result['000000F'].contig_len == 45201) assert(result['000001F'].contig_len == 33726) assert(result['000002F'].contig_len == 8473) assert(result['000000F'].v_to_edge == {'000092122:B': 0, '000081654:B': 1, '000034462:B': 2}) assert(result['000000F'].w_to_edge == {'000081654:B': 0, '000034462:B': 1, '000061403:B': 2}) assert(result['000001F'].v_to_edge == {'000092122:B': 0}) assert(result['000001F'].w_to_edge == {'000081654:B': 0}) assert(result['000002F'].v_to_edge == {'000014727:E': 0, '000024020:E': 1}) assert(result['000002F'].w_to_edge == {'000024020:E': 0, '000060868:E': 1}) def test_tiling_path_2(): """ This is a normal test case. Run with a dict specifying contig lengths. This should offset the coordinates. """ fp_in = StringIO(test_1_input_tp_as_text) # Run test. contig_lens = {'000000F': 50000, '000001F': 40000, '000002F': 10000} whitelist_seqs = None result = mod.load_tiling_paths_from_stream(fp_in, contig_lens=contig_lens, whitelist_seqs=whitelist_seqs) # Validate. assert(sorted(result.keys()) == ['000000F', '000001F', '000002F']) for key, lines in test_1_lines.iteritems(): sl = [line.strip().split() for line in lines.splitlines()] assert(result[key].dump_as_split_lines() == sl) # Check the coordinates. offset = contig_lens['000000F'] - 45201 assert(result['000000F'].coords == {'000092122:B': 0 + offset, '000081654:B': 33726 + offset, '000034462:B': 43849 + offset, '000061403:B': 45201 + offset}) offset = contig_lens['000001F'] - 33726 assert(result['000001F'].coords == {'000092122:B': 0 + offset, '000081654:B': 33726 + offset}) offset = contig_lens['000002F'] - 8473 assert(result['000002F'].coords == {'000014727:E': 0 + offset, '000024020:E': 5238 + offset, '000060868:E': 8473 + offset}) for key, tp in result.iteritems(): assert(tp.contig_len == contig_lens[key]) assert(result['000000F'].v_to_edge == {'000092122:B': 0, '000081654:B': 1, '000034462:B': 2}) assert(result['000000F'].w_to_edge == {'000081654:B': 0, '000034462:B': 1, '000061403:B': 2}) assert(result['000001F'].v_to_edge == {'000092122:B': 0}) assert(result['000001F'].w_to_edge == {'000081654:B': 0}) assert(result['000002F'].v_to_edge == {'000014727:E': 0, '000024020:E': 1}) assert(result['000002F'].w_to_edge == {'000024020:E': 0, '000060868:E': 1}) def test_tiling_path_3(): """ This is a normal test case. Test the whitelist filter. """ fp_in = StringIO(test_1_input_tp_as_text) # Run test. contig_lens = {'000000F': 50000, '000001F': 40000, '000002F': 10000} whitelist_seqs = set(['000000F', '000002F', 'key_that_doesnt_exist']) result = mod.load_tiling_paths_from_stream(fp_in, contig_lens=contig_lens, whitelist_seqs=whitelist_seqs) # Validate. assert(sorted(result.keys()) == ['000000F', '000002F']) for key in result.keys(): lines = test_1_lines[key] sl = [line.strip().split() for line in lines.splitlines()] assert(result[key].dump_as_split_lines() == sl) offset = contig_lens['000000F'] - 45201 assert(result['000000F'].coords == {'000092122:B': 0 + offset, '000081654:B': 33726 + offset, '000034462:B': 43849 + offset, '000061403:B': 45201 + offset}) offset = contig_lens['000002F'] - 8473 assert(result['000002F'].coords == {'000014727:E': 0 + offset, '000024020:E': 5238 + offset, '000060868:E': 8473 + offset}) for key, tp in result.iteritems(): assert(tp.contig_len == contig_lens[key]) assert(result['000000F'].v_to_edge == {'000092122:B': 0, '000081654:B': 1, '000034462:B': 2}) assert(result['000000F'].w_to_edge == {'000081654:B': 0, '000034462:B': 1, '000061403:B': 2}) assert(result['000002F'].v_to_edge == {'000014727:E': 0, '000024020:E': 1}) assert(result['000002F'].w_to_edge == {'000024020:E': 0, '000060868:E': 1}) def test_tiling_path_4_expect_crash(): """ This test attempts to create a tiling path from edges which are out of order. An exception should be raised when initializing the TilingPath object. The `calc_node_coords` should raise an exception for node '000021348:B'. """ test_3_lines = {} test_3_lines['000000F'] = test_1_lines['000000F'] + """\n000000F 000062240:B 000083779:B 000083779 862 0 30696 99.79""" test_3_lines['000001F'] = test_1_lines['000001F'] test_3_lines['000002F'] = test_1_lines['000002F'] test_3_input_tp_as_text = '\n'.join([val for key, val in test_3_lines.iteritems()]) fp_in = StringIO(test_3_input_tp_as_text) contig_lens = None whitelist_seqs = None with pytest.raises(Exception): result = mod.load_tiling_paths_from_stream(fp_in, contig_lens=contig_lens, whitelist_seqs=whitelist_seqs) def test_tiling_path_5(tmpdir): """ This is a normal test case for loading from file. The results should be the same as loading from stream. """ contig_lens = None whitelist_seqs = None tp_file = tmpdir.join('test_tiling_path') tp_file.write(test_1_input_tp_as_text) result = mod.load_tiling_paths(str(tp_file), contig_lens=contig_lens, whitelist_seqs=whitelist_seqs) fp_in = StringIO(test_1_input_tp_as_text) expected = mod.load_tiling_paths_from_stream(fp_in, contig_lens=contig_lens, whitelist_seqs=whitelist_seqs) assert(result.keys() == expected.keys()) for key in result: result_tp = result[key] expected_tp = expected[key] assert(result_tp.coords == expected_tp.coords) assert(result_tp.dump_as_split_lines() == expected_tp.dump_as_split_lines()) assert(result_tp.contig_len == expected_tp.contig_len) assert(result_tp.v_to_edge == expected_tp.v_to_edge) assert(result_tp.w_to_edge == expected_tp.w_to_edge) def test_calc_node_coords_1(): """ Run a normal test. """ fp_in = StringIO(test_1_input_tp_as_text) # Run test. # The calc_node_coords requires a list of TilingEdge objects. # Parsing of tiling paths and loading of TilingEdge objects was already # tested above, se here we just reuse the mechanism to get tp.edges. expected_coord_map = {} expected_coord_map['000000F'] = {'000092122:B': 0, '000081654:B': 33726, '000034462:B': 43849, '000061403:B': 45201} expected_coord_map['000001F'] = {'000092122:B': 0, '000081654:B': 33726} expected_coord_map['000002F'] = {'000014727:E': 0, '000024020:E': 5238, '000060868:E': 8473} expected_contig_len = {} expected_contig_len['000000F'] = 45201 expected_contig_len['000001F'] = 33726 expected_contig_len['000002F'] = 8473 contig_lens = expected_contig_len whitelist_seqs = None tps = mod.load_tiling_paths_from_stream(fp_in, contig_lens=contig_lens, whitelist_seqs=whitelist_seqs) for key, tp in tps.iteritems(): coord_map, contig_len = mod.calc_node_coords(tp.edges, first_node_offset=0) assert(coord_map == expected_coord_map[key]) assert(contig_len == expected_contig_len[key]) def test_calc_node_coords_2(): """ Test on empty input. """ coord_map, contig_len = mod.calc_node_coords([], first_node_offset=0) assert(len(coord_map.keys()) == 0) assert(contig_len == 0) def test_calc_node_coords_3(): """ Run a normal test. """ fp_in = StringIO(test_1_input_tp_as_text) # Run test. # The calc_node_coords requires a list of TilingEdge objects. # Parsing of tiling paths and loading of TilingEdge objects was already # tested above, se here we just reuse the mechanism to get tp.edges. first_node_offset = {} first_node_offset['000000F'] = 50000 - 45201 first_node_offset['000001F'] = 40000 - 33726 first_node_offset['000002F'] = 10000 - 8473 expected_contig_len = {} expected_contig_len['000000F'] = 50000 # 45201 expected_contig_len['000001F'] = 40000 # 33726 expected_contig_len['000002F'] = 10000 # 8473 expected_coord_map = {} offset = first_node_offset['000000F'] expected_coord_map['000000F'] = {'000092122:B': 0 + offset, '000081654:B': 33726 + offset, '000034462:B': 43849 + offset, '000061403:B': 45201 + offset} offset = first_node_offset['000001F'] expected_coord_map['000001F'] = {'000092122:B': 0 + offset, '000081654:B': 33726 + offset} offset = first_node_offset['000002F'] expected_coord_map['000002F'] = {'000014727:E': 0 + offset, '000024020:E': 5238 + offset, '000060868:E': 8473 + offset} contig_lens = expected_contig_len whitelist_seqs = None tps = mod.load_tiling_paths_from_stream(fp_in, contig_lens=contig_lens, whitelist_seqs=whitelist_seqs) for key, tp in tps.iteritems(): coord_map, contig_len = mod.calc_node_coords(tp.edges, first_node_offset=first_node_offset[key]) assert(coord_map == expected_coord_map[key]) assert(contig_len == expected_contig_len[key]) def test_calc_node_coords_1(): """ Attempt to run on edges which are out of order. This should raise an exception. """ test_input_tp_as_text = test_1_lines['000000F'] + """\n000000F 000062240:B 000083779:B 000083779 862 0 30696 99.79""" all_sl = [line.strip().split() for line in test_input_tp_as_text.splitlines()] edges = [mod.TilingPathEdge(sl) for sl in all_sl] with pytest.raises(Exception): coord_map, contig_len = mod.calc_node_coords(edges, first_node_offset=0) def test_find_a_ctg_placement_1(): """ Normal test case. The find_a_ctg_placement method expects a valid primary contig tiling path dict and a valid associate contig tiling path dict as inputs. Validation of the construction of TilingPath objects is performed in the tests above; here we take these objects for granted. """ fp_in = StringIO(test_placement_1_p_path_as_text) p_paths = mod.load_tiling_paths_from_stream(fp_in, contig_lens=None, whitelist_seqs=None) fp_in = StringIO(test_placement_1_a_path_as_text) a_paths = mod.load_tiling_paths_from_stream(fp_in, contig_lens=None, whitelist_seqs=None) result = mod.find_a_ctg_placement(p_paths, a_paths) for key, placement in result.iteritems(): assert(placement == test_placement_1_expected[key]) def test_find_a_ctg_placement_2(): """ Test empty a_ctg paths. """ fp_in = StringIO(test_placement_1_p_path_as_text) p_paths = mod.load_tiling_paths_from_stream(fp_in, contig_lens=None, whitelist_seqs=None) a_paths = {} result = mod.find_a_ctg_placement(p_paths, a_paths) assert(len(result.keys()) == 0) def test_find_a_ctg_placement_3(): """ Test empty p_ctg paths. If the primary contig cannot be found, this should throw an exception. """ p_paths = {} fp_in = StringIO(test_placement_1_a_path_as_text) a_paths = mod.load_tiling_paths_from_stream(fp_in, contig_lens=None, whitelist_seqs=None) with pytest.raises(Exception): result = mod.find_a_ctg_placement(p_paths, a_paths) def test_get_subpath_1(): """ Check the case when the beginning and the end of the contig are provided. This should extract the entire path. """ fp_in = StringIO(test_placement_1_p_path_as_text) p_paths = mod.load_tiling_paths_from_stream(fp_in, contig_lens=None, whitelist_seqs=None) p_path = p_paths['000000F'] # The result is composed of (subpath, start_in_subpath, end_in_subpath). test_start = 0 test_end = p_path.contig_len result = p_path.get_subpath(test_start, test_end) expected = [val.get_split_line() for val in p_path.edges], test_start, test_end assert(result == expected) def test_get_subpath_2(): """ Test with a start coord < 0, which is possible if the contig was improper. """ fp_in = StringIO(test_placement_1_p_path_as_text) p_paths = mod.load_tiling_paths_from_stream(fp_in, contig_lens=None, whitelist_seqs=None) p_path = p_paths['000000F'] # The result is composed of (subpath, start_in_subpath, end_in_subpath). test_start = -100 test_end = p_path.contig_len result = p_path.get_subpath(test_start, test_end) subpath, start_in_subpath, end_in_subpath = result expected = [val.get_split_line() for val in p_path.edges], test_start, test_end assert(result == expected) def test_get_subpath_3(): """ Test the end coordinate larger than the contig length. This is also possible if the contig was improper, but is frowned upon. """ fp_in = StringIO(test_placement_1_p_path_as_text) p_paths = mod.load_tiling_paths_from_stream(fp_in, contig_lens=None, whitelist_seqs=None) p_path = p_paths['000000F'] # The result is composed of (subpath, start_in_subpath, end_in_subpath). test_start = -100 test_end = p_path.contig_len + 1000 result = p_path.get_subpath(test_start, test_end) subpath, start_in_subpath, end_in_subpath = result expected = [val.get_split_line() for val in p_path.edges], test_start, test_end assert(result == expected) def test_get_subpath_4(): """ Normal test - extract a subpath between internal coordinates. """ fp_in = StringIO(test_placement_1_p_path_as_text) p_paths = mod.load_tiling_paths_from_stream(fp_in, contig_lens=None, whitelist_seqs=None) p_path = p_paths['000000F'] # The result is composed of (subpath, start_in_subpath, end_in_subpath). test_start = 43849 + 10 # Start is within the third edge. test_end = 68767 + 100 # End is within the 9th edge result = p_path.get_subpath(test_start, test_end) subpath, start_in_subpath, end_in_subpath = result expected = [val.get_split_line() for val in p_path.edges[2:9]], 10, (test_end - 43849) assert(result == expected) def test_get_subpath_5(): """ Test edge case, when the selected coordinates are right at the ends of the tiling path edges. """ fp_in = StringIO(test_placement_1_p_path_as_text) p_paths = mod.load_tiling_paths_from_stream(fp_in, contig_lens=None, whitelist_seqs=None) p_path = p_paths['000000F'] # The result is composed of (subpath, start_in_subpath, end_in_subpath). test_start = 43849 + 0 # Start is within the third edge. test_end = 69240 + 0 # End is within the 9th edge result = p_path.get_subpath(test_start, test_end) subpath, start_in_subpath, end_in_subpath = result expected = [val.get_split_line() for val in p_path.edges[2:9]], 0, (test_end - 43849) assert(result == expected) def test_get_subpath_6(): """ The end coordinate is only one base into a new edge. This edge should entirely be output. """ fp_in = StringIO(test_placement_1_p_path_as_text) p_paths = mod.load_tiling_paths_from_stream(fp_in, contig_lens=None, whitelist_seqs=None) p_path = p_paths['000000F'] # The result is composed of (subpath, start_in_subpath, end_in_subpath). test_start = 43849 + 0 # Start is within the third edge. test_end = 69240 + 1 # End is within the 9th edge result = p_path.get_subpath(test_start, test_end) subpath, start_in_subpath, end_in_subpath = result expected = [val.get_split_line() for val in p_path.edges[2:10]], 0, (test_end - 43849) assert(result == expected) def test_get_subpath_7(): """ When both coordinates are <= 0, then only the first edge should be output. """ fp_in = StringIO(test_placement_1_p_path_as_text) p_paths = mod.load_tiling_paths_from_stream(fp_in, contig_lens=None, whitelist_seqs=None) p_path = p_paths['000000F'] # The result is composed of (subpath, start_in_subpath, end_in_subpath). test_start = -100 test_end = -10 result = p_path.get_subpath(test_start, test_end) subpath, start_in_subpath, end_in_subpath = result expected = [val.get_split_line() for val in p_path.edges[0:1]], test_start, test_end assert(result == expected) def test_get_subpath_8(): """ The end coordinate should not be <= start coordinate. """ fp_in = StringIO(test_placement_1_p_path_as_text) p_paths = mod.load_tiling_paths_from_stream(fp_in, contig_lens=None, whitelist_seqs=None) p_path = p_paths['000000F'] test_start = 10 test_end = 7 with pytest.raises(Exception): result = p_path.get_subpath(test_start, test_end) ================================================ FILE: test/test_util_io.py ================================================ import time import pytest import falcon_kit.util.io as M def test_io_se1331(): """Regression test for unicode conversion slow-down. """ x = '' cmd = 'seq 20000' beg = time.clock() reader = M.CapturedProcessReaderContext(cmd) with reader: for line in reader.readlines(): x += line end = time.clock() assert end-beg < 1 @pytest.mark.parametrize('Context', [M.CapturedProcessReaderContext, M.StreamedProcessReaderContext]) def test_str_type(Context): cmd = 'seq 2' reader = Context(cmd) with reader: lines = list(reader.readlines()) assert isinstance(lines[0], str) assert lines == ['1', '2'] ================================================ FILE: test/test_util_system.py ================================================ import falcon_kit.util.system as mod from falcon_kit.run_support import cd from falcon_kit.bash import mkdir import helpers import pytest import os import shutil def touchtree(*fns): for fn in fns: mkdir(os.path.dirname(fn)) with open(fn, 'w'): pass @pytest.yield_fixture @pytest.fixture(scope="session") def dirtree(tmpdir_factory): tmpdir = tmpdir_factory.mktemp('mytmp') with cd(str(tmpdir)): touchtree(*dir_picture.strip().split()) yield shutil.rmtree(str(tmpdir)) def picture(fns): return '\n'.join(list(fns) + ['']) dir_picture = """\ find_files/file1.txt find_files/file3.csv find_files/level_2/file4.txt find_files/test_file2.txt find_files/.dotfile """ root_dir = 'find_files' def test_system_find_files(dirtree): # Find everything result = picture(mod.find_files(root_dir, '*')) expected = """\ find_files/.dotfile find_files/file1.txt find_files/file3.csv find_files/test_file2.txt find_files/level_2/file4.txt """ assert(result == expected) # Test normal pattern result = picture(mod.find_files(root_dir, '*.txt')) expected = """\ find_files/file1.txt find_files/test_file2.txt find_files/level_2/file4.txt """ assert(result == expected) # Test empty pattern result = picture(mod.find_files(root_dir, '')) expected = '' assert(result == expected) # Test non-existent pattern result = picture(mod.find_files(root_dir, 'Wubalubadubdub')) expected = '' assert(result == expected) # Test missing dir with pytest.raises(Exception) as excinfo: list(mod.find_files('Wubalubadubdub', '*')) # Test empty dir and empty pattern with pytest.raises(Exception) as excinfo: list(mod.find_files('', '')) def test_make_fofn_abs(tmpdir): """ Paths are expanded relative to resolved directory of the input FOFN. But otherwise, symlinks do not really need to be resolved. """ with tmpdir.as_cwd(): expected = os.path.abspath('link') + '\n' touchtree('./actual') os.symlink('actual', 'link') a_fn = './actual.fofn' mod.make_dirs('./subdir') i_fn = './subdir/i.fofn' o_fn = './subdir/o.fofn' os.symlink('../actual.fofn', i_fn) with open(i_fn, 'w') as stream: stream.write('link\n') mod.make_fofn_abs(i_fn, o_fn) assert open(o_fn).read() == expected ================================================ FILE: test_data/calc_cutoff/partial_capture.txt ================================================ Bin: Count % Reads % Bases Average 4: 2 0.0 0.0 xxx 3: 0 0.0 0.0 xxx 2: 3 0.0 0.0 xxx 1: 8 0.0 0.0 xxx ================================================ FILE: test_data/gfa-1/a_ctg.fa ================================================ >0-1 CTTTTGTAAGTCAACTAAGATCGCCAGTCGATTGTGCCTAAGTCCCGCTACATCATGTCGTCCCTGGTCGTCATTTCCTTGTTGCGAGTGTGGGCCGCGCATGTGGGATGGCGATTTCATATAACTCGCGAGCAATTGAGGTAGAATCTGCTAGGATATAGTTGGGGCAACACGTGTCCGAGCCTTGCAAGTCGACTGGTGAATTTAGTACGAGCGTCTAGACTCTTGCCTAGTAGAGCTTAGCAATGAATGTTCAAATCCTGGATGCTAGGGTGGCACTTGGACGATCAGGAATTCAAACTGGGCGTCATGATTTAATTTTACGACCTCCGAAACCTTATTAGGGGTCTAAGATACCCGTGTGTCCTTGCTACAGTGTCGCATTTTGGAGATATTTGCGTTTCGTCTGGGGCCTATGCTAGCCACAACAGAAAATGAAAGGACGACGACGAGCCGGGGTTTCGTGGGCCTTTATGGGGCGTTTCCAGACCGGAAAACGACTTCAGCGCAA ================================================ FILE: test_data/gfa-1/a_ctg_tiling_path ================================================ 0-1 000000007:B 000000005:B 000000005 9 0 1980 99.95 0-1 000000005:B 000000016:B 000000016 502 0 1487 99.93 0-2 000000007:B 000000005:B 000000005 9 0 1980 99.95 0-2 000000005:B 000000016:B 000000016 502 0 1487 99.93 ================================================ FILE: test_data/gfa-1/ctg_paths ================================================ 0 ctg_linear 000000007:B~000000018:B~000000004:B 000000007:B 5000 94450 000000007:B~000000018:B~000000004:B ================================================ FILE: test_data/gfa-1/expected-1-sg-r-c.gfa ================================================ H VN:Z:1.0 S 000000004 CAGACGCCGCGTCCTGGTTATTATCGAAAGGTCGGAGTGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGA LN:i:1989 S 000000005 TTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCCGTCCAGGGGCATCTAGCTAGAATACTGAGCTCCTTTCGATTCCCTTCGACTCCTCCTCGGGCTCTCGACAGGATCCATGCCGACGTCATTCTCTATAAAAAGCCTACAAGGACGACGTTTGGACCTCAGACTTCACGAACATGTGCCACCGCGATCCCACTGCTCATTGTCCAGGTACTAGACTGCGGGCTAGTAATGAGGCGGGTTCCTCAAAGTATAAGCGCCTAATGCTCCCAGTTTGAACATAGTCCTGCTGATTTCTTATTGCTTAGACACAGACACTTCACCTTGTGCGAGAGTTAAGGGCATGCTCCGGCTCAAGTCTTGAGCAAGTCATGTCAGTGCTAGTACTTTAACAAGATTAAATGAATCAGAGATAGCAAATCTGTGCATGAGTTACCAGGAACTCGAACCCGGCTAACTACACAGTGAGGAAAGTGAGAAGAGGGTCGAAAAGCTTGCTGGTCTCGATCATGGTTGTGACGATAGCACGTCCGAACCGCCGGCCGAATGAGCGCGTAGGTGAACGATATCATGGCCCGACGCCCCGTAGAGCTGGACTGGGGGCCAATGCCGAACAAGGGTATAACAAAAAAAAACCCCCTTGGAGTAACTGAAAGTCTCACCCGCGCAGCGGATACCCTTGGTGCACACTCACTTCCGCTGGGGGCTTACGTTTCGTGAACAGAGTAGGGTAGGCTCTGATGGGGCTGGACTCCTTCGACGTGTCTATTTGAGAGGTTCCGATCTTTTGATGCCCAGAAGCACCAAAAAAGCCAGAGCAATCCCCATCTTGCGGGTTGTATTGCGCTAGAGCCACCACACGCAAAACGAGCCTGGTTTCGTACTGTGGTGGAGGCTGACTGCCTAGCCTGTTGGTTACTCGGCCTCAACAAGCGATCCGGATGTTGATATTTCTCACCCGCCGCGGTCATTTCGAACCTGATTCTA LN:i:1989 S 000000007 ATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCCGTCCAGGGGCATCTAGCTAGAATACTGAGCTCCTTTCGATTCCCTTCGACTCCTCCTCGGGCTCTCGACAGGATCCATGCCGACGTCATTCTCTATAAAAAGCCTACAAGGACGACGTTTGGACCTCAGACTTCACGAACATGTGCCACCGCGATCCCACTGCTCATTGTCCAGGTACTAGACTGCGGGCTAGTAATGAGGCGGGTTCCTCAAAGTATAAGCGCCTAATGCTCCCAGTTTGAACATAGTCCTGCTGATTTCTTATTGCTTAGACACAGACACTTCACCTTGTGCGAGAGTTAAGGGCATGCTCCGGCTCAAGTCTTGAGCAAGTCATGTCAGTGCTAGTACTTTAACAAGATTAAATGAATCAGAGATAGCAAATCTGTGCATGAGTTACCAGGAACTCGAACCCGGCTAACTACACAGTGAGGAAAGTGAGAAGAGGGTCGAAAAGCTTGCTGGTCTCGATCATGGTTGTGACGATAGCACGTCCGAACCGCCGGCCGAATGAGCGCGTAGGTGAACGATATCATGGCCCGACGCCCCGTAGAGCTGGACTGGGGGCCAATGCCGAACAAGGGTATAACAAAAAAAAACCCCCTTGGAGTAACTGAAAGTCTCACCCGCGCAGCGGATACCCTTGGTGCACACTCACTTCCGCTGGGGGCTTACGTTTCGTGAACAGAGTAGGGTAGGCTCTGATGGGGCTGGACTCCTTCGACGTGTCTATTTGAGAGGTTCCGATCTTTTGATGCCCAGAAGCACCAAAAAAGCCAGAGCAATCCCCATCTTGCGGGTTGTATTGCGCTAGAGCCACCACACGCAAAACGAGCCTGGTTTCGTACTGTGGTGGAGGCTGACTGCCTAGCCTGTTGGTTACTCGGCCTCAACAAGCGATCCGGATGTTGATATTTCTCACCCGCCGCGGTCATTTCGAACCTGATTCTTCTCTCTCCA LN:i:1989 S 000000016 TTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCCGTCCAGGGGCATCTAGCTAGAATACTGAGCTCCTTTCGATTCCCTTCGACTCCTCCTCGGGCTCTCGACAGGATCCATGCCGACGTCATTCTCTATAAAAAGCCTACAAGGACGACGTTTGGACCTCAGACTTCACGAACATGTGCCACCGCGATCCCACTGCTCATTGTCCAGGTACTAGACTGCGGGCTAGTAATGAGGCGGGTTCCTCAAAGTATAAGCGCCTAATGCTCCCAGTTTGAACATAGTCCTGCTGATTTCTTATTGCTTAGACACAGACACTTCACCTTGTGCGAGAGTTAAGGGCATGCTCCGGCTCAAGTCTTGAGCAAGTCATGTCAGTGCTAGTACTTTAACAAGATTAAATGAATCAGAGATAGCAAATCTGTGCATGAGTTACCAGGAACTCGAACCCGGCTAACTACACAGTGAGGAAAGTGAGAAGAGGA LN:i:1989 S 000000018 AAAGGTCGGAGTGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTA LN:i:1989 S 000000025 TGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCA LN:i:1989 S 000000027 TGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCA LN:i:1989 S 0 CTTTTGTAAGTCAACTAAGATCGCCAGTCGATTGTGCCTAAGTCCCGCTACATCATGTCGTCCCTGGTCGTCATTTCCTTGTTGCGAGTGTGGGCCGCGCATGTGGGATGGCGATTTCATATAACTCGCGAGCAATTGAGGTAGAATCTGCTAGGATATAGTTGGGGCAACACGTGTCCGAGCCTTGCAAGTCGACTGGTGAATTTAGTACGAGCGTCTAGACTCTTGCCTAGTAGAGCTTAGCAATGAATGTTCAAATCCTGGATGCTAGGGTGGCACTTGGACGATCAGGAATTCAAACTGGGCGTCATGATTTAATTTTACGACCTCCGAAACCTTATTAGGGGTCTAAGATACCCGTGTGTCCTTGCTACAGTGTCGCATTTTGGAGATATTTGCGTTTCGTCTGGGGCCTATGCTAGCCACAACAGAAAATGAAAGGACGACGACGAGCCGGGGTTTCGTGGGCCTTTATGGGGCGTTTCCAGACCGGAAAACGACTTCAGCGCAAAAAGCTCGTGATGACTAAAGGTCATTGGAGGTAGTCGCGGCTAAATTATGTAGTGACCTCTGCCGGCGCGCGCGAATGGCTAATCAGGGTGTTAATTATCTTATCTGTTCAACGACGTGTGAAAAACGTGAAGCGTTTAGACGCTGATATGCATGGCTCCGGAAGTTCGATCGAATTAGGATTCAGCTCCCTCACTCATCAGCAGAATACATAGTAAATAAAGCGATGGTTGAGTATCCTGCTCTGCTCGATCGATAAAGTACGGGGCTACGCACCATCCGAGCTGATGTGACAATAGACTGCTGATAAGCGGCATTAGATGGTATTGAGACATCGTTATACGAAATATAGGGCTATGTTTAAGAGAGCCAATCGCTAATCTGCGCCATGTGAGCCCTGTTCAAGTAAAATTATGTCTGAGACAACGTGAGAGATTGACTGAATTGTCACTCCGACCTTTCGATAATAACCAGGACGCGGCGTCTG LN:i:997 S 0-1 CTTTTGTAAGTCAACTAAGATCGCCAGTCGATTGTGCCTAAGTCCCGCTACATCATGTCGTCCCTGGTCGTCATTTCCTTGTTGCGAGTGTGGGCCGCGCATGTGGGATGGCGATTTCATATAACTCGCGAGCAATTGAGGTAGAATCTGCTAGGATATAGTTGGGGCAACACGTGTCCGAGCCTTGCAAGTCGACTGGTGAATTTAGTACGAGCGTCTAGACTCTTGCCTAGTAGAGCTTAGCAATGAATGTTCAAATCCTGGATGCTAGGGTGGCACTTGGACGATCAGGAATTCAAACTGGGCGTCATGATTTAATTTTACGACCTCCGAAACCTTATTAGGGGTCTAAGATACCCGTGTGTCCTTGCTACAGTGTCGCATTTTGGAGATATTTGCGTTTCGTCTGGGGCCTATGCTAGCCACAACAGAAAATGAAAGGACGACGACGAGCCGGGGTTTCGTGGGCCTTTATGGGGCGTTTCCAGACCGGAAAACGACTTCAGCGCAA LN:i:511 L 000000016 - 000000027 - * ol:i:1540 oi:f:99.9 ob:i:449 oe:i:0 ci:Z:NA-NA L 000000005 - 000000016 - * ol:i:1487 oi:f:99.9 ob:i:502 oe:i:0 ci:Z:0-P L 000000016 - 000000025 - * ol:i:1540 oi:f:99.9 ob:i:449 oe:i:0 ci:Z:0-P L 000000007 - 000000005 - * ol:i:1980 oi:f:100.0 ob:i:9 oe:i:0 ci:Z:0-P L 000000018 - 000000004 - * ol:i:1963 oi:f:100.0 ob:i:26 oe:i:0 ci:Z:0-P L 000000025 - 000000018 - * ol:i:1978 oi:f:100.0 ob:i:11 oe:i:0 ci:Z:0-P P 0 000000007-,000000005-,000000016-,000000025-,000000018-,000000004- 1989M,9M,502M,449M,11M,26M P 0-1 000000007-,000000005-,000000016- 1989M,9M,502M ================================================ FILE: test_data/gfa-1/expected-2-tiling-r-c.gfa ================================================ H VN:Z:1.0 S 000000004 CAGACGCCGCGTCCTGGTTATTATCGAAAGGTCGGAGTGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGA LN:i:1989 S 000000005 TTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCCGTCCAGGGGCATCTAGCTAGAATACTGAGCTCCTTTCGATTCCCTTCGACTCCTCCTCGGGCTCTCGACAGGATCCATGCCGACGTCATTCTCTATAAAAAGCCTACAAGGACGACGTTTGGACCTCAGACTTCACGAACATGTGCCACCGCGATCCCACTGCTCATTGTCCAGGTACTAGACTGCGGGCTAGTAATGAGGCGGGTTCCTCAAAGTATAAGCGCCTAATGCTCCCAGTTTGAACATAGTCCTGCTGATTTCTTATTGCTTAGACACAGACACTTCACCTTGTGCGAGAGTTAAGGGCATGCTCCGGCTCAAGTCTTGAGCAAGTCATGTCAGTGCTAGTACTTTAACAAGATTAAATGAATCAGAGATAGCAAATCTGTGCATGAGTTACCAGGAACTCGAACCCGGCTAACTACACAGTGAGGAAAGTGAGAAGAGGGTCGAAAAGCTTGCTGGTCTCGATCATGGTTGTGACGATAGCACGTCCGAACCGCCGGCCGAATGAGCGCGTAGGTGAACGATATCATGGCCCGACGCCCCGTAGAGCTGGACTGGGGGCCAATGCCGAACAAGGGTATAACAAAAAAAAACCCCCTTGGAGTAACTGAAAGTCTCACCCGCGCAGCGGATACCCTTGGTGCACACTCACTTCCGCTGGGGGCTTACGTTTCGTGAACAGAGTAGGGTAGGCTCTGATGGGGCTGGACTCCTTCGACGTGTCTATTTGAGAGGTTCCGATCTTTTGATGCCCAGAAGCACCAAAAAAGCCAGAGCAATCCCCATCTTGCGGGTTGTATTGCGCTAGAGCCACCACACGCAAAACGAGCCTGGTTTCGTACTGTGGTGGAGGCTGACTGCCTAGCCTGTTGGTTACTCGGCCTCAACAAGCGATCCGGATGTTGATATTTCTCACCCGCCGCGGTCATTTCGAACCTGATTCTA LN:i:1989 S 000000007 ATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCCGTCCAGGGGCATCTAGCTAGAATACTGAGCTCCTTTCGATTCCCTTCGACTCCTCCTCGGGCTCTCGACAGGATCCATGCCGACGTCATTCTCTATAAAAAGCCTACAAGGACGACGTTTGGACCTCAGACTTCACGAACATGTGCCACCGCGATCCCACTGCTCATTGTCCAGGTACTAGACTGCGGGCTAGTAATGAGGCGGGTTCCTCAAAGTATAAGCGCCTAATGCTCCCAGTTTGAACATAGTCCTGCTGATTTCTTATTGCTTAGACACAGACACTTCACCTTGTGCGAGAGTTAAGGGCATGCTCCGGCTCAAGTCTTGAGCAAGTCATGTCAGTGCTAGTACTTTAACAAGATTAAATGAATCAGAGATAGCAAATCTGTGCATGAGTTACCAGGAACTCGAACCCGGCTAACTACACAGTGAGGAAAGTGAGAAGAGGGTCGAAAAGCTTGCTGGTCTCGATCATGGTTGTGACGATAGCACGTCCGAACCGCCGGCCGAATGAGCGCGTAGGTGAACGATATCATGGCCCGACGCCCCGTAGAGCTGGACTGGGGGCCAATGCCGAACAAGGGTATAACAAAAAAAAACCCCCTTGGAGTAACTGAAAGTCTCACCCGCGCAGCGGATACCCTTGGTGCACACTCACTTCCGCTGGGGGCTTACGTTTCGTGAACAGAGTAGGGTAGGCTCTGATGGGGCTGGACTCCTTCGACGTGTCTATTTGAGAGGTTCCGATCTTTTGATGCCCAGAAGCACCAAAAAAGCCAGAGCAATCCCCATCTTGCGGGTTGTATTGCGCTAGAGCCACCACACGCAAAACGAGCCTGGTTTCGTACTGTGGTGGAGGCTGACTGCCTAGCCTGTTGGTTACTCGGCCTCAACAAGCGATCCGGATGTTGATATTTCTCACCCGCCGCGGTCATTTCGAACCTGATTCTTCTCTCTCCA LN:i:1989 S 000000016 TTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCCGTCCAGGGGCATCTAGCTAGAATACTGAGCTCCTTTCGATTCCCTTCGACTCCTCCTCGGGCTCTCGACAGGATCCATGCCGACGTCATTCTCTATAAAAAGCCTACAAGGACGACGTTTGGACCTCAGACTTCACGAACATGTGCCACCGCGATCCCACTGCTCATTGTCCAGGTACTAGACTGCGGGCTAGTAATGAGGCGGGTTCCTCAAAGTATAAGCGCCTAATGCTCCCAGTTTGAACATAGTCCTGCTGATTTCTTATTGCTTAGACACAGACACTTCACCTTGTGCGAGAGTTAAGGGCATGCTCCGGCTCAAGTCTTGAGCAAGTCATGTCAGTGCTAGTACTTTAACAAGATTAAATGAATCAGAGATAGCAAATCTGTGCATGAGTTACCAGGAACTCGAACCCGGCTAACTACACAGTGAGGAAAGTGAGAAGAGGA LN:i:1989 S 000000018 AAAGGTCGGAGTGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTA LN:i:1989 S 000000025 TGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCA LN:i:1989 S 0 CTTTTGTAAGTCAACTAAGATCGCCAGTCGATTGTGCCTAAGTCCCGCTACATCATGTCGTCCCTGGTCGTCATTTCCTTGTTGCGAGTGTGGGCCGCGCATGTGGGATGGCGATTTCATATAACTCGCGAGCAATTGAGGTAGAATCTGCTAGGATATAGTTGGGGCAACACGTGTCCGAGCCTTGCAAGTCGACTGGTGAATTTAGTACGAGCGTCTAGACTCTTGCCTAGTAGAGCTTAGCAATGAATGTTCAAATCCTGGATGCTAGGGTGGCACTTGGACGATCAGGAATTCAAACTGGGCGTCATGATTTAATTTTACGACCTCCGAAACCTTATTAGGGGTCTAAGATACCCGTGTGTCCTTGCTACAGTGTCGCATTTTGGAGATATTTGCGTTTCGTCTGGGGCCTATGCTAGCCACAACAGAAAATGAAAGGACGACGACGAGCCGGGGTTTCGTGGGCCTTTATGGGGCGTTTCCAGACCGGAAAACGACTTCAGCGCAAAAAGCTCGTGATGACTAAAGGTCATTGGAGGTAGTCGCGGCTAAATTATGTAGTGACCTCTGCCGGCGCGCGCGAATGGCTAATCAGGGTGTTAATTATCTTATCTGTTCAACGACGTGTGAAAAACGTGAAGCGTTTAGACGCTGATATGCATGGCTCCGGAAGTTCGATCGAATTAGGATTCAGCTCCCTCACTCATCAGCAGAATACATAGTAAATAAAGCGATGGTTGAGTATCCTGCTCTGCTCGATCGATAAAGTACGGGGCTACGCACCATCCGAGCTGATGTGACAATAGACTGCTGATAAGCGGCATTAGATGGTATTGAGACATCGTTATACGAAATATAGGGCTATGTTTAAGAGAGCCAATCGCTAATCTGCGCCATGTGAGCCCTGTTCAAGTAAAATTATGTCTGAGACAACGTGAGAGATTGACTGAATTGTCACTCCGACCTTTCGATAATAACCAGGACGCGGCGTCTG LN:i:997 S 0-1 CTTTTGTAAGTCAACTAAGATCGCCAGTCGATTGTGCCTAAGTCCCGCTACATCATGTCGTCCCTGGTCGTCATTTCCTTGTTGCGAGTGTGGGCCGCGCATGTGGGATGGCGATTTCATATAACTCGCGAGCAATTGAGGTAGAATCTGCTAGGATATAGTTGGGGCAACACGTGTCCGAGCCTTGCAAGTCGACTGGTGAATTTAGTACGAGCGTCTAGACTCTTGCCTAGTAGAGCTTAGCAATGAATGTTCAAATCCTGGATGCTAGGGTGGCACTTGGACGATCAGGAATTCAAACTGGGCGTCATGATTTAATTTTACGACCTCCGAAACCTTATTAGGGGTCTAAGATACCCGTGTGTCCTTGCTACAGTGTCGCATTTTGGAGATATTTGCGTTTCGTCTGGGGCCTATGCTAGCCACAACAGAAAATGAAAGGACGACGACGAGCCGGGGTTTCGTGGGCCTTTATGGGGCGTTTCCAGACCGGAAAACGACTTCAGCGCAA LN:i:511 L 000000018 - 000000004 - * ol:i:1963 oi:f:100.0 ob:i:26 oe:i:0 ci:Z:0-P L 000000025 - 000000018 - * ol:i:1978 oi:f:100.0 ob:i:11 oe:i:0 ci:Z:0-P L 000000007 - 000000005 - * ol:i:1980 oi:f:100.0 ob:i:9 oe:i:0 ci:Z:0-P L 000000016 - 000000025 - * ol:i:1540 oi:f:99.9 ob:i:449 oe:i:0 ci:Z:0-P L 000000005 - 000000016 - * ol:i:1487 oi:f:99.9 ob:i:502 oe:i:0 ci:Z:0-P P 0 000000007-,000000005-,000000016-,000000025-,000000018-,000000004- 1989M,9M,502M,449M,11M,26M P 0-1 000000007-,000000005-,000000016- 1989M,9M,502M ================================================ FILE: test_data/gfa-1/expected-3-tiling-no_r-c.gfa ================================================ H VN:Z:1.0 S 000000004 * LN:i:1989 S 000000005 * LN:i:1989 S 000000007 * LN:i:1989 S 000000016 * LN:i:1989 S 000000018 * LN:i:1989 S 000000025 * LN:i:1989 S 0 CTTTTGTAAGTCAACTAAGATCGCCAGTCGATTGTGCCTAAGTCCCGCTACATCATGTCGTCCCTGGTCGTCATTTCCTTGTTGCGAGTGTGGGCCGCGCATGTGGGATGGCGATTTCATATAACTCGCGAGCAATTGAGGTAGAATCTGCTAGGATATAGTTGGGGCAACACGTGTCCGAGCCTTGCAAGTCGACTGGTGAATTTAGTACGAGCGTCTAGACTCTTGCCTAGTAGAGCTTAGCAATGAATGTTCAAATCCTGGATGCTAGGGTGGCACTTGGACGATCAGGAATTCAAACTGGGCGTCATGATTTAATTTTACGACCTCCGAAACCTTATTAGGGGTCTAAGATACCCGTGTGTCCTTGCTACAGTGTCGCATTTTGGAGATATTTGCGTTTCGTCTGGGGCCTATGCTAGCCACAACAGAAAATGAAAGGACGACGACGAGCCGGGGTTTCGTGGGCCTTTATGGGGCGTTTCCAGACCGGAAAACGACTTCAGCGCAAAAAGCTCGTGATGACTAAAGGTCATTGGAGGTAGTCGCGGCTAAATTATGTAGTGACCTCTGCCGGCGCGCGCGAATGGCTAATCAGGGTGTTAATTATCTTATCTGTTCAACGACGTGTGAAAAACGTGAAGCGTTTAGACGCTGATATGCATGGCTCCGGAAGTTCGATCGAATTAGGATTCAGCTCCCTCACTCATCAGCAGAATACATAGTAAATAAAGCGATGGTTGAGTATCCTGCTCTGCTCGATCGATAAAGTACGGGGCTACGCACCATCCGAGCTGATGTGACAATAGACTGCTGATAAGCGGCATTAGATGGTATTGAGACATCGTTATACGAAATATAGGGCTATGTTTAAGAGAGCCAATCGCTAATCTGCGCCATGTGAGCCCTGTTCAAGTAAAATTATGTCTGAGACAACGTGAGAGATTGACTGAATTGTCACTCCGACCTTTCGATAATAACCAGGACGCGGCGTCTG LN:i:997 S 0-1 CTTTTGTAAGTCAACTAAGATCGCCAGTCGATTGTGCCTAAGTCCCGCTACATCATGTCGTCCCTGGTCGTCATTTCCTTGTTGCGAGTGTGGGCCGCGCATGTGGGATGGCGATTTCATATAACTCGCGAGCAATTGAGGTAGAATCTGCTAGGATATAGTTGGGGCAACACGTGTCCGAGCCTTGCAAGTCGACTGGTGAATTTAGTACGAGCGTCTAGACTCTTGCCTAGTAGAGCTTAGCAATGAATGTTCAAATCCTGGATGCTAGGGTGGCACTTGGACGATCAGGAATTCAAACTGGGCGTCATGATTTAATTTTACGACCTCCGAAACCTTATTAGGGGTCTAAGATACCCGTGTGTCCTTGCTACAGTGTCGCATTTTGGAGATATTTGCGTTTCGTCTGGGGCCTATGCTAGCCACAACAGAAAATGAAAGGACGACGACGAGCCGGGGTTTCGTGGGCCTTTATGGGGCGTTTCCAGACCGGAAAACGACTTCAGCGCAA LN:i:511 L 000000018 - 000000004 - * ol:i:1963 oi:f:100.0 ob:i:26 oe:i:0 ci:Z:0-P L 000000025 - 000000018 - * ol:i:1978 oi:f:100.0 ob:i:11 oe:i:0 ci:Z:0-P L 000000007 - 000000005 - * ol:i:1980 oi:f:100.0 ob:i:9 oe:i:0 ci:Z:0-P L 000000016 - 000000025 - * ol:i:1540 oi:f:99.9 ob:i:449 oe:i:0 ci:Z:0-P L 000000005 - 000000016 - * ol:i:1487 oi:f:99.9 ob:i:502 oe:i:0 ci:Z:0-P P 0 000000007-,000000005-,000000016-,000000025-,000000018-,000000004- 1989M,9M,502M,449M,11M,26M P 0-1 000000007-,000000005-,000000016- 1989M,9M,502M ================================================ FILE: test_data/gfa-1/expected-4-tiling-no_r-no_c.gfa ================================================ H VN:Z:1.0 S 000000004 * LN:i:1989 S 000000005 * LN:i:1989 S 000000007 * LN:i:1989 S 000000016 * LN:i:1989 S 000000018 * LN:i:1989 S 000000025 * LN:i:1989 L 000000018 - 000000004 - * ol:i:1963 oi:f:100.0 ob:i:26 oe:i:0 ci:Z:0-P L 000000025 - 000000018 - * ol:i:1978 oi:f:100.0 ob:i:11 oe:i:0 ci:Z:0-P L 000000007 - 000000005 - * ol:i:1980 oi:f:100.0 ob:i:9 oe:i:0 ci:Z:0-P L 000000016 - 000000025 - * ol:i:1540 oi:f:99.9 ob:i:449 oe:i:0 ci:Z:0-P L 000000005 - 000000016 - * ol:i:1487 oi:f:99.9 ob:i:502 oe:i:0 ci:Z:0-P P 0 000000007-,000000005-,000000016-,000000025-,000000018-,000000004- 1989M,9M,502M,449M,11M,26M P 0-1 000000007-,000000005-,000000016- 1989M,9M,502M ================================================ FILE: test_data/gfa-1/expected-5-sg-no_r-no_c.gfa ================================================ H VN:Z:1.0 S 000000004 * LN:i:1989 S 000000005 * LN:i:1989 S 000000007 * LN:i:1989 S 000000016 * LN:i:1989 S 000000018 * LN:i:1989 S 000000025 * LN:i:1989 S 000000027 * LN:i:1989 L 000000016 - 000000027 - * ol:i:1540 oi:f:99.9 ob:i:449 oe:i:0 ci:Z:NA-NA L 000000005 - 000000016 - * ol:i:1487 oi:f:99.9 ob:i:502 oe:i:0 ci:Z:0-P L 000000016 - 000000025 - * ol:i:1540 oi:f:99.9 ob:i:449 oe:i:0 ci:Z:0-P L 000000007 - 000000005 - * ol:i:1980 oi:f:100.0 ob:i:9 oe:i:0 ci:Z:0-P L 000000018 - 000000004 - * ol:i:1963 oi:f:100.0 ob:i:26 oe:i:0 ci:Z:0-P L 000000025 - 000000018 - * ol:i:1978 oi:f:100.0 ob:i:11 oe:i:0 ci:Z:0-P P 0 000000007-,000000005-,000000016-,000000025-,000000018-,000000004- 1989M,9M,502M,449M,11M,26M P 0-1 000000007-,000000005-,000000016- 1989M,9M,502M ================================================ FILE: test_data/gfa-1/expected-6-tiling-no_r-no_c-minlen.gfa ================================================ H VN:Z:1.0 ================================================ FILE: test_data/gfa-1/expected-7-nx-no_r-no_c.gfa ================================================ H VN:Z:1.0 S 000000004 * LN:i:1989 S 000000005 * LN:i:1989 S 000000007 * LN:i:1989 S 000000016 * LN:i:1989 S 000000018 * LN:i:1989 S 000000025 * LN:i:1989 L 000000005 - 000000016 - * sg:Z:OP cp:Z:N ci:Z:NA-NA L 000000018 - 000000004 - * sg:Z:OP cp:Z:N ci:Z:NA-NA L 000000025 - 000000018 - * sg:Z:OP cp:Z:N ci:Z:NA-NA L 000000016 - 000000025 - * sg:Z:OP cp:Z:N ci:Z:NA-NA L 000000005 + 000000007 + * sg:Z:OP cp:Z:N ci:Z:NA-NA ================================================ FILE: test_data/gfa-1/expected-8-nx-tiling-no_r-no_c.gfa ================================================ H VN:Z:1.0 S 000000004 * LN:i:1989 S 000000005 * LN:i:1989 S 000000007 * LN:i:1989 S 000000016 * LN:i:1989 S 000000018 * LN:i:1989 S 000000025 * LN:i:1989 L 000000018 - 000000004 - * ol:i:1963 oi:f:100.0 ob:i:26 oe:i:0 sg:Z:OP cp:Z:N ci:Z:0-P L 000000025 - 000000018 - * ol:i:1978 oi:f:100.0 ob:i:11 oe:i:0 sg:Z:OP cp:Z:N ci:Z:0-P L 000000007 - 000000005 - * ol:i:1980 oi:f:100.0 ob:i:9 oe:i:0 sg:Z:OP cp:Z:N ci:Z:0-P L 000000016 - 000000025 - * ol:i:1540 oi:f:99.9 ob:i:449 oe:i:0 sg:Z:OP cp:Z:N ci:Z:0-P L 000000005 - 000000016 - * ol:i:1487 oi:f:99.9 ob:i:502 oe:i:0 sg:Z:OP cp:Z:N ci:Z:0-P P 0 000000007-,000000005-,000000016-,000000025-,000000018-,000000004- 1989M,9M,502M,449M,11M,26M P 0-1 000000007-,000000005-,000000016- 1989M,9M,502M ================================================ FILE: test_data/gfa-1/expected-9-nx-tiling-r-c.gfa ================================================ H VN:Z:1.0 S 000000004 CAGACGCCGCGTCCTGGTTATTATCGAAAGGTCGGAGTGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGA LN:i:1989 S 000000005 TTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCCGTCCAGGGGCATCTAGCTAGAATACTGAGCTCCTTTCGATTCCCTTCGACTCCTCCTCGGGCTCTCGACAGGATCCATGCCGACGTCATTCTCTATAAAAAGCCTACAAGGACGACGTTTGGACCTCAGACTTCACGAACATGTGCCACCGCGATCCCACTGCTCATTGTCCAGGTACTAGACTGCGGGCTAGTAATGAGGCGGGTTCCTCAAAGTATAAGCGCCTAATGCTCCCAGTTTGAACATAGTCCTGCTGATTTCTTATTGCTTAGACACAGACACTTCACCTTGTGCGAGAGTTAAGGGCATGCTCCGGCTCAAGTCTTGAGCAAGTCATGTCAGTGCTAGTACTTTAACAAGATTAAATGAATCAGAGATAGCAAATCTGTGCATGAGTTACCAGGAACTCGAACCCGGCTAACTACACAGTGAGGAAAGTGAGAAGAGGGTCGAAAAGCTTGCTGGTCTCGATCATGGTTGTGACGATAGCACGTCCGAACCGCCGGCCGAATGAGCGCGTAGGTGAACGATATCATGGCCCGACGCCCCGTAGAGCTGGACTGGGGGCCAATGCCGAACAAGGGTATAACAAAAAAAAACCCCCTTGGAGTAACTGAAAGTCTCACCCGCGCAGCGGATACCCTTGGTGCACACTCACTTCCGCTGGGGGCTTACGTTTCGTGAACAGAGTAGGGTAGGCTCTGATGGGGCTGGACTCCTTCGACGTGTCTATTTGAGAGGTTCCGATCTTTTGATGCCCAGAAGCACCAAAAAAGCCAGAGCAATCCCCATCTTGCGGGTTGTATTGCGCTAGAGCCACCACACGCAAAACGAGCCTGGTTTCGTACTGTGGTGGAGGCTGACTGCCTAGCCTGTTGGTTACTCGGCCTCAACAAGCGATCCGGATGTTGATATTTCTCACCCGCCGCGGTCATTTCGAACCTGATTCTA LN:i:1989 S 000000007 ATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCCGTCCAGGGGCATCTAGCTAGAATACTGAGCTCCTTTCGATTCCCTTCGACTCCTCCTCGGGCTCTCGACAGGATCCATGCCGACGTCATTCTCTATAAAAAGCCTACAAGGACGACGTTTGGACCTCAGACTTCACGAACATGTGCCACCGCGATCCCACTGCTCATTGTCCAGGTACTAGACTGCGGGCTAGTAATGAGGCGGGTTCCTCAAAGTATAAGCGCCTAATGCTCCCAGTTTGAACATAGTCCTGCTGATTTCTTATTGCTTAGACACAGACACTTCACCTTGTGCGAGAGTTAAGGGCATGCTCCGGCTCAAGTCTTGAGCAAGTCATGTCAGTGCTAGTACTTTAACAAGATTAAATGAATCAGAGATAGCAAATCTGTGCATGAGTTACCAGGAACTCGAACCCGGCTAACTACACAGTGAGGAAAGTGAGAAGAGGGTCGAAAAGCTTGCTGGTCTCGATCATGGTTGTGACGATAGCACGTCCGAACCGCCGGCCGAATGAGCGCGTAGGTGAACGATATCATGGCCCGACGCCCCGTAGAGCTGGACTGGGGGCCAATGCCGAACAAGGGTATAACAAAAAAAAACCCCCTTGGAGTAACTGAAAGTCTCACCCGCGCAGCGGATACCCTTGGTGCACACTCACTTCCGCTGGGGGCTTACGTTTCGTGAACAGAGTAGGGTAGGCTCTGATGGGGCTGGACTCCTTCGACGTGTCTATTTGAGAGGTTCCGATCTTTTGATGCCCAGAAGCACCAAAAAAGCCAGAGCAATCCCCATCTTGCGGGTTGTATTGCGCTAGAGCCACCACACGCAAAACGAGCCTGGTTTCGTACTGTGGTGGAGGCTGACTGCCTAGCCTGTTGGTTACTCGGCCTCAACAAGCGATCCGGATGTTGATATTTCTCACCCGCCGCGGTCATTTCGAACCTGATTCTTCTCTCTCCA LN:i:1989 S 000000016 TTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCCGTCCAGGGGCATCTAGCTAGAATACTGAGCTCCTTTCGATTCCCTTCGACTCCTCCTCGGGCTCTCGACAGGATCCATGCCGACGTCATTCTCTATAAAAAGCCTACAAGGACGACGTTTGGACCTCAGACTTCACGAACATGTGCCACCGCGATCCCACTGCTCATTGTCCAGGTACTAGACTGCGGGCTAGTAATGAGGCGGGTTCCTCAAAGTATAAGCGCCTAATGCTCCCAGTTTGAACATAGTCCTGCTGATTTCTTATTGCTTAGACACAGACACTTCACCTTGTGCGAGAGTTAAGGGCATGCTCCGGCTCAAGTCTTGAGCAAGTCATGTCAGTGCTAGTACTTTAACAAGATTAAATGAATCAGAGATAGCAAATCTGTGCATGAGTTACCAGGAACTCGAACCCGGCTAACTACACAGTGAGGAAAGTGAGAAGAGGA LN:i:1989 S 000000018 AAAGGTCGGAGTGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTA LN:i:1989 S 000000025 TGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCA LN:i:1989 S 0 CTTTTGTAAGTCAACTAAGATCGCCAGTCGATTGTGCCTAAGTCCCGCTACATCATGTCGTCCCTGGTCGTCATTTCCTTGTTGCGAGTGTGGGCCGCGCATGTGGGATGGCGATTTCATATAACTCGCGAGCAATTGAGGTAGAATCTGCTAGGATATAGTTGGGGCAACACGTGTCCGAGCCTTGCAAGTCGACTGGTGAATTTAGTACGAGCGTCTAGACTCTTGCCTAGTAGAGCTTAGCAATGAATGTTCAAATCCTGGATGCTAGGGTGGCACTTGGACGATCAGGAATTCAAACTGGGCGTCATGATTTAATTTTACGACCTCCGAAACCTTATTAGGGGTCTAAGATACCCGTGTGTCCTTGCTACAGTGTCGCATTTTGGAGATATTTGCGTTTCGTCTGGGGCCTATGCTAGCCACAACAGAAAATGAAAGGACGACGACGAGCCGGGGTTTCGTGGGCCTTTATGGGGCGTTTCCAGACCGGAAAACGACTTCAGCGCAAAAAGCTCGTGATGACTAAAGGTCATTGGAGGTAGTCGCGGCTAAATTATGTAGTGACCTCTGCCGGCGCGCGCGAATGGCTAATCAGGGTGTTAATTATCTTATCTGTTCAACGACGTGTGAAAAACGTGAAGCGTTTAGACGCTGATATGCATGGCTCCGGAAGTTCGATCGAATTAGGATTCAGCTCCCTCACTCATCAGCAGAATACATAGTAAATAAAGCGATGGTTGAGTATCCTGCTCTGCTCGATCGATAAAGTACGGGGCTACGCACCATCCGAGCTGATGTGACAATAGACTGCTGATAAGCGGCATTAGATGGTATTGAGACATCGTTATACGAAATATAGGGCTATGTTTAAGAGAGCCAATCGCTAATCTGCGCCATGTGAGCCCTGTTCAAGTAAAATTATGTCTGAGACAACGTGAGAGATTGACTGAATTGTCACTCCGACCTTTCGATAATAACCAGGACGCGGCGTCTG LN:i:997 S 0-1 CTTTTGTAAGTCAACTAAGATCGCCAGTCGATTGTGCCTAAGTCCCGCTACATCATGTCGTCCCTGGTCGTCATTTCCTTGTTGCGAGTGTGGGCCGCGCATGTGGGATGGCGATTTCATATAACTCGCGAGCAATTGAGGTAGAATCTGCTAGGATATAGTTGGGGCAACACGTGTCCGAGCCTTGCAAGTCGACTGGTGAATTTAGTACGAGCGTCTAGACTCTTGCCTAGTAGAGCTTAGCAATGAATGTTCAAATCCTGGATGCTAGGGTGGCACTTGGACGATCAGGAATTCAAACTGGGCGTCATGATTTAATTTTACGACCTCCGAAACCTTATTAGGGGTCTAAGATACCCGTGTGTCCTTGCTACAGTGTCGCATTTTGGAGATATTTGCGTTTCGTCTGGGGCCTATGCTAGCCACAACAGAAAATGAAAGGACGACGACGAGCCGGGGTTTCGTGGGCCTTTATGGGGCGTTTCCAGACCGGAAAACGACTTCAGCGCAA LN:i:511 L 000000018 - 000000004 - * ol:i:1963 oi:f:100.0 ob:i:26 oe:i:0 sg:Z:OP cp:Z:N ci:Z:0-P L 000000025 - 000000018 - * ol:i:1978 oi:f:100.0 ob:i:11 oe:i:0 sg:Z:OP cp:Z:N ci:Z:0-P L 000000007 - 000000005 - * ol:i:1980 oi:f:100.0 ob:i:9 oe:i:0 sg:Z:OP cp:Z:N ci:Z:0-P L 000000016 - 000000025 - * ol:i:1540 oi:f:99.9 ob:i:449 oe:i:0 sg:Z:OP cp:Z:N ci:Z:0-P L 000000005 - 000000016 - * ol:i:1487 oi:f:99.9 ob:i:502 oe:i:0 sg:Z:OP cp:Z:N ci:Z:0-P P 0 000000007-,000000005-,000000016-,000000025-,000000018-,000000004- 1989M,9M,502M,449M,11M,26M P 0-1 000000007-,000000005-,000000016- 1989M,9M,502M ================================================ FILE: test_data/gfa-1/p_ctg.fa ================================================ >0 000000007:B~000000034:B~000000044:B~000000044:B ctg_linear 997 94450 CTTTTGTAAGTCAACTAAGATCGCCAGTCGATTGTGCCTAAGTCCCGCTACATCATGTCGTCCCTGGTCGTCATTTCCTTGTTGCGAGTGTGGGCCGCGCATGTGGGATGGCGATTTCATATAACTCGCGAGCAATTGAGGTAGAATCTGCTAGGATATAGTTGGGGCAACACGTGTCCGAGCCTTGCAAGTCGACTGGTGAATTTAGTACGAGCGTCTAGACTCTTGCCTAGTAGAGCTTAGCAATGAATGTTCAAATCCTGGATGCTAGGGTGGCACTTGGACGATCAGGAATTCAAACTGGGCGTCATGATTTAATTTTACGACCTCCGAAACCTTATTAGGGGTCTAAGATACCCGTGTGTCCTTGCTACAGTGTCGCATTTTGGAGATATTTGCGTTTCGTCTGGGGCCTATGCTAGCCACAACAGAAAATGAAAGGACGACGACGAGCCGGGGTTTCGTGGGCCTTTATGGGGCGTTTCCAGACCGGAAAACGACTTCAGCGCAAAAAGCTCGTGATGACTAAAGGTCATTGGAGGTAGTCGCGGCTAAATTATGTAGTGACCTCTGCCGGCGCGCGCGAATGGCTAATCAGGGTGTTAATTATCTTATCTGTTCAACGACGTGTGAAAAACGTGAAGCGTTTAGACGCTGATATGCATGGCTCCGGAAGTTCGATCGAATTAGGATTCAGCTCCCTCACTCATCAGCAGAATACATAGTAAATAAAGCGATGGTTGAGTATCCTGCTCTGCTCGATCGATAAAGTACGGGGCTACGCACCATCCGAGCTGATGTGACAATAGACTGCTGATAAGCGGCATTAGATGGTATTGAGACATCGTTATACGAAATATAGGGCTATGTTTAAGAGAGCCAATCGCTAATCTGCGCCATGTGAGCCCTGTTCAAGTAAAATTATGTCTGAGACAACGTGAGAGATTGACTGAATTGTCACTCCGACCTTTCGATAATAACCAGGACGCGGCGTCTG >1 CTTTTGTAAGTCAACTAAGATCGCCAGTCGATTGTGCCTAAGTCCCGCTACATCATGTCGTCCCTGGTCGTCATTTCCTTGTTGCGAGTGTGGGCCGCGC ================================================ FILE: test_data/gfa-1/p_ctg_tiling_path ================================================ 0 000000007:B 000000005:B 000000005 9 0 1980 99.95 0 000000005:B 000000016:B 000000016 502 0 1487 99.93 0 000000016:B 000000025:B 000000025 449 0 1540 99.94 0 000000025:B 000000018:B 000000018 11 0 1978 99.95 0 000000018:B 000000004:B 000000004 26 0 1963 99.95 ================================================ FILE: test_data/gfa-1/preads4falcon.fasta ================================================ >000000004 CAGACGCCGCGTCCTGGTTATTATCGAAAGGTCGGAGTGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGA >000000005 TTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCCGTCCAGGGGCATCTAGCTAGAATACTGAGCTCCTTTCGATTCCCTTCGACTCCTCCTCGGGCTCTCGACAGGATCCATGCCGACGTCATTCTCTATAAAAAGCCTACAAGGACGACGTTTGGACCTCAGACTTCACGAACATGTGCCACCGCGATCCCACTGCTCATTGTCCAGGTACTAGACTGCGGGCTAGTAATGAGGCGGGTTCCTCAAAGTATAAGCGCCTAATGCTCCCAGTTTGAACATAGTCCTGCTGATTTCTTATTGCTTAGACACAGACACTTCACCTTGTGCGAGAGTTAAGGGCATGCTCCGGCTCAAGTCTTGAGCAAGTCATGTCAGTGCTAGTACTTTAACAAGATTAAATGAATCAGAGATAGCAAATCTGTGCATGAGTTACCAGGAACTCGAACCCGGCTAACTACACAGTGAGGAAAGTGAGAAGAGGGTCGAAAAGCTTGCTGGTCTCGATCATGGTTGTGACGATAGCACGTCCGAACCGCCGGCCGAATGAGCGCGTAGGTGAACGATATCATGGCCCGACGCCCCGTAGAGCTGGACTGGGGGCCAATGCCGAACAAGGGTATAACAAAAAAAAACCCCCTTGGAGTAACTGAAAGTCTCACCCGCGCAGCGGATACCCTTGGTGCACACTCACTTCCGCTGGGGGCTTACGTTTCGTGAACAGAGTAGGGTAGGCTCTGATGGGGCTGGACTCCTTCGACGTGTCTATTTGAGAGGTTCCGATCTTTTGATGCCCAGAAGCACCAAAAAAGCCAGAGCAATCCCCATCTTGCGGGTTGTATTGCGCTAGAGCCACCACACGCAAAACGAGCCTGGTTTCGTACTGTGGTGGAGGCTGACTGCCTAGCCTGTTGGTTACTCGGCCTCAACAAGCGATCCGGATGTTGATATTTCTCACCCGCCGCGGTCATTTCGAACCTGATTCTA >000000007 ATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCCGTCCAGGGGCATCTAGCTAGAATACTGAGCTCCTTTCGATTCCCTTCGACTCCTCCTCGGGCTCTCGACAGGATCCATGCCGACGTCATTCTCTATAAAAAGCCTACAAGGACGACGTTTGGACCTCAGACTTCACGAACATGTGCCACCGCGATCCCACTGCTCATTGTCCAGGTACTAGACTGCGGGCTAGTAATGAGGCGGGTTCCTCAAAGTATAAGCGCCTAATGCTCCCAGTTTGAACATAGTCCTGCTGATTTCTTATTGCTTAGACACAGACACTTCACCTTGTGCGAGAGTTAAGGGCATGCTCCGGCTCAAGTCTTGAGCAAGTCATGTCAGTGCTAGTACTTTAACAAGATTAAATGAATCAGAGATAGCAAATCTGTGCATGAGTTACCAGGAACTCGAACCCGGCTAACTACACAGTGAGGAAAGTGAGAAGAGGGTCGAAAAGCTTGCTGGTCTCGATCATGGTTGTGACGATAGCACGTCCGAACCGCCGGCCGAATGAGCGCGTAGGTGAACGATATCATGGCCCGACGCCCCGTAGAGCTGGACTGGGGGCCAATGCCGAACAAGGGTATAACAAAAAAAAACCCCCTTGGAGTAACTGAAAGTCTCACCCGCGCAGCGGATACCCTTGGTGCACACTCACTTCCGCTGGGGGCTTACGTTTCGTGAACAGAGTAGGGTAGGCTCTGATGGGGCTGGACTCCTTCGACGTGTCTATTTGAGAGGTTCCGATCTTTTGATGCCCAGAAGCACCAAAAAAGCCAGAGCAATCCCCATCTTGCGGGTTGTATTGCGCTAGAGCCACCACACGCAAAACGAGCCTGGTTTCGTACTGTGGTGGAGGCTGACTGCCTAGCCTGTTGGTTACTCGGCCTCAACAAGCGATCCGGATGTTGATATTTCTCACCCGCCGCGGTCATTTCGAACCTGATTCTTCTCTCTCCA >000000016 TTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCCGTCCAGGGGCATCTAGCTAGAATACTGAGCTCCTTTCGATTCCCTTCGACTCCTCCTCGGGCTCTCGACAGGATCCATGCCGACGTCATTCTCTATAAAAAGCCTACAAGGACGACGTTTGGACCTCAGACTTCACGAACATGTGCCACCGCGATCCCACTGCTCATTGTCCAGGTACTAGACTGCGGGCTAGTAATGAGGCGGGTTCCTCAAAGTATAAGCGCCTAATGCTCCCAGTTTGAACATAGTCCTGCTGATTTCTTATTGCTTAGACACAGACACTTCACCTTGTGCGAGAGTTAAGGGCATGCTCCGGCTCAAGTCTTGAGCAAGTCATGTCAGTGCTAGTACTTTAACAAGATTAAATGAATCAGAGATAGCAAATCTGTGCATGAGTTACCAGGAACTCGAACCCGGCTAACTACACAGTGAGGAAAGTGAGAAGAGGA >000000018 AAAGGTCGGAGTGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTA >000000023 GGGAGTGAATGAACCGTGTTAGGCCGCGATTGGGTTTTGCAGAAGTGCCCAGGTCTTGTAATAGAATCGGTTTCTGAAACCTTTTCGACAGAGCGACGTATACGTCTTTTCGCTCAAACTACGTTCTGCTGAGAAAATTGGCGTTATTAATTGACAGACGACGGGTAAGGCCAAGTATAATAACAGCCGAAGGAGGGTTACCTAAGATGGTGCCGCTATACAGCCCATGGCTTGCATGAATTATCAACAACGGCTCGGCTGTCAGCTGTTGACCTGACTCTTCATACTTCCGTTAGTTCTGCGCATGCTGTCAGTGCGCGCGTTGATGTTCATTCGCGTTTCTAAACGACGCTAACATTGGAGCTTGTGCGGGTCTGCCTAGCGTGGGCATTACCAGGCTCGTTGATGGAAGATCATCGATGCAATAATACGGACGCAAAGGAGTTGCATAGGTTACGTCCAATGAATGTGTGATTAAGATGGCAGACTACCGTCGACCCGATAGGGCGGCTGTATGTCTTACCTAACGCATTCACGAGTCTTGGATAGCCGCCCACCGGCGAGGTGCAAAAGAAAAAGTCCCAGGAGGGTTTGAATAAGAGGTAAGCATGCGCAAAACGGAGAGAAATAATGATACGCATCGGATAGTTAAATTACAACCAGTAGTGGCCGCCTTGTTCTCTAGCGTATTGCCGGCTCAGTCGGGCCTCAAGTCGGAGAAGACGGGCGGTCCGAAGGAGTACCAGAGTATTTTGTGATGAGACTTTAGTTCTTGTGTCGATAGCAGCAGTTAATTGACTGTGCTCCCCATGGAGGTGAGTCCGGGGCCGTGTCACACAATACCTCTTTGCAGACGCCGCGTCCTGGTTATTATCGAAAGGTCGGAGTGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGA >000000025 TGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCA >000000026 CAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCCGTCCAGGGGCATCTAGCTAGAATACTGAGCTCCTTTCGATTCCCTTCGACTCCTCCTCGGGCTCTCGACAGGATCCATGCCGACGTCATTCTCTATAAAAAGCCTACAAGGACGACGTTTGGACCTCAGACTTCACGAACATGTGCCACCGCGATCCCACTGCTCATTGTCCAGGTACTAGACTGCGGGCTAGTAATGAGGCGGGTTCCTCAAAGTATAAGCGCCTAATGCTCCCAGTTTGAACATAGTCCTGCTGATTTCTTATTGCTTAGACACAGACACTTCACCTTGTGCGAGAGTTAAGGGCATGCTCCGGCTCAAGTCTTGAGCAAGTCATGTCAGTGCTAGTACTTTAACAAGATTAAATGAATCAGAGATAGCAAATCTGTGCATGAGTTACCAGGAACTCGAACCCGGCTAACTACACAGTGAGGAAAGTGAGAAGAGGGTCGAAAAGCTTGCTGGTCTCGATCATGGTTGTGACGATAGCACGTCCGAACCGCCGGCCGAATGAGCGCGTAGGTGAACGATATCATGGCCCGACGCCCCGTAGAGCTGGACTGGGGGCCAATGCCGAACAAGGGTATAACAAAAAAAAACCCCCTTGGAGTAACTGAAAGTCTCACCCGCGCAGCGGATACCCTTGGTGCACACTCACTTCCGCTGGGGGCTTACGTTTCGTGAACAGAGTAGGGTAGGCTCTGATGGGGCTGGACTCCTTCGACGTGTCTATTTGAGAGGTTCCGATCTTTTGATGCCCAGAAGCACCAAAAAAGCCAGAGCAATCCCCATCTTGCGGGTTGTATTGCGCTAGAGCCACCACACGCAAAACGAGCCTGGTTTCGTACTGTGGTGGAGGCTGACTGCCTAGCCTGTTGGTTACTCGGCCTCAACAAGCGATCCGGATGTTGATATTTCTCACCCGCCGCGGTCATTTCGAACCTGATTCTTCTCTCTCCGATTGGACTTTACAGGCCACCCTCACCCTCACGTGAGATAAATATGCCTGAACAATTCGTAACAACAGTTATTGCTCACATATGACTACGTGTTACATCTGGAGTGCCCGTAGTGATTGGCGAATCGCAGCGTCAATTAATTCCCAGGCAAGATAATGTCACACAGGAGTGGTTACGAATATGCAGCAGAACTCCTTATCACTATCGAGCTCCCGGTGCCAGTAGCTAACGCGGGGTCACTCGAATTGCAAGGACCGAGATTTACTCCAGTAGCCCACGTCTCCCAGAGTTAGGTAGACATCTATCAATGCATATCCTCTTGTCGAGATAGCGGACTATGCGAGTGAGAGAAGCACATGCTGCCGCCCCACCACCCACGAGTCTAGACCTAGTCAAGTGCTTTACAATACATCGCCAGATCATGCACTTTGTGACTCAAAATCATATGAAGCAATCATGGTCGGCGGTGGCGAATATAGTAACTTGGGTATTAGTGTAGCCAGATAGTTTACACTTTGACTCTAGAACACCCAGGCGAATAGGTCGTGTCCCGTGCTTAATGAGGTACTTGAAGGAGACCTAAGGCCTTCCCCGGATGATGTCTCAGCTCTCGTCAAGACCCTCGAATATGCAATTCACTCCAAGGGCAAGATCACAGAGGCAACAAATTCACGAACCTGCGAGCTTAACTCAGAGCGTCGGCACTGCTCTCGTAGGGTACGGTACTTACGGTAGCCTAATAGTTATCCTCGGGTACGTGGGCTCGGTTTAGGATATTTTCCGTGGTCTCCGTGGCATGCAGTCCTTTTTACCACCGTCTCTCCGGGTTGACGCCCGGGCGGATTCTACTCTCAGTAGGCGAGCGCGAGTAAATCCCAGCGTGCTCCCTGTACTCATCGGAAACGTTTGTGTTACTGGGGCGACTAGCAGAGTTTGGCTTAGCCGGTGAAAACCTTGATGGATCTACGATCCTACTTAAGGATTCATAA >000000027 TGACAATTCAGTCAATCTCTCACGTTGTCTCAGACATAATTTTACTTGAACAGGGCTCACATGGCGCAGATTAGCGATTGGCTCTCTTAAACATAGCCCTATATTTCGTATAACGATGTCTCAATACCATCTAATGCCGCTTATCAGCAGTCTATTGTCACATCAGCTCGGATGGTGCGTAGCCCCGTACTTTATCGATCGAGCAGAGCAGGATACTCAACCATCGCTTTATTTACTATGTATTCTGCTGATGAGTGAGGGAGCTGAATCCTAATTCGATCGAACTTCCGGAGCCATGCATATCAGCGTCTAAACGCTTCACGTTTTTCACACGTCGTTGAACAGATAAGATAATTAACACCCTGATTAGCCATTCGCGCGCGCCGGCAGAGGTCACTACATAATTTAGCCGCGACTACCTCCAATGACCTTTAGTCATCACGAGCTTTTTGCGCTGAAGTCGTTTTCCGGTCTGGAAACGCCCCATAAAGGCCCACGAAACCCCGGCTCGTCGTCGTCCTTTCATTTTCTGTTGTGGCTAGCATAGGCCCCAGACGAAACGCAAATATCTCCAAAATGCGACACTGTAGCAAGGACACACGGGTATCTTAGACCCCTAATAAGGTTTCGGAGGTCGTAAAATTAAATCATGACGCCCAGTTTGAATTCCTGATCGTCCAAGTGCCACCCTAGCATCCAGGATTTGAACATTCATTGCTAAGCTCTACTAGGCAAGAGTCTAGACGCTCGTACTAAATTCACCAGTCGACTTGCAAGGCTCGGACACGTGTTGCCCCAACTATATCCTAGCAGATTCTACCTCAATTGCTCGCGAGTTATATGAAATCGCCATCCCACATGCGCGGCCCACACTCGCAACAAGGAAATGACGACCAGGGACGACATGATGTAGCGGGACTTAGGCACAATCGACTGGCGATCTTAGTTGACTTACAAAAGATCACGGGCCTACGCAATCGCCTAAGGAGCACCATGGCCCGGAGGCCTGCACAATAGACGTACGGCGCTCAAATACATTAGATCGCCAAACAGGGAGTATAGTCATGACCGCTATTCTCGCCTCAGGGGCGAGCGGCCCTGATGAAATGTGACGAACAGTGAACGGATCCCCGCATTCCCTAAGGATTCACGCGGCATTTGCAAACCCGATTCTGCTCATCACCAAGAGTCAGATGGCCGGCCAATATGTGGAGTGCTGACCTCCCCAAACCCTGTTCGAAGCAACGTCCTTAGGTGAGGTTAGCTTTGCCAATAACAAGGCCCTAATCCATCACCGTGGCATACATGTCAATTTTTGACACTCGGAATGCGCGAACGGATAATTCTACGCGTCTGTGGTGCGCAGGAAAAATCAACTGGTTCAATGAAAAAGGAAGCTACGCGTGTTCGCATTGATCCTGAGTTAGCTGGAAACGGGGGGATGGGGGTCGAATCGAGACAACGGCGACGGGGCCAACCCATGTGTATCTCTCTCGGATGCGCTGGTCTCGAGGTTAGCTCCCAAGCTTAGGTCGAGATCTAGTGCTCGTCGTGGCTGTATCCATTTTTCAGTAGTGGTACACTAAGCAAGTACAAGCCTCCAGAGAAAGTGTCGCGATTTCGCTGGAAGCCCTGGGGGTCATTTTAAACGAGAGATGGGTTCTTATCTCGGGTCTAACACCCAGGTTGCTAACGGACAGTAAGTTGTTGCCACGATTATGGACGCATGGCTACGGTAAGAAAGGGCCGAACACAATAATCAAGCCCAACTATCTATTGAATCCAGGATTGCGGCAACGATGGATAGCTAGGGTAACTCGGGTAGCCTTGTCGTGTACGGAGATGCTCTGCAGAAAAACCAGTTGAGCCCTAAAGCCACCTTCCGGAAAGGCACTCTGCCAACTACTGGGCACTCAGGGCAGTGATTGCCTCACCGGGTTCGGGCAAGCAGGGTGGTAATCCCAGTACGTTTTTTTTTTCCACCCACCA ================================================ FILE: test_data/gfa-1/sg.gexf ================================================ ================================================ FILE: test_data/gfa-1/sg_edges_list ================================================ 000000007:B 000000005:B 000000005 9 0 1980 99.95 G 000000005:B 000000016:B 000000016 502 0 1487 99.93 G 000000016:B 000000025:B 000000025 449 0 1540 99.94 G 000000025:B 000000018:B 000000018 11 0 1978 99.95 G 000000018:B 000000004:B 000000004 26 0 1963 99.95 G 000000026:B 000000005:B 000000005 997 0 992 99.90 TR 000000023:E 000000005:E 000000005 151 1989 151 100.00 TR 000000016:B 000000027:B 000000027 449 0 1540 99.94 G ================================================ FILE: test_data/gfa-1/utg_data ================================================ 000000007:B 000000018:B 000000004:B simple 997 94450 000000007:B~000000005:B~000000016:B~000000025:B~000000018:B~000000004:B 000000007:E 000000018:E 000000004:E simple 997 94450 000000004:E~000000018:E~000000025:E~000000016:E~000000005:E~000000007:E ================================================ FILE: test_data/p_ctg_tiling_path_1 ================================================ 000000F 000092122:B 000081654:B 000081654 33726 0 16258 99.45 000000F 000081654:B 000034462:B 000034462 10123 0 25619 99.85 000000F 000034462:B 000061403:B 000061403 1352 0 24447 99.96 000000F 000061403:B 000021348:B 000021348 9924 0 20804 99.74 000000F 000021348:B 000062240:B 000062240 5834 0 27313 99.67 000000F 000062240:B 000083779:B 000083779 862 0 30696 99.79 000000F 000083779:B 000019819:E 000019819 31327 36889 31331 99.94 000000F 000019819:E 000063672:E 000063672 29861 31245 29861 99.96 000000F 000063672:E 000026565:E 000026565 28347 28820 28363 99.87 000000F 000026565:E 000050047:B 000050047 2171 0 23431 99.62 000001F 000070651:E 000018109:E 000018109 16449 26526 16471 99.68 000001F 000018109:E 000068978:E 000068978 24989 28755 24989 99.65 000001F 000068978:E 000100559:E 000100559 27794 30442 27794 99.91 000001F 000100559:E 000010548:B 000010548 2421 0 26272 99.91 000001F 000010548:B 000006846:B 000006846 2089 0 25799 99.86 000001F 000006846:B 000065052:B 000065052 18168 0 27266 99.88 000001F 000065052:B 000071922:E 000071922 25982 28705 25982 99.97 000001F 000071922:E 000076878:E 000076878 26804 29255 26804 99.96 000001F 000076878:E 000000861:E 000000861 25184 25850 25179 99.94 000001F 000000861:E 000001755:B 000001755 15088 0 19711 99.94 000002F 000088930:E 000008918:E 000008918 8326 23541 8323 99.82 000002F 000008918:E 000100248:B 000100248 3113 0 22872 99.86 000002F 000100248:B 000085315:B 000085315 4851 0 23871 99.88 000002F 000085315:B 000071965:E 000071965 27539 29396 27553 99.84 000002F 000071965:E 000082497:E 000082497 19309 25344 19309 99.78 000003F 000084518:E 000011674:E 000011674 13681 23113 13688 99.28 000003F 000011674:E 000057445:B 000057445 23096 0 20291 99.73 000004F 000014727:E 000024020:E 000024020 15242 20480 15242 99.48 000004F 000024020:E 000060868:E 000060868 19975 23210 19975 99.76 ================================================ FILE: test_data/p_ctg_tiling_path_2 ================================================ 000000F 000092122:B 000081654:B 000081654 33726 0 16258 99.45 000000F 000081654:B 000034462:B 000034462 10123 0 25619 99.85 000000F 000034462:B 000061403:B 000061403 1352 0 24447 99.96 000000F 000061403:B 000021348:B 000021348 9924 0 20804 99.74 000000F 000061403:B 000081654:B 000021348 9924 0 20804 99.74 000000F 000021348:B 000062240:B 000062240 5834 0 27313 99.67 000000F 000062240:B 000083779:B 000083779 862 0 30696 99.79 000001F 000092122:B 000081654:B 000081654 33726 0 16258 99.45 000001F 000081654:B 000034462:B 000034462 10123 0 25619 99.85 000001F 000034462:B 000061403:B 000061403 1352 0 24447 99.96 000001F 000021348:B 000062240:B 000062240 5834 0 27313 99.67 000001F 000061403:B 000021348:B 000021348 9924 0 20804 99.74 000001F 000062240:B 000083779:B 000083779 862 0 30696 99.79 000002F 000014727:E 000024020:E 000024020 15242 20480 15242 99.48 000002F 000024020:E 000060868:E 000060868 19975 23210 19975 99.76 000002F 000060868:E 000014727:E 000014727 0 10000 10000 99.76 ================================================ FILE: test_data/t1.fa ================================================ >30a5633d_129405_0 AAAAGAGAGAGATCGCCCAATTTGGATTACAGTTAGGCACGCCGCTTGTTTTTTTTTTTATTTGCTTTTCGCAGAAAGGTTCTTTCCTTTAATCAGCGCCTCTTTGATTAATGGCGTCTCCGGCAATTGACAGGATTTGTTGTTTTGCAGTAAAAGGAGAAAAAAAATGAGTATGCCACGAATAACTAGAAATAGGGCTAAAAATGTTGCCAAGATCTTTGTGGCTCGGCCAGAGACAAGCGAGCAATGAGACAAAATTGGTCGCCAGATTTTTCTCTTTCTTTTGGATTTTTTTTTTTCTTATTTTCCAATGCCGTCTGCGGCATTCAAATATGCAACAGCAAAGGGCGCGGAAAAAGCAAGGAAAAATGGTGAAAATGGGGTTGGGTGAGAGATGCCTGGGCATGCCAAAGTAGCTGCCAATTTATTTTGGGCATTTTGCTTGGCTGATAGTTGGCCATCTTTATACTCTTCCCAAAAGTGTGAAAGAATATATGGAAACTAATATTATTAAATCTCTGATGGAGACTTTACGTTTATTTACAAAAATTTGAACCACGGATTTCTTTGACGAATTCAAAATTTAAACGCAGAGTATTGGTTACTTTATTATTATTATATATATCGTTGTGTGATTCTATTTTTTTTTTTCCTGTCGCCGGTTTCTTCTCGTTTTTATCGCGACATTTTTTCTGCGAGATTTTTTTTTTTTTATTTTTTTTTTTTTTTTTTTTTTTTTTGTGCAAAGGGAAAGTGGAATTCCTGGCATAATCGGGCATTGATACGCGGCACAAGAAATAAGTGGCAGAATGGACTTTTTCGCCTTTGTTCGCCGATAGACTTGGGCCACGTTTTATGGCCACGCCCCCTCTTAACCCATGAGAGCACCGCCTGGTCCTGCACGTGATGTGAAAGAATCGCTATGGCCAGCTGAGCCCAGAACGTGTCCTTGCCACCAAACTCCACGCAACTGGCAACTCGAATTCAGAATCTCAGCTGAGTCGACGTCTGGCCAGTGACACTGAGAACAAAAAAAGTGTATAACCTAGCAAAAAAAAAAACAAGAACCCCTTAGTTGGCATAAGTTAAAGATAATAAAAATAAACGCTTGCAAACGGCAAACAATAGCTCAAGTTTGCACTTGATAAAGTGAGTATCAACTATAGAAATGCTATTTTTTTGGCTTTTCGAGTTGGTTTTTTTTGGCAGTGAAGTCCTAATGATAAGTCTAAACTTTTTTTGAGGGGTGGTTAAGTTGCGCTAGGGGTTATAGGTTATATGCCGGAACTCTTGGTTTGCAGGCATGTGAGATTCATGTGACAAATGAGCCAGCAGCCAGGATTCAAGAGATGCGGGAAAGAAAGAAATTTGTAGAATAAAAAAGCAGTTTGGCAGTCTGGCGAGCAAAGGGGGCAGTAGGCGGATATGCCATAAGAAATGCATTGGCAAGGCATTGTGTGAATATCAATATTTGATCAAGAGAGGCTAGCGAAAAATCCCATTCAACGTTCGTTCCATTTACAATTTAGATTTCATTTTTGGGGCGCTTTGTTGTAACATAAAATTAAATAACCACCAAGAAACAAGATGAATACTTGTATATTTACGGGCGATAAAAGTGTCTTTTAAGCCGGCCAAATGGCACTTTAAAGGCCAAATGCCCCCTCCCCCCCTTTCTGGCAAGTGAGCGAATTTCGCCATCACTGATTGACTGCCATAAAGCGAATAATTCAAAGTTCCCTCGACAAACTTTCCTTTTGTTCCTGCCATTTCTTTTCCTTTCTTTTATGGGCTCTCGTGTTTATTTTTTTTCACTCGCTTGCCTTGATTTTTTTTTTTTGTTTATTTTTTTATTTTTTTTTTGGCTTTGGGCGGACTTGGCCCTAGAATTTTATTTTTATGACTCACGCACTTTTGGCGGCTTCCGCTTTGGAGCTGATGCTCCATCAAATGGAGGGGCCATCAACACCTGCTTAGAGTAAAAACGTGGGGTGGCAGTTCGTTGCAAGCGCGAGAGTGTAAGGACCAAAGTGCGAAATATTTATTTCGCTGGCAGAGAAAGCTTGGCTTTGAGTATGGGCCGGGCCTGTCTGCGGACTCATTTGAAATATAAATTTTGAAAACAAAACCAAGGCATATAGCACTGGAAAAAAAAAACGGAGGTTGGCACACGGCAGCCGCAAATGTAAATAAAAAGCGCTAACACTACGAAAAAACAAAAACTCAAACAGAAGGGCAAAAAGCCATCAAAATGAAGGGGCCAAGATTGAAGGGTTGTTAAGTTCTGCAAAATAGGGGGCAGTGATTTGCAGCCCCCCCTATCCCCCCTTCCCACCGGACATCCAAACACACACTGCCAAACTTTCGCGATGCGGCGGCTTAAAACGAAGTTTACGTGCATGGCAAGCGAGTAATTTTCCATTTTGCCGTTTGATTTTTACCTGACCATTTGTTTGGGGCCATTGCAATTGCCAAACAGTGGGCAAAAGTACAGTAAAACATGGTTTTGCATGTGTGAAGAATCAAGGCGCATACCACTTAAAAAAAAATGAAACAGTACAGTGCGAACTGGAAAAGCACGAACAGCGGTAAAGCTAAACAATGCAATTATAAATGATTAAAAATGAATGAATGAATGAAGTGATGAGGGCGTTGCTTTTTTGTAATTAAAAGGTGCCACTTTGCTCTTAACGGGCGTTCACTGGTAAGTCGCCCAGCGGCCCTTTTAAGCTTATTTACTGCTTTATTATATTTAAACACTACACCCGTGCCCCAAAAACTGGGCACAGCTTTTCGCCGCTGCATATCGCCGCCCCTGACAGAGCCCACCTAACCCCGCACCCTCGAAAGTTCGACGCCCCCCCCCCTCCCCTCCCCTGCGCCCAAGACGAGAAATGAATCCCCGAATAACAACAAACAACGATTCCCTCGCCTGTCGCGAGTATTGGAGGCGGGCTTCAAATATATATTTATTTTTGCGGCAGCATTCCGTGGGCAGTCAGCCAAAACACCCCCGCCCCCCCCTTCCCTTACCCTTTCACCCACTGAGGCATCCTGAGGCGGCGAATCTCCTGGCTAGCCAGCCCCCGCACTCCCCTCCCTCCCCTCCTCGTATGGCCGCATCCAACATGAAATGGCTTGCAAATCGTAACTCCTGTCGCGACCGTCCGCGTTGACAGCAAATGGTTTTTCCTTTCTTTTTTATTTTCTGTTTTCGGTGTCTTTTTTTTGTTGTTTGCTGCCGTATTTTTTATCGTTTATTTTTCATTATTTATTTATTTATTTAGCATTGCTTGTGCGATTTCGTTATAATTTATGCTGTAACGCATTTCTTTGCGCCTTAGTAGGCGAGCACGTAAAAACATTCTTAATCAGGCAAGTTTTCCGGGTTTCCGCTTTCACTTTTTTTTTTTTTTTCTGGCTAGCTGCCAACAAATAAAATAGGGACAGCCACTACAAAGAAGTCAGAGCTTTTAGCAACAGTTTGGATCTTAAAGTATTATTTGAAAAGCAAACTTTATTGGCTCTGAATGTAATGTAAAAGAGCGTTCGGAAGAAAGTGGAGATAAGAGTGATTTAAATAAAGCCATTCACGGCTTGAGAGTAATGCGAAAATTCGCCTCGAATTCATCCCAAAAGTTACTCGAACATTGATTTAAGGCCGCAACGCCCACCTGGCAGGGCTCGATTGAAGAACACAAAATGAACCCGGGCCAACCTTTTCCAAAATTGGTAAATTTGCGAAATTCAAGGCGTTTTTTTGAGGTTTGGCGAACCCTTTAACCTCCTCCTTTTAACGAGCCGCCAAAATGTCGCGGGCACCGAGTCTTGTCAACTTATTTTAGTGCTCGCCGCAAAAGACCGCAATCACAAACATACAAACAAGATGGGAAATATTAGCTAAAGAGTGAGACGAGACATATGGGCGGGCGGGAGAGAAGAGAGGGAGTGAGTGGTGAGATGGACATATATGCACCATATGTACATGTACGGGTATATGGCGCGGGAAAACAATGCACTGGCAACACGAAATCCAAAAAAGTGAACTAAAGTTCTAGAGGCGGAAATTTCGCAGCGACCGCAAGCGACGCAGAAAACAGAACCGAAAACGCAAAGCCAACCAACAGCTAGAGAGCTGGCGTTGGGTTAACGTGGGCGTTAGGGGGTTAAGAGGCGGCTGCCACTAAACTTTACGCATTACGCCCCCCACGTTGTCTGCGCACACTACACAGCACACACACCACACACCTTGACCGACAGTGGGGCTGCGCATAAAGGCATTAAATATTAGTTTTCATATGCCATATATCTAGATATATTTATATGAAAAGGTCGCAACGAATAGGTGGCCAAAAATGAGTATTGAGTTACATTCATTGGGCGGAGTTTGAACACTAAGGAATGTATTGTATTATTTTTGACGACGCGAGTGTATGGAACGTCTGACCATTTGGCGACCAGCGGCAGCTGGAAAAGCTCTCAGCAAAAAGAAGGCAAAACAAAGCGAAGGAAATAAAGAATAAAGTGGGGTTGTTTACGACTTTTCACAGAAAATTCATTGTCAAGCCGTGTGTGCGAGAAAATGAGGGAAAATGGGGGAAATGAGGGAAAAATGGTGGAAATGGAAGGGCGCGAATGAGTTGGGAGAATGAGTGGACTGCACTGACACGAAACTGTTGACGAAGTCGGGCCACTTCAAACAGTTGTTCCGCGCCACCCAACGACCTTCCGAGGCCGTTTATTAAAAGCTAATTAAAATTTTAAAACATTTATAGAACAAGCGGAATGAAGAGGAACGTTCGGGGGGAGGGGGGACGTGGCGGGGCTGGCAGGGAAGCAATACACTGGCAAGGACATTCAAGGGGAGGCGAGTCCTTAAAATTGGCCGTAATTAACGTTTGGCAACAACGCAGCAACCACCAAGCGCCATTCTGAATTTTGTTTTAGTAAGCCGGACGAACAAAACCGGAAAATACTTTATGCAATTTTTGTTTTTTTTTGTTTTCTTAAATGCAATATTTAGTGGCCTTTTCCAATTGAAGGCAGCAAAAACGTGATGTGCTACTACCAGCGCCTCTTTTCTTAAGAAGAGATCCTTGGAAAAATCGCCAAGCAATTCGGCTTTCGGCTGACCTCGTATAACTTTCGTTTGCCGGATTTTTCGCCGGCTGTATTTCCGCTGGCATCCTTCTAGACAAAGATCCTTGTGCGTCCGGCACTTCATCCCAATCCCTTGCTGCTCGCCATATCCCTTTCTGAGGCTGTTCCATTTTGGGTTTCTGCGAGGCATTCACTAACTGGCAGGAGCGTGATTTTGCTCCCTCTATTTTTCGCCTTTATCCAGTCAGATTTTCATTTTTTTTCATTTTTTTTTTTACTTCTTTTGATTTGCCATTTCTGCTGCTGACATCGATTTGGTCCGCTTTTCAAAGTGGCAGCAATTCTTTTATTTCCTTTTTGCCACACTCTCCATCTCGGCTCGCGGATTCTTTTGGTTTATCTTGCGCGATTTTTTTTTTTTTTTTTTGTTGAATATCGTTGCGCGACATTTGCATAAGTCCGCATAGAGCCACGTCCCCCCGCCCTGCTGATCCAAACGTTTTGAGAGTGTGCACTGGAAAATTGAAAAAGTCTTTCGTTGATGCAAAACGAAGAGTTGCGCACTTTATATAATATATTCAAAAAAGATAAAATGTGCATTATTGTCGAAATTCAACGATTTATAGCTGCCCTTTTGGGCTGTGTAACATATATGGTTATATAACACATACAGACACCCATGTGCTCTTTATTATTTACACTTGCACCAAGCGCACCACATGCCACTATTTCATCCACCTTGCAACTCTAGTCGCCCCCTCCCCATTCAACTTATTGGGCCACTCATGCGCAAGGACAAAATGCTTTTGCAAATTGATTGAAAGGGCAGCATCGGCTAGATAACTAATAATATATTTTTGTAATAATTATGCCAAAATCTATTAAAATTTATCTATGGAGGAGGAAACCGAGAACAATTTAACATCATTTTCATTTTTTTGTTTTTTTTTTTTTTTGAGATAAAATTCCTGCATGAAATTAAACAAAATACACTGCTTATTCGATTGGTAGCGCAAAATATGAAATTCTATAAGCATAATTTTCATTTTCGCATTTTTATGCTACGAATTGCTCGCCGGTTCTTCTTCGTTTTTCGCTTCAACGCAGGGCGCAGGAATGTATGCAACATTTTTTTGTTATTCAACTGCACCAAATTATTTTGGGAAAAAATAAAAACAGCAGCAGGGCAAAAAAAAAAAAAAAAAGGCAGAGAAACCAAATGGGCATGTCCTAAATTGATGACAGGGCAAAACATGGGCAAAGCAAAGAAATAGGAGAAGTAGTGAGCCAATATACAACTAGTGGGGGTAAATCGAAACTAAACACAAAACAAAAGCTAAACGAAACGCAAAACAAAAAAACAATAAAAAAAGAAAAACGGAAAACGCAACGAAGTTTTTGCACAATTTTAGTGCACACGTTGTTGCATTTATATGTTGTTATTGCCGCTGGTAAATTGACTTAACTGTACTGCAAACAGCAATAATAGCAACGCCCCCACACTGGCCTACACTTGGAAAAAAACAAGGCACAAAAATCATTTTTGACGTTTGAAGTCATTGAAAGCTGCCAGTTGTGCAAGGTCGCCATCAAGCAAAAGGGGGTCAACTGCAAACTTTATGATGATCCTAGCATATTCTAGCATAAATATTTTAGTCATAGAGAAAAAAGAAAGGATTTTTTTTTTCATGTGCACAAAAAAGCATTAGAAAAATCCCCGCTCCTTGTCTAACCCTTATTTTATTTCGTCCTACTGGTTAGGGAACTTGTGGGCCATTATTGGATCCACTGCATATAAGGAGAGATATTCACCTTAACAGAGGGGCCGTAACCTCGCTCGAACTCTCGACGCCCTGCCCTTTCGGAACACCCCGCTTCGCGCCTTCCGCCCATGGGCAATGCCTAATACGGGTGACTTTATTTAATTTAATGCCATTTTGTGCCTGCCCCCACACAAAAAAGGGATGAAGCCTGAAGGAAGCGAACAACCGCAGGAGCAAGCAAAGCTTAATATTCAATAATAATAATACGAGCATAGACTGTGCGATAAGATAGGAAAACATCAAATGCCACAAAGGGCGAAGCAGGATGGGCTTCTTAAAAGGCGATATGCTGTTGTGTATTCAAAAAAAAAAAAAAAAATATTTAAAAAAAAAAAAATAAAAAAAATATATAATGGAGCAAAAGAGTGGTTTATGCGTTACATAAATCGCCTTGAATATACATATATATGTATATAGCATATATTTATTGTGACTATGAAAAATATTGCAATAATTTAGCCGTGCTTTCATTCACAGTTAAGTCGTCGCCCTCAAATGGGCAGCGAACTTCTTAGCACTTTTCAATGTGCACTCAGCAATAAGCTTTAAACAATTCTTTAATATGTTTTCATTTTGCTTGGATCGTGCAGCCTTTTAGCTGTGGGCACTTCCACATGTTGACACTGCGCAAAATACGCAAATGATAAGTGTGGCACAAAAAAATTCAAAAAATGGCTAATGCTACATTGCAGTAACATTTATTTCTGCACTTTTGGCTCATTTAAGTAGCATATTAATGATTTCGTTTATCTCCCGCTTGAAAAAGCGTTTTTCAGATTCATACGTTAACGAAAAATTGTTAGGCATGTTACTCGTATTCATTACTGCGCTGAATGATTGCATTCGATAGTCGCTGCAGTTTGCAGCTATTCCCATGTAAAGTTGTGTGCTGTGTGTGCGGTGCAAGTCTGTGTGCCGTGTGTGTGTTAAAAAAAAAAAGAGAGAGAATTGTTTATTAAATACAGGCAGAAGGCGGAAGGCGCGGCGCATTCGCCTCCTTCTTGCACAATAAACACCAAAAATACAAAGAGCACAACAACAACAACAACAACGAGAAGACACATGTCCGCTTTGGGCGCCTTGTCTAACACCCCGCAACCCGCCCTCGAAACCCACTAAATTCCCAAGGACATACAGGCCCTTGTTTGCACATGAAATAGACACGCACCACACGTGCAATTACCAAGCACCCACCCCCCCACCCCTTTTGTGCTTTTCTTACTTTTCAGTTACTTTGCTTAAACGCTTTTAAATTGTTTTTCCATTTTTCCGTCTTTCCTTCTTTAATTATTTTTTTTTTTTTTTTTTTATTTTTGTTCGTTGTTGCTTTTGGGCAAGGAAAATTTGTAACCTAAGCGCATTTTGGGAATTTAAATGCATTTTATGAGCCTTTTCGTATGCTCCAGGACCCTCGTCCCTTTTTCCTCGATTTTCCATTAAGGGATACACTGAGTGAGCAGAGAAGCGGCAAAAAGATATGTTATGACAGTGTCCAAGTCGCAATTTTCAAAAAGGAGGCATGGCACTAATAATGTACGCTTACTAATAAAAAAAAAATAAAAAATTAAAAAAAAAATAACGCAAAGGAACTGCTAATCGTGCAACAATCACCATGGCTTTACGGAAAATGTTAACAAGTTTCATATTGAAAATGCAACAAAGTACGCGCTTGCCAAACGAACTTTATGCAAAATATCGTTGTAATTACGGCACTTCAACGTAACCAATTTAAGCCAACGAAGCACTGATGGGCTAGTAATGAAATATTTCGCCAGAAGTTAATTACATCACAGTTTAATCGTTCGTTGCCAGGAATTCGCCGGATTCCAATTGAATCAATTTACAAATTAGAAAATTTCACAGTTGCTCAATCACTATGCCAGGCCGGCAGCGCCATCTAGTGTAATATTGTGAAGGGCACTCTCATGCAGCCGTGGGTCAGACATTTGAACTTTGGCGGCGGGTAATTTTTGCTGGGGTGTAGAAGTTGGGGGGGGTTCATTTAAAGGGGCCCACTACACTTAACAAAAATATTTAAGAATTATCCCTGTGCTTGCTGCCCAAAAGGAAAAAAGGCCCCCTTCAAATAATAAATATATGGCACCTGGTGCGGCCACTGTTCTAAATATTAGAGGTGCCAAAAAGGGATGATGGGTCCGGTGGGTGTTGTTTGTGGACGGTGCCGCTTTGCTTAATTGTTATAGCGCAAACATTTCGTGTCATCC ================================================ FILE: test_data/t1.fofn ================================================ ./t1.fa ================================================ FILE: test_data/t2.fa ================================================ >5d64830a_48915_0 AGTAGAGATCATCTAAACTTTGGTGGTATTTGGCTAACTTGCTTATGTACACATATTAATTTAATTATACGAGTAAACTATTTCCATATTAGCGTATAGCAGCTACGCATAGTTTATAGAACAATAAAAATGAAATATTTTCGGCGACTTTGAACAAATGACGCTTTAGGGGCCTAACGGAGTATTTTTATGTGATAGACGATTTTTTGGCGGGCCAAAAAAAATAAAAGGGAAATTGGTGCTGCGCATAAAATTGAAAGCAGGCTTGCCCTCCAACCCCGCGTCTGCCCTCCCCCCCCCCCCCGCAGATCAAGAGATTATGCTATCCCGCAATAATTCGCGCCTTGCCCGCTTAACTACGTTGGCCATGCGTCGGGGGCGGGCGTCTATGCAATGGTTCAATTGGGCGTTGACTGGCCGCTGGCTAGTGTAAGCCCAGTTTTGCGGCTTATTGCCGCTACTCGGCTCGGGCAATCACATCGAGGTCATTAATCAGAACACGACAGCCCAAAGCGGCAGCGTCATGCCGCCGCACGTTTAACCCCCCTTGGCGATGCGTACTTGGGAAATCAGCTCATAGAGGTCAGAGGTATTGTATAATTGGGCTTTATGCGAAAAATCAGCGAGCCATCAAATCCCTTGATTCTACAGATACATATGTGTAAACATATGGGCTATTGTCCATCTTTATTTTACTCCCTACTTTAGGTAGTAGCACCGCTTGCAATGTCCATGCAAGCATTTTTCTAAATTATTTCCCTTGTGTTTTGTTTATTTTGTTTTCTTACTCTATGATATTTTTTTTTTATTTATTGTATTTATTTTTTTTTTGGCTTGTGTACGTTTTTATTAGTTTTTAGTTAGGGGCCGAAAAATGTTCTTTTGTTCGATTTGTGGCTGCATTGGCGAGATATATCAAATTAAATTGCAATTTGTTTTTGTAATTGGAGCTTGTCATATTGCTGTTGATGTTGTTGCTCACGATTCGTTTATAGCTATTGTTCCGGCTGTTTTTCAGTTAAGCGAATAAAATGGAATGCGCACACACATGGGCAGAGTGAAAAGAGTAGAAATATGAGAAAATTGACATATAACTCAAGAAAAATTATGCTGATCAAATTGTTATAAACATTGATTTTCCGCTATTTCCTGCTTTTTTTTTTTTGTTCGCTATTTTTCAGGTGAAGTTGGCAAAGCAGAGATTTCGAGGTGCTTTCATGGCTGTGTAAACTTGATAAGTGAGTGTAGCTTTGGTAATTTAAGTTATTTTTTCAACTGGCGAAGTACCCACTAACAAATAAACTGCCAAGAAAATACGCGCATTTATTTATAAAAATGAAAATGAGGAAATGCGAAAAAAAAGAAAAAATAACAAAGCGCCAATCTTCACTATCCAATAAATTTTATTCACTTTTTCGCGCTATGGAGTGTTGCGGCATCTATTTTTCGCAATTTTTTCATGCCAGGCCTCTAGATAATTTTTGTGGGCAGGCTTTGTTCGAAGACAGAGTGCGGCAAGAAGGTGAAATTCATTTTTAATTAAAACATAGCCTAGCGCGCACGCGCAAAAAAGTAAAGGCACGCTAAAAAAATAAAAAAAATTTGCGAAACATAACAATAGGGATATGAATATACACGATAATATATTAGTTGCATAATACAAGTTAGCTATGTGATATATATGCCGAATAACGCACAGGCCCAGCGGGTTTTTTTTTTTTGCCATGTTTCAGTCAATTCATTTCGTGTAGAACCTGTTAGGGCTTTGTGTGCAGTTTTTTTTTTTTAGCACAGCTTCTTCTAATTATTTTTATACTTTTTCCTGGCGAGGCAGCTTTTCAATTTGCCGTGGAAAACGCCCGTTGATTGCCTATTCATTTGCCATTTCGGCGCATGCATCCCTTAATCAGAGGGCACATTTCTGGCTTTACATGGCTTGCCGTAATTTGAAAGTTGGCAAAAATTACAGGTGAAAAGAGACTGCTTAGAAAGTTTTGCCGGGCATGGCAAAGCGCGGCAAATAAATAAGCAAGAAGGATGTAGGAAAAGCGCCTGCGCTGAGAAAAGCGCTGCACGAGAGGAGTGAACAACGAGTGGAAAACGGTGGTAAAATGTCGCAGCATTATTGACTTCAAAAAAATTCTAACAGCAGCACGACAAAAGAGAGGCAGAAAGTAAAATGCCGTTGCAAAAGGTAAAGCCAAGGATATTTATGAAATTAGAAATGCGGGTAGAAAGTATGTTCTGTAGATTTGTAGCAGTCTTTGCATCGGGATATATATTTCTTTAGAAGCTATGAAAAAAAAAAATTCTATATTAAATTACAAGCATTGAAGTGGCTTAAAAAATATATAAGGCTCCCGCTGCTTATGTTAGGAGCTAAAATCTCCTATGAACTTATAAGCCTATTTAGAATGTGCATAGAAATTAATATATATAATATATTTTTTTTTTTCTTATTTAAAGAAAGTTTTTTTTCCCTATTTTGGCGCAGTCCAGTGTCACTAATGGCCCTGACCTTGACTGTGGGCCCTGTGTTGAGGCTTTAAGGCAGCTTATCTGCTGGCTGAAATGTCTATTGGATATCGCGTTCTGGCATCAAGTCGTGGTCAGCACCCATGATGGATCCATTCTTAACTCCGCAAACGCCCTGTTCCGGGCTAGACGCTTACCATATCCAAGTTGCAAAGTGAGGCTATTTCGTGGGGGTGGTGGGGCATTTAATTAAGGCGGGGCGTGGGCAATTGATTATAATCGGGTGCCTAACCCGAATAGCGAAATGTACAGAACAATAACGAATTTCGATATCCAAAAACGGTTATCTCTTAAATGAAATGCGAATTCGCAAACCAATGTGATTGCAATAATGAGGGCAGAAATAACGATAAACAAGCAGTATAAATAAATTAGCATAAAAGGGTGTTGTATGGTCAAAACAGCGGCGTGACCGTTGCCGAACATTTGTTCTAAGGGCAGCAGCTTTTGCTCTTGAATAATGATTAATTTATTGCTAATTTTCGCTGCTCATCATTAATTTGCGAACAGTCAAATGTAAATATGCGGAGCCGCCAGGGCGCAAATAATTCTACTGGCAATATAGAAATCCTAAATTACGCAAATAAAACGGAATTTGCGGTTAATGTATTATCGTTCAATCAGCACGGAGGTAACACTAGTAAATTTCACAGAATTTATAAGCTAGTTATATATGGTTAAAATCGAGAAATTTCCTGCTCGAGCACTTTTTAGGCAAAAAAAAAAAGTATTTTTTTGTTTTTTTATTTTTTTTTTTTTTTGCTTATAATTATCGTGATAAAAGTGTAACAGTTATGTACTTCATCTAGTTGTTTTTCAATCGGCAATTTTCTTACGCACCTTTGCCATAGGGTTGAATTAGTTTTGCTTAACAGCTTCTGTTTGGGTCTTATTCGTTATATTTAACAAATTAATTGTGAGCAGAGTGCGGGCGCATTGCAAACTTTACTTTTCGGCCGTCTAAGTCAAGGCAGATACTTCGAAAACATTTTCAATTGTCATATATTATTTCAAAAACGTTTTCCGCCGAATTTGAATACAGTTAGGCACGCCGCTTGTTTTTTTTTTTTTATGGGCTTTTCAGAAAGGTTCTTTGCTTTAATGCACGCGCTCTTGTGATTAGATGGTGCTGCGGCAATTGAAATTTTGAATTTGTTGTTTGGGCTAGTAAAAGGAGAATAAAAAAATCGAGTAGCGCCACGAAAATAGATAATTAGGGTAAAAAGTTGCGAGATCTTTGTTGTGCTCGCAGAGGACAAGCGACAATGAGAGCAAATTGTCGCAGATTTTTTCTCTTTCTTTTGATTTTTTTTTCTTATTTTTATGCGCGCTGGCGGCATTCAAATATGGCAACAGCAAAGCGGCGGAAAAGCAGGTTAAAAATGGTGAAAATGGGTTGGGGGGAGAGATGCCTGGGCTATGCCTTAAGGTAGCTAGGCCATTTATTTTGCATTTTGGTTGCTGATATGTGCCATGTTTATACTCTCCGCTAATCAGGTGAAAGAATATATGGAAACTAATATTTTAGAATCTGCTGATGGAACTTTTAACTGTTTATTTAAGCAGTATAATTGAAGGCGCAGCGGTATTTTCTTTGACGTAATTCACATTTTAACGGCAGAGTATTGGTAGTTATATATTATTTATATATTCGTTTGTGTGATTCTATTTTTTTTTTCTGTCGCGGTTTCTTCCTCGTTTTATCGCGAACATTTTTCTGCGAGTATTTTTTTTTTTTTTTTTTTTATTTTTTGTGCAAGGAAAGTGGAGATTGCCCTGGCATATAATCGCAATTGATACGGGCCACAAAAAAAGAGGGCAGAGGTACTTTTCGCTTTGTTCGCTCGATAGACAATTGGTACGTTTTATGGCATCGCCTCTGCTTAACCGGCATGAGAGCACCGGCGGCTGGTCCCTGCACGTGTGTGAATTAGAAGTCGCTAATTGCAGCTGAGCCAGAACGTGTCCTTCCAGCCGAACTCCACGTGGCAACTGCAATCGAATTCAGATGCTTGCAGCTGGAGTCGACGTCTGCCGCAGATGACACTGAGTAACGAAAAAAGTGTTATAACGCTAGCAATAAGAAAAAAGCAAGATAGCCGGTAGTTGGCATAAGTTTAAAGTATTAATAAAAATAACGCTTGCAACGCAACAATAGCTCGTTTGCACTTGATAAAGTGGAGTATCAACTATATGATTATGCTTATTTTCTTTGGCTTTTCGAGTTGGTTTTTTTTTGCAGTGAGTGCCTAATGATAAAGTCTACTCTAAACTTTTTGCGGGTGGTTAAATTGGGCCAGGGGTTATGGTTATATCCGGAACGTGCTGGTTGGGCTATGTGAGTTGCATGGTTGACAAATGAGCCTAAGGCAGGCGCAGGATTCTAAGGAGTCGTCGAAGTAAAGGAAATTTGGTAGTATAAACCAGCATGTTGTTTTGCTAAGTCCTGGGCGTAGCTAATAGGGGCAGTAAGGGGAGTATGCATAAGAAATGCATTGCAGGGCTATTGTGTGATATCAAGTATTTGATACAGAGGCTAGCAACAGTCCAATTGCACGTTCGTCGCATTTACAATTTAGATTTTGCATATTTTGGGGGCGGCTTGTTTGTAACATAAATTAAAAACTAACCAGCTAAGAAACAAGATGAATATGCTTGTATTTTACGCGATAAAAACAGTTGTTCTTATTAAGCAGGCCCAAATGGCACTTTATAGGCCAAATGCCGCATCCCCCCCCCTTTTCTGGCAAGTGAGCGAATTTCGGCAATGCAGCTGTATTGAACTGCCGCATAAGAGCGAATAATTCAAAGTTCGCTTGAAAAGCTTTCGCCTTTTGTTGCCTTGCATTTCTTTTCCTTTCTTTATGCTCATCTTGTTTATTTTTTTCGACTCGCTTTCGGCCTTGATTTTTTTTTTTTTTTTTTTTTTGGCTTTGCGGAGCTTTGGCCGAGCTAGAATTTATTTTTATGACTGCACGCACTTTTGCGGGGCTTCCGGCTATTGGAGCTGATGCTCCATCTAAATGGAGCATCAACACCTGCTTTTAGAGTAAAAAAAGTGGGTGGCAGTTTCGTTGGCAAGCGGGCGAGAAGTGAAGGACAGTGGGCGAAATATTTATTTCGCTGGGCAGTAGAAAGCTTGGCCTTTGAGTTATGGCGCGCGGGCTGTCTGGCGGAACTGCAATTTGAATAAAATTGGTTGAACAACACTCCAGCATATTTATGCACTTGGGATAAAAAAAAAAATACGGAAGGTTGGGCCACTACGGCCGCGCAGAATGTAACATAAAAGCGCTACACTGGGCGAATACCAAACTCACAAAGGAGCAAAAGCCAGGTCAAAATGAAGGCCAAGATTGAGGGTTTGTTAAGTTTCTGGCTGCAAAATGGGGGGCAGTTGATTTGCAGCGGCGCCATTACCCCCCTATCCCACCGGCATCGCAACGACAACTGCCACTTTTCGCGATGGCGGCGGCTTAAAACGAAAGTTTATATCGCATGGCAGCGAGTAGGCTTTTGCCATTTTGCCGTTTGAAATTTTTTTACCAGCGCATTTGTTTGGGTCCTATTGCAGATTGCCTAACAGTTGGGAAGTACAGTAAAACATGTTTGTTGGCATGTGTGAAGAATCTAGGGCGCATACATTAAAAAAAATAATAAAAGTACAGTGCGACTTGGAAAAGCCGCAGAACAGCGGCTAGCTAAAAATGCTAATTATATGATTTAAAAATTGAATGAATGATGATGAATGAGGGCGTTCTATTGTAATTAAAAAAGGTGCACTTTTGCTCTGAACGGGCGTTGCTGTAGTCGCCCACGCGGCTTATTAGGCTTATTTACTGCTTATATATTTTAACACTACGCGTGGTGCCCACAAAACTGGGCAGCGGCTTCGCGGACTGGCATAATCGCCGCCGCGCTGACAAACGCCTACCTACCGCCGCACGTGCCGGCTCGAAGTTCGATCCCGCTCGCTCCGCGCTTCGCTGGTCCCGTAGGCCCATATGCGGAGTAATAATGAATCCGCGTCGAATAAACTAACAAGAAACGATTTCCTCGCCTGTTGTCGCGATATTTTTGAGCGGGGCTTCAATGTAAATATTTTATTTTTCGGCAGCACTTGCGCGTGGCAGTACCTAAACCGGCCCCCCCCCGCCTTCCCTTTTCGCTTCACCGCCTGAGGGGCATCCTGAGGCGGCGAATCTCCTGCAGCCAGCGACCGCTACCCTTCCCTCCTCGCGGCTCTGAGATGGCCGCTTCACGATGACAATTGGCTGCACATCGTCTTGCGCTTGTCGCGGGGGGAGCGCCGCCGCGTTGACGCGTAAATGGTTTTACTTTCTTTTTTATTCTGTTTTTTTGCGGTTGTCGTTTTTTTTTGTTGTTGCTGCCGTATTTTTTATCGTTATTTTTCTATTAATTTATTTTTTTTTATTTATTTAGCTATTGCTTGTGGCATTTTTCGTTATATTTATGGCGCTGTGCCTGCATTTCTTGCGGCCTTATAGGGGCACACGAAACATTCTTATGCAGCAAGTTTTGCCGGGTTTTTCGGCGGGCTTTATTTTTTTTTTTTTTTTCTGGCTAGCTGCCACAACATCAAATAGGGACAGCCACTAAAGTCAGAGCTTTAATACAACAGTTTGGTCTTAAGTATTATTTTGAATAAGCAACTTTTGTCTGTAAATGTAATGGTAAAAGAGCTGCGAATGACAAGTTGGAGTATATAGAGTGATTAAATAAAGCATTCAGTTGAGAGTATGGTCGTATCCCCCATATTCGCTCGCAATGTCATCCCATATAAGTAACTGGCGACATTGATATTTAAGCCGGCAACGCCCACTAGGGCGAGGGCTTGCGATTTGAAGACCAAAATGACCGCGGGCCAGAGCGCTTTTCCATATTGGTAAATTTGCGAATTCAAGCGTTTTGAGGTTATTGGCGAACTTTTACGGCCTCGCTGCCTTTAACCGCCTATAAATTTCCGGGCTAGCGGCAGTCGTTGTCAACGTTATTTAGTGCTCTGGCAGCAAGACCAATCACAAACATACAACCAGATGGGAATTATTAGCTAAGAGTTGAGAGCGAGACATATGGGCGGGCGGGAGAGAGAGAGGGAGTGAGGTTGAGTGAGTATGGACATTATATCACATATGTGCATGTAGCGTATATGGCGCGGGAAAACAAGCACTGGCGTAACTACGGTCAATCCAAAAGTGAACTAACCGTTCAGAGGCGGAATTTCGCATGCAGAGAACCGATGCGACCAAGAAAAGCAGAAGGCCGAAACCAAAGCTCTAACCAGCTACAGCTGCGTGGTTATACGTGGGCGTTAGGGGTTAAGGAGGGCGGCTGCATACTTAATAAGCATTGACGCTGCATACGGCCATCGTTGTGCTGGCAGGGCTTACACACACAGCACAGCACGACTAGCTTGACCGACAGTATGGGTGCTCGCATGATAGCATTACATATAGTTTTGCATATGCATAATATCTTAGATATATTATAATGATAAGGTAGCAACGAATATAGGTGGCCAAATTGCGTATTGAGTACATTTAATTGCGGAGTTTGAAGCACTAGTAATGTATTGTATTATTTTGCGCGCGGGCGAGTGTATGGTACGTCTGACCTATGTGGGCGTACGCAGCGCAGCTGGAAAGCTCTCTACATAAAGATAGCAAACAAAGCAGGAAGGAAATAAAGATAAAGTGGGCGACGAGCCTTTTCATCGAAAATTCTATTGTCCAGGCCGTGTGTGCCGAGAAAAAATGAGGGAAATATGGGGGAAATGAGGGGAAAATGGTGGAAATGGCCGGGGCGCGAATTGAGTGGGAGAATGAGTGGAACGCATGCACTGACATCGTAACTGTTGACGAAGTCGGGCGGCTACTTTCAAAGTTTTTGCGCCAAACCCACACAGAGCCTCGCGGCCGTTTTATTAAACTTATTAAAAATGTTTATAAAATTTATAGAAAATCGGAATGAAGAGGAACGTTTCGGGGGTGAGGGGGGACGGTTTGGCGGGGTCTGGCACACTAGGGAAGGCAATACACTGGCATAGGACATTCAAAGGAGCGAGTTCATTTTTAATTGCGCGTAGATTTAACGTTGGGCTATTAACGCAGCAACTCGGGCACGCAGAGCGCCCATGTCTGAATTTTGTTTTAGTACGAGAACAAAAACGGAATACCTTTTATGGCATTTTTTTTGTTTTTTTTTTGTTTTTGCTTTGCAATATTTTAGTGCTTCAAATTGCAGGCAGCATAAAAACGTGTGAGTGCTACTACTCTAGCGGGCTCTTTTCTTAGAAGAGTATCCTTGGAACATCGCCAGCTTTGTCGCATTTCGCTGACGCTCGTATAAGCTTTCGTTTGCGAGATTTCGCGCGTGTATTTCGCGCTTTGGCTATCTTCGTAGGAAGCCAAGAATCGCTTGTGCGTGCCGGGACTCCTGCAATTCGTAGCTGCTCGCTCATTATCCGTTTGCTGAGCTGTTCTATTTTGGGTTCCTGCGAGGACATTCACAAACTGGCAAGGTAGCGTGATTTTGCTCTCCTGTCTATTTCGCCTTATCCAGCAGATTTTCATTTTTTTTTCAATTTTTTTTTTTAGCTTCTCTTTGATTTGCATTTCTGCTGCTGACTATCGAATTATGGGGGCCGCTTTTCAATGTGCACAATTCTGCTTTCATTTTTTTCGCTTTTGGCGAAGCAAACACACATGCTCTCTGCGCTCGCGGTATTCTTTTGTTTTCTTCGCGATTTTTTTTTTTTTGTTGATATCGTTGCGCGACTATTGTGCATAAGTCGCATAGAGCCCGCCCCGCCCTGCTGATCTACGTTTTTTTGAGATGTGTGCACCTGGAAAATGAAAAGTCCTTGCGTTTGAATCGCAAAAGAAGGAGTATTGCGGCAGCTTTTATATACATATATTTCAAAAGTATAAAATGTGGATTATTGTGCTAAATTCAACGAGGTTTATAGCTGCGCCTTTTTGGGGCTGTGTAACATATAGTGGTATTATATCACAGGTCATATGCAGACCCCATTGCTCTTATTCTTTTAGCACTTGCAGCGCTACCGCGGGCAGCAGCTGCCAACTATTTCCTATCGGCCCCTGCAACTTCTAGTCCGCCTCTCCCTTCAGCCTATTGCCCGTGCATGGCGCAAGGATCATATAAATGGCTTTTGCATATTGAAATTGCAGGCGGCGGCTTCGGCTAGATAATACTCAATATATTTTTGTAATATTATGCCAAAAATCTATTAAATATTTATGGCTATGGAGGAGGAATACCGAGAAACAATTACACATCCCATTTTTTCATTTTTTTTGTTTTTTTTTTTTTTTTTGAGTAAATTTCGCTGCGATGAAATTAAAGCAAAAGATATCATCTTTATTCGAATGGTAGCTGCAAAATATGAAATTCTTATACTCATATTTTTCATTTTTCGCATTTTATCTACGAATTGCTCGCCGGTTCTTCGTTTCGGTTGCCATCCGCAGGGCGGGAGAATGTATGCATTACGATTTTTTTTGTTATTACTGCTAGCTACATTTATTTTGGGAAAAAATAAAACAGAGCAGGGCAAAAAAAAAAAAAAGCTAGAGAAACGGCAAATGCATGTCTCTAATTGTATGCCAGGGCAAACATGGGGGTGCAAAGCAAAGAATTAGGAGAAGGTAGTGGTAGCAATAACAACTATAGGGGGTAAAATCGTAAACTAGCTAATACAATACAGCTTAAAACCGAAAGCCAAAACTAAAATACAAGAAAAAAAAAATAGAAAGCGATGAAACGCAACGAAGTTTTGGCCACAATTTAGTGCACATTGTGCCTATTTTATTGTTGTTATTGCGCTTGTACACACTTGAGCGTAAGCTGTACTTGCAACAGGCAATAATAGCAGCGCCCCAACATGCCTCCTGGAAAAAACCCCAAGGCACAAATCATTTTTGACGTTTGAAGTCTTTGAAAGCTTGCAGTGTTGTGGCATAGGTCGCCTAATGAGCAGCACGGTCAACAACTGGCAAACTTTATGTATGATGAGCTAGCATATTCCTTAGGATATATTTTTAGTCAGTAGAGAATACGAAAGGATTTTTTTTTCATTGTGGCACACCTAAGGCATTAGAAATCCCCTCTTGTTCTAACTTTTTATTTGGCGTCCTACTGGTTTAGGGAGAAGCTTGTGGCTCTAATTATTGATGCCACTGGTATATAGGAGAGACTATTCCACGCTTAACAGATGGGGGTCGTCACGCGTCGCTCTAACTCTGCTGCCCCTGCGCCTTGTATCGAAGCAGCCCCCTTCGCCCGGCCGCTGCATGGATGCTATATACGGGTCTTTATTTAATTAATGCGCATTTTGTGGGCTGCCACGCTCCATCACAAAAAAGGGTTGAAGGGCGAAGGAACAACACCGCTAGGTAGCTATACAACTTCAATATTATAATAAATAATGACGAGCTAAATAGACTGTTGCGATTAGATAGGAAAACACATCAAATGCCAGCAAAAGGGCGTAGCAGGATGGGGCTTCTTAAAAAGGCGGATATGCTGTTGTGTATTCAAATAATAAAAAAATAATATTAAAAAAAAAAATATAATAAAAAAGTATATAATGGATGCAAAGAGTGGTTTTATGCGTTACATTAATATCGCCTTGATAATATACAGTATATTGGTATATAGCTATTATTTATGTGGACTAGTGAAAATATTGCATTTTTAAGCCGTCGGCTTTCAAATTCACTTAAGTTCGCGCTTCAAATGCAGCGACTTCTTGCACTTTGCAATGTGCGCACGTCAGCAAATAAGCTTGTAGCATATTTCTTAATATGTTTTGCATTTTGCTTGGATACGTGCACGCTTTTTAGGCTGTGCGCAGCTTCAGCTGTTGACACTGGCGCTAAAATAGCGGCAAATTGATAGTGTGGGAAAAAATTCAAAAAATGGGTCATTATGCACATTTGTCGTAACCGTATATTCTGGCAGCTTTTGGCTCAGTTTAAGTACATTATAATTATTTTCGTTTATGCTCTTGAAAAGCGTTTTTCCGAATTCATACGTTAACGGAAAATTGTTACTAGTGTACTCGGTATCTCATTAAGTGCGTGATGATTCATTCGATGTGCGCTGGCTTAGTTGGCAGGGCTATTGCAGCGATGGTAAAAAGTTGTGTGTGGTGTGTGCGTGCAATCTGTGTGGCTTGTGTGTGTGTTTAAATAAACAAAGAGAAGAGATTGTTTATTATAGCAGCAGACGGGCGGAAGGCAGCGGGCGCATTCGTCCTTCTTGGGCCTAAGCAATAAGGACACCAAATAACGCAAAAGGAGGGAACAACAACCATCAAAACAAGCGAGAATAACAACAGTGTCGCGCTTGGGCGCCTTGTTTAAGCCACAGCCGTGCGCAACCGCGCTCTCTGAAAGCGCCATCTAAATTCAGGACACAACAGGCGCCTGTTGCAGCATGATCGACATACGCACAATACGCACGGTGCTAATTAGCGGCAGGGCACGCCACCCCCCGCCCCTTGGTGCTTTCTTAGCTTTTCAGTAGATTTGCTTCATATACGCTTTAAATTGTTTTCGGCATTTTTCGGCGTCTTTCCTTTCTTATTTATTTTTTTTTGTTTTTTTATTTTTTGTTGCGTTGTTGTTTTGGGGCAATGGAAAATTTGTAGCTAAGGGCGCATTTGGGGAATTTATAACTCCATTTTAGTGAGGTCCTTTTCGTTAAATCGCCCAGGAACGCTCGTCCTTTTTCCATGATTTTGACCTATTAAGGGATGTACACTGAGTGAGCTAGTAGCACCAAGAAAGATATGTTTATGCCAGTGTCGCTTAAGTCGCAGCATTTTCGCACGGGAGGATGCAACGTAATATGTAACGGCTTTATGCTAAATAAAAAAAGTAATAAAAAAACAATTACTAAAAAATAAAATACAAAGCAATGCTATCGCTACATATCAGCTGGCTTACGGAAAATGTTAGCAGGTTTCATTAATTGATAAATGCAAACCAAAGTACGCGCTTGCGGCACGAACTTTATGCAAAATTATGCGTTGTTAAATTAACGGCAGCTTCACGTAACAAATTTAAGGCCACCGAGCAGCTGATTGGGTAGGTAATGAAATATTTCGCAGCATGCAGTTAATTACAACAGTTTAACTGCGTTCGTGTTGCCGGAATTGCGCGGCGGATTCGCATTATTGAATGCAATTTACAAATTCGACTTTCACCTTGGCCTTCATCAGCTATGCAGCGTCAGCGGCGCATCTAGTGTAAATATTGTGAAGCACTCTCATGCAGCCGTGGTCAACCGCAAAAATCTTTGAAACTTTGAAGCGTAATTTGTTGCTGGGGTGTAGAAGTGGGGGGGTTCATTGTTAAGGGTGCCTGCTTAGCTACACTTTAACGGAAAAATATTAAGCATTATCCCTGTGCTTGTCTGCCAAAGGTTAAAAGGCGCCCCTTCAATAATAAATCTATGCACCTGGGTGGGCGCAGCTGTTCTAATATTGAGAAGGTGCCAAAATATGGGAGTGATTGGTCGGTGGGTGTTGGTGTGGGCGGTGCGCTTGGGCTTCATTAGGTTATAGCGGCAACAATTTGCGTGTGCATGCGGCATTAGCTAGGCTTATGGCTCTTGGTCGCGTAGAATATCGATTTATTGCGAAGCTCATAGCTCGAATGTGGTGGGGGTAAGATGGCCCAGGGTTAAGGGATTCATGGGGTTCAGGGGTTTTGGCTAGTAGAGCTGCGCCATATATGCATGAGGTATCGCACATTCAACTAAGCATAGGGCAGGCTAGGAGATGCAAGGTGGCTAATGTGGGGCCAGTGCGGATTTGAAAGATAATAGCGATATGGTCGACACGCAATACTTTCAAAGTAGCGTTAAGGAATGATTGGGCAACTATTCTGAATATGCAGTATTATCTATTGCAGATAGATTATGATTTATATAAATTTTGATAAAGTAGAAGTCAATTTGAGCGGGAAAATATTCTGGTAGTTTAGCTTGTTTAGTTTTTCAGCTTGAGGAGTTAATGCCGCTCCAGGATCCGGGCGAATACGCTAATGCGCCCGCTTACCTCGAAATTTTCGCCAACACTACAGTAGCATAATTGAATTTAGTGTGAGCCGTAGCCGTTCGTGCCTCATTGCCATTCGAAAGCTGGATGAGGTTCAAATTGAAGTTGGGGCATTAACATTTGGACATCGTCAGGAGCGCAGGACATTTTCGGTCACGATGGTGTGGCAGACGTGGCTAAATACAAAATGGGCTACAAGCAGCAGTCGGTACGACAGCCTGCGAAGAAATGGGGGTGGGGCATTTTAAATTGATGTAGCCCAGCTCTTGAGGTCAAAACCTTTCACGGATTGCTTTTCAGTGAATGCCTACACACGAGATGTTGTGCATACATTAAAGGCAAAAAGGTTTTCGTCTTGTTCGTACAGCGCGCCGCCTGTGTTTCTCTGTAAAAGGCAACGTTGCTTGCTTTTGTTTTGCCGGAGCCTTAGACGGGCTAATATGCAGCGAATTTTGTTATTAATATTCAATTAATAAGGCTTGGCATGGCTGGAAGCGCAGCGGGGCGTGCGCGTTGATAAATGCGAAGGCGTCGGCGAAAGTTTTCCTGTACTCGCCTTTGCGGTTTCCTCTTCGTCGTATGCGGCCGCAAAAAAAAAACAAAAAAAAATAATAACAAAAAAAAAATTGATGCATTTATTGGCCGAGCACGTCTCCGGTGCCTGCTGGCCTCGACCAGCGCACGAGCTAATTTATTAGCTGCCTACTGATGAGCGGCAAGAGAGAGGACATCGTTGCTAGCCAGCTGAAGCACAATAAAATTGTGATTACGATTTCTGACGCCATTTTGGTTGCTGCCATTGGAAGAGTGTCCTTAAACTGTTCGCACTTTCTTGTTTTTTTTTCAATTTAAATAGTATAAATAGCTGGTAATGCGAAAAAAATATGTTTGAAGCTGAATTTTTGTTGAACGGTATTTTTACATCGACTATCTTTAGGTTAGTTCGGCTGCTGTGAAAGTAAAGCTTCCGCAAACTCAAATAAAAAAGGATAAATAAACACTATGACAATCGCGAGGAAATACGCGTGCAAGTGTGTGTGTGTGTGTGTGTGGTGTTAATTTGCTGCTAATTGCTAAGTATGTGTGTGTGGGCGTAGTTTTGCCAAAGAGGAGGAAAAACTTTTTGTTTACGGCCAATGCTAATCCTGGGAATGAAAGAGTATTTGCAGCCGAAAAATTGCTAATTGCGTGGGGATCTAATTAACATAATGTTGGGAAGCACACTCCCACTCCTGTTACCTTTTCTTTTCCTTCTTTTTTTGCCAACGTCATCTTATGACACCTGCAGCTTGTGTGGGTGTAGGTGTGTTCTGTGTATTTTGCTTGTGTGTGTCTATTAGCGTTTTCATGGCATGTGTTTTGTGTCCGCTTTCTGTCTACCGGTTAAGTTGCCGTTTAACAGCAAAGTAAAATACAACGTAACATATGTACGCAGTTTTTTGTGTTATAAAAACTCATTAGGAAGCATCTTAATTATTATATTTAAATTTCAATTATTATAATGCATTTTATTTGATCAGCTATTGAAATTGCTTCGTGTGTTTTTATTTTGATTACTTCTGGATAATAGCATTACATCCTCTTGGCACGCAGAATTCGTAAGCTACTTTGGTGGTTTTTTTTTTTTTTGCACGGCTGTCCCTTTCTGTCGTCAGTAATAGCGTGTCTGCTGCGTCTGCTTTGCTTTTTCTGGTGGCATTTTCAGAGCAAGCGTGCGTTCTCGACAATAGCATATCAAAAACAGTTAGTACCTAAAATAAACCTAAAACTCAAGTTACCTAAGATAAGGGCAGACAAGAACGCCGACAGTCAGGCAATTTAAATTAAAGCAAAAAAAACGCAGGCGAAATTCTGGAAAATGTAGGAAAGTTGGGGGTGAAGGGGGGAGGGGGGGGGGGGTGTGTGTGTGTGTGTGTGGAGAAAAAGAGCACAGAAACGAAAAGGAATGGGTTACTCGTGCAGGGGTAAACGACGTTTTGTTCGAAATTAAAGTGTACGCTGCGCTTGATTATGGTTCTATATTTTCGAAAAAAAAGTACAGGTCAGCAGGCAATTATACGCATAATATGTGCATTAGAAAACCCGATTGCACGAGTACACACTAAATTTTAACGATAACCAACGAGTGGGCTGGCTTCACGGATATGGAACATGCGAGGCGAAGAATTATGCAATGGGCTTAACCAAAAACGAACCCACATTTAACTGCAATCGCAAAAGCATAAGCGAATCCTAATCGAAGGTTAATAAAACCTTCATATTTTCGCCTGGGCTGGCGCACTTCACATAGCTGGGCTGGAGCATATGCGTGAGTGATGTATGTATATTCATGATGCTTGGGACAATAATAAACCAGTGAGCACAGGCGATGGCCAGACTGGCGAAAAGTATTTTAATGTCTCGCCTGAAGTAATAAGCGGAAAGTCGCTGGGGTGGCAGGGGATAAAGGTAAGAAAAAGTTAAGTTCCAATCCTCGCGGTCCGCAAGCATCGCTAAAAGAAATGGTGGAATAATGGTGAAAAATGTGGTGTGGGGGTCCGGGGGGTGTGTGGGGTCTAGAAGAGCTATCGGGGAAGTGGTTTTTCTTATGCGCAACCGGACCTGTAAACCGCAACTAAAACATAAAGTTATGTGTGCAGCGCGGGAAAAATCATGTCAGATCATTTCCTGGTACAAGCTTTTGGCCGAAGGAGCACATGGGGTCCTGCCAAACACTGCGGAGGGGAGGGTGAAAGGGTGGGGGGGGTGGAATTGGGGTTGGGGGCCCTGCCACTCGAGCCAAAGCCGCTTTCATTTCGGCTGGCGCTTTTAATGGTCATAAAAATTTTATTATAAATTTTTTAATAATTTAAGGCAAGCATATTGCTGCGCTATAGCGCAGTAGCTAACCTAAAGTGTTTTTCCACAGTTTTTTCTTTGCCTTTTGTCAGAGCCACCCCCCCCCTCCTGCTCTGCTCGCTGGCTCGGCTGCTCCCTTCTTTTTAATCACTGGCATATACGCCTGCCGGGCATTTGCCGGCTCTATATAATGCCGCGACTCGCTTCTGGGGGACGGACTAAGATACGGAGCGGACGAGCGAAATATGCGGACGAAGTGGTAGGCGCTAGTAGTCGCAGTCAAAGTGGCATATATGCGTAATCATGGCGCTGGTATAACAAGGCATACAGAGGGCTAGGCAGAGGCAGACACACAAAATAACGGGGCGAGTATAAGTCAATCGAGAAGGTACTATATGTACGTAGCTATGTATAGGCAATGGCAATATCCTGGAAAACTATAATGCAGTCCACTACTAGTCTTACTAGTGCCGAGCTATGGGCCACTCGTTTTTTTTTAGTTTAGGAATGCCATTATTGCTATACTGTTTTAAATTAAAAATAAGTAGATGGGAAATCAATTTGCTTTAAACTTATGCGTGCCTTAGTCAAATAATACCCTTTAATCATTTTATTGCGCTAAGTGTAGAAACCATGAAAGCAAAAGCAACAGAAATAGCAAAGGATAGCTCGGCCGTATATATAGCTATAGCACGCAGCTAAAGCGATAGTGATAGCGGAATTGTTCGGATATATGTATGTATATGCTGTCCGCTTGCGTGCGCGTTTCGTTTGGCGTTTTAAGCCGCGATTCGAGGGCGTTTTCAGTCGCGTTTTGTCTATTTTGCGCGCTTTTTCGTTTTCCGTTTATTGGTTTTCGCACCTTGTTTTGTTTTTTTTGTTGTTTTTTTTTGGCCCTTAGGCGCAAGGTGGTGGCCCAATTTGATGAATCGTTAGCATTACGGGCCAGTGGCTTAGATGGCGAAAGTAGATATATGGCTGGTAAAAACTGGGCAACTCCTTCCAGACTGTTTCAGAGGATGTGGCAAAAGGGAAAAAACAAGCTTCAGCATGTCTCAACGTTGGCGACCTAACTCGATAAGGAGTTTAAATTGTTTTGGGCCTAGCAATTGCATGAAACTTATATCGTATATAATATGTACTATATGCACCAACAAAGCATATTTAATTCTTTATTTTCATAAGTGTGAATAGCTTAATTGTACTTGCTGGCTTTAAATATTCTGCGCGTTGTAGTACCGGACTACAATAAAAAAAAATTAAAAAAAAAAGAACTGAAGGGGCGAGAAAAATCGAAAGGCGCTATAACAAAAGCCGCAATGCCAAGGGCGAAGCAGGGCAGGCTGAGCAAAGGGGATGAAAGGAAACTAGGGGTGTGGTCCTATGTCCGTGGCATATGTCGCATTACAAATGTTTGGTCGGCCTGTTTGTTTATGGGGCGCACATTGCAGTCGTAGGTAAAATGTACACGAAACCGGCTAAACGGACAGTAAAAAATAAAAAAAAAAATTGAACAGAGCAGTAATGTGTGAATAAACCAGCGTTCAGAATATCGCATGGAGAATATTGTGCAAAACGGCTACAAGGCTTGGCAAAGTTTGCAACGATAATTTTTAGTTTTAGTGAGTAGGATTGCAAGTGAAAGAACGGTAAGCTGTTAATAGTTTGTAGTAAGAAAATTTGGGGACAATGATTTACATAGTATTTTTTTTTTTTAGATGTATTCTTGGATGTCATTTGTTTGTTTGTTTCTTTCGGTGCACAATAATGCAGTAGCATTCACGGCTTTAGGCGGCGTTGCAGTTGCAGTCCGCTGCAGTTGTGGTCCCCAGAATCGCTAGACAGCTGACAAGCCGACATATTTTCGCTTTCGTAATTACCAGCGTTCGCCCCGAACACATCCTCTTACACTGGCTCTATTTTATTTGGCTTAATACTTGACGCGCTACAAACCCGAATTTCATTGCATTCGTTTGACAAATGGCTGAGAAGTAAATAACAAAAAAAAAAAAAAATAAATCCAAACGATAGAAAAAAGTAAAAGGTGGAACGGTCGAAAAGAAAAGGGGATTTTAAACAGTCGGTTATGTCGGCATTTTGGCTAGCGACCTCGCTTGTAATTATATTTTTTAATGGGCATTGCAGCTTGGCAATTCGTTGCATTCATTGCGAAAAAGCTGCAAGCTGTAATTCATTCCAGGGAAAATCGGCAATTAAATCGCGAAAATAAAGAGTGAAAAACAAGAAGAATTTTTAAGCAGATTTTAACGATAATGCTAACTGTTCTAAAGTCACTAATCCAATTATACTACTTATTATTCATTATTAATAAATGCTAAGCCTAACTTTTATATTGCAATCTTCGCATTTCTTTCAGGCTGAGTTAGCACCATTTGCGCTGGAAATGAAGCGAATGCGCAGCAGTCGCCCTTCGCTGGTTGAATGGGCCATTTGATCGGCTTGTGGCTGAATCTGACGCTGGCTCCTGCGCAACCGATTGCCGGTGCCACGCCATAATCGAAGAAGAACGAGTCCAGCGCGAGAGCTCCACGCACGGTGACTCATGCGCTCCTCTCCTGGCATTTTCCTGGCATGCCTCGTCGAGTTGGCTCGTCTACATCGGCGGGCAGTCATCGTCAGCGAAATGATGAAAAGCAAAGCCGATAGGGCCGGCGAAAATGTGGTCTTAGGAACTTTGGGCCATGGAGGGCCGTCGGATCAGACCCGGCGTCGTTGTTACTCGTAACGTTGCCATGCTCGGGTTATGGAGATAAGTTGGTGCCCTGCGAAATGGACGGCAAAGATGAGCTTCGGTGCTGGGCGCAAATCGCAATTTGCAGCGCTTGAACGCTACTGTCGATGGTCGGCAGCGATGTAGGATGGGTTGACTTCTGACATTGGACAATTTATCGACGCTAATGCTGGACGAAAACGATGCCAAGTACAGTGTCGATAGTGGGTCGCAGGTCACAGGCGAGCAGGGGTATTGCGTTCGCTGATTGGCGCGGCAAGCTAACCGTTCTCCGTTCCGGCAGCGAGGCGGGTCCGAAATCACACAGCAAGGTGACTATGCTGGTGCCGGCACCGAAGATGCGTGGAAATCGAAAATTGGAGTGCGTGTCGGCCAGGCGGCAAGCGCCGCTAGACCGAAATCACTGTGATTGACGGCTGGGCTAATGTGCGCTAACCAAGGTATTTGAAATATGTAAGGAACGCGCTGGCTCGATTCGCAAGTGCGATTACAGCCAGACTCGTATACTAGAATATTGGCGGCCGCAAGAAGGAAGCATTCACAACAGCGAGCGTTTGCACGGTGCGGCAGGCGCAATAAACGCGCGCGATGCGAACCTATAGATCGGCCAAACTGGCTGCCTGCGAGGGTGAAATATGGCGCCGGCAAGGTCATCGTTTCGGTGTGGGTGTGCATTGGCTGGTGGCAAATTCCGAAGTGCGCGCGAGGTAATACTAAGCTGTGCAGGCCGACGAGCCAATCCGCGATGAGCTCAGGCTTATCGTTGTTCATGCAACGATGGAGCTATATGACGTGCGGAGACTTTACCACTAGATTGGTAAGTGCATCAAAAGTCAAATAGGAAAAGCGGCTAAAAACGCAGTTGTTAAAGTTGCATGCGATTTCCTTTCAAGATGCTTAATTACAATGTTGCGAGCTAATATCACGATGGCCATACGTCATAAGTGCGAGTGGTTAATGCGGTGGGCGAAGAGCGAACAGAGGGCTAAGACACTGGACATATTAGTTTGTATAGTACTGCAATGGCCTATATATGGTGAATGATAGTTACAATGCCATGCTAATGAGATTCTACGTTTGCCTATAAAGCAAAGCGCAGTTGGTCATGCTAGTTTTCGGGCGCAGCGTCCGCGTTAGGGCGTGGATAGCGCGATCTGGCGCCACCGTTAGCATGCGTTGCGATGTGGCTGGCAATTCGCGGAAGCCTGTAAATCGAATGGATCAGCGAGAACTCCGCTCAGGTGCGTCAAAACTTGCGTTCTGGGGCTAACTGAGCATTCAAGTTAGCATATTCAAATCTCGGCGGCAAGCGTTGTTGGCGTTGCAGCGGAACTGAAATTGAATAGTGAGGCAGCGAAAGGCGGCAGGTCGCTAGCTGTTGAAAGGCTGTGTAATGGATTTTCCGCGAAATCGGTGCGCGAGGGCATACGCTGATAGTGTGAAAAGGGGCACGGCGGGATTATGCAATGCGGCAGCAAGGTGCATATTTGGCCGGAGTGGGGTCGGTTTAGTAAGATGCGATTGTTTGGCGCTTAGCATACGTGGCGAAGGGCGGAGCATATACTTGGCTGTCGTTCGAATGGGCTCAGAGCAATTATCAACTATGAGCAGCGCGAATGCCGATTATATATATATTCGAGAGGGCTATCCCATTTGCTCGGAGGGCCGTGCGAGCGGCGCTTGATTATTCGCGATAGAAGGCGACACATTTTGGCATATACAATTGTATCAGTGTATGATATTCGTATGGCGGTGATTCGTTGTTTAATAACATATGGCTACGCGAACGCGGGCAAGCATAGCCTGCGTTCTGCTGGTCGTTTATGGGCTGCCATGTTTTTTGTGCGTGGCATCATTCTTGATGACCTCGTAATGATTATTATGCTGTGTAGCCGCAGCGAGCGGCCCGTCGCAAGAAGGCCCCCATGCCCAGCGATGTCATCCGGAGGGCATCACGCGGCGGTGATAGCTTAAACGAATTGAAGATGGCGAGCTACGCTCGAAGGCCTTTATGATGTGGAATACGTCGAGCGGGCGGCGATGGACTGGCCAATAATGCTACCATGCAAGCGTCGATGCCCGTGTCAGATGAAGGGGGCCATCACTTGTGTGCCACTAGCCGGACCCGTTAAGTTCGTATGAGCGCTTTTGCGGGCGATTTCGGTGGCGATCGTTACAATCGAGCAGTGTCACATTAAGGGAATCTAAGAATCAAGCATGGAGACCGCCTACAAGGGTTAGTGCCACAGGCGCATGGCTATATGCCCATTAGGTTGAATATGCCGCTCGACTATAAGTCGCGCGGAGCGTGTGAGGGTGCTGGCGTGGTGTGGCAGCGGCGGCGTTGCAAGTTGAAGAAGCGGTGGCAATGAACTGCGGGCCGACGTTGCCGATCGGCAAACTCGCGGCTGCGCACCGTGAATATGGGCGTGGCTGGCAATGGGGGCGGTGCAGTTTGCCGCCGCGCATCAGGCGCAGCGAGATTCAACTAAGTCGCTAGGAATGCAACGGATTTCTCGGTGAGTTTAAATCTATAATATAATATTAGTATATATATATTTTAGGGCAATGAAGACTGTATTGATGGATCTTTACGACTTTCGGCAGGAACAACGGTCGCTGCTGTTGCAGTAATGGTGATCGATAGCGTTTGCGGCGCTATCTACTGGTAATCCCTATTTAAGGGACGAAGCTCCTCGCTAGTAATGCGCGCGCCTGCGCGGCGTGAGCACGCGCAATCGCGCGCGCCTAACGCCCGCCCGCCCCCTAATTCATGCCGGCTCGCGGCAGCGGCCAGCCGCCTCATGCACGGCCAAGGCGGACATCCAGGGCATTTGTGGGCGGCGCTGTGGATCACCACAGTGCCCGTGGATGAATGTGAACATTAATGCGGGCGGTAGGCGGTGGCTGACGCCGCATGGCGGTGGCGGCGGCGTGGGCGGTGTGGCGTTGGGGAGCTGGTGGGCACGTCAGCGCAGGCAGTTGCCAACTTGACGCCAGGCAGCATATCACTGCGGCGCAGGCCCCTAACGCGGGCGGGCGGCGTCGGCAACGAGCGGGCCAGTGGCGCCAGAGTCCGTCCGGTTCAGTTTTATATGTCGCATAATGGCAAAGGACACACGCAGTAAAAAGGACGTCTGCCAGCGTCATGGTTTAAAGCTACAAAGATAGATATACACAAGCAGCATCTTTTCTATATTATATATACTATATAGTAGAAGGCATAGCATAATGGCATGAAATGTATTTAAAAGCCGAACTTAGTGTGTAAACTTTTTTTTTGTCGCTATCGAATATTAGCGTATATTATTCTGTTCAAGCGGTGTGCTGAACTTTCGAAAAGATGCTTGAGTTGTAAATGCAACTGACTTGGATTTTATGCTGATATGGCTGAAATTCGACAGCTCCAGAATGTGAACTGCTTTCGTTTGTAAAATTTGTAAGGGTACAGCTCCGCAAATAACAAAAAAAAAGAGAAAAGAGTTCAAGCACATGCCGCTTGAGTACAAAAGGAATGTGTATCAAAAACGAAAAACAAAACACCAAAAAAACACAGAAGAAAACAATAACCGTATTGTGATTTATATGTATTAGGCGTTAATTATTTTAGATGGCTGAGCTCGATGAGTTTCGCAAGGCGGCAAATTTTATCACTAGTGGGGCTAAATCTTTTTAGCTAGCTTATGCGAGTAAAAAAATCGTATATCATTAAATCACGAAACGGCGTATCGAAAATGAACAAGTAATGTAAAAACCCAAAAAACACAAAAGCAACTACAAAACTTGAAAAAGTTTCATGTTTAAACAGCGTGTTGCAATACAATTTTAAAACGGAAATCGAATCAATTCTAATTATATGACATTATGACAAAACAAAAGCCTGTGTAGTTAGTTGGACAGCTATAAAAACAAAGCAAAATAATAAATAATATAAAAAGCAAACGAAAAAATGACTAAGTAAAGGCAGCAGCTAGCAGAAAGCAAAACTAATTTTTGCTAAGGCCAAAATTTATGCCCAATTTTGTTAGACATTAATTACGTATAGCATCATTAACGAAACGGCACTGAAATGGCAGTGAGAGAAAAATATTTAGTATTAAGGTGGCTGTGCTTGGCATCTGTGAGCGCCGGTCAAGAACGAGGCGCTAAAAGTACATAGTATAACTATTATTTTGGCACACAAACAAACTAAATTGAAATGAGATTGAAAACTATATTTTTAACGGGATGCTACGTAATTATGTGGCAATTTAATCGATAATGCCGCCATAGCCGCTATAAAATACTAAACAAAAAGATGTCGCAAAATATTTGGTGATTTAGGCGAGTAAAGTGAATAAAATTAGAAAACCTAGCCAACATTATTATACTATATATAATATATATATAGTTGCCACTTTCCAACTTTTTGATAGCGGTTTTTTGCAGTGGGAAGCATCTTCAGCATCCATGGTGGAAAAGTTGAAATATTTTTTTGTGCTTAGCCTAAGCGCGTAAATGATATTTGAAGCTTAAATCATTATTATGTAAAAGAGCTAATGAAATATTGTATATCGTATTATATATATATATATCATATATATAGACATAAATGTGTATGTCAACGCTATGAATTAAAAATGCTAGGCTAAGATTAGAGAGAATGTTTGTATATTTTTTTTTTTTTGTCTGCCTGAGTTTAGGTTTAAGGCTATTTATAGAACGTAAATGGAAGCATTTAAAAGGTACAGTAAAACTTAAAAAGCTTCCAGAAAAATTGTAAAACCATTTGAGGCGATCTACCAAAAAAAAAAAAACGCAATTGAAGTGTAAAGCGTTATGTTTAACGGACGGAAATATGCTGGGCCTTATGATTCCTCGTTGGGTCTTTATTCACTAAGGCCAATACTAGTATTATTAATTAACTAATTTATTGTTTGCATATTTTATTTTTTGTTTTTTCTCTTTCGAAAGAATATACATATGTATGTATTTATTCAAAGTAATTGCTGAAAATGCTTATAATAATATGCCGGTTCGTTAAACTGATTTATAGGCACTCGGAATCTAATTCTTATTTTTCCGTCGGCTGCAATTGCGCGAGCTTTTTAACCTTGGGATTAGCGTTCGATAAATAAGAGATAAGTATGGTGTTACATATTTTTTTTTGTTTTTCCGATAATTGTCAATACGATTCAATTATAGGCGTTCAATTATATAGGAGCTTACACACGAAAACGAAATAGAAATTCAAATGAAATCGCTATTAAGGCCTAAGTAGTAATGATAATTGCAGGAAGCGGAGTTGGCGATAAAGAAAGGTACGGAAAAATGATAAATAAGAAGCGTATTGGGGGAGTAAACTAACATAAGTCGAGAACAAGCTCAATATTAAGTTGAGAATAAAGATACGAGAACAAAAGGAAAATAAAATACTTATAAATGCTACACGAGTGCGTTTTTGTCAATCAAATTTATGGGCACCATTTTTCCAAGTGCTAGCAGAATTTTACATTGTGCGAATTTAACATTATACATAGCGTAATTTCTACGAATGGCTACATTTGTCGTAATTTTTAGCACTTTTACGATCAGCGTAATTTCTAGCATACGCGGCTAATGTACGTGCCCTAAAGGGCGCCATTGTGCGAAATGGGGAATAGCTACTCATGACAAGCGGCTCGGAGCCCGGCTTAACGTTATTTGTTCAGCGTGGCAACCGATCACTGCGCATACGCTGCGAAAGAGCGCGCTGCCAAATGGCTCGCCCGCGCCGATACGGTATTCTTTTTTCTTGCACCGACGCGGTCACACTGCCGATTTGTAAGGCAGATCGCTTTTTCGGCCAGTGAGCGAAACGTTGTGAAGCGACGTAGCGGTTAGCAGACGTAACGTGGATAAGGCGCAGAGCGACGAGTTGTTGCAAGATTATATTTTTTTTTGATGTGTGTGCTATAAACGCAGCGTAATAATCGCGCTGCCGAACAGGATATACAAACAAATCGAATTACATCAAGCAGCCTAATGCATGAAATGAAAGGATGGCCCGCAAGCGGTAAAAGCGTGTTCAGCTAAGTTAGCTTTAAGGAGTGCCTGTCGCAGGGATAGCAACGGAGAGAGGGGCGACAGCAGAGAGCGAGAGAGAGAGTAGGATGAGAAACAGGATTATTCGAAAGTGTATGCTACCTCGAGTGCGCGCAGTTGTGGAGGAGTGAGACGAAAAGCGCGAAGTGCTAAGAATGCGCTAAATGAGGAAGTAGAGCAAATAGCGCTATAGCGTGCGGCGTCGGTTTGTAATTTGAATTATTGTGGCTCGTATGCCTCGCGATAGAGAAAAAGCAAGCCATAAAAGAATACACGAAAAAGCGTTCTTTTTTTTGCCACTTTTTTTTTAATGTTTCGAAAACACGTCGAGCGGTAAATATGTCGCCGTCGTCGGGAGAGTGCTCTCTTAGTTTATCACAATAAGCTTTAAAGTCTGAAGTTCAAAAAGCTCATAAAAACAAGAAACAAAAAACAAAAAACAACTAACGCGCTTAAACAAAGTAAATTGGGCTTAACTAGCTGAGACATAAGCATACTTAACACCTAAAGCTCGCAGTTAAAGCATATCCTCAAAGAGAGACGGCAAGAGGAGGGCGGCTAAAGAAAGCGTAGAGCGAGTAGAGGTGAAAAACTGGAAAAGTGTTAACTAGGAAACTGGATTATCAATGCAATGCGCAGCGCAGCCTAGACGTCGCAGTCGGCGCGACCAAACACATTGTAGTTTTGTTTTGGGATTAACAATAATGCACGCCGTTGGCGTCGCTAGCCGCGTGGCTGACTCTGCTGGCTGTTGACGCTGGCTTTGGCGATTTGCGAAGAAACCGTTCGCGAGGAACTGGTTGAGTAAAGCGAGATCCGCCGATCAGACAACCTAGCGGGGGGAGGGCAGGGTGACATGGGCGGGGTGCGCCCGAAATAGGGTGGTGCACTAAACTGGATTCGCAAGGAGCTCAAAAACGTTTCGGCAAACGCCTTGCCATATAGAACGGTTTTTTAACAGAACCAAAACTATGAGATAAGATGATGATTGTATAGGCTGAAGATGTGGATGTCTCACCCTAATAGTAAGCTGAATCGCATCCATTGTTTTGGTCTTAGATGTCAGTTTTACAATGGTAGCATACTTAAGTATGAAACATACTAAAATTGGTGCAGATTAAAATATAGCCATACATTTGCATGGACTAGTTCCGGCTTAAACCGCGTTGGATAGATGCGCTACAATTGCATAGCTCGGAAATGTTGTCTATAAATTCGGATGCTATTCGCACACATATAAGTGACTGAGCAAAGCCATGGACCAATGGTAAATCCAAAAAGGAAGTGATGCTAAGCTGTTAATCTGGCTAATAAGCCTATAGGGATTGTTGAGAATCCTACCTTAAAGAATTTCACTTACAACGGTTCGCAATTCGTCGCATGCGCGCGCTCCAAATGCGTTCTCTGTGTTTGCTGCGCATTCGCCTTTTTCGAGTCCTGTTCGTTTGGTCTCCTTTTGGGGGCAGCTCCTTTTGCTTCGCTCTTGGGCGCTTGCGCTTTTCATAGCTTGTATTCAGCCGTGTGCTTTCTTTTTGCGGCTGTCTTCTTGGCTTCGGCATTGTGTCCGCTTTTCGACGGTGTCGTTTTTTTCCTCTCTGCATTTCTCTGCTTCTCTCTCTCTGTTGTGCCTCGCTTGATGTCGTTCTGCCGCTCTCGGCTCGATCGCTGTCCGCTCGTCGTCGCTCTGGCTTCCGCCGATGGCTGCATGCTCTCTCAGATTTGGAAACCAGCTCTTTTTCGAAGCAAGAAAGAGAGTTTTTTACGTCGGCTAAAAGGCGAGTTTTTTCCAATTCCGTCTAGCACTGGCATAGGCACTCTTTCTTTGTGTTTTTGCACTGCGCTATTGCTCGCTAGTAGTGAGTGGCGGCCACTTTCCTGTTGCCAGCTTTGGAAGCGAACTCTCCTAGCCTCCACTACCCGCTGTGTTAGTGCCGCATGCACCCAACTGGGGCTTAATTGGGTATGTTGCATTATGGAGCGTTCGTTTGTGCTAATCACTGAAATCAACACAGAATGTAATGCGATGCGGAATCGGATCGGTTGTAGGTGTAGCTTCGGGTGCGATTGACCGGCCAGTAAAATGTTCCACTTTTCGCCTGTAACTCGAAATAGCTCCTTCGACGGAATTCTCGGCTCAACGATGAGAAAGTATGGGGAATGCAGCTCGTATATCATAGTATTTATGACAAATTTGATAATGTCAGAGAATTTTTTGTTGTTGCATTATTCGATAAATCTATGAAATCCATCAATGCCATCAAGCGTTTAAAAGCAATTAAATGATCATTACTAGAAAGTTTTGAATGCCCTGAGCTACGTGGTGGCAATCTTTTATTATTACGCACAGGGTCGATGATCTCTGCTATTTTTTTTATATTTTTAATCGAGCTGCAACCGAAGAGCGTTGAAAGCTATTATGTTTATTAACTTTTACGGCTGGCATTTCCTGAGCTGCGAGTTTCCGCTCATAAACTCCTTTTTTTTCTGGCTATTATAGCCATGGTAAGTCGTGTGATTCTTTGCAGTTTTAGCGCAGAAGGAAGTTGTATGTAAAAGTTTAATAAATCGGTATATAAAAGTTAGCAAATGCATATGCATTATAACAGGTGAAAAAAAATGCTGAAGTAGTATAATAAGAGTGTTAATTTTGATGCAGGATTATATTGGGGCAAAAGACAAAGAAGGGCATCCTATTGCATTGCAGTTCTACTTGCAGAGGTGTCTACTACTGCGGGCTAACAGAAAAAGTGTTCGAGAGATGGAAAAAAAAAACCAAAAAAAAAACAAAAATCTCTGCGATGCTTGCAATGTAGCAATTTTTGTAACCTATTAAGTTCTCACAACTTTAACGCCCGCCATGTGCAATGCCATAAGTTTGTTCAACTTTGTGGAGTCGAACAGCCTGCATTTAGCCACAAATTTAGGGTAATTAATTTTTTTGGGGCAGGTTTAATGTGGCACGTACGGTTTCGAAGTAAAGCGAGACGCGAGAACCAACGCACGACGCATTCGATTTTCATCATATATGTAACACGAACCAGAGCGCATAATAGAAAGAATGTGTTGGAATAAAACGACAGCTGGGGCTCCTCGGAGCCAACCAGTGAATAGCAGCAGCAGGAGAAAGCATAGGAGCAGCGAGAGGCACGCCCTTGAGTCCTGGCATATTGCAGCATGCGCTCCTTTTTGCTGTTTGTTCACAGCTCAAATTACGATATGCTATGGCATTGGGCATCGCAAACGGCATGGTGTTGATTGTTTGTATGGTGAGCGAGAAGGGAAATGAGGCGGCAATAGAGTAGTAGATAACTTTTGTATCTGCGGCGCTCGTGTCTCGGCTATTTGCCTAGTATATCCTGTGGCGCAGCCCAAAAGCAAGAGTAAAAGACGAAACACGGTGTGTATCGCGTACGACTGGCCCACATTCTTGACTTTTCGTACAGTCAGCGCGCACACGGACGGAATGCCCTATTAGGCGCCTCGCGGCTAGACTTCAAGTCAATATAAATATCCTACATAAGTAACTCTTATGCTATGTACATTATATTACGTATAGTATGTTATGTAGGCTTCTGGCGGCATGAAGTCGGCCTGTATGGCGATGCAATACGCAATCATGCTCATGGTTATGGATCAGTAAAGTGTGCACTTTTATGGTGCGCATCATGATCATCCAGCATTAAAAGTTGCTGCAACCAATTTAATGAATATATAAAATTTAAGAGGGCGAATATGGAGGAGGGCAGCTTAAATTGAAGATGCACTAAGAGATGAGGGTTAGCATTCCATTAATTAAGATTTATGTCTTTGAAAAGGAACGAGTCCGCATGAAAGTCAAAAGCTAGCACGCATAAGTTAAATCCTGAATAATACCATACATCTATACATTTGAATAAATAATGCACTTAAATGATGCATGTAAAGATGTGAGAAGCAATTGTAAGAATGCTTTCAGTTAGTGAGTAATAAGCGCAAGGTAGTCATGTAATACTCTAACTCTACAATTGAATTCGAATCTGCATACGGTTCTATTCCATCAATATATAATAACTTGTAGGATGTATGTCTGAGATGCATTTATTAAGCACCTAAAGCAAAAAACAGGCGCAATTCCACCGCATGCTAAACCCATCTTCGCAAGGACGCGCAGCTTAAAACGCAGATTATTGTGCAAGTATCGTCATATTTGGGCGTTCTTCAATTCATTTGAGACACGGTCACTTATTCGACCATTTAGCTGTCGCATTTATTAATTATTGAGATAACGTCCGCGCGAGATGGCGCAAGCAGGGAAAAAAAAAAAGCGGCTAAGGAGTATTCAGCTTGAAAATATAACTTTGGTCCAATTGCAGTGAATTAAGAAGTACGACTTAATTAAAAAAGTATTCGTAATATGAAATCGGCTAATTTCCTCATGTGTTAAATGCTGCTGTTTACCTCTTGCCTTTCCGGCTTGGCCAAAATAAAACAAAAAACAAAACGCTGTAAGTGATAAAGTAAACTTAAAAAAAACTAAATAATAATATAAAAAGAAAACAAAGTAAGGCAGTAAGATGTCGAGGAATCTTGTTGGCTGGTCAATTGATACTGGGATTGGTGATATGCGGCAGAGCAGTTCGGGCGTTCCGTTTCGTTCGCAGACGATACCGATGTCGATGGCTGCGTATCGCTGTTTTTCGGGAGCTACACCTTTGAAACCAGAATTGCAAGGCTTGCTTGCAGGTAGATTTGCATATGGCAATAGTGCATATGTTGTTTCTCTCAGGGTAATCTTTGGCTGCTCTGCGGTAAATCCCCAATGTTTTTGCGGCTCCTTGTCTGGCGATGATATTTGTTATTTGTTCCCATAGTCATTATGCATCAACATGAAAATCTTTTCACGCAGCCTCTTTCTCGTTCTCTTGCTGCTCTGTGCTTCTCTAGTTTGATATTAGTGTTGACAACTACTTTCAAGTTTTTTGTTTGGGAAAATGCGCTCAAATGGCGCAAAGAATGAATTGAGGTTTTGCTTCTGCTAGCAGATATGTATGTACTGTTTTTTGCTGGCCAAAATAATTTGAAAACAGTCCTCAGCATGTGTCGGCTGGCATTAAATGCGTTTAAGAAAAATCCATGGATTGTATGGATTTAAATCTCAGCTGTCTTGGCTTGGCTTCGGATGGATCTTAAACTTGACTGTGGCTCTCCTAACACTACACTCTACAACTGTGCTTGCCATCTCTCGGCTTTTTATTTTGACTTTTAATGATGGCAGCTGCGAATTAGTGCGCCTGACTTACCTCTTTCTAGGCCTGATGGGCCTAGTTAATGAGTTTTCTTTATGGGCCAACAGCATGTACCTTTTGCGAGTCGTAGATAGCAGGTACTCACCGACAGATAGTATTCGAGTCAAGATACTAAGATACACCAGCAGAGACGAACGAAGGCGCACTGACCGAACAAGTTTTTTAGTTTTTTTTTTTTTTTTCCTTACTGTTTTCTTGGTTTTTGATTGGCTGGTCTCTGTTGGTCTTCTCTGCCTTTGTGTGGCTTTGTCTCGCTTGAAG ================================================ FILE: test_data/t2.fofn ================================================ ./t2.fa ================================================ FILE: travis.sh ================================================ #!/bin/sh # -e: fail on error # -v: show commands # -x: show expanded commands set -vex #env | sort mkdir -p LOCAL export PYTHONUSERBASE=$(pwd)/LOCAL export PATH=$PYTHONUSERBASE/bin:$PATH git clone git://github.com/PacificBiosciences/pypeFLOW.git cd pypeFLOW git checkout origin/develop pip install --user --edit . cd .. make install make test