soapdenovo2-240+dfsg.orig/0000755000000000000000000000000012166705361014203 5ustar rootrootsoapdenovo2-240+dfsg.orig/standardPregraph/0000755000000000000000000000000012166705341017472 5ustar rootrootsoapdenovo2-240+dfsg.orig/standardPregraph/kmerhash.c0000644000000000000000000003021412166703654021445 0ustar rootroot/* * kmerhash.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #include "def.h" #define PUBLIC_FUNC #define PROTECTED_FUNC #define EDGEIDBLOCKSIZE 10000 #ifdef MER127 static const kmer_t2 empty_kmer2 = {{0, 0, 0, 0}, 0, 0, 0, 0}; //Get the hash key. static inline ubyte8 modular ( KmerSet2 * set, Kmer seq ) { ubyte8 temp; temp = ( seq.high1 % set->size ) << 32 | ( seq.low1 >> 32 & 0xffffffff ); temp = ( temp % set->size ) << 32 | ( seq.low1 & 0xffffffff ); temp = ( temp % set->size ) << 32 | ( seq.high2 >> 32 & 0xffffffff ); temp = ( temp % set->size ) << 32 | ( seq.high2 & 0xffffffff ); temp = ( temp % set->size ) << 32 | ( seq.low2 >> 32 & 0xffffffff ); temp = ( temp % set->size ) << 32 | ( seq.low2 & 0xffffffff ); temp = ( ubyte8 ) ( temp % set->size ); return temp; } #else static const kmer_t2 empty_kmer2 = {{0, 0}, 0, 0, 0, 0}; static inline ubyte8 modular ( KmerSet2 * set, Kmer seq ) { ubyte8 hc; __uint128_t temp; temp = Kmer2int128 ( seq ); hc = temp % set->size; return hc; } #endif /************************************************* Function: update_kmer2 Description: Updates the id and flag of the kmer. Input: 1. mer: the current kmer 2. id: the id of edge 3. flag: the type of kmer(00: big "to kmer"; 01: big "from kmer"; 10: small "to kmer"; 11: small "from kmer") Output: None. Return: None. *************************************************/ PUBLIC_FUNC void update_kmer2 ( kmer_t2 * mer, int id, char flag ) { struct edgeID * edgeid; edgeid = ( struct edgeID * ) malloc ( sizeof ( struct edgeID ) ); edgeid->edge = id; edgeid->flag = flag; edgeid->next = NULL; if ( mer->edgeId ) { edgeid->next = mer->edgeId; } mer->edgeId = edgeid; mer->count++; } /************************************************* Function: set_new_kmer2 Description: Initializes the new kmer. Input: 1. mer: the point of the new kmer 2. seq: the sequence of the kmer 3. id: the id of edge 4. flag: the type of kmer(00: big "to kmer"; 01: big "from kmer"; 10: small "to kmer"; 11: small "from kmer") Output: None. Return: None. *************************************************/ PUBLIC_FUNC void set_new_kmer2 ( kmer_t2 * mer, Kmer seq, int id, char flag ) { *mer = empty_kmer2; set_kmer_seq ( *mer, seq ); update_kmer2 ( mer, id, flag ); } //Whether it's a prime number. static inline int is_prime_kh ( ubyte8 num ) { ubyte8 i, max; if ( num < 4 ) { return 1; } if ( num % 2 == 0 ) { return 0; } max = ( ubyte8 ) sqrt ( ( float ) num ); for ( i = 3; i < max; i += 2 ) { if ( num % i == 0 ) { return 0; } } return 1; } //Find next prime number. static inline ubyte8 find_next_prime_kh ( ubyte8 num ) { if ( num % 2 == 0 ) { num ++; } while ( 1 ) { if ( is_prime_kh ( num ) ) { return num; } num += 2; } } /************************************************* Function: init_kmerset2 Description: Initializes the kmerset. Input: 1. init_size: the initial size of the kmerset 2. load_factor: load factor of hash Output: None. Return: The initial kmerset. *************************************************/ PUBLIC_FUNC KmerSet2 * init_kmerset2 ( ubyte8 init_size, float load_factor ) { KmerSet2 * set; if ( init_size < 3 ) { init_size = 3; } else { init_size = find_next_prime_kh ( init_size ); } set = ( KmerSet2 * ) malloc ( sizeof ( KmerSet2 ) ); set->size = init_size; set->count = 0; set->max = set->size * load_factor; if ( load_factor <= 0 ) { load_factor = 0.25f; } else if ( load_factor >= 1 ) { load_factor = 0.75f; } set->load_factor = load_factor; set->iter_ptr = 0; set->array = calloc ( set->size, sizeof ( kmer_t2 ) ); set->flags = malloc ( ( set->size + 15 ) / 16 * 4 ); memset ( set->flags, 0x55, ( set->size + 15 ) / 16 * 4 ); return set; } PROTECTED_FUNC static inline ubyte8 get_kmerset2 ( KmerSet2 * set, Kmer seq ) { ubyte8 hc; // hc = modular (set, seq); #ifdef MER127 hc = modular ( set, seq ); #else __uint128_t temp; temp = Kmer2int128 ( seq ); hc = temp % set->size; #endif while ( 1 ) { if ( is_kmer_entity_null ( set->flags, hc ) ) { return hc; } else { if ( KmerEqual ( get_kmer_seq ( set->array[hc] ), seq ) ) { return hc; } } hc ++; if ( hc == set->size ) { hc = 0; } } return set->size; } /************************************************* Function: search_kmerset2 Description: Search kmer in kmerset. Input: 1. set: the kmerset 2. seq: the kmer 3. rs: the record node Output: None. Return: 1 if found. *************************************************/ PUBLIC_FUNC int search_kmerset2 ( KmerSet2 * set, Kmer seq, kmer_t2 ** rs ) { ubyte8 hc; // hc = modular (set, seq); #ifdef MER127 hc = modular ( set, seq ); #else __uint128_t temp; temp = Kmer2int128 ( seq ); hc = temp % set->size; #endif while ( 1 ) { if ( is_kmer_entity_null ( set->flags, hc ) ) { return 0; } else { if ( KmerEqual ( get_kmer_seq ( set->array[hc] ), seq ) ) { *rs = set->array + hc; return 1; } } hc ++; if ( hc == set->size ) { hc = 0; } } return 0; } /************************************************* Function: exists_kmerset Description: Whether the kmer exists in kmerset. Input: 1. set: the kmerset 2. seq: the kmer Output: None. Return: 1 if it exists. *************************************************/ PUBLIC_FUNC static inline int exists_kmerset ( KmerSet2 * set, Kmer seq ) { ubyte8 idx; idx = get_kmerset2 ( set, seq ); return !is_kmer_entity_null ( set->flags, idx ); } /************************************************* Function: encap_kmerset2 Description: Enlarges the kmerset if necessary. Input: 1. set: the hash of kmerset 2. num: the element number add to kmerset Output: None. Return: None. *************************************************/ PROTECTED_FUNC static inline void encap_kmerset2 ( KmerSet2 * set, ubyte8 num ) { ubyte4 * flags, *f; ubyte8 i, n, size, hc; kmer_t2 key, tmp; if ( set->count + num <= set->max ) { return; } if ( initKmerSetSize != 0 ) { if ( set->load_factor < 0.88 ) { set->load_factor = 0.88; set->max = set->size * set->load_factor; return; } else { fprintf ( stderr, "-- Static memory pool exploded, please define a larger value. --\nloadFactor\t%f\nsize\t%llu\ncnt\t%llu\n", set->load_factor, set->size, set->count ); abort(); } } n = set->size; do { if ( n < 0xFFFFFFFU ) { n <<= 1; } else { n += 0xFFFFFFU; } n = find_next_prime_kh ( n ); } while ( n * set->load_factor < set->count + num ); set->array = realloc ( set->array, n * sizeof ( kmer_t2 ) ); if ( set->array == NULL ) { fprintf ( stderr, "-- Out of memory --\n" ); abort(); } flags = malloc ( ( n + 15 ) / 16 * 4 ); memset ( flags, 0x55, ( n + 15 ) / 16 * 4 ); size = set->size; set->size = n; set->max = n * set->load_factor; f = set->flags; set->flags = flags; flags = f; __uint128_t temp; for ( i = 0; i < size; i++ ) { if ( !exists_kmer_entity ( flags, i ) ) { continue; } key = set->array[i]; set_kmer_entity_del ( flags, i ); while ( 1 ) { hc = modular ( set, get_kmer_seq ( key ) ); #ifdef MER127 hc = modular ( set, get_kmer_seq ( key ) ); #else temp = Kmer2int128 ( get_kmer_seq ( key ) ); hc = temp % set->size; #endif while ( !is_kmer_entity_null ( set->flags, hc ) ) { hc ++; if ( hc == set->size ) { hc = 0; } } clear_kmer_entity_null ( set->flags, hc ); if ( hc < size && exists_kmer_entity ( flags, hc ) ) { tmp = key; key = set->array[hc]; set->array[hc] = tmp; set_kmer_entity_del ( flags, hc ); } else { set->array[hc] = key; break; } } } free ( flags ); } /************************************************* Function: put_kmerset2 Description: Puts kmer into the kmerset. Input: 1. set: the hash of kmerset 2. seq: the sequence of the kmer 3. id: the id of edge 4. flag: the type of kmer(00: big "to kmer"; 01: big "from kmer"; 10: small "to kmer"; 11: small "from kmer") 5. kmer_p: used to record the info of the kmer Output: None. Return: 1 if it's successfully put kmer into kmerset. *************************************************/ PUBLIC_FUNC int put_kmerset2 ( KmerSet2 * set, Kmer seq, int id, char flag, kmer_t2 ** kmer_p ) { ubyte8 hc; if ( set->count + 1 > set->max ) { encap_kmerset2 ( set, 1 ); } // hc = modular (set, seq); #ifdef MER127 hc = modular ( set, seq ); #else __uint128_t temp; temp = Kmer2int128 ( seq ); hc = temp % set->size; #endif do { if ( is_kmer_entity_null ( set->flags, hc ) ) { clear_kmer_entity_null ( set->flags, hc ); set_new_kmer2 ( set->array + hc, seq, id, flag ); set->count ++; *kmer_p = set->array + hc; return 0; } else { if ( KmerEqual ( get_kmer_seq ( set->array[hc] ), seq ) ) { update_kmer2 ( set->array + hc, id, flag ); *kmer_p = set->array + hc; return 1; } } hc ++; if ( hc == set->size ) { hc = 0; } } while ( 1 ); *kmer_p = NULL; return 0; } /************************************************* Function: count_kmerset2 Description: Returns the kmer number of the kmerset. Input: None. Output: None. Return: The kmer number of the kmerset. *************************************************/ PUBLIC_FUNC byte8 count_kmerset2 ( KmerSet2 * set ) { return set->count; } PUBLIC_FUNC static inline void reset_iter_kmerset2 ( KmerSet2 * set ) { set->iter_ptr = 0; } PUBLIC_FUNC static inline ubyte8 iter_kmerset2 ( KmerSet2 * set, kmer_t2 ** rs ) { while ( set->iter_ptr < set->size ) { if ( !is_kmer_entity_null ( set->flags, set->iter_ptr ) ) { *rs = set->array + set->iter_ptr; set->iter_ptr ++; return 1; } set->iter_ptr ++; } return 0; } //Free. PUBLIC_FUNC void free_kmerset2 ( KmerSet2 * set ) { int i; struct edgeID * temp, *temp_next; kmer_t2 * node; set->iter_ptr = 0; while ( set->iter_ptr < set->size ) { if ( !is_kmer_entity_null ( set->flags, set->iter_ptr ) ) { node = set->array + set->iter_ptr; if ( node ) { temp = node->edgeId; while ( temp ) { temp_next = temp->next; free ( ( void * ) temp ); temp = temp_next; } } } set->iter_ptr ++; } free ( set->array ); set->array = NULL; free ( set->flags ); set->flags = NULL; free ( set ); set = NULL; } /************************************************* Function: free_Sets2 Description: Free all the kmersets. Input: 1. sets: the array of the kmerset 2. num: the number of kmerset Output: None. Return: None. *************************************************/ PUBLIC_FUNC void free_Sets2 ( KmerSet2 ** sets, int num ) { int i; for ( i = 0; i < num; ++i ) { free_kmerset2 ( sets[i] ); sets[i] = NULL; } free ( ( void * ) sets ); sets = NULL; } soapdenovo2-240+dfsg.orig/standardPregraph/makeclean.sh0000644000000000000000000000004712166703654021754 0ustar rootrootmake clean 63mer=1 make clean 127mer=1 soapdenovo2-240+dfsg.orig/standardPregraph/cutTip_graph2.c0000644000000000000000000002543612166703654022370 0ustar rootroot/* * cutTip_graph2.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" static int caseA, caseB, caseC, caseD, caseE; void removeDeadArcs2(); //Destroy the edge. void destroyEdge2 ( unsigned int edgeid ) { unsigned int bal_ed = getTwinEdge ( edgeid ); ARC * arc; if ( bal_ed == edgeid ) { edge_array[edgeid].length = 0; return; } arc = edge_array[edgeid].arcs; while ( arc ) { arc->bal_arc->to_ed = 0; arc = arc->next; } arc = edge_array[bal_ed].arcs; while ( arc ) { arc->bal_arc->to_ed = 0; arc = arc->next; } edge_array[edgeid].arcs = NULL; edge_array[bal_ed].arcs = NULL; edge_array[edgeid].length = 0; edge_array[bal_ed].length = 0; edge_array[edgeid].deleted = 1; edge_array[bal_ed].deleted = 1; } //Count the arc number of edge. ARC * arcCount2 ( unsigned int edgeid, unsigned int * num ) { ARC * arc; ARC * firstValidArc = NULL; unsigned int count = 0; arc = edge_array[edgeid].arcs; while ( arc ) { if ( arc->to_ed > 0 ) { count++; if ( count == 1 ) { firstValidArc = arc; } else if ( count > 1 ) { *num = count; return firstValidArc; } } arc = arc->next; } *num = count; return firstValidArc; } /* multiplicity < multiCutoff ==== - ==== - ==== length < lenCutoff */ /************************************************* Function: removeWeakEdges2 Description: If the edge is short and its in-degree(or out-degree) is weak, removes it. Input: 1. lenCutoff: the cutoff for the length of edge 2. multiCutoff: the cutoff for the weight of preArc 3. mink: the min k Output: None. Return: None. *************************************************/ void removeWeakEdges2 ( int lenCutoff, unsigned int multiCutoff, int mink ) { unsigned int bal_ed; unsigned int arcRight_n, arcLeft_n; ARC * arcLeft, *arcRight; unsigned int i; int counter = 0; int round = 1; fprintf ( stderr, "Start to destroy weak inner edges.\n" ); counter = 1; while ( counter ) { counter = 0; for ( i = 1; i <= num_ed; i++ ) { if ( edge_array[i].deleted || edge_array[i].length == 0 || edge_array[i].length > lenCutoff || EdSameAsTwin ( i ) || edge_array[i].multi || edge_array[i].cvg == 0 ) { continue; } //keep cvg == 1 from original step // if(edge_array[i].cvg == 1) // continue; bal_ed = getTwinEdge ( i ); arcRight = arcCount2 ( i, &arcRight_n ); if ( arcRight_n > 1 || !arcRight || arcRight->multiplicity > multiCutoff ) { continue; } arcLeft = arcCount2 ( bal_ed, &arcLeft_n ); if ( arcLeft_n > 1 || !arcLeft || arcLeft->multiplicity > multiCutoff ) { continue; } destroyEdge2 ( i ); counter++; } fprintf ( stderr, "%d weak inner edge(s) destroyed in cycle %d.\n", counter, round++ ); } removeDeadArcs2(); // linearConcatenate(); // compactEdgeArray(); } /* cvg < covCutoff 1. ==== - ==== - ==== ==== 2. ==== - ==== < ==== ==== 3. > ==== - ==== ==== ==== ==== 4. > ==== < ==== ==== length < lenCutoff */ /************************************************* Function: removeLowCovEdges2 Description: If the edge is short and its coverage is low, removes it. Input: 1. lenCutoff: the cutoff for the length of edge 2. covCutoff: the cutoff for the coverage of edge 3. mink: the min k 4. last: whether it's last iteration Output: None. Return: None. *************************************************/ void removeLowCovEdges2 ( int lenCutoff, unsigned short covCutoff, int mink, boolean last ) { unsigned int bal_ed; unsigned int arcRight_n, arcLeft_n; ARC * arcLeft, *arcRight; unsigned int i; int counter = 0; for ( i = 1; i <= num_ed; i++ ) { if ( edge_array[i].deleted || edge_array[i].cvg == 0 || edge_array[i].cvg > covCutoff * 10 || edge_array[i].length >= lenCutoff || EdSameAsTwin ( i ) || edge_array[i].length == 0 || edge_array[i].multi ) { continue; } //keep cvg == 1 from original SOAPdenovo step // if(edge_array[i].cvg == 1) // continue; bal_ed = getTwinEdge ( i ); arcRight = arcCount2 ( i, &arcRight_n ); arcLeft = arcCount2 ( bal_ed, &arcLeft_n ); if ( arcLeft_n < 1 || arcRight_n < 1 ) { continue; } destroyEdge2 ( i ); counter++; } fprintf ( stderr, "%d inner edge(s) with coverage lower than or equal to %d destroyed.\n", counter, covCutoff ); removeDeadArcs2(); linearConcatenate2 ( last ); compactEdgeArray(); } /************************************************* Function: isUnreliableTip2 Description: Check whether the path from edgeid is a tips. Input: 1. edgeid: the edge index 2. cutLen: the cutoff length 3. strict: whether it's the strict mode Output: None. Return: 1 if it's a unreliable tips. *************************************************/ boolean isUnreliableTip2 ( unsigned int edgeid, int cutLen, boolean strict ) { unsigned int arcRight_n, arcLeft_n; unsigned int bal_ed; unsigned int currentEd = edgeid; int length = 0; unsigned int mult = 0; ARC * arc, *activeArc = NULL, *tempArc; unsigned int prevEd = currentEd; if ( edgeid == 0 ) { return 0; } bal_ed = getTwinEdge ( edgeid ); if ( bal_ed == edgeid ) { return 0; } arcCount2 ( bal_ed, &arcLeft_n ); if ( arcLeft_n > 0 ) { return 0; } while ( currentEd ) { prevEd = currentEd; arcCount2 ( bal_ed, &arcLeft_n ); tempArc = arcCount2 ( currentEd, &arcRight_n ); if ( arcLeft_n > 1 || arcRight_n > 1 ) { break; } length += edge_array[currentEd].length; if ( tempArc ) { activeArc = tempArc; currentEd = activeArc->to_ed; bal_ed = getTwinEdge ( currentEd ); } else { currentEd = 0; } } if ( length >= cutLen ) { return 0; } if ( currentEd == 0 ) { caseB++; return 0; } if ( !strict ) { if ( arcLeft_n < 2 ) { length += edge_array[currentEd].length; } if ( length >= cutLen ) { return 0; } else { caseC++; return 1; } } if ( arcLeft_n < 2 ) { return 0; } if ( !activeArc ) { fprintf ( stderr, "No activeArc while checking edge %d.\n", edgeid ); } if ( activeArc->multiplicity == 1 ) { caseD++; return 1; } for ( arc = edge_array[bal_ed].arcs; arc != NULL; arc = arc->next ) if ( arc->multiplicity > mult ) { mult = arc->multiplicity; } if ( mult > activeArc->multiplicity ) { caseE++; } return mult > activeArc->multiplicity; } boolean isUnreliableTip_strict2 ( unsigned int edgeid, int cutLen ) { unsigned int arcRight_n, arcLeft_n; unsigned int bal_ed; unsigned int currentEd = edgeid; int length = 0; unsigned int mult = 0; ARC * arc, *activeArc = NULL, *tempArc; if ( edgeid == 0 ) { return 0; } bal_ed = getTwinEdge ( edgeid ); if ( bal_ed == edgeid ) { return 0; } arcCount2 ( bal_ed, &arcLeft_n ); if ( arcLeft_n > 0 ) { return 0; } while ( currentEd ) { arcCount2 ( bal_ed, &arcLeft_n ); tempArc = arcCount2 ( currentEd, &arcRight_n ); if ( arcLeft_n > 1 || arcRight_n > 1 ) { if ( arcLeft_n == 0 || length == 0 ) { return 0; } else { break; } } length += edge_array[currentEd].length; if ( length >= cutLen ) { return 0; } if ( tempArc ) { activeArc = tempArc; currentEd = activeArc->to_ed; bal_ed = getTwinEdge ( currentEd ); } else { currentEd = 0; } } if ( currentEd == 0 ) { caseA++; return 1; } if ( !activeArc ) { fprintf ( stderr, "No activeArc while checking edge %d.\n", edgeid ); } if ( activeArc->multiplicity == 1 ) { caseB++; return 1; } for ( arc = edge_array[bal_ed].arcs; arc != NULL; arc = arc->next ) if ( arc->multiplicity > mult ) { mult = arc->multiplicity; } if ( mult > activeArc->multiplicity ) { caseC++; } return mult > activeArc->multiplicity; } //Remove the arcs that set to 0. void removeDeadArcs2() { unsigned int i, count = 0; ARC * arc, *arc_temp; for ( i = 1; i <= num_ed; i++ ) { arc = edge_array[i].arcs; while ( arc ) { arc_temp = arc; arc = arc->next; if ( arc_temp->to_ed == 0 ) { count++; edge_array[i].arcs = deleteArc ( edge_array[i].arcs, arc_temp ); } } } fprintf ( stderr, "%d dead arc(s) removed.\n", count ); } /************************************************* Function: cutTipsInGraph2 Description: Clip the short tips. Input: 1. cutLen: the cutoff for the total length of the tips 2. strict: the pattern of the cutting tips 3. last: whether it's last iterate Output: None. Return: None. *************************************************/ void cutTipsInGraph2 ( int cutLen, boolean strict, boolean last ) { int flag = 1; unsigned int i; if ( !cutLen ) { cutLen = 2 * overlaplen; } fprintf ( stderr, "\nStrict: %d, cutoff length: %d.\n", strict, cutLen ); if ( strict ) { linearConcatenate2 ( last ); } caseA = caseB = caseC = caseD = caseE = 0; int round = 1; while ( flag ) { flag = 0; for ( i = 1; i <= num_ed; i++ ) { if ( edge_array[i].deleted ) { continue; } if ( !edge_array[i].multi && isUnreliableTip2 ( i, cutLen, strict ) ) { destroyEdge2 ( i ); flag++; } } fprintf ( stderr, "%d tips cut in cycle %d.\n", flag, round++ ); } removeDeadArcs2(); if ( strict ) { fprintf ( stderr, "Case A %d, B %d C %d D %d E %d.\n", caseA, caseB, caseC, caseD, caseE ); } linearConcatenate2 ( last ); compactEdgeArray(); } soapdenovo2-240+dfsg.orig/standardPregraph/dfib.c0000644000000000000000000002501012166703654020545 0ustar rootroot/* * dfib.c * * This file is part of SOAPdenovo. * */ /*- * Copyright 1997-2003 John-Mark Gurney. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND 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 THE AUTHOR OR 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. * * $Id: dfib.c,v 1.12 2007/10/19 13:09:26 zerbino Exp $ * */ #include #include #include "dfib.h" #include "dfibpriv.h" #include "extfunc2.h" #define HEAPBLOCKSIZE 1000 static int dfh_comparedata ( DFibHeap * h, Time key, unsigned int data, DFibHeapNode * b ); static DFibHeapNode * allocateDFibHeapNode ( DFibHeap * heap ) { return ( DFibHeapNode * ) getItem ( heap->nodeMemory ); }; static void deallocateDFibHeapNode ( DFibHeapNode * a, DFibHeap * heap ) { returnItem ( heap->nodeMemory, a ); } IDnum dfibheap_getSize ( DFibHeap * heap ) { return heap->dfh_n; } #define swap(type, a, b) \ do { \ type c; \ c = a; \ a = b; \ b = c; \ } while (0) \ #define INT_BITS (sizeof(IDnum) * 8) static inline IDnum ceillog2 ( IDnum a ) { IDnum oa; IDnum i; IDnum b; IDnum cons; oa = a; b = INT_BITS / 2; i = 0; while ( b ) { i = ( i << 1 ); cons = ( ( IDnum ) 1 ) << b; if ( a >= cons ) { a /= cons; i = i | 1; } else { a &= cons - 1; } b /= 2; } if ( ( ( ( IDnum ) 1 << i ) ) == oa ) { return i; } else { return i + 1; } } /* * Public Heap Functions */ DFibHeap * dfh_makekeyheap () { DFibHeap * n; if ( ( n = malloc ( sizeof * n ) ) == NULL ) { return NULL; } n->nodeMemory = createMem_manager ( HEAPBLOCKSIZE, sizeof ( DFibHeapNode ) ); n->dfh_n = 0; n->dfh_Dl = -1; n->dfh_cons = NULL; n->dfh_min = NULL; n->dfh_root = NULL; return n; } void dfh_deleteheap ( DFibHeap * h ) { fprintf ( stderr, "DFibHeap: %lld node(s) allocated.\n", h->nodeMemory->counter ); freeMem_manager ( h->nodeMemory ); h->nodeMemory = NULL; if ( h->dfh_cons != NULL ) { free ( h->dfh_cons ); } free ( h ); } /* * Public Key Heap Functions */ DFibHeapNode * dfh_insertkey ( DFibHeap * h, Time key, unsigned int data ) { DFibHeapNode * x; if ( ( x = dfhe_newelem ( h ) ) == NULL ) { return NULL; } /* just insert on root list, and make sure it's not the new min */ x->dfhe_data = data; x->dfhe_key = key; dfh_insertel ( h, x ); return x; } Time dfh_replacekey ( DFibHeap * h, DFibHeapNode * x, Time key ) { Time ret; ret = x->dfhe_key; ( void ) dfh_replacekeydata ( h, x, key, x->dfhe_data ); return ret; } unsigned int minInDHeap ( DFibHeap * h ) { if ( h->dfh_min ) { return h->dfh_min->dfhe_data; } else { return 0; } } boolean HasMin ( DFibHeap * h ) { if ( h->dfh_min ) { return 1; } else { return 0; } } unsigned int dfh_replacekeydata ( DFibHeap * h, DFibHeapNode * x, Time key, unsigned int data ) { unsigned int odata; Time okey; DFibHeapNode * y; int r; odata = x->dfhe_data; okey = x->dfhe_key; /* * we can increase a key by deleting and reinserting, that * requires O(lgn) time. */ if ( ( r = dfh_comparedata ( h, key, data, x ) ) > 0 ) { /* XXX - bad code! */ abort (); } x->dfhe_data = data; x->dfhe_key = key; /* because they are equal, we don't have to do anything */ if ( r == 0 ) { return odata; } y = x->dfhe_p; if ( okey == key ) { return odata; } if ( y != NULL && dfh_compare ( h, x, y ) <= 0 ) { dfh_cut ( h, x, y ); dfh_cascading_cut ( h, y ); } /* * the = is so that the call from dfh_delete will delete the proper * element. */ if ( dfh_compare ( h, x, h->dfh_min ) <= 0 ) { h->dfh_min = x; } return odata; } /* * Public void * Heap Functions */ /* * this will return these values: * NULL failed for some reason * ptr token to use for manipulation of data */ unsigned int dfh_extractmin ( DFibHeap * h ) { DFibHeapNode * z; unsigned int ret; ret = 0; if ( h->dfh_min != NULL ) { z = dfh_extractminel ( h ); ret = z->dfhe_data; deallocateDFibHeapNode ( z, h ); } return ret; } unsigned int dfh_replacedata ( DFibHeapNode * x, unsigned int data ) { unsigned int odata = x->dfhe_data; //printf("replace node value %d with %d\n",x->dfhe_data,data); x->dfhe_data = data; return odata; } unsigned int dfh_delete ( DFibHeap * h, DFibHeapNode * x ) { unsigned int k; //printf("destroy node %d in dheap\n",x->dfhe_data); k = x->dfhe_data; dfh_replacekey ( h, x, INT_MIN ); dfh_extractmin ( h ); return k; } /* * begin of private element fuctions */ static DFibHeapNode * dfh_extractminel ( DFibHeap * h ) { DFibHeapNode * ret; DFibHeapNode * x, *y, *orig; ret = h->dfh_min; orig = NULL; /* put all the children on the root list */ /* for true consistancy, we should use dfhe_remove */ for ( x = ret->dfhe_child; x != orig && x != NULL; ) { if ( orig == NULL ) { orig = x; } y = x->dfhe_right; x->dfhe_p = NULL; dfh_insertrootlist ( h, x ); x = y; } /* remove minimum from root list */ dfh_removerootlist ( h, ret ); h->dfh_n--; /* if we aren't empty, consolidate the heap */ if ( h->dfh_n == 0 ) { h->dfh_min = NULL; } else { h->dfh_min = ret->dfhe_right; dfh_consolidate ( h ); } return ret; } static void dfh_insertrootlist ( DFibHeap * h, DFibHeapNode * x ) { if ( h->dfh_root == NULL ) { h->dfh_root = x; x->dfhe_left = x; x->dfhe_right = x; return; } dfhe_insertafter ( h->dfh_root, x ); } static void dfh_removerootlist ( DFibHeap * h, DFibHeapNode * x ) { if ( x->dfhe_left == x ) { h->dfh_root = NULL; } else { h->dfh_root = dfhe_remove ( x ); } } static void dfh_consolidate ( DFibHeap * h ) { DFibHeapNode ** a; DFibHeapNode * w; DFibHeapNode * y; DFibHeapNode * x; IDnum i; IDnum d; IDnum D; dfh_checkcons ( h ); /* assign a the value of h->dfh_cons so I don't have to rewrite code */ D = h->dfh_Dl + 1; a = h->dfh_cons; for ( i = 0; i < D; i++ ) { a[i] = NULL; } while ( ( w = h->dfh_root ) != NULL ) { x = w; dfh_removerootlist ( h, w ); d = x->dfhe_degree; /* XXX - assert that d < D */ while ( a[d] != NULL ) { y = a[d]; if ( dfh_compare ( h, x, y ) > 0 ) { swap ( DFibHeapNode *, x, y ); } dfh_heaplink ( h, y, x ); a[d] = NULL; d++; } a[d] = x; } h->dfh_min = NULL; for ( i = 0; i < D; i++ ) if ( a[i] != NULL ) { dfh_insertrootlist ( h, a[i] ); if ( h->dfh_min == NULL || dfh_compare ( h, a[i], h->dfh_min ) < 0 ) { h->dfh_min = a[i]; } } } static void dfh_heaplink ( DFibHeap * h, DFibHeapNode * y, DFibHeapNode * x ) { /* make y a child of x */ if ( x->dfhe_child == NULL ) { x->dfhe_child = y; } else { dfhe_insertbefore ( x->dfhe_child, y ); } y->dfhe_p = x; x->dfhe_degree++; y->dfhe_mark = 0; } static void dfh_cut ( DFibHeap * h, DFibHeapNode * x, DFibHeapNode * y ) { dfhe_remove ( x ); y->dfhe_degree--; dfh_insertrootlist ( h, x ); x->dfhe_p = NULL; x->dfhe_mark = 0; } static void dfh_cascading_cut ( DFibHeap * h, DFibHeapNode * y ) { DFibHeapNode * z; while ( ( z = y->dfhe_p ) != NULL ) { if ( y->dfhe_mark == 0 ) { y->dfhe_mark = 1; return; } else { dfh_cut ( h, y, z ); y = z; } } } /* * begining of handling elements of dfibheap */ static DFibHeapNode * dfhe_newelem ( DFibHeap * h ) { DFibHeapNode * e; if ( ( e = allocateDFibHeapNode ( h ) ) == NULL ) { return NULL; } e->dfhe_degree = 0; e->dfhe_mark = 0; e->dfhe_p = NULL; e->dfhe_child = NULL; e->dfhe_left = e; e->dfhe_right = e; e->dfhe_data = 0; return e; } static void dfhe_insertafter ( DFibHeapNode * a, DFibHeapNode * b ) { if ( a == a->dfhe_right ) { a->dfhe_right = b; a->dfhe_left = b; b->dfhe_right = a; b->dfhe_left = a; } else { b->dfhe_right = a->dfhe_right; a->dfhe_right->dfhe_left = b; a->dfhe_right = b; b->dfhe_left = a; } } static inline void dfhe_insertbefore ( DFibHeapNode * a, DFibHeapNode * b ) { dfhe_insertafter ( a->dfhe_left, b ); } static DFibHeapNode * dfhe_remove ( DFibHeapNode * x ) { DFibHeapNode * ret; if ( x == x->dfhe_left ) { ret = NULL; } else { ret = x->dfhe_left; } /* fix the parent pointer */ if ( x->dfhe_p != NULL && x->dfhe_p->dfhe_child == x ) { x->dfhe_p->dfhe_child = ret; } x->dfhe_right->dfhe_left = x->dfhe_left; x->dfhe_left->dfhe_right = x->dfhe_right; /* clear out hanging pointers */ x->dfhe_p = NULL; x->dfhe_left = x; x->dfhe_right = x; return ret; } static void dfh_checkcons ( DFibHeap * h ) { IDnum oDl; /* make sure we have enough memory allocated to "reorganize" */ if ( h->dfh_Dl == -1 || h->dfh_n > ( 1 << h->dfh_Dl ) ) { oDl = h->dfh_Dl; if ( ( h->dfh_Dl = ceillog2 ( h->dfh_n ) + 1 ) < 8 ) { h->dfh_Dl = 8; } if ( oDl != h->dfh_Dl ) { h->dfh_cons = ( DFibHeapNode ** ) realloc ( h->dfh_cons, sizeof * h->dfh_cons * ( h->dfh_Dl + 1 ) ); } if ( h->dfh_cons == NULL ) { abort (); } } } static int dfh_compare ( DFibHeap * h, DFibHeapNode * a, DFibHeapNode * b ) { if ( a->dfhe_key < b->dfhe_key ) { return -1; } if ( a->dfhe_key == b->dfhe_key ) { return 0; } return 1; } static int dfh_comparedata ( DFibHeap * h, Time key, unsigned int data, DFibHeapNode * b ) { DFibHeapNode a; a.dfhe_key = key; a.dfhe_data = data; return dfh_compare ( h, &a, b ); } static void dfh_insertel ( DFibHeap * h, DFibHeapNode * x ) { dfh_insertrootlist ( h, x ); if ( h->dfh_min == NULL || x->dfhe_key < h->dfh_min->dfhe_key ) { h->dfh_min = x; } h->dfh_n++; } Time dfibheap_el_getKey ( DFibHeapNode * node ) { return node->dfhe_key; } soapdenovo2-240+dfsg.orig/standardPregraph/dfibHeap.c0000644000000000000000000000451212166703654021347 0ustar rootroot/* * dfibHeap.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include #include #include "def2.h" #include "dfib.h" // Return number of elements stored in heap IDnum getDFibHeapSize ( DFibHeap * heap ) { return dfibheap_getSize ( heap ); } // Constructor // Memory allocated DFibHeap * newDFibHeap () { return dfh_makekeyheap (); } // Add new node into heap with a key, and a pointer to the specified node DFibHeapNode * insertNodeIntoDHeap ( DFibHeap * heap, Time key, unsigned int node ) { DFibHeapNode * res; res = dfh_insertkey ( heap, key, node ); return res; } // Replaces the key for a given node Time replaceKeyInDHeap ( DFibHeap * heap, DFibHeapNode * node, Time newKey ) { Time res; res = dfh_replacekey ( heap, node, newKey ); return res; } /************************************************* Function: removeNextNodeFromDHeap Description: Removes the edge from DHeap, then returns it. Input: 1. heap : the heap Output: None. Return: The key. *************************************************/ unsigned int removeNextNodeFromDHeap ( DFibHeap * heap ) { unsigned int node; node = ( unsigned int ) dfh_extractmin ( heap ); return node; } // Destructor void destroyDHeap ( DFibHeap * heap ) { dfh_deleteheap ( heap ); } // Replace the node pointed to by a heap node void replaceValueInDHeap ( DFibHeapNode * node, unsigned int newValue ) { dfh_replacedata ( node, newValue ); } // Remove unwanted node void destroyNodeInDHeap ( DFibHeapNode * node, DFibHeap * heap ) { dfh_delete ( heap, node ); } Time getKey ( DFibHeapNode * node ) { return dfibheap_el_getKey ( node ); } soapdenovo2-240+dfsg.orig/standardPregraph/make.sh0000644000000000000000000000007712166703654020754 0ustar rootrootmake 63mer=1 make 127mer=1 make install make install 127mer=1 soapdenovo2-240+dfsg.orig/standardPregraph/prlRead2Ctg.c0000644000000000000000000007315412166703654021766 0ustar rootroot/* * prlRead2Ctg.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #include "zlib.h" static long long readsInGap = 0; static int buffer_size = 100000000; static long long readCounter; static long long mapCounter; static int ALIGNLEN = 0; //buffer related varibles for chop kmer static int read_c; static char ** rcSeq; static char ** seqBuffer; static int * lenBuffer; static unsigned int * ctgIdArray; static int * posArray; static char * orienArray; static char * footprint; // flag indicates whether the read shoulld leave markers on contigs static char ** read_name; // kmer related variables static int kmer_c; static Kmer * kmerBuffer; static ubyte8 * hashBanBuffer; static kmer_t ** nodeBuffer; static boolean * smallerBuffer; static unsigned int * indexArray; static int * insSizeArray; static int * deletion; static void parse1read ( int t ); static void threadRoutine ( void * thrdID ); static void searchKmer ( int t, KmerSet * kset ); static void chopKmer4read ( int t, int threadID ); static void thread_wait ( pthread_t * threads ); static void creatThrds ( pthread_t * threads, PARAMETER * paras ) { unsigned char i; int temp; for ( i = 0; i < thrd_num; i++ ) { if ( ( temp = pthread_create ( &threads[i], NULL, ( void * ) threadRoutine, & ( paras[i] ) ) ) != 0 ) { fprintf ( stderr, "Create threads failed.\n" ); exit ( 1 ); } } fprintf ( stderr, "%d thread(s) initialized.\n", thrd_num ); } static void threadRoutine ( void * para ) { PARAMETER * prm; int i, t; unsigned char id; prm = ( PARAMETER * ) para; id = prm->threadID; while ( 1 ) { if ( * ( prm->selfSignal ) == 1 ) { for ( i = 0; i < kmer_c; i++ ) { if ( ( hashBanBuffer[i] % thrd_num ) != id ) { continue; } searchKmer ( i, KmerSets[id] ); } * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 2 ) { for ( i = 0; i < read_c; i++ ) { if ( i % thrd_num != id ) { continue; } chopKmer4read ( i, id + 1 ); } * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 3 ) { // parse reads for ( t = 0; t < read_c; t++ ) { if ( t % thrd_num != id ) { continue; } parse1read ( t ); } * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 5 ) { * ( prm->selfSignal ) = 0; break; } usleep ( 1 ); } } /* static void chopReads() { int i; for(i=0;ideleted ) { nodeBuffer[t] = node; } else { nodeBuffer[t] = NULL; } } /************************************************* Function: parse1read Description: Aligns read to contig by choosing the contig on which the read has most kmers hits. Input: 1. t: read index Output: None. Return: None. *************************************************/ static void parse1read ( int t ) { unsigned int j, i, s; unsigned int contigID; int counter = 0, counter2 = 0; unsigned int ctgLen, pos = 0; kmer_t * node; boolean isSmaller; int flag, maxOcc = 0; kmer_t * maxNode = NULL; int alldgnLen = lenBuffer[t] > ALIGNLEN ? ALIGNLEN : lenBuffer[t]; int multi = alldgnLen - overlaplen + 1 < 2 ? 2 : alldgnLen - overlaplen + 1; unsigned int start, finish; footprint[t] = 0; start = indexArray[t]; finish = indexArray[t + 1]; if ( finish == start ) { ctgIdArray[t] = 0; return; } for ( j = start; j < finish; j++ ) { node = nodeBuffer[j]; if ( !node ) //same as previous { continue; } flag = 1; for ( s = j + 1; s < finish; s++ ) { if ( !nodeBuffer[s] ) { continue; } if ( nodeBuffer[s]->l_links == node->l_links ) { flag++; nodeBuffer[s] = NULL; } } if ( ( overlaplen < 32 && flag >= 2 ) || overlaplen > 32 ) { counter2++; } if ( flag >= multi ) { counter++; } else { continue; } if ( flag > maxOcc ) { pos = j; maxOcc = flag; maxNode = node; } } if ( !counter ) { ctgIdArray[t] = 0; return; } if ( counter2 > 1 ) { footprint[t] = 1; } j = pos; i = pos - start + 1; node = nodeBuffer[j]; isSmaller = smallerBuffer[j]; contigID = node->l_links; ctgLen = contig_array[contigID].length; pos = node->r_links; if ( node->twin == isSmaller ) { orienArray[t] = '-'; ctgIdArray[t] = getTwinCtg ( contigID ); posArray[t] = ctgLen - pos - overlaplen - i + 1; } else { orienArray[t] = '+'; ctgIdArray[t] = contigID; posArray[t] = pos - i + 1; } } static void sendWorkSignal ( unsigned char SIG, unsigned char * thrdSignals ) { int t; for ( t = 0; t < thrd_num; t++ ) { thrdSignals[t + 1] = SIG; } while ( 1 ) { usleep ( 10 ); for ( t = 0; t < thrd_num; t++ ) if ( thrdSignals[t + 1] ) { break; } if ( t == thrd_num ) { break; } } } static void locate1read ( int t ) { int i, j, start, finish; kmer_t * node; unsigned int contigID; int pos, ctgLen; boolean isSmaller; start = indexArray[t]; finish = indexArray[t + 1]; for ( j = start; j < finish; j++ ) { node = nodeBuffer[j]; if ( !node ) //same as previous { continue; } i = j - start + 1; isSmaller = smallerBuffer[j]; contigID = node->l_links; ctgLen = contig_array[contigID].length; pos = node->r_links; if ( node->twin == isSmaller ) { ctgIdArray[t] = getTwinCtg ( contigID ); posArray[t] = ctgLen - pos - overlaplen - i + 1; } else { ctgIdArray[t] = contigID; posArray[t] = pos - i + 1; } } } static void output1read_gz ( int t, gzFile * outfp, gzFile * outfp2, char orien, int dhflag ) { int len = lenBuffer[t]; int index; readsInGap++; for ( index = 0; index < len; index++ ) { writeChar2tightString ( seqBuffer[t][index], rcSeq[1], index ); } gzwrite ( outfp, &len, sizeof ( int ) ); gzwrite ( outfp, &ctgIdArray[t], sizeof ( int ) ); gzwrite ( outfp, &posArray[t], sizeof ( int ) ); gzwrite ( outfp, rcSeq[1], ( unsigned ) ( len / 4 + 1 ) ); if ( fill && insSizeArray[t] < 2000 && len > 0 ) { gzprintf ( outfp2, ">%d\t%d\t%d\t%c\t%d\t%d\n", len, ctgIdArray[t], posArray[t], orien, insSizeArray[t], dhflag ); for ( index = 0; index < len; index++ ) { gzprintf ( outfp2, "%c", int2base ( ( int ) seqBuffer[t][index] ) ); } gzprintf ( outfp2, "\n" ); } } static void output1read ( int t, FILE * outfp1, FILE * outfp2, char orien, int dhflag ) { int len = lenBuffer[t]; int index; readsInGap++; /* if(ctgIdArray[t]==735||ctgIdArray[t]==getTwinCtg(735)){ printf("%d\t%d\t%d\t",t+1,ctgIdArray[t],posArray[t]); int j; for(j=0;j 0 ) { fprintf ( outfp2, ">%d\t%d\t%d\t%c\t%d\t%d\n", len, ctgIdArray[t], posArray[t], orien, insSizeArray[t], dhflag ); for ( index = 0; index < len; index++ ) { fprintf ( outfp2, "%c", int2base ( ( int ) seqBuffer[t][index] ) ); } fprintf ( outfp2, "\n" ); } } static void output1Nread ( int t, FILE * outfp ) { int len = lenBuffer[t]; int index; fprintf ( outfp, "%d\t%d\t%d\n", lenBuffer[t], ctgIdArray[t], posArray[t] ); fprintf ( outfp, ">%s\n", read_name[t] ); for ( index = 0; index < len; index++ ) { fprintf ( outfp, "%c", int2base ( ( int ) seqBuffer[t][index] ) ); } fprintf ( outfp, "\n" ); } static void getPEreadOnContig ( int t, gzFile * outfp ) { int len1, len2, index; char orien1, orien2; len1 = lenBuffer[t - 1]; len2 = lenBuffer[t]; orien1 = orienArray[t - 1]; orien2 = orienArray[t]; if ( insSizeArray[t] < 2000 && insSizeArray[t] == insSizeArray[t - 1] ) { gzwrite ( outfp, &len1, sizeof ( int ) ); gzwrite ( outfp, &ctgIdArray[t - 1], sizeof ( int ) ); gzwrite ( outfp, &posArray[t - 1], sizeof ( int ) ); gzwrite ( outfp, &orien1, sizeof ( char ) ); gzwrite ( outfp, &insSizeArray[t - 1], sizeof ( int ) ); for ( index = 0; index < len1; index++ ) { writeChar2tightString ( seqBuffer[t - 1][index], rcSeq[1], index ); } gzwrite ( outfp, rcSeq[1], ( unsigned ) ( len1 / 4 + 1 ) ); gzwrite ( outfp, &len2, sizeof ( int ) ); gzwrite ( outfp, &ctgIdArray[t], sizeof ( int ) ); gzwrite ( outfp, &posArray[t], sizeof ( int ) ); gzwrite ( outfp, &orien2, sizeof ( char ) ); gzwrite ( outfp, &insSizeArray[t], sizeof ( int ) ); for ( index = 0; index < len2; index++ ) { writeChar2tightString ( seqBuffer[t][index], rcSeq[1], index ); } gzwrite ( outfp, rcSeq[1], ( unsigned ) ( len2 / 4 + 1 ) ); } } /* static void getPEreadOnContig(int t,FILE* outfp) { int len1,len2,index; char orien1,orien2; len1 = lenBuffer[t-1]; len2 = lenBuffer[t]; orien1 = orienArray[t-1]; orien2 = orienArray[t]; if(insSizeArray[t]<2000&&insSizeArray[t]==insSizeArray[t-1]){ fprintf(outfp,">%d\t%d\t%d\t%c\t%d\n",len1,ctgIdArray[t-1],posArray[t-1],orien1,insSizeArray[t-1]); for(index=0;index%d\t%d\t%d\t%c\t%d\n",len2,ctgIdArray[t],posArray[t],orien2,insSizeArray[t]); for(index=0;index R1 <-- R2 output1read_gz ( read2, outfp1, outfp2, orientation, 2 ); } } static void recordLongRead ( FILE * outfp1, FILE * outfp2 ) { int t; for ( t = 0; t < read_c; t++ ) { readCounter++; if ( footprint[t] ) { output1read ( t, outfp1, outfp2, orienArray[t], 0 ); } } } static void recordAlldgn ( gzFile * outfp, int * insSizeArr, gzFile * outfp1, gzFile * outfp2, gzFile * outfp4 ) { int t, ctgId; boolean rd1gap, rd2gap; char orientation; for ( t = 0; t < read_c; t++ ) { readCounter++; rd1gap = rd2gap = 0; ctgId = ctgIdArray[t]; if ( outfp1 && t % 2 == 1 ) //make sure this is read2 in a pair { if ( ctgIdArray[t] < 1 && ctgIdArray[t - 1] > 0 ) { getReadIngap ( t, insSizeArr[t], outfp1, outfp2, 0 ); rd2gap = 1; } else if ( ctgIdArray[t] > 0 && ctgIdArray[t - 1] < 1 ) { getReadIngap ( t - 1, insSizeArr[t - 1], outfp1, outfp2, 1 ); rd1gap = 1; } else if ( ctgIdArray[t] > 0 && ctgIdArray[t - 1] > 0 ) //PE read on contig { if ( fill ) { getPEreadOnContig ( t, outfp4 ); } } } if ( ctgId < 1 ) { continue; } mapCounter++; gzprintf ( outfp, "%lld\t%u\t%d\t%c\n", readCounter, ctgIdArray[t], posArray[t], orienArray[t] ); if ( t % 2 == 0 ) { continue; } // reads are not located by pe info but across edges if ( outfp1 && footprint[t - 1] && !rd1gap ) { if ( ctgIdArray[t - 1] < 1 ) { locate1read ( t - 1 ); } if ( orienArray[t] == '+' ) { orientation = '-'; } else { orientation = '+'; } output1read_gz ( t - 1, outfp1, outfp2, orientation, 1 ); //read1 in gap. } if ( outfp1 && footprint[t] && !rd2gap ) { if ( ctgIdArray[t] < 1 ) { locate1read ( t ); } if ( orienArray[t - 1] == '+' ) { orientation = '-'; } else { orientation = '+'; } output1read_gz ( t, outfp1, outfp2, orientation, 2 ); //read2 in gap. } } } /************************************************* Function: basicContigInfo Description: Loads contig index and length infromation. Input: 1. infile: the graph file prefix Output: None. Return: None. *************************************************/ void basicContigInfo ( char * infile ) { char name[256], lldne[1024]; FILE * fp; int length, bal_ed, num_all, num_long, index; sprintf ( name, "%s.ContigIndex", infile ); fp = ckopen ( name, "r" ); fgets ( lldne, sizeof ( lldne ), fp ); sscanf ( lldne + 8, "%d %d", &num_all, &num_long ); fprintf ( stderr, "%d edge(s) in the graph.\n", num_all ); num_ctg = num_all; contig_array = ( CONTIG * ) ckalloc ( ( num_all + 1 ) * sizeof ( CONTIG ) ); fgets ( lldne, sizeof ( lldne ), fp ); num_long = 0; while ( fgets ( lldne, sizeof ( lldne ), fp ) != NULL ) { sscanf ( lldne, "%d %d %d", &index, &length, &bal_ed ); contig_array[++num_long].length = length; contig_array[num_long].bal_edge = bal_ed + 1; if ( index != num_long ) { fprintf ( stderr, "BasicContigInfo: %d vs %d.\n", index, num_long ); } if ( bal_ed == 0 ) { continue; } contig_array[++num_long].length = length; contig_array[num_long].bal_edge = -bal_ed + 1; } fclose ( fp ); } /************************************************* Function: prlRead2Ctg Description: Maps reads to contigs one by one. Input: 1. libfile: the reads config file 2. outfile: the graph file prefix Output: None. Return: None. *************************************************/ void prlRead2Ctg ( char * libfile, char * outfile ) { long long i; char * src_name, *next_name, name[256]; FILE * fo2; gzFile * fo, *outfp1 = NULL, *outfp2 = NULL, *outfp3 = NULL, *outfp4 = NULL; int maxReadNum, libNo, prevLibNo, insSize = 0; boolean flag, pairs = 1; pthread_t threads[thrd_num]; unsigned char thrdSignal[thrd_num + 1]; PARAMETER paras[thrd_num]; //init maxReadLen = 0; maxNameLen = 256; scan_libInfo ( libfile ); alloc_pe_mem ( num_libs ); if ( !maxReadLen ) { maxReadLen = 100; } fprintf ( stderr, "In file: %s, max seq len %d, max name len %d\n", libfile, maxReadLen, maxNameLen ); if ( maxReadLen > maxReadLen4all ) { maxReadLen4all = maxReadLen; } src_name = ( char * ) ckalloc ( ( maxNameLen + 1 ) * sizeof ( char ) ); next_name = ( char * ) ckalloc ( ( maxNameLen + 1 ) * sizeof ( char ) ); kmerBuffer = ( Kmer * ) ckalloc ( buffer_size * sizeof ( Kmer ) ); hashBanBuffer = ( ubyte8 * ) ckalloc ( buffer_size * sizeof ( ubyte8 ) ); nodeBuffer = ( kmer_t ** ) ckalloc ( buffer_size * sizeof ( kmer_t * ) ); smallerBuffer = ( boolean * ) ckalloc ( buffer_size * sizeof ( boolean ) ); maxReadNum = buffer_size / ( maxReadLen - overlaplen + 1 ); maxReadNum = maxReadNum % 2 == 0 ? maxReadNum : maxReadNum - 1; //make sure paired reads are processed at the same batch seqBuffer = ( char ** ) ckalloc ( maxReadNum * sizeof ( char * ) ); lenBuffer = ( int * ) ckalloc ( maxReadNum * sizeof ( int ) ); indexArray = ( unsigned int * ) ckalloc ( ( maxReadNum + 1 ) * sizeof ( unsigned int ) ); ctgIdArray = ( unsigned int * ) ckalloc ( ( maxReadNum + 1 ) * sizeof ( unsigned int ) ); posArray = ( int * ) ckalloc ( ( maxReadNum + 1 ) * sizeof ( int ) ); orienArray = ( char * ) ckalloc ( ( maxReadNum + 1 ) * sizeof ( char ) ); footprint = ( char * ) ckalloc ( ( maxReadNum + 1 ) * sizeof ( char ) ); insSizeArray = ( int * ) ckalloc ( ( maxReadNum + 1 ) * sizeof ( int ) ); read_name = ( char ** ) ckalloc ( maxReadNum * sizeof ( char * ) ); if ( gLineLen < maxReadLen ) { gStr = ( char * ) ckalloc ( ( maxReadLen + 1 ) * sizeof ( char ) ); } for ( i = 0; i < maxReadNum; i++ ) { read_name[i] = ( char * ) ckalloc ( ( maxNameLen + 1 ) * sizeof ( char ) ); } for ( i = 0; i < maxReadNum; i++ ) { seqBuffer[i] = ( char * ) ckalloc ( maxReadLen * sizeof ( char ) ); } rcSeq = ( char ** ) ckalloc ( ( thrd_num + 1 ) * sizeof ( char * ) ); thrdSignal[0] = 0; if ( 1 ) { for ( i = 0; i < thrd_num; i++ ) { rcSeq[i + 1] = ( char * ) ckalloc ( maxReadLen * sizeof ( char ) ); thrdSignal[i + 1] = 0; paras[i].threadID = i; paras[i].mainSignal = &thrdSignal[0]; paras[i].selfSignal = &thrdSignal[i + 1]; } creatThrds ( threads, paras ); } if ( !contig_array ) { basicContigInfo ( outfile ); } sprintf ( name, "%s.readInGap.gz", outfile ); outfp1 = gzopen ( name, "wb" ); if ( fill ) { sprintf ( name, "%s.shortreadInGap.gz", outfile ); outfp2 = gzopen ( name, "w" ); } sprintf ( name, "%s.readOnContig.gz", outfile ); fo = gzopen ( name, "w" ); if ( fill ) { sprintf ( name, "%s.PEreadOnContig.gz", outfile ); outfp4 = gzopen ( name, "wb" ); } gzprintf ( fo, "read\tcontig\tpos\n" ); readCounter = mapCounter = readsInGap = 0; kmer_c = n_solexa = read_c = i = libNo = readNumBack = gradsCounter = 0; prevLibNo = -1; int type = 0; //decide whether the PE reads is good or bad while ( ( flag = read1seqInLib ( seqBuffer[read_c], read_name[read_c], & ( lenBuffer[read_c] ), &libNo, pairs, 0, &type ) ) != 0 ) { if ( type == -1 ) //if the reads is bad, go back. { i--; if ( lenBuffer[read_c - 1] >= overlaplen + 1 ) { kmer_c -= lenBuffer[read_c - 1] - overlaplen + 1; } read_c--; n_solexa -= 2; continue; } if ( libNo != prevLibNo ) { prevLibNo = libNo; insSize = lib_array[libNo].avg_ins; ALIGNLEN = lib_array[libNo].map_len; if ( insSize > 1000 ) { ALIGNLEN = ALIGNLEN < 35 ? 35 : ALIGNLEN; } else { ALIGNLEN = ALIGNLEN < 32 ? 32 : ALIGNLEN; } fprintf ( stderr, "Current insert size is %d, map_len is %d.\n", insSize, ALIGNLEN ); } insSizeArray[read_c] = insSize; if ( insSize > 1000 ) { ALIGNLEN = ALIGNLEN < ( lenBuffer[read_c] / 2 + 1 ) ? ( lenBuffer[read_c] / 2 + 1 ) : ALIGNLEN; } if ( ( ++i ) % 100000000 == 0 ) { fprintf ( stderr, "--- %lldth reads.\n", i ); } indexArray[read_c] = kmer_c; if ( lenBuffer[read_c] >= overlaplen + 1 ) { kmer_c += lenBuffer[read_c] - overlaplen + 1; } read_c++; if ( read_c == maxReadNum ) { indexArray[read_c] = kmer_c; sendWorkSignal ( 2, thrdSignal ); //chopKmer4read sendWorkSignal ( 1, thrdSignal ); //searchKmer sendWorkSignal ( 3, thrdSignal ); //parse1read recordAlldgn ( fo, insSizeArray, outfp1, outfp2, outfp4 ); kmer_c = 0; read_c = 0; } } if ( read_c ) { indexArray[read_c] = kmer_c; sendWorkSignal ( 2, thrdSignal ); //chopKmer4read sendWorkSignal ( 1, thrdSignal ); //searchKmer sendWorkSignal ( 3, thrdSignal ); //parse1read recordAlldgn ( fo, insSizeArray, outfp1, outfp2, outfp4 ); fprintf ( stderr, "\nTotal reads %lld\n", readCounter ); fprintf ( stderr, "Reads in gaps %lld\n", readsInGap ); fprintf ( stderr, "Ratio %.1f%%\n", ( float ) readsInGap / readCounter * 100 ); } fprintf ( stderr, "Reads on contigs %lld\n", mapCounter ); fprintf ( stderr, "Ratio %.1f%%\n", ( float ) mapCounter / readCounter * 100 ); sendWorkSignal ( 5, thrdSignal ); //stop threads thread_wait ( threads ); gzclose ( fo ); sprintf ( name, "%s.peGrads", outfile ); fo2 = ckopen ( name, "w" ); fprintf ( fo2, "grads&num: %d\t%lld\t%d\n", gradsCounter, n_solexa, maxReadLen4all ); if ( pairs ) { if ( gradsCounter ) { fprintf ( stderr, "%d pe insert size, the largest boundary is %lld.\n\n", gradsCounter, pes[gradsCounter - 1].PE_bound ); } else { fprintf ( stderr, "No paired reads found.\n" ); } for ( i = 0; i < gradsCounter; i++ ) { fprintf ( fo2, "%d\t%lld\t%d\t%d\n", pes[i].insertS, pes[i].PE_bound, pes[i].rank, pes[i].pair_num_cut ); } fclose ( fo2 ); } gzclose ( outfp1 ); if ( fill ) { gzclose ( outfp2 ); gzclose ( outfp4 ); } free_pe_mem (); free_libs (); if ( 1 ) // multi-threads { for ( i = 0; i < thrd_num; i++ ) { free ( ( void * ) rcSeq[i + 1] ); } } free ( ( void * ) rcSeq ); for ( i = 0; i < maxReadNum; i++ ) { free ( ( void * ) seqBuffer[i] ); } free ( ( void * ) seqBuffer ); free ( ( void * ) lenBuffer ); free ( ( void * ) indexArray ); for ( i = 0; i < maxReadNum; i++ ) { free ( ( void * ) read_name[i] ); } free ( ( void * ) read_name ); free ( ( void * ) kmerBuffer ); free ( ( void * ) smallerBuffer ); free ( ( void * ) hashBanBuffer ); free ( ( void * ) nodeBuffer ); free ( ( void * ) ctgIdArray ); free ( ( void * ) posArray ); free ( ( void * ) orienArray ); free ( ( void * ) footprint ); free ( ( void * ) insSizeArray ); free ( ( void * ) src_name ); free ( ( void * ) next_name ); if ( gLineLen < maxReadLen ) { free ( ( void * ) gStr ); gStr = NULL; } if ( contig_array ) { free ( ( void * ) contig_array ); contig_array = NULL; } } static void thread_wait ( pthread_t * threads ) { int i; for ( i = 0; i < thrd_num; i++ ) if ( threads[i] != 0 ) { pthread_join ( threads[i], NULL ); } } /************************************************* Function: prlLongRead2Ctg Description: Aligns long reads to contigs. Input: 1. libfile: the reads contig file 2. outfile: the output file prefix Output: None. Return: None. *************************************************/ void prlLongRead2Ctg ( char * libfile, char * outfile ) { long long i; char * src_name, *next_name, name[256]; FILE * outfp1, *outfp2, *outfp3; int maxReadNum, libNo, prevLibNo; boolean flag, pairs = 0; pthread_t threads[thrd_num]; unsigned char thrdSignal[thrd_num + 1]; PARAMETER paras[thrd_num]; maxReadLen = 0; maxNameLen = 256; scan_libInfo ( libfile ); if ( !maxReadLen ) { maxReadLen = 100; } int longReadLen = getMaxLongReadLen ( num_libs ); if ( longReadLen < 1 ) // no long reads { return; } maxReadLen4all = maxReadLen < longReadLen ? longReadLen : maxReadLen; fprintf ( stderr, "In file: %s, long read len %d, max name len %d.\n", libfile, longReadLen, maxNameLen ); maxReadLen = longReadLen; src_name = ( char * ) ckalloc ( ( maxNameLen + 1 ) * sizeof ( char ) ); next_name = ( char * ) ckalloc ( ( maxNameLen + 1 ) * sizeof ( char ) ); kmerBuffer = ( Kmer * ) ckalloc ( buffer_size * sizeof ( Kmer ) ); hashBanBuffer = ( ubyte8 * ) ckalloc ( buffer_size * sizeof ( ubyte8 ) ); nodeBuffer = ( kmer_t ** ) ckalloc ( buffer_size * sizeof ( kmer_t * ) ); smallerBuffer = ( boolean * ) ckalloc ( buffer_size * sizeof ( boolean ) ); maxReadNum = buffer_size / ( maxReadLen - overlaplen + 1 ); maxReadNum = maxReadNum % 2 == 0 ? maxReadNum : maxReadNum - 1; //make sure paired reads are processed at the same batch seqBuffer = ( char ** ) ckalloc ( maxReadNum * sizeof ( char * ) ); read_name = ( char ** ) ckalloc ( maxReadNum * sizeof ( char * ) ); for ( i = 0; i < maxReadNum; i++ ) { read_name[i] = ( char * ) ckalloc ( ( maxNameLen + 1 ) * sizeof ( char ) ); } lenBuffer = ( int * ) ckalloc ( maxReadNum * sizeof ( int ) ); indexArray = ( unsigned int * ) ckalloc ( ( maxReadNum + 1 ) * sizeof ( unsigned int ) ); ctgIdArray = ( unsigned int * ) ckalloc ( ( maxReadNum + 1 ) * sizeof ( unsigned int ) ); posArray = ( int * ) ckalloc ( ( maxReadNum + 1 ) * sizeof ( int ) ); orienArray = ( char * ) ckalloc ( ( maxReadNum + 1 ) * sizeof ( char ) ); footprint = ( char * ) ckalloc ( ( maxReadNum + 1 ) * sizeof ( char ) ); insSizeArray = ( int * ) ckalloc ( ( maxReadNum + 1 ) * sizeof ( int ) ); if ( gLineLen < maxReadLen ) { gStr = ( char * ) ckalloc ( ( maxReadLen + 1 ) * sizeof ( char ) ); } for ( i = 0; i < maxReadNum; i++ ) { seqBuffer[i] = ( char * ) ckalloc ( maxReadLen * sizeof ( char ) ); } rcSeq = ( char ** ) ckalloc ( ( thrd_num + 1 ) * sizeof ( char * ) ); deletion = ( int * ) ckalloc ( ( thrd_num + 1 ) * sizeof ( int ) ); thrdSignal[0] = 0; deletion[0] = 0; if ( 1 ) { for ( i = 0; i < thrd_num; i++ ) { rcSeq[i + 1] = ( char * ) ckalloc ( maxReadLen * sizeof ( char ) ); deletion[i + 1] = 0; thrdSignal[i + 1] = 0; paras[i].threadID = i; paras[i].mainSignal = &thrdSignal[0]; paras[i].selfSignal = &thrdSignal[i + 1]; } creatThrds ( threads, paras ); } if ( !contig_array ) { basicContigInfo ( outfile ); } sprintf ( name, "%s.longReadInGap", outfile ); outfp1 = ckopen ( name, "wb" ); if ( fill ) { sprintf ( name, "%s.RlongReadInGap", outfile ); outfp2 = ckopen ( name, "w" ); } readCounter = 0; kmer_c = n_solexa = read_c = i = libNo = 0; prevLibNo = -1; int type = 0; //decide whether the PE reads is good or bad while ( ( flag = read1seqInLib ( seqBuffer[read_c], read_name[read_c], & ( lenBuffer[read_c] ), &libNo, pairs, 4, &type ) ) != 0 ) { if ( type == -1 ) //if the reads is bad, go back. { i--; if ( lenBuffer[read_c - 1] >= overlaplen + 1 ) { kmer_c -= lenBuffer[read_c - 1] - overlaplen + 1; } read_c--; n_solexa -= 2; continue; } if ( libNo != prevLibNo ) { prevLibNo = libNo; ALIGNLEN = lib_array[libNo].map_len; ALIGNLEN = ALIGNLEN < 35 ? 35 : ALIGNLEN; fprintf ( stderr, "Map_len %d.\n", ALIGNLEN ); } insSizeArray[read_c] = 18; if ( ( ++i ) % 100000000 == 0 ) { fprintf ( stderr, "--- %lldth reads.\n", i ); } indexArray[read_c] = kmer_c; if ( lenBuffer[read_c] >= overlaplen + 1 ) { kmer_c += lenBuffer[read_c] - overlaplen + 1; } read_c++; if ( read_c == maxReadNum ) { indexArray[read_c] = kmer_c; sendWorkSignal ( 2, thrdSignal ); //chopKmer4read sendWorkSignal ( 1, thrdSignal ); //searchKmer sendWorkSignal ( 3, thrdSignal ); //parse1read recordLongRead ( outfp1, outfp2 ); kmer_c = 0; read_c = 0; } } if ( read_c ) { indexArray[read_c] = kmer_c; sendWorkSignal ( 2, thrdSignal ); //chopKmer4read sendWorkSignal ( 1, thrdSignal ); //searchKmer sendWorkSignal ( 3, thrdSignal ); //parse1read recordLongRead ( outfp1, outfp2 ); fprintf ( stderr, "Output %lld out of %lld (%.1f)%% reads in gaps.\n", readsInGap, readCounter, ( float ) readsInGap / readCounter * 100 ); } sendWorkSignal ( 5, thrdSignal ); //stop thread_wait ( threads ); fclose ( outfp1 ); if ( fill ) { fclose ( outfp2 ); } free_libs (); if ( 1 ) // multi-threads { for ( i = 0; i < thrd_num; i++ ) { deletion[0] += deletion[i + 1]; free ( ( void * ) rcSeq[i + 1] ); } } fprintf ( stderr, "%d reads deleted.\n", deletion[0] ); free ( ( void * ) rcSeq ); free ( ( void * ) deletion ); for ( i = 0; i < maxReadNum; i++ ) { free ( ( void * ) seqBuffer[i] ); } for ( i = 0; i < maxReadNum; i++ ) { free ( ( void * ) read_name[i] ); } free ( ( void * ) seqBuffer ); free ( ( void * ) lenBuffer ); free ( ( void * ) indexArray ); free ( ( void * ) kmerBuffer ); free ( ( void * ) smallerBuffer ); free ( ( void * ) hashBanBuffer ); free ( ( void * ) nodeBuffer ); free ( ( void * ) ctgIdArray ); free ( ( void * ) posArray ); free ( ( void * ) orienArray ); free ( ( void * ) footprint ); free ( ( void * ) insSizeArray ); free ( ( void * ) src_name ); free ( ( void * ) next_name ); if ( gLineLen < maxReadLen ) { free ( ( void * ) gStr ); gStr = NULL; } } soapdenovo2-240+dfsg.orig/standardPregraph/loadPath.c0000644000000000000000000001527612166703654021412 0ustar rootroot/* * loadPath.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" /************************************************* Function: add1marker2edge Description: Records the id of read which crosses the edge. Input: 1. edgeno: the edge index 2. readid: the read id Output: None. Return: None. *************************************************/ static void add1marker2edge ( unsigned int edgeno, long long readid ) { if ( edge_array[edgeno].multi == 255 ) { return; } unsigned int bal_ed = getTwinEdge ( edgeno ); unsigned char counter = edge_array[edgeno].multi++; edge_array[edgeno].markers[counter] = readid; counter = edge_array[bal_ed].multi++; edge_array[bal_ed].markers[counter] = -readid; } /************************************************* Function: loadPath Description: 1. Loads the path info. 2. Records the ids of reads crossing edges. Input: 1. graphfile: the input prefix Output: None. Return: None. *************************************************/ boolean loadPath ( char * graphfile ) { FILE * fp; char name[256], line[1024]; unsigned int i, bal_ed, num1, edgeno, num2; long long markCounter = 0, readid = 0; char * seg; sprintf ( name, "%s.markOnEdge", graphfile ); fp = fopen ( name, "r" ); if ( !fp ) { return 0; } for ( i = 1; i <= num_ed; i++ ) { edge_array[i].multi = 0; } for ( i = 1; i <= num_ed; i++ ) { fscanf ( fp, "%d", &num1 ); if ( EdSmallerThanTwin ( i ) ) { fscanf ( fp, "%d", &num2 ); bal_ed = getTwinEdge ( i ); if ( num1 + num2 >= 255 ) { edge_array[i].multi = 255; edge_array[bal_ed].multi = 255; } else { edge_array[i].multi = num1 + num2; edge_array[bal_ed].multi = num1 + num2; markCounter += 2 * ( num1 + num2 ); } i++; } else { if ( 2 * num1 >= 255 ) { edge_array[i].multi = 255; } else { edge_array[i].multi = 2 * num1; markCounter += 2 * num1; } } } fclose ( fp ); fprintf ( stderr, "%lld markers overall.\n", markCounter ); markersArray = ( long long * ) ckalloc ( markCounter * sizeof ( long long ) ); markCounter = 0; for ( i = 1; i <= num_ed; i++ ) { if ( edge_array[i].multi == 255 ) { continue; } edge_array[i].markers = markersArray + markCounter; markCounter += edge_array[i].multi; edge_array[i].multi = 0; } sprintf ( name, "%s.path", graphfile ); fp = fopen ( name, "r" ); if ( !fp ) { return 0; } while ( fgets ( line, sizeof ( line ), fp ) != NULL ) { //printf("%s",line); readid++; seg = strtok ( line, " " ); while ( seg ) { edgeno = atoi ( seg ); //printf("%s, %d\n",seg,edgeno); add1marker2edge ( edgeno, readid ); seg = strtok ( NULL, " " ); } } fclose ( fp ); markCounter = 0; for ( i = 1; i <= num_ed; i++ ) { if ( edge_array[i].multi == 255 ) { continue; } markCounter += edge_array[i].multi; } fprintf ( stderr, "%lld marks loaded.\n", markCounter ); return 1; } static int comp ( const void * a , const void * b ) { long long m , n ; m = * ( long long * ) a > 0 ? * ( long long * ) a : -* ( long long * ) a; n = * ( long long * ) b > 0 ? * ( long long * ) b : -* ( long long * ) b; // return (int)(m-n); if ( m > n ) { return 1; } else if ( m < n ) { return -1; } else { return 0; } } /************************************************* Function: loadPathBin Description: 1. Loads the path info. 2. Records the ids of reads crossing edges. Input: 1. graphfile: the input prefix Output: None. Return: 0 if it's fail to load the path. *************************************************/ boolean loadPathBin ( char * graphfile ) { FILE * fp; char name[256]; unsigned int i, bal_ed, num1, num2; long long markCounter = 0, readid = 0; unsigned char seg, ch; unsigned int * freadBuf; sprintf ( name, "%s.markOnEdge", graphfile ); fp = fopen ( name, "r" ); if ( !fp ) { return 0; } for ( i = 1; i <= num_ed; i++ ) { edge_array[i].multi = 0; edge_array[i].markers = NULL; } for ( i = 1; i <= num_ed; i++ ) { fscanf ( fp, "%d", &num1 ); if ( EdSmallerThanTwin ( i ) ) { fscanf ( fp, "%d", &num2 ); bal_ed = getTwinEdge ( i ); if ( num1 + num2 >= 255 ) { edge_array[i].multi = 255; edge_array[bal_ed].multi = 255; } else { edge_array[i].multi = num1 + num2; edge_array[bal_ed].multi = num1 + num2; markCounter += 2 * ( num1 + num2 ); } i++; } else { if ( 2 * num1 >= 255 ) { edge_array[i].multi = 255; } else { edge_array[i].multi = 2 * num1; markCounter += 2 * num1; } } } fclose ( fp ); fprintf ( stderr, "%lld markers overall.\n", markCounter ); markersArray = ( long long * ) ckalloc ( markCounter * sizeof ( long long ) ); markCounter = 0; for ( i = 1; i <= num_ed; i++ ) { if ( edge_array[i].multi == 255 ) { continue; } edge_array[i].markers = markersArray + markCounter; markCounter += edge_array[i].multi; edge_array[i].multi = 0; } sprintf ( name, "%s.path", graphfile ); fp = fopen ( name, "rb" ); if ( !fp ) { return 0; } freadBuf = ( unsigned int * ) ckalloc ( ( maxReadLen - overlaplen + 1 ) * sizeof ( unsigned int ) ); while ( fread ( &ch, sizeof ( char ), 1, fp ) == 1 ) { //printf("%s",line); if ( fread ( freadBuf, sizeof ( unsigned int ), ch, fp ) != ch ) { break; } readid++; for ( seg = 0; seg < ch; seg++ ) { add1marker2edge ( freadBuf[seg], readid ); } } fclose ( fp ); markCounter = 0; for ( i = 1; i <= num_ed; i++ ) { if ( edge_array[i].multi == 255 ) { continue; } markCounter += edge_array[i].multi; } for ( i = 0; i <= num_ed; i++ ) { if ( edge_array[i].multi >= 2 && edge_array[i].multi != 255 ) { qsort ( edge_array[i].markers, ( int ) edge_array[i].multi, sizeof ( long long ), comp ); } } fprintf ( stderr, "%lld markers loaded.\n", markCounter ); free ( ( void * ) freadBuf ); return 1; } soapdenovo2-240+dfsg.orig/standardPregraph/node2edge.c0000644000000000000000000003642612166703654021512 0ustar rootroot/* * node2edge.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #include "stack.h" #include "zlib.h" #define KMERPTBLOCKSIZE 1000 //static int loopCounter; static int nodeCounter; //count the node number including (K+1)mer node static int edge_length_limit = 100000; //static 'edge_seq' nax length static int edge_c, edgeCounter; // current edge count number for both strand , all edge number static preEDGE temp_edge; // for temp use in merge_V2() static char edge_seq[100000]; //use this static 'edge_seq ' as an temp seq in merge_V2() for speed .. static void make_edge ( gzFile * fp ); static void merge_linearV2 ( char bal_edge, STACK * nStack, int count, gzFile * fp ); static int check_iden_kmerList ( STACK * stack1, STACK * stack2 ); //for stack static STACK * nodeStack; //the stack for storing linear nodes static STACK * bal_nodeStack; // the stack for storing the reverse complemental nodes .. /************************************************* Function: kmer2edges Description: Builds edges by combining linear kmers. Input: 1.outfile: prefix of output file Output: None. Return: None. *************************************************/ void kmer2edges ( char * outfile ) { gzFile * fp; char temp[256]; sprintf ( temp, "%s.edge.gz", outfile ); fp = gzopen ( temp, "w" ); make_edge ( fp ); gzclose ( fp ); num_ed = edge_c; } /************************************************* Function: stringBeads Description: Puts the linear nodes into a stack (nodeStack). Input: 1. firstBead: the first node 2. nextch: the next base 3. node_c: the node number Output: None. Return: None. *************************************************/ static void stringBeads ( KMER_PT * firstBead, char nextch, int * node_c ) { boolean smaller, found; Kmer tempKmer, bal_word; Kmer word = firstBead->kmer; ubyte8 hash_ban; kmer_t * outgoing_node; int nodeCounter = 1, setPicker; char ch; unsigned char flag; KMER_PT * temp_pt, *prev_pt = firstBead; word = prev_pt->kmer; nodeCounter = 1; word = nextKmer ( word, nextch ); bal_word = reverseComplement ( word, overlaplen ); if ( KmerLarger ( word, bal_word ) ) { tempKmer = bal_word; bal_word = word; word = tempKmer; smaller = 0; } else { smaller = 1; } hash_ban = hash_kmer ( word ); setPicker = hash_ban % thrd_num; found = search_kmerset ( KmerSets[setPicker], word, &outgoing_node ); while ( found && ( outgoing_node->linear ) ) // for every node in this line { nodeCounter++; temp_pt = ( KMER_PT * ) stackPush ( nodeStack ); temp_pt->node = outgoing_node; temp_pt->isSmaller = smaller; if ( smaller ) { temp_pt->kmer = word; } else { temp_pt->kmer = bal_word; } prev_pt = temp_pt; if ( smaller ) { for ( ch = 0; ch < 4; ch++ ) { flag = get_kmer_right_cov ( *outgoing_node, ch ); if ( flag ) { break; } } word = nextKmer ( prev_pt->kmer, ch ); bal_word = reverseComplement ( word, overlaplen ); if ( KmerLarger ( word, bal_word ) ) { tempKmer = bal_word; bal_word = word; word = tempKmer; smaller = 0; } else { smaller = 1; } hash_ban = hash_kmer ( word ); setPicker = hash_ban % thrd_num; found = search_kmerset ( KmerSets[setPicker], word, &outgoing_node ); } else { for ( ch = 0; ch < 4; ch++ ) { flag = get_kmer_left_cov ( *outgoing_node, ch ); if ( flag ) { break; } } word = nextKmer ( prev_pt->kmer, int_comp ( ch ) ); bal_word = reverseComplement ( word, overlaplen ); if ( KmerLarger ( word, bal_word ) ) { tempKmer = bal_word; bal_word = word; word = tempKmer; smaller = 0; } else { smaller = 1; } hash_ban = hash_kmer ( word ); setPicker = hash_ban % thrd_num; found = search_kmerset ( KmerSets[setPicker], word, &outgoing_node ); } } if ( outgoing_node ) //this is always true { nodeCounter++; temp_pt = ( KMER_PT * ) stackPush ( nodeStack ); temp_pt->node = outgoing_node; temp_pt->isSmaller = smaller; if ( smaller ) { temp_pt->kmer = word; } else { temp_pt->kmer = bal_word; } } *node_c = nodeCounter; } /************************************************* Function: startEdgeFromNode Description: Constructs edges from a branched node. For every branch (left , right): 1. Puts the linear node into a stack. 2. Checks whether the edge is plalindrome. 3. Builds an edge by merging the linear nodes. Input: 1. node1: the start node 2. fp: output file Output: None. Return: 0. *************************************************/ static int startEdgeFromNode ( kmer_t * node1, gzFile * fp ) { int node_c, palindrome; unsigned char flag; KMER_PT * ite_pt, *temp_pt; Kmer word1, bal_word1; char ch1; /* if (node1->linear || node1->deleted) { return 0; } // */ // ignore floating loop word1 = node1->seq; bal_word1 = reverseComplement ( word1, overlaplen ); // linear structure for ( ch1 = 0; ch1 < 4; ch1++ ) // for every node on outgoing list { flag = get_kmer_right_cov ( *node1, ch1 ); if ( !flag ) { continue; } emptyStack ( nodeStack ); temp_pt = ( KMER_PT * ) stackPush ( nodeStack ); temp_pt->node = node1; temp_pt->isSmaller = 1; temp_pt->kmer = word1; stringBeads ( temp_pt, ch1, &node_c ); //printf("%d nodes\n",node_c); if ( node_c < 2 ) { fprintf ( stderr, "%d nodes in this line!!!!!!!!!!!\n", node_c ); } else { //make a reverse complement node list stackBackup ( nodeStack ); emptyStack ( bal_nodeStack ); while ( ( ite_pt = ( KMER_PT * ) stackPop ( nodeStack ) ) != NULL ) { temp_pt = ( KMER_PT * ) stackPush ( bal_nodeStack ); temp_pt->kmer = reverseComplement ( ite_pt->kmer, overlaplen ); } stackRecover ( nodeStack ); palindrome = check_iden_kmerList ( nodeStack, bal_nodeStack ); stackRecover ( nodeStack ); if ( palindrome ) { merge_linearV2 ( 0, nodeStack, node_c, fp ); } else { merge_linearV2 ( 1, nodeStack, node_c, fp ); } } } //every possible outgoing edges for ( ch1 = 0; ch1 < 4; ch1++ ) // for every node on incoming list { flag = get_kmer_left_cov ( *node1, ch1 ); if ( !flag ) { continue; } emptyStack ( nodeStack ); temp_pt = ( KMER_PT * ) stackPush ( nodeStack ); temp_pt->node = node1; temp_pt->isSmaller = 0; temp_pt->kmer = bal_word1; stringBeads ( temp_pt, int_comp ( ch1 ), &node_c ); if ( node_c < 2 ) { fprintf ( stderr, "%d nodes in this line!!!!!!!!!!!\n", node_c ); } else { //make a reverse complement node list stackBackup ( nodeStack ); emptyStack ( bal_nodeStack ); while ( ( ite_pt = ( KMER_PT * ) stackPop ( nodeStack ) ) != NULL ) { temp_pt = ( KMER_PT * ) stackPush ( bal_nodeStack ); temp_pt->kmer = reverseComplement ( ite_pt->kmer, overlaplen ); } stackRecover ( nodeStack ); palindrome = check_iden_kmerList ( nodeStack, bal_nodeStack ); stackRecover ( nodeStack ); if ( palindrome ) { merge_linearV2 ( 0, nodeStack, node_c, fp ); //printf("edge is palindrome with length %d\n",temp_edge.length); } else { merge_linearV2 ( 1, nodeStack, node_c, fp ); } } } //every possible incoming edges return 0; } /************************************************* Function: make_edge Description: Builds the edges and outputs them. Input: 1. fp: output file Output: None. Return: None. *************************************************/ void make_edge ( gzFile * fp ) { int i = 0; kmer_t * node1; KmerSet * set; KmerSetsPatch = ( KmerSet ** ) ckalloc ( thrd_num * sizeof ( KmerSet * ) ); for ( i = 0; i < thrd_num; i++ ) { KmerSetsPatch[i] = init_kmerset ( 1000, K_LOAD_FACTOR ); } nodeStack = ( STACK * ) createStack ( KMERPTBLOCKSIZE, sizeof ( KMER_PT ) ); bal_nodeStack = ( STACK * ) createStack ( KMERPTBLOCKSIZE, sizeof ( KMER_PT ) ); edge_c = nodeCounter = 0; edgeCounter = 0; for ( i = 0; i < thrd_num; i++ ) { set = KmerSets[i]; set->iter_ptr = 0; while ( set->iter_ptr < set->size ) { if ( !is_kmer_entity_null ( set->flags, set->iter_ptr ) ) { node1 = set->array + set->iter_ptr; // /* if ( !node1->linear && !node1->deleted ) { startEdgeFromNode ( node1, fp ); } // */ // startEdgeFromNode (node1, fp); } set->iter_ptr++; } } fprintf ( stderr, "%d (%d) edge(s) and %d extra node(s) constructed.\n", edge_c, edgeCounter, nodeCounter ); freeStack ( nodeStack ); freeStack ( bal_nodeStack ); } /************************************************* Function: merge_linearV2 Description: 1. Merges the linear nodes in a stack to build an edge. 2. Creates (K+1)mer for edges with length=1. Input: 1. bal_edge: 0:palindrome 1:normal 2. nStack: the stack of nodes 3. count: the number of the nodes in the nStack 4. fp: output file Output: None. Return: None. *************************************************/ static void merge_linearV2 ( char bal_edge, STACK * nStack, int count, gzFile * fp ) { int length, char_index; preEDGE * newedge; kmer_t * del_node, *longNode; char * tightSeq, firstCh; long long symbol = 0; int len_tSeq; Kmer wordplus, bal_wordplus; ubyte8 hash_ban; KMER_PT * last_np = ( KMER_PT * ) stackPop ( nStack ); KMER_PT * second_last_np = ( KMER_PT * ) stackPop ( nStack ); KMER_PT * first_np, *second_np = NULL; KMER_PT * temp; boolean found; int setPicker; length = count - 1; len_tSeq = length; if ( len_tSeq >= edge_length_limit ) { tightSeq = ( char * ) ckalloc ( len_tSeq * sizeof ( char ) ); } else { tightSeq = edge_seq; } char_index = length - 1; newedge = &temp_edge; newedge->to_node = last_np->kmer; newedge->length = length; newedge->bal_edge = bal_edge; tightSeq[char_index--] = lastCharInKmer ( last_np->kmer ); firstCh = firstCharInKmer ( second_last_np->kmer ); dislink2prevUncertain ( last_np->node, firstCh, last_np->isSmaller ); stackRecover ( nStack ); while ( nStack->item_c > 1 ) { second_np = ( KMER_PT * ) stackPop ( nStack ); } first_np = ( KMER_PT * ) stackPop ( nStack ); //unlink first node to the second one dislink2nextUncertain ( first_np->node, lastCharInKmer ( second_np->kmer ), first_np->isSmaller ); //printf("from %llx, to %llx\n",first_np->node->seq,last_np->node->seq); //now temp is the last node in line, out_node is the second last node in line newedge->from_node = first_np->kmer; //create a long kmer for edge with length 1 if ( length == 1 ) { nodeCounter++; wordplus = KmerPlus ( newedge->from_node, lastCharInKmer ( newedge->to_node ) ); bal_wordplus = reverseComplement ( wordplus, overlaplen + 1 ); /* Kmer temp = KmerPlus(reverseComplement(newedge->to_node,overlaplen), lastCharInKmer(reverseComplement(newedge->from_node,overlaplen))); fprintf(stderr,"(%llx %llx) (%llx %llx) (%llx %llx)\n", wordplus.high,wordplus.low,temp.high,temp.low, bal_wordplus.high,bal_wordplus.low); */ edge_c++; edgeCounter++; if ( KmerSmaller ( wordplus, bal_wordplus ) ) { hash_ban = hash_kmer ( wordplus ); setPicker = hash_ban % thrd_num; found = put_kmerset ( KmerSetsPatch[setPicker], wordplus, 4, 4, &longNode ); if ( found ) { fprintf ( stderr, "LongNode " ); PrintKmer ( stderr, wordplus ); fprintf ( stderr, " already exist.\n" ); /* #ifdef MER127 fprintf (stderr,"longNode %llx %llx %llx %llx already exist\n", wordplus.high1, wordplus.low1, wordplus.high2, wordplus.low2); #else fprintf (stderr,"longNode %llx %llx already exist\n", wordplus.high, wordplus.low); #endif */ } longNode->l_links = edge_c; longNode->twin = ( unsigned char ) ( bal_edge + 1 ); } else { hash_ban = hash_kmer ( bal_wordplus ); setPicker = hash_ban % thrd_num; found = put_kmerset ( KmerSetsPatch[setPicker], bal_wordplus, 4, 4, &longNode ); if ( found ) { fprintf ( stderr, "LongNode " ); PrintKmer ( stderr, wordplus ); fprintf ( stderr, " already exist.\n" ); /* #ifdef MER127 fprintf (stderr,"longNode %llx %llx %llx %llx already exist\n", wordplus.high1, wordplus.low1, wordplus.high2, wordplus.low2); #else fprintf (stderr,"longNode %llx %llx already exist\n", bal_wordplus.high, bal_wordplus.low); #endif */ } longNode->l_links = edge_c + bal_edge; longNode->twin = ( unsigned char ) ( -bal_edge + 1 ); } } else { edge_c++; edgeCounter++; } stackRecover ( nStack ); //mark all the internal nodes temp = ( KMER_PT * ) stackPop ( nStack ); while ( nStack->item_c > 1 ) { temp = ( KMER_PT * ) stackPop ( nStack ); del_node = temp->node; del_node->inEdge = 1; symbol += get_kmer_left_covs ( *del_node ); tightSeq[char_index--] = lastCharInKmer ( temp->kmer ); } stackRecover ( nStack ); temp = ( KMER_PT * ) stackPop ( nStack ); while ( nStack->item_c > 1 ) { temp = ( KMER_PT * ) stackPop ( nStack ); del_node = temp->node; del_node->inEdge = 1; if ( temp->isSmaller ) { del_node->l_links = edge_c; del_node->twin = ( unsigned char ) ( bal_edge + 1 ); } else { del_node->l_links = edge_c + bal_edge; del_node->twin = ( unsigned char ) ( -bal_edge + 1 ); } } newedge->seq = tightSeq; if ( length > 1 ) { newedge->cvg = symbol / ( length - 1 ) * 10 > MaxEdgeCov ? MaxEdgeCov : symbol / ( length - 1 ) * 10; } else { newedge->cvg = 0; } output_1edge ( newedge, fp ); if ( len_tSeq >= edge_length_limit ) { free ( ( void * ) tightSeq ); } edge_c += bal_edge; if ( edge_c % 10000000 == 0 ) { fprintf ( stderr, "--- %d edge(s) built.\n", edge_c ); } return; } /************************************************* Function: check_iden_kmerList Description: Checks if two statcks are equal. Input: 1. stack1: the first stack 2. stack2: the second stack Output: None. Return: 1 if the two statcks are equal. *************************************************/ static int check_iden_kmerList ( STACK * stack1, STACK * stack2 ) { KMER_PT * ite1, *ite2; if ( !stack1->item_c || !stack2->item_c ) // one of them is empty { return 0; } while ( ( ite1 = ( KMER_PT * ) stackPop ( stack1 ) ) != NULL && ( ite2 = ( KMER_PT * ) stackPop ( stack2 ) ) != NULL ) { if ( !KmerEqual ( ite1->kmer, ite2->kmer ) ) { return 0; } } if ( stack1->item_c || stack2->item_c ) // one of them is not empty { return 0; } else { return 1; } } soapdenovo2-240+dfsg.orig/standardPregraph/stack.c0000644000000000000000000000717212166703654020757 0ustar rootroot/* * stack.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stack.h" STACK * createStack ( int num_items, size_t unit_size ) { STACK * newStack = ( STACK * ) malloc ( 1 * sizeof ( STACK ) ); newStack->block_list = NULL; newStack->items_per_block = num_items; newStack->item_size = unit_size; newStack->item_c = 0; return newStack; } void emptyStack ( STACK * astack ) { BLOCK_STARTER * block; if ( !astack || !astack->block_list ) { return; } block = astack->block_list; if ( block->next ) { block = block->next; } astack->block_list = block; astack->item_c = 0; astack->index_in_block = 0; } void freeStack ( STACK * astack ) { BLOCK_STARTER * ite_block, *temp_block; if ( !astack ) { return; } ite_block = astack->block_list; if ( ite_block ) { while ( ite_block->next ) { ite_block = ite_block->next; } } while ( ite_block ) { temp_block = ite_block; ite_block = ite_block->prev; free ( ( void * ) temp_block ); } free ( ( void * ) astack ); } void stackBackup ( STACK * astack ) { astack->block_backup = astack->block_list; astack->index_backup = astack->index_in_block; astack->item_c_backup = astack->item_c; } void stackRecover ( STACK * astack ) { astack->block_list = astack->block_backup; astack->index_in_block = astack->index_backup; astack->item_c = astack->item_c_backup; } void * stackPop ( STACK * astack ) { BLOCK_STARTER * block; if ( !astack || !astack->block_list || !astack->item_c ) { return NULL; } astack->item_c--; block = astack->block_list; if ( astack->index_in_block == 1 ) { if ( block->next ) { astack->block_list = block->next; astack->index_in_block = astack->items_per_block; } else { astack->index_in_block = 0; astack->item_c = 0; } return ( void * ) ( ( void * ) block + sizeof ( BLOCK_STARTER ) ); } return ( void * ) ( ( void * ) block + sizeof ( BLOCK_STARTER ) + astack->item_size * ( --astack->index_in_block ) ); } void * stackPush ( STACK * astack ) { BLOCK_STARTER * block; if ( !astack ) { return NULL; } astack->item_c++; if ( !astack->block_list || ( astack->index_in_block == astack->items_per_block && !astack->block_list->prev ) ) { block = malloc ( sizeof ( BLOCK_STARTER ) + astack->items_per_block * astack->item_size ); block->prev = NULL; if ( astack->block_list ) { astack->block_list->prev = block; } block->next = astack->block_list; astack->block_list = block; astack->index_in_block = 1; return ( void * ) ( ( void * ) block + sizeof ( BLOCK_STARTER ) ); } else if ( astack->index_in_block == astack->items_per_block && astack->block_list->prev ) { astack->block_list = astack->block_list->prev; astack->index_in_block = 1; return ( void * ) ( ( void * ) astack->block_list + sizeof ( BLOCK_STARTER ) ); } block = astack->block_list; return ( void * ) ( ( void * ) block + sizeof ( BLOCK_STARTER ) + astack->item_size * astack->index_in_block++ ); } soapdenovo2-240+dfsg.orig/standardPregraph/attachPEinfo.c0000644000000000000000000003505112166703654022214 0ustar rootroot/* * attachPEinfo.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #include "stack.h" #include "zlib.h" #define CNBLOCKSIZE 10000 static STACK * isStack; static int ignorePE1, ignorePE2, ignorePE3, static_flag; static int onsameCtgPE; static unsigned long long peSUM; static boolean staticF; static int existCounter; static int calcuIS ( STACK * intStack ); static int cmp_pe ( const void * a, const void * b ) { PE_INFO * A, *B; A = ( PE_INFO * ) a; B = ( PE_INFO * ) b; if ( A->rank > B->rank ) { return 1; } else if ( A->rank == B->rank ) { return 0; } else { return -1; } } /************************************************* Function: loadPEgrads Description: Loads general mapped information of paired-end reads. Input: 1. infile: prefix of output graph file name Output: None. Return: None. *************************************************/ void loadPEgrads ( char * infile ) { FILE * fp; char name[256], line[1024]; int i; boolean rankSet = 1; sprintf ( name, "%s.peGrads", infile ); fp = fopen ( name, "r" ); if ( !fp ) { fprintf ( stderr, "Can not open file %s.\n", name ); gradsCounter = 0; return; } while ( fgets ( line, sizeof ( line ), fp ) != NULL ) { if ( line[0] == 'g' ) { sscanf ( line + 10, "%d %lld %d", &gradsCounter, &n_solexa, &maxReadLen ); fprintf ( stderr, "There are %d grad(s), %lld read(s), max read len %d.\n", gradsCounter, n_solexa, maxReadLen ); break; } } alloc_pe_mem ( gradsCounter ); for ( i = 0; i < gradsCounter; i++ ) { fgets ( line, sizeof ( line ), fp ); pes[i].rank = 0; sscanf ( line, "%d %lld %d %d", & ( pes[i].insertS ), & ( pes[i].PE_bound ), & ( pes[i].rank ), & ( pes[i].pair_num_cut ) ); if ( pes[i].rank < 1 ) { rankSet = 0; } } fclose ( fp ); if ( rankSet ) { qsort ( &pes[0], gradsCounter, sizeof ( PE_INFO ), cmp_pe ); return; } int lastRank = 0; for ( i = 0; i < gradsCounter; i++ ) { if ( i == 0 ) { pes[i].rank = ++lastRank; } else if ( pes[i].insertS < 300 ) { pes[i].rank = lastRank; } else if ( pes[i].insertS < 800 ) { if ( pes[i - 1].insertS < 300 ) { pes[i].rank = ++lastRank; } else { pes[i].rank = lastRank; } } else if ( pes[i].insertS < 3000 ) { if ( pes[i - 1].insertS < 800 ) { pes[i].rank = ++lastRank; } else { pes[i].rank = lastRank; } } else if ( pes[i].insertS < 7000 ) { if ( pes[i - 1].insertS < 3000 ) { pes[i].rank = ++lastRank; } else { pes[i].rank = lastRank; } } else { if ( pes[i - 1].insertS < 7000 ) { pes[i].rank = ++lastRank; } else { pes[i].rank = lastRank; } } } } /************************************************* Function: add1Connect Description: Updates the connection between two contigs. Input: 1. e1: left contig 2. e2: right contig 3. gap: distance between two contigs 4. weight: weight of connection 5. inherit: inheritance flag of connection Output: None. Return: NULL if failed adding, otherwise the pointer to new or updated connection. *************************************************/ CONNECT * add1Connect ( unsigned int e1, unsigned int e2, int gap, int weight, boolean inherit ) { if ( e1 == e2 || e1 == getTwinCtg ( e2 ) ) { return NULL; } CONNECT * connect = NULL, *bal_connect = NULL; long long sum; if ( weight > 255 ) { weight = 255; } connect = getCntBetween ( e1, e2 ); bal_connect = getCntBetween ( e2, e1 ); if ( connect ) { if ( !weight ) { return connect; } existCounter++; if ( !inherit ) { sum = connect->weightNotInherit * connect->gapLen + gap * weight; connect->gapLen = sum / ( connect->weightNotInherit + weight ); if ( connect->weightNotInherit + weight <= 255 ) { connect->weightNotInherit += weight; } else if ( connect->weightNotInherit < 255 ) { connect->weightNotInherit = 255; } } else { sum = connect->weight * connect->gapLen + gap * weight; connect->gapLen = sum / ( connect->weight + weight ); if ( !connect->inherit ) { connect->maxSingleWeight = connect->weightNotInherit; } connect->inherit = 1; connect->maxSingleWeight = connect->maxSingleWeight > weight ? connect->maxSingleWeight : weight; } if ( connect->weight + weight <= 255 ) { connect->weight += weight; } else if ( connect->weight < 255 ) { connect->weight = 255; } } else { newCntCounter++; connect = allocateCN ( e2, gap ); if ( cntLookupTable ) { putCnt2LookupTable ( e1, connect ); } connect->weight = weight; if ( contig_array[e1].mask || contig_array[e2].mask ) { connect->mask = 1; } connect->next = contig_array[e1].downwardConnect; contig_array[e1].downwardConnect = connect; if ( !inherit ) { connect->weightNotInherit = weight; } else { connect->weightNotInherit = 0; connect->inherit = 1; connect->maxSingleWeight = weight; } } return connect; } /************************************************* Function: attach1PE Description: Checks paired-end relation between two contigs, and updates the connection between contigs if the relation is fine. Input: 1. e1: left contig 2. pre_pos: read1's start position on left contig 3. bal_e2: right contig in reversed direction 4. pos: read2's start position on right contig 5. insert_size: insert size of paired-end reads Output: None. Return: -1 if left contig and the reversed right contig were the same contig . 0 if the calculated distance between contigs was abnormal. 1 if paired-end relation was normal. 2 if read1 and read2 were aligned to the same contig. *************************************************/ int attach1PE ( unsigned int e1, int pre_pos, unsigned int bal_e2, int pos, int insert_size ) { int gap, realpeSize; unsigned int bal_e1, e2; if ( e1 == bal_e2 ) { ignorePE1++; return -1; //orientation wrong } bal_e1 = getTwinCtg ( e1 ); e2 = getTwinCtg ( bal_e2 ); if ( e1 == e2 ) { realpeSize = contig_array[e1].length + overlaplen - pre_pos - pos; if ( realpeSize > 0 ) { peSUM += realpeSize; onsameCtgPE++; if ( ( int ) contig_array[e1].length > insert_size ) { int * item = ( int * ) stackPush ( isStack ); ( *item ) = realpeSize; } } return 2; } gap = insert_size - overlaplen + pre_pos + pos - contig_array[e1].length - contig_array[e2].length; if ( gap < - ( insert_size / 10 ) ) { ignorePE2++; return 0; } if ( gap > insert_size ) { ignorePE3++; return 0; } add1Connect ( e1, e2, gap, 1, 0 ); add1Connect ( bal_e2, bal_e1, gap, 1, 0 ); return 1; } /************************************************* Function: connectByPE_grad Description: Loads alignment information of paired-end reads of specified LIB and updates connection between contigs. Input: 1. fp: alignment information file 2. peGrad: LIB number 3. line: buffer to store one alignment record Output: None. Return: Loaded alignment record number. *************************************************/ int connectByPE_grad ( FILE * fp, int peGrad, char * line ) { long long pre_readno, readno, minno, maxno; int pre_pos, pos, flag, PE, count = 0, Total_PE = 0; unsigned int pre_contigno, contigno, newIndex; if ( peGrad < 0 || peGrad > gradsCounter ) { fprintf ( stderr, "Specified pe grad is out of bound.\n" ); return 0; } maxno = pes[peGrad].PE_bound; if ( peGrad == 0 ) { minno = 0; } else { minno = pes[peGrad - 1].PE_bound; } onsameCtgPE = peSUM = 0; PE = pes[peGrad].insertS; if ( strlen ( line ) ) { sscanf ( line, "%lld %d %d", &pre_readno, &pre_contigno, &pre_pos ); if ( pre_readno <= minno ) { pre_readno = -1; } } else { pre_readno = -1; } ignorePE1 = ignorePE2 = ignorePE3 = 0; static_flag = 1; isStack = ( STACK * ) createStack ( CNBLOCKSIZE, sizeof ( int ) ); while ( fgets ( line, lineLen, fp ) != NULL ) { sscanf ( line, "%lld %d %d", &readno, &contigno, &pos ); if ( readno > maxno ) { break; } if ( readno <= minno ) { continue; } newIndex = index_array[contigno]; if ( isSameAsTwin ( newIndex ) ) { continue; } if ( PE && ( readno % 2 == 0 ) && ( pre_readno == readno - 1 ) ) // they are a pair of reads { Total_PE++; flag = attach1PE ( pre_contigno, pre_pos, newIndex, pos, PE ); if ( flag == 1 ) { count++; } } pre_readno = readno; pre_contigno = newIndex; pre_pos = pos; } fprintf ( stderr, "For insert size: %d\n", PE ); fprintf ( stderr, " Total PE links %d\n", Total_PE ); fprintf ( stderr, " Normal PE links on same contig %d\n", onsameCtgPE ); fprintf ( stderr, " Abnormal PE links on same contig %d\n", ignorePE1 ); fprintf ( stderr, " PE links of minus distance %d\n", ignorePE2 ); fprintf ( stderr, " PE links of plus distance %d\n", ignorePE3 ); fprintf ( stderr, " Correct PE links %d\n", count ); fprintf ( stderr, " Accumulated connections %d\n", newCntCounter ); fprintf ( stderr, "Use contigs longer than %d to estimate insert size: \n", PE ); fprintf ( stderr, " PE links %d\n", isStack->item_c ); calcuIS ( isStack ); freeStack ( isStack ); return count; } /************************************************* Function: connectByPE_grad_gz Description: Loads alignment information of paired-end reads of specified LIB and updates connection between contigs. Input: 1. fp: alignment information file in gz format 2. peGrad: LIB number 3. line: buffer to store one alignment record Output: None. Return: Loaded alignment record number. *************************************************/ int connectByPE_grad_gz ( gzFile * fp, int peGrad, char * line ) { long long pre_readno, readno, minno, maxno; int pre_pos, pos, flag, PE, count = 0, Total_PE = 0; unsigned int pre_contigno, contigno, newIndex; if ( peGrad < 0 || peGrad > gradsCounter ) { fprintf ( stderr, "Specified pe grad is out of bound.\n" ); return 0; } maxno = pes[peGrad].PE_bound; if ( peGrad == 0 ) { minno = 0; } else { minno = pes[peGrad - 1].PE_bound; } onsameCtgPE = peSUM = 0; PE = pes[peGrad].insertS; if ( strlen ( line ) ) { sscanf ( line, "%lld %d %d", &pre_readno, &pre_contigno, &pre_pos ); if ( pre_readno <= minno ) { pre_readno = -1; } } else { pre_readno = -1; } ignorePE1 = ignorePE2 = ignorePE3 = 0; static_flag = 1; isStack = ( STACK * ) createStack ( CNBLOCKSIZE, sizeof ( int ) ); while ( gzgets ( fp, line, lineLen ) != NULL ) { sscanf ( line, "%lld %d %d", &readno, &contigno, &pos ); if ( readno > maxno ) { break; } if ( readno <= minno ) { continue; } newIndex = index_array[contigno]; if ( isSameAsTwin ( newIndex ) ) { continue; } if ( PE && ( readno % 2 == 0 ) && ( pre_readno == readno - 1 ) ) // they are a pair of reads { Total_PE++; flag = attach1PE ( pre_contigno, pre_pos, newIndex, pos, PE ); if ( flag == 1 ) { count++; } } pre_readno = readno; pre_contigno = newIndex; pre_pos = pos; } fprintf ( stderr, "For insert size: %d\n", PE ); fprintf ( stderr, " Total PE links %d\n", Total_PE ); fprintf ( stderr, " Normal PE links on same contig %d\n", onsameCtgPE ); fprintf ( stderr, " Incorrect oriented PE links %d\n", ignorePE1 ); fprintf ( stderr, " PE links of too small insert size %d\n", ignorePE2 ); fprintf ( stderr, " PE links of too large insert size %d\n", ignorePE3 ); fprintf ( stderr, " Correct PE links %d\n", count ); fprintf ( stderr, " Accumulated connections %d\n", newCntCounter ); fprintf ( stderr, "Use contigs longer than %d to estimate insert size: \n", PE ); fprintf ( stderr, " PE links %d\n", isStack->item_c ); calcuIS ( isStack ); freeStack ( isStack ); return count; } /************************************************* Function: calcuIS Description: Calculates insert size of LIB using paired-end reads that both reads were aligned to the same contig. Input: 1. intStack: stack storing the alignment information Output: None. Return: Calculated insert size. *************************************************/ static int calcuIS ( STACK * intStack ) { long long sum = 0; int avg = 0; int * item; int num = intStack->item_c; if ( num < 100 ) { fprintf ( stderr, "Too few PE links.\n" ); return avg; } stackBackup ( intStack ); while ( ( item = ( int * ) stackPop ( intStack ) ) != NULL ) { sum += *item; } stackRecover ( intStack ); num = intStack->item_c; avg = sum / num; sum = 0; stackBackup ( intStack ); while ( ( item = ( int * ) stackPop ( intStack ) ) != NULL ) { sum += ( ( long long ) * item - avg ) * ( ( long long ) * item - avg ); } int SD = sqrt ( sum / ( num - 1 ) ); if ( SD == 0 ) { fprintf ( stderr, " Average insert size %d\n SD %d\n", avg, SD ); return avg; } stackRecover ( intStack ); sum = num = 0; while ( ( item = ( int * ) stackPop ( intStack ) ) != NULL ) if ( abs ( *item - avg ) < 3 * SD ) { sum += *item; num++; } if ( num == 0 ) { avg = 0; } else { avg = sum / num; } fprintf ( stderr, " Average insert size %d\n SD %d\n", avg, SD ); return avg; } unsigned int getTwinCtg ( unsigned int ctg ) { return ctg + contig_array[ctg].bal_edge - 1; } boolean isSmallerThanTwin ( unsigned int ctg ) { return contig_array[ctg].bal_edge > 1; } boolean isLargerThanTwin ( unsigned int ctg ) { return contig_array[ctg].bal_edge < 1; } boolean isSameAsTwin ( unsigned int ctg ) { return contig_array[ctg].bal_edge == 1; } soapdenovo2-240+dfsg.orig/standardPregraph/map.c0000644000000000000000000001422212166703654020421 0ustar rootroot/* * map.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" static void initenv ( int argc, char ** argv ); static char shortrdsfile[256]; static char graphfile[256]; static void display_map_usage (); /************************************************* Function: getMinOverlap Description: Parses file *.preGraphBasic, and get vertex number, K size, MaxReadLen, MinReadLen, MaxNameLen. Input: 1. gfile the graph file prefix Output: None. Return: The kmer size. *************************************************/ static int getMinOverlap ( char * gfile ) { char name[256], ch; FILE * fp; int num_kmer, overlaplen = 23; char line[1024]; sprintf ( name, "%s.preGraphBasic", gfile ); fp = fopen ( name, "r" ); if ( !fp ) { return overlaplen; } while ( fgets ( line, sizeof ( line ), fp ) != NULL ) { if ( line[0] == 'V' ) { sscanf ( line + 6, "%d %c %d", &num_kmer, &ch, &overlaplen ); } else if ( line[0] == 'M' ) { sscanf ( line, "MaxReadLen %d MinReadLen %d MaxNameLen %d", &maxReadLen, &minReadLen, &maxNameLen ); } } fclose ( fp ); return overlaplen; } /************************************************* Function: call_align Description: This is the main function for map step. It includes the following steps: 1.Chops contig (>=k+2) into kmer sets, marks the kmer occured twice or more as deleted, records the unique kmers related contig's id and the position of the kmer on the contig. 2.Maps reads to edges. Input: @see display_map_usage() Output: Below files: 1. *.readOnCtg.gz 2. *.readInGap.gz Return: 0 if exits normally. *************************************************/ int call_align ( int argc, char ** argv ) { time_t start_t, stop_t, time_bef, time_aft; time ( &start_t ); fprintf ( stderr, "\n********************\n" ); fprintf ( stderr, "Map\n" ); fprintf ( stderr, "********************\n\n" ); initenv ( argc, argv ); overlaplen = getMinOverlap ( graphfile ); #ifdef MER127 if ( smallKmer > 12 && smallKmer < 128 && smallKmer % 2 == 1 ) { deltaKmer = overlaplen - smallKmer; overlaplen = smallKmer; } #else if ( smallKmer > 12 && smallKmer < 64 && smallKmer % 2 == 1 ) { deltaKmer = overlaplen - smallKmer; overlaplen = smallKmer; } #endif fprintf ( stderr, "Kmer size: %d.\n", overlaplen ); time ( &time_bef ); ctg_short = overlaplen + 2; fprintf ( stderr, "Contig length cutoff: %d.\n", ctg_short ); prlContig2nodes ( graphfile, ctg_short ); time ( &time_aft ); fprintf ( stderr, "Time spent on graph construction: %ds.\n\n", ( int ) ( time_aft - time_bef ) ); //map long read (asm_flags=4) to edge one by one time ( &time_bef ); prlLongRead2Ctg ( shortrdsfile, graphfile ); time ( &time_aft ); fprintf ( stderr, "Time spent on aligning long reads: %ds.\n\n", ( int ) ( time_aft - time_bef ) ); //map read to edge one by one time ( &time_bef ); prlRead2Ctg ( shortrdsfile, graphfile ); time ( &time_aft ); fprintf ( stderr, "Time spent on aligning reads: %ds.\n\n", ( int ) ( time_aft - time_bef ) ); free_Sets ( KmerSets, thrd_num ); time ( &stop_t ); fprintf ( stderr, "Overall time spent on alignment: %dm.\n\n", ( int ) ( stop_t - start_t ) / 60 ); return 0; } /***************************************************************************** * Parse command line switches *****************************************************************************/ void initenv ( int argc, char ** argv ) { int copt; int inpseq, outseq; extern char * optarg; char temp[100]; optind = 1; inpseq = outseq = 0; fprintf ( stderr, "Parameters: map " ); while ( ( copt = getopt ( argc, argv, "s:g:K:p:k:f" ) ) != EOF ) { //printf("get option\n"); switch ( copt ) { case 's': fprintf ( stderr, "-s %s ", optarg ); inpseq = 1; sscanf ( optarg, "%s", shortrdsfile ); break; case 'g': fprintf ( stderr, "-g %s ", optarg ); outseq = 1; sscanf ( optarg, "%s", graphfile ); break; case 'K': fprintf ( stderr, "-K %s ", optarg ); sscanf ( optarg, "%s", temp ); overlaplen = atoi ( temp ); break; case 'p': fprintf ( stderr, "-p %s ", optarg ); sscanf ( optarg, "%s", temp ); thrd_num = atoi ( temp ); break; case 'k': fprintf ( stderr, "-k %s ", optarg ); sscanf ( optarg, "%s", temp ); smallKmer = atoi ( temp ); break; case 'f': fill = 1; fprintf ( stderr, "-f " ); break; default: if ( inpseq == 0 || outseq == 0 ) { display_map_usage (); exit ( 1 ); } } } fprintf ( stderr, "\n\n" ); if ( inpseq == 0 || outseq == 0 ) { display_map_usage (); exit ( 1 ); } } static void display_map_usage () { fprintf ( stderr, "\nmap -s configFile -g inputGraph [-f] [-p n_cpu -k kmer_R2C]\n" ); fprintf ( stderr, " -s configFile: the config file of solexa reads\n" ); fprintf ( stderr, " -g inputGraph: prefix of input graph file names\n" ); fprintf ( stderr, " -f (optional) output gap related reads in map step for using SRkgf to fill gap, [NO]\n" ); fprintf ( stderr, " -p n_cpu: number of cpu for use, [8]\n" ); #ifdef MER127 fprintf ( stderr, " -k kmer_R2C(min 13, max 127): kmer size used for mapping read to contig, [K]\n" ); #else fprintf ( stderr, " -k kmer_R2C(min 13, max 63): kmer size used for mapping read to contig, [K]\n" ); #endif } soapdenovo2-240+dfsg.orig/standardPregraph/readseq1by1.c0000644000000000000000000006230112166703654021766 0ustar rootroot/* * readseq1by1.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #include #include "bam.h" #include "faidx.h" #include "knetfile.h" #include "sam_view.h" #include "xcurses.h" #include "zlib.h" #include "bgzf.h" #include "glf.h" #include "kstring.h" #include "razf.h" #include "sam_header.h" #include "zconf.h" static char src_rc_seq[1024]; static int state = -3; static int readstate = 0; boolean change = 1; //static boolean multi=0; //atic long curr_pos; void readseq1by1 ( char * src_seq, char * src_name, int * len_seq, FILE * fp, long long num_seq ) { int i, k, n, strL; char c; int lineLen = gLineLen; char tmpStr[lineLen]; char * str; if ( gStr == NULL ) { str = tmpStr; } else { str = gStr; lineLen = maxReadLen + 1; } n = 0; k = num_seq; while ( fgets ( str, lineLen, fp ) ) { if ( str[0] == '#' ) { continue; } if ( str[0] == '>' ) { /* if(k >= 0) { // if this isn't the first '>' in the file *len_seq = n; } */ /* if(multi) { curr_pos=ftell(fp); } */ *len_seq = n; n = 0; sscanf ( &str[1], "%s", src_name ); return; } else { strL = strlen ( str ); if ( strL + n > maxReadLen ) { strL = maxReadLen - n; } for ( i = 0; i < strL; i++ ) { if ( str[i] >= 'a' && str[i] <= 'z' ) { c = base2int ( str[i] - 'a' + 'A' ); src_seq[n++] = c; } else if ( str[i] >= 'A' && str[i] <= 'Z' ) { c = base2int ( str[i] ); src_seq[n++] = c; // after pre-process all the symbles would be a,g,c,t,n in lower or upper case. } else if ( str[i] == '.' ) { c = base2int ( 'A' ); src_seq[n++] = c; } // after pre-process all the symbles would be a,g,c,t,n in lower or upper case. } //printf("%d: %d\n",k,n); } } if ( k >= 0 ) { *len_seq = n; return; } *len_seq = 0; } void readseqInBuf ( char * src_seq, char * src_name, int * len_seq, char * buf, int * start, int offset ) { int i, n, strL, m, p; char c; int lineLen = gLineLen; char tmpStr[lineLen]; char * str; if ( gStr == NULL ) { str = tmpStr; } else { str = gStr; lineLen = maxReadLen + 1; } n = 0; for ( m = *start; m < offset; m++ ) { if ( buf[m] == '>' ) { p = m; } else if ( buf[m] == '\n' && buf[p] == '>' ) { memcpy ( src_name, &buf[p + 1], m - p - 1 ); //get name p = m; } else if ( buf[m] == '\n' && buf[p] == '\n' ) { memcpy ( str, &buf[p + 1], m - p - 1 ); //get seq //p = m; str[m - p - 1] = '\0'; *start = m + 1; strL = strlen ( str ); if ( strL + n > maxReadLen ) { strL = maxReadLen - n; } for ( i = 0; i < strL; i++ ) { if ( str[i] >= 'a' && str[i] <= 'z' ) { c = base2int ( str[i] - 'a' + 'A' ); src_seq[n++] = c; } else if ( str[i] >= 'A' && str[i] <= 'Z' ) { c = base2int ( str[i] ); src_seq[n++] = c; // after pre-process all the symbles would be a,g,c,t,n in lower or upper case. } else if ( str[i] == '.' ) { c = base2int ( 'A' ); src_seq[n++] = c; } // after pre-process all the symbles would be a,g,c,t,n in lower or upper case. } break; //printf("%d: %d\n",k,n); } } *len_seq = n; return; } /************************************************* Function: readseqpar Description: Parses a contig file to get the max contig length, the min contig length, the max name length. Input: 1. fp: the contig file Output: 1. max_leg: the max contig length 2. min_leg: the min contig length 3. max_name_leg: the max name length Return: The contig number. *************************************************/ long long readseqpar ( int * max_leg, int * min_leg, int * max_name_leg, FILE * fp ) { int l, n; long long k; char str[5000], src_name[5000]; n = 0; k = -1; while ( fgets ( str, 4950, fp ) ) { if ( str[0] == '>' ) { if ( k >= 0 ) { if ( n > *max_leg ) { *max_leg = n; } if ( n < *min_leg ) { *min_leg = n; } } n = 0; k++; sscanf ( &str[1], "%s", src_name ); if ( ( l = strlen ( src_name ) ) > *max_name_leg ) { *max_name_leg = l; } } else { n += strlen ( str ) - 1; } } if ( n > *max_leg ) { *max_leg = n; } if ( n < *min_leg ) { *min_leg = n; } k++; return ( k ); } void readseqfq ( char * src_seq, char * src_name, int * len_seq, char * buf, int * start, int offset ) { int i, n, strL, m, p = 0; char c; int lineLen = gLineLen; char tmpStr[lineLen]; char * str; if ( gStr == NULL ) { str = tmpStr; } else { str = gStr; lineLen = maxReadLen + 1; } n = 0; for ( m = *start; m < offset; m++ ) { if ( buf[m] == '@' ) { p = m; } else if ( buf[m] == '\n' && buf[p] == '@' ) { memcpy ( src_name, &buf[p + 1], m - p - 1 ); p = m; } else if ( buf[m] == '\n' && buf[p] == '\n' && m > p ) { //p = m; memcpy ( str, &buf[p + 1], m - p - 1 ); str[m - p - 1] = '\0'; strL = strlen ( str ); if ( strL + n > maxReadLen ) { strL = maxReadLen - n; } for ( i = 0; i < strL; i++ ) { if ( str[i] >= 'a' && str[i] <= 'z' ) { c = base2int ( str[i] - 'a' + 'A' ); src_seq[n++] = c; } else if ( str[i] >= 'A' && str[i] <= 'Z' ) { c = base2int ( str[i] ); src_seq[n++] = c; // after pre-process all the symbles would be a,g,c,t,n in lower or upper case. } else if ( str[i] == '.' ) { c = base2int ( 'A' ); src_seq[n++] = c; } } for ( m++; buf[m] != '\n'; m++ ) { ; } *start = ( m + 2 + strlen ( str ) ); break; } /* else if (buf[m] == '\n' && buf[p] == '+' && buf[m - 1] != '+') { *start = m + 1; break; }*/ } *len_seq = n; return; } void read1seqfq ( char * src_seq, char * src_name, int * len_seq, FILE * fp ) { int i, n, strL; char c; int lineLen = gLineLen; char tmpStr[lineLen]; char * str; if ( gStr == NULL ) { str = tmpStr; } else { str = gStr; lineLen = maxReadLen + 1; } boolean flag = 0; while ( fgets ( str, lineLen, fp ) ) { if ( str[0] == '@' ) { flag = 1; sscanf ( &str[1], "%s", src_name ); break; } } if ( !flag ) //last time reading fq file get this { *len_seq = 0; return; } /* if(multi) { curr_pos=ftell(fp); } */ n = 0; while ( fgets ( str, lineLen, fp ) ) { if ( str[0] == '+' ) { fgets ( str, lineLen, fp ); // pass quality value line *len_seq = n; return; } else { strL = strlen ( str ); if ( strL + n > maxReadLen ) { strL = maxReadLen - n; } for ( i = 0; i < strL; i++ ) { if ( str[i] >= 'a' && str[i] <= 'z' ) { c = base2int ( str[i] - 'a' + 'A' ); src_seq[n++] = c; } else if ( str[i] >= 'A' && str[i] <= 'Z' ) { c = base2int ( str[i] ); src_seq[n++] = c; // after pre-process all the symbles would be a,g,c,t,n in lower or upper case. } else if ( str[i] == '.' ) { c = base2int ( 'A' ); src_seq[n++] = c; } // after pre-process all the symbles would be a,g,c,t,n in lower or upper case. } } } *len_seq = n; return; } void read1seqbam ( char * src_seq, char * src_name, int * len_seq, samfile_t * in, int * type, int asm_flag ) //read one sequence from bam file { bam1_t * b = bam_init1 (); char c; char * line1 = NULL; int n = 0; int len; int i, j; char * seq1; unsigned int flag1 = 0; *type = 0; readstate = 0; boolean isGood = true; // if ((readstate = samread (in, b)) >= 0) while ( ( readstate = samread ( in, b ) ) >= 0 ) { if ( !__g_skip_aln ( in->header, b ) ) { line1 = bam_format1_core ( in->header, b, in->type >> 2 & 3 ); } seq1 = strtok ( line1, "\t" ); for ( i = 0; i < 10; i++ ) { if ( i == 0 ) { sscanf ( seq1, "%s", src_name ); } else if ( i == 1 ) { flag1 = atoi ( seq1 ); if ( flag1 & 0x0200 ) //whether it's good or not { if ( asm_flag == 1 ) { isGood = false; break; } switch ( state ) { case -3: state = -2; break; case -2: state = 0; break; case -1: state = 2; break; default: state = -3; } } else { isGood = true; switch ( state ) { case -3: state = -1; break; case -2: state = 1; break; case -1: state = 3; break; default: state = -3; } } } else if ( i == 9 ) //the sequence { len = strlen ( seq1 ); if ( len + n > maxReadLen ) { len = maxReadLen - n; } for ( j = 0; j < len; j++ ) { if ( seq1[j] >= 'a' && seq1[j] <= 'z' ) { c = base2int ( seq1[j] - 'a' + 'A' ); src_seq[n++] = c; } else if ( seq1[j] >= 'A' && seq1[j] <= 'Z' ) { c = base2int ( seq1[j] ); src_seq[n++] = c; // after pre-process all the symbles would be a,g,c,t,n in lower or upper case. } else if ( seq1[j] == '.' ) { c = base2int ( 'A' ); src_seq[n++] = c; } // after pre-process all the symbles would be a,g,c,t,n in lower or upper case. } if ( 3 == state ) { state = -3; } else { if ( 0 == state || 1 == state || 2 == state ) { state = -3; *type = -1; } } } seq1 = strtok ( NULL, "\t" ); } if ( isGood ) { break; } } if ( readstate < 0 ) { state = -3; } free ( line1 ); bam_destroy1 ( b ); *len_seq = n; } // find the next file to open in libs int nextValidIndex ( int libNo, boolean pair, unsigned char asm_ctg ) { int i = libNo; while ( i < num_libs ) { if ( asm_ctg == 1 && ( lib_array[i].asm_flag != 1 && lib_array[i].asm_flag != 3 ) ) { i++; continue; } else if ( asm_ctg == 0 && ( lib_array[i].asm_flag != 2 && lib_array[i].asm_flag != 3 ) ) { i++; continue; } else if ( asm_ctg > 1 && lib_array[i].asm_flag != asm_ctg ) // reads for other purpose { i++; continue; } if ( lib_array[i].curr_type == 1 && lib_array[i].curr_index < lib_array[i].num_a1_file ) { return i; } if ( lib_array[i].curr_type == 2 && lib_array[i].curr_index < lib_array[i].num_q1_file ) { return i; } if ( lib_array[i].curr_type == 3 && lib_array[i].curr_index < lib_array[i].num_p_file ) { return i; } if ( lib_array[i].curr_type == 4 && lib_array[i].curr_index < lib_array[i].num_b_file ) { return i; } if ( pair ) { if ( lib_array[i].curr_type < 4 ) { lib_array[i].curr_type++; lib_array[i].curr_index = 0; } else { i++; } continue; } if ( lib_array[i].curr_type == 5 && lib_array[i].curr_index < lib_array[i].num_s_a_file ) { return i; } if ( lib_array[i].curr_type == 6 && lib_array[i].curr_index < lib_array[i].num_s_q_file ) { return i; } if ( lib_array[i].curr_type < 6 ) { lib_array[i].curr_type++; lib_array[i].curr_index = 0; } else { i++; } } //for each lib return i; } static FILE * openFile4read ( char * fname ) { FILE * fp; int i, j = 0; char str_sub[4]; for ( i = strlen ( fname ) - 1; i >= 0; i-- ) { if ( fname[i] == ' ' ) { j++; } else { break; } } for ( i = 0; i < 3; i++ ) { str_sub[i] = fname[strlen ( fname ) - 3 - j + i]; } str_sub[3] = '\0'; if ( strlen ( fname ) > 3 && strcmp ( str_sub, ".gz" ) == 0 ) { char * cmd = ( char * ) ckalloc ( ( strlen ( fname ) + 20 ) * sizeof ( char ) ); sprintf ( cmd, "gzip -dc %s", fname ); fp = popen ( cmd, "r" ); free ( cmd ); return fp; } else { fname[strlen ( fname ) - j] = '\0'; return ckopen ( fname, "r" ); } } static samfile_t * openFile4readb ( char * fname ) //open file to read bam file { samfile_t * in; char * fn_list = 0; if ( ( in = ( samfile_t * ) samopen ( fname, "rb", fn_list ) ) == 0 ) { fprintf ( stderr, "Cannot open %s. Now exit to system...\n", fname ); exit ( -1 ); } if ( in->header == 0 ) { fprintf ( stderr, "Cannot read the header.\n" ); exit ( -1 ); } return ( in ); } void openFileInLib ( int libNo ) { int i = libNo; if ( lib_array[i].curr_type == 1 ) { fprintf ( stderr, "Import reads from file:\n %s\n", lib_array[i].a1_fname[lib_array[i].curr_index] ); fprintf ( stderr, "Import reads from file:\n %s\n", lib_array[i].a2_fname[lib_array[i].curr_index] ); lib_array[i].fp1 = openFile4read ( lib_array[i].a1_fname[lib_array[i].curr_index] ); lib_array[i].fp2 = openFile4read ( lib_array[i].a2_fname[lib_array[i].curr_index] ); lib_array[i].curr_index++; lib_array[i].paired = 1; } else if ( lib_array[i].curr_type == 2 ) { fprintf ( stderr, "Import reads from file:\n %s\n", lib_array[i].q1_fname[lib_array[i].curr_index] ); fprintf ( stderr, "Import reads from file:\n %s\n", lib_array[i].q2_fname[lib_array[i].curr_index] ); lib_array[i].fp1 = openFile4read ( lib_array[i].q1_fname[lib_array[i].curr_index] ); lib_array[i].fp2 = openFile4read ( lib_array[i].q2_fname[lib_array[i].curr_index] ); lib_array[i].curr_index++; lib_array[i].paired = 1; } else if ( lib_array[i].curr_type == 3 ) { fprintf ( stderr, "Import reads from file:\n %s\n", lib_array[i].p_fname[lib_array[i].curr_index] ); lib_array[i].fp1 = openFile4read ( lib_array[i].p_fname[lib_array[i].curr_index] ); lib_array[i].curr_index++; lib_array[i].paired = 0; } else if ( lib_array[i].curr_type == 5 ) { fprintf ( stderr, "Import reads from file:\n %s\n", lib_array[i].s_a_fname[lib_array[i].curr_index] ); lib_array[i].fp1 = openFile4read ( lib_array[i].s_a_fname[lib_array[i].curr_index] ); lib_array[i].curr_index++; lib_array[i].paired = 0; } else if ( lib_array[i].curr_type == 6 ) { fprintf ( stderr, "Import reads from file:\n %s\n", lib_array[i].s_q_fname[lib_array[i].curr_index] ); lib_array[i].fp1 = openFile4read ( lib_array[i].s_q_fname[lib_array[i].curr_index] ); lib_array[i].curr_index++; lib_array[i].paired = 0; } else if ( lib_array[i].curr_type == 4 ) { fprintf ( stderr, "Import reads from file:\n %s\n", lib_array[i].b_fname[lib_array[i].curr_index] ); lib_array[i].fp3 = openFile4readb ( lib_array[i].b_fname[lib_array[i].curr_index] ); lib_array[i].curr_index++; lib_array[i].paired = 0; } } static void reverse2k ( char * src_seq, int len_seq ) { if ( !len_seq ) { return; } int i; reverseComplementSeq ( src_seq, len_seq, src_rc_seq ); for ( i = 0; i < len_seq; i++ ) { src_seq[i] = src_rc_seq[i]; } } void closeFp1InLab ( int libNo ) { int ftype = lib_array[libNo].curr_type; int index = lib_array[libNo].curr_index - 1; char * fname; int i, j = 0; char str_sub[4]; if ( ftype == 1 ) { fname = lib_array[libNo].a1_fname[index]; } else if ( ftype == 2 ) { fname = lib_array[libNo].q1_fname[index]; } else if ( ftype == 3 ) { fname = lib_array[libNo].p_fname[index]; } else if ( ftype == 5 ) { fname = lib_array[libNo].s_a_fname[index]; } else if ( ftype == 6 ) { fname = lib_array[libNo].s_q_fname[index]; } else if ( ftype == 4 ) { fname = lib_array[libNo].b_fname[index]; } else { return; } if ( ftype == 4 ) { samclose ( lib_array[libNo].fp3 ); //close file3 } else { for ( i = strlen ( fname ) - 1; i >= 0; i-- ) { if ( fname[i] == ' ' ) { j++; } else { break; } } for ( i = 0; i < 3; i++ ) { str_sub[i] = fname[strlen ( fname ) - 3 - j + i]; } str_sub[3] = '\0'; if ( strlen ( fname ) > 3 && strcmp ( str_sub, ".gz" ) == 0 ) { pclose ( lib_array[libNo].fp1 ); } else { fclose ( lib_array[libNo].fp1 ); } } } void closeFp2InLab ( int libNo ) { int ftype = lib_array[libNo].curr_type; int index = lib_array[libNo].curr_index - 1; char * fname; int i, j = 0; char str_sub[4]; if ( ftype == 1 ) { fname = lib_array[libNo].a2_fname[index]; } else if ( ftype == 2 ) { fname = lib_array[libNo].q2_fname[index]; } else { return; } for ( i = strlen ( fname ) - 1; i >= 0; i-- ) { if ( fname[i] == ' ' ) { j++; } else { break; } } for ( i = 0; i < 3; i++ ) { str_sub[i] = fname[strlen ( fname ) - 3 - j + i]; } str_sub[3] = '\0'; if ( strlen ( fname ) > 3 && strcmp ( str_sub, ".gz" ) == 0 ) { pclose ( lib_array[libNo].fp2 ); } else { fclose ( lib_array[libNo].fp2 ); } } boolean readseqInLib ( char * src_seq, char * src_name, int * len_seq, char * buf, int * start, int offset, int i ) { if ( lib_array[i].curr_type == 1 ) { if ( lib_array[i].paired == 1 ) { readseqInBuf ( src_seq, src_name, len_seq, buf, start, offset ); if ( lib_array[i].reverse ) { reverse2k ( src_seq, *len_seq ); } lib_array[i].paired = 2; n_solexa++; return 1; } else { readseqInBuf ( src_seq, src_name, len_seq, buf, start, offset ); if ( lib_array[i].reverse ) { reverse2k ( src_seq, *len_seq ); } lib_array[i].paired = 1; n_solexa++; return 1; //can't fail to read a read2 } } if ( lib_array[i].curr_type == 2 ) { if ( lib_array[i].paired == 1 ) { readseqfq ( src_seq, src_name, len_seq, buf, start, offset ); if ( lib_array[i].reverse ) { reverse2k ( src_seq, *len_seq ); } lib_array[i].paired = 2; n_solexa++; return 1; } else { readseqfq ( src_seq, src_name, len_seq, buf, start, offset ); if ( lib_array[i].reverse ) { reverse2k ( src_seq, *len_seq ); } lib_array[i].paired = 1; n_solexa++; return 1; //can't fail to read a read2 } } if ( lib_array[i].curr_type == 6 ) { readseqfq ( src_seq, src_name, len_seq, buf, start, offset ); } else { readseqInBuf ( src_seq, src_name, len_seq, buf, start, offset ); } /* int t; for(t=0;t<*len_seq;t++) printf("%d",src_seq[t]); printf("\n"); */ if ( lib_array[i].reverse ) { reverse2k ( src_seq, *len_seq ); } n_solexa++; return 1; } boolean read1seqInLib ( char * src_seq, char * src_name, int * len_seq, int * libNo, boolean pair, unsigned char asm_ctg, int * type ) { int i = *libNo; int prevLib = i; if ( ( ( lib_array[i].curr_type != 4 ) && !lib_array[i].fp1 ) // file1 does not exist || ( ( lib_array[i].curr_type == 4 ) && ( lib_array[i].fp3 == NULL ) ) //file3 does not exist || ( ( lib_array[i].curr_type == 4 ) && readstate < 0 ) //file3 reaches end || ( ( lib_array[i].curr_type == 1 ) && feof ( lib_array[i].fp1 ) && feof ( lib_array[i].fp2 ) ) //f1 && f2 reach end || ( ( lib_array[i].curr_type == 2 ) && ( feof ( lib_array[i].fp1 ) || feof ( lib_array[i].fp2 ) )) //f1||f2 reaches end || ( ( lib_array[i].curr_type != 1 && lib_array[i].curr_type != 2 ) && ( lib_array[i].curr_type != 4 ) && feof ( lib_array[i].fp1 ) ) ) // file1 reaches end and not type1 type2 and not type6 { if ( lib_array[i].curr_type == 4 ) { if ( lib_array[i].fp3 && readstate < 0 ) // file3 reaches end { closeFp1InLab ( i ); } readstate = 0; } else { if ( lib_array[i].fp1 && feof ( lib_array[i].fp1 ) ) { closeFp1InLab ( i ); if ( lib_array[i].fp2 ) { closeFp2InLab ( i ); } } else if ( lib_array[i].fp2 && feof ( lib_array[i].fp2 ) ) { closeFp2InLab ( i ); if ( lib_array[i].fp1 ) { closeFp1InLab ( i ); } } } *libNo = nextValidIndex ( i, pair, asm_ctg ); i = *libNo; if ( lib_array[i].rd_len_cutoff > 0 ) { maxReadLen = lib_array[i].rd_len_cutoff < maxReadLen4all ? lib_array[i].rd_len_cutoff : maxReadLen4all; } else { maxReadLen = maxReadLen4all; } //record insert size info if ( pair && i != prevLib ) { if ( readNumBack < n_solexa ) { pes[gradsCounter].PE_bound = n_solexa; pes[gradsCounter].rank = lib_array[prevLib].rank; pes[gradsCounter].pair_num_cut = lib_array[prevLib].pair_num_cut; pes[gradsCounter++].insertS = lib_array[prevLib].avg_ins; readNumBack = n_solexa; } } if ( i >= num_libs ) { return 0; } openFileInLib ( i ); if ( lib_array[i].curr_type == 1 ) { readseq1by1 ( src_seq, src_name, len_seq, lib_array[i].fp1, -1 ); readseq1by1 ( src_seq, src_name, len_seq, lib_array[i].fp2, -1 ); } else if ( lib_array[i].curr_type == 3 || lib_array[i].curr_type == 5 ) { readseq1by1 ( src_seq, src_name, len_seq, lib_array[i].fp1, -1 ); } } if ( lib_array[i].curr_type == 1 ) { if ( lib_array[i].paired == 1 ) { readseq1by1 ( src_seq, src_name, len_seq, lib_array[i].fp1, 1 ); if ( lib_array[i].reverse ) { reverse2k ( src_seq, *len_seq ); } lib_array[i].paired = 2; if ( *len_seq > 0 || !feof ( lib_array[i].fp1 ) ) { n_solexa++; return 1; } else { return read1seqInLib ( src_seq, src_name, len_seq, libNo, pair, asm_ctg, type ); } } else { readseq1by1 ( src_seq, src_name, len_seq, lib_array[i].fp2, 1 ); if ( lib_array[i].reverse ) { reverse2k ( src_seq, *len_seq ); } lib_array[i].paired = 1; n_solexa++; return 1; //can't fail to read a read2 } } if ( lib_array[i].curr_type == 2 ) { if ( lib_array[i].paired == 1 ) { read1seqfq ( src_seq, src_name, len_seq, lib_array[i].fp1 ); /* if(*len_seq>0){ for(j=0;j<*len_seq;j++) printf("%c",int2base(src_seq[j])); printf("\n"); } */ if ( lib_array[i].reverse ) { reverse2k ( src_seq, *len_seq ); } lib_array[i].paired = 2; if ( *len_seq > 0 || !feof ( lib_array[i].fp1 ) ) { n_solexa++; return 1; } else { return read1seqInLib ( src_seq, src_name, len_seq, libNo, pair, asm_ctg, type ); } } else { read1seqfq ( src_seq, src_name, len_seq, lib_array[i].fp2 ); if ( lib_array[i].reverse ) { reverse2k ( src_seq, *len_seq ); } lib_array[i].paired = 1; n_solexa++; return 1; //can't fail to read a read2 } } if ( lib_array[i].curr_type == 6 ) { read1seqfq ( src_seq, src_name, len_seq, lib_array[i].fp1 ); } else if ( lib_array[i].curr_type == 4 ) { read1seqbam ( src_seq, src_name, len_seq, lib_array[i].fp3, type, lib_array[i].asm_flag ); } else { readseq1by1 ( src_seq, src_name, len_seq, lib_array[i].fp1, 1 ); } /* int t; for(t=0;t<*len_seq;t++) printf("%d",src_seq[t]); printf("\n"); */ if ( lib_array[i].reverse ) { reverse2k ( src_seq, *len_seq ); } if ( lib_array[i].curr_type != 4 && ( *len_seq > 0 || !feof ( lib_array[i].fp1 ) ) ) { n_solexa++; return 1; } else if ( lib_array[i].curr_type == 4 && ( *len_seq > 0 || readstate >= 0 ) ) { n_solexa++; return 1; } else { return read1seqInLib ( src_seq, src_name, len_seq, libNo, pair, asm_ctg, type ); } } boolean read1seqInLibBam ( char * src_seq, char * src_name, int * len_seq, int * libNo, boolean pair, unsigned char asm_ctg, int * type ) { int i = *libNo; if ( lib_array[i].fp3 == NULL ) { fprintf ( stderr, "Empty file handle.\n" ); return 0; } if ( lib_array[i].fp3 && readstate < 0 ) // file3 reaches end { closeFp1InLab ( i ); readstate = 0; return 0; } read1seqbam ( src_seq, src_name, len_seq, lib_array[i].fp3, type, lib_array[i].asm_flag ); if ( lib_array[i].reverse ) { reverse2k ( src_seq, *len_seq ); } if ( *len_seq > 0 || readstate >= 0 ) { n_solexa++; return 1; } else { return read1seqInLibBam ( src_seq, src_name, len_seq, libNo, pair, asm_ctg, type ); } } FILE * file = NULL; boolean read1seqInLibpos ( char * src_seq, char * src_name, int * len_seq, // FILE *file, int * file_No, int file_num, char ** fileName, int * fileType, int * maxLen, long * pos_seq ) { if ( *file_No < 0 || feof ( file ) ) { ( *file_No ) ++; if ( *file_No >= file_num ) { return 0; } maxReadLen = maxLen[*file_No]; if ( file != NULL ) { fclose ( file ); } file = openFile4read ( fileName[*file_No] ); if ( file != NULL ) { fprintf ( stderr, "Import reads from file:\n %s\n", fileName[*file_No] ); } if ( fileType[*file_No] == 1 || fileType[*file_No] == 3 ) { readseq1by1 ( src_seq, src_name, len_seq, file, 1 ); // *pos_seq = curr_pos; } } // multi=1; *len_seq = 0; if ( fileType[*file_No] == 1 ) { // *pos_seq = curr_pos; readseq1by1 ( src_seq, src_name, len_seq, file, 1 ); } else if ( fileType[*file_No] == 2 ) { read1seqfq ( src_seq, src_name, len_seq, file ); // *pos_seq = curr_pos; } else if ( fileType[*file_No] == 3 ) { // *pos_seq = curr_pos; readseq1by1 ( src_seq, src_name, len_seq, file, 1 ); } else if ( fileType[*file_No] == 4 ) { read1seqfq ( src_seq, src_name, len_seq, file ); // *pos_seq = curr_pos; } else { return 0; } // multi=0; if ( *len_seq > 0 || feof ( file ) ) { n_solexa++; return 1; } else { return read1seqInLibpos ( src_seq, src_name, len_seq, file_No, file_num, fileName, fileType, maxLen, pos_seq ); } } soapdenovo2-240+dfsg.orig/standardPregraph/seq.c0000644000000000000000000001165412166703654020442 0ustar rootroot/* * seq.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" /* void print_kmer(FILE *fp,Kmer kmer,char c) { fprintf(fp,"%llx %llx %llx %llx",kmer.high1,kmer.low1,kmer.high2,kmer.low2); fprintf(fp,"%c",c); }*/ /************************************************* Function: printTightString Description: Outputs the sequence. Input: 1. tightSeq: the sequence 2. len: the length of sequence Output: None. Return: None. *************************************************/ void printTightString ( char * tightSeq, int len ) { int i; for ( i = 0; i < len; i++ ) { fprintf ( stderr, "%c", int2base ( ( int ) getCharInTightString ( tightSeq, i ) ) ); if ( ( i + 1 ) % 100 == 0 && i < len - 1 ) { fprintf ( stderr, "\n" ); } } fprintf ( stderr, "\n" ); } /************************************************* Function: writeChar2tightString Description: Writes base in specified position of sequence. Input: 1. nt: the base 2. tightSeq: the sequence 3. pos: the position Output: None. Return: None. *************************************************/ void writeChar2tightString ( char nt, char * tightSeq, int pos ) { char * byte = tightSeq + pos / 4; switch ( pos % 4 ) { case 0: *byte &= 63; *byte += nt << 6; return; case 1: *byte &= 207; *byte += nt << 4; return; case 2: *byte &= 243; *byte += nt << 2; return; case 3: *byte &= 252; *byte += nt; return; } } /************************************************* Function: getCharInTightString Description: Gets the base in sipcified pos of sequence. Input: 1. tightSeq: the sequence 2. pos: the position Output: None. Return: The target base. *************************************************/ char getCharInTightString ( char * tightSeq, int pos ) { char * byte = tightSeq + pos / 4; switch ( pos % 4 ) { case 3: return ( *byte & 3 ); case 2: return ( *byte & 12 ) >> 2; case 1: return ( *byte & 48 ) >> 4; case 0: return ( *byte & 192 ) >> 6; } return 0; } /************************************************* Function: reverseComplementSeq Description: Gets the reverse complement of a sequence. Input: 1. seq: the sequence 2. len: the length of the sequence Output: 1. bal_seq: the reversed complement of the sequence Return: None. *************************************************/ void reverseComplementSeq ( char * seq, int len, char * bal_seq ) { int i, index = 0; if ( len < 1 ) { return; } for ( i = len - 1; i >= 0; i-- ) { bal_seq[index++] = int_comp ( seq[i] ); } return; } /************************************************* Function: compl_int_seq Description: Gets the reverse complement of a sequence. Input: 1. seq: the sequence 2. len: the length of the sequence Output: None. Return: The reversed complement of sequence "seq". *************************************************/ char * compl_int_seq ( char * seq, int len ) { char * bal_seq = NULL, c, bal_c; int i, index; if ( len < 1 ) { return bal_seq; } bal_seq = ( char * ) ckalloc ( len * sizeof ( char ) ); index = 0; for ( i = len - 1; i >= 0; i-- ) { c = seq[i]; if ( c < 4 ) { bal_c = int_comp ( c ); } //3-c; else { bal_c = c; } bal_seq[index++] = bal_c; } return bal_seq; } /************************************************* Function: trans_seq Description: Translates the prefix of a sequence to an integer. Input: 1. seq: the sequence in the format "char" 2. len: the length of the prefix Output: None. Return: The integer. *************************************************/ long long trans_seq ( char * seq, int len ) { int i; long long res; res = 0; for ( i = 0; i < len; i++ ) { res = res * 4 + seq[i]; } return ( res ); } /* char *kmer2seq(Kmer word) { int i; char *seq; Kmer charMask = 3; seq = (char *)ckalloc(overlaplen*sizeof(char)); for(i=overlaplen-1;i>=0;i--){ seq[i] = charMask&word; word >>= 2; } return seq; } */ soapdenovo2-240+dfsg.orig/standardPregraph/prlReadFillGap.c0000644000000000000000000012654212166703654022505 0ustar rootroot/* * prlReadFillGap.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #include "zlib.h" #define RDBLOCKSIZE 50 #define CTGappend 50 static Kmer MAXKMER; static int Ncounter; static int allGaps; // for multi threads static int * counters; static pthread_mutex_t mutex; static int scafBufSize = 100; static boolean * flagBuf; static unsigned char * thrdNoBuf; static STACK ** ctgStackBuffer; static int scafCounter; static int scafInBuf; static char * scaffBuffer; static void MarkCtgOccu ( unsigned int ctg ); /* static void printRead(int len,char *seq) { int j; fprintf(stderr,">read\n"); for(j=0;jlen = len; rd->dis = pos; rd->seqStarter = starter; } static void convertIndex () { int * length_array = ( int * ) ckalloc ( ( num_ctg + 1 ) * sizeof ( int ) ); unsigned int i; for ( i = 1; i <= num_ctg; i++ ) { length_array[i] = 0; } for ( i = 1; i <= num_ctg; i++ ) { if ( index_array[i] > 0 ) { length_array[index_array[i]] = i; } } for ( i = 1; i <= num_ctg; i++ ) { index_array[i] = length_array[i]; } //contig i with new index: index_array[i] free ( ( void * ) length_array ); } static long long getRead1by1_gz ( gzFile * fp, DARRAY * readSeqInGap ) { long long readCounter = 0; if ( !fp ) { return readCounter; } int len, ctgID, pos; long long starter; char * pt; char * freadBuf = ( char * ) ckalloc ( ( maxReadLen / 4 + 1 ) * sizeof ( char ) ); while ( gzread ( fp, &len, sizeof ( int ) ) == 4 ) { if ( gzread ( fp, &ctgID, sizeof ( int ) ) != 4 ) { break; } if ( gzread ( fp, &pos, sizeof ( int ) ) != 4 ) { break; } if ( gzread ( fp, freadBuf, sizeof ( char ) * ( unsigned ) ( len / 4 + 1 ) ) != ( unsigned ) ( len / 4 + 1 ) ) { break; } //put seq to dynamic array starter = readSeqInGap->item_c; if ( !darrayPut ( readSeqInGap, starter + len / 4 ) ) // make sure there's room for this seq { break; } pt = ( char * ) darrayPut ( readSeqInGap, starter ); bcopy ( freadBuf, pt, len / 4 + 1 ); attach1read2contig ( ctgID, len, pos, starter ); readCounter++; } free ( ( void * ) freadBuf ); return readCounter; } static long long getRead1by1 ( FILE * fp, DARRAY * readSeqInGap ) { long long readCounter = 0; if ( !fp ) { return readCounter; } int len, ctgID, pos; long long starter; char * pt; char * freadBuf = ( char * ) ckalloc ( ( maxReadLen / 4 + 1 ) * sizeof ( char ) ); while ( fread ( &len, sizeof ( int ), 1, fp ) == 1 ) { if ( fread ( &ctgID, sizeof ( int ), 1, fp ) != 1 ) { break; } if ( fread ( &pos, sizeof ( int ), 1, fp ) != 1 ) { break; } if ( fread ( freadBuf, sizeof ( char ), len / 4 + 1, fp ) != ( unsigned ) ( len / 4 + 1 ) ) { break; } //put seq to dynamic array starter = readSeqInGap->item_c; if ( !darrayPut ( readSeqInGap, starter + len / 4 ) ) // make sure there's room for this seq { break; } pt = ( char * ) darrayPut ( readSeqInGap, starter ); bcopy ( freadBuf, pt, len / 4 + 1 ); attach1read2contig ( ctgID, len, pos, starter ); readCounter++; } free ( ( void * ) freadBuf ); return readCounter; } // Darray *readSeqInGap static boolean loadReads4gap ( char * graphfile ) { FILE * fp1, *fp2; gzFile * fp; char name[1024]; long long readCounter; if ( COMPATIBLE_MODE == 1 ) { sprintf ( name, "%s.readInGap", graphfile ); fp1 = fopen ( name, "rb" ); } else { sprintf ( name, "%s.readInGap.gz", graphfile ); fp = gzopen ( name, "rb" ); } sprintf ( name, "%s.longReadInGap", graphfile ); fp2 = fopen ( name, "rb" ); if ( COMPATIBLE_MODE == 1 && !fp1 && !fp2 ) { fprintf ( stderr, "Can't open %s.readInGap and %s.longReadInGap!\n", graphfile, graphfile ); return 0; } else if ( COMPATIBLE_MODE == 0 && !fp && !fp2 ) { fprintf ( stderr, "Can't open %s.readInGap.gz and %s.longReadInGap!\n", graphfile, graphfile ); return 0; } if ( !orig2new ) { convertIndex (); orig2new = 1; } readSeqInGap = ( DARRAY * ) createDarray ( 1000000, sizeof ( char ) ); if ( COMPATIBLE_MODE == 1 && fp1 ) { readCounter = getRead1by1 ( fp1, readSeqInGap ); fprintf ( stderr, "Loaded %lld reads from %s.readInGap.\n", readCounter, graphfile ); fclose ( fp1 ); } else if ( COMPATIBLE_MODE == 0 && fp ) { readCounter = getRead1by1_gz ( fp, readSeqInGap ); fprintf ( stderr, "Loaded %lld reads from %s.readInGap.\n", readCounter, graphfile ); gzclose ( fp ); } if ( fp2 ) { readCounter = getRead1by1 ( fp2, readSeqInGap ); fprintf ( stderr, "Loaded %lld reads from %s.LongReadInGap.\n", readCounter, graphfile ); fclose ( fp2 ); } return 1; } static void debugging1 () { unsigned int i; if ( orig2new ) { unsigned int * length_array = ( unsigned int * ) ckalloc ( ( num_ctg + 1 ) * sizeof ( unsigned int ) ); //use length_array to change info in index_array for ( i = 1; i <= num_ctg; i++ ) { length_array[i] = 0; } for ( i = 1; i <= num_ctg; i++ ) { if ( index_array[i] > 0 ) { length_array[index_array[i]] = i; } } for ( i = 1; i <= num_ctg; i++ ) { index_array[i] = length_array[i]; } //contig i with original index: index_array[i] orig2new = 0; } READNEARBY * rd; int j; char * pt; for ( i = 1; i <= num_ctg; i++ ) { if ( !contig_array[i].closeReads ) { continue; } if ( index_array[i] != 735 ) { continue; } fprintf ( stderr, "Contig %d, len %d: \n", index_array[i], contig_array[i].length ); stackBackup ( contig_array[i].closeReads ); while ( ( rd = ( READNEARBY * ) stackPop ( contig_array[i].closeReads ) ) != NULL ) { fprintf ( stderr, "%d\t%d\t%lld\t", rd->dis, rd->len, rd->seqStarter ); pt = ( char * ) darrayGet ( readSeqInGap, rd->seqStarter ); for ( j = 0; j < rd->len; j++ ) { fprintf ( stderr, "%c", int2base ( ( int ) getCharInTightString ( pt, j ) ) ); } fprintf ( stderr, "\n" ); } stackRecover ( contig_array[i].closeReads ); } } static void initiateCtgInScaf ( CTGinSCAF * actg ) { actg->cutTail = 0; actg->cutHead = overlaplen; actg->gapSeqLen = 0; } static int procGap ( char * line, STACK * ctgsStack ) { char * tp; int length, i, seg; unsigned int ctg; CTGinSCAF * ctgPt; tp = strtok ( line, " " ); tp = strtok ( NULL, " " ); //length length = atoi ( tp ); tp = strtok ( NULL, " " ); //seg seg = atoi ( tp ); if ( !seg ) { return length; } for ( i = 0; i < seg; i++ ) { tp = strtok ( NULL, " " ); ctg = atoi ( tp ); MarkCtgOccu ( ctg ); ctgPt = ( CTGinSCAF * ) stackPush ( ctgsStack ); initiateCtgInScaf ( ctgPt ); ctgPt->ctgID = ctg; ctgPt->start = 0; ctgPt->end = 0; ctgPt->scaftig_start = 0; ctgPt->mask = 1; } return length; } static void debugging2 ( int index, STACK * ctgsStack ) { CTGinSCAF * actg; stackBackup ( ctgsStack ); fprintf ( stderr, ">scaffold%d\t%d 0.0\n", index, ctgsStack->item_c ); while ( ( actg = stackPop ( ctgsStack ) ) != NULL ) { fprintf ( stderr, "%d\t%d\t%d\t%d\n", actg->ctgID, actg->start, actg->end, actg->scaftig_start ); } stackRecover ( ctgsStack ); } static int cmp_reads ( const void * a, const void * b ) { READNEARBY * A, *B; A = ( READNEARBY * ) a; B = ( READNEARBY * ) b; if ( A->dis > B->dis ) { return 1; } else if ( A->dis == B->dis ) { return 0; } else { return -1; } } static void cutRdArray ( READNEARBY * rdArray, int gapStart, int gapEnd, int * count, int arrayLen, READNEARBY * cutArray ) { int i; int num = 0; for ( i = 0; i < arrayLen; i++ ) { if ( rdArray[i].dis > gapEnd ) { break; } if ( ( rdArray[i].dis + rdArray[i].len ) >= gapStart ) { cutArray[num].dis = rdArray[i].dis; cutArray[num].len = rdArray[i].len; cutArray[num++].seqStarter = rdArray[i].seqStarter; } } *count = num; } static void outputTightStr2Visual ( FILE * foc2, int ctg, int * num, int start, int length, int outputlen, int revS ) { int i, end, column = 0, n = *num; char * tightStr = contig_array[ctg].seq; if ( n == 1 ) { fprintf ( foc2, ">%d\n", index_array[ctg] ); } else { fprintf ( foc2, ">%d-%d\n", index_array[ctg], n - 1 ); } if ( !revS ) { end = start + outputlen <= length ? start + outputlen : length; for ( i = start; i < end; i++ ) { fprintf ( foc2, "%c", int2base ( ( int ) getCharInTightString ( tightStr, i ) ) ); if ( ( ++column ) % 100 == 0 ) { //column = 0; fprintf ( foc2, "\n" ); } } if ( column % 100 != 0 ) { fprintf ( foc2, "\n" ); } } else { end = length - start - outputlen - 1 >= 0 ? length - start - outputlen : 0; for ( i = end; i <= length - 1 - start; i++ ) { fprintf ( foc2, "%c", int2base ( ( int ) getCharInTightString ( tightStr, i ) ) ); if ( ( ++column ) % 100 == 0 ) { fprintf ( foc2, "\n" ); //column = 0; } } if ( column % 100 != 0 ) { fprintf ( foc2, "\n" ); } } } void outputTightStr ( FILE * fp, char * tightStr, int start, int length, int outputlen, int revS, int * col ) { int i; int end; int column = *col; if ( !revS ) { end = start + outputlen <= length ? start + outputlen : length; for ( i = start; i < end; i++ ) { fprintf ( fp, "%c", int2base ( ( int ) getCharInTightString ( tightStr, i ) ) ); if ( ( ++column ) % 100 == 0 ) { //column = 0; fprintf ( fp, "\n" ); } } } else { end = length - start - outputlen - 1 >= 0 ? length - start - outputlen : 0; for ( i = length - 1 - start; i >= end; i-- ) { fprintf ( fp, "%c", int2compbase ( ( int ) getCharInTightString ( tightStr, i ) ) ); if ( ( ++column ) % 100 == 0 ) { fprintf ( fp, "\n" ); //column = 0; } } } *col = column; } static void outputTightStr2 ( char * tightStr, char * scaff, int start, int length, int outputlen, int revS, int * col ) { int i; int end; int column = *col; char a; if ( !revS ) { end = start + outputlen <= length ? start + outputlen : length; for ( i = start; i < end; i++ ) { a = int2base ( ( int ) getCharInTightString ( tightStr, i ) ); // fprintf (fp, "%c", int2base ((int) getCharInTightString (tightStr, i))); scaff[column++] = a; } } else { end = length - start - outputlen - 1 >= 0 ? length - start - outputlen : 0; for ( i = length - 1 - start; i >= end; i-- ) { a = int2compbase ( ( int ) getCharInTightString ( tightStr, i ) ); // fprintf (fp, "%c", int2compbase ((int) getCharInTightString (tightStr, i))); scaff[column++] = a; } } *col = column; } static void outputTightStrLowerCase2Visual ( FILE * foc2, int gapNum, char * tightStr, int start, int length, int outputlen ) { int i, end, column = 0; end = start + outputlen <= length ? start + outputlen : length; fprintf ( foc2, ">%d-0\n", gapNum ); for ( i = start; i < end; i++ ) { fprintf ( foc2, "%c", "actg"[ ( int ) getCharInTightString ( tightStr, i )] ); if ( ( ++column ) % 100 == 0 ) { //column = 0; fprintf ( foc2, "\n" ); } } if ( column % 100 != 0 ) { fprintf ( foc2, "\n" ); } } static void outputTightStrLowerCase ( FILE * fp, char * tightStr, int start, int length, int outputlen, int revS, int * col ) { int i; int end; int column = *col; if ( !revS ) { end = start + outputlen <= length ? start + outputlen : length; for ( i = start; i < end; i++ ) { fprintf ( fp, "%c", "actg"[ ( int ) getCharInTightString ( tightStr, i )] ); if ( ( ++column ) % 100 == 0 ) { //column = 0; fprintf ( fp, "\n" ); } } } else { end = length - start - outputlen - 1 >= 0 ? length - start - outputlen : 0; for ( i = length - 1 - start; i >= end; i-- ) { fprintf ( fp, "%c", "tgac"[ ( int ) getCharInTightString ( tightStr, i )] ); if ( ( ++column ) % 100 == 0 ) { fprintf ( fp, "\n" ); //column = 0; } } } *col = column; } static void outputTightStrLowerCase2 ( char * tightStr, char * scaff, int start, int length, int outputlen, int revS, int * col ) { int i; int end; int column = *col; char a; if ( !revS ) { end = start + outputlen <= length ? start + outputlen : length; for ( i = start; i < end; i++ ) { a = "actg"[ ( int ) getCharInTightString ( tightStr, i )]; // fprintf (fp, "%c", "actg"[(int) getCharInTightString (tightStr, i)]); scaff[column++] = a; } } else { end = length - start - outputlen - 1 >= 0 ? length - start - outputlen : 0; for ( i = length - 1 - start; i >= end; i-- ) { a = "tgac"[ ( int ) getCharInTightString ( tightStr, i )]; // fprintf (fp, "%c", "tgac"[(int) getCharInTightString (tightStr, i)]); scaff[column++] = a; } } *col = column; } static void outputNs ( FILE * fp, int gapN, int * col ) { int i, column = *col; for ( i = 0; i < gapN; i++ ) { fprintf ( fp, "N" ); if ( ( ++column ) % 100 == 0 ) { //column = 0; fprintf ( fp, "\n" ); } } *col = column; } static void outputNs2 ( char * scaff, int gapN, int * col ) { int i, column = *col; for ( i = 0; i < gapN; i++ ) { scaff[column] = 'N'; column++; } *col = column; } static void outputGapInfo ( unsigned int ctg1, unsigned int ctg2 ) { unsigned int bal_ctg1 = getTwinCtg ( ctg1 ); unsigned int bal_ctg2 = getTwinCtg ( ctg2 ); if ( isLargerThanTwin ( ctg1 ) ) { fprintf ( stderr, "%d\t", index_array[bal_ctg1] ); } else { fprintf ( stderr, "%d\t", index_array[ctg1] ); } if ( isLargerThanTwin ( ctg2 ) ) { fprintf ( stderr, "%d\n", index_array[bal_ctg2] ); } else { fprintf ( stderr, "%d\n", index_array[ctg2] ); } } static void output1gap ( FILE * fo, int scafIndex, CTGinSCAF * prevCtg, CTGinSCAF * actg, DARRAY * gapSeqArray ) { unsigned int ctg1, bal_ctg1, length1; int start1, outputlen1; unsigned int ctg2, bal_ctg2, length2; int start2, outputlen2; char * pt; int column = 0; ctg1 = prevCtg->ctgID; bal_ctg1 = getTwinCtg ( ctg1 ); start1 = prevCtg->cutHead; length1 = contig_array[ctg1].length + overlaplen; if ( length1 - prevCtg->cutTail - start1 > CTGappend ) { outputlen1 = CTGappend; start1 = length1 - prevCtg->cutTail - outputlen1; } else { outputlen1 = length1 - prevCtg->cutTail - start1; } ctg2 = actg->ctgID; bal_ctg2 = getTwinCtg ( ctg2 ); start2 = actg->cutHead; length2 = contig_array[ctg2].length + overlaplen; if ( length2 - actg->cutTail - start2 > CTGappend ) { outputlen2 = CTGappend; } else { outputlen2 = length2 - actg->cutTail - start2; } if ( isLargerThanTwin ( ctg1 ) ) { fprintf ( fo, ">S%d_C%d_L%d_G%d", scafIndex, index_array[bal_ctg1], outputlen1, prevCtg->gapSeqLen ); } else { fprintf ( fo, ">S%d_C%d_L%d_G%d", scafIndex, index_array[ctg1], outputlen1, prevCtg->gapSeqLen ); } if ( isLargerThanTwin ( ctg2 ) ) { fprintf ( fo, "_C%d_L%d\t", index_array[bal_ctg2], outputlen2 ); } else { fprintf ( fo, "_C%d_L%d\t", index_array[ctg2], outputlen2 ); } fprintf ( fo, "%d\n", start2 ); if ( contig_array[ctg1].seq ) { outputTightStr ( fo, contig_array[ctg1].seq, start1, length1, outputlen1, 0, &column ); } else if ( contig_array[bal_ctg1].seq ) { outputTightStr ( fo, contig_array[bal_ctg1].seq, start1, length1, outputlen1, 1, &column ); } pt = ( char * ) darrayPut ( gapSeqArray, prevCtg->gapSeqOffset ); outputTightStrLowerCase ( fo, pt, 0, prevCtg->gapSeqLen, prevCtg->gapSeqLen, 0, &column ); if ( contig_array[ctg2].seq ) { outputTightStr ( fo, contig_array[ctg2].seq, start2, length2, outputlen2, 0, &column ); } else if ( contig_array[bal_ctg2].seq ) { outputTightStr ( fo, contig_array[bal_ctg2].seq, start2, length2, outputlen2, 1, &column ); } if ( column % 100 != 0 ) { fprintf ( fo, "\n" ); } } static void outputGapSeq ( FILE * fo, int index, STACK * ctgsStack, DARRAY * gapSeqArray ) { CTGinSCAF * actg, *prevCtg = NULL; stackRecover ( ctgsStack ); // fprintf (fo, ">scaffold%d\n", index); while ( ( actg = stackPop ( ctgsStack ) ) != NULL ) { /* if (prevCtg) { if (actg->scaftig_start) { fprintf (fo, "0\t%d\t%d\n", prevCtg->mask, actg->mask); } else { fprintf (fo, "1\t%d\t%d\n", prevCtg->mask, actg->mask); } } */ if ( prevCtg && prevCtg->gapSeqLen > 0 ) { output1gap ( fo, index, prevCtg, actg, gapSeqArray ); } prevCtg = actg; } } static void outputScafSeq ( FILE * fo, FILE * foc, FILE * foc2, FILE * fo3, int index, STACK * ctgsStack, DARRAY * gapSeqArray ) { CTGinSCAF * actg, *prevCtg = NULL; unsigned int ctg, bal_ctg, ctg_out, length; int start, outputlen, gapN; char * pt; int column = 0; long long cvgSum = 0; int lenSum = 0; int i, t, lu_len = 0, lu_end = 0; unsigned int ctg_start_pos = 0; char strand; unsigned int * pos_start = ( unsigned int * ) ckalloc ( 1000000 * sizeof ( unsigned int ) ); unsigned int * pos_end = ( unsigned int * ) ckalloc ( 1000000 * sizeof ( unsigned int ) ); // char index_contig[num_ctg][20]; char ** index_contig = ( char ** ) ckalloc ( 1000000 * sizeof ( char * ) ); for ( i = 0; i < 1000000; i++ ) { index_contig[i] = ( char * ) ckalloc ( 20 * sizeof ( char ) ); } char * orien_array; orien_array = ( char * ) ckalloc ( 1000000 * sizeof ( char ) ); // scaffBuffer = (char *) ckalloc (300000000 * sizeof (char)); stackRecover ( ctgsStack ); while ( ( actg = stackPop ( ctgsStack ) ) != NULL ) { if ( ! ( contig_array[actg->ctgID].cvg > 0 ) ) { continue; } lenSum += contig_array[actg->ctgID].length; cvgSum += contig_array[actg->ctgID].length * contig_array[actg->ctgID].cvg; } if ( lenSum > 0 ) { fprintf ( fo, ">scaffold%d %4.1f\n", index, ( double ) cvgSum / lenSum ); } else { fprintf ( fo, ">scaffold%d 0.0\n", index ); } fprintf ( foc, ">scaffold%d\n", index ); stackRecover ( ctgsStack ); while ( ( actg = stackPop ( ctgsStack ) ) != NULL ) { ctg = actg->ctgID; bal_ctg = getTwinCtg ( ctg ); length = contig_array[ctg].length + overlaplen; if ( prevCtg && actg->scaftig_start ) { gapN = actg->start - prevCtg->start - contig_array[prevCtg->ctgID].length; gapN = gapN > 0 ? gapN : 1; outputNs ( fo, gapN, &column ); ctg_start_pos += gapN; //outputGapInfo(prevCtg->ctgID,ctg); Ncounter++; } if ( !prevCtg ) { start = 0; } else { start = actg->cutHead; } outputlen = length - start - actg->cutTail; if ( contig_array[ctg].seq ) { outputTightStr ( fo, contig_array[ctg].seq, start, length, outputlen, 0, &column ); lu_end = start + outputlen > length ? length : start + outputlen; lu_len = lu_end - start; strand = '+'; fprintf ( foc, "%d\t", index_array[ctg] ); } else if ( contig_array[bal_ctg].seq ) { outputTightStr ( fo, contig_array[bal_ctg].seq, start, length, outputlen, 1, &column ); lu_end = length - start - outputlen - 1 >= 0 ? length - start - outputlen : 0; lu_len = length - start - lu_end; strand = '-'; fprintf ( foc, "%d\t", index_array[bal_ctg] ); } fprintf ( foc, "%u\t%c\t%d\n", ctg_start_pos, strand, lu_len ); ctg_start_pos += lu_len; if ( actg->gapSeqLen < 1 ) { prevCtg = actg; continue; } pt = ( char * ) darrayPut ( gapSeqArray, actg->gapSeqOffset ); outputTightStrLowerCase ( fo, pt, 0, actg->gapSeqLen, actg->gapSeqLen, 0, &column ); ctg_start_pos = ctg_start_pos + actg->gapSeqLen; prevCtg = actg; } if ( column % 100 != 0 ) { fprintf ( fo, "\n" ); } if ( visual ) { scaffBuffer = ( char * ) ckalloc ( ( ctg_start_pos + 5 ) * sizeof ( char ) ); prevCtg = NULL; column = 0; ctg_start_pos = 0; lenSum = 0; stackRecover ( ctgsStack ); while ( ( actg = stackPop ( ctgsStack ) ) != NULL ) { ctg = actg->ctgID; bal_ctg = getTwinCtg ( ctg ); length = contig_array[ctg].length + overlaplen; if ( prevCtg && actg->scaftig_start ) { gapN = actg->start - prevCtg->start - contig_array[prevCtg->ctgID].length; gapN = gapN > 0 ? gapN : 1; outputNs2 ( scaffBuffer, gapN, &column ); ctg_start_pos += gapN; // Ncounter++; } if ( !prevCtg ) { start = 0; } else { start = actg->cutHead; } outputlen = length - start - actg->cutTail; if ( contig_array[ctg].seq ) { t = ++contig_index_array[index_array[ctg]]; outputTightStr2 ( contig_array[ctg].seq, scaffBuffer, start, length, outputlen, 0, &column ); lu_end = start + outputlen > length ? length : start + outputlen; lu_len = lu_end - start; strand = '+'; // fprintf (foc, "%d\t", index_array[ctg]); lenSum++; if ( ctg_start_pos - start >= 0 ) { pos_start[lenSum] = ctg_start_pos - start; pos_end[lenSum] = ctg_start_pos + length - start; orien_array[lenSum] = '+'; if ( t == 1 ) { sprintf ( index_contig[lenSum], "%u", index_array[ctg] ); } else { sprintf ( index_contig[lenSum], "%u-%d", index_array[ctg], t - 1 ); } fprintf ( fo3, "{AFG\nacc:%s\nclr:0,%d\n}\n", ( index_contig[lenSum] ), length ); outputTightStr2Visual ( foc2, ctg, & ( contig_index_array[index_array[ctg]] ), 0, length, length, 0 ); } else { pos_start[lenSum] = 0; pos_end[lenSum] = ctg_start_pos + length - start; orien_array[lenSum] = '+'; if ( t == 1 ) { sprintf ( index_contig[lenSum], "%u", index_array[ctg] ); } else { sprintf ( index_contig[lenSum], "%u-%d", index_array[ctg], t - 1 ); } fprintf ( fo3, "{AFG\nacc:%s\nclr:0,%d\n}\n", ( index_contig[lenSum] ), length ); outputTightStr2Visual ( foc2, ctg, & ( contig_index_array[index_array[ctg]] ), start - ctg_start_pos, length, length - start + ctg_start_pos, 0 ); } } else if ( contig_array[bal_ctg].seq ) { t = ++contig_index_array[index_array[bal_ctg]]; outputTightStr2 ( contig_array[bal_ctg].seq, scaffBuffer, start, length, outputlen, 1, &column ); lu_end = length - start - outputlen - 1 >= 0 ? length - start - outputlen : 0; lu_len = length - start - lu_end; strand = '-'; // fprintf (foc, "%d\t", index_array[bal_ctg]); lenSum++; if ( ctg_start_pos - start >= 0 ) { pos_start[lenSum] = ctg_start_pos - start; pos_end[lenSum] = ctg_start_pos + length - start; orien_array[lenSum] = '-'; if ( t == 1 ) { sprintf ( index_contig[lenSum], "%u", index_array[bal_ctg] ); } else { sprintf ( index_contig[lenSum], "%u-%d", index_array[bal_ctg], t - 1 ); } fprintf ( fo3, "{AFG\nacc:%s\nclr:0,%d\n}\n", ( index_contig[lenSum] ), length ); outputTightStr2Visual ( foc2, bal_ctg, & ( contig_index_array[index_array[bal_ctg]] ), 0, length, length, 1 ); } else { pos_start[lenSum] = ctg_start_pos; pos_end[lenSum] = ctg_start_pos + lu_len; orien_array[lenSum] = '-'; if ( t == 1 ) { sprintf ( index_contig[lenSum], "%u", index_array[bal_ctg] ); } else { sprintf ( index_contig[lenSum], "%u-%d", index_array[bal_ctg], t - 1 ); } fprintf ( fo3, "{AFG\nacc:%s\nclr:0,%d\n}\n", ( index_contig[lenSum] ), length ); outputTightStr2Visual ( foc2, bal_ctg, & ( contig_index_array[index_array[bal_ctg]] ), start, length, outputlen, 1 ); } } // fprintf (foc, "%u\t%c\t%d\n", ctg_start_pos, strand, lu_len); ctg_start_pos += lu_len; if ( actg->gapSeqLen < 1 ) { prevCtg = actg; continue; } pt = ( char * ) darrayPut ( gapSeqArray, actg->gapSeqOffset ); outputTightStrLowerCase2 ( pt, scaffBuffer, 0, actg->gapSeqLen, actg->gapSeqLen, 0, &column ); outputTightStrLowerCase2Visual ( foc2, gapNum, pt, 0, actg->gapSeqLen, actg->gapSeqLen ); fprintf ( fo3, "{AFG\nacc:%d-0\nclr:0,%d\n}\n", gapNum, actg->gapSeqLen ); lenSum++; pos_start[lenSum] = ctg_start_pos; pos_end[lenSum] = ctg_start_pos + actg->gapSeqLen; orien_array[lenSum] = '+'; sprintf ( index_contig[lenSum], "%d-0", gapNum ); gapNum++; ctg_start_pos = ctg_start_pos + actg->gapSeqLen; prevCtg = actg; } scaffNum++; fprintf ( fo3, "{CCO\nacc:%d\npla:P\nlen:%u\ncns:\n", scaffNum, ctg_start_pos ); for ( i = 0; i < ctg_start_pos; i++ ) { if ( i != 0 && i % 100 == 0 && i < ctg_start_pos - 1 ) { fprintf ( fo3, "\n" ); } fprintf ( fo3, "%c", scaffBuffer[i] ); } fprintf ( fo3, "\n.\nqlt:\n" ); for ( i = 0; i < ctg_start_pos; i++ ) { if ( i != 0 && i % 100 == 0 && i < ctg_start_pos - 1 ) { fprintf ( fo3, "\n" ); } fprintf ( fo3, "D" ); } fprintf ( fo3, "\n.\nnpc:%d\n", lenSum ); for ( i = 1; i <= lenSum; i++ ) { if ( orien_array[i] == '+' ) { fprintf ( fo3, "{MPS\ntyp:R\nmid:%s\nsrc:\n.\npos:%u,%u\ndln:0\ndel:\n}\n", ( index_contig[i] ), pos_start[i], pos_end[i] ); } if ( orien_array[i] == '-' ) { fprintf ( fo3, "{MPS\ntyp:R\nmid:%s\nsrc:\n.\npos:%u,%u\ndln:0\ndel:\n}\n", ( index_contig[i] ), pos_end[i], pos_start[i] ); } } fprintf ( fo3, "}\n" ); free ( ( void * ) scaffBuffer ); } free ( ( void * ) pos_start ); free ( ( void * ) pos_end ); free ( ( void * ) orien_array ); for ( i = 0; i < 1000000; i++ ) { free ( ( void * ) index_contig[i] ); } free ( ( void * ) index_contig ); } static void fill1scaf ( int index, STACK * ctgsStack, int thrdID ); static void check1scaf ( int t, int thrdID ) { if ( flagBuf[t] ) { return; } boolean late = 0; pthread_mutex_lock ( &mutex ); if ( !flagBuf[t] ) { flagBuf[t] = 1; thrdNoBuf[t] = thrdID; } else { late = 1; } pthread_mutex_unlock ( &mutex ); if ( late ) { return; } counters[thrdID]++; fill1scaf ( scafCounter + t + 1, ctgStackBuffer[t], thrdID ); } static void fill1scaf ( int index, STACK * ctgsStack, int thrdID ) { CTGinSCAF * actg, *prevCtg = NULL; READNEARBY * rdArray, *rdArray4gap, *rd; int numRd = 0, count, maxGLen = 0; unsigned int ctg, bal_ctg; STACK * rdStack; while ( ( actg = stackPop ( ctgsStack ) ) != NULL ) { if ( prevCtg ) { maxGLen = maxGLen < ( actg->start - prevCtg->end ) ? ( actg->start - prevCtg->end ) : maxGLen; } ctg = actg->ctgID; bal_ctg = getTwinCtg ( ctg ); if ( actg->mask ) { prevCtg = actg; continue; } if ( contig_array[ctg].closeReads ) { numRd += contig_array[ctg].closeReads->item_c; } else if ( contig_array[bal_ctg].closeReads ) { numRd += contig_array[bal_ctg].closeReads->item_c; } prevCtg = actg; } if ( numRd < 1 ) { return; } rdArray = ( READNEARBY * ) ckalloc ( numRd * sizeof ( READNEARBY ) ); rdArray4gap = ( READNEARBY * ) ckalloc ( numRd * sizeof ( READNEARBY ) ); //fprintf(stderr,"scaffold%d reads4gap %d\n",index,numRd); // collect reads appended to contigs in this scaffold int numRd2 = 0; stackRecover ( ctgsStack ); while ( ( actg = stackPop ( ctgsStack ) ) != NULL ) { ctg = actg->ctgID; bal_ctg = getTwinCtg ( ctg ); if ( actg->mask ) { continue; } if ( contig_array[ctg].closeReads ) { rdStack = contig_array[ctg].closeReads; } else if ( contig_array[bal_ctg].closeReads ) { rdStack = contig_array[bal_ctg].closeReads; } else { continue; } stackBackup ( rdStack ); while ( ( rd = ( READNEARBY * ) stackPop ( rdStack ) ) != NULL ) { rdArray[numRd2].len = rd->len; rdArray[numRd2].seqStarter = rd->seqStarter; if ( isSmallerThanTwin ( ctg ) ) { rdArray[numRd2++].dis = actg->start - overlaplen + rd->dis; } else { rdArray[numRd2++].dis = actg->start - overlaplen + contig_array[ctg].length - rd->len - rd->dis; } } stackRecover ( rdStack ); } if ( numRd2 != numRd ) { fprintf ( stderr, "##reads numbers doesn't match, %d vs %d when scaffold %d.\n", numRd, numRd2, index ); } qsort ( rdArray, numRd, sizeof ( READNEARBY ), cmp_reads ); //fill gap one by one int gapStart, gapEnd; int numIn = 0; boolean flag; int buffer_size = maxReadLen > 100 ? maxReadLen : 100; int maxGSLen = maxGLen + GLDiff < 10 ? 10 : maxGLen + GLDiff; //fprintf(stderr,"maxGlen %d, maxGSlen %d\n",maxGLen,maxGSLen); char * seqGap = ( char * ) ckalloc ( maxGSLen * sizeof ( char ) ); // temp array for gap sequence Kmer * kmerCtg1 = ( Kmer * ) ckalloc ( buffer_size * sizeof ( Kmer ) ); Kmer * kmerCtg2 = ( Kmer * ) ckalloc ( buffer_size * sizeof ( Kmer ) ); char * seqCtg1 = ( char * ) ckalloc ( buffer_size * sizeof ( char ) ); char * seqCtg2 = ( char * ) ckalloc ( buffer_size * sizeof ( char ) ); prevCtg = NULL; stackRecover ( ctgsStack ); while ( ( actg = stackPop ( ctgsStack ) ) != NULL ) { if ( !prevCtg || !actg->scaftig_start ) { prevCtg = actg; continue; } gapStart = prevCtg->end - 100; gapEnd = actg->start - overlaplen + 100; cutRdArray ( rdArray, gapStart, gapEnd, &count, numRd, rdArray4gap ); numIn += count; /* if(!count){ prevCtg = actg; continue; } */ int overlap; for ( overlap = overlaplen; overlap > 14; overlap -= 2 ) { flag = localGraph ( rdArray4gap, count, prevCtg, actg, overlaplen, kmerCtg1, kmerCtg2, overlap, darrayBuf[thrdID], seqCtg1, seqCtg2, seqGap ); //free_kmerset(kmerSet); if ( flag == 1 ) { /* fprintf(stderr,"Between ctg %d and %d, Found with %d\n",prevCtg->ctgID ,actg->ctgID,overlap); */ break; } } /* if(count==0) printf("Gap closed without reads\n"); if(!flag) fprintf(stderr,"Between ctg %d and %d, NO routes found\n",prevCtg->ctgID,actg->ctgID); */ prevCtg = actg; } //fprintf(stderr,"____scaffold%d reads in gap %d\n",index,numIn); free ( ( void * ) seqGap ); free ( ( void * ) kmerCtg1 ); free ( ( void * ) kmerCtg2 ); free ( ( void * ) seqCtg1 ); free ( ( void * ) seqCtg2 ); free ( ( void * ) rdArray ); free ( ( void * ) rdArray4gap ); } static void reverseStack ( STACK * dStack, STACK * sStack ) { CTGinSCAF * actg, *ctgPt; emptyStack ( dStack ); while ( ( actg = ( CTGinSCAF * ) stackPop ( sStack ) ) != NULL ) { ctgPt = ( CTGinSCAF * ) stackPush ( dStack ); ctgPt->ctgID = actg->ctgID; ctgPt->start = actg->start; ctgPt->end = actg->end; ctgPt->scaftig_start = actg->scaftig_start; ctgPt->mask = actg->mask; ctgPt->cutHead = actg->cutHead; ctgPt->cutTail = actg->cutTail; ctgPt->gapSeqLen = actg->gapSeqLen; ctgPt->gapSeqOffset = actg->gapSeqOffset; } stackBackup ( dStack ); } #ifdef MER127 static Kmer tightStr2Kmer ( char * tightStr, int start, int length, int revS ) { int i; Kmer word; word.high1 = word.low1 = word.high2 = word.low2 = 0; if ( !revS ) { if ( start + overlaplen > length ) { fprintf ( stderr, "The tightStr2Kmer A: no enough bases for kmer.\n" ); return word; } for ( i = start; i < start + overlaplen; i++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low2 |= getCharInTightString ( tightStr, i ); } } else { if ( length - start - overlaplen < 0 ) { fprintf ( stderr, "The tightStr2Kmer B: no enough bases for kmer.\n" ); return word; } for ( i = length - 1 - start; i > length - 1 - start - overlaplen; i-- ) { word = KmerLeftBitMoveBy2 ( word ); word.low2 |= int_comp ( getCharInTightString ( tightStr, i ) ); } } return word; } static Kmer maxKmer () { Kmer word; word.high1 = word.low1 = word.high2 = word.low2 = 0; int i; for ( i = 0; i < overlaplen; i++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low2 |= 0x3; } return word; } #else static Kmer tightStr2Kmer ( char * tightStr, int start, int length, int revS ) { int i; Kmer word; word.high = word.low = 0; if ( !revS ) { if ( start + overlaplen > length ) { fprintf ( stderr, "The tightStr2Kmer A: no enough bases for kmer.\n" ); return word; } for ( i = start; i < start + overlaplen; i++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low |= getCharInTightString ( tightStr, i ); } } else { if ( length - start - overlaplen < 0 ) { fprintf ( stderr, "The tightStr2Kmer B: no enough bases for kmer.\n" ); return word; } for ( i = length - 1 - start; i > length - 1 - start - overlaplen; i-- ) { word = KmerLeftBitMoveBy2 ( word ); word.low |= int_comp ( getCharInTightString ( tightStr, i ) ); } } return word; } static Kmer maxKmer () { Kmer word; word.high = word.low = 0; int i; for ( i = 0; i < overlaplen; i++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low |= 0x3; } return word; } #endif static int contigCatch ( unsigned int prev_ctg, unsigned int ctg ) { if ( contig_array[prev_ctg].length == 0 || contig_array[ctg].length == 0 ) { return 0; } Kmer kmerAtEnd, kmerAtStart; Kmer MaxKmer; unsigned int bal_ctg1 = getTwinCtg ( prev_ctg ); unsigned int bal_ctg2 = getTwinCtg ( ctg ); int i, start; int len1 = contig_array[prev_ctg].length + overlaplen; int len2 = contig_array[ctg].length + overlaplen; start = contig_array[prev_ctg].length; if ( contig_array[prev_ctg].seq ) { kmerAtEnd = tightStr2Kmer ( contig_array[prev_ctg].seq, start, len1, 0 ); } else { kmerAtEnd = tightStr2Kmer ( contig_array[bal_ctg1].seq, start, len1, 1 ); } start = 0; if ( contig_array[ctg].seq ) { kmerAtStart = tightStr2Kmer ( contig_array[ctg].seq, start, len2, 0 ); } else { kmerAtStart = tightStr2Kmer ( contig_array[bal_ctg2].seq, start, len2, 1 ); } MaxKmer = MAXKMER; for ( i = 0; i < 10; i++ ) { if ( KmerEqual ( kmerAtStart, kmerAtEnd ) ) { break; } MaxKmer = KmerRightBitMoveBy2 ( MaxKmer ); kmerAtEnd = KmerAnd ( kmerAtEnd, MaxKmer ); kmerAtStart = KmerRightBitMoveBy2 ( kmerAtStart ); } if ( i < 10 ) { return overlaplen - i; } else { return 0; } } static void initStackBuf ( STACK ** ctgStackBuffer, int scafBufSize ) { int i; for ( i = 0; i < scafBufSize; i++ ) { flagBuf[i] = 1; ctgStackBuffer[i] = ( STACK * ) createStack ( 100, sizeof ( CTGinSCAF ) ); } } static void freeStackBuf ( STACK ** ctgStackBuffer, int scafBufSize ) { int i; for ( i = 0; i < scafBufSize; i++ ) { freeStack ( ctgStackBuffer[i] ); } } static void threadRoutine ( void * para ) { PARAMETER * prm; int i; prm = ( PARAMETER * ) para; //printf("%dth thread with threadID %d, hash_table %p\n",id,prm.threadID,prm.hash_table); while ( 1 ) { if ( * ( prm->selfSignal ) == 1 ) { emptyDarray ( darrayBuf[prm->threadID] ); for ( i = 0; i < scafInBuf; i++ ) { check1scaf ( i, prm->threadID ); } * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 2 ) { * ( prm->selfSignal ) = 0; break; } usleep ( 1 ); } } static void creatThrds ( pthread_t * threads, PARAMETER * paras ) { unsigned char i; int temp; for ( i = 0; i < thrd_num; i++ ) { if ( ( temp = pthread_create ( &threads[i], NULL, ( void * ) threadRoutine, & ( paras[i] ) ) ) != 0 ) { fprintf ( stderr, "Create threads failed.\n" ); exit ( 1 ); } } fprintf ( stderr, "%d thread(s) initialized.\n", thrd_num ); } static void sendWorkSignal ( unsigned char SIG, unsigned char * thrdSignals ) { int t; for ( t = 0; t < thrd_num; t++ ) { thrdSignals[t + 1] = SIG; } while ( 1 ) { usleep ( 10 ); for ( t = 0; t < thrd_num; t++ ) if ( thrdSignals[t + 1] ) { break; } if ( t == thrd_num ) { break; } } } static void thread_wait ( pthread_t * threads ) { int i; for ( i = 0; i < thrd_num; i++ ) if ( threads[i] != 0 ) { pthread_join ( threads[i], NULL ); } } static void outputSeqs ( FILE * fo, FILE * foc, FILE * foc2, FILE * fo2, FILE * fo3, int scafInBuf ) { int i, thrdID; for ( i = 0; i < scafInBuf; i++ ) { thrdID = thrdNoBuf[i]; outputScafSeq ( fo, foc, foc2, fo3, scafCounter + i + 1, ctgStackBuffer[i], darrayBuf[thrdID] ); outputGapSeq ( fo2, scafCounter + i + 1, ctgStackBuffer[i], darrayBuf[thrdID] ); } } static void MaskContig ( unsigned int ctg ) { contig_array[ctg].mask = 1; contig_array[getTwinCtg ( ctg )].mask = 1; } static void MarkCtgOccu ( unsigned int ctg ) { contig_array[ctg].flag = 1; contig_array[getTwinCtg ( ctg )].flag = 1; } static void output_ctg ( unsigned int ctg, FILE * fo ) { if ( contig_array[ctg].length < 1 ) { return; } int len; unsigned int bal_ctg = getTwinCtg ( ctg ); len = contig_array[ctg].length + overlaplen; int col = 0; if ( contig_array[ctg].seq ) { fprintf ( fo, ">C%d %4.1f\n", ctg, ( double ) contig_array[ctg].cvg ); outputTightStr ( fo, contig_array[ctg].seq, 0, len, len, 0, &col ); } else if ( contig_array[bal_ctg].seq ) { fprintf ( fo, ">C%d %4.1f\n", bal_ctg, ( double ) contig_array[ctg].cvg ); outputTightStr ( fo, contig_array[bal_ctg].seq, 0, len, len, 0, &col ); } contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; if ( len % 100 != 0 ) { fprintf ( fo, "\n" ); } } void prlReadsCloseGap ( char * graphfile ) { //thrd_num=1; if ( fillGap ) { boolean flag; fprintf ( stderr, "\nStart to load reads for gap filling. %d length discrepancy is allowed.\n", GLDiff ); fprintf ( stderr, "...\n" ); flag = loadReads4gap ( graphfile ); if ( !flag ) { return; } } if ( orig2new ) { convertIndex (); orig2new = 0; } FILE * fp, *fo, *fo2, *fo3 = NULL, *foc, *foc2 = NULL; char line[1024]; CTGinSCAF * actg; STACK * ctgStack, *aStack; int index = 0, offset = 0, counter, overallLen; int i, starter, prev_start, gapLen, catchable, scafnum; unsigned int ctg, prev_ctg = 0; boolean IsPrevGap; pthread_t threads[thrd_num]; unsigned char thrdSignal[thrd_num + 1]; PARAMETER paras[thrd_num]; for ( ctg = 1; ctg <= num_ctg; ctg++ ) { contig_array[ctg].flag = 0; } MAXKMER = maxKmer (); ctgStack = ( STACK * ) createStack ( 1000, sizeof ( CTGinSCAF ) ); sprintf ( line, "%s.scaf_gap", graphfile ); fp = ckopen ( line, "r" ); sprintf ( line, "%s.scafSeq", graphfile ); fo = ckopen ( line, "w" ); sprintf ( line, "%s.contigPosInscaff", graphfile ); foc = ckopen ( line, "w" ); if ( visual ) { sprintf ( line, "%s.contig4asm", graphfile ); foc2 = ckopen ( line, "w" ); sprintf ( line, "%s.asm", graphfile ); fo3 = ckopen ( line, "w" ); } sprintf ( line, "%s.gapSeq", graphfile ); fo2 = ckopen ( line, "w" ); pthread_mutex_init ( &mutex, NULL ); flagBuf = ( boolean * ) ckalloc ( scafBufSize * sizeof ( boolean ) );; thrdNoBuf = ( unsigned char * ) ckalloc ( scafBufSize * sizeof ( unsigned char ) );; memset ( thrdNoBuf, 0, scafBufSize * sizeof ( char ) ); ctgStackBuffer = ( STACK ** ) ckalloc ( scafBufSize * sizeof ( STACK * ) ); initStackBuf ( ctgStackBuffer, scafBufSize ); darrayBuf = ( DARRAY ** ) ckalloc ( thrd_num * sizeof ( DARRAY * ) ); counters = ( int * ) ckalloc ( thrd_num * sizeof ( int ) ); contig_index_array = ( int * ) ckalloc ( ( num_ctg + 1 ) * sizeof ( int ) ); for ( i = 0; i <= num_ctg; i++ ) { contig_index_array[i] = 0; } for ( i = 0; i < thrd_num; i++ ) { counters[i] = 0; darrayBuf[i] = ( DARRAY * ) createDarray ( 100000, sizeof ( char ) ); thrdSignal[i + 1] = 0; paras[i].threadID = i; paras[i].mainSignal = &thrdSignal[0]; paras[i].selfSignal = &thrdSignal[i + 1]; } if ( fillGap ) { creatThrds ( threads, paras ); } Ncounter = scafCounter = scafInBuf = allGaps = 0; while ( fgets ( line, sizeof ( line ), fp ) != NULL ) { if ( line[0] == '>' ) { if ( index ) { aStack = ctgStackBuffer[scafInBuf]; flagBuf[scafInBuf++] = 0; reverseStack ( aStack, ctgStack ); if ( scafInBuf == scafBufSize ) { if ( fillGap ) { sendWorkSignal ( 1, thrdSignal ); } outputSeqs ( fo, foc, foc2, fo2, fo3, scafInBuf ); scafCounter += scafInBuf; scafInBuf = 0; } if ( index % 1000 == 0 ) { fprintf ( stderr, "%d scaffolds processed.\n", index ); } } //read next scaff emptyStack ( ctgStack ); IsPrevGap = offset = prev_ctg = 0; sscanf ( line + 9, "%d %d %d", &index, &counter, &overallLen ); continue; } if ( line[0] == 'G' ) // gap appears { if ( fillGap ) { gapLen = procGap ( line, ctgStack ); IsPrevGap = 1; } continue; } if ( line[0] >= '0' && line[0] <= '9' ) // a contig line { sscanf ( line, "%d %d", &ctg, &starter ); actg = ( CTGinSCAF * ) stackPush ( ctgStack ); actg->ctgID = ctg; if ( contig_array[ctg].flag ) { MaskContig ( ctg ); } else { MarkCtgOccu ( ctg ); } initiateCtgInScaf ( actg ); if ( !prev_ctg ) { actg->cutHead = 0; } else if ( !IsPrevGap ) { allGaps++; } if ( !IsPrevGap ) { if ( prev_ctg && ( starter - prev_start - ( int ) contig_array[prev_ctg].length ) < ( ( int ) overlaplen * 4 ) ) { /* if(fillGap) catchable = contigCatch(prev_ctg,ctg); else */ catchable = 0; if ( catchable ) // prev_ctg and ctg overlap **bp { allGaps--; /* if(isLargerThanTwin(prev_ctg)) fprintf(stderr,"%d ####### by_overlap\n",getTwinCtg(prev_ctg)); else fprintf(stderr,"%d ####### by_overlap\n",prev_ctg); */ actg->scaftig_start = 0; actg->cutHead = catchable; offset += - ( starter - prev_start - contig_array[prev_ctg].length ) + ( overlaplen - catchable ); } else { actg->scaftig_start = 1; } } else { actg->scaftig_start = 1; } } else { offset += - ( starter - prev_start - contig_array[prev_ctg].length ) + gapLen; actg->scaftig_start = 0; } actg->start = starter + offset; actg->end = actg->start + contig_array[ctg].length - 1; actg->mask = contig_array[ctg].mask; IsPrevGap = 0; prev_ctg = ctg; prev_start = starter; } } if ( index ) { aStack = ctgStackBuffer[scafInBuf]; flagBuf[scafInBuf++] = 0; reverseStack ( aStack, ctgStack ); if ( fillGap ) { sendWorkSignal ( 1, thrdSignal ); } outputSeqs ( fo, foc, foc2, fo2, fo3, scafInBuf ); } if ( visual ) { scafnum = scaffNum; for ( i = 1; i <= scafnum; i++ ) { fprintf ( fo3, "{SCF\nacc:%d\nnoc:0\n{CTP\nct1:%d\nct2:%d\nmea:0\nstd:0\nori:N\n}\n}\n", ++scaffNum, i, i ); } } if ( fillGap ) { sendWorkSignal ( 2, thrdSignal ); thread_wait ( threads ); } for ( ctg = 1; ctg <= num_ctg; ctg++ ) { if ( ( contig_array[ctg].length + overlaplen ) < 100 || contig_array[ctg].flag ) { continue; } output_ctg ( ctg, fo ); } fprintf ( stderr, "\nDone with %d scaffolds, %d gaps finished, %d gaps overall.\n", index, allGaps - Ncounter, allGaps ); index = 0; for ( i = 0; i < thrd_num; i++ ) { freeDarray ( darrayBuf[i] ); index += counters[i]; } if ( fillGap ) { fprintf ( stderr, "Threads processed %d scaffolds.\n", index ); } free ( ( void * ) darrayBuf ); if ( readSeqInGap ) { freeDarray ( readSeqInGap ); } fclose ( fp ); fclose ( fo ); fclose ( foc ); fclose ( fo2 ); if ( visual ) { fclose ( foc2 ); fclose ( fo3 ); } freeStack ( ctgStack ); freeStackBuf ( ctgStackBuffer, scafBufSize ); free ( ( void * ) flagBuf ); free ( ( void * ) thrdNoBuf ); free ( ( void * ) ctgStackBuffer ); } soapdenovo2-240+dfsg.orig/standardPregraph/cutTip_graph.c0000644000000000000000000002522612166703654022303 0ustar rootroot/* * cutTip_graph.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" static int caseA, caseB, caseC, caseD, caseE; /************************************************* Function: destroyEdge Description: Removes the edge and its arc. Input: 1. edgeid: the edge index. Output: None. Return: None. *************************************************/ void destroyEdge ( unsigned int edgeid ) { unsigned int bal_ed = getTwinEdge ( edgeid ); ARC * arc; if ( bal_ed == edgeid ) { edge_array[edgeid].length = 0; return; } arc = edge_array[edgeid].arcs; while ( arc ) { arc->bal_arc->to_ed = 0; arc = arc->next; } arc = edge_array[bal_ed].arcs; while ( arc ) { arc->bal_arc->to_ed = 0; arc = arc->next; } edge_array[edgeid].arcs = NULL; edge_array[bal_ed].arcs = NULL; edge_array[edgeid].length = 0; edge_array[bal_ed].length = 0; edge_array[edgeid].deleted = 1; edge_array[bal_ed].deleted = 1; //printf("Destroyed %d and %d\n",edgeid,bal_ed); } /************************************************* Function: arcCount Description: Computes the count of arc of the edge. Input: 1. edgeid: the edge index 2. num: used to record the count of arc of the edge Output: None. Return: The first arc of the edge. *************************************************/ ARC * arcCount ( unsigned int edgeid, unsigned int * num ) { ARC * arc; ARC * firstValidArc = NULL; unsigned int count = 0; arc = edge_array[edgeid].arcs; while ( arc ) { if ( arc->to_ed > 0 ) { count++; if ( count == 1 ) { firstValidArc = arc; } else if ( count > 1 ) { *num = count; return firstValidArc; } } arc = arc->next; } *num = count; return firstValidArc; } /* multiplicity < multiCutoff ==== - ==== - ==== length < lenCutoff */ /************************************************* Function: removeWeakEdges Description: Checks if the edge is short and its in-degree(or out-degree) is weak. Input: 1. lenCutoff: the cutoff for the length of edge 2. multiCutoff: the cutoff for the weight of preArc Output: None. Return: None. *************************************************/ void removeWeakEdges ( int lenCutoff, unsigned int multiCutoff ) { unsigned int bal_ed; unsigned int arcRight_n, arcLeft_n; ARC * arcLeft, *arcRight; unsigned int i; int counter = 0; int round = 1; fprintf ( stderr, "Start to destroy weak inner edges.\n" ); counter = 1; while ( counter ) { counter = 0; for ( i = 1; i <= num_ed; i++ ) { if ( edge_array[i].deleted || edge_array[i].length == 0 || edge_array[i].length > lenCutoff || EdSameAsTwin ( i ) ) { continue; } bal_ed = getTwinEdge ( i ); arcRight = arcCount ( i, &arcRight_n ); if ( arcRight_n > 1 || !arcRight || arcRight->multiplicity > multiCutoff ) { continue; } arcLeft = arcCount ( bal_ed, &arcLeft_n ); if ( arcLeft_n > 1 || !arcLeft || arcLeft->multiplicity > multiCutoff ) { continue; } destroyEdge ( i ); counter++; } fprintf ( stderr, "%d weak inner edge(s) destroyed in cycle %d.\n", counter, round++ ); } removeDeadArcs (); /* linearConcatenate(); compactEdgeArray(); */ } /* cvg < covCutoff 1. ==== - ==== - ==== ==== 2. ==== - ==== < ==== ==== 3. > ==== - ==== ==== ==== ==== 4. > ==== < ==== ==== length < lenCutoff */ /************************************************* Function: removeLowCovEdges Description: Checks if the edge is short and its coverage is low. Input: 1. lenCutoff: the cutoff for the length of edge. 2. covCutoff: the cutoff for the coverage of edge. Output: None. Return: None. *************************************************/ void removeLowCovEdges ( int lenCutoff, unsigned short covCutoff, boolean last ) { unsigned int bal_ed; unsigned int arcRight_n, arcLeft_n; ARC * arcLeft, *arcRight; unsigned int i; int counter = 0; for ( i = 1; i <= num_ed; i++ ) { if ( edge_array[i].deleted || edge_array[i].cvg == 0 || edge_array[i].cvg > covCutoff * 10 || edge_array[i].length >= lenCutoff || EdSameAsTwin ( i ) || edge_array[i].length == 0 ) { continue; } bal_ed = getTwinEdge ( i ); arcRight = arcCount ( i, &arcRight_n ); arcLeft = arcCount ( bal_ed, &arcLeft_n ); if ( arcLeft_n < 1 || arcRight_n < 1 ) { continue; } destroyEdge ( i ); counter++; } fprintf ( stderr, "%d inner edge(s) with coverage lower than or equal to %d destroyed.\n", counter, covCutoff ); removeDeadArcs (); linearConcatenate ( 0, last ); compactEdgeArray (); } /************************************************* Function: isUnreliableTip Description: Checks if the tips is suitable to cut. Input: 1. edgeid: the edge index 2. cutLen: the length requirement for tips 3. strict: the choice for the pattern of cutting tips Output: None. Return: 0 if the tip couldn't be cut. *************************************************/ boolean isUnreliableTip ( unsigned int edgeid, int cutLen, boolean strict ) { unsigned int arcRight_n, arcLeft_n; unsigned int bal_ed; unsigned int currentEd = edgeid; int length = 0; unsigned int mult = 0; ARC * arc, *activeArc = NULL, *tempArc; if ( edgeid == 0 ) { return 0; } bal_ed = getTwinEdge ( edgeid ); if ( bal_ed == edgeid ) { return 0; } arcCount ( bal_ed, &arcLeft_n ); if ( arcLeft_n > 0 ) { return 0; } while ( currentEd ) { arcCount ( bal_ed, &arcLeft_n ); tempArc = arcCount ( currentEd, &arcRight_n ); if ( arcLeft_n > 1 || arcRight_n > 1 ) { break; } length += edge_array[currentEd].length; if ( tempArc ) { activeArc = tempArc; currentEd = activeArc->to_ed; bal_ed = getTwinEdge ( currentEd ); } else { currentEd = 0; } } if ( length >= cutLen ) { return 0; } if ( currentEd == 0 ) { caseB++; return 1; } if ( !strict ) { if ( arcLeft_n < 2 ) { length += edge_array[currentEd].length; } if ( length >= cutLen ) { return 0; } else { caseC++; return 1; } } if ( arcLeft_n < 2 ) { return 0; } if ( !activeArc ) { fprintf ( stderr, "No activeArc while checking edge %d.\n", edgeid ); } if ( activeArc->multiplicity == 1 ) { caseD++; return 1; } for ( arc = edge_array[bal_ed].arcs; arc != NULL; arc = arc->next ) if ( arc->multiplicity > mult ) { mult = arc->multiplicity; } if ( mult > activeArc->multiplicity ) { caseE++; } return mult > activeArc->multiplicity; } boolean isUnreliableTip_strict ( unsigned int edgeid, int cutLen ) { unsigned int arcRight_n, arcLeft_n; unsigned int bal_ed; unsigned int currentEd = edgeid; int length = 0; unsigned int mult = 0; ARC * arc, *activeArc = NULL, *tempArc; if ( edgeid == 0 ) { return 0; } bal_ed = getTwinEdge ( edgeid ); if ( bal_ed == edgeid ) { return 0; } arcCount ( bal_ed, &arcLeft_n ); if ( arcLeft_n > 0 ) { return 0; } while ( currentEd ) { arcCount ( bal_ed, &arcLeft_n ); tempArc = arcCount ( currentEd, &arcRight_n ); if ( arcLeft_n > 1 || arcRight_n > 1 ) { if ( arcLeft_n == 0 || length == 0 ) { return 0; } else { break; } } length += edge_array[currentEd].length; if ( length >= cutLen ) { return 0; } if ( tempArc ) { activeArc = tempArc; currentEd = activeArc->to_ed; bal_ed = getTwinEdge ( currentEd ); } else { currentEd = 0; } } if ( currentEd == 0 ) { caseA++; return 1; } if ( !activeArc ) { fprintf ( stderr, "No activeArc while checking edge %d.\n", edgeid ); } if ( activeArc->multiplicity == 1 ) { caseB++; return 1; } for ( arc = edge_array[bal_ed].arcs; arc != NULL; arc = arc->next ) if ( arc->multiplicity > mult ) { mult = arc->multiplicity; } if ( mult > activeArc->multiplicity ) { caseC++; } return mult > activeArc->multiplicity; } /************************************************* Function: removeDeadArcs Description: Removes unvalid arcs. Input: None. Output: None. Return: None. *************************************************/ void removeDeadArcs () { unsigned int i, count = 0; ARC * arc, *arc_temp; for ( i = 1; i <= num_ed; i++ ) { arc = edge_array[i].arcs; while ( arc ) { arc_temp = arc; arc = arc->next; if ( arc_temp->to_ed == 0 ) { count++; edge_array[i].arcs = deleteArc ( edge_array[i].arcs, arc_temp ); } } } fprintf ( stderr, "%d dead arc(s) removed.\n", count ); } /************************************************* Function: cutTipsInGraph Description: Cuts the short tips. Input: 1. cutLen: the cutoff for the total length of the tips 2. strict: the pattern of the cutting tips Output: None. Return: None. *************************************************/ void cutTipsInGraph ( int cutLen, boolean strict, boolean last ) { int flag = 1; unsigned int i; if ( !cutLen ) { cutLen = 2 * overlaplen; } fprintf ( stderr, "\nStrict: %d, cutoff length: %d.\n", strict, cutLen ); if ( strict ) { linearConcatenate ( 0, last ); } caseA = caseB = caseC = caseD = caseE = 0; int round = 1; while ( flag ) { flag = 0; for ( i = 1; i <= num_ed; i++ ) { if ( edge_array[i].deleted ) { continue; } if ( isUnreliableTip ( i, cutLen, strict ) ) { destroyEdge ( i ); flag++; } } fprintf ( stderr, "%d tips cut in cycle %d.\n", flag, round++ ); } removeDeadArcs (); if ( strict ) { fprintf ( stderr, "Case A %d, B %d C %d D %d E %d.\n", caseA, caseB, caseC, caseD, caseE ); } linearConcatenate ( 0, last ); compactEdgeArray (); } soapdenovo2-240+dfsg.orig/standardPregraph/splitReps.c0000644000000000000000000003327112166703654021636 0ustar rootroot/* * splitReps.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" //Note: branches number is greater than 4 for sparse static const int MAX_BRANCH_NUM = 1024; // the limit for the branch. static unsigned int involved[2049]; //record the upstream and downstream edge static unsigned int lefts[1024]; //record the upstream edge static unsigned int rights[1024]; //record the downstream edge static unsigned char gothrough[1024][1024]; //record the path from upstream edges to downstream edges /************************************************* Function: interferingCheck Description: 1. Records the upsteam and downstream edges of current edge. 2. Checks if any of the upstream/downstream edge (or its twin edge) is the upstream edge and the downstream edge at the same time. Input: 1. edgeno: the current edge 2. repTimes: the in-degree (or out-degree) Output: None. Return: 1 if the repeat is not suitable to solve. *************************************************/ static boolean interferingCheck ( unsigned int edgeno, int repTimes ) { int i, j, t; unsigned int bal_ed; involved[0] = edgeno; i = 1; for ( j = 0; j < repTimes; j++ ) { involved[i++] = lefts[j]; } for ( j = 0; j < repTimes; j++ ) { involved[i++] = rights[j]; } for ( j = 0; j < i - 1; j++ ) for ( t = j + 1; t < i; t++ ) if ( involved[j] == involved[t] ) { return 1; } for ( j = 0; j < i; j++ ) { bal_ed = getTwinEdge ( involved[j] ); for ( t = 0; t < i; t++ ) if ( bal_ed == involved[t] ) { return 1; } } return 0; } /************************************************* Function: arcCounts Description: Calculates the num of the downstream edges. Input: 1. edgeid: the edge index Output: 1. num: the number of downstream edges Return: The first downstream arc. *************************************************/ static ARC * arcCounts ( unsigned int edgeid, unsigned int * num ) { ARC * arc; ARC * firstValidArc = NULL; unsigned int count = 0; arc = edge_array[edgeid].arcs; while ( arc ) { if ( arc->to_ed > 0 ) { count++; } if ( count == 1 ) { firstValidArc = arc; } arc = arc->next; } *num = count; return firstValidArc; } /************************************************* Function: readOnEdge Description: Checks if the read ID exists in the marker array of a edge. Input: 1. readid: the read ID 2. edge: the edge Output: None. Return: 1 if the read ID exists in array. *************************************************/ static boolean readOnEdge ( long long readid, unsigned int edge ) { int index; int markNum; long long * marklist; if ( edge_array[edge].markers ) { markNum = edge_array[edge].multi; marklist = edge_array[edge].markers; } else { return 0; } for ( index = 0; index < markNum; index++ ) { if ( readid == marklist[index] ) { return 1; } } return 0; } /************************************************* Function: cntByReads Description: Checks if the read supports the path acrossing three edges. Input: 1. left: the left edge 2. middle: the middle edge 3. right: the right edge Output: None. Return: 1 if the read supports the path. *************************************************/ static long long cntByReads ( unsigned int left, unsigned int middle, unsigned int right ) { int markNum; long long * marklist; if ( edge_array[left].markers ) { markNum = edge_array[left].multi; marklist = edge_array[left].markers; } else { return 0; } int index; long long readid; /* if(middle==8553) printf("%d markers on %d\n",markNum,left); */ for ( index = 0; index < markNum; index++ ) { readid = marklist[index]; if ( readOnEdge ( readid, middle ) && readOnEdge ( readid, right ) ) { return readid; } } return 0; } /* - - > - < - - */ /************************************************* Function: solvable Description: Checks if a edge is within a solvable repeat structure according to the following criterions: 1. in-degree equals to the out-degree. 2. the in-degree of the downstream edge is 1. 3. the out-degree of the upsteam edge is 1. 4. no interleaved read path between upstream and downstream edges. Input: 1. edgeno: the edge Output: None. Return: 0 if it is not. *************************************************/ unsigned int solvable ( unsigned int edgeno ) { if ( EdSameAsTwin ( edgeno ) || edge_array[edgeno].multi == 255 ) { return 0; } unsigned int bal_ed = getTwinEdge ( edgeno ); unsigned int arcRight_n, arcLeft_n; unsigned int counter; unsigned int i, j; unsigned int branch, bal_branch; ARC * parcL, *parcR; parcL = arcCounts ( bal_ed, &arcLeft_n ); if ( arcLeft_n < 2 ) { return 0; } parcR = arcCounts ( edgeno, &arcRight_n ); if ( arcLeft_n != arcRight_n ) { return 0; } // check each right branch only has one upsteam connection /* if(edgeno==2551){ for(i=0;ito_ed == 0 ) { parcR = parcR->next; continue; } branch = parcR->to_ed; if ( EdSameAsTwin ( branch ) || edge_array[branch].multi == 255 ) { return 0; } rights[arcRight_n++] = branch; if ( arcRight_n >= MAX_BRANCH_NUM ) { fprintf ( stderr, "ERROR: right arc number is bigger than the max %d.\n", MAX_BRANCH_NUM ); exit ( -1 ); } bal_branch = getTwinEdge ( branch ); arcCounts ( bal_branch, &counter ); if ( counter != 1 ) { return 0; } parcR = parcR->next; } // check if each left branch only has one downsteam connection arcLeft_n = 0; while ( parcL ) { if ( parcL->to_ed == 0 ) { parcL = parcL->next; continue; } branch = parcL->to_ed; if ( EdSameAsTwin ( branch ) || edge_array[branch].multi == 255 ) { return 0; } bal_branch = getTwinEdge ( branch ); lefts[arcLeft_n++] = bal_branch; if ( arcLeft_n >= MAX_BRANCH_NUM ) { fprintf ( stderr, "ERROR: left arc number is bigger than the max %d.\n", MAX_BRANCH_NUM ); exit ( -1 ); } arcCounts ( bal_branch, &counter ); if ( counter != 1 ) { return 0; } parcL = parcL->next; } //check if reads indicate one to one connection between upsteam and downstream edges for ( i = 0; i < arcLeft_n; i++ ) { counter = 0; for ( j = 0; j < arcRight_n; j++ ) { gothrough[i][j] = cntByReads ( lefts[i], edgeno, rights[j] ) == 0 ? 0 : 1; counter += gothrough[i][j]; if ( counter > 1 ) { return 0; } } if ( counter != 1 ) { return 0; } } for ( j = 0; j < arcRight_n; j++ ) { counter = 0; for ( i = 0; i < arcLeft_n; i++ ) { counter += gothrough[i][j]; } if ( counter != 1 ) { return 0; } } return arcLeft_n; } /************************************************* Function: cp1edge Description: Copies the info of one edge to the other. Input: 1. source: the source edge 2. target: the target edge Output: None. Return: The target edge. *************************************************/ static unsigned int cp1edge ( unsigned int source, unsigned int target ) { int length = edge_array[source].length; char * tightSeq; int index; unsigned int bal_source = getTwinEdge ( source ); unsigned int bal_target; if ( bal_source > source ) { bal_target = target + 1; } else { bal_target = target; target = target + 1; } tightSeq = ( char * ) ckalloc ( ( length / 4 + 1 ) * sizeof ( char ) ); for ( index = 0; index < length / 4 + 1; index++ ) { tightSeq[index] = edge_array[source].seq[index]; } edge_array[target].length = length; edge_array[target].cvg = edge_array[source].cvg; edge_array[target].to_vt = edge_array[source].to_vt; edge_array[target].from_vt = edge_array[source].from_vt; edge_array[target].seq = tightSeq; edge_array[target].bal_edge = edge_array[source].bal_edge; edge_array[target].rv = NULL; edge_array[target].arcs = NULL; edge_array[target].markers = NULL; edge_array[target].flag = 0; edge_array[target].deleted = 0; tightSeq = ( char * ) ckalloc ( ( length / 4 + 1 ) * sizeof ( char ) ); for ( index = 0; index < length / 4 + 1; index++ ) { tightSeq[index] = edge_array[bal_source].seq[index]; } edge_array[bal_target].length = length; edge_array[bal_target].cvg = edge_array[bal_source].cvg; edge_array[bal_target].to_vt = edge_array[bal_source].to_vt; edge_array[bal_target].from_vt = edge_array[bal_source].from_vt; edge_array[bal_target].seq = tightSeq; edge_array[bal_target].bal_edge = edge_array[bal_source].bal_edge; edge_array[bal_target].rv = NULL; edge_array[bal_target].arcs = NULL; edge_array[bal_target].markers = NULL; edge_array[bal_target].flag = 0; edge_array[bal_target].deleted = 0; return target; } /************************************************* Function: moveArc2cp Description: Moves the upstream and downstream arc information of source edge to target edge. Input: 1. leftEd: upstream edge 2. rightEd: dowmstream edge 3. source: the source edge 4. target: the target edge Output: None. Return: None. *************************************************/ static void moveArc2cp ( unsigned int leftEd, unsigned int rightEd, unsigned int source, unsigned int target ) { unsigned int bal_left = getTwinEdge ( leftEd ); unsigned int bal_right = getTwinEdge ( rightEd ); unsigned int bal_source = getTwinEdge ( source ); unsigned int bal_target = getTwinEdge ( target ); ARC * arc; ARC * newArc, *twinArc; //between left and source arc = getArcBetween ( leftEd, source ); arc->to_ed = 0; newArc = allocateArc ( target ); newArc->multiplicity = arc->multiplicity; newArc->prev = NULL; newArc->next = edge_array[leftEd].arcs; if ( edge_array[leftEd].arcs ) { edge_array[leftEd].arcs->prev = newArc; } edge_array[leftEd].arcs = newArc; arc = getArcBetween ( bal_source, bal_left ); arc->to_ed = 0; twinArc = allocateArc ( bal_left ); twinArc->multiplicity = arc->multiplicity; twinArc->prev = NULL; twinArc->next = NULL; edge_array[bal_target].arcs = twinArc; newArc->bal_arc = twinArc; twinArc->bal_arc = newArc; //between source and right arc = getArcBetween ( source, rightEd ); arc->to_ed = 0; newArc = allocateArc ( rightEd ); newArc->multiplicity = arc->multiplicity; newArc->prev = NULL; newArc->next = NULL; edge_array[target].arcs = newArc; arc = getArcBetween ( bal_right, bal_source ); arc->to_ed = 0; twinArc = allocateArc ( bal_target ); twinArc->multiplicity = arc->multiplicity; twinArc->prev = NULL; twinArc->next = edge_array[bal_right].arcs; if ( edge_array[bal_right].arcs ) { edge_array[bal_right].arcs->prev = twinArc; } edge_array[bal_right].arcs = twinArc; newArc->bal_arc = twinArc; twinArc->bal_arc = newArc; } /************************************************* Function: split1edge Description: Copies the center edge to a new edge and updates related arc information if the center edge is in a solvable repeat sturcture. Input: 1. edgeno: the edge index , which is the repeat 2. repTimes: the in-degree( or out-degree) Output: None. Return: None. *************************************************/ static void split1edge ( unsigned int edgeno, int repTimes ) { int i, j; unsigned int target; for ( i = 1; i < repTimes; i++ ) { for ( j = 0; j < repTimes; j++ ) if ( gothrough[i][j] > 0 ) // a path supported by read { break; } target = cp1edge ( edgeno, extraEdgeNum ); moveArc2cp ( lefts[i], rights[j], edgeno, target ); extraEdgeNum += 2; } } static void debugging ( unsigned int i ) { ARC * parc; parc = edge_array[i].arcs; if ( !parc ) { fprintf ( stderr, "No downward connection for %d.\n", i ); } while ( parc ) { fprintf ( stderr, "%d -> %d\n", i, parc->to_ed ); parc = parc->next; } } /************************************************* Function: solveReps Description: Uses the read path information to solve the repeats. Input: None. Output: None. Return: None. *************************************************/ void solveReps () { unsigned int i; unsigned int repTime; int counter = 0; boolean flag; //debugging(30514); extraEdgeNum = num_ed + 1; for ( i = 1; i <= num_ed; i++ ) { repTime = solvable ( i ); if ( repTime == 0 ) { continue; } flag = interferingCheck ( i, repTime ); if ( flag ) { continue; } split1edge ( i, repTime ); counter++; //+= 2*(repTime-1); if ( EdSmallerThanTwin ( i ) ) { i++; } } fprintf ( stderr, "%d repeat(s) are solvable, %d more edge(s).\n", counter, extraEdgeNum - 1 - num_ed ); num_ed = extraEdgeNum - 1; removeDeadArcs (); if ( markersArray ) { free ( ( void * ) markersArray ); markersArray = NULL; } } soapdenovo2-240+dfsg.orig/standardPregraph/localAsm.c0000644000000000000000000016416612166703654021414 0ustar rootroot/* * localAsm.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #define CTGendLen 35 // shouldn't larger than max_read_len #define UPlimit 5000 #define MaxRouteNum 10 static void kmerSet_mark ( KmerSet * set ); static void trace4Repeat ( Kmer currW, int steps, int min, int max, int * num_route, KmerSet * kset, Kmer kmerDest, int overlap, Kmer WORDF, int * traceCounter, int maxRoute, kmer_t ** soFarNode, short * multiOccu1, short * multiOccu2, int * routeLens, char ** foundRoutes, char * soFarSeq, long long * soFarLinks, double * avgLinks ); #ifdef MER127 static Kmer prevKmerLocal ( Kmer next, char ch, int overlap ) { Kmer word = KmerRightBitMoveBy2 ( next ); if ( 2 * ( overlap - 1 ) < 64 ) { word.low2 |= ( ( ( ubyte8 ) ch ) << 2 * ( overlap - 1 ) ); } if ( 2 * ( overlap - 1 ) >= 64 && 2 * ( overlap - 1 ) < 128 ) { word.high2 |= ( ( ubyte8 ) ch ) << ( 2 * ( overlap - 1 ) - 64 ); } if ( 2 * ( overlap - 1 ) >= 128 && 2 * ( overlap - 1 ) < 192 ) { word.low1 |= ( ( ubyte8 ) ch ) << ( 2 * ( overlap - 1 ) - 128 ); } if ( 2 * ( overlap - 1 ) >= 192 && 2 * ( overlap - 1 ) < 256 ) { word.high1 |= ( ( ubyte8 ) ch ) << ( 2 * ( overlap - 1 ) - 192 ); } return word; } static Kmer nextKmerLocal ( Kmer prev, char ch, Kmer WordFilter ) { Kmer word = KmerLeftBitMoveBy2 ( prev ); word = KmerAnd ( word, WordFilter ); word.low2 |= ch; return word; } #else static Kmer prevKmerLocal ( Kmer next, char ch, int overlap ) { Kmer word = KmerRightBitMoveBy2 ( next ); if ( 2 * ( overlap - 1 ) < 64 ) { word.low |= ( ( ( ubyte8 ) ch ) << 2 * ( overlap - 1 ) ); } else { word.high |= ( ( ubyte8 ) ch ) << ( 2 * ( overlap - 1 ) - 64 ); } return word; } static Kmer nextKmerLocal ( Kmer prev, char ch, Kmer WordFilter ) { Kmer word = KmerLeftBitMoveBy2 ( prev ); word = KmerAnd ( word, WordFilter ); word.low |= ch; return word; } #endif static void singleKmer ( int t, KmerSet * kset, int flag, Kmer * kmerBuffer, char * prevcBuffer, char * nextcBuffer ) { kmer_t * pos; put_kmerset ( kset, kmerBuffer[t], prevcBuffer[t], nextcBuffer[t], &pos ); if ( pos->inEdge == flag ) { return; } else if ( pos->inEdge == 0 ) { pos->inEdge = flag; } else if ( pos->inEdge == 1 && flag == 2 ) { pos->inEdge = 3; } else if ( pos->inEdge == 2 && flag == 1 ) { pos->inEdge = 3; } } static void putKmer2DBgraph ( KmerSet * kset, int flag, int kmer_c, Kmer * kmerBuffer, char * prevcBuffer, char * nextcBuffer ) { int t; for ( t = 0; t < kmer_c; t++ ) { singleKmer ( t, kset, flag, kmerBuffer, prevcBuffer, nextcBuffer ); } } static void getSeqFromRead ( READNEARBY read, char * src_seq ) { int len_seq = read.len; int j; char * tightSeq = ( char * ) darrayGet ( readSeqInGap, read.seqStarter ); for ( j = 0; j < len_seq; j++ ) { src_seq[j] = getCharInTightString ( tightSeq, j ); } } #ifdef MER127 static void chopKmer4Ctg ( Kmer * kmerCtg, int lenCtg, int overlap, char * src_seq, Kmer WORDF ) { int index, j; Kmer word; word.high1 = word.low1 = word.high2 = word.low2 = 0; for ( index = 0; index < overlap; index++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low2 |= src_seq[index]; } index = 0; kmerCtg[index++] = word; for ( j = 1; j <= lenCtg - overlap; j++ ) { word = nextKmerLocal ( word, src_seq[j - 1 + overlap], WORDF ); kmerCtg[index++] = word; } } #else static void chopKmer4Ctg ( Kmer * kmerCtg, int lenCtg, int overlap, char * src_seq, Kmer WORDF ) { int index, j; Kmer word; word.high = word.low = 0; for ( index = 0; index < overlap; index++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low |= src_seq[index]; } index = 0; kmerCtg[index++] = word; for ( j = 1; j <= lenCtg - overlap; j++ ) { word = nextKmerLocal ( word, src_seq[j - 1 + overlap], WORDF ); kmerCtg[index++] = word; } } #endif static void chopKmer4read ( int len_seq, int overlap, char * src_seq, char * bal_seq, Kmer * kmerBuffer, char * prevcBuffer, char * nextcBuffer, int * kmer_c, Kmer WORDF ) { int j, bal_j; Kmer word, bal_word; int index; char InvalidCh = 4; if ( len_seq < overlap + 1 ) { *kmer_c = 0; return; } #ifdef MER127 word.high1 = word.low1 = word.high2 = word.low2 = 0; for ( index = 0; index < overlap; index++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low2 |= src_seq[index]; } #else word.high = word.low = 0; for ( index = 0; index < overlap; index++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low |= src_seq[index]; } #endif reverseComplementSeq ( src_seq, len_seq, bal_seq ); // complementary node bal_word = reverseComplement ( word, overlap ); bal_j = len_seq - 0 - overlap; // 0; index = 0; if ( KmerSmaller ( word, bal_word ) ) { kmerBuffer[index] = word; prevcBuffer[index] = InvalidCh; nextcBuffer[index++] = src_seq[0 + overlap]; } else { kmerBuffer[index] = bal_word; prevcBuffer[index] = bal_seq[bal_j - 1]; nextcBuffer[index++] = InvalidCh; } for ( j = 1; j <= len_seq - overlap; j++ ) { word = nextKmerLocal ( word, src_seq[j - 1 + overlap], WORDF ); bal_j = len_seq - j - overlap; // j; bal_word = prevKmerLocal ( bal_word, bal_seq[bal_j], overlap ); if ( KmerSmaller ( word, bal_word ) ) { kmerBuffer[index] = word; prevcBuffer[index] = src_seq[j - 1]; if ( j < len_seq - overlap ) { nextcBuffer[index++] = src_seq[j + overlap]; } else { nextcBuffer[index++] = InvalidCh; } //printf("%dth: %p with %p\n",kmer_c-1,word,hashBanBuffer[kmer_c-1]); } else { // complementary node kmerBuffer[index] = bal_word; if ( bal_j > 0 ) { prevcBuffer[index] = bal_seq[bal_j - 1]; } else { prevcBuffer[index] = InvalidCh; } nextcBuffer[index++] = bal_seq[bal_j + overlap]; //printf("%dth: %p with %p\n",kmer_c-1,bal_word,hashBanBuffer[kmer_c-1]); } } *kmer_c = index; } static void headTightStr ( char * tightStr, int length, int start, int headLen, int revS, char * src_seq ) { int i, index = 0; if ( !revS ) { for ( i = start; i < start + headLen; i++ ) { src_seq[index++] = getCharInTightString ( tightStr, i ); } } else { for ( i = length - 1 - start; i >= length - headLen - start; i-- ) { src_seq[index++] = int_comp ( getCharInTightString ( tightStr, i ) ); } } } static int getSeqFromCtg ( CTGinSCAF * ctg, boolean fromHead, unsigned int len, int originOverlap, char * src_seq ) { unsigned int ctgId = ctg->ctgID; unsigned int bal_ctg = getTwinCtg ( ctgId ); if ( contig_array[ctgId].length < 1 ) { return 0; } unsigned int length = contig_array[ctgId].length + originOverlap; len = len < length ? len : length; if ( fromHead ) { if ( contig_array[ctgId].seq ) { headTightStr ( contig_array[ctgId].seq, length, 0, len, 0, src_seq ); } else { headTightStr ( contig_array[bal_ctg].seq, length, 0, len, 1, src_seq ); } } else { if ( contig_array[ctgId].seq ) { headTightStr ( contig_array[ctgId].seq, length, length - len, len, 0, src_seq ); } else { headTightStr ( contig_array[bal_ctg].seq, length, length - len, len, 1, src_seq ); } } return len; } static KmerSet * readsInGap2DBgraph ( READNEARBY * rdArray, int num, CTGinSCAF * ctg1, CTGinSCAF * ctg2, int originOverlap, Kmer * kmerCtg1, Kmer * kmerCtg2, int overlap, Kmer WordFilter ) { int kmer_c; Kmer * kmerBuffer; char * nextcBuffer, *prevcBuffer; int i; int buffer_size = maxReadLen > CTGendLen ? maxReadLen : CTGendLen; KmerSet * kmerS = NULL; int lenCtg1; int lenCtg2; char * bal_seq; char * src_seq; src_seq = ( char * ) ckalloc ( buffer_size * sizeof ( char ) ); bal_seq = ( char * ) ckalloc ( buffer_size * sizeof ( char ) ); lenCtg1 = getSeqFromCtg ( ctg1, 0, CTGendLen, originOverlap, src_seq ); lenCtg2 = getSeqFromCtg ( ctg2, 1, CTGendLen, originOverlap, src_seq ); if ( lenCtg1 <= overlap || lenCtg2 <= overlap ) { free ( ( void * ) src_seq ); free ( ( void * ) bal_seq ); return kmerS; } kmerBuffer = ( Kmer * ) ckalloc ( buffer_size * sizeof ( Kmer ) ); prevcBuffer = ( char * ) ckalloc ( buffer_size * sizeof ( char ) ); nextcBuffer = ( char * ) ckalloc ( buffer_size * sizeof ( char ) ); kmerS = init_kmerset ( 1024, 0.77f ); for ( i = 0; i < num; i++ ) { getSeqFromRead ( rdArray[i], src_seq ); chopKmer4read ( rdArray[i].len, overlap, src_seq, bal_seq, kmerBuffer, prevcBuffer, nextcBuffer, &kmer_c, WordFilter ); putKmer2DBgraph ( kmerS, 0, kmer_c, kmerBuffer, prevcBuffer, nextcBuffer ); } lenCtg1 = getSeqFromCtg ( ctg1, 0, CTGendLen, originOverlap, src_seq ); chopKmer4Ctg ( kmerCtg1, lenCtg1, overlap, src_seq, WordFilter ); chopKmer4read ( lenCtg1, overlap, src_seq, bal_seq, kmerBuffer, prevcBuffer, nextcBuffer, &kmer_c, WordFilter ); putKmer2DBgraph ( kmerS, 1, kmer_c, kmerBuffer, prevcBuffer, nextcBuffer ); lenCtg2 = getSeqFromCtg ( ctg2, 1, CTGendLen, originOverlap, src_seq ); chopKmer4Ctg ( kmerCtg2, lenCtg2, overlap, src_seq, WordFilter ); chopKmer4read ( lenCtg2, overlap, src_seq, bal_seq, kmerBuffer, prevcBuffer, nextcBuffer, &kmer_c, WordFilter ); putKmer2DBgraph ( kmerS, 2, kmer_c, kmerBuffer, prevcBuffer, nextcBuffer ); /* if(ctg1->ctgID==3733&&ctg2->ctgID==3067){ for(i=0;i= 32 && overlap < 64 ) { bit4 = 32; bit3 = overlap - 32; bit2 = 0; bit1 = 0; } if ( overlap >= 64 && overlap < 96 ) { bit4 = 32; bit3 = 32; bit2 = overlap - 64; bit1 = 0; } if ( overlap >= 96 && overlap < 128 ) { bit4 = 32; bit3 = 32; bit2 = 32; bit1 = overlap - 96; } for ( i = bit1 - 1; i >= 0; i-- ) { ch = kmer.high1 & 0x3; kmer.high1 >>= 2; kmerSeq[i] = ch; } for ( i = bit2 - 1; i >= 0; i-- ) { ch = kmer.low1 & 0x3; kmer.low1 >>= 2; kmerSeq[i + bit1] = ch; } for ( i = bit3 - 1; i >= 0; i-- ) { ch = kmer.high2 & 0x3; kmer.high2 >>= 2; kmerSeq[i + bit1 + bit2] = ch; } for ( i = bit4 - 1; i >= 0; i-- ) { ch = kmer.low2 & 0x3; kmer.low2 >>= 2; kmerSeq[i + bit1 + bit2 + bit3] = ch; } for ( i = 0; i < overlap; i++ ) { fprintf ( fp, "%c", int2base ( ( int ) kmerSeq[i] ) ); } } #else static void printKmerSeqLocal ( FILE * fp, Kmer kmer, int overlap ) { int i, bit1, bit2; char ch; char kmerSeq[64]; bit2 = overlap > 32 ? 32 : overlap; bit1 = overlap > 32 ? overlap - 32 : 0; for ( i = bit1 - 1; i >= 0; i-- ) { ch = kmer.high & 0x3; kmer.high >>= 2; kmerSeq[i] = ch; } for ( i = bit2 - 1; i >= 0; i-- ) { ch = kmer.low & 0x3; kmer.low >>= 2; kmerSeq[i + bit1] = ch; } for ( i = 0; i < overlap; i++ ) { fprintf ( fp, "%c", int2base ( ( int ) kmerSeq[i] ) ); } } #endif static void kmerSet_mark ( KmerSet * set ) { int i, in_num, out_num, cvgSingle; kmer_t * rs; long long counter = 0, linear = 0; Kmer word; set->iter_ptr = 0; while ( set->iter_ptr < set->size ) { if ( !is_kmer_entity_null ( set->flags, set->iter_ptr ) ) { in_num = out_num = 0; rs = set->array + set->iter_ptr; word = rs->seq; for ( i = 0; i < 4; i++ ) { cvgSingle = get_kmer_left_cov ( *rs, i ); if ( cvgSingle > 0 ) { in_num++; } cvgSingle = get_kmer_right_cov ( *rs, i ); if ( cvgSingle > 0 ) { out_num++; } } if ( rs->single ) { counter++; } if ( in_num == 1 && out_num == 1 ) { rs->linear = 1; linear++; } } set->iter_ptr++; } //printf("Allocated %ld node, %ld single nodes, %ld linear\n",(long)count_kmerset(set),counter,linear); } static kmer_t * searchNode ( Kmer word, KmerSet * kset, int overlap ) { Kmer bal_word = reverseComplement ( word, overlap ); kmer_t * node; boolean found; if ( KmerSmaller ( word, bal_word ) ) { found = search_kmerset ( kset, word, &node ); } else { found = search_kmerset ( kset, bal_word, &node ); } if ( found ) { return node; } else { return NULL; } } static int searchKmerOnCtg ( Kmer currW, Kmer * kmerDest, int num ) { int i; for ( i = 0; i < num; i++ ) { if ( KmerEqual ( currW, kmerDest[i] ) ) { return i; } } return -1; } // pick on from n items randomly static int nPick1 ( int * array, int n ) { int m, i; m = n - 1; //(int)(drand48()*n); int value = array[m]; for ( i = m; i < n - 1; i++ ) { array[i] = array[i + 1]; } return value; } static void traceAlongDBgraph ( Kmer currW, int steps, int min, int max, int * num_route, KmerSet * kset, Kmer * kmerDest, int num, int overlap, Kmer WORDF, char ** foundRoutes, int * routeEndOnCtg2, int * routeLens, char * soFarSeq, int * traceCounter, int maxRoute, kmer_t ** soFarNode, boolean * multiOccu, long long * soFarLinks, double * avgLinks ) { ( *traceCounter ) ++; if ( *traceCounter > UPlimit ) { /* if(overlap==19&&kmerDest[0]==pubKmer) printf("UPlimit\n"); */ return; } if ( steps > max || *num_route >= maxRoute ) { /* if(overlap==19&&kmerDest[0]==pubKmer) printf("max steps/maxRoute\n"); */ return; } Kmer word = reverseComplement ( currW, overlap ); boolean isSmaller = KmerSmaller ( currW, word ); int i; char ch; unsigned char links; if ( isSmaller ) { word = currW; } kmer_t * node; boolean found = search_kmerset ( kset, word, &node ); // #ifdef DEBUG if ( !found ) { fprintf ( stderr, "%s Trace: can't find kmer ", __FUNCTION__ ); PrintKmer ( stderr, word ); fprintf ( stderr, " (input " ); PrintKmer ( stderr, currW ); fprintf ( stderr, ") at step %d.\n", steps ); /* #ifdef MER127 fprintf (stderr, "%s Trace: can't find kmer %llx %llx %llx %llx (input %llx %llx %llx %llx) at step %d.\n", __FUNCTION__, word.high1, word.low1, word.high2, word.low2, currW.high1, currW.low1, currW.high2, currW.low2, steps ); #else printf ( "Trace: can't find kmer %llx %llx (input %llx %llx) at step %d\n", word.high, word.low, currW.high, currW.low, steps ); #endif */ return; } // #else // if (!found) return; // #endif if ( node->twin > 1 ) { return; } if ( soFarNode ) { soFarNode[steps] = node; } if ( steps > 0 ) { soFarSeq[steps - 1] = lastCharInKmer ( currW ); } int index, end; int linkCounter = *soFarLinks; if ( steps >= min && node->inEdge > 1 && ( end = searchKmerOnCtg ( currW, kmerDest, num ) ) >= 0 ) { index = *num_route; if ( steps > 0 ) { avgLinks[index] = ( double ) linkCounter / steps; } else { avgLinks[index] = 0; } //find node that appears more than once in the path multiOccu[index] = 0; for ( i = 0; i < steps + 1; i++ ) { soFarNode[i]->deleted = 0; } for ( i = 0; i < steps + 1; i++ ) { if ( soFarNode[i]->deleted ) { multiOccu[index] = 1; break; } soFarNode[i]->deleted = 1; } routeEndOnCtg2[index] = end; routeLens[index] = steps; char * array = foundRoutes[index]; for ( i = 0; i < steps; i++ ) { array[i] = soFarSeq[i]; } if ( i < max ) { array[i] = 4; } //indicate the end of the sequence *num_route = ++index; return; } steps++; if ( isSmaller ) { int array[] = { 0, 1, 2, 3 }; for ( i = 4; i > 0; i-- ) { ch = nPick1 ( array, i ); links = get_kmer_right_cov ( *node, ch ); if ( !links ) { continue; } *soFarLinks = linkCounter + links; word = nextKmerLocal ( currW, ch, WORDF ); traceAlongDBgraph ( word, steps, min, max, num_route, kset, kmerDest, num, overlap, WORDF, foundRoutes, routeEndOnCtg2, routeLens, soFarSeq, traceCounter, maxRoute, soFarNode, multiOccu, soFarLinks, avgLinks ); } } else { int array[] = { 0, 1, 2, 3 }; for ( i = 4; i > 0; i-- ) { ch = nPick1 ( array, i ); links = get_kmer_left_cov ( *node, ch ); if ( !links ) { continue; } *soFarLinks = linkCounter + links; word = nextKmerLocal ( currW, int_comp ( ch ), WORDF ); traceAlongDBgraph ( word, steps, min, max, num_route, kset, kmerDest, num, overlap, WORDF, foundRoutes, routeEndOnCtg2, routeLens, soFarSeq, traceCounter, maxRoute, soFarNode, multiOccu, soFarLinks, avgLinks ); } } } static int searchFgap ( KmerSet * kset, CTGinSCAF * ctg1, CTGinSCAF * ctg2, Kmer * kmerCtg1, Kmer * kmerCtg2, unsigned int origOverlap, int overlap, DARRAY * gapSeqArray, int len1, int len2, Kmer WordFilter, int * offset1, int * offset2, char * seqGap, int * cut1, int * cut2 ) { int i; int ret = 0; kmer_t * node, **soFarNode; int num_route; int gapLen = ctg2->start - ctg1->end - origOverlap + overlap; int min = gapLen - GLDiff > 0 ? gapLen - GLDiff : 0; //0531 int max = gapLen + GLDiff < 10 ? 10 : gapLen + GLDiff; char ** foundRoutes; char * soFarSeq; int traceCounter; int * routeEndOnCtg2; int * routeLens; boolean * multiOccu; long long soFarLinks; double * avgLinks; //mask linear internal linear kmer on contig1 end routeEndOnCtg2 = ( int * ) ckalloc ( MaxRouteNum * sizeof ( int ) ); routeLens = ( int * ) ckalloc ( MaxRouteNum * sizeof ( int ) ); multiOccu = ( boolean * ) ckalloc ( MaxRouteNum * sizeof ( boolean ) ); short * MULTI1 = ( short * ) ckalloc ( MaxRouteNum * sizeof ( short ) ); short * MULTI2 = ( short * ) ckalloc ( MaxRouteNum * sizeof ( short ) ); soFarSeq = ( char * ) ckalloc ( max * sizeof ( char ) ); soFarNode = ( kmer_t ** ) ckalloc ( ( max + 1 ) * sizeof ( kmer_t * ) ); foundRoutes = ( char ** ) ckalloc ( MaxRouteNum * sizeof ( char * ) );; avgLinks = ( double * ) ckalloc ( MaxRouteNum * sizeof ( double ) );; for ( i = 0; i < MaxRouteNum; i++ ) { foundRoutes[i] = ( char * ) ckalloc ( max * sizeof ( char ) ); } for ( i = len1 - 1; i >= 0; i-- ) { num_route = traceCounter = soFarLinks = 0; int steps = 0; traceAlongDBgraph ( kmerCtg1[i], steps, min, max, &num_route, kset, kmerCtg2, len2, overlap, WordFilter, foundRoutes, routeEndOnCtg2, routeLens, soFarSeq, &traceCounter, MaxRouteNum, soFarNode, multiOccu, &soFarLinks, avgLinks ); if ( num_route > 0 ) { int m, minEnd = routeEndOnCtg2[0]; for ( m = 0; m < num_route; m++ ) { if ( routeLens[m] < 0 ) { continue; } if ( routeEndOnCtg2[m] < minEnd ) { minEnd = routeEndOnCtg2[m]; } } /* else if(minFreq>1){ for(m=0;m3) break; printf("%c",int2base((int)foundRoutes[m][j])); } printf(": %4.2f\n",avgLinks[m]); } } */ num_route = traceCounter = soFarLinks = 0; steps = 0; trace4Repeat ( kmerCtg1[i], steps, min, max, &num_route, kset, kmerCtg2[minEnd], overlap, WordFilter, &traceCounter, MaxRouteNum, soFarNode, MULTI1, MULTI2, routeLens, foundRoutes, soFarSeq, &soFarLinks, avgLinks ); int j, best = 0; int maxLen = routeLens[0]; double maxLink = avgLinks[0]; char * pt; boolean repeat = 0, sameLen = 1; int leftMost = max, rightMost = max; #ifdef DEBUG if ( num_route < 1 ) { fprintf ( stderr, "After trace4Repeat: non route was found.\n" ); continue; } #else if ( num_route < 1 ) { continue; } #endif if ( num_route > 1 ) { // if multi paths are found, we check on the repeatative occurrences and links/length for ( m = 0; m < num_route; m++ ) { if ( routeLens[m] < 0 ) { continue; } if ( MULTI1[m] >= 0 && MULTI2[m] >= 0 ) { repeat = 1; leftMost = leftMost > MULTI1[m] ? MULTI1[m] : leftMost; rightMost = rightMost > MULTI2[m] ? MULTI2[m] : rightMost; } if ( routeLens[m] != maxLen ) { sameLen = 0; } if ( routeLens[m] < maxLen ) { maxLen = routeLens[m]; } if ( avgLinks[m] > maxLink ) { maxLink = avgLinks[m]; best = m; } } } if ( repeat ) { *offset1 = *offset2 = *cut1 = *cut2 = 0; int index = 0; char ch; for ( j = 0; j < leftMost; j++ ) { if ( routeLens[0] < j + overlap + 1 ) { break; } else { ch = foundRoutes[0][j]; } for ( m = 1; m < num_route; m++ ) { if ( routeLens[m] < 0 ) { continue; } if ( ch != foundRoutes[m][j] ) { break; } } if ( m == num_route ) { seqGap[index++] = ch; } else { break; } } *offset1 = index; index = 0; for ( j = 0; j < rightMost; j++ ) { if ( routeLens[0] - overlap - 1 < j ) { break; } else { ch = foundRoutes[0][routeLens[0] - overlap - 1 - j]; } for ( m = 1; m < num_route; m++ ) { if ( routeLens[m] < 0 ) { continue; } if ( ch != foundRoutes[m][routeLens[m] - overlap - 1 - j] ) { break; } } if ( m == num_route ) { index++; } else { break; } } *offset2 = index; for ( j = 0; j < *offset2; j++ ) { seqGap[*offset1 + *offset2 - 1 - j] = foundRoutes[0][routeLens[0] - overlap - 1 - j]; } if ( *offset1 > 0 || *offset2 > 0 ) { *cut1 = len1 - i - 1; *cut2 = minEnd; //fprintf(stderr,"\n"); for ( m = 0; m < num_route; m++ ) { for ( j = 0; j < max; j++ ) { if ( foundRoutes[m][j] > 3 ) { break; } //fprintf(stderr,"%c",int2base((int)foundRoutes[m][j])); } //fprintf(stderr,": %4.2f\n",avgLinks[m]); } /* fprintf(stderr,">Gap (%d + %d) (%d + %d)\n",*offset1,*offset2,*cut1,*cut2); for(index=0;index<*offset1+*offset2;index++) fprintf(stderr,"%c",int2base(seqGap[index])); fprintf(stderr,"\n"); */ } ret = 3; break; } if ( overlap + ( len1 - i - 1 ) + minEnd - routeLens[best] > ( int ) origOverlap ) { continue; } ctg1->gapSeqOffset = gapSeqArray->item_c; ctg1->gapSeqLen = routeLens[best]; if ( !darrayPut ( gapSeqArray, ctg1->gapSeqOffset + maxLen / 4 ) ) { continue; } pt = ( char * ) darrayPut ( gapSeqArray, ctg1->gapSeqOffset ); /* printKmerSeqLocal(stderr,kmerCtg1[i],overlap); fprintf(stderr,"-"); */ for ( j = 0; j < max; j++ ) { if ( foundRoutes[best][j] > 3 ) { break; } writeChar2tightString ( foundRoutes[best][j], pt, j ); //fprintf(stderr,"%c",int2base((int)foundRoutes[best][j])); } //fprintf(stderr,": GAPSEQ %d + %d, avglink %4.2f\n",len1-i-1,minEnd,avgLinks[best]); ctg1->cutTail = len1 - i - 1; ctg2->cutHead = overlap + minEnd; ctg2->scaftig_start = 0; ret = 1; break; /* }if(num_route>1){ ret = 2; break; */ } else //mark node which leads to dead end { node = searchNode ( kmerCtg1[i], kset, overlap ); if ( node ) { node->twin = 2; } } } for ( i = 0; i < MaxRouteNum; i++ ) { free ( ( void * ) foundRoutes[i] ); } free ( ( void * ) soFarSeq ); free ( ( void * ) soFarNode ); free ( ( void * ) multiOccu ); free ( ( void * ) MULTI1 ); free ( ( void * ) MULTI2 ); free ( ( void * ) foundRoutes ); free ( ( void * ) routeEndOnCtg2 ); free ( ( void * ) routeLens ); return ret; } static void trace4Repeat ( Kmer currW, int steps, int min, int max, int * num_route, KmerSet * kset, Kmer kmerDest, int overlap, Kmer WORDF, int * traceCounter, int maxRoute, kmer_t ** soFarNode, short * multiOccu1, short * multiOccu2, int * routeLens, char ** foundRoutes, char * soFarSeq, long long * soFarLinks, double * avgLinks ) { ( *traceCounter ) ++; if ( *traceCounter > UPlimit ) { return; } if ( steps > max || *num_route >= maxRoute ) { return; } Kmer word = reverseComplement ( currW, overlap ); boolean isSmaller = KmerSmaller ( currW, word ); char ch; unsigned char links; int index, i; if ( isSmaller ) { word = currW; } kmer_t * node; boolean found = search_kmerset ( kset, word, &node ); // #ifdef DEBUG if ( !found ) { fprintf ( stderr, "%s Trace: can't find kmer ", __FUNCTION__ ); PrintKmer ( stderr, word ); fprintf ( stderr, " (input " ); PrintKmer ( stderr, currW ); fprintf ( stderr, ") at step %d.\n", steps ); /* #ifdef MER127 printf ( "%s Trace: can't find kmer %llx %llx %llx %llx (input %llx %llx %llx %llx) at step %d\n", __FUNCTION__, word.high1, word.low1, word.high2, word.low2, currW.high1, currW.low1, currW.high2, currW.low2, steps ); #else printf ( "Trace: can't find kmer %llx %llx (input %llx %llx) at step %d\n", word.high, word.low, currW.high, currW.low, steps ); #endif */ return; } // #else // if (!found) return; // #endif if ( soFarNode ) { soFarNode[steps] = node; } if ( soFarSeq && steps > 0 ) { soFarSeq[steps - 1] = lastCharInKmer ( currW ); } int linkCounter; if ( soFarLinks ) { linkCounter = *soFarLinks; } if ( steps >= min && KmerEqual ( currW, kmerDest ) ) { index = *num_route; if ( avgLinks && steps > 0 ) { avgLinks[index] = ( double ) linkCounter / steps; } else if ( avgLinks ) { avgLinks[index] = 0; } //find node that appears more than once in the path if ( multiOccu1 && multiOccu2 ) { for ( i = 0; i < steps + 1; i++ ) { soFarNode[i]->deleted = 0; } int rightMost = 0; boolean MULTI = 0; for ( i = 0; i < steps + 1; i++ ) { if ( soFarNode[i]->deleted ) { rightMost = rightMost < i - 1 ? i - 1 : rightMost; MULTI = 1; } soFarNode[i]->deleted = 1; } if ( !MULTI ) { multiOccu1[index] = multiOccu2[index] = -1; } else { multiOccu2[index] = steps - 2 - rightMost < 0 ? 0 : steps - 2 - rightMost; //[0 steps-2] for ( i = 0; i < steps + 1; i++ ) { soFarNode[i]->deleted = 0; } int leftMost = steps - 2; for ( i = steps; i >= 0; i-- ) { if ( soFarNode[i]->deleted ) { leftMost = leftMost > i - 1 ? i - 1 : leftMost; } soFarNode[i]->deleted = 1; } multiOccu1[index] = leftMost < 0 ? 0 : leftMost; //[0 steps-2] } } if ( routeLens ) { routeLens[index] = steps; } if ( soFarSeq ) { char * array = foundRoutes[index]; for ( i = 0; i < steps; i++ ) { array[i] = soFarSeq[i]; } if ( i < max ) { array[i] = 4; } //indicate the end of the sequence } *num_route = ++index; } steps++; if ( isSmaller ) { int array[] = { 0, 1, 2, 3 }; for ( i = 4; i > 0; i-- ) { ch = nPick1 ( array, i ); links = get_kmer_right_cov ( *node, ch ); if ( !links ) { continue; } if ( soFarLinks ) { *soFarLinks = linkCounter + links; } word = nextKmerLocal ( currW, ch, WORDF ); trace4Repeat ( word, steps, min, max, num_route, kset, kmerDest, overlap, WORDF, traceCounter, maxRoute, soFarNode, multiOccu1, multiOccu2, routeLens, foundRoutes, soFarSeq, soFarLinks, avgLinks ); } } else { int array[] = { 0, 1, 2, 3 }; for ( i = 4; i > 0; i-- ) { ch = nPick1 ( array, i ); links = get_kmer_left_cov ( *node, ch ); if ( !links ) { continue; } if ( soFarLinks ) { *soFarLinks = linkCounter + links; } word = nextKmerLocal ( currW, int_comp ( ch ), WORDF ); trace4Repeat ( word, steps, min, max, num_route, kset, kmerDest, overlap, WORDF, traceCounter, maxRoute, soFarNode, multiOccu1, multiOccu2, routeLens, foundRoutes, soFarSeq, soFarLinks, avgLinks ); } } } //found repeat node on contig ends static void maskRepeatNode ( KmerSet * kset, Kmer * kmerCtg1, Kmer * kmerCtg2, int overlap, int len1, int len2, int max, Kmer WordFilter ) { int i; int num_route, steps; int min = 1, maxRoute = 1; int traceCounter; Kmer word, bal_word; kmer_t * node; boolean found; int counter = 0; for ( i = 0; i < len1; i++ ) { word = kmerCtg1[i]; bal_word = reverseComplement ( word, overlap ); if ( KmerLarger ( word, bal_word ) ) { word = bal_word; } found = search_kmerset ( kset, word, &node ); if ( !found || node->linear ) { //printf("Found no node for kmer %llx\n",word); continue; } num_route = traceCounter = 0; steps = 0; trace4Repeat ( word, steps, min, max, &num_route, kset, word, overlap, WordFilter, &traceCounter, maxRoute, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); if ( num_route < 1 ) { continue; } counter++; node->checked = 1; } for ( i = 0; i < len2; i++ ) { word = kmerCtg2[i]; bal_word = reverseComplement ( word, overlap ); if ( KmerLarger ( word, bal_word ) ) { word = bal_word; } found = search_kmerset ( kset, word, &node ); if ( !found || node->linear ) { //printf("Found no node for kmer %llx\n",word); continue; } num_route = traceCounter = 0; steps = 0; trace4Repeat ( word, steps, min, max, &num_route, kset, word, overlap, WordFilter, &traceCounter, maxRoute, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); if ( num_route < 1 ) { continue; } counter++; node->checked = 1; } //printf("MR: %d(%d)\n",counter,len1+len2); } /* static boolean chopReadFillGap(int len_seq,int overlap,char *src_seq, char *bal_seq, KmerSet *kset,Kmer WORDF,int *start,int *end,boolean *bal, Kmer *KmerCtg1,int len1,Kmer *KmerCtg2,int len2,int *index1,int *index2) { int index,j=0,bal_j; Kmer word,bal_word; int flag=0,bal_flag=0; int ctg1start,bal_ctg1start,ctg2end,bal_ctg2end; int seqStart,bal_start,seqEnd,bal_end; kmer_t *node; boolean found; if(len_seqlinear&&!node->checked){ if(!flag&&node->inEdge==1){ ctg1start = searchKmerOnCtg(word,KmerCtg1,len1); if(ctg1start>0){ flag = 1; seqStart = j + overlap-1; } } if(!bal_flag&&node->inEdge==2){ bal_ctg2end = searchKmerOnCtg(bal_word,KmerCtg2,len2); if(bal_ctg2end>0){ bal_flag = 2; bal_end = bal_j+overlap-1; } } } for(j = 1; j <= len_seq - overlap; j ++) { word = nextKmerLocal(word,src_seq[j-1+overlap],WORDF); bal_j = len_seq-j-overlap; // j; bal_word = prevKmerLocal(bal_word,bal_seq[bal_j],overlap); if(wordlinear&&!node->checked){ if(!flag&&node->inEdge==1){ ctg1start = searchKmerOnCtg(word,KmerCtg1,len1); if(ctg1start>0){ flag = 1; seqStart = j + overlap-1; } }else if(flag==1&&node->inEdge==1){ index = searchKmerOnCtg(word,KmerCtg1,len1); if(index>ctg1start){ // choose hit closer to gap ctg1start = index; seqStart = j + overlap-1; } }else if(flag==1&&node->inEdge==2){ ctg2end = searchKmerOnCtg(word,KmerCtg2,len2); if(ctg2end>0){ flag = 3; seqEnd = j+overlap-1; break; } } if(!bal_flag&&node->inEdge==2){ bal_ctg2end = searchKmerOnCtg(bal_word,KmerCtg2,len2); if(bal_ctg2end>0){ bal_flag = 2; bal_end = bal_j+overlap-1; } }else if(bal_flag==2&&node->inEdge==2){ index = searchKmerOnCtg(bal_word,KmerCtg2,len2); if(indexinEdge==1){ bal_ctg1start = searchKmerOnCtg(bal_word,KmerCtg1,len1); if(bal_ctg1start>0){ bal_flag = 3; bal_start = bal_j+overlap-1; break; } } } } if(flag==3){ *start = seqStart; *end = seqEnd; *bal = 0; *index1 = ctg1start; *index2 = ctg2end; return 1; }else if(bal_flag==3){ *start = bal_start; *end = bal_end; *bal = 1; *index1 = bal_ctg1start; *index2 = bal_ctg2end; return 1; } return 0; } static boolean readsCrossGap(READNEARBY *rdArray, int num, int originOverlap,DARRAY *gapSeqArray, Kmer *kmerCtg1,Kmer *kmerCtg2,int overlap,int len1,int len2, CTGinSCAF *ctg1,CTGinSCAF *ctg2,KmerSet *kmerS,Kmer WordFilter,int min,int max) { int i,j,start,end,startOnCtg1,endOnCtg2; char *bal_seq; char *src_seq; char *pt; boolean bal,ret=0,FILL; src_seq = (char *)ckalloc(maxReadLen*sizeof(char)); bal_seq = (char *)ckalloc(maxReadLen*sizeof(char)); for(i=0;imax) continue; fprintf(stderr,"Read across\n"); //printf("Filled: K %d, ctg1 %d ctg2 %d,start %d end %d\n",overlap,startOnCtg1,endOnCtg2,start,end); if(overlap+(len1-startOnCtg1-1)+endOnCtg2-(end-start)>(int)originOverlap) continue; // contig1 and contig2 could not overlap more than origOverlap bases ctg1->gapSeqOffset = gapSeqArray->item_c; ctg1->gapSeqLen = end-start; if(!darrayPut(gapSeqArray,ctg1->gapSeqOffset+(end-start)/4)) continue; pt = (char *)darrayPut(gapSeqArray,ctg1->gapSeqOffset); for(j=start+1;j<=end;j++){ if(bal) writeChar2tightString(bal_seq[j],pt,j-start-1); else writeChar2tightString(src_seq[j],pt,j-start-1); } ctg1->cutTail = len1-startOnCtg1-1; ctg2->cutHead = overlap + endOnCtg2; ctg2->scaftig_start = 0; ret = 1; break; } free((void*)src_seq); free((void*)bal_seq); return ret; } */ static void kmerSet_markTandem ( KmerSet * set, Kmer WordFilter, int overlap ); static boolean readsCrossGap ( READNEARBY * rdArray, int num, int originOverlap, DARRAY * gapSeqArray, Kmer * kmerCtg1, Kmer * kmerCtg2, int overlap, CTGinSCAF * ctg1, CTGinSCAF * ctg2, KmerSet * kmerS, Kmer WordFilter, int min, int max, int offset1, int offset2, char * seqGap, char * seqCtg1, char * seqCtg2, int cut1, int cut2 ); int localGraph ( READNEARBY * rdArray, int num, CTGinSCAF * ctg1, CTGinSCAF * ctg2, int origOverlap, Kmer * kmerCtg1, Kmer * kmerCtg2, int overlap, DARRAY * gapSeqArray, char * seqCtg1, char * seqCtg2, char * seqGap ) { /**************** put kmer in DBgraph ****************/ KmerSet * kmerSet; Kmer WordFilter = createFilter ( overlap ); /* if(ctg1->ctgID==56410&&ctg2->ctgID==61741) printf("Extract %d reads for gap [%d %d]\n",num,ctg1->ctgID,ctg2->ctgID); */ kmerSet = readsInGap2DBgraph ( rdArray, num, ctg1, ctg2, origOverlap, kmerCtg1, kmerCtg2, overlap, WordFilter ); if ( !kmerSet ) { //printf("no kmer found\n"); return 0; } time_t tt; time ( &tt ); //srand48 ( ( int ) tt ); /* int i,j; for(i=0;i<2;i++){ int array[] = {0,1,2,3}; for(j=4;j>0;j--) fprintf(stderr,"%d ", nPick1(array,j)); } fprintf(stderr,"\n"); */ /***************** search path to connect contig ends ********/ int gapLen = ctg2->start - ctg1->end - origOverlap + overlap; int min = gapLen - GLDiff > 0 ? gapLen - GLDiff : 0; int max = gapLen + GLDiff < 10 ? 10 : gapLen + GLDiff; //count kmer number for contig1 and contig2 ends int len1, len2; len1 = CTGendLen < contig_array[ctg1->ctgID].length + origOverlap ? CTGendLen : contig_array[ctg1->ctgID].length + origOverlap; len2 = CTGendLen < contig_array[ctg2->ctgID].length + origOverlap ? CTGendLen : contig_array[ctg2->ctgID].length + origOverlap; len1 -= overlap - 1; len2 -= overlap - 1; //int pathNum = 2; int offset1 = 0, offset2 = 0, cut1 = 0, cut2 = 0; int pathNum = searchFgap ( kmerSet, ctg1, ctg2, kmerCtg1, kmerCtg2, origOverlap, overlap, gapSeqArray, len1, len2, WordFilter, &offset1, &offset2, seqGap, &cut1, &cut2 ); //printf("SF: %d K %d\n",pathNum,overlap); if ( pathNum == 0 ) { free_kmerset ( kmerSet ); return 0; } else if ( pathNum == 1 ) { free_kmerset ( kmerSet ); return 1; } /* else{ printf("ret %d\n",pathNum); free_kmerset(kmerSet); return 0; } */ /******************* cross the gap by single reads *********/ //kmerSet_markTandem(kmerSet,WordFilter,overlap); maskRepeatNode ( kmerSet, kmerCtg1, kmerCtg2, overlap, len1, len2, max, WordFilter ); boolean found = readsCrossGap ( rdArray, num, origOverlap, gapSeqArray, kmerCtg1, kmerCtg2, overlap, ctg1, ctg2, kmerSet, WordFilter, min, max, offset1, offset2, seqGap, seqCtg1, seqCtg2, cut1, cut2 ); if ( found ) { //fprintf(stderr,"read across\n"); free_kmerset ( kmerSet ); return found; } else { free_kmerset ( kmerSet ); return 0; } } static void kmerSet_markTandem ( KmerSet * set, Kmer WordFilter, int overlap ) { kmer_t * rs; long long counter = 0; int num_route, steps; int min = 1, max = overlap, maxRoute = 1; int traceCounter; set->iter_ptr = 0; while ( set->iter_ptr < set->size ) { if ( !is_kmer_entity_null ( set->flags, set->iter_ptr ) ) { rs = set->array + set->iter_ptr; if ( rs->inEdge > 0 ) { set->iter_ptr++; continue; } num_route = traceCounter = 0; steps = 0; trace4Repeat ( rs->seq, steps, min, max, &num_route, set, rs->seq, overlap, WordFilter, &traceCounter, maxRoute, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); if ( num_route < 1 ) { set->iter_ptr++; continue; } /* printKmerSeqLocal(stderr,rs->seq,overlap); fprintf(stderr, "\n"); */ rs->checked = 1; counter++; } set->iter_ptr++; } } /******************* the following is for read-crossing gaps *************************/ #define MAXREADLENGTH 100 static const int INDEL = 0; static const int SIM[4][4] = { {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1} }; static char fastSequence[MAXREADLENGTH]; static char slowSequence[MAXREADLENGTH]; static int Fmatrix[MAXREADLENGTH + 1][MAXREADLENGTH + 1]; static int slowToFastMapping[MAXREADLENGTH + 1]; static int fastToSlowMapping[MAXREADLENGTH + 1]; static int max ( int A, int B, int C ) { A = A >= B ? A : B; return ( A >= C ? A : C ); } static int compareSequences ( char * sequence1, char * sequence2, int length1, int length2 ) { if ( length1 < 1 || length2 < 1 || length1 > MAXREADLENGTH || length2 > MAXREADLENGTH ) { return 0; } int i, j; int Choice1, Choice2, Choice3; int maxScore; for ( i = 0; i <= length1; i++ ) { Fmatrix[i][0] = 0; } for ( j = 0; j <= length2; j++ ) { Fmatrix[0][j] = 0; } for ( i = 1; i <= length1; i++ ) { for ( j = 1; j <= length2; j++ ) { Choice1 = Fmatrix[i - 1][j - 1] + SIM[ ( int ) sequence1[i - 1]][ ( int ) sequence2[j - 1]]; Choice2 = Fmatrix[i - 1][j] + INDEL; Choice3 = Fmatrix[i][j - 1] + INDEL; Fmatrix[i][j] = max ( Choice1, Choice2, Choice3 ); } } maxScore = Fmatrix[length1][length2]; return maxScore; } static void mapSlowOntoFast ( int slowSeqLength, int fastSeqLength ) { int slowIndex = slowSeqLength; int fastIndex = fastSeqLength; int fastn, slown; if ( slowIndex == 0 ) { slowToFastMapping[0] = fastIndex; while ( fastIndex >= 0 ) { fastToSlowMapping[fastIndex--] = 0; } return; } if ( fastIndex == 0 ) { while ( slowIndex >= 0 ) { slowToFastMapping[slowIndex--] = 0; } fastToSlowMapping[0] = slowIndex; return; } while ( slowIndex > 0 && fastIndex > 0 ) { fastn = ( int ) fastSequence[fastIndex - 1]; //getCharInTightString(fastSequence,fastIndex-1); slown = ( int ) slowSequence[slowIndex - 1]; //getCharInTightString(slowSequence,slowIndex-1); if ( Fmatrix[fastIndex][slowIndex] == Fmatrix[fastIndex - 1][slowIndex - 1] + SIM[fastn][slown] ) { fastToSlowMapping[--fastIndex] = --slowIndex; slowToFastMapping[slowIndex] = fastIndex; } else if ( Fmatrix[fastIndex][slowIndex] == Fmatrix[fastIndex - 1][slowIndex] + INDEL ) { fastToSlowMapping[--fastIndex] = slowIndex - 1; } else if ( Fmatrix[fastIndex][slowIndex] == Fmatrix[fastIndex][slowIndex - 1] + INDEL ) { slowToFastMapping[--slowIndex] = fastIndex - 1; } else { fprintf ( stderr, "CompareSequence: Error trace.\n" ); abort (); } } while ( slowIndex > 0 ) { slowToFastMapping[--slowIndex] = -1; } while ( fastIndex > 0 ) { fastToSlowMapping[--fastIndex] = -1; } slowToFastMapping[slowSeqLength] = fastSeqLength; fastToSlowMapping[fastSeqLength] = slowSeqLength; } static boolean chopReadFillGap ( int len_seq, int overlap, char * src_seq, char * bal_seq, KmerSet * kset, Kmer WORDF, int * start, int * end, boolean * bal, Kmer * KmerCtg1, int len1, Kmer * KmerCtg2, int len2, int * index1, int * index2 ) { int index, j = 0, bal_j; Kmer word, bal_word; int flag = 0, bal_flag = 0; int ctg1start, bal_ctg1start, ctg2end, bal_ctg2end; int seqStart, bal_start, seqEnd, bal_end; kmer_t * node; boolean found; if ( len_seq < overlap + 1 ) { return 0; } #ifdef MER127 word.high1 = word.low1 = word.high2 = word.low2 = 0; for ( index = 0; index < overlap; index++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low2 |= src_seq[index]; } #else word.high = word.low = 0; for ( index = 0; index < overlap; index++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low |= src_seq[index]; } #endif reverseComplementSeq ( src_seq, len_seq, bal_seq ); // complementary node bal_word = reverseComplement ( word, overlap ); bal_j = len_seq - 0 - overlap; // 0; flag = bal_flag = 0; if ( KmerSmaller ( word, bal_word ) ) { found = search_kmerset ( kset, word, &node ); } else { found = search_kmerset ( kset, bal_word, &node ); } //if ( !found ) { printf ( "chopReadFillGap 1292 not found!\n" ); } if ( found && !node->linear && !node->checked ) { if ( !flag && node->inEdge == 1 ) { ctg1start = searchKmerOnCtg ( word, KmerCtg1, len1 ); if ( ctg1start >= 0 ) { flag = 1; seqStart = j + overlap - 1; } } if ( !bal_flag && node->inEdge == 2 ) { bal_ctg2end = searchKmerOnCtg ( bal_word, KmerCtg2, len2 ); if ( bal_ctg2end >= 0 ) { bal_flag = 2; bal_end = bal_j + overlap - 1; } } } for ( j = 1; j <= len_seq - overlap; j++ ) { word = nextKmerLocal ( word, src_seq[j - 1 + overlap], WORDF ); bal_j = len_seq - j - overlap; // j; bal_word = prevKmerLocal ( bal_word, bal_seq[bal_j], overlap ); if ( KmerSmaller ( word, bal_word ) ) { found = search_kmerset ( kset, word, &node ); } else { found = search_kmerset ( kset, bal_word, &node ); } //if ( !found ) { printf ( "chopReadFillGap 1321 not found!\n" ); } if ( found && !node->linear && !node->checked ) { if ( !flag && node->inEdge == 1 ) { ctg1start = searchKmerOnCtg ( word, KmerCtg1, len1 ); if ( ctg1start >= 0 ) { flag = 1; seqStart = j + overlap - 1; } } else if ( flag == 1 && node->inEdge == 1 ) { index = searchKmerOnCtg ( word, KmerCtg1, len1 ); if ( index >= 0 && index > ctg1start ) // choose hit closer to gap { ctg1start = index; seqStart = j + overlap - 1; } } else if ( flag == 1 && node->inEdge == 2 ) { ctg2end = searchKmerOnCtg ( word, KmerCtg2, len2 ); if ( ctg2end >= 0 ) { flag = 3; seqEnd = j + overlap - 1; break; } } if ( !bal_flag && node->inEdge == 2 ) { bal_ctg2end = searchKmerOnCtg ( bal_word, KmerCtg2, len2 ); if ( bal_ctg2end >= 0 ) { bal_flag = 2; bal_end = bal_j + overlap - 1; } } else if ( bal_flag == 2 && node->inEdge == 2 ) { index = searchKmerOnCtg ( bal_word, KmerCtg2, len2 ); if ( index >= 0 && index < bal_ctg2end ) // choose hit closer to gap { bal_ctg2end = index; bal_end = bal_j + overlap - 1; } } else if ( bal_flag == 2 && node->inEdge == 1 ) { bal_ctg1start = searchKmerOnCtg ( bal_word, KmerCtg1, len1 ); if ( bal_ctg1start >= 0 ) { bal_flag = 3; bal_start = bal_j + overlap - 1; break; } } } } if ( flag == 3 ) { *start = seqStart; *end = seqEnd; *bal = 0; *index1 = ctg1start; *index2 = ctg2end; return 1; } else if ( bal_flag == 3 ) { *start = bal_start; *end = bal_end; *bal = 1; *index1 = bal_ctg1start; *index2 = bal_ctg2end; return 1; } return 0; } static int cutSeqFromTightStr ( char * tightStr, int length, int start, int end, int revS, char * src_seq ) { int i, index = 0; end = end < length ? end : length - 1; start = start >= 0 ? start : 0; if ( !revS ) { for ( i = start; i <= end; i++ ) { src_seq[index++] = getCharInTightString ( tightStr, i ); } } else { for ( i = length - 1 - start; i >= length - end - 1; i-- ) { src_seq[index++] = int_comp ( getCharInTightString ( tightStr, i ) ); } } return end - start + 1; } static int cutSeqFromCtg ( unsigned int ctgID, int start, int end, char * sequence, int originOverlap ) { unsigned int bal_ctg = getTwinCtg ( ctgID ); if ( contig_array[ctgID].length < 1 ) { return 0; } int length = contig_array[ctgID].length + originOverlap; if ( contig_array[ctgID].seq ) { return cutSeqFromTightStr ( contig_array[ctgID].seq, length, start, end, 0, sequence ); } else { return cutSeqFromTightStr ( contig_array[bal_ctg].seq, length, start, end, 1, sequence ); } } static int cutSeqFromRead ( char * src_seq, int length, int start, int end, char * sequence ) { if ( end >= length ) { fprintf ( stderr, "The index is bigger than the length: end %d length %d.\n", end, length ); } end = end < length ? end : length - 1; start = start >= 0 ? start : 0; int i; for ( i = start; i <= end; i++ ) { sequence[i - start] = src_seq[i]; } return end - start + 1; } void printSeq ( FILE * fo, char * seq, int len ) { int i; for ( i = 0; i < len; i++ ) { fprintf ( fo, "%c", int2base ( ( int ) seq[i] ) ); } fprintf ( fo, "\n" ); } static boolean readsCrossGap ( READNEARBY * rdArray, int num, int originOverlap, DARRAY * gapSeqArray, Kmer * kmerCtg1, Kmer * kmerCtg2, int overlap, CTGinSCAF * ctg1, CTGinSCAF * ctg2, KmerSet * kmerS, Kmer WordFilter, int min, int max, int offset1, int offset2, char * seqGap, char * seqCtg1, char * seqCtg2, int cut1, int cut2 ) { int i, j, start, end, startOnCtg1, endOnCtg2; char * bal_seq; char * src_seq; char * pt; boolean bal, ret = 0, FILL; double maxScore = 0.0; int maxIndex; int lenCtg1, lenCtg2; //build sequences on left and right of the uncertain region int buffer_size = maxReadLen > 100 ? maxReadLen : 100; int length = contig_array[ctg1->ctgID].length + originOverlap; if ( buffer_size > offset1 ) { lenCtg1 = cutSeqFromCtg ( ctg1->ctgID, length - cut1 - ( buffer_size - offset1 ), length - 1 - cut1, seqCtg1, originOverlap ); for ( i = 0; i < offset1; i++ ) { seqCtg1[lenCtg1 + i] = seqGap[i]; } lenCtg1 += offset1; } else { for ( i = offset1 - buffer_size; i < offset1; i++ ) { seqCtg1[i + buffer_size - offset1] = seqGap[i]; } lenCtg1 = buffer_size; } length = contig_array[ctg2->ctgID].length + originOverlap; if ( buffer_size > offset2 ) { lenCtg2 = cutSeqFromCtg ( ctg2->ctgID, cut2, buffer_size - offset2 - 1 + cut2, & ( seqCtg2[offset2] ), originOverlap ); for ( i = 0; i < offset2; i++ ) { seqCtg2[i] = seqGap[i + offset1]; } lenCtg2 += offset2; } else { for ( i = 0; i < buffer_size; i++ ) { seqCtg2[i] = seqGap[i + offset1]; } lenCtg2 = buffer_size; } /* if(offset1>0||offset2>0){ for(i=0;i max ) { continue; } if ( overlap + ( len1 - startOnCtg1 - 1 ) + endOnCtg2 - ( end - start ) > ( int ) originOverlap ) { continue; } // contig1 and contig2 could not overlap more than origOverlap bases START[i] = start; END[i] = end; INDEX1[i] = startOnCtg1; INDEX2[i] = endOnCtg2; BAL[i] = bal; int matchLen = 2 * overlap < ( end - start + overlap ) ? 2 * overlap : ( end - start + overlap ); int match; int alignLen = matchLen; //compare the left of hit kmer on ctg1 //int ctgLeft = (contig_array[ctg1->ctgID].length+originOverlap)-(len1+overlap-1)+startOnCtg1; int ctgLeft = ( lenCtg1 ) - ( len1 + overlap - 1 ) + startOnCtg1; int readLeft = start - overlap + 1; int cmpLen = ctgLeft < readLeft ? ctgLeft : readLeft; cmpLen = cmpLen <= MAXREADLENGTH ? cmpLen : MAXREADLENGTH; //cutSeqFromCtg(ctg1->ctgID,ctgLeft-cmpLen,ctgLeft-1,fastSequence,originOverlap); cutSeqFromRead ( seqCtg1, lenCtg1, ctgLeft - cmpLen, ctgLeft - 1, fastSequence ); if ( !bal ) { cutSeqFromRead ( src_seq, rdArray[i].len, readLeft - cmpLen, readLeft - 1, slowSequence ); } else { cutSeqFromRead ( bal_seq, rdArray[i].len, readLeft - cmpLen, readLeft - 1, slowSequence ); } match = compareSequences ( fastSequence, slowSequence, cmpLen, cmpLen ); alignLen += cmpLen; matchLen += match; //compare the right of hit kmer on ctg1 int ctgRight = len1 - startOnCtg1 - 1; cmpLen = ctgRight < ( rdArray[i].len - start - 1 ) ? ctgRight : ( rdArray[i].len - start - 1 ); cmpLen = cmpLen <= MAXREADLENGTH ? cmpLen : MAXREADLENGTH; //cutSeqFromCtg(ctg1->ctgID,ctgLeft+overlap,ctgLeft+overlap+cmpLen-1,fastSequence,originOverlap); cutSeqFromRead ( seqCtg1, lenCtg1, ctgLeft + overlap, ctgLeft + overlap + cmpLen - 1, fastSequence ); if ( !bal ) { cutSeqFromRead ( src_seq, rdArray[i].len, start + 1, start + cmpLen, slowSequence ); } else { cutSeqFromRead ( bal_seq, rdArray[i].len, start + 1, start + cmpLen, slowSequence ); } match = compareSequences ( fastSequence, slowSequence, cmpLen, cmpLen ); //fprintf(stderr,"%d -- %d\n",match,cmpLen); alignLen += cmpLen; matchLen += match; //compare the left of hit kmer on ctg2 ctgLeft = endOnCtg2; readLeft = end - overlap + 1; cmpLen = ctgLeft < readLeft ? ctgLeft : readLeft; cmpLen = ctgLeft <= MAXREADLENGTH ? ctgLeft : MAXREADLENGTH; //cutSeqFromCtg(ctg2->ctgID,endOnCtg2-cmpLen,endOnCtg2-1,fastSequence,originOverlap); cutSeqFromRead ( seqCtg2, lenCtg2, endOnCtg2 - cmpLen, endOnCtg2 - 1, fastSequence ); if ( !bal ) { cutSeqFromRead ( src_seq, rdArray[i].len, readLeft - cmpLen, readLeft - 1, slowSequence ); } else { cutSeqFromRead ( bal_seq, rdArray[i].len, readLeft - cmpLen, readLeft - 1, slowSequence ); } match = compareSequences ( fastSequence, slowSequence, cmpLen, cmpLen ); alignLen += cmpLen; matchLen += match; //compare the right of hit kmer on ctg2 //ctgRight = contig_array[ctg2->ctgID].length+originOverlap-endOnCtg2-overlap; ctgRight = lenCtg2 - endOnCtg2 - overlap; cmpLen = ctgRight < ( rdArray[i].len - end - 1 ) ? ctgRight : ( rdArray[i].len - end - 1 ); cmpLen = cmpLen <= MAXREADLENGTH ? cmpLen : MAXREADLENGTH; //cutSeqFromCtg(ctg2->ctgID,endOnCtg2+overlap,endOnCtg2+overlap+cmpLen-1,fastSequence,originOverlap); cutSeqFromRead ( seqCtg2, lenCtg2, endOnCtg2 + overlap, endOnCtg2 + overlap + cmpLen - 1, fastSequence ); if ( !bal ) { cutSeqFromRead ( src_seq, rdArray[i].len, end + 1, end + cmpLen, slowSequence ); } else { cutSeqFromRead ( bal_seq, rdArray[i].len, end + 1, end + cmpLen, slowSequence ); } match = compareSequences ( fastSequence, slowSequence, cmpLen, cmpLen ); alignLen += cmpLen; matchLen += match; /* if(cmpLen>0&&match!=cmpLen+overlap){ printSeq(stderr,fastSequence,cmpLen+overlap); printSeq(stderr,slowSequence,cmpLen+overlap); printKmerSeqLocal(stderr,kmerCtg2[endOnCtg2],overlap); fprintf(stderr,": %d(%d)\n",bal,endOnCtg2); }else if(cmpLen>0&&match==cmpLen+overlap) fprintf(stderr,"Perfect\n"); */ double score = ( double ) matchLen / alignLen; if ( maxScore < score ) { maxScore = score; //fprintf(stderr,"%4.2f (%d/%d)\n",maxScore,matchLen,alignLen); maxIndex = i; } SCORE[i] = score; } /* if(maxScore>0.0) fprintf(stderr,"SCORE: %4.2f\n",maxScore); */ if ( maxScore > 0.9 ) { /* for(i=0;i 0 ? offset1 - ( len1 - INDEX1[maxIndex] - 1 ) : 0; int rightRemain = offset2 - ( overlap + INDEX2[maxIndex] ) > 0 ? offset2 - ( overlap + INDEX2[maxIndex] ) : 0; ctg1->gapSeqOffset = gapSeqArray->item_c; ctg1->gapSeqLen = END[maxIndex] - START[maxIndex] + leftRemain + rightRemain; if ( darrayPut ( gapSeqArray, ctg1->gapSeqOffset + ( END[maxIndex] - START[maxIndex] + leftRemain + rightRemain ) / 4 ) ) { pt = ( char * ) darrayPut ( gapSeqArray, ctg1->gapSeqOffset ); for ( j = 0; j < leftRemain; j++ ) //get the left side of the gap region from search { writeChar2tightString ( seqGap[j], pt, j ); //fprintf(stderr,"%c",int2base(seqGap[j])); } for ( j = START[maxIndex] + 1; j <= END[maxIndex]; j++ ) { if ( BAL[maxIndex] ) { writeChar2tightString ( bal_seq[j], pt, j - START[maxIndex] - 1 + leftRemain ); //fprintf(stderr,"%c",int2base(bal_seq[j])); } else { writeChar2tightString ( src_seq[j], pt, j - START[maxIndex] - 1 + leftRemain ); //fprintf(stderr,"%c",int2base(src_seq[j])); } } for ( j = offset2 - rightRemain; j < offset2; j++ ) //get the right side of the gap region from search { writeChar2tightString ( seqGap[j + leftRemain], pt, j + END[maxIndex] - START[maxIndex] + leftRemain ); //fprintf(stderr,"%c",int2base(seqGap[j+leftRemain])); } /* fprintf(stderr,": GAPSEQ (%d+%d)(%d+%d)(%d+%d)(%d+%d) B %d\n",offset1,offset2,cut1,cut2, len1-INDEX1[maxIndex]-1,INDEX2[maxIndex],START[maxIndex],END[maxIndex],BAL[maxIndex]); */ ctg1->cutTail = len1 - INDEX1[maxIndex] - 1 - offset1 + cut1 > cut1 ? len1 - INDEX1[maxIndex] - 1 - offset1 + cut1 : cut1; ctg2->cutHead = overlap + INDEX2[maxIndex] - offset2 + cut2 > cut2 ? overlap + INDEX2[maxIndex] - offset2 + cut2 : cut2; ctg2->scaftig_start = 0; ret = 1; } } free ( ( void * ) START ); free ( ( void * ) END ); free ( ( void * ) INDEX1 ); free ( ( void * ) INDEX2 ); free ( ( void * ) SCORE ); free ( ( void * ) BAL ); free ( ( void * ) src_seq ); free ( ( void * ) bal_seq ); return ret; } soapdenovo2-240+dfsg.orig/standardPregraph/output_scaffold.c0000644000000000000000000000510612166703654023046 0ustar rootroot/* * output_scaffold.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" void output_contig_graph ( char * outfile ) { char name[256]; FILE * fp; unsigned int i; sprintf ( name, "%s.contig.gvz", outfile ); fp = ckopen ( name, "w" ); fprintf ( fp, "digraph G{\n" ); fprintf ( fp, "\tsize=\"512,512\";\n" ); for ( i = num_ctg; i > 0; i-- ) { fprintf ( fp, "\tV%d -> V%d[label =\"%d(%d)\"];\n", contig_array[i].from_vt, contig_array[i].to_vt, i, contig_array[i].length ); } fprintf ( fp, "}\n" ); fclose ( fp ); } void output_scaf ( char * outfile ) { char name[256]; FILE * fp; unsigned int i; CONNECT * connect; boolean flag; sprintf ( name, "%s.scaffold.gvz", outfile ); fp = ckopen ( name, "w" ); fprintf ( fp, "digraph G{\n" ); fprintf ( fp, "\tsize=\"512,512\";\n" ); for ( i = num_ctg; i > 0; i-- ) { //if(contig_array[i].mask||!contig_array[i].downwardConnect) if ( !contig_array[i].downwardConnect ) { continue; } connect = contig_array[i].downwardConnect; while ( connect ) { //if(connect->mask||connect->deleted){ if ( connect->deleted ) { connect = connect->next; continue; } if ( connect->prevInScaf || connect->nextInScaf ) { flag = 1; } else { flag = 0; } if ( !connect->mask ) fprintf ( fp, "\tC%d_%d -> C%d_%d [label = \"%d(%d_%d)\"];\n", i, contig_array[i].length, connect->contigID, contig_array[connect->contigID].length, connect->gapLen, flag, connect->weight ); else fprintf ( fp, "\tC%d_%d -> C%d_%d [label = \"%d(%d_%d)\", color = red];\n", i, contig_array[i].length, connect->contigID, contig_array[connect->contigID].length, connect->gapLen, flag, connect->weight ); connect = connect->next; } } fprintf ( fp, "}\n" ); fclose ( fp ); } soapdenovo2-240+dfsg.orig/standardPregraph/cutTipPreGraph.c0000644000000000000000000003336412166703654022555 0ustar rootroot/* * cutTipPreGraph.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" static int tip_c; //tips counter static long long * linearCounter; //counter for linear kmer node number static void Mark1in1outNode (); static void thread_mark ( KmerSet * set, unsigned char thrdID ); /* static void printKmer(Kmer kmer) { printKmerSeq(stdout,kmer); printf("\n"); } */ static int clipTipFromNode ( kmer_t * node1, int cut_len, boolean THIN ) { unsigned char ret = 0, in_num, out_num, link; int sum, count; kmer_t * out_node; Kmer tempKmer, pre_word, word, bal_word; ubyte8 hash_ban; char ch1, ch; boolean smaller, found; int setPicker; unsigned int max_links, singleCvg; /* if (node1->linear || node1->deleted) { return ret; } if (THIN && !node1->single) { return ret; } */ in_num = count_branch2prev ( node1 ); out_num = count_branch2next ( node1 ); if ( in_num == 0 && out_num == 1 ) { pre_word = node1->seq; for ( ch1 = 0; ch1 < 4; ch1++ ) { link = get_kmer_right_cov ( *node1, ch1 ); if ( link ) { break; } } word = nextKmer ( pre_word, ch1 ); } else if ( in_num == 1 && out_num == 0 ) { pre_word = reverseComplement ( node1->seq, overlaplen ); for ( ch1 = 0; ch1 < 4; ch1++ ) { link = get_kmer_left_cov ( *node1, ch1 ); if ( link ) { break; } } word = nextKmer ( pre_word, int_comp ( ch1 ) ); } else { return ret; } count = 1; bal_word = reverseComplement ( word, overlaplen ); if ( KmerLarger ( word, bal_word ) ) { tempKmer = bal_word; bal_word = word; word = tempKmer; smaller = 0; } else { smaller = 1; } hash_ban = hash_kmer ( word ); setPicker = hash_ban % thrd_num; found = search_kmerset ( KmerSets[setPicker], word, &out_node ); if ( !found ) { fprintf ( stderr, "Kmer " ); PrintKmer ( stderr, word ); fprintf ( stderr, " is not found, node1 " ); PrintKmer ( stderr, node1->seq ); fprintf ( stderr, " .\n" ); /* #ifdef MER127 fprintf (stderr,"kmer %llx%llx%llx%llx not found, node1 %llx%llx%llx%llx\n", word.high1, word.low1, word.high2, word.low2, node1->seq.high1, node1->seq.low1, node1->seq.high2, node1->seq.low2); #else fprintf (stderr,"kmer %llx%llx not found, node1 %llx%llx\n", word.high, word.low, node1->seq.high, node1->seq.low); #endif */ exit ( 1 ); } while ( out_node->linear ) { count++; if ( THIN && !out_node->single ) { break; } if ( count > cut_len ) { return ret; } if ( smaller ) { pre_word = word; for ( ch = 0; ch < 4; ch++ ) { link = get_kmer_right_cov ( *out_node, ch ); if ( link ) { break; } } word = nextKmer ( pre_word, ch ); bal_word = reverseComplement ( word, overlaplen ); if ( KmerLarger ( word, bal_word ) ) { tempKmer = bal_word; bal_word = word; word = tempKmer; smaller = 0; } else { smaller = 1; } hash_ban = hash_kmer ( word ); setPicker = hash_ban % thrd_num; found = search_kmerset ( KmerSets[setPicker], word, &out_node ); if ( !found ) { fprintf ( stderr, "Kmer " ); PrintKmer ( stderr, word ); fprintf ( stderr, " is not found, node1 " ); PrintKmer ( stderr, node1->seq ); fprintf ( stderr, " .\n" ); fprintf ( stderr, "Pre_word " ); PrintKmer ( stderr, pre_word ); fprintf ( stderr, " with %d(smaller).\n", ch ); /* #ifdef MER127 fprintf (stderr,"kmer %llx%llx%llx%llx not found, node1 %llx%llx%llx%llx\n", word.high1, word.low1, word.high2, word.low2, node1->seq.high1, node1->seq.low1, node1->seq.high2, node1->seq.low2); fprintf (stderr,"pre_word %llx%llx%llx%llx with %d(smaller)\n", pre_word.high1, pre_word.low1, pre_word.high2, pre_word.low2, ch); #else fprintf (stderr,"kmer %llx%llx not found, node1 %llx%llx\n", word.high, word.low, node1->seq.high, node1->seq.low); fprintf (stderr,"pre_word %llx%llx with %d(smaller)\n", pre_word.high, pre_word.low, ch); #endif */ exit ( 1 ); } } else { pre_word = bal_word; for ( ch = 0; ch < 4; ch++ ) { link = get_kmer_left_cov ( *out_node, ch ); if ( link ) { break; } } word = nextKmer ( pre_word, int_comp ( ch ) ); bal_word = reverseComplement ( word, overlaplen ); if ( KmerLarger ( word, bal_word ) ) { tempKmer = bal_word; bal_word = word; word = tempKmer; smaller = 0; } else { smaller = 1; } hash_ban = hash_kmer ( word ); setPicker = hash_ban % thrd_num; found = search_kmerset ( KmerSets[setPicker], word, &out_node ); if ( !found ) { fprintf ( stderr, "Kmer " ); PrintKmer ( stderr, word ); fprintf ( stderr, " is not found, node1 " ); PrintKmer ( stderr, node1->seq ); fprintf ( stderr, " .\n" ); fprintf ( stderr, "Pre_word " ); PrintKmer ( stderr, reverseComplement ( pre_word, overlaplen ) ); fprintf ( stderr, " with %d(larger).\n", int_comp ( ch ) ); /* #ifdef MER127 fprintf (stderr,"kmer %llx%llx%llx%llx not found, node1 %llx%llx%llx%llx\n", word.high1, word.low1, word.high2, word.low2, node1->seq.high1, node1->seq.low1, node1->seq.high2, node1->seq.low2); fprintf (stderr,"pre_word %llx%llx%llx%llx with %d(larger)\n", reverseComplement (pre_word, overlaplen).high1, reverseComplement (pre_word, overlaplen).low1, reverseComplement (pre_word, overlaplen).high2, reverseComplement (pre_word, overlaplen).low2, int_comp (ch)); #else fprintf (stderr,"kmer %llx%llx not found, node1 %llx%llx\n", word.high, word.low, node1->seq.high, node1->seq.low); fprintf (stderr,"pre_word %llx%llx with %d(larger)\n", reverseComplement (pre_word, overlaplen).high, reverseComplement (pre_word, overlaplen).low, int_comp (ch)); #endif */ exit ( 1 ); } } } if ( ( sum = count_branch2next ( out_node ) + count_branch2prev ( out_node ) ) == 1 ) { tip_c++; node1->deleted = 1; out_node->deleted = 1; return 1; } else { ch = firstCharInKmer ( pre_word ); if ( THIN ) { tip_c++; node1->deleted = 1; dislink2prevUncertain ( out_node, ch, smaller ); out_node->linear = 0; return 1; } // make sure this tip doesn't provide most links to out_node max_links = 0; for ( ch1 = 0; ch1 < 4; ch1++ ) { if ( smaller ) { singleCvg = get_kmer_left_cov ( *out_node, ch1 ); if ( singleCvg > max_links ) { max_links = singleCvg; } } else { singleCvg = get_kmer_right_cov ( *out_node, ch1 ); if ( singleCvg > max_links ) { max_links = singleCvg; } } } if ( smaller && get_kmer_left_cov ( *out_node, ch ) < max_links ) { tip_c++; node1->deleted = 1; dislink2prevUncertain ( out_node, ch, smaller ); if ( count_branch2prev ( out_node ) == 1 && count_branch2next ( out_node ) == 1 ) { out_node->linear = 1; } return 1; } if ( !smaller && get_kmer_right_cov ( *out_node, int_comp ( ch ) ) < max_links ) { tip_c++; node1->deleted = 1; dislink2prevUncertain ( out_node, ch, smaller ); if ( count_branch2prev ( out_node ) == 1 && count_branch2next ( out_node ) == 1 ) { out_node->linear = 1; } return 1; } } return 0; } /************************************************* Function: removeSingleTips Description: Removes the tips starting from a kmer whose coverage is 1, and marks the linear kmers again (max tips length is 2 * k-mer). Input: None. Output: None. Return: None. *************************************************/ void removeSingleTips () { int i, flag = 0, cut_len_tip; kmer_t * rs; KmerSet * set; //count_ends(hash_table); cut_len_tip = 2 * overlaplen; // >= maxReadLen4all-overlaplen+1 ? 2*overlaplen : maxReadLen4all-overlaplen+1; //if(cut_len_tip > 100) cut_len_tip = 100; fprintf ( stderr, "Start to remove frequency-one-kmer tips shorter than %d.\n", cut_len_tip ); tip_c = 0; for ( i = 0; i < thrd_num; i++ ) { set = KmerSets[i]; set->iter_ptr = 0; while ( set->iter_ptr < set->size ) { if ( !is_kmer_entity_null ( set->flags, set->iter_ptr ) ) { rs = set->array + set->iter_ptr; if ( !rs->linear && !rs->deleted && rs->single ) { flag += clipTipFromNode ( rs, cut_len_tip, 1 ); } // flag += clipTipFromNode (rs, cut_len_tip, 1); } set->iter_ptr++; } } fprintf ( stderr, "Total %d tip(s) removed.\n", tip_c ); Mark1in1outNode (); } /************************************************* Function: removeSingleTips Description: Removes tips and marks the linear kmers again(max tips length is 2 * k-mer). Input: None. Output: None. Return: None. *************************************************/ void removeMinorTips () { int i, flag = 0, cut_len_tip; kmer_t * rs; KmerSet * set; //count_ends(hash_table); //cut_len_tip = 2*overlaplen >= maxReadLen4all-overlaplen+1 ? 2*overlaplen : maxReadLen4all-overlaplen+1; cut_len_tip = 2 * overlaplen; //if(cut_len_tip > 100) cut_len_tip = 100; fprintf ( stderr, "Start to remove tips with minority links.\n" ); tip_c = 0; flag = 1; int round = 1; while ( flag ) { flag = 0; for ( i = 0; i < thrd_num; i++ ) { set = KmerSets[i]; set->iter_ptr = 0; while ( set->iter_ptr < set->size ) { if ( !is_kmer_entity_null ( set->flags, set->iter_ptr ) ) { rs = set->array + set->iter_ptr; if ( !rs->linear && !rs->deleted ) { flag += clipTipFromNode ( rs, cut_len_tip, 0 ); } // flag += clipTipFromNode (rs, cut_len_tip, 0); } set->iter_ptr++; } // fprintf (stderr,"Remove minor tips in kmer set %d is done.\n", i); } fprintf ( stderr, "%d tip(s) removed in cycle %d.\n", flag, round++ ); } /* for (i = 0; i < thrd_num; i++) { set = KmerSets[i]; flag = 1; while (flag) { flag = 0; set->iter_ptr = 0; while (set->iter_ptr < set->size) { if (!is_kmer_entity_null (set->flags, set->iter_ptr)) { rs = set->array + set->iter_ptr; flag += clipTipFromNode (rs, cut_len_tip, 0); } set->iter_ptr++; } } fprintf (stderr,"Remove minor tips in kmer set %d is done.\n", i); } */ fprintf ( stderr, "Total %d tip(s) removed.\n", tip_c ); Mark1in1outNode (); } static void threadRoutine ( void * para ) { PARAMETER * prm; unsigned char id; prm = ( PARAMETER * ) para; id = prm->threadID; //printf("%dth thread with threadID %d, hash_table %p\n",id,prm.threadID,prm.hash_table); while ( 1 ) { if ( * ( prm->selfSignal ) == 2 ) { * ( prm->selfSignal ) = 0; break; } else if ( * ( prm->selfSignal ) == 1 ) { thread_mark ( KmerSets[id], id ); * ( prm->selfSignal ) = 0; } usleep ( 1 ); } } static void creatThrds ( pthread_t * threads, PARAMETER * paras ) { unsigned char i; int temp; for ( i = 0; i < thrd_num; i++ ) { if ( ( temp = pthread_create ( &threads[i], NULL, ( void * ) threadRoutine, & ( paras[i] ) ) ) != 0 ) { fprintf ( stderr, "Create threads failed.\n" ); exit ( 1 ); } } fprintf ( stderr, "%d thread(s) initialized.\n", thrd_num ); } static void thread_mark ( KmerSet * set, unsigned char thrdID ) { int in_num, out_num; kmer_t * rs; set->iter_ptr = 0; while ( set->iter_ptr < set->size ) { if ( !is_kmer_entity_null ( set->flags, set->iter_ptr ) ) { rs = set->array + set->iter_ptr; if ( rs->deleted || rs->linear ) { set->iter_ptr++; continue;; } in_num = count_branch2prev ( rs ); out_num = count_branch2next ( rs ); if ( in_num == 1 && out_num == 1 ) { rs->linear = 1; linearCounter[thrdID]++; } } set->iter_ptr++; } //printf("%lld more linear\n",linearCounter[thrdID]); } static void thread_wait ( pthread_t * threads ) { int i; for ( i = 0; i < thrd_num; i++ ) if ( threads[i] != 0 ) { pthread_join ( threads[i], NULL ); } } static void sendWorkSignal ( unsigned char SIG, unsigned char * thrdSignals ) { int t; for ( t = 0; t < thrd_num; t++ ) { thrdSignals[t + 1] = SIG; } while ( 1 ) { usleep ( 10 ); for ( t = 0; t < thrd_num; t++ ) if ( thrdSignals[t + 1] ) { break; } if ( t == thrd_num ) { break; } } } static void Mark1in1outNode () { int i; long long counter = 0; pthread_t threads[thrd_num]; unsigned char thrdSignal[thrd_num + 1]; PARAMETER paras[thrd_num]; for ( i = 0; i < thrd_num; i++ ) { thrdSignal[i + 1] = 0; paras[i].threadID = i; paras[i].mainSignal = &thrdSignal[0]; paras[i].selfSignal = &thrdSignal[i + 1]; } creatThrds ( threads, paras ); thrdSignal[0] = 0; linearCounter = ( long long * ) ckalloc ( thrd_num * sizeof ( long long ) ); for ( i = 0; i < thrd_num; i++ ) { linearCounter[i] = 0; } sendWorkSignal ( 1, thrdSignal ); //mark linear nodes sendWorkSignal ( 2, thrdSignal ); //stop threads thread_wait ( threads ); for ( i = 0; i < thrd_num; i++ ) { counter += linearCounter[i]; } free ( ( void * ) linearCounter ); fprintf ( stderr, "%lld linear node(s) marked.\n", counter ); } soapdenovo2-240+dfsg.orig/standardPregraph/prlHashCtg.c0000644000000000000000000002636512166703654021716 0ustar rootroot/* * prlHashCtg.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" //debugging variables static long long * kmerCounter; //buffer related varibles for chop kmer static unsigned int read_c; static char ** rcSeq; static char * seqBuffer; static int * lenBuffer; static unsigned int * indexArray; static unsigned int * seqBreakers; //record sum length to indicate start pos on seqBuffer static int * ctgIdArray; //static Kmer *firstKmers; //buffer related varibles for splay tree static unsigned int buffer_size = 100000000; static unsigned int seq_buffer_size; static unsigned int max_read_c; static volatile unsigned int kmer_c; static Kmer * kmerBuffer; static ubyte8 * hashBanBuffer; static boolean * smallerBuffer; static void singleKmer ( int t, KmerSet * kset, unsigned int seq_index, unsigned int pos ); static void chopKmer4read ( int t, int threadID ); static void threadRoutine ( void * para ) { PARAMETER * prm; unsigned int i; unsigned char id; prm = ( PARAMETER * ) para; id = prm->threadID; while ( 1 ) { if ( * ( prm->selfSignal ) == 1 ) { unsigned int seq_index = 0; unsigned int pos = 0; for ( i = 0; i < kmer_c; i++ ) { if ( seq_index < read_c && indexArray[seq_index + 1] == i ) { seq_index++; // which sequence this kmer belongs to pos = 0; } if ( ( unsigned char ) ( hashBanBuffer[i] % thrd_num ) != id ) { pos++; continue; } kmerCounter[id + 1]++; singleKmer ( i, KmerSets[id], seq_index, pos++ ); } * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 2 ) { for ( i = 0; i < read_c; i++ ) { if ( i % thrd_num != id ) { continue; } chopKmer4read ( i, id + 1 ); } * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 3 ) { * ( prm->selfSignal ) = 0; break; } usleep ( 1 ); } } /************************************************* Function: singleKmer Description: Stores a kmer into kmerset and updates related status. Input: 1. t: kmerBuffer index 2. kset: KmerSet 3. seq_index: contig id array index 4. pos: the postion of the kmer on contig Output: None. Return: None. *************************************************/ static void singleKmer ( int t, KmerSet * kset, unsigned int seq_index, unsigned int pos ) { boolean flag; kmer_t * node; flag = put_kmerset ( kset, kmerBuffer[t], 4, 4, &node ); if ( !flag ) { if ( smallerBuffer[t] ) { node->twin = 0; } else { node->twin = 1; }; node->l_links = ctgIdArray[seq_index]; node->r_links = pos; } else { node->deleted = 1; } } static void creatThrds ( pthread_t * threads, PARAMETER * paras ) { unsigned char i; int temp; for ( i = 0; i < thrd_num; i++ ) { if ( ( temp = pthread_create ( &threads[i], NULL, ( void * ) threadRoutine, & ( paras[i] ) ) ) != 0 ) { fprintf ( stderr, "Create threads failed.\n" ); exit ( 1 ); } } fprintf ( stderr, "%d thread(s) initialized.\n", thrd_num ); } static void thread_wait ( pthread_t * threads ) { int i; for ( i = 0; i < thrd_num; i++ ) if ( threads[i] != 0 ) { pthread_join ( threads[i], NULL ); } } static void chopKmer4read ( int t, int threadID ) { char * src_seq = seqBuffer + seqBreakers[t]; char * bal_seq = rcSeq[threadID]; int len_seq = lenBuffer[t]; int j, bal_j; ubyte8 hash_ban, bal_hash_ban; Kmer word, bal_word; int index; #ifdef MER127 word.high1 = word.low1 = word.high2 = word.low2 = 0; for ( index = 0; index < overlaplen; index++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low2 |= src_seq[index]; } #else word.high = word.low = 0; for ( index = 0; index < overlaplen; index++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low |= src_seq[index]; } #endif reverseComplementSeq ( src_seq, len_seq, bal_seq ); // complementary node bal_word = reverseComplement ( word, overlaplen ); bal_j = len_seq - 0 - overlaplen; index = indexArray[t]; if ( KmerSmaller ( word, bal_word ) ) { hash_ban = hash_kmer ( word ); kmerBuffer[index] = word; hashBanBuffer[index] = hash_ban; smallerBuffer[index++] = 1; } else { bal_hash_ban = hash_kmer ( bal_word ); kmerBuffer[index] = bal_word; hashBanBuffer[index] = bal_hash_ban; smallerBuffer[index++] = 0; } for ( j = 1; j <= len_seq - overlaplen; j++ ) { word = nextKmer ( word, src_seq[j - 1 + overlaplen] ); bal_j = len_seq - j - overlaplen; bal_word = prevKmer ( bal_word, bal_seq[bal_j] ); if ( KmerSmaller ( word, bal_word ) ) { hash_ban = hash_kmer ( word ); kmerBuffer[index] = word; hashBanBuffer[index] = hash_ban; smallerBuffer[index++] = 1; } else { // complementary node bal_hash_ban = hash_kmer ( bal_word ); kmerBuffer[index] = bal_word; hashBanBuffer[index] = bal_hash_ban; smallerBuffer[index++] = 0; } } } static void sendWorkSignal ( unsigned char SIG, unsigned char * thrdSignals ) { int t; for ( t = 0; t < thrd_num; t++ ) { thrdSignals[t + 1] = SIG; } while ( 1 ) { usleep ( 10 ); for ( t = 0; t < thrd_num; t++ ) if ( thrdSignals[t + 1] ) { break; } if ( t == thrd_num ) { break; } } } /************************************************* Function: getID Description: Gets contig id. Input: 1.name contig name Output: None. Return: None. *************************************************/ static int getID ( char * name ) { if ( name[0] >= '0' && name[0] <= '9' ) { return atoi ( & ( name[0] ) ); } else { return 0; } } /************************************************* Function: prlContig2nodes Description: Chops contigs not shorter than 'len_cut' into kmers: 1. if the kmer occured twice or more , mark it deleted; 2. 'node->l_links' stores the contig id and 'node->r_links' stores the position the kmer on contig. Input: 1. grapfile: the prefix of contig file 2. len_cut: the minimum length of contig Output: None. Return: True always. *************************************************/ boolean prlContig2nodes ( char * grapfile, int len_cut ) { long long i, num_seq; char name[256], *next_name; FILE * fp; pthread_t threads[thrd_num]; time_t start_t, stop_t; unsigned char thrdSignal[thrd_num + 1]; PARAMETER paras[thrd_num]; int maxCtgLen, minCtgLen, nameLen; unsigned int lenSum, contigId; //init WORDFILTER = createFilter ( overlaplen ); time ( &start_t ); sprintf ( name, "%s.contig", grapfile ); fp = ckopen ( name, "r" ); maxCtgLen = nameLen = 10; minCtgLen = 1000; num_seq = readseqpar ( &maxCtgLen, &minCtgLen, &nameLen, fp ); fprintf ( stderr, "\n%lld contig(s), maximum sequence length %d, minimum sequence length %d, maximum name length %d.\n", num_seq, maxCtgLen, minCtgLen, nameLen ); maxReadLen = maxCtgLen; fclose ( fp ); time ( &stop_t ); fprintf ( stderr, "Time spent on parsing contigs file: %ds.\n", ( int ) ( stop_t - start_t ) ); next_name = ( char * ) ckalloc ( ( maxNameLen + 1 ) * sizeof ( char ) ); // extract all the EDONs seq_buffer_size = buffer_size * 2; max_read_c = seq_buffer_size / 20; kmerBuffer = ( Kmer * ) ckalloc ( buffer_size * sizeof ( Kmer ) ); hashBanBuffer = ( ubyte8 * ) ckalloc ( buffer_size * sizeof ( ubyte8 ) ); smallerBuffer = ( boolean * ) ckalloc ( buffer_size * sizeof ( boolean ) ); seqBuffer = ( char * ) ckalloc ( seq_buffer_size * sizeof ( char ) ); lenBuffer = ( int * ) ckalloc ( max_read_c * sizeof ( int ) ); indexArray = ( unsigned int * ) ckalloc ( ( max_read_c + 1 ) * sizeof ( unsigned int ) ); seqBreakers = ( unsigned int * ) ckalloc ( ( max_read_c + 1 ) * sizeof ( unsigned int ) ); ctgIdArray = ( int * ) ckalloc ( max_read_c * sizeof ( int ) ); fp = ckopen ( name, "r" ); rcSeq = ( char ** ) ckalloc ( ( thrd_num + 1 ) * sizeof ( char * ) ); if ( 1 ) { kmerCounter = ( long long * ) ckalloc ( ( thrd_num + 1 ) * sizeof ( long long ) ); KmerSets = ( KmerSet ** ) ckalloc ( thrd_num * sizeof ( KmerSet * ) ); for ( i = 0; i < thrd_num; i++ ) { KmerSets[i] = init_kmerset ( 1024, 0.77f ); thrdSignal[i + 1] = 0; paras[i].threadID = i; paras[i].mainSignal = &thrdSignal[0]; paras[i].selfSignal = &thrdSignal[i + 1]; kmerCounter[i + 1] = 0; rcSeq[i + 1] = ( char * ) ckalloc ( maxCtgLen * sizeof ( char ) ); } creatThrds ( threads, paras ); } kmer_c = thrdSignal[0] = kmerCounter[0] = 0; time ( &start_t ); read_c = lenSum = i = seqBreakers[0] = indexArray[0] = 0; readseq1by1 ( seqBuffer + seqBreakers[read_c], next_name, & ( lenBuffer[read_c] ), fp, -1 ); while ( !feof ( fp ) ) { contigId = getID ( next_name ); readseq1by1 ( seqBuffer + seqBreakers[read_c], next_name, & ( lenBuffer[read_c] ), fp, 1 ); if ( ( ++i ) % 10000000 == 0 ) { fprintf ( stderr, "--- %lldth contig(s).\n", i ); } if ( lenBuffer[read_c] < overlaplen + 1 || lenBuffer[read_c] < len_cut ) { contigId = getID ( next_name ); continue; } ctgIdArray[read_c] = contigId > 0 ? contigId : i; lenSum += lenBuffer[read_c]; kmer_c += lenBuffer[read_c] - overlaplen + 1; read_c++; seqBreakers[read_c] = lenSum; indexArray[read_c] = kmer_c; if ( read_c == max_read_c || ( lenSum + maxCtgLen ) > seq_buffer_size || ( kmer_c + maxCtgLen - overlaplen + 1 ) > buffer_size ) { kmerCounter[0] += kmer_c; sendWorkSignal ( 2, thrdSignal ); //chopKmer4read sendWorkSignal ( 1, thrdSignal ); //singleKmer kmer_c = read_c = lenSum = 0; } } if ( read_c ) { kmerCounter[0] += kmer_c; sendWorkSignal ( 2, thrdSignal ); //chopKmer4read sendWorkSignal ( 1, thrdSignal ); //singleKmer } sendWorkSignal ( 3, thrdSignal ); //stop threads thread_wait ( threads ); time ( &stop_t ); fprintf ( stderr, "Time spent on hashing contigs: %ds.\n", ( int ) ( stop_t - start_t ) ); if ( 1 ) { unsigned long long alloCounter = 0; unsigned long long allKmerCounter = 0; for ( i = 0; i < thrd_num; i++ ) { alloCounter += count_kmerset ( ( KmerSets[i] ) ); allKmerCounter += kmerCounter[i + 1]; free ( ( void * ) rcSeq[i + 1] ); } fprintf ( stderr, "%lli node(s) allocated, %lli kmer(s) in contigs, %lli kmer(s) processed.\n", alloCounter, kmerCounter[0], allKmerCounter ); } free ( ( void * ) rcSeq ); free ( ( void * ) kmerCounter ); free ( ( void * ) seqBuffer ); free ( ( void * ) lenBuffer ); free ( ( void * ) indexArray ); free ( ( void * ) seqBreakers ); free ( ( void * ) ctgIdArray ); free ( ( void * ) kmerBuffer ); free ( ( void * ) hashBanBuffer ); free ( ( void * ) smallerBuffer ); free ( ( void * ) next_name ); fclose ( fp ); return 1; } soapdenovo2-240+dfsg.orig/standardPregraph/newhash.c0000644000000000000000000003251612166703654021307 0ustar rootroot/* * newhash.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #include "def.h" #define PUBLIC_FUNC #define PROTECTED_FUNC #ifdef MER127 static const kmer_t empty_kmer = { {0, 0, 0, 0}, 0, 0, 0, 0, 0, 1, 0, 0 }; static inline ubyte8 modular ( KmerSet * set, Kmer seq ) { ubyte8 temp; temp = ( seq.high1 % set->size ) << 32 | ( seq.low1 >> 32 & 0xffffffff ); temp = ( temp % set->size ) << 32 | ( seq.low1 & 0xffffffff ); temp = ( temp % set->size ) << 32 | ( seq.high2 >> 32 & 0xffffffff ); temp = ( temp % set->size ) << 32 | ( seq.high2 & 0xffffffff ); temp = ( temp % set->size ) << 32 | ( seq.low2 >> 32 & 0xffffffff ); temp = ( temp % set->size ) << 32 | ( seq.low2 & 0xffffffff ); temp = ( ubyte8 ) ( temp % set->size ); return temp; } #else static const kmer_t empty_kmer = { {0, 0}, 0, 0, 0, 0, 0, 1, 0, 0 }; static inline ubyte8 modular ( KmerSet * set, Kmer seq ) { ubyte8 hc; __uint128_t temp; temp = Kmer2int128 ( seq ); hc = temp % set->size; return hc; } #endif /************************************************* Function: update_kmer Description: Updates the coverage of the kmer. Input: 1. mer: the current kmer 2. left: the upstream character 3. right: the downstream character Output: None. Return: None. *************************************************/ static inline void update_kmer ( kmer_t * mer, ubyte left, ubyte right ) { ubyte4 cov; if ( left < 4 ) { cov = get_kmer_left_cov ( *mer, left ); if ( cov < MAX_KMER_COV ) { set_kmer_left_cov ( *mer, left, cov + 1 ); } } if ( right < 4 ) { cov = get_kmer_right_cov ( *mer, right ); if ( cov < MAX_KMER_COV ) { set_kmer_right_cov ( *mer, right, cov + 1 ); } } } /************************************************* Function: set_new_kmer Description: Initializes the new kmer. Input: 1. mer: the point of the new kmer 2. seq: the sequence of the kmer 3. left: the upstream character 4. right: the downstream character Output: None. Return: None. *************************************************/ static inline void set_new_kmer ( kmer_t * mer, Kmer seq, ubyte left, ubyte right ) { *mer = empty_kmer; set_kmer_seq ( *mer, seq ); if ( left < 4 ) { set_kmer_left_cov ( *mer, left, 1 ); } if ( right < 4 ) { set_kmer_right_cov ( *mer, right, 1 ); } } static inline int is_prime_kh ( ubyte8 num ) { ubyte8 i, max; if ( num < 4 ) { return 1; } if ( num % 2 == 0 ) { return 0; } max = ( ubyte8 ) sqrt ( ( float ) num ); for ( i = 3; i < max; i += 2 ) { if ( num % i == 0 ) { return 0; } } return 1; } static inline ubyte8 find_next_prime_kh ( ubyte8 num ) { if ( num % 2 == 0 ) { num++; } while ( 1 ) { if ( is_prime_kh ( num ) ) { return num; } num += 2; } } /************************************************* Function: init_kmerset Description: Initializes the kmerset Input: 1. init_size: the initial size of the kmerset 2.load_factor: load factor of hash Output: None. Return: The new kmer hash. *************************************************/ PUBLIC_FUNC KmerSet * init_kmerset ( ubyte8 init_size, float load_factor ) { KmerSet * set; if ( init_size < 3 ) { init_size = 3; } else { init_size = find_next_prime_kh ( init_size ); } set = ( KmerSet * ) malloc ( sizeof ( KmerSet ) ); set->size = init_size; set->count = 0; set->max = set->size * load_factor; if ( load_factor <= 0 ) { load_factor = 0.25f; } else if ( load_factor >= 1 ) { load_factor = 0.75f; } set->load_factor = load_factor; set->iter_ptr = 0; set->array = calloc ( set->size, sizeof ( kmer_t ) ); set->flags = malloc ( ( set->size + 15 ) / 16 * 4 ); memset ( set->flags, 0x55, ( set->size + 15 ) / 16 * 4 ); return set; } PROTECTED_FUNC static inline ubyte8 get_kmerset ( KmerSet * set, Kmer seq ) { ubyte8 hc; // U256b temp; // temp = Kmer2int256(seq); // hc = temp.low % set->size; // hc = modular (set, seq); // /* #ifdef MER127 hc = modular ( set, seq ); #else __uint128_t temp; temp = Kmer2int128 ( seq ); hc = temp % set->size; #endif // */ while ( 1 ) { if ( is_kmer_entity_null ( set->flags, hc ) ) { return hc; } else { if ( KmerEqual ( get_kmer_seq ( set->array[hc] ), seq ) ) { return hc; } } hc++; if ( hc == set->size ) { hc = 0; } } return set->size; } PUBLIC_FUNC int search_kmerset ( KmerSet * set, Kmer seq, kmer_t ** rs ) { ubyte8 hc; // U256b temp; // temp = Kmer2int256(seq); // hc = temp.low % set->size; // hc = modular (set, seq); // /* #ifdef MER127 hc = modular ( set, seq ); #else __uint128_t temp; temp = Kmer2int128 ( seq ); hc = temp % set->size; #endif // */ while ( 1 ) { if ( is_kmer_entity_null ( set->flags, hc ) ) { return 0; } else { if ( KmerEqual ( get_kmer_seq ( set->array[hc] ), seq ) ) { *rs = set->array + hc; return 1; } } hc++; if ( hc == set->size ) { hc = 0; } } return 0; } PUBLIC_FUNC static inline int exists_kmerset ( KmerSet * set, Kmer seq ) { ubyte8 idx; idx = get_kmerset ( set, seq ); return !is_kmer_entity_null ( set->flags, idx ); } /************************************************* Function: encap_kmerset Description: Enlarges the kmerset if necessary. Input: 1. set : the hash of kmerset 2. num: the element number add to kmerset Output: None. Return: None. *************************************************/ PROTECTED_FUNC static inline void encap_kmerset ( KmerSet * set, ubyte8 num ) { ubyte4 * flags, *f; ubyte8 i, n, size, hc; kmer_t key, tmp; if ( set->count + num <= set->max ) { return; } n = set->size; if ( initKmerSetSize != 0 ) { if ( set->load_factor < 0.88 ) { set->load_factor = 0.88; set->max = set->size * set->load_factor; return; } else { fprintf ( stderr, "-- Static memory pool exploded, please define a larger value. --\n" ); abort(); } } do { if ( n < 0xFFFFFFFU ) { n <<= 1; } else { n += 0xFFFFFFU; } n = find_next_prime_kh ( n ); } while ( n * set->load_factor < set->count + num ); set->array = realloc ( set->array, n * sizeof ( kmer_t ) ); //printf("Allocate Mem %lld(%d*%lld*%d)bytes\n",thrd_num*n*sizeof(kmer_t),thrd_num,n,sizeof(kmer_t)); if ( set->array == NULL ) { fprintf ( stderr, "-- Out of memory --\n" ); abort (); } flags = malloc ( ( n + 15 ) / 16 * 4 ); memset ( flags, 0x55, ( n + 15 ) / 16 * 4 ); size = set->size; set->size = n; set->max = n * set->load_factor; f = set->flags; set->flags = flags; flags = f; __uint128_t temp; // U256b temp; for ( i = 0; i < size; i++ ) { if ( !exists_kmer_entity ( flags, i ) ) { continue; } key = set->array[i]; set_kmer_entity_del ( flags, i ); while ( 1 ) { // temp = Kmer2int256(get_kmer_seq(key)); // hc = temp.low % set->size; // hc = modular (set, get_kmer_seq (key)); // /* #ifdef MER127 hc = modular ( set, get_kmer_seq ( key ) ); #else temp = Kmer2int128 ( get_kmer_seq ( key ) ); hc = temp % set->size; #endif // */ while ( !is_kmer_entity_null ( set->flags, hc ) ) { hc++; if ( hc == set->size ) { hc = 0; } } clear_kmer_entity_null ( set->flags, hc ); if ( hc < size && exists_kmer_entity ( flags, hc ) ) { tmp = key; key = set->array[hc]; set->array[hc] = tmp; set_kmer_entity_del ( flags, hc ); } else { set->array[hc] = key; break; } } } free ( flags ); } /************************************************* Function: put_kmerset Description: Put a kmer into the kmerset. Input: 1. set : the hash of kmerset 2. seq: the sequence of the kmer 3. left: the upstream charactor of the kmer 4. right: the downstream charactor of the kmer 5. kmer_p: the pointer to the kmer Output: None. Return: 0 if it failed to put kmer into kmerset. *************************************************/ PUBLIC_FUNC int put_kmerset ( KmerSet * set, Kmer seq, ubyte left, ubyte right, kmer_t ** kmer_p ) { ubyte8 hc; if ( set->count + 1 > set->max ) { encap_kmerset ( set, 1 ); } // U256b temp; // temp = Kmer2int256(seq); // hc = temp.low % set->size; // hc = modular (set, seq); // /* #ifdef MER127 hc = modular ( set, seq ); #else __uint128_t temp; temp = Kmer2int128 ( seq ); hc = temp % set->size; #endif // */ do { if ( is_kmer_entity_null ( set->flags, hc ) ) { clear_kmer_entity_null ( set->flags, hc ); set_new_kmer ( set->array + hc, seq, left, right ); set->count++; *kmer_p = set->array + hc; return 0; } else { if ( KmerEqual ( get_kmer_seq ( set->array[hc] ), seq ) ) { update_kmer ( set->array + hc, left, right ); set->array[hc].single = 0; *kmer_p = set->array + hc; return 1; } } hc++; if ( hc == set->size ) { hc = 0; } } while ( 1 ); *kmer_p = NULL; return 0; } /************************************************* Function: count_kmerset Description: 1. Returns the kmer number of the kmerset. Input: 1. set: the kmer hash Output: None. Return: The kmer number of the kmerset. *************************************************/ PUBLIC_FUNC byte8 count_kmerset ( KmerSet * set ) { return set->count; } /************************************************* Function: reset_iter_kmerset Description: Resets the iterator of kmerset. Input: 1. set: the kmer hash Output: None. Return: None. *************************************************/ PUBLIC_FUNC static inline void reset_iter_kmerset ( KmerSet * set ) { set->iter_ptr = 0; } PUBLIC_FUNC static inline ubyte8 iter_kmerset ( KmerSet * set, kmer_t ** rs ) { while ( set->iter_ptr < set->size ) { if ( !is_kmer_entity_null ( set->flags, set->iter_ptr ) ) { *rs = set->array + set->iter_ptr; set->iter_ptr++; return 1; } set->iter_ptr++; } return 0; } PUBLIC_FUNC void free_kmerset ( KmerSet * set ) { free ( set->array ); free ( set->flags ); free ( set ); } /************************************************* Function: free_Sets Description: Releases all the kmerset. Input: 1. set: the kmer hash 2. num: the number of kmersets Output: None. Return: None. *************************************************/ PUBLIC_FUNC void free_Sets ( KmerSet ** sets, int num ) { int i; for ( i = 0; i < num; i++ ) { free_kmerset ( sets[i] ); } free ( ( void * ) sets ); } /************************************************* Function: count_branch2prev Description: Calculates the number of the upstream branches of a kmer. Input: 1. node: the kmer Output: None. Return: The number of the upstream branches. *************************************************/ int count_branch2prev ( kmer_t * node ) { int num = 0, i; for ( i = 0; i < 4; i++ ) { if ( get_kmer_left_cov ( *node, i ) > 0 ) { num++; } } return num; } /************************************************* Function: count_branch2next Description: Calculates the number of the downstream branches of a kmer. Input: 1. node: the kmer Output: None. Return: The number of the downstream branches. *************************************************/ int count_branch2next ( kmer_t * node ) { int num = 0, i; for ( i = 0; i < 4; i++ ) { if ( get_kmer_right_cov ( *node, i ) > 0 ) { num++; } } return num; } /************************************************* Function: dislink2prevUncertain Description: Removes the relation between a kmer and an upstream base. Input: 1. node: the current kmer 2. ch: the upstream base 3. smaller: the direction of the kmer Output: None. Return: None. *************************************************/ void dislink2prevUncertain ( kmer_t * node, char ch, boolean smaller ) { if ( smaller ) { set_kmer_left_cov ( *node, ch, 0 ); } else { set_kmer_right_cov ( *node, int_comp ( ch ), 0 ); } } /************************************************* Function: dislink2nextUncertain Description: Removes the relation between a kmer and a downstream base. Input: 1. node: the current kmer 2. ch: the downstream base 3. smaller: the direction of the kmer Output: None. Return: None. *************************************************/ void dislink2nextUncertain ( kmer_t * node, char ch, boolean smaller ) { if ( smaller ) { set_kmer_right_cov ( *node, ch, 0 ); } else { set_kmer_left_cov ( *node, int_comp ( ch ), 0 ); } } soapdenovo2-240+dfsg.orig/standardPregraph/linearEdge.c0000644000000000000000000002561712166703654021715 0ustar rootroot/* * linearEdge.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #ifdef MER127 //Get the char in Kmer. char getCharInKmer ( Kmer kmer, int pos ) { if ( 2 * pos < 64 ) { kmer.low2 >>= 2 * pos; return kmer.low2 & 3; } else if ( 2 * pos < 128 ) { kmer.high2 >>= 2 * pos - 64; return kmer.high2 & 3; } else if ( 2 * pos < 192 ) { kmer.low1 >>= 2 * pos - 128; return kmer.low1 & 3; } else { kmer.high1 >>= 2 * pos - 192; return kmer.high1 & 3; } } #else char getCharInKmer ( Kmer kmer, int pos ) { if ( 2 * pos < 64 ) { kmer.low >>= 2 * pos; return kmer.low & 3; } else { kmer.high >>= 2 * pos - 64; return kmer.high & 3; } } #endif /************************************************* Function: copyinter Description: Coyies the interger kmer to char seq. Input: 1. targetS: the target seq 2. sourceS: the source kmer 3. pos: the pos at kmer 4. length: the length of sequence to copy Output: None. Return: None. *************************************************/ void copyinter ( char * targetS, Kmer sourceS, int pos, int length ) { char ch; int i, index; index = pos; for ( i = 0; i < length; ++i ) { ch = getCharInKmer ( sourceS, step - i - 1 ); writeChar2tightString ( ch, targetS, index++ ); } } /************************************************* Function: copySeq2 Description: Copies seq from source to target. Input: 1. targetS: the target seq 2. sourceS: the source seq 3. pos: the pos at source 4. length: the length of sequence to copy Output: None. Return: None. *************************************************/ void copySeq2 ( char * targetS, char * sourceS, int pos, int length ) { char ch; int i, index; index = pos; for ( i = 0; i < length; ++i ) { ch = getCharInTightString ( sourceS, i ); writeChar2tightString ( ch, targetS, index++ ); } } /************************************************* Function: checkstep Description: Checks the step between two kmer. Input: 1. to_vt: the to vertex 2. from_vt: the from vertex Output: None. Return: step between two kmer. *************************************************/ int checkstep ( unsigned int to_vt, unsigned int from_vt ) { Kmer to, from; Kmer filtertemp; to = vt_arraynew[to_vt].kmer; from = vt_arraynew[from_vt].kmer; int i = 1; filtertemp = createFilter ( overlaplen - i ); if ( KmerEqual ( KmerRightBitMove ( from, i << 1 ), KmerAnd ( to, filtertemp ) ) ) { return i; } fprintf ( stderr, "When checking step of two edge, step is not found and step is changed to %d, 'to kmer' is ", step ); printKmerSeq ( stderr, to ); fprintf ( stderr, " , 'from kmer' is " ); printKmerSeq ( stderr, from ); fprintf ( stderr, " .\n" ); return step; } /************************************************* Function: linearUpdateConnection2 Description: Updates the arc and coverage information of edges to be merged. Input: 1. e1: edge1 index 2. e2: edge2 index 3. indicate: indicates which edge would remain Output: None. Return: None. *************************************************/ void linearUpdateConnection2 ( unsigned int e1, unsigned int e2, int indicate ) { unsigned int bal_ed; ARC * parc; //caution: length and seq if ( !indicate ) { // edge_array[e1].to_vt = edge_array[e2].to_vt; bal_ed = getTwinEdge ( e1 ); parc = edge_array[e2].arcs; while ( parc ) { parc->bal_arc->to_ed = bal_ed; parc = parc->next; } edge_array[e1].arcs = edge_array[e2].arcs; edge_array[e2].arcs = NULL; if ( edge_array[e1].length < 0 || edge_array[e2].length < 0 ) { fprintf ( stderr, "Error: length < 0.\n" ); } if ( ( edge_array[e1].length || edge_array[e2].length ) && ( edge_array[e1].length + edge_array[e2].length + step > 0 ) ) edge_array[e1].cvg = ( edge_array[e1].cvg * ( edge_array[e1].length + step ) + edge_array[e2].cvg * ( edge_array[e2].length + step ) ) / ( edge_array[e1].length + edge_array[e2].length + step ); edge_array[e2].deleted = 1; } else { //all the arcs pointing to e1 switched to e2 parc = edge_array[getTwinEdge ( e1 )].arcs; while ( parc ) { parc->bal_arc->to_ed = e2; parc = parc->next; } edge_array[e1].arcs = NULL; // edge_array[e2].from_vt = edge_array[e1].from_vt; if ( edge_array[e1].length < 0 || edge_array[e2].length < 0 ) { fprintf ( stderr, "Error: length < 0.\n" ); } if ( ( edge_array[e1].length || edge_array[e2].length ) && ( edge_array[e1].length + edge_array[e2].length + step > 0 ) ) edge_array[e2].cvg = ( edge_array[e1].cvg * ( edge_array[e1].length + step ) + edge_array[e2].cvg * ( edge_array[e2].length + step ) ) / ( edge_array[e1].length + edge_array[e2].length + step ); edge_array[e1].deleted = 1; } } /************************************************* Function: allpathUpdateEdge2 Description: Update graph topology. Input: 1. e1: edge1 index 2. e2: edge2 index 3. indicate: indicates which edge would remain. 4. last: whether it's the last iterate. Output: None. Return: None. *************************************************/ void allpathUpdateEdge2 ( unsigned int e1, unsigned int e2, int indicate, boolean last ) { int tightLen; char * tightSeq = NULL; int tempstep = 0; //caution: length and seq if ( edge_array[e1].cvg == 0 ) { edge_array[e1].cvg = edge_array[e2].cvg; } if ( edge_array[e2].cvg == 0 ) { edge_array[e2].cvg = edge_array[e1].cvg; } unsigned int cvgsum = edge_array[e1].cvg * ( edge_array[e1].length + step ) + edge_array[e2].cvg * ( edge_array[e2].length + step ); tightLen = edge_array[e1].length + edge_array[e2].length + step; if ( tightLen ) { tightSeq = ( char * ) ckalloc ( ( tightLen / 4 + 1 ) * sizeof ( char ) ); } tightLen = 0; if ( edge_array[e1].length ) { copySeq2 ( tightSeq, edge_array[e1].seq, 0, edge_array[e1].length ); tightLen = edge_array[e1].length; if ( edge_array[e1].seq ) { free ( ( void * ) edge_array[e1].seq ); edge_array[e1].seq = NULL; } else { fprintf ( stderr, "AllpathUpdateEdge: edge %d with length %d, but without seq.\n", e1, edge_array[e1].length ); } } { if ( step > 0 ) { tempstep = checkstep ( edge_array[e1].to_vt, edge_array[e2].from_vt ); copyinter ( tightSeq, vt_arraynew[edge_array[e2].from_vt].kmer, tightLen, tempstep ); tightLen += tempstep; } } if ( edge_array[e2].length ) { copySeq2 ( tightSeq, edge_array[e2].seq, tightLen, edge_array[e2].length ); tightLen += edge_array[e2].length; if ( edge_array[e2].seq ) { free ( ( void * ) edge_array[e2].seq ); edge_array[e2].seq = NULL; } else { fprintf ( stderr, "AllpathUpdateEdge: edge %d with length %d, but without seq.\n", e2, edge_array[e2].length ); } } //edge_array[e2].extend_len = tightLen-edge_array[e2].length; //the sequence of e1 is to be updated if ( !indicate ) { edge_array[e2].length = 0; //e2 is removed from the graph edge_array[e1].to_vt = edge_array[e2].to_vt; //e2 is part of e1 now edge_array[e1].length = tightLen; edge_array[e1].seq = tightSeq; if ( tightLen ) { edge_array[e1].cvg = cvgsum / tightLen; } if ( last ) { edge_array[e1].cvg = edge_array[e1].cvg > 0 ? edge_array[e1].cvg : 1; } } else { edge_array[e1].length = 0; //e1 is removed from the graph edge_array[e2].from_vt = edge_array[e1].from_vt; //e1 is part of e2 now edge_array[e2].length = tightLen; edge_array[e2].seq = tightSeq; if ( tightLen ) { edge_array[e2].cvg = cvgsum / tightLen; } if ( last ) { edge_array[e2].cvg = edge_array[e2].cvg > 0 ? edge_array[e2].cvg : 1; } } } static void debugging ( unsigned int i ) { ARC * parc; parc = edge_array[i].arcs; if ( !parc ) { fprintf ( stderr, "No downward connection for %d.\n", i ); } while ( parc ) { fprintf ( stderr, "%d -> %d\n", i, parc->to_ed ); parc = parc->next; } } /************************************************* Function: linearConcatenate2 Description: Concatenates two edges if they are linearly linked. Input: 1. last: whether it's the last iterations. Output: None. Return: None. *************************************************/ void linearConcatenate2 ( boolean last ) { unsigned int i; int conc_c = 1; int counter; unsigned int from_ed, to_ed, bal_ed; ARC * parc, *parc2; unsigned int bal_fe; ARC * temp; int donot1 = 0; int round = 1; while ( conc_c ) { conc_c = 0; counter = 0; donot1 = 0; for ( i = 1; i <= num_ed; i++ ) { if ( edge_array[i].deleted || EdSameAsTwin ( i ) ) { continue; } if ( edge_array[i].length > 0 ) { counter++; } parc = edge_array[i].arcs; if ( !parc || parc->next ) { continue; } to_ed = parc->to_ed; bal_ed = getTwinEdge ( to_ed ); parc2 = edge_array[bal_ed].arcs; if ( bal_ed == to_ed || !parc2 || parc2->next ) { continue; } from_ed = i; if ( from_ed == to_ed || from_ed == bal_ed ) { continue; } //linear connection found if ( parc->multiplicity <= arcfilter ) { donot1++; continue; } conc_c++; bal_fe = getTwinEdge ( from_ed ); linearUpdateConnection2 ( from_ed, to_ed, 0 ); allpathUpdateEdge2 ( from_ed, to_ed, 0, last ); linearUpdateConnection2 ( bal_ed, bal_fe, 1 ); allpathUpdateEdge2 ( bal_ed, bal_fe, 1, last ); } fprintf ( stderr, "%d edge(s) concatenated in cycle %d.\n", conc_c, round++ ); if ( arcfilter ) { fprintf ( stderr, "%d edge(s) are not linearized because of arc weight is %d.\n", donot1, arcfilter ); } } fprintf ( stderr, "%d edge(s) in the graph.\n", counter ); } soapdenovo2-240+dfsg.orig/standardPregraph/scaffold.c0000644000000000000000000001721712166703654021434 0ustar rootroot/* * scaffold.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" static void initenv ( int argc, char ** argv ); static void display_scaff_usage (); static boolean LINK, SCAFF; static char graphfile[256]; /************************************************* Function: call_scaffold Description: This is the main function of 'scaff' step. It includes the following steps: 1. Reads required input information. 2. Constructs scaffolds. 3. Fills gaps if required, then output result. Input: See @display_scaff_usage (). Output: Scaffolds results and related information. 1. *.scafSeq 2. *.scafStatistics 3. *.contigPosInscaff 4. *.bubbleInScaff 5. *.gapSeq 6. *.links 7. *.scaf 8. *.scaf_gap 9. *.newContigIndex Return: 0 if exit normally. *************************************************/ int call_scaffold ( int argc, char ** argv ) { time_t start_t, stop_t, time_bef, time_aft; fprintf ( stderr, "\n********************\n" ); fprintf ( stderr, "Scaff\n" ); fprintf ( stderr, "********************\n\n" ); ctg_short = 0; time ( &start_t ); initenv ( argc, argv ); checkFiles4Scaff ( graphfile ); loadPEgrads ( graphfile ); time ( &time_bef ); loadUpdatedEdges ( graphfile ); time ( &time_aft ); fprintf ( stderr, "Time spent on loading updated edges: %ds.\n\n", ( int ) ( time_aft - time_bef ) ); if ( !SCAFF ) { time ( &time_bef ); PE2Links ( graphfile ); time ( &time_aft ); fprintf ( stderr, "Time spent on loading paired-end reads information: %ds.\n", ( int ) ( time_aft - time_bef ) ); time ( &time_bef ); fprintf ( stderr, "\n*****************************************************\nStart to construct scaffolds.\n" ); Links2Scaf ( graphfile ); time ( &time_aft ); fprintf ( stderr, "Time spent on constructing scaffolds: %ds.\n", ( int ) ( time_aft - time_bef ) ); scaffolding ( 100, graphfile ); } prlReadsCloseGap ( graphfile ); ScafStat ( 100, graphfile ); free_pe_mem (); if ( index_array ) { free ( ( void * ) index_array ); } freeContig_array (); destroyPreArcMem (); destroyConnectMem (); deleteCntLookupTable (); time ( &stop_t ); fprintf ( stderr, "\nOverall time spent on constructing scaffolds: %dm.\n", ( int ) ( stop_t - start_t ) / 60 ); return 0; } /***************************************************************************** * Parse command line switches *****************************************************************************/ void initenv ( int argc, char ** argv ) { int copt; int inpseq; extern char * optarg; char temp[256]; inpseq = 0; LINK = 0; SCAFF = 0; optind = 1; fprintf ( stderr, "Parameters: scaff " ); while ( ( copt = getopt ( argc, argv, "g:L:p:G:N:c:C:b:B:FzuSVw" ) ) != EOF ) { switch ( copt ) { case 'g': fprintf ( stderr, "-g %s ", optarg ); inGraph = 1; sscanf ( optarg, "%s", graphfile ); break; case 'G': fprintf ( stderr, "-G %s ", optarg ); sscanf ( optarg, "%s", temp ); GLDiff = atoi ( temp ); break; case 'L': fprintf ( stderr, "-L %s ", optarg ); sscanf ( optarg, "%s", temp ); ctg_short = atoi ( temp ); break; case 'N': fprintf ( stderr, "-N %s ", optarg ); sscanf ( optarg, "%s", temp ); known_genome_size = atoi ( temp ); break; case 'F': fillGap = 1; fprintf ( stderr, "-F " ); break; case 'u': maskRep = 0; fprintf ( stderr, "-u " ); break; case 'S': SCAFF = 1; fprintf ( stderr, "-S " ); break; case 'V': visual = 1; fprintf ( stderr, "-V " ); break; case 'w': score_mask = 0; fprintf ( stderr, "-w " ); break; case 'p': fprintf ( stderr, "-p %s ", optarg ); sscanf ( optarg, "%s", temp ); thrd_num = atoi ( temp ); break; case 'c': fprintf ( stderr, "-c %s ", optarg ); sscanf ( optarg, "%s", temp ); cvg_low = atof ( temp ) > 0 ? atof ( temp ) : 0.0; break; case 'C': fprintf ( stderr, "-C %s ", optarg ); sscanf ( optarg, "%s", temp ); cvg_high = atof ( temp ) > 0 ? atof ( temp ) : 0.0; break; case 'b': fprintf ( stderr, "-b %s ", optarg ); sscanf ( optarg, "%s", temp ); ins_var_idx = atof ( temp ) > 1.0 ? atof ( temp ) : 0.0; break; case 'B': fprintf ( stderr, "-B %s ", optarg ); sscanf ( optarg, "%s", temp ); cvg4SNP = atof ( temp ) > 0 ? atof ( temp ) : 0.0; break; case 'z': COMPATIBLE_MODE = 1; fprintf ( stderr, "-m " ); break; default: if ( inGraph == 0 ) { display_scaff_usage (); exit ( -1 ); } } } fprintf ( stderr, "\n\n" ); if ( inGraph == 0 ) { display_scaff_usage (); exit ( -1 ); } } static void display_scaff_usage () { fprintf ( stderr, "\nscaff -g inputGraph [-F -z -u -S -w] [-G gapLenDiff -L minContigLen -c minContigCvg -C maxContigCvg -b insertSizeUpperBound -B bubbleCoverage -N genomeSize -p n_cpu]\n" ); fprintf ( stderr, " -g inputGraph: prefix of input graph file names\n" ); fprintf ( stderr, " -F (optional) fill gaps in scaffold, [No]\n" ); fprintf ( stderr, " -z (optional) use compatible mode to build scaffold with contig produced by Version 1.05, [No]\n" ); fprintf ( stderr, " -u (optional) un-mask contigs with high/low coverage before scaffolding, [mask]\n" ); fprintf ( stderr, " -S (optional) if scaffold structure exists, do gapfilling only(-F), [NO]\n" ); fprintf ( stderr, " -w (optional) keep contigs weakly connected to other contigs in scaffold, [NO]\n" ); fprintf ( stderr, " -V (optional) output information for Hawkeye to visualize the assembly, [NO]\n" ); fprintf ( stderr, " -G gapLenDiff: allowed length difference between estimated and filled gap, [50]\n" ); fprintf ( stderr, " -L minContigLen: shortest contig for scaffolding, [K+2]\n" ); fprintf ( stderr, " -c minContigCvg: minimum contig coverage (c*avgCvg), contigs shorter than 100bp with coverage smaller than c*avgCvg will be masked before scaffolding unless -u is set, [0.1]\n" ); fprintf ( stderr, " -C maxContigCvg: maximum contig coverage (C*avgCvg), contigs with coverage larger than C*avgCvg or contigs shorter than 100bp with coverage larger than 0.8*C*avgCvg will be masked before scaffolding unless -u is set, [2]\n" ); fprintf ( stderr, " -b insertSizeUpperBound: (b*avg_ins) will be used as upper bound of insert size for large insert size ( > 1000) when handling pair-end connections between contigs if b is set to larger than 1, [1.5]\n" ); fprintf ( stderr, " -B bubbleCoverage: remove contig with lower cvoerage in bubble structure if both contigs' coverage are smaller than bubbleCoverage*avgCvg, [0.6]\n" ); fprintf ( stderr, " -N genomeSize: genome size for statistics, [0]\n" ); fprintf ( stderr, " -p n_cpu: number of cpu for use, [8]\n" ); } soapdenovo2-240+dfsg.orig/standardPregraph/readInterval.c0000644000000000000000000000352412166703654022267 0ustar rootroot/* * readInterval.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #define RVBLOCKSIZE 1000 void destroyReadIntervMem () { freeMem_manager ( rv_mem_manager ); rv_mem_manager = NULL; } READINTERVAL * allocateRV ( int readid, int edgeid ) { READINTERVAL * newRV; newRV = ( READINTERVAL * ) getItem ( rv_mem_manager ); newRV->readid = readid; newRV->edgeid = edgeid; newRV->nextInRead = NULL; newRV->prevInRead = NULL; newRV->nextOnEdge = NULL; newRV->prevOnEdge = NULL; return newRV; } void dismissRV ( READINTERVAL * rv ) { returnItem ( rv_mem_manager, rv ); } /************************************************* Function: createRVmemo Description: Alloc the memory for rv_mem_manager. Input: None. Output: None. Return: None. *************************************************/ void createRVmemo () { if ( !rv_mem_manager ) { rv_mem_manager = createMem_manager ( RVBLOCKSIZE, sizeof ( READINTERVAL ) ); } else { fprintf ( stderr, "Warning from createRVmemo: rv_mem_manager is an active pointer.\n" ); } } soapdenovo2-240+dfsg.orig/standardPregraph/seperateScaff.pl0000644000000000000000000000604112166703654022610 0ustar rootroot#!/usr/bin/perl -w use strict; use Getopt::Long; =head1 Description Program: seperateScaff.pl Author: BGI-Shenzhen Version: 1.0 Contact: soap@genomics.cn This script is used to seperate singletons from scaffolds in *.scafSeq file output by SOAPdenovo. There are two new output files as follow: 1) *.scafSeq.scaffold, containing scaffolds only. 2) *.scafSeq.singleton, containing singletons only. User can set the minimun length of sequence to output. =head1 Usage perl seperateScaff.pl [options] >seperateScaff.log --scafSeq *.scafSeq file output by SOAPdenovo, required --scafLen minumum length of scaffold to output, default 0 --sigtLen minumum length of singleton to output, default 0 -h output help information =cut die `pod2text $0` if (@ARGV < 1); my ($scafSeq, $help); my ($scafLen, $sigtLen) = (0, 0); GetOptions ( "scafSeq:s"=>\$scafSeq, "scafLen:i"=>\$scafLen, "sigtLen:i"=>\$sigtLen, "h"=>\$help ); die `pod2text $0` if ($help); if (! -f $scafSeq) { print "\n[Error] $scafSeq does not exist.\n\n"; die `pod2text $0`; } if ($scafLen < 0) { print "\n[Warning] Set minimum length of scaffold is negative, program will use 0 instead.\n\n"; $scafLen = 0; } if ($sigtLen < 0) { print "\n[Warning] Set minimum length of singleton is negative, program will use 0 instead.\n\n"; $sigtLen = 0; } print "Command:\n perl $0 --scafSeq $scafSeq --scafLen $scafLen --sigtLen $sigtLen\n\n"; my ($gotScaf, $gotSigt, $id, $seq, $len) = (0, 0, "", "", 0); my ($totalScafNum, $totalScafLen, $totalSigtNum, $totalSigtLen) = (0, 0, 0, 0); my ($outputScafNum, $outputScafLen, $outputSigtNum, $outputSigtLen) = (0, 0, 0, 0); open SCAF, ">$scafSeq.scaffold" or die "Can't open output file: $scafSeq.scaffold\n"; open SIGT, ">$scafSeq.singleton" or die "Can't open output file: $scafSeq.singleton\n"; open IN, "$scafSeq" or die "Can't open input file: $scafSeq\n"; while () { if (/^>/) { handleOneSeq(); $id = $_; $seq = ""; $len = 0; if ($_ =~ /^>scaff/) { $gotScaf = 1; $gotSigt = 0; } elsif ($_ =~ /^>C/) { $gotSigt = 1; $gotScaf = 0; } } else { $seq .= $_; $len += length ($_) - 1; } } handleOneSeq(); close IN; close SCAF; close SIGT; print "Total scaffold number: $totalScafNum\nTotal scaffold length: $totalScafLen\nNumber of scaffold no shorter than $scafLen: $outputScafNum\nLength of scaffold no shorter than $scafLen: $outputScafLen\n\n"; print "Total singleton number: $totalSigtNum\nTotal singleton length: $totalSigtLen\nNumber of singleton no shorter than $sigtLen: $outputSigtNum\nLength of singleton no shorter than $sigtLen: $outputSigtLen\n"; ################################# ########## Sub Routine ########## ################################# sub handleOneSeq { if ($gotScaf == 1) { $totalScafNum++; $totalScafLen += $len; if ($len >= $scafLen) { $outputScafNum++; $outputScafLen += $len; print SCAF "$id$seq"; } } elsif ($gotSigt == 1) { $totalSigtNum++; $totalSigtLen += $len; if ($len >= $sigtLen) { $outputSigtNum++; $outputSigtLen += $len; print SIGT "$id$seq"; } } 1; } soapdenovo2-240+dfsg.orig/standardPregraph/prlHashReads.c0000644000000000000000000006256512166703654022241 0ustar rootroot/* * prlHashReads.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" //debugging variables static long long * tips; static long long * kmerCounter; //kmer number for each KmerSet[thread id] static long long ** kmerFreq; //buffer related varibles for chop kmer static int read_c; static char ** rcSeq; //sequence pointer for each thread static char ** seqBuffer; //read buffer static int * lenBuffer; //read length buffer static int * indexArray; // the read's begin kmer 's kmer_c //buffer related varibles for splay tree static int buffer_size = 100000000; //buffer size for kmerBuffer... static volatile int kmer_c; // kmer count number static Kmer * kmerBuffer; //kmer buffer array static ubyte8 * hashBanBuffer; //the buffered hash value for 'kmerBuffer' static char * nextcBuffer, *prevcBuffer; //next char buffer , previous char buffer for 'kmerBuffer' static struct aiocb aio1; static struct aiocb aio2; static char * aioBuffer1; static char * aioBuffer2; static char * readBuffer1; static char * readBuffer2; static void thread_mark ( KmerSet * set, unsigned char thrdID ); static void Mark1in1outNode ( unsigned char * thrdSignal ); static void thread_delow ( KmerSet * set, unsigned char thrdID ); static void deLowCov ( unsigned char * thrdSignal ); static void singleKmer ( int t, KmerSet * kset ); static void chopKmer4read ( int t, int threadID ); static void freqStat ( char * outfile ); static void threadRoutine ( void * para ) { PARAMETER * prm; int i; unsigned char id; prm = ( PARAMETER * ) para; id = prm->threadID; //printf("%dth thread with threadID %d, hash_table %p\n",id,prm.threadID,prm.hash_table); while ( 1 ) { if ( * ( prm->selfSignal ) == 1 ) { for ( i = 0; i < kmer_c; i++ ) { //if((unsigned char)(magic_seq(hashBanBuffer[i])%thrd_num)!=id) //if((kmerBuffer[i]%thrd_num)!=id) if ( ( hashBanBuffer[i] % thrd_num ) != id ) { continue; } kmerCounter[id + 1]++; singleKmer ( i, KmerSets[id] ); } * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 2 ) { for ( i = 0; i < read_c; i++ ) { if ( i % thrd_num != id ) { continue; } chopKmer4read ( i, id + 1 ); } * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 3 ) { * ( prm->selfSignal ) = 0; break; } else if ( * ( prm->selfSignal ) == 4 ) { thread_mark ( KmerSets[id], id ); * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 5 ) { thread_delow ( KmerSets[id], id ); * ( prm->selfSignal ) = 0; } usleep ( 1 ); } } static void singleKmer ( int t, KmerSet * kset ) { kmer_t * pos; put_kmerset ( kset, kmerBuffer[t], prevcBuffer[t], nextcBuffer[t], &pos ); } static void creatThrds ( pthread_t * threads, PARAMETER * paras ) { unsigned char i; int temp; for ( i = 0; i < thrd_num; i++ ) { //printf("to create %dth thread\n",(*(char *)&(threadID[i]))); if ( ( temp = pthread_create ( &threads[i], NULL, ( void * ) threadRoutine, & ( paras[i] ) ) ) != 0 ) { fprintf ( stderr, "Create threads failed.\n" ); exit ( 1 ); } } fprintf ( stderr, "%d thread(s) initialized.\n", thrd_num ); } static void thread_wait ( pthread_t * threads ) { int i; for ( i = 0; i < thrd_num; i++ ) if ( threads[i] != 0 ) { pthread_join ( threads[i], NULL ); } } static void chopKmer4read ( int t, int threadID ) { char * src_seq = seqBuffer[t]; char * bal_seq = rcSeq[threadID]; int len_seq = lenBuffer[t]; int j, bal_j; ubyte8 hash_ban, bal_hash_ban; Kmer word, bal_word; int index; char InvalidCh = 4; #ifdef MER127 word.high1 = word.low1 = word.high2 = word.low2 = 0; for ( index = 0; index < overlaplen; index++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low2 |= src_seq[index]; } #else word.high = word.low = 0; for ( index = 0; index < overlaplen; index++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low |= src_seq[index]; } #endif reverseComplementSeq ( src_seq, len_seq, bal_seq ); // complementary node bal_word = reverseComplement ( word, overlaplen ); bal_j = len_seq - overlaplen; index = indexArray[t]; if ( KmerSmaller ( word, bal_word ) ) { hash_ban = hash_kmer ( word ); hashBanBuffer[index] = hash_ban; kmerBuffer[index] = word; prevcBuffer[index] = InvalidCh; nextcBuffer[index++] = src_seq[0 + overlaplen]; } else { bal_hash_ban = hash_kmer ( bal_word ); hashBanBuffer[index] = bal_hash_ban; kmerBuffer[index] = bal_word; prevcBuffer[index] = bal_seq[bal_j - 1]; nextcBuffer[index++] = InvalidCh; } for ( j = 1; j <= len_seq - overlaplen; j++ ) { word = nextKmer ( word, src_seq[j - 1 + overlaplen] ); bal_j = len_seq - j - overlaplen; bal_word = prevKmer ( bal_word, bal_seq[bal_j] ); if ( KmerSmaller ( word, bal_word ) ) { hash_ban = hash_kmer ( word ); hashBanBuffer[index] = hash_ban; kmerBuffer[index] = word; prevcBuffer[index] = src_seq[j - 1]; if ( j < len_seq - overlaplen ) { nextcBuffer[index++] = src_seq[j + overlaplen]; } else { nextcBuffer[index++] = InvalidCh; } //printf("%dth: %p with %p\n",kmer_c-1,word,hashBanBuffer[kmer_c-1]); } else { // complementary node bal_hash_ban = hash_kmer ( bal_word ); hashBanBuffer[index] = bal_hash_ban; kmerBuffer[index] = bal_word; if ( bal_j > 0 ) { prevcBuffer[index] = bal_seq[bal_j - 1]; } else { prevcBuffer[index] = InvalidCh; } nextcBuffer[index++] = bal_seq[bal_j + overlaplen]; //printf("%dth: %p with %p\n",kmer_c-1,bal_word,hashBanBuffer[kmer_c-1]); } } } static void sendWorkSignal ( unsigned char SIG, unsigned char * thrdSignals ) { int t; for ( t = 0; t < thrd_num; t++ ) { thrdSignals[t + 1] = SIG; } while ( 1 ) { usleep ( 10 ); for ( t = 0; t < thrd_num; t++ ) if ( thrdSignals[t + 1] ) { break; } if ( t == thrd_num ) { break; } } } /************************************************* Function: prlRead2HashTable Description: 1. Imports the reads from the lib file one by one. 2. Chops the reads into kmers and store them in KmerSets. 3. Removes the kmers with low coverage. 4. Marks the linear kmers. 5. Counts the kmer frequences. Input: 1. libfile : the reads config file 2. outfile : the output file prefix Output: None. Return: 1 if exits normally. *************************************************/ boolean prlRead2HashTable ( char * libfile, char * outfile ) { char * cach1; char * cach2; unsigned char asm_ctg = 1; long long i; char * next_name, name[256]; FILE * fo; time_t start_t, stop_t; int maxReadNum; int libNo; pthread_t threads[thrd_num]; unsigned char thrdSignal[thrd_num + 1]; PARAMETER paras[thrd_num]; boolean flag, pairs = 0; WORDFILTER = createFilter ( overlaplen ); maxReadLen = 0; maxNameLen = 256; scan_libInfo ( libfile ); alloc_pe_mem ( num_libs ); if ( !maxReadLen ) { maxReadLen = 100; } if ( gLineLen < maxReadLen ) { gStr = ( char * ) ckalloc ( ( maxReadLen + 1 ) * sizeof ( char ) ); } //init maxReadLen4all = maxReadLen; fprintf ( stderr, "In %s, %d lib(s), maximum read length %d, maximum name length %d.\n\n", libfile, num_libs, maxReadLen, maxNameLen ); next_name = ( char * ) ckalloc ( ( maxNameLen + 1 ) * sizeof ( char ) ); kmerBuffer = ( Kmer * ) ckalloc ( buffer_size * sizeof ( Kmer ) ); hashBanBuffer = ( ubyte8 * ) ckalloc ( buffer_size * sizeof ( ubyte8 ) ); prevcBuffer = ( char * ) ckalloc ( buffer_size * sizeof ( char ) ); nextcBuffer = ( char * ) ckalloc ( buffer_size * sizeof ( char ) ); maxReadNum = buffer_size / ( maxReadLen - overlaplen + 1 ); //printf("buffer size %d, max read len %d, max read num %d\n",buffer_size,maxReadLen,maxReadNum); int maxAIOSize = 32768; aioBuffer1 = ( char * ) ckalloc ( ( maxAIOSize ) * sizeof ( char ) ); aioBuffer2 = ( char * ) ckalloc ( ( maxAIOSize ) * sizeof ( char ) ); readBuffer1 = ( char * ) ckalloc ( ( maxAIOSize + ( maxReadLen * 4 + 1024 ) ) * sizeof ( char ) ); //(char *)ckalloc(maxAIOSize*sizeof(char)); //1024 readBuffer2 = ( char * ) ckalloc ( ( maxAIOSize + ( maxReadLen * 4 + 1024 ) ) * sizeof ( char ) ); //1024 cach1 = ( char * ) ckalloc ( ( maxReadLen * 4 + 1024 ) * sizeof ( char ) ); //1024 cach2 = ( char * ) ckalloc ( ( maxReadLen * 4 + 1024 ) * sizeof ( char ) ); //1024 memset ( cach1, '\0', ( maxReadLen * 4 + 1024 ) ); //1024 memset ( cach2, '\0', ( maxReadLen * 4 + 1024 ) ); //1024 seqBuffer = ( char ** ) ckalloc ( maxReadNum * sizeof ( char * ) ); lenBuffer = ( int * ) ckalloc ( maxReadNum * sizeof ( int ) ); indexArray = ( int * ) ckalloc ( maxReadNum * sizeof ( int ) ); for ( i = 0; i < maxReadNum; i++ ) { seqBuffer[i] = ( char * ) ckalloc ( maxReadLen * sizeof ( char ) ); } rcSeq = ( char ** ) ckalloc ( ( thrd_num + 1 ) * sizeof ( char * ) ); if ( 1 ) { kmerCounter = ( long long * ) ckalloc ( ( thrd_num + 1 ) * sizeof ( long long ) ); KmerSets = ( KmerSet ** ) ckalloc ( thrd_num * sizeof ( KmerSet * ) ); ubyte8 init_size = 1024; ubyte8 k = 0; if ( initKmerSetSize ) { #ifdef MER127 init_size = ( ubyte8 ) ( ( double ) initKmerSetSize * 1024.0f * 1024.0f * 1024.0f / ( double ) thrd_num / 40 ); #else init_size = ( ubyte8 ) ( ( double ) initKmerSetSize * 1024.0f * 1024.0f * 1024.0f / ( double ) thrd_num / 24 ); //is it true? #endif do { ++k; } while ( k * 0xFFFFFFLLU < init_size ); } for ( i = 0; i < thrd_num; i++ ) { //KmerSets[i] = init_kmerset(1024,0.77f); KmerSets[i] = init_kmerset ( ( ( initKmerSetSize ) ? ( k * 0xFFFFFFLLU ) : ( init_size ) ), 0.77f ); thrdSignal[i + 1] = 0; paras[i].threadID = i; paras[i].mainSignal = &thrdSignal[0]; paras[i].selfSignal = &thrdSignal[i + 1]; kmerCounter[i + 1] = 0; rcSeq[i + 1] = ( char * ) ckalloc ( maxReadLen * sizeof ( char ) ); } creatThrds ( threads, paras ); } thrdSignal[0] = kmerCounter[0] = 0; time ( &start_t ); kmer_c = n_solexa = read_c = i = libNo = readNumBack = gradsCounter = 0; while ( openNextFile ( &libNo, pairs, asm_ctg ) ) { //read bam file if ( lib_array[libNo].curr_type == 4 ) { int type = 0; //deside the PE reads is good or bad while ( ( flag = read1seqInLibBam ( seqBuffer[read_c], next_name, & ( lenBuffer[read_c] ), &libNo, pairs, 1, &type ) ) != 0 ) { if ( type == -1 ) //if the reads is bad, go back. { i--; if ( lenBuffer[read_c - 1] >= overlaplen + 1 ) { kmer_c -= lenBuffer[read_c - 1] - overlaplen + 1; read_c--; } n_solexa -= 2; continue; } if ( ( ++i ) % 100000000 == 0 ) { fprintf ( stderr, "--- %lldth reads.\n", i ); } if ( lenBuffer[read_c] < 0 ) { fprintf ( stderr, "Read len %d.\n", lenBuffer[read_c] ); } if ( lenBuffer[read_c] < overlaplen + 1 ) { continue; } /* if(lenBuffer[read_c]>70) lenBuffer[read_c] = 50; else if(lenBuffer[read_c]>40) lenBuffer[read_c] = 40; */ indexArray[read_c] = kmer_c; kmer_c += lenBuffer[read_c] - overlaplen + 1; read_c++; if ( read_c == maxReadNum ) { kmerCounter[0] += kmer_c; sendWorkSignal ( 2, thrdSignal ); //chopKmer4read sendWorkSignal ( 1, thrdSignal ); //singleKmer kmer_c = read_c = 0; } } } //read PE fasta or fastq else if ( lib_array[libNo].curr_type == 1 || lib_array[libNo].curr_type == 2 ) { initAIO ( &aio1, aioBuffer1, fileno ( lib_array[libNo].fp1 ), maxAIOSize ); initAIO ( &aio2, aioBuffer2, fileno ( lib_array[libNo].fp2 ), maxAIOSize ); int offset1, offset2, flag1, flag2, rt1, rt2; offset1 = offset2 = 0; rt1 = aio_read ( &aio1 ); rt2 = aio_read ( &aio2 ); flag1 = AIORead ( &aio1, &offset1, readBuffer1, cach1, &rt1, lib_array[libNo].curr_type ); flag2 = AIORead ( &aio2, &offset2, readBuffer2, cach2, &rt2, lib_array[libNo].curr_type ); if ( flag1 && flag2 ) { int start1, start2, turn; start1 = start2 = 0; turn = 1; while ( start1 < offset1 || start2 < offset2 ) { if ( turn == 1 ) { turn = 2; readseqInLib ( seqBuffer[read_c], next_name, & ( lenBuffer[read_c] ), readBuffer1, &start1, offset1, libNo ); if ( ( ++i ) % 100000000 == 0 ) { fprintf ( stderr, "--- %lldth reads.\n", i ); } if ( lenBuffer[read_c] < 0 ) { fprintf ( stderr, "Read len %d.\n", lenBuffer[read_c] ); } if ( lenBuffer[read_c] < overlaplen + 1 ) { if ( start1 >= offset1 ) { start1 = 0; offset1 = 0; flag1 = AIORead ( &aio1, &offset1, readBuffer1, cach1, &rt1, lib_array[libNo].curr_type ); } continue; } indexArray[read_c] = kmer_c; kmer_c += lenBuffer[read_c] - overlaplen + 1; read_c++; if ( start1 >= offset1 ) { start1 = 0; offset1 = 0; flag1 = AIORead ( &aio1, &offset1, readBuffer1, cach1, &rt1, lib_array[libNo].curr_type ); } if ( read_c == maxReadNum ) { kmerCounter[0] += kmer_c; sendWorkSignal ( 2, thrdSignal ); //chopKmer4read sendWorkSignal ( 1, thrdSignal ); //singleKmer kmer_c = read_c = 0; } continue; } if ( turn == 2 ) { turn = 1; readseqInLib ( seqBuffer[read_c], next_name, & ( lenBuffer[read_c] ), readBuffer2, &start2, offset2, libNo ); if ( ( ++i ) % 100000000 == 0 ) { fprintf ( stderr, "--- %lldth reads.\n", i ); } if ( lenBuffer[read_c] < 0 ) { fprintf ( stderr, "Read len %d.\n", lenBuffer[read_c] ); } if ( lenBuffer[read_c] < overlaplen + 1 ) { if ( ( flag2 == 2 ) && ( start2 >= offset2 ) ) { break; } if ( start2 >= offset2 ) { start2 = 0; offset2 = 0; flag2 = AIORead ( &aio2, &offset2, readBuffer2, cach2, &rt2, lib_array[libNo].curr_type ); } continue; } indexArray[read_c] = kmer_c; kmer_c += lenBuffer[read_c] - overlaplen + 1; read_c++; if ( ( flag2 == 2 ) && ( start2 >= offset2 ) ) { break; } if ( start2 >= offset2 ) { start2 = 0; offset2 = 0; flag2 = AIORead ( &aio2, &offset2, readBuffer2, cach2, &rt2, lib_array[libNo].curr_type ); } if ( read_c == maxReadNum ) { kmerCounter[0] += kmer_c; sendWorkSignal ( 2, thrdSignal ); //chopKmer4read sendWorkSignal ( 1, thrdSignal ); //singleKmer kmer_c = read_c = 0; } continue; } } } else { fprintf(stderr, "Error: aio_read error.\n"); } } //read single fasta, single fastq and PE fasta in one file else { initAIO ( &aio1, aioBuffer1, fileno ( lib_array[libNo].fp1 ), maxAIOSize ); int offset, flag1, rt; offset = 0; rt = aio_read ( &aio1 ); while ( ( flag1 = AIORead ( &aio1, &offset, readBuffer1, cach1, &rt, lib_array[libNo].curr_type ) ) ) { int start = 0; while ( start < offset ) { readseqInLib ( seqBuffer[read_c], next_name, & ( lenBuffer[read_c] ), readBuffer1, &start, offset, libNo ); if ( ( ++i ) % 100000000 == 0 ) { fprintf ( stderr, "--- %lldth reads.\n", i ); } if ( lenBuffer[read_c] < 0 ) { fprintf ( stderr, "Read len %d.\n", lenBuffer[read_c] ); } if ( lenBuffer[read_c] < overlaplen + 1 ) { continue; } indexArray[read_c] = kmer_c; kmer_c += lenBuffer[read_c] - overlaplen + 1; read_c++; } if ( read_c > maxReadNum - 1024 ) { kmerCounter[0] += kmer_c; sendWorkSignal ( 2, thrdSignal ); //chopKmer4read sendWorkSignal ( 1, thrdSignal ); //singleKmer kmer_c = read_c = 0; } if ( flag1 == 2 ) { break; } } } } if ( read_c ) { kmerCounter[0] += kmer_c; sendWorkSignal ( 2, thrdSignal ); //chopKmer4read sendWorkSignal ( 1, thrdSignal ); //singleKmer } time ( &stop_t ); fprintf ( stderr, "Time spent on hashing reads: %ds, %lld read(s) processed.\n", ( int ) ( stop_t - start_t ), i ); //record insert size info if ( pairs ) { if ( gradsCounter ) { fprintf ( stderr, "%d pe insert size, the largest boundary is %lld.\n\n", gradsCounter, pes[gradsCounter - 1].PE_bound ); } else { fprintf ( stderr, "No paired reads found.\n" ); } sprintf ( name, "%s.peGrads", outfile ); fo = ckopen ( name, "w" ); fprintf ( fo, "grads&num: %d\t%lld\n", gradsCounter, n_solexa ); for ( i = 0; i < gradsCounter; i++ ) { fprintf ( fo, "%d\t%lld\t%d\n", pes[i].insertS, pes[i].PE_bound, pes[i].rank ); } fclose ( fo ); } free_pe_mem (); free_libs (); if ( 1 ) { unsigned long long alloCounter = 0; unsigned long long allKmerCounter = 0; for ( i = 0; i < thrd_num; i++ ) { alloCounter += count_kmerset ( ( KmerSets[i] ) ); allKmerCounter += kmerCounter[i + 1]; free ( ( void * ) rcSeq[i + 1] ); } fprintf ( stderr, "%lli node(s) allocated, %lli kmer(s) in reads, %lli kmer(s) processed.\n", alloCounter, kmerCounter[0], allKmerCounter ); } free ( ( void * ) rcSeq ); free ( ( void * ) kmerCounter ); for ( i = 0; i < maxReadNum; i++ ) { free ( ( void * ) seqBuffer[i] ); } free ( ( void * ) seqBuffer ); free ( ( void * ) lenBuffer ); free ( ( void * ) indexArray ); free ( ( void * ) kmerBuffer ); free ( ( void * ) hashBanBuffer ); free ( ( void * ) nextcBuffer ); free ( ( void * ) prevcBuffer ); free ( ( void * ) next_name ); free ( ( void * ) aioBuffer1 ); free ( ( void * ) aioBuffer2 ); free ( ( void * ) readBuffer1 ); free ( ( void * ) readBuffer2 ); free ( ( void * ) cach1 ); free ( ( void * ) cach2 ); fprintf ( stderr, "done hashing nodes\n" ); if ( deLowKmer ) { time ( &start_t ); deLowCov ( thrdSignal ); time ( &stop_t ); fprintf ( stderr, "Time spent on delowcvgNode: %ds.\n", ( int ) ( stop_t - start_t ) ); } time ( &start_t ); Mark1in1outNode ( thrdSignal ); freqStat ( outfile ); time ( &stop_t ); fprintf ( stderr, "Time spent on marking linear nodes: %ds.\n", ( int ) ( stop_t - start_t ) ); sendWorkSignal ( 3, thrdSignal ); //exit thread_wait ( threads ); return 1; } void initAIO ( struct aiocb * aio, char * buf, int fd, int size ) { bzero ( aio, sizeof ( struct aiocb ) ); aio->aio_buf = ( void * ) buf; aio->aio_fildes = fd; aio->aio_nbytes = size; aio->aio_offset = 0; } int AIORead ( struct aiocb * mycb, int * offset, char * buf, char * cach, int * rt, int curr_type ) { int i, i2, i3, j; int num; size_t mode, get, max_list; // rt = aio_read(mycb); if ( *rt == 0 ) { struct aiocb * aiocb_list[1]; aiocb_list[0] = mycb; max_list = 1; while ( 1 ) { mode = aio_suspend ( ( const struct aiocb * const * ) aiocb_list, max_list, NULL ); if ( mode == -1 ) { if ( errno != EAGAIN && errno != EINTR ) { fprintf ( stderr, "Error:%s.\n", errno ); return 0; } else { continue; } } else { //while(aio_error(mycb) == EINPROGRESS); get = aio_return ( mycb ); j = strlen ( cach ); if ( get > 0 ) { char * temp = ( char * ) ( ( *mycb ).aio_buf ); if ( ( get % 32768 ) != 0 ) { strcpy ( buf, cach ); memcpy ( &buf[j], temp, get ); memset ( cach, '\0', j ); //printf("%s",buf); *offset = j + get; return 2; } if ( ( curr_type == 2 ) || ( curr_type == 6 ) ) { num = 0; for ( i = get - 1; ( temp[i] != '@' ) || ( temp[i - 1] != '\n' ); i-- ) { if ( temp[i] == '\n' ) {num++;} } if ( num <= 1 ) { for ( i2 = i - 2; temp[i2] != '\n'; i2-- ) { ; } if ( temp[i2 + 1] == '+' ) { for ( i2 = i2 - 1; temp[i2] != '\n'; i2-- ) { ; } if ( temp[i2 + 1] != '+' ) {for ( i = i2 - 1; ( temp[i] != '@' ) || ( temp[i - 1] != '\n' ); i-- ) { ; }} } } } else if ( ( curr_type == 1 ) || ( curr_type == 3 ) || ( curr_type == 5 ) ) for ( i = get - 1; temp[i] != '>'; i-- ) { ; } //for (i = get - 1; temp[i] != '>' && temp[i] != '@'; i--) ; strcpy ( buf, cach ); memcpy ( &buf[j], temp, i ); //printf("%s",buf); *offset = i + j; memset ( cach, '\0', j ); memcpy ( cach, &temp[i], get - i ); ( *mycb ).aio_offset += get; *rt = aio_read ( mycb ); return 1; } else { fprintf(stderr, "Error: aio_return error.\n"); } /*else { char *temp = (char *)((*mycb).aio_buf); strcpy(buf,cach); strcpy(&buf[j],temp); *offset = j + get; return 2; } */ } } } else { fprintf(stderr, "Error: (*rt != 0) in AIORead.\n"); } return 0; } boolean openNextFile ( int * libNo, boolean pairs, unsigned char asm_ctg ) { int i = *libNo; int prevLib = i; if ( lib_array[i].fp1 ) { closeFp1InLab ( i ); } if ( lib_array[i].fp2 ) { closeFp2InLab ( i ); } *libNo = nextValidIndex ( i, pairs, asm_ctg ); i = *libNo; if ( lib_array[i].rd_len_cutoff > 0 ) { maxReadLen = lib_array[i].rd_len_cutoff < maxReadLen4all ? lib_array[i].rd_len_cutoff : maxReadLen4all; } else { maxReadLen = maxReadLen4all; } //record insert size info //printf("from lib %d to %d, read %lld to %ld\n",prevLib,i,readNumBack,n_solexa); if ( pairs && i != prevLib ) { if ( readNumBack < n_solexa ) { pes[gradsCounter].PE_bound = n_solexa; pes[gradsCounter].rank = lib_array[prevLib].rank; pes[gradsCounter].pair_num_cut = lib_array[prevLib].pair_num_cut; pes[gradsCounter++].insertS = lib_array[prevLib].avg_ins; readNumBack = n_solexa; } } if ( i >= num_libs ) { return 0; } openFileInLib ( i ); return 1; } static void thread_delow ( KmerSet * set, unsigned char thrdID ) { int i, in_num, out_num, cvgSingle; int l_cvg, r_cvg; kmer_t * rs; set->iter_ptr = 0; while ( set->iter_ptr < set->size ) { if ( !is_kmer_entity_null ( set->flags, set->iter_ptr ) ) { in_num = out_num = l_cvg = r_cvg = 0; rs = set->array + set->iter_ptr; for ( i = 0; i < 4; i++ ) { cvgSingle = get_kmer_left_cov ( *rs, i ); if ( cvgSingle > 0 && cvgSingle <= deLowKmer ) { set_kmer_left_cov ( *rs, i, 0 ); } cvgSingle = get_kmer_right_cov ( *rs, i ); if ( cvgSingle > 0 && cvgSingle <= deLowKmer ) { set_kmer_right_cov ( *rs, i, 0 ); } } if ( rs->l_links == 0 && rs->r_links == 0 ) { rs->deleted = 1; tips[thrdID]++; } } set->iter_ptr++; } //printf("%lld single nodes, %lld linear\n",counter,tips[thrdID]); } static void deLowCov ( unsigned char * thrdSignal ) { int i; long long counter = 0; tips = ( long long * ) ckalloc ( thrd_num * sizeof ( long long ) ); for ( i = 0; i < thrd_num; i++ ) { tips[i] = 0; } sendWorkSignal ( 5, thrdSignal ); //mark linear nodes for ( i = 0; i < thrd_num; i++ ) { counter += tips[i]; } free ( ( void * ) tips ); fprintf ( stderr, "%lld kmer(s) removed.\n", counter ); } static void thread_mark ( KmerSet * set, unsigned char thrdID ) { int i, in_num, out_num, cvgSingle; int l_cvg, r_cvg; kmer_t * rs; long long counter = 0; set->iter_ptr = 0; while ( set->iter_ptr < set->size ) { if ( !is_kmer_entity_null ( set->flags, set->iter_ptr ) ) { in_num = out_num = l_cvg = r_cvg = 0; rs = set->array + set->iter_ptr; for ( i = 0; i < 4; i++ ) { cvgSingle = get_kmer_left_cov ( *rs, i ); if ( cvgSingle > 0 ) { in_num++; l_cvg += cvgSingle; } cvgSingle = get_kmer_right_cov ( *rs, i ); if ( cvgSingle > 0 ) { out_num++; r_cvg += cvgSingle; } } if ( rs->single ) { kmerFreq[thrdID][1]++; counter++; } else { kmerFreq[thrdID][ ( l_cvg > r_cvg ? l_cvg : r_cvg )]++; } if ( in_num == 1 && out_num == 1 ) { rs->linear = 1; tips[thrdID]++; } } set->iter_ptr++; } //printf("%lld single nodes, %lld linear\n",counter,tips[thrdID]); } static void Mark1in1outNode ( unsigned char * thrdSignal ) { int i; long long counter = 0; tips = ( long long * ) ckalloc ( thrd_num * sizeof ( long long ) ); kmerFreq = ( long long ** ) ckalloc ( thrd_num * sizeof ( long long * ) ); for ( i = 0; i < thrd_num; i++ ) { kmerFreq[i] = ( long long * ) ckalloc ( 257 * sizeof ( long long ) ); memset ( kmerFreq[i], 0, 257 * sizeof ( long long ) ); tips[i] = 0; } sendWorkSignal ( 4, thrdSignal ); //mark linear nodes for ( i = 0; i < thrd_num; i++ ) { counter += tips[i]; } free ( ( void * ) tips ); fprintf ( stderr, "%lld linear node(s) marked.\n", counter ); } static void freqStat ( char * outfile ) { FILE * fo; char name[256]; int i, j; long long sum; sprintf ( name, "%s.kmerFreq", outfile ); fo = ckopen ( name, "w" ); for ( i = 1; i < 256; i++ ) { sum = 0; for ( j = 0; j < thrd_num; j++ ) { sum += kmerFreq[j][i]; } fprintf ( fo, "%lld\n", sum ); } for ( i = 0; i < thrd_num; i++ ) { free ( ( void * ) kmerFreq[i] ); } free ( ( void * ) kmerFreq ); fclose ( fo ); } soapdenovo2-240+dfsg.orig/standardPregraph/kmer.c0000644000000000000000000004637312166703654020616 0ustar rootroot/* * kmer.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #ifdef MER127 void PrintKmer ( FILE * fp, Kmer kmer ) { fprintf ( fp, "%llx %llx %llx %llx", kmer.high1, kmer.low1, kmer.high2, kmer.low2 ); } /************************************************* Function: KmerSmaller Description: Checks if kmer1 is smaller than kmer2. if no, returns 0. Input: 1. kmer1: the first kmer 2. kmer2: the second kmer Output: None. Return: 1 if kmer1 is smaller than kmer2. *************************************************/ boolean KmerSmaller ( Kmer kmer1, Kmer kmer2 ) { if ( kmer1.high1 != kmer2.high1 ) { return ( kmer1.high1 < kmer2.high1 ); } else { if ( kmer1.low1 != kmer2.low1 ) { return ( kmer1.low1 < kmer2.low1 ); } else { if ( kmer1.high2 != kmer2.high2 ) { return ( kmer1.high2 < kmer2.high2 ); } else { return ( kmer1.low2 < kmer2.low2 ); } } } } /************************************************* Function: KmerLarger Description: Checks if kmer1 is larger than kmer2. if no, returns 0. Input: 1. kmer1: the first kmer 2. kmer2: the second kmer Output: None. Return: 1 if kmer1 is larger than kmer2. *************************************************/ boolean KmerLarger ( Kmer kmer1, Kmer kmer2 ) { if ( kmer1.high1 != kmer2.high1 ) { return ( kmer1.high1 > kmer2.high1 ); } else { if ( kmer1.low1 != kmer2.low1 ) { return ( kmer1.low1 > kmer2.low1 ); } else { if ( kmer1.high2 != kmer2.high2 ) { return ( kmer1.high2 > kmer2.high2 ); } else { return ( kmer1.low2 > kmer2.low2 ); } } } } /************************************************* Function: KmerEqual Description: Checks if kmer1 is same as kmer2. if no, returns 0. Input: 1. kmer1: the first kmer 2. kmer2: the second kmer Output: None. Return: 1 if if kmer1 is same as kmer2. *************************************************/ boolean KmerEqual ( Kmer kmer1, Kmer kmer2 ) { if ( kmer1.low2 != kmer2.low2 || kmer1.high2 != kmer2.high2 || kmer1.low1 != kmer2.low1 || kmer1.high1 != kmer2.high1 ) { return 0; } else { return 1; } } /************************************************* Function: KmerAnd Description: kmer1 & kmer2 Input: 1. kmer1: the first kmer 2. kmer2: the second kmer Output: None. Return: kmer1 & kmer2. *************************************************/ Kmer KmerAnd ( Kmer kmer1, Kmer kmer2 ) { kmer1.high1 &= kmer2.high1; kmer1.low1 &= kmer2.low1; kmer1.high2 &= kmer2.high2; kmer1.low2 &= kmer2.low2; return kmer1; } /************************************************* Function: KmerLeftBitMoveBy2 Description: word <<= 2. Input: 1. word: the kmer Output: None. Return: word <<= 2. *************************************************/ Kmer KmerLeftBitMoveBy2 ( Kmer word ) { word.high1 = ( word.high1 << 2 ) | ( word.low1 >> 62 ); word.low1 = ( word.low1 << 2 ) | ( word.high2 >> 62 ); word.high2 = ( word.high2 << 2 ) | ( word.low2 >> 62 ); word.low2 <<= 2; return word; } /************************************************* Function: KmerRightBitMoveBy2 Description: word >>= 2. Input: 1. word: the kmer Output: None. Return: word >>= 2. *************************************************/ Kmer KmerRightBitMoveBy2 ( Kmer word ) { word.low2 = ( word.low2 >> 2 ) | ( word.high2 & 0x3 ) << 62; word.high2 = ( word.high2 >> 2 ) | ( word.low1 & 0x3 ) << 62; word.low1 = ( word.low1 >> 2 ) | ( word.high1 & 0x3 ) << 62; word.high1 >>= 2; return word; } /************************************************* Function: KmerPlus Description: Appends a base to kmer to get (k+1)mer. Input: 1. prev: the kmer 2. ch: the downstream Output: None. Return: (k+1)mer. *************************************************/ Kmer KmerPlus ( Kmer prev, char ch ) { Kmer word = KmerLeftBitMoveBy2 ( prev ); word.low2 |= ch; return word; } /************************************************* Function: nextKmer Description: Combines the last (k-1) bases of a kmer with another base to get new kmer. Input: 1. prev: the kmer 2. ch: the appened base Output: None. Return: The new kmer. *************************************************/ Kmer nextKmer ( Kmer prev, char ch ) { Kmer word = KmerLeftBitMoveBy2 ( prev ); word = KmerAnd ( word, WORDFILTER ); word.low2 |= ch; return word; } /************************************************* Function: prevKmer Description: Combines a base with the first (k-1) bases of a kmer to get new kmer. Input: 1. next: the kmer 2. ch: the first base of new kmer Output: None. Return: The new kmer. *************************************************/ Kmer prevKmer ( Kmer next, char ch ) { Kmer word = KmerRightBitMoveBy2 ( next ); switch ( overlaplen ) { case 1 ... 32: word.low2 |= ( ( ( ubyte8 ) ch ) << 2 * ( overlaplen - 1 ) ); break; case 33 ... 64: word.high2 |= ( ( ubyte8 ) ch ) << ( 2 * ( overlaplen - 1 ) - 64 ); break; case 65 ... 96: word.low1 |= ( ( ubyte8 ) ch ) << ( 2 * ( overlaplen - 1 ) - 128 ); break; case 97 ... 128: word.high1 |= ( ( ubyte8 ) ch ) << ( 2 * ( overlaplen - 1 ) - 192 ); break; } return word; } /************************************************* Function: lastCharInKmer Description: Gets the last char of a kmer, and returns it. Input: 1. kmer: the kmer Output: None. Return: The last char of kmer. *************************************************/ char lastCharInKmer ( Kmer kmer ) { return ( char ) ( kmer.low2 & 0x3 ); } /************************************************* Function: firstCharInKmer Description: Gets the first char of a kmer, and returns it. Input: 1. kmer: the kmer Output: None. Return: The first char of kmer. *************************************************/ char firstCharInKmer ( Kmer kmer ) { switch ( overlaplen ) { case 1 ... 32: kmer.low2 >>= 2 * ( overlaplen - 1 ); return kmer.low2; // & 3; case 33 ... 64: kmer.high2 >>= 2 * ( overlaplen - 1 ) - 64; return kmer.high2; // & 3; case 65 ... 96: kmer.low1 >>= 2 * ( overlaplen - 1 ) - 128; return kmer.low1; case 97 ... 128: kmer.high1 >>= 2 * ( overlaplen - 1 ) - 192; return kmer.high1; } } /************************************************* Function: createFilter Description: Creates filter for masking. Input: 1. overlaplen: the kmer value Output: None. Return: The filter kmer. *************************************************/ Kmer createFilter ( int overlaplen ) { Kmer word; word.high1 = word.low1 = word.high2 = word.low2 = 0; switch ( overlaplen ) { case 1 ... 31: word.low2 = ( ( ( ubyte8 ) 1 ) << ( 2 * overlaplen ) ) - 1; break; case 32 ... 63: word.low2 = ~word.low2; word.high2 = ( ( ( ubyte8 ) 1 ) << ( 2 * overlaplen - 64 ) ) - 1; break; case 64 ... 95: word.high2 = word.low2 = ~word.low2; word.low1 = ( ( ( ubyte8 ) 1 ) << ( 2 * overlaplen - 128 ) ) - 1; break; case 96 ... 127: word.low1 = word.high2 = word.low2 = ~word.low2; word.high1 = ( ( ( ubyte8 ) 1 ) << ( 2 * overlaplen - 192 ) ) - 1; break; } return word; } /************************************************* Function: KmerRightBitMove Description: Makes right shifts to a kmer by specified bits and returns the new kmer. Input: 1. word: the kmer 2. dis: the shifted bits Output: None. Return: The new kmer. *************************************************/ Kmer KmerRightBitMove ( Kmer word, int dis ) { ubyte8 mask; switch ( dis ) { case 0 ... 63: mask = ( ( ( ubyte8 ) 1 ) << dis ) - 1; word.low2 = ( word.low2 >> dis ) | ( word.high2 & mask ) << ( 64 - dis ); word.high2 = ( word.high2 >> dis ) | ( word.low1 & mask ) << ( 64 - dis ); word.low1 = ( word.low1 >> dis ) | ( word.high1 & mask ) << ( 64 - dis ); word.high1 >>= dis; return word; case 64 ... 127: mask = ( ( ( ubyte8 ) 1 ) << ( dis - 64 ) ) - 1; word.low2 = word.high2 >> ( dis - 64 ) | ( word.low1 & mask ) << ( 128 - dis ); word.high2 = word.low1 >> ( dis - 64 ) | ( word.high1 & mask ) << ( 128 - dis ); word.low1 = word.high1 >> ( dis - 64 ); word.high1 = 0; return word; case 128 ... 191: mask = ( ( ( ubyte8 ) 1 ) << ( dis - 128 ) ) - 1; word.low2 = word.low1 >> ( dis - 128 ) | ( word.high1 & mask ) << ( 192 - dis ); word.high2 = word.high1 >> ( dis - 128 ); word.high1 = word.low1 = 0; return word; case 192 ... 255: word.low2 = word.high1 >> ( dis - 192 ); word.high1 = word.low1 = word.high2 = 0; return word; } } /************************************************* Function: printKmerSeq Description: Prints seq of kmer. Input: 1. fp: output file 2. kmer: the output kmer Output: None. Return: None. *************************************************/ void printKmerSeq ( FILE * fp, Kmer kmer ) { int i, bit1, bit2, bit3, bit4; bit4 = bit3 = bit2 = bit1 = 0; char kmerSeq[128]; switch ( overlaplen ) { case 1 ... 31: bit4 = overlaplen; break; case 32 ... 63: bit4 = 32; bit3 = overlaplen - 32; break; case 64 ... 95: bit4 = bit3 = 32; bit2 = overlaplen - 64; break; case 96 ... 127: bit4 = bit3 = bit2 = 32; bit1 = overlaplen - 96; break; } for ( i = bit1 - 1; i >= 0; i-- ) { kmerSeq[i] = kmer.high1 & 0x3; kmer.high1 >>= 2; } for ( i = bit2 - 1; i >= 0; i-- ) { kmerSeq[i + bit1] = kmer.low1 & 0x3; kmer.low1 >>= 2; } for ( i = bit3 - 1; i >= 0; i-- ) { kmerSeq[i + bit1 + bit2] = kmer.high2 & 0x3; kmer.high2 >>= 2; } for ( i = bit4 - 1; i >= 0; i-- ) { kmerSeq[i + bit1 + bit2 + bit3] = kmer.low2 & 0x3; kmer.low2 >>= 2; } for ( i = 0; i < overlaplen; i++ ) { fprintf ( fp, "%c", int2base ( ( int ) kmerSeq[i] ) ); } } void print_kmer ( FILE * fp, Kmer kmer, char c ) { fprintf ( fp, "%llx %llx %llx %llx", kmer.high1, kmer.low1, kmer.high2, kmer.low2 ); fprintf ( fp, "%c", c ); } void print_kmer_gz ( gzFile * fp, Kmer kmer, char c ) { gzprintf ( fp, "%llx %llx %llx %llx", kmer.high1, kmer.low1, kmer.high2, kmer.low2 ); gzprintf ( fp, "%c", c ); } static const ubyte2 BitReverseTable[65536] = { # define R2(n) n, n + 1*16384, n + 2*16384, n + 3*16384 # define R4(n) R2(n), R2(n + 1*4096), R2(n + 2*4096), R2(n + 3*4096) # define R6(n) R4(n), R4(n + 1*1024), R4(n + 2*1024), R4(n + 3*1024) # define R8(n) R6(n), R6(n + 1*256 ), R6(n + 2*256 ), R6(n + 3*256 ) # define R10(n) R8(n), R8(n + 1*64 ), R8(n + 2*64 ), R8(n + 3*64 ) # define R12(n) R10(n),R10(n + 1*16), R10(n + 2*16 ), R10(n + 3*16 ) # define R14(n) R12(n),R12(n + 1*4 ), R12(n + 2*4 ), R12(n + 3*4 ) R14 ( 0 ), R14 ( 1 ), R14 ( 2 ), R14 ( 3 ) }; /************************************************* Function: fastReverseComp Description: Gets the reverse complement of a kmer. Input: 1. seq: the kmer 2. seq_size: the length of the kmer Output: None. Return: The reverse complement of kmer. *************************************************/ static Kmer fastReverseComp ( Kmer seq, char seq_size ) { seq.low2 ^= 0xAAAAAAAAAAAAAAAALLU; seq.low2 = ( ( ubyte8 ) BitReverseTable[seq.low2 & 0xffff] << 48 ) | ( ( ubyte8 ) BitReverseTable[ ( seq.low2 >> 16 ) & 0xffff] << 32 ) | ( ( ubyte8 ) BitReverseTable[ ( seq.low2 >> 32 ) & 0xffff] << 16 ) | ( ( ubyte8 ) BitReverseTable[ ( seq.low2 >> 48 ) & 0xffff] ); if ( seq_size < 32 ) { seq.low2 >>= ( 64 - ( seq_size << 1 ) ); return seq; } seq.high2 ^= 0xAAAAAAAAAAAAAAAALLU; seq.high2 = ( ( ubyte8 ) BitReverseTable[seq.high2 & 0xffff] << 48 ) | ( ( ubyte8 ) BitReverseTable[ ( seq.high2 >> 16 ) & 0xffff] << 32 ) | ( ( ubyte8 ) BitReverseTable[ ( seq.high2 >> 32 ) & 0xffff] << 16 ) | ( ( ubyte8 ) BitReverseTable[ ( seq.high2 >> 48 ) & 0xffff] ); if ( seq_size < 64 ) { seq.high2 = seq.high2 ^ seq.low2; seq.low2 = seq.high2 ^ seq.low2; seq.high2 = seq.high2 ^ seq.low2; seq = KmerRightBitMove ( seq, 128 - ( seq_size << 1 ) ); return seq; } seq.low1 ^= 0xAAAAAAAAAAAAAAAALLU; seq.low1 = ( ( ubyte8 ) BitReverseTable[seq.low1 & 0xffff] << 48 ) | ( ( ubyte8 ) BitReverseTable[ ( seq.low1 >> 16 ) & 0xffff] << 32 ) | ( ( ubyte8 ) BitReverseTable[ ( seq.low1 >> 32 ) & 0xffff] << 16 ) | ( ( ubyte8 ) BitReverseTable[ ( seq.low1 >> 48 ) & 0xffff] ); if ( seq_size < 96 ) { seq.low1 = seq.low1 ^ seq.low2; seq.low2 = seq.low1 ^ seq.low2; seq.low1 = seq.low1 ^ seq.low2; seq = KmerRightBitMove ( seq, 192 - ( seq_size << 1 ) ); return seq; } seq.high1 ^= 0xAAAAAAAAAAAAAAAALLU; seq.high1 = ( ( ubyte8 ) BitReverseTable[seq.high1 & 0xffff] << 48 ) | ( ( ubyte8 ) BitReverseTable[ ( seq.high1 >> 16 ) & 0xffff] << 32 ) | ( ( ubyte8 ) BitReverseTable[ ( seq.high1 >> 32 ) & 0xffff] << 16 ) | ( ( ubyte8 ) BitReverseTable[ ( seq.high1 >> 48 ) & 0xffff] ); seq.low1 = seq.low1 ^ seq.high2; seq.high2 = seq.low1 ^ seq.high2; seq.low1 = seq.low1 ^ seq.high2; seq.low2 = seq.low2 ^ seq.high1; seq.high1 = seq.low2 ^ seq.high1; seq.low2 = seq.low2 ^ seq.high1; seq = KmerRightBitMove ( seq, 256 - ( seq_size << 1 ) ); return seq; } Kmer reverseComplementVerbose ( Kmer word, int overlap ) { return fastReverseComp ( word, overlap ); } Kmer reverseComplement ( Kmer word, int overlap ) { return fastReverseComp ( word, overlap ); } #else void PrintKmer ( FILE * fp, Kmer kmer ) { fprintf ( fp, "%llx %llx", kmer.high, kmer.low ); } __uint128_t Kmer2int128 ( Kmer seq ) { __uint128_t temp; temp = seq.high; temp <<= 64; temp |= seq.low; return temp; } boolean KmerSmaller ( Kmer kmer1, Kmer kmer2 ) { if ( kmer1.high < kmer2.high ) { return 1; } else if ( kmer1.high == kmer2.high ) { if ( kmer1.low < kmer2.low ) { return 1; } else { return 0; } } else { return 0; } } boolean KmerLarger ( Kmer kmer1, Kmer kmer2 ) { if ( kmer1.high > kmer2.high ) { return 1; } else if ( kmer1.high == kmer2.high ) { if ( kmer1.low > kmer2.low ) { return 1; } else { return 0; } } else { return 0; } } boolean KmerEqual ( Kmer kmer1, Kmer kmer2 ) { if ( kmer1.high == kmer2.high && kmer1.low == kmer2.low ) { return 1; } else { return 0; } } Kmer KmerAnd ( Kmer kmer1, Kmer kmer2 ) { kmer1.high &= kmer2.high; kmer1.low &= kmer2.low; return kmer1; } Kmer KmerLeftBitMoveBy2 ( Kmer word ) { ubyte8 temp = word.low >> 62; word.high <<= 2; word.high |= temp; word.low <<= 2; return word; } Kmer KmerRightBitMoveBy2 ( Kmer word ) { ubyte8 temp = ( word.high & 0x3 ) << 62; word.high >>= 2; word.low >>= 2; word.low |= temp; return word; } Kmer KmerPlus ( Kmer prev, char ch ) { Kmer word = KmerLeftBitMoveBy2 ( prev ); word.low |= ch; return word; } Kmer nextKmer ( Kmer prev, char ch ) { Kmer word = KmerLeftBitMoveBy2 ( prev ); word = KmerAnd ( word, WORDFILTER ); word.low |= ch; return word; } Kmer prevKmer ( Kmer next, char ch ) { Kmer word = KmerRightBitMoveBy2 ( next ); if ( 2 * ( overlaplen - 1 ) < 64 ) { word.low |= ( ( ( ubyte8 ) ch ) << 2 * ( overlaplen - 1 ) ); } else { word.high |= ( ( ubyte8 ) ch ) << ( 2 * ( overlaplen - 1 ) - 64 ); } return word; } char lastCharInKmer ( Kmer kmer ) { return ( char ) ( kmer.low & 0x3 ); } char firstCharInKmer ( Kmer kmer ) { if ( 2 * ( overlaplen - 1 ) < 64 ) { kmer.low >>= 2 * ( overlaplen - 1 ); return kmer.low; // & 3; } else { kmer.high >>= 2 * ( overlaplen - 1 ) - 64; return kmer.high; // & 3; } } Kmer createFilter ( int overlaplen ) { Kmer word; word.high = word.low = 0; if ( 2 * overlaplen < 64 ) { word.low = ( ( ( ubyte8 ) 1 ) << ( 2 * overlaplen ) ) - 1; } else { word.low = ~word.low; if ( 2 * overlaplen > 64 ) { word.high = ( ( ( ubyte8 ) 1 ) << ( 2 * overlaplen - 64 ) ) - 1; } } return word; } Kmer KmerRightBitMove ( Kmer word, int dis ) { if ( dis < 64 ) { ubyte8 mask = ( ( ( ubyte8 ) 1 ) << dis ) - 1; ubyte8 temp = ( word.high & mask ) << ( 64 - dis ); word.high >>= dis; word.low >>= dis; word.low |= temp; return word; } word.high >>= ( dis - 64 ); word.low = word.high; word.high = 0; return word; } void printKmerSeq ( FILE * fp, Kmer kmer ) { int i, bit1, bit2; char ch; char kmerSeq[64]; bit2 = overlaplen > 32 ? 32 : overlaplen; bit1 = overlaplen > 32 ? overlaplen - 32 : 0; for ( i = bit1 - 1; i >= 0; i-- ) { ch = kmer.high & 0x3; kmer.high >>= 2; kmerSeq[i] = ch; } for ( i = bit2 - 1; i >= 0; i-- ) { ch = kmer.low & 0x3; kmer.low >>= 2; kmerSeq[i + bit1] = ch; } for ( i = 0; i < overlaplen; i++ ) { fprintf ( fp, "%c", int2base ( ( int ) kmerSeq[i] ) ); } } void print_kmer ( FILE * fp, Kmer kmer, char c ) { fprintf ( fp, "%llx %llx", kmer.high, kmer.low ); fprintf ( fp, "%c", c ); } void print_kmer_gz ( gzFile * fp, Kmer kmer, char c ) { gzprintf ( fp, "%llx %llx", kmer.high, kmer.low ); gzprintf ( fp, "%c", c ); } static Kmer fastReverseComp ( Kmer seq, char seq_size ) { seq.low ^= 0xAAAAAAAAAAAAAAAALLU; seq.low = ( ( seq.low & 0x3333333333333333LLU ) << 2 ) | ( ( seq.low & 0xCCCCCCCCCCCCCCCCLLU ) >> 2 ); seq.low = ( ( seq.low & 0x0F0F0F0F0F0F0F0FLLU ) << 4 ) | ( ( seq.low & 0xF0F0F0F0F0F0F0F0LLU ) >> 4 ); seq.low = ( ( seq.low & 0x00FF00FF00FF00FFLLU ) << 8 ) | ( ( seq.low & 0xFF00FF00FF00FF00LLU ) >> 8 ); seq.low = ( ( seq.low & 0x0000FFFF0000FFFFLLU ) << 16 ) | ( ( seq.low & 0xFFFF0000FFFF0000LLU ) >> 16 ); seq.low = ( ( seq.low & 0x00000000FFFFFFFFLLU ) << 32 ) | ( ( seq.low & 0xFFFFFFFF00000000LLU ) >> 32 ); if ( seq_size < 32 ) { seq.low >>= ( 64 - ( seq_size << 1 ) ); return seq; } seq.high ^= 0xAAAAAAAAAAAAAAAALLU; seq.high = ( ( seq.high & 0x3333333333333333LLU ) << 2 ) | ( ( seq.high & 0xCCCCCCCCCCCCCCCCLLU ) >> 2 ); seq.high = ( ( seq.high & 0x0F0F0F0F0F0F0F0FLLU ) << 4 ) | ( ( seq.high & 0xF0F0F0F0F0F0F0F0LLU ) >> 4 ); seq.high = ( ( seq.high & 0x00FF00FF00FF00FFLLU ) << 8 ) | ( ( seq.high & 0xFF00FF00FF00FF00LLU ) >> 8 ); seq.high = ( ( seq.high & 0x0000FFFF0000FFFFLLU ) << 16 ) | ( ( seq.high & 0xFFFF0000FFFF0000LLU ) >> 16 ); seq.high = ( ( seq.high & 0x00000000FFFFFFFFLLU ) << 32 ) | ( ( seq.high & 0xFFFFFFFF00000000LLU ) >> 32 ); ubyte8 temp = seq.high; seq.high = seq.low; seq.low = temp; seq = KmerRightBitMove ( seq, 128 - ( seq_size << 1 ) ); return seq; } Kmer reverseComplementVerbose ( Kmer word, int overlap ) { return fastReverseComp ( word, overlap ); } Kmer reverseComplement ( Kmer word, int overlap ) { return fastReverseComp ( word, overlap ); } #endif soapdenovo2-240+dfsg.orig/standardPregraph/read2edge.c0000644000000000000000000012171612166703654021475 0ustar rootroot/* * read2edge.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include #include "kmerhash.h" #include "newhash.h" #include #include static pthread_mutex_t mutex_arc; long long foundreadcount = 0; #ifdef MER127 static const Kmer kmerZero = { 0, 0, 0, 0}; #else static const Kmer kmerZero = { 0, 0 }; #endif static int buffer_size = 100000000; //buffer related varibles for chop kmer static int read_c; static char ** rcSeq; static char ** seqBuffer; static int * lenBuffer; static char * seqLine; static int lLineLen = 5000; // kmer related variables static int kmer_c; static Kmer * kmerBuffer; //static ubyte8 *hashBanBuffer; static boolean * smallerBuffer; static int * indexArray; int nowstep = 0; int firsttime = 1; typedef struct fileReadSet { long offset; struct fileReadSet * next; } FILEREADSET; //record useful reads from parse1readcheck() static int file_num = 0; static char ** file_Name; //record file type:1=fa£¬2=fq static int * file_type; //record file max read length static int * file_maxReadLen; //record reads offset in file //static long * offset; static boolean * nodeBuffer; FILE * readSeqFile; static int writeFileNo; FILE * writeSeqFile; static void threadRoutine ( void * thrdID ); static void chopKmer4read ( int t, int threadID ); static void thread_wait ( pthread_t * threads ); void Read2edge ( char * libfile, char * graph, int maxk ); void Read2edge2 ( char * libfile, char * graph, int last, int maxk ); //, boolean keepReadFile); static void parse1readcheck ( int t ); static void searchKmer ( int t, KmerSet2 * kset, int threaID ); static void add1Arc2 ( unsigned int from_ed, unsigned int to_ed, unsigned int weight ); static void sendWorkSignal ( unsigned char SIG, unsigned char * thrdSignals ); static void creatThrds ( pthread_t * threads, PARAMETER * paras ); static void searchKmer1read ( int i, KmerSet2 * kset, int threadID ); struct preArc { unsigned int to_ed; unsigned int multiplicity; struct preArc * next; }; struct preArc_array_t { struct preArc ** store_pos; unsigned int array_sz; }; //arc array struct preArc_array_t arc_arr; pthread_mutex_t * locks; /************************************************* Function: put_preArc Description: Puts messages of arc into array. Input: 1. arc_arr: array of arcs 2. left_id: from edge id 3. right_id: to edge id 4. added_multi: weight of arc Output: None. Return: None. *************************************************/ inline void put_preArc ( struct preArc_array_t * arc_arr, unsigned int left_id, unsigned int right_id, unsigned int added_multi ) { struct preArc * arc = ( arc_arr->store_pos ) [left_id]; if ( !arc ) { ( arc_arr->store_pos ) [left_id] = ( struct preArc * ) malloc ( sizeof ( struct preArc ) ); arc = ( arc_arr->store_pos ) [left_id]; arc->to_ed = right_id; arc->multiplicity = added_multi; arc->next = NULL; return; } while ( arc ) { if ( arc->to_ed == right_id ) { arc->multiplicity += added_multi; return; } if ( arc->next == NULL ) { break; } arc = arc->next; } arc->next = ( struct preArc * ) malloc ( sizeof ( struct preArc ) ); arc->next->to_ed = right_id; arc->next->multiplicity = added_multi; arc->next->next = NULL; } //Multi thread. inline void put_preArc_threaded ( struct preArc_array_t * arc_arr, pthread_mutex_t * locks, unsigned int left_id, unsigned int right_id, unsigned int added_multi ) { pthread_mutex_lock ( &locks[left_id] ); put_preArc ( arc_arr, left_id, right_id, added_multi ); pthread_mutex_unlock ( &locks[left_id] ); } //Init. void init_preArc_array ( struct preArc_array_t * arc_array, unsigned int sz ) { arc_array->array_sz = sz; arc_array->store_pos = ( struct preArc ** ) calloc ( sz, sizeof ( struct preArc * ) ); } static void creatThrds ( pthread_t * threads, PARAMETER * paras ) { unsigned char i; int temp; for ( i = 0; i < thrd_num; i++ ) { //printf("to create %dth thread\n",(*(char *)&(threadID[i]))); if ( ( temp = pthread_create ( &threads[i], NULL, ( void * ) threadRoutine, & ( paras[i] ) ) ) != 0 ) { fprintf ( stderr, "Create threads failed.\n" ); exit ( 1 ); } } fprintf ( stderr, "%d thread(s) initialized.\n", thrd_num ); } static void thread_wait ( pthread_t * threads ) { int i; for ( i = 0; i < thrd_num; i++ ) if ( threads[i] != 0 ) { pthread_join ( threads[i], NULL ); } } static void sendWorkSignal ( unsigned char SIG, unsigned char * thrdSignals ) { int t; for ( t = 0; t < thrd_num; t++ ) { thrdSignals[t + 1] = SIG; } while ( 1 ) { usleep ( 10 ); for ( t = 0; t < thrd_num; t++ ) if ( thrdSignals[t + 1] ) { break; } if ( t == thrd_num ) { break; } } } static void threadRoutine ( void * para ) { PARAMETER * prm; int i, t, j, start, finish, k; unsigned char id; prm = ( PARAMETER * ) para; id = prm->threadID; //printf("%dth thread with task %d, hash_table %p\n",id,prm.task,prm.hash_table); while ( 1 ) { if ( * ( prm->selfSignal ) == 1 ) { for ( i = 0; i < read_c; ++i ) { if ( i % thrd_num != id ) { continue; } chopKmer4read ( i, id + 1 ); } * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 3 ) { * ( prm->selfSignal ) = 0; break; } else if ( * ( prm->selfSignal ) == 5 ) { for ( i = 0; i < read_c; ++i ) { if ( i % thrd_num != id ) { continue; } searchKmer1read ( i, KmerSetsNew, id ); } * ( prm->selfSignal ) = 0; } usleep ( 1 ); } } /************************************************* Function: searchKmer1read Description: Searches kmers on reads to add arcs. Input: 1. i: index of reads 2. kset: kmer set 3. threadID: thread id Output: None. Return: None. *************************************************/ static void searchKmer1read ( int i, KmerSet2 * kset, int threadID ) { kmer_t2 * node1, *node2; struct edgeID * edge1, *edge2; unsigned int from_ed, to_ed, temp_from, temp_to; boolean found; ARC * temp = NULL; boolean last = false; int t; for ( t = indexArray[i]; t < indexArray[i + 1] - 1; ++t ) { //get first match if ( !last ) { found = search_kmerset2 ( kset, kmerBuffer[t], &node1 ); } else { found = true; node1 = node2; } //get next match if ( found ) { found = search_kmerset2 ( kset, kmerBuffer[t + step], &node2 ); if ( found ) { edge1 = node1->edgeId; while ( edge1 ) { edge2 = node2->edgeId; while ( edge2 ) { temp_from = edge1->edge; temp_to = edge2->edge; if ( smallerBuffer[t] && smallerBuffer[t + step] ) { if ( ( edge1->flag == 2 || edge1->flag == 4 || edge1->flag == 8 ) && ( edge2->flag == 3 || edge2->flag == 4 || edge2->flag == 6 ) ) { { if ( temp_from == temp_to || temp_from == getTwinEdge ( temp_to ) ) { pthread_mutex_lock ( &locks[temp_from] ); edge_array[temp_from].multi = 1; pthread_mutex_unlock ( &locks[temp_from] ); pthread_mutex_lock ( &locks[getTwinEdge ( temp_from )] ); edge_array[getTwinEdge ( temp_from )].multi = 1; pthread_mutex_unlock ( &locks[getTwinEdge ( temp_from )] ); } else { if ( t == indexArray[i] || t == indexArray[i + 1] - 2 ) { if ( t == indexArray[i] ) { put_preArc_threaded ( &arc_arr, locks, temp_from, temp_to, 1 ); } else { put_preArc_threaded ( &arc_arr, locks, temp_from, temp_to, 1 ); } } else { put_preArc_threaded ( &arc_arr, locks, temp_from, temp_to, 1 ); } } } } } else if ( smallerBuffer[t] && !smallerBuffer[t + step] ) { if ( ( edge1->flag == 2 || edge1->flag == 4 || edge1->flag == 8 ) && ( edge2->flag == 1 || edge2->flag == 5 || edge2->flag == 7 ) ) { { if ( temp_from == temp_to || temp_from == getTwinEdge ( temp_to ) ) { pthread_mutex_lock ( &locks[temp_from] ); edge_array[temp_from].multi = 1; pthread_mutex_unlock ( &locks[temp_from] ); pthread_mutex_lock ( &locks[getTwinEdge ( temp_from )] ); edge_array[getTwinEdge ( temp_from )].multi = 1; pthread_mutex_unlock ( &locks[getTwinEdge ( temp_from )] ); } else { if ( t == indexArray[i] || t == indexArray[i + 1] - 2 ) { if ( t == indexArray[i] ) { put_preArc_threaded ( &arc_arr, locks, temp_from, temp_to, 1 ); } else { put_preArc_threaded ( &arc_arr, locks, temp_from, temp_to, 1 ); } } else { put_preArc_threaded ( &arc_arr, locks, temp_from, temp_to, 1 ); } } } } } else if ( !smallerBuffer[t] && smallerBuffer[t + step] ) { if ( ( edge1->flag == 0 || edge1->flag == 5 || edge1->flag == 9 ) && ( edge2->flag == 3 || edge2->flag == 4 || edge2->flag == 6 ) ) { { if ( temp_from == temp_to || temp_from == getTwinEdge ( temp_to ) ) { pthread_mutex_lock ( &locks[temp_from] ); edge_array[temp_from].multi = 1; pthread_mutex_unlock ( &locks[temp_from] ); pthread_mutex_lock ( &locks[getTwinEdge ( temp_from )] ); edge_array[getTwinEdge ( temp_from )].multi = 1; pthread_mutex_unlock ( &locks[getTwinEdge ( temp_from )] ); } else { if ( t == indexArray[i] || t == indexArray[i + 1] - 2 ) { if ( t == indexArray[i] ) { put_preArc_threaded ( &arc_arr, locks, temp_from, temp_to, 1 ); } else { put_preArc_threaded ( &arc_arr, locks, temp_from, temp_to, 1 ); } } else { put_preArc_threaded ( &arc_arr, locks, temp_from, temp_to, 1 ); } } } } } else if ( !smallerBuffer[t] && !smallerBuffer[t + step] ) { if ( ( edge1->flag == 0 || edge1->flag == 5 || edge1->flag == 9 ) && ( edge2->flag == 1 || edge2->flag == 5 || edge2->flag == 7 ) ) { { if ( temp_from == temp_to || temp_from == getTwinEdge ( temp_to ) ) { pthread_mutex_lock ( &locks[temp_from] ); edge_array[temp_from].multi = 1; pthread_mutex_unlock ( &locks[temp_from] ); pthread_mutex_lock ( &locks[getTwinEdge ( temp_from )] ); edge_array[getTwinEdge ( temp_from )].multi = 1; pthread_mutex_unlock ( &locks[getTwinEdge ( temp_from )] ); } else { if ( t == indexArray[i] || t == indexArray[i + 1] - 2 ) { if ( t == indexArray[i] ) { put_preArc_threaded ( &arc_arr, locks, temp_from, temp_to, 1 ); } else { put_preArc_threaded ( &arc_arr, locks, temp_from, temp_to, 1 ); } } else { put_preArc_threaded ( &arc_arr, locks, temp_from, temp_to, 1 ); } } } } } edge2 = edge2->next; } edge1 = edge1->next; } if ( firsttime ) { nodeBuffer[t + step] = 1; } last = true; } else { last = false; } if ( firsttime ) { nodeBuffer[t] = 1; } } } } /************************************************* Function: chopKmer4read Description: Chops reads to kmers. Input: 1. t: index of reads 2. threadID: thread id Output: None. Return: None. *************************************************/ static void chopKmer4read ( int t, int threadID ) { char * src_seq = seqBuffer[t]; char * bal_seq = rcSeq[threadID]; int len_seq = lenBuffer[t]; int j, bal_j; ubyte8 hash_ban, bal_hash_ban; Kmer word, bal_word; int index; if ( len_seq < overlaplen + 1 ) { return; } #ifdef MER127 word = kmerZero; for ( index = 0; index < overlaplen; index++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low2 |= src_seq[index]; } #else word = kmerZero; for ( index = 0; index < overlaplen; index++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low |= src_seq[index]; } #endif reverseComplementSeq ( src_seq, len_seq, bal_seq ); // complementary node bal_word = reverseComplement ( word, overlaplen ); bal_j = len_seq - 0 - overlaplen; index = indexArray[t]; if ( KmerSmaller ( word, bal_word ) ) { kmerBuffer[index] = word; smallerBuffer[index] = 1; index++; } else { kmerBuffer[index] = bal_word; smallerBuffer[index] = 0; index++; } for ( j = 1; j <= len_seq - overlaplen; j ++ ) { word = nextKmer ( word, src_seq[j - 1 + overlaplen] ); bal_j = len_seq - j - overlaplen; // j; bal_word = prevKmer ( bal_word, bal_seq[bal_j] ); if ( KmerSmaller ( word, bal_word ) ) { kmerBuffer[index] = word; smallerBuffer[index] = 1; index++; } else { // complementary node kmerBuffer[index] = bal_word; smallerBuffer[index] = 0; index++; } } } /************************************************* Function: getArcBetween2 Description: Get arcs between two edges. Input: 1. from_ed: the from edge 2. to_ed: the to edge Output: None. Return: Arc between two edges. *************************************************/ ARC * getArcBetween2 ( unsigned int from_ed, unsigned int to_ed ) { ARC * parc; parc = edge_array[from_ed].arcs; while ( parc ) { if ( parc->to_ed == to_ed ) { return parc; } parc = parc->next; } return parc; } /************************************************* Function: add1Arc2 Description: Add one arc for two edges. Input: 1. from_ed: the from edge 2. to_ed: the to edge 3. weight: the weight of arc Output: None. Return: None. *************************************************/ static void add1Arc2 ( unsigned int from_ed, unsigned int to_ed, unsigned int weight ) { unsigned int bal_fe = getTwinEdge ( from_ed ); unsigned int bal_te = getTwinEdge ( to_ed ); if ( from_ed > num_ed || to_ed > num_ed || bal_fe > num_ed || bal_te > num_ed ) { return; } ARC * parc, *bal_parc; //both arcs already exist parc = getArcBetween ( from_ed, to_ed ); if ( parc ) { bal_parc = parc->bal_arc; parc->multiplicity += weight; bal_parc->multiplicity += weight; return; } //create new arcs parc = allocateArc ( to_ed ); parc->multiplicity = weight; parc->prev = NULL; if ( edge_array[from_ed].arcs ) { edge_array[from_ed].arcs->prev = parc; } parc->next = edge_array[from_ed].arcs; edge_array[from_ed].arcs = parc; // A->A' if ( bal_te == from_ed ) { parc->bal_arc = parc; parc->multiplicity += weight; return; } bal_parc = allocateArc ( bal_fe ); bal_parc->multiplicity = weight; bal_parc->prev = NULL; if ( edge_array[bal_te].arcs ) { edge_array[bal_te].arcs->prev = bal_parc; } bal_parc->next = edge_array[bal_te].arcs; edge_array[bal_te].arcs = bal_parc; //link them to each other parc->bal_arc = bal_parc; bal_parc->bal_arc = parc; } /************************************************* Function: parse1readcheck Description: Checks whether a read is usablel. Input: 1. t: the index of read Output: None. Return: None. *************************************************/ static void parse1readcheck ( int t ) { unsigned int j; unsigned int start, finish; boolean found; start = indexArray[t]; finish = indexArray[t + 1]; boolean readfound = 0; nowstep = 1; int curr_fileNo; FILEREADSET * head, * next, *curr; for ( j = start; j < finish - nowstep; ++j ) { found = nodeBuffer[j]; if ( found ) { found = nodeBuffer[j + nowstep]; if ( found ) { readfound = 1; break; } } } if ( readfound ) { ++foundreadcount; if ( !writeFileNo ) { int index, num_actg; for ( index = 0; index < lenBuffer[t]; index++ ) { fprintf ( writeSeqFile, "%c", int2base ( seqBuffer[t][index] ) ); } fprintf ( writeSeqFile, "\n" ); } } } //Free. void free_new() { free_libs(); free ( file_Name ); free ( file_type ); file_type = NULL; free ( file_maxReadLen ); file_maxReadLen = NULL; } /************************************************* Function: Read2edge Description: 1. Maps reads back to edges. 2. Outputs selected reads if -r is set. Input: 1. libfile: the reads config file 2. graph: the output file prefix 3. maxk: the max kmer when using multikmer Output: None. Return: None. *************************************************/ void Read2edge ( char * libfile, char * graph, int maxk ) { long long i; char * next_name; int maxReadNum, fileNo; boolean flag, pairs = 0; pthread_t threads[thrd_num]; unsigned char thrdSignal[thrd_num + 1]; PARAMETER paras[thrd_num]; maxReadLen = 0; maxNameLen = 256; //scan lib info scan_libInfo ( libfile ); if ( !maxReadLen ) { maxReadLen = 100; } if ( maxk > maxReadLen ) { fprintf ( stderr, "-- Max kmer %d larger than max read length %d, please define a smaller value. --\n", maxk, maxReadLen ); abort(); } maxReadLen4all = maxReadLen; fprintf ( stderr, "In file: %s, max seq len %d, max name len %d.\n", libfile, maxReadLen, maxNameLen ); int m, n, index; file_num = 0; for ( m = 0; m < num_libs; m++ ) { if ( lib_array[m].asm_flag == 1 || lib_array[m].asm_flag == 3 ) file_num += lib_array[m].num_a1_file + lib_array[m].num_a2_file + lib_array[m].num_p_file + lib_array[m].num_q1_file + lib_array[m].num_q2_file + lib_array[m].num_s_a_file + lib_array[m].num_s_q_file; } file_Name = ( char ** ) ckalloc ( file_num * sizeof ( char * ) ); file_type = ( int * ) ckalloc ( file_num * sizeof ( int ) ); file_maxReadLen = ( int * ) ckalloc ( file_num * sizeof ( int ) ); index = 0; //2013-5-14 int maxReadLenLocal = 0; for ( m = 0; m < num_libs; m++ ) { if ( lib_array[m].asm_flag != 1 && lib_array[m].asm_flag != 3 ) { continue; } //2013-5-14 if ( lib_array[m].rd_len_cutoff > 0 ) { maxReadLenLocal = lib_array[m].rd_len_cutoff < maxReadLen4all ? lib_array[m].rd_len_cutoff : maxReadLen4all; } else { maxReadLenLocal = maxReadLen4all; } //fa1 fa2 for ( n = 0; n < lib_array[m].num_a1_file; n++ ) { if ( strlen ( lib_array[m].a1_fname[n] ) > 3 && strcmp ( lib_array[m].a1_fname[n] + strlen ( lib_array[m].a1_fname[n] ) - 3, ".gz" ) == 0 ) { file_type[index] = 3; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].a1_fname[n]; file_type[index] = 3; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].a2_fname[n]; } else { file_type[index] = 1; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].a1_fname[n]; file_type[index] = 1; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].a2_fname[n]; } } //fq1 fq2 for ( n = 0; n < lib_array[m].num_q1_file; n++ ) { if ( strlen ( lib_array[m].q1_fname[n] ) > 3 && strcmp ( lib_array[m].q1_fname[n] + strlen ( lib_array[m].q1_fname[n] ) - 3, ".gz" ) == 0 ) { file_type[index] = 4; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].q1_fname[n]; file_type[index] = 4; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].q2_fname[n]; } else { file_type[index] = 2; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].q1_fname[n]; file_type[index] = 2; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].q2_fname[n]; } } //fp for ( n = 0; n < lib_array[m].num_p_file; n++ ) { if ( strlen ( lib_array[m].p_fname[n] ) > 3 && strcmp ( lib_array[m].p_fname[n] + strlen ( lib_array[m].p_fname[n] ) - 3, ".gz" ) == 0 ) { file_type[index] = 3; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].p_fname[n]; } else { file_type[index] = 1; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].p_fname[n]; } } //fa for ( n = 0; n < lib_array[m].num_s_a_file; n++ ) { if ( strlen ( lib_array[m].s_a_fname[n] ) > 3 && strcmp ( lib_array[m].s_a_fname[n] + strlen ( lib_array[m].s_a_fname[n] ) - 3, ".gz" ) == 0 ) { file_type[index] = 3; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].s_a_fname[n]; } else { file_type[index] = 1; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].s_a_fname[n]; } } //fq for ( n = 0; n < lib_array[m].num_s_q_file; n++ ) { if ( strlen ( lib_array[m].s_q_fname[n] ) > 3 && strcmp ( lib_array[m].s_q_fname[n] + strlen ( lib_array[m].s_q_fname[n] ) - 3, ".gz" ) == 0 ) { file_type[index] = 4; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].s_q_fname[n]; } else { file_type[index] = 2; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].s_q_fname[n]; } } } //init next_name = ( char * ) ckalloc ( ( maxNameLen + 1 ) * sizeof ( char ) ); kmerBuffer = ( Kmer * ) ckalloc ( buffer_size * sizeof ( Kmer ) ); smallerBuffer = ( boolean * ) ckalloc ( buffer_size * sizeof ( boolean ) ); pthread_mutex_init ( &mutex_arc, NULL ); nodeBuffer = ( boolean * ) ckalloc ( buffer_size * sizeof ( boolean ) ); maxReadNum = buffer_size / ( maxReadLen - overlaplen + 1 ); seqBuffer = ( char ** ) ckalloc ( maxReadNum * sizeof ( char * ) ); lenBuffer = ( int * ) ckalloc ( maxReadNum * sizeof ( int ) ); indexArray = ( int * ) ckalloc ( ( maxReadNum + 1 ) * sizeof ( int ) ); init_preArc_array ( &arc_arr, num_ed + 2 ); locks = ( pthread_mutex_t * ) calloc ( arc_arr.array_sz, sizeof ( pthread_mutex_t ) ); unsigned int ii; for ( ii = 0; ii < arc_arr.array_sz; ++ii ) { pthread_mutex_init ( &locks[ii], NULL ); } for ( i = 0; i < maxReadNum; i++ ) { seqBuffer[i] = ( char * ) ckalloc ( maxReadLen * sizeof ( char ) ); } rcSeq = ( char ** ) ckalloc ( ( thrd_num + 1 ) * sizeof ( char * ) ); thrdSignal[0] = 0; if ( 1 ) { for ( i = 0; i < thrd_num; i++ ) { rcSeq[i + 1] = ( char * ) ckalloc ( maxReadLen * sizeof ( char ) ); thrdSignal[i + 1] = 0; paras[i].threadID = i; paras[i].mainSignal = &thrdSignal[0]; paras[i].selfSignal = &thrdSignal[i + 1]; } creatThrds ( threads, paras ); } if ( 1 ) { rcSeq[0] = ( char * ) ckalloc ( maxReadLen * sizeof ( char ) ); } kmer_c = n_solexa = read_c = i = readNumBack = gradsCounter = 0; fileNo = -1; int t0, t1, t2, t3, t4, t5, t6; t0 = t1 = t2 = t3 = t4 = t5 = t6 = 0; time_t read_start, read_end, time_bef, time_aft; time ( &read_start ); int t; char writeSeqName[256]; writeFileNo = 0; sprintf ( writeSeqName, "%s.read", graph ); writeSeqFile = ckopen ( writeSeqName, "w" ); int type; FILE * file = NULL; long pos_seq = 0; //parse all reads while ( ( flag = read1seqInLibpos ( seqBuffer[read_c], next_name, & ( lenBuffer[read_c] ), //file, &fileNo, file_num, file_Name, file_type, file_maxReadLen, &pos_seq ) ) != 0 ) { if ( ( ++i ) % 100000000 == 0 ) { fprintf ( stderr, "--- %lldth reads.\n", i ); } if ( lenBuffer[read_c] < overlaplen + 1 ) { continue; } indexArray[read_c] = kmer_c; kmer_c += lenBuffer[read_c] - overlaplen + 1; read_c++; if ( read_c == maxReadNum ) { indexArray[read_c] = kmer_c; time ( &read_end ); t0 += read_end - read_start; time ( &time_bef ); //chop kmer for reads sendWorkSignal ( 1, thrdSignal ); //chopKmer4read time ( &time_aft ); t1 += time_aft - time_bef; time ( &time_bef ); //add arc sendWorkSignal ( 5, thrdSignal ); //searchKmer1read time ( &time_aft ); t2 += time_aft - time_bef; time ( &time_bef ); //check whether reads is useful for ( t = 0; t < read_c; ++t ) { parse1readcheck ( t ); } memset ( nodeBuffer, '\0', buffer_size * sizeof ( boolean ) ); time ( &time_aft ); t3 += time_aft - time_bef; kmer_c = 0; read_c = 0; time ( &read_start ); } } //take care of last round if ( read_c ) { indexArray[read_c] = kmer_c; time ( &read_end ); t0 += read_end - read_start; time ( &time_bef ); //chop kmer for reads sendWorkSignal ( 1, thrdSignal ); //chopKmer4read time ( &time_aft ); t1 += time_aft - time_bef; time ( &time_bef ); //add arc sendWorkSignal ( 5, thrdSignal ); //searchKmer1read time ( &time_aft ); t2 += time_aft - time_bef; time ( &time_bef ); struct preArc * parc; unsigned int ii; for ( ii = 0; ii < arc_arr.array_sz; ++ii ) { parc = ( arc_arr.store_pos ) [ii]; if ( parc ) { while ( parc ) { add1Arc2 ( ii, parc->to_ed, parc->multiplicity ); parc = parc->next; } } } //check whether reads is useful for ( t = 0; t < read_c; ++t ) { parse1readcheck ( t ); } time ( &time_aft ); t3 += time_aft - time_bef; } else { struct preArc * parc; unsigned int ii; for ( ii = 0; ii < arc_arr.array_sz; ++ii ) { parc = ( arc_arr.store_pos ) [ii]; if ( parc ) { while ( parc ) { add1Arc2 ( ii, parc->to_ed, parc->multiplicity ); parc = parc->next; } } } } fprintf ( stderr, "%lld read(s) processed.\n", i ); // fprintf(stderr, "Time spent on reading file: %ds,chop reads: %ds, search kmer: %ds, parse reads: %ds.\n",t0,t1,t2, t3); fprintf ( stderr, "Time spent on:\n" ); fprintf ( stderr, " importing reads: %ds,\n", t0 ); fprintf ( stderr, " chopping reads to kmers: %ds,\n", t1 ); fprintf ( stderr, " searching kmers in hash: %ds,\n", t2 ); fprintf ( stderr, " parsing reads: %ds.\n", t3 ); if ( foundreadcount ) { fprintf ( stderr, "%lld reads available.\n", foundreadcount ); } foundreadcount = 0; //exit sendWorkSignal ( 3, thrdSignal ); thread_wait ( threads ); if ( 1 ) { for ( i = 0; i < thrd_num; i++ ) { free ( ( void * ) rcSeq[i + 1] ); } } if ( 1 ) { free ( ( void * ) rcSeq[0] ); } free ( ( void * ) rcSeq ); rcSeq = NULL; for ( i = 0; i < maxReadNum; i++ ) { free ( ( void * ) seqBuffer[i] ); } free ( ( void * ) seqBuffer ); seqBuffer = NULL; free ( ( void * ) lenBuffer ); lenBuffer = NULL; free ( ( void * ) indexArray ); indexArray = NULL; free ( ( void * ) kmerBuffer ); kmerBuffer = NULL; free ( ( void * ) smallerBuffer ); smallerBuffer = NULL; free ( ( void * ) nodeBuffer ); nodeBuffer = NULL; free ( ( void * ) locks ); struct preArc * temp, *temp_next; for ( i = 0; i < arc_arr.array_sz; ++i ) { temp = ( arc_arr.store_pos ) [i]; while ( temp ) { temp_next = temp->next; free ( ( void * ) ( temp ) ); temp = temp_next; } } free ( ( void * ) arc_arr.store_pos ); free ( ( void * ) next_name ); writeFileNo++; fclose ( writeSeqFile ); free_new(); } int temp_times = 1; /************************************************* Function: read1seqInNewFile Description: Read one seq in file. Input: 1. src_seq: seq buffer 2. len_seq: length of seq 3. pos_seq: pos in file Output: None. Return: 1 if success. *************************************************/ static boolean read1seqInNewFile ( char * src_seq, int * len_seq, long * pos_seq ) { char c; char * str = seqLine; int strLen = 0, i; /* if(temp_times>0) { *pos_seq = ftell(readSeqFile); } */ if ( fgets ( str, lLineLen, readSeqFile ) ) { strLen = strlen ( str ); *len_seq = strLen - 1; for ( i = 0; i < strLen - 1; i++ ) { if ( str[i] >= 'a' && str[i] <= 'z' ) { c = base2int ( str[i] - 'a' + 'A' ); src_seq[i] = c; } else if ( str[i] >= 'A' && str[i] <= 'Z' ) { c = base2int ( str[i] ); src_seq[i] = c; // after pre-process all the symbles would be a,g,c,t,n in lower or upper case. } else if ( str[i] == '.' ) { c = base2int ( 'A' ); src_seq[i] = c; } // after pre-process all the symbles would be a,g,c,t,n in lower or upper case. } } if ( strLen == 0 ) { return 0; } else { return 1; } } /************************************************* Function: Read2edge Description: 1. Maps reads back to edges and re-builds arcs between edges. 2. Outputs selected reads if -r is set. Input: 1. libfile: the reads config file 2. graph: the output file prefix 3. lastTime: whether it's the last iteration 4. maxk: the max kmer when using multikmer // 5. keepReadFile: keep tmp reads file that selected for building arcs Output: None. Return: None. *************************************************/ //void Read2edge2(char *libfile, char *graph, int lastTime, int maxk, boolean keepReadFile) void Read2edge2 ( char * libfile, char * graph, int lastTime, int maxk ) { long long i; char * next_name; int maxReadNum, fileNo; boolean flag, pairs = 0; pthread_t threads[thrd_num]; unsigned char thrdSignal[thrd_num + 1]; PARAMETER paras[thrd_num]; maxReadLen = 0; maxNameLen = 256; //scan lib info scan_libInfo ( libfile ); if ( !maxReadLen ) { maxReadLen = 100; } if ( maxk > maxReadLen ) { fprintf ( stderr, "-- Max kmer %d larger than max read length %d, please define a smaller value. --\n", maxk, maxReadLen ); abort(); } maxReadLen4all = maxReadLen; fprintf ( stderr, "In file: %s, max seq len %d, max name len %d.\n", libfile, maxReadLen, maxNameLen ); int m, n, index; file_num = 0; for ( m = 0; m < num_libs; m++ ) { if ( lib_array[m].asm_flag == 1 || lib_array[m].asm_flag == 3 ) file_num += lib_array[m].num_a1_file + lib_array[m].num_a2_file + lib_array[m].num_p_file + lib_array[m].num_q1_file + lib_array[m].num_q2_file + lib_array[m].num_s_a_file + lib_array[m].num_s_q_file; } file_Name = ( char ** ) ckalloc ( file_num * sizeof ( char * ) ); file_type = ( int * ) ckalloc ( file_num * sizeof ( int ) ); file_maxReadLen = ( int * ) ckalloc ( file_num * sizeof ( int ) ); index = 0; //2013-5-14 int maxReadLenLocal = 0; for ( m = 0; m < num_libs; m++ ) { if ( lib_array[m].asm_flag != 1 && lib_array[m].asm_flag != 3 ) { continue; } if ( lib_array[m].rd_len_cutoff > 0 ) { maxReadLenLocal = lib_array[m].rd_len_cutoff < maxReadLen4all ? lib_array[m].rd_len_cutoff : maxReadLen4all; } else { maxReadLenLocal = maxReadLen4all; } //fa1 fa2 for ( n = 0; n < lib_array[m].num_a1_file; n++ ) { if ( strlen ( lib_array[m].a1_fname[n] ) > 3 && strcmp ( lib_array[m].a1_fname[n] + strlen ( lib_array[m].a1_fname[n] ) - 3, ".gz" ) == 0 ) { file_type[index] = 3; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].a1_fname[n]; file_type[index] = 3; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].a2_fname[n]; } else { file_type[index] = 1; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].a1_fname[n]; file_type[index] = 1; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].a2_fname[n]; } } //fq1 fq2 for ( n = 0; n < lib_array[m].num_q1_file; n++ ) { if ( strlen ( lib_array[m].q1_fname[n] ) > 3 && strcmp ( lib_array[m].q1_fname[n] + strlen ( lib_array[m].q1_fname[n] ) - 3, ".gz" ) == 0 ) { file_type[index] = 4; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].q1_fname[n]; file_type[index] = 4; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].q2_fname[n]; } else { file_type[index] = 2; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].q1_fname[n]; file_type[index] = 2; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].q2_fname[n]; } } //fp for ( n = 0; n < lib_array[m].num_p_file; n++ ) { if ( strlen ( lib_array[m].p_fname[n] ) > 3 && strcmp ( lib_array[m].p_fname[n] + strlen ( lib_array[m].p_fname[n] ) - 3, ".gz" ) == 0 ) { file_type[index] = 3; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].p_fname[n]; } else { file_type[index] = 1; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].p_fname[n]; } } //fa for ( n = 0; n < lib_array[m].num_s_a_file; n++ ) { if ( strlen ( lib_array[m].s_a_fname[n] ) > 3 && strcmp ( lib_array[m].s_a_fname[n] + strlen ( lib_array[m].s_a_fname[n] ) - 3, ".gz" ) == 0 ) { file_type[index] = 3; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].s_a_fname[n]; } else { file_type[index] = 1; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].s_a_fname[n]; } } //fq for ( n = 0; n < lib_array[m].num_s_q_file; n++ ) { if ( strlen ( lib_array[m].s_q_fname[n] ) > 3 && strcmp ( lib_array[m].s_q_fname[n] + strlen ( lib_array[m].s_q_fname[n] ) - 3, ".gz" ) == 0 ) { file_type[index] = 4; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].s_q_fname[n]; } else { file_type[index] = 2; file_maxReadLen[index] = maxReadLenLocal; file_Name[index++] = lib_array[m].s_q_fname[n]; } } } //init next_name = ( char * ) ckalloc ( ( maxNameLen + 1 ) * sizeof ( char ) ); kmerBuffer = ( Kmer * ) ckalloc ( buffer_size * sizeof ( Kmer ) ); smallerBuffer = ( boolean * ) ckalloc ( buffer_size * sizeof ( boolean ) ); init_preArc_array ( &arc_arr, num_ed + 2 ); locks = ( pthread_mutex_t * ) calloc ( arc_arr.array_sz, sizeof ( pthread_mutex_t ) ); unsigned int ii; for ( ii = 0; ii < arc_arr.array_sz; ++ii ) { pthread_mutex_init ( &locks[ii], NULL ); } pthread_mutex_init ( &mutex_arc, NULL ); firsttime = 0; maxReadNum = buffer_size / ( maxReadLen - overlaplen + 1 ); seqBuffer = ( char ** ) ckalloc ( maxReadNum * sizeof ( char * ) ); lenBuffer = ( int * ) ckalloc ( maxReadNum * sizeof ( int ) ); indexArray = ( int * ) ckalloc ( ( maxReadNum + 1 ) * sizeof ( int ) ); // offset = (long*)ckalloc((maxReadNum+1)*sizeof(long)); for ( i = 0; i < maxReadNum; i++ ) { seqBuffer[i] = ( char * ) ckalloc ( maxReadLen * sizeof ( char ) ); } rcSeq = ( char ** ) ckalloc ( ( thrd_num + 1 ) * sizeof ( char * ) ); thrdSignal[0] = 0; if ( 1 ) { for ( i = 0; i < thrd_num; i++ ) { rcSeq[i + 1] = ( char * ) ckalloc ( maxReadLen * sizeof ( char ) ); thrdSignal[i + 1] = 0; paras[i].threadID = i; paras[i].mainSignal = &thrdSignal[0]; paras[i].selfSignal = &thrdSignal[i + 1]; } creatThrds ( threads, paras ); } if ( 1 ) { rcSeq[0] = ( char * ) ckalloc ( maxReadLen * sizeof ( char ) ); } kmer_c = n_solexa = read_c = i = readNumBack = gradsCounter = 0; fileNo = -1; int t0, t1, t2, t3, t4, t5, t6; t0 = t1 = t2 = t3 = t4 = t5 = t6 = 0; time_t read_start, read_end, time_bef, time_aft; time ( &read_start ); // fprintf(stderr, "Start to read.\n"); int t; char readSeqName[256]; sprintf ( readSeqName, "%s.read", graph ); readSeqFile = ckopen ( readSeqName, "r" ); FILE * file = NULL; long pos_seq = 0; char tmp[lLineLen]; if ( maxReadLen > lLineLen ) { lLineLen = maxReadLen + 1; seqLine = ( char * ) ckalloc ( lLineLen * sizeof ( char ) ); } else { seqLine = tmp; } //parse all reads while ( ( flag = read1seqInNewFile ( seqBuffer[read_c], & ( lenBuffer[read_c] ), &pos_seq ) ) ) { if ( ( ++i ) % 100000000 == 0 ) { fprintf ( stderr, "--- %lldth reads.\n", i ); } if ( lenBuffer[read_c] < overlaplen + 1 ) { continue; } // offset[read_c]=pos_seq; indexArray[read_c] = kmer_c; kmer_c += lenBuffer[read_c] - overlaplen + 1; read_c++; if ( read_c == maxReadNum ) { indexArray[read_c] = kmer_c; time ( &read_end ); t0 += read_end - read_start; time ( &time_bef ); //chop kmer sendWorkSignal ( 1, thrdSignal ); //chopKmer4read time ( &time_aft ); t1 += time_aft - time_bef; time ( &time_bef ); //add arc sendWorkSignal ( 5, thrdSignal ); //searchKmer1read time ( &time_aft ); t2 += time_aft - time_bef; time ( &time_bef ); time ( &time_aft ); t3 += time_aft - time_bef; kmer_c = 0; read_c = 0; time ( &read_start ); } } if ( read_c ) { indexArray[read_c] = kmer_c; time ( &read_end ); t0 += read_end - read_start; time ( &time_bef ); //chop kmer sendWorkSignal ( 1, thrdSignal ); //chopKmer4read time ( &time_aft ); t1 += time_aft - time_bef; time ( &time_bef ); //add arc sendWorkSignal ( 5, thrdSignal ); //searchKmer1read time ( &time_aft ); t2 += time_aft - time_bef; time ( &time_bef ); struct preArc * parc; unsigned int ii; for ( ii = 0; ii < arc_arr.array_sz; ++ii ) { parc = ( arc_arr.store_pos ) [ii]; if ( parc ) { while ( parc ) { add1Arc2 ( ii, parc->to_ed, parc->multiplicity ); parc = parc->next; } } } time ( &time_aft ); t3 += time_aft - time_bef; } else { struct preArc * parc; unsigned int ii; for ( ii = 0; ii < arc_arr.array_sz; ++ii ) { parc = ( arc_arr.store_pos ) [ii]; if ( parc ) { while ( parc ) { add1Arc2 ( ii, parc->to_ed, parc->multiplicity ); parc = parc->next; } } } } fprintf ( stderr, "%lld read(s) processed.\n", i ); // fprintf(stderr, "Time spent on reading file: %ds,chop reads: %ds, search kmer: %ds, parse reads: %ds.\n",t0,t1,t2, t3); fprintf ( stderr, "Time spent on:\n" ); fprintf ( stderr, " importing reads: %ds,\n", t0 ); fprintf ( stderr, " chopping reads to kmers: %ds,\n", t1 ); fprintf ( stderr, " searching kmers in hash: %ds,\n", t2 ); fprintf ( stderr, " parsing reads: %ds.\n", t3 ); if ( foundreadcount ) { fprintf ( stderr, "%lld reads available.\n", foundreadcount ); } foundreadcount = 0; //exit sendWorkSignal ( 3, thrdSignal ); thread_wait ( threads ); if ( 1 ) { for ( i = 0; i < thrd_num; i++ ) { free ( ( void * ) rcSeq[i + 1] ); } } if ( 1 ) { free ( ( void * ) rcSeq[0] ); } free ( ( void * ) rcSeq ); rcSeq = NULL; for ( i = 0; i < maxReadNum; i++ ) { free ( ( void * ) seqBuffer[i] ); } free ( ( void * ) seqBuffer ); seqBuffer = NULL; free ( ( void * ) lenBuffer ); lenBuffer = NULL; free ( ( void * ) indexArray ); indexArray = NULL; free ( ( void * ) kmerBuffer ); kmerBuffer = NULL; free ( ( void * ) smallerBuffer ); smallerBuffer = NULL; // free((void*)offset); // offset=NULL; free ( ( void * ) locks ); struct preArc * temp, *temp_next; for ( i = 0; i < arc_arr.array_sz; ++i ) { temp = ( arc_arr.store_pos ) [i]; while ( temp ) { temp_next = temp->next; free ( ( void * ) ( temp ) ); temp = temp_next; } } free ( ( void * ) arc_arr.store_pos ); free ( ( void * ) next_name ); fclose ( readSeqFile ); if ( !lastTime ) { // if(!keepReadFile) remove ( readSeqName ); } free_new(); if ( maxReadLen > lLineLen ) { free ( ( void * ) seqLine ); } } soapdenovo2-240+dfsg.orig/standardPregraph/Makefile0000644000000000000000000000567712166705341021151 0ustar rootroot#################################### # # Use "make 127mer=1" to make 127mer version # Use "make 63mer=1" to make 63mer version(default) # ################################### CC= gcc GCCVERSIONMAJOR := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 4) GCCVERSIONMINOR := $(shell expr `$(CC) -dumpversion | cut -f2 -d.` \>= 4) ifdef debug CFLAGS= -O0 -g -fomit-frame-pointer #-static #-mcrc32 -march=core2 -msse4.1 -msse4.2 else CFLAGS= -O4 -fomit-frame-pointer #-static #-mcrc32 -march=core2 -msse4.1 -msse4.2 endif DFLAGS= OBJS= arc.o attachPEinfo.o bubble.o check.o compactEdge.o \ concatenateEdge.o connect.o contig.o cutTipPreGraph.o cutTip_graph.o \ darray.o dfib.o dfibHeap.o fib.o fibHeap.o \ hashFunction.o kmer.o lib.o loadGraph.o loadPath.o \ loadPreGraph.o localAsm.o main.o map.o mem_manager.o \ newhash.o node2edge.o orderContig.o output_contig.o output_pregraph.o \ output_scaffold.o pregraph.o prlHashCtg.o prlHashReads.o prlRead2Ctg.o \ prlRead2path.o prlReadFillGap.o read2scaf.o readInterval.o stack.o\ readseq1by1.o scaffold.o searchPath.o seq.o splitReps.o \ cutTip_graph2.o linearEdge.o kmerhash.o read2edge.o iterate.o PROG= SOAPdenovo-63mer INCLUDES= -Iinc SUBDIRS= . LIBPATH= -L/lib64 -L/usr/lib64 -L./inc LIBS= -pthread -lz -lm EXTRA_FLAGS= BIT_ERR = 0 ifeq (,$(findstring $(shell uname -m), x86_64 ppc64 ia64)) BIT_ERR = 1 endif ifdef 127mer CFLAGS += -DMER127 PROG = SOAPdenovo-127mer else CFLAGS += -DMER63 PROG = SOAPdenovo-63mer endif ifneq (,$(findstring Linux,$(shell uname))) EXTRA_FLAGS += -Wl,--hash-style=both LIBS += -lbam -lrt endif ifneq (,$(findstring Unix,$(shell uname))) EXTRA_FLAGS += -Wl,--hash-style=both LIBS += -lbam -lrt endif ifneq (,$(findstring Darwin,$(shell uname))) LIBS += -lbammac endif ifneq (,$(findstring $(shell uname -m), x86_64)) CFLAGS += -m64 endif ifneq (,$(findstring $(shell uname -m), ia64)) CFLAGS += endif ifneq (,$(findstring $(shell uname -m), ppc64)) CFLAGS += -mpowerpc64 endif .SUFFIXES:.c .o .c.o: @printf "Compiling $<... \r"; \ $(CC) -c $(CFLAGS) $(DFLAGS) $(INCLUDES) $< || echo "Error in command: $(CC) -c $(CFLAGS) $(DFLAGS) $(INCLUDES) $<" all: clean $(OBJS) #SOAPdenovo .PHONY:all clean install envTest: @test $(BIT_ERR) != 1 || sh -c 'echo "Fatal: 64bit CPU and Operating System required!";false;' @test $(GCCVERSIONMAJOR) == 1 || sh -c 'echo "GCC version lower than 4.4.0";false;' @test $(GCCVERSIONMINOR) == 1 || sh -c 'echo "GCC version lower than 4.4.0";false;' SOAPdenovo: envTest $(OBJS) @printf "Linking... \r" @$(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBPATH) $(LIBS) $(ENTRAFLAGS) @printf "$(PROG) compilation done.\n"; clean: @rm -fr gmon.out *.o a.out *.exe *.dSYM $(PROG) *~ *.a *.so.* *.so *.dylib @printf "$(PROG) cleaning done.\n"; install: @cp $(PROG) ../bin/ @printf "$(PROG) installed at ../bin/$(PROG)\n" soapdenovo2-240+dfsg.orig/standardPregraph/orderContig.c0000644000000000000000000067152012166703654022135 0ustar rootroot#include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #include "dfibHeap.h" #include "fibHeap.h" #include "darray.h" #include "zlib.h" #define CNBLOCKSIZE 10000 #define MAXC 10000 #define MAXCinBetween 200 #define MaxNodeInSub 10000 #define GapLowerBound -2000 #define GapUpperBound 300000 #define MaxCntNode 1000 static int DEBUG = 0; static int DEBUG1 = 0; static int DEBUG2 = 0; static int bySmall = 1; static boolean static_f = 0; static double OverlapPercent = 0.05; static double ConflPercent = 0.05; static int MinWeakCut = 3; static int gapCounter; static int orienCounter; static int orienCounter2; static int throughCounter; static int breakPointAtRepeat = 0; static FILE * snp_fp = NULL; static DARRAY * solidArray; static DARRAY * tempArray; static int solidCounter; static CTGinHEAP ctg4heapArray[MaxNodeInSub + 1]; static unsigned int nodesInSub[MaxNodeInSub]; static int nodeDistance[MaxNodeInSub]; static int nodeCounter; static int dCntCounter1; static int uCntCounter1; static int dCntCounter2; static int uCntCounter2; static unsigned int dCntNodeArr1[MaxCntNode]; //downstream static unsigned int uCntNodeArr1[MaxCntNode]; //upstream static int dCntGapArr1[MaxCntNode]; static int uCntGapArr1[MaxCntNode]; static unsigned int dCntNodeArr2[MaxCntNode]; static unsigned int uCntNodeArr2[MaxCntNode]; static int dCntGapArr2[MaxCntNode]; static int uCntGapArr2[MaxCntNode]; static unsigned int * cntNodeArr; static int * cntGapArr; static unsigned int nodesInSubInOrder[MaxNodeInSub]; static int nodeDistanceInOrder[MaxNodeInSub]; static DARRAY * scaf3, *scaf5; static DARRAY * gap3, *gap5; static unsigned int downstreamCTG[MAXCinBetween]; static unsigned int upstreamCTG[MAXCinBetween]; static int dsCtgCounter; static int usCtgCounter; static CONNECT * checkConnect ( unsigned int from_c, unsigned int to_c ); static int maskPuzzle ( int num_connect, unsigned int contigLen ); static void freezing(); static boolean checkOverlapInBetween ( double tolerance ); static int setConnectDelete ( unsigned int from_c, unsigned int to_c, char flag, boolean cleanBinding ); static int setConnectMask ( unsigned int from_c, unsigned int to_c, char mask ); static int setConnectWP ( unsigned int from_c, unsigned int to_c, char flag ); static void general_linearization ( boolean strict ); static void debugging2(); static void smallScaf(); static void clearNewInsFlag(); static void detectBreakScaff(); static void detectBreakScaf(); static boolean checkSimple ( DARRAY * ctgArray, int count ); static void checkCircle(); /************************************************* Function: checkFiles4Scaff Description: Checks the required files for scaffolding. Input: 1. infile: prefix of graph Output: None. Return: 1 if all files were OK. *************************************************/ boolean checkFiles4Scaff ( char * infile ) { char name[7][256]; boolean filesOK = 1; int i = 0; sprintf ( name[0], "%s.Arc", infile ); sprintf ( name[1], "%s.contig", infile ); sprintf ( name[2], "%s.peGrads", infile ); sprintf ( name[3], "%s.preGraphBasic", infile ); sprintf ( name[4], "%s.updated.edge", infile ); sprintf ( name[5], "%s.readOnContig.gz", infile ); for ( ; i < 6; i++ ) { filesOK = check_file ( name[i] ); if ( !filesOK ) { fprintf ( stderr, "%s: no such file or empty file!\n\n", name[i] ); return filesOK; } } fprintf ( stderr, "Files for scaffold construction are OK.\n\n" ); return filesOK; } /************************************************* Function: getBindCnt Description: Gets the only connection of current contig. Input: 1. ctg: current contig Output: None. Return: The pointer to connection if only one connection was found. *************************************************/ static CONNECT * getBindCnt ( unsigned int ctg ) { CONNECT * ite_cnt; CONNECT * bindCnt = NULL; CONNECT * temp_cnt = NULL; CONNECT * temp3_cnt = NULL; int count = 0; int count2 = 0; int count3 = 0; ite_cnt = contig_array[ctg].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->nextInScaf ) { count++; bindCnt = ite_cnt; } if ( ite_cnt->prevInScaf ) { temp_cnt = ite_cnt; count2++; } if ( ite_cnt->singleInScaf ) { temp3_cnt = ite_cnt; count3++; } ite_cnt = ite_cnt->next; } if ( count == 1 ) { return bindCnt; } if ( count == 0 && count2 == 1 ) { return temp_cnt; } if ( count == 0 && count2 == 0 && count3 == 1 ) { return temp3_cnt; } return NULL; } /************************************************* Function: createAnalogousCnt Description: Creats new relation between two non-connected contigs according to toplogy sturcture supported by large insert size paired-end reads. Input: 1. sourceStart: contig that has connection relations to other two contigs 2. originCnt: direct connection supported by large insert size paired-end reads 3. gap: calculated distance between two non-connected contigs 4. targetStart: left contig of those two non-connected contigs 5. targetStop: right contig of those two non-connected contigs Output: None. Return: 1 if creation successed. *************************************************/ static boolean createAnalogousCnt ( unsigned int sourceStart, CONNECT * originCnt, int gap, unsigned int targetStart, unsigned int targetStop ) { CONNECT * temp_cnt; unsigned int balTargetStart = getTwinCtg ( targetStart ); unsigned int balTargetStop = getTwinCtg ( targetStop ); unsigned int balSourceStart = getTwinCtg ( sourceStart ); unsigned int balSourceStop = getTwinCtg ( originCnt->contigID ); boolean change_flag = 0; int add_weight = originCnt->weight; if ( gap < GapLowerBound ) { gapCounter++; originCnt->deleted = 1; temp_cnt = getCntBetween ( balSourceStop, balSourceStart ); temp_cnt->deleted = 1; return change_flag; } int startLen = ( int ) contig_array[targetStart].length; int stopLen = ( int ) contig_array[targetStop].length; if ( gap < -overlaplen ) { if ( ( int ) contig_array[targetStart].length - overlaplen <= -gap && ( int ) contig_array[targetStart].length > 5 * overlaplen ) { unsigned int tmp_id = targetStart; targetStart = targetStop; targetStop = tmp_id; tmp_id = balTargetStart; balTargetStart = balTargetStop; balTargetStop = tmp_id; gap = -gap; change_flag = 1; } else { gapCounter++; return change_flag; } } originCnt->deleted = 1; temp_cnt = getCntBetween ( balSourceStop, balSourceStart ); temp_cnt->deleted = 1; temp_cnt = add1Connect ( targetStart, targetStop, gap, add_weight, 1 ); if ( temp_cnt ) { temp_cnt->inherit = 1; } temp_cnt = add1Connect ( balTargetStop, balTargetStart, gap, add_weight, 1 ); if ( temp_cnt ) { temp_cnt->inherit = 1; } return change_flag; } /************************************************* Function: add1LongPEcov Description: Increases the connections weight supported by large insert size paired-end reads between contigs in one scaffold. Input: 1. fromCtg: left contig of pair contig connected by large insert size paired-end reads 2. toCtg: right contig of pair contig connected by large insert size paired-end reads 3. weight: weight of connection Output: None. Return: None. *************************************************/ static void add1LongPEcov ( unsigned int fromCtg, unsigned int toCtg, int weight ) { //check if they are on the same scaff if ( contig_array[fromCtg].from_vt != contig_array[toCtg].from_vt || contig_array[fromCtg].to_vt != contig_array[toCtg].to_vt ) { fprintf ( stderr, "Warning from add1LongPEcov: contig %d and %d not on the same scaffold\n", fromCtg, toCtg ); return; } if ( contig_array[fromCtg].indexInScaf >= contig_array[toCtg].indexInScaf ) { fprintf ( stderr, "Warning from add1LongPEcov: wrong about order between contig %d and %d\n", fromCtg, toCtg ); return; } CONNECT * bindCnt; unsigned int prevCtg = fromCtg; bindCnt = getBindCnt ( fromCtg ); while ( bindCnt ) { if ( bindCnt->maxGap + weight <= 1000 ) { bindCnt->maxGap += weight; } else { bindCnt->maxGap = 1000; } if ( fromCtg == 0 && toCtg == 0 ) fprintf ( stderr, "link (%d %d ) covered by link (%d %d), wt %d\n", prevCtg, bindCnt->contigID, fromCtg, toCtg, weight ); if ( bindCnt->contigID == toCtg ) { break; } prevCtg = bindCnt->contigID; bindCnt = bindCnt->nextInScaf; } unsigned int bal_fc = getTwinCtg ( fromCtg ); unsigned int bal_tc = getTwinCtg ( toCtg ); bindCnt = getBindCnt ( bal_tc ); prevCtg = bal_tc; while ( bindCnt ) { if ( bindCnt->maxGap + weight <= 1000 ) { bindCnt->maxGap += weight; } else { bindCnt->maxGap = 1000; } if ( fromCtg == 0 && toCtg == 0 ) fprintf ( stderr, "link (%d %d ) covered by link (%d %d), wt %d\n", prevCtg, bindCnt->contigID, fromCtg, toCtg, weight ); if ( bindCnt->contigID == bal_fc ) { return; } prevCtg = bindCnt->contigID; bindCnt = bindCnt->nextInScaf; } } /************************************************* Function: downSlide Description: Deals with connections supported by large insert size paired-end reads. If a connecton is abnormal, or the two connected contigs are in the same scaffold and the distance between them is normal, set the connection's status to 'deleted'. If the two connected contigs locate in different scaffolds, trys to creat a connection between these two scaffolds. Input: None. Output: None. Return: None. *************************************************/ static void downSlide() { int len = 0, gap; unsigned int i; CONNECT * ite_cnt, *bindCnt, *temp_cnt; unsigned int bottomCtg, topCtg, bal_i; unsigned int targetCtg, bal_target; boolean getThrough, orienConflict; int slideLen, slideLen2; int slideexchange1 = 0, slideexchange2 = 0; orienCounter = throughCounter = 0; orienCounter2 = 0; int slidebreak1 = 0, slidebreak2 = 0, slidebreak = 0, recoverCnt = 0; for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].mask || !contig_array[i].downwardConnect ) { continue; } bindCnt = getBindCnt ( i ); if ( !bindCnt ) { continue; } bal_i = getTwinCtg ( i ); len = slideLen = 0; bottomCtg = i; //find the last unmasked contig in this binding while ( bindCnt->nextInScaf ) { len += bindCnt->gapLen + contig_array[bindCnt->contigID].length; if ( contig_array[bindCnt->contigID].mask == 0 ) { bottomCtg = bindCnt->contigID; slideLen = len; } bindCnt = bindCnt->nextInScaf; } len += bindCnt->gapLen + contig_array[bindCnt->contigID].length; if ( contig_array[bindCnt->contigID].mask == 0 || bottomCtg == 0 ) { bottomCtg = bindCnt->contigID; slideLen = len; } //check each connetion from long pair ends ite_cnt = contig_array[i].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->deleted || ite_cnt->mask || ite_cnt->singleInScaf || ite_cnt->nextInScaf || ite_cnt->prevInScaf || ite_cnt->inherit ) { ite_cnt = ite_cnt->next; continue; } targetCtg = ite_cnt->contigID; if ( contig_array[i].from_vt == contig_array[targetCtg].from_vt ) // on the same scaff { if ( contig_array[i].indexInScaf > contig_array[targetCtg].indexInScaf ) { orienCounter++; } else { throughCounter++; } setConnectDelete ( i, ite_cnt->contigID, 1, 0 ); ite_cnt = ite_cnt->next; continue; } if ( ( ins_var_idx > 0 ) && ( slideLen > Insert_size * ins_var_idx ) ) { setConnectDelete ( i, ite_cnt->contigID, 1, 0 ); ite_cnt = ite_cnt->next; slidebreak1++; continue; } //contig i and targetctg is not in same scaffold //check if this connection conflicts with previous scaffold orientationally temp_cnt = getBindCnt ( targetCtg ); orienConflict = 0; if ( temp_cnt ) { while ( temp_cnt->nextInScaf ) { if ( temp_cnt->contigID == i ) { orienConflict = 1; fprintf ( stderr, "Warning from downSlide: still on the same scaff: %d and %d\n" , i, targetCtg ); fprintf ( stderr, "on scaff %d and %d\n", contig_array[i].from_vt, contig_array[targetCtg].from_vt ); fprintf ( stderr, "on bal_scaff %d and %d\n", contig_array[bal_target].to_vt, contig_array[bal_i].to_vt ); break; } temp_cnt = temp_cnt->nextInScaf; } if ( temp_cnt->contigID == i ) { orienConflict = 1; } } if ( orienConflict ) { orienCounter++; orienCounter2++; setConnectDelete ( i, ite_cnt->contigID, 1, 0 ); ite_cnt = ite_cnt->next; continue; } //connection path to i was not found //find the most top contig along previous scaffold starting with the target contig of this connection bal_target = getTwinCtg ( targetCtg ); slideLen2 = 0; if ( contig_array[targetCtg].mask == 0 ) { topCtg = bal_target; } else { topCtg = 0; } temp_cnt = getBindCnt ( bal_target ); getThrough = len = 0; int slidebreak = 0; if ( temp_cnt ) { //find the last contig in this binding while ( temp_cnt->nextInScaf ) { //check if this route reaches bal_i if ( temp_cnt->contigID == bal_i ) { fprintf ( stderr, "Warning from downSlide: (B) still on the same scaff: %d and %d (%d and %d)\n", i, targetCtg, bal_target, bal_i ); fprintf ( stderr, "on scaff %d and %d\n", contig_array[i].from_vt, contig_array[targetCtg].from_vt ); fprintf ( stderr, "on bal_scaff %d and %d\n", contig_array[bal_target].to_vt, contig_array[bal_i].to_vt ); getThrough = 1; break; } len += temp_cnt->gapLen + contig_array[temp_cnt->contigID].length; if ( contig_array[temp_cnt->contigID].mask == 0 ) { topCtg = temp_cnt->contigID; slideLen2 = len; } if ( ( ins_var_idx > 0 ) && ( len > ins_var_idx * Insert_size ) ) { slidebreak = 1; break; } temp_cnt = temp_cnt->nextInScaf; } len += temp_cnt->gapLen + contig_array[temp_cnt->contigID].length; if ( contig_array[temp_cnt->contigID].mask == 0 || topCtg == 0 ) { topCtg = temp_cnt->contigID; slideLen2 = len; } if ( slidebreak == 1 ) { setConnectDelete ( i, ite_cnt->contigID, 1, 0 ); ite_cnt = ite_cnt->next; slidebreak2++; continue; } if ( temp_cnt->contigID == bal_i ) { getThrough = 1; } else { topCtg = getTwinCtg ( topCtg ); } } else { topCtg = targetCtg; } if ( getThrough ) { throughCounter++; setConnectDelete ( i, ite_cnt->contigID, 1, 0 ); ite_cnt = ite_cnt->next; continue; } //connection path to bal_id was not found CONNECT * dh_cnt; gap = ite_cnt->gapLen - slideLen - slideLen2; dh_cnt = getCntBetween ( topCtg, bottomCtg ); if ( dh_cnt && dh_cnt->weight >= MinWeakCut ) { slideexchange1++; setConnectDelete ( topCtg, bottomCtg, 0, 0 ); setConnectMask ( topCtg, bottomCtg, 0 ); ite_cnt = ite_cnt->next; continue; } //add a connection between bottomCtg and topCtg if ( bottomCtg != topCtg && ! ( i == bottomCtg && targetCtg == topCtg ) ) { boolean creat_flag = createAnalogousCnt ( i, ite_cnt, gap, bottomCtg, topCtg ); if ( creat_flag ) { slideexchange2++; } if ( contig_array[bottomCtg].mask || contig_array[topCtg].mask ) { fprintf ( stderr, "downSlide to masked contig, bottomCtg %u[mask %d], topCtg %u[mask %d]\n", bottomCtg, contig_array[bottomCtg].mask, topCtg, contig_array[topCtg].mask ); } } ite_cnt = ite_cnt->next; } } // fprintf(stderr,"downSliding stat:\norienConflict\tfall_inside\tslidebreak1\tslidebreak2\trecoverCnt\tslideexchange1\tslideexchange2\n%d\t%d\t%d\t%d\t%d\t%d\t%d\n",orienCounter, throughCounter, slidebreak1, slidebreak2, recoverCnt, slideexchange1, slideexchange2); fprintf ( stderr, "Add large insert size PE links: %d orientation-conflict links, %d contigs acrossed by normal links.\n", orienCounter, throughCounter ); } /************************************************* Function: setNextInScaf Description: Sets the downstream connection of current connection. Input: 1. cnt: current connection 2. nextCnt: next connection Output: None. Return: 1 if setting successed. *************************************************/ static boolean setNextInScaf ( CONNECT * cnt, CONNECT * nextCnt ) { if ( !cnt ) { fprintf ( stderr, "setNextInScaf: empty pointer\n" ); return 0; } if ( !nextCnt ) { cnt->nextInScaf = nextCnt; return 1; } if ( cnt->mask || cnt->deleted ) { fprintf ( stderr, "setNextInScaf: cnt is masked or deleted\n" ); return 0; } if ( nextCnt->deleted || nextCnt->mask ) { fprintf ( stderr, "setNextInScaf: nextCnt is masked or deleted\n" ); return 0; } cnt->nextInScaf = nextCnt; return 1; } /************************************************* Function: setPrevInScaf Description: Sets the upstream connection status of current connection. Input: 1. cnt: current connection 2. flag: new status Output: None. Return: 1 if setting successed. *************************************************/ static boolean setPrevInScaf ( CONNECT * cnt, boolean flag ) { if ( !cnt ) { fprintf ( stderr, "setPrevInScaf: empty pointer\n" ); return 0; } if ( !flag ) { cnt->prevInScaf = flag; return 1; } if ( cnt->mask || cnt->deleted ) { fprintf ( stderr, "setPrevInScaf: cnt is masked or deleted\n" ); return 0; } cnt->prevInScaf = flag; return 1; } /************************************************* Function: substitueUSinScaf Description: Substitutes the upstream connection of current connection with new connection. from_c -> branch_c -> to_c from_c_new Input: 1. origin: original upstream connection of current connection (from_c -> branch_c) 2. from_c_new: new upstream contig of current contig (branch_c) Output: None. Return: None. *************************************************/ static void substitueUSinScaf ( CONNECT * origin, unsigned int from_c_new ) { if ( !origin || !origin->nextInScaf ) { return; } unsigned int branch_c, to_c; unsigned int bal_branch_c, bal_to_c; unsigned int bal_from_c_new = getTwinCtg ( from_c_new ); CONNECT * bal_origin, *bal_nextCNT, *prevCNT, *bal_prevCNT; branch_c = origin->contigID; to_c = origin->nextInScaf->contigID; bal_branch_c = getTwinCtg ( branch_c ); bal_to_c = getTwinCtg ( to_c ); prevCNT = checkConnect ( from_c_new, branch_c ); bal_nextCNT = checkConnect ( bal_to_c, bal_branch_c ); if ( !bal_nextCNT ) { fprintf ( stderr, "substitueUSinScaf: no connect between %d and %d\n", bal_to_c, bal_branch_c ); return; } bal_origin = bal_nextCNT->nextInScaf; bal_prevCNT = checkConnect ( bal_branch_c, bal_from_c_new ); setPrevInScaf ( bal_nextCNT->nextInScaf, 0 ); setNextInScaf ( prevCNT, origin->nextInScaf ); setNextInScaf ( bal_nextCNT, bal_prevCNT ); setPrevInScaf ( bal_prevCNT, 1 ); setNextInScaf ( origin, NULL ); setPrevInScaf ( bal_origin, 0 ); } /************************************************* Function: substitueDSinScaf Description: Substitutes the downstream connection of current connection with new connection. to_c from_c -> branch_c -> to_c_new Input: 1. origin: original downstream connection of current connection (branch_c -> to_c) 2. branch_c: current contig 3. to_c_new: new downstream contig of current contig Output: None. Return: None. *************************************************/ static void substitueDSinScaf ( CONNECT * origin, unsigned int branch_c, unsigned int to_c_new ) { if ( !origin || !origin->prevInScaf ) { return; } unsigned int to_c; unsigned int bal_branch_c, bal_to_c, bal_to_c_new; unsigned int from_c, bal_from_c; CONNECT * bal_origin, *prevCNT, *bal_prevCNT; CONNECT * nextCNT, *bal_nextCNT; to_c = origin->contigID; bal_branch_c = getTwinCtg ( branch_c ); bal_to_c = getTwinCtg ( to_c ); bal_origin = getCntBetween ( bal_to_c, bal_branch_c ); if ( !bal_origin ) { fprintf ( stderr, "substitueDSinScaf: no connect between %d and %d\n", bal_to_c, bal_branch_c ); return; } if ( bal_origin->nextInScaf ) { bal_from_c = bal_origin->nextInScaf->contigID; } else { fprintf ( stderr, "next null! %d\t%d\n", bal_to_c, bal_branch_c ); exit ( 3 ); } bal_from_c = bal_origin->nextInScaf->contigID; from_c = getTwinCtg ( bal_from_c ); bal_to_c_new = getTwinCtg ( to_c_new ); prevCNT = checkConnect ( from_c, branch_c ); nextCNT = checkConnect ( branch_c, to_c_new ); setNextInScaf ( prevCNT, nextCNT ); setPrevInScaf ( nextCNT, 1 ); bal_nextCNT = checkConnect ( bal_to_c_new, bal_branch_c ); bal_prevCNT = checkConnect ( bal_branch_c, bal_from_c ); setNextInScaf ( bal_nextCNT, bal_prevCNT ); setPrevInScaf ( origin, 0 ); setNextInScaf ( bal_origin, NULL ); } /************************************************* Function: validConnect Description: Calculates the valid connections number of a contig. 1. Check whether the contig has upstream conntcion and downstream connection. 2. Calculates the non-deleted and non-masked connections number. Input: 1. ctg: contig 2. preCNT: upstream connection Output: None. Return: 0 if contig did NOT have connection to other contigs. 1 if contig had upstream conntcion and downstream connection. Non-deleted and non-masked connections number otherwise. *************************************************/ static int validConnect ( unsigned int ctg, CONNECT * preCNT ) { if ( preCNT && preCNT->nextInScaf ) { return 1; } CONNECT * cn_temp; int count = 0; if ( !contig_array[ctg].downwardConnect ) { return count; } cn_temp = contig_array[ctg].downwardConnect; while ( cn_temp ) { if ( !cn_temp->deleted && !cn_temp->mask ) { count++; } cn_temp = cn_temp->next; } return count; } /************************************************* Function: getNextContig Description: Gets the connection to next contig of current contig through constructed connection in scaffold or direct connection to other contigs. In the latter case, one and only one non-deleted and non-masked connection is qualified. Input: 1. ctg: current contig 2. preCNT: upstream connection of current contig Output: 1. exception: indicate that whether found connection through constructed connection in scaffold is deleted or masked Return: Pointer to qualified connection or NULL. *************************************************/ static CONNECT * getNextContig ( unsigned int ctg, CONNECT * preCNT, boolean * exception ) { CONNECT * cn_temp, *retCNT = NULL, *dh_cnt; int count = 0, valid_in; unsigned int nextCtg, bal_ctg; *exception = 0; if ( preCNT && preCNT->nextInScaf ) { if ( preCNT->contigID != ctg ) { fprintf ( stderr, "pre cnt does not lead to %d\n", ctg ); } nextCtg = preCNT->nextInScaf->contigID; cn_temp = getCntBetween ( ctg, nextCtg ); dh_cnt = getCntBetween ( getTwinCtg ( nextCtg ), getTwinCtg ( ctg ) ); if ( cn_temp && ( cn_temp->mask || cn_temp->deleted ) ) { int id1 = 0, id2 = 0; if ( dh_cnt->nextInScaf ) { id1 = dh_cnt->nextInScaf->contigID; id2 = getTwinCtg ( dh_cnt->nextInScaf->contigID ); } if ( !cn_temp->prevInScaf ) { fprintf ( stderr, "not even has a prevInScaf %d and %d, %d and %d with before %d with twin %d\n", ctg, nextCtg, getTwinCtg ( nextCtg ), getTwinCtg ( ctg ), id1, id2 ); } cn_temp = getCntBetween ( getTwinCtg ( nextCtg ), getTwinCtg ( ctg ) ); if ( !cn_temp->nextInScaf ) { fprintf ( stderr, "its twin cnt not has a nextInScaf\n" ); } fflush ( stdout ); *exception = 1; } else { return preCNT->nextInScaf; } } bal_ctg = getTwinCtg ( ctg ); valid_in = validConnect ( bal_ctg, NULL ); if ( valid_in > 1 ) { return NULL; } if ( !contig_array[ctg].downwardConnect ) { return NULL; } cn_temp = contig_array[ctg].downwardConnect; while ( cn_temp ) { if ( cn_temp->mask || cn_temp->deleted ) { cn_temp = cn_temp->next; continue; } count++; if ( count == 1 ) { retCNT = cn_temp; } else if ( count == 2 ) { return NULL; } cn_temp = cn_temp->next; } return retCNT; } /************************************************* Function: checkConnect Description: Check whether the connection between two contigs exists and the connection's status. Input: 1. from_c: left contig 2. to_c: right contig Output: None. Return: Pointer to qualified connection or NULL. *************************************************/ static CONNECT * checkConnect ( unsigned int from_c, unsigned int to_c ) { CONNECT * cn_temp = getCntBetween ( from_c, to_c ); if ( !cn_temp ) { return NULL; } if ( !cn_temp->mask && !cn_temp->deleted ) { return cn_temp; } //else //printf("masked or deleted: %d\t%d\t%d\t%d\n",from_c,to_c,cn_temp->mask,cn_temp->deleted); return NULL; } /************************************************* Function: setConnectMask Description: Sets the "mask" status of connection between two contigs and releated upstream and downstream connection's status if these connections exist. Input: 1. from_c: left contig 2. to_c: right contig 3. mask: new status Output: None. Return: 1 if setting successed. *************************************************/ static int setConnectMask ( unsigned int from_c, unsigned int to_c, char mask ) { CONNECT * cn_temp, *cn_bal, *cn_ds, *cn_us; unsigned int bal_fc = getTwinCtg ( from_c ); unsigned int bal_tc = getTwinCtg ( to_c ); unsigned int ctg3, bal_ctg3; cn_temp = getCntBetween ( from_c, to_c ); cn_bal = getCntBetween ( bal_tc, bal_fc ); if ( !cn_temp || !cn_bal ) { return 0; } cn_temp->mask = mask; cn_bal->mask = mask; if ( !mask ) { return 1; } if ( cn_temp->nextInScaf ) //undo the binding { setPrevInScaf ( cn_temp->nextInScaf, 0 ); ctg3 = cn_temp->nextInScaf->contigID; setNextInScaf ( cn_temp, NULL ); bal_ctg3 = getTwinCtg ( ctg3 ); cn_ds = getCntBetween ( bal_ctg3, bal_tc ); setNextInScaf ( cn_ds, NULL ); setPrevInScaf ( cn_bal, 0 ); } // ctg3 -> from_c -> to_c // bal_ctg3 <- bal_fc <- bal_tc if ( cn_bal->nextInScaf ) { setPrevInScaf ( cn_bal->nextInScaf, 0 ); bal_ctg3 = cn_bal->nextInScaf->contigID; setNextInScaf ( cn_bal, NULL ); ctg3 = getTwinCtg ( bal_ctg3 ); cn_us = getCntBetween ( ctg3, from_c ); setNextInScaf ( cn_us, NULL ); setPrevInScaf ( cn_temp, 0 ); } return 1; } /************************************************* Function: setConnectUsed Description: Sets the "used" status of connection between two contigs if the connection exists. Input: 1. from_c: left contig 2. to_c: right contig 3. flag: new status Output: None. Return: 1 if setting successed. *************************************************/ static boolean setConnectUsed ( unsigned int from_c, unsigned int to_c, char flag ) { CONNECT * cn_temp, *cn_bal; unsigned int bal_fc = getTwinCtg ( from_c ); unsigned int bal_tc = getTwinCtg ( to_c ); cn_temp = getCntBetween ( from_c, to_c ); cn_bal = getCntBetween ( bal_tc, bal_fc ); if ( !cn_temp || !cn_bal ) { return 0; } cn_temp->used = flag; cn_bal->used = flag; return 1; } /************************************************* Function: setConnectWP Description: Sets the "weakPoint" status of connection between two contigs if the connection exists. Input: 1. from_c: left contig 2. to_c: right contig 3. flag: new status Output: None. Return: 1 if setting successed. *************************************************/ static int setConnectWP ( unsigned int from_c, unsigned int to_c, char flag ) { CONNECT * cn_temp, *cn_bal; unsigned int bal_fc = getTwinCtg ( from_c ); unsigned int bal_tc = getTwinCtg ( to_c ); cn_temp = getCntBetween ( from_c, to_c ); cn_bal = getCntBetween ( bal_tc, bal_fc ); if ( !cn_temp || !cn_bal ) { return 0; } cn_temp->weakPoint = flag; cn_bal->weakPoint = flag; return 1; } /************************************************* Function: setConnectDelete Description: Sets the "deleted" status of connection between two contigs if the connection exists. Cleans the related upstream and downstream connections if required. Input: 1. from_c: left contig 2. to_c: right contig 3. flag: new status 4. cleanBinding: indicator of whether cleaning related connections Output: None. Return: 1 if setting successed. *************************************************/ static int setConnectDelete ( unsigned int from_c, unsigned int to_c, char flag, boolean cleanBinding ) { CONNECT * cn_temp, *cn_bal; unsigned int bal_fc = getTwinCtg ( from_c ); unsigned int bal_tc = getTwinCtg ( to_c ); cn_temp = getCntBetween ( from_c, to_c ); cn_bal = getCntBetween ( bal_tc, bal_fc ); if ( !cn_temp || !cn_bal ) { return 0; } cn_temp->deleted = flag; cn_bal->deleted = flag; if ( !flag ) { return 1; } if ( cleanBinding ) { cn_temp->prevInScaf = 0; cn_temp->nextInScaf = NULL; cn_bal->prevInScaf = 0; cn_bal->nextInScaf = NULL; } return 1; } /************************************************* Function: maskContig Description: Sets the "mask" status of target contig and its connections to other contigs except those connections in scaffold. Input: 1. ctg: target contig 2. flag: new status Output: None. Return: None. *************************************************/ static void maskContig ( unsigned int ctg, boolean flag ) { unsigned int bal_ctg, ctg2, bal_ctg2; CONNECT * cn_temp; bal_ctg = getTwinCtg ( ctg ); cn_temp = contig_array[ctg].downwardConnect; while ( cn_temp ) { if ( cn_temp->mask || cn_temp->prevInScaf || cn_temp->nextInScaf || cn_temp->singleInScaf ) { cn_temp = cn_temp->next; continue; } ctg2 = cn_temp->contigID; setConnectMask ( ctg, ctg2, flag ); cn_temp = cn_temp->next; } // bal_ctg2 <- bal_ctg cn_temp = contig_array[bal_ctg].downwardConnect; while ( cn_temp ) { if ( cn_temp->mask || cn_temp->prevInScaf || cn_temp->nextInScaf || cn_temp->singleInScaf ) { cn_temp = cn_temp->next; continue; } bal_ctg2 = cn_temp->contigID; setConnectMask ( bal_ctg, bal_ctg2, flag ); cn_temp = cn_temp->next; } contig_array[ctg].mask = flag; contig_array[bal_ctg].mask = flag; } /************************************************* Function: maskPuzzle Description: For contigs longer than "contigLen", masks them if they have more than one valid connection in either upstream of downstream direction, and have more than 'num_connect' valid connection. Input: 1. num_connect: allowed valid connection number cutoff 2. contigLen: contig length cutoff Output: None. Return: Masked contig number. *************************************************/ static int maskPuzzle ( int num_connect, unsigned int contigLen ) { int in_num, out_num, flag = 0, puzzleCounter = 0; unsigned int i, bal_i; fprintf ( stderr, "Start to mask puzzles.\n" ); for ( i = 1; i <= num_ctg; i++ ) { if ( contigLen && contig_array[i].length > contigLen ) { break; } if ( contig_array[i].mask ) { continue; } bal_i = getTwinCtg ( i ); in_num = validConnect ( bal_i, NULL ); out_num = validConnect ( i, NULL ); if ( ( in_num > 1 || out_num > 1 ) && ( in_num + out_num >= num_connect ) ) { flag++; maskContig ( i, 1 ); } // upstream connection in scaffold in_num = validConnect ( bal_i, NULL ); // downstream connection in scaffold out_num = validConnect ( i, NULL ); if ( in_num > 1 || out_num > 1 ) { puzzleCounter++; //debugging2(i); } if ( isSmallerThanTwin ( i ) ) { i++; } } fprintf ( stderr, " Masked contigs %d\n Remained puzzles %d\n", flag, puzzleCounter ); return flag; } /************************************************* Function: deleteWeakCnt Description: Updates the status of contigs' connections according to "cut_off", and then mask those contigs which form circle structure. A -> B -> A Input: 1. cut_off: weight cutoff of connection Output: None. Return: None. *************************************************/ static void deleteWeakCnt ( int cut_off ) { unsigned int i; CONNECT * cn_temp1; int weaks = 0, counter = 0; for ( i = 1; i <= num_ctg; i++ ) { cn_temp1 = contig_array[i].downwardConnect; while ( cn_temp1 ) { if ( !cn_temp1->mask && !cn_temp1->deleted && !cn_temp1->nextInScaf && !cn_temp1->singleInScaf && !cn_temp1->prevInScaf ) { counter++; } if ( cn_temp1->weak && cn_temp1->deleted && cn_temp1->weight >= cut_off ) { cn_temp1->deleted = 0; cn_temp1->weak = 0; } else if ( !cn_temp1->deleted && cn_temp1->weight > 0 && cn_temp1->weight < cut_off && !cn_temp1->nextInScaf && !cn_temp1->prevInScaf ) { cn_temp1->deleted = 1; cn_temp1->weak = 1; if ( cn_temp1->singleInScaf ) { cn_temp1->singleInScaf = 0; } if ( !cn_temp1->mask ) { weaks++; } } cn_temp1 = cn_temp1->next; } } if ( counter > 0 ) { fprintf ( stderr, " Active connections %d\n Weak connections %d\n Weak ratio %.1f%%\n", counter, weaks, ( float ) weaks / counter * 100 ); } checkCircle(); } /************************************************* Function: linearC2C Description: For three contigs A, B and C, connections A->B and A->C exist, check if there is a connection path connecting B and C or whether a new connection can be created between B and C. -------> A -> B -?-> C Input: 1. starter: leftmost contig 2. cnt2c1: connection A->B 3. c2: rightmost contig 4. min_dis: minimum distance between middle and rightmost contig 5. max_dis: maximum distance between middle and rightmost contig Output: None. Return: -1 if B and C were the same contig. 1 if connection path was found or connection was created. 0 otherwise. *************************************************/ static int linearC2C ( unsigned int starter, CONNECT * cnt2c1, unsigned int c2, int min_dis, int max_dis ) { int out_num, in_num; CONNECT * prevCNT, *cnt, *cn_temp; unsigned int c1, bal_c1, ctg, bal_c2; int len = 0; unsigned int bal_start = getTwinCtg ( starter ); boolean excep; c1 = cnt2c1->contigID; if ( c1 == c2 ) { fprintf ( stderr, "linearC2C: c1(%d) and c2(%d) are the same contig.\n", c1, c2 ); return -1; } bal_c1 = getTwinCtg ( c1 ); dsCtgCounter = 1; usCtgCounter = 0; downstreamCTG[dsCtgCounter++] = c1; bal_c2 = getTwinCtg ( c2 ); upstreamCTG[usCtgCounter++] = bal_c2; // check if c1 is linearly connected to c2 by pe connections cnt = prevCNT = cnt2c1; while ( ( cnt = getNextContig ( c1, prevCNT, &excep ) ) != NULL ) { c1 = cnt->contigID; len += cnt->gapLen + contig_array[c1].length; if ( c1 == c2 ) { usCtgCounter--; return 1; //is interleaving. } if ( len > max_dis || c1 == starter || c1 == bal_start ) { return 0; } downstreamCTG[dsCtgCounter++] = c1; if ( dsCtgCounter >= MAXCinBetween ) { fprintf ( stderr, "%d downstream contigs, start at %d, max_dis %d, current dis %d\n" , dsCtgCounter, starter, max_dis, len ); return 0; } prevCNT = cnt; } out_num = validConnect ( c1, NULL ); //new c1 should have no outgoing link. if ( out_num ) { return 0; } //find the most upstream contig to c2 cnt = prevCNT = NULL; ctg = bal_c2; while ( ( cnt = getNextContig ( ctg, prevCNT, &excep ) ) != NULL ) { ctg = cnt->contigID; len += cnt->gapLen + contig_array[ctg].length; if ( len > max_dis || ctg == starter || ctg == bal_start ) { return 0; } prevCNT = cnt; upstreamCTG[usCtgCounter++] = ctg; if ( usCtgCounter >= MAXCinBetween ) { fprintf ( stderr, "%d upstream contigs, start at %d, max_dis %d, current dis %d\n" , usCtgCounter, starter, max_dis, len ); return 0; } } if ( dsCtgCounter + usCtgCounter > MAXCinBetween ) { fprintf ( stderr, "%d downstream and %d upstream contigs.\n", dsCtgCounter, usCtgCounter ); return 0; } out_num = validConnect ( ctg, NULL ); //new c2 have no incoming link. if ( out_num ) { return 0; } c2 = getTwinCtg ( ctg ); min_dis -= len; max_dis -= len; if ( c1 == c2 || c1 == ctg || max_dis < 0 ) { return 0; } usCtgCounter--; cn_temp = getCntBetween ( c1, c2 ); //have connection between new c1 and new c2 if ( cn_temp ) { setConnectMask ( c1, c2, 0 ); setConnectDelete ( c1, c2, 0, 0 ); return 1; } int oldsize = usCtgCounter; while ( getCntBetween ( c2, c1 ) && usCtgCounter > 1 ) { usCtgCounter--; c2 = getTwinCtg ( upstreamCTG[usCtgCounter] ); } if ( usCtgCounter != oldsize ) { unsigned int prev_c2 = upstreamCTG[usCtgCounter + 1]; unsigned int bal_prev_c2 = getTwinCtg ( prev_c2 ); setConnectMask ( bal_prev_c2, c2, 1 ); setConnectMask ( bal_prev_c2, c2, 0 ); int i = usCtgCounter + 1; for ( ; i <= oldsize; i++ ) { contig_array[upstreamCTG[i]].from_vt = prev_c2; contig_array[getTwinCtg ( upstreamCTG[i] )].to_vt = bal_prev_c2; } if ( ( cn_temp = getCntBetween ( c1, c2 ) ) != NULL ) { setConnectMask ( c1, c2, 0 ); setConnectDelete ( c1, c2, 0, 0 ); return 1; } } len = ( min_dis + max_dis ) / 2 >= 0 ? ( min_dis + max_dis ) / 2 : 0; cn_temp = allocateCN ( c2, len ); if ( cntLookupTable ) { putCnt2LookupTable ( c1, cn_temp ); } cn_temp->weight = 0; // special connect from the original graph cn_temp->next = contig_array[c1].downwardConnect; contig_array[c1].downwardConnect = cn_temp; bal_c1 = getTwinCtg ( c1 ); bal_c2 = getTwinCtg ( c2 ); cn_temp = allocateCN ( bal_c1, len ); if ( cntLookupTable ) { putCnt2LookupTable ( bal_c2, cn_temp ); } cn_temp->weight = 0; // special connect from the original graph cn_temp->next = contig_array[bal_c2].downwardConnect; contig_array[bal_c2].downwardConnect = cn_temp; return 1; } /************************************************* Function: catUsDsContig Description: Concatenates upstream and downstream contig arrays together. Input: None. Output: None. Return: None. *************************************************/ static void catUsDsContig() { int i; for ( i = 0; i < dsCtgCounter; i++ ) { * ( unsigned int * ) darrayPut ( solidArray, i ) = downstreamCTG[i]; } for ( i = usCtgCounter; i >= 0; i-- ) { * ( unsigned int * ) darrayPut ( solidArray, dsCtgCounter++ ) = getTwinCtg ( upstreamCTG[i] ); } solidCounter = dsCtgCounter; } /************************************************* Function: consolidate Description: Constructs scaffolds by binding connection relation among contigs in "solidArray". Input: None. Output: None. Return: None. *************************************************/ static void consolidate() { int i, j; CONNECT * prevCNT = NULL; CONNECT * cnt; unsigned int to_ctg; unsigned int from_ctg = * ( unsigned int * ) darrayGet ( solidArray, 0 ); for ( i = 1; i < solidCounter; i++ ) { to_ctg = * ( unsigned int * ) darrayGet ( solidArray, i ); cnt = checkConnect ( from_ctg, to_ctg ); if ( !cnt ) { fprintf ( stderr, "consolidate A: no connect from %d to %d\n", from_ctg, to_ctg ); for ( j = 0; j < solidCounter; j++ ) { fprintf ( stderr, "%d-->", * ( unsigned int * ) darrayGet ( solidArray, j ) ); } fprintf ( stderr, "\n" ); return; } cnt->singleInScaf = solidCounter == 2 ? 1 : 0; if ( prevCNT ) { setNextInScaf ( prevCNT, cnt ); setPrevInScaf ( cnt, 1 ); } prevCNT = cnt; from_ctg = to_ctg; } //the reverse complementary path from_ctg = getTwinCtg ( * ( unsigned int * ) darrayGet ( solidArray, solidCounter - 1 ) ); prevCNT = NULL; for ( i = solidCounter - 2; i >= 0; i-- ) { to_ctg = getTwinCtg ( * ( unsigned int * ) darrayGet ( solidArray, i ) ); cnt = checkConnect ( from_ctg, to_ctg ); if ( !cnt ) { fprintf ( stderr, "consolidate B: no connect from %d to %d\n", from_ctg, to_ctg ); return; } cnt->singleInScaf = solidCounter == 2 ? 1 : 0; if ( prevCNT ) { setNextInScaf ( prevCNT, cnt ); setPrevInScaf ( cnt, 1 ); } prevCNT = cnt; from_ctg = to_ctg; } } static void debugging1 ( unsigned int ctg1, unsigned int ctg2 ) { CONNECT * cn1; cn1 = getCntBetween ( ctg1, ctg2 ); if ( cn1 ) { fprintf ( stderr, "(%d,%d) mask %d deleted %d w %d,singleInScaf %d\n", ctg1, ctg2, cn1->mask, cn1->deleted, cn1->weight, cn1->singleInScaf ); if ( cn1->nextInScaf ) { fprintf ( stderr, "%d->%d->%d\n", ctg1, ctg2, cn1->nextInScaf->contigID ); } if ( cn1->prevInScaf ) { fprintf ( stderr, "*->%d->%d\n", ctg1, ctg2 ); } else if ( !cn1->nextInScaf ) { fprintf ( stderr, "NULL->%d->%d->NULL\n", ctg1, ctg2 ); } } else { fprintf ( stderr, "%d -X- %d\n", ctg1, ctg2 ); } } /************************************************* Function: removeTransitive Description: For three contigs A, B and C, connections A->B and A->C exist. If there is a connection path connecting B and C or a new connection can be created between B and C, then deletes connection A->C. -------> A -> B -?-> C Input: None. Output: None. Return: None. *************************************************/ static void removeTransitive() { unsigned int i, bal_ctg; int flag = 1, out_num, in_num, count, min, max, linear; CONNECT * cn_temp, *cn1 = NULL, *cn2 = NULL; int multi_out = 0, single_out = 0, two_out = 0, may_transitive = 0, not_transitive = 0, cycle_num = 0, mask_ctg = 0, no_out = 0; fprintf ( stderr, "Start to remove transitive connection.\n" ); while ( flag ) { flag = 0; two_out = 0; not_transitive = 0; may_transitive = 0; cycle_num++; for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].mask ) { if ( cycle_num == 1 ) { mask_ctg++; } continue; } out_num = validConnect ( i, NULL ); if ( out_num != 2 ) { if ( out_num == 1 && cycle_num == 1 ) { single_out++; } if ( out_num > 2 && cycle_num == 1 ) { multi_out++; } if ( out_num == 0 && cycle_num == 1 ) { no_out++; } continue; } two_out++; cn_temp = contig_array[i].downwardConnect; count = 0; while ( cn_temp ) { if ( cn_temp->deleted || cn_temp->mask ) { cn_temp = cn_temp->next; continue; } count++; if ( count == 1 ) { cn1 = cn_temp; } else if ( count == 2 ) { cn2 = cn_temp; } else { break; } cn_temp = cn_temp->next; } if ( count > 2 ) { fprintf ( stderr, "%d valid connections from ctg %d\n", count, i ); continue; } if ( cn1->gapLen > cn2->gapLen ) { cn_temp = cn1; cn1 = cn2; cn2 = cn_temp; } //make sure cn1 is closer to contig i than cn2 if ( cn1->prevInScaf && cn2->prevInScaf ) { continue; } bal_ctg = getTwinCtg ( cn2->contigID ); in_num = validConnect ( bal_ctg, NULL ); if ( in_num > 2 ) { continue; } int bal_c1 = getTwinCtg ( cn1->contigID ); in_num = validConnect ( bal_c1, NULL ); if ( in_num > 1 ) { continue; } min = cn2->gapLen - cn1->gapLen - contig_array[cn1->contigID].length - ins_size_var / 2; max = cn2->gapLen - cn1->gapLen - contig_array[cn1->contigID].length + ins_size_var / 2; if ( max < 0 ) { continue; } may_transitive++; //temprarily delete cn2 setConnectDelete ( i, cn2->contigID, 1, 0 ); int oldc2 = cn2->contigID; linear = linearC2C ( i, cn1, cn2->contigID, min, max ); if ( linear != 1 ) { not_transitive++; setConnectDelete ( i, cn2->contigID, 0, 0 ); continue; } else { downstreamCTG[0] = i; catUsDsContig(); if ( !checkSimple ( solidArray, solidCounter ) ) { continue; } cn1 = getCntBetween ( * ( unsigned int * ) darrayGet ( solidArray, solidCounter - 2 ), * ( unsigned int * ) darrayGet ( solidArray, solidCounter - 1 ) ); if ( cn1 && cn1->nextInScaf && cn2->nextInScaf ) { setConnectDelete ( i, cn2->contigID, 0, 0 ); continue; } consolidate(); if ( cn2->prevInScaf ) substitueDSinScaf ( cn2, * ( unsigned int * ) darrayGet ( solidArray, 0 ), * ( unsigned int * ) darrayGet ( solidArray, 1 ) ); if ( cn2->nextInScaf ) { substitueUSinScaf ( cn2, * ( unsigned int * ) darrayGet ( solidArray, solidCounter - 2 ) ); } flag++; } } if ( cycle_num == 1 ) { fprintf ( stderr, "Total contigs %u\n", num_ctg ); fprintf ( stderr, "Masked contigs %d\n", mask_ctg ); fprintf ( stderr, "Remained contigs %u\n", num_ctg - mask_ctg ); fprintf ( stderr, "None-outgoing-connection contigs %d", no_out ); if ( num_ctg - mask_ctg > 0 ) { fprintf ( stderr, " (%1f%%)", ( float ) no_out / ( num_ctg - mask_ctg ) * 100 ); } fprintf ( stderr, "\nSingle-outgoing-connection contigs %d\n", single_out ); fprintf ( stderr, "Multi-outgoing-connection contigs %d\n", multi_out ); } fprintf ( stderr, "Cycle %d\n Two-outgoing-connection contigs %d\n Potential transitive connections %d\n Transitive connections %d\n", cycle_num, two_out, may_transitive, flag ); if ( two_out > 0 ) { fprintf ( stderr, " Transitive ratio %.1f%%\n", ( float ) flag / two_out * 100 ); } if ( flag == 0 ) { break; } } } static void debugging2 ( unsigned int ctg ) { if ( ctg > num_ctg ) { return; } CONNECT * cn1 = contig_array[ctg].downwardConnect; while ( cn1 ) { if ( cn1->nextInScaf ) { fprintf ( stderr, "with nextInScaf %u,", cn1->nextInScaf->contigID ); } if ( cn1->prevInScaf ) { fprintf ( stderr, "with prevInScaf," ); } fprintf ( stderr, "%u >> %u, weight %d, gapLen %d, mask %d deleted %d, inherit %d, singleInScaf %d, bySmall %d\n", ctg, cn1->contigID, cn1->weight, cn1->gapLen, cn1->mask, cn1->deleted, cn1->inherit, cn1->singleInScaf, cn1->bySmall ); cn1 = cn1->next; } } static void debugging() { // debugging1(13298356, 13245956); } /************************************************* Function: simplifyCnt Description: Simplifys contig graph by two operations. 1) Removes transitive connections. 2) Picks up local contig graph and tries to line involved contigs. Input: None. Output: None. Return: None. *************************************************/ static void simplifyCnt() { removeTransitive(); debugging(); general_linearization ( 1 ); debugging(); } /************************************************* Function: getIndexInArray Description: Gets contig's index in array. Input: 1. node: contig Output: None. Return: Index of contig if contig existed. -1 otherwise. *************************************************/ static int getIndexInArray ( unsigned int node ) { int index; for ( index = 0; index < nodeCounter; index++ ) if ( nodesInSub[index] == node ) { return index; } return -1; } /************************************************* Function: putNodeIntoSubgraph Description: Puts contig into sub-graph. Input: 1. heap: heap to store contigs 2. distance: current contig's distance to base contig 3. node: current contig 4. index: contig's index in array Output: None. Return: 0 if contig already existed in sub-graph. 1 if operation succeeded. -1 if index was larger than allowed maximum sub-graph size. *************************************************/ static boolean putNodeIntoSubgraph ( FibHeap * heap, int distance, unsigned int node, int index ) { int pos = getIndexInArray ( node ); if ( pos > 0 ) { return 0; } if ( index >= MaxNodeInSub ) { return -1; } insertNodeIntoHeap ( heap, distance, node ); nodesInSub[index] = node; nodeDistance[index] = distance; return 1; } /************************************************* Function: putChainIntoSubgraph Description: Puts contigs of connection chain into sub-graph. Input: 1. heap: heap to store contigs 2. distance: current contig's distance to base contig 3. node: current contig 4. index: contig's index in array 5. prevC: upstream connection of current contig Output: 1. index: index of next contig to add 2. prevC: upstream connection of last contig in connection chain Return: 0 if operation of putting contig into sub-graph failed. *************************************************/ static boolean putChainIntoSubgraph ( FibHeap * heap, int distance, unsigned int node, int * index, CONNECT * prevC ) { unsigned int ctg = node; CONNECT * nextCnt; boolean excep, flag; int counter = *index; while ( 1 ) { nextCnt = getNextContig ( ctg, prevC, &excep ); if ( excep || !nextCnt ) { *index = counter; return 1; } ctg = nextCnt->contigID; distance += nextCnt->gapLen + contig_array[ctg].length; flag = putNodeIntoSubgraph ( heap, distance, ctg, counter ); if ( flag < 0 ) { return 0; } if ( flag > 0 ) { counter++; } prevC = nextCnt; } } /************************************************* Function: checkUnique Description: Checks if a contig is unique by trying to line its upstream and downstream contigs. Input: 1. node: contig to check 2. tolerance: allowed percentage that overlap length among contigs in sub-graph accounts for in all involved contigs' length Output: None. Return: 1 if contig was unique. *************************************************/ static boolean checkUnique ( unsigned int node, double tolerance ) { CONNECT * ite_cnt; unsigned int currNode; int distance; int popCounter = 0; boolean flag; currNode = node; FibHeap * heap = newFibHeap(); putNodeIntoSubgraph ( heap, 0, currNode, 0 ); nodeCounter = 1; ite_cnt = contig_array[currNode].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->deleted || ite_cnt->mask ) { ite_cnt = ite_cnt->next; continue; } currNode = ite_cnt->contigID; distance = ite_cnt->gapLen + contig_array[currNode].length; flag = putNodeIntoSubgraph ( heap, distance, currNode, nodeCounter ); if ( flag < 0 ) { destroyHeap ( heap ); return 0; } if ( flag > 0 ) { nodeCounter++; } flag = putChainIntoSubgraph ( heap, distance, currNode, &nodeCounter, ite_cnt ); if ( !flag ) { destroyHeap ( heap ); return 0; } ite_cnt = ite_cnt->next; } if ( nodeCounter <= 2 ) // no more than 2 valid connections { destroyHeap ( heap ); return 1; } while ( ( currNode = removeNextNodeFromHeap ( heap ) ) != 0 ) { nodesInSubInOrder[popCounter++] = currNode; } destroyHeap ( heap ); flag = checkOverlapInBetween ( tolerance ); return flag; } /************************************************* Function: maskRepeat Description: Masks repeat contigs. Input: None. Output: None. Return: None. *************************************************/ static void maskRepeat() { int in_num, out_num, flagA, flagB; int counter = 0; int puzzleCounter = 0; unsigned int i, bal_i; for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].mask ) { continue; } bal_i = getTwinCtg ( i ); in_num = validConnect ( bal_i, NULL ); out_num = validConnect ( i, NULL ); if ( in_num > 1 || out_num > 1 ) { puzzleCounter++; } else { if ( isSmallerThanTwin ( i ) ) { i++; } continue; } if ( contig_array[i].cvg > 1.4 * cvgAvg ) { counter++; maskContig ( i, 1 ); if ( isSmallerThanTwin ( i ) ) { i++; } continue; } if ( in_num > 1 ) { flagA = checkUnique ( bal_i, OverlapPercent ); } else { flagA = 1; } if ( out_num > 1 ) { flagB = checkUnique ( i, OverlapPercent ); } else { flagB = 1; } if ( !flagA || !flagB ) { counter++; maskContig ( i, 1 ); } if ( isSmallerThanTwin ( i ) ) { i++; } } fprintf ( stderr, "Mask repeats:\n Puzzles %d\n Masked contigs %d\n", puzzleCounter, counter ); } /************************************************* Function: Countlink Description: Counts valid connections of all contigs. Input: None. Output: None. Return: Valid connections of all contigs. *************************************************/ static int Countlink() { unsigned int i, bal_i; int conflict_count = 0; for ( i = 1; i < num_ctg; i++ ) { if ( contig_array[i].mask ) { continue; } int out_num = validConnect ( i, NULL ); if ( out_num > 1 ) { conflict_count++; } } return conflict_count; } /************************************************* Function: ordering Description: Constructs scaffold using alignment information of paired-end reads rank by rank. Input: 1. deWeak: indicator of deleting weak connection. 2. downS: indicator of large insert size paired-end reads 3. nonlinear: indicator of simplifying graph using loose restraint 4. infile: prefix of graph Output: None. Return: None. *************************************************/ static void ordering ( boolean deWeak, boolean downS, boolean nonlinear, char * infile ) { int conf0, conf1, conf2, conf3, conf4, conf5; debugging(); if ( downS ) { downSlide(); debugging(); if ( deWeak ) { deleteWeakCnt ( weakPE ); } } else { if ( deWeak ) { deleteWeakCnt ( weakPE ); } } debugging(); simplifyCnt(); debugging(); maskRepeat(); debugging(); simplifyCnt(); debugging(); if ( nonlinear ) { fprintf ( stderr, "Non-strict linearization.\n" ); general_linearization ( 0 ); } maskPuzzle ( 2, 0 ); debugging(); freezing(); debugging(); } /************************************************* Function: checkOverlapInBetween Description: Checks if adjacent contigs in the array have reasonable overlap. Input: 1. tolerance: max percentage that overlap length accounts for Output: None. Return: 1 if the overlap situation was resonable. *************************************************/ boolean checkOverlapInBetween ( double tolerance ) { int i, gap; int index; unsigned int node; int lenSum, lenOlp; lenSum = lenOlp = 0; for ( i = 0; i < nodeCounter; i++ ) { node = nodesInSubInOrder[i]; lenSum += contig_array[node].length; index = getIndexInArray ( node ); nodeDistanceInOrder[i] = nodeDistance[index]; } if ( lenSum < 1 ) { return 1; } for ( i = 0; i < nodeCounter - 1; i++ ) { gap = nodeDistanceInOrder[i + 1] - nodeDistanceInOrder[i] - contig_array[nodesInSubInOrder[i + 1]].length; if ( -gap > 0 ) { lenOlp += -gap; } if ( ( double ) lenOlp / lenSum > tolerance ) { return 0; } } return 1; } /********* the following codes are for freezing current scaffolds ****************/ /************************************************* Function: setUsed Description: Checks status of connection between contigs. If none of them equals to "flag", sets all status to "flag" and adjusts the related indicators accordingly. Otherwise does NOT change the status at all. Input: 1. start: the first contig 2. array: contig array 3. max_steps: max number of connection to check 4. flag: new status Output: None. Return: o if setting successed. *************************************************/ static boolean setUsed ( unsigned int start, unsigned int * array, int max_steps, boolean flag ) { unsigned int prevCtg = start; unsigned int twinA, twinB; int j; CONNECT * cnt; boolean usedFlag = 0; // save 'used' to 'checking' prevCtg = start; for ( j = 0; j < max_steps; j++ ) { if ( array[j] == 0 ) { break; } cnt = getCntBetween ( prevCtg, array[j] ); if ( !cnt ) { fprintf ( stderr, "setUsed: no connect between %d and %d\n", prevCtg, array[j] ); prevCtg = array[j]; continue; } if ( cnt->used == flag || cnt->nextInScaf || cnt->prevInScaf || cnt->singleInScaf ) { return 1; } cnt->checking = cnt->used; twinA = getTwinCtg ( prevCtg ); twinB = getTwinCtg ( array[j] ); cnt = getCntBetween ( twinB, twinA ); if ( cnt ) { cnt->checking = cnt->used; } prevCtg = array[j]; } // set used to flag prevCtg = start; for ( j = 0; j < max_steps; j++ ) { if ( array[j] == 0 ) { break; } cnt = getCntBetween ( prevCtg, array[j] ); if ( !cnt ) { prevCtg = array[j]; continue; } if ( cnt->used == flag ) { usedFlag = 1; break; } cnt->used = flag; twinA = getTwinCtg ( prevCtg ); twinB = getTwinCtg ( array[j] ); cnt = getCntBetween ( twinB, twinA ); if ( cnt ) { cnt->used = flag; } prevCtg = array[j]; } // set mask to 'NOT flag' or set used to original value prevCtg = start; for ( j = 0; j < max_steps; j++ ) { if ( array[j] == 0 ) { break; } cnt = getCntBetween ( prevCtg, array[j] ); if ( !cnt ) { prevCtg = array[j]; continue; } if ( !usedFlag ) { cnt->mask = 1 - flag; } else { cnt->used = cnt->checking; } twinA = getTwinCtg ( prevCtg ); twinB = getTwinCtg ( array[j] ); cnt = getCntBetween ( twinB, twinA ); cnt->used = 1 - flag; if ( !usedFlag ) { cnt->mask = 1 - flag; } else { cnt->used = cnt->checking; } prevCtg = array[j]; } return usedFlag; } /************************************************* Function: score_pass Description: Checks whether a contig is supposed to locate in a scaffold according to its connections to other contigs in this scaffold. Input: 1. array: array of contigs of part of or whole scaffold 2. Counter: contig number in array 3. beforep: index of previous contig 4. afterp: index of next contig 5. id: current contig Output: None. Return: 1 if this contig had enough support from other contigs. *************************************************/ int score_pass ( DARRAY * array, int Counter, int beforep, int afterp, int id ) { int outnum = allConnect ( id, NULL ); int innum = allConnect ( getTwinCtg ( id ), NULL ); int start = beforep - 2 * innum > 0 ? beforep - 2 * innum : 0; int end = afterp + 2 * outnum < Counter ? afterp + 2 * outnum : Counter; int i, inc = 1, outc = 1; CONNECT * dh_cnt; for ( i = start; i < end; i++ ) { if ( i < beforep ) { dh_cnt = getCntBetween ( * ( unsigned int * ) darrayGet ( array, i ), id ); if ( dh_cnt ) { inc++; } } if ( i > afterp ) { dh_cnt = getCntBetween ( id, * ( unsigned int * ) darrayGet ( array, i ) ); if ( dh_cnt ) { outc++; } } } if ( inc == innum || outc == outnum ) { return 1; } if ( ( inc == 1 && innum > 2 ) || ( outc == 1 && outnum > 2 ) ) { return 0; } int score = ( int ) ( ( ( double ) ( inc * outc ) / ( double ) ( innum * outnum ) ) * 100 ); if ( score > 30 ) { return 1; } return 0; } /************************************************* Function: recoverMask Description: Searchs a contig path between two contigs accroding to connection relation. If a path is found, recovers those masked connection between contigs in this path. A ------ D > [i] < B E Input: None. Output: None. Return: None. *************************************************/ static void recoverMask() { unsigned int i, ctg, bal_ctg, start, finish; int num3, num5, j, t; CONNECT * bindCnt, *cnt; int min, max, max_steps = 5, num_route, length; int tempCounter, recoverCounter = 0; boolean multiUSE, change; int stat[] = {0, 0, 0, 0, 0, 0, 0}; for ( i = 1; i <= num_ctg; i++ ) { contig_array[i].flag = 0; } so_far = ( unsigned int * ) ckalloc ( max_n_routes * sizeof ( unsigned int ) ); found_routes = ( unsigned int ** ) ckalloc ( max_n_routes * sizeof ( unsigned int * ) ); for ( j = 0; j < max_n_routes; j++ ) { found_routes[j] = ( unsigned int * ) ckalloc ( max_steps * sizeof ( unsigned int ) ); } for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].flag || contig_array[i].mask || !contig_array[i].downwardConnect ) { continue; } bindCnt = getBindCnt ( i ); if ( !bindCnt ) { continue; } //first scan get the average coverage by longer pe num5 = num3 = 0; ctg = i; * ( unsigned int * ) darrayPut ( scaf5, num5++ ) = i; contig_array[i].flag = 1; contig_array[getTwinCtg ( i )].flag = 1; while ( bindCnt ) { if ( bindCnt->used ) { break; } setConnectUsed ( ctg, bindCnt->contigID, 1 ); ctg = bindCnt->contigID; * ( unsigned int * ) darrayPut ( scaf5, num5++ ) = ctg; bal_ctg = getTwinCtg ( ctg ); contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; bindCnt = bindCnt->nextInScaf; } ctg = getTwinCtg ( i ); bindCnt = getBindCnt ( ctg ); while ( bindCnt ) { if ( bindCnt->used ) { break; } setConnectUsed ( ctg, bindCnt->contigID, 1 ); ctg = bindCnt->contigID; bal_ctg = getTwinCtg ( ctg ); contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; * ( unsigned int * ) darrayPut ( scaf3, num3++ ) = bal_ctg; bindCnt = bindCnt->nextInScaf; } if ( num5 + num3 < 2 ) { continue; } tempCounter = solidCounter = 0; for ( j = num3 - 1; j >= 0; j-- ) * ( unsigned int * ) darrayPut ( tempArray, tempCounter++ ) = * ( unsigned int * ) darrayGet ( scaf3, j ); for ( j = 0; j < num5; j++ ) * ( unsigned int * ) darrayPut ( tempArray, tempCounter++ ) = * ( unsigned int * ) darrayGet ( scaf5, j ); change = 0; for ( t = 0; t < tempCounter - 1; t++ ) { * ( unsigned int * ) darrayPut ( solidArray, solidCounter++ ) = * ( unsigned int * ) darrayGet ( tempArray, t ); start = * ( unsigned int * ) darrayGet ( tempArray, t ); finish = * ( unsigned int * ) darrayGet ( tempArray, t + 1 ); num_route = num_trace = 0; cnt = checkConnect ( start, finish ); if ( !cnt ) { fprintf ( stderr, "Warning from recoverMask: no connection (%d %d), start at %d\n", start, finish, i ); cnt = getCntBetween ( start, finish ); if ( cnt ) { debugging1 ( start, finish ); } continue; } length = cnt->gapLen + contig_array[finish].length; min = length - 1.5 * ins_size_var; max = length + 1.5 * ins_size_var; traceAlongMaskedCnt ( finish, start, max_steps, min, max, 0, 0, &num_route ); if ( finish == start ) { for ( j = 0; j < tempCounter; j++ ) { fprintf ( stderr, "->%d", * ( unsigned int * ) darrayGet ( tempArray, j ) ); } fprintf ( stderr, ": start at %d\n", i ); } if ( num_route == 1 ) { for ( j = 0; j < max_steps; j++ ) if ( found_routes[0][j] == 0 ) { break; } if ( j < 1 ) { continue; } //check if connects have been used more than once multiUSE = setUsed ( start, found_routes[0], max_steps, 1 ); if ( multiUSE ) { continue; } for ( j = 0; j < max_steps; j++ ) { if ( j + 1 == max_steps || found_routes[0][j + 1] == 0 ) { break; } * ( unsigned int * ) darrayPut ( solidArray, solidCounter++ ) = found_routes[0][j]; contig_array[found_routes[0][j]].flag = 1; contig_array[getTwinCtg ( found_routes[0][j] )].flag = 1; } recoverCounter += j; setConnectDelete ( start, finish, 1, 1 ); change = 1; stat[0]++; } //end if num_route=1 else if ( num_route > 1 ) { //multi-route. int k, l, num, longest = 0, longestid = 0; int merg = 0, quality = 0; // get the longest route. for ( k = 0; k < num_route; k++ ) { for ( j = 0; j < max_steps; j++ ) { if ( j + 1 == max_steps || found_routes[k][j + 1] == 0 ) { if ( j > longest ) { longest = j; longestid = k; } break; } } } stat[1]++; if ( longest == 1 ) //multi one. { stat[2]++; for ( k = 0; k < num_route; k++ ) { if ( score_pass ( tempArray, tempCounter, t, t + 1, found_routes[k][0] ) ) { longestid = k; quality = 1; stat[3]++; break; } } if ( quality == 0 ) { continue; } } else { stat[4]++; for ( k = 0; k < num_route; k++ ) { if ( k == longestid ) { continue; } int merg_num = 0, total = 0; for ( j = 0; j < max_steps; j++ ) { if ( j + 1 == max_steps || found_routes[k][j + 1] == 0 ) { total = j; break; } for ( l = 0; l < longest; l++ ) { if ( found_routes[k][j] == found_routes[longestid][l] ) { merg_num++; break; } } } if ( merg_num == total ) { merg++; } } } if ( merg == num_route - 1 || quality == 1 || merg >= longest ) { multiUSE = setUsed ( start, found_routes[longestid], max_steps, 1 ); if ( multiUSE ) { continue; } stat[5]++; for ( j = 0; j < longest; j++ ) { * ( unsigned int * ) darrayPut ( solidArray, solidCounter++ ) = found_routes[longestid][j]; contig_array[found_routes[longestid][j]].flag = 1; contig_array[getTwinCtg ( found_routes[longestid][j] )].flag = 1; } stat[6] += j; recoverCounter += j; setConnectDelete ( start, finish, 1, 1 ); change = 1; } } } * ( unsigned int * ) darrayPut ( solidArray, solidCounter++ ) = * ( unsigned int * ) darrayGet ( tempArray, tempCounter - 1 ); if ( change ) { consolidate(); } } fprintf ( stderr, "\nRecover contigs.\n" ); fprintf ( stderr, " Total recovered contigs %d\n", recoverCounter ); fprintf ( stderr, " Single-route cases %d\n", stat[0] ); fprintf ( stderr, " Multi-route cases %d\n", stat[1] ); for ( i = 1; i <= num_ctg; i++ ) { cnt = contig_array[i].downwardConnect; while ( cnt ) { cnt->used = 0; cnt->checking = 0; cnt = cnt->next; } } for ( j = 0; j < max_n_routes; j++ ) { free ( ( void * ) found_routes[j] ); } free ( ( void * ) found_routes ); free ( ( void * ) so_far ); } /************************************************* Function: unBindLink Description: Destroys upstream and downstram connections of connection between two specified contigs. Input: 1. CB: the first specified contig 2. CC: the second specified contig Output: None. Return: None. *************************************************/ static void unBindLink ( unsigned int CB, unsigned int CC ) { CONNECT * cnt1 = getCntBetween ( CB, CC ); if ( !cnt1 ) { return; } if ( cnt1->singleInScaf ) { cnt1->singleInScaf = 0; } CONNECT * cnt2 = getCntBetween ( getTwinCtg ( CC ), getTwinCtg ( CB ) ); if ( !cnt2 ) { return; } if ( cnt2->singleInScaf ) { cnt2->singleInScaf = 0; } if ( cnt1->nextInScaf ) { unsigned int CD = cnt1->nextInScaf->contigID; cnt1->nextInScaf->prevInScaf = 0; cnt1->nextInScaf = NULL; CONNECT * cnt3 = getCntBetween ( getTwinCtg ( CD ), getTwinCtg ( CC ) ); if ( cnt3 ) { cnt3->nextInScaf = NULL; } cnt2->prevInScaf = 0; } if ( cnt2->nextInScaf ) { unsigned int bal_CA = cnt2->nextInScaf->contigID; cnt2->nextInScaf->prevInScaf = 0; cnt2->nextInScaf = NULL; CONNECT * cnt4 = getCntBetween ( getTwinCtg ( bal_CA ), CB ); if ( cnt4 ) { cnt4->nextInScaf = NULL; } cnt1->prevInScaf = 0; } } /************************************************* Function: freezing Description: Updates connection relation and scaffold ID of contigs in a scaffold. Input: None. Output: None. Return: None. *************************************************/ static void freezing() { int num5, num3; unsigned int ctg, bal_ctg; unsigned int i; int j, t; CONNECT * cnt, *prevCNT, *nextCnt; boolean excep; for ( i = 1; i <= num_ctg; i++ ) { contig_array[i].flag = 0; contig_array[i].from_vt = 0; contig_array[i].to_vt = 0; cnt = contig_array[i].downwardConnect; while ( cnt ) { cnt->used = 0; cnt->checking = 0; cnt->singleInScaf = 0; cnt = cnt->next; } } for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].flag || contig_array[i].mask ) { continue; } if ( !contig_array[i].downwardConnect || !validConnect ( i, NULL ) ) { continue; } num5 = num3 = 0; ctg = i; * ( unsigned int * ) darrayPut ( scaf5, num5++ ) = i; contig_array[i].flag = 1; contig_array[getTwinCtg ( i )].flag = 1; prevCNT = NULL; cnt = getNextContig ( ctg, prevCNT, &excep ); while ( cnt ) { if ( contig_array[cnt->contigID].flag ) { unBindLink ( ctg, cnt->contigID ); break; } nextCnt = getNextContig ( cnt->contigID, cnt, &excep ); setConnectUsed ( ctg, cnt->contigID, 1 ); ctg = cnt->contigID; * ( unsigned int * ) darrayPut ( scaf5, num5++ ) = ctg; bal_ctg = getTwinCtg ( ctg ); contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; prevCNT = cnt; cnt = nextCnt; } ctg = getTwinCtg ( i ); if ( num5 >= 2 ) { prevCNT = checkConnect ( getTwinCtg ( * ( unsigned int * ) darrayGet ( scaf5, 1 ) ), ctg ); } else { prevCNT = NULL; } cnt = getNextContig ( ctg, prevCNT, &excep ); while ( cnt ) { if ( contig_array[cnt->contigID].flag ) { unBindLink ( ctg, cnt->contigID ); break; } nextCnt = getNextContig ( cnt->contigID, cnt, &excep ); setConnectUsed ( ctg, cnt->contigID, 1 ); ctg = cnt->contigID; bal_ctg = getTwinCtg ( ctg ); contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; * ( unsigned int * ) darrayPut ( scaf3, num3++ ) = bal_ctg; prevCNT = cnt; cnt = nextCnt; } if ( num5 + num3 < 2 ) { continue; } solidCounter = 0; for ( j = num3 - 1; j >= 0; j-- ) * ( unsigned int * ) darrayPut ( solidArray, solidCounter++ ) = * ( unsigned int * ) darrayGet ( scaf3, j ); for ( j = 0; j < num5; j++ ) * ( unsigned int * ) darrayPut ( solidArray, solidCounter++ ) = * ( unsigned int * ) darrayGet ( scaf5, j ); unsigned int firstCtg = 0; unsigned int lastCtg = 0; unsigned int firstTwin = 0; unsigned int lastTwin = 0; for ( t = 0; t < solidCounter; t++ ) if ( !contig_array[* ( unsigned int * ) darrayGet ( solidArray, t )].mask ) { firstCtg = * ( unsigned int * ) darrayGet ( solidArray, t ); break; } for ( t = solidCounter - 1; t >= 0; t-- ) if ( !contig_array[* ( unsigned int * ) darrayGet ( solidArray, t )].mask ) { lastCtg = * ( unsigned int * ) darrayGet ( solidArray, t ); break; } if ( firstCtg == 0 || lastCtg == 0 ) { fprintf ( stderr, "scaffold start at %d, stop at %d, freezing began with %d\n", firstCtg, lastCtg, i ); for ( j = 0; j < solidCounter; j++ ) fprintf ( stderr, "->%d(%d %d)", * ( unsigned int * ) darrayGet ( solidArray, j ) , contig_array[* ( unsigned int * ) darrayGet ( solidArray, j )].mask , contig_array[* ( unsigned int * ) darrayGet ( solidArray, j )].flag ); fprintf ( stderr, "\n" ); } else { firstTwin = getTwinCtg ( firstCtg ); lastTwin = getTwinCtg ( lastCtg ); } for ( t = 0; t < solidCounter; t++ ) { unsigned int ctg = * ( unsigned int * ) darrayGet ( solidArray, t ); if ( contig_array[ctg].from_vt > 0 ) { contig_array[ctg].mask = 1; contig_array[getTwinCtg ( ctg )].mask = 1; fprintf ( stderr, "Repeat: contig %d (%d) appears more than once\n", ctg, getTwinCtg ( ctg ) ); } else { contig_array[ctg].from_vt = firstCtg; contig_array[ctg].to_vt = lastCtg; contig_array[ctg].indexInScaf = t + 1; contig_array[getTwinCtg ( ctg )].from_vt = lastTwin; contig_array[getTwinCtg ( ctg )].to_vt = firstTwin; contig_array[getTwinCtg ( ctg )].indexInScaf = solidCounter - t; } } consolidate(); } fprintf ( stderr, "Freezing done.\n" ); fflush ( stdout ); for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].flag ) { contig_array[i].flag = 0; } if ( contig_array[i].from_vt == 0 ) { contig_array[i].from_vt = i; contig_array[i].to_vt = i; } cnt = contig_array[i].downwardConnect; while ( cnt ) { cnt->used = 0; cnt->checking = 0; cnt = cnt->next; } } } /************** codes below this line are for pulling the scaffolds out ************/ /************************************************* Function: output1gap Description: Outputs information of a filled gap. Input: 1. fo: output file 2. max_steps: maximum allowed found contigs for filling gap Output: None. Return: None. *************************************************/ void output1gap ( FILE * fo, int max_steps ) { int i, len, seg; len = seg = 0; for ( i = 0; i < max_steps - 1; i++ ) { if ( found_routes[0][i + 1] == 0 ) { break; } len += contig_array[found_routes[0][i]].length; seg++; } fprintf ( fo, "GAP %d %d", len, seg ); for ( i = 0; i < max_steps - 1; i++ ) { if ( found_routes[0][i + 1] == 0 ) { break; } fprintf ( fo, " %d", found_routes[0][i] ); } fprintf ( fo, "\n" ); } static int weakCounter; /************************************************* Function: printCnts Description: Outputs connection information of specified contig. Input: 1. fp: output file 2. ctg: specified contig Output: None. Return: 0 if contig's downstream connection was not weak connection. *************************************************/ static boolean printCnts ( FILE * fp, unsigned int ctg ) { CONNECT * cnt = contig_array[ctg].downwardConnect; boolean flag = 0, ret = 0; unsigned int bal_ctg = getTwinCtg ( ctg ); unsigned int linkCtg; if ( isSameAsTwin ( ctg ) ) { return ret; } CONNECT * bindCnt = getBindCnt ( ctg ); if ( bindCnt && bindCnt->bySmall && bindCnt->weakPoint ) { weakCounter++; fprintf ( fp, "\tWP" ); ret = 1; } while ( cnt ) { if ( cnt->weight && !cnt->inherit ) { if ( !flag ) { flag = 1; fprintf ( fp, "\t#DOWN " ); } linkCtg = cnt->contigID; if ( isLargerThanTwin ( linkCtg ) ) { linkCtg = getTwinCtg ( linkCtg ); } fprintf ( fp, "%d:%d:%d ", index_array[linkCtg], cnt->weight, cnt->gapLen ); } cnt = cnt->next; } flag = 0; cnt = contig_array[bal_ctg].downwardConnect; while ( cnt ) { if ( cnt->weight && !cnt->inherit ) { if ( !flag ) { flag = 1; fprintf ( fp, "\t#UP " ); } linkCtg = cnt->contigID; if ( isLargerThanTwin ( linkCtg ) ) { linkCtg = getTwinCtg ( linkCtg ); } fprintf ( fp, "%d:%d:%d ", index_array[linkCtg], cnt->weight, cnt->gapLen ); } cnt = cnt->next; } fprintf ( fp, "\n" ); return ret; } /************************************************* Function: ScafStat Description: Makes statistic of scaffolds and contigs, including total length, non-N length, number, N50, etc. Input: 1. len_cut: length cutoff 2. graphfile: prefix of graph Output: None. Return: None. *************************************************/ void ScafStat ( int len_cut, char * graphfile ) { FILE * fp, *fp2, *fo; char line[1024]; sprintf ( line, "%s.scafSeq", graphfile ); fp = ckopen ( line, "r" ); sprintf ( line, "%s.contig", graphfile ); fp2 = ckopen ( line, "r" ); sprintf ( line, "%s.scafStatistics", graphfile ); fo = ckopen ( line, "w" ); fprintf ( fo, "<-- Information for assembly Scaffold '%s.scafSeq'.(cut_off_length < 100bp) -->\n\n", graphfile ); int cut_off_len = 0; char Nucleotide; char buf[4000]; long Scaffold_Number = 0; long Scaffold_Number_Scaf = 0; long Scaffold_Number_Contig = 0; long Singleton_Number_Scaf = 0; long Singleton_Number = 0; long * Singleton_Seq = ( long * ) malloc ( sizeof ( long ) ); long long A_num_all = 0; long * A_num = ( long * ) malloc ( sizeof ( long ) ); long long C_num_all = 0; long * C_num = ( long * ) malloc ( sizeof ( long ) ); long long G_num_all = 0; long * G_num = ( long * ) malloc ( sizeof ( long ) ); long long T_num_all = 0; long * T_num = ( long * ) malloc ( sizeof ( long ) ); long long N_num_all = 0; long * N_num = ( long * ) malloc ( sizeof ( long ) ); long long Non_ACGTN_all = 0; long * Non_ACGTN = ( long * ) malloc ( sizeof ( long ) ); long long Size_includeN = 0; long * Size_Seq = ( long * ) malloc ( sizeof ( long ) ); int k; long long Sum = 0; int flag[10]; int flag_known = 0; long n100 = 0; long n500 = 0; long n1k = 0; long n10k = 0; long n100k = 0; long n1m = 0; long N50 = 0; long N50_known = 0; long Num_N50_known = 0; cut_off_len = len_cut; A_num[Scaffold_Number] = 0; C_num[Scaffold_Number] = 0; G_num[Scaffold_Number] = 0; T_num[Scaffold_Number] = 0; N_num[Scaffold_Number] = 0; Non_ACGTN[Scaffold_Number] = 0; Size_Seq[Scaffold_Number] = 0; Singleton_Seq[Scaffold_Number] = 0; Nucleotide = fgetc ( fp ); while ( Nucleotide != EOF ) { if ( Nucleotide == '>' ) { if ( ( Scaffold_Number > 0 ) && ( Size_Seq[Scaffold_Number - 1] < cut_off_len ) ) { A_num_all = A_num_all - A_num[Scaffold_Number - 1]; C_num_all = C_num_all - C_num[Scaffold_Number - 1]; G_num_all = G_num_all - G_num[Scaffold_Number - 1]; T_num_all = T_num_all - T_num[Scaffold_Number - 1]; N_num_all = N_num_all - N_num[Scaffold_Number - 1]; Non_ACGTN_all = Non_ACGTN_all - Non_ACGTN[Scaffold_Number - 1]; Size_includeN = Size_includeN - Size_Seq[Scaffold_Number - 1]; Singleton_Number = Singleton_Number - Singleton_Seq[Scaffold_Number - 1]; Scaffold_Number = Scaffold_Number - 1; } else { Size_Seq = ( long * ) realloc ( Size_Seq, ( Scaffold_Number + 2 ) * sizeof ( long ) ); A_num = ( long * ) realloc ( A_num, ( Scaffold_Number + 2 ) * sizeof ( long ) ); C_num = ( long * ) realloc ( C_num, ( Scaffold_Number + 2 ) * sizeof ( long ) ); G_num = ( long * ) realloc ( G_num, ( Scaffold_Number + 2 ) * sizeof ( long ) ); T_num = ( long * ) realloc ( T_num, ( Scaffold_Number + 2 ) * sizeof ( long ) ); N_num = ( long * ) realloc ( N_num, ( Scaffold_Number + 2 ) * sizeof ( long ) ); Non_ACGTN = ( long * ) realloc ( Non_ACGTN, ( Scaffold_Number + 2 ) * sizeof ( long ) ); Singleton_Seq = ( long * ) realloc ( Singleton_Seq, ( Scaffold_Number + 2 ) * sizeof ( long ) ); } Scaffold_Number++; A_num[Scaffold_Number - 1] = 0; C_num[Scaffold_Number - 1] = 0; G_num[Scaffold_Number - 1] = 0; T_num[Scaffold_Number - 1] = 0; N_num[Scaffold_Number - 1] = 0; Non_ACGTN[Scaffold_Number - 1] = 0; Size_Seq[Scaffold_Number - 1] = 0; Singleton_Seq[Scaffold_Number - 1] = 0; Nucleotide = fgetc ( fp ); if ( Nucleotide == 'C' ) { Singleton_Number++; Singleton_Seq[Scaffold_Number - 1] ++; } fgets ( buf, 4000, fp ); } else if ( ( Nucleotide == 'N' ) || ( Nucleotide == 'n' ) ) { N_num[Scaffold_Number - 1] ++; N_num_all++; Size_Seq[Scaffold_Number - 1] ++; Size_includeN++; } else if ( ( Nucleotide == 'A' ) || ( Nucleotide == 'a' ) ) { A_num[Scaffold_Number - 1] ++; A_num_all++; Size_Seq[Scaffold_Number - 1] ++; Size_includeN++; } else if ( ( Nucleotide == 'C' ) || ( Nucleotide == 'c' ) ) { C_num[Scaffold_Number - 1] ++; C_num_all++; Size_Seq[Scaffold_Number - 1] ++; Size_includeN++; } else if ( ( Nucleotide == 'G' ) || ( Nucleotide == 'g' ) ) { G_num[Scaffold_Number - 1] ++; G_num_all++; Size_Seq[Scaffold_Number - 1] ++; Size_includeN++; } else if ( ( Nucleotide == 'T' ) || ( Nucleotide == 't' ) ) { T_num[Scaffold_Number - 1] ++; T_num_all++; Size_Seq[Scaffold_Number - 1] ++; Size_includeN++; } else { if ( ( Nucleotide != '\n' ) && ( Nucleotide != '\r' ) ) { Non_ACGTN[Scaffold_Number - 1] ++; Non_ACGTN_all++; Size_Seq[Scaffold_Number - 1] ++; Size_includeN++; } } Nucleotide = fgetc ( fp ); } if ( Size_Seq[Scaffold_Number - 1] < cut_off_len ) { A_num_all = A_num_all - A_num[Scaffold_Number - 1]; C_num_all = C_num_all - C_num[Scaffold_Number - 1]; G_num_all = G_num_all - G_num[Scaffold_Number - 1]; T_num_all = T_num_all - T_num[Scaffold_Number - 1]; N_num_all = N_num_all - N_num[Scaffold_Number - 1]; Non_ACGTN_all = Non_ACGTN_all - Non_ACGTN[Scaffold_Number - 1]; Size_includeN = Size_includeN - Size_Seq[Scaffold_Number - 1]; Singleton_Number = Singleton_Number - Singleton_Seq[Scaffold_Number - 1]; Scaffold_Number = Scaffold_Number - 1; } qsort ( Size_Seq, Scaffold_Number, sizeof ( Size_Seq[0] ), cmp_int ); fprintf ( fo, "Size_includeN\t%lld\n", Size_includeN ); fprintf ( fo, "Size_withoutN\t%lld\n", Size_includeN - N_num_all ); fprintf ( fo, "Scaffold_Num\t%ld\n", Scaffold_Number ); fprintf ( fo, "Mean_Size\t%lld\n", Size_includeN / Scaffold_Number ); fprintf ( fo, "Median_Size\t%ld\n", Size_Seq[ ( Scaffold_Number + 1 ) / 2 - 1] ); fprintf ( fo, "Longest_Seq\t%ld\n", Size_Seq[Scaffold_Number - 1] ); fprintf ( fo, "Shortest_Seq\t%ld\n", Size_Seq[0] ); fprintf ( fo, "Singleton_Num\t%ld\n", Singleton_Number ); fprintf ( fo, "Average_length_of_break(N)_in_scaffold\t%lld\n", N_num_all / Scaffold_Number ); fprintf ( fo, "\n" ); if ( known_genome_size ) { fprintf ( fo, "Known_genome_size\t%ld\n", known_genome_size ); fprintf ( fo, "Total_scaffold_length_as_percentage_of_known_genome_size\t%.2f%\n", 100 * ( 1.0 * Size_includeN / known_genome_size ) ); } else { fprintf ( fo, "Known_genome_size\tNaN\n" ); fprintf ( fo, "Total_scaffold_length_as_percentage_of_known_genome_size\tNaN\n" ); } fprintf ( fo, "\n" ); for ( k = 0; k < Scaffold_Number; k++ ) { if ( Size_Seq[k] > 100 ) { n100++; } if ( Size_Seq[k] > 500 ) { n500++; } if ( Size_Seq[k] > 1000 ) { n1k++; } if ( Size_Seq[k] > 10000 ) { n10k++; } if ( Size_Seq[k] > 100000 ) { n100k++; } if ( Size_Seq[k] > 1000000 ) { n1m++; } } fprintf ( fo, "scaffolds>100 \t%ld\t%.2f%\n", n100 , 100 * ( 1.0 * n100 / Scaffold_Number ) ); fprintf ( fo, "scaffolds>500 \t%ld\t%.2f%\n", n500 , 100 * ( 1.0 * n500 / Scaffold_Number ) ); fprintf ( fo, "scaffolds>1K \t%ld\t%.2f%\n", n1k , 100 * ( 1.0 * n1k / Scaffold_Number ) ); fprintf ( fo, "scaffolds>10K \t%ld\t%.2f%\n", n10k , 100 * ( 1.0 * n10k / Scaffold_Number ) ); fprintf ( fo, "scaffolds>100K\t%ld\t%.2f%\n", n100k, 100 * ( 1.0 * n100k / Scaffold_Number ) ); fprintf ( fo, "scaffolds>1M \t%ld\t%.2f%\n", n1m , 100 * ( 1.0 * n1m / Scaffold_Number ) ); fprintf ( fo, "\n" ); fprintf ( fo, "Nucleotide_A\t%lld\t%.2f%\n", A_num_all, 100 * ( 1.0 * A_num_all / Size_includeN ) ); fprintf ( fo, "Nucleotide_C\t%lld\t%.2f%\n", C_num_all, 100 * ( 1.0 * C_num_all / Size_includeN ) ); fprintf ( fo, "Nucleotide_G\t%lld\t%.2f%\n", G_num_all, 100 * ( 1.0 * G_num_all / Size_includeN ) ); fprintf ( fo, "Nucleotide_T\t%lld\t%.2f%\n", T_num_all, 100 * ( 1.0 * T_num_all / Size_includeN ) ); fprintf ( fo, "GapContent_N\t%lld\t%.2f%\n", N_num_all, 100 * ( 1.0 * N_num_all / Size_includeN ) ); fprintf ( fo, "Non_ACGTN\t%lld\t%.2f%\n", Non_ACGTN_all, 100 * ( 1.0 * Non_ACGTN_all / Size_includeN ) ); fprintf ( fo, "GC_Content\t%.2f%\t\t(G+C)/(A+C+G+T)\n", 100 * ( 1.0 * ( G_num_all + C_num_all ) / ( A_num_all + C_num_all + G_num_all + T_num_all ) ) ); fprintf ( fo, "\n" ); for ( k = 0; k < 10; k++ ) { flag[k] = 0; } for ( k = Scaffold_Number - 1; k >= 0; k-- ) { Sum = Sum + Size_Seq[k]; if ( ( Sum >= Size_includeN * 0.1 ) && ( Sum < Size_includeN * 0.2 ) && ( flag[1] == 0 ) ) { fprintf ( fo, "N10\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[1] = 1; } else if ( ( Sum >= Size_includeN * 0.2 ) && ( Sum < Size_includeN * 0.3 ) && ( flag[2] == 0 ) ) { fprintf ( fo, "N20\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[2] = 1; } else if ( ( Sum >= Size_includeN * 0.3 ) && ( Sum < Size_includeN * 0.4 ) && ( flag[3] == 0 ) ) { fprintf ( fo, "N30\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[3] = 1; } else if ( ( Sum >= Size_includeN * 0.4 ) && ( Sum < Size_includeN * 0.5 ) && ( flag[4] == 0 ) ) { fprintf ( fo, "N40\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[4] = 1; } else if ( ( Sum >= Size_includeN * 0.5 ) && ( Sum < Size_includeN * 0.6 ) && ( flag[5] == 0 ) ) { fprintf ( fo, "N50\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[5] = 1; N50 = Size_Seq[k]; } else if ( ( Sum >= Size_includeN * 0.6 ) && ( Sum < Size_includeN * 0.7 ) && ( flag[6] == 0 ) ) { fprintf ( fo, "N60\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[6] = 1; } else if ( ( Sum >= Size_includeN * 0.7 ) && ( Sum < Size_includeN * 0.8 ) && ( flag[7] == 0 ) ) { fprintf ( fo, "N70\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[7] = 1; } else if ( ( Sum >= Size_includeN * 0.8 ) && ( Sum < Size_includeN * 0.9 ) && ( flag[8] == 0 ) ) { fprintf ( fo, "N80\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[8] = 1; } else if ( ( Sum >= Size_includeN * 0.9 ) && ( flag[9] == 0 ) ) { fprintf ( fo, "N90\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[9] = 1; } if ( ( Sum >= known_genome_size * 0.5 ) && ( flag_known == 0 ) ) { N50_known = Size_Seq[k]; Num_N50_known = Scaffold_Number - k; flag_known = 1; } } if ( flag[5] == 0 ) { Sum = 0; for ( k = Scaffold_Number - 1; k >= 0; k-- ) { Sum = Sum + Size_Seq[k]; if ( Sum >= Size_includeN * 0.5 ) { fprintf ( fo, "N50\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); break; } } } fprintf ( fo, "\n" ); if ( known_genome_size ) { fprintf ( fo, "NG50\t%ld\t%ld\n", N50_known, Num_N50_known ); fprintf ( fo, "N50_scaffold-NG50_scaffold_length_difference\t%ld\n", abs ( N50 - N50_known ) ); } else { fprintf ( fo, "NG50\tNaN\tNaN\n" ); fprintf ( fo, "N50_scaffold-NG50_scaffold_length_difference\tNaN\n" ); } fprintf ( fo, "\n" ); free ( A_num ); free ( C_num ); free ( G_num ); free ( T_num ); free ( N_num ); free ( Non_ACGTN ); free ( Singleton_Seq ); free ( Size_Seq ); Scaffold_Number_Scaf = Scaffold_Number; Singleton_Number_Scaf = Singleton_Number; /*********************** Contig ******************************/ fprintf ( fo, "<-- Information for assembly Contig '%s.contig'.(cut_off_length < 100bp) -->\n\n", graphfile ); cut_off_len = 0; Scaffold_Number = 0; Singleton_Number = 0; Singleton_Seq = ( long * ) malloc ( sizeof ( long ) ); A_num_all = 0; A_num = ( long * ) malloc ( sizeof ( long ) ); C_num_all = 0; C_num = ( long * ) malloc ( sizeof ( long ) ); G_num_all = 0; G_num = ( long * ) malloc ( sizeof ( long ) ); T_num_all = 0; T_num = ( long * ) malloc ( sizeof ( long ) ); N_num_all = 0; N_num = ( long * ) malloc ( sizeof ( long ) ); Non_ACGTN_all = 0; Non_ACGTN = ( long * ) malloc ( sizeof ( long ) ); Size_includeN = 0; Size_Seq = ( long * ) malloc ( sizeof ( long ) ); Sum = 0; n100 = 0; n500 = 0; n1k = 0; n10k = 0; n100k = 0; n1m = 0; N50 = 0; N50_known = 0; Num_N50_known = 0; flag_known = 0; cut_off_len = len_cut; A_num[Scaffold_Number] = 0; C_num[Scaffold_Number] = 0; G_num[Scaffold_Number] = 0; T_num[Scaffold_Number] = 0; N_num[Scaffold_Number] = 0; Non_ACGTN[Scaffold_Number] = 0; Size_Seq[Scaffold_Number] = 0; Singleton_Seq[Scaffold_Number] = 0; Nucleotide = fgetc ( fp2 ); while ( Nucleotide != EOF ) { if ( Nucleotide == '>' ) { if ( ( Scaffold_Number > 0 ) && ( Size_Seq[Scaffold_Number - 1] < cut_off_len ) ) { A_num_all = A_num_all - A_num[Scaffold_Number - 1]; C_num_all = C_num_all - C_num[Scaffold_Number - 1]; G_num_all = G_num_all - G_num[Scaffold_Number - 1]; T_num_all = T_num_all - T_num[Scaffold_Number - 1]; N_num_all = N_num_all - N_num[Scaffold_Number - 1]; Non_ACGTN_all = Non_ACGTN_all - Non_ACGTN[Scaffold_Number - 1]; Size_includeN = Size_includeN - Size_Seq[Scaffold_Number - 1]; Singleton_Number = Singleton_Number - Singleton_Seq[Scaffold_Number - 1]; Scaffold_Number = Scaffold_Number - 1; } else { Size_Seq = ( long * ) realloc ( Size_Seq, ( Scaffold_Number + 2 ) * sizeof ( long ) ); A_num = ( long * ) realloc ( A_num, ( Scaffold_Number + 2 ) * sizeof ( long ) ); C_num = ( long * ) realloc ( C_num, ( Scaffold_Number + 2 ) * sizeof ( long ) ); G_num = ( long * ) realloc ( G_num, ( Scaffold_Number + 2 ) * sizeof ( long ) ); T_num = ( long * ) realloc ( T_num, ( Scaffold_Number + 2 ) * sizeof ( long ) ); N_num = ( long * ) realloc ( N_num, ( Scaffold_Number + 2 ) * sizeof ( long ) ); Non_ACGTN = ( long * ) realloc ( Non_ACGTN, ( Scaffold_Number + 2 ) * sizeof ( long ) ); Singleton_Seq = ( long * ) realloc ( Singleton_Seq, ( Scaffold_Number + 2 ) * sizeof ( long ) ); } Scaffold_Number++; A_num[Scaffold_Number - 1] = 0; C_num[Scaffold_Number - 1] = 0; G_num[Scaffold_Number - 1] = 0; T_num[Scaffold_Number - 1] = 0; N_num[Scaffold_Number - 1] = 0; Non_ACGTN[Scaffold_Number - 1] = 0; Size_Seq[Scaffold_Number - 1] = 0; Singleton_Seq[Scaffold_Number - 1] = 0; Nucleotide = fgetc ( fp2 ); if ( Nucleotide == 'C' ) { Singleton_Number++; Singleton_Seq[Scaffold_Number - 1] ++; } fgets ( buf, 4000, fp2 ); } else if ( ( Nucleotide == 'N' ) || ( Nucleotide == 'n' ) ) { N_num[Scaffold_Number - 1] ++; N_num_all++; Size_Seq[Scaffold_Number - 1] ++; Size_includeN++; } else if ( ( Nucleotide == 'A' ) || ( Nucleotide == 'a' ) ) { A_num[Scaffold_Number - 1] ++; A_num_all++; Size_Seq[Scaffold_Number - 1] ++; Size_includeN++; } else if ( ( Nucleotide == 'C' ) || ( Nucleotide == 'c' ) ) { C_num[Scaffold_Number - 1] ++; C_num_all++; Size_Seq[Scaffold_Number - 1] ++; Size_includeN++; } else if ( ( Nucleotide == 'G' ) || ( Nucleotide == 'g' ) ) { G_num[Scaffold_Number - 1] ++; G_num_all++; Size_Seq[Scaffold_Number - 1] ++; Size_includeN++; } else if ( ( Nucleotide == 'T' ) || ( Nucleotide == 't' ) ) { T_num[Scaffold_Number - 1] ++; T_num_all++; Size_Seq[Scaffold_Number - 1] ++; Size_includeN++; } else { if ( ( Nucleotide != '\n' ) && ( Nucleotide != '\r' ) ) { Non_ACGTN[Scaffold_Number - 1] ++; Non_ACGTN_all++; Size_Seq[Scaffold_Number - 1] ++; Size_includeN++; } } Nucleotide = fgetc ( fp2 ); } if ( Size_Seq[Scaffold_Number - 1] < cut_off_len ) { A_num_all = A_num_all - A_num[Scaffold_Number - 1]; C_num_all = C_num_all - C_num[Scaffold_Number - 1]; G_num_all = G_num_all - G_num[Scaffold_Number - 1]; T_num_all = T_num_all - T_num[Scaffold_Number - 1]; N_num_all = N_num_all - N_num[Scaffold_Number - 1]; Non_ACGTN_all = Non_ACGTN_all - Non_ACGTN[Scaffold_Number - 1]; Size_includeN = Size_includeN - Size_Seq[Scaffold_Number - 1]; Singleton_Number = Singleton_Number - Singleton_Seq[Scaffold_Number - 1]; Scaffold_Number = Scaffold_Number - 1; } qsort ( Size_Seq, Scaffold_Number, sizeof ( Size_Seq[0] ), cmp_int ); fprintf ( fo, "Size_includeN\t%lld\n", Size_includeN ); fprintf ( fo, "Size_withoutN\t%lld\n", Size_includeN - N_num_all ); fprintf ( fo, "Contig_Num\t%ld\n", Scaffold_Number ); fprintf ( fo, "Mean_Size\t%lld\n", Size_includeN / Scaffold_Number ); fprintf ( fo, "Median_Size\t%ld\n", Size_Seq[ ( Scaffold_Number + 1 ) / 2 - 1] ); fprintf ( fo, "Longest_Seq\t%ld\n", Size_Seq[Scaffold_Number - 1] ); fprintf ( fo, "Shortest_Seq\t%ld\n", Size_Seq[0] ); fprintf ( fo, "\n" ); for ( k = 0; k < Scaffold_Number; k++ ) { if ( Size_Seq[k] > 100 ) { n100++; } if ( Size_Seq[k] > 500 ) { n500++; } if ( Size_Seq[k] > 1000 ) { n1k++; } if ( Size_Seq[k] > 10000 ) { n10k++; } if ( Size_Seq[k] > 100000 ) { n100k++; } if ( Size_Seq[k] > 1000000 ) { n1m++; } } fprintf ( fo, "Contig>100 \t%ld\t%.2f%\n", n100 , 100 * ( 1.0 * n100 / Scaffold_Number ) ); fprintf ( fo, "Contig>500 \t%ld\t%.2f%\n", n500 , 100 * ( 1.0 * n500 / Scaffold_Number ) ); fprintf ( fo, "Contig>1K \t%ld\t%.2f%\n", n1k , 100 * ( 1.0 * n1k / Scaffold_Number ) ); fprintf ( fo, "Contig>10K \t%ld\t%.2f%\n", n10k , 100 * ( 1.0 * n10k / Scaffold_Number ) ); fprintf ( fo, "Contig>100K\t%ld\t%.2f%\n", n100k, 100 * ( 1.0 * n100k / Scaffold_Number ) ); fprintf ( fo, "Contig>1M \t%ld\t%.2f%\n", n1m , 100 * ( 1.0 * n1m / Scaffold_Number ) ); fprintf ( fo, "\n" ); fprintf ( fo, "Nucleotide_A\t%lld\t%.2f%\n", A_num_all, 100 * ( 1.0 * A_num_all / Size_includeN ) ); fprintf ( fo, "Nucleotide_C\t%lld\t%.2f%\n", C_num_all, 100 * ( 1.0 * C_num_all / Size_includeN ) ); fprintf ( fo, "Nucleotide_G\t%lld\t%.2f%\n", G_num_all, 100 * ( 1.0 * G_num_all / Size_includeN ) ); fprintf ( fo, "Nucleotide_T\t%lld\t%.2f%\n", T_num_all, 100 * ( 1.0 * T_num_all / Size_includeN ) ); fprintf ( fo, "GapContent_N\t%lld\t%.2f%\n", N_num_all, 100 * ( 1.0 * N_num_all / Size_includeN ) ); fprintf ( fo, "Non_ACGTN\t%lld\t%.2f%\n", Non_ACGTN_all, 100 * ( 1.0 * Non_ACGTN_all / Size_includeN ) ); fprintf ( fo, "GC_Content\t%.2f%\t\t(G+C)/(A+C+G+T)\n", 100 * ( 1.0 * ( G_num_all + C_num_all ) / ( A_num_all + C_num_all + G_num_all + T_num_all ) ) ); fprintf ( fo, "\n" ); for ( k = 0; k < 10; k++ ) { flag[k] = 0; } for ( k = Scaffold_Number - 1; k >= 0; k-- ) { Sum = Sum + Size_Seq[k]; if ( ( Sum >= Size_includeN * 0.1 ) && ( Sum < Size_includeN * 0.2 ) && ( flag[1] == 0 ) ) { fprintf ( fo, "N10\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[1] = 1; } else if ( ( Sum >= Size_includeN * 0.2 ) && ( Sum < Size_includeN * 0.3 ) && ( flag[2] == 0 ) ) { fprintf ( fo, "N20\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[2] = 1; } else if ( ( Sum >= Size_includeN * 0.3 ) && ( Sum < Size_includeN * 0.4 ) && ( flag[3] == 0 ) ) { fprintf ( fo, "N30\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[3] = 1; } else if ( ( Sum >= Size_includeN * 0.4 ) && ( Sum < Size_includeN * 0.5 ) && ( flag[4] == 0 ) ) { fprintf ( fo, "N40\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[4] = 1; } else if ( ( Sum >= Size_includeN * 0.5 ) && ( Sum < Size_includeN * 0.6 ) && ( flag[5] == 0 ) ) { fprintf ( fo, "N50\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[5] = 1; N50 = Size_Seq[k]; } else if ( ( Sum >= Size_includeN * 0.6 ) && ( Sum < Size_includeN * 0.7 ) && ( flag[6] == 0 ) ) { fprintf ( fo, "N60\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[6] = 1; } else if ( ( Sum >= Size_includeN * 0.7 ) && ( Sum < Size_includeN * 0.8 ) && ( flag[7] == 0 ) ) { fprintf ( fo, "N70\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[7] = 1; } else if ( ( Sum >= Size_includeN * 0.8 ) && ( Sum < Size_includeN * 0.9 ) && ( flag[8] == 0 ) ) { fprintf ( fo, "N80\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[8] = 1; } else if ( ( Sum >= Size_includeN * 0.9 ) && ( flag[9] == 0 ) ) { fprintf ( fo, "N90\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); flag[9] = 1; } if ( ( Sum >= known_genome_size * 0.5 ) && ( flag_known == 0 ) ) { N50_known = Size_Seq[k]; Num_N50_known = Scaffold_Number - k; flag_known = 1; } } if ( flag[5] == 0 ) { Sum = 0; for ( k = Scaffold_Number - 1; k >= 0; k-- ) { Sum = Sum + Size_Seq[k]; if ( Sum >= Size_includeN * 0.5 ) { fprintf ( fo, "N50\t%ld\t%ld\n", Size_Seq[k], Scaffold_Number - k ); break; } } } fprintf ( fo, "\n" ); if ( known_genome_size ) { fprintf ( fo, "NG50\t%ld\t%ld\n", N50_known, Num_N50_known ); fprintf ( fo, "N50_contig-NG50_contig_length_difference\t%ld\n", abs ( N50 - N50_known ) ); } else { fprintf ( fo, "NG50\tNaN\tNaN\n" ); fprintf ( fo, "N50_contig-NG50_contig_length_difference\tNaN\n" ); } fprintf ( fo, "\n" ); free ( A_num ); free ( C_num ); free ( G_num ); free ( T_num ); free ( N_num ); free ( Non_ACGTN ); free ( Singleton_Seq ); free ( Size_Seq ); Scaffold_Number_Contig = Scaffold_Number; fprintf ( fo, "Number_of_contigs_in_scaffolds\t%ld\n", Scaffold_Number_Contig - Singleton_Number_Scaf ); fprintf ( fo, "Number_of_contigs_not_in_scaffolds(Singleton)\t%ld\n", Singleton_Number_Scaf ); fprintf ( fo, "Average_number_of_contigs_per_scaffold\t%.1f\n", 1.0 * ( Scaffold_Number_Contig - Singleton_Number_Scaf ) / ( Scaffold_Number_Scaf - Singleton_Number_Scaf ) ); fprintf ( fo, "\n" ); fclose ( fp ); fclose ( fp2 ); fclose ( fo ); } /************************************************* Function: getCnt Description: Gets connection between two contigs. Input: 1. from_c: left contig 2. to_c: right contig Output: None. Return: Connection between two contigs. *************************************************/ CONNECT * getCnt ( unsigned int from_c, unsigned int to_c ) { CONNECT * pcnt; pcnt = contig_array[from_c].downwardConnect; while ( pcnt ) { if ( pcnt->contigID == to_c ) { return pcnt; } pcnt = pcnt->next; } return pcnt; } /************************************************* Function: allConnect Description: Counts contig's downstrem connection number if this contig does NOT have neigher upstream nor downstream connection in scaffold. Input: 1. ctg: contig 2. preCNT: contig's upstream connection Output: None. Return: 1 if contig had both upstream and downstream connections in scaffold. Contig's downstream connection number otherwise. *************************************************/ int allConnect ( unsigned int ctg, CONNECT * preCNT ) { if ( preCNT && preCNT->nextInScaf ) { return 1; } CONNECT * cn_temp; int count = 0; if ( !contig_array[ctg].downwardConnect ) { return count; } cn_temp = contig_array[ctg].downwardConnect; while ( cn_temp ) { count++; cn_temp = cn_temp->next; } return count; } /************************************************* Function: get_ctg_score2 Description: Calculates a score to indicate the strengh of connections between a contig and other contigs in scaffold. Input: 1. pos: contig index 2. tempCounter: maximum contig number in scaffold Output: None. Return: Calculated score. *************************************************/ int get_ctg_score2 ( int pos, int tempCounter ) { int id, innum, outnum, in = 0, out = 0, i, currId; CONNECT * dh_cnt; id = * ( unsigned int * ) darrayGet ( tempArray, pos ); outnum = allConnect ( id, NULL ); innum = allConnect ( getTwinCtg ( id ), NULL ); int outlen = 0, inlen = 0, outcut, incut; if ( contig_array[id].downwardConnect ) { outlen = contig_array[id].downwardConnect->gapLen; } if ( contig_array[getTwinCtg ( id )].downwardConnect ) { inlen = contig_array[getTwinCtg ( id )].downwardConnect->gapLen; } outcut = outlen / overlaplen; incut = inlen / overlaplen; if ( outcut > outnum * 10 || outcut < outnum * 2 ) { outcut = outnum * 10; } if ( incut > innum * 10 || incut < innum * 2 ) { incut = innum * 10; } int start = pos - incut > 0 ? pos - incut : 0; int end = pos + outcut < tempCounter ? pos + outcut : tempCounter; for ( i = start; i < end; i++ ) { if ( i == pos ) { continue; } currId = * ( unsigned int * ) darrayGet ( tempArray, i ); if ( i < pos ) { dh_cnt = getCnt ( currId, id ); if ( dh_cnt && dh_cnt->weight > 0 ) { in++; } } if ( i > pos ) { dh_cnt = getCnt ( id, currId ); if ( dh_cnt && dh_cnt->weight > 0 ) { out++; } } } if ( innum > pos ) { innum = pos; } if ( outnum > tempCounter - pos - 1 ) { outnum = tempCounter - pos - 1; } if ( innum > 0 && outnum > 0 ) { if ( pos < tempCounter - 1 && pos > 0 ) { if ( outnum < 3 && out == 0 ) { if ( in > 0 ) { return ( int ) ( ( ( double ) ( in ) / ( double ) ( innum ) ) * 100 ); } } if ( innum < 3 && in == 0 ) { if ( out > 0 ) { return ( int ) ( ( ( double ) ( out ) / ( double ) ( outnum ) ) * 100 ); } } if ( in == 0 || out == 0 ) { return 0; } return ( int ) ( ( ( double ) ( in * out ) / ( double ) ( innum * outnum ) ) * 100 ); } if ( pos == 0 ) { return ( int ) ( ( ( double ) ( out ) / ( double ) ( outnum ) ) * 100 ); } if ( pos == tempCounter - 1 ) { return ( int ) ( ( ( double ) ( in ) / ( double ) ( innum ) ) * 100 ); } } else if ( innum > 0 ) { if ( pos == tempCounter - 1 && in == 1 && innum > 5 ) { return 0; } return ( int ) ( ( ( double ) ( in ) / ( double ) ( innum ) ) * 100 ); } else if ( outnum > 0 ) { if ( pos == 0 && out == 1 && outnum > 5 ) { return 0; } return ( int ) ( ( ( double ) ( out ) / ( double ) ( outnum ) ) * 100 ); } return 0; } /************************************************* Function: get_ctg_score2 Description: Calculates a score to indicate the strengh of connections between a contig and other contigs in scaffold. Input: 1. pos: contig index 2. tempCounter: maximum contig number in scaffold Output: None. Return: Calculated score. *************************************************/ int get_ctg_score ( int pos, int num3, int num5, int flag ) { int i = 0, in = 0, out = 0, innum = 0, outnum = 0, threeid; CONNECT * dh_cnt; int id; if ( flag == 0 ) { id = * ( unsigned int * ) darrayGet ( scaf3, pos ); int end = pos > 100 ? pos - 100 : 0; int start = pos + 100 < num3 ? pos + 100 : num3; in = 0, out = 0; for ( i = start; i >= end; i-- ) { threeid = * ( unsigned int * ) darrayGet ( scaf3, i ); if ( threeid == id ) { pos = i; continue; } dh_cnt = getCnt ( id, threeid ); if ( dh_cnt && dh_cnt->weight > 0 ) { out++; } dh_cnt = getCnt ( threeid, id ); if ( dh_cnt && dh_cnt->weight > 0 ) { in++; } } outnum = allConnect ( id, NULL ); innum = allConnect ( getTwinCtg ( id ), NULL ); int num5_check = 0; if ( pos - end < outnum ) { for ( i = 0; i < num5; i++ ) { num5_check++; threeid = * ( unsigned int * ) darrayGet ( scaf5, i ); dh_cnt = getCnt ( id, threeid ); if ( dh_cnt && dh_cnt->weight > 0 ) { out++; } if ( num5_check == outnum ) { break; } } } if ( pos - end + num5_check < outnum ) { outnum = pos - end + num5_check; } if ( start - pos < innum ) { innum = start - pos; } if ( innum > 0 && outnum > 0 ) { if ( pos != num3 && pos > 0 ) { if ( outnum < 5 && out == 0 ) { if ( innum > 0 ) { return ( int ) ( ( ( double ) ( in ) / ( double ) ( innum ) ) * 100 ); } } if ( innum < 5 && in == 0 ) { if ( outnum > 0 ) { return ( int ) ( ( ( double ) ( out ) / ( double ) ( outnum ) ) * 100 ); } } if ( in == 0 || out == 0 ) { return 0; } return ( int ) ( ( ( double ) ( in * out ) / ( double ) ( innum * outnum ) ) * 100 ); } if ( pos == num3 ) { return ( int ) ( ( ( double ) ( out ) / ( double ) ( outnum ) ) * 100 ); } if ( pos == 0 ) { return ( int ) ( ( ( double ) ( in ) / ( double ) ( innum ) ) * 100 ); } } else if ( innum > 0 ) { return ( int ) ( ( ( double ) ( in ) / ( double ) ( innum ) ) * 100 ); } else if ( outnum > 0 ) { if ( pos == num3 && out == 1 && outnum > 5 ) { return 0; } return ( int ) ( ( ( double ) ( out ) / ( double ) ( outnum ) ) * 100 ); } return 0; } else { id = * ( unsigned int * ) darrayGet ( scaf5, pos ); int start = pos > 100 ? pos - 100 : 0; int end = pos + 100 < num5 ? pos + 100 : num5; in = 0, out = 0; for ( i = start; i < end; i++ ) { threeid = * ( unsigned int * ) darrayGet ( scaf5, i ); if ( threeid == id ) { pos = i; continue; } dh_cnt = getCnt ( id, threeid ); if ( dh_cnt && dh_cnt->weight > 0 ) { out++; } dh_cnt = getCnt ( threeid, id ); if ( dh_cnt && dh_cnt->weight > 0 ) { in++; } } outnum = allConnect ( id, NULL ); innum = allConnect ( getTwinCtg ( id ), NULL ); int num3_check = 0; if ( pos - start < innum ) { for ( i = 0; i < num3; i++ ) { num3_check++; threeid = * ( unsigned int * ) darrayGet ( scaf3, i ); dh_cnt = getCnt ( threeid, id ); if ( dh_cnt && dh_cnt->weight > 0 ) { in++; } if ( num3_check == innum ) { break; } } } if ( pos - start + num3_check < innum ) { innum = pos - start + num3_check; } if ( end - pos - 1 < outnum ) { outnum = end - pos - 1; } if ( innum > 0 && outnum > 0 ) { if ( pos != num5 - 1 && pos > 0 ) { if ( outnum < 5 && out == 0 && innum > 0 ) { return ( int ) ( ( ( double ) ( in ) / ( double ) ( innum ) ) * 100 ); } if ( innum < 5 && in == 0 && outnum > 0 ) { return ( int ) ( ( ( double ) ( out ) / ( double ) ( outnum ) ) * 100 ); } if ( in == 0 || out == 0 ) { return 0; } return ( int ) ( ( ( double ) ( in * out ) / ( double ) ( innum * outnum ) ) * 100 ); } if ( pos == 0 ) { return ( int ) ( ( ( double ) ( out ) / ( double ) ( outnum ) ) * 100 ); } if ( pos == num5 - 1 ) { return ( int ) ( ( ( double ) ( in ) / ( double ) ( innum ) ) * 100 ); } } else if ( innum > 0 ) { if ( pos == num5 - 1 && in == 1 && innum > 5 ) { return 0; } return ( int ) ( ( ( double ) ( in ) / ( double ) ( innum ) ) * 100 ); } else if ( outnum > 0 ) { return ( int ) ( ( ( double ) ( out ) / ( double ) ( outnum ) ) * 100 ); } return 0; } return 0; } /************************************************* Function: scaffolding Description: Masks contigs having low connection score in scaffold. Fills gaps by using ARC information. Outputs scaffold structure and filled gaps' information. Input: 1. len_cut: length cutoff 2. outfile: prefix of graph Output: None. Return: None. *************************************************/ void scaffolding ( unsigned int len_cut, char * outfile ) { unsigned int prev_ctg, ctg, bal_ctg, *length_array, count = 0, num_lctg = 0, *score_array; unsigned int i, max_steps = 5; int num5, num3, j, len, flag, num_route, gap_c = 0; int tempCounter; short gap = 0; long long sum = 0, N50, N90; FILE * fp, *fo = NULL; char name[256]; CONNECT * cnt, *prevCNT, *nextCnt, *dh_cnt; boolean excep, weak; weakCounter = 0; so_far = ( unsigned int * ) ckalloc ( max_n_routes * sizeof ( unsigned int ) ); found_routes = ( unsigned int ** ) ckalloc ( max_n_routes * sizeof ( unsigned int * ) ); for ( j = 0; j < max_n_routes; j++ ) { found_routes[j] = ( unsigned int * ) ckalloc ( max_steps * sizeof ( unsigned int ) ); } length_array = ( unsigned int * ) ckalloc ( ( num_ctg + 1 ) * sizeof ( unsigned int ) ); //use length_array to change info in index_array for ( i = 1; i <= num_ctg; i++ ) { length_array[i] = 0; } for ( i = 1; i <= num_ctg; i++ ) { if ( index_array[i] > 0 ) { length_array[index_array[i]] = i; } } for ( i = 1; i <= num_ctg; i++ ) { index_array[i] = length_array[i]; } orig2new = 0; sprintf ( name, "%s.scaf", outfile ); fp = ckopen ( name, "w" ); sprintf ( name, "%s.scaf_gap", outfile ); fo = ckopen ( name, "w" ); scaf3 = ( DARRAY * ) createDarray ( 1000, sizeof ( unsigned int ) ); scaf5 = ( DARRAY * ) createDarray ( 1000, sizeof ( unsigned int ) ); gap3 = ( DARRAY * ) createDarray ( 1000, sizeof ( int ) ); gap5 = ( DARRAY * ) createDarray ( 1000, sizeof ( int ) ); tempArray = ( DARRAY * ) createDarray ( 1000, sizeof ( unsigned int ) ); for ( i = 1; i <= num_ctg; i++ ) { contig_array[i].flag = 0; } for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].length + ( unsigned int ) overlaplen >= len_cut ) { num_lctg++; } else { continue; } if ( contig_array[i].flag || contig_array[i].mask || !contig_array[i].downwardConnect || !validConnect ( i, NULL ) ) { continue; } num5 = num3 = 0; ctg = i; * ( unsigned int * ) darrayPut ( scaf5, num5++ ) = i; contig_array[i].flag = 1; bal_ctg = getTwinCtg ( ctg ); contig_array[bal_ctg].flag = 1; len = contig_array[i].length; prevCNT = NULL; cnt = getNextContig ( ctg, prevCNT, &excep ); while ( cnt ) { nextCnt = getNextContig ( cnt->contigID, cnt, &excep ); if ( excep && prevCNT ) { fprintf ( stderr, "scaffolding: exception --- prev cnt from %u\n", prevCNT->contigID ); } if ( nextCnt && nextCnt->used ) { break; } setConnectUsed ( ctg, cnt->contigID, 1 ); * ( int * ) darrayPut ( gap5, num5 - 1 ) = cnt->gapLen; ctg = cnt->contigID; * ( unsigned int * ) darrayPut ( scaf5, num5++ ) = ctg; len += cnt->gapLen + contig_array[ctg].length; bal_ctg = getTwinCtg ( ctg ); contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; prevCNT = cnt; cnt = nextCnt; } ctg = getTwinCtg ( i ); if ( num5 >= 2 ) { prevCNT = checkConnect ( getTwinCtg ( * ( unsigned int * ) darrayGet ( scaf5, 1 ) ), ctg ); } else { prevCNT = NULL; } cnt = getNextContig ( ctg, prevCNT, &excep ); while ( cnt ) { nextCnt = getNextContig ( cnt->contigID, cnt, &excep ); if ( excep && prevCNT ) { fprintf ( stderr, "scaffolding: exception -- prev cnt from %u\n", prevCNT->contigID ); } if ( nextCnt && nextCnt->used ) { break; } setConnectUsed ( ctg, cnt->contigID, 1 ); ctg = cnt->contigID; len += cnt->gapLen + contig_array[ctg].length; bal_ctg = getTwinCtg ( ctg ); contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; * ( int * ) darrayPut ( gap3, num3 ) = cnt->gapLen; * ( unsigned int * ) darrayPut ( scaf3, num3++ ) = bal_ctg; prevCNT = cnt; cnt = nextCnt; } if ( num5 + num3 == 1 ) { contig_array[i].flag = 0; continue; } len += overlaplen; sum += len; length_array[count++] = len; if ( num5 + num3 < 1 ) { fprintf ( stderr, "no scaffold created for contig %d\n", i ); continue; } tempCounter = 0; for ( j = num3 - 1; j >= 0; j-- ) { * ( unsigned int * ) darrayPut ( tempArray, tempCounter++ ) = * ( unsigned int * ) darrayGet ( scaf3, j ); } for ( j = 0; j < num5; j++ ) { * ( unsigned int * ) darrayPut ( tempArray, tempCounter++ ) = * ( unsigned int * ) darrayGet ( scaf5, j ); } score_array = ( unsigned int * ) ckalloc ( tempCounter * sizeof ( unsigned int ) ); int now_cnt_weight, curr_ctg_score, pre_score = -1, prev_id = 0, mask_num = 0, score_count = 0, prev_p = 0; for ( j = 0; j < tempCounter; j++ ) { int currId = * ( unsigned int * ) darrayGet ( tempArray, j ); dh_cnt = getCntBetween ( prev_id, currId ); if ( dh_cnt ) { now_cnt_weight = dh_cnt ->weight; } else { now_cnt_weight = 0; } curr_ctg_score = get_ctg_score2 ( j, tempCounter ); if ( prev_id == 0 ) { pre_score = curr_ctg_score; prev_id = currId; prev_p = j; continue; } if ( score_mask ) { if ( now_cnt_weight == 0 && j > 0 && j < tempCounter - 1 ) { if ( pre_score == 0 ) { * ( unsigned int * ) darrayPut ( tempArray, prev_p ) = 0; contig_array[prev_id].flag = 0; contig_array[getTwinCtg ( prev_id )].flag = 0; mask_num++; } else if ( curr_ctg_score == 0 ) { * ( unsigned int * ) darrayPut ( tempArray, j ) = 0; contig_array[currId].flag = 0; contig_array[getTwinCtg ( currId )].flag = 0; mask_num++; if ( j < tempCounter - 1 ) { continue; } } } if ( abs ( prev_id - currId ) <= 2 && now_cnt_weight == 0 && * ( unsigned int * ) darrayGet ( tempArray, prev_p ) != 0 && * ( unsigned int * ) darrayGet ( tempArray, j ) != 0 ) { mask_num++; if ( contig_array[prev_id].cvg < contig_array[currId].cvg ) { * ( unsigned int * ) darrayPut ( tempArray, prev_p ) = 0; contig_array[prev_id].flag = 0; contig_array[getTwinCtg ( prev_id )].flag = 0; } else { * ( unsigned int * ) darrayPut ( tempArray, j ) = 0; contig_array[currId].flag = 0; contig_array[getTwinCtg ( currId )].flag = 0; if ( j < tempCounter - 1 ) { continue; } } } } if ( * ( unsigned int * ) darrayGet ( tempArray, prev_p ) != 0 ) { score_array[score_count++] = pre_score; } pre_score = curr_ctg_score; prev_id = currId; prev_p = j; } if ( * ( unsigned int * ) darrayGet ( tempArray, prev_p ) != 0 ) { score_array[score_count++] = pre_score; } if ( score_mask == 1 && ( ( num3 + num5 > 5 && score_count < 2 ) || score_count == 1 ) ) { free ( ( void * ) score_array ); --count; sum -= len; for ( j = 0; j < num3; j++ ) { ctg = * ( unsigned int * ) darrayGet ( scaf3, j ); contig_array[ctg].flag = 0; contig_array[getTwinCtg ( ctg )].flag = 0; } for ( j = 0; j < num5; j++ ) { ctg = * ( unsigned int * ) darrayGet ( scaf5, j ); contig_array[ctg].flag = 0; contig_array[getTwinCtg ( ctg )].flag = 0; } continue; } fprintf ( fp, ">scaffold%d %d %d %d\n", count, score_count, len, num3 + num5, mask_num ); fprintf ( fo, ">scaffold%d %d %d %d\n", count, score_count, len, num3 + num5, mask_num ); len = prev_ctg = 0; tempCounter = 0, score_count = 0; for ( j = num3 - 1; j >= 0; j-- ) { int now_cnt_weigth = 0; int nextid, start = 0; int currId = * ( unsigned int * ) darrayGet ( scaf3, j ); int tmpid = * ( unsigned int * ) darrayGet ( tempArray, tempCounter++ ); if ( tmpid == 0 ) { if ( j == num3 - 1 ) { len = 0; continue; } len += contig_array[* ( unsigned int * ) darrayGet ( scaf3, j )].length + * ( int * ) darrayGet ( gap3, j ); int tmpgap = contig_array[* ( unsigned int * ) darrayGet ( scaf3, j )].length + * ( int * ) darrayGet ( gap3, j ); gap += tmpgap > 0 ? tmpgap : 0; continue; } if ( j > 0 ) { nextid = * ( unsigned int * ) darrayGet ( tempArray, tempCounter + start ); while ( nextid == 0 && tempCounter + start + 1 < num3 + num5 ) { start++; nextid = * ( unsigned int * ) darrayGet ( tempArray, tempCounter + start ); } } else { nextid = i; } CONNECT * dh_cnt = getCntBetween ( currId, nextid ); if ( dh_cnt ) { now_cnt_weigth = dh_cnt->weight; } else { now_cnt_weigth = 0; } curr_ctg_score = score_array[score_count++]; if ( score_mask == 1 && curr_ctg_score == 0 && ( num3 + num5 > 2 ) && ( ( j == num3 - 1 && contig_array[nextid].length < 200 && num3 + num5 > 5 ) || ( now_cnt_weigth == 0 && j > 0 ) ) ) { if ( j == num3 - 1 ) { len = 0; continue; } len += contig_array[* ( unsigned int * ) darrayGet ( scaf3, j )].length + * ( int * ) darrayGet ( gap3, j ); int tmpgap = contig_array[* ( unsigned int * ) darrayGet ( scaf3, j )].length + * ( int * ) darrayGet ( gap3, j ); gap += tmpgap > 0 ? tmpgap : 0; continue; } if ( !isLargerThanTwin ( * ( unsigned int * ) darrayGet ( scaf3, j ) ) ) { fprintf ( fp, "%-10d %-10d + %d %d %d" , index_array[* ( unsigned int * ) darrayGet ( scaf3, j )], len, contig_array[* ( unsigned int * ) darrayGet ( scaf3, j )].length + overlaplen, now_cnt_weigth, curr_ctg_score ); weak = printCnts ( fp, * ( unsigned int * ) darrayGet ( scaf3, j ) ); } else { fprintf ( fp, "%-10d %-10d - %d %d %d" , index_array[getTwinCtg ( * ( unsigned int * ) darrayGet ( scaf3, j ) )], len , contig_array[* ( unsigned int * ) darrayGet ( scaf3, j )].length + overlaplen, now_cnt_weigth, curr_ctg_score ); weak = printCnts ( fp, * ( unsigned int * ) darrayGet ( scaf3, j ) ); } if ( prev_ctg ) { num_route = num_trace = 0; traceAlongArc ( * ( unsigned int * ) darrayGet ( scaf3, j ), prev_ctg, max_steps , gap - ins_size_var, gap + ins_size_var, 0, 0, &num_route ); if ( num_route == 1 ) { output1gap ( fo, max_steps ); gap_c++; } } fprintf ( fo, "%-10d %-10d\n", * ( unsigned int * ) darrayGet ( scaf3, j ), len ); len += contig_array[* ( unsigned int * ) darrayGet ( scaf3, j )].length + * ( int * ) darrayGet ( gap3, j ); prev_ctg = * ( unsigned int * ) darrayGet ( scaf3, j ); gap = * ( int * ) darrayGet ( gap3, j ) > 0 ? * ( int * ) darrayGet ( gap3, j ) : 0; } for ( j = 0; j < num5; j++ ) { int now_cnt_weigth = 0; int currId, nextid, start = 0; currId = * ( unsigned int * ) darrayGet ( scaf5, j ); int tmpid = * ( unsigned int * ) darrayGet ( tempArray, tempCounter++ ); if ( tmpid == 0 ) { if ( j == num5 - 1 ) { continue; } len += contig_array[* ( unsigned int * ) darrayGet ( scaf5, j )].length + * ( int * ) darrayGet ( gap5, j ); int tmpgap = contig_array[* ( unsigned int * ) darrayGet ( scaf5, j )].length + * ( int * ) darrayGet ( gap5, j ); gap += tmpgap > 0 ? tmpgap : 0; continue; } if ( j < num5 - 1 ) { nextid = * ( unsigned int * ) darrayGet ( tempArray, tempCounter + start ); while ( nextid == 0 && tempCounter + start + 1 < num3 + num5 ) { start ++; nextid = * ( unsigned int * ) darrayGet ( tempArray, tempCounter + start ); } CONNECT * dh_cnt = getCntBetween ( currId, nextid ); if ( dh_cnt ) { now_cnt_weigth = dh_cnt->weight; } else { now_cnt_weigth = 0; } } curr_ctg_score = score_array [score_count++]; if ( score_mask == 1 && curr_ctg_score == 0 && ( num3 + num5 > 2 ) && ( ( j == num5 - 1 && contig_array[* ( unsigned int * ) darrayGet ( scaf5, j - 1 )].length < 200 && num3 + num5 > 5 ) || ( j != num5 - 1 && now_cnt_weigth == 0 ) ) ) { if ( j == num5 - 1 ) { continue; } len += contig_array[* ( unsigned int * ) darrayGet ( scaf5, j )].length + * ( int * ) darrayGet ( gap5, j ); int tmpgap = contig_array[* ( unsigned int * ) darrayGet ( scaf5, j )].length + * ( int * ) darrayGet ( gap5, j ); gap += tmpgap > 0 ? tmpgap : 0; continue; } if ( !isLargerThanTwin ( * ( unsigned int * ) darrayGet ( scaf5, j ) ) ) { fprintf ( fp, "%-10d %-10d + %d %d %d" , index_array[* ( unsigned int * ) darrayGet ( scaf5, j )], len , contig_array[* ( unsigned int * ) darrayGet ( scaf5, j )].length + overlaplen, now_cnt_weigth, curr_ctg_score ); weak = printCnts ( fp, * ( unsigned int * ) darrayGet ( scaf5, j ) ); } else { fprintf ( fp, "%-10d %-10d - %d %d %d" , index_array[getTwinCtg ( * ( unsigned int * ) darrayGet ( scaf5, j ) )], len , contig_array[* ( unsigned int * ) darrayGet ( scaf5, j )].length + overlaplen, now_cnt_weigth, curr_ctg_score ); weak = printCnts ( fp, * ( unsigned int * ) darrayGet ( scaf5, j ) ); } if ( prev_ctg ) { num_route = num_trace = 0; traceAlongArc ( * ( unsigned int * ) darrayGet ( scaf5, j ), prev_ctg, max_steps , gap - ins_size_var, gap + ins_size_var, 0, 0, &num_route ); if ( num_route == 1 ) { output1gap ( fo, max_steps ); gap_c++; } } fprintf ( fo, "%-10d %-10d\n", * ( unsigned int * ) darrayGet ( scaf5, j ), len ); if ( j < num5 - 1 ) { len += contig_array[* ( unsigned int * ) darrayGet ( scaf5, j )].length + * ( int * ) darrayGet ( gap5, j ); prev_ctg = * ( unsigned int * ) darrayGet ( scaf5, j ); gap = * ( int * ) darrayGet ( gap5, j ) > 0 ? * ( int * ) darrayGet ( gap5, j ) : 0; } } free ( ( void * ) score_array ); } freeDarray ( scaf3 ); freeDarray ( scaf5 ); freeDarray ( gap3 ); freeDarray ( gap5 ); freeDarray ( tempArray ); fclose ( fp ); fclose ( fo ); fprintf ( stderr, "\nThe final rank\n" ); if ( count == 0 ) { fprintf ( stderr, "\n\nNo scaffold was constructed.\n\n" ); free ( ( void * ) length_array ); for ( j = 0; j < max_n_routes; j++ ) { free ( ( void * ) found_routes[j] ); } free ( ( void * ) found_routes ); free ( ( void * ) so_far ); return; } fprintf ( stderr, "\n*******************************\n" ); fprintf ( stderr, " Scaffold number %d\n", count ); fprintf ( stderr, " In-scaffold contig number %u\n", num_lctg / 2 ); fprintf ( stderr, " Total scaffold length %lld\n", sum ); fprintf ( stderr, " Average scaffold length %lld\n", sum / count ); fprintf ( stderr, " Filled gap number %d\n", gap_c ); //output singleton for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].length + ( unsigned int ) overlaplen < len_cut || contig_array[i].flag ) { continue; } length_array[count++] = contig_array[i].length; sum += contig_array[i].length; if ( isSmallerThanTwin ( i ) ) { i++; } } long long total_len = sum; qsort ( length_array, count, sizeof ( length_array[0] ), cmp_int ); N50 = sum * 0.5; N90 = sum * 0.9; int N50length = 0; int N90length = 0; sum = flag = 0; for ( j = count - 1; j >= 0; j-- ) { sum += length_array[j]; if ( !flag && sum >= N50 && N50length == 0 ) { N50length = length_array[j]; flag++; } if ( sum >= N90 && N90length == 0 ) { N90length = length_array[j]; break; } } fprintf ( stderr, " Longest scaffold %lld\n", length_array[count - 1] ); fprintf ( stderr, " Scaffold and singleton number %d\n", count ); fprintf ( stderr, " Scaffold and singleton length %lld\n", total_len ); fprintf ( stderr, " Average length %d\n", total_len / count ); fprintf ( stderr, " N50 %d\n", N50length ); fprintf ( stderr, " N90 %d\n", N90length ); fprintf ( stderr, " Weak points %d\n", weakCounter ); fprintf ( stderr, "\n*******************************\n" ); fflush ( stdout ); free ( ( void * ) length_array ); for ( j = 0; j < max_n_routes; j++ ) { free ( ( void * ) found_routes[j] ); } free ( ( void * ) found_routes ); free ( ( void * ) so_far ); } /************************************************* Function: scaffold_count Description: Makes statistic of scaffold till current rank. Input: 1. rank: current rank number 2. len_cut: length cutoff Output: None. Return: None. *************************************************/ void scaffold_count ( int rank, unsigned int len_cut ) { static DARRAY * scaf3, *scaf5; static DARRAY * gap3, *gap5; unsigned int prev_ctg, ctg, bal_ctg, *length_array, count = 0, num_lctg = 0; unsigned int i, max_steps = 5; int num5, num3, j, len, flag, num_route, gap_c = 0; short gap = 0; long long sum = 0, N50, N90; CONNECT * cnt, *prevCNT, *nextCnt; boolean excep; so_far = ( unsigned int * ) ckalloc ( max_n_routes * sizeof ( unsigned int ) ); found_routes = ( unsigned int ** ) ckalloc ( max_n_routes * sizeof ( unsigned int * ) ); for ( j = 0; j < max_n_routes; j++ ) { found_routes[j] = ( unsigned int * ) ckalloc ( max_steps * sizeof ( unsigned int ) ); } length_array = ( unsigned int * ) ckalloc ( ( num_ctg + 1 ) * sizeof ( unsigned int ) ); //use length_array to change info in index_array for ( i = 1; i <= num_ctg; i++ ) { length_array[i] = 0; } for ( i = 1; i <= num_ctg; i++ ) { if ( index_array[i] > 0 ) { length_array[index_array[i]] = i; } } for ( i = 1; i <= num_ctg; i++ ) { index_array[i] = length_array[i]; } //contig i with original index: index_array[i] orig2new = 0; scaf3 = ( DARRAY * ) createDarray ( 1000, sizeof ( unsigned int ) ); scaf5 = ( DARRAY * ) createDarray ( 1000, sizeof ( unsigned int ) ); gap3 = ( DARRAY * ) createDarray ( 1000, sizeof ( int ) ); gap5 = ( DARRAY * ) createDarray ( 1000, sizeof ( int ) ); for ( i = 1; i <= num_ctg; i++ ) { contig_array[i].flag = 0; } for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].length + ( unsigned int ) overlaplen >= len_cut ) { num_lctg++; } else { continue; } if ( contig_array[i].flag || contig_array[i].mask || !contig_array[i].downwardConnect || !validConnect ( i, NULL ) ) { continue; } num5 = num3 = 0; ctg = i; * ( unsigned int * ) darrayPut ( scaf5, num5++ ) = i; contig_array[i].flag = 1; bal_ctg = getTwinCtg ( ctg ); contig_array[bal_ctg].flag = 1; len = contig_array[i].length; prevCNT = NULL; cnt = getNextContig ( ctg, prevCNT, &excep ); while ( cnt ) { nextCnt = getNextContig ( cnt->contigID, cnt, &excep ); if ( excep && prevCNT ) { fprintf ( stderr, "scaffolding: exception --- prev cnt from %u\n", prevCNT->contigID ); } if ( nextCnt && nextCnt->used ) { break; } setConnectUsed ( ctg, cnt->contigID, 1 ); * ( int * ) darrayPut ( gap5, num5 - 1 ) = cnt->gapLen; ctg = cnt->contigID; * ( unsigned int * ) darrayPut ( scaf5, num5++ ) = ctg; len += cnt->gapLen + contig_array[ctg].length; bal_ctg = getTwinCtg ( ctg ); contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; prevCNT = cnt; cnt = nextCnt; } ctg = getTwinCtg ( i ); if ( num5 >= 2 ) { prevCNT = checkConnect ( getTwinCtg ( * ( unsigned int * ) darrayGet ( scaf5, 1 ) ), ctg ); } else { prevCNT = NULL; } cnt = getNextContig ( ctg, prevCNT, &excep ); while ( cnt ) { nextCnt = getNextContig ( cnt->contigID, cnt, &excep ); if ( excep && prevCNT ) { fprintf ( stderr, "scaffolding: exception -- prev cnt from %u\n", prevCNT->contigID ); } if ( nextCnt && nextCnt->used ) { break; } setConnectUsed ( ctg, cnt->contigID, 1 ); ctg = cnt->contigID; len += cnt->gapLen + contig_array[ctg].length; bal_ctg = getTwinCtg ( ctg ); contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; * ( int * ) darrayPut ( gap3, num3 ) = cnt->gapLen; * ( unsigned int * ) darrayPut ( scaf3, num3++ ) = bal_ctg; prevCNT = cnt; cnt = nextCnt; } len += overlaplen; sum += len; length_array[count++] = len; if ( num5 + num3 < 1 ) { fprintf ( stderr, "no scaffold created for contig %d\n", i ); continue; } len = prev_ctg = 0; for ( j = num3 - 1; j >= 0; j-- ) { if ( prev_ctg ) { num_route = num_trace = 0; traceAlongArc ( * ( unsigned int * ) darrayGet ( scaf3, j ), prev_ctg, max_steps , gap - ins_size_var, gap + ins_size_var, 0, 0, &num_route ); if ( num_route == 1 ) { gap_c++; } } len += contig_array[* ( unsigned int * ) darrayGet ( scaf3, j )].length + * ( int * ) darrayGet ( gap3, j ); prev_ctg = * ( unsigned int * ) darrayGet ( scaf3, j ); gap = * ( int * ) darrayGet ( gap3, j ) > 0 ? * ( int * ) darrayGet ( gap3, j ) : 0; } for ( j = 0; j < num5; j++ ) { if ( prev_ctg ) { num_route = num_trace = 0; traceAlongArc ( * ( unsigned int * ) darrayGet ( scaf5, j ), prev_ctg, max_steps , gap - ins_size_var, gap + ins_size_var, 0, 0, &num_route ); if ( num_route == 1 ) { gap_c++; } } if ( j < num5 - 1 ) { len += contig_array[* ( unsigned int * ) darrayGet ( scaf5, j )].length + * ( int * ) darrayGet ( gap5, j ); prev_ctg = * ( unsigned int * ) darrayGet ( scaf5, j ); gap = * ( int * ) darrayGet ( gap5, j ) > 0 ? * ( int * ) darrayGet ( gap5, j ) : 0; } } } freeDarray ( scaf3 ); freeDarray ( scaf5 ); freeDarray ( gap3 ); freeDarray ( gap5 ); if ( count == 0 ) { fprintf ( stderr, "\n\nNo scaffold was constructed.\n\n" ); free ( ( void * ) length_array ); for ( j = 0; j < max_n_routes; j++ ) { free ( ( void * ) found_routes[j] ); } free ( ( void * ) found_routes ); free ( ( void * ) so_far ); return; } fprintf ( stderr, "\nRank %d\n", rank ); fprintf ( stderr, " Scaffold number %d\n", count ); fprintf ( stderr, " In-scaffold contig number %u\n", num_lctg / 2 ); fprintf ( stderr, " Total scaffold length %lld\n", sum ); fprintf ( stderr, " Average scaffold length %lld\n", sum / count ); fprintf ( stderr, " Filled gap number %d\n", gap_c ); //output singleton for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].length + ( unsigned int ) overlaplen < len_cut || contig_array[i].flag ) { continue; } length_array[count++] = contig_array[i].length; sum += contig_array[i].length; if ( isSmallerThanTwin ( i ) ) { i++; } } long int total_len = sum; // calculate N50/N90 qsort ( length_array, count, sizeof ( length_array[0] ), cmp_int ); N50 = sum * 0.5; N90 = sum * 0.9; int N50length = 0; int N90length = 0; sum = flag = 0; for ( j = count - 1; j >= 0; j-- ) { sum += length_array[j]; if ( !flag && sum >= N50 && N50length == 0 ) { N50length = length_array[j]; flag++; } if ( sum >= N90 && N90length == 0 ) { N90length = length_array[j]; break; } } fprintf ( stderr, " Longest scaffold %lld\n", length_array[count - 1] ); fprintf ( stderr, " Scaffold and singleton number %d\n", count ); fprintf ( stderr, " Scaffold and singleton length %lld\n", total_len ); fprintf ( stderr, " Average length %d\n", total_len / count ); fprintf ( stderr, " N50 %d\n", N50length ); fprintf ( stderr, " N90 %d\n", N90length ); free ( ( void * ) length_array ); for ( j = 0; j < max_n_routes; j++ ) { free ( ( void * ) found_routes[j] ); } free ( ( void * ) found_routes ); free ( ( void * ) so_far ); } /************************************************* Function: outputLinks Description: Outputs connection information of current insert size LIB. Input: 1. fp: output file 2. insertS: current insert size Output: None. Return: None. *************************************************/ static void outputLinks ( FILE * fp, int insertS ) { unsigned int i, bal_ctg, bal_toCtg; CONNECT * cnts, *temp_cnt; for ( i = 1; i <= num_ctg; i++ ) { cnts = contig_array[i].downwardConnect; bal_ctg = getTwinCtg ( i ); while ( cnts ) { if ( cnts->weight < 1 ) { cnts = cnts->next; continue; } fprintf ( fp, "%-10d %-10d\t%d\t%d\t%d\n" , i, cnts->contigID, cnts->gapLen, cnts->weight, insertS ); cnts->weight = 0; bal_toCtg = getTwinCtg ( cnts->contigID ); temp_cnt = getCntBetween ( bal_toCtg, bal_ctg ); if ( temp_cnt ) { temp_cnt->weight = 0; } cnts = cnts->next; } } } /************************************************* Function: PE2Links Description: Updates connections between contigs based on alignment information of paired-end reads. Input: 1. infile: alignment information file of paired-end reads Output: None. Return: None. *************************************************/ void PE2Links ( char * infile ) { char name[256], *line; FILE * fp1; FILE * linkF; gzFile * fp2; int i; int flag = 0; unsigned int j; sprintf ( name, "%s.links", infile ); boolean filesOK = check_file ( name ); if ( filesOK ) { fprintf ( stderr, "File %s exists, skip creating the links...\n", name ); return; } linkF = ckopen ( name, "w" ); if ( !pes ) { loadPEgrads ( infile ); } fprintf ( stderr, "*****************************************************\nStart to load paired-end reads information.\n\n" ); if ( COMPATIBLE_MODE == 1 ) { sprintf ( name, "%s.readOnContig", infile ); fp1 = ckopen ( name, "r" ); } else { sprintf ( name, "%s.readOnContig.gz", infile ); fp2 = gzopen ( name, "r" ); } lineLen = 1024; line = ( char * ) ckalloc ( lineLen * sizeof ( char ) ); if ( COMPATIBLE_MODE == 1 ) { fgets ( line, lineLen, fp1 ); } else { gzgets ( fp2, line, lineLen ); } line[0] = '\0'; for ( i = 0; i < gradsCounter; i++ ) { createCntMemManager(); createCntLookupTable(); newCntCounter = 0; if ( COMPATIBLE_MODE == 1 ) { flag += connectByPE_grad ( fp1, i, line ); } else { flag += connectByPE_grad_gz ( fp2, i, line ); } fprintf ( stderr, "%lld new connections.\n\n", newCntCounter / 2 ); if ( !flag ) { destroyConnectMem(); deleteCntLookupTable(); for ( j = 1; j <= num_ctg; j++ ) { contig_array[j].downwardConnect = NULL; } fprintf ( stderr, "\n" ); continue; } flag = 0; outputLinks ( linkF, pes[i].insertS ); destroyConnectMem(); deleteCntLookupTable(); for ( j = 1; j <= num_ctg; j++ ) { contig_array[j].downwardConnect = NULL; } } free ( ( void * ) line ); if ( COMPATIBLE_MODE == 1 ) { fclose ( fp1 ); } else { gzclose ( fp2 ); } fclose ( linkF ); fprintf ( stderr, "All paired-end reads information loaded.\n" ); } /************************************************* Function: inputLinks Description: Loads links information of certain insert size. Input: 1. fp: alignment inofrmation file 2. insertS: insert size boundary 3. line: the first alignment record of current LIB Output: 1. line: the first alignment record of next LIB Return: loaded record number. *************************************************/ static int inputLinks ( FILE * fp, int insertS, char * line ) { unsigned int ctg, bal_ctg, toCtg, bal_toCtg; int gap, wt, ins; unsigned int counter = 0, onScafCounter = 0; unsigned int maskCounter = 0; CONNECT * cnt, *bal_cnt; if ( strlen ( line ) ) { sscanf ( line, "%d %d %d %d %d", &ctg, &toCtg, &gap, &wt, &ins ); if ( ins != insertS ) { return counter; } if ( 1 ) { bal_ctg = getTwinCtg ( ctg ); bal_toCtg = getTwinCtg ( toCtg ); cnt = add1Connect ( ctg, toCtg, gap, wt, 0 ); bal_cnt = add1Connect ( bal_toCtg, bal_ctg, gap, wt, 0 ); if ( cnt && insertS > 1000 ) { cnt->newIns = bal_cnt->newIns = 1; } counter++; if ( contig_array[ctg].mask || contig_array[toCtg].mask ) { maskCounter++; } if ( insertS > 1000 && contig_array[ctg].from_vt == contig_array[toCtg].from_vt && // on the same scaff contig_array[ctg].indexInScaf < contig_array[toCtg].indexInScaf ) { add1LongPEcov ( ctg, toCtg, wt ); onScafCounter++; } } } while ( fgets ( line, lineLen, fp ) != NULL ) { sscanf ( line, "%d %d %d %d %d", &ctg, &toCtg, &gap, &wt, &ins ); if ( ins > insertS ) { break; } if ( insertS > 1000 && contig_array[ctg].from_vt == contig_array[toCtg].from_vt && // on the same scaff contig_array[ctg].indexInScaf < contig_array[toCtg].indexInScaf ) { add1LongPEcov ( ctg, toCtg, wt ); onScafCounter++; } bal_ctg = getTwinCtg ( ctg ); bal_toCtg = getTwinCtg ( toCtg ); cnt = add1Connect ( ctg, toCtg, gap, wt, 0 ); bal_cnt = add1Connect ( bal_toCtg, bal_ctg, gap, wt, 0 ); if ( cnt && insertS > 1000 ) { cnt->newIns = bal_cnt->newIns = 1; } counter++; if ( contig_array[ctg].mask || contig_array[toCtg].mask ) { maskCounter++; } } fprintf ( stderr, "***************************\nFor insert size: %d\n", insertS ); fprintf ( stderr, " Total PE links %d\n", counter ); fprintf ( stderr, " PE links to masked contigs %d\n", maskCounter ); fprintf ( stderr, " On same scaffold PE links %d\n", onScafCounter ); return counter; } /************************************************* Function: Links2Scaf Description: Constructs scaffolds based on alignment information. Input: 1. infile: prefix of graph Output: None. Return: None. *************************************************/ void Links2Scaf ( char * infile ) { char name[256], *line; FILE * fp; int i, j = 1, lib_n = 0, cutoff_sum = 0; int flag = 0, flag2; boolean downS, nonLinear = 0, smallPE = 0, isPrevSmall = 0, markSmall; if ( cvg4SNP > 0.001 ) { sprintf ( name, "%s.bubbleInScaff", infile ); snp_fp = ckopen ( name, "w" ); } cvg4SNP = ( double ) ( cvg4SNP * cvgAvg ); if ( !pes ) { loadPEgrads ( infile ); } sprintf ( name, "%s.links", infile ); fp = ckopen ( name, "r" ); createCntMemManager(); createCntLookupTable(); lineLen = 1024; line = ( char * ) ckalloc ( lineLen * sizeof ( char ) ); fgets ( line, lineLen, fp ); line[0] = '\0'; solidArray = ( DARRAY * ) createDarray ( 1000, sizeof ( unsigned int ) ); tempArray = ( DARRAY * ) createDarray ( 1000, sizeof ( unsigned int ) ); scaf3 = ( DARRAY * ) createDarray ( 1000, sizeof ( unsigned int ) ); scaf5 = ( DARRAY * ) createDarray ( 1000, sizeof ( unsigned int ) ); gap3 = ( DARRAY * ) createDarray ( 1000, sizeof ( int ) ); gap5 = ( DARRAY * ) createDarray ( 1000, sizeof ( int ) ); weakPE = 3; fprintf ( stderr, "\n" ); for ( i = 0; i < gradsCounter; i++ ) { if ( MinWeakCut == 0 && i == 0 ) { MinWeakCut = pes[i].pair_num_cut; } if ( pes[i].insertS < 1000 ) { isPrevSmall = 1; if ( MinWeakCut > pes[i].pair_num_cut ) { MinWeakCut = pes[i].pair_num_cut; } } else if ( pes[i].insertS > 1000 && isPrevSmall ) { smallScaf(); isPrevSmall = 0; } Insert_size = pes[i].insertS; discardCntCounter = 0; flag2 = inputLinks ( fp, pes[i].insertS, line ); if ( flag2 ) { lib_n++; cutoff_sum += pes[i].pair_num_cut; } flag += flag2; if ( !flag ) { fprintf ( stderr, "\n" ); continue; } if ( i == gradsCounter - 1 || pes[i + 1].rank != pes[i].rank ) { flag = nonLinear = downS = markSmall = 0; if ( pes[i].insertS > 1000 && pes[i].rank > 1 ) { downS = 1; } if ( pes[i].insertS <= 1000 ) { smallPE = 1; } if ( pes[i].insertS >= 1000 ) { ins_size_var = 50; OverlapPercent = 0.05; } else if ( pes[i].insertS >= 300 ) { ins_size_var = 30; OverlapPercent = 0.05; } else { ins_size_var = 20; OverlapPercent = 0.05; } if ( pes[i].insertS > 1000 ) { weakPE = 5; } bySmall = Insert_size > 1000 ? 0 : 1; if ( lib_n > 0 ) { weakPE = weakPE < cutoff_sum / lib_n ? cutoff_sum / lib_n : weakPE; lib_n = cutoff_sum = 0; } if ( MinWeakCut > weakPE ) { MinWeakCut = weakPE; } fprintf ( stderr, "Cutoff of PE links to make a reliable connection: %d\n", weakPE ); if ( i == gradsCounter - 1 ) { nonLinear = 1; } if ( Insert_size > 1000 ) { detectBreakScaff(); } ordering ( 1, downS, nonLinear, infile ); if ( i == gradsCounter - 1 ) { recoverMask(); } else { scaffold_count ( j, 100 ); j++; fprintf ( stderr, "\n" ); } if ( Insert_size > 1000 && i != gradsCounter - 1 ) { clearNewInsFlag(); } } } freeDarray ( tempArray ); freeDarray ( solidArray ); freeDarray ( scaf3 ); freeDarray ( scaf5 ); freeDarray ( gap3 ); freeDarray ( gap5 ); free ( ( void * ) line ); fclose ( fp ); if ( cvg4SNP > 0.001 ) { fclose ( snp_fp ); } fprintf ( stderr, "\nAll links loaded.\n" ); } /************************************************* Function: putNodeInArray Description: Puts contig in "ctg4heapArray". Input: 1. node: contig 2. maxNodes: maximum allowed contig number in array 3. dis: contig's distance to base contig Output: None. Return: 1 if contig was already in array or putting operation succeeds. 0 if array size was larger than cutoff or contig's reverse complement format was already in array. *************************************************/ static boolean putNodeInArray ( unsigned int node, int maxNodes, int dis ) { if ( contig_array[node].inSubGraph ) { return 1; } int index = nodeCounter; if ( index > maxNodes ) { return 0; } if ( contig_array[getTwinCtg ( node )].inSubGraph ) { return 0; } ctg4heapArray[index].ctgID = node; ctg4heapArray[index].dis = dis; contig_array[node].inSubGraph = 1; ctg4heapArray[index].ds_shut4dheap = 0; ctg4heapArray[index].us_shut4dheap = 0; ctg4heapArray[index].ds_shut4uheap = 0; ctg4heapArray[index].us_shut4uheap = 0; return 1; } /************************************************* Function: setInGraph Description: Sets contig's status of "inSubGraph". Input: 1. flag: new status. Output: None. Return: None. *************************************************/ static void setInGraph ( boolean flag ) { int i; int node; nodeCounter = nodeCounter > MaxNodeInSub ? MaxNodeInSub : nodeCounter; for ( i = 1; i <= nodeCounter; i++ ) { node = ctg4heapArray[i].ctgID; if ( node > 0 ) { contig_array[node].inSubGraph = flag; } } } /************************************************* Function: getIndexInArr Description: Gets contig's index in "ctg4heapArray". Input: 1. node: contig. Output: None. Return: Contig's index if contig was in array. 0 otherwise. *************************************************/ static int getIndexInArr ( const unsigned int node ) { int i = 1; for ( ; i <= nodeCounter; ++i ) { if ( node == ctg4heapArray[i].ctgID ) { return i; } } return 0; } /************************************************* Function: dispatch1node Description: Dispatchs a contig to heap according to its distance to base contig, then updates related information of heaps. Input: 1. dis: distance to base contig 2. tempNode: contig to be dispatched 3. maxNodes: maximum allowed contig number in sub-graph 4. dheap: heap for downstream contigs of base contig 5. uheap: heap for upstream contigs of base contig 6. DmaxDis: maximum distance of downstream contig to base contig 7. UmaxDis: maximum distance of upstream contig to base contig Output: 1. dheap: updated heap for downstream contigs 2. uheap: updated heap for upstream contigs 3. DmaxDis: updated maximum distance of downstream contig to base contig 4. UmaxDis: updated maximum distance of upstream contig to base contig Return: 1 if contig was dispatched to "dheap". -1 if contig was dispatched to "uheap". 0 otherwise. *************************************************/ static boolean dispatch1node ( int dis, unsigned int tempNode, int maxNodes, FibHeap * dheap, FibHeap * uheap, int * DmaxDis, int * UmaxDis ) { boolean ret; if ( dis >= 0 ) // put it to Dheap { nodeCounter++; ret = putNodeInArray ( tempNode, maxNodes, dis ); if ( !ret ) { return 0; } insertNodeIntoHeap ( dheap, dis, nodeCounter ); if ( dis > *DmaxDis ) { *DmaxDis = dis; } return 1; } else // put it to Uheap { nodeCounter++; ret = putNodeInArray ( tempNode, maxNodes, dis ); if ( !ret ) { return 0; } insertNodeIntoHeap ( uheap, -dis, nodeCounter ); int temp_len = contig_array[tempNode].length; if ( -dis + temp_len > *UmaxDis ) { *UmaxDis = -dis + contig_array[tempNode].length; } return -1; } return 0; } /************************************************* Function: canDheapWait Description: Checks whether current contig is the furthest contig to base contig in 'dheap'. Input: 1. currNode: current contig 2. dis: current contig's distance to base contig 3. DmaxDis: maximum distance of downstream contig to base contig Output: None. Return: 0 if current contig was not the furthest contig. *************************************************/ static boolean canDheapWait ( unsigned int currNode, int dis, int DmaxDis ) { if ( dis < DmaxDis ) { return 0; } else { return 1; } } /************************************************* Function: workOnDheap Description: Travers 'dheap' and adds related contigs into 'dheap' or 'uheap'. Input: 1. dheap: heap for downstream contigs of base contig 2. uheap: heap for upstream contigs of base contig 3. Dwait: indicator of whether all contigs in 'dheap' have been traversed, 1 for yes 4. Uwait: indicator of whether all contigs in 'uheap' have been traversed, 1 for yes 5. DmaxDis: maximum distance of downstream contig to base contig 6. UmaxDis: maximum distance of upstream contig to base contig 7. maxNodes: maximum allowed contig number in sub-graph Output: 1. dheap: updated heap for downstream contigs 2. uheap: updated heap for upstream contigs 3. Dwait: indicator of whether all contigs in 'dheap' have been traversed, 1 for yes 4. Uwait: indicator of whether all contigs in 'uheap' have been traversed, 1 for yes 5. DmaxDis: updated maximum distance of downstream contig to base contig 6. UmaxDis: updated maximum distance of upstream contig to base contig Return: 0 if operation of putting contig into sub-graph failed. *************************************************/ static boolean workOnDheap ( FibHeap * dheap, FibHeap * uheap, boolean * Dwait, boolean * Uwait, int * DmaxDis, int * UmaxDis, int maxNodes ) { if ( *Dwait ) { return 1; } unsigned int currNode, twin, tempNode; CTGinHEAP * ctgInHeap; int indexInArray; CONNECT * us_cnt, *ds_cnt; int dis0, dis; boolean ret, isEmpty; while ( ( indexInArray = removeNextNodeFromHeap ( dheap ) ) != 0 ) { ctgInHeap = &ctg4heapArray[indexInArray]; currNode = ctgInHeap->ctgID; dis0 = ctgInHeap->dis; isEmpty = IsHeapEmpty ( dheap ); twin = getTwinCtg ( currNode ); us_cnt = ctgInHeap->us_shut4dheap ? NULL : contig_array[twin].downwardConnect; while ( us_cnt ) { if ( us_cnt->deleted || us_cnt->mask || contig_array[getTwinCtg ( us_cnt->contigID )].inSubGraph ) { us_cnt = us_cnt->next; continue; } tempNode = getTwinCtg ( us_cnt->contigID ); if ( contig_array[tempNode].inSubGraph ) { us_cnt = us_cnt->next; continue; } dis = dis0 - us_cnt->gapLen - ( int ) contig_array[twin].length; ret = dispatch1node ( dis, tempNode, maxNodes, dheap, uheap, DmaxDis, UmaxDis ); if ( ret == 0 ) { return 0; } else if ( ret < 0 ) { *Uwait = 0; } us_cnt = us_cnt->next; } if ( nodeCounter > 1 && isEmpty ) { *Dwait = canDheapWait ( currNode, dis0, *DmaxDis ); if ( *Dwait ) { isEmpty = IsHeapEmpty ( dheap ); insertNodeIntoHeap ( dheap, dis0, indexInArray ); ctg4heapArray[indexInArray].us_shut4dheap = 1; if ( isEmpty ) { return 1; } else { continue; } } } ds_cnt = ctgInHeap->ds_shut4dheap ? NULL : contig_array[currNode].downwardConnect; while ( ds_cnt ) { if ( ds_cnt->deleted || ds_cnt->mask || contig_array[ds_cnt->contigID].inSubGraph ) { ds_cnt = ds_cnt->next; continue; } tempNode = ds_cnt->contigID; dis = dis0 + ds_cnt->gapLen + ( int ) contig_array[tempNode].length; ret = dispatch1node ( dis, tempNode, maxNodes, dheap, uheap, DmaxDis, UmaxDis ); if ( ret == 0 ) { return 0; } else if ( ret < 0 ) { *Uwait = 0; } ds_cnt = ds_cnt->next; } // for each downstream connections } // for each node comes off the heap *Dwait = 1; return 1; } /************************************************* Function: canUheapWait Description: Checks whether current contig is the furthest contig to base contig in "uheap". Input: 1. currNode: current contig 2. dis: current contig's distance to base contig 3. DmaxDis: maximum distance of downstream contig to base contig Output: None. Return: 0 if current contig was not the furthest contig. *************************************************/ static boolean canUheapWait ( unsigned int currNode, int dis, int UmaxDis ) { int temp_len = contig_array[currNode].length; if ( -dis + temp_len < UmaxDis ) { return 0; } else { return 1; } } /************************************************* Function: workOnUheap Description: Travers 'uheap' and adds related contigs into "dheap" or "uheap". Input: 1. dheap: heap for downstream contigs of base contig 2. uheap: heap for upstream contigs of base contig 3. Dwait: indicator of whether all contigs in 'dheap' have been traversed, 1 for yes 4. Uwait: indicator of whether all contigs in 'uheap' have been traversed, 1 for yes 5. DmaxDis: maximum distance of downstream contig to base contig 6. UmaxDis: maximum distance of upstream contig to base contig 7. maxNodes: maximum allowed contig number in sub-graph Output: 1. dheap: updated heap for downstream contigs 2. uheap: updated heap for upstream contigs 3. Dwait: indicator of whether all contigs in "dheap" have been traversed, 1 for yes 4. Uwait: indicator of whether all contigs in "uheap" have been traversed, 1 for yes 5. DmaxDis: updated maximum distance of downstream contig to base contig 6. UmaxDis: updated maximum distance of upstream contig to base contig Return: 0 if operation of putting contig into sub-graph failed. *************************************************/ static boolean workOnUheap ( FibHeap * dheap, FibHeap * uheap, boolean * Dwait, boolean * Uwait, int * DmaxDis, int * UmaxDis, int maxNodes ) { if ( *Uwait ) { return 1; } unsigned int currNode, twin, tempNode; CTGinHEAP * ctgInHeap; int indexInArray; CONNECT * us_cnt, *ds_cnt; int dis0, dis; boolean ret, isEmpty; while ( ( indexInArray = removeNextNodeFromHeap ( uheap ) ) != 0 ) { ctgInHeap = &ctg4heapArray[indexInArray]; currNode = ctgInHeap->ctgID; dis0 = ctgInHeap->dis; isEmpty = IsHeapEmpty ( uheap ); ds_cnt = ctgInHeap->ds_shut4uheap ? NULL : contig_array[currNode].downwardConnect; while ( ds_cnt ) { if ( ds_cnt->deleted || ds_cnt->mask || contig_array[ds_cnt->contigID].inSubGraph ) { ds_cnt = ds_cnt->next; continue; } tempNode = ds_cnt->contigID; dis = dis0 + ds_cnt->gapLen + contig_array[tempNode].length; ret = dispatch1node ( dis, tempNode, maxNodes, dheap, uheap, DmaxDis, UmaxDis ); if ( ret == 0 ) { return 0; } else if ( ret > 0 ) { *Dwait = 0; } ds_cnt = ds_cnt->next; } // for each downstream connections if ( nodeCounter > 1 && isEmpty ) { *Uwait = canUheapWait ( currNode, dis0, *UmaxDis ); if ( *Uwait ) { isEmpty = IsHeapEmpty ( uheap ); insertNodeIntoHeap ( uheap, dis0, indexInArray ); ctg4heapArray[indexInArray].ds_shut4uheap = 1; if ( isEmpty ) { return 1; } else { continue; } } } twin = getTwinCtg ( currNode ); us_cnt = ctgInHeap->us_shut4uheap ? NULL : contig_array[twin].downwardConnect; while ( us_cnt ) { if ( us_cnt->deleted || us_cnt->mask || contig_array[getTwinCtg ( us_cnt->contigID )].inSubGraph ) { us_cnt = us_cnt->next; continue; } tempNode = getTwinCtg ( us_cnt->contigID ); if ( contig_array[tempNode].inSubGraph ) { us_cnt = us_cnt->next; continue; } dis = dis0 - us_cnt->gapLen - contig_array[twin].length; ret = dispatch1node ( dis, tempNode, maxNodes, dheap, uheap, DmaxDis, UmaxDis ); if ( ret == 0 ) { return 0; } else if ( ret > 0 ) { *Dwait = 0; } us_cnt = us_cnt->next; } } // for each node comes off the heap *Uwait = 1; return 1; } /************************************************* Function: pickUpGeneralSubgraph Description: Starting from a base contig, gathers related contigs to form a sub-graph. Input: 1. node1: base contig 2. maxNodes: maximum allowed contig number in sub-graph Output: None. Return: 0 if sub-graph was not found. *************************************************/ static boolean pickUpGeneralSubgraph ( unsigned int node1, int maxNodes ) { FibHeap * Uheap = newFibHeap(); // heap for upstream contigs to node1 FibHeap * Dheap = newFibHeap(); int UmaxDis; // max distance upstream to node1 int DmaxDis; boolean Uwait; // wait signal for Uheap boolean Dwait; int dis; boolean ret; //initiate: node1 is put to array once, and to both Dheap and Uheap dis = 0; nodeCounter = 1; putNodeInArray ( node1, maxNodes, dis ); insertNodeIntoHeap ( Dheap, dis, nodeCounter ); ctg4heapArray[nodeCounter].us_shut4dheap = 1; Dwait = 0; DmaxDis = 0; insertNodeIntoHeap ( Uheap, dis, nodeCounter ); ctg4heapArray[nodeCounter].ds_shut4uheap = 1; Uwait = 1; UmaxDis = contig_array[node1].length; while ( 1 ) { ret = workOnDheap ( Dheap, Uheap, &Dwait, &Uwait, &DmaxDis, &UmaxDis, maxNodes ); if ( !ret ) { setInGraph ( 0 ); destroyHeap ( Dheap ); destroyHeap ( Uheap ); return 0; } ret = workOnUheap ( Dheap, Uheap, &Dwait, &Uwait, &DmaxDis, &UmaxDis, maxNodes ); if ( !ret ) { setInGraph ( 0 ); destroyHeap ( Dheap ); destroyHeap ( Uheap ); return 0; } if ( Uwait && Dwait ) { destroyHeap ( Dheap ); destroyHeap ( Uheap ); return 1; } } } /************************************************* Function: cmp_ctg Description: Compares two contigs according to their distances to base contig. Input: 1. a: pointer to the first contig in heap 2. b: pointer to the second contig in heap Output: None. Return: 1 if the first contig was further than the second contig. -1 if the second contig was further than the first contig. 0 if the distances were equal. *************************************************/ static int cmp_ctg ( const void * a, const void * b ) { CTGinHEAP * A, *B; A = ( CTGinHEAP * ) a; B = ( CTGinHEAP * ) b; if ( A->dis > B->dis ) { return 1; } else if ( A->dis == B->dis ) { return 0; } else { return -1; } } /************************************************* Function: checkEligible Description: Checks if the sub-graph accords with the follwing criterions: 1. The reversed complement of the first contig has neither downstream connection to contigs in sub-graph, nor more than one upstream connections in scaffold. 2. The last contig has neither downstream connection to reversed complement of any contig in sub-graph, nor more than one upstream connections in scaffold. 3. Except the first and the last contigs, none of other contigs in sub-graph has connection to contig which is out of sub-graph. Input: None. Output: None. Return: 1 if the sub-graph accorded with all above criterions. *************************************************/ static boolean checkEligible() { unsigned int firstNode = ctg4heapArray[1].ctgID; unsigned int twin; int i; boolean flag = 0; //check if the first node has incoming link from twin of any node in subgraph // or it has multi outgoing links bound to incoming links twin = getTwinCtg ( firstNode ); CONNECT * ite_cnt = contig_array[twin].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->deleted || ite_cnt->mask ) { ite_cnt = ite_cnt->next; continue; } if ( contig_array[ite_cnt->contigID].inSubGraph ) { return 0; } if ( ite_cnt->prevInScaf ) { if ( flag ) { return 0; } flag = 1; } ite_cnt = ite_cnt->next; } //check if the last node has outgoing link to twin of any node in subgraph // or it has multi outgoing links bound to incoming links unsigned int lastNode = ctg4heapArray[nodeCounter].ctgID; ite_cnt = contig_array[lastNode].downwardConnect; flag = 0; while ( ite_cnt ) { if ( ite_cnt->deleted || ite_cnt->mask ) { ite_cnt = ite_cnt->next; continue; } twin = getTwinCtg ( ite_cnt->contigID ); if ( contig_array[twin].inSubGraph ) { return 0; } if ( ite_cnt->prevInScaf ) { if ( flag ) { return 0; } flag = 1; } ite_cnt = ite_cnt->next; } //check if any node has outgoing link to node outside the subgraph for ( i = 1; i < nodeCounter; i++ ) { ite_cnt = contig_array[ctg4heapArray[i].ctgID].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->deleted || ite_cnt->mask ) { ite_cnt = ite_cnt->next; continue; } if ( !contig_array[ite_cnt->contigID].inSubGraph ) { return 0; } ite_cnt = ite_cnt->next; } } //check if any node has incoming link from node outside the subgraph for ( i = 2; i <= nodeCounter; i++ ) { twin = getTwinCtg ( ctg4heapArray[i].ctgID ); ite_cnt = contig_array[twin].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->deleted || ite_cnt->mask ) { ite_cnt = ite_cnt->next; continue; } if ( !contig_array[getTwinCtg ( ite_cnt->contigID )].inSubGraph ) { return 0; } ite_cnt = ite_cnt->next; } } return 1; } /************************************************* Function: arrayvalue Description: Copies one contig's values to another in array. Input: 1. init_array: pointer to target contig in array 2. value_array: pointer to source contig in array Output: None. Return: None. *************************************************/ static void arrayvalue ( CTGinHEAP * init_array, CTGinHEAP * value_array ) { init_array->ctgID = value_array->ctgID; init_array->dis = value_array->dis; init_array->ds_shut4dheap = value_array->ds_shut4dheap; init_array->ds_shut4uheap = value_array->ds_shut4uheap; init_array->us_shut4dheap = value_array->us_shut4dheap; init_array->us_shut4uheap = value_array->us_shut4uheap; } /************************************************* Function: arrayexchange Description: Exchanges two contigs' values. Input: 1. from_id: the first contig in array 2. to_id: the second contig in array Output: None. Return: None. *************************************************/ static void arrayexchange ( unsigned int from_id, unsigned int to_id ) { CTGinHEAP tmp_h; arrayvalue ( &tmp_h, & ( ctg4heapArray[from_id] ) ); arrayvalue ( & ( ctg4heapArray[from_id] ), & ( ctg4heapArray[to_id] ) ); arrayvalue ( & ( ctg4heapArray[to_id] ), &tmp_h ); } static void deletearray ( unsigned int id ) { int i; for ( i = 1; i < nodeCounter; i++ ) { if ( i >= id ) { arrayvalue ( & ( ctg4heapArray[i] ), & ( ctg4heapArray[i + 1] ) ); } } nodeCounter--; } int getnextInScafCtg ( int id, int mask, int flag ) { CONNECT * tmp_cn = contig_array[id].downwardConnect; int currId = 0; while ( tmp_cn ) { if ( tmp_cn->prevInScaf ) { currId = tmp_cn->contigID; if ( mask != 0 && tmp_cn->contigID != mask ) { break; } } tmp_cn = tmp_cn->next; } if ( mask == currId && mask != 0 ) { currId = 0; } if ( flag == 0 && currId != 0 ) { currId = getTwinCtg ( currId ); } return currId; } void delete_PrevNext ( int i, int flag ) { int id = ctg4heapArray[i].ctgID; int pid = getTwinCtg ( id ); CONNECT * ite_cnt = contig_array[id].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->mask || ite_cnt->deleted || !contig_array[ite_cnt->contigID].inSubGraph ) { ite_cnt = ite_cnt->next; continue; } if ( flag == 1 ) { setNextInScaf ( ite_cnt, NULL ); } if ( flag == 0 ) { setPrevInScaf ( ite_cnt, 0 ); } ite_cnt = ite_cnt->next; } ite_cnt = contig_array[pid].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->mask || ite_cnt->deleted || !contig_array[ite_cnt->contigID].inSubGraph ) { ite_cnt = ite_cnt->next; continue; } if ( flag == 0 ) { setNextInScaf ( ite_cnt, NULL ); } if ( flag == 1 ) { setPrevInScaf ( ite_cnt, 0 ); } ite_cnt = ite_cnt->next; } } /************************************************* Function: getCntNodes Description: Gets contig's downstream connection provided by short insert size paired-end reads. Input: 1. node: contig Output: 1. nodeArray: array to store downstream contigs 2. gapArray: array to store distance from current contig to downstream contigs Return: Found downstream contig number. *************************************************/ static int getCntNodes ( unsigned int node, unsigned int * nodeArray, unsigned int * gapArray ) { int count = 0; CONNECT * cnt = contig_array[node].downwardConnect; while ( cnt ) { if ( 0 == bySmall && cnt->weight < 3 && !cnt->smallIns && !cnt->bySmall ) { cnt = cnt->next; continue; } nodeArray[count] = cnt->contigID; gapArray[count++] = cnt->gapLen; if ( count == MaxCntNode ) { break; } cnt = cnt->next; } return count; } /************************************************* Function: calGapLen Description: Calculates two contigs' distance through the common contig to which both contigs connected. Input: 1. cntCounter: contig numbet in the "cntNodeArr" 2. cntNodeArr: the array of third-party contigs 3. cntGapArr: the array of distances to third-party contigs 4. node1: the first contig 5. node2: the second contig 6. tmpNode: the contig whose upstream/downstream contigs array was not selected as "cntNodeArr" Output: 1. cntCounter: common contig number of these two contigs Return: Accumulated distance between these two contigs. *************************************************/ static int calGapLen ( int * cntCounter, unsigned int * cntNodeArr, int * cntGapArr, unsigned int node1, unsigned int node2, unsigned int tmpNode ) { int i = 0, gapLen = 0, count = 0; unsigned int target_node; CONNECT * cnt; int len = contig_array[node2].length; for ( ; i < *cntCounter; ++i ) { cnt = getCntBetween ( tmpNode, cntNodeArr[i] ); if ( cnt && ( cnt->weight >= 3 || bySmall || cnt->smallIns || cnt->bySmall ) ) { if ( tmpNode == node1 ) { gapLen += cnt->gapLen - cntGapArr[i] - len; } else { gapLen += cntGapArr[i] - cnt->gapLen - len; } ++count; } } *cntCounter = count; return gapLen; } /************************************************* Function: arrangeNodes_general Description: Arranges contigs in sub-graph and updates related relation. Input: None. Output: None. Return: None. *************************************************/ static void arrangeNodes_general() { int i, j, gap, adjustedGap; CONNECT * ite_cnt, *temp_cnt, *bal_cnt, *prev_cnt, *next_cnt, *dh_cnt, *three_cnt; unsigned int node1, node2, tmpNode; unsigned int bal_nd1, bal_nd2; unsigned int pre_node, bal_pre_node, next_node, bal_next_node; // pre/next node that connected to first/last node if there is unsigned int first_node, bal_first_node, last_node, bal_last_node; unsigned int affected_node1, bal_affected_node1, affected_node2, bal_affected_node2; unsigned int exchangeNode1 = 0, exchangeNode2 = 0; int cntCounter, comCount; int tmp_dis; //delete original connections for ( i = 1; i <= nodeCounter; i++ ) { node1 = ctg4heapArray[i].ctgID; ite_cnt = contig_array[node1].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->mask || ite_cnt->deleted || !contig_array[ite_cnt->contigID].inSubGraph ) { ite_cnt = ite_cnt->next; continue; } ite_cnt->deleted = 1; setNextInScaf ( ite_cnt, NULL ); setPrevInScaf ( ite_cnt, 0 ); ite_cnt = ite_cnt->next; } bal_nd1 = getTwinCtg ( node1 ); ite_cnt = contig_array[bal_nd1].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->mask || ite_cnt->deleted || !contig_array[getTwinCtg ( ite_cnt->contigID )].inSubGraph ) { ite_cnt = ite_cnt->next; continue; } ite_cnt->deleted = 1; setNextInScaf ( ite_cnt, NULL ); setPrevInScaf ( ite_cnt, 0 ); ite_cnt = ite_cnt->next; } } CONNECT * first_cnt = NULL, *last_cnt = NULL, *tmp_cnt; CONNECT * affected_cnt = NULL, *bal_affected_cnt = NULL; //connections connected to pre_cnt and next_cnt pre_node = bal_pre_node = next_node = bal_next_node = 0; first_node = ctg4heapArray[1].ctgID; bal_first_node = getTwinCtg ( first_node ); ite_cnt = contig_array[bal_first_node].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->deleted || ite_cnt->mask ) { ite_cnt = ite_cnt->next; continue; } if ( ite_cnt->prevInScaf ) { if ( !first_cnt ) { first_cnt = ite_cnt; } bal_pre_node = ite_cnt->contigID; pre_node = getTwinCtg ( bal_pre_node ); tmp_cnt = getCntBetween ( pre_node, first_node ); } ite_cnt = ite_cnt->next; } last_node = ctg4heapArray[nodeCounter].ctgID; bal_last_node = getTwinCtg ( last_node ); ite_cnt = contig_array[last_node].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->deleted || ite_cnt->mask ) { ite_cnt = ite_cnt->next; continue; } if ( ite_cnt->prevInScaf ) { if ( !last_cnt ) { last_cnt = ite_cnt; } next_node = ite_cnt->contigID; bal_next_node = getTwinCtg ( next_node ); tmp_cnt = getCntBetween ( bal_next_node, bal_last_node ); } ite_cnt = ite_cnt->next; } prev_cnt = next_cnt = NULL; for ( i = 1; i < nodeCounter; ++i ) { node1 = ctg4heapArray[i].ctgID; node2 = ctg4heapArray[i + 1].ctgID; bal_nd1 = getTwinCtg ( node1 ); bal_nd2 = getTwinCtg ( node2 ); gap = ctg4heapArray[i + 1].dis - ctg4heapArray[i].dis - contig_array[node2].length; temp_cnt = getCntBetween ( node1, node2 ); dh_cnt = getCntBetween ( node2, node1 ); if ( i >= 2 ) { three_cnt = getCntBetween ( ctg4heapArray[i - 1].ctgID, node2 ); } if ( dh_cnt ) { tmp_dis = ( int ) contig_array[node1].length + ( int ) contig_array[node2].length + gap + dh_cnt->gapLen; } else { tmp_dis = -1; } if ( temp_cnt && ( bySmall || temp_cnt->bySmall || temp_cnt->smallIns || !dh_cnt || !dh_cnt->bySmall || !dh_cnt->smallIns ) ) { temp_cnt->deleted = 0; temp_cnt->mask = 0; bal_cnt = getCntBetween ( bal_nd2, bal_nd1 ); bal_cnt->deleted = 0; bal_cnt->mask = 0; } else if ( dh_cnt && ( ( dh_cnt->bySmall || dh_cnt->smallIns || bySmall ) || ( ( -gap > ( int ) contig_array[node1].length || -gap > ( int ) contig_array[node2].length ) && tmp_dis > 0 && tmp_dis < 500 && dh_cnt->weight > 3 ) ) ) { dh_cnt->deleted = 0; dh_cnt->mask = 0; dh_cnt = getCntBetween ( bal_nd1, bal_nd2 ); dh_cnt->deleted = 0; dh_cnt->mask = 0; arrayexchange ( i, i + 1 ); if ( i == 1 ) { i = 0; continue; } if ( i == 2 ) { prev_cnt->deleted = 1; prev_cnt = NULL; next_cnt->deleted = 1; next_cnt = NULL; i = 0; continue; } bal_affected_node2 = next_cnt->contigID; affected_node2 = getTwinCtg ( bal_affected_node2 ); bal_affected_cnt = next_cnt->nextInScaf; bal_affected_node1 = bal_affected_cnt->contigID; affected_node1 = getTwinCtg ( bal_affected_node1 ); affected_cnt = getCntBetween ( affected_node1, affected_node2 ); if ( !affected_cnt ) { fprintf ( stderr, "affected cnt between %u(%u) and %u(%u) doesn't exists!\n", affected_node1, bal_affected_node1, affected_node2, bal_affected_node2 ); exit ( 1 ); } setNextInScaf ( affected_cnt, NULL ); setPrevInScaf ( bal_affected_cnt, 0 ); setNextInScaf ( next_cnt, NULL ); setPrevInScaf ( prev_cnt, 0 ); prev_cnt->deleted = 1; prev_cnt = NULL; next_cnt->deleted = 1; next_cnt = NULL; i -= 3; continue; } else { if ( ( bySmall > 0 && gap < 0 ) || ( -gap > ( int ) contig_array[node1].length || -gap > ( int ) contig_array[node2].length ) && ( i != nodeCounter - 1 ) ) { adjustedGap = comCount = 0; uCntCounter1 = getCntNodes ( getTwinCtg ( node1 ), uCntNodeArr1, uCntGapArr1 ); dCntCounter1 = getCntNodes ( node1, dCntNodeArr1, dCntGapArr1 ); uCntCounter2 = getCntNodes ( getTwinCtg ( node2 ), uCntNodeArr2, uCntGapArr2 ); dCntCounter2 = getCntNodes ( node2, dCntNodeArr2, dCntGapArr2 ); if ( uCntCounter1 < uCntCounter2 ) { tmpNode = getTwinCtg ( node2 ); cntCounter = uCntCounter1; cntNodeArr = &uCntNodeArr1[0]; cntGapArr = &uCntGapArr1[0]; } else { tmpNode = getTwinCtg ( node1 ); cntCounter = uCntCounter2; cntNodeArr = &uCntNodeArr2[0]; cntGapArr = &uCntGapArr2[0]; } adjustedGap += calGapLen ( &cntCounter, cntNodeArr, cntGapArr, getTwinCtg ( node2 ), getTwinCtg ( node1 ), tmpNode ); comCount += cntCounter; if ( dCntCounter1 < dCntCounter2 ) { tmpNode = node2; cntCounter = dCntCounter1; cntNodeArr = &dCntNodeArr1[0]; cntGapArr = &dCntGapArr1[0]; } else { tmpNode = node1; cntCounter = dCntCounter2; cntNodeArr = &dCntNodeArr2[0]; cntGapArr = &dCntGapArr2[0]; } adjustedGap += calGapLen ( &cntCounter, cntNodeArr, cntGapArr, node1, node2, tmpNode ); comCount += cntCounter; if ( comCount > 0 ) { gap = adjustedGap / comCount; } } if ( ( -gap > ( int ) contig_array[node1].length || -gap > ( int ) contig_array[node2].length ) && ( i != nodeCounter - 1 ) && ( ( exchangeNode1 == 0 && exchangeNode2 == 0 ) || ( exchangeNode1 != ctg4heapArray[i + 1].ctgID && exchangeNode2 != ctg4heapArray[i].ctgID ) ) ) { exchangeNode1 = ctg4heapArray[i].ctgID; exchangeNode2 = ctg4heapArray[i + 1].ctgID; arrayexchange ( i, i + 1 ); if ( i == 1 ) { i--; continue; } if ( i == 2 ) { prev_cnt->deleted = 1; prev_cnt = NULL; next_cnt->deleted = 1; next_cnt = NULL; i = 0; continue; } bal_affected_node2 = next_cnt->contigID; affected_node2 = getTwinCtg ( bal_affected_node2 ); bal_affected_cnt = next_cnt->nextInScaf; bal_affected_node1 = bal_affected_cnt->contigID; affected_node1 = getTwinCtg ( bal_affected_node1 ); affected_cnt = getCntBetween ( affected_node1, affected_node2 ); if ( !affected_cnt ) { fprintf ( stderr, "affected cnt between %u(%u) and %u(%u) doesn't exists!\n", affected_node1, bal_affected_node1, affected_node2, bal_affected_node2 ); exit ( 1 ); } setNextInScaf ( affected_cnt, NULL ); setPrevInScaf ( bal_affected_cnt, 0 ); setNextInScaf ( next_cnt, NULL ); setPrevInScaf ( prev_cnt, 0 ); prev_cnt->deleted = 1; prev_cnt = NULL; next_cnt->deleted = 1; next_cnt = NULL; i -= 3; continue; } temp_cnt = allocateCN ( node2, gap ); if ( cntLookupTable ) { putCnt2LookupTable ( node1, temp_cnt ); } temp_cnt->weight = 0; temp_cnt->next = contig_array[node1].downwardConnect; contig_array[node1].downwardConnect = temp_cnt; bal_cnt = allocateCN ( bal_nd1, gap ); if ( cntLookupTable ) { putCnt2LookupTable ( bal_nd2, bal_cnt ); } bal_cnt->weight = 0; bal_cnt->next = contig_array[bal_nd2].downwardConnect; contig_array[bal_nd2].downwardConnect = bal_cnt; } if ( prev_cnt ) { setNextInScaf ( prev_cnt, temp_cnt ); setPrevInScaf ( temp_cnt, 1 ); } if ( next_cnt ) { setNextInScaf ( bal_cnt, next_cnt ); setPrevInScaf ( next_cnt, 1 ); } prev_cnt = temp_cnt; next_cnt = bal_cnt; } if ( first_cnt ) { if ( ctg4heapArray[1].ctgID == first_node ) { bal_nd1 = first_cnt->contigID; node1 = getTwinCtg ( bal_nd1 ); node2 = first_node; temp_cnt = checkConnect ( node1, node2 ); bal_cnt = first_cnt; next_cnt = checkConnect ( ctg4heapArray[1].ctgID, ctg4heapArray[2].ctgID ); prev_cnt = checkConnect ( getTwinCtg ( ctg4heapArray[2].ctgID ), getTwinCtg ( ctg4heapArray[1].ctgID ) ); if ( temp_cnt ) { setNextInScaf ( temp_cnt, next_cnt ); setPrevInScaf ( temp_cnt->nextInScaf, 0 ); setPrevInScaf ( next_cnt, 1 ); setNextInScaf ( prev_cnt, bal_cnt ); } } else { bal_pre_node = first_cnt->contigID; pre_node = getTwinCtg ( bal_pre_node ); j = 1; node1 = ctg4heapArray[j].ctgID; node2 = ctg4heapArray[j + 1].ctgID; ite_cnt = getCntBetween ( pre_node, node1 ); bal_cnt = getCntBetween ( getTwinCtg ( node1 ), bal_pre_node ); while ( !ite_cnt && node2 != first_node ) { tmp_cnt = getCntBetween ( node1, node2 ); bal_cnt = getCntBetween ( getTwinCtg ( node2 ), getTwinCtg ( node1 ) ); setNextInScaf ( tmp_cnt, NULL ); setPrevInScaf ( tmp_cnt, 0 ); tmp_cnt->deleted = 1; setNextInScaf ( bal_cnt, NULL ); setPrevInScaf ( bal_cnt, 0 ); bal_cnt->deleted = 1; ++j; node1 = ctg4heapArray[j].ctgID; node2 = ctg4heapArray[j + 1].ctgID; ite_cnt = getCntBetween ( pre_node, node1 ); bal_cnt = getCntBetween ( getTwinCtg ( node1 ), bal_pre_node ); } if ( !ite_cnt ) { tmp_cnt = getCntBetween ( node1, first_node ); gap = first_cnt->gapLen - tmp_cnt->gapLen - contig_array[node1].length; ite_cnt = allocateCN ( node1, gap ); ite_cnt->weight = 0; if ( cntLookupTable ) { putCnt2LookupTable ( pre_node, ite_cnt ); } ite_cnt->next = contig_array[pre_node].downwardConnect; contig_array[pre_node].downwardConnect = ite_cnt; bal_cnt = allocateCN ( bal_pre_node, gap ); bal_cnt->weight = 0; if ( cntLookupTable ) { putCnt2LookupTable ( getTwinCtg ( node1 ), bal_cnt ); } bal_cnt->next = contig_array[getTwinCtg ( node1 )].downwardConnect; contig_array[getTwinCtg ( node1 )].downwardConnect = bal_cnt; } ite_cnt->deleted = 0; ite_cnt->mask = 0; bal_cnt->deleted = 0; bal_cnt->mask = 0; tmp_cnt = getCntBetween ( node1, node2 ); setNextInScaf ( ite_cnt, tmp_cnt ); setPrevInScaf ( tmp_cnt, 1 ); tmp_cnt = getCntBetween ( getTwinCtg ( node2 ), getTwinCtg ( node1 ) ); setNextInScaf ( tmp_cnt, bal_cnt ); setPrevInScaf ( bal_cnt, 1 ); if ( first_cnt->nextInScaf ) { setNextInScaf ( bal_cnt, first_cnt->nextInScaf ); bal_affected_node1 = first_cnt->nextInScaf->contigID; affected_node1 = getTwinCtg ( bal_affected_node1 ); affected_cnt = getCntBetween ( affected_node1, pre_node ); setNextInScaf ( affected_cnt, ite_cnt ); setPrevInScaf ( ite_cnt, 1 ); } setNextInScaf ( first_cnt, NULL ); setPrevInScaf ( first_cnt, 0 ); first_cnt->deleted = 1; first_cnt->mask = 1; tmp_cnt = getCntBetween ( pre_node, first_node ); setNextInScaf ( tmp_cnt, NULL ); setPrevInScaf ( tmp_cnt, 0 ); tmp_cnt->deleted = 1; tmp_cnt->mask = 1; } } if ( last_cnt ) { node1 = ctg4heapArray[nodeCounter].ctgID; if ( node1 == last_node ) { node2 = last_cnt->contigID; bal_nd1 = getTwinCtg ( node1 ); bal_nd2 = getTwinCtg ( node2 ); temp_cnt = last_cnt; bal_cnt = checkConnect ( bal_nd2, bal_nd1 ); next_cnt = checkConnect ( getTwinCtg ( ctg4heapArray[nodeCounter].ctgID ), getTwinCtg ( ctg4heapArray[nodeCounter - 1].ctgID ) ); prev_cnt = checkConnect ( ctg4heapArray[nodeCounter - 1].ctgID, ctg4heapArray[nodeCounter].ctgID ); setNextInScaf ( prev_cnt, temp_cnt ); setNextInScaf ( bal_cnt, next_cnt ); setPrevInScaf ( next_cnt, 1 ); } else { next_node = last_cnt->contigID; bal_next_node = getTwinCtg ( next_node ); j = nodeCounter; node1 = ctg4heapArray[j - 1].ctgID; node2 = ctg4heapArray[j].ctgID; ite_cnt = getCntBetween ( node2, next_node ); bal_cnt = getCntBetween ( bal_next_node, getTwinCtg ( node2 ) ); while ( !ite_cnt && node1 != last_node ) { tmp_cnt = getCntBetween ( node1, node2 ); bal_cnt = getCntBetween ( getTwinCtg ( node2 ), getTwinCtg ( node1 ) ); setNextInScaf ( tmp_cnt, NULL ); setPrevInScaf ( tmp_cnt, 0 ); tmp_cnt->deleted = 1; setNextInScaf ( bal_cnt, NULL ); setPrevInScaf ( bal_cnt, 0 ); bal_cnt->deleted = 1; --j; node1 = ctg4heapArray[j - 1].ctgID; node2 = ctg4heapArray[j].ctgID; ite_cnt = getCntBetween ( node2, next_node ); bal_cnt = getCntBetween ( bal_next_node, getTwinCtg ( node2 ) ); } if ( !ite_cnt ) { tmp_cnt = getCntBetween ( node1, node2 ); gap = last_cnt->gapLen - tmp_cnt->gapLen - contig_array[node2].length; ite_cnt = allocateCN ( next_node, gap ); ite_cnt->weight = 0; if ( cntLookupTable ) { putCnt2LookupTable ( node2, ite_cnt ); } ite_cnt->next = contig_array[node2].downwardConnect; contig_array[node2].downwardConnect = ite_cnt; bal_cnt = allocateCN ( getTwinCtg ( node2 ), gap ); bal_cnt->weight = 0; if ( cntLookupTable ) { putCnt2LookupTable ( bal_next_node, bal_cnt ); } bal_cnt->next = contig_array[bal_next_node].downwardConnect; contig_array[bal_next_node].downwardConnect = bal_cnt; } ite_cnt->deleted = 0; ite_cnt->mask = 0; bal_cnt->deleted = 0; bal_cnt->mask = 0; tmp_cnt = getCntBetween ( node1, node2 ); setNextInScaf ( tmp_cnt, ite_cnt ); setPrevInScaf ( ite_cnt, 1 ); tmp_cnt = getCntBetween ( getTwinCtg ( node2 ), getTwinCtg ( node1 ) ); setNextInScaf ( bal_cnt, tmp_cnt ); setPrevInScaf ( tmp_cnt, 1 ); if ( last_cnt->nextInScaf ) { setNextInScaf ( ite_cnt, last_cnt->nextInScaf ); affected_node1 = last_cnt->nextInScaf->contigID; bal_affected_node1 = getTwinCtg ( affected_node1 ); bal_affected_cnt = getCntBetween ( bal_affected_node1, bal_next_node ); setNextInScaf ( bal_affected_cnt, bal_cnt ); setPrevInScaf ( bal_cnt, 1 ); } setNextInScaf ( last_cnt, NULL ); setPrevInScaf ( last_cnt, 0 ); last_cnt->deleted = 1; tmp_cnt = getCntBetween ( bal_next_node, bal_last_node ); setNextInScaf ( tmp_cnt, NULL ); setPrevInScaf ( tmp_cnt, 0 ); tmp_cnt->deleted = 1; } } } /************************************************* Function: checkOverlapInBetween_general Description: Checks if adjacent contigs in the array have reasonable overlap. Input: 1. tolerance: max percentage that overlap length accounts for Output: None. Return: 1 if the overlap situation was resonable. *************************************************/ boolean checkOverlapInBetween_general ( double tolerance ) { int i, gap; unsigned int node1, node2; int lenSum, lenOlp; CONNECT * cnt; lenSum = lenOlp = 0; for ( i = 1; i <= nodeCounter; i++ ) { node1 = ctg4heapArray[i].ctgID; lenSum += contig_array[node1].length; } if ( lenSum < 1 ) { return 0; } for ( i = 1; i < nodeCounter; i++ ) { node2 = ctg4heapArray[i + 1].ctgID; gap = ctg4heapArray[i + 1].dis - ctg4heapArray[i].dis - contig_array[node2].length; if ( -gap > 0 ) { node1 = ctg4heapArray[i].ctgID; cnt = getCntBetween ( node1, node2 ); if ( cnt && cnt->gapLen > gap ) { continue; } else if ( ( cnt = getCntBetween ( node2, node1 ) ) != NULL && cnt->gapLen > gap ) { continue; } else if ( -gap < overlaplen ) { continue; } lenOlp += -gap; } if ( ( double ) lenOlp / lenSum > tolerance ) { return 0; } } return 1; } int canexchange = 0, exchange_num = 0, failexchange = 0; /************************************************* Function: checkConflictCnt_general Description: Checks if the conflict connections between adjacent contigs in the array are acceptable. Input: 1. tolerance: max percentage that conflict connections accounts for Output: None. Return: 0 if acceptable. *************************************************/ static boolean checkConflictCnt_general ( double tolerance ) { int i, j, gap; int supportCounter = 0; int objectCounter = 0; CONNECT * cnt; for ( i = 1; i < nodeCounter; i++ ) { for ( j = i + 1; j <= nodeCounter; j++ ) { cnt = checkConnect ( ctg4heapArray[i].ctgID, ctg4heapArray[j].ctgID ); if ( cnt ) { supportCounter += cnt->weight; } cnt = checkConnect ( ctg4heapArray[j].ctgID, ctg4heapArray[i].ctgID ); if ( cnt ) { gap = ctg4heapArray[j].dis - ctg4heapArray[i].dis - contig_array[ctg4heapArray[j].ctgID].length; if ( gap > -overlaplen && gap >= cnt->gapLen && cnt->inherit == 0 ) { objectCounter += cnt->weight; } } } } if ( supportCounter < 1 ) { return 1; } if ( ( double ) objectCounter / supportCounter < tolerance ) { return 0; } return 1; } /************************************************* Function: getIndexInSortedSubgraph Description: Gets contig's index in sorted array. Input: 1. node: contig 2. count: array size Output: None. Return: Contig's index if found. -1 otherwise. *************************************************/ static int getIndexInSortedSubgraph ( unsigned int node, int count ) { int index; for ( index = 0; index < count; ++index ) { if ( nodesInSubInOrder[index] == node ) { return index; } } return -1; } /************************************************* Function: getIndexInSortedSubgraph Description: Gets contig's arc if contig has only one arc with weight > 1. Input: 1. node: contig Output: None. Return: Pointer to arc if existed. NULL otherwise. *************************************************/ static preARC * getValidArc ( unsigned int node ) { int num = 0; preARC * arc = contig_array[node].arcs; while ( arc ) { if ( arc->multiplicity > 1 ) { ++num; if ( num > 1 ) { return NULL; } } arc = arc->next; } return arc; } static boolean clearUpSubgraph() { unsigned int i, ctg1, bal_ctg1, ctg2, bal_ctg2; int j, arc_num, num5, num3, index = 0, count = 0; preARC * arc; CONNECT * cnt; //put all contigs in "nodesInSub" array for ( i = 1; i <= nodeCounter; ++i ) { nodesInSub[i - 1] = ctg4heapArray[i].ctgID; } for ( i = 0; i < nodeCounter; ++i ) { ctg1 = nodesInSub[i]; index = getIndexInSortedSubgraph ( ctg1, count ); if ( index >= 0 && index < count - 1 ) //this contig is already in array { continue; } bal_ctg1 = getTwinCtg ( ctg1 ); num5 = 0; num3 = 0; arc_num = 0; * ( unsigned int * ) darrayPut ( scaf5, num5++ ) = ctg1; arc = getValidArc ( ctg1 ); while ( arc ) { ctg2 = arc->to_ed; bal_ctg2 = getTwinCtg ( ctg2 ); if ( ( arc = getValidArc ( bal_ctg2 ) ) == NULL ) { break; } else if ( arc->to_ed != bal_ctg1 ) { break; } ctg1 = ctg2; * ( unsigned int * ) darrayPut ( scaf5, num5++ ) = ctg1; arc = getValidArc ( ctg1 ); } ctg1 = nodesInSub[i]; arc = getValidArc ( bal_ctg1 ); while ( arc ) { bal_ctg2 = arc->to_ed; ctg2 = getTwinCtg ( bal_ctg2 ); if ( ( arc = getValidArc ( ctg2 ) ) == NULL ) { break; } else if ( arc->to_ed != ctg1 ) { break; } ctg1 = ctg2; * ( unsigned int * ) darrayPut ( scaf3, num3++ ) = ctg1; arc = getValidArc ( bal_ctg2 ); } for ( j = num3 - 1; j >= 0; --j ) { nodesInSubInOrder[index++] = * ( unsigned int * ) darrayGet ( scaf3, j ); } for ( j = 0; j < num5; ++j ) { nodesInSubInOrder[index++] = * ( unsigned int * ) darrayGet ( scaf5, j ); } } } /************************************************* Function: transferCnt2RemainNode Description: In bubble structure, transfers connections of contig which is to be masked, to remained contig. Input: 1. maskNode: contig to be masked 2. remainNode: remained contig Output: None. Return: None. *************************************************/ static void transferCnt2RemainNode ( unsigned int maskNode, unsigned int remainNode ) { CONNECT * cnt = contig_array[maskNode].downwardConnect; CONNECT * bal_cnt, *nextCnt, *bal_nextCnt, *tmpCnt, *bal_tmpCnt; unsigned int nextNode1, bal_nextNode1, nextNode2, bal_nextNode2; unsigned int bal_maskNode = getTwinCtg ( maskNode ), bal_remainNode = getTwinCtg ( remainNode ); int gap, weight, inherit; while ( cnt ) { if ( cnt->mask ) { cnt = cnt->next; continue; } nextNode1 = cnt->contigID; bal_nextNode1 = getTwinCtg ( nextNode1 ); bal_cnt = getCntBetween ( bal_nextNode1, bal_maskNode ); gap = cnt->gapLen; weight = cnt->weight; tmpCnt = getCntBetween ( remainNode, nextNode1 ); if ( tmpCnt ) { inherit = 0; } else { inherit = 1; } if ( cnt->nextInScaf ) { nextNode2 = cnt->nextInScaf->contigID; bal_nextNode2 = getTwinCtg ( nextNode2 ); nextCnt = getCntBetween ( nextNode1, nextNode2 ); bal_nextCnt = getCntBetween ( bal_nextNode2, bal_nextNode1 ); if ( nextNode1 != remainNode && nextNode2 != remainNode ) { tmpCnt = add1Connect ( remainNode, nextNode1, gap, weight, inherit ); bal_tmpCnt = add1Connect ( bal_nextNode1, bal_remainNode, gap, weight, inherit ); tmpCnt->nextInScaf = nextCnt; tmpCnt->mask = 0; tmpCnt->deleted = 0; bal_nextCnt->nextInScaf = bal_tmpCnt; bal_tmpCnt->prevInScaf = 1; bal_tmpCnt->mask = 0; bal_tmpCnt->deleted = 0; } else { nextCnt->prevInScaf = 0; bal_nextCnt->nextInScaf = NULL; } } cnt->nextInScaf = NULL; cnt->prevInScaf = 0; cnt->mask = 1; cnt->deleted = 1; bal_cnt->nextInScaf = NULL; bal_cnt->prevInScaf = 0; bal_cnt->mask = 1; bal_cnt->deleted = 1; cnt = cnt->next; } } /************************************************* Function: maskNodeCnt Description: Masks contig's downstream connections in scaffold. Input: 1. node: contig whose downstream connections are going to be masked Output: None. Return: None. *************************************************/ static void maskNodeCnt ( unsigned int node ) { CONNECT * cnt = contig_array[node].downwardConnect; CONNECT * bal_cnt, *bal_nextCnt; unsigned int bal_nextNode1, bal_nextNode2; while ( cnt ) { bal_nextNode1 = getTwinCtg ( cnt->contigID ); bal_cnt = getCntBetween ( bal_nextNode1, getTwinCtg ( node ) ); if ( cnt->nextInScaf ) { cnt->nextInScaf->prevInScaf = 0; bal_nextNode2 = getTwinCtg ( cnt->nextInScaf->contigID ); bal_nextCnt = getCntBetween ( bal_nextNode2, bal_nextNode1 ); if ( !bal_nextCnt ) { exit ( 1 ); } bal_nextCnt->nextInScaf = NULL; } cnt->nextInScaf = NULL; cnt->prevInScaf = 0; cnt->mask = 1; cnt->deleted = 1; bal_cnt->nextInScaf = NULL; bal_cnt->prevInScaf = 0; bal_cnt->mask = 1; bal_cnt->deleted = 1; cnt = cnt->next; } } /************************************************* Function: getEndKmers Description: Gets contig's first and last kmers' sequences. Input: 1. seq: contig sequence 2. len: contig length 3. rev: indicator of reversed complement Output: 1. firstKmer: first kmer's sequence 2. lastKmer: last kmer's sequence Return: None. *************************************************/ static void getEndKmers ( char * seq, int len, int rev, char * firstKmer, char * lastKmer ) { int j; if ( 0 == rev ) { for ( j = 0; j < overlaplen; ++j ) { firstKmer[j] = int2base ( ( int ) getCharInTightString ( seq, j ) ); lastKmer[j] = int2base ( ( int ) getCharInTightString ( seq, len - j - 1 ) ); } } else { for ( j = 0; j < overlaplen; ++j ) { firstKmer[j] = int2compbase ( ( int ) getCharInTightString ( seq, len - j - 1 ) ); lastKmer[j] = int2compbase ( ( int ) getCharInTightString ( seq, j ) ); } } } /************************************************* Function: output_ctg Description: Outputs contig sequence. Input: 1. ctg: contig 2. fo: output file Output: None. Return: None. *************************************************/ static void output_ctg ( unsigned int ctg, FILE * fo ) { if ( contig_array[ctg].length < 1 ) { return; } int len; unsigned int bal_ctg = getTwinCtg ( ctg ); len = contig_array[ctg].length + overlaplen; int col = 0; if ( contig_array[ctg].seq ) { fprintf ( fo, ">C%d %4.1f\n", ctg, ( double ) contig_array[ctg].cvg ); outputTightStr ( fo, contig_array[ctg].seq, 0, len, len, 0, &col ); } else if ( contig_array[bal_ctg].seq ) { fprintf ( fo, ">C%d %4.1f\n", bal_ctg, ( double ) contig_array[ctg].cvg ); outputTightStr ( fo, contig_array[bal_ctg].seq, 0, len, len, 0, &col ); } fprintf ( fo, "\n" ); } /************************************************* Function: removeBubbleCtg Description: Searchs bubble structure in sub-graph. Removes the contig with lower coverage and transfers its connection relation to the remained contig if found structure accords with following criterions: 1. Both contigs' coverage smaller than a cutoff. 2. The first and last kmers of two contigs are the same. Input: None. Output: None. Return: Handled bubble structure number. *************************************************/ static int removeBubbleCtg() { int i, j, count, gap, SnpCounter = 0, conflict = 0; unsigned int node1, node2, bal_node1, bal_node2; int len1, len2, addLast = 0; char * tightStr1, *tightStr2; char firstKmer1[overlaplen + 1], lastKmer1[overlaplen + 1], firstKmer2[overlaplen + 1], lastKmer2[overlaplen + 1]; CONNECT * cnt, *bal_cnt; count = 0; for ( i = 1; i < nodeCounter; ++i ) { node1 = ctg4heapArray[i].ctgID; node2 = ctg4heapArray[i + 1].ctgID; bal_node1 = getTwinCtg ( node1 ); bal_node2 = getTwinCtg ( node2 ); cnt = getCntBetween ( node1, node2 ); bal_cnt = getCntBetween ( node2, node1 ); gap = ctg4heapArray[i + 1].dis - ctg4heapArray[i].dis - ( int ) contig_array[node2].length; if ( gap >= 0 || contig_array[node1].cvg >= cvg4SNP || contig_array[node2].cvg >= cvg4SNP || cnt || bal_cnt ) { nodesInSubInOrder[count] = node1; nodeDistanceInOrder[count++] = ctg4heapArray[i].dis; continue; } len1 = contig_array[node1].length + overlaplen; len2 = contig_array[node2].length + overlaplen; if ( contig_array[node1].seq ) { getEndKmers ( contig_array[node1].seq, len1, 0, firstKmer1, lastKmer1 ); } else { getEndKmers ( contig_array[bal_node1].seq, len1, 1, firstKmer1, lastKmer1 ); } if ( contig_array[node2].seq ) { getEndKmers ( contig_array[node2].seq, len2, 0, firstKmer2, lastKmer2 ); } else { getEndKmers ( contig_array[bal_node2].seq, len2, 1, firstKmer2, lastKmer2 ); } for ( j = 0; j < overlaplen; ++j ) { if ( firstKmer1[j] != firstKmer2[j] || lastKmer1[j] != lastKmer2[j] ) { nodesInSubInOrder[count] = node1; nodeDistanceInOrder[count++] = ctg4heapArray[i].dis; conflict = 1; break; } } if ( 1 == conflict ) { conflict = 0; continue; } ++SnpCounter; if ( contig_array[node1].bubbleInScaff == 0 || contig_array[node2].bubbleInScaff == 0 ) { contig_array[node1].bubbleInScaff = 1; contig_array[bal_node1].bubbleInScaff = 1; contig_array[node2].bubbleInScaff = 1; contig_array[bal_node2].bubbleInScaff = 1; output_ctg ( node1, snp_fp ); output_ctg ( node2, snp_fp ); } if ( contig_array[node1].cvg > contig_array[node2].cvg || ( len1 > len2 && contig_array[node1].cvg == contig_array[node2].cvg ) ) { if ( i == nodeCounter - 1 ) { nodesInSubInOrder[count] = node1; nodeDistanceInOrder[count++] = ctg4heapArray[i].dis; addLast = 1; } transferCnt2RemainNode ( node2, node1 ); transferCnt2RemainNode ( bal_node2, bal_node1 ); contig_array[node2].mask = 1; contig_array[bal_node2].mask = 1; ctg4heapArray[i + 1].ctgID = node1; ctg4heapArray[i + 1].dis = ctg4heapArray[i].dis; } else { if ( i == nodeCounter - 1 ) { nodesInSubInOrder[count] = node2; nodeDistanceInOrder[count++] = ctg4heapArray[i + 1].dis; addLast = 1; } transferCnt2RemainNode ( node1, node2 ); transferCnt2RemainNode ( bal_node1, bal_node2 ); contig_array[node1].mask = 1; contig_array[getTwinCtg ( node1 )].mask = 1; } } if ( 0 == addLast ) { nodesInSubInOrder[count] = ctg4heapArray[nodeCounter].ctgID; nodeDistanceInOrder[count++] = ctg4heapArray[nodeCounter].dis; } for ( i = 0; i < count; ++i ) { ctg4heapArray[i + 1].ctgID = nodesInSubInOrder[i]; ctg4heapArray[i + 1].dis = nodeDistanceInOrder[i]; } nodeCounter = count; return SnpCounter; } /************************************************* Function: general_linearization Description: Picks up sub-graph and trys to line involved contigs. Input: 1. strict: indicator of whether using strict cutoff to deal with sub-graph Output: None. Return: None. *************************************************/ static void general_linearization ( boolean strict ) { unsigned int i; int subCounter = 0; int out_num; boolean flag; int conflCounter = 0, overlapCounter = 0, eligibleCounter = 0; int SNPCtgCounter = 0; double overlapTolerance, conflTolerance; canexchange = 0, exchange_num = 0, failexchange = 0; fprintf ( stderr, "Start to linearize sub-graph.\n" ); for ( i = num_ctg; i > 0; i-- ) { if ( contig_array[i].mask ) { continue; } out_num = validConnect ( i, NULL ); if ( out_num < 2 ) { continue; } flag = pickUpGeneralSubgraph ( i, MaxNodeInSub ); if ( !flag ) { continue; } subCounter++; qsort ( &ctg4heapArray[1], nodeCounter, sizeof ( CTGinHEAP ), cmp_ctg ); if ( Insert_size < 1000 && cvg4SNP > 0.001 ) { SNPCtgCounter += removeBubbleCtg(); } flag = checkEligible(); if ( !flag ) { eligibleCounter++; setInGraph ( 0 ); continue; } if ( strict ) { overlapTolerance = OverlapPercent; conflTolerance = ConflPercent; } else { overlapTolerance = 2 * OverlapPercent; conflTolerance = 2 * ConflPercent; } flag = checkOverlapInBetween_general ( overlapTolerance ); if ( !flag ) { overlapCounter++; setInGraph ( 0 ); continue; } flag = checkConflictCnt_general ( conflTolerance ); if ( flag ) { conflCounter++; setInGraph ( 0 ); continue; } arrangeNodes_general(); setInGraph ( 0 ); } fprintf ( stderr, " Picked sub-graphs %d\n Connection-conflict %d\n Significant overlapping %d\n Eligible %d\n Bubble structures %d\n", subCounter, conflCounter, overlapCounter, eligibleCounter, SNPCtgCounter ); } /**** the fowllowing codes for detecting and break down scaffold at weak point **********/ /************************************************* Function: smallScaf Description: Counts constructed scaffold number by using short insert size paired-end reads and sets connections' flags: "bySmall" and "smallIns". Input: None. Output: None. Return: None. *************************************************/ static void smallScaf() { unsigned int i, ctg, bal_ctg, prevCtg; int counter = 0; CONNECT * bindCnt, *cnt; for ( i = 1; i <= num_ctg; i++ ) { contig_array[i].flag = 0; } for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].flag || contig_array[i].mask || !contig_array[i].downwardConnect ) { continue; } bindCnt = getBindCnt ( i ); if ( !bindCnt ) { continue; } counter++; contig_array[i].flag = 1; contig_array[getTwinCtg ( i )].flag = 1; prevCtg = getTwinCtg ( i ); while ( bindCnt ) { ctg = bindCnt->contigID; bal_ctg = getTwinCtg ( ctg ); bindCnt->bySmall = 1; cnt = getCntBetween ( bal_ctg, prevCtg ); if ( cnt ) { cnt->bySmall = 1; } contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; prevCtg = bal_ctg; bindCnt = bindCnt->nextInScaf; } ctg = getTwinCtg ( i ); bindCnt = getBindCnt ( ctg ); prevCtg = i; while ( bindCnt ) { ctg = bindCnt->contigID; bal_ctg = getTwinCtg ( ctg ); bindCnt->bySmall = 1; cnt = getCntBetween ( bal_ctg, prevCtg ); if ( cnt ) { cnt->bySmall = 1; } contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; prevCtg = bal_ctg; bindCnt = bindCnt->nextInScaf; } } fprintf ( stderr, "Report from smallScaf: %d scaffolds by smallPE.\n", counter ); for ( i = 1; i <= num_ctg; i++ ) { if ( !contig_array[i].downwardConnect ) { continue; } cnt = contig_array[i].downwardConnect; while ( cnt ) { cnt->smallIns = 1; cnt = cnt->next; } } } /************************************************* Function: clearNewInsFlag Description: Clears conections' flag "newIns". Input: None. Output: None. Return: None. *************************************************/ static void clearNewInsFlag() { int i = 1; CONNECT * cnt; for ( ; i <= num_ctg; i++ ) { cnt = contig_array[i].downwardConnect; while ( cnt ) { cnt->newIns = 0; if ( Insert_size > 15000 ) { cnt = cnt->next; continue; } cnt->maxGap = 0; cnt = cnt->next; } } } /************************************************* Function: putItem2Sarray Description: Checks whether a scaffold ID is in array. If not, puts it in to array. Input: 1. scaf: scaffold ID to be checked and put in to array 2. wt: weight of connection to scaffold ID 3. SCAF: array of scaffold IDs 4. WT: array of connections' weight 5. counter: size of scaffold ID array Output: 1. SCAF: updated array of scaffold IDs 2. WT: updated array of connections' weight Return: 1 if operation of putting succeeded. *************************************************/ static boolean putItem2Sarray ( unsigned int scaf, int wt, DARRAY * SCAF, DARRAY * WT, int counter ) { int i; unsigned int * scafP, *wtP; for ( i = 0; i < counter; i++ ) { scafP = ( unsigned int * ) darrayGet ( SCAF, i ); if ( ( *scafP ) == scaf ) { wtP = ( unsigned int * ) darrayGet ( WT, i ); *wtP = ( *wtP + wt ); return 0; } } scafP = ( unsigned int * ) darrayPut ( SCAF, counter ); wtP = ( unsigned int * ) darrayPut ( WT, counter ); *scafP = scaf; *wtP = wt; return 1; } /************************************************* Function: getDSLink2Scaf Description: Gets downstream connections to other scaffolds and stores related information including other scaffolds' ID and connections' weight. Input: 1. scafStack: scaffold stack consisting of contigs 2. SCAF: array to store other scaffolds' IDs 3. WT: array to store connections' weight 4. total_len: length sum of contigs used to search connections to other scaffolds Output: 1. SCAF: updated array of scaffold IDs 2. WT: updated array of connections' weight Return: Number of other scaffolds being connected. *************************************************/ static int getDSLink2Scaf ( STACK * scafStack, DARRAY * SCAF, DARRAY * WT, int total_len ) { CONNECT * ite_cnt; CONNECT * bind_cnt; unsigned int ctg, targetCtg, bal_targetCtg, *pt; int counter = 0; int len = 0, gap; boolean inc; stackRecover ( scafStack ); while ( ( pt = ( unsigned int * ) stackPop ( scafStack ) ) != NULL ) { ctg = *pt; bind_cnt = getBindCnt ( ctg ); gap = bind_cnt ? bind_cnt->gapLen : 0; len += contig_array[ctg].length + gap; if ( ( contig_array[ctg].mask && contig_array[ctg].length < 500 ) || !contig_array[ctg].downwardConnect || total_len - len > Insert_size ) { continue; } ite_cnt = contig_array[ctg].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->newIns != 1 ) { ite_cnt = ite_cnt->next; continue; } targetCtg = ite_cnt->contigID; bal_targetCtg = getTwinCtg ( targetCtg ); if ( ( ite_cnt->mask && contig_array[targetCtg].length < 500 ) || ite_cnt->singleInScaf || ite_cnt->nextInScaf || ite_cnt->prevInScaf || ite_cnt->inherit ) { ite_cnt = ite_cnt->next; continue; } if ( contig_array[ctg].from_vt == contig_array[targetCtg].from_vt // on the same scaff || ( targetCtg == contig_array[targetCtg].from_vt && bal_targetCtg == contig_array[bal_targetCtg].from_vt ) ) //targetCtg isn't in any scaffold { ite_cnt = ite_cnt->next; continue; } inc = putItem2Sarray ( contig_array[targetCtg].from_vt, ite_cnt->weight, SCAF, WT, counter ); if ( inc ) { counter++; } ite_cnt = ite_cnt->next; } } return counter; } /************************************************* Function: getScaffold Description: Starting from a contig, gets downstream contig chain in a scaffold. Input: 1. start: start contig Output: 1. scafStack: stack to store contig chain Return: Length of contig chain. *************************************************/ static int getScaffold ( unsigned int start, STACK * scafStack ) { int len = contig_array[start].length; unsigned int * pt, ctg; emptyStack ( scafStack ); pt = ( unsigned int * ) stackPush ( scafStack ); *pt = start; CONNECT * bindCnt = getBindCnt ( start ); while ( bindCnt ) { ctg = bindCnt->contigID; pt = ( unsigned int * ) stackPush ( scafStack ); *pt = ctg; len += bindCnt->gapLen + contig_array[ctg].length; bindCnt = bindCnt->nextInScaf; } stackBackup ( scafStack ); return len; } /************************************************* Function: isLinkReliable Description: Checks whether there is a reliable connection. Input: 1. WT: weight of connections 2. count: connection number Output: None. Return: 1 if a reliable connection was found. *************************************************/ static boolean isLinkReliable ( DARRAY * WT, int count ) { int i; for ( i = 0; i < count; i++ ) if ( * ( int * ) darrayGet ( WT, i ) >= weakPE ) { return 1; } return 0; } /************************************************* Function: getWtFromSarray Description: Gets weight of connection to specified scaffold. Input: 1. SCAF: array of scaffold ID 2. WT: array of onnection weight 3. count: array size 4. scaf: specified scaffold Output: None. Return: Weight of connection was found. 0 otherwise. *************************************************/ static int getWtFromSarray ( DARRAY * SCAF, DARRAY * WT, int count, unsigned int scaf ) { int i; for ( i = 0; i < count; i++ ) if ( * ( unsigned int * ) darrayGet ( SCAF, i ) == scaf ) { return * ( int * ) darrayGet ( WT, i ); } return 0; } /************************************************* Function: switch2twin Description: Transfers contigs to their reversed complements. Input: 1. scafStack: stack of contigs Output: 1. scafStack: updated stack of contigs Return: None. *************************************************/ static void switch2twin ( STACK * scafStack ) { unsigned int * pt; stackRecover ( scafStack ); while ( ( pt = ( unsigned int * ) stackPop ( scafStack ) ) != NULL ) { *pt = getTwinCtg ( *pt ); } } /************************************************* Function: recoverLinks Description: Recovers contigs' connections to other scaffold if they accords with some criterions. Input: 1. scafStack: stack of contigs Output: None. Return: None. *************************************************/ static void recoverLinks ( STACK * scafStack ) { CONNECT * ite_cnt; unsigned int ctg, targetCtg, *pt; int counter = 0; boolean inc; unsigned int bal_ctg; stackRecover ( scafStack ); while ( ( pt = ( unsigned int * ) stackPop ( scafStack ) ) != NULL ) { ctg = *pt; if ( contig_array[ctg].mask || !contig_array[ctg].downwardConnect ) { continue; } ite_cnt = contig_array[ctg].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->mask || ite_cnt->singleInScaf || ite_cnt->nextInScaf || ite_cnt->prevInScaf || ite_cnt->inherit || ite_cnt->weight < weakPE ) { ite_cnt = ite_cnt->next; continue; } targetCtg = ite_cnt->contigID; if ( contig_array[ctg].from_vt == contig_array[targetCtg].from_vt ) // on the same scaff { ite_cnt = ite_cnt->next; continue; } setConnectDelete ( ctg, targetCtg, 0, 0 ); ite_cnt = ite_cnt->next; } bal_ctg = getTwinCtg ( ctg ); if ( contig_array[bal_ctg].mask || !contig_array[bal_ctg].downwardConnect ) { continue; } ite_cnt = contig_array[bal_ctg].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->mask || ite_cnt->singleInScaf || ite_cnt->nextInScaf || ite_cnt->prevInScaf || ite_cnt->inherit || ite_cnt->weight < weakPE ) { ite_cnt = ite_cnt->next; continue; } targetCtg = ite_cnt->contigID; if ( contig_array[bal_ctg].from_vt == contig_array[targetCtg].from_vt ) // on the same scaff { ite_cnt = ite_cnt->next; continue; } setConnectDelete ( bal_ctg, targetCtg, 0, 0 ); ite_cnt = ite_cnt->next; } } } /* ------> scaf1 --- --- -- --- scaf2 -- --- --- -- ----> */ /************************************************* Function: checkScafConsist Description: Checks if both sets of contigs in two stacks have reliable connection to different scaffolds. Input: 1. scafStack1: stack of contig set one 2. len1: total length of contigs in set one 3. scafStack2: stack of contig set two 4. len2: total length of contigs in set two Output: None. Return: 0 if both sets of contigs did not have reliable connection to different scaffolds. *************************************************/ static boolean checkScafConsist ( STACK * scafStack1, int len1, STACK * scafStack2, int len2 ) { DARRAY * downwardTo1 = ( DARRAY * ) createDarray ( 1000, sizeof ( unsigned int ) ); // scaf links to those scaffolds DARRAY * downwardTo2 = ( DARRAY * ) createDarray ( 1000, sizeof ( unsigned int ) ); DARRAY * downwardWt1 = ( DARRAY * ) createDarray ( 1000, sizeof ( unsigned int ) ); // scaf links to scaffolds with those wt DARRAY * downwardWt2 = ( DARRAY * ) createDarray ( 1000, sizeof ( unsigned int ) ); int linkCount1 = getDSLink2Scaf ( scafStack1, downwardTo1, downwardWt1, len1 ); int linkCount2 = getDSLink2Scaf ( scafStack2, downwardTo2, downwardWt2, len2 ); if ( !linkCount1 ) { freeDarray ( downwardTo1 ); freeDarray ( downwardTo2 ); freeDarray ( downwardWt1 ); freeDarray ( downwardWt2 ); return 1; } boolean flag1 = isLinkReliable ( downwardWt1, linkCount1 ); if ( !flag1 ) { freeDarray ( downwardTo1 ); freeDarray ( downwardTo2 ); freeDarray ( downwardWt1 ); freeDarray ( downwardWt2 ); return 1; } unsigned int scaf; int i, wt1, wt2, ret = 1; for ( i = 0; i < linkCount1; i++ ) { wt1 = * ( int * ) darrayGet ( downwardWt1, i ); if ( wt1 < weakPE ) { continue; } scaf = * ( unsigned int * ) darrayGet ( downwardTo1, i ); wt2 = getWtFromSarray ( downwardTo2, downwardWt2, linkCount2, scaf ); if ( wt2 < 1 ) { ret = 0; break; } } if ( ret == 0 ) { if ( linkCount1 && flag1 ) { recoverLinks ( scafStack1 ); } if ( linkCount2 ) { recoverLinks ( scafStack2 ); } } freeDarray ( downwardTo1 ); freeDarray ( downwardTo2 ); freeDarray ( downwardWt1 ); freeDarray ( downwardWt2 ); return ret; } /************************************************* Function: setBreakPoints Description: Sets break points of scaffold at weak connections. Input: 1. ctgArray: array of contig in scaffold 2. count: total contig number 3. weakest: contig whose downstream connection was estimated break point Output: 1. start: the first contig with weak downstream connection 2. finish: the last contig with downstream connection Return: None. *************************************************/ static void setBreakPoints ( DARRAY * ctgArray, int count, int weakest, int * start, int * finish ) { int index = weakest - 1; unsigned int thisCtg; unsigned int nextCtg = * ( unsigned int * ) darrayGet ( ctgArray, weakest ); CONNECT * cnt; *start = weakest; while ( index >= 0 ) { thisCtg = * ( unsigned int * ) darrayGet ( ctgArray, index ); cnt = getCntBetween ( thisCtg, nextCtg ); if ( cnt->maxGap > 2 ) { break; } else { *start = index; } nextCtg = thisCtg; index--; } unsigned int prevCtg = * ( unsigned int * ) darrayGet ( ctgArray, weakest + 1 ); *finish = weakest + 1; index = weakest + 2; while ( index < count ) { thisCtg = * ( unsigned int * ) darrayGet ( ctgArray, index ); cnt = getCntBetween ( prevCtg, thisCtg ); if ( cnt->maxGap > 2 ) { break; } else { *finish = index; } prevCtg = thisCtg; index++; } } /************************************************* Function: changeScafEnd Description: Changes "to_vt" of contigs in a scaffold to a specified contig. Input: 1. scafStack: stack of contigs in scaffold 2. end: specified contig Output: None. Return: None. *************************************************/ static void changeScafEnd ( STACK * scafStack, unsigned int end ) { unsigned int ctg, *pt; unsigned int start = getTwinCtg ( end ); stackRecover ( scafStack ); while ( ( pt = ( unsigned int * ) stackPop ( scafStack ) ) != NULL ) { ctg = *pt; contig_array[ctg].to_vt = end; contig_array[getTwinCtg ( ctg )].from_vt = start; } } /************************************************* Function: changeScafBegin Description: Changes "from_vt" of contigs in a scaffold to a specified contig. Input: 1. scafStack: stack of contigs in scaffold 2. start: specified contig Output: None. Return: None. *************************************************/ static void changeScafBegin ( STACK * scafStack, unsigned int start ) { unsigned int ctg, *pt; unsigned int end = getTwinCtg ( start ); stackRecover ( scafStack ); while ( ( pt = ( unsigned int * ) stackPop ( scafStack ) ) != NULL ) { ctg = *pt; contig_array[ctg].from_vt = start; contig_array[getTwinCtg ( ctg )].to_vt = end; } } /************************************************* Function: detectBreakScaff Description: Detects and breaks the weak connection between contigs in scaffold according to the support of large insert size paired-end reads. Input: None. Output: None. Return: None. *************************************************/ static void detectBreakScaf() { unsigned int i, avgPE, scafLen, len, ctg, bal_ctg, prevCtg, thisCtg; long long peCounter, linkCounter; int num3, num5, weakPoint, tempCounter, j, t, counter = 0; CONNECT * bindCnt, *cnt, *weakCnt; STACK * scafStack1 = ( STACK * ) createStack ( 1000, sizeof ( unsigned int ) ); STACK * scafStack2 = ( STACK * ) createStack ( 1000, sizeof ( unsigned int ) ); for ( i = 1; i <= num_ctg; i++ ) { contig_array[i].flag = 0; } for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].flag || contig_array[i].mask || !contig_array[i].downwardConnect ) { continue; } bindCnt = getBindCnt ( i ); if ( !bindCnt ) { continue; } //first scan to get the average coverage by longer pe num5 = num3 = peCounter = linkCounter = 0; scafLen = contig_array[i].length; ctg = i; * ( unsigned int * ) darrayPut ( scaf5, num5++ ) = i; contig_array[i].flag = 1; contig_array[getTwinCtg ( i )].flag = 1; while ( bindCnt ) { if ( !bindCnt->bySmall ) { break; } linkCounter++; peCounter += bindCnt->maxGap; ctg = bindCnt->contigID; scafLen += contig_array[ctg].length; * ( unsigned int * ) darrayPut ( scaf5, num5++ ) = ctg; bal_ctg = getTwinCtg ( ctg ); contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; bindCnt = bindCnt->nextInScaf; } ctg = getTwinCtg ( i ); bindCnt = getBindCnt ( ctg ); while ( bindCnt ) { if ( !bindCnt->bySmall ) { break; } linkCounter++; peCounter += bindCnt->maxGap; ctg = bindCnt->contigID; scafLen += contig_array[ctg].length; bal_ctg = getTwinCtg ( ctg ); contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; * ( unsigned int * ) darrayPut ( scaf3, num3++ ) = bal_ctg; bindCnt = bindCnt->nextInScaf; } if ( linkCounter < 1 || scafLen < 5000 ) { continue; } avgPE = peCounter / linkCounter; if ( avgPE < 10 ) { continue; } tempCounter = 0; for ( j = num3 - 1; j >= 0; j-- ) * ( unsigned int * ) darrayPut ( tempArray, tempCounter++ ) = * ( unsigned int * ) darrayGet ( scaf3, j ); for ( j = 0; j < num5; j++ ) * ( unsigned int * ) darrayPut ( tempArray, tempCounter++ ) = * ( unsigned int * ) darrayGet ( scaf5, j ); prevCtg = * ( unsigned int * ) darrayGet ( tempArray, 0 ); weakCnt = NULL; weakPoint = 0; len = contig_array[prevCtg].length; for ( t = 1; t < tempCounter; t++ ) { thisCtg = * ( unsigned int * ) darrayGet ( tempArray, t ); if ( len < 2000 ) { len += contig_array[thisCtg].length; prevCtg = thisCtg; continue; } else if ( len > scafLen - 2000 ) { break; } len += contig_array[thisCtg].length; if ( contig_array[prevCtg].from_vt != contig_array[thisCtg].from_vt || contig_array[prevCtg].indexInScaf > contig_array[thisCtg].indexInScaf ) { prevCtg = thisCtg; continue; } cnt = getCntBetween ( prevCtg, thisCtg ); if ( !weakCnt || weakCnt->maxGap > cnt->maxGap ) { weakCnt = cnt; weakPoint = t; } prevCtg = thisCtg; } if ( !weakCnt || ( weakCnt->maxGap > 2 && weakCnt->maxGap > avgPE / 5 ) ) { continue; } prevCtg = * ( unsigned int * ) darrayGet ( tempArray, weakPoint - 1 ); thisCtg = * ( unsigned int * ) darrayGet ( tempArray, weakPoint ); if ( contig_array[prevCtg].from_vt != contig_array[thisCtg].from_vt || contig_array[prevCtg].indexInScaf > contig_array[thisCtg].indexInScaf ) { fprintf ( stderr, "contig %d and %d not on the same scaff\n", prevCtg, thisCtg ); continue; } setConnectWP ( prevCtg, thisCtg, 1 ); int index1, index2; setBreakPoints ( tempArray, tempCounter, weakPoint - 1, &index1, &index2 ); unsigned int start = * ( unsigned int * ) darrayGet ( tempArray, index1 ); unsigned int finish = * ( unsigned int * ) darrayGet ( tempArray, index2 ); int len1 = getScaffold ( getTwinCtg ( start ), scafStack1 ); int len2 = getScaffold ( finish, scafStack2 ); if ( len1 < 2000 || len2 < 2000 ) { continue; } switch2twin ( scafStack1 ); int flag1 = checkScafConsist ( scafStack1, len1, scafStack2, len2 ); switch2twin ( scafStack1 ); switch2twin ( scafStack2 ); int flag2 = checkScafConsist ( scafStack2, len2, scafStack1, len1 ); if ( !flag1 || !flag2 ) { changeScafBegin ( scafStack1, getTwinCtg ( start ) ); changeScafEnd ( scafStack2, getTwinCtg ( finish ) ); //unbind links unsigned int nextCtg = * ( unsigned int * ) darrayGet ( tempArray, index1 + 1 ); thisCtg = * ( unsigned int * ) darrayGet ( tempArray, index1 ); cnt = getCntBetween ( getTwinCtg ( nextCtg ), getTwinCtg ( thisCtg ) ); if ( cnt->nextInScaf ) { prevCtg = getTwinCtg ( cnt->nextInScaf->contigID ); cnt->nextInScaf->prevInScaf = 0; cnt = getCntBetween ( prevCtg, thisCtg ); cnt->nextInScaf = NULL; } prevCtg = * ( unsigned int * ) darrayGet ( tempArray, index2 - 1 ); thisCtg = * ( unsigned int * ) darrayGet ( tempArray, index2 ); cnt = getCntBetween ( prevCtg, thisCtg ); if ( cnt->nextInScaf ) { nextCtg = cnt->nextInScaf->contigID; cnt->nextInScaf->prevInScaf = 0; cnt = getCntBetween ( getTwinCtg ( nextCtg ), getTwinCtg ( thisCtg ) ); cnt->nextInScaf = NULL; } prevCtg = * ( unsigned int * ) darrayGet ( tempArray, index1 ); for ( t = index1 + 1; t <= index2; t++ ) { thisCtg = * ( unsigned int * ) darrayGet ( tempArray, t ); cnt = getCntBetween ( prevCtg, thisCtg ); cnt->mask = 1; cnt->nextInScaf = NULL; cnt->prevInScaf = 0; cnt = getCntBetween ( getTwinCtg ( thisCtg ), getTwinCtg ( prevCtg ) ); cnt->mask = 1; cnt->nextInScaf = NULL; cnt->prevInScaf = 0; prevCtg = thisCtg; } counter++; } } freeStack ( scafStack1 ); freeStack ( scafStack2 ); fprintf ( stderr, "Report from checkScaf: %d scaffold segments broken.\n", counter ); } /************************************************* Function: detectBreakScaff Description: Detects and breaks the weak connection between contigs in scaffold according to the support of large insert size paired-end reads. Input: None. Output: None. Return: None. *************************************************/ static void detectBreakScaff() { unsigned int i, avgPE, scafLen, len, ctg, bal_ctg, prevCtg, thisCtg; long long peCounter, linkCounter; int num3, num5, weakPoint, tempCounter, j, t, counter = 0; int newInsNum; CONNECT * bindCnt, *cnt, *weakCnt; CONNECT * bal_cnt; STACK * scafStack1 = ( STACK * ) createStack ( 1000, sizeof ( unsigned int ) ); STACK * scafStack2 = ( STACK * ) createStack ( 1000, sizeof ( unsigned int ) ); for ( i = 1; i <= num_ctg; i++ ) { contig_array[i].flag = 0; } for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].flag || contig_array[i].mask || !contig_array[i].downwardConnect ) { continue; } bindCnt = getBindCnt ( i ); if ( !bindCnt ) { continue; } //first scan to get the average coverage by longer pe num5 = num3 = peCounter = linkCounter = 0; scafLen = contig_array[i].length; ctg = i; * ( unsigned int * ) darrayPut ( scaf5, num5++ ) = i; contig_array[i].flag = 1; contig_array[getTwinCtg ( i )].flag = 1; while ( bindCnt ) { linkCounter++; peCounter += bindCnt->maxGap; ctg = bindCnt->contigID; scafLen += bindCnt->gapLen + contig_array[ctg].length; * ( unsigned int * ) darrayPut ( scaf5, num5++ ) = ctg; bal_ctg = getTwinCtg ( ctg ); contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; bindCnt = bindCnt->nextInScaf; } ctg = getTwinCtg ( i ); bindCnt = getBindCnt ( ctg ); while ( bindCnt ) { linkCounter++; peCounter += bindCnt->maxGap; ctg = bindCnt->contigID; scafLen += bindCnt->gapLen + contig_array[ctg].length; bal_ctg = getTwinCtg ( ctg ); contig_array[ctg].flag = 1; contig_array[bal_ctg].flag = 1; * ( unsigned int * ) darrayPut ( scaf3, num3++ ) = bal_ctg; bindCnt = bindCnt->nextInScaf; } if ( scafLen < Insert_size ) { continue; } avgPE = peCounter / linkCounter; if ( avgPE < 10 ) { continue; } tempCounter = 0; for ( j = num3 - 1; j >= 0; j-- ) * ( unsigned int * ) darrayPut ( tempArray, tempCounter++ ) = * ( unsigned int * ) darrayGet ( scaf3, j ); for ( j = 0; j < num5; j++ ) * ( unsigned int * ) darrayPut ( tempArray, tempCounter++ ) = * ( unsigned int * ) darrayGet ( scaf5, j ); prevCtg = * ( unsigned int * ) darrayGet ( tempArray, 0 ); weakCnt = NULL; weakPoint = 0; len = contig_array[prevCtg].length; for ( t = 1; t < tempCounter; t++ ) { newInsNum = 0; thisCtg = * ( unsigned int * ) darrayGet ( tempArray, t ); cnt = contig_array[thisCtg].downwardConnect; while ( cnt ) { if ( cnt->newIns == 1 ) { ctg = cnt->contigID; bal_ctg = getTwinCtg ( ctg ); newInsNum++; } cnt = cnt->next; } bal_cnt = contig_array[getTwinCtg ( thisCtg )].downwardConnect; cnt = getCntBetween ( prevCtg, thisCtg ); if ( len < Insert_size ) { len += cnt->gapLen + contig_array[thisCtg].length; prevCtg = thisCtg; continue; } else if ( len > scafLen - Insert_size ) { break; } len += cnt->gapLen + contig_array[thisCtg].length; if ( contig_array[prevCtg].from_vt != contig_array[thisCtg].from_vt || contig_array[prevCtg].indexInScaf > contig_array[thisCtg].indexInScaf ) { prevCtg = thisCtg; continue; } if ( !weakCnt || weakCnt->maxGap > cnt->maxGap ) { weakCnt = cnt; weakPoint = t; } prevCtg = thisCtg; } if ( !weakCnt || ( weakCnt->maxGap > 2 && weakCnt->maxGap > avgPE / 5 ) ) { continue; } prevCtg = * ( unsigned int * ) darrayGet ( tempArray, weakPoint - 1 ); thisCtg = * ( unsigned int * ) darrayGet ( tempArray, weakPoint ); if ( contig_array[prevCtg].from_vt != contig_array[thisCtg].from_vt || contig_array[prevCtg].indexInScaf > contig_array[thisCtg].indexInScaf ) { printf ( "contig %d and %d not on the same scaff\n", prevCtg, thisCtg ); continue; } setConnectWP ( prevCtg, thisCtg, 1 ); // set start and end to break down the scaffold int index1, index2; setBreakPoints ( tempArray, tempCounter, weakPoint - 1, &index1, &index2 ); unsigned int start = * ( unsigned int * ) darrayGet ( tempArray, index1 ); unsigned int finish = * ( unsigned int * ) darrayGet ( tempArray, index2 ); int len1 = getScaffold ( getTwinCtg ( start ), scafStack1 ); int len2 = getScaffold ( finish, scafStack2 ); if ( len1 < Insert_size || len2 < Insert_size ) { continue; } switch2twin ( scafStack1 ); int flag1 = checkScafConsist ( scafStack1, len1, scafStack2, len2 ); switch2twin ( scafStack1 ); switch2twin ( scafStack2 ); int flag2 = checkScafConsist ( scafStack2, len2, scafStack1, len1 ); if ( !flag1 || !flag2 ) { changeScafBegin ( scafStack1, getTwinCtg ( start ) ); changeScafEnd ( scafStack2, getTwinCtg ( finish ) ); //unbind links unsigned int nextCtg = * ( unsigned int * ) darrayGet ( tempArray, index1 + 1 ); thisCtg = * ( unsigned int * ) darrayGet ( tempArray, index1 ); cnt = getCntBetween ( getTwinCtg ( nextCtg ), getTwinCtg ( thisCtg ) ); if ( cnt->nextInScaf ) { prevCtg = getTwinCtg ( cnt->nextInScaf->contigID ); cnt->nextInScaf->prevInScaf = 0; cnt = getCntBetween ( prevCtg, thisCtg ); cnt->nextInScaf = NULL; } prevCtg = * ( unsigned int * ) darrayGet ( tempArray, index2 - 1 ); thisCtg = * ( unsigned int * ) darrayGet ( tempArray, index2 ); cnt = getCntBetween ( prevCtg, thisCtg ); if ( cnt->nextInScaf ) { nextCtg = cnt->nextInScaf->contigID; cnt->nextInScaf->prevInScaf = 0; cnt = getCntBetween ( getTwinCtg ( nextCtg ), getTwinCtg ( thisCtg ) ); cnt->nextInScaf = NULL; } prevCtg = * ( unsigned int * ) darrayGet ( tempArray, index1 ); for ( t = index1 + 1; t <= index2; t++ ) { thisCtg = * ( unsigned int * ) darrayGet ( tempArray, t ); cnt = getCntBetween ( prevCtg, thisCtg ); cnt->mask = 1; cnt->nextInScaf = NULL; cnt->prevInScaf = 0; cnt = getCntBetween ( getTwinCtg ( thisCtg ), getTwinCtg ( prevCtg ) ); cnt->mask = 1; cnt->nextInScaf = NULL; cnt->prevInScaf = 0; prevCtg = thisCtg; } counter++; } } freeStack ( scafStack1 ); freeStack ( scafStack2 ); fprintf ( stderr, "Report from checkScaf: %d scaffold segments broken.\n", counter ); } /************************************************* Function: checkSimple Description: Checks whether there is a contig appearing more than once in array. Input: 1. ctgArray: array of contigs 2. count: contig number Output: None. Return: 1 if no contig appeared more than once. *************************************************/ static boolean checkSimple ( DARRAY * ctgArray, int count ) { int i; unsigned int ctg; for ( i = 0; i < count; i++ ) { ctg = * ( unsigned int * ) darrayGet ( ctgArray, i ); contig_array[ctg].flag = 0; contig_array[getTwinCtg ( ctg )].flag = 0; } for ( i = 0; i < count; i++ ) { ctg = * ( unsigned int * ) darrayGet ( ctgArray, i ); if ( contig_array[ctg].flag ) { return 0; } contig_array[ctg].flag = 1; contig_array[getTwinCtg ( ctg )].flag = 1; } return 1; } /************************************************* Function: checkCircle Description: Detects and masks contigs having circle connections. A --> B, B --> A. Input: None. Output: None. Return: None. *************************************************/ static void checkCircle() { unsigned int i, ctg; CONNECT * cn_temp1; int counter = 0; for ( i = 1; i <= num_ctg; i++ ) { cn_temp1 = contig_array[i].downwardConnect; while ( cn_temp1 ) { if ( cn_temp1->weak || cn_temp1->deleted ) { cn_temp1 = cn_temp1->next; continue; } ctg = cn_temp1->contigID; if ( checkConnect ( ctg, i ) ) { counter++; maskContig ( i, 1 ); maskContig ( ctg, 1 ); } cn_temp1 = cn_temp1->next; } } fprintf ( stderr, "%d circles removed.\n", counter ); } soapdenovo2-240+dfsg.orig/standardPregraph/inc/0000755000000000000000000000000012177735462020254 5ustar rootrootsoapdenovo2-240+dfsg.orig/standardPregraph/inc/dfibpriv.h0000644000000000000000000000554012166703654022232 0ustar rootroot/* * inc/dfibpriv.h * * This file is part of SOAPdenovo. * */ /* * Copyright 1997, 1999-2003 John-Mark Gurney. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND 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 THE AUTHOR OR 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. * * $Id: dfibpriv.h,v 1.8 2007/10/09 09:56:46 zerbino Exp $ * */ #ifndef _DFIBPRIV_H_ #define _DFIBPRIV_H_ //#include "globals.h" #include "def2.h" /* * specific node operations */ static DFibHeapNode * dfhe_newelem ( DFibHeap * ); static void dfhe_insertafter ( DFibHeapNode * a, DFibHeapNode * b ); static inline void dfhe_insertbefore ( DFibHeapNode * a, DFibHeapNode * b ); static DFibHeapNode * dfhe_remove ( DFibHeapNode * a ); /* * global heap operations */ struct dfibheap { MEM_MANAGER * nodeMemory; IDnum dfh_n; IDnum dfh_Dl; DFibHeapNode ** dfh_cons; DFibHeapNode * dfh_min; DFibHeapNode * dfh_root; }; static void dfh_insertrootlist ( DFibHeap *, DFibHeapNode * ); static void dfh_removerootlist ( DFibHeap *, DFibHeapNode * ); static void dfh_consolidate ( DFibHeap * ); static void dfh_heaplink ( DFibHeap * h, DFibHeapNode * y, DFibHeapNode * x ); static void dfh_cut ( DFibHeap *, DFibHeapNode *, DFibHeapNode * ); static void dfh_cascading_cut ( DFibHeap *, DFibHeapNode * ); static DFibHeapNode * dfh_extractminel ( DFibHeap * ); static void dfh_checkcons ( DFibHeap * h ); static int dfh_compare ( DFibHeap * h, DFibHeapNode * a, DFibHeapNode * b ); static int dfh_comparedata ( DFibHeap * h, Time key, unsigned int data, DFibHeapNode * b ); static void dfh_insertel ( DFibHeap * h, DFibHeapNode * x ); /* * general functions */ static inline IDnum ceillog2 ( IDnum a ); #endif /* _FIBPRIV_H_ */ soapdenovo2-240+dfsg.orig/standardPregraph/inc/sam_header.h0000644000000000000000000000125512166703654022514 0ustar rootroot#ifndef __SAM_HEADER_H__ #define __SAM_HEADER_H__ #ifdef __cplusplus extern "C" { #endif void * sam_header_parse2 ( const char * headerText ); void * sam_header_merge ( int n, const void ** dicts ); void sam_header_free ( void * header ); char * sam_header_write ( const void * headerDict ); // returns a newly allocated string char ** sam_header2list ( const void * _dict, char type[2], char key_tag[2], int * _n ); void * sam_header2tbl ( const void * dict, char type[2], char key_tag[2], char value_tag[2] ); const char * sam_tbl_get ( void * h, const char * key ); int sam_tbl_size ( void * h ); void sam_tbl_destroy ( void * h ); #ifdef __cplusplus } #endif #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/glf.h0000644000000000000000000000346112166703654021175 0ustar rootroot #ifndef GLF_H_ #define GLF_H_ typedef struct { unsigned char ref_base: 4, dummy: 4; /** "XACMGRSVTWYHKDBN"[ref_base] gives the reference base */ unsigned char max_mapQ; /** maximum mapping quality */ unsigned char lk[10]; /** log likelihood ratio, capped at 255 */ unsigned min_lk: 8, depth: 24; /** minimum lk capped at 255, and the number of mapped reads */ } glf1_t; #include #include "bgzf.h" typedef BGZF * glfFile; #define GLF3_RTYPE_END 0 #define GLF3_RTYPE_SUB 1 #define GLF3_RTYPE_INDEL 2 typedef struct { uint8_t ref_base: 4, rtype: 4; /** "XACMGRSVTWYHKDBN"[ref_base] gives the reference base */ uint8_t rms_mapQ; /** RMS mapping quality */ uint8_t lk[10]; /** log likelihood ratio, capped at 255 */ uint32_t min_lk: 8, depth: 24; /** minimum lk capped at 255, and the number of mapped reads */ int32_t offset; /** the first base in a chromosome has offset zero. */ // for indel (lkHom1, lkHom2 and lkHet are the first three elements in lk[10]) int16_t indel_len[2]; int32_t max_len; // maximum indel len; will be modified by glf3_read1() char * indel_seq[2]; } glf3_t; typedef struct { int32_t l_text; uint8_t * text; } glf3_header_t; #ifdef __cplusplus extern "C" { #endif #define glf3_init1() ((glf3_t*)calloc(1, sizeof(glf3_t))) #define glf3_destroy1(g3) do { free((g3)->indel_seq[0]); free((g3)->indel_seq[1]); free(g3); } while (0) glf3_header_t * glf3_header_init(); glf3_header_t * glf3_header_read ( glfFile fp ); void glf3_header_write ( glfFile fp, const glf3_header_t * h ); void glf3_header_destroy ( glf3_header_t * h ); char * glf3_ref_read ( glfFile fp, int * len ); void glf3_ref_write ( glfFile fp, const char * name, int len ); int glf3_write1 ( glfFile fp, const glf3_t * g3 ); int glf3_read1 ( glfFile fp, glf3_t * g3 ); #ifdef __cplusplus } #endif #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/dfib.h0000644000000000000000000000423412166703654021330 0ustar rootroot/* * inc/dfib.h * * This file is part of SOAPdenovo. * */ /*- * Copyright 1997, 1998-2003 John-Mark Gurney. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND 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 THE AUTHOR OR 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. * * $Id: dfib.h,v 1.8 2007/04/24 12:16:41 zerbino Exp $ * */ #ifndef _DFIB_H_ #define _DFIB_H_ #include #include "def2.h" //#include "globals.h" /* functions for key heaps */ DFibHeap * dfh_makekeyheap ( void ); DFibHeapNode * dfh_insertkey ( DFibHeap *, Time, unsigned int ); Time dfh_replacekey ( DFibHeap *, DFibHeapNode *, Time ); unsigned int dfh_replacekeydata ( DFibHeap *, DFibHeapNode *, Time, unsigned int ); unsigned int dfh_extractmin ( DFibHeap * ); unsigned int dfh_replacedata ( DFibHeapNode *, unsigned int ); unsigned int dfh_delete ( DFibHeap *, DFibHeapNode * ); void dfh_deleteheap ( DFibHeap * ); // DEBUG IDnum dfibheap_getSize ( DFibHeap * ); Time dfibheap_el_getKey ( DFibHeapNode * ); // END DEBUG #endif /* _FIB_H_ */ soapdenovo2-240+dfsg.orig/standardPregraph/inc/stdinc.h0000644000000000000000000000176712166703654021720 0ustar rootroot/* * inc/stdinc.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include #include #include #include #include #include #include #include #include "def.h" #include "types.h" #include #include soapdenovo2-240+dfsg.orig/standardPregraph/inc/newhash.h0000644000000000000000000000761512166703654022067 0ustar rootroot/* * inc/newhash.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef __NEW_HASH_RJ #define __NEW_HASH_RJ #ifndef K_LOAD_FACTOR #define K_LOAD_FACTOR 0.75 #endif #define MAX_KMER_COV 63 #define EDGE_BIT_SIZE 6 //6 bit for each edge #define EDGE_XOR_MASK 0x3FU #define LINKS_BITS 0x00FFFFFFU #define get_kmer_seq(mer) ((mer).seq) #define set_kmer_seq(mer, val) ((mer).seq = val) #define get_kmer_left_cov(mer, idx) (((mer).l_links>>((idx)*EDGE_BIT_SIZE))&EDGE_XOR_MASK) #define set_kmer_left_cov(mer, idx, val) ((mer).l_links = ((mer).l_links&(~(EDGE_XOR_MASK<<((idx)*EDGE_BIT_SIZE)))) | (((val)&EDGE_XOR_MASK)<<((idx)*EDGE_BIT_SIZE)) ) #define get_kmer_left_covs(mer) (get_kmer_left_cov(mer, 0) + get_kmer_left_cov(mer, 1) + get_kmer_left_cov(mer, 2) + get_kmer_left_cov(mer, 3)) #define get_kmer_right_cov(mer, idx) (((mer).r_links>>((idx)*EDGE_BIT_SIZE))&EDGE_XOR_MASK) #define set_kmer_right_cov(mer, idx, val) ((mer).r_links = ((mer).r_links&(~(EDGE_XOR_MASK<<((idx)*EDGE_BIT_SIZE)))) | (((val)&EDGE_XOR_MASK)<<((idx)*EDGE_BIT_SIZE)) ) #define get_kmer_right_covs(mer) (get_kmer_right_cov(mer, 0) + get_kmer_right_cov(mer, 1) + get_kmer_right_cov(mer, 2) + get_kmer_right_cov(mer, 3)) #define is_kmer_entity_null(flags, idx) ((flags)[(idx)>>4]>>(((idx)&0x0f)<<1)&0x01) #define is_kmer_entity_del(flags, idx) ((flags)[(idx)>>4]>>(((idx)&0x0f)<<1)&0x02) #define set_kmer_entity_null(flags, idx) ((flags)[(idx)>>4] |= (0x01u<<(((idx)&0x0f)<<1))) #define set_kmer_entity_del(flags, idx) ((flags)[(idx)>>4] |= (0x02u<<(((idx)&0x0f)<<1))) #define clear_kmer_entity_null(flags, idx) ((flags)[(idx)>>4] &= ~(0x01u<<(((idx)&0x0f)<<1))) #define clear_kmer_entity_del(flags, idx) ((flags)[(idx)>>4] &= ~(0x02u<<(((idx)&0x0f)<<1))) #define exists_kmer_entity(flags, idx) (!((flags)[(idx)>>4]>>(((idx)&0x0f)<<1)&0x03)) #ifdef MER127 typedef __uint128_t u128b; typedef struct u256b { u128b low; u128b high; } U256b; #else #endif typedef struct kmer_st { Kmer seq; //kmer set ubyte4 l_links; // sever as edgeID since make_edge ubyte4 r_links: 4 * EDGE_BIT_SIZE; ubyte4 linear: 1; ubyte4 deleted: 1; ubyte4 checked: 1; ubyte4 single: 1; ubyte4 twin: 2; ubyte4 inEdge: 2; } kmer_t; typedef struct kmerSet_st { kmer_t * array; //kmer set ubyte4 * flags; //mark the element pos that exist in array ubyte8 size; ubyte8 count; ubyte8 max; float load_factor; ubyte8 iter_ptr; //iter in set } KmerSet; typedef struct kmer_pt { kmer_t * node; Kmer kmer; boolean isSmaller; struct kmer_pt * next; } KMER_PT; extern KmerSet * init_kmerset ( ubyte8 init_size, float load_factor ); extern int search_kmerset ( KmerSet * set, Kmer seq, kmer_t ** rs ); extern int put_kmerset ( KmerSet * set, Kmer seq, ubyte left, ubyte right, kmer_t ** kmer_p ); extern byte8 count_kmerset ( KmerSet * set ); extern void free_Sets ( KmerSet ** KmerSets, int num ); extern void free_kmerset ( KmerSet * set ); extern void dislink2nextUncertain ( kmer_t * node, char ch, boolean smaller ); extern void dislink2prevUncertain ( kmer_t * node, char ch, boolean smaller ); extern int count_branch2prev ( kmer_t * node ); extern int count_branch2next ( kmer_t * node ); extern char firstCharInKmer ( Kmer kmer ); #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/knetfile.h0000644000000000000000000000314212166703654022222 0ustar rootroot#ifndef KNETFILE_H #define KNETFILE_H #include #include #ifndef _WIN32 #define netread(fd, ptr, len) read(fd, ptr, len) #define netwrite(fd, ptr, len) write(fd, ptr, len) #define netclose(fd) close(fd) #else #include #define netread(fd, ptr, len) recv(fd, ptr, len, 0) #define netwrite(fd, ptr, len) send(fd, ptr, len, 0) #define netclose(fd) closesocket(fd) #endif // FIXME: currently I/O is unbuffered #define KNF_TYPE_LOCAL 1 #define KNF_TYPE_FTP 2 #define KNF_TYPE_HTTP 3 typedef struct knetFile_s { int type, fd; int64_t offset; char * host, *port; // the following are for FTP only int ctrl_fd, pasv_ip[4], pasv_port, max_response, no_reconnect, is_ready; char * response, *retr, *size_cmd; int64_t seek_offset; // for lazy seek int64_t file_size; // the following are for HTTP only char * path, *http_host; } knetFile; #define knet_tell(fp) ((fp)->offset) #define knet_fileno(fp) ((fp)->fd) #ifdef __cplusplus extern "C" { #endif #ifdef _WIN32 int knet_win32_init(); void knet_win32_destroy(); #endif knetFile * knet_open ( const char * fn, const char * mode ); /* This only works with local files. */ knetFile * knet_dopen ( int fd, const char * mode ); /* If ->is_ready==0, this routine updates ->fd; otherwise, it simply reads from ->fd. */ off_t knet_read ( knetFile * fp, void * buf, off_t len ); /* This routine only sets ->offset and ->is_ready=0. It does not communicate with the FTP server. */ off_t knet_seek ( knetFile * fp, int64_t off, int whence ); int knet_close ( knetFile * fp ); #ifdef __cplusplus } #endif #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/razf.h0000644000000000000000000001006512166703654021365 0ustar rootroot/*- * RAZF : Random Access compressed(Z) File * Version: 1.0 * Release Date: 2008-10-27 * * Copyright 2008, Jue Ruan , Heng Li * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND 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 THE AUTHOR OR 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. */ #ifndef __RAZF_RJ_H #define __RAZF_RJ_H #include #include #include "zlib.h" #ifdef _USE_KNETFILE #include "knetfile.h" #endif #if ZLIB_VERNUM < 0x1221 #define _RZ_READONLY struct _gz_header_s; typedef struct _gz_header_s _gz_header; #define gz_header _gz_header #endif #define WINDOW_BITS 15 #ifndef RZ_BLOCK_SIZE #define RZ_BLOCK_SIZE (1<mode from HEAD to TYPE after call inflateReset */ int buf_off, buf_len; int z_err, z_eof; int seekable; /* Indice where the source is seekable */ int load_index; /* set has_index to 0 in mode 'w', then index will be discarded */ } RAZF; #ifdef __cplusplus extern "C" { #endif RAZF * razf_dopen ( int data_fd, const char * mode ); RAZF * razf_open ( const char * fn, const char * mode ); int razf_write ( RAZF * rz, const void * data, int size ); int razf_read ( RAZF * rz, void * data, int size ); int64_t razf_seek ( RAZF * rz, int64_t pos, int where ); void razf_close ( RAZF * rz ); #define razf_tell(rz) ((rz)->out) RAZF * razf_open2 ( const char * filename, const char * mode ); RAZF * razf_dopen2 ( int fd, const char * mode ); uint64_t razf_tell2 ( RAZF * rz ); int64_t razf_seek2 ( RAZF * rz, uint64_t voffset, int where ); #ifdef __cplusplus } #endif #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/def2.h0000644000000000000000000000323612166703654021245 0ustar rootroot/* * inc/def2.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef _DEF2 #define _DEF2 typedef char boolean; typedef long long IDnum; typedef double Time; typedef long long Coordinate; // Fibonacci heaps used mainly in Tour Bus typedef struct fibheap FibHeap; typedef struct fibheap_el FibHeapNode; typedef struct dfibheap DFibHeap; typedef struct dfibheap_el DFibHeapNode; //Memory manager typedef struct block_start { struct block_start * next; } BLOCK_START; typedef struct recycle_mark { struct recycle_mark * next; } RECYCLE_MARK; typedef struct mem_manager { BLOCK_START * block_list; int index_in_block; int items_per_block; size_t item_size; RECYCLE_MARK * recycle_list; unsigned long long counter; } MEM_MANAGER; struct dfibheap_el { int dfhe_degree; boolean dfhe_mark; DFibHeapNode * dfhe_p; DFibHeapNode * dfhe_child; DFibHeapNode * dfhe_left; DFibHeapNode * dfhe_right; Time dfhe_key; unsigned int dfhe_data;//void *dfhe_data; }; #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/fib.h0000644000000000000000000000470712166703654021171 0ustar rootroot/* * inc/fib.h * * This file is part of SOAPdenovo. * */ /*- * Copyright 1997, 1998-2003 John-Mark Gurney. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND 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 THE AUTHOR OR 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. * */ #ifndef _FIB_H_ #define _FIB_H_ //#include "globals.h" #include #include "def2.h" typedef Coordinate ( *voidcmp ) ( unsigned int , unsigned int ); /* functions for key heaps */ boolean fh_isempty ( FibHeap * ); FibHeap * fh_makekeyheap ( void ); FibHeapNode * fh_insertkey ( FibHeap *, Coordinate, unsigned int ); Coordinate fh_minkey ( FibHeap * ); Coordinate fh_replacekey ( FibHeap *, FibHeapNode *, Coordinate ); unsigned int fh_replacekeydata ( FibHeap *, FibHeapNode *, Coordinate, unsigned int ); /* functions for unsigned int * heaps */ FibHeap * fh_makeheap ( void ); voidcmp fh_setcmp ( FibHeap *, voidcmp ); unsigned int fh_setneginf ( FibHeap *, unsigned int ); FibHeapNode * fh_insert ( FibHeap *, unsigned int ); /* shared functions */ unsigned int fh_extractmin ( FibHeap * ); unsigned int fh_min ( FibHeap * ); unsigned int fh_replacedata ( FibHeapNode *, unsigned int ); unsigned int fh_delete ( FibHeap *, FibHeapNode * ); void fh_deleteheap ( FibHeap * ); FibHeap * fh_union ( FibHeap *, FibHeap * ); #endif /* _FIB_H_ */ soapdenovo2-240+dfsg.orig/standardPregraph/inc/kstring.h0000644000000000000000000000321012166703654022076 0ustar rootroot#ifndef KSTRING_H #define KSTRING_H #include #include #include #ifndef kroundup32 #define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) #endif #ifndef KSTRING_T #define KSTRING_T kstring_t typedef struct __kstring_t { size_t l, m; char * s; } kstring_t; #endif int ksprintf ( kstring_t * s, const char * fmt, ... ); int ksplit_core ( char * s, int delimiter, int * _max, int ** _offsets ); // calculate the auxiliary array, allocated by calloc() int * ksBM_prep ( const uint8_t * pat, int m ); /* Search pat in str and returned the list of matches. The size of the * list is returned as n_matches. _prep is the array returned by * ksBM_prep(). If it is a NULL pointer, ksBM_prep() will be called. */ int * ksBM_search ( const uint8_t * str, int n, const uint8_t * pat, int m, int * _prep, int * n_matches ); static inline int kputsn ( const char * p, int l, kstring_t * s ) { if ( s->l + l + 1 >= s->m ) { s->m = s->l + l + 2; kroundup32 ( s->m ); s->s = ( char * ) realloc ( s->s, s->m ); } strncpy ( s->s + s->l, p, l ); s->l += l; s->s[s->l] = 0; return l; } static inline int kputs ( const char * p, kstring_t * s ) { return kputsn ( p, strlen ( p ), s ); } static inline int kputc ( int c, kstring_t * s ) { if ( s->l + 1 >= s->m ) { s->m = s->l + 2; kroundup32 ( s->m ); s->s = ( char * ) realloc ( s->s, s->m ); } s->s[s->l++] = c; s->s[s->l] = 0; return c; } static inline int * ksplit ( kstring_t * s, int delimiter, int * n ) { int max = 0, *offsets = 0; *n = ksplit_core ( s->s, delimiter, &max, &offsets ); return offsets; } #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/kmerhash.h0000644000000000000000000000370412166703654022227 0ustar rootroot/* * inc/kmerhash.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef __KMER_HASH_RJ #define __KMER_HASH_RJ #define set_kmer_id(mer, val) ((mer).edgeId = val) typedef struct edgeID { unsigned int edge; //edge id char flag; //00: big to, 01: big from, 10: small to, 11: small from struct edgeID * next; } EDGEID; typedef struct kmer_st2 { Kmer seq; //kmer sequence ubyte4 l_links; //left out degree ubyte4 r_links; //right out degree int count; //edge number struct edgeID * edgeId; } kmer_t2; typedef struct kmerSet_st2 { kmer_t2 * array; //kmer set ubyte4 * flags; //mark the element pos that exist in array ubyte8 size; ubyte8 count; ubyte8 max; double load_factor; ubyte8 iter_ptr; } KmerSet2; extern KmerSet2 * init_kmerset2 ( ubyte8 init_size, float load_factor ); extern int search_kmerset2 ( KmerSet2 * set, Kmer seq, kmer_t2 ** rs ); extern int put_kmerset2 ( KmerSet2 * set, Kmer seq, int id, char flag, kmer_t2 ** kmer_p ); extern byte8 count_kmerset2 ( KmerSet2 * set ); extern void free_Sets2 ( KmerSet2 ** KmerSets, int num ); extern void free_kmerset2 ( KmerSet2 * set ); extern void update_kmer2 ( kmer_t2 * mer, int id, char flag ); extern void set_new_kmer2 ( kmer_t2 * mer, Kmer seq, int id, char flag ); #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/check.h0000644000000000000000000000170412166703654021500 0ustar rootroot/* * inc/check.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ extern void * ckalloc ( unsigned long long amount ); extern void * ckrealloc ( void * p, size_t new_size, size_t old_size ); extern FILE * ckopen ( char * name, char * mode ); soapdenovo2-240+dfsg.orig/standardPregraph/inc/dfibHeap.h0000644000000000000000000000255412166703654022131 0ustar rootroot/* * inc/dfibHeap.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef _DFIBHEAP_H_ #define _DFIBHEAP_H_ DFibHeap * newDFibHeap(); DFibHeapNode * insertNodeIntoDHeap ( DFibHeap * heap, Time key, unsigned int node ); Time replaceKeyInDHeap ( DFibHeap * heap, DFibHeapNode * node, Time newKey ); unsigned int removeNextNodeFromDHeap ( DFibHeap * heap ); void destroyDHeap ( DFibHeap * heap ); boolean HasMin ( DFibHeap * h ); void replaceValueInDHeap ( DFibHeapNode * node, unsigned int newValue ); void * destroyNodeInDHeap ( DFibHeapNode * node, DFibHeap * heap ); IDnum getDFibHeapSize ( DFibHeap * heap ); Time getKey ( DFibHeapNode * node ); #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/xcurses.h0000644000000000000000000014465212166703654022131 0ustar rootroot/* Public Domain Curses */ /* $Id: curses.h,v 1.295 2008/07/15 17:13:25 wmcbrine Exp $ */ /*----------------------------------------------------------------------* * PDCurses * *----------------------------------------------------------------------*/ #ifndef __PDCURSES__ #define __PDCURSES__ 1 /*man-start************************************************************** PDCurses definitions list: (Only define those needed) XCURSES True if compiling for X11. PDC_RGB True if you want to use RGB color definitions (Red = 1, Green = 2, Blue = 4) instead of BGR. PDC_WIDE True if building wide-character support. PDC_DLL_BUILD True if building a Win32 DLL. NCURSES_MOUSE_VERSION Use the ncurses mouse API instead of PDCurses' traditional mouse API. PDCurses portable platform definitions list: PDC_BUILD Defines API build version. PDCURSES Enables access to PDCurses-only routines. XOPEN Always true. SYSVcurses True if you are compiling for SYSV portability. BSDcurses True if you are compiling for BSD portability. **man-end****************************************************************/ #define PDC_BUILD 3401 #define PDCURSES 1 /* PDCurses-only routines */ #define XOPEN 1 /* X/Open Curses routines */ #define SYSVcurses 1 /* System V Curses routines */ #define BSDcurses 1 /* BSD Curses routines */ #define CHTYPE_LONG 1 /* size of chtype; long */ /*----------------------------------------------------------------------*/ #include #include #include /* Required by X/Open usage below */ #ifdef PDC_WIDE # include #endif #if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS) extern "C" { # define bool _bool #endif /*---------------------------------------------------------------------- * * PDCurses Manifest Constants * */ #ifndef FALSE # define FALSE 0 #endif #ifndef TRUE # define TRUE 1 #endif #ifndef NULL # define NULL (void *)0 #endif #ifndef ERR # define ERR (-1) #endif #ifndef OK # define OK 0 #endif /*---------------------------------------------------------------------- * * PDCurses Type Declarations * */ //typedef unsigned char bool; /* PDCurses Boolean type */ #ifdef CHTYPE_LONG # if _LP64 typedef unsigned int chtype; # else typedef unsigned long chtype; /* 16-bit attr + 16-bit char */ # endif #else typedef unsigned short chtype; /* 8-bit attr + 8-bit char */ #endif #ifdef PDC_WIDE typedef chtype cchar_t; #endif typedef chtype attr_t; /*---------------------------------------------------------------------- * * PDCurses Mouse Interface -- SYSVR4, with extensions * */ typedef struct { int x; /* absolute column, 0 based, measured in characters */ int y; /* absolute row, 0 based, measured in characters */ short button[3]; /* state of each button */ int changes; /* flags indicating what has changed with the mouse */ } MOUSE_STATUS; #define BUTTON_RELEASED 0x0000 #define BUTTON_PRESSED 0x0001 #define BUTTON_CLICKED 0x0002 #define BUTTON_DOUBLE_CLICKED 0x0003 #define BUTTON_TRIPLE_CLICKED 0x0004 #define BUTTON_MOVED 0x0005 /* PDCurses */ #define WHEEL_SCROLLED 0x0006 /* PDCurses */ #define BUTTON_ACTION_MASK 0x0007 /* PDCurses */ #define PDC_BUTTON_SHIFT 0x0008 /* PDCurses */ #define PDC_BUTTON_CONTROL 0x0010 /* PDCurses */ #define PDC_BUTTON_ALT 0x0020 /* PDCurses */ #define BUTTON_MODIFIER_MASK 0x0038 /* PDCurses */ #define MOUSE_X_POS (Mouse_status.x) #define MOUSE_Y_POS (Mouse_status.y) /* * Bits associated with the .changes field: * 3 2 1 0 * 210987654321098765432109876543210 * 1 <- button 1 has changed * 10 <- button 2 has changed * 100 <- button 3 has changed * 1000 <- mouse has moved * 10000 <- mouse position report * 100000 <- mouse wheel up * 1000000 <- mouse wheel down */ #define PDC_MOUSE_MOVED 0x0008 #define PDC_MOUSE_POSITION 0x0010 #define PDC_MOUSE_WHEEL_UP 0x0020 #define PDC_MOUSE_WHEEL_DOWN 0x0040 #define A_BUTTON_CHANGED (Mouse_status.changes & 7) #define MOUSE_MOVED (Mouse_status.changes & PDC_MOUSE_MOVED) #define MOUSE_POS_REPORT (Mouse_status.changes & PDC_MOUSE_POSITION) #define BUTTON_CHANGED(x) (Mouse_status.changes & (1 << ((x) - 1))) #define BUTTON_STATUS(x) (Mouse_status.button[(x) - 1]) #define MOUSE_WHEEL_UP (Mouse_status.changes & PDC_MOUSE_WHEEL_UP) #define MOUSE_WHEEL_DOWN (Mouse_status.changes & PDC_MOUSE_WHEEL_DOWN) /* mouse bit-masks */ #define BUTTON1_RELEASED 0x00000001L #define BUTTON1_PRESSED 0x00000002L #define BUTTON1_CLICKED 0x00000004L #define BUTTON1_DOUBLE_CLICKED 0x00000008L #define BUTTON1_TRIPLE_CLICKED 0x00000010L #define BUTTON1_MOVED 0x00000010L /* PDCurses */ #define BUTTON2_RELEASED 0x00000020L #define BUTTON2_PRESSED 0x00000040L #define BUTTON2_CLICKED 0x00000080L #define BUTTON2_DOUBLE_CLICKED 0x00000100L #define BUTTON2_TRIPLE_CLICKED 0x00000200L #define BUTTON2_MOVED 0x00000200L /* PDCurses */ #define BUTTON3_RELEASED 0x00000400L #define BUTTON3_PRESSED 0x00000800L #define BUTTON3_CLICKED 0x00001000L #define BUTTON3_DOUBLE_CLICKED 0x00002000L #define BUTTON3_TRIPLE_CLICKED 0x00004000L #define BUTTON3_MOVED 0x00004000L /* PDCurses */ /* For the ncurses-compatible functions only, BUTTON4_PRESSED and BUTTON5_PRESSED are returned for mouse scroll wheel up and down; otherwise PDCurses doesn't support buttons 4 and 5 */ #define BUTTON4_RELEASED 0x00008000L #define BUTTON4_PRESSED 0x00010000L #define BUTTON4_CLICKED 0x00020000L #define BUTTON4_DOUBLE_CLICKED 0x00040000L #define BUTTON4_TRIPLE_CLICKED 0x00080000L #define BUTTON5_RELEASED 0x00100000L #define BUTTON5_PRESSED 0x00200000L #define BUTTON5_CLICKED 0x00400000L #define BUTTON5_DOUBLE_CLICKED 0x00800000L #define BUTTON5_TRIPLE_CLICKED 0x01000000L #define MOUSE_WHEEL_SCROLL 0x02000000L /* PDCurses */ #define BUTTON_MODIFIER_SHIFT 0x04000000L /* PDCurses */ #define BUTTON_MODIFIER_CONTROL 0x08000000L /* PDCurses */ #define BUTTON_MODIFIER_ALT 0x10000000L /* PDCurses */ #define ALL_MOUSE_EVENTS 0x1fffffffL #define REPORT_MOUSE_POSITION 0x20000000L /* ncurses mouse interface */ typedef unsigned long mmask_t; typedef struct { short id; /* unused, always 0 */ int x, y, z; /* x, y same as MOUSE_STATUS; z unused */ mmask_t bstate; /* equivalent to changes + button[], but in the same format as used for mousemask() */ } MEVENT; #ifdef NCURSES_MOUSE_VERSION # define BUTTON_SHIFT BUTTON_MODIFIER_SHIFT # define BUTTON_CONTROL BUTTON_MODIFIER_CONTROL # define BUTTON_CTRL BUTTON_MODIFIER_CONTROL # define BUTTON_ALT BUTTON_MODIFIER_ALT #else # define BUTTON_SHIFT PDC_BUTTON_SHIFT # define BUTTON_CONTROL PDC_BUTTON_CONTROL # define BUTTON_ALT PDC_BUTTON_ALT #endif /*---------------------------------------------------------------------- * * PDCurses Structure Definitions * */ typedef struct _win /* definition of a window */ { int _cury; /* current pseudo-cursor */ int _curx; int _maxy; /* max window coordinates */ int _maxx; int _begy; /* origin on screen */ int _begx; int _flags; /* window properties */ chtype _attrs; /* standard attributes and colors */ chtype _bkgd; /* background, normally blank */ bool _clear; /* causes clear at next refresh */ bool _leaveit; /* leaves cursor where it is */ bool _scroll; /* allows window scrolling */ bool _nodelay; /* input character wait flag */ bool _immed; /* immediate update flag */ bool _sync; /* synchronise window ancestors */ bool _use_keypad; /* flags keypad key mode active */ chtype ** _y; /* pointer to line pointer array */ int * _firstch; /* first changed character in line */ int * _lastch; /* last changed character in line */ int _tmarg; /* top of scrolling region */ int _bmarg; /* bottom of scrolling region */ int _delayms; /* milliseconds of delay for getch() */ int _parx, _pary; /* coords relative to parent (0,0) */ struct _win * _parent; /* subwin's pointer to parent win */ } WINDOW; /* Avoid using the SCREEN struct directly -- use the corresponding functions if possible. This struct may eventually be made private. */ typedef struct { bool alive; /* if initscr() called, and not endwin() */ bool autocr; /* if cr -> lf */ bool cbreak; /* if terminal unbuffered */ bool echo; /* if terminal echo */ bool raw_inp; /* raw input mode (v. cooked input) */ bool raw_out; /* raw output mode (7 v. 8 bits) */ bool audible; /* FALSE if the bell is visual */ bool mono; /* TRUE if current screen is mono */ bool resized; /* TRUE if TERM has been resized */ bool orig_attr; /* TRUE if we have the original colors */ short orig_fore; /* original screen foreground color */ short orig_back; /* original screen foreground color */ int cursrow; /* position of physical cursor */ int curscol; /* position of physical cursor */ int visibility; /* visibility of cursor */ int orig_cursor; /* original cursor size */ int lines; /* new value for LINES */ int cols; /* new value for COLS */ unsigned long _trap_mbe; /* trap these mouse button events */ unsigned long _map_mbe_to_key; /* map mouse buttons to slk */ int mouse_wait; /* time to wait (in ms) for a button release after a press, in order to count it as a click */ int slklines; /* lines in use by slk_init() */ WINDOW * slk_winptr; /* window for slk */ int linesrippedoff; /* lines ripped off via ripoffline() */ int linesrippedoffontop; /* lines ripped off on top via ripoffline() */ int delaytenths; /* 1/10ths second to wait block getch() for */ bool _preserve; /* TRUE if screen background to be preserved */ int _restore; /* specifies if screen background to be restored, and how */ bool save_key_modifiers; /* TRUE if each key modifiers saved with each key press */ bool return_key_modifiers; /* TRUE if modifier keys are returned as "real" keys */ bool key_code; /* TRUE if last key is a special key; used internally by get_wch() */ #ifdef XCURSES int XcurscrSize; /* size of Xcurscr shared memory block */ bool sb_on; int sb_viewport_y; int sb_viewport_x; int sb_total_y; int sb_total_x; int sb_cur_y; int sb_cur_x; #endif short line_color; /* color of line attributes - default -1 */ } SCREEN; /*---------------------------------------------------------------------- * * PDCurses External Variables * */ #ifdef PDC_DLL_BUILD # ifdef CURSES_LIBRARY # define PDCEX __declspec(dllexport) extern # else # define PDCEX __declspec(dllimport) # endif #else # define PDCEX extern #endif PDCEX int LINES; /* terminal height */ PDCEX int COLS; /* terminal width */ PDCEX WINDOW * stdscr; /* the default screen window */ PDCEX WINDOW * curscr; /* the current screen image */ PDCEX SCREEN * SP; /* curses variables */ PDCEX MOUSE_STATUS Mouse_status; PDCEX int COLORS; PDCEX int COLOR_PAIRS; PDCEX int TABSIZE; PDCEX chtype acs_map[]; /* alternate character set map */ PDCEX char ttytype[]; /* terminal name/description */ /*man-start************************************************************** PDCurses Text Attributes ======================== Originally, PDCurses used a short (16 bits) for its chtype. To include color, a number of things had to be sacrificed from the strict Unix and System V support. The main problem was fitting all character attributes and color into an unsigned char (all 8 bits!). Today, PDCurses by default uses a long (32 bits) for its chtype, as in System V. The short chtype is still available, by undefining CHTYPE_LONG and rebuilding the library. The following is the structure of a win->_attrs chtype: short form: ------------------------------------------------- |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| ------------------------------------------------- color number | attrs | character eg 'a' The available non-color attributes are bold, reverse and blink. Others have no effect. The high order char is an index into an array of physical colors (defined in color.c) -- 32 foreground/background color pairs (5 bits) plus 3 bits for other attributes. long form: ---------------------------------------------------------------------------- |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|..| 3| 2| 1| 0| ---------------------------------------------------------------------------- color number | modifiers | character eg 'a' The available non-color attributes are bold, underline, invisible, right-line, left-line, protect, reverse and blink. 256 color pairs (8 bits), 8 bits for other attributes, and 16 bits for character data. **man-end****************************************************************/ /*** Video attribute macros ***/ #define A_NORMAL (chtype)0 #ifdef CHTYPE_LONG # define A_ALTCHARSET (chtype)0x00010000 # define A_RIGHTLINE (chtype)0x00020000 # define A_LEFTLINE (chtype)0x00040000 # define A_INVIS (chtype)0x00080000 # define A_UNDERLINE (chtype)0x00100000 # define A_REVERSE (chtype)0x00200000 # define A_BLINK (chtype)0x00400000 # define A_BOLD (chtype)0x00800000 # define A_ATTRIBUTES (chtype)0xffff0000 # define A_CHARTEXT (chtype)0x0000ffff # define A_COLOR (chtype)0xff000000 # define A_ITALIC A_INVIS # define A_PROTECT (A_UNDERLINE | A_LEFTLINE | A_RIGHTLINE) # define PDC_ATTR_SHIFT 19 # define PDC_COLOR_SHIFT 24 #else # define A_BOLD (chtype)0x0100 /* X/Open */ # define A_REVERSE (chtype)0x0200 /* X/Open */ # define A_BLINK (chtype)0x0400 /* X/Open */ # define A_ATTRIBUTES (chtype)0xff00 /* X/Open */ # define A_CHARTEXT (chtype)0x00ff /* X/Open */ # define A_COLOR (chtype)0xf800 /* System V */ # define A_ALTCHARSET A_NORMAL /* X/Open */ # define A_PROTECT A_NORMAL /* X/Open */ # define A_UNDERLINE A_NORMAL /* X/Open */ # define A_LEFTLINE A_NORMAL # define A_RIGHTLINE A_NORMAL # define A_ITALIC A_NORMAL # define A_INVIS A_NORMAL # define PDC_ATTR_SHIFT 8 # define PDC_COLOR_SHIFT 11 #endif #define A_STANDOUT (A_REVERSE | A_BOLD) /* X/Open */ #define A_DIM A_NORMAL #define CHR_MSK A_CHARTEXT /* Obsolete */ #define ATR_MSK A_ATTRIBUTES /* Obsolete */ #define ATR_NRM A_NORMAL /* Obsolete */ /* For use with attr_t -- X/Open says, "these shall be distinct", so this is a non-conforming implementation. */ #define WA_ALTCHARSET A_ALTCHARSET #define WA_BLINK A_BLINK #define WA_BOLD A_BOLD #define WA_DIM A_DIM #define WA_INVIS A_INVIS #define WA_LEFT A_LEFTLINE #define WA_PROTECT A_PROTECT #define WA_REVERSE A_REVERSE #define WA_RIGHT A_RIGHTLINE #define WA_STANDOUT A_STANDOUT #define WA_UNDERLINE A_UNDERLINE #define WA_HORIZONTAL A_NORMAL #define WA_LOW A_NORMAL #define WA_TOP A_NORMAL #define WA_VERTICAL A_NORMAL /*** Alternate character set macros ***/ /* 'w' = 32-bit chtype; acs_map[] index | A_ALTCHARSET 'n' = 16-bit chtype; it gets the fallback set because no bit is available for A_ALTCHARSET */ #ifdef CHTYPE_LONG # define ACS_PICK(w, n) ((chtype)w | A_ALTCHARSET) #else # define ACS_PICK(w, n) ((chtype)n) #endif /* VT100-compatible symbols -- box chars */ #define ACS_ULCORNER ACS_PICK('l', '+') #define ACS_LLCORNER ACS_PICK('m', '+') #define ACS_URCORNER ACS_PICK('k', '+') #define ACS_LRCORNER ACS_PICK('j', '+') #define ACS_RTEE ACS_PICK('u', '+') #define ACS_LTEE ACS_PICK('t', '+') #define ACS_BTEE ACS_PICK('v', '+') #define ACS_TTEE ACS_PICK('w', '+') #define ACS_HLINE ACS_PICK('q', '-') #define ACS_VLINE ACS_PICK('x', '|') #define ACS_PLUS ACS_PICK('n', '+') /* VT100-compatible symbols -- other */ #define ACS_S1 ACS_PICK('o', '-') #define ACS_S9 ACS_PICK('s', '_') #define ACS_DIAMOND ACS_PICK('`', '+') #define ACS_CKBOARD ACS_PICK('a', ':') #define ACS_DEGREE ACS_PICK('f', '\'') #define ACS_PLMINUS ACS_PICK('g', '#') #define ACS_BULLET ACS_PICK('~', 'o') /* Teletype 5410v1 symbols -- these are defined in SysV curses, but are not well-supported by most terminals. Stick to VT100 characters for optimum portability. */ #define ACS_LARROW ACS_PICK(',', '<') #define ACS_RARROW ACS_PICK('+', '>') #define ACS_DARROW ACS_PICK('.', 'v') #define ACS_UARROW ACS_PICK('-', '^') #define ACS_BOARD ACS_PICK('h', '#') #define ACS_LANTERN ACS_PICK('i', '*') #define ACS_BLOCK ACS_PICK('0', '#') /* That goes double for these -- undocumented SysV symbols. Don't use them. */ #define ACS_S3 ACS_PICK('p', '-') #define ACS_S7 ACS_PICK('r', '-') #define ACS_LEQUAL ACS_PICK('y', '<') #define ACS_GEQUAL ACS_PICK('z', '>') #define ACS_PI ACS_PICK('{', 'n') #define ACS_NEQUAL ACS_PICK('|', '+') #define ACS_STERLING ACS_PICK('}', 'L') /* Box char aliases */ #define ACS_BSSB ACS_ULCORNER #define ACS_SSBB ACS_LLCORNER #define ACS_BBSS ACS_URCORNER #define ACS_SBBS ACS_LRCORNER #define ACS_SBSS ACS_RTEE #define ACS_SSSB ACS_LTEE #define ACS_SSBS ACS_BTEE #define ACS_BSSS ACS_TTEE #define ACS_BSBS ACS_HLINE #define ACS_SBSB ACS_VLINE #define ACS_SSSS ACS_PLUS /* cchar_t aliases */ #ifdef PDC_WIDE # define WACS_ULCORNER (&(acs_map['l'])) # define WACS_LLCORNER (&(acs_map['m'])) # define WACS_URCORNER (&(acs_map['k'])) # define WACS_LRCORNER (&(acs_map['j'])) # define WACS_RTEE (&(acs_map['u'])) # define WACS_LTEE (&(acs_map['t'])) # define WACS_BTEE (&(acs_map['v'])) # define WACS_TTEE (&(acs_map['w'])) # define WACS_HLINE (&(acs_map['q'])) # define WACS_VLINE (&(acs_map['x'])) # define WACS_PLUS (&(acs_map['n'])) # define WACS_S1 (&(acs_map['o'])) # define WACS_S9 (&(acs_map['s'])) # define WACS_DIAMOND (&(acs_map['`'])) # define WACS_CKBOARD (&(acs_map['a'])) # define WACS_DEGREE (&(acs_map['f'])) # define WACS_PLMINUS (&(acs_map['g'])) # define WACS_BULLET (&(acs_map['~'])) # define WACS_LARROW (&(acs_map[','])) # define WACS_RARROW (&(acs_map['+'])) # define WACS_DARROW (&(acs_map['.'])) # define WACS_UARROW (&(acs_map['-'])) # define WACS_BOARD (&(acs_map['h'])) # define WACS_LANTERN (&(acs_map['i'])) # define WACS_BLOCK (&(acs_map['0'])) # define WACS_S3 (&(acs_map['p'])) # define WACS_S7 (&(acs_map['r'])) # define WACS_LEQUAL (&(acs_map['y'])) # define WACS_GEQUAL (&(acs_map['z'])) # define WACS_PI (&(acs_map['{'])) # define WACS_NEQUAL (&(acs_map['|'])) # define WACS_STERLING (&(acs_map['}'])) # define WACS_BSSB WACS_ULCORNER # define WACS_SSBB WACS_LLCORNER # define WACS_BBSS WACS_URCORNER # define WACS_SBBS WACS_LRCORNER # define WACS_SBSS WACS_RTEE # define WACS_SSSB WACS_LTEE # define WACS_SSBS WACS_BTEE # define WACS_BSSS WACS_TTEE # define WACS_BSBS WACS_HLINE # define WACS_SBSB WACS_VLINE # define WACS_SSSS WACS_PLUS #endif /*** Color macros ***/ #define COLOR_BLACK 0 #ifdef PDC_RGB /* RGB */ # define COLOR_RED 1 # define COLOR_GREEN 2 # define COLOR_BLUE 4 #else /* BGR */ # define COLOR_BLUE 1 # define COLOR_GREEN 2 # define COLOR_RED 4 #endif #define COLOR_CYAN (COLOR_BLUE | COLOR_GREEN) #define COLOR_MAGENTA (COLOR_RED | COLOR_BLUE) #define COLOR_YELLOW (COLOR_RED | COLOR_GREEN) #define COLOR_WHITE 7 /*---------------------------------------------------------------------- * * Function and Keypad Key Definitions. * Many are just for compatibility. * */ #define KEY_CODE_YES 0x100 /* If get_wch() gives a key code */ #define KEY_BREAK 0x101 /* Not on PC KBD */ #define KEY_DOWN 0x102 /* Down arrow key */ #define KEY_UP 0x103 /* Up arrow key */ #define KEY_LEFT 0x104 /* Left arrow key */ #define KEY_RIGHT 0x105 /* Right arrow key */ #define KEY_HOME 0x106 /* home key */ #define KEY_BACKSPACE 0x107 /* not on pc */ #define KEY_F0 0x108 /* function keys; 64 reserved */ #define KEY_DL 0x148 /* delete line */ #define KEY_IL 0x149 /* insert line */ #define KEY_DC 0x14a /* delete character */ #define KEY_IC 0x14b /* insert char or enter ins mode */ #define KEY_EIC 0x14c /* exit insert char mode */ #define KEY_CLEAR 0x14d /* clear screen */ #define KEY_EOS 0x14e /* clear to end of screen */ #define KEY_EOL 0x14f /* clear to end of line */ #define KEY_SF 0x150 /* scroll 1 line forward */ #define KEY_SR 0x151 /* scroll 1 line back (reverse) */ #define KEY_NPAGE 0x152 /* next page */ #define KEY_PPAGE 0x153 /* previous page */ #define KEY_STAB 0x154 /* set tab */ #define KEY_CTAB 0x155 /* clear tab */ #define KEY_CATAB 0x156 /* clear all tabs */ #define KEY_ENTER 0x157 /* enter or send (unreliable) */ #define KEY_SRESET 0x158 /* soft/reset (partial/unreliable) */ #define KEY_RESET 0x159 /* reset/hard reset (unreliable) */ #define KEY_PRINT 0x15a /* print/copy */ #define KEY_LL 0x15b /* home down/bottom (lower left) */ #define KEY_ABORT 0x15c /* abort/terminate key (any) */ #define KEY_SHELP 0x15d /* short help */ #define KEY_LHELP 0x15e /* long help */ #define KEY_BTAB 0x15f /* Back tab key */ #define KEY_BEG 0x160 /* beg(inning) key */ #define KEY_CANCEL 0x161 /* cancel key */ #define KEY_CLOSE 0x162 /* close key */ #define KEY_COMMAND 0x163 /* cmd (command) key */ #define KEY_COPY 0x164 /* copy key */ #define KEY_CREATE 0x165 /* create key */ #define KEY_END 0x166 /* end key */ #define KEY_EXIT 0x167 /* exit key */ #define KEY_FIND 0x168 /* find key */ #define KEY_HELP 0x169 /* help key */ #define KEY_MARK 0x16a /* mark key */ #define KEY_MESSAGE 0x16b /* message key */ #define KEY_MOVE 0x16c /* move key */ #define KEY_NEXT 0x16d /* next object key */ #define KEY_OPEN 0x16e /* open key */ #define KEY_OPTIONS 0x16f /* options key */ #define KEY_PREVIOUS 0x170 /* previous object key */ #define KEY_REDO 0x171 /* redo key */ #define KEY_REFERENCE 0x172 /* ref(erence) key */ #define KEY_REFRESH 0x173 /* refresh key */ #define KEY_REPLACE 0x174 /* replace key */ #define KEY_RESTART 0x175 /* restart key */ #define KEY_RESUME 0x176 /* resume key */ #define KEY_SAVE 0x177 /* save key */ #define KEY_SBEG 0x178 /* shifted beginning key */ #define KEY_SCANCEL 0x179 /* shifted cancel key */ #define KEY_SCOMMAND 0x17a /* shifted command key */ #define KEY_SCOPY 0x17b /* shifted copy key */ #define KEY_SCREATE 0x17c /* shifted create key */ #define KEY_SDC 0x17d /* shifted delete char key */ #define KEY_SDL 0x17e /* shifted delete line key */ #define KEY_SELECT 0x17f /* select key */ #define KEY_SEND 0x180 /* shifted end key */ #define KEY_SEOL 0x181 /* shifted clear line key */ #define KEY_SEXIT 0x182 /* shifted exit key */ #define KEY_SFIND 0x183 /* shifted find key */ #define KEY_SHOME 0x184 /* shifted home key */ #define KEY_SIC 0x185 /* shifted input key */ #define KEY_SLEFT 0x187 /* shifted left arrow key */ #define KEY_SMESSAGE 0x188 /* shifted message key */ #define KEY_SMOVE 0x189 /* shifted move key */ #define KEY_SNEXT 0x18a /* shifted next key */ #define KEY_SOPTIONS 0x18b /* shifted options key */ #define KEY_SPREVIOUS 0x18c /* shifted prev key */ #define KEY_SPRINT 0x18d /* shifted print key */ #define KEY_SREDO 0x18e /* shifted redo key */ #define KEY_SREPLACE 0x18f /* shifted replace key */ #define KEY_SRIGHT 0x190 /* shifted right arrow */ #define KEY_SRSUME 0x191 /* shifted resume key */ #define KEY_SSAVE 0x192 /* shifted save key */ #define KEY_SSUSPEND 0x193 /* shifted suspend key */ #define KEY_SUNDO 0x194 /* shifted undo key */ #define KEY_SUSPEND 0x195 /* suspend key */ #define KEY_UNDO 0x196 /* undo key */ /* PDCurses-specific key definitions -- PC only */ #define ALT_0 0x197 #define ALT_1 0x198 #define ALT_2 0x199 #define ALT_3 0x19a #define ALT_4 0x19b #define ALT_5 0x19c #define ALT_6 0x19d #define ALT_7 0x19e #define ALT_8 0x19f #define ALT_9 0x1a0 #define ALT_A 0x1a1 #define ALT_B 0x1a2 #define ALT_C 0x1a3 #define ALT_D 0x1a4 #define ALT_E 0x1a5 #define ALT_F 0x1a6 #define ALT_G 0x1a7 #define ALT_H 0x1a8 #define ALT_I 0x1a9 #define ALT_J 0x1aa #define ALT_K 0x1ab #define ALT_L 0x1ac #define ALT_M 0x1ad #define ALT_N 0x1ae #define ALT_O 0x1af #define ALT_P 0x1b0 #define ALT_Q 0x1b1 #define ALT_R 0x1b2 #define ALT_S 0x1b3 #define ALT_T 0x1b4 #define ALT_U 0x1b5 #define ALT_V 0x1b6 #define ALT_W 0x1b7 #define ALT_X 0x1b8 #define ALT_Y 0x1b9 #define ALT_Z 0x1ba #define CTL_LEFT 0x1bb /* Control-Left-Arrow */ #define CTL_RIGHT 0x1bc #define CTL_PGUP 0x1bd #define CTL_PGDN 0x1be #define CTL_HOME 0x1bf #define CTL_END 0x1c0 #define KEY_A1 0x1c1 /* upper left on Virtual keypad */ #define KEY_A2 0x1c2 /* upper middle on Virt. keypad */ #define KEY_A3 0x1c3 /* upper right on Vir. keypad */ #define KEY_B1 0x1c4 /* middle left on Virt. keypad */ #define KEY_B2 0x1c5 /* center on Virt. keypad */ #define KEY_B3 0x1c6 /* middle right on Vir. keypad */ #define KEY_C1 0x1c7 /* lower left on Virt. keypad */ #define KEY_C2 0x1c8 /* lower middle on Virt. keypad */ #define KEY_C3 0x1c9 /* lower right on Vir. keypad */ #define PADSLASH 0x1ca /* slash on keypad */ #define PADENTER 0x1cb /* enter on keypad */ #define CTL_PADENTER 0x1cc /* ctl-enter on keypad */ #define ALT_PADENTER 0x1cd /* alt-enter on keypad */ #define PADSTOP 0x1ce /* stop on keypad */ #define PADSTAR 0x1cf /* star on keypad */ #define PADMINUS 0x1d0 /* minus on keypad */ #define PADPLUS 0x1d1 /* plus on keypad */ #define CTL_PADSTOP 0x1d2 /* ctl-stop on keypad */ #define CTL_PADCENTER 0x1d3 /* ctl-enter on keypad */ #define CTL_PADPLUS 0x1d4 /* ctl-plus on keypad */ #define CTL_PADMINUS 0x1d5 /* ctl-minus on keypad */ #define CTL_PADSLASH 0x1d6 /* ctl-slash on keypad */ #define CTL_PADSTAR 0x1d7 /* ctl-star on keypad */ #define ALT_PADPLUS 0x1d8 /* alt-plus on keypad */ #define ALT_PADMINUS 0x1d9 /* alt-minus on keypad */ #define ALT_PADSLASH 0x1da /* alt-slash on keypad */ #define ALT_PADSTAR 0x1db /* alt-star on keypad */ #define ALT_PADSTOP 0x1dc /* alt-stop on keypad */ #define CTL_INS 0x1dd /* ctl-insert */ #define ALT_DEL 0x1de /* alt-delete */ #define ALT_INS 0x1df /* alt-insert */ #define CTL_UP 0x1e0 /* ctl-up arrow */ #define CTL_DOWN 0x1e1 /* ctl-down arrow */ #define CTL_TAB 0x1e2 /* ctl-tab */ #define ALT_TAB 0x1e3 #define ALT_MINUS 0x1e4 #define ALT_EQUAL 0x1e5 #define ALT_HOME 0x1e6 #define ALT_PGUP 0x1e7 #define ALT_PGDN 0x1e8 #define ALT_END 0x1e9 #define ALT_UP 0x1ea /* alt-up arrow */ #define ALT_DOWN 0x1eb /* alt-down arrow */ #define ALT_RIGHT 0x1ec /* alt-right arrow */ #define ALT_LEFT 0x1ed /* alt-left arrow */ #define ALT_ENTER 0x1ee /* alt-enter */ #define ALT_ESC 0x1ef /* alt-escape */ #define ALT_BQUOTE 0x1f0 /* alt-back quote */ #define ALT_LBRACKET 0x1f1 /* alt-left bracket */ #define ALT_RBRACKET 0x1f2 /* alt-right bracket */ #define ALT_SEMICOLON 0x1f3 /* alt-semi-colon */ #define ALT_FQUOTE 0x1f4 /* alt-forward quote */ #define ALT_COMMA 0x1f5 /* alt-comma */ #define ALT_STOP 0x1f6 /* alt-stop */ #define ALT_FSLASH 0x1f7 /* alt-forward slash */ #define ALT_BKSP 0x1f8 /* alt-backspace */ #define CTL_BKSP 0x1f9 /* ctl-backspace */ #define PAD0 0x1fa /* keypad 0 */ #define CTL_PAD0 0x1fb /* ctl-keypad 0 */ #define CTL_PAD1 0x1fc #define CTL_PAD2 0x1fd #define CTL_PAD3 0x1fe #define CTL_PAD4 0x1ff #define CTL_PAD5 0x200 #define CTL_PAD6 0x201 #define CTL_PAD7 0x202 #define CTL_PAD8 0x203 #define CTL_PAD9 0x204 #define ALT_PAD0 0x205 /* alt-keypad 0 */ #define ALT_PAD1 0x206 #define ALT_PAD2 0x207 #define ALT_PAD3 0x208 #define ALT_PAD4 0x209 #define ALT_PAD5 0x20a #define ALT_PAD6 0x20b #define ALT_PAD7 0x20c #define ALT_PAD8 0x20d #define ALT_PAD9 0x20e #define CTL_DEL 0x20f /* clt-delete */ #define ALT_BSLASH 0x210 /* alt-back slash */ #define CTL_ENTER 0x211 /* ctl-enter */ #define SHF_PADENTER 0x212 /* shift-enter on keypad */ #define SHF_PADSLASH 0x213 /* shift-slash on keypad */ #define SHF_PADSTAR 0x214 /* shift-star on keypad */ #define SHF_PADPLUS 0x215 /* shift-plus on keypad */ #define SHF_PADMINUS 0x216 /* shift-minus on keypad */ #define SHF_UP 0x217 /* shift-up on keypad */ #define SHF_DOWN 0x218 /* shift-down on keypad */ #define SHF_IC 0x219 /* shift-insert on keypad */ #define SHF_DC 0x21a /* shift-delete on keypad */ #define KEY_MOUSE 0x21b /* "mouse" key */ #define KEY_SHIFT_L 0x21c /* Left-shift */ #define KEY_SHIFT_R 0x21d /* Right-shift */ #define KEY_CONTROL_L 0x21e /* Left-control */ #define KEY_CONTROL_R 0x21f /* Right-control */ #define KEY_ALT_L 0x220 /* Left-alt */ #define KEY_ALT_R 0x221 /* Right-alt */ #define KEY_RESIZE 0x222 /* Window resize */ #define KEY_SUP 0x223 /* Shifted up arrow */ #define KEY_SDOWN 0x224 /* Shifted down arrow */ #define KEY_MIN KEY_BREAK /* Minimum curses key value */ #define KEY_MAX KEY_SDOWN /* Maximum curses key */ #define KEY_F(n) (KEY_F0 + (n)) /*---------------------------------------------------------------------- * * PDCurses Function Declarations * */ /* Standard */ int addch ( const chtype ); int addchnstr ( const chtype *, int ); int addchstr ( const chtype * ); int addnstr ( const char *, int ); int addstr ( const char * ); int attroff ( chtype ); int attron ( chtype ); int attrset ( chtype ); int attr_get ( attr_t *, short *, void * ); int attr_off ( attr_t, void * ); int attr_on ( attr_t, void * ); int attr_set ( attr_t, short, void * ); int baudrate ( void ); int beep ( void ); int bkgd ( chtype ); void bkgdset ( chtype ); int border ( chtype, chtype, chtype, chtype, chtype, chtype, chtype, chtype ); int box ( WINDOW *, chtype, chtype ); bool can_change_color ( void ); int cbreak ( void ); int chgat ( int, attr_t, short, const void * ); int clearok ( WINDOW *, bool ); int clear ( void ); int clrtobot ( void ); int clrtoeol ( void ); int color_content ( short, short *, short *, short * ); int color_set ( short, void * ); int copywin ( const WINDOW *, WINDOW *, int, int, int, int, int, int, int ); int curs_set ( int ); int def_prog_mode ( void ); int def_shell_mode ( void ); int delay_output ( int ); int delch ( void ); int deleteln ( void ); void delscreen ( SCREEN * ); int delwin ( WINDOW * ); WINDOW * derwin ( WINDOW *, int, int, int, int ); int doupdate ( void ); WINDOW * dupwin ( WINDOW * ); int echochar ( const chtype ); int echo ( void ); int endwin ( void ); char erasechar ( void ); int erase ( void ); void filter ( void ); int flash ( void ); int flushinp ( void ); chtype getbkgd ( WINDOW * ); int getnstr ( char *, int ); int getstr ( char * ); WINDOW * getwin ( FILE * ); int halfdelay ( int ); bool has_colors ( void ); bool has_ic ( void ); bool has_il ( void ); int hline ( chtype, int ); void idcok ( WINDOW *, bool ); int idlok ( WINDOW *, bool ); void immedok ( WINDOW *, bool ); int inchnstr ( chtype *, int ); int inchstr ( chtype * ); chtype inch ( void ); int init_color ( short, short, short, short ); int init_pair ( short, short, short ); WINDOW * initscr ( void ); int innstr ( char *, int ); int insch ( chtype ); int insdelln ( int ); int insertln ( void ); int insnstr ( const char *, int ); int insstr ( const char * ); int instr ( char * ); int intrflush ( WINDOW *, bool ); bool isendwin ( void ); bool is_linetouched ( WINDOW *, int ); bool is_wintouched ( WINDOW * ); char * keyname ( int ); int keypad ( WINDOW *, bool ); char killchar ( void ); int leaveok ( WINDOW *, bool ); char * longname ( void ); int meta ( WINDOW *, bool ); int move ( int, int ); int mvaddch ( int, int, const chtype ); int mvaddchnstr ( int, int, const chtype *, int ); int mvaddchstr ( int, int, const chtype * ); int mvaddnstr ( int, int, const char *, int ); int mvaddstr ( int, int, const char * ); int mvchgat ( int, int, int, attr_t, short, const void * ); int mvcur ( int, int, int, int ); int mvdelch ( int, int ); int mvderwin ( WINDOW *, int, int ); int mvgetch ( int, int ); int mvgetnstr ( int, int, char *, int ); int mvgetstr ( int, int, char * ); int mvhline ( int, int, chtype, int ); chtype mvinch ( int, int ); int mvinchnstr ( int, int, chtype *, int ); int mvinchstr ( int, int, chtype * ); int mvinnstr ( int, int, char *, int ); int mvinsch ( int, int, chtype ); int mvinsnstr ( int, int, const char *, int ); int mvinsstr ( int, int, const char * ); int mvinstr ( int, int, char * ); int mvprintw ( int, int, const char *, ... ); int mvscanw ( int, int, const char *, ... ); int mvvline ( int, int, chtype, int ); int mvwaddchnstr ( WINDOW *, int, int, const chtype *, int ); int mvwaddchstr ( WINDOW *, int, int, const chtype * ); int mvwaddch ( WINDOW *, int, int, const chtype ); int mvwaddnstr ( WINDOW *, int, int, const char *, int ); int mvwaddstr ( WINDOW *, int, int, const char * ); int mvwchgat ( WINDOW *, int, int, int, attr_t, short, const void * ); int mvwdelch ( WINDOW *, int, int ); int mvwgetch ( WINDOW *, int, int ); int mvwgetnstr ( WINDOW *, int, int, char *, int ); int mvwgetstr ( WINDOW *, int, int, char * ); int mvwhline ( WINDOW *, int, int, chtype, int ); int mvwinchnstr ( WINDOW *, int, int, chtype *, int ); int mvwinchstr ( WINDOW *, int, int, chtype * ); chtype mvwinch ( WINDOW *, int, int ); int mvwinnstr ( WINDOW *, int, int, char *, int ); int mvwinsch ( WINDOW *, int, int, chtype ); int mvwinsnstr ( WINDOW *, int, int, const char *, int ); int mvwinsstr ( WINDOW *, int, int, const char * ); int mvwinstr ( WINDOW *, int, int, char * ); int mvwin ( WINDOW *, int, int ); int mvwprintw ( WINDOW *, int, int, const char *, ... ); int mvwscanw ( WINDOW *, int, int, const char *, ... ); int mvwvline ( WINDOW *, int, int, chtype, int ); int napms ( int ); WINDOW * newpad ( int, int ); SCREEN * newterm ( const char *, FILE *, FILE * ); WINDOW * newwin ( int, int, int, int ); int nl ( void ); int nocbreak ( void ); int nodelay ( WINDOW *, bool ); int noecho ( void ); int nonl ( void ); void noqiflush ( void ); int noraw ( void ); int notimeout ( WINDOW *, bool ); int overlay ( const WINDOW *, WINDOW * ); int overwrite ( const WINDOW *, WINDOW * ); int pair_content ( short, short *, short * ); int pechochar ( WINDOW *, chtype ); int pnoutrefresh ( WINDOW *, int, int, int, int, int, int ); int prefresh ( WINDOW *, int, int, int, int, int, int ); int printw ( const char *, ... ); int putwin ( WINDOW *, FILE * ); void qiflush ( void ); int raw ( void ); int redrawwin ( WINDOW * ); int refresh ( void ); int reset_prog_mode ( void ); int reset_shell_mode ( void ); int resetty ( void ); int ripoffline ( int, int ( * ) ( WINDOW *, int ) ); int savetty ( void ); int scanw ( const char *, ... ); int scr_dump ( const char * ); int scr_init ( const char * ); int scr_restore ( const char * ); int scr_set ( const char * ); int scrl ( int ); int scroll ( WINDOW * ); int scrollok ( WINDOW *, bool ); SCREEN * set_term ( SCREEN * ); int setscrreg ( int, int ); int slk_attroff ( const chtype ); int slk_attr_off ( const attr_t, void * ); int slk_attron ( const chtype ); int slk_attr_on ( const attr_t, void * ); int slk_attrset ( const chtype ); int slk_attr_set ( const attr_t, short, void * ); int slk_clear ( void ); int slk_color ( short ); int slk_init ( int ); char * slk_label ( int ); int slk_noutrefresh ( void ); int slk_refresh ( void ); int slk_restore ( void ); int slk_set ( int, const char *, int ); int slk_touch ( void ); int standend ( void ); int standout ( void ); int start_color ( void ); WINDOW * subpad ( WINDOW *, int, int, int, int ); WINDOW * subwin ( WINDOW *, int, int, int, int ); int syncok ( WINDOW *, bool ); chtype termattrs ( void ); attr_t term_attrs ( void ); char * termname ( void ); void timeout ( int ); int touchline ( WINDOW *, int, int ); int touchwin ( WINDOW * ); int typeahead ( int ); int untouchwin ( WINDOW * ); void use_env ( bool ); int vidattr ( chtype ); int vid_attr ( attr_t, short, void * ); int vidputs ( chtype, int ( * ) ( int ) ); int vid_puts ( attr_t, short, void *, int ( * ) ( int ) ); int vline ( chtype, int ); int vw_printw ( WINDOW *, const char *, va_list ); int vwprintw ( WINDOW *, const char *, va_list ); int vw_scanw ( WINDOW *, const char *, va_list ); int vwscanw ( WINDOW *, const char *, va_list ); int waddchnstr ( WINDOW *, const chtype *, int ); int waddchstr ( WINDOW *, const chtype * ); int waddch ( WINDOW *, const chtype ); int waddnstr ( WINDOW *, const char *, int ); int waddstr ( WINDOW *, const char * ); int wattroff ( WINDOW *, chtype ); int wattron ( WINDOW *, chtype ); int wattrset ( WINDOW *, chtype ); int wattr_get ( WINDOW *, attr_t *, short *, void * ); int wattr_off ( WINDOW *, attr_t, void * ); int wattr_on ( WINDOW *, attr_t, void * ); int wattr_set ( WINDOW *, attr_t, short, void * ); void wbkgdset ( WINDOW *, chtype ); int wbkgd ( WINDOW *, chtype ); int wborder ( WINDOW *, chtype, chtype, chtype, chtype, chtype, chtype, chtype, chtype ); int wchgat ( WINDOW *, int, attr_t, short, const void * ); int wclear ( WINDOW * ); int wclrtobot ( WINDOW * ); int wclrtoeol ( WINDOW * ); int wcolor_set ( WINDOW *, short, void * ); void wcursyncup ( WINDOW * ); int wdelch ( WINDOW * ); int wdeleteln ( WINDOW * ); int wechochar ( WINDOW *, const chtype ); int werase ( WINDOW * ); int wgetch ( WINDOW * ); int wgetnstr ( WINDOW *, char *, int ); int wgetstr ( WINDOW *, char * ); int whline ( WINDOW *, chtype, int ); int winchnstr ( WINDOW *, chtype *, int ); int winchstr ( WINDOW *, chtype * ); chtype winch ( WINDOW * ); int winnstr ( WINDOW *, char *, int ); int winsch ( WINDOW *, chtype ); int winsdelln ( WINDOW *, int ); int winsertln ( WINDOW * ); int winsnstr ( WINDOW *, const char *, int ); int winsstr ( WINDOW *, const char * ); int winstr ( WINDOW *, char * ); int wmove ( WINDOW *, int, int ); int wnoutrefresh ( WINDOW * ); int wprintw ( WINDOW *, const char *, ... ); int wredrawln ( WINDOW *, int, int ); int wrefresh ( WINDOW * ); int wscanw ( WINDOW *, const char *, ... ); int wscrl ( WINDOW *, int ); int wsetscrreg ( WINDOW *, int, int ); int wstandend ( WINDOW * ); int wstandout ( WINDOW * ); void wsyncdown ( WINDOW * ); void wsyncup ( WINDOW * ); void wtimeout ( WINDOW *, int ); int wtouchln ( WINDOW *, int, int, int ); int wvline ( WINDOW *, chtype, int ); /* Wide-character functions */ #ifdef PDC_WIDE int addnwstr ( const wchar_t *, int ); int addwstr ( const wchar_t * ); int add_wch ( const cchar_t * ); int add_wchnstr ( const cchar_t *, int ); int add_wchstr ( const cchar_t * ); int border_set ( const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t * ); int box_set ( WINDOW *, const cchar_t *, const cchar_t * ); int echo_wchar ( const cchar_t * ); int erasewchar ( wchar_t * ); int getbkgrnd ( cchar_t * ); int getcchar ( const cchar_t *, wchar_t *, attr_t *, short *, void * ); int getn_wstr ( wint_t *, int ); int get_wch ( wint_t * ); int get_wstr ( wint_t * ); int hline_set ( const cchar_t *, int ); int innwstr ( wchar_t *, int ); int ins_nwstr ( const wchar_t *, int ); int ins_wch ( const cchar_t * ); int ins_wstr ( const wchar_t * ); int inwstr ( wchar_t * ); int in_wch ( cchar_t * ); int in_wchnstr ( cchar_t *, int ); int in_wchstr ( cchar_t * ); char * key_name ( wchar_t ); int killwchar ( wchar_t * ); int mvaddnwstr ( int, int, const wchar_t *, int ); int mvaddwstr ( int, int, const wchar_t * ); int mvadd_wch ( int, int, const cchar_t * ); int mvadd_wchnstr ( int, int, const cchar_t *, int ); int mvadd_wchstr ( int, int, const cchar_t * ); int mvgetn_wstr ( int, int, wint_t *, int ); int mvget_wch ( int, int, wint_t * ); int mvget_wstr ( int, int, wint_t * ); int mvhline_set ( int, int, const cchar_t *, int ); int mvinnwstr ( int, int, wchar_t *, int ); int mvins_nwstr ( int, int, const wchar_t *, int ); int mvins_wch ( int, int, const cchar_t * ); int mvins_wstr ( int, int, const wchar_t * ); int mvinwstr ( int, int, wchar_t * ); int mvin_wch ( int, int, cchar_t * ); int mvin_wchnstr ( int, int, cchar_t *, int ); int mvin_wchstr ( int, int, cchar_t * ); int mvvline_set ( int, int, const cchar_t *, int ); int mvwaddnwstr ( WINDOW *, int, int, const wchar_t *, int ); int mvwaddwstr ( WINDOW *, int, int, const wchar_t * ); int mvwadd_wch ( WINDOW *, int, int, const cchar_t * ); int mvwadd_wchnstr ( WINDOW *, int, int, const cchar_t *, int ); int mvwadd_wchstr ( WINDOW *, int, int, const cchar_t * ); int mvwgetn_wstr ( WINDOW *, int, int, wint_t *, int ); int mvwget_wch ( WINDOW *, int, int, wint_t * ); int mvwget_wstr ( WINDOW *, int, int, wint_t * ); int mvwhline_set ( WINDOW *, int, int, const cchar_t *, int ); int mvwinnwstr ( WINDOW *, int, int, wchar_t *, int ); int mvwins_nwstr ( WINDOW *, int, int, const wchar_t *, int ); int mvwins_wch ( WINDOW *, int, int, const cchar_t * ); int mvwins_wstr ( WINDOW *, int, int, const wchar_t * ); int mvwin_wch ( WINDOW *, int, int, cchar_t * ); int mvwin_wchnstr ( WINDOW *, int, int, cchar_t *, int ); int mvwin_wchstr ( WINDOW *, int, int, cchar_t * ); int mvwinwstr ( WINDOW *, int, int, wchar_t * ); int mvwvline_set ( WINDOW *, int, int, const cchar_t *, int ); int pecho_wchar ( WINDOW *, const cchar_t * ); int setcchar ( cchar_t *, const wchar_t *, const attr_t, short, const void * ); int slk_wset ( int, const wchar_t *, int ); int unget_wch ( const wchar_t ); int vline_set ( const cchar_t *, int ); int waddnwstr ( WINDOW *, const wchar_t *, int ); int waddwstr ( WINDOW *, const wchar_t * ); int wadd_wch ( WINDOW *, const cchar_t * ); int wadd_wchnstr ( WINDOW *, const cchar_t *, int ); int wadd_wchstr ( WINDOW *, const cchar_t * ); int wbkgrnd ( WINDOW *, const cchar_t * ); void wbkgrndset ( WINDOW *, const cchar_t * ); int wborder_set ( WINDOW *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t * ); int wecho_wchar ( WINDOW *, const cchar_t * ); int wgetbkgrnd ( WINDOW *, cchar_t * ); int wgetn_wstr ( WINDOW *, wint_t *, int ); int wget_wch ( WINDOW *, wint_t * ); int wget_wstr ( WINDOW *, wint_t * ); int whline_set ( WINDOW *, const cchar_t *, int ); int winnwstr ( WINDOW *, wchar_t *, int ); int wins_nwstr ( WINDOW *, const wchar_t *, int ); int wins_wch ( WINDOW *, const cchar_t * ); int wins_wstr ( WINDOW *, const wchar_t * ); int winwstr ( WINDOW *, wchar_t * ); int win_wch ( WINDOW *, cchar_t * ); int win_wchnstr ( WINDOW *, cchar_t *, int ); int win_wchstr ( WINDOW *, cchar_t * ); wchar_t * wunctrl ( cchar_t * ); int wvline_set ( WINDOW *, const cchar_t *, int ); #endif /* Quasi-standard */ chtype getattrs ( WINDOW * ); int getbegx ( WINDOW * ); int getbegy ( WINDOW * ); int getmaxx ( WINDOW * ); int getmaxy ( WINDOW * ); int getparx ( WINDOW * ); int getpary ( WINDOW * ); int getcurx ( WINDOW * ); int getcury ( WINDOW * ); void traceoff ( void ); void traceon ( void ); char * unctrl ( chtype ); int crmode ( void ); int nocrmode ( void ); int draino ( int ); int resetterm ( void ); int fixterm ( void ); int saveterm ( void ); int setsyx ( int, int ); int mouse_set ( unsigned long ); int mouse_on ( unsigned long ); int mouse_off ( unsigned long ); int request_mouse_pos ( void ); int map_button ( unsigned long ); void wmouse_position ( WINDOW *, int *, int * ); unsigned long getmouse ( void ); unsigned long getbmap ( void ); /* ncurses */ int assume_default_colors ( int, int ); const char * curses_version ( void ); bool has_key ( int ); int use_default_colors ( void ); int wresize ( WINDOW *, int, int ); int mouseinterval ( int ); mmask_t mousemask ( mmask_t, mmask_t * ); bool mouse_trafo ( int *, int *, bool ); int nc_getmouse ( MEVENT * ); int ungetmouse ( MEVENT * ); bool wenclose ( const WINDOW *, int, int ); bool wmouse_trafo ( const WINDOW *, int *, int *, bool ); /* PDCurses */ int addrawch ( chtype ); int insrawch ( chtype ); bool is_termresized ( void ); int mvaddrawch ( int, int, chtype ); int mvdeleteln ( int, int ); int mvinsertln ( int, int ); int mvinsrawch ( int, int, chtype ); int mvwaddrawch ( WINDOW *, int, int, chtype ); int mvwdeleteln ( WINDOW *, int, int ); int mvwinsertln ( WINDOW *, int, int ); int mvwinsrawch ( WINDOW *, int, int, chtype ); int raw_output ( bool ); int resize_term ( int, int ); WINDOW * resize_window ( WINDOW *, int, int ); int waddrawch ( WINDOW *, chtype ); int winsrawch ( WINDOW *, chtype ); char wordchar ( void ); #ifdef PDC_WIDE wchar_t * slk_wlabel ( int ); #endif void PDC_debug ( const char *, ... ); int PDC_ungetch ( int ); int PDC_set_blink ( bool ); int PDC_set_line_color ( short ); void PDC_set_title ( const char * ); int PDC_clearclipboard ( void ); int PDC_freeclipboard ( char * ); int PDC_getclipboard ( char **, long * ); int PDC_setclipboard ( const char *, long ); unsigned long PDC_get_input_fd ( void ); unsigned long PDC_get_key_modifiers ( void ); int PDC_return_key_modifiers ( bool ); int PDC_save_key_modifiers ( bool ); #ifdef XCURSES WINDOW * Xinitscr ( int, char ** ); void XCursesExit ( void ); int sb_init ( void ); int sb_set_horz ( int, int, int ); int sb_set_vert ( int, int, int ); int sb_get_horz ( int *, int *, int * ); int sb_get_vert ( int *, int *, int * ); int sb_refresh ( void ); #endif /*** Functions defined as macros ***/ /* getch() and ungetch() conflict with some DOS libraries */ #define getch() wgetch(stdscr) #define ungetch(ch) PDC_ungetch(ch) #define COLOR_PAIR(n) (((chtype)(n) << PDC_COLOR_SHIFT) & A_COLOR) #define PAIR_NUMBER(n) (((n) & A_COLOR) >> PDC_COLOR_SHIFT) /* These will _only_ work as macros */ #define getbegyx(w, y, x) (y = getbegy(w), x = getbegx(w)) #define getmaxyx(w, y, x) (y = getmaxy(w), x = getmaxx(w)) #define getparyx(w, y, x) (y = getpary(w), x = getparx(w)) #define getyx(w, y, x) (y = getcury(w), x = getcurx(w)) #define getsyx(y, x) { if (curscr->_leaveit) (y)=(x)=-1; \ else getyx(curscr,(y),(x)); } #ifdef NCURSES_MOUSE_VERSION # define getmouse(x) nc_getmouse(x) #endif /* return codes from PDC_getclipboard() and PDC_setclipboard() calls */ #define PDC_CLIP_SUCCESS 0 #define PDC_CLIP_ACCESS_ERROR 1 #define PDC_CLIP_EMPTY 2 #define PDC_CLIP_MEMORY_ERROR 3 /* PDCurses key modifier masks */ #define PDC_KEY_MODIFIER_SHIFT 1 #define PDC_KEY_MODIFIER_CONTROL 2 #define PDC_KEY_MODIFIER_ALT 4 #define PDC_KEY_MODIFIER_NUMLOCK 8 #if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS) # undef bool } #endif #endif /* __PDCURSES__ */ soapdenovo2-240+dfsg.orig/standardPregraph/inc/extfunc2.h0000644000000000000000000000210012166703654022150 0ustar rootroot/* * inc/extfunc2.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef _MEM_MANAGER #define _MEM_MANAGER extern MEM_MANAGER * createMem_manager ( int num_items, size_t unit_size ); extern void * getItem ( MEM_MANAGER * mem_Manager ); extern void returnItem ( MEM_MANAGER * mem_Manager, void * ); extern void freeMem_manager ( MEM_MANAGER * mem_Manager ); #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/types.h0000644000000000000000000000211412166703654021563 0ustar rootroot/* * inc/types.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef __TYPES_RJ #define __TYPES_RJ typedef unsigned long long ubyte8; typedef unsigned int ubyte4; typedef unsigned short ubyte2; typedef unsigned char ubyte; typedef long long byte8; typedef int byte4; typedef short byte2; typedef char byte; #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/def.h0000644000000000000000000001754412166703654021172 0ustar rootroot/* * inc/def.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ /* this file provides some datatype definition */ #ifndef _DEF #define _DEF #include "def2.h" #include "types.h" #include "stack.h" #include "darray.h" #include "sam.h" //support the samfile_t struct #define EDGE_BIT_SIZE 6 #define word_len 12 #define taskMask 0xf //the last 7 bits #define MaxEdgeCov 16000 #define base2int(base) (char)(((base)&0x06)>>1) //base ACTG => int 0123 #define int2base(seq) "ACTG"[seq] //int 0123 => base ACTG #define int2compbase(seq) "TGAC"[seq] //int 0123 => base TGAC complement of ACTG #define int_comp(seq) (char)(seq^0x02) //(char)((0x4E>>((seq)<<1))&0x03) int b_ban; #ifdef MER127 typedef struct kmer { unsigned long long high1, low1, high2, low2; } Kmer; #else typedef struct kmer { unsigned long long high, low; } Kmer; #endif typedef struct preedge { Kmer from_node; Kmer to_node; char * seq; int length; unsigned short cvg: 14; unsigned bal_edge: 2; //indicate whether it's bal_edge is the previous edge, next edge or itself } preEDGE; typedef struct readinterval //record two paths of bubble { int readid; unsigned int edgeid; int start; struct readinterval * bal_rv; struct readinterval * nextOnEdge; // the downstream in the path struct readinterval * prevOnEdge; // the upstream in the path struct readinterval * nextInRead; struct readinterval * prevInRead; } READINTERVAL; struct arc; typedef struct edge { unsigned int from_vt; //from kmer id unsigned int to_vt; //to kmer id int length; //edge length unsigned short cvg: 14; //coverage unsigned short bal_edge: 2; // 2:smaller 0:larger 1:rev-com equal to itself unsigned short multi: 14; unsigned short deleted : 1; unsigned short flag : 1; char * seq; //edge content READINTERVAL * rv; struct arc * arcs; long long * markers; //reads id } EDGE; typedef struct edge_sub { unsigned int from_vt; //from kmer id unsigned int to_vt; //to kmer id int length; //edge length char * seq; //edge content } EDGE_SUB; typedef struct edge_pt { EDGE * edge; struct edge_pt * next; } EDGE_PT; typedef struct vertex { Kmer kmer; } VERTEX; /* typedef struct connection { unsigned int contigID; int gapLen; short maxGap; unsigned char minGap; unsigned char bySmall:1; unsigned char weakPoint:1; unsigned char weightNotInherit; unsigned char weight; unsigned char maxSingleWeight; unsigned char mask : 1; unsigned char used : 1; unsigned char weak : 1; unsigned char deleted : 1; unsigned char prevInScaf : 1; unsigned char inherit : 1; unsigned char checking : 1; unsigned char singleInScaf : 1; struct connection *nextInScaf; struct connection *next; struct connection *nextInLookupTable; }CONNECT; */ typedef struct connection { unsigned int contigID; int gapLen; unsigned short maxGap; unsigned char minGap; unsigned char bySmall: 1; unsigned char weakPoint: 1; unsigned char smallIns: 1; unsigned char newIns: 1; unsigned char weightNotInherit; unsigned char weight; unsigned char maxSingleWeight; unsigned char mask : 1; unsigned char used : 1; unsigned char weak : 1; unsigned char deleted : 1; unsigned char prevInScaf : 1; unsigned char inherit : 1; unsigned char checking : 1; unsigned char singleInScaf : 1; struct connection * nextInScaf; struct connection * next; struct connection * nextInLookupTable; } CONNECT; typedef struct prearc { unsigned int to_ed; // the destination edge of prearc unsigned int multiplicity; struct prearc * next; } preARC; /* typedef struct contig { unsigned int from_vt; unsigned int to_vt; unsigned int length; int to_right; unsigned short indexInScaf; unsigned char cvg; unsigned char bal_edge:2; // 0, 1 or 2 unsigned char mask : 1; unsigned char flag : 1; unsigned char multi: 1; unsigned char inSubGraph: 1; char *seq; CONNECT *downwardConnect; preARC *arcs; STACK *closeReads; }CONTIG; */ typedef struct contig { unsigned int from_vt; // the first kmer of the contig unsigned int to_vt; // the last kmer of the contig unsigned int length; unsigned short indexInScaf; // the index in the scaffold unsigned char cvg; unsigned char bal_edge: 2; // 0, 1 or 2 unsigned char mask : 1; unsigned char flag : 1; unsigned char multi: 1; unsigned char inSubGraph: 1; unsigned char bubbleInScaff: 1; char * seq; CONNECT * downwardConnect; // record the links to other contigs preARC * arcs; STACK * closeReads; } CONTIG; typedef struct read_nearby { int len; int dis; // dis to nearby contig or scaffold's start position long long seqStarter; //sequence start position in dynamic array } READNEARBY; typedef struct annotation { unsigned long long readID; unsigned int contigID; int pos; } ANNOTATION; typedef struct parameter { unsigned char threadID; void ** hash_table; unsigned char * mainSignal; unsigned char * selfSignal; } PARAMETER; typedef struct lightannot { int contigID; int pos; } LIGHTANNOT; typedef struct edgepatch { Kmer from_kmer, to_kmer; unsigned int length; char bal_edge; } EDGEPATCH; typedef struct lightctg { unsigned int index; int length; char * seq; } LIGHTCTG; typedef struct arc { unsigned int to_ed; unsigned int multiplicity; struct arc * prev; struct arc * next; struct arc * bal_arc; struct arc * nextInLookupTable; } ARC; typedef struct arcexist { Kmer kmer; struct arcexist * left; struct arcexist * right; } ARCEXIST; typedef struct lib_info { int min_ins; int max_ins; int avg_ins; int rd_len_cutoff; //read length cutoff int reverse; int asm_flag; int map_len; int pair_num_cut; int rank; //indicate which file is next to be read int curr_type; int curr_index; //file handlers to opened files FILE * fp1; FILE * fp2; boolean f1_start; boolean f2_start; //whether last read is read1 in pair int paired; // 0 -- single; 1 -- read1; 2 -- read2; //type1 char ** a1_fname; char ** a2_fname; int num_a1_file; int num_a2_file; //type2 char ** q1_fname; char ** q2_fname; int num_q1_file; int num_q2_file; //type3 char ** p_fname; int num_p_file; //fasta only //type4 &5 char ** s_a_fname; int num_s_a_file; char ** s_q_fname; int num_s_q_file; samfile_t * fp3; //the file handle to read bam file char ** b_fname; //the name of the bam file int num_b_file; //the number of the bam file } LIB_INFO; typedef struct ctg4heap { unsigned int ctgID; int dis; unsigned char ds_shut4dheap: 1; // ignore downstream connections unsigned char us_shut4dheap: 1; // ignore upstream connections unsigned char ds_shut4uheap: 1; // ignore downstream connections unsigned char us_shut4uheap: 1; // ignore upstream connections } CTGinHEAP; typedef struct ctg4scaf { unsigned int ctgID; int start; int end; //position in scaff unsigned int cutHead : 8; unsigned int cutTail : 7; unsigned int scaftig_start : 1; //is it a scaftig starter unsigned int mask : 1; // is it masked for further operations unsigned int gapSeqLen: 15; int gapSeqOffset; } CTGinSCAF; typedef struct pe_info { int insertS; long long PE_bound; int rank; int pair_num_cut; } PE_INFO; #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/nuc.h0000644000000000000000000000166112166703654021212 0ustar rootroot/* * inc/nuc.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ int total_nuc = 16; char na_name[17] = {'g', 'a', 't', 'c', 'n', 'r', 'y', 'w', 's', 'm', 'k', 'h', 'b', 'v', 'd', 'x' }; soapdenovo2-240+dfsg.orig/standardPregraph/inc/fibpriv.h0000644000000000000000000000621312166703654022064 0ustar rootroot/* * inc/fibpriv.h * * This file is part of SOAPdenovo. * */ /*- * Copyright 1997, 1999-2003 John-Mark Gurney. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND 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 THE AUTHOR OR 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. * * $Id: fibpriv.h,v 1.10 2007/10/09 09:56:46 zerbino Exp $ * */ #ifndef _FIBPRIV_H_ #define _FIBPRIV_H_ #include "def2.h" /* * specific node operations */ struct fibheap_el { int fhe_degree; boolean fhe_mark; FibHeapNode * fhe_p; FibHeapNode * fhe_child; FibHeapNode * fhe_left; FibHeapNode * fhe_right; Coordinate fhe_key; unsigned int fhe_data; }; static FibHeapNode * fhe_newelem ( struct fibheap * ); static void fhe_initelem ( FibHeapNode * ); static void fhe_insertafter ( FibHeapNode * a, FibHeapNode * b ); static inline void fhe_insertbefore ( FibHeapNode * a, FibHeapNode * b ); static FibHeapNode * fhe_remove ( FibHeapNode * a ); /* * global heap operations */ struct fibheap { Coordinate ( *fh_cmp_fnct ) ( unsigned int, unsigned int ); MEM_MANAGER * nodeMemory; IDnum fh_n; IDnum fh_Dl; FibHeapNode ** fh_cons; FibHeapNode * fh_min; FibHeapNode * fh_root; unsigned int fh_neginf; boolean fh_keys: 1; }; static void fh_initheap ( FibHeap * ); static void fh_insertrootlist ( FibHeap *, FibHeapNode * ); static void fh_removerootlist ( FibHeap *, FibHeapNode * ); static void fh_consolidate ( FibHeap * ); static void fh_heaplink ( FibHeap * h, FibHeapNode * y, FibHeapNode * x ); static void fh_cut ( FibHeap *, FibHeapNode *, FibHeapNode * ); static void fh_cascading_cut ( FibHeap *, FibHeapNode * ); static FibHeapNode * fh_extractminel ( FibHeap * ); static void fh_checkcons ( FibHeap * h ); static void fh_destroyheap ( FibHeap * h ); static int fh_compare ( FibHeap * h, FibHeapNode * a, FibHeapNode * b ); static int fh_comparedata ( FibHeap * h, Coordinate key, unsigned int data, FibHeapNode * b ); static void fh_insertel ( FibHeap * h, FibHeapNode * x ); /* * general functions */ static inline IDnum ceillog2 ( IDnum a ); #endif /* _FIBPRIV_H_ */ soapdenovo2-240+dfsg.orig/standardPregraph/inc/fibHeap.h0000644000000000000000000000261512166703654021763 0ustar rootroot/* * inc/fibHeap.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef _FIBHEAP_H_ #define _FIBHEAP_H_ FibHeap * newFibHeap(); FibHeapNode * insertNodeIntoHeap ( FibHeap * heap, Coordinate key, unsigned int node ); Coordinate minKeyOfHeap ( FibHeap * heap ); Coordinate replaceKeyInHeap ( FibHeap * heap, FibHeapNode * node, Coordinate newKey ); void replaceValueInHeap ( FibHeapNode * node, unsigned int newValue ); unsigned int removeNextNodeFromHeap ( FibHeap * heap ); void * destroyNodeInHeap ( FibHeapNode * node, FibHeap * heap ); void destroyHeap ( FibHeap * heap ); boolean IsHeapEmpty ( FibHeap * heap ); #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/darray.h0000644000000000000000000000235112166703654021704 0ustar rootroot/* * inc/darray.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef __DARRAY__ #define __DARRAY__ #include #include #include typedef struct dynamic_array { void * array; long long array_size; size_t item_size; long long item_c; } DARRAY; void * darrayPut ( DARRAY * darray, long long index ); void * darrayGet ( DARRAY * darray, long long index ); DARRAY * createDarray ( int num_items, size_t unit_size ); void freeDarray ( DARRAY * darray ); void emptyDarray ( DARRAY * darray ); #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/sam_view.h0000644000000000000000000000220612166703654022233 0ustar rootroot#ifndef SAM_VIEW_H #define SAM_VIEW_H static int g_min_mapQ = 0, g_flag_on = 0, g_flag_off = 0; static char * g_library, *g_rg; static int g_sol2sanger_tbl[128]; static void sol2sanger ( bam1_t * b ) { int l; uint8_t * qual = bam1_qual ( b ); if ( g_sol2sanger_tbl[30] == 0 ) { for ( l = 0; l != 128; ++l ) { g_sol2sanger_tbl[l] = ( int ) ( 10.0 * log ( 1.0 + pow ( 10.0, ( l - 64 + 33 ) / 10.0 ) ) / log ( 10.0 ) + .499 ); if ( g_sol2sanger_tbl[l] >= 93 ) { g_sol2sanger_tbl[l] = 93; } } } for ( l = 0; l < b->core.l_qseq; ++l ) { int q = qual[l]; if ( q > 127 ) { q = 127; } qual[l] = g_sol2sanger_tbl[q]; } } static inline int __g_skip_aln ( const bam_header_t * h, const bam1_t * b ) { if ( b->core.qual < g_min_mapQ || ( ( b->core.flag & g_flag_on ) != g_flag_on ) || ( b->core.flag & g_flag_off ) ) { return 1; } if ( g_rg ) { uint8_t * s = bam_aux_get ( b, "RG" ); if ( s && strcmp ( g_rg, ( char * ) ( s + 1 ) ) == 0 ) { return 0; } } if ( g_library ) { const char * p = bam_get_library ( ( bam_header_t * ) h, b ); return ( p && strcmp ( p, g_library ) == 0 ) ? 0 : 1; } return 0; } #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/extfunc.h0000644000000000000000000002641612166703654022106 0ustar rootroot/* * inc/extfunc.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "check.h" #include "extfunc2.h" extern void initAIO ( struct aiocb * aio, char * buf, int fd, int size ); extern int AIORead ( struct aiocb * mycb, int * offset, char * buf, char * cach, int * rt, int curr_type ); extern boolean check_file ( char * name ); //add 2012.7.6 extern boolean checkFiles4Scaff ( char * infile ); extern boolean openNextFile ( int * libNo, boolean pairs, unsigned char asm_ctg ); extern int nextValidIndex ( int libNo, boolean pair, unsigned char asm_ctg ); extern void openFileInLib ( int libNo ); extern void closeFp1InLab ( int libNo ); extern void closeFp2InLab ( int libNo ); extern boolean readseqInLib ( char * src_seq, char * src_name, int * len_seq, char * buf, int * start, int offset, int i ); extern void readseq1by1 ( char * src_seq, char * src_name, int * len_seq, FILE * fp, long long num_seq ); extern void readseqPbyP ( char * src_seq, char * src_name, int * insertS, int * len_seq, FILE * fp, long long num_seq ); extern long long readseqpar ( int * max_len, int * min_leg, int * max_name_len, FILE * fp ); extern void free_edge_list ( EDGE_PT * el ); extern void reverseComplementSeq ( char * seq, int len, char * bal_seq ); extern void free_edge_array ( EDGE * ed_array, int ed_num ); extern void free_lightctg_array ( LIGHTCTG * ed_array, int ed_num ); extern char getCharInTightString ( char * tightSeq, int pos ); extern void writeChar2tightSting ( char nt, char * tightSeq, int pos ); extern void short_reads_sum(); extern void read_one_sequence ( FILE * fp, long long * T, char ** X ); extern void output_edges ( preEDGE * ed_array, int ed_num, char * outfile ); extern void loadVertex ( char * graphfile ); extern void loadEdge ( char * graphfile ); extern boolean loadPath ( char * graphfile ); extern READINTERVAL * allocateRV ( int readid, int edgeid ); extern void createRVmemo(); extern void dismissRV ( READINTERVAL * rv ); extern void destroyReadIntervMem(); extern void destroyConnectMem(); extern void u2uConcatenate(); extern void output_contig ( EDGE * ed_array, unsigned int ed_num, char * outfile, int cut_len ); extern void printTightString ( char * tightSeq, int len ); extern int roughUniqueness ( unsigned int edgeno, char ignore_cvg, char * ignored ); extern void outputReadPos ( char * graphfile, int min_len ); extern void testSearch(); extern void allpathConcatenate(); extern void output_updated_edges ( char * outfile ); extern void output_updated_vertex ( char * outfile ); extern void loadUpdatedEdges ( char * graphfile ); extern void loadUpdatedVertex ( char * graphfile ); extern void connectByPE ( char * infile ); extern void output_cntGVZ ( char * outfile ); extern void output_graph ( char * outfile ); extern void testLinearC2C(); extern void output_contig_graph ( char * outfile ); extern void scaffolding ( unsigned int cut_len, char * outfile ); extern int cmp_int ( const void * a, const void * b ); extern CONNECT * allocateCN ( unsigned int contigId, int gap ); extern int recoverRep(); extern void loadPEgrads ( char * infile ); extern int putInsertS ( long long readid, int size, int * currGrads ); extern int getInsertS ( long long readid, int * readlen ); extern int connectByPE_grad ( FILE * fp, int peGrad, char * line ); extern int connectByPE_grad_gz ( gzFile * fp, int peGrad, char * line ); extern void PEgradsScaf ( char * infile ); extern void reorderAnnotation ( char * infile, char * outfile ); extern void output_1edge ( preEDGE * edge, gzFile * fp ); extern void prlRead2edge ( char * libfile, char * outfile ); extern void annotFileTrans ( char * infile, char * outfile ); extern void prlLoadPath ( char * graphfile ); extern void misCheck ( char * infile, char * outfile ); extern int uniqueLenSearch ( unsigned int * len_array, unsigned int * flag_array, int num, unsigned int target ); extern int cmp_vertex ( const void * a, const void * b ); extern void linkContig2Vts(); extern int connectByPE_gradPatch ( FILE * fp1, FILE * fp2, int peGrad, char * line1, char * line2 ); extern void scaftiging ( char * graphfile, int len_cut ); extern void gapFilling ( char * graphfile, int cut_len ); extern ARC * getArcBetween ( unsigned int from_ed, unsigned int to_ed ); extern void bubblePinch ( double simiCutoff, char * outfile, int M, boolean isIter, boolean last ); extern void linearConcatenate ( boolean isIter, boolean last ); extern unsigned char setArcMulti ( unsigned int from_ed, unsigned int to_ed, unsigned char value ); extern ARC * allocateArc ( unsigned int edgeid ); extern void cutTipsInGraph ( int cutLen, boolean strict, boolean last ); extern ARC * deleteArc ( ARC * arc_list, ARC * arc ); extern void compactEdgeArray(); extern void dismissArc ( ARC * arc ); extern void createArcMemo(); extern ARC * getArcBetween ( unsigned int from_ed, unsigned int to_ed ); extern ARC * allocateArc ( unsigned int edgeid ); extern void writeChar2tightString ( char nt, char * tightSeq, int pos ); extern void output_heavyArcs ( char * outfile ); extern preARC * allocatePreArc ( unsigned int edgeid ); extern void destroyPreArcMem(); extern void traceAlongArc ( unsigned int destE, unsigned int currE, int max_steps, int min, int max, int index, int len, int * num_route ); extern void freeContig_array(); extern void output_scafSeq ( char * graphfile, int len_cut ); extern void putArcInHash ( unsigned int from_ed, unsigned int to_ed ); extern boolean DoesArcExist ( unsigned int from_ed, unsigned int to_ed ); extern void recordArcInHash(); extern void destroyArcHash(); extern void removeWeakEdges ( int lenCutoff, unsigned int multiCutoff ); extern void createArcLookupTable(); extern void deleteArcLookupTable(); extern void putArc2LookupTable ( unsigned int from_ed, ARC * arc ); extern void removeArcInLookupTable ( unsigned int from_ed, unsigned int to_ed ); extern ARC * arcCount ( unsigned int edgeid, unsigned int * num ); extern void mapFileTrans ( char * infile ); extern void solveReps(); extern void removeDeadArcs(); extern void destroyArcMem(); extern void getCntsInFile ( char * infile ); extern void scafByCntInfo ( char * infile ); extern CONNECT * add1Connect ( unsigned int e1, unsigned int e2, int gap, int weight, boolean inherit ); extern void getScaff ( char * infile ); extern void traceAlongMaskedCnt ( unsigned int destE, unsigned int currE, int max_steps, int min, int max, int index, int len, int * num_route ); extern void createPreArcMemManager(); extern boolean loadPathBin ( char * graphfile ); extern void recordArcsInLookupTable(); extern FILE * multiFileRead1seq ( char * src_seq, char * src_name, int * len_seq, FILE * fp, FILE * freads ); extern void multiFileSeqpar ( FILE * fp ); extern long long multiFileParse ( int * max_leg, int * min_leg, int * max_name_leg, FILE * fp ); extern CONNECT * getCntBetween ( unsigned int from_ed, unsigned int to_ed ); extern void createCntMemManager(); extern void destroyConnectMem(); extern void createCntLookupTable(); extern void deleteCntLookupTable(); extern void putCnt2LookupTable ( unsigned int from_c, CONNECT * cnt ); extern void prlRead2Ctg ( char * seqfile, char * outfile ); extern boolean prlContig2nodes ( char * grapfile, int len_cut ); extern void scan_libInfo ( char * libfile ); extern void free_libs(); extern boolean read1seqInLibBam ( char * src_seq, char * src_name, int * len_seq, int * libNo, boolean pair, unsigned char asm_ctg, int * type ); extern boolean read1seqInLib ( char * src_seq, char * src_name, int * len_seq, int * libNo, boolean pair, unsigned char asm_ctg , int * type ); extern void save4laterSolve(); extern void solveRepsAfter(); extern void free_pe_mem(); extern void alloc_pe_mem ( int gradsCounter ); extern void prlDestroyPreArcMem(); extern preARC * prlAllocatePreArc ( unsigned int edgeid, MEM_MANAGER * manager ); extern boolean prlRead2HashTable ( char * libfile, char * outfile ); extern void free_allSets(); extern void removeSingleTips(); extern void removeMinorTips(); extern void kmer2edges ( char * outfile ); extern void output_vertex ( char * outfile ); extern boolean prlRead2HashTable ( char * libfile, char * outfile ); extern void Links2Scaf ( char * infile ); extern void PE2Links ( char * infile ); extern unsigned int getTwinCtg ( unsigned int ctg ); extern void basicContigInfo ( char * infile ); extern boolean isSmallerThanTwin ( unsigned int ctg ); extern boolean isLargerThanTwin ( unsigned int ctg ); extern boolean isSameAsTwin ( unsigned int ctg ); extern boolean loadMarkerBin ( char * graphfile ); extern void readsCloseGap ( char * graphfile ); extern void prlReadsCloseGap ( char * graphfile ); extern void locateReadOnScaf ( char * graphfile ); /*********** Kmer related *************/ extern Kmer createFilter ( int overlaplen ); extern void printKmerSeq ( FILE * fp, Kmer kmer ); //extern U256b Kmer2int256(Kmer seq); extern boolean KmerLarger ( Kmer kmer1, Kmer kmer2 ); extern boolean KmerSmaller ( Kmer kmer1, Kmer kmer2 ); extern boolean KmerEqual ( Kmer kmer1, Kmer kmer2 ); extern Kmer KmerAnd ( Kmer kmer1, Kmer kmer2 ); extern Kmer KmerLeftBitMoveBy2 ( Kmer word ); extern Kmer KmerRightBitMoveBy2 ( Kmer word ); extern Kmer KmerPlus ( Kmer prev, char ch ); extern Kmer nextKmer ( Kmer prev, char ch ); extern Kmer prevKmer ( Kmer next, char ch ); extern char firstCharInKmer ( Kmer kmer ); extern Kmer KmerRightBitMove ( Kmer word, int dis ); extern Kmer reverseComplement ( Kmer word, int overlap ); extern ubyte8 hash_kmer ( Kmer kmer ); extern int kmer2vt ( Kmer kmer ); extern void print_kmer ( FILE * fp, Kmer kmer, char c ); extern int bisearch ( VERTEX * vts, int num, Kmer target ); extern void printKmerSeq ( FILE * fp, Kmer kmer ); extern char lastCharInKmer ( Kmer kmer ); int localGraph ( READNEARBY * rdArray, int num, CTGinSCAF * ctg1, CTGinSCAF * ctg2, int origOverlap, Kmer * kmerCtg1, Kmer * kmerCtg2, int overlap, DARRAY * gapSeqArray, char * seqCtg1, char * seqCtg2, char * seqGap ); extern unsigned int getTwinEdge ( unsigned int edgeno ); extern boolean EdSmallerThanTwin ( unsigned int edgeno ); extern boolean EdLargerThanTwin ( unsigned int edgeno ); extern boolean EdSameAsTwin ( unsigned int edgeno ); extern void removeLowCovEdges ( int lenCutoff, unsigned short covCutoff, boolean last ); extern int getMaxLongReadLen ( int num_libs ); extern void prlLongRead2Ctg ( char * libfile, char * outfile ); extern void outputTightStr ( FILE * fp, char * tightStr, int start, int length, int outputlen, int revS, int * col ); extern void crc32c_Init(); extern int validArcCount ( preARC * arc, int cutoff ); extern unsigned int maxArcWeight ( preARC * arc ); extern __uint128_t Kmer2int128 ( Kmer seq ); extern void printSeq ( FILE * fo, char * seq, int len ); soapdenovo2-240+dfsg.orig/standardPregraph/inc/faidx.h0000644000000000000000000000632612166703654021523 0ustar rootroot/* * inc/extvab.h * * This file is part of SOAPdenovo. * */ /* The MIT License Copyright (c) 2008 Genome Research Ltd (GRL). Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* Contact: Heng Li */ #ifndef FAIDX_H #define FAIDX_H /*! @header Index FASTA files and extract subsequence. @copyright The Wellcome Trust Sanger Institute. */ struct __faidx_t; typedef struct __faidx_t faidx_t; #ifdef __cplusplus extern "C" { #endif /*! @abstract Build index for a FASTA or razip compressed FASTA file. @param fn FASTA file name @return 0 on success; or -1 on failure @discussion File "fn.fai" will be generated. */ int fai_build ( const char * fn ); /*! @abstract Distroy a faidx_t struct. @param fai Pointer to the struct to be destroyed */ void fai_destroy ( faidx_t * fai ); /*! @abstract Load index from "fn.fai". @param fn File name of the FASTA file */ faidx_t * fai_load ( const char * fn ); /*! @abstract Fetch the sequence in a region. @param fai Pointer to the faidx_t struct @param reg Region in the format "chr2:20,000-30,000" @param len Length of the region @return Pointer to the sequence; null on failure @discussion The returned sequence is allocated by malloc family and should be destroyed by end users by calling free() on it. */ char * fai_fetch ( const faidx_t * fai, const char * reg, int * len ); /*! @abstract Fetch the number of sequences. @param fai Pointer to the faidx_t struct @return The number of sequences */ int faidx_fetch_nseq ( const faidx_t * fai ); /*! @abstract Fetch the sequence in a region. @param fai Pointer to the faidx_t struct @param c_name Region name @param p_beg_i Beginning position number (zero-based) @param p_end_i End position number (zero-based) @param len Length of the region @return Pointer to the sequence; null on failure @discussion The returned sequence is allocated by malloc family and should be destroyed by end users by calling free() on it. */ char * faidx_fetch_seq ( const faidx_t * fai, char * c_name, int p_beg_i, int p_end_i, int * len ); #ifdef __cplusplus } #endif #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/extvab.h0000644000000000000000000000713612166703654021721 0ustar rootroot/* * inc/extvab.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ /*** global variables ****/ extern boolean fill; extern int overlaplen; extern int inGraph; extern long long n_ban; extern Kmer WORDFILTER; extern boolean globalFlag; extern int thrd_num; extern int gLineLen; extern char * gStr; /**** reads info *****/ extern long long n_solexa; extern long long prevNum; extern int ins_size_var; extern PE_INFO * pes; extern int maxReadLen; extern int maxReadLen4all; extern int minReadLen; extern int maxNameLen; extern int num_libs; extern LIB_INFO * lib_array; extern int libNo; extern long long readNumBack; extern int gradsCounter; /*** used for pregraph *****/ extern MEM_MANAGER * prearc_mem_manager; //also used in scaffolding extern MEM_MANAGER ** preArc_mem_managers; extern boolean deLowKmer; extern boolean deLowEdge; extern KmerSet ** KmerSets; // also used in mapping extern KmerSet ** KmerSetsPatch; /**** used for contiging ****/ extern boolean repsTie; extern long long arcCounter; extern unsigned int num_ed; extern unsigned int num_ed_limit; extern unsigned int extraEdgeNum; extern EDGE * edge_array; extern VERTEX * vt_array; extern MEM_MANAGER * rv_mem_manager; extern MEM_MANAGER * arc_mem_manager; extern unsigned int num_vt; extern unsigned long long new_num_vt; extern int len_bar; extern ARC ** arcLookupTable; extern long long * markersArray; /***** used for scaffolding *****/ extern MEM_MANAGER * cn_mem_manager; extern unsigned int num_ctg; extern unsigned int * index_array; extern CONTIG * contig_array; extern int lineLen; extern int weakPE; extern long long newCntCounter; extern CONNECT ** cntLookupTable; extern unsigned int ctg_short; extern int cvgAvg; extern boolean orig2new; extern int Insert_size; extern int score_mask; extern long long discardCntCounter; extern int COMPATIBLE_MODE; extern float cvg4SNP; /**** used for gapFilling ****/ extern DARRAY * readSeqInGap; extern DARRAY * gapSeqDarray; extern DARRAY ** darrayBuf; extern int fillGap; /**** used for searchPath *****/ extern int maxSteps; extern int num_trace; extern unsigned int ** found_routes; extern unsigned int * so_far; extern int max_n_routes; extern boolean maskRep; extern int GLDiff; extern int initKmerSetSize; extern long known_genome_size; extern int smallKmer; extern int deltaKmer; extern int gapNum; extern int scaffNum; extern int * contig_index_array; extern double cvg_low; extern double cvg_high; extern double len_times; extern float ins_var_idx; extern int visual; extern unsigned int num_vtnew; extern unsigned int kmer_cnew; extern const int step; extern unsigned int * edge_id; extern VERTEX * vt_arraynew; extern KmerSet2 * KmerSetsNew; extern MEM_MANAGER * edgeid_mem_manager; extern char libfilename[256]; extern boolean parse; extern int nowstep2; extern unsigned int num_ed_temp; extern int arcfilter; extern boolean outputContig; extern int clean; extern long long pinCounter; extern unsigned int num_kmer_limit; soapdenovo2-240+dfsg.orig/standardPregraph/inc/stack.h0000644000000000000000000000271412166703654021532 0ustar rootroot/* * inc/stack.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef __STACK__ #define __STACK__ #include #include #include typedef struct block_starter { struct block_starter * prev; struct block_starter * next; } BLOCK_STARTER; typedef struct stack { BLOCK_STARTER * block_list; int index_in_block; int items_per_block; int item_c; size_t item_size; BLOCK_STARTER * block_backup; int index_backup; int item_c_backup; } STACK; void stackBackup ( STACK * astack ); void stackRecover ( STACK * astack ); void * stackPush ( STACK * astack ); void * stackPop ( STACK * astack ); void freeStack ( STACK * astack ); void emptyStack ( STACK * astack ); STACK * createStack ( int num_items, size_t unit_size ); #endif soapdenovo2-240+dfsg.orig/standardPregraph/inc/global.h0000644000000000000000000001304712166703654021666 0ustar rootroot/* * inc/global.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ int visual = 0; // 1 for output some files , which are useful for visual int * contig_index_array = NULL; int scaffNum = 0; int gapNum = 1; boolean fill = 0; // 1 for output some files ,which are useful for the software "kgf" int overlaplen = 23;//k-mer Size int inGraph; //for checking whether -g is set, (graph prefix) long long n_ban; //not used long long n_solexa = 0; //reads number long long prevNum = 0; //not used int ins_size_var = 20; // SD of insert-size PE_INFO * pes = NULL; //record the pe info in lib file MEM_MANAGER * rv_mem_manager = NULL; MEM_MANAGER * cn_mem_manager = NULL; MEM_MANAGER * arc_mem_manager = NULL; unsigned int num_vt = 0; // num of the end-kmer unsigned long long new_num_vt = 0; // the new num of the end-kmer after adding the new end-kmer unsigned int ** found_routes = NULL; unsigned int * so_far = NULL; // recorf the path of contig while filling gap int max_n_routes = 10; int num_trace; Kmer WORDFILTER; //mask code for extracting Kmer info from raw data (two unsigned long long int) unsigned int num_ed = 0; //number of edges unsigned int num_ctg = 0; // num of contig unsigned int num_ed_limit; // the count of edge unsigned int extraEdgeNum; // the new count of edge after adding the new edge EDGE * edge_array = NULL; // used to record all the info of edge VERTEX * vt_array = NULL; // used to record the sequence info of the end-kmer unsigned int * index_array = NULL; // used to translate the old contig index to the new contig index CONTIG * contig_array = NULL; // used to record all the info of contig int lineLen; int len_bar = 100; int weakPE = 3; // the minimun weight requirement for the connection int fillGap = 0; // 1 for fill the gap after scaffold asm boolean globalFlag; long long arcCounter; // record the num of the arc MEM_MANAGER * prearc_mem_manager = NULL; MEM_MANAGER ** preArc_mem_managers = NULL; int maxReadLen = 0; //max length will be used for each LIB, soapdenovo read LIBs one by one , for each set a maxReadLen int maxReadLen4all = 0; //max length will be used for all reads int minReadLen = 0; // min length will be used for all readss int maxNameLen = 0; //max length for the name of reads or sequences ARC ** arcLookupTable = NULL; long long * markersArray = NULL; boolean deLowKmer = 0; //remove the kmers which coverage are not bigger than deLowKmer boolean deLowEdge = 1; //remove the edges which coverage are not bigger than deLowEdge long long newCntCounter; // record the number of the new connection in one insert-size long long discardCntCounter; boolean repsTie = 0; //sovle tiny repeat or not CONNECT ** cntLookupTable = NULL; int num_libs = 0; //number of LIBs in read config file LIB_INFO * lib_array = NULL; //store LIB's info into lib_array int libNo = 0; // the current number of lib long long readNumBack; int gradsCounter; //pair number in lib file unsigned int ctg_short = 0; //shortest contig for scaffolding int thrd_num = 8; //thread number int cvgAvg = 0; // the average coverage of contigs KmerSet ** KmerSets = NULL; //KmerSet [i] for thread i KmerSet ** KmerSetsPatch = NULL; //KmerSet for (k+1) mer DARRAY * readSeqInGap = NULL; DARRAY * gapSeqDarray = NULL; DARRAY ** darrayBuf; boolean orig2new; // 1 for re-arrange the contig index using the length int maxSteps; boolean maskRep = 1; // 1 for masking repeat for scaffold asm , 0 for un-masking repeat. int GLDiff = 50; int initKmerSetSize = 0; // init_size = (ubyte8) ((double) initKmerSetSize * 1024.0f * 1024.0f * 1024.0f / (double) thrd_num / 24); long known_genome_size = 0; int smallKmer = 0; // the kmer of the step "Map" int deltaKmer = 0; // for map, K-k double cvg_low = 0.1; double cvg_high = 2; double len_times = 0; float ins_var_idx = 1.5; int Insert_size = 0; // the current insert-size int score_mask = 1; int COMPATIBLE_MODE = 0; // 1 for the gz file ; 0 for the normal file float cvg4SNP = 0.6; MEM_MANAGER * edgeid_mem_manager = NULL; unsigned int num_vtnew = 0; //new vertex num unsigned int kmer_cnew = 0; //new kmer num const int step = 1; //step for multi kmer //int nowstep = 1; int nowstep2 = 1; unsigned int * edge_id = NULL; //edge id array VERTEX * vt_arraynew = NULL; //vertex array for k+1mer KmerSet2 * KmerSetsNew = NULL; //kmer set for k+1mer char libfilename[256]; boolean parse = 0; unsigned int num_ed_temp = 0; // record the count of the edge int arcfilter = 0; //arc filter thrd boolean outputContig = 0; long long pinCounter; //the count of the merged bubble int clean; //merge clean bubble unsigned int num_kmer_limit; int gLineLen = 5000; char * gStr = NULL; soapdenovo2-240+dfsg.orig/standardPregraph/fib.c0000644000000000000000000003024212166703654020404 0ustar rootroot/* * fib.c * * This file is part of SOAPdenovo. * */ /*- * Copyright 1997-2003 John-Mark Gurney. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND 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 THE AUTHOR OR 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. * * $Id: fib.c,v 1.10 2007/10/19 13:09:26 zerbino Exp $ * */ #include #include #include "fib.h" #include "fibpriv.h" #include "extfunc2.h" #define HEAPBLOCKSIZE 10000 static int fh_comparedata ( FibHeap * h, Coordinate key, unsigned int data, FibHeapNode * b ); unsigned int fh_replacekeydata ( FibHeap * h, FibHeapNode * x, Coordinate key, unsigned int data ); static FibHeapNode * allocateFibHeapEl ( FibHeap * heap ) { return ( FibHeapNode * ) getItem ( heap->nodeMemory ); }; static void deallocateFibHeapEl ( FibHeapNode * a, FibHeap * heap ) { returnItem ( heap->nodeMemory, a ); } #define swap(type, a, b) \ do { \ type c; \ c = a; \ a = b; \ b = c; \ } while (0) \ #define INT_BITS (sizeof(IDnum) * 8) static inline IDnum ceillog2 ( IDnum a ) { IDnum oa; IDnum i; IDnum b; IDnum cons; oa = a; b = INT_BITS / 2; i = 0; while ( b ) { i = ( i << 1 ); cons = ( ( IDnum ) 1 ) << b; if ( a >= cons ) { a /= cons; i = i | 1; } else { a &= cons - 1; } b /= 2; } if ( ( ( ( IDnum ) 1 << i ) ) == oa ) { return i; } else { return i + 1; } } /* * Private Heap Functions */ static void fh_initheap ( FibHeap * new ) { new->fh_cmp_fnct = NULL; new->nodeMemory = createMem_manager ( sizeof ( FibHeapNode ), HEAPBLOCKSIZE ); new->fh_neginf = 0; new->fh_n = 0; new->fh_Dl = -1; new->fh_cons = NULL; new->fh_min = NULL; new->fh_root = NULL; new->fh_keys = 0; } static void fh_destroyheap ( FibHeap * h ) { h->fh_cmp_fnct = NULL; h->fh_neginf = 0; if ( h->fh_cons != NULL ) { free ( h->fh_cons ); } h->fh_cons = NULL; free ( h ); } /* * Public Heap Functions */ FibHeap * fh_makekeyheap () { FibHeap * n; if ( ( n = malloc ( sizeof * n ) ) == NULL ) { return NULL; } fh_initheap ( n ); n->fh_keys = 1; return n; } FibHeap * fh_makeheap () { FibHeap * n; if ( ( n = malloc ( sizeof * n ) ) == NULL ) { return NULL; } fh_initheap ( n ); return n; } voidcmp fh_setcmp ( FibHeap * h, voidcmp fnct ) { voidcmp oldfnct; oldfnct = h->fh_cmp_fnct; h->fh_cmp_fnct = fnct; return oldfnct; } unsigned int fh_setneginf ( FibHeap * h, unsigned int data ) { unsigned int old; old = h->fh_neginf; h->fh_neginf = data; return old; } FibHeap * fh_union ( FibHeap * ha, FibHeap * hb ) { FibHeapNode * x; if ( ha->fh_root == NULL || hb->fh_root == NULL ) { /* either one or both are empty */ if ( ha->fh_root == NULL ) { fh_destroyheap ( ha ); return hb; } else { fh_destroyheap ( hb ); return ha; } } ha->fh_root->fhe_left->fhe_right = hb->fh_root; hb->fh_root->fhe_left->fhe_right = ha->fh_root; x = ha->fh_root->fhe_left; ha->fh_root->fhe_left = hb->fh_root->fhe_left; hb->fh_root->fhe_left = x; ha->fh_n += hb->fh_n; /* * we probably should also keep stats on number of unions */ /* set fh_min if necessary */ if ( fh_compare ( ha, hb->fh_min, ha->fh_min ) < 0 ) { ha->fh_min = hb->fh_min; } fh_destroyheap ( hb ); return ha; } void fh_deleteheap ( FibHeap * h ) { freeMem_manager ( h->nodeMemory ); h->nodeMemory = NULL; fh_destroyheap ( h ); } /* * Public Key Heap Functions */ FibHeapNode * fh_insertkey ( FibHeap * h, Coordinate key, unsigned int data ) { FibHeapNode * x; if ( ( x = fhe_newelem ( h ) ) == NULL ) { return NULL; } /* just insert on root list, and make sure it's not the new min */ x->fhe_data = data; x->fhe_key = key; fh_insertel ( h, x ); return x; } boolean fh_isempty ( FibHeap * h ) { if ( h->fh_min == NULL ) { return 1; } else { return 0; } } Coordinate fh_minkey ( FibHeap * h ) { if ( h->fh_min == NULL ) { return INT_MIN; } return h->fh_min->fhe_key; } unsigned int fh_replacekeydata ( FibHeap * h, FibHeapNode * x, Coordinate key, unsigned int data ) { unsigned int odata; Coordinate okey; FibHeapNode * y; int r; odata = x->fhe_data; okey = x->fhe_key; /* * we can increase a key by deleting and reinserting, that * requires O(lgn) time. */ if ( ( r = fh_comparedata ( h, key, data, x ) ) > 0 ) { /* XXX - bad code! */ abort (); } x->fhe_data = data; x->fhe_key = key; /* because they are equal, we don't have to do anything */ if ( r == 0 ) { return odata; } y = x->fhe_p; if ( h->fh_keys && okey == key ) { return odata; } if ( y != NULL && fh_compare ( h, x, y ) <= 0 ) { fh_cut ( h, x, y ); fh_cascading_cut ( h, y ); } /* * the = is so that the call from fh_delete will delete the proper * element. */ if ( fh_compare ( h, x, h->fh_min ) <= 0 ) { h->fh_min = x; } return odata; } Coordinate fh_replacekey ( FibHeap * h, FibHeapNode * x, Coordinate key ) { Coordinate ret; ret = x->fhe_key; ( void ) fh_replacekeydata ( h, x, key, x->fhe_data ); return ret; } /* * Public void * Heap Functions */ /* * this will return these values: * NULL failed for some reason * ptr token to use for manipulation of data */ FibHeapNode * fh_insert ( FibHeap * h, unsigned int data ) { FibHeapNode * x; if ( ( x = fhe_newelem ( h ) ) == NULL ) { return NULL; } /* just insert on root list, and make sure it's not the new min */ x->fhe_data = data; fh_insertel ( h, x ); return x; } unsigned int fh_min ( FibHeap * h ) { if ( h->fh_min == NULL ) { return 0; } return h->fh_min->fhe_data; } unsigned int fh_extractmin ( FibHeap * h ) { FibHeapNode * z; unsigned int ret = 0; if ( h->fh_min != NULL ) { z = fh_extractminel ( h ); ret = z->fhe_data; #ifndef NO_FREE deallocateFibHeapEl ( z, h ); #endif } return ret; } unsigned int fh_replacedata ( FibHeapNode * x, unsigned int data ) { unsigned int odata = x->fhe_data; x->fhe_data = data; return odata; } unsigned int fh_delete ( FibHeap * h, FibHeapNode * x ) { unsigned int k; k = x->fhe_data; if ( !h->fh_keys ) { fh_replacedata ( x, h->fh_neginf ); } else { fh_replacekey ( h, x, INT_MIN ); } fh_extractmin ( h ); return k; } /* * begin of private element fuctions */ static FibHeapNode * fh_extractminel ( FibHeap * h ) { FibHeapNode * ret; FibHeapNode * x, *y, *orig; ret = h->fh_min; orig = NULL; /* put all the children on the root list */ /* for true consistancy, we should use fhe_remove */ for ( x = ret->fhe_child; x != orig && x != NULL; ) { if ( orig == NULL ) { orig = x; } y = x->fhe_right; x->fhe_p = NULL; fh_insertrootlist ( h, x ); x = y; } /* remove minimum from root list */ fh_removerootlist ( h, ret ); h->fh_n--; /* if we aren't empty, consolidate the heap */ if ( h->fh_n == 0 ) { h->fh_min = NULL; } else { h->fh_min = ret->fhe_right; fh_consolidate ( h ); } return ret; } static void fh_insertrootlist ( FibHeap * h, FibHeapNode * x ) { if ( h->fh_root == NULL ) { h->fh_root = x; x->fhe_left = x; x->fhe_right = x; return; } fhe_insertafter ( h->fh_root, x ); } static void fh_removerootlist ( FibHeap * h, FibHeapNode * x ) { if ( x->fhe_left == x ) { h->fh_root = NULL; } else { h->fh_root = fhe_remove ( x ); } } static void fh_consolidate ( FibHeap * h ) { FibHeapNode ** a; FibHeapNode * w; FibHeapNode * y; FibHeapNode * x; IDnum i; IDnum d; IDnum D; fh_checkcons ( h ); /* assign a the value of h->fh_cons so I don't have to rewrite code */ D = h->fh_Dl + 1; a = h->fh_cons; for ( i = 0; i < D; i++ ) { a[i] = NULL; } while ( ( w = h->fh_root ) != NULL ) { x = w; fh_removerootlist ( h, w ); d = x->fhe_degree; /* XXX - assert that d < D */ while ( a[d] != NULL ) { y = a[d]; if ( fh_compare ( h, x, y ) > 0 ) { swap ( FibHeapNode *, x, y ); } fh_heaplink ( h, y, x ); a[d] = NULL; d++; } a[d] = x; } h->fh_min = NULL; for ( i = 0; i < D; i++ ) if ( a[i] != NULL ) { fh_insertrootlist ( h, a[i] ); if ( h->fh_min == NULL || fh_compare ( h, a[i], h->fh_min ) < 0 ) { h->fh_min = a[i]; } } } static void fh_heaplink ( FibHeap * h, FibHeapNode * y, FibHeapNode * x ) { /* make y a child of x */ if ( x->fhe_child == NULL ) { x->fhe_child = y; } else { fhe_insertbefore ( x->fhe_child, y ); } y->fhe_p = x; x->fhe_degree++; y->fhe_mark = 0; } static void fh_cut ( FibHeap * h, FibHeapNode * x, FibHeapNode * y ) { fhe_remove ( x ); y->fhe_degree--; fh_insertrootlist ( h, x ); x->fhe_p = NULL; x->fhe_mark = 0; } static void fh_cascading_cut ( FibHeap * h, FibHeapNode * y ) { FibHeapNode * z; while ( ( z = y->fhe_p ) != NULL ) { if ( y->fhe_mark == 0 ) { y->fhe_mark = 1; return; } else { fh_cut ( h, y, z ); y = z; } } } /* * begining of handling elements of fibheap */ static FibHeapNode * fhe_newelem ( FibHeap * h ) { FibHeapNode * e; if ( ( e = allocateFibHeapEl ( h ) ) == NULL ) { return NULL; } fhe_initelem ( e ); return e; } static void fhe_initelem ( FibHeapNode * e ) { e->fhe_degree = 0; e->fhe_mark = 0; e->fhe_p = NULL; e->fhe_child = NULL; e->fhe_left = e; e->fhe_right = e; e->fhe_data = 0; } static void fhe_insertafter ( FibHeapNode * a, FibHeapNode * b ) { if ( a == a->fhe_right ) { a->fhe_right = b; a->fhe_left = b; b->fhe_right = a; b->fhe_left = a; } else { b->fhe_right = a->fhe_right; a->fhe_right->fhe_left = b; a->fhe_right = b; b->fhe_left = a; } } static inline void fhe_insertbefore ( FibHeapNode * a, FibHeapNode * b ) { fhe_insertafter ( a->fhe_left, b ); } static FibHeapNode * fhe_remove ( FibHeapNode * x ) { FibHeapNode * ret; if ( x == x->fhe_left ) { ret = NULL; } else { ret = x->fhe_left; } /* fix the parent pointer */ if ( x->fhe_p != NULL && x->fhe_p->fhe_child == x ) { x->fhe_p->fhe_child = ret; } x->fhe_right->fhe_left = x->fhe_left; x->fhe_left->fhe_right = x->fhe_right; /* clear out hanging pointers */ x->fhe_p = NULL; x->fhe_left = x; x->fhe_right = x; return ret; } static void fh_checkcons ( FibHeap * h ) { IDnum oDl; /* make sure we have enough memory allocated to "reorganize" */ if ( h->fh_Dl == -1 || h->fh_n > ( 1 << h->fh_Dl ) ) { oDl = h->fh_Dl; if ( ( h->fh_Dl = ceillog2 ( h->fh_n ) + 1 ) < 8 ) { h->fh_Dl = 8; } if ( oDl != h->fh_Dl ) { h->fh_cons = ( FibHeapNode ** ) realloc ( h->fh_cons, sizeof * h->fh_cons * ( h->fh_Dl + 1 ) ); } if ( h->fh_cons == NULL ) { abort (); } } } static int fh_compare ( FibHeap * h, FibHeapNode * a, FibHeapNode * b ) { if ( a->fhe_key < b->fhe_key ) { return -1; } if ( a->fhe_key == b->fhe_key ) { return 0; } return 1; } static int fh_comparedata ( FibHeap * h, Coordinate key, unsigned int data, FibHeapNode * b ) { FibHeapNode a; a.fhe_key = key; a.fhe_data = data; return fh_compare ( h, &a, b ); } static void fh_insertel ( FibHeap * h, FibHeapNode * x ) { fh_insertrootlist ( h, x ); if ( h->fh_min == NULL || ( h->fh_keys ? x->fhe_key < h->fh_min->fhe_key : h->fh_cmp_fnct ( x->fhe_data, h->fh_min->fhe_data ) < 0 ) ) { h->fh_min = x; } h->fh_n++; } soapdenovo2-240+dfsg.orig/standardPregraph/check.c0000644000000000000000000000516112166703654020723 0ustar rootroot/* * check.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include void * ckalloc ( unsigned long long amount ); FILE * ckopen ( char * name, char * mode ); FILE * ckopen ( char * name, char * mode ) { FILE * fp; if ( ( fp = fopen ( name, mode ) ) == NULL ) { fprintf ( stderr, "Cannot open %s. Now exit to system...\n", name ); exit ( -1 ); } return ( fp ); } static int GetFileSize ( FILE * fp ) { char c = fgetc ( fp ); if ( c == EOF ) { return 0; } return 1; } boolean check_file ( char * name ) { FILE * linkF; if ( strlen ( name ) > 3 && strcmp ( name + strlen ( name ) - 3, ".gz" ) == 0 ) { char cmd[1000]; sprintf ( cmd, "gzip -dc %s", name ); linkF = popen ( cmd, "r" ); if ( linkF ) { if ( GetFileSize ( linkF ) != 0 ) { pclose ( linkF ); return 1; } pclose ( linkF ); } return 0; } else { linkF = fopen ( name, "r" ); if ( linkF ) { if ( GetFileSize ( linkF ) != 0 ) { fclose ( linkF ); return 1; } fclose ( linkF ); } return 0; } } /* ckalloc - allocate space; check for success */ void * ckalloc ( unsigned long long amount ) { void * p; if ( ( p = ( void * ) calloc ( 1, ( unsigned long long ) amount ) ) == NULL && amount != 0 ) { fprintf ( stderr, "Ran out of memory while applying %lldbytes\n", amount ); fprintf ( stderr, "There may be errors as follows:\n" ); fprintf ( stderr, "1) Not enough memory.\n" ); fprintf ( stderr, "2) The ARRAY may be overrode.\n" ); fprintf ( stderr, "3) The wild pointers.\n" ); exit ( -1 ); } return ( p ); } /* reallocate memory */ void * ckrealloc ( void * p, size_t new_size, size_t old_size ) { void * q; q = realloc ( ( void * ) p, new_size ); if ( new_size == 0 || q != ( void * ) 0 ) { return q; } /* manually reallocate space */ q = ckalloc ( new_size ); /* move old memory to new space */ bcopy ( p, q, old_size ); free ( p ); return q; } soapdenovo2-240+dfsg.orig/standardPregraph/contig.c0000644000000000000000000002074612166703654021137 0ustar rootroot/* * contig.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" static void initenv ( int argc, char ** argv ); static void display_contig_usage (); char shortrdsfile[256], graphfile[256]; static boolean repeatSolve; //whether solve repeat or not //static boolean keepReadFile = 0; //whether keep tmp selected reads file or not static boolean iter = 0; //whether use multikmer or not static boolean cleanBubble = 0; //whether merge clean bubble before iterate static int M = 1; //merge bubble level static int maxk = 0; //max kmer of multikmer /************************************************* Function: call_heavygraph Description: The main function for contig step . its processes are as below: 1. Solve repeat 2. Merge bubble(clean bubble is optional for multikmer) 3. Remove weak edge and low coverage edge 4. Cut tips 5. Iterate multikmer(optional) Input: @see display_contig_usage () Output: The files below: 1. *.contig 2. *.ContigIndex 3. *.update.edge 4. *.Arc 5. *.read [optional] 6. *.preGraphBasic [optional] Return: None. *************************************************/ int call_heavygraph ( int argc, char ** argv ) { time_t start_t, stop_t, time_bef, time_aft; time ( &start_t ); boolean ret; fprintf ( stderr, "\n********************\n" ); fprintf ( stderr, "Contig\n" ); fprintf ( stderr, "********************\n\n" ); initenv ( argc, argv ); loadVertex ( graphfile ); loadEdge ( graphfile ); if ( repeatSolve ) { ret = loadPathBin ( graphfile ); } swapedge(); sortedge(); freshArc(); if ( repeatSolve ) { time ( &time_bef ); // ret = loadPathBin (graphfile); if ( ret ) { solveReps (); } else { fprintf ( stderr, "Repeat solving can't be done...\n" ); } time ( &time_aft ); fprintf ( stderr, "Time spent on solving repeat: %ds.\n", ( int ) ( time_aft - time_bef ) ); } //edgecvg_bar(edge_array,num_ed,graphfile,100); if ( !iter && M > 0 ) { time ( &time_bef ); bubblePinch ( 0.90, graphfile, M, 0, 1 ); time ( &time_aft ); fprintf ( stderr, "Time spent on pinching bubbles: %ds.\n", ( int ) ( time_aft - time_bef ) ); } if ( iter && cleanBubble && M > 0 ) { time ( &time_bef ); clean = 1; long long oldpinCounter = 0; long long min = 10; int times = 0; while ( min >= 10 ) { times++; if ( times >= 4 ) { break; } bubblePinch ( 0.90, graphfile, M, 1, 0 ); min = pinCounter; fprintf ( stderr, "%lld clean bubbles merged.\n", pinCounter ); } time ( &time_aft ); fprintf ( stderr, "Time spent on pinching clean bubbles: %ds.\n", ( int ) ( time_aft - time_bef ) ); clean = 0; } if ( deLowEdge ) { removeWeakEdges ( 2 * overlaplen, 1 ); removeLowCovEdges ( 2 * overlaplen, deLowEdge, !iter ); } cutTipsInGraph ( 0, 0, !iter ); if ( iter ) { Iterate ( shortrdsfile, graphfile, maxk, M ); //keepReadFile, if ( M > 0 ) { time ( &time_bef ); bubblePinch ( 0.90, graphfile, M, 1, 0 ); time ( &time_aft ); fprintf ( stderr, "Time spent on pinching bubbles: %ds.\n", ( int ) ( time_aft - time_bef ) ); } freshpreGraphBasic ( iter, maxk, graphfile ); } //output_graph(graphfile); output_contig ( edge_array, num_ed, graphfile, overlaplen + 1 ); output_updated_edges ( graphfile ); output_heavyArcs ( graphfile ); if ( vt_array ) { free ( ( void * ) vt_array ); vt_array = NULL; } if ( edge_array ) { free_edge_array ( edge_array, num_ed_limit ); edge_array = NULL; } destroyArcMem (); time ( &stop_t ); fprintf ( stderr, "\nTime spent on constructing contig: %dm.\n\n", ( int ) ( stop_t - start_t ) / 60 ); return 0; } /***************************************************************************** * Parse command line switches *****************************************************************************/ void initenv ( int argc, char ** argv ) { int copt; int inpseq, outseq; extern char * optarg; char temp[100]; inpseq = outseq = repeatSolve = iter = cleanBubble = 0;//keepReadFile = optind = 1; fprintf ( stderr, "Parameters: contig " ); while ( ( copt = getopt ( argc, argv, "g:M:D:Rs:m:p:e:E" ) ) != EOF ) // r { switch ( copt ) { case 'M': fprintf ( stderr, "-M %s ", optarg ); sscanf ( optarg, "%s", temp ); M = atoi ( temp ); break; case 'D': fprintf ( stderr, "-D %s ", optarg ); sscanf ( optarg, "%s", temp ); deLowEdge = atoi ( temp ) >= 0 ? atoi ( temp ) : 0; break; case 'g': fprintf ( stderr, "-g %s ", optarg ); inGraph = 1; sscanf ( optarg, "%s", graphfile ); break; case 'R': repeatSolve = 1; fprintf ( stderr, "-R " ); break; case 's': fprintf ( stderr, "-s %s ", optarg ); inpseq = 1; sscanf ( optarg, "%s", shortrdsfile ); break; case 'm': fprintf ( stderr, "-m %s ", optarg ); iter = 1; sscanf ( optarg, "%s", temp ); maxk = atoi ( temp ); break; /* case 'r': keepReadFile = 1; fprintf(stderr, "-r "); break; */ case 'e': fprintf ( stderr, "-e %s ", optarg ); sscanf ( optarg, "%s", temp ); arcfilter = atoi ( temp ); break; case 'p': fprintf ( stderr, "-p %s ", optarg ); sscanf ( optarg, "%s", temp ); thrd_num = atoi ( temp ); break; case 'E': cleanBubble = 1; fprintf ( stderr, "-E " ); break; default: if ( ( iter && inpseq == 0 ) || inGraph == 0 ) { display_contig_usage (); exit ( -1 ); } } } fprintf ( stderr, "\n\n" ); if ( iter ) { if ( maxk % 2 == 0 ) { maxk++; fprintf ( stderr, "Max K should be an odd number, change to %d.\n", maxk ); } if ( maxk < 13 ) { maxk = 13; fprintf ( stderr, "Max K should not be less than 13, change to %d.\n", maxk ); } #ifdef MER127 else if ( maxk > 127 ) { maxk = 127; fprintf ( stderr, "Max K should not be greater than 127, change to %d.\n", maxk ); } #else else if ( maxk > 63 ) { maxk = 63; fprintf ( stderr, "Max K should not be greater than 63, change to %d.\n", maxk ); } #endif if ( maxk <= overlaplen ) { fprintf ( stderr, "Max K %d is not greater than overlaplen %d.\n", maxk, overlaplen ); display_contig_usage (); exit ( -1 ); } } if ( ( iter && inpseq == 0 ) || inGraph == 0 ) { display_contig_usage (); exit ( -1 ); } } static void display_contig_usage () { fprintf ( stderr, "\ncontig -g InputGraph [-R] [-M mergeLevel -D EdgeCovCutoff] [-s readsInfoFile -m maxkmer -p n_cpu -r]\n" ); fprintf ( stderr, " -g inputGraph: prefix of input graph file names\n" ); fprintf ( stderr, " -R (optional) resolve repeats using information generated in pregraph step, works only if -R is set in pregraph step too, [NO]\n" ); fprintf ( stderr, " -M mergeLevel(min 0, max 3): the strength of merging similar sequences during contiging, [1]\n" ); fprintf ( stderr, " -D EdgeCovCutoff: edges shorter than (2*K+1) with coverage no larger than EdgeCovCutoff will be deleted, [1]\n" ); fprintf ( stderr, " -e arcWeight: two edges, between which the arc's weight is larger than arcWeight, will be linerized, [0]\n" ); fprintf ( stderr, " -m max k when using multi-kmer, and the parameters below are used along with multi-kmer, [NO]\n" ); fprintf ( stderr, " -s readsInfoFile:The file contains information of solexa reads(It's necessary when using multi-kmer)\n" ); fprintf ( stderr, " -p number of cpu, [8]\n" ); fprintf ( stderr, " -E (optional) merge clean bubble before iterate, works only if -M is set when using multi-kmer, [NO]\n" ); // fprintf (stderr," -r (optional) keep available read(*.read)\n"); } soapdenovo2-240+dfsg.orig/standardPregraph/searchPath.c0000644000000000000000000001367312166703654021737 0ustar rootroot/* * searchPath.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" static int trace_limit = 5000; //the times function is called in a search /* search connection paths which were masked along related contigs start from one contig, end with another path length includes the length of the last contig */ void traceAlongMaskedCnt ( unsigned int destE, unsigned int currE, int max_steps, int min, int max, int index, int len, int * num_route ) { num_trace++; if ( num_trace > trace_limit || *num_route >= max_n_routes ) { return; } unsigned int * array; int num, i, length; CONNECT * ite_cnt; if ( index > 0 ) // there're at most max_steps edges stored in this array including the destination edge { length = len + contig_array[currE].length; } else { length = 0; } if ( index > max_steps || length > max ) { return; } // this is the only situation we stop if ( index > 0 ) // there're at most max_steps edges stored in this array including the destination edge { so_far[index - 1] = currE; } if ( currE == destE && index == 0 ) { fprintf ( stderr, "The traceAlongMaskedCnt: start and destination are the same.\n" ); return; } if ( currE == destE && length >= min && length <= max ) { num = *num_route; array = found_routes[num]; for ( i = 0; i < index; i++ ) { array[i] = so_far[i]; } if ( index < max_steps ) { array[index] = 0; } //indicate the end of the route *num_route = ++num; } // one route is extrated, but we don't terminate searching ite_cnt = contig_array[currE].downwardConnect; while ( ite_cnt ) { if ( !ite_cnt->mask || ite_cnt->deleted ) { ite_cnt = ite_cnt->next; continue; } traceAlongMaskedCnt ( destE, ite_cnt->contigID, max_steps, min, max, index + 1, length + ite_cnt->gapLen, num_route ); ite_cnt = ite_cnt->next; } } // search connection paths from one connect to a contig // path length includes the length of the last contig void traceAlongConnect ( unsigned int destE, CONNECT * currCNT, int max_steps, int min, int max, int index, int len, int * num_route ) { num_trace++; if ( num_trace > trace_limit || *num_route >= max_n_routes ) { return; } unsigned int * array, currE; int num, i, length; CONNECT * ite_cnt; currE = currCNT->contigID; length = len + currCNT->gapLen; length += contig_array[currE].length; if ( index > max_steps || length > max ) { return; } // this is the only situation we stop /* if(globalFlag) printf("B: step %d, ctg %d, length %d\n",index,currCNT->contigID,length); */ if ( currE == destE && index == 1 ) { fprintf ( stderr, "The traceAlongConnect: start and destination are the same.\n" ); return; } so_far[index - 1] = currE; // there're at most max_steps edges stored in this array including the destination edge if ( currE == destE && length >= min && length <= max ) { num = *num_route; array = found_routes[num]; for ( i = 0; i < index; i++ ) { array[i] = so_far[i]; } if ( index < max_steps ) { array[index] = 0; } //indicate the end of the route *num_route = ++num; } // one route is extrated, but we don't terminate searching if ( currCNT->nextInScaf ) { traceAlongConnect ( destE, currCNT->nextInScaf, max_steps, min, max, index + 1, length, num_route ); return; } ite_cnt = contig_array[currE].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->mask || ite_cnt->deleted ) { ite_cnt = ite_cnt->next; continue; } traceAlongConnect ( destE, ite_cnt, max_steps, min, max, index + 1, length, num_route ); ite_cnt = ite_cnt->next; } } //find paths in the graph from currE to destE, its length does not include length of both end contigs void traceAlongArc ( unsigned int destE, unsigned int currE, int max_steps, int min, int max, int index, int len, int * num_route ) { num_trace++; if ( num_trace > trace_limit || *num_route >= max_n_routes ) { return; } unsigned int * array, out_ed, vt; int num, i, pos, length; preARC * parc; pos = index; if ( pos > max_steps || len > max ) { return; } // this is the only situation we stop if ( currE == destE && pos == 0 ) { fprintf ( stderr, "The traceAlongArc: start and destination are the same.\n" ); return; } if ( pos > 0 ) // pos starts with 0 for the starting edge { so_far[pos - 1] = currE; } // there're at most max_steps edges stored in this array including the destination edge if ( currE == destE && len >= min ) { num = *num_route; array = found_routes[num]; for ( i = 0; i < pos; i++ ) { array[i] = so_far[i]; } if ( pos < max_steps ) { array[pos] = 0; } //indicate the end of the route *num_route = ++num; } // one route is extrated, but we don't terminate searching if ( pos == max_steps || len == max ) { return; } if ( pos++ > 0 ) //not the starting edge { length = len + contig_array[currE].length; } else { length = len; } vt = contig_array[currE].to_vt; parc = contig_array[currE].arcs; while ( parc ) { out_ed = parc->to_ed; traceAlongArc ( destE, out_ed, max_steps, min, max, pos, length, num_route ); parc = parc->next; } } soapdenovo2-240+dfsg.orig/standardPregraph/concatenateEdge.c0000644000000000000000000001757412166703654022732 0ustar rootroot/* * concatenateEdge.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" void copySeq ( char * targetS, char * sourceS, int pos, int length ) { char ch; int i, index; index = pos; for ( i = 0; i < length; i++ ) { ch = getCharInTightString ( sourceS, i ); writeChar2tightString ( ch, targetS, index++ ); } } /************************************************* Function: linearUpdateConnection Description: A path from e1 to e2 is merged in to e1 (indicate=0) or e2 (indicate=1), update graph topology. Input: 1. e1: edge1 index 2. e2: edge2 index 3. indicate: indicate which edge to be merged into Output: None. Return: None. *************************************************/ void linearUpdateConnection ( unsigned int e1, unsigned int e2, int indicate ) { unsigned int bal_ed; ARC * parc; if ( !indicate ) { edge_array[e1].to_vt = edge_array[e2].to_vt; bal_ed = getTwinEdge ( e1 ); parc = edge_array[e2].arcs; while ( parc ) { parc->bal_arc->to_ed = bal_ed; parc = parc->next; } edge_array[e1].arcs = edge_array[e2].arcs; edge_array[e2].arcs = NULL; if ( edge_array[e1].length || edge_array[e2].length ) { edge_array[e1].cvg = ( edge_array[e1].cvg * edge_array[e1].length + edge_array[e2].cvg * edge_array[e2].length ) / ( edge_array[e1].length + edge_array[e2].length ); } edge_array[e2].deleted = 1; } else { //all the arcs pointing to e1 switch to e2 parc = edge_array[getTwinEdge ( e1 )].arcs; while ( parc ) { parc->bal_arc->to_ed = e2; parc = parc->next; } edge_array[e1].arcs = NULL; edge_array[e2].from_vt = edge_array[e1].from_vt; if ( edge_array[e1].length || edge_array[e2].length ) { edge_array[e2].cvg = ( edge_array[e1].cvg * edge_array[e1].length + edge_array[e2].cvg * edge_array[e2].length ) / ( edge_array[e1].length + edge_array[e2].length ); } edge_array[e1].deleted = 1; } } static void printEdgeSeq ( FILE * fp, char * tightSeq, int len ) { int i; for ( i = 0; i < len; i++ ) { fprintf ( fp, "%c", int2base ( ( int ) getCharInTightString ( tightSeq, i ) ) ); if ( ( i + overlaplen + 1 ) % 100 == 0 && i < len - 1 ) { fprintf ( fp, "\n" ); } } fprintf ( fp, "\n" ); } void allpathUpdateEdge ( unsigned int e1, unsigned int e2, int indicate, boolean last ) { int tightLen; char * tightSeq = NULL; if ( edge_array[e1].cvg == 0 ) { edge_array[e1].cvg = edge_array[e2].cvg; } if ( edge_array[e2].cvg == 0 ) { edge_array[e2].cvg = edge_array[e1].cvg; } /* if(edge_array[e1].length&&edge_array[e2].length){ fprintf(stderr,">e1\n"); printEdgeSeq(stderr,edge_array[e1].seq,edge_array[e1].length); fprintf(stderr,">e2\n"); printEdgeSeq(stderr,edge_array[e2].seq,edge_array[e2].length); } */ unsigned int cvgsum = edge_array[e1].cvg * edge_array[e1].length + edge_array[e2].cvg * edge_array[e2].length; tightLen = edge_array[e1].length + edge_array[e2].length; if ( tightLen ) { tightSeq = ( char * ) ckalloc ( ( tightLen / 4 + 1 ) * sizeof ( char ) ); } tightLen = 0; if ( edge_array[e1].length ) { copySeq ( tightSeq, edge_array[e1].seq, 0, edge_array[e1].length ); tightLen = edge_array[e1].length; if ( edge_array[e1].seq ) { free ( ( void * ) edge_array[e1].seq ); edge_array[e1].seq = NULL; } else { fprintf ( stderr, "AllpathUpdateEdge: edge %d with length %d, but without seq.\n", e1, edge_array[e1].length ); } } if ( edge_array[e2].length ) { copySeq ( tightSeq, edge_array[e2].seq, tightLen, edge_array[e2].length ); tightLen += edge_array[e2].length; if ( edge_array[e2].seq ) { free ( ( void * ) edge_array[e2].seq ); edge_array[e2].seq = NULL; } else { fprintf ( stderr, "AllpathUpdateEdge: edge %d with length %d, but without seq.\n", e2, edge_array[e2].length ); } } /* if(edge_array[e1].length&&edge_array[e2].length){ fprintf(stderr,">e1+e2\n"); printEdgeSeq(stderr,tightSeq,tightLen); } */ //edge_array[e2].extend_len = tightLen-edge_array[e2].length; //the sequence of e1 is to be updated if ( !indicate ) { edge_array[e2].length = 0; //e1 is removed from the graph edge_array[e1].to_vt = edge_array[e2].to_vt; //e2 is part of e1 now edge_array[e1].length = tightLen; edge_array[e1].seq = tightSeq; if ( tightLen ) { edge_array[e1].cvg = cvgsum / tightLen; } if ( last ) { edge_array[e1].cvg = edge_array[e1].cvg > 0 ? edge_array[e1].cvg : 1; } // edge_array[e1].cvg = edge_array[e1].cvg > 0 ? edge_array[e1].cvg : 1; } else { edge_array[e1].length = 0; //e1 is removed from the graph edge_array[e2].from_vt = edge_array[e1].from_vt; //e1 is part of e2 now edge_array[e2].length = tightLen; edge_array[e2].seq = tightSeq; if ( tightLen ) { edge_array[e2].cvg = cvgsum / tightLen; } if ( last ) { edge_array[e2].cvg = edge_array[e2].cvg > 0 ? edge_array[e2].cvg : 1; } // edge_array[e2].cvg = edge_array[e2].cvg > 0 ? edge_array[e2].cvg : 1; } } static void debugging ( unsigned int i ) { ARC * parc; parc = edge_array[i].arcs; if ( !parc ) { fprintf ( stderr, "No downward connection for %d.\n", i ); } while ( parc ) { fprintf ( stderr, "%d -> %d\n", i, parc->to_ed ); parc = parc->next; } } /************************************************* Function: linearConcatenate Description: Concatenates two edges if they are linearly linked. Input: 1. isIter: whether it is multi kmer 2. last: whether it is the last iteration Output: None. Return: None. *************************************************/ void linearConcatenate ( boolean isIter, boolean last ) { unsigned int i; int conc_c = 1; int counter; unsigned int from_ed, to_ed, bal_ed; ARC * parc, *parc2; unsigned int bal_fe; int donot1 = 0; int round = 1; //debugging(30514); while ( conc_c ) { conc_c = 0; counter = 0; donot1 = 0; for ( i = 1; i <= num_ed; i++ ) //num_ed { if ( edge_array[i].deleted || EdSameAsTwin ( i ) ) { continue; } if ( edge_array[i].length > 0 ) { counter++; } parc = edge_array[i].arcs; if ( !parc || parc->next ) { continue; } to_ed = parc->to_ed; bal_ed = getTwinEdge ( to_ed ); parc2 = edge_array[bal_ed].arcs; if ( bal_ed == to_ed || !parc2 || parc2->next ) { continue; } from_ed = i; if ( from_ed == to_ed || from_ed == bal_ed ) { continue; } if ( parc->multiplicity <= arcfilter ) { donot1++; continue; } //linear connection found conc_c++; linearUpdateConnection ( from_ed, to_ed, 0 ); allpathUpdateEdge ( from_ed, to_ed, 0, last ); bal_fe = getTwinEdge ( from_ed ); linearUpdateConnection ( bal_ed, bal_fe, 1 ); allpathUpdateEdge ( bal_ed, bal_fe, 1, last ); /* if(from_ed==6589||to_ed==6589) printf("%d <- %d (%d)\n",from_ed,to_ed,i); if(bal_fe==6589||bal_ed==6589) printf("%d <- %d (%d)\n",bal_fe,bal_ed,i); */ } fprintf ( stderr, "%d edge(s) concatenated in cycle %d.\n", conc_c, round++ ); if ( arcfilter ) { fprintf ( stderr, "%d edge(s) with weight %d were not linearized.\n", donot1, arcfilter ); } } } soapdenovo2-240+dfsg.orig/standardPregraph/loadGraph.c0000644000000000000000000003477712166703654021566 0ustar rootroot/* * loadGraph.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #define preARCBLOCKSIZE 100000 static unsigned int loadArcs ( char * graphfile ); static void loadContig ( char * graphfile ); static int maskRepeatByArc ( unsigned avg_weight ); /* void loadUpdatedVertex (char *graphfile) { char name[256], line[256]; FILE *fp; Kmer word, bal_word; int num_kmer, i; char ch; sprintf (name, "%s.updated.vertex", graphfile); fp = ckopen (name, "r"); while (fgets (line, sizeof (line), fp) != NULL) { if (line[0] == 'V') { sscanf (line + 6, "%d %c %d", &num_kmer, &ch, &overlaplen); printf ("there're %d kmers in vertex file\n", num_kmer); break; } } vt_array = (VERTEX *) ckalloc ((2 * num_kmer) * sizeof (VERTEX)); for (i = 0; i < num_kmer; i++) { fscanf (fp, "%llx ", &word); vt_array[i].kmer = word; } fclose (fp); for (i = 0; i < num_kmer; i++) { bal_word = reverseComplement (vt_array[i].kmer, overlaplen); vt_array[i + num_kmer].kmer = bal_word; } num_vt = num_kmer; }*/ int uniqueLenSearch ( unsigned int * len_array, unsigned int * flag_array, int num, unsigned int target ) { int mid, low, high; low = 1; high = num; while ( low <= high ) { mid = ( low + high ) / 2; if ( len_array[mid] == target ) { break; } else if ( target > len_array[mid] ) { low = mid + 1; } else { high = mid - 1; } } if ( low > high ) { return -1; } //locate the first same length unflaged return flag_array[mid]++; } int lengthSearch ( unsigned int * len_array, unsigned int * flag_array, int num, unsigned int target ) { int mid, low, high, i; low = 1; high = num; while ( low <= high ) { mid = ( low + high ) / 2; if ( len_array[mid] == target ) { break; } else if ( target > len_array[mid] ) { low = mid + 1; } else { high = mid - 1; } } if ( low > high ) { return -1; } //locate the first same length unflaged if ( !flag_array[mid] ) { for ( i = mid - 1; i > 0; i-- ) { if ( len_array[i] != len_array[mid] || flag_array[i] ) { break; } } flag_array[i + 1] = 1; return i + 1; } else { for ( i = mid + 1; i <= num; i++ ) { if ( !flag_array[i] ) { break; } } flag_array[i] = 1; return i; } } void quick_sort_int ( unsigned int * length_array, int low, int high ) { int i, j; unsigned int pivot; if ( low < high ) { pivot = length_array[low]; i = low; j = high; while ( i < j ) { while ( i < j && length_array[j] >= pivot ) { j--; } if ( i < j ) { length_array[i++] = length_array[j]; } while ( i < j && length_array[i] <= pivot ) { i++; } if ( i < j ) { length_array[j--] = length_array[i]; } } length_array[i] = pivot; quick_sort_int ( length_array, low, i - 1 ); quick_sort_int ( length_array, i + 1, high ); } } static int maskRepeatByArc ( unsigned avg_weight ) { unsigned int i, bal_i; int counter = 0; int arc_num; unsigned int arc_weight1, arc_weight2; preARC * arc; for ( i = 1; i <= num_ctg; ++i ) { if ( contig_array[i].mask == 1 ) { if ( isSmallerThanTwin ( i ) ) { ++i; } continue; } bal_i = getTwinCtg ( i ); arc = contig_array[bal_i].arcs; arc_weight1 = maxArcWeight ( arc ); arc = contig_array[i].arcs; arc_weight2 = maxArcWeight ( arc ); if ( arc_weight1 + arc_weight2 >= 4 * avg_weight ) { contig_array[i].mask = 1; contig_array[bal_i].mask = 1; if ( i == bal_i ) { counter += 1; } else { counter += 2; } } if ( isSmallerThanTwin ( i ) ) { ++i; } } return counter; } /************************************************* Function: loadUpdatedEdges Description: Loads contig information and masks some contigs according to setting. Input: 1. graphfile: prefix of graph file Output: None. Return: None. *************************************************/ void loadUpdatedEdges ( char * graphfile ) { char c, name[256], line[1024]; int bal_ed, cvg; FILE * fp, *out_fp; Kmer from_kmer, to_kmer; unsigned int num_ctgge, length, index = 0, num_kmer; unsigned int i = 0, j; int newIndex; unsigned int * length_array, *flag_array, diff_len; char * outfile = graphfile; long long cvgSum = 0; long long counter = 0; unsigned int avg_arc_wt; int ctg_short_cutoff; float high_cvg_cutoff1, high_cvg_cutoff2, low_cvg_cutoff; int cut_len; //get overlaplen from *.preGraphBasic sprintf ( name, "%s.preGraphBasic", graphfile ); fp = ckopen ( name, "r" ); while ( fgets ( line, sizeof ( line ), fp ) != NULL ) { if ( line[0] == 'V' ) { sscanf ( line + 6, "%d %c %d", &num_kmer, &c, &overlaplen ); fprintf ( stderr, "Kmer size: %d\n", overlaplen ); break; } } cut_len = COMPATIBLE_MODE == 0 ? overlaplen : 0; if ( ctg_short == 0 ) { ctg_short = overlaplen + 2; } ctg_short_cutoff = 2 * overlaplen + 2 < 100 ? 100 : 0; fclose ( fp ); sprintf ( name, "%s.updated.edge", graphfile ); fp = ckopen ( name, "r" ); sprintf ( name, "%s.newContigIndex", outfile ); out_fp = ckopen ( name, "w" ); while ( fgets ( line, sizeof ( line ), fp ) != NULL ) { if ( line[0] == 'E' ) { sscanf ( line + 5, "%d", &num_ctgge ); fprintf ( stderr, "There are %d edge(s) in edge file.\n", num_ctgge ); break; } } index_array = ( unsigned int * ) ckalloc ( ( num_ctgge + 1 ) * sizeof ( unsigned int ) ); length_array = ( unsigned int * ) ckalloc ( ( num_ctgge + 1 ) * sizeof ( unsigned int ) ); flag_array = ( unsigned int * ) ckalloc ( ( num_ctgge + 1 ) * sizeof ( unsigned int ) ); while ( fgets ( line, sizeof ( line ), fp ) != NULL ) { if ( line[0] == '>' ) { sscanf ( line + 7, "%d", &length ); index_array[++index] = length; length_array[++i] = length; } } num_ctg = index; orig2new = 1; qsort ( & ( length_array[1] ), num_ctg, sizeof ( length_array[0] ), cmp_int ); //extract unique length diff_len = 0; for ( i = 1; i <= num_ctg; i++ ) { for ( j = i + 1; j <= num_ctg; j++ ) if ( length_array[j] != length_array[i] ) { break; } length_array[++diff_len] = length_array[i]; flag_array[diff_len] = i; i = j - 1; } contig_array = ( CONTIG * ) ckalloc ( ( num_ctg + 1 ) * sizeof ( CONTIG ) ); //load edges index = 0; rewind ( fp ); while ( fgets ( line, sizeof ( line ), fp ) != NULL ) { if ( line[0] == '>' ) { sscanf ( line, ">length %u,%d,%d", &length, &bal_ed, &cvg ); newIndex = uniqueLenSearch ( length_array, flag_array, diff_len, length ); index_array[++index] = newIndex; if ( length != 0 ) { contig_array[newIndex].length = length - cut_len; } else { contig_array[newIndex].length = 0; } contig_array[newIndex].bal_edge = bal_ed + 1; contig_array[newIndex].downwardConnect = NULL; contig_array[newIndex].mask = 0; contig_array[newIndex].flag = 0; contig_array[newIndex].arcs = NULL; contig_array[newIndex].seq = NULL; contig_array[newIndex].multi = 0; contig_array[newIndex].inSubGraph = 0; contig_array[newIndex].bubbleInScaff = 0; contig_array[newIndex].cvg = cvg / 10; if ( cvg && length > 100 ) { counter += length - cut_len; cvgSum += cvg * ( length - cut_len ); } fprintf ( out_fp, "%d %d %d\n", index, newIndex, contig_array[newIndex].bal_edge ); } } if ( counter ) { cvgAvg = cvgSum / counter / 10 > 2 ? cvgSum / counter / 10 : 3; } //mark repeats int bal_i; if ( maskRep ) { high_cvg_cutoff1 = cvg_high * cvgAvg; high_cvg_cutoff2 = cvg_high * cvgAvg * 0.8; low_cvg_cutoff = cvg_low * cvgAvg; counter = 0; fprintf ( stderr, "Mask contigs with coverage lower than %.1f or higher than %.1f, and strict length %d.\n", low_cvg_cutoff, high_cvg_cutoff1, ctg_short_cutoff ); for ( i = 1; i <= num_ctg; i++ ) { bal_i = getTwinCtg ( i ); if ( ( contig_array[i].cvg + contig_array[bal_i].cvg ) > 2 * high_cvg_cutoff1 ) { contig_array[i].mask = 1; contig_array[bal_i].mask = 1; if ( i == bal_i ) { counter += 1; } else { counter += 2; } } else if ( contig_array[i].length < ctg_short_cutoff && ( contig_array[i].cvg > high_cvg_cutoff2 || contig_array[bal_i].cvg > high_cvg_cutoff2 || ( contig_array[i].cvg < low_cvg_cutoff && contig_array[bal_i].cvg < low_cvg_cutoff ) ) ) { contig_array[i].mask = 1; contig_array[bal_i].mask = 1; if ( i == bal_i ) { counter += 1; } else { counter += 2; } } else if ( cvgAvg < 50 && ( contig_array[i].cvg >= 63 || contig_array[bal_i].cvg >= 63 ) ) { contig_array[i].mask = 1; contig_array[bal_i].mask = 1; if ( i == bal_i ) { counter += 1; } else { counter += 2; } } if ( isSmallerThanTwin ( i ) ) { i++; } } fprintf ( stderr, "Average contig coverage is %d, %lld contig(s) masked.\n", cvgAvg, counter ); } counter = 0; for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].mask ) { continue; } bal_i = getTwinCtg ( i ); if ( contig_array[i].length < ctg_short ) { contig_array[i].mask = 1; contig_array[bal_i].mask = 1; if ( i == bal_i ) { counter += 1; } else { counter += 2; } } if ( isSmallerThanTwin ( i ) ) { i++; } } fprintf ( stderr, "Mask contigs shorter than %d, %lld contig(s) masked.\n", ctg_short, counter ); avg_arc_wt = loadArcs ( graphfile ); counter = 0; //counter = maskRepeatByArc(avg_arc_wt); //printf ("Mask contigs with multi arcs, %d contig masked\n", counter); //tipsCount(); loadContig ( graphfile ); fprintf ( stderr, "Done loading updated edges.\n" ); free ( ( void * ) length_array ); free ( ( void * ) flag_array ); fclose ( fp ); fclose ( out_fp ); } static void add1Arc ( unsigned int from_ed, unsigned int to_ed, unsigned int weight ) { preARC * parc; unsigned int from_c = index_array[from_ed]; unsigned int to_c = index_array[to_ed]; parc = allocatePreArc ( to_c ); parc->multiplicity = weight; parc->next = contig_array[from_c].arcs; contig_array[from_c].arcs = parc; } /************************************************* Function: loadArcs Description: Loads arc information of contigs and calculates the average weight of arcs. Input: 1. graphfile: prefix of graph file Output: None. Return: The average weight of arcs. *************************************************/ static unsigned int loadArcs ( char * graphfile ) { FILE * fp; char name[256], line[1024]; unsigned int target, weight; unsigned int from_ed; char * seg; unsigned int avg_weight = 0, weight_sum = 0, arc_num = 0; sprintf ( name, "%s.Arc", graphfile ); fp = ckopen ( name, "r" ); createPreArcMemManager (); arcCounter = 0; while ( fgets ( line, sizeof ( line ), fp ) != NULL ) { seg = strtok ( line, " " ); from_ed = atoi ( seg ); //printf("%d\n",from_ed); while ( ( seg = strtok ( NULL, " " ) ) != NULL ) { target = atoi ( seg ); seg = strtok ( NULL, " " ); weight = atoi ( seg ); add1Arc ( from_ed, target, weight ); if ( !contig_array[index_array[from_ed]].mask && !contig_array[index_array[target]].mask ) { weight_sum += weight; ++arc_num; } } } if ( arc_num ) { avg_weight = weight_sum / arc_num; } fprintf ( stderr, "%lld arc(s) loaded, average weight is %u.\n", arcCounter, avg_weight ); fclose ( fp ); return avg_weight; } /************************************************* Function: loadContig Description: Loads contigs sequence. Input: 1. graphfile: prefix of graph file Output: None. Return: None. *************************************************/ void loadContig ( char * graphfile ) { char c, name[256], line[1024], *tightSeq = NULL; FILE * fp; int n = 0, length, index = -1, edgeno; unsigned int i; unsigned int newIndex; sprintf ( name, "%s.contig", graphfile ); fp = ckopen ( name, "r" ); while ( fgets ( line, sizeof ( line ), fp ) != NULL ) { if ( line[0] == '>' ) { if ( index >= 0 ) { newIndex = index_array[edgeno]; contig_array[newIndex].seq = tightSeq; } n = 0; index++; sscanf ( line + 1, "%d %s %d", &edgeno, name, &length ); //printf("contig %d, length %d\n",edgeno,length); tightSeq = ( char * ) ckalloc ( ( length / 4 + 1 ) * sizeof ( char ) ); } else { for ( i = 0; i < strlen ( line ); i++ ) { if ( line[i] >= 'a' && line[i] <= 'z' ) { c = base2int ( line[i] - 'a' + 'A' ); writeChar2tightString ( c, tightSeq, n++ ); } else if ( line[i] >= 'A' && line[i] <= 'Z' ) { c = base2int ( line[i] ); writeChar2tightString ( c, tightSeq, n++ ); } } } } if ( index >= 0 ) { newIndex = index_array[edgeno]; contig_array[newIndex].seq = tightSeq; } fprintf ( stderr, "%d contig(s) loaded.\n", index + 1 ); fclose ( fp ); //printf("the %dth contig with index 107\n",index); } void freeContig_array () { if ( !contig_array ) { return; } unsigned int i; for ( i = 1; i <= num_ctg; i++ ) { if ( contig_array[i].seq ) { free ( ( void * ) contig_array[i].seq ); } if ( contig_array[i].closeReads ) { freeStack ( contig_array[i].closeReads ); } } free ( ( void * ) contig_array ); contig_array = NULL; } /* void loadCvg(char *graphfile) { char name[256],line[1024]; FILE *fp; int cvg; unsigned int newIndex,edgeno,bal_ctg; sprintf(name,"%s.contigCVG",graphfile); fp = fopen(name,"r"); if(!fp){ printf("contig coverage file %s is not found!\n",name); return; } while(fgets(line,sizeof(line),fp)!=NULL){ if(line[0]=='>'){ sscanf(line+1,"%d %d",&edgeno,&cvg); newIndex = index_array[edgeno]; cvg = cvg <= 255 ? cvg:255; contig_array[newIndex].multi = cvg; bal_ctg = getTwinCtg(newIndex); contig_array[bal_ctg].multi= cvg; } } fclose(fp); } */ soapdenovo2-240+dfsg.orig/standardPregraph/output_contig.c0000644000000000000000000002143112166703654022547 0ustar rootroot/* * output_contig.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" static char * kmerSeq; static unsigned int * flag_array; void output_graph ( char * outfile ) { char name[256]; FILE * fp; unsigned int i, bal_i; sprintf ( name, "%s.edge.gvz", outfile ); fp = ckopen ( name, "w" ); fprintf ( fp, "digraph G{\n" ); fprintf ( fp, "\tsize=\"512,512\";\n" ); for ( i = num_ed; i > 0; i-- ) { if ( edge_array[i].deleted ) { continue; } /* arcCount(i,&arcNum); if(arcNum<1) continue; */ bal_i = getTwinEdge ( i ); /* arcCount(bal_i,&arcNum); if(arcNum<1) continue; */ fprintf ( fp, "\tV%d -> V%d[label =\"%d(%d)\"];\n", edge_array[i].from_vt, edge_array[i].to_vt, i, edge_array[i].length ); } fprintf ( fp, "}\n" ); fclose ( fp ); } static void output_1contig ( int id, EDGE * edge, FILE * fp, boolean tip ) { int i; Kmer kmer; fprintf ( fp, ">%d length %d cvg_%.1f_tip_%d\n", id, edge->length + overlaplen, ( double ) edge->cvg / 10, tip ); //fprintf(fp,">%d\n",id); kmer = vt_array[edge->from_vt].kmer; printKmerSeq ( fp, kmer ); for ( i = 0; i < edge->length; i++ ) { fprintf ( fp, "%c", int2base ( ( int ) getCharInTightString ( edge->seq, i ) ) ); if ( ( i + overlaplen + 1 ) % 100 == 0 ) { fprintf ( fp, "\n" ); } } if ( ( edge->length + overlaplen ) % 100 != 0 ) { fprintf ( fp, "\n" ); } } int cmp_int ( const void * a, const void * b ) { int * A, *B; A = ( int * ) a; B = ( int * ) b; if ( *A > *B ) { return 1; } else if ( *A == *B ) { return 0; } else { return -1; } } int cmp_edge ( const void * a, const void * b ) { EDGE * A, *B; A = ( EDGE * ) a; B = ( EDGE * ) b; if ( A->length > B->length ) { return 1; } else if ( A->length == B->length ) { return 0; } else { return -1; } } /************************************************* Function: output_contig Description: 1. Sorts the edges by the length. 2. Makes statistic of the contig. 3. Outputs the info of the contig. Input: 1. ed_array: edges array 2. ed_num: the count of the edge 3. outfile: the output file prefix 4. cut_len: cutoff length Output: None. Return: None. *************************************************/ void output_contig ( EDGE * ed_array, unsigned int ed_num, char * outfile, int cut_len ) { char temp[256]; FILE * fp, *fp_contig; int flag, count, len_c; int signI; unsigned int i, j, diff_len = 0; long long sum = 0, N90, N50; unsigned int * length_array; boolean tip; sprintf ( temp, "%s.contig", outfile ); fp = ckopen ( temp, "w" ); unsigned int * all_length_arr = ( unsigned int * ) ckalloc ( ( ed_num + 1 ) * sizeof ( unsigned int ) ); index_array = ( unsigned int * ) ckalloc ( ( ed_num + 1 ) * sizeof ( unsigned int ) ); flag_array = ( unsigned int * ) ckalloc ( ( ed_num + 1 ) * sizeof ( unsigned int ) ); for ( i = 1; i <= ed_num; ++i ) { index_array[i] = ed_array[i].length; all_length_arr[i] = ed_array[i].length; } qsort ( &all_length_arr[1], ed_num, sizeof ( all_length_arr[0] ), cmp_int ); for ( i = 1; i <= ed_num; ++i ) { for ( j = i + 1; j <= ed_num; ++j ) { if ( all_length_arr[i] != all_length_arr[j] ) { break; } } all_length_arr[++diff_len] = all_length_arr[i]; flag_array[diff_len] = i; i = j - 1; } for ( i = 1; i <= ed_num; ++i ) { index_array[i] = uniqueLenSearch ( all_length_arr, flag_array, diff_len, index_array[i] ); } for ( i = 1; i <= ed_num; ++i ) { flag_array[index_array[i]] = i; } free ( ( void * ) all_length_arr ); length_array = ( unsigned int * ) ckalloc ( ed_num * sizeof ( unsigned int ) ); kmerSeq = ( char * ) ckalloc ( overlaplen * sizeof ( char ) ); //first scan for number counting count = len_c = 0; for ( i = 1; i <= ed_num; i++ ) { if ( ( ed_array[i].length + overlaplen ) >= len_bar ) { length_array[len_c++] = ed_array[i].length + overlaplen; } if ( ed_array[i].length < 1 || ed_array[i].deleted ) { continue; } count++; if ( EdSmallerThanTwin ( i ) ) { i++; } } sum = 0; for ( signI = len_c - 1; signI >= 0; signI-- ) { sum += length_array[signI]; } qsort ( length_array, len_c, sizeof ( length_array[0] ), cmp_int ); if ( len_c > 0 ) { fprintf ( stderr, "\nThere are %d contig(s) longer than %d, sum up %lld bp, with average length %lld.\n", len_c, len_bar, sum, sum / len_c ); fprintf ( stderr, "The longest length is %d bp, ", length_array[len_c - 1] ); } else { fprintf ( stderr, "No contig was constructed!\n" ); } N50 = sum * 0.5; N90 = sum * 0.9; sum = flag = 0; for ( signI = len_c - 1; signI >= 0; signI-- ) { sum += length_array[signI]; if ( !flag && sum >= N50 ) { fprintf ( stderr, "contig N50 is %d bp,", length_array[signI] ); flag = 1; } if ( sum >= N90 ) { fprintf ( stderr, "contig N90 is %d bp.\n", length_array[signI] ); break; } } for ( i = 1; i <= ed_num; i++ ) { j = flag_array[i]; if ( ed_array[j].deleted || ed_array[j].length < 1 ) { continue; } if ( ed_array[j].arcs && ed_array[getTwinEdge ( j )].arcs ) { tip = 0; } else { tip = 1; } output_1contig ( i, & ( ed_array[j] ), fp, tip ); if ( EdSmallerThanTwin ( j ) ) { i++; } } fclose ( fp ); free ( ( void * ) kmerSeq ); free ( ( void * ) length_array ); fprintf ( stderr, "%d contig(s) longer than %d output.\n", count, cut_len ); sprintf ( temp, "%s.ContigIndex", outfile ); fp_contig = ckopen ( temp, "w" ); fprintf ( fp_contig, "Edge_num %d %d\n", ed_num, count ); fprintf ( fp_contig, "index\tlength\treverseComplement\n" ); for ( i = 1; i <= num_ed; i++ ) { j = flag_array[i]; fprintf ( fp_contig, "%d\t%d\t", i, edge_array[j].length + overlaplen ); if ( EdSmallerThanTwin ( j ) ) { fprintf ( fp_contig, "1\n" ); ++i; } else if ( EdLargerThanTwin ( j ) ) { fprintf ( fp_contig, "-1\n" ); } else { fprintf ( fp_contig, "0\n" ); } } fclose ( fp_contig ); } /************************************************* Function: output_updated_edges Description: Outputs the info of the edges. Input: 1. outfile: the output file prefix Output: None. Return: None. *************************************************/ void output_updated_edges ( char * outfile ) { FILE * fp; char name[256]; unsigned int i, j, validCounter = 0; EDGE * edge; sprintf ( name, "%s.updated.edge", outfile ); fp = ckopen ( name, "w" ); for ( i = 1; i <= num_ed; i++ ) { validCounter++; } fprintf ( fp, "EDGEs %d\n", validCounter ); validCounter = 0; for ( i = 1; i <= num_ed; i++ ) { j = flag_array[i]; edge = &edge_array[j]; if ( edge->length != 0 ) { fprintf ( fp, ">length %d,", edge->length + overlaplen ); } else { fprintf ( fp, ">length %d,", edge->length ); } if ( EdSmallerThanTwin ( j ) ) { fprintf ( fp, "1," ); } else if ( EdLargerThanTwin ( j ) ) { fprintf ( fp, "-1," ); } else { fprintf ( fp, "0," ); } fprintf ( fp, "%d,", edge->cvg ); print_kmer ( fp, vt_array[edge->from_vt].kmer, ',' ); print_kmer ( fp, vt_array[edge->to_vt].kmer, ',' ); fprintf ( fp, "\n" ); } fclose ( fp ); } /************************************************* Function: output_heavyArcs Description: Outputs the info of arcs. Input: 1. outfile: the output file prefix Output: None. Return: None. *************************************************/ void output_heavyArcs ( char * outfile ) { unsigned int i, j; char name[256]; FILE * outfp; ARC * parc; sprintf ( name, "%s.Arc", outfile ); outfp = ckopen ( name, "w" ); for ( i = 1; i <= num_ed; i++ ) { parc = edge_array[flag_array[i]].arcs; if ( !parc ) { continue; } j = 0; fprintf ( outfp, "%u", i ); while ( parc ) { fprintf ( outfp, " %u %u", index_array[parc->to_ed], parc->multiplicity ); if ( ( ++j ) % 10 == 0 ) { fprintf ( outfp, "\n%u", i ); } parc = parc->next; } fprintf ( outfp, "\n" ); } fclose ( outfp ); free ( ( void * ) index_array ); free ( ( void * ) flag_array ); } soapdenovo2-240+dfsg.orig/standardPregraph/arc.c0000644000000000000000000001562312166703654020417 0ustar rootroot/* * arc.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #define preARCBLOCKSIZE 100000 void createPreArcMemManager () { prearc_mem_manager = createMem_manager ( preARCBLOCKSIZE, sizeof ( preARC ) ); } void prlDestroyPreArcMem () { if ( !preArc_mem_managers ) { return; } int i; for ( i = 0; i < thrd_num; i++ ) { freeMem_manager ( preArc_mem_managers[i] ); } free ( ( void * ) preArc_mem_managers ); preArc_mem_managers = NULL; } void destroyPreArcMem () { freeMem_manager ( prearc_mem_manager ); prearc_mem_manager = NULL; } preARC * prlAllocatePreArc ( unsigned int edgeid, MEM_MANAGER * manager ) { preARC * newArc; newArc = ( preARC * ) getItem ( manager ); newArc->to_ed = edgeid; newArc->multiplicity = 1; newArc->next = NULL; return newArc; } preARC * allocatePreArc ( unsigned int edgeid ) { arcCounter++; preARC * newArc; newArc = ( preARC * ) getItem ( prearc_mem_manager ); newArc->to_ed = edgeid; newArc->multiplicity = 1; newArc->next = NULL; return newArc; } void output_arcGVZ ( char * outfile, boolean IsContig ) { ARC * pArc; preARC * pPreArc; char name[256]; FILE * fp; unsigned int i; sprintf ( name, "%s.arc.gvz", outfile ); fp = ckopen ( name, "w" ); fprintf ( fp, "digraph G{\n" ); fprintf ( fp, "\tsize=\"512,512\";\n" ); for ( i = 1; i <= num_ed; i++ ) { if ( IsContig ) { pPreArc = contig_array[i].arcs; while ( pPreArc ) { fprintf ( fp, "\tC%d -> C%d[label =\"%d\"];\n", i, pPreArc->to_ed, pPreArc->multiplicity ); pPreArc = pPreArc->next; } } else { pArc = edge_array[i].arcs; while ( pArc ) { fprintf ( fp, "\tC%d -> C%d[label =\"%d\"];\n", i, pArc->to_ed, pArc->multiplicity ); pArc = pArc->next; } } } fprintf ( fp, "}\n" ); fclose ( fp ); } /**************** below this line all codes are about ARC ****************/ #define ARCBLOCKSIZE 100000 void createArcMemo () { if ( !arc_mem_manager ) { arc_mem_manager = createMem_manager ( ARCBLOCKSIZE, sizeof ( ARC ) ); } else { fprintf ( stderr, "Warning from createArcMemo: arc_mem_manager is a active pointer.\n" ); } } void destroyArcMem () { freeMem_manager ( arc_mem_manager ); arc_mem_manager = NULL; } ARC * allocateArc ( unsigned int edgeid ) { arcCounter++; ARC * newArc; newArc = ( ARC * ) getItem ( arc_mem_manager ); newArc->to_ed = edgeid; newArc->multiplicity = 1; newArc->prev = NULL; newArc->next = NULL; return newArc; } void dismissArc ( ARC * arc ) { returnItem ( arc_mem_manager, arc ); } /***************** below this line all codes are about lookup table *****************/ void createArcLookupTable () { if ( !arcLookupTable ) { arcLookupTable = ( ARC ** ) ckalloc ( ( 3 * num_ed + 1 ) * sizeof ( ARC * ) ); } } void deleteArcLookupTable () { if ( arcLookupTable ) { free ( ( void * ) arcLookupTable ); arcLookupTable = NULL; } } void putArc2LookupTable ( unsigned int from_ed, ARC * arc ) { if ( !arc || !arcLookupTable ) { return; } unsigned int index = 2 * from_ed + arc->to_ed; arc->nextInLookupTable = arcLookupTable[index]; arcLookupTable[index] = arc; } static ARC * getArcInLookupTable ( unsigned int from_ed, unsigned int to_ed ) { unsigned int index = 2 * from_ed + to_ed; ARC * ite_arc = arcLookupTable[index]; while ( ite_arc ) { if ( ite_arc->to_ed == to_ed ) { return ite_arc; } ite_arc = ite_arc->nextInLookupTable; } return NULL; } void removeArcInLookupTable ( unsigned int from_ed, unsigned int to_ed ) { unsigned int index = 2 * from_ed + to_ed; ARC * ite_arc = arcLookupTable[index]; ARC * arc; if ( !ite_arc ) { fprintf ( stderr, "RemoveArcInLookupTable: not found A.\n" ); return; } if ( ite_arc->to_ed == to_ed ) { arcLookupTable[index] = ite_arc->nextInLookupTable; return; } while ( ite_arc->nextInLookupTable && ite_arc->nextInLookupTable->to_ed != to_ed ) { ite_arc = ite_arc->nextInLookupTable; } if ( ite_arc->nextInLookupTable ) { arc = ite_arc->nextInLookupTable; ite_arc->nextInLookupTable = arc->nextInLookupTable; return; } fprintf ( stderr, "RemoveArcInLookupTable: not found B.\n" ); return; } void recordArcsInLookupTable () { unsigned int i; ARC * ite_arc; for ( i = 1; i <= num_ed; i++ ) { ite_arc = edge_array[i].arcs; while ( ite_arc ) { putArc2LookupTable ( i, ite_arc ); ite_arc = ite_arc->next; } } } /************************************************* Function: getArcBetween Description: Gets the arc between the edge "from_ed" and the edge "to_ed", then return it. Input: 1. from_ed: the origin edge 2. to_ed: the destination edge Output: None. Return: The arc between the edge "from_ed" and the edge "to_ed". *************************************************/ ARC * getArcBetween ( unsigned int from_ed, unsigned int to_ed ) { ARC * parc; if ( arcLookupTable ) { parc = getArcInLookupTable ( from_ed, to_ed ); return parc; } parc = edge_array[from_ed].arcs; while ( parc ) { if ( parc->to_ed == to_ed ) { return parc; } parc = parc->next; } return parc; } /************************************************* Function: validArcCount Description: Compute the count of the valid arc, whose weight is larger than "cutoff", then return it. Input: 1. arc: the head of the "preARC" linked list 2. cutoff: the minimum requirement for the weight of the valid arc Output: None. Return: The number of the valid arc. *************************************************/ int validArcCount ( preARC * arc, int cutoff ) { int arc_num = 0; while ( arc ) { if ( arc->multiplicity >= cutoff ) { ++arc_num; } arc = arc->next; } return arc_num; } /************************************************* Function: maxArcWeight Description: Gets the maximum weight in all arcs, then return it. Input: 1. arc: the head of the "preARC" linked list Output: None. Return: The maximum weight. *************************************************/ unsigned int maxArcWeight ( preARC * arc ) { unsigned int max = 0; while ( arc ) { if ( arc->multiplicity > max ) { max = arc->multiplicity; } arc = arc->next; } return max; } soapdenovo2-240+dfsg.orig/standardPregraph/output_pregraph.c0000644000000000000000000000507012166703654023075 0ustar rootroot/* * 31mer/output_pregraph.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include #include "newhash.h" #include "kmerhash.h" #include #include static int outvCounter = 0; //after this LINKFLAGFILTER in the Kmer is destroyed static void output1vt ( kmer_t * node1, FILE * fp ) { if ( !node1 ) { return; } if ( ! ( node1->linear ) && ! ( node1->deleted ) ) { outvCounter++; print_kmer ( fp, node1->seq, ' ' ); if ( outvCounter % 8 == 0 ) { fprintf ( fp, "\n" ); } } } void output_vertex ( char * outfile ) { char temp[256]; FILE * fp; int i; kmer_t * node; KmerSet * set; sprintf ( temp, "%s.vertex", outfile ); fp = ckopen ( temp, "w" ); for ( i = 0; i < thrd_num; i++ ) { set = KmerSets[i]; set->iter_ptr = 0; while ( set->iter_ptr < set->size ) { if ( !is_kmer_entity_null ( set->flags, set->iter_ptr ) ) { node = set->array + set->iter_ptr; output1vt ( node, fp ); } set->iter_ptr++; } } fprintf ( fp, "\n" ); fprintf ( stderr, "%d vertex(es) output.\n", outvCounter ); fclose ( fp ); sprintf ( temp, "%s.preGraphBasic", outfile ); fp = ckopen ( temp, "w" ); fprintf ( fp, "VERTEX %d K %d\n", outvCounter, overlaplen ); fprintf ( fp, "\nEDGEs %d\n", num_ed ); fprintf ( fp, "\nMaxReadLen %d MinReadLen %d MaxNameLen %d\n", maxReadLen4all, minReadLen, maxNameLen ); fclose ( fp ); } void output_1edge ( preEDGE * edge, gzFile * fp ) { int i; gzprintf ( fp, ">length %d,", edge->length ); print_kmer_gz ( fp, edge->from_node, ',' ); print_kmer_gz ( fp, edge->to_node, ',' ); gzprintf ( fp, "cvg %d, %d\n", edge->cvg, edge->bal_edge ); for ( i = 0; i < edge->length; i++ ) { gzprintf ( fp, "%c", int2base ( ( int ) edge->seq[i] ) ); if ( ( i + 1 ) % 100 == 0 ) { gzprintf ( fp, "\n" ); } } if ( edge->length % 100 != 0 ) { gzprintf ( fp, "\n" ); } } soapdenovo2-240+dfsg.orig/standardPregraph/change.log0000644000000000000000000011021012166703654021422 0ustar rootroot####################### 2012-00-00 Purpose: a) Details: 1) main.c::fun() a) ####################### 2012-00-00 Purpose: a)fix bug for map, zombie process cause by fclose Details: 1) readseq1by1.c::openFile4read() a)delete these lines #if defined(SIGCHLD) signal(SIGCHLD,SIG_IGN); #elif defined(SIGCLD) signal(SIGCLD,SIG_IGN); #endif b) || ((lib_array[i].curr_type == 1) && feof (lib_array[i].fp1) && feof (lib_array[i].fp2)) || ((lib_array[i].curr_type != 1) && (lib_array[i].curr_type != 4) && feof (lib_array[i].fp1))) --> || ((lib_array[i].curr_type == 1 || lib_array[i].curr_type == 2) && feof (lib_array[i].fp1) && feof (lib_array[i].fp2)) || ((lib_array[i].curr_type != 1 && lib_array[i].curr_type != 2) && (lib_array[i].curr_type != 4) && feof (lib_array[i].fp1))) 2012-07-31 Purpose: a) fix bug for map, zombie process cause by fclose Details: 1) readseq1by1.c::openFile4read() a) sprintf (cmd, "gzip -dc %s", fname); fp = popen (cmd, "r"); free (cmd); return fp; --> sprintf (cmd, "gzip -dc %s", fname); fp = popen (cmd, "r"); #if defined(SIGCHLD) signal(SIGCHLD,SIG_IGN); #elif defined(SIGCLD) signal(SIGCLD,SIG_IGN); #endif free (cmd); return fp; 2012-07-13 Purpose: a) fix bugs for output, delete the empty line of the output(*.edge.gz, *.contig, *.scafSeq) Details: 1) concatenateEdge.c::printEdgeSeq() a) if ((i + overlaplen + 1) % 100 == 0) --> if ((i + overlaplen + 1) % 100 == 0 && i < len - 1) 2) iterate.c::output_1contig() a) if ((i + overlaplen + 1) % 100 == 0) --> if ((i + overlaplen + 1) % 100 == 0 && i < edge->length - 1) 3) output_contig.c::output_1contig() a) if ((i + overlaplen + 1) % 100 == 0) --> if ((i + overlaplen + 1) % 100 == 0 && i < edge->length - 1) 4) output_pregraph.c::output_1edge() a) if ((i + 1) % 100 == 0) --> if ((i + 1) % 100 == 0 && i < edge->length - 1) 5) seq.c::printTightString() a) if ((i + 1) % 100 == 0) --> if ((i + 1) % 100 == 0 && i < len - 1) 6) prlReadFillGap.c a)outputTightStr2Visual() if ((++column) % 100 == 0) --> if ((++column) % 100 == 0 && i < end - 1) if ((++column) % 100 == 0) --> if ((++column) % 100 == 0 && i < length - 1 - start) b)outputTightStrLowerCase2Visual() if ((++column) % 100 == 0) --> if ((++column) % 100 == 0 && i < end - 1) c)outputScafSeq() fprintf (fo, "\n"); --> if(column % 100 != 0) fprintf (fo, "\n"); if(i != 0 && i % 100 == 0) fprintf(fo3, "\n"); --> if(i != 0 && i % 100 == 0 && i < ctg_start_pos - 1) fprintf(fo3, "\n"); if(i != 0 && i % 100 == 0) fprintf(fo3, "\n"); --> if(i != 0 && i % 100 == 0 && i < ctg_start_pos - 1) fprintf(fo3, "\n"); d)output_ctg() fprintf (fo, "\n"); --> if(len % 100 != 0) fprintf (fo, "\n"); e)output1gap() fprintf (fo, "\n"); --> if(column % 100 != 0) fprintf (fo, "\n"); 2012-07-13 Purpose: a) fix bugs for removeWeakEdges Details: 1) cutTip_graph.c::removeWeakEdges() a) for (i = 1; i <= num_ed; i++) { if (edge_array[i].deleted || edge_array[i].length == 0 || edge_array[i].length > lenCutoff || EdSameAsTwin (i)) { continue; } bal_ed = getTwinEdge (i); arcRight = arcCount (i, &arcRight_n); if (arcRight_n > 1 || !arcRight || arcRight->multiplicity > multiCutoff) { continue; } arcLeft = arcCount (bal_ed, &arcLeft_n); if (arcLeft_n > 1 || !arcLeft || arcLeft->multiplicity > multiCutoff) { continue; } destroyEdge (i); counter++; } --> while(counter) { counter = 0; for (i = 1; i <= num_ed; i++) { if (edge_array[i].deleted || edge_array[i].length == 0 || edge_array[i].length > lenCutoff || EdSameAsTwin (i)) { continue; } bal_ed = getTwinEdge (i); arcRight = arcCount (i, &arcRight_n); if (arcRight_n > 1 || !arcRight || arcRight->multiplicity > multiCutoff) { continue; } arcLeft = arcCount (bal_ed, &arcLeft_n); if (arcLeft_n > 1 || !arcLeft || arcLeft->multiplicity > multiCutoff) { continue; } destroyEdge (i); counter++; } fprintf (stderr,"%d weak inner edges are destroyed.\n", counter); } 2012-07-13 Purpose: a) Make the output of SOAPdevovo the same when using different threads. Details: 1) contig.c::call_heavygraph() a) if (repeatSolve) { ret = loadPathBin (graphfile); } --> if (repeatSolve) { ret = loadPathBin (graphfile); } swapedge(); sortedge(); freshArc(); 2012-07-13 Purpose: a) fix bugs for merge_linearV2, get the correct coverage of edge, l_links maybe change in the original process Details: 1)node2edge.c:merge_linearV2() a) while (nStack->item_c > 1) { temp = (KMER_PT *) stackPop (nStack); del_node = temp->node; del_node->inEdge = 1; symbol += get_kmer_left_covs (*del_node); if (temp->isSmaller) { del_node->l_links = edge_c; del_node->twin = (unsigned char) (bal_edge + 1); } else { del_node->l_links = edge_c + bal_edge; del_node->twin = (unsigned char) (-bal_edge + 1); } tightSeq[char_index--] = lastCharInKmer (temp->kmer); } --> while (nStack->item_c > 1) { temp = (KMER_PT *) stackPop (nStack); del_node = temp->node; del_node->inEdge = 1; symbol += get_kmer_left_covs (*del_node); tightSeq[char_index--] = lastCharInKmer (temp->kmer); } stackRecover(nStack); temp = (KMER_PT *) stackPop (nStack); while(nStack->item_c > 1) { temp = (KMER_PT *) stackPop (nStack); del_node = temp->node; del_node->inEdge = 1; if (temp->isSmaller) { del_node->l_links = edge_c; del_node->twin = (unsigned char) (bal_edge + 1); } else { del_node->l_links = edge_c + bal_edge; del_node->twin = (unsigned char) (-bal_edge + 1); } } 2012-07-13 Purpose: a) fix bugs for removeMinorTips Details: 1)cutTipPreGraph.c:removeMinorTips () a) for (i = 0; i < thrd_num; i++) { set = KmerSets[i]; flag = 1; while (flag) { flag = 0; set->iter_ptr = 0; while (set->iter_ptr < set->size) { if (!is_kmer_entity_null (set->flags, set->iter_ptr)) { rs = set->array + set->iter_ptr; flag += clipTipFromNode (rs, cut_len_tip, 0); } set->iter_ptr++; } } fprintf (stderr,"Remove minor tips in kmer set %d is done.\n", i); } --> while (flag) { flag = 0; for (i = 0; i < thrd_num; i++) { set = KmerSets[i]; set->iter_ptr = 0; while (set->iter_ptr < set->size) { if (!is_kmer_entity_null (set->flags, set->iter_ptr)) { rs = set->array + set->iter_ptr; if (!rs->linear && !rs->deleted) { flag += clipTipFromNode (rs, cut_len_tip, 0); } } set->iter_ptr++; } } fprintf (stderr,"Remove minor tips in kmer set is done(round %d).\n", round++); } 2012-07-13 Purpose: a) merge 63mer and 127mer version Details: 1) Use #define MER127 to define 127mer version 2) Use #define MER63 to define 63mer version 2012-02-15 Purpose: a) fix bugs of AIORead in reading fastq file which has "@" at the beginning of qulity line. Edited by panqi. Details: 1) prlHashReads.c::AIORead() a) if((curr_type == 2) || (curr_type == 6)) { for (i = get - 1; (temp[i] != '@') || (temp[i-1] != '\n') || (temp[i-2] == '+')|| (temp[i-3] == '/'); i--); for (i2 = i - 2; temp[i2] != '\n'; i2--); if (temp[i2 + 1] == '+') { for(i3 = i2 - 1; temp[i3] != '\n'; i3--); for(i2 = i3 - 1; temp[i2] != '\n'; i2--); if(temp[i2 + 1] == '@') {i = i2 + 1;} } } --> int num; if((curr_type == 2) || (curr_type == 6)) { num = 0; for (i = get - 1; (temp[i] != '@') || (temp[i-1] != '\n'); i--) { if(temp[i] == '\n') {num++;} } if (num <= 1) { for (i2 = i - 2; temp[i2] != '\n'; i2--); if (temp[i2 + 1] == '+') { for(i2 = i2 - 1; temp[i2] != '\n'; i2--); if(temp[i2 + 1] != '+') {for (i = i2 - 1; (temp[i] != '@') || (temp[i-1] != '\n'); i--);} } } } 2012-02-14 Purpose: a) seperate codes related to visualization from other codes. Edited by panqi. Details: 1) prlReadFillGap.c codes related to visualization Purpose: a) fix bugs of AIORead in reading fastq file which has "@" at the beginning of qulity line. Edited by panqi. Details: 1) prlHashReads.c::AIORead() a) if((curr_type == 2) || (curr_type == 6)) for (i = get - 1; (temp[i] != '@') || (temp[i-1] != '\n') || (temp[i-2] == '+')|| (temp[i-3] == '/'); i--); else if((curr_type == 1) || (curr_type == 3) ||(curr_type == 5)) for (i = get - 1; temp[i] != '>';i--) ; --> if((curr_type == 2) || (curr_type == 6)) { for (i = get - 1; (temp[i] != '@') || (temp[i-1] != '\n') || (temp[i-2] == '+')|| (temp[i-3] == '/'); i--); for (i2 = i - 2; temp[i2] != '\n'; i2--); if (temp[i2 + 1] == '+') { for(i3 = i2 - 1; temp[i3] != '\n'; i3--); for(i2 = i3 - 1; temp[i2] != '\n'; i2--); if(temp[i2 + 1] == '@') {i = i2 + 1;} } } else if((curr_type == 1) || (curr_type == 3) ||(curr_type == 5) for (i = get - 1; temp[i] != '>';i--) ; Purpose: a) fix bug of AIORead to deal with the case that read length is shorter than Kmer size. Edited by panqi. Details: 1) prlHashReads.c::prlRead2HashTable() a) while (start1 < offset1 || start2 < offset2) { if (turn == 1) { turn = 2; readseqInLib (seqBuffer[read_c], next_name, &(lenBuffer[read_c]), readBuffer1, &start1, offset1, libNo); if ((++i) % 100000000 == 0) printf ("--- %lldth reads\n", i); if (lenBuffer[read_c] < 0) printf ("read len %d\n", lenBuffer[read_c]); if (lenBuffer[read_c] < overlaplen + 1) continue; ...... } if (turn == 2) { turn = 1; readseqInLib (seqBuffer[read_c], next_name, &(lenBuffer[read_c]), readBuffer2, &start2, offset2, libNo); if ((++i) % 100000000 == 0) printf ("--- %lldth reads\n", i); if (lenBuffer[read_c] < 0) printf ("read len %d\n", lenBuffer[read_c]); if (lenBuffer[read_c] < overlaplen + 1) continue; ...... } } --> while (start1 < offset1 || start2 < offset2) { if (turn == 1) { turn = 2; readseqInLib (seqBuffer[read_c], next_name, &(lenBuffer[read_c]), readBuffer1, &start1, offset1, libNo); if ((++i) % 100000000 == 0) printf ("--- %lldth reads\n", i); if (lenBuffer[read_c] < 0) printf ("read len %d\n", lenBuffer[read_c]); if (lenBuffer[read_c] < overlaplen + 1) { if(start1>=offset1) { start1=0; flag1=AIORead (&aio1, &offset1, readBuffer1, cach1, &rt1, lib_array[libNo].curr_type); } continue; } } if (turn == 2) { turn = 1; readseqInLib (seqBuffer[read_c], next_name, &(lenBuffer[read_c]), readBuffer2, &start2, offset2, libNo); if ((++i) % 100000000 == 0) printf ("--- %lldth reads\n", i); if (lenBuffer[read_c] < 0) printf ("read len %d\n", lenBuffer[read_c]); if (lenBuffer[read_c] < overlaplen + 1) { if((flag2 == 2) && (start2 >= offset2)) break; if(start2 >= offset2) { start2=0; flag2 = AIORead (&aio2, &offset2, readBuffer2, cach2, &rt2, lib_array[libNo].curr_type); } continue; } } } 2012-01-09 Purpose: a) add a parameter "-V" so that some information for visualization can be output by setting this parameter. Edited by panqi. Details: a) prlReadFillGap.c codes related to visualization 2011-12-16 Purpose: a) Fix a bug of scaffolding which may lead to segmentation fault or endless loop Details: 1) Function: orderContig.c::linearC2C() a) new: if (usCtgCounter != oldsize) { unsigned int prev_c2 = upstreamCTG[usCtgCounter+1]; unsigned int bal_prev_c2 = getTwinCtg (prev_c2); setConnectMask (bal_prev_c2, c2, 1); setConnectMask (bal_prev_c2, c2, 0); int i = usCtgCounter+1; for ( ; i <= oldsize; i++) { contig_array[upstreamCTG[i]].from_vt = prev_c2; contig_array[getTwinCtg(upstreamCTG[i])].to_vt = bal_prev_c2; } if ((cn_temp = getCntBetween(c1,c2)) != NULL) { setConnectMask (c1, c2, 0); setConnectDelete (c1, c2, 0, 0); return 1; } } 2011-11-08 Purpose: a) Change default value of '-b' from 0 to 1.5. Update relative statements. b) Change default value of '-B' from 0 to 0.6. Update relative statements. c) Update some code so it can read '*.readInGap' and '*.readOnContig' produced by V1.05. Details: 1) Variant: inc/globe.h a) float cvg4SNP = 0.0; --> float cvg4SNP = 0.6; b) float ins_var_idx=0; --> float ins_var_idx=1.5 2) Function: scaffold.c::display_scaff_usage() a) printf ("\nscaff -g inputGraph [-F -m -u -S -w] [-G gapLenDiff -L minContigLen -c minContigCvg -C maxContigCvg -b insertSizeUpperBound -N genomeSize -p n_cpu]\n"); --> printf ("\nscaff -g inputGraph [-F -m -u -S -w] [-G gapLenDiff -L minContigLen -c minContigCvg -C maxContigCvg -b insertSizeUpperBound -B bubbleCoverage -N genomeSize -p n_cpu]\n"); b) printf (" -b \tinsertSizeUpperBound: (b*avg_ins) will be used as upper bound of insert size for long insert size ( > 1000) when handling pair-end connections between contigs if b is set to larger than 1, [0]\n"); --> printf (" -b \tinsertSizeUpperBound: (b*avg_ins) will be used as upper bound of insert size for long insert size ( > 1000) when handling pair-end connections between contigs if b is set to larger than 1, [1.5]\n"); c) printf (" -B \tbubbleCoverage: remove contig with lower cvoerage in bubble structure if both contigs' coverage are smaller than bubbleCoverage*avgCvg, [0]\n"); --> printf (" -B \tbubbleCoverage: remove contig with lower cvoerage in bubble structure if both contigs' coverage are smaller than bubbleCoverage*avgCvg, [0.6]\n"); 3) Variant: main.c::pipeline() a) unsigned char getB is now related with "bubbleCoverage" instead of "insertSizeUpperBound". b) new: unsigned char getb; //related with "insertSizeUpperBound". c) new: char bubble_coverage_s[16]; d) new: float bubble_coverage = 0.0; e) int insert_size_bound = 0; --> float insert_size_bound = 0.0; 4) Function: main.c::pipeline() a) while ((copt = getopt (argc, argv, "a:s:o:K:M:L:p:G:d:D:RuFk:fc:C:b:N:w")) != EOF) --> while ((copt = getopt (argc, argv, "a:s:o:K:M:L:p:G:d:D:RuFk:fc:C:b:B:N:w")) != EOF) b) new: case 'B': getB = 1; sscanf (optarg, "\s", temp); bubble_coverage = atof (temp); break; c) new: if (getB) { options[index++] = "-B"; sprintf (bubble_coverage_s, "%f", bubble_coverage); options[index++] = bubble_coverage_s; } 5) Function: main.c::display_all_usage() a) printf ("\nSOAPdenovo all -s configFile -o outputGraph [-R -f -F -u -w] [-K kmer -p n_cpu -a initMemoryAssumption -d KmerFreqCutOff -D EdgeCovCutoff -M mergeLevel -k kmer_R2C, -G gapLenDiff -L minContigLen -c minContigCvg -C maxContigCvg -b insertSizeUpperBound -N genomeSize]\n"); --> printf ("\nSOAPdenovo all -s configFile -o outputGraph [-R -f -F -u -w] [-K kmer -p n_cpu -a initMemoryAssumption -d KmerFreqCutOff -D EdgeCovCutoff -M mergeLevel -k kmer_R2C, -G gapLenDiff -L minContigLen -c minContigCvg -C maxContigCvg -b insertSizeUpperBound -B bubbleCoverage -N genomeSize]\n"); b) printf (" -b \tinsertSizeUpperBound: (b*avg_ins) will be used as upper bound of insert size for large insert size ( > 1000) when handling pair-end connections between contigs if b is set to larger than 1, [0]\n"); --> printf (" -b \tinsertSizeUpperBound: (b*avg_ins) will be used as upper bound of insert size for large insert size ( > 1000) when handling pair-end connections between contigs if b is set to larger than 1, [1.5]\n"); c) new: printf (" -B \tbubbleCoverage: remove contig with lower cvoerage in bubble structure if both contigs' coverage are smaller than bubbleCoverage*avgCvg, [0.6]\n"); 6) Function: orderContig.c::PE2Links() a) gzFile *fp --> FILE *fp1; gzFile *fp2; b) sprintf (name, "%s.readOnContig.gz", infile); fp = gzopen (name, "r"); --> if (COMPATIBLE_MODE == 1) { sprintf(name,"%s.readOnContig",infile); fp1 = ckopen(name,"r"); } else { sprintf (name, "%s.readOnContig.gz", infile); fp2 = gzopen (name, "r"); } c) gzgets (fp, line, lineLen); --> if (COMPATIBLE_MODE == 1) { fgets(line,lineLen,fp1); } else { gzgets (fp2, line, lineLen); } d) flag += connectByPE_grad(fp,i,line); --> if (COMPATIBLE_MODE == 1) { flag += connectByPE_grad(fp1,i,line); } else { flag += connectByPE_grad_gz(fp2,i,line); } e) gzclose(fp); --> if (COMPATIBLE_MODE == 1) { fclose(fp1); } else { gzclose(fp2); } 7) Function: inc/extfunc.h a) connectByPE_grad( gzFile* fp, int peGrad, char * line ); --> extern int connectByPE_grad_gz ( gzFile * fp, int peGrad, char * line ); 8) Function: attachPEinfo.c a) recover: int connectByPE_grad (FILE * fp, int peGrad, char *line) b) int connectByPE_grad (gzFile * fp, int peGrad, char *line) --> int connectByPE_grad_gz (gzFile * fp, int peGrad, char *line) 9) Function: prlReadFillGap.c::loadReads4gap() a) update some code to read '*.readInGap'. 2011-11-04 1) Variant: inc/globe.h a) new: float cvg4SNP = 0.0; 2) Variant: inc/extvab.h a) new: extern float cvg4SNP; 3) struct: inc/def.h::struct contig a) new: unsigned char bubbleInScaff: 1; 4) Function: scaffold.c::initenv() a) while ((copt = getopt (argc, argv, "g:L:p:G:N:c:C:b:FmuSw")) != EOF) --> while ((copt = getopt (argc, argv, "g:L:p:G:N:c:C:b:B:FmuSw")) != EOF) b) new: case 'B': sscanf (optarg, "%s", temp); cvg4SNP = atof (temp) > 0 ? atof (temp) : 0.0; break; 5) Function: scaffold.c::display_scaff_usage() a) new: printf (" -B \tbubbleCoverage: remove contig with lower cvoerage in bubble structure if both contigs' coverage are smaller than bubbleCoverage*avgCvg, [0]\n"); 6) Function: loadGraph.c::loadUpdatedEdges() a) new: contig_array[newIndex].bubbleInScaff = 0; 7) Variant: orderContig.c a) new: static FILE *snp_fp = NULL; 8) Fucntion: orderContig.c::Links2Scaf() a) cvg4SNP = ((double)(0.5*cvgAvg) + sqrt(2*cvgAvg)); --> if (cvg4SNP > 0.001) { sprintf(name, "%s.bubbleInScaff", infile); snp_fp = ckopen(name, "w"); } cvg4SNP = (double)(cvg4SNP*cvgAvg); b) new: if (cvg4SNP > 0.001) { fclose (snp_fp); } 9) Fucntion: inc/extfunc.h a) new: extern void outputTightStr(FILE *fp,char *tightStr,int start,int length, int outputlen,int revS,int *col); 10) Fcuntion: prlReadFillGap.c::outputTightStr() a) static void outputTightStr (FILE * fp, char *tightStr, int start, int length, int outputlen, int revS, int *col) --> void outputTightStr (FILE * fp, char *tightStr, int start, int length, int outputlen, int revS, int *col) 11) Function: orderContig.c a) new: static void output_ctg(unsigned int ctg,FILE *fo) { if(contig_array[ctg].length<1) return; int len; unsigned int bal_ctg = getTwinCtg(ctg); len = contig_array[ctg].length + overlaplen; int col = 0; if(contig_array[ctg].seq){ fprintf(fo,">C%d %4.1f\n",ctg,(double)contig_array[ctg].cvg); outputTightStr(fo,contig_array[ctg].seq,0,len,len,0,&col); } else if(contig_array[bal_ctg].seq){ fprintf(fo,">C%d %4.1f\n",bal_ctg,(double)contig_array[ctg].cvg); outputTightStr(fo,contig_array[bal_ctg].seq,0,len,len,0,&col); } fprintf(fo,"\n"); } 12) Function: orderContig.c::removeSNPCtg() a) unsigned int node1, node2; --> unsigned int node1, node2, bal_node1, bal_node2; b) new: bal_node1 = getTwinCtg(node1); bal_node2 = getTwinCtg(node2); c) getEndKmers(contig_array[getTwinCtg(node1)].seq, len1, 1, firstKmer1, lastKmer1); --> getEndKmers(contig_array[bal_node1].seq, len1, 1, firstKmer1, lastKmer1); d) getEndKmers(contig_array[getTwinCtg(node2)].seq, len2, 1, firstKmer2, lastKmer2); --> getEndKmers(contig_array[bal_node2].seq, len2, 1, firstKmer2, lastKmer2); e) new: if (contig_array[node1].bubbleInScaff == 0 || contig_array[node2].bubbleInScaff == 0) { contig_array[node1].bubbleInScaff = 1; contig_array[bal_node1].bubbleInScaff = 1; contig_array[node2].bubbleInScaff = 1; contig_array[bal_node2].bubbleInScaff = 1; output_ctg(node1, snp_fp); output_ctg(node2, snp_fp); } f) transferCnt2RemainNode(getTwinCtg(node2), getTwinCtg(node1)); --> transferCnt2RemainNode(bal_node2, bal_node1); g) transferCnt2RemainNode(getTwinCtg(node1), getTwinCtg(node2)); --> transferCnt2RemainNode(bal_node1, bal_node2); 2011-11-03 1) Function: orderContig.c::scaffolding() a) if(pre_score == 0) { *(unsigned int *)darrayPut(tempArray,prev_p)=0; mask_num++; } else if(now_ctg_score == 0) { *(unsigned int *)darrayPut(tempArray,j)=0; mask_num++; if(j < tempCounter -1) continue; } --> if(pre_score == 0) { *(unsigned int *)darrayPut(tempArray,prev_p)=0; contig_array[prev_id].flag = 0; contig_array[getTwinCtg(prev_id)].flag = 0; mask_num++; } else if(now_ctg_score == 0) { *(unsigned int *)darrayPut(tempArray,j)=0; contig_array[nowid].flag = 0; contig_array[getTwinCtg(nowid)].flag = 0; mask_num++; if(j < tempCounter -1) continue; } b) if(contig_array[prev_id].cvg < contig_array[nowid].cvg) { *(unsigned int *)darrayPut(tempArray,prev_p)=0; } else { *(unsigned int *)darrayPut(tempArray,j)=0; if(j < tempCounter -1) continue; } --> if(contig_array[prev_id].cvg < contig_array[nowid].cvg) { *(unsigned int *)darrayPut(tempArray,prev_p)=0; contig_array[prev_id].flag = 0; contig_array[getTwinCtg(prev_id)].flag = 0; } else { *(unsigned int *)darrayPut(tempArray,j)=0; contig_array[nowid].flag = 0; contig_array[getTwinCtg(nowid)].flag = 0; if(j < tempCounter -1) continue; } c) if(score_count < 2) { free((void *)score_array); continue; } --> if(score_mask == 1 && num3 + num5 > 5 && score_count < 2) { free((void *)score_array); --count; sum -= len; for (j=0; j if(!linkCount1) 2) Function: loadGraph.c:: a) new: int cut_len; cut_len = COMPATIBLE_MODE == 0 ? overlaplen : 0; b) if(length != 0) contig_array[newIndex].length = length - overlaplen; --> if(length != 0) contig_array[newIndex].length = length - cut_len; c) counter += length - overlaplen; cvgSum += cvg * (length - overlaplen); --> counter += length - cut_len; cvgSum += cvg * (length - cut_len); 2011-10-24 1) Function: orderContig.c::checkScafConsist() a) boolean checkScafConsist(STACK *scafStack1, int len1, STACK *scafStack2) --> boolean checkScafConsist(STACK *scafStack1, int len1, STACK *scafStack2, int len2) b) int linkCount1 = getDSLink2Scaf(scafStack1,downwardTo1,downwardWt1); int linkCount2 = getDSLink2Scaf(scafStack2,downwardTo2,downwardWt2); --> int linkCount1 = getDSLink2Scaf(scafStack1,downwardTo1,downwardWt1, len1); int linkCount2 = getDSLink2Scaf(scafStack2,downwardTo2,downwardWt2, len2); c) annotate: boolean flag2 = isLinkReliable(downwardWt2,linkCount2); d) if(!flag1||!flag2) --> if(!flag1) e) if (linkCount2 && flag2) --> if (linkCount2) 2) Function: orderContig.c::detectBreakScaff() a) int flag1 = checkScafConsist(scafStack1,scafStack2); int flag2 = checkScafConsist(scafStack2,scafStack1); --> int flag1 = checkScafConsist(scafStack1, len1, scafStack2, len2); int flag2 = checkScafConsist(scafStack2, len2, scafStack1, len1); 3) Function: a) int getDSLink2Scaf(STACK *scafStack,DARRAY *SCAF,DARRAY *WT) --> int getDSLink2Scaf(STACK *scafStack,DARRAY *SCAF,DARRAY *WT, int total_len) b) new: CONNECT *bind_cnt; int len=0, gap; c) new: bind_cnt = getBindCnt(ctg); gap = bind_cnt ? bind_cnt->gapLen : 0; len += contig_array[ctg].length + gap; d) if ((contig_array[ctg].mask && contig_array[ctg].length < 500) || !contig_array[ctg].downwardConnect) --> if ((contig_array[ctg].mask && contig_array[ctg].length < 500) || !contig_array[ctg].downwardConnect || total_len - len > Insert_size) 2011-10-21 1) Function: orderContig.c::getDSLink2Scaf() a) new: if (ite_cnt->newIns != 1) { ite_cnt = ite_cnt->next; continue; } 2011-10-19 1) Function: orderContig.c::getScaffold() a) len += contig_array[ctg].length; --> len += bindCnt->gapLen + contig_array[ctg].length; 2) Function: orderContig.c::getDSLink2Scaf() a) new: unsigned int targetCtg,bal_targetCtg; b) new: targetCtg = ite_cnt->contigID; bal_targetCtg = getTwinCtg(targetCtg); c) if ((ite_cnt->mask && contig_array[ctg].length < 500) || ite_cnt->singleInScaf --> if ((ite_cnt->mask && contig_array[targetCtg].length < 500) || ite_cnt->singleInScaf d) if(contig_array[ctg].from_vt==contig_array[targetCtg].from_vt) --> if(contig_array[ctg].from_vt==contig_array[targetCtg].from_vt || (targetCtg==contig_array[targetCtg].from_vt && bal_targetCtg==contig_array[bal_targetCtg].from_vt)) 2011-10-18 1) struct: inc/def.h::struct connection a) add new member: unsigned char newIns:1; It's used to indicate whether the PE relationship between contigs is provided by the latest rank 2) Function: orderContig.c::inputLinks() a) add variants: CONNECT *cnt, *bal_cnt; b) add1Connect(ctg,toCtg,gap,wt,0); add1Connect(bal_toCtg,bal_ctg,gap,wt,0); --> cnt = add1Connect(ctg,toCtg,gap,wt,0); bal_cnt = add1Connect(bal_toCtg,bal_ctg,gap,wt,0); if (cnt && insertS > 1000) { cnt->newIns = bal_cnt->newIns = 1; } 3) Function: orderContig.c::detectBreakScaff() a) new function, developed from detectBreakScaf(). 4) Function: orderContig.c::clearNewInsFlag() a) new function. 5) Function: orderContig.c::Links2Scaf() a) if(i==gradsCounter-1&&!isPrevSmall&&smallPE) detectBreakScaf(); --> if(Insert_size > 1000) detectBreakScaff(); b) new: if (Insert_size > 1000 && i != gradsCounter-1) clearNewInsFlag(); 2011-10-11 1) Function: readseq1by1.c::openFile4read() a) fp = popen (cmd, "r"); free (cmd); return fp; --> do { if ((fp = popen (cmd, "r")) != NULL) { free (cmd); return fp; } } while (1); 2011-09-28 1) Function: readseqfq() a) int i, n, strL, m, p; --> int i, n, strL, m, p=0; b) else if (buf[m] == '\n' && buf[p] == '\n') --> else if (buf[m] == '\n' && buf[p] == '\n' && m>p) Note: Both modifications are provided by Pan Qi. 2011-09-27 1) Function: Links2Scaf() a) cvg4SNP = ((double)(0.5*cvgAvg) + sqrt(2*cvgAvg)); --> cvg4SNP = ((double)(0.5*cvgAvg) + 3.0*sqrt(cvgAvg/2.0)); Note: This change maybe not suit for all cases 2) Function: general_linearization() a) SNPCtgCounter += removeSNPCtg(); --> if (Insert_size < 10000) { SNPCtgCounter += removeSNPCtg(); } 2011-09-21 1) Function: arrangeNodes_general() a) if(temp_cnt) { //recover connections } --> if(temp_cnt && (bySmall || temp_cnt->bySmall || temp_cnt->smallIns || (!dh_cnt || !dh_cnt->bySmall || !dh_cnt->smallIns))) { //recover connections } b) else if (dh_cnt && ((dh_cnt->bySmall || dh_cnt->smallIns || bySmall) || ((-gap > (int)contig_array[node1].length || -gap > (int)contig_array[node2].length) && tmp_dis > 0 && tmp_dis < 0.2*Insert_size ))) { //exchange connections } --> else if (dh_cnt && ((dh_cnt->bySmall || dh_cnt->smallIns || bySmall) || ((-gap > (int)contig_array[node1].length || -gap > (int)contig_array[node2].length) && tmp_dis > 0 && tmp_dis < 500 ))) { //exchange connections } 2011-09-15 1) Function: createAnalogousCnt() a) if(gap if(gapdeleted = 1; temp_cnt = getCntBetween(balSourceStop,balSourceStart); return change_flag; } 2011-09-07 1) Function: downSlide() a) annotate the codes related to "lastTop". 2) Function: scaffolding() a) replace the old codes related to the calculation of the score of contig's connection with the new codes from version 0729/63mer updated by Binghang Liu b) if(now_ctg_score == 0 && ((j == num3-1 && contig_array[nextid].length < 200 && num3 + num5 > 5)|| (now_cnt_weigth == 0&& j>0 ))) --> if(score_mask == 1 && now_ctg_score == 0 && ((j == num3-1 && contig_array[nextid].length < 200 && num3 + num5 > 5)|| (now_cnt_weigth == 0&& j>0 ))) c) if(now_ctg_score == 0 && ((j == num5-1 && contig_array[*(unsigned int *)darrayGet(scaf5,j-1)].length <200 && num3 + num5 > 5)|| (j != num5-1 && now_cnt_weigth == 0))) --> if(score_mask == 1 && now_ctg_score == 0 && ((j == num5-1 && contig_array[*(unsigned int *)darrayGet(scaf5,j-1)].length <200 && num3 + num5 > 5) || (j != num5-1 && now_cnt_weigth == 0))) 3) Function: get_ctg_score2() a) if(dh_cnt && dh_cnt->weight >0) i++; --> if(dh_cnt && dh_cnt->weight >0) in++; 4) Function: arrangeNodes_general() a) else if(dh_cnt && ((dh_cnt->weight > weakPE && (-gap > (int)contig_array[node1].length || -gap > (int)contig_array[node2].length))|| (dh_cnt->bySmall || dh_cnt->smallIns || bySmall))) --> else if (dh_cnt && ((dh_cnt->bySmall || dh_cnt->smallIns || bySmall) || ((-gap > (int)contig_array[node1].length || -gap > (int)contig_array[node2].length) && tmp_dis > 0 && tmp_dis < 0.2*Insert_size ))) 5) Function: removeSNPCtg() a) add: CONNECT *cnt, *bal_cnt; cnt = getCntBetween(node1, node2); dh_cnt = getCntBetween(node2, node1); change: if (gap >= 0 || contig_array[node1].cvg > cvg4SNP || contig_array[node2].cvg > cvg4SNP) --> if (gap >= 0 || contig_array[node1].cvg > cvg4SNP || contig_array[node2].cvg > cvg4SNP || cnt || bal_cnt) 6) Function: outputScafSeq() a) if (prevCtg && actg->scaftig_start) { if(!fillGap) { gapN = actg->start - prevCtg->start - contig_array[prevCtg->ctgID].length - overlaplen; } else gapN = actg->start - prevCtg->start - contig_array[prevCtg->ctgID].length; // gapN = actg->start - prevCtg->start - contig_array[prevCtg->ctgID].length; //lzy 0907 gapN = gapN > 0 ? gapN : 1; outputNs (fo, scaffBuffer, gapN, &column); ctg_start_pos += gapN; //outputGapInfo(prevCtg->ctgID,ctg); Ncounter++; } if(fillGap) { if (!prevCtg) { start = 0; } else { start = actg->cutHead; } } else start = 0; --> if (prevCtg && actg->scaftig_start) { /*<start - prevCtg->start - contig_array[prevCtg->ctgID].length - overlaplen; } else gapN = actg->start - prevCtg->start - contig_array[prevCtg->ctgID].length; >>*/ gapN = actg->start - prevCtg->start - contig_array[prevCtg->ctgID].length; //lzy 0907 gapN = gapN > 0 ? gapN : 1; outputNs (fo, scaffBuffer, gapN, &column); ctg_start_pos += gapN; //outputGapInfo(prevCtg->ctgID,ctg); Ncounter++; } if (!prevCtg) { start = 0; } else { start = actg->cutHead; } 2011-09-06 1) Function: removeSNPCtg() a) maskNodeCnt() --> transferCnt2RemainNode() reason: not only mask SNP contig, but also transfer the PE information from masked SNP contig to remain SNP contig 2011-09-02 1) Function: Links2Scaf() a) cvg4SNP = 0.6*cvgAvg; --> cvg4SNP = ((double)(0.5*cvgAvg) + sqrt(2*cvgAvg)); 2011-08-31 1) recover the function removeSNPCtg() 2) Function: removeSNPCtg() a) if (len1 > len2 || (len1 == len2 && contig_array[node1].cvg > contig_array[node2].cvg)) --> if (contig_array[node1].cvg > contig_array[node2].cvg || (len1 > len2 && contig_array[node1].cvg == contig_array[node2].cvg)) REASON: to keep accordance with the operation of merging bubble that remains the edge with higher coverage 2011-08-29 1) Function: arrangeNodes_general() a) if (comCount > 0 && abs(adjustedGap/comCount) > abs(gap)) --> if (comCount > 0) b) if (bySmall > 0 ||(-gap > (int)contig_array[node1].length || -gap > (int)contig_array[node2].length) && (i != nodeCounter-1)) --> if (bySmall > 0 && gap < 0 ||((-gap > (int)contig_array[node1].length || -gap > (int)contig_array[node2].length) && (i != nodeCounter-1))) 2) Function: getCntNodes() a) if (cnt->weight < 3) --> if (0 == bySmall && cnt->weight < 3 && !cnt->smallIns && !cnt->bySmall) 3) Function: calGapLen() a) if (cnt && cnt->weight>=3) --> if (cnt && (cnt->weight>=3 || bySmall || cnt->smallIns || cnt->bySmall)) 2011-08-26 1) Function: arrangeNodes_general() a) else if(dh_cnt && ((dh_cnt->weight > weakPE && (-gap > (int)contig_array[node1].length || -gap > (int)contig_array[node2].length))|| (dh_cnt->bySmall && gap < -overlaplen ))) --> else if(dh_cnt && ((dh_cnt->weight > weakPE && (-gap > (int)contig_array[node1].length || -gap > (int)contig_array[node2].length))|| (dh_cnt->bySmall || dh_cnt->smallIns || bySmall))) b) if ((-gap > (int)contig_array[node1].length || -gap > (int)contig_array[node2].length) && (i != nodeCounter-1)) --> if ((bySmall > 0) ||(-gap > (int)contig_array[node1].length || -gap > (int)contig_array[node2].length) && (i != nodeCounter-1)) c) if (comCount > 0 && adjustedGap/comCount) > gap) --> if (comCount > 0 && abs(adjustedGap/comCount) > abs(gap)) 2) Function: Links2Scaf() a) bySmall = Insert_size > 1000 ? 2 : 0; --> bySmall = Insert_size > 1000 ? 0 : 1; soapdenovo2-240+dfsg.orig/standardPregraph/compactEdge.c0000644000000000000000000000626312166703654022065 0ustar rootroot/* * compactEdge.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" void copyEdge ( unsigned int source, unsigned int target ) { edge_array[target].from_vt = edge_array[source].from_vt; edge_array[target].to_vt = edge_array[source].to_vt; edge_array[target].length = edge_array[source].length; edge_array[target].cvg = edge_array[source].cvg; edge_array[target].multi = edge_array[source].multi; edge_array[target].flag = edge_array[source].flag; if ( edge_array[target].seq ) { free ( ( void * ) edge_array[target].seq ); } edge_array[target].seq = edge_array[source].seq; edge_array[source].seq = NULL; edge_array[target].arcs = edge_array[source].arcs; edge_array[source].arcs = NULL; edge_array[target].markers = edge_array[source].markers; edge_array[source].markers = NULL; edge_array[target].deleted = edge_array[source].deleted; } //move edge from source to target void edgeMove ( unsigned int source, unsigned int target ) { unsigned int bal_source, bal_target; ARC * arc; copyEdge ( source, target ); bal_source = getTwinEdge ( source ); //bal_edge if ( bal_source != source ) { bal_target = target + 1; copyEdge ( bal_source, bal_target ); edge_array[target].bal_edge = 2; edge_array[bal_target].bal_edge = 0; } else { edge_array[target].bal_edge = 1; bal_target = target; } //take care of the arcs arc = edge_array[target].arcs; while ( arc ) { arc->bal_arc->to_ed = bal_target; arc = arc->next; } if ( bal_target == target ) { return; } arc = edge_array[bal_target].arcs; while ( arc ) { arc->bal_arc->to_ed = target; arc = arc->next; } } /************************************************* Function: compactEdgeArray Description: Compacts the edge array by removing deleted edges. Input: None. Output: None. Return: None. *************************************************/ void compactEdgeArray () { unsigned int i; unsigned int validCounter = 0; unsigned int bal_ed; fprintf ( stderr, "Before compacting, %d edge(s) existed.\n", num_ed ); for ( i = 1; i <= num_ed; i++ ) { if ( edge_array[i].deleted ) { continue; } validCounter++; if ( i == validCounter ) { continue; } bal_ed = getTwinEdge ( i ); edgeMove ( i, validCounter ); if ( bal_ed != i ) { i++; validCounter++; } } num_ed = validCounter; fprintf ( stderr, "After compacting, %d edge(s) left.\n", num_ed ); } soapdenovo2-240+dfsg.orig/standardPregraph/prlRead2path.c0000644000000000000000000007622412166703654022206 0ustar rootroot/* * prlRead2path.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include #include "newhash.h" #include "kmerhash.h" #include #include #define preARCBLOCKSIZE 100000 #ifdef MER127 static const Kmer kmerZero = { 0, 0, 0, 0 }; #else static const Kmer kmerZero = { 0, 0 }; #endif static unsigned int * arcCounters; static int buffer_size = 100000000; static long long markCounter = 0; static unsigned int * fwriteBuf; static unsigned char * markerOnEdge; //edge occured times for each edge //buffer related varibles for chop kmer static int read_c; static char ** rcSeq; static char ** seqBuffer; static int * lenBuffer; //edge and (K+1)mer related variables static preARC ** preArc_array; static Kmer * mixBuffer; //kmer buffer; after searching, mixBuffer[j].low = node->l_links; 'node->l_links' static boolean * flagArray; //indicate each item in mixBuffer whether it's a (K+1)mer // kmer related variables static char ** flags; static int kmer_c; static Kmer * kmerBuffer; static ubyte8 * hashBanBuffer; static kmer_t ** nodeBuffer; //kmer_t buffer related to 'kmerBuffer' static boolean * smallerBuffer; static int * indexArray; static int * deletion; //read deletion number for each thread static struct aiocb aio1; static struct aiocb aio2; static char * aioBuffer1; static char * aioBuffer2; static char * readBuffer1; static char * readBuffer2; static void parse1read ( int t, int threadID ); static void search1kmerPlus ( int j, unsigned char thrdID ); static void threadRoutine ( void * thrdID ); static void searchKmer ( int t, KmerSet * kset ); static void chopKmer4read ( int t, int threadID ); static void thread_wait ( pthread_t * threads ); static void thread_add1preArc ( unsigned int from_ed, unsigned int to_ed, unsigned int thrdID ); static void creatThrds ( pthread_t * threads, PARAMETER * paras ) { unsigned char i; int temp; for ( i = 0; i < thrd_num; i++ ) { //printf("to create %dth thread\n",(*(char *)&(threadID[i]))); if ( ( temp = pthread_create ( &threads[i], NULL, ( void * ) threadRoutine, & ( paras[i] ) ) ) != 0 ) { fprintf ( stderr, "Create threads failed.\n" ); exit ( 1 ); } } fprintf ( stderr, "%d thread(s) initialized.\n", thrd_num ); } static void threadRoutine ( void * para ) { PARAMETER * prm; int i, t, j, start, finish; unsigned char id; prm = ( PARAMETER * ) para; id = prm->threadID; //printf("%dth thread with task %d, hash_table %p\n",id,prm.task,prm.hash_table); while ( 1 ) { if ( * ( prm->selfSignal ) == 1 ) { for ( i = 0; i < kmer_c; i++ ) { //if((hashBanBuffer[i]&taskMask)!=prm.threadID) if ( ( hashBanBuffer[i] % thrd_num ) != id ) { continue; } searchKmer ( i, KmerSets[id] ); } * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 2 ) { for ( i = 0; i < read_c; i++ ) { if ( i % thrd_num != id ) { continue; } chopKmer4read ( i, id + 1 ); } * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 3 ) { // parse reads for ( t = 0; t < read_c; t++ ) { if ( t % thrd_num != id ) { continue; } parse1read ( t, id + 1 ); } * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 4 ) { //printf("thread %d, reads %d splay kmerplus\n",id,read_c); for ( t = 0; t < read_c; t++ ) { start = indexArray[t]; finish = indexArray[t + 1]; #ifdef MER127 for ( j = start; j < finish; j++ ) { if ( flagArray[j] == 0 ) { if ( mixBuffer[j].low2 == 0 ) { break; } } else if ( hashBanBuffer[j] % thrd_num == id ) { //fprintf(stderr,"thread %d search for ban %lld\n",id,hashBanBuffer[j]); search1kmerPlus ( j, id ); } /* if(flagArray[j]==0&&mixBuffer[j]==0) break; if(!flagArray[j]||(hashBanBuffer[j]%thrd_num)!=id) continue; search1kmerPlus(j,id); */ } #else for ( j = start; j < finish; j++ ) { if ( flagArray[j] == 0 ) { if ( mixBuffer[j].low == 0 ) { break; } } else if ( hashBanBuffer[j] % thrd_num == id ) { //fprintf(stderr,"thread %d search for ban %lld\n",id,hashBanBuffer[j]); search1kmerPlus ( j, id ); } /* if(flagArray[j]==0&&mixBuffer[j]==0) break; if(!flagArray[j]||(hashBanBuffer[j]%thrd_num)!=id) continue; search1kmerPlus(j,id); */ } #endif } * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 6 ) { for ( t = 0; t < read_c; t++ ) { start = indexArray[t]; finish = indexArray[t + 1]; #ifdef MER127 for ( j = start; j < finish - 1; j++ ) { if ( mixBuffer[j].low2 == 0 || mixBuffer[j + 1].low2 == 0 ) { break; } if ( mixBuffer[j].low2 % thrd_num != id ) { continue; } thread_add1preArc ( mixBuffer[j].low2, mixBuffer[j + 1].low2, id ); } #else for ( j = start; j < finish - 1; j++ ) { if ( mixBuffer[j].low == 0 || mixBuffer[j + 1].low == 0 ) { break; } if ( mixBuffer[j].low % thrd_num != id ) { continue; } thread_add1preArc ( mixBuffer[j].low, mixBuffer[j + 1].low, id ); } #endif } * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 5 ) { * ( prm->selfSignal ) = 0; break; } usleep ( 1 ); } } static void chopKmer4read ( int t, int threadID ) { char * src_seq = seqBuffer[t]; char * bal_seq = rcSeq[threadID]; int len_seq = lenBuffer[t]; int j, bal_j; ubyte8 hash_ban, bal_hash_ban; Kmer word, bal_word; int index; #ifdef MER127 word = kmerZero; for ( index = 0; index < overlaplen; index++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low2 |= src_seq[index]; } #else word = kmerZero; for ( index = 0; index < overlaplen; index++ ) { word = KmerLeftBitMoveBy2 ( word ); word.low |= src_seq[index]; } #endif reverseComplementSeq ( src_seq, len_seq, bal_seq ); // complementary node bal_word = reverseComplement ( word, overlaplen ); bal_j = len_seq - 0 - overlaplen; // 0; index = indexArray[t]; if ( KmerSmaller ( word, bal_word ) ) { hash_ban = hash_kmer ( word ); kmerBuffer[index] = word; smallerBuffer[index] = 1; hashBanBuffer[index++] = hash_ban; } else { bal_hash_ban = hash_kmer ( bal_word ); kmerBuffer[index] = bal_word; smallerBuffer[index] = 0; hashBanBuffer[index++] = bal_hash_ban; } //printf("%dth: %p with %p\n",kmer_c-1,bal_word,bal_hash_ban); for ( j = 1; j <= len_seq - overlaplen; j++ ) { word = nextKmer ( word, src_seq[j - 1 + overlaplen] ); bal_j = len_seq - j - overlaplen; // j; bal_word = prevKmer ( bal_word, bal_seq[bal_j] ); if ( KmerSmaller ( word, bal_word ) ) { hash_ban = hash_kmer ( word ); kmerBuffer[index] = word; smallerBuffer[index] = 1; hashBanBuffer[index++] = hash_ban; //printf("%dth: %p with %p\n",kmer_c-1,word,hashBanBuffer[kmer_c-1]); } else { // complementary node bal_hash_ban = hash_kmer ( bal_word ); kmerBuffer[index] = bal_word; smallerBuffer[index] = 0; hashBanBuffer[index++] = bal_hash_ban; //printf("%dth: %p with %p\n",kmer_c-1,bal_word,hashBanBuffer[kmer_c-1]); } } } //splay for one kmer in buffer and save the node to nodeBuffer static void searchKmer ( int t, KmerSet * kset ) { kmer_t * node; boolean found = search_kmerset ( kset, kmerBuffer[t], &node ); if ( !found ) { fprintf ( stderr, "SearchKmer: kmer " ); PrintKmer ( stderr, kmerBuffer[t] ); fprintf ( stderr, " is not found.\n" ); /* #ifdef MER127 fprintf (stderr,"searchKmer: kmer %llx %llx %llx %llx is not found\n", kmerBuffer[t].high1, kmerBuffer[t].low1, kmerBuffer[t].high2, kmerBuffer[t].low2); #else fprintf (stderr,"searchKmer: kmer %llx %llx is not found\n", kmerBuffer[t].high, kmerBuffer[t].low); #endif */ } nodeBuffer[t] = node; } static preARC * getPreArcBetween ( unsigned int from_ed, unsigned int to_ed ) { preARC * parc; parc = preArc_array[from_ed]; while ( parc ) { if ( parc->to_ed == to_ed ) { return parc; } parc = parc->next; } return parc; } static void thread_add1preArc ( unsigned int from_ed, unsigned int to_ed, unsigned int thrdID ) { preARC * parc = getPreArcBetween ( from_ed, to_ed ); if ( parc ) { parc->multiplicity++; } else { parc = prlAllocatePreArc ( to_ed, preArc_mem_managers[thrdID] ); arcCounters[thrdID]++; parc->next = preArc_array[from_ed]; preArc_array[from_ed] = parc; } } static void memoAlloc4preArc () { unsigned int i; preArc_array = ( preARC ** ) ckalloc ( ( num_ed + 1 ) * sizeof ( preARC * ) ); for ( i = 0; i <= num_ed; i++ ) { preArc_array[i] = NULL; } } static void memoFree4preArc () { prlDestroyPreArcMem (); if ( preArc_array ) { free ( ( void * ) preArc_array ); } } static void output_arcs ( char * outfile ) { unsigned int i; char name[256]; FILE * outfp, *outfp2 = NULL; preARC * parc; sprintf ( name, "%s.preArc", outfile ); outfp = ckopen ( name, "w" ); if ( repsTie ) { sprintf ( name, "%s.markOnEdge", outfile ); outfp2 = ckopen ( name, "w" ); } markCounter = 0; for ( i = 1; i <= num_ed; i++ ) { if ( repsTie ) { markCounter += markerOnEdge[i]; fprintf ( outfp2, "%d\n", markerOnEdge[i] ); } parc = preArc_array[i]; if ( !parc ) { continue; } fprintf ( outfp, "%u", i ); while ( parc ) { fprintf ( outfp, " %u %u", parc->to_ed, parc->multiplicity ); parc = parc->next; } fprintf ( outfp, "\n" ); } fclose ( outfp ); if ( repsTie ) { fclose ( outfp2 ); // fprintf (stderr,"%lld marker(s) counted.\n", markCounter); } } static void recordPathBin ( FILE * outfp ) { int t, j, start, finish; unsigned char counter; for ( t = 0; t < read_c; t++ ) { start = indexArray[t]; finish = indexArray[t + 1]; #ifdef MER127 if ( finish - start < 3 || mixBuffer[start].low2 == 0 || mixBuffer[start + 1].low2 == 0 || mixBuffer[start + 2].low2 == 0 ) { continue; } counter = 0; for ( j = start; j < finish; j++ ) { if ( mixBuffer[j].low2 == 0 ) { break; } fwriteBuf[counter++] = ( unsigned int ) mixBuffer[j].low2; if ( markerOnEdge[mixBuffer[j].low2] < 255 ) { markerOnEdge[mixBuffer[j].low2]++; } markCounter++; } #else if ( finish - start < 3 || mixBuffer[start].low == 0 || mixBuffer[start + 1].low == 0 || mixBuffer[start + 2].low == 0 ) { continue; } counter = 0; for ( j = start; j < finish; j++ ) { if ( mixBuffer[j].low == 0 ) { break; } fwriteBuf[counter++] = ( unsigned int ) mixBuffer[j].low; if ( markerOnEdge[mixBuffer[j].low] < 255 ) { markerOnEdge[mixBuffer[j].low]++; } markCounter++; } #endif fwrite ( &counter, sizeof ( char ), 1, outfp ); fwrite ( fwriteBuf, sizeof ( unsigned int ), ( int ) counter, outfp ); } } /************************************************* Function: search1kmerPlus Description: Searchs (k+1) kmer in hashset. Input: 1. j: (k+1) mer's index 2. thrdID: thread id Output: None. Return: None. *************************************************/ static void search1kmerPlus ( int j, unsigned char thrdID ) { kmer_t * node; boolean found = search_kmerset ( KmerSetsPatch[thrdID], mixBuffer[j], &node ); if ( !found ) { /* fprintf(stderr,"kmerPlus %llx %llx (hashban %lld) not found, flag %d!\n", mixBuffer[j].high,mixBuffer[j].low,hashBanBuffer[j],flagArray[j]); */ mixBuffer[j] = kmerZero; return; } //else fprintf(stderr,"kmerPlus found\n"); #ifdef MER127 if ( smallerBuffer[j] ) { mixBuffer[j].low2 = node->l_links; } else { mixBuffer[j].low2 = node->l_links + node->twin - 1; } #else if ( smallerBuffer[j] ) { mixBuffer[j].low = node->l_links; } else { mixBuffer[j].low = node->l_links + node->twin - 1; } #endif } static void parse1read ( int t, int threadID ) { unsigned int j, retain = 0; unsigned int edge_index = 0; kmer_t * node; boolean isSmaller; Kmer wordplus, bal_wordplus; unsigned int start, finish, pos; Kmer prevKmer, currentKmer; boolean IsPrevKmer = 0; start = indexArray[t]; finish = indexArray[t + 1]; pos = start; for ( j = start; j < finish; j++ ) { node = nodeBuffer[j]; //extract edges or keep kmers if ( ( node->deleted ) || ( node->linear && !node->inEdge ) ) // deleted or in a floating loop { if ( retain < 2 ) { retain = 0; pos = start; } else { break; } continue; } isSmaller = smallerBuffer[j]; if ( node->linear ) { if ( isSmaller ) { edge_index = node->l_links; } else { edge_index = node->l_links + node->twin - 1; } #ifdef MER127 if ( retain == 0 || IsPrevKmer ) { retain++; mixBuffer[pos].low2 = edge_index; flagArray[pos++] = 0; IsPrevKmer = 0; } else if ( edge_index != mixBuffer[pos - 1].low2 ) { retain++; mixBuffer[pos].low2 = edge_index; flagArray[pos++] = 0; } #else if ( retain == 0 || IsPrevKmer ) { retain++; mixBuffer[pos].low = edge_index; flagArray[pos++] = 0; IsPrevKmer = 0; } else if ( edge_index != mixBuffer[pos - 1].low ) { retain++; mixBuffer[pos].low = edge_index; flagArray[pos++] = 0; } #endif } else { if ( isSmaller ) { currentKmer = node->seq; } else { currentKmer = reverseComplement ( node->seq, overlaplen ); } if ( IsPrevKmer ) { retain++; wordplus = KmerPlus ( prevKmer, lastCharInKmer ( currentKmer ) ); bal_wordplus = reverseComplement ( wordplus, overlaplen + 1 ); if ( KmerSmaller ( wordplus, bal_wordplus ) ) { smallerBuffer[pos] = 1; hashBanBuffer[pos] = hash_kmer ( wordplus ); mixBuffer[pos] = wordplus; } else { smallerBuffer[pos] = 0; hashBanBuffer[pos] = hash_kmer ( bal_wordplus ); mixBuffer[pos] = bal_wordplus; } // fprintf(stderr,"%lld\n",hashBanBuffer[pos]); flagArray[pos++] = 1; } IsPrevKmer = 1; prevKmer = currentKmer; } } /* for(j=start;j= overlaplen + 1 ) { kmer_c -= lenBuffer[read_c - 1] - overlaplen + 1; read_c--; } n_solexa -= 2; continue; } if ( ( ++i ) % 100000000 == 0 ) { fprintf ( stderr, "--- %lldth reads.\n", i ); } if ( lenBuffer[read_c] < overlaplen + 1 ) { continue; } //if(lenBuffer[read_c]>70) // lenBuffer[read_c] = 70; //else if(lenBuffer[read_c]>40) // lenBuffer[read_c] = 40; indexArray[read_c] = kmer_c; kmer_c += lenBuffer[read_c] - overlaplen + 1; read_c++; if ( read_c == maxReadNum ) { indexArray[read_c] = kmer_c; time ( &read_end ); t0 += read_end - read_start; time ( &time_bef ); sendWorkSignal ( 2, thrdSignal ); //chopKmer4read time ( &time_aft ); t1 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 1, thrdSignal ); //searchKmer time ( &time_aft ); t2 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 3, thrdSignal ); //parse1read time ( &time_aft ); t3 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 4, thrdSignal ); //search1kmerPlus time ( &time_aft ); t4 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 6, thrdSignal ); //thread_add1preArc time ( &time_aft ); t5 += time_aft - time_bef; time ( &time_bef ); //recordPreArc(); if ( repsTie ) { recordPathBin ( outfp ); } time ( &time_aft ); t6 += time_aft - time_bef; //output_path(read_c,edge_no,flags,outfp); kmer_c = 0; read_c = 0; time ( &read_start ); } } } else if ( lib_array[libNo].curr_type == 1 || lib_array[libNo].curr_type == 2 ) { initAIO ( &aio1, aioBuffer1, fileno ( lib_array[libNo].fp1 ), maxAIOSize ); initAIO ( &aio2, aioBuffer2, fileno ( lib_array[libNo].fp2 ), maxAIOSize ); int offset1, offset2, flag1, flag2, rt1, rt2; offset1 = offset2 = 0; rt1 = aio_read ( &aio1 ); rt2 = aio_read ( &aio2 ); flag1 = AIORead ( &aio1, &offset1, readBuffer1, cach1, &rt1, lib_array[libNo].curr_type ); flag2 = AIORead ( &aio2, &offset2, readBuffer2, cach2, &rt2, lib_array[libNo].curr_type ); if ( flag1 && flag2 ) { int start1, start2, turn; start1 = start2 = 0; turn = 1; while ( start1 < offset1 || start2 < offset2 ) { if ( turn == 1 ) { turn = 2; readseqInLib ( seqBuffer[read_c], next_name, & ( lenBuffer[read_c] ), readBuffer1, &start1, offset1, libNo ); if ( ( ++i ) % 100000000 == 0 ) { fprintf ( stderr, "--- %lldth reads.\n", i ); } if ( lenBuffer[read_c] < overlaplen + 1 ) { if ( start1 >= offset1 ) { start1 = 0; offset1 = 0; flag1 = AIORead ( &aio1, &offset1, readBuffer1, cach1, &rt1, lib_array[libNo].curr_type ); } continue; } indexArray[read_c] = kmer_c; kmer_c += lenBuffer[read_c] - overlaplen + 1; read_c++; if ( start1 >= offset1 ) { start1 = 0; offset1 = 0; flag1 = AIORead ( &aio1, &offset1, readBuffer1, cach1, &rt1, lib_array[libNo].curr_type ); } if ( read_c == maxReadNum ) { indexArray[read_c] = kmer_c; time ( &read_end ); t0 += read_end - read_start; time ( &time_bef ); sendWorkSignal ( 2, thrdSignal ); //chopKmer4read time ( &time_aft ); t1 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 1, thrdSignal ); //searchKmer time ( &time_aft ); t2 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 3, thrdSignal ); //parse1read time ( &time_aft ); t3 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 4, thrdSignal ); //search1kmerPlus time ( &time_aft ); t4 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 6, thrdSignal ); //thread_add1preArc time ( &time_aft ); t5 += time_aft - time_bef; time ( &time_bef ); //recordPreArc(); if ( repsTie ) { recordPathBin ( outfp ); } time ( &time_aft ); t6 += time_aft - time_bef; //output_path(read_c,edge_no,flags,outfp); kmer_c = 0; read_c = 0; time ( &read_start ); } continue; } if ( turn == 2 ) { turn = 1; readseqInLib ( seqBuffer[read_c], next_name, & ( lenBuffer[read_c] ), readBuffer2, &start2, offset2, libNo ); if ( ( ++i ) % 100000000 == 0 ) { fprintf ( stderr, "--- %lldth reads.\n", i ); } if ( lenBuffer[read_c] < overlaplen + 1 ) { if ( ( flag2 == 2 ) && ( start2 >= offset2 ) ) { break; } if ( start2 >= offset2 ) { start2 = 0; offset2 = 0; flag2 = AIORead ( &aio2, &offset2, readBuffer2, cach2, &rt2, lib_array[libNo].curr_type ); } continue; } indexArray[read_c] = kmer_c; kmer_c += lenBuffer[read_c] - overlaplen + 1; read_c++; if ( ( flag2 == 2 ) && ( start2 >= offset2 ) ) { break; } if ( start2 >= offset2 ) { start2 = 0; offset2 = 0; flag2 = AIORead ( &aio2, &offset2, readBuffer2, cach2, &rt2, lib_array[libNo].curr_type ); } if ( read_c == maxReadNum ) { indexArray[read_c] = kmer_c; time ( &read_end ); t0 += read_end - read_start; time ( &time_bef ); sendWorkSignal ( 2, thrdSignal ); //chopKmer4read time ( &time_aft ); t1 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 1, thrdSignal ); //searchKmer time ( &time_aft ); t2 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 3, thrdSignal ); //parse1read time ( &time_aft ); t3 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 4, thrdSignal ); //search1kmerPlus time ( &time_aft ); t4 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 6, thrdSignal ); //thread_add1preArc time ( &time_aft ); t5 += time_aft - time_bef; time ( &time_bef ); //recordPreArc(); if ( repsTie ) { recordPathBin ( outfp ); } time ( &time_aft ); t6 += time_aft - time_bef; //output_path(read_c,edge_no,flags,outfp); kmer_c = 0; read_c = 0; time ( &read_start ); } continue; } } } else { fprintf(stderr, "Error: aio_read error.\n"); } } else { initAIO ( &aio1, aioBuffer1, fileno ( lib_array[libNo].fp1 ), maxAIOSize ); int offset, flag1, rt; offset = 0; rt = aio_read ( &aio1 ); while ( ( flag1 = AIORead ( &aio1, &offset, readBuffer1, cach1, &rt, lib_array[libNo].curr_type ) ) ) { int start = 0; while ( start < offset ) { readseqInLib ( seqBuffer[read_c], next_name, & ( lenBuffer[read_c] ), readBuffer1, &start, offset, libNo ); if ( ( ++i ) % 100000000 == 0 ) { fprintf ( stderr, "--- %lldth reads.\n", i ); } if ( lenBuffer[read_c] < overlaplen + 1 ) { continue; } indexArray[read_c] = kmer_c; kmer_c += lenBuffer[read_c] - overlaplen + 1; read_c++; } if ( read_c > maxReadNum - 1024 ) { indexArray[read_c] = kmer_c; time ( &read_end ); t0 += read_end - read_start; time ( &time_bef ); sendWorkSignal ( 2, thrdSignal ); //chopKmer4read time ( &time_aft ); t1 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 1, thrdSignal ); //searchKmer time ( &time_aft ); t2 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 3, thrdSignal ); //parse1read time ( &time_aft ); t3 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 4, thrdSignal ); //search1kmerPlus time ( &time_aft ); t4 += time_aft - time_bef; time ( &time_bef ); sendWorkSignal ( 6, thrdSignal ); //thread_add1preArc time ( &time_aft ); t5 += time_aft - time_bef; time ( &time_bef ); //recordPreArc(); if ( repsTie ) { recordPathBin ( outfp ); } time ( &time_aft ); t6 += time_aft - time_bef; //output_path(read_c,edge_no,flags,outfp); kmer_c = 0; read_c = 0; time ( &read_start ); } if ( flag1 == 2 ) { break; } } } } fprintf ( stderr, "%lld read(s) processed.\n", i ); // fprintf (stderr,"Time ReadingReads: %d,chopKmer4read: %d,searchKmer: %d,parse1read: %d,search1kmerPlus: %d,thread_add1preArc: %d,recordPathBin: %d\n", t0, t1, t2, t3, t4, t5, t6); fprintf ( stderr, "Time spent on:\n" ); fprintf ( stderr, " importing reads: %ds,\n", t0 ); fprintf ( stderr, " chopping reads to kmers: %ds,\n", t1 ); fprintf ( stderr, " searching kmers: %ds,\n", t2 ); fprintf ( stderr, " aligning reads to edges: %ds,\n", t3 ); fprintf ( stderr, " searching (K+1)mers: %ds,\n", t4 ); fprintf ( stderr, " adding pre-arcs: %ds,\n", t5 ); fprintf ( stderr, " recording read paths: %ds.\n", t6 ); if ( read_c ) { indexArray[read_c] = kmer_c; sendWorkSignal ( 2, thrdSignal ); //chopKmer4read sendWorkSignal ( 1, thrdSignal ); //searchKmer sendWorkSignal ( 3, thrdSignal ); //parse1read sendWorkSignal ( 4, thrdSignal ); //search1kmerPlus sendWorkSignal ( 6, thrdSignal ); //thread_add1preArc //recordPreArc(); if ( repsTie ) { recordPathBin ( outfp ); } } fprintf ( stderr, "%lld marker(s) output.\n", markCounter ); sendWorkSignal ( 5, thrdSignal ); //over thread_wait ( threads ); output_arcs ( outfile ); memoFree4preArc (); if ( 1 ) // multi-threads { arcCounter = 0; for ( i = 0; i < thrd_num; i++ ) { arcCounter += arcCounters[i]; free ( ( void * ) flags[i + 1] ); deletion[0] += deletion[i + 1]; free ( ( void * ) rcSeq[i + 1] ); } } if ( 1 ) { free ( ( void * ) flags[0] ); free ( ( void * ) rcSeq[0] ); } fprintf ( stderr, "Reads alignment done, %d read(s) deleted, %lld pre-arc(s) added.\n", deletion[0], arcCounter ); if ( repsTie ) { free ( ( void * ) markerOnEdge ); free ( ( void * ) fwriteBuf ); } free ( ( void * ) arcCounters ); free ( ( void * ) rcSeq ); for ( i = 0; i < maxReadNum; i++ ) { free ( ( void * ) seqBuffer[i] ); } free ( ( void * ) seqBuffer ); free ( ( void * ) lenBuffer ); free ( ( void * ) indexArray ); free ( ( void * ) flags ); free ( ( void * ) deletion ); free ( ( void * ) kmerBuffer ); free ( ( void * ) mixBuffer ); free ( ( void * ) smallerBuffer ); free ( ( void * ) flagArray ); free ( ( void * ) hashBanBuffer ); free ( ( void * ) nodeBuffer ); free ( ( void * ) src_name ); free ( ( void * ) next_name ); free ( ( void * ) aioBuffer1 ); free ( ( void * ) aioBuffer2 ); free ( ( void * ) readBuffer1 ); free ( ( void * ) readBuffer2 ); free ( ( void * ) cach1 ); free ( ( void * ) cach2 ); if ( gLineLen < maxReadLen ) { free ( ( void * ) gStr ); gStr = NULL; } if ( repsTie ) { fclose ( outfp ); } free_pe_mem (); free_libs (); } static void thread_wait ( pthread_t * threads ) { int i; for ( i = 0; i < thrd_num; i++ ) if ( threads[i] != 0 ) { pthread_join ( threads[i], NULL ); } } soapdenovo2-240+dfsg.orig/standardPregraph/hashFunction.c0000644000000000000000000001276212166703654022304 0ustar rootroot/* * hashFunction.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include #define KMER_HASH_MASK 0x0000000000ffffffL #define KMER_HASH_BUCKETS 16777216 // 4^12 static int crc_table[256] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; typedef int ( *CRC32CFunctionPtr ) ( uint32_t, const char *, size_t ); static CRC32CFunctionPtr crc32; static uint32_t cpuid ( uint32_t functionInput ) { uint32_t eax; uint32_t ebx; uint32_t ecx; uint32_t edx; #ifdef __PIC__ asm ( "pushl %%ebx\n\t" /* save %ebx */ "cpuid\n\t" "movl %%ebx, %[ebx]\n\t" /* save what cpuid just put in %ebx */ "popl %%ebx" : "=a" ( eax ), [ebx] "=r" ( ebx ), "=c" ( ecx ), "=d" ( edx ) : "a" ( functionInput ) : "cc" ); #else asm ( "cpuid" : "=a" ( eax ), "=b" ( ebx ), "=c" ( ecx ), "=d" ( edx ) : "a" ( functionInput ) ); #endif return ecx; } static inline int crc32cHardware64 ( uint32_t crc, const char * data, size_t length ) { size_t i; for ( i = 0; i < ( length / sizeof ( uint64_t ) ); ++i ) { crc = __builtin_ia32_crc32di ( crc, * ( uint64_t * ) data ); data += sizeof ( uint64_t ); } return ( int ) crc; } static inline int crc32cTable ( uint32_t crc, const char * buf, size_t len ) { while ( len-- ) { crc = crc_table[ ( ( int ) crc ^ ( *buf++ ) ) & 0xff] ^ ( crc >> 8 ); } return crc ^ 0xffffffff; } CRC32CFunctionPtr detectBestCRC32C() { static const int SSE42_BIT = 20; uint32_t ecx = cpuid ( 1 ); bool hasSSE42 = ecx & ( 1 << SSE42_BIT ); if ( hasSSE42 ) { //fprintf(stderr, "SSE4.2 enabled\n"); return crc32cTable; } else { //fprintf(stderr, "SSE4.2 disabled\n"); return crc32cTable; } } ubyte8 hash_kmer ( Kmer kmer ) { return ( crc32 ( 0, ( char * ) &kmer, sizeof ( Kmer ) ) ); } void crc32c_Init() { crc32 = detectBestCRC32C(); } soapdenovo2-240+dfsg.orig/standardPregraph/darray.c0000644000000000000000000000424412166703654021131 0ustar rootroot/* * darray.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "darray.h" #include "check.h" DARRAY * createDarray ( int num_items, size_t unit_size ) { DARRAY * newDarray = ( DARRAY * ) malloc ( 1 * sizeof ( DARRAY ) ); newDarray->array_size = num_items; newDarray->item_size = unit_size; newDarray->item_c = 0; newDarray->array = ( void * ) ckalloc ( num_items * unit_size ); return newDarray; } void * darrayPut ( DARRAY * darray, long long index ) { int i = 2; if ( index + 1 > darray->item_c ) { darray->item_c = index + 1; } if ( index < darray->array_size ) { return darray->array + darray->item_size * index; } while ( index > i * darray->array_size ) { i++; } darray->array = ( void * ) ckrealloc ( darray->array, i * darray->array_size * darray->item_size, darray->array_size * darray->item_size ); darray->array_size *= i; return ( void * ) ( ( void * ) darray->array + darray->item_size * index ); } void * darrayGet ( DARRAY * darray, long long index ) { if ( index < darray->array_size ) { return ( void * ) ( ( void * ) darray->array + darray->item_size * index ); } fprintf ( stderr, "Index %lld of the array is out of range and the size is %lld.\n", index, darray->array_size ); return NULL; } void emptyDarray ( DARRAY * darray ) { darray->item_c = 0; } void freeDarray ( DARRAY * darray ) { if ( !darray ) { return; } if ( darray->array ) { free ( ( void * ) darray->array ); } free ( ( void * ) darray ); } soapdenovo2-240+dfsg.orig/standardPregraph/mem_manager.c0000644000000000000000000000537412166703654022124 0ustar rootroot/* * mem_manager.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" MEM_MANAGER * createMem_manager ( int num_items, size_t unit_size ) { MEM_MANAGER * mem_Manager = ( MEM_MANAGER * ) ckalloc ( 1 * sizeof ( MEM_MANAGER ) ); mem_Manager->block_list = NULL; mem_Manager->items_per_block = num_items; mem_Manager->item_size = unit_size; mem_Manager->recycle_list = NULL; mem_Manager->counter = 0; return mem_Manager; } void freeMem_manager ( MEM_MANAGER * mem_Manager ) { BLOCK_START * ite_block, *temp_block; if ( !mem_Manager ) { return; } ite_block = mem_Manager->block_list; while ( ite_block ) { temp_block = ite_block; ite_block = ite_block->next; free ( ( void * ) temp_block ); } free ( ( void * ) mem_Manager ); } void * getItem ( MEM_MANAGER * mem_Manager ) { RECYCLE_MARK * mark; //this is the type of return value BLOCK_START * block; if ( !mem_Manager ) { return NULL; } if ( mem_Manager->recycle_list ) { mark = mem_Manager->recycle_list; mem_Manager->recycle_list = mark->next; return mark; } mem_Manager->counter++; if ( !mem_Manager->block_list || mem_Manager->index_in_block == mem_Manager->items_per_block ) { //pthread_mutex_lock(&gmutex); block = ckalloc ( sizeof ( BLOCK_START ) + mem_Manager->items_per_block * mem_Manager->item_size ); //mem_Manager->counter += sizeof(BLOCK_START)+mem_Manager->items_per_block*mem_Manager->item_size; //pthread_mutex_unlock(&gmutex); block->next = mem_Manager->block_list; mem_Manager->block_list = block; mem_Manager->index_in_block = 1; return ( RECYCLE_MARK * ) ( ( void * ) block + sizeof ( BLOCK_START ) ); } block = mem_Manager->block_list; return ( RECYCLE_MARK * ) ( ( void * ) block + sizeof ( BLOCK_START ) + mem_Manager->item_size * ( mem_Manager->index_in_block++ ) ); } void returnItem ( MEM_MANAGER * mem_Manager, void * item ) { RECYCLE_MARK * mark; mark = item; mark->next = mem_Manager->recycle_list; mem_Manager->recycle_list = mark; } soapdenovo2-240+dfsg.orig/standardPregraph/iterate.c0000644000000000000000000017267312166703654021320 0ustar rootroot/* * iterate.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" static Kmer * kmerBuffer; static ubyte8 * hashBanBuffer; static char * flagBuffer; static int buffer_size = 100000000;//2013-5-13 long long foundcount = 0; long long notfoundcount = 0; long long newfoundcount = 0; long long newnotfoundcount = 0; long long edgeaddnumber = 0; unsigned int ** arcBuffer; unsigned int arcBufferCount = 0; unsigned int ** delarcBuffer; unsigned int delarcBufferCount = 0; static void forward ( unsigned int index, int first ); //Fresh preGraphBasic to record the original message and the multikmer message. void freshpreGraphBasic ( boolean iterate, int maxk, char * graph ) { char name[256], line[256]; FILE * fp; int num_kmer; char ch; int min = 0, max = 0; int numed = 0; int maxreadlen = 0, minreadlen = 0, maxnamelen = 0; sprintf ( name, "%s.preGraphBasic", graph ); fp = ckopen ( name, "r" ); while ( fgets ( line, sizeof ( line ), fp ) != NULL ) { if ( line[0] == 'V' ) { sscanf ( line + 6, "%d %c %d", &num_kmer, &ch, &min ); } else if ( line[0] == 'E' ) { sscanf ( line + 5, "%d", &numed ); } else if ( line[0] == 'M' ) { sscanf ( line, "MaxReadLen %d MinReadLen %d MaxNameLen %d", &maxreadlen, &minreadlen, &maxnamelen ); } else if ( line[0] == 'B' ) { if ( line[7] == 'V' ) { sscanf ( line, "Backup VERTEX %d %c %d", &num_kmer, &ch, &min ); } else if ( line[7] == 'E' ) { sscanf ( line, "Backup EDGEs %d", &numed ); } else if ( line[7] == 'M' ) { sscanf ( line, "Backup MaxReadLen %d MinReadLen %d MaxNameLen %d", &maxreadlen, &minreadlen, &maxnamelen ); } } } fclose ( fp ); sprintf ( name, "%s.preGraphBasic", graph ); fp = ckopen ( name, "w" ); if ( iterate ) { fprintf ( fp, "VERTEX %d K %d\n", num_vt, maxk ); fprintf ( fp, "\nEDGEs %d\n", num_ed ); fprintf ( fp, "\nMaxReadLen %d MinReadLen %d MaxNameLen %d\n", maxreadlen, minreadlen, maxnamelen ); fprintf ( fp, "\nBackup VERTEX %d K %d\n", num_kmer, min ); fprintf ( fp, "\nBackup EDGEs %d\n", numed ); fprintf ( fp, "\nBackup MaxReadLen %d MinReadLen %d MaxNameLen %d\n", maxreadlen, minreadlen, maxnamelen ); } else { fprintf ( fp, "VERTEX %d K %d\n", num_kmer, min ); fprintf ( fp, "\nEDGEs %d\n", numed ); fprintf ( fp, "\nMaxReadLen %d MinReadLen %d MaxNameLen %d\n", maxreadlen, minreadlen, maxnamelen ); } fclose ( fp ); } #ifdef MER127 // kmer1 = kmer1 | kmer2 inline Kmer KmerOr ( Kmer kmer1, Kmer kmer2 ) { kmer1.high1 |= kmer2.high1; kmer1.low1 |= kmer2.low1; kmer1.high2 |= kmer2.high2; kmer1.low2 |= kmer2.low2; return kmer1; } //Add ch at the head of prev. inline Kmer KmerPlusHead ( Kmer prev, char ch, int len ) { Kmer word; word.high1 = word.low1 = word.high2 = word.low2 = 0; if ( 2 * len < 64 ) { word.low2 = ch & 0x3; word.low2 <<= ( 2 * len ); } else if ( 2 * len < 128 ) { word.high2 = ch & 0x3; word.high2 <<= ( 2 * len - 64 ); } else if ( 2 * len < 192 ) { word.low1 = ch & 0x3; word.low1 <<= ( 2 * len - 128 ); } else { word.high1 = ch & 0x3; word.high1 <<= ( 2 * len - 192 ); } word = KmerOr ( word, prev ); return word; } //Add ch at the tail of prev. inline Kmer KmerPlusTail ( Kmer prev, char ch ) { Kmer word = KmerLeftBitMoveBy2 ( prev ); word.low2 += ch & 0x3; return word; } static const Kmer kmerZero = { 0, 0, 0, 0 }; #else //kmer1 = kmer1 | kmer2 Kmer KmerOr ( Kmer kmer1, Kmer kmer2 ) { kmer1.high |= kmer2.high; kmer1.low |= kmer2.low; return kmer1; } //Add ch at the head of prev. Kmer KmerPlusHead ( Kmer prev, char ch, int len ) { Kmer word; word.high = word.low = 0; if ( 2 * len < 64 ) { word.low = ch & 0x3; word.low <<= ( 2 * len ); } else { word.high = ch & 0x3; word.high <<= ( 2 * len - 64 ); } word = KmerOr ( word, prev ); return word; } //Add ch at the tail of prev. inline Kmer KmerPlusTail ( Kmer prev, char ch ) { Kmer word = KmerLeftBitMoveBy2 ( prev ); word.low += ch & 0x3; return word; } static const Kmer kmerZero = { 0, 0 }; #endif /************************************************* Function: getFromKmer Description: Get front (k+1)mer of edge. Input: 1. index : index in edge array Output: None. Return: (k+1)mer at the front. *************************************************/ Kmer getFromKmer ( unsigned int index ) { Kmer temp = kmerZero; temp = vt_array[edge_array[index].from_vt].kmer; int i = 0; char c; for ( i = 0; i < step; ++i ) { c = getCharInTightString ( edge_array[index].seq, i ); temp = KmerPlusTail ( temp, c ); } return temp; } /************************************************* Function: getToKmer Description: Get last (k+1)mer of edge. Input: 1. index : index in edge array Output: None. Return: (k+1)mer at the end. *************************************************/ Kmer getToKmer ( unsigned int index ) { Kmer temp = kmerZero; Kmer temp2 = kmerZero; int len = edge_array[index].length - overlaplen + step; char c; temp = vt_array[edge_array[index].to_vt].kmer; temp2 = vt_array[edge_array[index].from_vt].kmer; int i = 0; if ( len >= step ) { for ( i = 0; i < step; ++i ) { c = getCharInTightString ( edge_array[index].seq, len - i - 1 ); temp = KmerPlusHead ( temp, c, i + overlaplen - step ); } } else if ( len > 0 && len < step ) { for ( i = 0; i < len; ++i ) { c = getCharInTightString ( edge_array[index].seq, len - i - 1 ); temp = KmerPlusHead ( temp, c, i + overlaplen - step ); } for ( i = 0; i < ( step - len ); ++i ) { c = lastCharInKmer ( KmerRightBitMove ( temp2, i << 1 ) ); //.low2 & 0x3; temp = KmerPlusHead ( temp, c, i + overlaplen - step + len ); } } else { for ( i = 0; i < step; ++i ) { c = lastCharInKmer ( KmerRightBitMove ( temp2, ( i - len ) << 1 ) ); //.low2 & 0x3; temp = KmerPlusHead ( temp, c, i + overlaplen - step ); } } return temp; } //Only mark on edge. inline void delete1Edge ( unsigned int index ) { edge_array[index].deleted = 1; } /************************************************* Function: kmer2vtnew Description: Updates kmer edge to (k+1)mer edge. Input: 1. index : edge index in array Output: None. Return: index of new kmer set. -1 if not found. *************************************************/ int kmer2vtnew ( unsigned int index, int from ) { Kmer kmer; Kmer bal_word; int vt_id; int found = 0; kmer_t2 * node = NULL; if ( from ) { kmer = getFromKmer ( index ); } else { kmer = getToKmer ( index ); } bal_word = reverseComplement ( kmer, overlaplen ); if ( KmerSmaller ( kmer, bal_word ) ) { vt_id = bisearch ( &vt_arraynew[0], num_vtnew, kmer ); if ( vt_id < 0 ) { ++notfoundcount; fprintf ( stderr, "Updating edge, small vertex " ); printKmerSeq ( stderr, kmer ); fprintf ( stderr, " is not found, it's twin is " ); printKmerSeq ( stderr, reverseComplement ( kmer, overlaplen ) ); fprintf ( stderr, " .\n" ); found = search_kmerset2 ( KmerSetsNew, kmer, &node ); if ( found ) { fprintf ( stderr, "The kmer is in kmer set but not in vt_array.\n" ); } else { fprintf ( stderr, "The kmer is not in kmer set and vt_array.\n" ); } } else { ++foundcount; } return vt_id; } else { vt_id = bisearch ( &vt_arraynew[0], num_vtnew, bal_word ); if ( vt_id >= 0 ) { vt_id += num_vtnew; ++foundcount; } else { ++notfoundcount; fprintf ( stderr, "Updating edge, big vertex " ); printKmerSeq ( stderr, reverseComplement ( bal_word, overlaplen ) ); fprintf ( stderr, " is not found, it's twin is " ); printKmerSeq ( stderr, bal_word ); fprintf ( stderr, " .\n" ); found = search_kmerset2 ( KmerSetsNew, bal_word, &node ); if ( found ) { fprintf ( stderr, "The kmer is in kmer set but not in vt_array.\n" ); } else { fprintf ( stderr, "The kmer is not in kmer set and vt_array.\n" ); } } return vt_id; } } /************************************************* Function: update1Edge Description: Updates kmer edge to (k+1)mer edge. Input: 1. index : edge index in array Output: None. Return: None. *************************************************/ void update1Edge ( unsigned int index ) { int templength = edge_array[index].length; int i = 0; int temp_from_vt; int temp_to_vt; char * tightSeq = NULL; temp_from_vt = kmer2vtnew ( index, 1 ); temp_to_vt = kmer2vtnew ( index, 0 ); if ( temp_from_vt < 0 || temp_to_vt < 0 ) { destroyEdge2 ( index ); delete1Edge ( index ); fprintf ( stderr, "Warning : Kmer is not found, from_vt %d, to_vt %d.\n", temp_from_vt, temp_to_vt ); return; } edge_array[index].from_vt = temp_from_vt; edge_array[index].to_vt = temp_to_vt; edge_array[index].length -= step; if ( edge_array[index].length == 1 || edge_array[index].length == 0 ) { edge_array[index].cvg = 0; } tightSeq = ( char * ) ckalloc ( ( edge_array[index].length / 4 + 1 ) * sizeof ( char ) ); for ( i = 0; i < edge_array[index].length; ++i ) { writeChar2tightString ( getCharInTightString ( edge_array[index].seq, i + step ), tightSeq, i ); } if ( edge_array[index].seq ) { free ( ( void * ) edge_array[index].seq ); edge_array[index].seq = NULL; } edge_array[index].seq = tightSeq; edge_array[index].rv = NULL; ARC * currArc = edge_array[index].arcs; ARC * tempArc = NULL; while ( currArc ) { tempArc = currArc; currArc = currArc->next; edge_array[index].arcs = deleteArc ( edge_array[index].arcs, tempArc ); } edge_array[index].arcs = NULL; edge_array[index].markers = NULL; } /************************************************* Function: getNewHash Description: Gets (k+1)mer hash set. Input: None. Output: None. Return: None. *************************************************/ void getNewHash() { unsigned int i; ubyte8 hash_ban, bal_hash_ban; Kmer word, bal_word; kmer_t2 * node; unsigned int deletecount = 0; kmer_cnew = 0; kmerBuffer = ( Kmer * ) ckalloc ( 2 * ( num_ed + 1 ) * sizeof ( Kmer ) ); hashBanBuffer = ( ubyte8 * ) ckalloc ( 2 * ( num_ed + 1 ) * sizeof ( ubyte8 ) ); edge_id = ( unsigned int * ) ckalloc ( 2 * ( num_ed + 1 ) * sizeof ( unsigned int ) ); //00 : big to 01 : big from,10 : small to, 11 : small from flagBuffer = ( boolean * ) ckalloc ( 2 * ( num_ed + 1 ) * sizeof ( boolean ) ); for ( i = 1; i <= num_ed; ++i ) { if ( edge_array[i].deleted ) { continue; } if ( edge_array[i].length < step ) //= { destroyEdge2 ( i ); delete1Edge ( i ); deletecount++; continue; } word = kmerZero; bal_word = kmerZero; if ( edge_array[i].length == step ) { word = getFromKmer ( i ); bal_word = reverseComplement ( word, overlaplen ); if ( KmerSmaller ( word, bal_word ) ) { hash_ban = hash_kmer ( word ); hashBanBuffer[kmer_cnew] = hash_ban; kmerBuffer[kmer_cnew] = word; flagBuffer[kmer_cnew] = 4; } else { bal_hash_ban = hash_kmer ( bal_word ); hashBanBuffer[kmer_cnew] = bal_hash_ban; kmerBuffer[kmer_cnew] = bal_word; flagBuffer[kmer_cnew] = 5; } edge_id[kmer_cnew] = i; ++kmer_cnew; continue; } if ( edge_array[i].bal_edge == 1 ) { word = getFromKmer ( i ); bal_word = reverseComplement ( word, overlaplen ); if ( KmerSmaller ( word, bal_word ) ) { hash_ban = hash_kmer ( word ); hashBanBuffer[kmer_cnew] = hash_ban; kmerBuffer[kmer_cnew] = word; flagBuffer[kmer_cnew] = 6; } else { bal_hash_ban = hash_kmer ( bal_word ); hashBanBuffer[kmer_cnew] = bal_hash_ban; kmerBuffer[kmer_cnew] = bal_word; flagBuffer[kmer_cnew] = 7; } edge_id[kmer_cnew] = i; ++kmer_cnew; word = kmerZero; bal_word = kmerZero; word = getToKmer ( i ); bal_word = reverseComplement ( word, overlaplen ); if ( KmerSmaller ( word, bal_word ) ) { hash_ban = hash_kmer ( word ); hashBanBuffer[kmer_cnew] = hash_ban; kmerBuffer[kmer_cnew] = word; flagBuffer[kmer_cnew] = 8; } else { bal_hash_ban = hash_kmer ( bal_word ); hashBanBuffer[kmer_cnew] = bal_hash_ban; kmerBuffer[kmer_cnew] = bal_word; flagBuffer[kmer_cnew] = 9; } edge_id[kmer_cnew] = i; ++kmer_cnew; continue; } word = getFromKmer ( i ); bal_word = reverseComplement ( word, overlaplen ); if ( KmerSmaller ( word, bal_word ) ) { hash_ban = hash_kmer ( word ); hashBanBuffer[kmer_cnew] = hash_ban; kmerBuffer[kmer_cnew] = word; flagBuffer[kmer_cnew] = 3; } else { bal_hash_ban = hash_kmer ( bal_word ); hashBanBuffer[kmer_cnew] = bal_hash_ban; kmerBuffer[kmer_cnew] = bal_word; flagBuffer[kmer_cnew] = 1; } edge_id[kmer_cnew] = i; ++kmer_cnew; word = kmerZero; bal_word = kmerZero; word = getToKmer ( i ); bal_word = reverseComplement ( word, overlaplen ); if ( KmerSmaller ( word, bal_word ) ) { hash_ban = hash_kmer ( word ); hashBanBuffer[kmer_cnew] = hash_ban; kmerBuffer[kmer_cnew] = word; flagBuffer[kmer_cnew] = 2; } else { bal_hash_ban = hash_kmer ( bal_word ); hashBanBuffer[kmer_cnew] = bal_hash_ban; kmerBuffer[kmer_cnew] = bal_word; flagBuffer[kmer_cnew] = 0; } edge_id[kmer_cnew] = i; ++kmer_cnew; } fprintf ( stderr, "%lld edge(s) deleted in length of 0.\n", deletecount ); KmerSetsNew = init_kmerset2 ( 1024, 0.77f ); for ( i = 0; i < kmer_cnew; ++i ) { put_kmerset2 ( KmerSetsNew, kmerBuffer[i], edge_id[i], flagBuffer[i], &node ); } num_vtnew = count_kmerset2 ( KmerSetsNew ); fprintf ( stderr, "%u new kmer(s).\n", num_vtnew ); free ( kmerBuffer ); kmerBuffer = NULL; free ( hashBanBuffer ); hashBanBuffer = NULL; free ( edge_id ); edge_id = NULL; free ( flagBuffer ); flagBuffer = NULL; } /************************************************* Function: getNewVertex Description: Gets (k+1)mer vertex from hash. Input: None. Output: None. Return: None. *************************************************/ void getNewVertex() { unsigned int i; Kmer word, bal_word; vt_arraynew = ( VERTEX * ) ckalloc ( 4 * ( num_vtnew + 1 ) * sizeof ( VERTEX ) ); num_kmer_limit = 4 * num_vtnew; KmerSet2 * set; kmer_t2 * node; unsigned int count = 0; set = KmerSetsNew; set->iter_ptr = 0; while ( set->iter_ptr < set->size ) { if ( !is_kmer_entity_null ( set->flags, set->iter_ptr ) ) { node = set->array + set->iter_ptr; if ( node ) { word = node->seq; bal_word = reverseComplement ( word, overlaplen ); if ( KmerSmaller ( word, bal_word ) ) { vt_arraynew[count].kmer = word; } else { vt_arraynew[count].kmer = bal_word; } ++count; } } set->iter_ptr ++; } num_vtnew = count; qsort ( &vt_arraynew[0], num_vtnew, sizeof ( vt_arraynew[0] ), cmp_vertex ); for ( i = 0; i < num_vtnew; ++i ) { bal_word = reverseComplement ( vt_arraynew[i].kmer, overlaplen ); vt_arraynew[i + num_vtnew].kmer = bal_word; } } /************************************************* Function: buildGraphHash Description: 1. Builds (k+1)mer graph in memory based on kmer graph. 2. Gets (k+1)mer hash set. 3. Gets (k+1)mer vertex. 4. Updates kmer edges to (k+1)mer edges. Input: None. Output: None. Return: None. *************************************************/ void buildGraphHash() { unsigned int i; unsigned int count = 0; //use from kmer & to kmer to build hash fprintf ( stderr, "Construct new kmer hash.\n" ); getNewHash(); getNewVertex(); foundcount = 0; notfoundcount = 0; for ( i = 1; i <= num_ed; ++i ) { if ( edge_array[i].deleted ) { continue; } if ( edge_array[i].length < step ) //= { destroyEdge2 ( i ); delete1Edge ( i ); continue; } //update twin edge together update1Edge ( i ); ++count; } if ( notfoundcount ) { fprintf ( stderr, "There are %lld kmer(s) found.\n", foundcount ); fprintf ( stderr, "There are %lld kmer(s) not found.\n", notfoundcount ); } fprintf ( stderr, "%u edge(s) updated to %dmer edge.\n", count, overlaplen ); if ( vt_array ) { free ( ( void * ) vt_array ); vt_array = NULL; } vt_array = vt_arraynew; num_vt = num_vtnew; } //FILE *tempF = NULL; /************************************************* Function: addArc Description: 1. Re-build arcs by reads. // 2. Output selected reads if -r is set(keepReadFile is true). Input: 1. libfile : the reads config file 2. graph : the output prefix 3. flag : whether the selected reads file exist 4. last : whether it's the last iterate 5. maxk : the max kmer when using multikmer // 6. keepReadFile : keep tmp reads file that selected for building arc Output: 1. *.read : the selected reads that use for assembly Return: None. *************************************************/ void addArc ( char * libfile, char * graph, int flag, int last, int maxk ) //, boolean keepReadFile { /* if(!flag) { char readSeqName[256]; sprintf(readSeqName,"%s.read",graph); tempF=fopen(readSeqName,"r"); } else { tempF = NULL; } */ if ( flag ) // || tempF) { // if(tempF) // fclose(tempF); Read2edge2 ( libfile, graph, last, maxk ); //, keepReadFile } else { Read2edge ( libfile, graph, maxk ); } unsigned int i; for ( i = 1; i <= num_ed; ++i ) { if ( edge_array[i].deleted ) { destroyEdge2 ( i ); } } removeDeadArcs2(); } /************************************************* Function: kmer2edge Description: Extend edges. Input: 1. from : whether changing from kmer 2. index : index of edge 3. ch : next char to extend 4. backup : backup char Output: None. Return: Index of new extended kmer. *************************************************/ int kmer2edge ( int from, unsigned int index, char ch, char * backup ) { //add 1 kmer to edge Kmer kmer = kmerZero, bal_word = kmerZero; int vt_id = 0; char * tightSeq = NULL; // if(edge_array[index].arcs && edge_array[edge_array[index].arcs->to_ed].length <= 1) // return; if ( from <= 2 ) { kmer = vt_array[edge_array[index].from_vt].kmer; *backup = lastCharInKmer ( kmer ); //.low2 & 3; kmer = prevKmer ( kmer, ch ); } else { kmer = vt_array[edge_array[index].to_vt].kmer; *backup = ch; kmer = nextKmer ( kmer, ch ); } bal_word = reverseComplement ( kmer, overlaplen ); if ( KmerSmaller ( kmer, bal_word ) ) { vt_id = bisearch ( &vt_array[0], num_vt, kmer ); if ( vt_id < 0 ) { ++newnotfoundcount; fprintf ( stderr, "When extending edge 'small vertex' is not found, edge %d kmer ", index ); printKmerSeq ( stderr, kmer ); fprintf ( stderr, " , it's twin " ); printKmerSeq ( stderr, bal_word ); fprintf ( stderr, " .\n" ); } else { ++newfoundcount; } } else { vt_id = bisearch ( &vt_array[0], num_vt, bal_word ); if ( vt_id >= 0 ) { vt_id += num_vt; ++newfoundcount; } else { ++newnotfoundcount; fprintf ( stderr, "When extending edge 'big vertex' is not found, edge %d kmer ", index ); printKmerSeq ( stderr, kmer ); fprintf ( stderr, " , it's twin " ); printKmerSeq ( stderr, bal_word ); fprintf ( stderr, " .\n" ); } } if ( vt_id < 0 ) { return vt_id; } char backup1 = 0; char ch1 = int_comp ( ch ); Kmer kmer1 = kmerZero, bal_word1 = kmerZero; int vt_id1 = 0; char * tightSeq1 = NULL; if ( from <= 2 ) { kmer1 = vt_array[edge_array[index + 1].to_vt].kmer; backup1 = ch1; kmer1 = nextKmer ( kmer1, ch1 ); } else { kmer1 = vt_array[edge_array[index + 1].from_vt].kmer; backup1 = lastCharInKmer ( kmer1 ); //.low2 & 3; kmer1 = prevKmer ( kmer1, ch1 ); } bal_word1 = reverseComplement ( kmer1, overlaplen ); if ( KmerSmaller ( kmer1, bal_word1 ) ) { vt_id1 = bisearch ( &vt_array[0], num_vt, kmer1 ); if ( vt_id1 < 0 ) { ++newnotfoundcount; fprintf ( stderr, "When extending edge 'small vertex' is not found, edge %d kmer ", index + 1 ); printKmerSeq ( stderr, kmer1 ); fprintf ( stderr, " , it's twin " ); printKmerSeq ( stderr, bal_word1 ); fprintf ( stderr, " .\n" ); } else { ++newfoundcount; } } else { vt_id1 = bisearch ( &vt_array[0], num_vt, bal_word1 ); if ( vt_id1 >= 0 ) { vt_id1 += num_vt; ++newfoundcount; } else { ++newnotfoundcount; fprintf ( stderr, "When extending edge big vertex is not found, edge %d kmer ", index + 1 ); printKmerSeq ( stderr, kmer1 ); fprintf ( stderr, " , it's twin " ); printKmerSeq ( stderr, bal_word1 ); fprintf ( stderr, " .\n" ); } } if ( vt_id1 < 0 ) { return vt_id1; } int i = 0; if ( from <= 2 ) { //small edge_array[index].from_vt = vt_id; tightSeq = ( char * ) ckalloc ( ( ( edge_array[index].length + 1 ) / 4 + 1 ) * sizeof ( char ) ); writeChar2tightString ( *backup, tightSeq, 0 ); for ( i = 0; i < edge_array[index].length; ++i ) { writeChar2tightString ( getCharInTightString ( edge_array[index].seq, i ), tightSeq, i + 1 ); } if ( edge_array[index].seq ) { free ( ( void * ) edge_array[index].seq ); edge_array[index].seq = NULL; } edge_array[index].seq = tightSeq; edge_array[index].length += 1; //big edge_array[index + 1].to_vt = vt_id1; tightSeq1 = ( char * ) ckalloc ( ( ( edge_array[index + 1].length + 1 ) / 4 + 1 ) * sizeof ( char ) ); for ( i = 0; i < edge_array[index + 1].length; ++i ) { writeChar2tightString ( getCharInTightString ( edge_array[index + 1].seq, i ), tightSeq1, i ); } writeChar2tightString ( backup1, tightSeq1, i ); if ( edge_array[index + 1].seq ) { free ( ( void * ) edge_array[index + 1].seq ); edge_array[index + 1].seq = NULL; } edge_array[index + 1].seq = tightSeq1; edge_array[index + 1].length += 1; } else { //small edge_array[index].to_vt = vt_id; tightSeq = ( char * ) ckalloc ( ( ( edge_array[index].length + 1 ) / 4 + 1 ) * sizeof ( char ) ); for ( i = 0; i < edge_array[index].length; ++i ) { writeChar2tightString ( getCharInTightString ( edge_array[index].seq, i ), tightSeq, i ); } writeChar2tightString ( *backup, tightSeq, i ); if ( edge_array[index].seq ) { free ( ( void * ) edge_array[index].seq ); edge_array[index].seq = NULL; } edge_array[index].seq = tightSeq; edge_array[index].length += 1; //big edge_array[index + 1].from_vt = vt_id1; tightSeq1 = ( char * ) ckalloc ( ( ( edge_array[index + 1].length + 1 ) / 4 + 1 ) * sizeof ( char ) ); writeChar2tightString ( backup1, tightSeq1, 0 ); for ( i = 0; i < edge_array[index + 1].length; ++i ) { writeChar2tightString ( getCharInTightString ( edge_array[index + 1].seq, i ), tightSeq1, i + 1 ); } if ( edge_array[index + 1].seq ) { free ( ( void * ) edge_array[index + 1].seq ); edge_array[index + 1].seq = NULL; } edge_array[index + 1].seq = tightSeq1; edge_array[index + 1].length += 1; } return 0; } //Add edge and reverse complement. void addEdge ( unsigned int from, unsigned int to, char ch, int bal_edge, unsigned int cvg ) { if ( num_ed_temp + 1 > num_ed_limit ) { unsigned int new_num_ed = num_ed_limit * 1.2; edge_array = ( EDGE * ) ckrealloc ( edge_array, ( new_num_ed + 1 ) * sizeof ( EDGE ), ( num_ed_limit + 1 ) * sizeof ( EDGE ) ); num_ed_limit = new_num_ed; int j; for ( j = num_ed_temp + 1; j <= num_ed_limit; j++ ) { edge_array[j].seq = NULL; } fprintf ( stderr, "Realloc edge array.\n" ); } char * tightSeq = ( char * ) ckalloc ( sizeof ( char ) ); writeChar2tightString ( ch, tightSeq, 0 ); edge_array[num_ed_temp + 1].from_vt = from; edge_array[num_ed_temp + 1].to_vt = to; edge_array[num_ed_temp + 1].length = 1; edge_array[num_ed_temp + 1].cvg = cvg; edge_array[num_ed_temp + 1].bal_edge = bal_edge; edge_array[num_ed_temp + 1].multi = 0; edge_array[num_ed_temp + 1].deleted = 0; edge_array[num_ed_temp + 1].flag = 0; if ( edge_array[num_ed_temp + 1].seq ) { free ( edge_array[num_ed_temp + 1].seq ); } edge_array[num_ed_temp + 1].seq = tightSeq; edge_array[num_ed_temp + 1].rv = NULL; edge_array[num_ed_temp + 1].arcs = NULL; edge_array[num_ed_temp + 1].markers = NULL; ++num_ed_temp; } //Check whether kmers are equal to the front kmer and last kmer of the edge. boolean checkEqual ( unsigned int from, unsigned int to, char ch, unsigned int index, unsigned int * getIndex ) { if ( edge_array[index].length == 1 && ( ( edge_array[index].from_vt == from && edge_array[index].to_vt == to ) ) ) { return true; } return false; } //Whether edge exist in set. boolean EdgeExist ( unsigned int from, unsigned int to, char ch, kmer_t2 * node, unsigned int * index ) { int i = 0; EDGEID * temp = node->edgeId; while ( temp ) { *index = temp->edge; if ( checkEqual ( from, to, ch, temp->edge, index ) ) { return true; } temp = temp->next; } return false; } //Update edgeId in node. void updateNode ( kmer_t2 * node, kmer_t2 * node1 ) { struct edgeID * edgeid; edgeid = ( struct edgeID * ) malloc ( sizeof ( struct edgeID ) ); edgeid->edge = num_ed_temp + 1; edgeid->flag = 0; edgeid->next = NULL; if ( node->edgeId ) { edgeid->next = node->edgeId; } node->edgeId = edgeid; node->count++; edgeid = ( struct edgeID * ) malloc ( sizeof ( struct edgeID ) ); edgeid->edge = num_ed_temp + 2; edgeid->flag = 1; edgeid->next = NULL; if ( node->edgeId ) { edgeid->next = node->edgeId; } node->edgeId = edgeid; node->count++; edgeid = ( struct edgeID * ) malloc ( sizeof ( struct edgeID ) ); edgeid->edge = num_ed_temp + 1; edgeid->flag = 2; edgeid->next = NULL; if ( node1->edgeId ) { edgeid->next = node1->edgeId; } node1->edgeId = edgeid; node1->count++; edgeid = ( struct edgeID * ) malloc ( sizeof ( struct edgeID ) ); edgeid->edge = num_ed_temp + 2; edgeid->flag = 3; edgeid->next = NULL; if ( node1->edgeId ) { edgeid->next = node1->edgeId; } node1->edgeId = edgeid; node1->count++; } /************************************************* Function: checkindegree Description: 1. Check whether it can be solved or not. 2. Add edge when necessary. Input: 1. from : whether it's 'from kmer' 2. from_ed : index of 'from edge' 3. to_ed : index of 'to edge' 4. node : node of 'last kmer' of 'from edge' 5. node1 : node of 'front kmer' of 'to edge' 6. maxk : max kmer Output: None. Return: None. *************************************************/ void checkindegree ( int from, unsigned int from_ed, unsigned int to_ed, kmer_t2 * node, kmer_t2 * node1, int maxk ) { int arcLeft_n = 0; int arcRight_n = 0; boolean exist = false; char ch = lastCharInKmer ( vt_array[edge_array[to_ed].from_vt].kmer ); //.low2 & 3; char backup = lastCharInKmer ( KmerRightBitMove ( vt_array[edge_array[from_ed].to_vt].kmer, ( overlaplen - 1 ) << 1 ) ); //.low2 & 3; unsigned int index; ARC * originalArc = NULL; if ( from <= 2 ) { //out->in > 1 arcCount2 ( from_ed, &arcRight_n ); if ( arcRight_n > 1 ) { exist = EdgeExist ( edge_array[from_ed].to_vt, edge_array[to_ed].from_vt, ch, node, &index ); if ( !exist ) { updateNode ( node, node1 ); originalArc = getArcBetween ( from_ed, to_ed ); edgeaddnumber += 2; addEdge ( edge_array[from_ed].to_vt, edge_array[to_ed].from_vt, ch, 2, originalArc->multiplicity * 10 ); // if(overlaplen + step > maxk) { arcBuffer[0][arcBufferCount] = from_ed; arcBuffer[1][arcBufferCount] = num_ed_temp; arcBuffer[2][arcBufferCount++] = to_ed; } addEdge ( edge_array[getTwinEdge ( to_ed )].to_vt, edge_array[getTwinEdge ( from_ed )].from_vt, int_comp ( backup ), 0, originalArc->multiplicity * 10 ); } else { // if(overlaplen + step > maxk) { arcBuffer[0][arcBufferCount] = from_ed; arcBuffer[1][arcBufferCount] = index; arcBuffer[2][arcBufferCount++] = to_ed; } } } } else { //out->in > 1 arcCount2 ( getTwinEdge ( to_ed ), &arcLeft_n ); if ( arcLeft_n > 1 ) { exist = EdgeExist ( edge_array[from_ed].to_vt, edge_array[to_ed].from_vt, ch, node, &index ); if ( !exist ) { updateNode ( node, node1 ); originalArc = getArcBetween ( from_ed, to_ed ); edgeaddnumber += 2; addEdge ( edge_array[from_ed].to_vt, edge_array[to_ed].from_vt, ch, 2, originalArc->multiplicity * 10 ); // if(overlaplen + step > maxk) { arcBuffer[0][arcBufferCount] = from_ed; arcBuffer[1][arcBufferCount] = num_ed_temp; arcBuffer[2][arcBufferCount++] = to_ed; } addEdge ( edge_array[getTwinEdge ( to_ed )].to_vt, edge_array[getTwinEdge ( from_ed )].from_vt, int_comp ( backup ), 0, originalArc->multiplicity * 10 ); } else { // if(overlaplen + step > maxk) { arcBuffer[0][arcBufferCount] = from_ed; arcBuffer[1][arcBufferCount] = index; arcBuffer[2][arcBufferCount++] = to_ed; } } } } } //Add arc between two edges. static void add1Arc2 ( unsigned int from_ed, unsigned int to_ed, unsigned int weight ) { if ( edge_array[from_ed].to_vt != edge_array[to_ed].from_vt ) { fprintf ( stderr, "Warning : Inconsistant joins between %d and %d.\n", from_ed, to_ed ); } unsigned int bal_fe = getTwinEdge ( from_ed ); unsigned int bal_te = getTwinEdge ( to_ed ); // fprintf(stderr, "from %u, bal %u\n", from_ed, bal_fe); // fprintf(stderr, "to %u, bal %u\n", to_ed, bal_te); if ( from_ed > num_ed_temp || to_ed > num_ed_temp || bal_fe > num_ed_temp || bal_te > num_ed_temp ) { fprintf ( stderr, "Error : Edge id is out of range.\n" ); return; } ARC * parc, *bal_parc; //both arcs already exist parc = getArcBetween ( from_ed, to_ed ); if ( parc ) { bal_parc = parc->bal_arc; parc->multiplicity += weight; bal_parc->multiplicity += weight; return; } //create new arcs parc = allocateArc ( to_ed ); parc->multiplicity = weight; parc->prev = NULL; if ( edge_array[from_ed].arcs ) { edge_array[from_ed].arcs->prev = parc; } parc->next = edge_array[from_ed].arcs; edge_array[from_ed].arcs = parc; // A->A' if ( bal_te == from_ed ) { parc->bal_arc = parc; parc->multiplicity += weight; return; } bal_parc = allocateArc ( bal_fe ); bal_parc->multiplicity = weight; bal_parc->prev = NULL; if ( edge_array[bal_te].arcs ) { edge_array[bal_te].arcs->prev = bal_parc; } bal_parc->next = edge_array[bal_te].arcs; edge_array[bal_te].arcs = bal_parc; //link them to each other parc->bal_arc = bal_parc; bal_parc->bal_arc = parc; } //Count step between two neighbour edges. int countstep ( unsigned int to_vt, unsigned int from_vt ) { if ( to_vt == from_vt ) { return 0; } Kmer to, from; Kmer filtertemp; to = vt_array[to_vt].kmer; from = vt_array[from_vt].kmer; int i = 0; for ( i = 0; i <= nowstep2; ++i ) { filtertemp = createFilter ( overlaplen - i ); if ( KmerEqual ( KmerRightBitMove ( from, i << 1 ), KmerAnd ( to, filtertemp ) ) ) { return i; } } return -1; } /************************************************* Function: freshEdge Description: Extend edges or add edges. Input: 1. maxk : max kmer of multi kmer Output: None. Return: None. *************************************************/ void freshEdge ( int maxk ) { unsigned int i = 0, j = 0; boolean found = 0; kmer_t2 * node, *node1; int count = 0; char ch = 0; Kmer word, bal_word; int from_vt_id = 0, to_vt_id = 0; char from_backup, to_backup; char * tightSeq = NULL; int bal_ed = 0; int arcLeft_n = 0, arcRight_n = 0; ARC * temparc = NULL; unsigned int tempto_ed = 0; fprintf ( stderr, "There are %d edge(s).\n", num_ed ); // if(overlaplen + step > maxk) { arcBuffer = ( unsigned int ** ) ckalloc ( sizeof ( unsigned int * ) * 3 ); arcBuffer[0] = ( unsigned int * ) ckalloc ( sizeof ( unsigned int ) * num_ed * 3 ); arcBuffer[1] = ( unsigned int * ) ckalloc ( sizeof ( unsigned int ) * num_ed * 3 ); arcBuffer[2] = ( unsigned int * ) ckalloc ( sizeof ( unsigned int ) * num_ed * 3 ); } int count_noextend = 0; num_ed_temp = num_ed; for ( i = 1; i <= num_ed; ++i ) { if ( edge_array[i].deleted || EdSameAsTwin ( i ) ) { continue; } bal_ed = getTwinEdge ( i ); arcCount2 ( i, &arcRight_n ); arcCount2 ( bal_ed, &arcLeft_n ); if ( arcLeft_n == 1 ) { if ( edge_array[bal_ed].to_vt != edge_array[edge_array[bal_ed].arcs->to_ed].from_vt ) { ch = lastCharInKmer ( KmerRightBitMove ( vt_array[edge_array[getTwinEdge ( edge_array[bal_ed].arcs->to_ed )].to_vt].kmer, ( overlaplen - 1 ) << 1 ) ); //.low2 & 3; int temp = kmer2edge ( 1, i, ch, &from_backup ); if ( temp != 0 ) { count_noextend++; } } } else if ( arcLeft_n > 1 ) { word = vt_array[edge_array[i].from_vt].kmer; bal_word = reverseComplement ( word, overlaplen ); if ( KmerSmaller ( word, bal_word ) ) { found = search_kmerset2 ( KmerSetsNew, word, &node ); } else { found = search_kmerset2 ( KmerSetsNew, bal_word, &node ); } if ( !found ) { fprintf ( stderr, "When refreshing edges, 'from vertex' is not found, to_vt %d kmer ", edge_array[i].from_vt ); printKmerSeq ( stderr, vt_array[edge_array[i].from_vt].kmer ); fprintf ( stderr, " .\n" ); exit ( -1 ); } // if(overlaplen < maxk) { temparc = edge_array[bal_ed].arcs; while ( temparc ) { tempto_ed = getTwinEdge ( temparc->to_ed ); word = vt_array[edge_array[tempto_ed].to_vt].kmer; bal_word = reverseComplement ( word, overlaplen ); if ( KmerSmaller ( word, bal_word ) ) { found = search_kmerset2 ( KmerSetsNew, word, &node1 ); } else { found = search_kmerset2 ( KmerSetsNew, bal_word, &node1 ); } if ( !found ) { fprintf ( stderr, "When refreshing edges, 'to vertex' is not found, to_vt %d kmer ", edge_array[tempto_ed].to_vt ); printKmerSeq ( stderr, vt_array[edge_array[tempto_ed].to_vt].kmer ); fprintf ( stderr, " .\n" ); exit ( -1 ); } if ( node1 && node ) { checkindegree ( 1, tempto_ed, i, node1, node, maxk ); } temparc = temparc->next; } } } if ( arcRight_n == 1 ) { if ( edge_array[i].to_vt != edge_array[edge_array[i].arcs->to_ed].from_vt ) { ch = lastCharInKmer ( vt_array[edge_array[edge_array[i].arcs->to_ed].from_vt].kmer ); //.low2 & 3; int temp = kmer2edge ( 3, i, ch, &to_backup ); if ( temp != 0 ) { count_noextend++; } } } else if ( arcRight_n > 1 ) { word = vt_array[edge_array[i].to_vt].kmer; bal_word = reverseComplement ( word, overlaplen ); if ( KmerSmaller ( word, bal_word ) ) { found = search_kmerset2 ( KmerSetsNew, word, &node ); } else { found = search_kmerset2 ( KmerSetsNew, bal_word, &node ); } if ( !found ) { fprintf ( stderr, "When refreshing edges, 'to vertex' is not found, to_vt %d kmer ", edge_array[i].to_vt ); printKmerSeq ( stderr, vt_array[edge_array[i].to_vt].kmer ); fprintf ( stderr, " .\n" ); exit ( -1 ); } // if(overlaplen < maxk) { temparc = edge_array[i].arcs; while ( temparc ) { tempto_ed = temparc->to_ed; word = vt_array[edge_array[tempto_ed].from_vt].kmer; bal_word = reverseComplement ( word, overlaplen ); if ( KmerSmaller ( word, bal_word ) ) { found = search_kmerset2 ( KmerSetsNew, word, &node1 ); } else { found = search_kmerset2 ( KmerSetsNew, bal_word, &node1 ); } if ( !found ) { fprintf ( stderr, "When refreshing edges, 'from vertex' is not found, from_vt %d kmer ", edge_array[tempto_ed].from_vt ); printKmerSeq ( stderr, vt_array[edge_array[tempto_ed].from_vt].kmer ); fprintf ( stderr, " .\n" ); exit ( -1 ); } if ( node1 && node ) { checkindegree ( 3, i, tempto_ed, node, node1, maxk ); } temparc = temparc->next; } } } //two edge change at the same time ++i; } if ( count_noextend ) { fprintf ( stderr, "%d edge(s) not extended.\n", count_noextend ); } // if(overlaplen + step > maxk) { ARC * tempArc, *tempBalArc, *originalArc, *temp, *bal_temp; unsigned int from = 0; unsigned int mid = 0; unsigned int to = 0; int count_arcdelete = 0, count_arcadd = 0; int arcmulti = 0; int arcnotfound = 0; for ( i = 0; i < arcBufferCount; ++i ) { from = arcBuffer[0][i]; mid = arcBuffer[1][i]; to = arcBuffer[2][i]; if ( from > num_ed || mid > num_ed_temp || to > num_ed ) { fprintf ( stderr, "Error : Edge id is out of range.\n" ); exit ( -1 ); } originalArc = getArcBetween ( from, to ); if ( originalArc ) { arcmulti = originalArc->multiplicity; count_arcdelete++; edge_array[from].arcs = deleteArc ( edge_array[from].arcs, originalArc ); count_arcadd += 2; add1Arc2 ( from, mid, arcmulti ); add1Arc2 ( mid, to, arcmulti ); } else { originalArc = getArcBetween ( getTwinEdge ( to ), getTwinEdge ( from ) ); if ( originalArc ) { arcmulti = originalArc->multiplicity; count_arcdelete++; edge_array[getTwinEdge ( to )].arcs = deleteArc ( edge_array[getTwinEdge ( to )].arcs, originalArc ); } else { ++arcnotfound; arcmulti = 2; } count_arcadd += 2; add1Arc2 ( from, mid, arcmulti ); add1Arc2 ( mid, to, arcmulti ); } } fprintf ( stderr, "Add edges to the graph: %d arc(s) deleted, %d arc(s) added.\n", count_arcdelete, count_arcadd ); if ( arcnotfound ) { fprintf ( stderr, "Warning : %d arc(s) are not found when checking.\n", arcnotfound ); } arcBufferCount = 0; } num_ed = num_ed_temp; // if(overlaplen + step > maxk) { free ( arcBuffer[2] ); free ( arcBuffer[1] ); free ( arcBuffer[0] ); free ( arcBuffer ); } } //Copy edge from source to target. void copy1Edge ( EDGE * source, EDGE * target ) { target->from_vt = source->from_vt; target->to_vt = source->to_vt; target->length = source->length; target->cvg = source->cvg; target->multi = source->multi; if ( target->seq ) { free ( ( void * ) target->seq ); } target->seq = source->seq; source->seq = NULL; target->arcs = source->arcs; source->arcs = NULL; target->deleted = source->deleted; } //Check whether two bases are equal. int BaseEqual ( char ch1, char ch2 ) { if ( ch1 == ch2 ) { return 0; } else if ( ch1 > ch2 ) { return 1; } else { return -1; } } //Check whether two edges are equal. int EdgeEqual ( unsigned int prev, unsigned int next ) { int i = 0; int length = edge_array[prev].length; char ch1, ch2; int equal = 0; for ( i = 0; i < length; ++i ) { ch1 = int2base ( ( int ) getCharInTightString ( edge_array[prev].seq, i ) ); ch2 = int2base ( ( int ) getCharInTightString ( edge_array[next].seq, i ) ); if ( ( equal = BaseEqual ( ch1, ch2 ) ) ) { return equal; } } return 0; } /************************************************* Function: swapedge Description: Re-arrange the edges, swap smaller edges at front. Input: None. Output: None. Return: None. *************************************************/ void swapedge() { unsigned int i; ARC * arc, *bal_arc, *temp_arc; int count_swap = 0, count_equal = 0; for ( i = 1; i <= num_ed; ++i ) { if ( edge_array[i].deleted || EdSameAsTwin ( i ) ) { continue; } if ( EdSmallerThanTwin ( i ) ) { if ( KmerLarger ( vt_array[edge_array[i].from_vt].kmer, vt_array[edge_array[i + 1].from_vt].kmer ) ) { count_swap++; copyEdge ( i, num_ed + 1 + 1 ); copyEdge ( i + 1, num_ed + 1 ); copyEdge ( num_ed + 1, i ); copyEdge ( num_ed + 1 + 1, i + 1 ); edge_array[i].bal_edge = 2; edge_array[i + 1].bal_edge = 0; //take care of the arcs arc = edge_array[i].arcs; while ( arc ) { arc->bal_arc->to_ed = i + 1; arc = arc->next; } arc = edge_array[i + 1].arcs; while ( arc ) { arc->bal_arc->to_ed = i; arc = arc->next; } } else if ( KmerEqual ( vt_array[edge_array[i].from_vt].kmer, vt_array[edge_array[i + 1].from_vt].kmer ) ) { int temp = EdgeEqual ( i, i + 1 ); if ( temp == 0 ) { count_equal++; edge_array[i].bal_edge = 1; delete1Edge ( i + 1 ); //take care of the arcs arc = edge_array[i].arcs; while ( arc ) { arc->bal_arc->to_ed = i; arc = arc->next; } bal_arc = edge_array[i + 1].arcs; edge_array[i + 1].arcs = NULL; while ( bal_arc ) { temp_arc = bal_arc; bal_arc = bal_arc->next; if ( edge_array[i].arcs ) { edge_array[i].arcs->prev = temp_arc; } temp_arc->next = edge_array[i].arcs; edge_array[i].arcs = temp_arc; } } else if ( temp > 0 ) { count_swap++; copyEdge ( i, num_ed + 1 + 1 ); copyEdge ( i + 1, num_ed + 1 ); copyEdge ( num_ed + 1, i ); copyEdge ( num_ed + 1 + 1, i + 1 ); edge_array[i].bal_edge = 2; edge_array[i + 1].bal_edge = 0; //take care of the arcs arc = edge_array[i].arcs; while ( arc ) { arc->bal_arc->to_ed = i + 1; arc = arc->next; } arc = edge_array[i + 1].arcs; while ( arc ) { arc->bal_arc->to_ed = i; arc = arc->next; } } } ++i; } else { delete1Edge ( i ); fprintf ( stderr, "Warning : Front edge %d is larger than %d.\n", i, i + 1 ); } } fprintf ( stderr, "%d none-palindrome edge(s) swapped, %d palindrome edge(s) processed.\n", count_swap, count_equal ); } /************************************************* Function: cmp_seq Description: Compare two seq. Input: 1. a : seq a. 2. b : seq b. Output: None. Return: 1 if a larger than b. -1 if a smaller than b. 0 if a equal to b. *************************************************/ static int cmp_seq ( const void * a, const void * b ) { EDGE_SUB * A, *B; A = ( EDGE_SUB * ) a; B = ( EDGE_SUB * ) b; if ( KmerLarger ( vt_array[A->from_vt].kmer, vt_array[B->from_vt].kmer ) ) { return 1; } else if ( KmerSmaller ( vt_array[A->from_vt].kmer , vt_array[B->from_vt].kmer ) ) { return -1; } else { if ( A->seq[0] > B->seq[0] ) { return 1; } else if ( A->seq[0] == B->seq[0] ) { int i = 0; for ( i = 1; i < A->length && i < B->length; i++ ) { if ( getCharInTightString ( A->seq, i ) > getCharInTightString ( B->seq, i ) ) { return 1; } else if ( getCharInTightString ( A->seq, i ) < getCharInTightString ( B->seq, i ) ) { return -1; } } if ( i == A->length && i < B->length ) { return -1; } else if ( i < A->length && i == B->length ) { return 1; } else { printKmerSeq ( stderr , vt_array[A->from_vt].kmer ); fprintf ( stderr , "\n" ); printKmerSeq ( stderr , vt_array[B->from_vt].kmer ); fprintf ( stderr , "\n" ); for ( i = 0; i < A->length; i++ ) { fprintf ( stderr, "%c", int2base ( ( int ) getCharInTightString ( A->seq, i ) ) ); } fprintf ( stderr , "\n" ); for ( i = 0; i < B->length; i++ ) { fprintf ( stderr, "%c", int2base ( ( int ) getCharInTightString ( B->seq, i ) ) ); } fprintf ( stderr , "\n" ); fprintf ( stderr, "cmp_seq:\terr\n" ); exit ( 0 ); return 0; } } else { return -1; } } } //Copy edge from source to target. static void copyOneEdge ( EDGE * target , EDGE * source ) { target->from_vt = source->from_vt; target->to_vt = source->to_vt; target->length = source->length; target->cvg = source->cvg; target->multi = source->multi; target->flag = source->flag; target->bal_edge = source->bal_edge; target->seq = source->seq; source->seq = NULL; target->arcs = source->arcs; source->arcs = NULL ; target->markers = source->markers; source->markers = NULL; target->deleted = source->deleted; } /************************************************* Function: updateArcToEd Description: Update the arcs of edges. Input: 1. ed_index : the index of edge Output: None. Return: None. *************************************************/ static void updateArcToEd ( unsigned int ed_index ) { ARC * arc = edge_array[ed_index].arcs; while ( arc ) { arc->to_ed = index_array[arc->to_ed]; arc = arc->next; } } /************************************************* Function: sortedge Description: Sort edges base on seq of edges. Input: None. Output: None. Return: None. *************************************************/ ///* void sortedge() { unsigned int index ; EDGE_SUB * sort_edge; sort_edge = ( EDGE_SUB * ) ckalloc ( sizeof ( EDGE_SUB ) * ( num_ed + 1 ) ); unsigned int i = 1; for ( index = 1 ; index <= num_ed ; index ++ ) { sort_edge[i].from_vt = edge_array[index].from_vt; sort_edge[i].seq = edge_array[index].seq; sort_edge[i].to_vt = index; // record old id sort_edge[i].length = edge_array[index].length; i++; if ( !EdSameAsTwin ( index ) ) { index++; } } qsort ( & ( sort_edge[1] ), i - 1, sizeof ( sort_edge[1] ), cmp_seq ); index_array = ( unsigned int * ) ckalloc ( sizeof ( unsigned int ) * ( num_ed + 1 ) ); // used to record new id unsigned int new_index = 1, old_index; for ( index = 1; index <= i - 1; index++ ) { old_index = sort_edge[index].to_vt; // old id sort_edge[index].seq = NULL; index_array[old_index] = new_index++;// old id -> new id if ( !EdSameAsTwin ( old_index ) ) { index_array[old_index + 1] = new_index++; // old id -> new id } } bool * copy_array = (bool * ) ckalloc ( sizeof ( bool ) * ( num_ed + 1 ) ); EDGE *old_edge = ( EDGE * ) ckalloc ( sizeof ( EDGE ) ); EDGE *new_edge = ( EDGE * ) ckalloc ( sizeof ( EDGE ) ); unsigned int next_index; for ( index = 1; index <= num_ed; index++ ) { if(!copy_array[index]) { next_index = index; new_index = index_array[next_index]; if(!copy_array[next_index])// && next_index != new_index { if(copy_array[new_index]) { fprintf(stderr, "Copy error: never reach here."); } copy_array[next_index] = 1; if(next_index != new_index) { copyOneEdge (old_edge, &(edge_array[new_index])); copyOneEdge ( & ( edge_array[new_index] ), & ( edge_array[next_index] ) ); } updateArcToEd ( new_index ); next_index = new_index; new_index = index_array[next_index]; while(!copy_array[next_index]) { if(next_index == new_index) { fprintf(stderr, "Index error: never reach here."); } copy_array[next_index] = 1; copyOneEdge (new_edge, &(edge_array[new_index])); copyOneEdge ( & ( edge_array[new_index] ), old_edge); updateArcToEd ( new_index ); copyOneEdge (old_edge, new_edge); next_index = new_index; new_index = index_array[next_index]; } } } } free (copy_array); free (old_edge); free (new_edge); free ( index_array ); free ( sort_edge ); fprintf(stderr, "%d edge(s) sorted.\n", num_ed); } //*/ /* void sortedge() { unsigned int index ; EDGE * backup_edge ; EDGE_SUB * sort_edge; sort_edge = ( EDGE_SUB * ) ckalloc ( sizeof ( EDGE_SUB ) * ( num_ed + 1 ) ); backup_edge = ( EDGE * ) ckalloc ( sizeof ( EDGE ) * ( num_ed + 1 ) ); unsigned int i = 1; for ( index = 1 ; index <= num_ed ; index ++ ) { sort_edge[i].from_vt = edge_array[index].from_vt; sort_edge[i].seq = edge_array[index].seq; sort_edge[i].to_vt = index; // record old id sort_edge[i].length = edge_array[index].length; i++; copyOneEdge ( & ( backup_edge[index] ) , & ( edge_array[index] ) ); if ( !EdSameAsTwin ( index ) ) { index++; copyOneEdge ( & ( backup_edge[index] ) , & ( edge_array[index] ) ); } } qsort ( & ( sort_edge[1] ), i - 1, sizeof ( sort_edge[1] ), cmp_seq ); index_array = ( unsigned int * ) ckalloc ( sizeof ( unsigned int ) * ( num_ed + 1 ) ); // used to record new id unsigned int new_index = 1, old_index; for ( index = 1; index <= i - 1; index++ ) { old_index = sort_edge[index].to_vt; // old id sort_edge[index].seq = NULL; index_array[old_index] = new_index++;// old id -> new id if ( !EdSameAsTwin ( old_index ) ) { index_array[old_index + 1] = new_index++; // old id -> new id } } for ( index = 1; index <= num_ed; index++ ) { new_index = index_array[index]; copyOneEdge ( & ( edge_array[new_index] ), & ( backup_edge[index] ) ); updateArcToEd ( new_index ); } free ( index_array ); free ( sort_edge ); free ( backup_edge ); fprintf(stderr, "%d edge(s) sorted.\n", num_ed); } */ /************************************************* Function: delete0Edge Description: Delete edge whose leght is zero. Input: None. Output: None. Return: None. *************************************************/ void delete0Edge() { unsigned int i = 0; ARC * arc_left, *arc_right; arcBufferCount = 0; arcBuffer = ( unsigned int ** ) ckalloc ( sizeof ( unsigned int * ) * 3 ); arcBuffer[0] = ( unsigned int * ) ckalloc ( sizeof ( unsigned int ) * num_ed * 3 ); arcBuffer[1] = ( unsigned int * ) ckalloc ( sizeof ( unsigned int ) * num_ed * 3 ); arcBuffer[2] = ( unsigned int * ) ckalloc ( sizeof ( unsigned int ) * num_ed * 3 ); for ( i = 1; i <= num_ed; ++i ) { if ( edge_array[i].deleted || EdSameAsTwin ( i ) ) { continue; } if ( edge_array[i].length == 0 ) { arc_left = edge_array[i + 1].arcs; while ( arc_left ) { arc_right = edge_array[i].arcs; while ( arc_right ) { arcBuffer[0][arcBufferCount] = getTwinEdge ( arc_left->to_ed ); arcBuffer[1][arcBufferCount] = ( arc_left->multiplicity + arc_right->multiplicity + 1 ) / 2; arcBuffer[2][arcBufferCount++] = arc_right->to_ed; arc_right = arc_right->next; } arc_left = arc_left->next; } } ++i; } unsigned int from = 0; unsigned int multi = 0; unsigned int to = 0; int count_edgedelete = 0, count_arcadd = 0; for ( i = 1; i <= num_ed; ++i ) { if ( edge_array[i].deleted || EdSameAsTwin ( i ) ) { continue; } if ( edge_array[i].length == 0 ) { destroyEdge2 ( i ); count_edgedelete += 2; } } removeDeadArcs2(); for ( i = 0; i < arcBufferCount; ++i ) { from = arcBuffer[0][i]; multi = arcBuffer[1][i]; to = arcBuffer[2][i]; if ( from == 0 || to == 0 ) { fprintf ( stderr, "Error : Edge id is zero.\n" ); continue; } if ( from > num_ed || to > num_ed ) { fprintf ( stderr, "Error : Edge id is out of range.\n" ); continue; } count_arcadd++; add1Arc2 ( from, to, multi ); } arcBufferCount = 0; fprintf ( stderr, "%d edge(s) in length of 0, %d arc(s) added.\n", count_edgedelete, count_arcadd ); free ( arcBuffer[0] ); free ( arcBuffer[1] ); free ( arcBuffer[2] ); free ( arcBuffer ); } /************************************************* Function: fresh Description: 1. Extend edges. 2. Delete edges whose leght is zero. 3. Re-arrange the edges, swap smaller edge at front. Input: 1. maxk : max kmer of multi kmer Output: None. Return: None. *************************************************/ void fresh ( int maxk ) { int num = 0; ARC * arc_temp, *parc; newfoundcount = 0; newnotfoundcount = 0; edgeaddnumber = 0; freshEdge ( maxk ); fprintf ( stderr, "Refresh edge: %lld edge(s) added.\n", edgeaddnumber ); if ( newnotfoundcount ) { fprintf ( stderr, "Refresh edge: %d kmer(s) found.\n", newfoundcount ); fprintf ( stderr, "Refresh edge: %d kmer(s) not found.\n", newnotfoundcount ); } if ( overlaplen + step > maxk ) { delete0Edge(); } //swap the smaller one forward swapedge(); compactEdgeArray(); } /************************************************* Function: statistics Description: Output statistics of edge array, the N50 N90 longest, etc. Input: 1. ed_array : the edge array 2. ed_num : the number of edges Output: 1. statistics of edges Return: None. *************************************************/ void statistics ( EDGE * ed_array, unsigned int ed_num ) { unsigned int i = 0; unsigned int * length_array; int flag, count, len_c; long long sum = 0, N90, N50; int signI; length_array = ( unsigned int * ) ckalloc ( ed_num * sizeof ( unsigned int ) ); //first scan for number counting count = len_c = 0; for ( i = 1; i <= ed_num; i++ ) { if ( ( ed_array[i].length + overlaplen - 1 ) >= len_bar ) { length_array[len_c++] = ed_array[i].length + overlaplen - 1; } if ( ed_array[i].length < 1 || ed_array[i].deleted ) { continue; } count++; if ( EdSmallerThanTwin ( i ) ) { i++; } } sum = 0; for ( signI = len_c - 1; signI >= 0; signI-- ) { sum += length_array[signI]; } if ( len_c > 0 ) { fprintf ( stderr, "\nThere are %d contig(s) longer than %d, sum up %lld bp, with average length %lld.\n", len_c, len_bar, sum, sum / len_c ); } qsort ( length_array, len_c, sizeof ( length_array[0] ), cmp_int ); fprintf ( stderr, "The longest length is %d bp, ", length_array[len_c - 1] ); N50 = sum * 0.5; N90 = sum * 0.9; sum = flag = 0; for ( signI = len_c - 1; signI >= 0; signI-- ) { sum += length_array[signI]; if ( !flag && sum >= N50 ) { fprintf ( stderr, "contig N50 is %d bp, ", length_array[signI] ); flag = 1; } if ( sum >= N90 ) { fprintf ( stderr, "contig N90 is %d bp.\n", length_array[signI] ); break; } } free ( ( void * ) length_array ); } /************************************************* Function: sort_arc Description: Sort arcs Input: 1. list : unsorted arcs list Output: None. Return: Sorted arcs list. *************************************************/ ARC * sort_arc ( ARC * list ) { if ( !list ) { return list; } // ARC * head = ( ARC * ) malloc ( sizeof ( ARC ) ); ARC * head = ( ARC * ) ckalloc ( sizeof ( ARC )); head->next = list; list->prev = head; ARC * curr = list; ARC * temp = list; ARC * temp1 = NULL; while ( curr ) { temp = curr; if ( temp ) { temp1 = temp->next; while ( temp1 ) { if ( temp->to_ed > temp1->to_ed ) { temp = temp1; } temp1 = temp1->next; } } if ( temp && temp != curr ) { if ( temp->next ) { temp->prev->next = temp->next; temp->next->prev = temp->prev; } else { temp->prev->next = NULL; } temp->next = curr; temp->prev = curr->prev; curr->prev->next = temp; curr->prev = temp; } else { curr = curr->next; } } list = head->next; list->prev = NULL; head->next = NULL; free ( head ); return list; } //Sort disorder arcs causing by multi thread. void freshArc() { unsigned int i; ARC * arc_temp, *parc; for ( i = 1; i <= num_ed; ++i ) { if ( edge_array[i].deleted ) { continue; } edge_array[i].arcs = sort_arc ( edge_array[i].arcs ); } fprintf(stderr, "Arcs sorted.\n"); } /************************************************* Function: getUnlikeArc Description: Delete arcs that are chose. Input: None. Output: None. Return: None. *************************************************/ static void deleteUnlikeArc() { unsigned int i, bal; ARC * arc_temp; int count = 0; for ( i = 0; i < delarcBufferCount; ++i ) { arc_temp = getArcBetween ( delarcBuffer[0][i], delarcBuffer[1][i] ); if ( arc_temp ) { edge_array[delarcBuffer[0][i]].arcs = deleteArc ( edge_array[delarcBuffer[0][i]].arcs, arc_temp ); ++count; } arc_temp = getArcBetween ( getTwinEdge ( delarcBuffer[1][i] ), getTwinEdge ( delarcBuffer[0][i] ) ); if ( arc_temp ) { edge_array[getTwinEdge ( delarcBuffer[1][i] )].arcs = deleteArc ( edge_array[getTwinEdge ( delarcBuffer[1][i] )].arcs, arc_temp ); ++count; } } fprintf ( stderr, "%d unreliable arc(s) deleted.\n", count ); free ( delarcBuffer[0] ); free ( delarcBuffer[1] ); free ( delarcBuffer ); delarcBufferCount = 0; } /************************************************* Function: forward Description: Go forward to collect the related arcs out going from index. Input: 1. index : the index of edge 2. first : whether it's the first one to be parsed Output: None. Return: None. *************************************************/ static void forward ( unsigned int index, int first ) { ARC * fArc, *temp; fArc = edge_array[index].arcs; unsigned int twin = getTwinEdge ( index ); // if(!EdSameAsTwin(index)) { if ( edge_array[index].multi != 1 ) { edge_array[index].multi = 2; } if ( edge_array[twin].multi != 1 ) { edge_array[twin].multi = 2; } } edge_array[index].flag = 1; edge_array[twin].flag = 1; while ( fArc ) { temp = fArc; fArc = fArc->next; delarcBuffer[0][delarcBufferCount] = index; delarcBuffer[1][delarcBufferCount++] = temp->to_ed; if ( edge_array[temp->to_ed].flag ) { continue; } forward ( getTwinEdge ( temp->to_ed ), 0 ); } } /************************************************* Function: getUnlikeArc Description: Get arcs that could be processed incorrectly. Input: None. Output: None. Return: None. *************************************************/ static void getUnlikeArc() { unsigned int i, bal; for ( i = 1; i <= num_ed; ++i ) { if ( edge_array[i].deleted ) { continue; } if ( EdSameAsTwin ( i ) ) { edge_array[i].multi = 1; } } delarcBuffer = ( unsigned int ** ) ckalloc ( sizeof ( unsigned int * ) * 2 ); delarcBuffer[0] = ( unsigned int * ) ckalloc ( sizeof ( unsigned int ) * num_ed * 3 ); delarcBuffer[1] = ( unsigned int * ) ckalloc ( sizeof ( unsigned int ) * num_ed * 3 ); unsigned int last = 0, curr = 0; for ( i = 1; i <= num_ed; ++i ) { if ( edge_array[i].deleted ) { continue; } if ( edge_array[i].multi == 1 ) { last = delarcBufferCount; forward ( i, 1 ); if ( !EdSameAsTwin ( i ) ) { forward ( getTwinEdge ( i ), 1 ); ++i; } curr = delarcBufferCount; unsigned int j; edge_array[i].flag = 0; edge_array[getTwinEdge ( i )].flag = 0; for ( j = last; j < curr; ++j ) { edge_array[delarcBuffer[0][j]].flag = 0; edge_array[getTwinEdge ( delarcBuffer[0][j] )].flag = 0; edge_array[delarcBuffer[1][j]].flag = 0; edge_array[getTwinEdge ( delarcBuffer[1][j] )].flag = 0; } } } } /************************************************* Function: Iterate Description: 1. Iterately gets larger kmer graph and solves some repeats. 2. Builds (k+1)mer graph based on k mer graph. 3. Re-builds arcs by reads. 4. Removes errors(weak edge, low cov edge and tips). Input: 1. libfile : the reads config file 2. graph : the output prefix 3. maxk : the max kmer when using multikmer // 4. keepReadFile : keep temp reads file that selected for building arcs 5. M : the strength of merging bubbles Output: None. Return: None. *************************************************/ void Iterate ( char * libfile, char * graph, int maxk, int M ) //boolean keepReadFile, { time_t start_t, stop_t, time_bef, time_aft, inner_start, inner_stop; time ( &start_t ); unsigned int i; for ( i = 1; i <= num_ed; ++i ) { edge_array[i].multi = 0; } int cutlen = 2 * overlaplen; int mink = overlaplen; overlaplen += step; nowstep2 = step; int flag = 0; statistics ( edge_array, num_ed ); fprintf ( stderr, "\nIteration start.\n" ); int round = 1; while ( overlaplen <= maxk ) { unsigned int j; time ( &inner_start ); WORDFILTER = createFilter ( overlaplen ); fprintf ( stderr, "\n***************************\n" ); fprintf ( stderr, "Iteration %d, kmer: %d\n", round++, overlaplen ); fprintf ( stderr, "Edge number: %d\n", num_ed ); time ( &time_bef ); //build (k+1)mer graph fprintf ( stderr, "Construct %dmer graph.\n", overlaplen ); buildGraphHash(); time ( &time_aft ); fprintf ( stderr, "Time spent on building hash graph: %ds.\n", ( int ) ( time_aft - time_bef ) ); time ( &time_bef ); //add arcs for (k+1)mer graph fprintf ( stderr, "\nAdd arcs to graph.\n" ); addArc ( libfile, graph, flag, maxk - overlaplen, maxk ); //, keepReadFile //get arcs that could be processed incorrectly getUnlikeArc(); //delete this arcs deleteUnlikeArc(); flag++; time ( &time_aft ); fprintf ( stderr, "Time spent on adding arcs: %ds.\n", ( int ) ( time_aft - time_bef ) ); time ( &time_bef ); //sort disorder arcs causing by multi thread fprintf ( stderr, "Sort arcs.\n" ); freshArc(); time ( &time_aft ); fprintf ( stderr, "Time spent on sorting arcs: %ds.\n", ( int ) ( time_aft - time_bef ) ); if ( deLowEdge ) { time ( &time_bef ); fprintf ( stderr, "\nRemove weak edges and low coverage edges.\n" ); removeWeakEdges2 ( cutlen, 1, mink ); removeLowCovEdges2 ( cutlen, deLowEdge, mink, 0 ); time ( &time_aft ); fprintf ( stderr, "Time spent on removing Edges: %ds\n", ( int ) ( time_aft - time_bef ) ); } if ( overlaplen + step > maxk ) { time ( &time_bef ); fprintf ( stderr, "Cut tips of the graph.\n" ); cutTipsInGraph2 ( cutlen, 0, 0 ); time ( &time_aft ); fprintf ( stderr, "Time spent on cutting tips: %ds.\n", ( int ) ( time_aft - time_bef ) ); } time ( &time_bef ); fprintf ( stderr, "Refresh edges.\n" ); //refresh to extend edge and get the edge order right fresh ( maxk ); time ( &time_aft ); fprintf ( stderr, "Time spent on refreshing edges: %ds.\n", ( int ) ( time_aft - time_bef ) ); //free kmer set free_kmerset2 ( KmerSetsNew ); overlaplen += step; nowstep2 += step; statistics ( edge_array, num_ed ); time ( &inner_stop ); fprintf ( stderr, "Time spent on this round: %dm.\n\n", ( int ) ( inner_stop - inner_start ) / 60 ); } for ( i = 1; i <= num_ed; ++i ) { edge_array[i].multi = 0; } overlaplen = maxk; time ( &stop_t ); fprintf ( stderr, "Iteration finished.\n" ); fprintf ( stderr, "Time spent on iteration: %dm.\n\n", ( int ) ( stop_t - start_t ) / 60 ); } soapdenovo2-240+dfsg.orig/standardPregraph/main.c0000644000000000000000000003475512166703654020605 0ustar rootroot/* * main.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "global.h" extern int call_pregraph ( int arc, char ** argv ); extern int call_pregraph_sparse(int arc, char ** argv); extern int call_heavygraph ( int arc, char ** argv ); extern int call_map2contig ( int arc, char ** argv ); extern int call_scaffold ( int arc, char ** argv ); extern int call_align ( int arc, char ** argv ); static void display_usage (); static void display_all_usage (); static void pipeline ( int argc, char ** argv ); /************************************************* Function: main Description: The main function. It includes four modules: 1.pregraph 2.contig 3.map 4.scaffold Input: @see display_all_usage () Output: Below files: 1. *.contig 2. *.scafSeq etc. Return: None. *************************************************/ int main ( int argc, char ** argv ) { crc32c_Init(); fprintf ( stderr, "\nVersion 2.04: released on July 13th, 2012\nCompile %s\t%s\n", __DATE__, __TIME__ ); argc--; argv++; if ( argc == 0 ) { display_usage (); return 0; } if ( strcmp ( "pregraph", argv[0] ) == 0 ) { call_pregraph ( argc, argv ); } else if(strcmp ( "sparse_pregraph", argv[0] ) == 0 ){ call_pregraph_sparse ( argc, argv ); } else if ( strcmp ( "contig", argv[0] ) == 0 ) { call_heavygraph ( argc, argv ); } else if ( strcmp ( "map", argv[0] ) == 0 ) { call_align ( argc, argv ); } //call_map2contig(argc,argv); else if ( strcmp ( "scaff", argv[0] ) == 0 ) { call_scaffold ( argc, argv ); } else if ( strcmp ( "all", argv[0] ) == 0 ) { pipeline ( argc, argv ); } else { display_usage (); } return 0; } static void display_usage () { fprintf ( stderr, "\nUsage: SOAPdenovo [option]\n" ); fprintf ( stderr, " pregraph construct kmer-graph\n" ); fprintf ( stderr, " sparse_pregraph construct sparse kmer-graph\n"); fprintf ( stderr, " contig eliminate errors and output contigs\n" ); fprintf ( stderr, " map map reads to contigs\n" ); fprintf ( stderr, " scaff construct scaffolds\n" ); fprintf ( stderr, " all do pregraph-contig-map-scaff in turn\n" ); } static void pipeline ( int argc, char ** argv ) { char * options[32]; unsigned char getK, getRfile, getOfile, getD, getDD, getL, getR, getP, getF, getf, getk, getu, getG, getc, getC, getb, getB, getN, getw, getV; unsigned char getm, getE; //getr, char readfile[256], outfile[256]; char temp[128]; char * name; int kmer = 0, cutoff_len = 0, ncpu = 0, lowK = 0, lowC = 0, kmer_small = 0, gap_diff = 0, genome_size = 0; float min_cvg = 0.0, max_cvg = 0.0, insert_size_bound = 0.0, bubble_coverage = 0.0; char kmer_s[16], len_s[16], ncpu_s[16], M_s[16], lowK_s[16], lowC_s[16], kmer_small_s[16], gap_diff_s[16], min_cvg_s[16], max_cvg_s[16], insert_size_bound_s[16], bubble_coverage_s[16], genome_size_s[16]; int i, copt, index, M = 1; int maxk; char maxk_s[16]; char arcfilter_s[16]; extern char * optarg; time_t start_t, stop_t; time ( &start_t ); getK = getRfile = getOfile = getD = getDD = getL = getR = getP = getF = getf = getk = getu = getG = getc = getC = getb = getB = getN = getw = getm = getE = getV = 0; while ( ( copt = getopt ( argc, argv, "a:s:o:K:M:L:p:G:d:D:RuFk:fc:C:b:B:N:wm:e:EV" ) ) != EOF ) //r { switch ( copt ) { case 's': getRfile = 1; sscanf ( optarg, "%s", readfile ); break; case 'o': getOfile = 1; sscanf ( optarg, "%s", outfile ); break; case 'K': getK = 1; sscanf ( optarg, "%s", temp ); kmer = atoi ( temp ); break; case 'G': getG = 1; sscanf ( optarg, "%s", temp ); gap_diff = atoi ( temp ); break; case 'M': sscanf ( optarg, "%s", temp ); M = atoi ( temp ); break; case 'p': getP = 1; sscanf ( optarg, "%s", temp ); ncpu = atoi ( temp ); break; case 'L': getL = 1; sscanf ( optarg, "%s", temp ); cutoff_len = atoi ( temp ); break; case 'R': getR = 1; break; case 'u': getu = 1; maskRep = 0; break; case 'd': getD = 1; sscanf ( optarg, "%s", temp ); lowK = atoi ( temp ); break; case 'D': getDD = 1; sscanf ( optarg, "%s", temp ); lowC = atoi ( temp ); break; case 'a': initKmerSetSize = atoi ( optarg ); break; case 'F': getF = 1; break; case 'k': getk = 1; sscanf ( optarg, "%s", temp ); kmer_small = atoi ( temp ); break; case 'f': getf = 1; break; case 'c': getc = 1; sscanf ( optarg, "%s", temp ); min_cvg = atof ( temp ); break; case 'C': getC = 1; sscanf ( optarg, "%s", temp ); max_cvg = atof ( temp ); break; case 'b': getb = 1; sscanf ( optarg, "%s", temp ); insert_size_bound = atof ( temp ); break; case 'B': getB = 1; sscanf ( optarg, "%s", temp ); bubble_coverage = atof ( temp ); break; case 'N': getN = 1; sscanf ( optarg, "%s", temp ); genome_size = atoi ( temp ); break; case 'w': getw = 1; break; case 'm': getm = 1; sscanf ( optarg, "%s", temp ); maxk = atoi ( temp ); break; /* case 'r': getr = 1; break; */ case 'e': sscanf ( optarg, "%s", temp ); arcfilter = atoi ( temp ); break; case 'E': getE = 1; break; case 'V': getV = 1; break; default: if ( getRfile == 0 || getOfile == 0 ) { display_all_usage (); exit ( -1 ); } } } if ( getRfile == 0 || getOfile == 0 ) { display_all_usage (); exit ( -1 ); } if ( thrd_num < 1 ) { thrd_num = 1; } // getK = getRfile = getOfile = getD = getL = getR = 0; name = "pregraph"; index = 0; options[index++] = name; options[index++] = "-s"; options[index++] = readfile; if ( getK ) { options[index++] = "-K"; sprintf ( kmer_s, "%d", kmer ); options[index++] = kmer_s; } if ( getP ) { options[index++] = "-p"; sprintf ( ncpu_s, "%d", ncpu ); options[index++] = ncpu_s; } if ( getD ) { options[index++] = "-d"; sprintf ( lowK_s, "%d", lowK ); options[index++] = lowK_s; } if ( getR ) { options[index++] = "-R"; } options[index++] = "-o"; options[index++] = outfile; /* for (i = 0; i < index; i++) { fprintf (stderr,"%s ", options[i]); } fprintf (stderr,"\n"); */ call_pregraph ( index, options ); name = "contig"; index = 0; options[index++] = name; options[index++] = "-g"; options[index++] = outfile; options[index++] = "-M"; sprintf ( M_s, "%d", M ); options[index++] = M_s; if ( getR ) { options[index++] = "-R"; } if ( getDD ) { options[index++] = "-D"; sprintf ( lowC_s, "%d", lowC ); options[index++] = lowC_s; } if ( getRfile ) { options[index++] = "-s"; options[index++] = readfile; } if ( getP ) { options[index++] = "-p"; sprintf ( ncpu_s, "%d", ncpu ); options[index++] = ncpu_s; } if ( getm ) { options[index++] = "-m"; sprintf ( maxk_s, "%d", maxk ); options[index++] = maxk_s; } /* if(getr){ options[index++] = "-r"; } */ if ( getE ) { options[index++] = "-E"; } if ( arcfilter ) { options[index++] = "-e"; sprintf ( arcfilter_s, "%d", arcfilter ); options[index++] = arcfilter_s; } /* for (i = 0; i < index; i++) { fprintf (stderr,"%s ", options[i]); } fprintf (stderr,"\n"); */ call_heavygraph ( index, options ); name = "map"; index = 0; options[index++] = name; options[index++] = "-s"; options[index++] = readfile; options[index++] = "-g"; options[index++] = outfile; if ( getP ) { options[index++] = "-p"; sprintf ( ncpu_s, "%d", ncpu ); options[index++] = ncpu_s; } if ( getK ) { options[index++] = "-K"; sprintf ( kmer_s, "%d", kmer ); options[index++] = kmer_s; } if ( getk ) { options[index++] = "-k"; sprintf ( kmer_small_s, "%d", kmer_small ); options[index++] = kmer_small_s; } if ( getf ) { options[index++] = "-f"; } /* for (i = 0; i < index; i++) { fprintf (stderr,"%s ", options[i]); } fprintf (stderr,"\n"); */ call_align ( index, options ); name = "scaff"; index = 0; options[index++] = name; options[index++] = "-g"; options[index++] = outfile; if ( getF ) { options[index++] = "-F"; } if ( getP ) { options[index++] = "-p"; sprintf ( ncpu_s, "%d", ncpu ); options[index++] = ncpu_s; } if ( getL ) { options[index++] = "-L"; sprintf ( len_s, "%d", cutoff_len ); options[index++] = len_s; } if ( getG ) { options[index++] = "-G"; sprintf ( gap_diff_s, "%d", gap_diff ); options[index++] = gap_diff_s; } if ( getu ) { options[index++] = "-u"; } if ( getc ) { options[index++] = "-c"; sprintf ( min_cvg_s, "%f", min_cvg ); options[index++] = min_cvg_s; } if ( getC ) { options[index++] = "-C"; sprintf ( max_cvg_s, "%f", max_cvg ); options[index++] = max_cvg_s; } if ( getb ) { options[index++] = "-b"; sprintf ( insert_size_bound_s, "%f", insert_size_bound ); options[index++] = insert_size_bound_s; } if ( getB ) { options[index++] = "-B"; sprintf ( bubble_coverage_s, "%f", bubble_coverage ); options[index++] = bubble_coverage_s; } if ( getN ) { options[index++] = "-N"; sprintf ( genome_size_s, "%d", genome_size ); options[index++] = genome_size_s; } if ( getw ) { options[index++] = "-w"; } if ( getV ) { options[index++] = "-V"; } /* for (i = 0; i < index; i++) { fprintf (stderr,"%s ", options[i]); } fprintf (stderr,"\n"); */ call_scaffold ( index, options ); time ( &stop_t ); fprintf ( stderr, "Time for the whole pipeline: %dm.\n", ( int ) ( stop_t - start_t ) / 60 ); } static void display_all_usage () { // fprintf (stderr,"\nSOAPdenovo all -s configFile -o outputGraph [-R -f -F -u -w] [-K kmer -p n_cpu -a initMemoryAssumption -d KmerFreqCutOff -D EdgeCovCutoff -M mergeLevel -k kmer_R2C, -G gapLenDiff -L minContigLen -c minContigCvg -C maxContigCvg -b insertSizeUpperBound -B bubbleCoverage -N genomeSize]\n"); fprintf ( stderr, "\nSOAPdenovo all -s configFile -o outputGraph [-R -F -u -w] [-K kmer -p n_cpu -a initMemoryAssumption -d KmerFreqCutOff -D EdgeCovCutoff -M mergeLevel -k kmer_R2C, -G gapLenDiff -L minContigLen -c minContigCvg -C maxContigCvg -b insertSizeUpperBound -B bubbleCoverage -N genomeSize]\n" ); fprintf ( stderr, " -s configFile: the config file of solexa reads\n" ); fprintf ( stderr, " -o outputGraph: prefix of output graph file name\n" ); #ifdef MER127 fprintf ( stderr, " -K kmer(min 13, max 127): kmer size, [23]\n" ); #else fprintf ( stderr, " -K kmer(min 13, max 63): kmer size, [23]\n" ); #endif fprintf ( stderr, " -p n_cpu: number of cpu for use, [8]\n" ); fprintf ( stderr, " -a initMemoryAssumption: memory assumption initialized to avoid further reallocation, unit G, [0]\n" ); fprintf ( stderr, " -d kmerFreqCutoff: kmers with frequency no larger than KmerFreqCutoff will be deleted, [0]\n" ); fprintf ( stderr, " -R (optional) resolve repeats by reads, [NO]\n" ); fprintf ( stderr, " -D edgeCovCutoff: edges with coverage no larger than EdgeCovCutoff will be deleted, [1]\n" ); fprintf ( stderr, " -M mergeLevel(min 0, max 3): the strength of merging similar sequences during contiging, [1]\n" ); fprintf ( stderr, " -e arcWeight: two edges, between which the arc's weight is larger than arcWeight, will be linerized, [0]\n" ); #ifdef MER127 fprintf ( stderr, " -m maxKmer (max 127): maximum kmer size used for multi-kmer, [NO]\n" ); #else fprintf ( stderr, " -m maxKmer (max 63): maximum kmer size used for multi-kmer, [NO]\n" ); #endif fprintf ( stderr, " -E (optional) merge clean bubble before iterate, works only if -M is set when using multi-kmer, [NO]\n" ); // printf (" -O (optional)\toutput contig of each kmer when iterating\n"); // fprintf (stderr," -f (optional) output gap related reads in map step for using SRkgf to fill gaps, [NO]\n"); #ifdef MER127 fprintf ( stderr, " -k kmer_R2C(min 13, max 127): kmer size used for mapping reads to contigs, [K]\n" ); #else fprintf ( stderr, " -k kmer_R2C(min 13, max 63): kmer size used for mapping reads to contigs, [K]\n" ); #endif fprintf ( stderr, " -F (optional) fill gaps in scaffolds, [NO]\n" ); fprintf ( stderr, " -u (optional) un-mask contigs with high/low coverage before scaffolding, [mask]\n" ); fprintf ( stderr, " -w (optional) keep contigs weakly connected to other contigs in scaffold, [NO]\n" ); fprintf ( stderr, " -G gapLenDiff: allowed length difference between estimated and filled gap, [50]\n" ); fprintf ( stderr, " -L minContigLen: shortest contig for scaffolding, [K+2]\n" ); fprintf ( stderr, " -c minContigCvg: minimum contig coverage (c*avgCvg), contigs shorter than 100bp with coverage smaller than c*avgCvg will be masked before scaffolding unless -u is set, [0.1]\n" ); fprintf ( stderr, " -C maxContigCvg: maximum contig coverage (C*avgCvg), contigs with coverage larger than C*avgCvg or contigs shorter than 100bp with coverage larger than 0.8*C*avgCvg will be masked before scaffolding unless -u is set, [2]\n" ); fprintf ( stderr, " -b insertSizeUpperBound: (b*avg_ins) will be used as upper bound of insert size for large insert size ( > 1000) when handling pair-end connections between contigs if b is set to larger than 1, [1.5]\n" ); fprintf ( stderr, " -B bubbleCoverage: remove contig with lower cvoerage in bubble structure if both contigs' coverage are smaller than bubbleCoverage*avgCvg, [0.6]\n" ); fprintf ( stderr, " -N genomeSize: genome size for statistics, [0]\n" ); fprintf ( stderr, " -V (optional) output information for Hawkeye to visualize the assembly, [NO]\n" ); } soapdenovo2-240+dfsg.orig/standardPregraph/loadPreGraph.c0000644000000000000000000004000512166703654022212 0ustar rootroot/* * loadPreGraph.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #include "zlib.h" static void loadPreArcs ( char * graphfile ); int cmp_vertex ( const void * a, const void * b ) { VERTEX * A, *B; A = ( VERTEX * ) a; B = ( VERTEX * ) b; if ( KmerLarger ( A->kmer, B->kmer ) ) { return 1; } else if ( KmerEqual ( A->kmer, B->kmer ) ) { return 0; } else { return -1; } } /************************************************* Function: loadVertex Description: 1. Loads first kmer and the last kmer of the edge. 2. Sorts kmers. Input: 1. graphfile: the input prefix Output: None. Return: None. *************************************************/ void loadVertex ( char * graphfile ) { char name[256], line[256]; FILE * fp; Kmer word, bal_word, temp; int num_kmer, i; char ch; sprintf ( name, "%s.preGraphBasic", graphfile ); fp = ckopen ( name, "r" ); while ( fgets ( line, sizeof ( line ), fp ) != NULL ) { if ( line[0] == 'V' ) { sscanf ( line + 6, "%d %c %d", &num_kmer, &ch, &overlaplen ); fprintf ( stderr, "There are %d kmer(s) in vertex file.\n", num_kmer ); } else if ( line[0] == 'E' ) { sscanf ( line + 5, "%d", &num_ed ); fprintf ( stderr, "There are %d edge(s) in edge file.\n", num_ed ); } else if ( line[0] == 'M' ) { sscanf ( line, "MaxReadLen %d MinReadLen %d MaxNameLen %d", &maxReadLen, &minReadLen, &maxNameLen ); } else if ( line[0] == 'B' ) { if ( line[7] == 'V' ) { sscanf ( line, "Backup VERTEX %d %c %d", &num_kmer, &ch, &overlaplen ); fprintf ( stderr, "Backup there are %d kmer(s) in vertex file.\n", num_kmer ); } else if ( line[7] == 'E' ) { sscanf ( line, "Backup EDGEs %d", &num_ed ); fprintf ( stderr, "Backup there are %d edge(s) in edge file.\n", num_ed ); } else if ( line[7] == 'M' ) { sscanf ( line, "Backup MaxReadLen %d MinReadLen %d MaxNameLen %d", &maxReadLen, &minReadLen, &maxNameLen ); } } } fclose ( fp ); vt_array = ( VERTEX * ) ckalloc ( ( 4 * num_kmer ) * sizeof ( VERTEX ) ); num_kmer_limit = 4 * num_kmer; sprintf ( name, "%s.vertex", graphfile ); fp = ckopen ( name, "r" ); for ( i = 0; i < num_kmer; i++ ) { #ifdef MER127 fscanf ( fp, "%llx %llx %llx %llx", & ( word.high1 ), & ( word.low1 ), & ( word.high2 ), & ( word.low2 ) ); #else fscanf ( fp, "%llx %llx", & ( word.high ), & ( word.low ) ); #endif bal_word = reverseComplement ( word, overlaplen ); if ( KmerSmaller ( word, bal_word ) ) { vt_array[i].kmer = word; } else { vt_array[i].kmer = bal_word; } } temp = vt_array[num_kmer - 1].kmer; qsort ( &vt_array[0], num_kmer, sizeof ( vt_array[0] ), cmp_vertex ); fprintf ( stderr, "Kmers sorted.\n" ); fclose ( fp ); for ( i = 0; i < num_kmer; i++ ) { bal_word = reverseComplement ( vt_array[i].kmer, overlaplen ); vt_array[i + num_kmer].kmer = bal_word; } num_vt = num_kmer; } /************************************************* Function: bisearch Description: Uses binary search to get the index of a kmer in array. Input: 1. vts: the array of the kmer 2. num: the count of the total kmers 3. target: the kmer to search Output: None. Return: The kmer's index in array. *************************************************/ int bisearch ( VERTEX * vts, int num, Kmer target ) { int mid, low, high; low = 0; high = num - 1; while ( low <= high ) { mid = ( low + high ) / 2; if ( KmerEqual ( vts[mid].kmer, target ) ) { break; } else if ( KmerLarger ( target, vts[mid].kmer ) ) { low = mid + 1; } else { high = mid - 1; } } if ( low <= high ) { return mid; } else { return -1; } } /************************************************* Function: kmer2vt Description: Searchs the index of a kmer in array. Input: 1. kmer: the kmer Output: None. Return: The index of the kmer in the array. *************************************************/ int kmer2vt ( Kmer kmer ) { Kmer bal_word; int vt_id; bal_word = reverseComplement ( kmer, overlaplen ); if ( KmerSmaller ( kmer, bal_word ) ) { vt_id = bisearch ( &vt_array[0], num_vt, kmer ); if ( vt_id < 0 ) { fprintf ( stderr, "There is no vertex for kmer " ); PrintKmer ( stderr, kmer ); fprintf ( stderr, " .\n" ); /* #ifdef MER127 fprintf (stderr,"There is not the vertex for kmer %llx %llx %llx %llx.\n", kmer.high1, kmer.low1, kmer.high2, kmer.low2); #else fprintf (stderr,"There is not the vertex for kmer %llx %llx.\n", kmer.high, kmer.low); #endif */ } return vt_id; } else { vt_id = bisearch ( &vt_array[0], num_vt, bal_word ); if ( vt_id >= 0 ) { vt_id += num_vt; } else { fprintf ( stderr, "There is no vertex for kmer " ); PrintKmer ( stderr, kmer ); fprintf ( stderr, " .\n" ); /* #ifdef MER127 fprintf (stderr,"There is not the vertex for kmer %llx %llx %llx %llx.\n", kmer.high1, kmer.low1, kmer.high2, kmer.low2); #else fprintf (stderr,"There is not the vertex for kmer %llx %llx.\n", kmer.high, kmer.low); #endif */ } return vt_id; } } /************************************************* Function: buildReverseComplementEdge Description: Creates reverse complementary edge of a edge. Input: 1. edgeno: the edge index Output: None. Return: None. *************************************************/ #ifdef MER127 static void buildReverseComplementEdge ( unsigned int edgeno ) { int length = edge_array[edgeno].length; int i, index = 0; char * sequence, ch, *tightSeq; Kmer kmer = vt_array[edge_array[edgeno].from_vt].kmer; sequence = ( char * ) ckalloc ( ( overlaplen + length ) * sizeof ( char ) ); int bit1, bit2, bit3, bit4; if ( overlaplen < 32 ) { bit4 = overlaplen; bit3 = 0; bit2 = 0; bit1 = 0; } if ( overlaplen >= 32 && overlaplen < 64 ) { bit4 = 32; bit3 = overlaplen - 32; bit2 = 0; bit1 = 0; } if ( overlaplen >= 64 && overlaplen < 96 ) { bit4 = 32; bit3 = 32; bit2 = overlaplen - 64; bit1 = 0; } if ( overlaplen >= 96 && overlaplen < 128 ) { bit4 = 32; bit3 = 32; bit2 = 32; bit1 = overlaplen - 96; } for ( i = bit1 - 1; i >= 0; i-- ) { ch = kmer.high1 & 0x3; kmer.high1 >>= 2; sequence[i] = ch; } for ( i = bit2 - 1; i >= 0; i-- ) { ch = kmer.low1 & 0x3; kmer.low1 >>= 2; sequence[i + bit1] = ch; } for ( i = bit3 - 1; i >= 0; i-- ) { ch = kmer.high2 & 0x3; kmer.high2 >>= 2; sequence[i + bit1 + bit2] = ch; } for ( i = bit4 - 1; i >= 0; i-- ) { ch = kmer.low2 & 0x3; kmer.low2 >>= 2; sequence[i + bit1 + bit2 + bit3] = ch; } for ( i = 0; i < length; i++ ) { sequence[i + overlaplen] = getCharInTightString ( edge_array[edgeno].seq, i ); } tightSeq = ( char * ) ckalloc ( ( length / 4 + 1 ) * sizeof ( char ) ); for ( i = length - 1; i >= 0; i-- ) { writeChar2tightString ( int_comp ( sequence[i] ), tightSeq, index++ ); } edge_array[edgeno + 1].length = length; edge_array[edgeno + 1].cvg = edge_array[edgeno].cvg; kmer = vt_array[edge_array[edgeno].from_vt].kmer; edge_array[edgeno + 1].to_vt = kmer2vt ( reverseComplement ( kmer, overlaplen ) ); kmer = vt_array[edge_array[edgeno].to_vt].kmer; edge_array[edgeno + 1].from_vt = kmer2vt ( reverseComplement ( kmer, overlaplen ) ); edge_array[edgeno + 1].seq = tightSeq; edge_array[edgeno + 1].bal_edge = 0; edge_array[edgeno + 1].rv = NULL; edge_array[edgeno + 1].arcs = NULL; edge_array[edgeno + 1].flag = 0; edge_array[edgeno + 1].deleted = 0; free ( ( void * ) sequence ); } #else /************************************************* Function: buildReverseComplementEdge Description: Creates reverse complementary edge of a edge. Input: 1. edgeno: the edge index Output: None. Return: None. *************************************************/ static void buildReverseComplementEdge ( unsigned int edgeno ) { int length = edge_array[edgeno].length; int i, index = 0; char * sequence, ch, *tightSeq; Kmer kmer = vt_array[edge_array[edgeno].from_vt].kmer; sequence = ( char * ) ckalloc ( ( overlaplen + length ) * sizeof ( char ) ); int bit2 = overlaplen > 32 ? 32 : overlaplen; int bit1 = overlaplen > 32 ? overlaplen - 32 : 0; for ( i = bit1 - 1; i >= 0; i-- ) { ch = kmer.high & 0x3; kmer.high >>= 2; sequence[i] = ch; } for ( i = bit2 - 1; i >= 0; i-- ) { ch = kmer.low & 0x3; kmer.low >>= 2; sequence[i + bit1] = ch; } for ( i = 0; i < length; i++ ) { sequence[i + overlaplen] = getCharInTightString ( edge_array[edgeno].seq, i ); } tightSeq = ( char * ) ckalloc ( ( length / 4 + 1 ) * sizeof ( char ) ); for ( i = length - 1; i >= 0; i-- ) { writeChar2tightString ( int_comp ( sequence[i] ), tightSeq, index++ ); } edge_array[edgeno + 1].length = length; edge_array[edgeno + 1].cvg = edge_array[edgeno].cvg; kmer = vt_array[edge_array[edgeno].from_vt].kmer; edge_array[edgeno + 1].to_vt = kmer2vt ( reverseComplement ( kmer, overlaplen ) ); kmer = vt_array[edge_array[edgeno].to_vt].kmer; edge_array[edgeno + 1].from_vt = kmer2vt ( reverseComplement ( kmer, overlaplen ) ); edge_array[edgeno + 1].seq = tightSeq; edge_array[edgeno + 1].bal_edge = 0; edge_array[edgeno + 1].rv = NULL; edge_array[edgeno + 1].arcs = NULL; edge_array[edgeno + 1].flag = 0; edge_array[edgeno + 1].deleted = 0; free ( ( void * ) sequence ); } #endif /************************************************* Function: loadEdge Description: 1. Loads the info of the edges. 2. Loads the links between the edges. Input: 1. graphfile: the input prefix Output: None. Return: None. *************************************************/ void loadEdge ( char * graphfile ) { char c, name[256], line[1024], str[32]; char * tightSeq = NULL; gzFile * fp; Kmer from_kmer, to_kmer; int n = 0, i, length, cvg, index = -1, bal_ed, edgeno; int linelen; unsigned int j; sprintf ( name, "%s.edge.gz", graphfile ); fp = gzopen ( name, "r" ); num_ed_limit = 1.2 * num_ed; edge_array = ( EDGE * ) ckalloc ( ( num_ed_limit + 1 ) * sizeof ( EDGE ) ); for ( j = num_ed + 1; j <= num_ed_limit; j++ ) { edge_array[j].seq = NULL; } while ( gzgets ( fp, line, sizeof ( line ) ) != NULL ) { if ( line[0] == '>' ) { if ( index >= 0 ) { edgeno = index + 1; edge_array[edgeno].length = length; edge_array[edgeno].cvg = cvg; edge_array[edgeno].from_vt = kmer2vt ( from_kmer ); edge_array[edgeno].to_vt = kmer2vt ( to_kmer ); edge_array[edgeno].seq = tightSeq; edge_array[edgeno].bal_edge = bal_ed + 1; edge_array[edgeno].rv = NULL; edge_array[edgeno].arcs = NULL; edge_array[edgeno].flag = 0; edge_array[edgeno].deleted = 0; if ( bal_ed ) { buildReverseComplementEdge ( edgeno ); index++; } } n = 0; index++; #ifdef MER127 sscanf ( line + 7, "%d,%llx %llx %llx %llx,%llx %llx %llx %llx,%s %d,%d", &length, & ( from_kmer.high1 ), & ( from_kmer.low1 ), & ( from_kmer.high2 ), & ( from_kmer.low2 ), & ( to_kmer.high1 ), & ( to_kmer.low1 ), & ( to_kmer.high2 ), & ( to_kmer.low2 ), str, &cvg, &bal_ed ); #else sscanf ( line + 7, "%d,%llx %llx,%llx %llx,%s %d,%d", &length, & ( from_kmer.high ), & ( from_kmer.low ), & ( to_kmer.high ), & ( to_kmer.low ), str, &cvg, &bal_ed ); #endif tightSeq = ( char * ) ckalloc ( ( length / 4 + 1 ) * sizeof ( char ) ); } else { linelen = strlen ( line ); for ( i = 0; i < linelen; i++ ) { if ( line[i] >= 'a' && line[i] <= 'z' ) { c = base2int ( line[i] - 'a' + 'A' ); writeChar2tightString ( c, tightSeq, n++ ); } else if ( line[i] >= 'A' && line[i] <= 'Z' ) { c = base2int ( line[i] ); writeChar2tightString ( c, tightSeq, n++ ); } } } } if ( index >= 0 ) { edgeno = index + 1; edge_array[edgeno].length = length; edge_array[edgeno].cvg = cvg; edge_array[edgeno].from_vt = kmer2vt ( from_kmer ); edge_array[edgeno].to_vt = kmer2vt ( to_kmer ); edge_array[edgeno].seq = tightSeq; edge_array[edgeno].bal_edge = bal_ed + 1; if ( bal_ed ) { buildReverseComplementEdge ( edgeno ); index++; } } fprintf ( stderr, "%d edge(s) input.\n", index + 1 ); gzclose ( fp ); createArcMemo (); loadPreArcs ( graphfile ); } unsigned int getTwinEdge ( unsigned int edgeno ) { return edgeno + edge_array[edgeno].bal_edge - 1; } boolean EdSmallerThanTwin ( unsigned int edgeno ) { return edge_array[edgeno].bal_edge > 1; } boolean EdLargerThanTwin ( unsigned int edgeno ) { return edge_array[edgeno].bal_edge < 1; } boolean EdSameAsTwin ( unsigned int edgeno ) { return edge_array[edgeno].bal_edge == 1; } /************************************************* Function: add1Arc Description: Updates the arc information between two edges. Input: 1. from_ed: the first edge 2. to_ed: the second edge 3. weight: the weight of the arc to add Output: None. Return: None. *************************************************/ static void add1Arc ( unsigned int from_ed, unsigned int to_ed, unsigned int weight ) { if ( edge_array[from_ed].to_vt != edge_array[to_ed].from_vt ) { //fprintf(stderr,"add1Arc: inconsistant joins\n"); return; } unsigned int bal_fe = getTwinEdge ( from_ed ); unsigned int bal_te = getTwinEdge ( to_ed ); if ( from_ed > num_ed || to_ed > num_ed || bal_fe > num_ed || bal_te > num_ed ) { return; } ARC * parc, *bal_parc; //both arcs already exist parc = getArcBetween ( from_ed, to_ed ); if ( parc ) { bal_parc = parc->bal_arc; parc->multiplicity += weight; bal_parc->multiplicity += weight; return; } //create new arcs parc = allocateArc ( to_ed ); parc->multiplicity = weight; parc->prev = NULL; if ( edge_array[from_ed].arcs ) { edge_array[from_ed].arcs->prev = parc; } parc->next = edge_array[from_ed].arcs; edge_array[from_ed].arcs = parc; // A->A' if ( bal_te == from_ed ) { //printf("preArc from A to A'\n"); parc->bal_arc = parc; parc->multiplicity += weight; return; } bal_parc = allocateArc ( bal_fe ); bal_parc->multiplicity = weight; bal_parc->prev = NULL; if ( edge_array[bal_te].arcs ) { edge_array[bal_te].arcs->prev = bal_parc; } bal_parc->next = edge_array[bal_te].arcs; edge_array[bal_te].arcs = bal_parc; //link them to each other parc->bal_arc = bal_parc; bal_parc->bal_arc = parc; } /************************************************* Function: loadPreArcs Description: Loads the info of pre-arcs. Input: 1. graphfile: the input prefix Output: None. Return: None. *************************************************/ void loadPreArcs ( char * graphfile ) { FILE * fp; char name[256], line[1024]; unsigned int target, weight; unsigned int from_ed; char * seg; sprintf ( name, "%s.preArc", graphfile ); fp = ckopen ( name, "r" ); arcCounter = 0; while ( fgets ( line, sizeof ( line ), fp ) != NULL ) { seg = strtok ( line, " " ); from_ed = atoi ( seg ); while ( ( seg = strtok ( NULL, " " ) ) != NULL ) { target = atoi ( seg ); seg = strtok ( NULL, " " ); weight = atoi ( seg ); add1Arc ( from_ed, target, weight ); } } fprintf ( stderr, "%lli pre-arcs loaded.\n", arcCounter ); fclose ( fp ); } void free_edge_array ( EDGE * ed_array, int ed_num ) { int i; for ( i = 1; i <= ed_num; i++ ) if ( ed_array[i].seq ) { free ( ( void * ) ed_array[i].seq ); } free ( ( void * ) ed_array ); } soapdenovo2-240+dfsg.orig/standardPregraph/fibHeap.c0000644000000000000000000000367312166703654021212 0ustar rootroot/* * fibHeap.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "fib.h" // Constructor // Memory allocated FibHeap * newFibHeap () { return fh_makekeyheap (); } // Add new node into heap with a key, and a pointer to the specified node FibHeapNode * insertNodeIntoHeap ( FibHeap * heap, Coordinate key, unsigned int node ) { return fh_insertkey ( heap, key, node ); } // Returns smallest key in heap Coordinate minKeyOfHeap ( FibHeap * heap ) { return fh_minkey ( heap ); } // Replaces the key for a given node Coordinate replaceKeyInHeap ( FibHeap * heap, FibHeapNode * node, Coordinate newKey ) { return fh_replacekey ( heap, node, newKey ); } // Removes the node with the shortest key, then returns it. unsigned int removeNextNodeFromHeap ( FibHeap * heap ) { return ( unsigned int ) fh_extractmin ( heap ); } boolean IsHeapEmpty ( FibHeap * heap ) { return fh_isempty ( heap ); } // Destructor void destroyHeap ( FibHeap * heap ) { fh_deleteheap ( heap ); } // Replace the node pointed to by a heap node void replaceValueInHeap ( FibHeapNode * node, unsigned int newValue ) { fh_replacedata ( node, newValue ); } // Remove unwanted node void destroyNodeInHeap ( FibHeapNode * node, FibHeap * heap ) { fh_delete ( heap, node ); } soapdenovo2-240+dfsg.orig/standardPregraph/pregraph.c0000644000000000000000000001505512166703654021461 0ustar rootroot/* * pregraph.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" static char shortrdsfile[256]; //the reads config file name ,see -s option static char graphfile[256]; //the output prefix name ,see -o option static int cutTips = 1; //whether remove single tips or not. single tips , the tips starting from a kmer which coverage = 1 static void initenv ( int argc, char ** argv ); static void display_pregraph_usage (); /************************************************* Function: call_pregraph Description: The main function for pregraph step . its processes are as below: 1. Builds the kmer hash sets and remove the low coverage kmers. 2. Removes the tips which length are no greater than 2*K. 3. Builds edges by combining linear kmers. 4. Maps the reads back to edges and build preArcs (the connection between edges). Input: @see display_pregraph_usage () Output: Below files: *.kmerFreq *.edge.gz *.vertex *.preArc *.preGraphBasic *.markOnEdge (optional) *.path (optional) Return: Zero always *************************************************/ int call_pregraph ( int argc, char ** argv ) { time_t start_t, stop_t, time_bef, time_aft; time ( &start_t ); fprintf ( stderr, "\n********************\n" ); fprintf ( stderr, "Pregraph\n" ); fprintf ( stderr, "********************\n\n" ); initenv ( argc, argv ); if ( overlaplen % 2 == 0 ) { overlaplen++; fprintf ( stderr, "K should be an odd number.\n" ); } if ( overlaplen < 13 ) { overlaplen = 13; fprintf ( stderr, "K should not be less than 13.\n" ); } #ifdef MER127 else if ( overlaplen > 127 ) { overlaplen = 127; fprintf ( stderr, "K should not be greater than 127.\n" ); } #else else if ( overlaplen > 63 ) { overlaplen = 63; fprintf ( stderr, "K should not be greater than 63.\n" ); } #endif time ( &time_bef ); prlRead2HashTable ( shortrdsfile, graphfile ); time ( &time_aft ); fprintf ( stderr, "Time spent on pre-graph construction: %ds.\n\n", ( int ) ( time_aft - time_bef ) ); // printf ("deLowKmer %d, deLowEdge %d\n", deLowKmer, deLowEdge); // fprintf (stderr,"DeLowKmer %d\n", deLowKmer); //analyzeTips(hash_table, graphfile); if ( !deLowKmer && cutTips ) { time ( &time_bef ); removeSingleTips (); removeMinorTips (); time ( &time_aft ); fprintf ( stderr, "Time spent on removing tips: %ds.\n\n", ( int ) ( time_aft - time_bef ) ); } else { time ( &time_bef ); removeMinorTips (); time ( &time_aft ); fprintf ( stderr, "Time spent on removing tips: %ds.\n\n", ( int ) ( time_aft - time_bef ) ); } initKmerSetSize = 0; //combine each linear part to an edge time ( &time_bef ); kmer2edges ( graphfile ); time ( &time_aft ); fprintf ( stderr, "Time spent on constructing edges: %ds.\n\n", ( int ) ( time_aft - time_bef ) ); //map read to edge one by one time ( &time_bef ); prlRead2edge ( shortrdsfile, graphfile ); time ( &time_aft ); fprintf ( stderr, "Time spent on aligning reads: %ds.\n\n", ( int ) ( time_aft - time_bef ) ); output_vertex ( graphfile ); free_Sets ( KmerSets, thrd_num ); free_Sets ( KmerSetsPatch, thrd_num ); time ( &stop_t ); fprintf ( stderr, "Overall time spent on constructing pre-graph: %dm.\n\n", ( int ) ( stop_t - start_t ) / 60 ); return 0; } void initenv ( int argc, char ** argv ) { int copt; int inpseq, outseq; extern char * optarg; char temp[100]; optind = 1; inpseq = outseq = 0; fprintf ( stderr, "Parameters: pregraph " ); while ( ( copt = getopt ( argc, argv, "a:s:o:K:p:d:R" ) ) != EOF ) { //printf("get option\n"); switch ( copt ) { case 's': fprintf ( stderr, "-s %s ", optarg ); inpseq = 1; sscanf ( optarg, "%s", shortrdsfile ); break; case 'o': fprintf ( stderr, "-o %s ", optarg ); outseq = 1; sscanf ( optarg, "%s", graphfile ); break; case 'K': fprintf ( stderr, "-K %s ", optarg ); sscanf ( optarg, "%s", temp ); overlaplen = atoi ( temp ); break; case 'p': fprintf ( stderr, "-p %s ", optarg ); sscanf ( optarg, "%s", temp ); thrd_num = atoi ( temp ); break; case 'R': repsTie = 1; fprintf ( stderr, "-R " ); break; case 'd': fprintf ( stderr, "-d %s ", optarg ); sscanf ( optarg, "%s", temp ); deLowKmer = atoi ( temp ) >= 0 ? atoi ( temp ) : 0; break; /* case 'D': deLowEdge = 1; break; */ case 'a': fprintf ( stderr, "-a %s ", optarg ); initKmerSetSize = atoi ( optarg ); break; default: if ( inpseq == 0 || outseq == 0 ) { display_pregraph_usage (); exit ( -1 ); } } } fprintf ( stderr, "\n\n" ); if ( inpseq == 0 || outseq == 0 ) { //printf("need more\n"); display_pregraph_usage (); exit ( -1 ); } } static void display_pregraph_usage () { fprintf ( stderr, "\npregraph -s configFile -o outputGraph [-R] [-K kmer -p n_cpu -a initMemoryAssumption -d KmerFreqCutoff]\n" ); fprintf ( stderr, " -s configFile: the config file of solexa reads\n" ); fprintf ( stderr, " -o outputGraph: prefix of output graph file name\n" ); #ifdef MER127 fprintf ( stderr, " -K kmer(min 13, max 127): kmer size, [23]\n" ); #else fprintf ( stderr, " -K kmer(min 13, max 63): kmer size, [23]\n" ); #endif fprintf ( stderr, " -p n_cpu: number of cpu for use, [8]\n" ); fprintf ( stderr, " -a initMemoryAssumption: memory assumption initialized to avoid further reallocation, unit GB, [0]\n" ); fprintf ( stderr, " -R (optional) output extra information for resolving repeats in contig step, [NO]\n" ); fprintf ( stderr, " -d KmerFreqCutoff: kmers with frequency no larger than KmerFreqCutoff will be deleted, [0]\n" ); } soapdenovo2-240+dfsg.orig/standardPregraph/connect.c0000644000000000000000000001151612166703654021300 0ustar rootroot/* * connect.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #define CNBLOCKSIZE 100000 void createCntMemManager () { if ( !cn_mem_manager ) { cn_mem_manager = createMem_manager ( CNBLOCKSIZE, sizeof ( CONNECT ) ); } else { fprintf ( stderr, "The cn_mem_manger created.\n" ); } } void destroyConnectMem () { freeMem_manager ( cn_mem_manager ); cn_mem_manager = NULL; } CONNECT * allocateCN ( unsigned int contigId, int gap ) { CONNECT * newCN; newCN = ( CONNECT * ) getItem ( cn_mem_manager ); newCN->contigID = contigId; newCN->gapLen = gap; newCN->minGap = 0; newCN->maxGap = 0; newCN->bySmall = 0; newCN->smallIns = 0; newCN->weakPoint = 0; newCN->weight = 1; newCN->weightNotInherit = 0; newCN->mask = 0; newCN->used = 0; newCN->checking = 0; newCN->deleted = 0; newCN->prevInScaf = 0; newCN->inherit = 0; newCN->singleInScaf = 0; newCN->nextInScaf = NULL; return newCN; } void output_cntGVZ ( char * outfile ) { char name[256]; FILE * fp; unsigned int i; CONNECT * connect; boolean flag; sprintf ( name, "%s.scaffold.gvz", outfile ); fp = ckopen ( name, "w" ); fprintf ( fp, "digraph G{\n" ); fprintf ( fp, "\tsize=\"512,512\";\n" ); for ( i = num_ctg; i > 0; i-- ) { if ( !contig_array[i].downwardConnect ) { continue; } connect = contig_array[i].downwardConnect; while ( connect ) { if ( connect->deleted ) { connect = connect->next; continue; } if ( connect->prevInScaf || connect->nextInScaf ) { flag = 1; } else { flag = 0; } if ( !connect->mask ) fprintf ( fp, "\tC%d_%d -> C%d_%d [label = \"%d(%d_%d)\"];\n", i, contig_array[i].length, connect->contigID, contig_array[connect->contigID].length, connect->gapLen, flag, connect->weight ); else fprintf ( fp, "\tC%d_%d -> C%d_%d [label = \"%d(%d_%d)\", color = red];\n", i, contig_array[i].length, connect->contigID, contig_array[connect->contigID].length, connect->gapLen, flag, connect->weight ); connect = connect->next; } } fprintf ( fp, "}\n" ); fclose ( fp ); } /***************** below this line all codes are about lookup table *****************/ void createCntLookupTable () { if ( !cntLookupTable ) { cntLookupTable = ( CONNECT ** ) ckalloc ( ( 3 * num_ctg + 1 ) * sizeof ( CONNECT * ) ); } } void deleteCntLookupTable () { if ( cntLookupTable ) { free ( ( void * ) cntLookupTable ); cntLookupTable = NULL; } } void putCnt2LookupTable ( unsigned int from_c, CONNECT * cnt ) { if ( !cnt || !cntLookupTable ) { return; } unsigned int index = 2 * from_c + cnt->contigID; cnt->nextInLookupTable = cntLookupTable[index]; cntLookupTable[index] = cnt; } static CONNECT * getCntInLookupTable ( unsigned int from_c, unsigned int to_c ) { unsigned int index = 2 * from_c + to_c; CONNECT * ite_cnt = cntLookupTable[index]; while ( ite_cnt ) { if ( ite_cnt->contigID == to_c ) { return ite_cnt; } ite_cnt = ite_cnt->nextInLookupTable; } return NULL; } CONNECT * getCntBetween ( unsigned int from_c, unsigned int to_c ) { CONNECT * pcnt; if ( cntLookupTable ) { pcnt = getCntInLookupTable ( from_c, to_c ); return pcnt; } pcnt = contig_array[from_c].downwardConnect; while ( pcnt ) { if ( pcnt->contigID == to_c ) { return pcnt; } pcnt = pcnt->next; } return pcnt; } /* void removeCntInLookupTable(unsigned int from_c,unsigned int to_c) { unsigned int index = 2*from_c + to_c; CONNECT *ite_cnt = cntLookupTable[index]; CONNECT *cnt; if(!ite_cnt){ printf("removeCntInLookupTable: not found A\n"); return; } if(ite_cnt->contigID==to_c){ cntLookupTable[index] = ite_cnt->nextInLookupTable; return; } while(ite_cnt->nextInLookupTable&&ite_cnt->nextInLookupTable->contigID!=to_c) ite_cnt = ite_cnt->nextInLookupTable; if(ite_cnt->nextInLookupTable){ cnt = ite_cnt->nextInLookupTable; ite_cnt->nextInLookupTable = cnt->nextInLookupTable; return; } printf("removeCntInLookupTable: not found B\n"); return; } */ soapdenovo2-240+dfsg.orig/standardPregraph/lib.c0000644000000000000000000003324012166703654020413 0ustar rootroot/* * lib.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" static char tabs[2][1024]; //for splitColumn() /************************************************* Function: getMaxLongReadLen Description: Get the max length for long reads (asm_flags=4) in lib. Input: 1. num_libs: number of lib Output: None. Return: Max read length. *************************************************/ int getMaxLongReadLen ( int num_libs ) { int i; int maxLong = 0; boolean Has = 0; for ( i = 0; i < num_libs; i++ ) { if ( lib_array[i].asm_flag != 4 ) { continue; } Has = 1; maxLong = maxLong < lib_array[i].rd_len_cutoff ? lib_array[i].rd_len_cutoff : maxLong; } if ( !Has ) { return maxLong; } else { return maxLong > 0 ? maxLong : maxReadLen; } } static boolean splitColumn ( char * line ) { int len = strlen ( line ); int i = 0, j; int tabs_n = 0; while ( i < len ) { if ( line[i] >= 32 && line[i] <= 126 && line[i] != '=' ) { j = 0; while ( i < len && line[i] >= 32 && line[i] <= 126 && line[i] != '=' ) { tabs[tabs_n][j++] = line[i]; i++; } tabs[tabs_n][j] = '\0'; tabs_n++; if ( tabs_n == 2 ) { return 1; } } i++; } if ( tabs_n == 2 ) { return 1; } else { return 0; } } static int cmp_lib ( const void * a, const void * b ) { LIB_INFO * A, *B; A = ( LIB_INFO * ) a; B = ( LIB_INFO * ) b; if ( A->avg_ins > B->avg_ins ) { return 1; } else if ( A->avg_ins == B->avg_ins ) { return 0; } else { return -1; } } void scan_libInfo ( char * libfile ) { FILE * fp; char line[1024], ch; int i, j, index; int libCounter; boolean flag; boolean * pe; fp = ckopen ( libfile, "r" ); num_libs = 0; while ( fgets ( line, 1024, fp ) ) { ch = line[5]; line[5] = '\0'; if ( strcmp ( line, "[LIB]" ) == 0 ) { num_libs++; } if ( !num_libs ) { line[5] = ch; flag = splitColumn ( line ); if ( !flag ) { continue; } if ( strcmp ( tabs[0], "max_rd_len" ) == 0 ) { maxReadLen = atoi ( tabs[1] ); } } } if ( num_libs == 0 ) { fprintf ( stderr, "Config file error: no [LIB] in file\n" ); exit ( -1 ); } //count file numbers of each type lib_array = ( LIB_INFO * ) ckalloc ( num_libs * sizeof ( LIB_INFO ) ); pe = ( boolean * ) ckalloc ( num_libs * sizeof ( boolean ) ); for ( i = 0; i < num_libs; i++ ) { lib_array[i].asm_flag = 3; lib_array[i].rank = 0; lib_array[i].pair_num_cut = 0; lib_array[i].rd_len_cutoff = 0; lib_array[i].map_len = 0; lib_array[i].num_s_a_file = 0; lib_array[i].num_s_q_file = 0; lib_array[i].num_p_file = 0; lib_array[i].num_a1_file = 0; lib_array[i].num_a2_file = 0; lib_array[i].num_q1_file = 0; lib_array[i].num_q2_file = 0; lib_array[i].num_b_file = 0; //init pe[i] = false; } libCounter = -1; rewind ( fp ); i = -1; while ( fgets ( line, 1024, fp ) ) { ch = line[5]; line[5] = '\0'; if ( strcmp ( line, "[LIB]" ) == 0 ) { i++; continue; } line[5] = ch; flag = splitColumn ( line ); if ( !flag ) { continue; } if ( strcmp ( tabs[0], "f1" ) == 0 ) { lib_array[i].num_a1_file++; pe[i] = true; } else if ( strcmp ( tabs[0], "q1" ) == 0 ) { lib_array[i].num_q1_file++; pe[i] = true; } else if ( strcmp ( tabs[0], "f2" ) == 0 ) { lib_array[i].num_a2_file++; pe[i] = true; } else if ( strcmp ( tabs[0], "q2" ) == 0 ) { lib_array[i].num_q2_file++; pe[i] = true; } else if ( strcmp ( tabs[0], "f" ) == 0 ) { lib_array[i].num_s_a_file++; } else if ( strcmp ( tabs[0], "q" ) == 0 ) { lib_array[i].num_s_q_file++; } else if ( strcmp ( tabs[0], "p" ) == 0 ) { lib_array[i].num_p_file++; pe[i] = true; } else if ( strcmp ( tabs[0], "b" ) == 0 ) // the bam file { lib_array[i].num_b_file++; pe[i] = true; } } //allocate memory for filenames for ( i = 0; i < num_libs; i++ ) { if ( lib_array[i].num_a2_file != lib_array[i].num_a1_file ) { fprintf ( stderr, "Config file error: the number of mark \"f1\" is not the same as \"f2\"!\n" ); exit ( -1 ); } if ( lib_array[i].num_q2_file != lib_array[i].num_q1_file ) { fprintf ( stderr, "Config file error: the number of mark \"q1\" is not the same as \"q2\"!\n" ); exit ( -1 ); } if ( lib_array[i].num_s_a_file ) { lib_array[i].s_a_fname = ( char ** ) ckalloc ( lib_array[i].num_s_a_file * sizeof ( char * ) ); for ( j = 0; j < lib_array[i].num_s_a_file; j++ ) { lib_array[i].s_a_fname[j] = ( char * ) ckalloc ( 1024 * sizeof ( char ) ); } } if ( lib_array[i].num_s_q_file ) { lib_array[i].s_q_fname = ( char ** ) ckalloc ( lib_array[i].num_s_q_file * sizeof ( char * ) ); for ( j = 0; j < lib_array[i].num_s_q_file; j++ ) { lib_array[i].s_q_fname[j] = ( char * ) ckalloc ( 1024 * sizeof ( char ) ); } } if ( lib_array[i].num_p_file ) { lib_array[i].p_fname = ( char ** ) ckalloc ( lib_array[i].num_p_file * sizeof ( char * ) ); for ( j = 0; j < lib_array[i].num_p_file; j++ ) { lib_array[i].p_fname[j] = ( char * ) ckalloc ( 1024 * sizeof ( char ) ); } } if ( lib_array[i].num_a1_file ) { lib_array[i].a1_fname = ( char ** ) ckalloc ( lib_array[i].num_a1_file * sizeof ( char * ) ); for ( j = 0; j < lib_array[i].num_a1_file; j++ ) { lib_array[i].a1_fname[j] = ( char * ) ckalloc ( 1024 * sizeof ( char ) ); } } if ( lib_array[i].num_a2_file ) { lib_array[i].a2_fname = ( char ** ) ckalloc ( lib_array[i].num_a2_file * sizeof ( char * ) ); for ( j = 0; j < lib_array[i].num_a2_file; j++ ) { lib_array[i].a2_fname[j] = ( char * ) ckalloc ( 1024 * sizeof ( char ) ); } } if ( lib_array[i].num_q1_file ) { lib_array[i].q1_fname = ( char ** ) ckalloc ( lib_array[i].num_q1_file * sizeof ( char * ) ); for ( j = 0; j < lib_array[i].num_q1_file; j++ ) { lib_array[i].q1_fname[j] = ( char * ) ckalloc ( 1024 * sizeof ( char ) ); } } if ( lib_array[i].num_q2_file ) { lib_array[i].q2_fname = ( char ** ) ckalloc ( lib_array[i].num_q2_file * sizeof ( char * ) ); for ( j = 0; j < lib_array[i].num_q2_file; j++ ) { lib_array[i].q2_fname[j] = ( char * ) ckalloc ( 1024 * sizeof ( char ) ); } } if ( lib_array[i].num_b_file ) //allot memory for bam file name { lib_array[i].b_fname = ( char ** ) ckalloc ( lib_array[i].num_b_file * sizeof ( char * ) ); for ( j = 0; j < lib_array[i].num_b_file; j++ ) { lib_array[i].b_fname[j] = ( char * ) ckalloc ( 1024 * sizeof ( char ) ); } } } // get file names for ( i = 0; i < num_libs; i++ ) { lib_array[i].curr_type = 1; lib_array[i].curr_index = 0; lib_array[i].fp1 = NULL; lib_array[i].fp2 = NULL; lib_array[i].num_s_a_file = 0; lib_array[i].num_s_q_file = 0; lib_array[i].num_p_file = 0; lib_array[i].num_a1_file = 0; lib_array[i].num_a2_file = 0; lib_array[i].num_q1_file = 0; lib_array[i].num_q2_file = 0; lib_array[i].num_b_file = 0; //init lib_array[i].fp3 = NULL; } libCounter = -1; rewind ( fp ); i = -1; while ( fgets ( line, 1024, fp ) ) { ch = line[5]; line[5] = '\0'; if ( strcmp ( line, "[LIB]" ) == 0 ) { i++; continue; } line[5] = ch; flag = splitColumn ( line ); if ( !flag ) { continue; } if ( strcmp ( tabs[0], "f1" ) == 0 ) { index = lib_array[i].num_a1_file++; strcpy ( lib_array[i].a1_fname[index], tabs[1] ); } else if ( strcmp ( tabs[0], "q1" ) == 0 ) { index = lib_array[i].num_q1_file++; strcpy ( lib_array[i].q1_fname[index], tabs[1] ); } else if ( strcmp ( tabs[0], "f2" ) == 0 ) { index = lib_array[i].num_a2_file++; strcpy ( lib_array[i].a2_fname[index], tabs[1] ); if ( strcmp ( lib_array[i].a2_fname[index], lib_array[i].a1_fname[index] ) == 0 ) { fprintf ( stderr, "Config file error: f2 file is the same as f1 file\n" ); fprintf ( stderr, "f1=%s\n", lib_array[i].a1_fname[index] ); fprintf ( stderr, "f2=%s\n", lib_array[i].a2_fname[index] ); exit ( -1 ); } } else if ( strcmp ( tabs[0], "q2" ) == 0 ) { index = lib_array[i].num_q2_file++; strcpy ( lib_array[i].q2_fname[index], tabs[1] ); if ( strcmp ( lib_array[i].q2_fname[index], lib_array[i].q1_fname[index] ) == 0 ) { fprintf ( stderr, "Config file error: q2 file is the same as q1 file\n" ); fprintf ( stderr, "q1=%s\n", lib_array[i].q1_fname[index] ); fprintf ( stderr, "q2=%s\n", lib_array[i].q2_fname[index] ); exit ( -1 ); } } else if ( strcmp ( tabs[0], "f" ) == 0 ) { index = lib_array[i].num_s_a_file++; strcpy ( lib_array[i].s_a_fname[index], tabs[1] ); } else if ( strcmp ( tabs[0], "q" ) == 0 ) { index = lib_array[i].num_s_q_file++; strcpy ( lib_array[i].s_q_fname[index], tabs[1] ); } else if ( strcmp ( tabs[0], "p" ) == 0 ) { index = lib_array[i].num_p_file++; strcpy ( lib_array[i].p_fname[index], tabs[1] ); } else if ( strcmp ( tabs[0], "b" ) == 0 ) { //bam file index = lib_array[i].num_b_file++; strcpy ( lib_array[i].b_fname[index], tabs[1] ); } else if ( strcmp ( tabs[0], "min_ins" ) == 0 ) { lib_array[i].min_ins = atoi ( tabs[1] ); } else if ( strcmp ( tabs[0], "max_ins" ) == 0 ) { lib_array[i].max_ins = atoi ( tabs[1] ); } else if ( strcmp ( tabs[0], "avg_ins" ) == 0 ) { lib_array[i].avg_ins = atoi ( tabs[1] ); } else if ( strcmp ( tabs[0], "rd_len_cutoff" ) == 0 ) { lib_array[i].rd_len_cutoff = atoi ( tabs[1] ); } else if ( strcmp ( tabs[0], "reverse_seq" ) == 0 ) { lib_array[i].reverse = atoi ( tabs[1] ); } else if ( strcmp ( tabs[0], "asm_flags" ) == 0 ) { lib_array[i].asm_flag = atoi ( tabs[1] ); } else if ( strcmp ( tabs[0], "rank" ) == 0 ) { lib_array[i].rank = atoi ( tabs[1] ); } else if ( strcmp ( tabs[0], "pair_num_cutoff" ) == 0 ) { lib_array[i].pair_num_cut = atoi ( tabs[1] ); } else if ( strcmp ( tabs[0], "rd_len_cutoff" ) == 0 ) { lib_array[i].rd_len_cutoff = atoi ( tabs[1] ); } else if ( strcmp ( tabs[0], "map_len" ) == 0 ) { lib_array[i].map_len = atoi ( tabs[1] ); } } for ( i = 0; i < num_libs; i++ ) { if ( pe[i] && lib_array[i].avg_ins == 0 ) { fprintf ( stderr, "Config file error: PE reads need avg_ins in [LIB] %d\n", i + 1 ); exit ( -1 ); } } fclose ( fp ); qsort ( &lib_array[0], num_libs, sizeof ( LIB_INFO ), cmp_lib ); } void free_libs () { if ( !lib_array ) { return; } int i, j; fprintf ( stderr, "LIB(s) information:\n" ); for ( i = 0; i < num_libs; i++ ) { fprintf ( stderr, " [LIB] %d, avg_ins %d, reverse %d.\n", i, lib_array[i].avg_ins, lib_array[i].reverse ); if ( lib_array[i].num_s_a_file ) { //printf("%d single fasta files\n",lib_array[i].num_s_a_file); for ( j = 0; j < lib_array[i].num_s_a_file; j++ ) { free ( ( void * ) lib_array[i].s_a_fname[j] ); } free ( ( void * ) lib_array[i].s_a_fname ); } if ( lib_array[i].num_s_q_file ) { //printf("%d single fastq files\n",lib_array[i].num_s_q_file); for ( j = 0; j < lib_array[i].num_s_q_file; j++ ) { free ( ( void * ) lib_array[i].s_q_fname[j] ); } free ( ( void * ) lib_array[i].s_q_fname ); } if ( lib_array[i].num_p_file ) { //printf("%d paired fasta files\n",lib_array[i].num_p_file); for ( j = 0; j < lib_array[i].num_p_file; j++ ) { free ( ( void * ) lib_array[i].p_fname[j] ); } free ( ( void * ) lib_array[i].p_fname ); } if ( lib_array[i].num_a1_file ) { //printf("%d read1 fasta files\n",lib_array[i].num_a1_file); for ( j = 0; j < lib_array[i].num_a1_file; j++ ) { free ( ( void * ) lib_array[i].a1_fname[j] ); } free ( ( void * ) lib_array[i].a1_fname ); } if ( lib_array[i].num_a2_file ) { //printf("%d read2 fasta files\n",lib_array[i].num_a2_file); for ( j = 0; j < lib_array[i].num_a2_file; j++ ) { free ( ( void * ) lib_array[i].a2_fname[j] ); } free ( ( void * ) lib_array[i].a2_fname ); } if ( lib_array[i].num_q1_file ) { //printf("%d read1 fastq files\n",lib_array[i].num_q1_file); for ( j = 0; j < lib_array[i].num_q1_file; j++ ) { free ( ( void * ) lib_array[i].q1_fname[j] ); } free ( ( void * ) lib_array[i].q1_fname ); } if ( lib_array[i].num_q2_file ) { //printf("%d read2 fastq files\n",lib_array[i].num_q2_file); for ( j = 0; j < lib_array[i].num_q2_file; j++ ) { free ( ( void * ) lib_array[i].q2_fname[j] ); } free ( ( void * ) lib_array[i].q2_fname ); } if ( lib_array[i].num_b_file ) { //free the bam file name //printf("%d bam files\n",lib_array[i].num_b_file); for ( j = 0; j < lib_array[i].num_b_file; j++ ) { free ( ( void * ) lib_array[i].b_fname[j] ); } free ( ( void * ) lib_array[i].b_fname ); } } num_libs = 0; free ( ( void * ) lib_array ); } void alloc_pe_mem ( int gradsCounter ) { if ( gradsCounter ) { pes = ( PE_INFO * ) ckalloc ( gradsCounter * sizeof ( PE_INFO ) ); } } void free_pe_mem () { if ( pes ) { free ( ( void * ) pes ); pes = NULL; } } soapdenovo2-240+dfsg.orig/standardPregraph/bubble.c0000644000000000000000000016432012166703654021104 0ustar rootroot/* * bubble.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" #include "dfibHeap.h" #include "fibHeap.h" #define false 0 #define true 1 #define SLOW_TO_FAST 1 #define FAST_TO_SLOW 0 #define MAXREADLENGTH 100 #define MAXCONNECTION 100 static int MAXNODELENGTH; // the limit for the edge in the path static int DIFF; // the mininum for the difference between the paths static unsigned int outNodeArray[MAXCONNECTION]; // static ARC * outArcArray[MAXCONNECTION]; static boolean HasChanged; // whether reset the arc static const int INDEL = 0; static const int SIM[4][4] = // the score matrix of comparison { {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1} }; //static variables static READINTERVAL * fastPath; // used to record the ordered edges, which is the saved path static READINTERVAL * slowPath; // used to record the ordered edges, which is the merged path static char fastSequence[MAXREADLENGTH]; // used to record the sequence of the fast path static char slowSequence[MAXREADLENGTH]; // used to record the sequence of the slow path static int fastSeqLength; // the length of the sequence of the fast path static int slowSeqLength; // the length of the sequence of the slow path static Time * times; // record the weight from the upstream edge to the current edge and used to decide which upstream edge is better static unsigned int * previous; // record the upstream edge static unsigned int expCounter; static unsigned int * expanded; static double cutoff; // the mini difference between the paths static int Fmatrix[MAXREADLENGTH + 1][MAXREADLENGTH + 1]; //the score matrix of comparing the paths static int slowToFastMapping[MAXREADLENGTH + 1]; // the edge in the slow path map to the fast path static int fastToSlowMapping[MAXREADLENGTH + 1]; // the edge in the fast path map to the slow path static DFibHeapNode ** dheapNodes; static DFibHeap * dheap; static unsigned int activeNode; //static ARC *activeArc; static unsigned int startingNode; static int progress; static unsigned int * eligibleStartingPoints; // DEBUG static long long caseA, caseB, caseC, caseD, caseE; static long long dnodeCounter; static long long rnodeCounter; static long long btCounter; static long long cmpCounter; static long long simiCounter; //static long long pinCounter; static long long replaceCounter; static long long getArcCounter; // END OF DEBUG /* static void output_contig1(int id, EDGE *edge) { int i; Kmer kmer; char ch; char kmerSeq[100]; printf(">%d_\n",id); kmer = vt_array[edge->from_vt].kmer; for(i=overlaplen-1;i>=0;i--){ ch = kmer&3; kmer >>= 2; kmerSeq[i] = ch; } for(i=0;ilength;i++){ printf("%c",int2base((int)getCharInTightString(edge->seq,i))); if((i+overlaplen+1)%100==0) printf("\n"); } printf("\n"); }*/ static void output_seq ( char * seq, int length, FILE * fp, unsigned int from_vt, unsigned int dest ) { int i; Kmer kmer; kmer = vt_array[from_vt].kmer; printKmerSeq ( fp, kmer ); fprintf ( fp, " " ); for ( i = 0; i < length; i++ ) { fprintf ( fp, "%c", int2base ( ( int ) seq[i] ) ); } if ( edge_array[dest].seq ) { fprintf ( fp, " %c\n", int2base ( ( int ) getCharInTightString ( edge_array[dest].seq, 0 ) ) ); } else { fprintf ( fp, " N\n" ); } } static void print_path ( FILE * fp ) { READINTERVAL * marker; marker = fastPath->nextInRead; while ( marker->nextInRead ) { fprintf ( fp, "%u ", marker->edgeid ); marker = marker->nextInRead; } fprintf ( fp, "\n" ); marker = slowPath->nextInRead; while ( marker->nextInRead ) { fprintf ( fp, "%u ", marker->edgeid ); marker = marker->nextInRead; } fprintf ( fp, "\n" ); } static void output_pair ( int lengthF, int lengthS, FILE * fp, int nodeF, int nodeS, boolean merged, unsigned int source, unsigned int destination ) { fprintf ( fp, "$$ %d vs %d $$ %d\n", nodeF, nodeS, merged ); output_seq ( fastSequence, lengthF, fp, edge_array[source].to_vt, destination ); output_seq ( slowSequence, lengthS, fp, edge_array[source].to_vt, destination ); } /************************************************* Function: resetNodeStatus Description: Resets the status of the edge. Input: None. Output: None. Return: None. *************************************************/ static void resetNodeStatus () { unsigned int index; ARC * arc; unsigned int bal_ed; for ( index = 1; index <= num_ed; index++ ) { if ( EdSameAsTwin ( index ) ) { edge_array[index].multi = 1; continue; } arc = edge_array[index].arcs; bal_ed = getTwinEdge ( index ); while ( arc ) { if ( arc->to_ed == bal_ed ) { break; } arc = arc->next; } if ( arc ) { edge_array[index].multi = 1; edge_array[bal_ed].multi = 1; index++; continue; } arc = edge_array[bal_ed].arcs; while ( arc ) { if ( arc->to_ed == index ) { break; } arc = arc->next; } if ( arc ) { edge_array[index].multi = 1; edge_array[bal_ed].multi = 1; } else { edge_array[index].multi = 0; edge_array[bal_ed].multi = 0; } index++; } } /* static void determineEligibleStartingPoints() { long long index,counter=0; unsigned int node; unsigned int maxmult; ARC *parc; FibHeap *heap = newFibHeap(); for(index=1;index<=num_ed;index++){ if(edge_array[index].deleted||edge_array[index].length<1) continue; maxmult = counter = 0; parc = edge_array[index].arcs; while(parc){ if(parc->multiplicity > maxmult) maxmult = parc->multiplicity; parc = parc->next; } if(maxmult<1){ continue; } insertNodeIntoHeap(heap,-maxmult,index); } counter = 0; while((index=removeNextNodeFromHeap(heap))!=0){ eligibleStartingPoints[counter++] = index; } destroyHeap(heap); printf("%lld edges out of %d are eligible starting points\n",counter,num_ed); } */ /************************************************* Function: nextStartingPoint Description: Gets the next start edge. Input: None. Output: None. Return: The next start edge. *************************************************/ static unsigned int nextStartingPoint () { unsigned int index = 1; unsigned int result = 0; for ( index = progress + 1; index < num_ed; index++ ) { result = index; if ( edge_array[index].deleted || edge_array[index].length < 1 ) { continue; } if ( result == 0 ) { return 0; } if ( edge_array[result].multi > 0 ) { continue; } progress = index; return result; } return 0; } /************************************************* Function: updateNodeStatus Description: Updates the status of the edge. Input: None. Output: None. Return: None. *************************************************/ static void updateNodeStatus () { unsigned int i, node; for ( i = 0; i < expCounter; i++ ) { node = expanded[i]; edge_array[node].multi = 1; edge_array[getTwinEdge ( node )].multi = 1; } } /************************************************* Function: getNodePrevious Description: Gets the previous edge of the current edge , then return it. Input: 1. node: the current edge. Output: None. Return: The previous edge of the current edge. *************************************************/ unsigned int getNodePrevious ( unsigned int node ) { return previous[node]; } /************************************************* Function: isPreviousToNode Description: Checks if the edge "previous" is the previous of the edge "target", if it is, return 1. Input: 1. previous: the edge index 2. target: the edge index Output: None. Return: 1 if the edge "previous" is the previous of the edge "target". *************************************************/ static boolean isPreviousToNode ( unsigned int previous, unsigned int target ) { unsigned int currentNode = target; unsigned int previousNode = 0; Time targetTime = times[target]; while ( currentNode ) { if ( currentNode == previous ) { return 1; } if ( currentNode == previousNode ) { return 0; } if ( times[currentNode] != targetTime ) { return 0; } previousNode = currentNode; currentNode = getNodePrevious ( currentNode ); } return 0; } /************************************************* Function: copySeq Description: Copies the sequence from "sourseS" to "targetS". Input: 1. targetS: the sequence 2. sourceS: the sequence 3. pos: the start position of the targetS 4. length: the length of the sourceS Output: None. Return: None. *************************************************/ static void copySeq ( char * targetS, char * sourceS, int pos, int length ) { char ch; int i, index; index = pos; for ( i = 0; i < length; i++ ) { ch = getCharInTightString ( sourceS, i ); targetS[index++] = ch; } } /************************************************* Function: extractSequence Description: Copies all the sequence of the path to sequence. Input: 1. path: a path consists of the ordered edge 2. sequence: used to record the sequence of the path Output: None. Return: The length of sequence. *************************************************/ static int extractSequence ( READINTERVAL * path, char * sequence ) { READINTERVAL * marker; int seqLength, writeIndex; seqLength = writeIndex = 0; path->start = -10; marker = path->nextInRead; while ( marker->nextInRead ) { marker->start = seqLength; seqLength += edge_array[marker->edgeid].length; marker = marker->nextInRead; } marker->start = seqLength; if ( seqLength > MAXREADLENGTH ) { return 0; } marker = path->nextInRead; while ( marker->nextInRead ) { if ( edge_array[marker->edgeid].length && edge_array[marker->edgeid].seq ) { copySeq ( sequence, edge_array[marker->edgeid].seq, writeIndex, edge_array[marker->edgeid].length ); writeIndex += edge_array[marker->edgeid].length; } /* else if(edge_array[marker->edgeid].length==0) printf("node %d with length 0 in this path\n",marker->edgeid); else if(edge_array[marker->edgeid].seq==NULL) printf("node %d without seq in this path\n",marker->edgeid); */ marker = marker->nextInRead; } return seqLength; } static int max ( int A, int B, int C ) { A = A >= B ? A : B; return ( A >= C ? A : C ); } /************************************************* Function: compareSequences Description: Checks if the sequences are long enough and high similar. if not, return 0. Input: 1. sequence1: the first sequence 2. sequence2: the second sequence 3. length1: the length of the first sequence 4. length2: the length of the second sequence Output: None. Return: 0 if the bubble is not suitable to merge. *************************************************/ static boolean compareSequences ( char * sequence1, char * sequence2, int length1, int length2 ) { int i, j; int maxLength; int Choice1, Choice2, Choice3; int maxScore; if ( length1 == 0 || length2 == 0 ) { caseA++; return 0; } if ( abs ( ( int ) length1 - ( int ) length2 ) > 2 ) { caseB++; return 0; } if ( length1 < overlaplen - 1 || length2 < overlaplen - 1 ) { caseE++; return 0; } /* if (length1 < overlaplen || length2 < overlaplen){ if(abs((int)length1 - (int)length2) > 3){ caseB++; return 0; } } */ for ( i = 0; i <= length1; i++ ) { Fmatrix[i][0] = 0; } for ( j = 0; j <= length2; j++ ) { Fmatrix[0][j] = 0; } for ( i = 1; i <= length1; i++ ) { for ( j = 1; j <= length2; j++ ) { Choice1 = Fmatrix[i - 1][j - 1] + SIM[ ( int ) sequence1[i - 1]][ ( int ) sequence2[j - 1]]; Choice2 = Fmatrix[i - 1][j] + INDEL; Choice3 = Fmatrix[i][j - 1] + INDEL; Fmatrix[i][j] = max ( Choice1, Choice2, Choice3 ); } } maxScore = Fmatrix[length1][length2]; maxLength = ( length1 > length2 ? length1 : length2 ); if ( maxScore < maxLength - DIFF ) { caseC++; return 0; } if ( ( 1 - ( double ) maxScore / maxLength ) > cutoff ) { caseD++; return 0; } return 1; } /************************************************* Function: mapSlowOntoFast Description: Maps the sequence of the slow path to the one of the fast path. Input: None. Output: None. Return: None. *************************************************/ static void mapSlowOntoFast () { int slowIndex = slowSeqLength; int fastIndex = fastSeqLength; int fastn, slown; if ( slowIndex == 0 ) { slowToFastMapping[0] = fastIndex; while ( fastIndex >= 0 ) { fastToSlowMapping[fastIndex--] = 0; } return; } if ( fastIndex == 0 ) { while ( slowIndex >= 0 ) { slowToFastMapping[slowIndex--] = 0; } fastToSlowMapping[0] = slowIndex; return; } while ( slowIndex > 0 && fastIndex > 0 ) { fastn = ( int ) fastSequence[fastIndex - 1]; //getCharInTightString(fastSequence,fastIndex-1); slown = ( int ) slowSequence[slowIndex - 1]; //getCharInTightString(slowSequence,slowIndex-1); if ( Fmatrix[fastIndex][slowIndex] == Fmatrix[fastIndex - 1][slowIndex - 1] + SIM[fastn][slown] ) { fastToSlowMapping[--fastIndex] = --slowIndex; slowToFastMapping[slowIndex] = fastIndex; } else if ( Fmatrix[fastIndex][slowIndex] == Fmatrix[fastIndex - 1][slowIndex] + INDEL ) { fastToSlowMapping[--fastIndex] = slowIndex - 1; } else if ( Fmatrix[fastIndex][slowIndex] == Fmatrix[fastIndex][slowIndex - 1] + INDEL ) { slowToFastMapping[--slowIndex] = fastIndex - 1; } else { fprintf ( stderr, "Error in the step: map the slow path to the fast path.\n" ); abort (); } } while ( slowIndex > 0 ) { slowToFastMapping[--slowIndex] = -1; } while ( fastIndex > 0 ) { fastToSlowMapping[--fastIndex] = -1; } slowToFastMapping[slowSeqLength] = fastSeqLength; fastToSlowMapping[fastSeqLength] = slowSeqLength; } /************************************************* Function: deleteArc Description: Removes an arc from the double linked list and return the updated list Input: 1. arc_list: the linked of the arc 2. arc: the deleted arc Output: None. Return: The new linked of the arc. *************************************************/ ARC * deleteArc ( ARC * arc_list, ARC * arc ) { if ( arc->prev ) { arc->prev->next = arc->next; } else { arc_list = arc->next; } if ( arc->next ) { arc->next->prev = arc->prev; } /* if(checkActiveArc&&arc==activeArc){ activeArc = arc->next; } */ dismissArc ( arc ); return arc_list; } /************************************************* Function: addRv Description: Add a rv to the head of a rv list. Input: 1. rv_list: the linked of the path 2. rv: the new one, which will be added into the path Output: None. Return: The new linked of the path. *************************************************/ static READINTERVAL * addRv ( READINTERVAL * rv_list, READINTERVAL * rv ) { rv->prevOnEdge = NULL; rv->nextOnEdge = rv_list; if ( rv_list ) { rv_list->prevOnEdge = rv; } rv_list = rv; return rv_list; } /************************************************* Function: deleteRv Description: Removes a rv from the double linked list and return the updated list Input: 1. rv_list: the linked of the path 2. rv: the deleted head from the path Output: None. Return: The new linked of the path. *************************************************/ static READINTERVAL * deleteRv ( READINTERVAL * rv_list, READINTERVAL * rv ) { if ( rv->prevOnEdge ) { rv->prevOnEdge->nextOnEdge = rv->nextOnEdge; } else { rv_list = rv->nextOnEdge; } if ( rv->nextOnEdge ) { rv->nextOnEdge->prevOnEdge = rv->prevOnEdge; } return rv_list; } /* static void disconnect(unsigned int from_ed, unsigned int to_ed) { READINTERVAL *rv_temp; rv_temp = edge_array[from_ed].rv; while(rv_temp){ if(!rv_temp->nextInRead||rv_temp->nextInRead->edgeid!=to_ed){ rv_temp = rv_temp->nextOnEdge; continue; } rv_temp->nextInRead->prevInRead = NULL; rv_temp->nextInRead = NULL; rv_temp = rv_temp->nextOnEdge; } } */ /************************************************* Function: mapDistancesOntoPaths Description: Sets the distance of the edge on the path. Input: None. Output: None. Return: The total distance of the fast path. *************************************************/ static int mapDistancesOntoPaths () { READINTERVAL * marker; int totalDistance = 0; marker = slowPath; while ( marker->nextInRead ) { marker = marker->nextInRead; marker->start = totalDistance; totalDistance += edge_array[marker->edgeid].length; marker->bal_rv->start = totalDistance; } totalDistance = 0; marker = fastPath; while ( marker->nextInRead ) { marker = marker->nextInRead; marker->start = totalDistance; totalDistance += edge_array[marker->edgeid].length; marker->bal_rv->start = totalDistance; } return totalDistance; } /************************************************* Function: attachPath Description: Attaches a path to the graph and mean while make the reverse complementary path of it Input: 1. path: the target path Output: None. Return: None. *************************************************/ static void attachPath ( READINTERVAL * path ) { READINTERVAL * marker, *bal_marker; unsigned int ed, bal_ed; marker = path; while ( marker ) { ed = marker->edgeid; edge_array[ed].rv = addRv ( edge_array[ed].rv, marker ); bal_ed = getTwinEdge ( ed ); bal_marker = allocateRV ( -marker->readid, bal_ed ); edge_array[bal_ed].rv = addRv ( edge_array[bal_ed].rv, bal_marker ); if ( marker->prevInRead ) { marker->prevInRead->bal_rv->prevInRead = bal_marker; bal_marker->nextInRead = marker->prevInRead->bal_rv; } bal_marker->bal_rv = marker; marker->bal_rv = bal_marker; marker = marker->nextInRead; } } static void detachPathSingle ( READINTERVAL * path ) { READINTERVAL * marker, *nextMarker; unsigned int ed; marker = path; while ( marker ) { nextMarker = marker->nextInRead; ed = marker->edgeid; edge_array[ed].rv = deleteRv ( edge_array[ed].rv, marker ); dismissRV ( marker ); marker = nextMarker; } } /************************************************* Function: detachPath Description: Removes the path. Input: 1. path: the linked of the path Output: None. Return: None. *************************************************/ static void detachPath ( READINTERVAL * path ) { READINTERVAL * marker, *bal_marker, *nextMarker; unsigned int ed, bal_ed; marker = path; while ( marker ) { nextMarker = marker->nextInRead; bal_marker = marker->bal_rv; ed = marker->edgeid; edge_array[ed].rv = deleteRv ( edge_array[ed].rv, marker ); dismissRV ( marker ); bal_ed = getTwinEdge ( ed ); edge_array[bal_ed].rv = deleteRv ( edge_array[bal_ed].rv, bal_marker ); dismissRV ( bal_marker ); marker = nextMarker; } } static void remapNodeMarkersOntoNeighbour ( unsigned int source, unsigned int target ) { READINTERVAL * marker, *bal_marker; unsigned int bal_source = getTwinEdge ( source ); unsigned int bal_target = getTwinEdge ( target ); while ( ( marker = edge_array[source].rv ) != NULL ) { edge_array[source].rv = deleteRv ( edge_array[source].rv, marker ); marker->edgeid = target; edge_array[target].rv = addRv ( edge_array[target].rv, marker ); bal_marker = marker->bal_rv; edge_array[bal_source].rv = deleteRv ( edge_array[bal_source].rv, bal_marker ); bal_marker->edgeid = bal_target; edge_array[bal_target].rv = addRv ( edge_array[bal_target].rv, bal_marker ); } } static void remapNodeInwardReferencesOntoNode ( unsigned int source, unsigned int target ) { ARC * arc; unsigned int destination; for ( arc = edge_array[source].arcs; arc != NULL; arc = arc->next ) { destination = arc->to_ed; if ( destination == target || destination == source ) { continue; } if ( previous[destination] == source ) { previous[destination] = target; } } } static void remapNodeTimesOntoTargetNode ( unsigned int source, unsigned int target ) { Time nodeTime = times[source]; unsigned int prevNode = previous[source]; Time targetTime = times[target]; if ( nodeTime == -1 ) { return; } if ( prevNode == source ) { times[target] = nodeTime; previous[target] = target; } else if ( targetTime == -1 || targetTime > nodeTime || ( targetTime == nodeTime && !isPreviousToNode ( target, prevNode ) ) ) { times[target] = nodeTime; if ( prevNode != getTwinEdge ( source ) ) { previous[target] = prevNode; } else { previous[target] = getTwinEdge ( target ); } } remapNodeInwardReferencesOntoNode ( source, target ); previous[source] = 0; } static void remapNodeTimesOntoNeighbour ( unsigned int source, unsigned int target ) { remapNodeTimesOntoTargetNode ( source, target ); remapNodeTimesOntoTargetNode ( getTwinEdge ( source ), getTwinEdge ( target ) ); //questionable } static void destroyArc ( unsigned int from_ed, ARC * arc ) { unsigned int bal_dest; ARC * twinArc; if ( !arc ) { return; } bal_dest = getTwinEdge ( arc->to_ed ); twinArc = arc->bal_arc; removeArcInLookupTable ( from_ed, arc->to_ed ); edge_array[from_ed].arcs = deleteArc ( edge_array[from_ed].arcs, arc ); if ( bal_dest != from_ed ) { removeArcInLookupTable ( bal_dest, getTwinEdge ( from_ed ) ); edge_array[bal_dest].arcs = deleteArc ( edge_array[bal_dest].arcs, twinArc ); } } static void createAnalogousArc ( unsigned int originNode, unsigned int destinationNode, ARC * refArc ) { ARC * arc, *twinArc; unsigned int destinationTwin; arc = getArcBetween ( originNode, destinationNode ); if ( arc ) { if ( refArc->bal_arc != refArc ) { arc->multiplicity += refArc->multiplicity; arc->bal_arc->multiplicity += refArc->multiplicity; } else { arc->multiplicity += refArc->multiplicity / 2; arc->bal_arc->multiplicity += refArc->multiplicity / 2; } return; } arc = allocateArc ( destinationNode ); arc->multiplicity = refArc->multiplicity; arc->prev = NULL; arc->next = edge_array[originNode].arcs; if ( edge_array[originNode].arcs ) { edge_array[originNode].arcs->prev = arc; } edge_array[originNode].arcs = arc; putArc2LookupTable ( originNode, arc ); destinationTwin = getTwinEdge ( destinationNode ); if ( destinationTwin == originNode ) { arc->bal_arc = arc; if ( refArc->bal_arc != refArc ) { arc->multiplicity += refArc->multiplicity; } return; } twinArc = allocateArc ( getTwinEdge ( originNode ) ); arc->bal_arc = twinArc; twinArc->bal_arc = arc; twinArc->multiplicity = refArc->multiplicity; twinArc->prev = NULL; twinArc->next = edge_array[destinationTwin].arcs; if ( edge_array[destinationTwin].arcs ) { edge_array[destinationTwin].arcs->prev = twinArc; } edge_array[destinationTwin].arcs = twinArc; putArc2LookupTable ( destinationTwin, twinArc ); } static void remapNodeArcsOntoTarget ( unsigned int source, unsigned int target ) { ARC * arc; if ( source == activeNode ) { activeNode = target; } arc = edge_array[source].arcs; if ( !arc ) { return; } while ( arc != NULL ) { createAnalogousArc ( target, arc->to_ed, arc ); destroyArc ( source, arc ); arc = edge_array[source].arcs; } } static void remapNodeArcsOntoNeighbour ( unsigned int source, unsigned int target ) { remapNodeArcsOntoTarget ( source, target ); remapNodeArcsOntoTarget ( getTwinEdge ( source ), getTwinEdge ( target ) ); } static DFibHeapNode * getNodeDHeapNode ( unsigned int node ) { return dheapNodes[node]; } static void setNodeDHeapNode ( unsigned int node, DFibHeapNode * dheapNode ) { dheapNodes[node] = dheapNode; } static void remapNodeFibHeapReferencesOntoNode ( unsigned int source, unsigned int target ) { DFibHeapNode * sourceDHeapNode = getNodeDHeapNode ( source ); DFibHeapNode * targetDHeapNode = getNodeDHeapNode ( target ); if ( sourceDHeapNode == NULL ) { return; } if ( targetDHeapNode == NULL ) { setNodeDHeapNode ( target, sourceDHeapNode ); replaceValueInDHeap ( sourceDHeapNode, target ); } else if ( getKey ( targetDHeapNode ) > getKey ( sourceDHeapNode ) ) { setNodeDHeapNode ( target, sourceDHeapNode ); replaceValueInDHeap ( sourceDHeapNode, target ); destroyNodeInDHeap ( targetDHeapNode, dheap ); } else { destroyNodeInDHeap ( sourceDHeapNode, dheap ); } setNodeDHeapNode ( source, NULL ); } static void combineCOV ( unsigned int source, int len_s, unsigned int target, int len_t ) { if ( len_s < 1 || len_t < 1 ) { return; } int cov = ( len_s * edge_array[source].cvg + len_t * edge_array[target].cvg ) / len_t; edge_array[target].cvg = cov > MaxEdgeCov ? MaxEdgeCov : cov; edge_array[getTwinEdge ( target )].cvg = cov > MaxEdgeCov ? MaxEdgeCov : cov; } /************************************************* Function: remapNodeOntoNeighbour Description: Replaces the edge 'source' with the edge 'target' and adds the position info from 'source' to 'target'. Input: 1. source: the edge index 2. target: the edge index Output: None. Return: None. *************************************************/ static void remapNodeOntoNeighbour ( unsigned int source, unsigned int target ) { combineCOV ( source, edge_array[source].length, target, edge_array[target].length ); remapNodeMarkersOntoNeighbour ( source, target ); remapNodeTimesOntoNeighbour ( source, target ); //questionable remapNodeArcsOntoNeighbour ( source, target ); remapNodeFibHeapReferencesOntoNode ( source, target ); remapNodeFibHeapReferencesOntoNode ( getTwinEdge ( source ), getTwinEdge ( target ) ); edge_array[source].deleted = 1; edge_array[getTwinEdge ( source )].deleted = 1; if ( startingNode == source ) { startingNode = target; } if ( startingNode == getTwinEdge ( source ) ) { startingNode = getTwinEdge ( target ); } edge_array[source].length = 0; edge_array[getTwinEdge ( source )].length = 0; } static void connectInRead ( READINTERVAL * previous, READINTERVAL * next ) { if ( previous ) { previous->nextInRead = next; if ( next ) { previous->bal_rv->prevInRead = next->bal_rv; } else { previous->bal_rv->prevInRead = NULL; } } if ( next ) { next->prevInRead = previous; if ( previous ) { next->bal_rv->nextInRead = previous->bal_rv; } else { next->bal_rv->nextInRead = NULL; } } } static int remapBackOfNodeMarkersOntoNeighbour ( unsigned int source, READINTERVAL * sourceMarker, unsigned int target, READINTERVAL * targetMarker, boolean slowToFast ) { READINTERVAL * marker, *newMarker, *bal_new, *previousMarker; int halfwayPoint, halfwayPointOffset, breakpoint; int * targetToSourceMapping, *sourceToTargetMapping; unsigned int bal_ed; int targetFinish = targetMarker->bal_rv->start; int sourceStart = sourceMarker->start; int sourceFinish = sourceMarker->bal_rv->start; int alignedSourceLength = sourceFinish - sourceStart; int realSourceLength = edge_array[source].length; if ( slowToFast ) { sourceToTargetMapping = slowToFastMapping; targetToSourceMapping = fastToSlowMapping; } else { sourceToTargetMapping = fastToSlowMapping; targetToSourceMapping = slowToFastMapping; } if ( alignedSourceLength > 0 && targetFinish > 0 ) { halfwayPoint = targetToSourceMapping[targetFinish - 1] - sourceStart + 1; halfwayPoint *= realSourceLength; halfwayPoint /= alignedSourceLength; } else { halfwayPoint = 0; } if ( halfwayPoint < 0 ) { halfwayPoint = 0; } if ( halfwayPoint > realSourceLength ) { halfwayPoint = realSourceLength; } halfwayPointOffset = realSourceLength - halfwayPoint; bal_ed = getTwinEdge ( target ); for ( marker = edge_array[source].rv; marker != NULL; marker = marker->nextOnEdge ) { if ( marker->prevInRead && marker->prevInRead->edgeid == target ) { continue; } newMarker = allocateRV ( marker->readid, target ); edge_array[target].rv = addRv ( edge_array[target].rv, newMarker ); bal_new = allocateRV ( -marker->readid, bal_ed ); edge_array[bal_ed].rv = addRv ( edge_array[bal_ed].rv, bal_new ); newMarker->bal_rv = bal_new; bal_new->bal_rv = newMarker; newMarker->start = marker->start; if ( realSourceLength > 0 ) { breakpoint = halfwayPoint + marker->start; } else { breakpoint = marker->start; } bal_new->start = breakpoint; marker->start = breakpoint; previousMarker = marker->prevInRead; connectInRead ( previousMarker, newMarker ); connectInRead ( newMarker, marker ); } return halfwayPointOffset; } static void printKmer ( Kmer kmer ) { printKmerSeq ( stderr, kmer ); fprintf ( stderr, "\n" ); } static int splitNodeDescriptor ( unsigned int source, unsigned int target, int offset ) { int originalLength = edge_array[source].length; int backLength = originalLength - offset; int index, seqLen; char * tightSeq, nt, *newSeq; unsigned int bal_source = getTwinEdge ( source ); unsigned int bal_target = getTwinEdge ( target ); edge_array[source].length = offset; edge_array[bal_source].length = offset; edge_array[source].flag = 1; edge_array[bal_source].flag = 1; if ( target != 0 ) { edge_array[target].length = backLength; edge_array[bal_target].length = backLength; free ( ( void * ) edge_array[target].seq ); edge_array[target].seq = NULL; free ( ( void * ) edge_array[bal_target].seq ); edge_array[bal_target].seq = NULL; } if ( backLength == 0 ) { return 0; } tightSeq = edge_array[source].seq; seqLen = backLength / 4 + 1; if ( target != 0 ) { edge_array[target].flag = 1; edge_array[bal_target].flag = 1; newSeq = ( char * ) ckalloc ( seqLen * sizeof ( char ) ); edge_array[target].seq = newSeq; for ( index = 0; index < backLength; index++ ) { nt = getCharInTightString ( tightSeq, index ); writeChar2tightString ( nt, newSeq, index ); } } //source node for ( index = backLength; index < originalLength; index++ ) { nt = getCharInTightString ( tightSeq, index ); writeChar2tightString ( nt, tightSeq, index - backLength ); } if ( target == 0 ) { return backLength; } //target twin tightSeq = edge_array[bal_source].seq; newSeq = ( char * ) ckalloc ( seqLen * sizeof ( char ) ); edge_array[bal_target].seq = newSeq; for ( index = offset; index < originalLength; index++ ) { nt = getCharInTightString ( tightSeq, index ); writeChar2tightString ( nt, newSeq, index - offset ); } return backLength; } static void remapBackOfNodeDescriptorOntoNeighbour ( unsigned int source, unsigned int target, boolean slowToFast, int offset ) { unsigned int bal_source = getTwinEdge ( source ); unsigned int bal_target = getTwinEdge ( target ); Kmer source_from_vt_kmer , bal_source_from_vt_kmer; Kmer word; int index; char nt; int backlength ; if ( slowToFast ) { backlength = splitNodeDescriptor ( source, 0, offset ); edge_array[source].from_vt = edge_array[target].to_vt; edge_array[bal_source].to_vt = edge_array[bal_target].from_vt; } else { backlength = splitNodeDescriptor ( source, target, offset ); source_from_vt_kmer = vt_array[edge_array[source].from_vt].kmer; bal_source_from_vt_kmer = vt_array[edge_array[bal_source].to_vt].kmer; edge_array[target].from_vt = new_num_vt; if ( new_num_vt + 1 > num_kmer_limit ) { fprintf ( stderr, "Error : Number of vertex is out of range.\n" ); exit ( -1 ); } vt_array[new_num_vt++].kmer = source_from_vt_kmer; edge_array[bal_target].to_vt = new_num_vt; if ( new_num_vt + 1 > num_kmer_limit ) { fprintf ( stderr, "Error : Number of vertex is out of range.\n" ); exit ( -1 ); } vt_array[new_num_vt++].kmer = bal_source_from_vt_kmer; word = vt_array[edge_array[target].from_vt].kmer; for ( index = 0; index < backlength; index++ ) { nt = getCharInTightString ( edge_array[target].seq, index ); word = nextKmer ( word, nt ); } edge_array[target].to_vt = new_num_vt; if ( new_num_vt + 1 > num_kmer_limit ) { fprintf ( stderr, "Error : Number of vertex is out of range.\n" ); exit ( -1 ); } vt_array[new_num_vt++].kmer = word; edge_array[source].from_vt = new_num_vt; if ( new_num_vt + 1 > num_kmer_limit ) { fprintf ( stderr, "Error : Number of vertex is out of range.\n" ); exit ( -1 ); } vt_array[new_num_vt++].kmer = word; word = vt_array[edge_array[bal_source].from_vt].kmer; for ( index = 0; index < offset; index++ ) { nt = getCharInTightString ( edge_array[bal_source].seq, index ); word = nextKmer ( word, nt ); } edge_array[bal_target].from_vt = new_num_vt; if ( new_num_vt + 1 > num_kmer_limit ) { fprintf ( stderr, "Error : Number of vertex is out of range.\n" ); exit ( -1 ); } vt_array[new_num_vt++].kmer = word; edge_array[bal_source].to_vt = new_num_vt; if ( new_num_vt + 1 > num_kmer_limit ) { fprintf ( stderr, "Error : Number of vertex is out of range.\n" ); exit ( -1 ); } vt_array[new_num_vt++].kmer = word; } } static void remapBackOfNodeTimesOntoNeighbour ( unsigned int source, unsigned int target ) { Time targetTime = times[target]; Time nodeTime = times[source]; unsigned int twinTarget = getTwinEdge ( target ); unsigned int twinSource = getTwinEdge ( source ); unsigned int previousNode; if ( nodeTime != -1 ) { previousNode = previous[source]; if ( previousNode == source ) { times[target] = nodeTime; previous[target] = target; } else if ( targetTime == -1 || targetTime > nodeTime || ( targetTime == nodeTime && !isPreviousToNode ( target, previousNode ) ) ) { times[target] = nodeTime; if ( previousNode != twinSource ) { previous[target] = previousNode; } else { previous[target] = twinTarget; } } previous[source] = target; } targetTime = times[twinTarget]; nodeTime = times[twinSource]; if ( nodeTime != -1 ) { if ( targetTime == -1 || targetTime > nodeTime || ( targetTime == nodeTime && !isPreviousToNode ( twinTarget, twinSource ) ) ) { times[twinTarget] = nodeTime; previous[twinTarget] = twinSource; } } remapNodeInwardReferencesOntoNode ( twinSource, twinTarget ); } static void remapBackOfNodeArcsOntoNeighbour ( unsigned int source, unsigned int target ) { ARC * arc; remapNodeArcsOntoTarget ( getTwinEdge ( source ), getTwinEdge ( target ) ); for ( arc = edge_array[source].arcs; arc != NULL; arc = arc->next ) { createAnalogousArc ( target, source, arc ); } } /************************************************* Function: remapBackOfNodeOntoNeighbour Description: Splits the edge 'source' and updates the info. Input: 1. source: the source edge index 2. sourceMarker: the linked of the source path 3. target: the target edge index 4. targetMarker: the linked of the target path 5. slowToFast: 1 for slow edge map onto fast edge; 0 for fast edge map onto slow edge Output: None. Return: None. *************************************************/ static void remapBackOfNodeOntoNeighbour ( unsigned int source, READINTERVAL * sourceMarker, unsigned int target, READINTERVAL * targetMarker, boolean slowToFast ) { int offset; offset = remapBackOfNodeMarkersOntoNeighbour ( source, sourceMarker, target, targetMarker, slowToFast ); remapBackOfNodeDescriptorOntoNeighbour ( source, target, slowToFast, offset ); combineCOV ( source, edge_array[source].length, target, edge_array[target].length ); remapBackOfNodeTimesOntoNeighbour ( source, target ); remapBackOfNodeArcsOntoNeighbour ( source, target ); remapNodeFibHeapReferencesOntoNode ( getTwinEdge ( source ), getTwinEdge ( target ) ); //why not "remapNodeFibHeapReferencesOntoNode(source,target);" //because the downstream part of source still retains, which can serve as previousNode as before if ( getTwinEdge ( source ) == startingNode ) { startingNode = getTwinEdge ( target ); } } /************************************************* Function: markerLeadsToNode Description: Checks if the path exists the edge. Input: 1. marker: the linked of the path 2. node: the edge index Output: None. Return: True if the edge is on the path. *************************************************/ static boolean markerLeadsToNode ( READINTERVAL * marker, unsigned int node ) { READINTERVAL * currentMarker; for ( currentMarker = marker; currentMarker != NULL; currentMarker = currentMarker->nextInRead ) if ( currentMarker->edgeid == node ) { return true; } return false; } /************************************************* Function: reduceNode Description: Deletes the edge. Input: 1. node: the edge index Output: None. Return: None. *************************************************/ static void reduceNode ( unsigned int node ) { unsigned int bal_ed = getTwinEdge ( node ); edge_array[node].length = 0; edge_array[bal_ed].length = 0; } /************************************************* Function: reduceSlowNodes Description: Removes the edges from the slow path until the edge 'finish'. Input: 1. slowMarker: the linked of the slow path 2. finish: the edge index Output: None. Return: None. *************************************************/ static void reduceSlowNodes ( READINTERVAL * slowMarker, unsigned int finish ) { READINTERVAL * marker; for ( marker = slowMarker; marker->edgeid != finish; marker = marker->nextInRead ) { reduceNode ( marker->edgeid ); } } static boolean markerLeadsToArc ( READINTERVAL * marker, unsigned int nodeA, unsigned int nodeB ) { READINTERVAL * current, *next; unsigned int twinA = getTwinEdge ( nodeA ); unsigned int twinB = getTwinEdge ( nodeB ); current = marker; while ( current != NULL ) { next = current->nextInRead; if ( current->edgeid == nodeA && next->edgeid == nodeB ) { return true; } if ( current->edgeid == twinB && next->edgeid == twinA ) { return true; } current = next; } return false; } static void remapEmptyPathArcsOntoMiddlePathSimple ( READINTERVAL * emptyPath, READINTERVAL * targetPath ) { READINTERVAL * pathMarker, *marker; unsigned int start = emptyPath->prevInRead->edgeid; unsigned int finish = emptyPath->edgeid; unsigned int previousNode = start; unsigned int currentNode; ARC * originalArc = getArcBetween ( start, finish ); if ( !originalArc ) { fprintf ( stderr, "RemapEmptyPathArcsOntoMiddlePathSimple: no arc between %d and %d.\n", start, finish ); marker = fastPath; fprintf ( stderr, "Fast path: " ); while ( marker ) { fprintf ( stderr, "%d,", marker->edgeid ); marker = marker->nextInRead; } fprintf ( stderr, "\n" ); marker = slowPath; fprintf ( stderr, "Slow path: " ); while ( marker ) { fprintf ( stderr, "%d,", marker->edgeid ); marker = marker->nextInRead; } fprintf ( stderr, "\n" ); } for ( pathMarker = targetPath; pathMarker->edgeid != finish; pathMarker = pathMarker->nextInRead ) { currentNode = pathMarker->edgeid; createAnalogousArc ( previousNode, currentNode, originalArc ); previousNode = currentNode; } createAnalogousArc ( previousNode, finish, originalArc ); destroyArc ( start, originalArc ); } static void remapEmptyPathMarkersOntoMiddlePathSimple ( READINTERVAL * emptyPath, READINTERVAL * targetPath, boolean slowToFast ) { READINTERVAL * marker, *newMarker, *previousMarker, *pathMarker, *bal_marker; unsigned int start = emptyPath->prevInRead->edgeid; unsigned int finish = emptyPath->edgeid; unsigned int markerStart, bal_ed; READINTERVAL * oldMarker = edge_array[finish].rv; while ( oldMarker ) { marker = oldMarker; oldMarker = marker->nextOnEdge; newMarker = marker->prevInRead; if ( newMarker->edgeid != start ) { continue; } if ( ( slowToFast && marker->readid != 2 ) || ( !slowToFast && marker->readid != 1 ) ) { continue; } markerStart = marker->start; for ( pathMarker = targetPath; pathMarker->edgeid != finish; pathMarker = pathMarker->nextInRead ) { previousMarker = newMarker; //maker a new marker newMarker = allocateRV ( marker->readid, pathMarker->edgeid ); newMarker->start = markerStart; edge_array[pathMarker->edgeid].rv = addRv ( edge_array[pathMarker->edgeid].rv, newMarker ); //maker the twin marker bal_ed = getTwinEdge ( pathMarker->edgeid ); bal_marker = allocateRV ( -marker->readid, bal_ed ); bal_marker->start = markerStart; edge_array[bal_ed].rv = addRv ( edge_array[bal_ed].rv, bal_marker ); newMarker->bal_rv = bal_marker; bal_marker->bal_rv = newMarker; connectInRead ( previousMarker, newMarker ); } connectInRead ( newMarker, marker ); } } static void remapNodeTimesOntoForwardMiddlePath ( unsigned int source, READINTERVAL * path ) { READINTERVAL * marker; unsigned int target; Time nodeTime = times[source]; unsigned int previousNode = previous[source]; Time targetTime; for ( marker = path; marker->edgeid != source; marker = marker->nextInRead ) { target = marker->edgeid; targetTime = times[target]; if ( targetTime == -1 || targetTime > nodeTime || ( targetTime == nodeTime && !isPreviousToNode ( target, previousNode ) ) ) { times[target] = nodeTime; previous[target] = previousNode; } previousNode = target; } previous[source] = previousNode; } static void remapNodeTimesOntoTwinMiddlePath ( unsigned int source, READINTERVAL * path ) { READINTERVAL * marker; unsigned int target; unsigned int previousNode = getTwinEdge ( source ); Time targetTime; READINTERVAL * limit = path->prevInRead->bal_rv; Time nodeTime = times[limit->edgeid]; marker = path; while ( marker->edgeid != source ) { marker = marker->nextInRead; } marker = marker->bal_rv; while ( marker != limit ) { marker = marker->nextInRead; target = marker->edgeid; targetTime = times[target]; if ( targetTime == -1 || targetTime > nodeTime || ( targetTime == nodeTime && !isPreviousToNode ( target, previousNode ) ) ) { times[target] = nodeTime; previous[target] = previousNode; } previousNode = target; } } /************************************************* Function: remapEmptyPathOntoMiddlePath Description: Updates the info of the slow path according to the fast path. Input: 1. emptyPath: the linked of the path 2. targetPath: the linked of the path 3. slowToFast: 0 for 'emptyPath' is the fast path and 'targetPath' is the slow path Output: None. Return: None. *************************************************/ static void remapEmptyPathOntoMiddlePath ( READINTERVAL * emptyPath, READINTERVAL * targetPath, boolean slowToFast ) { unsigned int start = emptyPath->prevInRead->edgeid; unsigned int finish = emptyPath->edgeid; // Remapping markers if ( !markerLeadsToArc ( targetPath, start, finish ) ) { remapEmptyPathArcsOntoMiddlePathSimple ( emptyPath, targetPath ); } remapEmptyPathMarkersOntoMiddlePathSimple ( emptyPath, targetPath, slowToFast ); //Remap times and previous(if necessary) if ( getNodePrevious ( finish ) == start ) { remapNodeTimesOntoForwardMiddlePath ( finish, targetPath ); } if ( getNodePrevious ( getTwinEdge ( start ) ) == getTwinEdge ( finish ) ) { remapNodeTimesOntoTwinMiddlePath ( finish, targetPath ); } } /************************************************* Function: cleanUpRedundancy Description: Merges the bubble and copies the position info from the slow path to the fast path. Input: None. Output: None. Return: 1 if the bubble is merged successfully. *************************************************/ static boolean cleanUpRedundancy () { READINTERVAL * slowMarker = slowPath->nextInRead, *fastMarker = fastPath->nextInRead; unsigned int slowNode, fastNode; int slowLength, fastLength; int fastConstraint = 0; int slowConstraint = 0; int finalLength; attachPath ( slowPath ); attachPath ( fastPath ); mapSlowOntoFast (); finalLength = mapDistancesOntoPaths (); slowLength = fastLength = 0; while ( slowMarker != NULL && fastMarker != NULL ) { if ( !slowMarker->nextInRead ) { slowLength = finalLength; } else { slowLength = slowToFastMapping[slowMarker->bal_rv->start - 1]; if ( slowLength < slowConstraint ) { slowLength = slowConstraint; } } fastLength = fastMarker->bal_rv->start - 1; if ( fastLength < fastConstraint ) { fastLength = fastConstraint; } slowNode = slowMarker->edgeid; fastNode = fastMarker->edgeid; if ( false ) { fprintf ( stderr, "Slow %d Fast %d.\n", slowLength, fastLength ); } if ( slowNode == fastNode ) { if ( false ) { fprintf ( stderr, "0/ Already merged together %d == %d.\n", slowNode, fastNode ); } if ( fastLength > slowLength ) { slowConstraint = fastLength; } fastConstraint = slowLength; slowMarker = slowMarker->nextInRead; fastMarker = fastMarker->nextInRead; } else if ( slowNode == getTwinEdge ( fastNode ) ) { if ( false ) { fprintf ( stderr, "1/ Creme de la hairpin %d $$ %d.\n", slowNode, fastNode ); } if ( fastLength > slowLength ) { slowConstraint = fastLength; } fastConstraint = slowLength; slowMarker = slowMarker->nextInRead; fastMarker = fastMarker->nextInRead; } else if ( markerLeadsToNode ( slowMarker, fastNode ) ) { if ( false ) { fprintf ( stderr, "2/ Remapping empty fast arc onto slow nodes.\n" ); } reduceSlowNodes ( slowMarker, fastNode ); remapEmptyPathOntoMiddlePath ( fastMarker, slowMarker, FAST_TO_SLOW ); while ( slowMarker->edgeid != fastNode ) { slowMarker = slowMarker->nextInRead; } } else if ( markerLeadsToNode ( fastMarker, slowNode ) ) { if ( false ) { fprintf ( stderr, "3/ Remapping empty slow arc onto fast nodes.\n" ); } remapEmptyPathOntoMiddlePath ( slowMarker, fastMarker, SLOW_TO_FAST ); while ( fastMarker->edgeid != slowNode ) { fastMarker = fastMarker->nextInRead; } } else if ( slowLength == fastLength ) { if ( false ) { fprintf ( stderr, "A/ Mapped equivalent nodes together %d <=> %d.\n", slowNode, fastNode ); } remapNodeOntoNeighbour ( slowNode, fastNode ); slowMarker = slowMarker->nextInRead; fastMarker = fastMarker->nextInRead; } else if ( slowLength < fastLength ) { if ( false ) { fprintf ( stderr, "B/ Mapped back of fast node into slow %d -> %d.\n", fastNode, slowNode ); } remapBackOfNodeOntoNeighbour ( fastNode, fastMarker, slowNode, slowMarker, FAST_TO_SLOW ); slowMarker = slowMarker->nextInRead; } else { if ( false ) { fprintf ( stderr, "C/ Mapped back of slow node into fast %d -> %d.\n", slowNode, fastNode ); } remapBackOfNodeOntoNeighbour ( slowNode, slowMarker, fastNode, fastMarker, SLOW_TO_FAST ); fastMarker = fastMarker->nextInRead; } } detachPath ( fastPath ); detachPath ( slowPath ); return 1; } /************************************************* Function: comparePaths Description: 1. Gets two path of the bubble. 2. Checks if the bubble is suitable to merge. 3. Merges the bubble. Input: 1. destination: the edge index, the start node of the fast path 2. origin: the edge index, the start node of the slow path Output: None. Return: None. *************************************************/ static void comparePaths ( unsigned int destination, unsigned int origin ) { int slowLength, fastLength, i; unsigned int fastNode, slowNode; READINTERVAL * marker; slowLength = fastLength = 0; fastNode = destination; slowNode = origin; btCounter++; while ( fastNode != slowNode ) { if ( times[fastNode] > times[slowNode] ) { fastLength++; fastNode = previous[fastNode]; } else if ( times[fastNode] < times[slowNode] ) { slowLength++; slowNode = previous[slowNode]; } else if ( isPreviousToNode ( slowNode, fastNode ) ) { while ( fastNode != slowNode ) { fastLength++; fastNode = previous[fastNode]; } } else if ( isPreviousToNode ( fastNode, slowNode ) ) { while ( slowNode != fastNode ) { slowLength++; slowNode = previous[slowNode]; } } else { fastLength++; fastNode = previous[fastNode]; slowLength++; slowNode = previous[slowNode]; } if ( slowLength > MAXNODELENGTH || fastLength > MAXNODELENGTH ) { return; } } if ( fastLength == 0 ) { return; } marker = allocateRV ( 1, destination ); fastPath = marker; for ( i = 0; i < fastLength; i++ ) { marker = allocateRV ( 1, previous[fastPath->edgeid] ); marker->nextInRead = fastPath; fastPath->prevInRead = marker; fastPath = marker; } marker = allocateRV ( 2, destination ); slowPath = marker; marker = allocateRV ( 2, origin ); marker->nextInRead = slowPath; slowPath->prevInRead = marker; slowPath = marker; for ( i = 0; i < slowLength; i++ ) { marker = allocateRV ( 2, previous[slowPath->edgeid] ); marker->nextInRead = slowPath; slowPath->prevInRead = marker; slowPath = marker; } fastSeqLength = extractSequence ( fastPath, fastSequence ); slowSeqLength = extractSequence ( slowPath, slowSequence ); /* if(destination==6359){ printf("destination %d, slowLength %d, fastLength %d\n",destination,slowLength,fastLength); printf("fastSeqLength %d, slowSeqLength %d\n",fastSeqLength,slowSeqLength); } */ if ( !fastSeqLength || !slowSeqLength ) { detachPathSingle ( slowPath ); detachPathSingle ( fastPath ); return; } cmpCounter++; if ( !compareSequences ( fastSequence, slowSequence, fastSeqLength, slowSeqLength ) ) { detachPathSingle ( slowPath ); detachPathSingle ( fastPath ); return; } //only merge clean bubble ... if ( clean ) { unsigned int bal_ed; unsigned int arcRight_n, arcLeft_n; READINTERVAL * tmp; tmp = fastPath->nextInRead; while ( tmp->nextInRead ) { bal_ed = getTwinEdge ( tmp->edgeid ); arcCount ( tmp->edgeid, &arcRight_n ); arcCount ( bal_ed, &arcLeft_n ); if ( arcRight_n != 1 || arcLeft_n != 1 ) //not clean bubble { return; } tmp = tmp->nextInRead; } tmp = slowPath->nextInRead; while ( tmp->nextInRead ) { bal_ed = getTwinEdge ( tmp->edgeid ); arcCount ( tmp->edgeid, &arcRight_n ); arcCount ( bal_ed, &arcLeft_n ); if ( arcRight_n != 1 || arcLeft_n != 1 ) //not clean bubble { return; } tmp = tmp->nextInRead; } } simiCounter++; pinCounter += cleanUpRedundancy (); if ( pinCounter % 100000 == 0 ) { fprintf ( stderr, ".............%lld bubbles merged.\n", pinCounter ); } HasChanged = 1; } /************************************************* Function: tourBusArc Description: 1. Searchs the bubble using the "Tour Bus algorithm" by the Function "tourBus", "tourBusNode", "tourBusArc". 2. Checks if the edge "destination" is visited. if not, return. 3. Compares two path if the edge "destination" is visited twice. Input: 1. origin: the origin edge 2. destination: the destination edge 3. arcMulti: the weight of the arc, which is from the origin edge to the destination edge 4. originTime: the times to the origin edge Output: None. Return: None. *************************************************/ static void tourBusArc ( unsigned int origin, unsigned int destination, unsigned int arcMulti, Time originTime ) { Time arcTime, totalTime, destinationTime; unsigned int oldPrevious = previous[destination]; if ( oldPrevious == origin || edge_array[destination].multi == 1 ) { return; } arcCounter++; if ( arcMulti > 0 ) { arcTime = ( ( Time ) edge_array[origin].length ) / ( ( Time ) arcMulti ); } else { arcTime = 0.0; fprintf ( stderr, "Arc from %d to %d with flags %d originTime %f, arc %d.\n", origin, destination, edge_array[destination].multi, originTime, arcMulti ); } totalTime = originTime + arcTime; /* if(destination==289129||destination==359610){ printf("arc from %d to %d with flags %d time %f originTime %f, arc %d\n", origin,destination,edge_array[destination].multi,totalTime,originTime,arcMulti); fflush(stdout); } */ destinationTime = times[destination]; if ( destinationTime == -1 ) { times[destination] = totalTime; dheapNodes[destination] = insertNodeIntoDHeap ( dheap, totalTime, destination ); dnodeCounter++; previous[destination] = origin; return; } else if ( destinationTime > totalTime ) { if ( dheapNodes[destination] == NULL ) { return; } replaceCounter++; times[destination] = totalTime; replaceKeyInDHeap ( dheap, dheapNodes[destination], totalTime ); previous[destination] = origin; comparePaths ( destination, oldPrevious ); return; } else { if ( destinationTime == times[origin] && isPreviousToNode ( destination, origin ) ) { return; } comparePaths ( destination, origin ); } } /************************************************* Function: tourBusNode Description: Searchs the bubble using the "Tour Bus algorithm" by the function "tourBus", "tourBusNode", "tourBusArc". Input: 1. node: the current edge Output: None. Return: None. *************************************************/ static void tourBusNode ( unsigned int node ) { ARC * parc; int index = 0, outNodeNum; expanded[expCounter++] = node; activeNode = node; parc = edge_array[activeNode].arcs; while ( parc ) { outArcArray[index] = parc; outNodeArray[index++] = parc->to_ed; if ( index >= MAXCONNECTION ) { break; } parc = parc->next; } outNodeNum = index; HasChanged = 0; for ( index = 0; index < outNodeNum; index++ ) { if ( HasChanged ) { parc = getArcBetween ( activeNode, outNodeArray[index] ); getArcCounter++; } else { parc = outArcArray[index]; } if ( !parc ) { continue; } tourBusArc ( activeNode, outNodeArray[index], parc->multiplicity, times[activeNode] ); } } /* static void dumpNodeFromDHeap() { unsigned int currentNode; while((currentNode = removeNextNodeFromDHeap(dheap))!=0){ rnodeCounter++; times[currentNode] = -1; previous[currentNode] = 0; dheapNodes[currentNode] = NULL; if(dnodeCounter-rnodeCounter<250) break; } } */ /************************************************* Function: tourBus Description: Searchs the bubble using the "Tour Bus algorithm" by the function "tourBus", "tourBusNode", "tourBusArc". Input: 1. startingPoint: the start edge Output: None. Return: None. *************************************************/ static void tourBus ( unsigned int startingPoint ) { unsigned int currentNode = startingPoint; times[startingPoint] = 0; previous[startingPoint] = currentNode; while ( currentNode > 0 ) { dheapNodes[currentNode] = NULL; tourBusNode ( currentNode ); currentNode = removeNextNodeFromDHeap ( dheap ); if ( currentNode > 0 ) { rnodeCounter++; } } } /************************************************* Function: bubblePinch Description: Removes bubbles with the Tour Bus algorithm. Input: 1. simiCutoff: the minimum requirements for similarity 2. outfile: the output prefix 3. M: the strength of merging bubble 4. isIter: whether it's multikmer 5. last: whether it's the last iteration Output: None. Return: None. *************************************************/ void bubblePinch ( double simiCutoff, char * outfile, int M, boolean isIter, boolean last ) { new_num_vt = 2 * num_vt; unsigned int index, counter = 0; unsigned int startingNode; char temp[256]; sprintf ( temp, "%s.pathpair", outfile ); caseA = caseB = caseC = caseD = caseE = 0; progress = 0; arcCounter = 0; dnodeCounter = 0; rnodeCounter = 0; btCounter = 0; cmpCounter = 0; simiCounter = 0; pinCounter = 0; replaceCounter = 0; getArcCounter = 0; cutoff = 1.0 - simiCutoff; if ( M <= 1 ) { MAXNODELENGTH = 3; DIFF = 2; } else if ( M == 2 ) { MAXNODELENGTH = 9; DIFF = 3; } else { MAXNODELENGTH = 30; DIFF = 10; } fprintf ( stderr, "Start to pinch bubbles, cutoff %f, MAX NODE NUM %d, MAX DIFF NUM %d.\n", cutoff, MAXNODELENGTH, DIFF ); createRVmemo (); times = ( Time * ) ckalloc ( ( num_ed + 1 ) * sizeof ( Time ) ); previous = ( unsigned int * ) ckalloc ( ( num_ed + 1 ) * sizeof ( unsigned int ) ); expanded = ( unsigned int * ) ckalloc ( ( num_ed + 1 ) * sizeof ( unsigned int ) ); dheapNodes = ( DFibHeapNode ** ) ckalloc ( ( num_ed + 1 ) * sizeof ( DFibHeapNode * ) ); WORDFILTER = createFilter ( overlaplen ); for ( index = 1; index <= num_ed; index++ ) { times[index] = -1; previous[index] = 0; dheapNodes[index] = NULL; } dheap = newDFibHeap (); eligibleStartingPoints = ( unsigned int * ) ckalloc ( ( num_ed + 1 ) * sizeof ( unsigned int ) ); resetNodeStatus (); createArcLookupTable (); recordArcsInLookupTable (); while ( ( startingNode = nextStartingPoint () ) > 0 ) { counter++; expCounter = 0; tourBus ( startingNode ); updateNodeStatus (); } resetNodeStatus (); deleteArcLookupTable (); destroyReadIntervMem (); fprintf ( stderr, "%d start points, %lld dheap nodes.\n", counter, dnodeCounter ); fprintf ( stderr, "%lld pair(s) found, %lld pair of path(s) compared, %lld pair(s) merged.\n", btCounter, cmpCounter, pinCounter ); fprintf ( stderr, "Sequence comparison failed:\n" ); fprintf ( stderr, " Path crossing deleted edge %lld\n", caseA ); fprintf ( stderr, " Length difference of two paths greater than two %lld\n", caseB ); fprintf ( stderr, " Mismatch score greater than cutoff (%d) %lld\n", DIFF, caseC ); fprintf ( stderr, " Mismatch score ratio greater than cutoff (%.1f) %lld\n", cutoff, caseD ); fprintf ( stderr, " Path length shorter than (Kmer-1) %lld\n", caseE ); free ( ( void * ) eligibleStartingPoints ); destroyDHeap ( dheap ); free ( ( void * ) dheapNodes ); free ( ( void * ) times ); free ( ( void * ) previous ); free ( ( void * ) expanded ); linearConcatenate ( isIter, last ); } soapdenovo2-240+dfsg.orig/standardPregraph/read2scaf.c0000644000000000000000000001655712166703654021513 0ustar rootroot/* * read2scaf.c * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" static int Ncounter; static int allGaps; // for multi threads static int scafBufSize = 100; static STACK ** ctgStackBuffer; static int scafCounter; static int scafInBuf; static void convertIndex () { int * length_array = ( int * ) ckalloc ( ( num_ctg + 1 ) * sizeof ( int ) ); unsigned int i; for ( i = 1; i <= num_ctg; i++ ) { length_array[i] = 0; } for ( i = 1; i <= num_ctg; i++ ) { if ( index_array[i] > 0 ) { length_array[index_array[i]] = i; } } for ( i = 1; i <= num_ctg; i++ ) { index_array[i] = length_array[i]; } //contig i with new index: index_array[i] free ( ( void * ) length_array ); } static void reverseStack ( STACK * dStack, STACK * sStack ) { CTGinSCAF * actg, *ctgPt; emptyStack ( dStack ); while ( ( actg = ( CTGinSCAF * ) stackPop ( sStack ) ) != NULL ) { ctgPt = ( CTGinSCAF * ) stackPush ( dStack ); ctgPt->ctgID = actg->ctgID; ctgPt->start = actg->start; ctgPt->end = actg->end; } stackBackup ( dStack ); } static void initStackBuf ( STACK ** ctgStackBuffer, int scafBufSize ) { int i; for ( i = 0; i < scafBufSize; i++ ) { ctgStackBuffer[i] = ( STACK * ) createStack ( 100, sizeof ( CTGinSCAF ) ); } } static void freeStackBuf ( STACK ** ctgStackBuffer, int scafBufSize ) { int i; for ( i = 0; i < scafBufSize; i++ ) { freeStack ( ctgStackBuffer[i] ); } } static void mapCtg2Scaf ( int scafInBuf ) { int i, scafID; CTGinSCAF * actg; STACK * ctgsStack; unsigned int ctg, bal_ctg; for ( i = 0; i < scafInBuf; i++ ) { scafID = scafCounter + i + 1; ctgsStack = ctgStackBuffer[i]; while ( ( actg = stackPop ( ctgsStack ) ) != NULL ) { ctg = actg->ctgID; bal_ctg = getTwinCtg ( ctg ); if ( contig_array[ctg].from_vt != 0 ) { contig_array[ctg].multi = 1; contig_array[bal_ctg].multi = 1; continue; } contig_array[ctg].from_vt = scafID; contig_array[ctg].to_vt = actg->start; contig_array[ctg].flag = 0; //ctg and scaf on the same strand contig_array[bal_ctg].from_vt = scafID; contig_array[bal_ctg].to_vt = actg->start; contig_array[bal_ctg].flag = 1; } } } static void locateContigOnscaff ( char * graphfile ) { FILE * fp; char line[1024]; CTGinSCAF * actg; STACK * ctgStack, *aStack; int index = 0, counter, overallLen; int starter, prev_start, gapN, scafLen; unsigned int ctg, prev_ctg = 0; for ( ctg = 1; ctg <= num_ctg; ctg++ ) { contig_array[ctg].from_vt = 0; contig_array[ctg].multi = 0; } ctgStack = ( STACK * ) createStack ( 1000, sizeof ( CTGinSCAF ) ); sprintf ( line, "%s.scaf_gap", graphfile ); fp = ckopen ( line, "r" ); ctgStackBuffer = ( STACK ** ) ckalloc ( scafBufSize * sizeof ( STACK * ) ); initStackBuf ( ctgStackBuffer, scafBufSize ); Ncounter = scafCounter = scafInBuf = allGaps = 0; while ( fgets ( line, sizeof ( line ), fp ) != NULL ) { if ( line[0] == '>' ) { if ( index ) { aStack = ctgStackBuffer[scafInBuf++]; reverseStack ( aStack, ctgStack ); if ( scafInBuf == scafBufSize ) { mapCtg2Scaf ( scafInBuf ); scafCounter += scafInBuf; scafInBuf = 0; } if ( index % 1000 == 0 ) { fprintf ( stderr, "Processed %d scaffolds.\n", index ); } } //read next scaff scafLen = prev_ctg = 0; emptyStack ( ctgStack ); sscanf ( line + 9, "%d %d %d", &index, &counter, &overallLen ); //fprintf(stderr,">%d\n",index); continue; } if ( line[0] == 'G' ) // gap appears { continue; } if ( line[0] >= '0' && line[0] <= '9' ) // a contig line { sscanf ( line, "%d %d", &ctg, &starter ); actg = ( CTGinSCAF * ) stackPush ( ctgStack ); actg->ctgID = ctg; if ( !prev_ctg ) { actg->start = scafLen; actg->end = actg->start + overlaplen + contig_array[ctg].length - 1; } else { gapN = starter - prev_start - ( int ) contig_array[prev_ctg].length; gapN = gapN < 1 ? 1 : gapN; actg->start = scafLen + gapN; actg->end = actg->start + contig_array[ctg].length - 1; } //fprintf(stderr,"%d\t%d\n",actg->start,actg->end); scafLen = actg->end + 1; prev_ctg = ctg; prev_start = starter; } } if ( index ) { aStack = ctgStackBuffer[scafInBuf++]; reverseStack ( aStack, ctgStack ); mapCtg2Scaf ( scafInBuf ); } gapN = 0; for ( ctg = 1; ctg <= num_ctg; ctg++ ) { if ( contig_array[ctg].from_vt == 0 || contig_array[ctg].multi == 1 ) { continue; } gapN++; } fprintf ( stderr, "\nDone with %d scaffolds, %d contigs in Scaffolld\n", index, gapN ); /* if(readSeqInGap) freeDarray(readSeqInGap); */ fclose ( fp ); freeStack ( ctgStack ); freeStackBuf ( ctgStackBuffer, scafBufSize ); free ( ( void * ) ctgStackBuffer ); } static boolean contigElligible ( unsigned int contigno ) { unsigned int ctg = index_array[contigno]; if ( contig_array[ctg].from_vt == 0 || contig_array[ctg].multi == 1 ) { return 0; } else { return 1; } } static void output1read ( FILE * fo, long long readno, unsigned int contigno, int pos ) { unsigned int ctg = index_array[contigno]; int posOnScaf; char orien; pos = pos < 0 ? 0 : pos; if ( contig_array[ctg].flag == 0 ) { posOnScaf = contig_array[ctg].to_vt + pos - overlaplen; orien = '+'; } else { posOnScaf = contig_array[ctg].to_vt + contig_array[ctg].length - pos; orien = '-'; } /* if(readno==676) printf("Read %lld in region from %d, extend %d, pos %d, orien %c\n", readno,contig_array[ctg].to_vt,contig_array[ctg].length,posOnScaf,orien); */ fprintf ( fo, "%lld\t%d\t%d\t%c\n", readno, contig_array[ctg].from_vt, posOnScaf, orien ); } void locateReadOnScaf ( char * graphfile ) { char name[1024], line[1024]; FILE * fp, *fo; long long readno, counter = 0, pre_readno = 0; unsigned int contigno, pre_contigno; int pre_pos, pos; locateContigOnscaff ( graphfile ); sprintf ( name, "%s.readOnContig", graphfile ); fp = ckopen ( name, "r" ); sprintf ( name, "%s.readOnScaf", graphfile ); fo = ckopen ( name, "w" ); if ( !orig2new ) { convertIndex (); orig2new = 1; } fgets ( line, 1024, fp ); while ( fgets ( line, 1024, fp ) != NULL ) { sscanf ( line, "%lld %d %d", &readno, &contigno, &pos ); if ( ( readno % 2 == 0 ) && ( pre_readno == readno - 1 ) // they are a pair of reads && contigElligible ( pre_contigno ) && contigElligible ( contigno ) ) { output1read ( fo, pre_readno, pre_contigno, pre_pos ); output1read ( fo, readno, contigno, pos ); counter++; } pre_readno = readno; pre_contigno = contigno; pre_pos = pos; } fprintf ( stderr, "%lld pair(s) on contig\n", counter ); fclose ( fp ); fclose ( fo ); } soapdenovo2-240+dfsg.orig/sparsePregraph/0000755000000000000000000000000012166705350017167 5ustar rootrootsoapdenovo2-240+dfsg.orig/sparsePregraph/pregraph_sparse.cpp0000644000000000000000000004733012166703654023074 0ustar rootroot/* * pregraph_sparse.cpp * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "global.h" #include "stdinc.h" #include "core.h" #include "multi_threads.h" #include "build_graph.h" #include "build_edge.h" #include "build_preArc.h" #include "io_func.h" #include "seq_util.h" #include "convert_soapdenovo.h" static int LOAD_GRAPH = 0, BUILD_DBG = 1, BUILD_EDGES = 1, BUILD_PREARCS = 1; //static int run_mode=0; extern "C" int call_pregraph_sparse ( int argc, char ** argv ); static void initenv ( int argc, char ** argv ); static void parse_args ( vector &in_filenames_vt ); static void display_pregraph_usage(); /* int main ( int argc, char ** argv ) { fprintf ( stderr, "\nVersion 1.0.3: released on July 13th, 2012\nCompile %s\t%s\n\n", __DATE__, __TIME__ ); call_pregraph_sparse ( argc, argv ); }*/ /************************************************* Function: call_pregraph_sparse Description: The entry function for calling pregraph_sparse, its processes include 1. Parses the args form command. 2. Builds the sparse-kmer graph. 3. Removes low coverage sparse-kmers and kmer-edges (the connections between edges). 4. Removes tips. 5. Builds edges by compacting linear kmer nodes. 6. Builds preArc (the connections between edges) by maping reads to edges. Input: @see display_pregraph_usage() Output: files: *.ht_idx *.ht_content *.kmerFreq *.sparse.edge *.edge.gz *.preArc Return: None. *************************************************/ extern "C" int call_pregraph_sparse ( int argc, char ** argv ) { time_t all_beg_time, all_end_time; time ( &all_beg_time ); initenv ( argc, argv ); vector in_filenames_vt; parse_args ( in_filenames_vt ); struct hashtable2 ht2; size_t hashTableSZ = 1000000; time_t beg_time, read_time; size_t bucket_count = 0, edge_cnt = 0; if ( ( !LOAD_GRAPH ) && BUILD_DBG ) { int round = 1; for ( round = 1; round <= 2; round++ ) { //fprintf(stderr,"Building the sparse de Brujin graph, round: %d\n",round); fprintf ( stderr, "Start to build the sparse de Brujin graph, round: %d\n", round ); if ( round == 1 ) { time ( &beg_time ); edge_cnt = 0; uint64_t TotalSamplings = 0; //initialize the hashtable size if ( GenomeSize == 0 ) { fprintf ( stderr, "Error! Genome size not given.\n" ); return -1; } hashTableSZ = ( size_t ) GenomeSize / max ( gap - 1, 5 ); int read_buf_sz = 102400 * thrd_num_s; Init_HT2 ( &ht2, hashTableSZ ); //create main io thread read_buf0 = new string[read_buf_sz]; read_buf1 = new string[read_buf_sz]; io_stat0 = 1; //must be one, if io_stat0 equals 0, the io threads will work immediately io_stat1 = 1; io_ready = 0; io_para_main io_para_mains; io_para_mains.read_buf_sz = read_buf_sz; io_para_mains.in_filenames_vt = &in_filenames_vt; pthread_t io_thread; int temp; // fprintf(stderr,"Creating main io thread ...\n"); if ( ( temp = pthread_create ( &io_thread, NULL, run_io_thread_main, &io_para_mains ) ) != 0 ) { fprintf ( stderr, "ERROR: failed creating main io thread.\n" ); exit ( -1 ); } fprintf ( stderr, "1 io thread initialized.\n" ); //create work threads for round 1 pthread_t threads[thrd_num_s]; unsigned char thrdSignal[thrd_num_s + 1]; PARAMETER paras[thrd_num_s]; locks = ( pthread_spinlock_t * ) calloc ( ht2.ht_sz, sizeof ( pthread_spinlock_t ) ); //initialize the locks unlock for ( size_t i = 0; i < ht2.ht_sz; ++i ) { locks[i] = 1; } //create threads //fprintf(stderr,"Creating work threads ...\n"); bucket_count_total = ( size_t * ) calloc ( thrd_num_s, sizeof ( size_t ) ); edge_cnt_total = ( size_t * ) calloc ( thrd_num_s, sizeof ( size_t ) ); for ( int k = 0; k < thrd_num_s; k++ ) { thrdSignal[k + 1] = 0; paras[k].threadID = k; paras[k].mainSignal = &thrdSignal[0]; paras[k].selfSignal = &thrdSignal[k + 1]; paras[k].ht = &ht2; paras[k].K_size = K_size; paras[k].gap = gap; } creatThrds ( threads, paras ); thrdSignal[0] = 0; //begin to work size_t processed_reads = 0; while ( 1 ) { sendIOWorkSignal(); while ( io_ready == 0 ) {usleep ( 1 );} if ( io_ready ) { processed_reads += read_num; sendWorkSignal ( 10, thrdSignal ); for ( int k1 = 0; k1 < thrd_num_s; ++k1 ) { bucket_count += bucket_count_total[k1]; bucket_count_total[k1] = 0; } } if ( io_ready == 2 ) { //fprintf(stderr,"All reads have been processed !\n"); break; } } sendWorkSignal ( 3, thrdSignal ); thread_wait ( threads ); SwitchBuckets ( &ht2, K_size ); for ( size_t i = 0; i < ht2.ht_sz; ++i ) //this procedure can be removed { struct bucket2 * bktptr = ht2.store_pos[i]; while ( bktptr != NULL ) { bktptr->kmer_info.cov1 = 0; bktptr = bktptr->nxt_bucket; } } free ( ( void * ) bucket_count_total ); free ( ( void * ) locks ); free ( ( void * ) edge_cnt_total ); delete [] read_buf0; delete [] read_buf1; time ( &read_time ); //fprintf(stderr,"Round 1 consumes time: %.fs.\n",difftime(read_time,beg_time)); //fprintf(stderr,"Number of processed reads: %llu \n",processed_reads); fprintf ( stderr, "Time spent on building graph round 1: %.fs, %llu reads processed, %llu nodes allocated\n", difftime ( read_time, beg_time ), processed_reads, bucket_count ); fprintf ( stderr, "\n" ); } if ( round == 2 ) { time ( &beg_time ); edge_cnt = 0; //create main io thread int read_buf_sz = 102400 * thrd_num_s; read_buf0 = new string[read_buf_sz]; read_buf1 = new string[read_buf_sz]; io_stat0 = 1; //must be one, if io_stat0 =0 ,the io thread will work immediately io_stat1 = 1; io_ready = 0; io_para_main io_para_mains; io_para_mains.read_buf_sz = read_buf_sz; io_para_mains.in_filenames_vt = &in_filenames_vt; pthread_t io_thread; int temp; //fprintf(stderr,"Creating main io thread ...\n"); if ( ( temp = pthread_create ( &io_thread, NULL, run_io_thread_main, &io_para_mains ) ) != 0 ) { fprintf ( stderr, "ERROR: failed creating main io thread.\n" ); exit ( -1 ); } fprintf ( stderr, "1 io thread initialized.\n" ); //create work threads for round 2 pthread_t threads[thrd_num_s]; unsigned char thrdSignal[thrd_num_s + 1]; PARAMETER paras[thrd_num_s]; locks = ( pthread_spinlock_t * ) calloc ( ht2.ht_sz, sizeof ( pthread_spinlock_t ) ); //initialize locks unlock for ( size_t i = 0; i < ht2.ht_sz; ++i ) { locks[i] = 1; } //create threads //fprintf(stderr,"Creating work threads ...\n"); bucket_count_total = ( size_t * ) calloc ( thrd_num_s, sizeof ( size_t ) ); edge_cnt_total = ( size_t * ) calloc ( thrd_num_s, sizeof ( size_t ) ); for ( int k = 0; k < thrd_num_s; k++ ) { thrdSignal[k + 1] = 0; paras[k].threadID = k; paras[k].mainSignal = &thrdSignal[0]; paras[k].selfSignal = &thrdSignal[k + 1]; paras[k].ht = &ht2; paras[k].K_size = K_size; paras[k].gap = gap; } creatThrds ( threads, paras ); thrdSignal[0] = 0; //begin to work int foundcount = 0; int flipcount = 0; size_t processed_reads = 0; while ( 1 ) { sendIOWorkSignal(); while ( io_ready == 0 ) {usleep ( 1 );} if ( io_ready ) { //read_c = read_num; processed_reads += read_num; sendWorkSignal ( 11, thrdSignal ); for ( int k1 = 0; k1 < thrd_num_s; ++k1 ) { edge_cnt += edge_cnt_total[k1]; edge_cnt_total[k1] = 0; } } if ( io_ready == 2 ) { //fprintf(stderr,"All reads have been processed !\n"); break; } } sendWorkSignal ( 3, thrdSignal ); thread_wait ( threads ); free ( ( void * ) bucket_count_total ); free ( ( void * ) locks ); free ( ( void * ) edge_cnt_total ); delete [] read_buf0; delete [] read_buf1; SavingSparseKmerGraph2 ( &ht2, graphfile ); time ( &read_time ); //fprintf(stderr,"Round 2 consumed time: %.fs.\n",difftime(read_time,beg_time)); //fprintf(stderr,"Number of processed reads: %llu \n",processed_reads); fprintf ( stderr, "Time spent on building graph round 2: %.fs, %llu reads processed\n", difftime ( read_time, beg_time ), processed_reads ); fprintf ( stderr, "%llu nodes allocated, %llu kmer-edges allocated.\n", bucket_count, edge_cnt ); fprintf ( stderr, "\n" ); } } } if ( LOAD_GRAPH ) { fprintf ( stderr, "Loading the graph ...\n" ); LoadingSparseKmerGraph2 ( &ht2, graphfile ); } if ( BUILD_EDGES ) { RemovingWeakNodesAndEdges2 ( &ht2, K_size, NodeCovTh, EdgeCovTh, &bucket_count, &edge_cnt ); int cut_len_tip = 2 * K_size; int tip_c = 0; time_t start, finish, interval; fprintf ( stderr, "Start to remove tips with minority links.\n" ); start = time ( NULL ); removeMinorTips ( &ht2, K_size, cut_len_tip, tip_c ); finish = time ( NULL ); interval = ( finish - start ) ; //fprintf(stderr,"Removing minor tips consumes %llu s.\n\n",interval); fprintf ( stderr, "Time spent on removing tips: %llus.\n\n", interval ); fprintf ( stderr, "Start to construct edges.\n" ); start = time ( NULL ); char outfile[256]; sprintf ( outfile, "%s.sparse.edge", graphfile ); kmer2edges ( &ht2, K_size, outfile ); free_hashtable ( &ht2 ); char temp[256]; sprintf ( temp, "%s.sparse.edge", graphfile ); convert ( temp, K_size, graphfile ); finish = time ( NULL ); interval = ( finish - start ) ; //fprintf(stderr,"Building edges consumes %llu s.\n\n",interval); fprintf ( stderr, "Time spent on constructing edges: %llus.\n\n", interval ); } if ( BUILD_PREARCS ) //build preArc { size_t v_sz, e_sz; int K_size; char basicInfo[128]; sprintf ( basicInfo, "%s.preGraphBasic", graphfile ); FILE * fin; char line[1024]; char str[32]; fin = fopen ( basicInfo, "r" ); if ( !fin ) { fprintf ( stderr, "ERROR: can't open file %s\n", basicInfo ); exit ( 1 ); } bool a = 0, b = 0; while ( fgets ( line, 1024, fin ) != NULL ) { if ( line[0] == 'V' ) //VERTEX { sscanf ( line + 6, "%lu %s %d", &v_sz, str, &K_size ); a = 1; } if ( line[0] == 'E' ) //EDGEs { sscanf ( line, "%s %lu", str, &e_sz ); b = 1; break; } } if ( !a || !b ) { fprintf ( stderr, "ERROR: preGraphBasic file is in invaild format!\n" ); exit ( 1 ); } vertex_hash2 v_ht; preArc_array arc_arr; char edge_file[128]; sprintf ( edge_file, "%s.sparse.edge", graphfile ); time_t start, finish, interval; //step1: //fprintf(stderr,"Building vertexes ...\n"); fprintf ( stderr, "Start to build vertex indexes.\n" ); start = time ( NULL ); init_vertex_hash ( &v_ht, v_sz ); build_vertexes ( &v_ht, K_size, edge_file ); finish = time ( NULL ); interval = ( finish - start ) ; //fprintf(stderr,"Building vertexes consumes %llu s.\n\n",interval); fprintf ( stderr, "Time spent on building vertex indexes: %llus.\n\n", interval ); //step2: //fprintf(stderr,"Building preArcs ...\n"); fprintf ( stderr, "Start to build preArcs.\n" ); start = time ( NULL ); int cut_off_len = 256;//tmp init_preArc_array ( &arc_arr, e_sz + 1 ); if ( solve ) { /* initialize the threads' common data mark_on_edge s_locks*/ mark_on_edge = ( unsigned int * ) calloc ( e_sz + 1, sizeof ( unsigned int ) ); s_locks = ( pthread_spinlock_t * ) calloc ( e_sz + 1, sizeof ( pthread_spinlock_t ) ); for ( size_t i = 0; i < e_sz + 1; i++ ) { s_locks[i] = 1; } /*buffers for seperate threads*/ path_buffer = ( edge_path_buffer ** ) calloc ( thrd_num_s, sizeof ( edge_path_buffer ) ); for ( int i = 0; i < thrd_num_s; i++ ) { path_buffer[i] = create_edge_path_buffer ( mark_on_edge, s_locks, buff_size, max_path_length ); } /*initialize the output file */ char mark_file[128], path_file[128]; sprintf ( mark_file, "%s.markOnEdge", graphfile ); sprintf ( path_file, "%s.path", graphfile ); mark_fp = fopen ( mark_file, "w" ); path_fp = fopen ( path_file, "w" ); pthread_mutex_init ( &file_lock, NULL ); } build_preArc_threaded ( &arc_arr, &v_ht, K_size, cut_off_len, &in_filenames_vt, thrd_num_s ); if ( solve ) { //output mark_on_edge size_t markCounter = 0; for ( size_t i = 1; i <= e_sz; i++ ) { markCounter += mark_on_edge[i]; fprintf ( mark_fp, "%d\n", mark_on_edge[i] ); } fprintf ( stderr, "Total number of marks in file markOnEdge: %lu\n", markCounter ); fclose ( mark_fp ); //output path_buffer for ( int i = 0; i < thrd_num_s; i++ ) { output_edge_path_buffer ( path_buffer[i], path_fp ); } fclose ( path_fp ); //destory buffers ... for ( int i = 0; i < thrd_num_s; i++ ) { destory_edge_path_buffer ( path_buffer[i] ); } free ( ( void * ) mark_on_edge ); free ( ( void * ) s_locks ); pthread_mutex_destroy ( &file_lock ); } finish = time ( NULL ); interval = ( finish - start ); //fprintf(stderr,"Building preArcs consumes %llu s.\n\n",interval); fprintf ( stderr, "Time spent on building preArcs: %llus.\n\n", interval ); char prearc_file[128]; sprintf ( prearc_file, "%s.preArc", graphfile ); output_preArcs ( &arc_arr, prearc_file ); } time ( &all_end_time ); fprintf ( stderr, "Overall time spent on constructing lightgraph: %.fm.\n", difftime ( all_end_time, all_beg_time ) / 60 ); return 0; } static void initenv ( int argc, char ** argv ) { int copt; int inpseq, outseq, genome_sz; extern char * optarg; char temp[100]; optind = 1; inpseq = outseq = genome_sz = 0; while ( ( copt = getopt ( argc, argv, "s:o:K:g:z:d:e:p:m:r:R" ) ) != EOF ) { switch ( copt ) { case 's': inpseq = 1; sscanf ( optarg, "%s", shortrdsfile ); continue; case 'o': outseq = 1; sscanf ( optarg, "%s", graphfile ); continue; case 'K': sscanf ( optarg, "%s", temp ); K_size = atoi ( temp ); continue; case 'g': sscanf ( optarg, "%s", temp ); gap = atoi ( temp ); continue; case 'z': genome_sz = 1; sscanf ( optarg, "%Lu", &GenomeSize ); continue; case 'd': sscanf ( optarg, "%s", temp ); NodeCovTh = atoi ( temp ) >= 0 ? atoi ( temp ) : 0; continue; case 'e': sscanf ( optarg, "%s", temp ); EdgeCovTh = atoi ( temp ) >= 0 ? atoi ( temp ) : 0; continue; case 'R': solve = 1; continue; case 'p': sscanf ( optarg, "%s", temp ); thrd_num_s = atoi ( temp ); continue; case 'm': continue; case 'r': sscanf ( optarg, "%s", temp ); run_mode = atoi ( temp ); continue; default: if ( inpseq == 0 || outseq == 0 ) { display_pregraph_usage(); exit ( -1 ); } } } if ( inpseq == 0 || outseq == 0 || genome_sz == 0 ) { display_pregraph_usage(); exit ( -1 ); } } static void parse_args ( vector &in_filenames_vt ) { if ( K_size % 2 == 0 ) { K_size--; } #ifdef _63MER_ if ( K_size > 63 ) { fprintf ( stderr, "ERROR: Parameter K is set too large, max value is 63.\n" ); exit ( -1 ); } #endif #ifdef _127MER_ if ( K_size > 127 ) { fprintf ( stderr, "ERROR: Parameter K is set too large, max value is 127.\n" ); exit ( -1 ); } #endif if ( gap > 25 ) { fprintf ( stderr, "ERROR: Parameter g is set too large, max value is 25.\n" ); exit ( -1 ); } //print the args fprintf ( stderr, "********************\n" ); fprintf ( stderr, "SparsePregraph\n" ); fprintf ( stderr, "********************\n" ); fprintf ( stderr, "\n" ); fprintf ( stderr, "Parameters: " ); fprintf ( stderr, "pregraph_sparse -s %s", shortrdsfile ); fprintf ( stderr, " -K %d", K_size ); fprintf ( stderr, " -g %d", gap ); fprintf ( stderr, " -z %lu", GenomeSize ); fprintf ( stderr, " -d %d", NodeCovTh ); fprintf ( stderr, " -e %d", EdgeCovTh ); if ( solve ) { fprintf ( stderr, " -R " ); } fprintf ( stderr, " -r %d", run_mode ); fprintf ( stderr, " -p %d", thrd_num_s ); fprintf ( stderr, " -o %s\n\n", graphfile ); if ( run_mode == 0 ) //build all { LOAD_GRAPH = 0; BUILD_DBG = 1; BUILD_EDGES = 1; BUILD_PREARCS = 1; } else if ( run_mode == 1 ) //build edges ,build preArcs { LOAD_GRAPH = 1; BUILD_EDGES = 1; BUILD_PREARCS = 1; } else if ( run_mode == 2 ) //build graph only { LOAD_GRAPH = 0; BUILD_DBG = 1; BUILD_EDGES = 0; BUILD_PREARCS = 0; } else if ( run_mode == 3 ) //build edges only { LOAD_GRAPH = 1; BUILD_EDGES = 1; BUILD_PREARCS = 0; } else if ( run_mode == 4 ) //build preArc only { LOAD_GRAPH = 0; BUILD_DBG = 0; BUILD_EDGES = 0; BUILD_PREARCS = 1; } else { fprintf ( stderr, "ERROR: invalid runMode!\n" ); exit ( -1 ); } read_lib ( in_filenames_vt, shortrdsfile ); /* fprintf(stderr,"The reads for building sparse de Brujin graph:\n"); for (int i=0;i configFile: the config file of solexa reads\n" ); #ifdef _63MER_ fprintf ( stderr, " -K kmer(min 13, max 63): kmer size, [23]\n" ); #endif #ifdef _127MER_ fprintf ( stderr, " -K kmer(min 13, max 127): kmer size, [23]\n" ); #endif fprintf ( stderr, " -g maxKmerEdgeLength(min 1, max 25): number of skipped intermediate kmers, [15]\n" ); fprintf ( stderr, " -z genomeSize(required): estimated genome size\n" ); fprintf ( stderr, " -d kmerFreqCutoff: delete kmers with frequency no larger than,[1]\n" ); fprintf ( stderr, " -e kmerEdgeFreqCutoff: delete kmers' related edge with frequency no larger than [1]\n" ); fprintf ( stderr, " -R (optional) output extra information for resolving repeats in contig step, [NO]\n" ); fprintf ( stderr, " -r runMode: 0 build graph & build edge and preArc, 1 load graph by prefix & build edge and preArc, 2 build graph only, 3 build edges only, 4 build preArcs only [0] \n" ); fprintf ( stderr, " -p n_cpu: number of cpu for use,[8]\n" ); fprintf ( stderr, " -o outputGraph: prefix of output graph file name\n" ); } soapdenovo2-240+dfsg.orig/sparsePregraph/make.sh0000644000000000000000000000006612166703654020447 0ustar rootrootmake make 127mer=1 make install make install 127mer=1 soapdenovo2-240+dfsg.orig/sparsePregraph/build_preArc.cpp0000644000000000000000000007777312166703654022320 0ustar rootroot/* * build_preArc.cpp * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "build_preArc.h" #include "seq_util.h" #include "global.h" #include "multi_threads.h" #include #include "bam.h" #include "faidx.h" #include "knetfile.h" #include "sam_view.h" #include "xcurses.h" #include "zlib.h" #include "bgzf.h" #include "glf.h" #include "kstring.h" #include "razf.h" #include "sam_header.h" #include "zconf.h" #include "sam.h" #include "sparse_kmer.h" //programming guide: //step1:read edge & build vertex hash //step1_include: //a.create id for every edge & it's rev_comp id //b.build vertex for every edge (done...) //step2:read reads & chop kmers //step3:search vertex with the kmers & mark the found position & get the Vertex //step3_extend:if found two or more vetex in one read , record the path to solve tiny repeat //step4:compare the left kmer right kmer to vertex's edge_kmer //step5: if left & right both match build a preArc or increase the multiplicity by 1 void init_vertex_hash ( vertex_hash2 * v_ht, size_t sz ) { v_ht->ht_sz = sz; v_ht->store_pos = ( vertex2 ** ) calloc ( sz, sizeof ( vertex2 * ) ); } /************************************************* Function: build_vertexes Description: 1. Reads sequence from *.sparse.edge. 2. Builds vertexes by cutting the edge sequence's end kmers. Input: 1. v_ht: vertex hashtable 2. K_size: kmer size 3. edge_file: edge file Output: None. Return: None. *************************************************/ void build_vertexes ( vertex_hash2 * v_ht, int K_size, char * edge_file ) { FILE * fp; kmer_t2 from_kmer, to_kmer; size_t line_len, edge_len_left; int edge_len; int cvg; bool bal_ed;//»ØÎÄΪ0 const int BUFF_LEN = 1024; char line[BUFF_LEN]; char str[32]; char to_buff[BUFF_LEN];//buffer 2k edge seq BUFF_LEN>4*K_size int processed = 0; //0±íʾδ´¦Àí 1±íʾ ´¦ÀíÍê±Ï 2 ±íʾÒѾ­´¦ÀíÁËfrom_vertex ,to_vertex »¹Ã»Óд¦Àí size_t edge_id = 0; fp = fopen ( edge_file, "r" ); if ( !fp ) { fprintf ( stderr, "ERROR: Cannot open edge_file %s. Now exit to system...\n", edge_file ); exit ( -1 ); } vertex2 * v_tmp; edge_starter2 * e_tmp; int is_found; bool is_left; while ( fgets ( line, BUFF_LEN, fp ) != NULL ) { //debug<<"processed "<' ) //get one edge length, from vertex, to vertex,cvg,bal { if ( processed == 1 && bal_ed ) { edge_id++;//Èç¹û²»ÊÇ»ØÎÄ } #ifdef _63MER_ sscanf ( line + 7, "%d,%llx %llx ,%llx %llx ,%s %d,%d", &edge_len, & ( from_kmer.kmer ) [0], & ( from_kmer.kmer ) [1], & ( to_kmer.kmer ) [0], & ( to_kmer.kmer ) [1], str, &cvg, &bal_ed ); // from_kmer to_kmer is of no use here #endif #ifdef _127MER_ sscanf ( line + 7, "%d,%llx %llx %llx %llx ,%llx %llx %llx %llx ,%s %d,%d", &edge_len, & ( from_kmer.kmer ) [0], & ( from_kmer.kmer ) [1], & ( from_kmer.kmer ) [2], & ( from_kmer.kmer ) [3], & ( to_kmer.kmer ) [0], & ( to_kmer.kmer ) [1], & ( to_kmer.kmer ) [2], & ( to_kmer.kmer ) [3], str, &cvg, &bal_ed ); // from_kmer to_kmer is of no use here #endif edge_len_left = K_size + edge_len; processed = 0; edge_id++;// current edge positive strand id //debug< 0 { fprintf ( stderr, "ERROR:it won't happen in 63mer/127mer\n" ); exit ( 1 ); } else { process_edge ( v_ht, K_size, line, line_len, 2, edge_id, bal_ed ); processed = 2; edge_len_left -= line_len; if ( edge_len_left >= 2 * K_size ) { //no need to buf the to kmer seq } else if ( edge_len_left < 2 * K_size ) { //to_buff[100];/ copy the last 2K char of line to to_buff already no '\n' strcpy ( to_buff, line + ( line_len - 2 * K_size ) ); } else { fprintf ( stderr, "ERROR: in cal the edge_len_left!!\n" ); exit ( 1 ); } } } } else if ( processed == 2 ) { //if(line[0]=='\n') continue; line_len = strlen ( line ); if ( line[line_len - 1] == '\n' ) { line[line_len - 1] = '\0'; line_len --; } edge_len_left -= line_len; if ( edge_len_left == 0 ) //load the complete edge sequence { //process the to kmer if ( line_len >= 2 * K_size ) { process_edge ( v_ht, K_size, line, line_len, 3, edge_id, bal_ed ); } else { //need to use the to_buff int buf_len = strlen ( to_buff ); strcpy ( to_buff + buf_len, line ); buf_len = strlen ( to_buff ); process_edge ( v_ht, K_size, to_buff, buf_len, 3, edge_id, bal_ed ); } processed = 1; continue; } else { if ( edge_len_left >= 2 * K_size ) { //no need to buf the to kmer seq } else if ( edge_len_left < 2 * K_size ) { //to_buff[100];/ copy the last 2K char of line to to_buff strcpy ( to_buff, line + ( line_len - 2 * K_size ) ); } else { fprintf ( stderr, "ERROR: in cal the edge_len_left!!\n" ); exit ( 1 ); } } } else { if ( line[0] == '\n' ) { continue; } //µ±len = 1023ʱ fprintf ( stderr, "ERROR: in cal the status_processed !! %d \n", processed ); exit ( 1 ); } } } fclose ( fp ); } /************************************************* Function: process_edge Description: It builds vetexes from one or part of one edge sequence. Input: 1. v_ht: hashtable 2. K_size: kmer size 3. seq: edge sequence 4. len: edge length 5. type: 1: process head and tail; 2: process head ; 3:process tail 6. edge_id: edge id 7. bal_edge: 0:palindrome 1:else Output: None. Return: None. *************************************************/ static void process_edge ( vertex_hash2 * v_ht, int K_size, char * seq, int len, int type, size_t edge_id, bool bal_edge ) { kmer_t2 vertex_kmer; kmer_t2 edge_kmer; vertex2 * v_tmp; edge_starter2 * e_tmp; int is_found; bool is_left; int edge_kmer_len; switch ( type ) { case 1: //process all .. //process the head get_kmer_from_seq ( seq, len, K_size, 0, &vertex_kmer ); if ( len <= K_size + gap ) //get the last kmer { get_kmer_from_seq ( seq, len, K_size, len - K_size, &edge_kmer ); edge_kmer_len = len - K_size; } else { //get_kmer_from_seq(seq, len, K_size, K_size,&edge_kmer); get_kmer_from_seq ( seq, len, K_size, gap, &edge_kmer ); edge_kmer_len = gap; } is_left = 0;//right v_tmp = put_vertex ( v_ht, vertex_kmer, is_found ); put_edge ( v_tmp, edge_kmer, is_left, edge_kmer_len, edge_id ); reverseCompKmer ( &vertex_kmer, K_size ); reverseCompKmer ( &edge_kmer, K_size ); is_left = 1;//left v_tmp = put_vertex ( v_ht, vertex_kmer, is_found ); put_edge ( v_tmp, edge_kmer, is_left, edge_kmer_len, edge_id + bal_edge ); //process the tail get_kmer_from_seq ( seq, len, K_size, len - K_size, &vertex_kmer ); if ( len <= K_size + gap ) //get the first kmer { get_kmer_from_seq ( seq, len, K_size, 0, &edge_kmer ); edge_kmer_len = len - K_size; } else { get_kmer_from_seq ( seq, len, K_size, len - K_size - gap, &edge_kmer ); edge_kmer_len = gap; } is_left = 1; v_tmp = put_vertex ( v_ht, vertex_kmer, is_found ); put_edge ( v_tmp, edge_kmer, is_left, edge_kmer_len, edge_id ); reverseCompKmer ( &vertex_kmer, K_size ); reverseCompKmer ( &edge_kmer, K_size ); is_left = 0;//right v_tmp = put_vertex ( v_ht, vertex_kmer, is_found ); put_edge ( v_tmp, edge_kmer, is_left, edge_kmer_len, edge_id + bal_edge ); break; case 2: //process only the head get_kmer_from_seq ( seq, len, K_size, 0, &vertex_kmer ); if ( len <= K_size + gap ) { get_kmer_from_seq ( seq, len, K_size, len - K_size, &edge_kmer ); edge_kmer_len = len - K_size; } else { get_kmer_from_seq ( seq, len, K_size, gap, &edge_kmer ); edge_kmer_len = gap; } is_left = 0;//right v_tmp = put_vertex ( v_ht, vertex_kmer, is_found ); put_edge ( v_tmp, edge_kmer, is_left, edge_kmer_len, edge_id ); reverseCompKmer ( &vertex_kmer, K_size ); reverseCompKmer ( &edge_kmer, K_size ); is_left = 1;//left v_tmp = put_vertex ( v_ht, vertex_kmer, is_found ); put_edge ( v_tmp, edge_kmer, is_left, edge_kmer_len, edge_id + bal_edge ); break; case 3: //process only the tail get_kmer_from_seq ( seq, len, K_size, len - K_size, &vertex_kmer ); if ( len <= K_size + gap ) { get_kmer_from_seq ( seq, len, K_size, 0, &edge_kmer ); edge_kmer_len = len - K_size; } else { get_kmer_from_seq ( seq, len, K_size, len - K_size - gap, &edge_kmer ); edge_kmer_len = gap; } is_left = 1; v_tmp = put_vertex ( v_ht, vertex_kmer, is_found ); put_edge ( v_tmp, edge_kmer, is_left, edge_kmer_len, edge_id ); reverseCompKmer ( &vertex_kmer, K_size ); reverseCompKmer ( &edge_kmer, K_size ); is_left = 0;//right v_tmp = put_vertex ( v_ht, vertex_kmer, is_found ); put_edge ( v_tmp, edge_kmer, is_left, edge_kmer_len, edge_id + bal_edge ); break; default: fprintf ( stderr, "ERROR: wrong process type in process_edge()\n" ); exit ( 1 ); } } static vertex2 * put_vertex ( vertex_hash2 * v_ht, kmer_t2 vertex_kmer, int & is_found ) //63 127 differ fixed { uint64_t hv = MurmurHash64A ( vertex_kmer.kmer, sizeof ( kmer_t2 ), 0 ); //hash value uint64_t idx = ( size_t ) ( hv % v_ht->ht_sz ); vertex2 * ver = ( v_ht->store_pos ) [idx]; if ( !ver ) { ( v_ht->store_pos ) [idx] = ( vertex2 * ) malloc ( sizeof ( vertex2 ) ); ver = ( v_ht->store_pos ) [idx]; ver->kmer_t2 = vertex_kmer; ver->left = NULL; ver->right = NULL; ver->next = NULL; is_found = 0; return ver; } while ( ver ) { if ( kmerCompare ( & ( ver->kmer_t2 ), &vertex_kmer ) == 0 ) { is_found = 1; return ver; } if ( ver->next == NULL ) { break; } ver = ver->next; } is_found = 0; ver->next = ( vertex2 * ) malloc ( sizeof ( vertex2 ) ); ver->next->kmer_t2 = vertex_kmer; ver->next->left = NULL; ver->next->right = NULL; ver->next->next = NULL; return ver->next; } static void put_edge ( vertex2 * ver, kmer_t2 edge_kmer, bool is_left, int len, size_t edge_id ) //fixed { edge_starter2 * tmp = NULL; if ( is_left ) { if ( !ver->left ) { ver->left = ( edge_starter2 * ) malloc ( sizeof ( edge_starter2 ) ); ver->left->edge_kmer = edge_kmer; ver->left->edge_id = edge_id; ver->left->len = len;//record the length of edge (1~k) ver->left->next = NULL; return; } tmp = ver->left; } else { if ( !ver->right ) { ver->right = ( edge_starter2 * ) malloc ( sizeof ( edge_starter2 ) ); ver->right->edge_kmer = edge_kmer; ver->right->edge_id = edge_id; ver->right->len = len;//record the length of edge (1~k) ver->right->next = NULL; return; } tmp = ver->right; } while ( tmp->next ) //because there are no two edges equal attached with one node ... { tmp = tmp->next; } tmp->next = ( edge_starter2 * ) malloc ( sizeof ( edge_starter2 ) ); tmp->next->edge_kmer = edge_kmer; tmp->next->edge_id = edge_id; tmp->next->len = len;//record the length of edge (1~k) tmp->next->next = NULL; } static vertex2 * search_vertex ( vertex_hash2 * v_ht, kmer_t2 * vertex_kmer ) //fixed ... { uint64_t hv = MurmurHash64A ( vertex_kmer->kmer, sizeof ( kmer_t2 ), 0 ); //hash value uint64_t idx = ( size_t ) ( hv % v_ht->ht_sz ); vertex2 * ver = ( v_ht->store_pos ) [idx]; while ( ver ) { if ( kmerCompare ( & ( ver->kmer_t2 ), vertex_kmer ) == 0 ) { return ver; } ver = ver->next; } return NULL; } void init_preArc_array ( preArc_array * arc_array, size_t sz ) //63 127 same { arc_array->array_sz = sz; arc_array->store_pos = ( preArc ** ) calloc ( sz, sizeof ( preArc * ) ); } static void chop_kmers ( const char * read, int len, int K_size, kmer_t2 * kmer_array, int kmer_array_len, int & kmer_num ) { if ( len <= K_size ) { kmer_num = 0; return ; } kmer_num = len - K_size + 1; if ( kmer_num > kmer_array_len ) { fprintf ( stderr, "ERROR: the kmer_array_len is not enough! %d\n", kmer_num ); exit ( 1 ); } kmer_t2 kmer; for ( int i = 0; i < kmer_num; ++i ) //optimize later { get_kmer_from_seq ( read, len, K_size, i, &kmer ); kmer_array[i] = kmer; } } /************************************************* Function: put_preArc_threaded Description: Stores one preArc into preArc_array Input: 1. arc_arr: preArc array 2. locks: the locks array for modifying preArc array 3. left_id: left edge id 4. right_id: right edge id 5. added_multi: added weigth Output: None. Return: None. *************************************************/ static inline void put_preArc_threaded ( preArc_array * arc_arr, pthread_spinlock_t * locks, size_t left_id, size_t right_id, int added_multi ) { pthread_spin_lock ( &locks[left_id] ); put_preArc ( arc_arr, left_id, right_id, added_multi ); pthread_spin_unlock ( &locks[left_id] ); } static inline void put_preArc ( preArc_array * arc_arr, size_t left_id, size_t right_id, int added_multi ) { preArc * arc = ( arc_arr->store_pos ) [left_id]; if ( !arc ) { ( arc_arr->store_pos ) [left_id] = ( preArc * ) malloc ( sizeof ( preArc ) ); arc = ( arc_arr->store_pos ) [left_id]; arc->to_ed = right_id; arc->multiplicity = added_multi; arc->next = NULL; return; } while ( arc ) { if ( arc->to_ed == right_id ) { arc->multiplicity += added_multi; return; } if ( arc->next == NULL ) { break; } arc = arc->next; } arc->next = ( preArc * ) malloc ( sizeof ( preArc ) ); arc->next->to_ed = right_id; arc->next->multiplicity = added_multi; arc->next->next = NULL; } static inline void put_preArc ( preArc_array * arc_arr, size_t left_id, size_t right_id ) { preArc * arc = ( arc_arr->store_pos ) [left_id]; if ( !arc ) { ( arc_arr->store_pos ) [left_id] = ( preArc * ) malloc ( sizeof ( preArc ) ); arc = ( arc_arr->store_pos ) [left_id]; arc->to_ed = right_id; arc->multiplicity = 1; arc->next = NULL; return; } while ( arc ) { if ( arc->to_ed == right_id ) { arc->multiplicity++; return; } if ( arc->next == NULL ) { break; } arc = arc->next; } arc->next = ( preArc * ) malloc ( sizeof ( preArc ) ); arc->next->to_ed = right_id; arc->next->multiplicity = 1; arc->next->next = NULL; } void output_preArcs ( preArc_array * arc_arr, char * outfile ) { FILE * fp; fp = fopen ( outfile, "w" ); if ( !fp ) { fprintf ( stderr, "ERROR: can't create file %s in output_preArc\n", outfile ); exit ( 1 ); } preArc * parc; for ( size_t i = 0; i < arc_arr->array_sz; ++i ) { parc = ( arc_arr->store_pos ) [i]; if ( parc ) { fprintf ( fp, "%u", i ); int j = 0; while ( parc ) { j++; fprintf ( fp, " %u %u", parc->to_ed, parc->multiplicity ); parc = parc->next; if ( parc && j % 4 == 0 ) { fprintf ( fp, "\n" ); fprintf ( fp, "%u", i ); } } fprintf ( fp, "\n" ); } } fclose ( fp ); } static void free_vertex ( vertex2 * tmp ) { edge_starter2 * edge_s, *edge_s2; edge_s = tmp->left; while ( edge_s ) { edge_s2 = edge_s; edge_s = edge_s->next; free ( edge_s2 ); } edge_s = tmp->right; while ( edge_s ) { edge_s2 = edge_s; edge_s = edge_s->next; free ( edge_s2 ); } free ( tmp ); } void free_vertex_hash ( vertex_hash2 * v_ht ) { vertex2 * tmp, *tmp2; for ( size_t i = 0; i < v_ht->ht_sz; ++i ) { tmp = ( v_ht->store_pos ) [i]; while ( tmp ) { tmp2 = tmp; tmp = tmp->next; free_vertex ( tmp2 ); } } free ( v_ht->store_pos ); } /************************************************* Function: process_1read_preArc Description: This is the core function for building preArcs. 1. Chops one read into kmers. 2. Searches the kmers in vertex hash. 3. Aligns the vertex's kmer-edge sequences to the read sequence on both sides. 4. Constructs preArcs according the mapping result on both sides of a vertex. @since r53: 5. add -R support, solves tiny repeat. Input: 1. arc_arr: preArc array 2. locks: locks array 3. v_ht: vertex hash 4. K_size: kmer size 5. cut_off_len: cut off length 6. read: read Output: None. Return: None. *************************************************/ void process_1read_preArc ( preArc_array * arc_arr, pthread_spinlock_t * locks, int thread_id, vertex_hash2 * v_ht, int K_size, int cut_off_len, const char * read ) { const int BUFF_LEN = 1024; kmer_t2 kmers[BUFF_LEN]; int kmer_array_len = cut_off_len - K_size + 1; int kmer_num ; vertex2 * v_tmp; edge_starter2 * e_tmp; size_t left_id; size_t right_id; int left_found = 0, right_found = 0; int edge_len; //update //int map_len; //int shortest_maplen = 0; //add for -R solving tiny repeats unsigned int path[128]; unsigned int counter = 0; //int read_len,i=0; int read_len = strlen ( read ); /* while(read[i]!='\0'){ i++; } read_len = i; //read_len = strlen(read); if(read[read_len-1]=='\n'){ read[read_len-1]='\0'; read_len--; }*/ if ( read_len > cut_off_len ) { read_len = cut_off_len; } kmer_array_len = read_len - K_size + 1; chop_kmers ( read, read_len, K_size, kmers, kmer_array_len, kmer_num ); for ( int i = 1; i < kmer_num - 1; ++i ) //search every kmer exclude the begin and end kmer { v_tmp = search_vertex ( v_ht, &kmers[i] ); if ( v_tmp ) //found { //search left edge kmer got left id e_tmp = v_tmp->left; while ( e_tmp ) { edge_len = e_tmp->len; if ( edge_len <= i ) { if ( kmerCompare ( & ( kmers[i - edge_len] ), & ( e_tmp->edge_kmer ) ) == 0 ) { left_id = e_tmp->edge_id; if ( left_found ) { fprintf ( stderr, "ERROR: left edge id found already !new found id %llu \n", left_id ); fprintf ( stderr, "i:%d ,edge_len:%d\n", i, edge_len ); printKmerSeq ( & ( kmers[i - edge_len] ), K_size, stderr ); printKmerSeq ( & ( e_tmp->edge_kmer ), K_size, stderr ); exit ( 1 ); }; left_found = 1; break; } } else { kmer_t2 read_edge = kmers[0]; if ( K_size > i ) { kmerMoveRight ( &read_edge, K_size - i ); } kmer_t2 KMER_FILTER; initKmerFilter ( i, &KMER_FILTER ); kmer_t2 edge_kmer = e_tmp->edge_kmer; if ( K_size > edge_len ) { kmerMoveRight ( &edge_kmer, K_size - edge_len ); } kmerAnd ( &read_edge, &KMER_FILTER ); kmerAnd ( &edge_kmer, &KMER_FILTER ); if ( kmerCompare ( &read_edge, &edge_kmer ) == 0 ) { left_found++; left_id = e_tmp->edge_id; if ( left_found == 2 ) { //debug_build<<"can't distinct which left edge\n"; break; } } } e_tmp = e_tmp->next; } //update maplen_control /* if(edge_len >= shortest_maplen){ if(map_len < shortest_maplen) left_found = 0; }else{ if(map_len != edge_len) left_found = 0; }*/ if ( left_found != 1 ) {left_found = 0; right_found = 0; continue;} //not found or multi found //todo : aln if left_found = 0 ... find the best //search right edge kmer got right id e_tmp = v_tmp->right; while ( e_tmp ) { edge_len = e_tmp->len; if ( edge_len <= kmer_num - 1 - i ) { if ( kmerCompare ( & ( kmers[i + edge_len] ), & ( e_tmp->edge_kmer ) ) == 0 ) { right_id = e_tmp->edge_id; if ( right_found ) { fprintf ( stderr, "ERROR: right edge id found already, new found id %llu !\n", right_id ); fprintf ( stderr, "i:%d ,edge_len:%d\n", i, edge_len ); printKmerSeq ( & ( kmers[i + edge_len] ), K_size, stderr ); printKmerSeq ( & ( e_tmp->edge_kmer ), K_size, stderr ); exit ( 1 ); }; right_found = 1; break; } } else { int read_edge_len = ( kmer_num - 1 - i ); kmer_t2 KMER_FILTER; initKmerFilter ( read_edge_len, &KMER_FILTER ); kmer_t2 read_edge = kmers[kmer_num - 1]; kmerAnd ( &read_edge, &KMER_FILTER ); kmer_t2 edge_kmer = e_tmp->edge_kmer; if ( edge_len > read_edge_len ) { kmerMoveRight ( &edge_kmer, ( edge_len - read_edge_len ) ); } kmerAnd ( &edge_kmer, &KMER_FILTER ); if ( kmerCompare ( &read_edge, &edge_kmer ) == 0 ) { right_found++; right_id = e_tmp->edge_id; if ( right_found == 2 ) { //debug_build<<"can't distinct which right edge\n"; break; } } } e_tmp = e_tmp->next; } //update map_len control /* if(edge_len >= shortest_maplen){ if(map_len < shortest_maplen) right_found = 0; }else{ if(map_len != edge_len) right_found = 0; }*/ if ( right_found != 1 ) {left_found = 0; right_found = 0; continue;} //todo : aln if right_found = 0 ... find the best //if(left_found == 1 && right_found ==1) //store this preArc //preArc_array *arc_arr put_preArc_threaded ( arc_arr, locks, left_id, right_id, 1 ); //constructing the path ... if ( solve ) { if ( counter == 0 ) { counter = 2; path[1] = left_id; path[2] = right_id; } else if ( counter <= 100 ) { if ( path[counter] == left_id ) { path[++counter] = right_id; } else { path[++counter] = left_id; path[++counter] = right_id; } } } //end ... left_found = 0; right_found = 0; } } //add to path buffer , if full filled ,output it if ( solve ) { if ( counter >= 3 && counter <= 100 ) { path[0] = counter; int tmp = is_full ( path_buffer[thread_id] ); if ( tmp == 1 ) { //output it output_edge_path_buffer_locked ( path_buffer[thread_id], path_fp, &file_lock ); } else if ( tmp == -1 ) { //error status fprintf ( stderr, "ERROR: path buffer overflow!! system exit .\n" ); exit ( -1 ); } put_path_2_buffer ( path_buffer[thread_id], path ); } } } void free_preArc_array ( preArc_array * arc_array ) { preArc * tmp, *tmp2; for ( size_t i = 0; i < arc_array->array_sz; ++i ) { tmp = ( arc_array->store_pos ) [i]; while ( tmp ) { tmp2 = tmp; tmp = tmp->next; free ( tmp2 ); } } free ( arc_array->store_pos ); } /************************************************* Function: build_preArc_threaded Description: This is the main entry for building preArcs. Input: 1. arc_arr: preArc array 2. v_ht: vertex hash 3. K_size: kmer size 4. cut_off_len: cut off length 5. in_filenames_vt: input reads file names 6. thread_num: thread number Output: None. Return: None. *************************************************/ void build_preArc_threaded ( preArc_array * arc_arr, vertex_hash2 * v_ht, int K_size, int cut_off_len, vector *in_filenames_vt, int thread_num ) { //create main io thread int read_buf_sz = 102400 * thrd_num_s; read_buf0 = new string[read_buf_sz]; read_buf1 = new string[read_buf_sz]; io_stat0 = 1; //must be one, if io_stat0 =0 ,the io thread will work immediately io_stat1 = 1; io_ready = 0; io_para_main io_para_mains; io_para_mains.read_buf_sz = read_buf_sz; io_para_mains.in_filenames_vt = in_filenames_vt; pthread_t io_thread; int temp; //fprintf(stderr,"Creating main io thread ...\n"); if ( ( temp = pthread_create ( &io_thread, NULL, run_io_thread_main, &io_para_mains ) ) != 0 ) { fprintf ( stderr, "ERROR: failed creating main io thread.\n" ); exit ( -1 ); } fprintf ( stderr, "1 io thread initialized.\n" ); //create work threads .. //fprintf(stderr,"Creating work threads ...\n"); pthread_t threads[thrd_num_s]; unsigned char thrdSignal[thrd_num_s + 1]; PARAMETER paras[thrd_num_s]; locks = ( pthread_spinlock_t * ) calloc ( arc_arr->array_sz, sizeof ( pthread_spinlock_t ) ); //init as unlock stat .. for ( size_t i = 0; i < arc_arr->array_sz; ++i ) { locks[i] = 1; } for ( int k = 0; k < thrd_num_s; k++ ) { thrdSignal[k + 1] = 0; paras[k].threadID = k; paras[k].mainSignal = &thrdSignal[0]; paras[k].selfSignal = &thrdSignal[k + 1]; paras[k].ht = NULL; paras[k].preArcs = arc_arr; paras[k].v_ht = v_ht; paras[k].cut_off_len = cut_off_len; paras[k].K_size = K_size; paras[k].gap = gap; } creatThrds ( threads, paras ); thrdSignal[0] = 0; //run it while ( 1 ) { sendIOWorkSignal(); while ( io_ready == 0 ) {usleep ( 1 );} if ( io_ready ) { sendWorkSignal ( 12, thrdSignal ); } if ( io_ready == 2 ) { //fprintf(stderr,"All reads have been processed!\n"); break; } } sendWorkSignal ( 3, thrdSignal ); thread_wait ( threads ); delete [] read_buf0; delete [] read_buf1; free ( ( void * ) locks ); free_vertex_hash ( v_ht ); } /************************************************* Function: create_edge_path_buffer Description: Creates an edge_path_buffer struct dynamicly. Input: None. Output: None. Return: an edge_path_buffer pointer to heap *************************************************/ edge_path_buffer * create_edge_path_buffer ( unsigned int * mark_on_edge, pthread_spinlock_t * locks, unsigned long long buff_size, unsigned int max_path_length ) { if ( ! ( mark_on_edge && locks ) ) { fprintf ( stderr, "ERROR: The initial mark_on_edge array or locks are not valid! Exit System ...\n" ); exit ( -1 ); } edge_path_buffer * new_buffer = ( edge_path_buffer * ) calloc ( 1, sizeof ( edge_path_buffer ) ); new_buffer->mark_on_edge = mark_on_edge; new_buffer->locks = locks; new_buffer->buff_size = buff_size; new_buffer->max_path_length = max_path_length; new_buffer->filled_num = 0; new_buffer->path_buffer = NULL; unsigned int ** tmp; tmp = ( unsigned int ** ) calloc ( buff_size, sizeof ( unsigned int * ) ); for ( size_t i = 0; i < buff_size; i++ ) { tmp[i] = ( unsigned int * ) calloc ( max_path_length, sizeof ( unsigned int ) ); } new_buffer->path_buffer = tmp; return new_buffer; } /************************************************* Function: create_edge_path_buffer Description: free the path_buffer in an edge_path_buffer struct Input: None Output: None Return: None *************************************************/ void destory_edge_path_buffer ( struct edge_path_buffer * buffer ) { unsigned int ** tmp = buffer->path_buffer; for ( size_t i = 0; i < buffer->buff_size; i++ ) { free ( ( void * ) ( tmp[i] ) ); } free ( ( void * ) tmp ); buffer->filled_num = 0; } void clear_edge_path_buffer ( struct edge_path_buffer * buffer ) { unsigned int ** tmp = buffer->path_buffer; for ( size_t i = 0; i < buffer->buff_size; i++ ) { memset ( tmp[i], 0, buffer->max_path_length * sizeof ( unsigned int ) ); } buffer->filled_num = 0; } void output_edge_path_buffer ( struct edge_path_buffer * buffer, FILE * path_file ) { if ( debug ) { static size_t times = 0, total = 0; total += buffer->filled_num; fprintf ( stderr, "call output_edge_path_buffer %lu %lu\n", times++, total ); } if ( !path_file ) { fprintf ( stderr, "ERROR: The path_file is not avilable!\n" ); exit ( -1 ); } unsigned int counter; unsigned int ** tmp = buffer->path_buffer; for ( size_t i = 0; i < buffer->filled_num; i++ ) { counter = tmp[i][0]; fwrite ( &counter, sizeof ( char ), 1, path_file ); fwrite ( tmp[i] + 1, sizeof ( unsigned int ), ( int ) counter, path_file ); } buffer->filled_num = 0; } /************************************************* Function: output_edge_path_buffer_locked Description: Output the buffer to a file for multi-threading. Input: None. Output: None. Return: None. *************************************************/ void output_edge_path_buffer_locked ( struct edge_path_buffer * buffer, FILE * path_file, pthread_mutex_t * file_mutex ) { static size_t times = 0, total = 0;; if ( !path_file ) { fprintf ( stderr, "ERROR: The path_file is not avilable!\n" ); exit ( -1 ); } unsigned int counter; unsigned int ** tmp = buffer->path_buffer; pthread_mutex_lock ( file_mutex ); if ( debug ) { total += buffer->filled_num; fprintf ( stderr, "call output_edge_path_buffer_locked %lu %lu\n", times++, total ); } for ( size_t i = 0; i < buffer->filled_num; i++ ) { counter = tmp[i][0]; fwrite ( &counter, sizeof ( char ), 1, path_file ); fwrite ( tmp[i] + 1, sizeof ( unsigned int ), ( int ) counter, path_file ); } pthread_mutex_unlock ( file_mutex ); buffer->filled_num = 0; } /************************************************* Function: put_path_2_buffer Description: Stores the path to buffer and update mark_on_edge array at the same time. Input: None. Output: None. Return: None. *************************************************/ int put_path_2_buffer ( struct edge_path_buffer * buffer, unsigned int * path ) { if ( debug ) { static size_t times = 0; static pthread_spinlock_t lock = 1; pthread_spin_lock ( &lock ); fprintf ( stderr, "call put_path_2_buffer %lu\n", times++ ); pthread_spin_unlock ( &lock ); } unsigned long long pos = buffer->filled_num; if ( pos >= buffer->buff_size ) { return -1; } memcpy ( ( buffer->path_buffer ) [pos], path, buffer->max_path_length * sizeof ( unsigned int ) ); for ( unsigned int i = 1; i < path[0]; i++ ) { pthread_spin_lock ( ( buffer->locks ) + path[i] ); ( ( buffer->mark_on_edge ) [path[i]] ) ++; pthread_spin_unlock ( ( buffer->locks ) + path[i] ); } buffer->filled_num++; return 1; } int is_full ( struct edge_path_buffer * buffer ) { if ( buffer->filled_num == buffer->buff_size ) { return 1; } else if ( buffer->filled_num < buffer->buff_size ) { return 0; } else { return -1; } } void clear_status ( struct edge_path_buffer * buffer ) { buffer->filled_num = 0; } soapdenovo2-240+dfsg.orig/sparsePregraph/io_func.cpp0000644000000000000000000005125012166703654021325 0ustar rootroot/* * io_func.cpp * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "io_func.h" #include "stdinc.h" #include #include #include "bam.h" #include "faidx.h" #include "knetfile.h" #include "sam_view.h" #include "xcurses.h" #include "zlib.h" #include "bgzf.h" #include "glf.h" #include "kstring.h" #include "razf.h" #include "sam_header.h" #include "zconf.h" #include "sam.h" #include "errno.h" //for bam reading ... static int state = -3; static int readstate = 0; static samfile_t * openFile4readb ( const char * fname ); void read1seqbam ( char * src_seq, char * src_name, int max_read_len, samfile_t * in, int * type ); /************************************************* Function: filter_N Description: filters N on reads. Input: 1. seq_s: input read sequence Output: 1. seq_s: read sequence without N 2. bad_flag: indicat whether the sequence is vaild Return: None. *************************************************/ void filter_N ( string & seq_s, int & bad_flag ) { //global max_rd_len //global min_rd_len if ( seq_s.size() > max_rd_len ) { max_rd_len = seq_s.size(); } if ( seq_s.size() < min_rd_len ) { min_rd_len = seq_s.size(); } bad_flag = 0; if ( seq_s[seq_s.size() - 1] == '\n' || seq_s[seq_s.size() - 1] == '\r' ) { seq_s.resize ( seq_s.size() - 1 ); } int seq_sz = seq_s.size(); int nN = seq_sz, isN = -1; for ( int i = 0; i < seq_sz; ++i ) { if ( seq_s[i] == '-' || seq_s[i] == 'N' ) { if ( i <= seq_sz / 2 ) { isN = i; continue; } else { nN = i - 1; break; } } } if ( nN == seq_sz && isN == -1 ) {bad_flag = 0; return;} if ( ( nN - isN ) <= seq_sz / 2 ) { bad_flag = 1; } if ( bad_flag == 1 ) { return; } seq_s = seq_s.substr ( isN + 1, nN - isN ); } /************************************************* Function: read_lib Description: When the asm_flags equals 1 or 3, adds the filename into vector filenames. Input: 1. filenames: filenames vector 2. lib_file: read lib config file Output: 1. filenames: filenames vector Return: None. *************************************************/ void read_lib ( vector &filenames, char * lib_file ) { ifstream lib_in ( lib_file ); string str; int read_stat = 0; // 1: begin a lib, 2:asm_flags=1 or 3 size_t found; int asm_flags; while ( getline ( lib_in, str ) ) { if ( read_stat == 0 ) //not start a lib { found = str.find ( "[LIB]" ); if ( found == string::npos ) { continue; } else { read_stat = 1; asm_flags = 0; } } else if ( read_stat == 1 ) //start reading a lib fetch asm flags { //split by "=" found = str.find ( "asm_flags" ); if ( found == string::npos ) { continue; } else { found = str.find ( "=" ); str = str.substr ( found + 1, str.size() - found ); if ( str.size() == 0 ) { fprintf ( stderr, "ERROR: please check asm_flags in lib file\n" ); exit ( -1 ); } asm_flags = atoi ( str.c_str() ); if ( asm_flags == 1 || asm_flags == 3 ) { read_stat = 2; } else { read_stat = 0; // next lib } } } else if ( read_stat == 2 ) // reading file { found = str.find_first_of ( "fqpb" ); if ( found == 0 ) //f1 f2 q1 q2 p b { found = str.find ( "=" ); if ( found > 2 ) {continue;} // the "=" should be the second or thrid poistion str = str.substr ( found + 1, str.size() - found ); filenames.push_back ( str ); } else { found = str.find ( "[LIB]" ); if ( found == string::npos ) { continue; } else { read_stat = 1; asm_flags = 0; } } } } } /************************************************* Function: sendIOWorkSignal Description: Initializes the io status, makes the io threads ready to work. Input: None Output: None Return: None *************************************************/ void sendIOWorkSignal() { if ( io_ready == 2 ) { return ; } //finish io job io_stat0 = 0; io_stat1 = 0; io_ready = 0; } /************************************************* Function: run_io_thread_main Description: This is the main io thread working rountine. Two buffer "read_buf0" and "read_buf0" are applied to implement AIO. It makes the pointer "seq_t" always pointing to the filled buffer. Input: 1. arg: args for io threads Output: None. Return: None. *************************************************/ void * run_io_thread_main ( void * arg ) { io_para_main * paras; paras = ( io_para_main * ) arg; if ( !paras ) { fprintf ( stderr, "ERROR: the argument passed to main io thread is NULL!\n" ); exit ( -1 ); } int read_buf_sz = paras->read_buf_sz; vector in_filenames_vt = * ( paras->in_filenames_vt ); /* for(int i=0;i= 1 ) { string temp; size_t found; found = in_filenames_vt[file_num].find_last_of ( "." ); if ( found == string::npos ) { //fp = fopen(in_filenames_vt[file_num].c_str(),"r"); //normal fp = ( FILE * ) open_file_robust ( "plain", in_filenames_vt[file_num].c_str(), "r" ); filetype = 0; } else { temp = in_filenames_vt[file_num].substr ( found ); if ( temp.compare ( ".gz" ) == 0 ) //gzip { //temp = "gzip -dc "; //temp.append(in_filenames_vt[file_num]); //fp = popen(temp.c_str(),"r"); fp = ( FILE * ) open_file_robust ( "gz", in_filenames_vt[file_num].c_str(), "r" ); filetype = 1; } else if ( temp.compare ( ".bam" ) == 0 ) //bam { //fp3 = openFile4readb(in_filenames_vt[file_num].c_str()); fp3 = ( samfile_t * ) open_file_robust ( "bam", in_filenames_vt[file_num].c_str(), "r" ); filetype = 2; } else { //fp = fopen(in_filenames_vt[file_num].c_str(),"r"); //normal fp = ( FILE * ) open_file_robust ( "plain", in_filenames_vt[file_num].c_str(), "r" ); filetype = 0; } } if ( !fp && !fp3 ) { fprintf ( stderr, "ERROR: can't open file %s \n", in_filenames_vt[file_num].c_str() ); exit ( 1 ); } } else { fprintf ( stderr, "ERROR: input filenames vector is empty! please check the reads config file,option \"asm_flags\" is requried!\n" ); exit ( 1 ); } //fprintf(stderr,"processing file %d %s \n",file_num,in_filenames_vt[file_num].c_str()); fprintf ( stderr, "Import reads from file:\n %s\n", in_filenames_vt[file_num].c_str() ); while ( 1 ) { while ( ( io_stat0 ) && ( io_stat1 ) ) { usleep ( 1 ); } if ( ! ( io_stat0 ) ) //fill buf0 { io_stat0 = 1;// reading reads stat int ready = 0; int i = 0; if ( filetype == 0 || filetype == 1 ) //normal or gzip reading ... { while ( i < read_buf_sz ) { if ( fgets ( line, read_buf_len, fp ) != NULL ) { switch ( line[0] ) { case '@': case '>': ready = 1; break; case '+': ready = 0; break; default: if ( ready ) { read_buf0[i].clear(); read_buf0[i].append ( line ); i++; } } } else { break; } } } else if ( filetype == 2 ) //bam reading { int type = 0; char src_name[128]; while ( i < read_buf_sz && readstate >= 0 ) //readstate { read1seqbam ( line, src_name, read_buf_len, fp3, &type ); if ( type != -1 ) { read_buf0[i].clear(); read_buf0[i].append ( line ); //cout<<"line:"<': ready = 1; break; case '+': ready = 0; break; default: if ( ready ) { read_buf1[i].clear(); read_buf1[i].append ( line ); i++; } } } else { break; } } } else if ( filetype == 2 ) //bam reading { int type = 0; char src_name[128]; while ( i < read_buf_sz && readstate >= 0 ) //readstate { read1seqbam ( line, src_name, read_buf_len, fp3, &type ); if ( type != -1 ) { read_buf1[i].clear(); read_buf1[i].append ( line ); i++; } } } else { fprintf ( stderr, "ERROR: filetype is not support or filename has a wrong suffix!\n" ); exit ( 1 ); } read_num1 = i; reads_all_num += i; while ( io_ready != 0 ) {usleep ( 1 );}; //wait for main send work sign if ( i == read_buf_sz && ( fp || fp3 ) ) { io_stat1 = 2; } else if ( i != read_buf_sz && file_num < in_filenames_vt.size() - 1 ) //still has file unread { io_stat1 = 2; if ( filetype == 0 ) { fclose ( fp ); } else if ( filetype == 1 ) { pclose ( fp ); } else if ( filetype == 2 ) { samclose ( fp3 ); state = -3; readstate = 0; } file_num++; //open a new file ... string temp; size_t found; found = in_filenames_vt[file_num].find_last_of ( "." ); if ( found == string::npos ) { //fp = fopen(in_filenames_vt[file_num].c_str(),"r"); //normal fp = ( FILE * ) open_file_robust ( "plain", in_filenames_vt[file_num].c_str(), "r" ); filetype = 0; } else { temp = in_filenames_vt[file_num].substr ( found ); if ( temp.compare ( ".gz" ) == 0 ) //gzip { //temp = "gzip -dc "; //temp.append(in_filenames_vt[file_num]); //fp = popen(temp.c_str(),"r"); fp = ( FILE * ) open_file_robust ( "gz", in_filenames_vt[file_num].c_str(), "r" ); filetype = 1; } else if ( temp.compare ( ".bam" ) == 0 ) //bam { //fp3 = openFile4readb(in_filenames_vt[file_num].c_str()); fp3 = ( samfile_t * ) open_file_robust ( "bam", in_filenames_vt[file_num].c_str(), "r" ); filetype = 2; } else { //fp = fopen(in_filenames_vt[file_num].c_str(),"r"); //normal fp = ( FILE * ) open_file_robust ( "plain", in_filenames_vt[file_num].c_str(), "r" ); filetype = 0; } } if ( !fp && !fp3 ) { fprintf ( stderr, "ERRPR: can't open file %s \n", in_filenames_vt[file_num].c_str() ); exit ( 1 ); } //fprintf(stderr,"processing file %d %s \n",file_num,in_filenames_vt[file_num].c_str()); fprintf ( stderr, "Import reads from file:\n %s\n", in_filenames_vt[file_num].c_str() ); } else { io_stat1 = 3; } seq_t = read_buf1; read_num = read_num1; if ( io_stat1 == 3 ) { //fprintf(stderr,"Io thread's job is finished! all reads: %llu \n",reads_all_num); if ( filetype == 0 ) { fclose ( fp ); } else if ( filetype == 1 ) { pclose ( fp ); } else if ( filetype == 2 ) { samclose ( fp3 ); state = -3; readstate = 0; } io_ready = 2; break; } io_ready = 1; } } return NULL; } /************************************************* Function: read1seqbam Description: Reads sequence from bam and write it into *src_seq. Input: 1. max_read_len: max read length 2. in: sam file Output: 1. src_seq: read sequence 2. src_name: read name 3. type: record the "state" situation Return: None. *************************************************/ void read1seqbam ( char * src_seq, char * src_name, int max_read_len, samfile_t * in, int * type ) //read one sequence from bam file { bam1_t * b = bam_init1 (); char c; char * line1 = NULL; int n = 0; int len; int i, j; char * seq1; unsigned int flag1 = 0; *type = 0; readstate = 0; if ( ( readstate = samread ( in, b ) ) >= 0 ) { if ( !__g_skip_aln ( in->header, b ) ) { line1 = bam_format1_core ( in->header, b, in->type >> 2 & 3 ); } //printf("%s\n", line2); seq1 = strtok ( line1, "\t" ); for ( i = 0; i < 10; i++ ) { if ( i == 0 ) { sscanf ( seq1, "%s", src_name ); } else if ( i == 1 ) { flag1 = atoi ( seq1 ); if ( flag1 & 0x0200 ) //whether it's good or not { //state(1st read state, 2nd read state) : -3(init), -2(0), -1(1), 0(0, 0), 1(0, 1), 2(1, 0), 3(1, 1) switch ( state ) { case -3: state = -2; break; case -2: state = 0; break; case -1: state = 2; break; default: state = -3; } } else { switch ( state ) { case -3: state = -1; break; case -2: state = 1; break; case -1: state = 3; break; default: state = -3; } } } else if ( i == 9 ) //the sequence { //printf("%s\n", seq1); len = strlen ( seq1 ); if ( len + n > max_read_len ) { len = max_read_len - n; } for ( j = 0; j < len; j++ ) { if ( seq1[j] >= 'a' && seq1[j] <= 'z' ) { src_seq[n++] = ( char ) ( seq1[j] - 'a' + 'A' ); } else if ( seq1[j] >= 'A' && seq1[j] <= 'Z' ) { src_seq[n++] = seq1[j]; // after pre-process all the symbles would be a,g,c,t,n in lower or upper case. } else if ( seq1[j] == '.' ) { src_seq[n++] = 'A'; } // after pre-process all the symbles would be a,g,c,t,n in lower or upper case. } if ( 3 == state ) { state = -3; } else { if ( 0 == state || 1 == state || 2 == state ) { state = -3; *type = -1; } } } seq1 = strtok ( NULL, "\t" ); } } free ( line1 ); bam_destroy1 ( b ); src_seq[n++] = '\0'; } /************************************************* Function: openFile4readb Description: Opens a bam file for reads. Input: 1. fname bam file name Output: None. Return: a samfile pointer *************************************************/ static samfile_t * openFile4readb ( const char * fname ) //open file to read bam file { samfile_t * in; char * fn_list = 0; if ( ( in = ( samfile_t * ) samopen ( fname, "rb", fn_list ) ) == 0 ) { fprintf ( stderr, "ERROR: Cannot open %s. Now exit to system...\n", fname ); return NULL; //exit (-1); } if ( in->header == 0 ) { fprintf ( stderr, "ERROR: Cannot read the header.\n" ); return NULL; //exit (-1); } return ( in ); } /************************************************* Function: open_file_robust Description: It opens a file in a "failed-try-again" way. It supports plain , gzip and bam format. Input: 1. filetype the value enumerate here: "plain", "gz", "bam" 2. path the file path 3. mode read/write (rw) mode for plain type file, NOTE: gz or bam files are read only Output: None Return: A file pointer with void* type *************************************************/ void * open_file_robust ( const char * filetype, const char * path, const char * mode ) { void * fp = NULL; const int max_times = 10; const int max_sleep = 60; int cur_times = 1; int cur_sleep = 1; while ( !fp ) { if ( strcmp ( filetype, "plain" ) == 0 ) { if ( access ( path, 0 ) == 0 ) { fp = fopen ( path, mode ); } } else if ( strcmp ( filetype, "gz" ) == 0 ) { char tmp[256]; sprintf ( tmp, "gzip -dc %s", path ); if ( access ( path, 0 ) == 0 ) { fp = popen ( tmp, "r" ); /* if(fp && feof((FILE*)fp)){ //it's useless for "file not found but popen success" bug pclose((FILE*)fp); fp = NULL; }*/ } } else if ( strcmp ( filetype, "bam" ) == 0 ) { if ( access ( path, 0 ) == 0 ) { fp = openFile4readb ( path ); } } if ( fp ) { //fprintf(stderr,"%llx \n",fp); return fp; } else { fprintf ( stderr, "ERROR: open file %s failed!\n", path ); fprintf ( stderr, "try opening it again after %d seconds\n", cur_sleep ); sleep ( cur_sleep ); cur_times ++; cur_sleep *= 2; if ( cur_sleep >= max_sleep ) { cur_sleep = max_sleep; } if ( cur_times > max_times ) { fprintf ( stderr, "ERROR: can't open file %s , now exit system !!!", path ); exit ( -1 ); return NULL; } } } } soapdenovo2-240+dfsg.orig/sparsePregraph/build_graph.cpp0000644000000000000000000005405012166703654022164 0ustar rootroot/* * build_graph.cpp * * This file is part of SOAPdenovo. * * Part of this file is refered and modified from SparseAssembler * (See ). * */ #include "stdinc.h" #include "core.h" #include "global.h" #include "seq_util.h" #include "io_func.h" #include "build_graph.h" static void process_round1_threaded ( struct read_t * read, struct hashtable2 * ht, pthread_spinlock_t * locks, size_t * bucket_count, int K_size, int gap ); //static void process_round2_threaded(struct read_t *read,struct hashtable2 *ht,pthread_spinlock_t *locks,size_t *edge_cnt,int K_size,int gap); //for debug //static void process_round1_threaded_d(struct read_t *read, struct hashtable2 *ht,pthread_spinlock_t *locks,size_t *bucket_count,int K_size,int gap); static void process_round2_threaded_d ( struct read_t * read, struct hashtable2 * ht, pthread_spinlock_t * locks, size_t * edge_cnt, int K_size, int gap ); /************************************************* Function: run_process_threaded Description: Builds the sparse de-Brujin graph from reads. It calls function "process_round1_threaded" for round1 and "process_round2_threaded_d" for round 2 building process. Input: 1. ht: the graph hashtable 2. locks: the locks array for hashtable 3. K_size: kmer size 3. gap: the skipped distance 4. read_num: the number of reads for processing 5. thrd_num_s: the thread number for building sparse de-Brujin graph 6. thrd_id: current thread's id 7. round: current building round (1,2) Output: None. Return: None. *************************************************/ void run_process_threaded ( struct hashtable2 * ht, pthread_spinlock_t * locks, int K_size, int gap, size_t read_num, int thrd_num_s, int thrd_id, int round ) { read_t read_tmp; for ( int i = thrd_id; i < read_num; i += thrd_num_s ) { int bad_flag = 0; filter_N ( seq_t[i], bad_flag ); if ( bad_flag ) {seq_t[i].clear(); continue;} Init_Read ( seq_t[i], read_tmp ); if ( round == 1 ) { //cout << "round 1:"<< seq_t[i] <readLen; int OverlappingKmers = readLen - K_size + 1; if ( gap >= OverlappingKmers ) { return;} int Read_arr_sz = readLen / 32 + 1; int rem = readLen % 32; if ( rem == 0 ) {Read_arr_sz--;} #ifdef _63MER_ int Kmer_arr_sz = 2; int tot_bits = Read_arr_sz * 64; #endif #ifdef _127MER_ int Kmer_arr_sz = 4; int tot_bits = Read_arr_sz * 128; #endif size_t ht_sz = ht->ht_sz; bool flip[500], found[500]; size_t hash_idx[500]; memset ( flip, 0, sizeof ( flip ) ); memset ( found, 0, sizeof ( found ) ); kmer_t2 seq[500], f_seq[500]; memset ( seq, 0, sizeof ( seq ) ); uint64_t hv[500], temp_bits[500]; bucket2 ** bktptr[500]; char c_str[500]; for ( int j = 0; j < OverlappingKmers; j++ ) { get_sub_arr ( read->read_bits, read->readLen, j, K_size, seq[j].kmer ); #ifdef _63MER_ if ( K_size <= 31 ) //fix the represent bug { ( seq[j].kmer ) [1] = ( seq[j].kmer ) [0]; ( seq[j].kmer ) [0] = 0; } #endif #ifdef _127MER_ //fix the represent bug if ( K_size <= 31 ) //fix the represent bug { ( seq[j].kmer ) [3] = ( seq[j].kmer ) [0]; ( seq[j].kmer ) [0] = 0; } else if ( K_size <= 63 ) { ( seq[j].kmer ) [3] = ( seq[j].kmer ) [1]; ( seq[j].kmer ) [2] = ( seq[j].kmer ) [0]; ( seq[j].kmer ) [1] = 0; ( seq[j].kmer ) [0] = 0; } else if ( K_size <= 95 ) { ( seq[j].kmer ) [3] = ( seq[j].kmer ) [2]; ( seq[j].kmer ) [2] = ( seq[j].kmer ) [1]; ( seq[j].kmer ) [1] = ( seq[j].kmer ) [0]; ( seq[j].kmer ) [0] = 0; } #endif memcpy ( &f_seq[j], &seq[j], Kmer_arr_sz * sizeof ( uint64_t ) ); get_rev_comp_seq_arr ( ( f_seq[j].kmer ), K_size, Kmer_arr_sz ); //TODO ,add 127mer support if ( uint64_t_cmp ( seq[j].kmer, f_seq[j].kmer, Kmer_arr_sz ) > 0 ) { flip[j] = 1; } if ( flip[j] == 1 ) { memcpy ( temp_bits, & ( seq[j].kmer ), Kmer_arr_sz * sizeof ( uint64_t ) ); memcpy ( & ( seq[j].kmer ), & ( f_seq[j].kmer ), Kmer_arr_sz * sizeof ( uint64_t ) ); memcpy ( & ( f_seq[j].kmer ), temp_bits, Kmer_arr_sz * sizeof ( uint64_t ) ); } hv[j] = MurmurHash64A ( ( seq[j].kmer ), sizeof ( seq[j] ), 0 ); hash_idx[j] = ( size_t ) ( hv[j] % ht_sz ); bktptr[j] = & ( ht->store_pos[hash_idx[j]] ); } int g, h; g = 0; for ( int k = 0; k < gap; ++k ) { pthread_spin_lock ( &locks[hash_idx[k]] ); found[k] = look_up_in_a_list2_r1 ( &seq[k], ( struct bucket2_r1 ** * ) &bktptr[k] ); pthread_spin_unlock ( &locks[hash_idx[k]] ); if ( found[k] == 1 ) { g = k; break; } } for ( int j = g; j < OverlappingKmers; ) { h = gap; for ( int k = 0; k < gap; ++k ) { if ( ( j + k ) >= OverlappingKmers - 1 ) { h = k + 1; //ÉáÆúµô×îºóÒ»¸ökmer break; } pthread_spin_lock ( &locks[hash_idx[j + k]] ); found[j + k] = look_up_in_a_list2_r1 ( &seq[j + k], ( bucket2_r1 ** * ) &bktptr[j + k] ); //lock... pthread_spin_unlock ( &locks[hash_idx[j + k]] ); if ( k > 0 && found[j + k] == 1 ) { h = k; break; } } pthread_spin_lock ( &locks[hash_idx[j]] ); found[j] = look_up_in_a_list2_r1 ( &seq[j], ( bucket2_r1 ** * ) &bktptr[j] ); //lock... pthread_spin_unlock ( &locks[hash_idx[j]] ); if ( found[j] == 0 ) { pthread_spin_lock ( &locks[hash_idx[j]] ); * ( bktptr[j] ) = ( struct bucket2 * ) malloc ( sizeof ( struct bucket2_r1 ) ); //lock ... memset ( * ( bktptr[j] ), 0, sizeof ( struct bucket2_r1 ) ); memcpy ( & ( ( ( struct bucket2_r1 * ) * ( bktptr[j] ) )->kmer_t2.kmer ), & ( seq[j].kmer ), Kmer_arr_sz * sizeof ( uint64_t ) ); ( ( struct bucket2_r1 * ) * ( bktptr[j] ) )->kmer_info.cov1 = 0; // the cvg is useless in round 1 pthread_spin_unlock ( &locks[hash_idx[j]] ); ( *bucket_count ) ++; } j = j + h; if ( j >= OverlappingKmers ) {break;} } } /************************************************* Function: process_round2_threaded_d Description: Processes one read in round2: 1. Chops read to kmers 2. Searches the selected sparse-kmers 3. Builds the kmer-edges (the connection between sparse-kmers) Input: 1. read: a read 2. ht: the graph hashtable 3. locks: the locks array for hashtable 4. edge_cnt: useless 5. K_size: kmer size 6. gap: the skipped distance Output: None. Return: None. *************************************************/ static void process_round2_threaded_d ( struct read_t * read, struct hashtable2 * ht, pthread_spinlock_t * locks, size_t * edge_cnt, int K_size, int gap ) { static size_t i; int readLen = read->readLen; int OverlappingKmers = readLen - K_size + 1; if ( gap >= OverlappingKmers ) { return;} int Read_arr_sz = readLen / 32 + 1; int rem = readLen % 32; if ( rem == 0 ) {Read_arr_sz--;} #ifdef _63MER_ int Kmer_arr_sz = 2; int tot_bits = Read_arr_sz * 64; #endif #ifdef _127MER_ int Kmer_arr_sz = 4; int tot_bits = Read_arr_sz * 128; #endif size_t ht_sz = ht->ht_sz; bool flip[500], found[500]; size_t hash_idx[500]; memset ( flip, 0, sizeof ( flip ) ); memset ( found, 0, sizeof ( found ) ); kmer_t2 seq[500], f_seq[500]; uint64_t hv[500], temp_bits[500]; bucket2 ** bktptr[500]; char c_str[500]; for ( int j = 0; j < OverlappingKmers; j++ ) { get_sub_arr ( read->read_bits, read->readLen, j, K_size, seq[j].kmer ); #ifdef _63MER_ if ( K_size <= 31 ) //fix the represent bug { ( seq[j].kmer ) [1] = ( seq[j].kmer ) [0]; ( seq[j].kmer ) [0] = 0; } #endif #ifdef _127MER_ //fix the represent bug if ( K_size <= 31 ) //fix the represent bug { ( seq[j].kmer ) [3] = ( seq[j].kmer ) [0]; ( seq[j].kmer ) [0] = 0; } else if ( K_size <= 63 ) { ( seq[j].kmer ) [3] = ( seq[j].kmer ) [1]; ( seq[j].kmer ) [2] = ( seq[j].kmer ) [0]; ( seq[j].kmer ) [1] = 0; ( seq[j].kmer ) [0] = 0; } else if ( K_size <= 95 ) { ( seq[j].kmer ) [3] = ( seq[j].kmer ) [2]; ( seq[j].kmer ) [2] = ( seq[j].kmer ) [1]; ( seq[j].kmer ) [1] = ( seq[j].kmer ) [0]; ( seq[j].kmer ) [0] = 0; } #endif memcpy ( &f_seq[j], &seq[j], Kmer_arr_sz * sizeof ( uint64_t ) ); get_rev_comp_seq_arr ( ( f_seq[j].kmer ), K_size, Kmer_arr_sz ); if ( uint64_t_cmp ( seq[j].kmer, f_seq[j].kmer, Kmer_arr_sz ) > 0 ) { flip[j] = 1; } if ( flip[j] == 1 ) { memcpy ( temp_bits, & ( seq[j].kmer ), Kmer_arr_sz * sizeof ( uint64_t ) ); memcpy ( & ( seq[j].kmer ), & ( f_seq[j].kmer ), Kmer_arr_sz * sizeof ( uint64_t ) ); memcpy ( & ( f_seq[j].kmer ), temp_bits, Kmer_arr_sz * sizeof ( uint64_t ) ); } hv[j] = MurmurHash64A ( ( seq[j].kmer ), sizeof ( seq[j] ), 0 ); hash_idx[j] = ( size_t ) ( hv[j] % ht_sz ); bktptr[j] = & ( ht->store_pos[hash_idx[j]] ); found[j] = look_up_in_a_list2 ( &seq[j], &bktptr[j] ); } int last_found = -1; int cur_found = -1; int h = -1; for ( int i = 0; i < OverlappingKmers; ++i ) { if ( found[i] ) { pthread_spin_lock ( &locks[hash_idx[i]] ); if ( ( * ( bktptr[i] ) )->kmer_info.cov1 < 0xffff ) { ( * ( bktptr[i] ) )->kmer_info.cov1++; } pthread_spin_unlock ( &locks[hash_idx[i]] ); cur_found = i; if ( last_found != -1 ) { if ( cur_found - last_found > gap ) { fprintf ( stderr, "ERROR: cur_found - last_found > gap !\n" ); exit ( -1 ); } //add edge ... h = cur_found - last_found; uint64_t left_bits; get_sub_arr ( read->read_bits, read->readLen, last_found, h, &left_bits ); pthread_spin_lock ( &locks[hash_idx[cur_found]] ); //lock for cur_found node to add left edge if ( flip[cur_found] == 0 ) { struct edge_node ** edge_node_p2p = & ( ( * ( bktptr[cur_found] ) )->kmer_info.left ); while ( ( *edge_node_p2p ) != NULL ) { if ( ( *edge_node_p2p )->edge == ( uint64_t ) left_bits && ( ( *edge_node_p2p )->len + 1 ) == h ) { if ( ( *edge_node_p2p )->edge_cov < 0x7f ) { ( *edge_node_p2p )->edge_cov++;} break; } edge_node_p2p = & ( ( *edge_node_p2p )->nxt_edge ); } if ( ( *edge_node_p2p ) == NULL ) { ( *edge_node_p2p ) = ( struct edge_node * ) malloc ( sizeof ( struct edge_node ) ); ( *edge_cnt ) ++; memset ( *edge_node_p2p, 0, sizeof ( struct edge_node ) ); ( *edge_node_p2p )->edge = ( uint64_t ) left_bits; ( *edge_node_p2p )->edge_cov = 1; ( *edge_node_p2p )->len = h - 1; } } else { left_bits = get_rev_comp_seq ( left_bits, h ); struct edge_node ** edge_node_p2p = & ( ( * ( bktptr[cur_found] ) )->kmer_info.right ); while ( ( *edge_node_p2p ) != NULL ) { if ( ( *edge_node_p2p )->edge == ( uint64_t ) left_bits && ( ( *edge_node_p2p )->len + 1 ) == h ) { if ( ( *edge_node_p2p )->edge_cov < 0x7f ) { ( *edge_node_p2p )->edge_cov++;} break; } edge_node_p2p = & ( ( *edge_node_p2p )->nxt_edge ); } if ( ( *edge_node_p2p ) == NULL ) { ( *edge_node_p2p ) = ( struct edge_node * ) malloc ( sizeof ( struct edge_node ) ); ( *edge_cnt ) ++; memset ( *edge_node_p2p, 0, sizeof ( struct edge_node ) ); ( *edge_node_p2p )->edge = ( uint64_t ) left_bits; ( *edge_node_p2p )->edge_cov = 1; ( *edge_node_p2p )->len = h - 1; } } pthread_spin_unlock ( &locks[hash_idx[cur_found]] ); uint64_t right_bits; get_sub_arr ( read->read_bits, read->readLen, last_found + K_size, h, &right_bits ); pthread_spin_lock ( &locks[hash_idx[last_found]] ); //lock ... if ( flip[last_found] == 1 ) { right_bits = get_rev_comp_seq ( right_bits, h ); struct edge_node ** edge_node_p2p = & ( ( * ( bktptr[last_found] ) )->kmer_info.left ); while ( ( *edge_node_p2p ) != NULL ) { if ( ( *edge_node_p2p )->edge == ( uint64_t ) right_bits && ( ( *edge_node_p2p )->len + 1 ) == h ) { if ( ( *edge_node_p2p )->edge_cov < 0x7f ) { ( *edge_node_p2p )->edge_cov++;} break; } edge_node_p2p = & ( ( *edge_node_p2p )->nxt_edge ); } if ( ( *edge_node_p2p ) == NULL ) { ( *edge_node_p2p ) = ( struct edge_node * ) malloc ( sizeof ( struct edge_node ) ); ( *edge_cnt ) ++; memset ( *edge_node_p2p, 0, sizeof ( struct edge_node ) ); ( *edge_node_p2p )->edge = ( uint64_t ) right_bits; ( *edge_node_p2p )->edge_cov = 1; ( *edge_node_p2p )->len = h - 1; } } else { struct edge_node ** edge_node_p2p = & ( ( * ( bktptr[last_found] ) )->kmer_info.right ); while ( ( *edge_node_p2p ) != NULL ) { if ( ( *edge_node_p2p )->edge == ( uint64_t ) right_bits && ( ( *edge_node_p2p )->len + 1 == h ) ) { if ( ( *edge_node_p2p )->edge_cov < 0x7f ) { ( *edge_node_p2p )->edge_cov++;} break; } edge_node_p2p = & ( ( *edge_node_p2p )->nxt_edge ); } if ( ( *edge_node_p2p ) == NULL ) { ( *edge_node_p2p ) = ( struct edge_node * ) malloc ( sizeof ( struct edge_node ) ); ( *edge_cnt ) ++; memset ( *edge_node_p2p, 0, sizeof ( struct edge_node ) ); ( *edge_node_p2p )->edge = ( uint64_t ) right_bits; ( *edge_node_p2p )->edge_cov = 1; ( *edge_node_p2p )->len = h - 1; } } pthread_spin_unlock ( &locks[hash_idx[last_found]] ); //lock ... } last_found = cur_found; } } } /************************************************* Function: SwitchBuckets Description: Switches struct bucket form round1 bucket to round2 bucket. Input: 1. ht: the graph hashtable 2. K_size: the kmer size Output: None. Return: None. *************************************************/ void SwitchBuckets ( hashtable2 * ht2, int K_size ) { size_t ht_sz; ht_sz = ht2->ht_sz; bucket2_r1 * store_pos_o, *store_pos_t; bucket2 * store_pos_n; bucket2 ** bktp2p; for ( size_t i = 0; i < ht_sz; ++i ) { bktp2p = & ( ht2->store_pos[i] ); store_pos_o = ( bucket2_r1 * ) ht2->store_pos[i]; while ( store_pos_o != NULL ) { store_pos_n = ( bucket2 * ) malloc ( sizeof ( struct bucket2 ) ); memset ( store_pos_n, 0, sizeof ( bucket2 ) ); store_pos_n->kmer_t2 = store_pos_o->kmer_t2; store_pos_n->kmer_info.cov1 = store_pos_o->kmer_info.cov1; *bktp2p = store_pos_n; bktp2p = & ( store_pos_n->nxt_bucket ); store_pos_t = store_pos_o; store_pos_o = store_pos_o->nxt_bucket; free ( store_pos_t ); } } } /* c++ implementation .. void SavingSparseKmerGraph2(hashtable2 *ht,char * outfile) { ofstream o_ht_idx,o_ht_content; string ht_idx_name,ht_content_name,kmer_freq; ht_idx_name.append(outfile).append(".ht_idx"); ht_content_name.append(outfile).append(".ht_content"); kmer_freq.append(outfile).append(".kmerFreq"); map cov_hist; //string ht_idx_name="HT_idx.txt",ht_content_name="HT_content"; o_ht_idx.open(ht_idx_name.c_str(),ios_base::out|ios_base::binary); o_ht_content.open(ht_content_name.c_str(),ios_base::out|ios_base::binary); o_ht_idx<<"Hashtable size: "<ht_sz<ht_sz;++i) { size_t list_sz=0; bktptr=ht->store_pos[i]; while(bktptr!=NULL) { if(o_ht_content.write((char*) bktptr,sizeof(struct bucket2))) { edge_ptr=bktptr->kmer_info.left; while(edge_ptr!=NULL) { o_ht_content.write((char*) edge_ptr,sizeof(struct edge_node)); edge_ptr=edge_ptr->nxt_edge; } edge_ptr=bktptr->kmer_info.right; while(edge_ptr!=NULL) { o_ht_content.write((char*) edge_ptr,sizeof(struct edge_node)); edge_ptr=edge_ptr->nxt_edge; } int cov=bktptr->kmer_info.cov1; cov_hist[cov]++; bktptr=bktptr->nxt_bucket; list_sz++; } else {cout<<"Write error!"<::iterator mit; for(mit=cov_hist.begin();mit!=cov_hist.end();++mit) { o_cov<first<<" "<second<ht_sz ); bucket2 * bktptr = NULL; struct edge_node * edge_ptr; for ( size_t i = 0; i < ht->ht_sz; ++i ) { size_t list_sz = 0; bktptr = ht->store_pos[i]; while ( bktptr != NULL ) { if ( fwrite ( ( char * ) bktptr, sizeof ( struct bucket2 ), 1, o_ht_content ) ) { edge_ptr = bktptr->kmer_info.left; while ( edge_ptr != NULL ) { fwrite ( ( char * ) edge_ptr, sizeof ( struct edge_node ), 1, o_ht_content ); edge_ptr = edge_ptr->nxt_edge; } edge_ptr = bktptr->kmer_info.right; while ( edge_ptr != NULL ) { fwrite ( ( char * ) edge_ptr, sizeof ( struct edge_node ), 1, o_ht_content ); edge_ptr = edge_ptr->nxt_edge; } int cov = bktptr->kmer_info.cov1; if ( cov >= 255 ) { cov_hist[255]++; } else { cov_hist[cov]++; } bktptr = bktptr->nxt_bucket; list_sz++; } else {cerr << "Write error!" << endl;} } fprintf ( o_ht_idx, "%llu\n", list_sz ); } for ( int i = 1; i < 256; i++ ) { fprintf ( o_cov, "%d\t%llu\n", i, cov_hist[i] ); } fclose ( o_ht_idx ); fclose ( o_ht_content ); fclose ( o_cov ); } void LoadingSparseKmerGraph2 ( hashtable2 * ht, char * outfile ) { string ht_idx_name, ht_content_name; ht_idx_name.append ( outfile ).append ( ".ht_idx" ); ht_content_name.append ( outfile ).append ( ".ht_content" ); ifstream in_ht_idx ( ht_idx_name.c_str(), ios_base::in | ios_base::binary ), in_ht_content ( ht_content_name.c_str(), ios_base::in | ios_base::binary ); size_t ht_sz; string s; getline ( in_ht_idx, s ); getline ( in_ht_idx, s ); ht_sz = atoi ( s.c_str() ); //cerr<store_pos[i] ); *bktp2p = NULL; for ( int j = 0; j < list_sz; ++j ) { *bktp2p = ( struct bucket2 * ) malloc ( sizeof ( struct bucket2 ) ); if ( in_ht_content.read ( ( char * ) ( *bktp2p ), sizeof ( struct bucket2 ) ) ) { ( *bktp2p )->nxt_bucket = NULL; ( *bktp2p )->kmer_info.used = 0; edge_p2p = & ( ( *bktp2p )->kmer_info.left ); while ( ( *edge_p2p ) != NULL ) { ( *edge_p2p ) = ( struct edge_node * ) malloc ( sizeof ( struct edge_node ) ); in_ht_content.read ( ( char * ) ( *edge_p2p ), sizeof ( struct edge_node ) ); edge_p2p = & ( ( *edge_p2p )->nxt_edge ); } edge_p2p = & ( ( *bktp2p )->kmer_info.right ); while ( ( *edge_p2p ) != NULL ) { ( *edge_p2p ) = ( struct edge_node * ) malloc ( sizeof ( struct edge_node ) ); in_ht_content.read ( ( char * ) ( *edge_p2p ), sizeof ( struct edge_node ) ); edge_p2p = & ( ( *edge_p2p )->nxt_edge ); } bktp2p = & ( ( *bktp2p )->nxt_bucket ); } else {cerr << "Read error!" << endl;} } } } soapdenovo2-240+dfsg.orig/sparsePregraph/global.cpp0000644000000000000000000000437412166703654021150 0ustar rootroot/* * global.cpp * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "global.h" char shortrdsfile[256];//in lib file char graphfile[256];//out prefix int NodeCovTh = 1; int EdgeCovTh = 1; //BE :build edge ,BPA:build preArc int K_size = 23; int gap = 15; uint64_t GenomeSize = 0; int solve = 0; //default not solving repeats int run_mode = 0; int thrd_num_s = 8; size_t * edge_cnt_total = NULL; //used int lock strategy size_t * bucket_count_total = NULL; //used in lock strategy //for io thread @see io_func.h //for io thread string * seq_t = NULL; int io_ready; //0 ready to work 1 working 2 *seq_t ready 3 end reading signal int read_num = 0; //the read num in *seq_t string * read_buf0 = NULL; string * read_buf1 = NULL; int io_stat0 = 1; //must be one, if io_stat0 =0 ,the io thread will work immediately int io_stat1 = 1; size_t reads_all_num = 0; int max_rd_len = 0; int min_rd_len = 100000; //for the hashing lock strategy ... pthread_spinlock_t * locks; // solving tiny repeats, temporarily using global vars to implements this feature unsigned int * mark_on_edge = NULL; pthread_spinlock_t * s_locks = NULL; struct edge_path_buffer ** path_buffer = NULL; unsigned long long buff_size = 1024; unsigned int max_path_length = 128; //max_path_length-1 is the real max path length, because the first int of buffer record the path length FILE * mark_fp = NULL; // FILE * path_fp = NULL; // pthread_mutex_t file_lock;// int debug = 0 ; soapdenovo2-240+dfsg.orig/sparsePregraph/Makefile0000644000000000000000000000407312166705350020633 0ustar rootrootCC= g++ # /opt/blc/gcc-4.5.0/bin/gcc #gcc ifdef debug CFLAGS= -O0 -g -fomit-frame-pointer #-static #-mcrc32 -march=core2 -msse4.1 -msse4.2 else CFLAGS= -O4 -fomit-frame-pointer #-static #-mcrc32 -march=core2 -msse4.1 -msse4.2 endif DFLAGS= OBJS= build_graph.o build_edge.o multi_threads.o \ build_preArc.o pregraph_sparse.o io_func.o\ global.o convert_soapdenovo.o PROG= INCLUDES= -I./inc SUBDIRS= . LIBPATH= -L/usr/lib64 LIBS= -pthread -lz -L./inc EXTRA_FLAGS= VERSION = 1.0.3 ifdef 127mer CFLAGS += -D_127MER_ PROG = pregraph_sparse_127mer.v$(VERSION) else CFLAGS += -D_63MER_ PROG = pregraph_sparse_63mer.v$(VERSION) endif BIT_ERR = 0 ifeq (,$(findstring $(shell uname -m), x86_64 ppc64 ia64)) BIT_ERR = 1 endif ifneq (,$(findstring Linux,$(shell uname))) EXTRA_FLAGS += -Wl,--hash-style=both LIBS += -lbam endif ifneq (,$(findstring Unix,$(shell uname))) EXTRA_FLAGS += -Wl,--hash-style=both LIBS += -lbam -lrt endif ifneq (,$(findstring Darwin,$(shell uname))) LIBS += -lbammac endif ifneq (,$(findstring $(shell uname -m), x86_64)) CFLAGS += -m64 endif ifneq (,$(findstring $(shell uname -m), ia64)) CFLAGS += endif ifneq (,$(findstring $(shell uname -m), ppc64)) CFLAGS += -mpowerpc64 endif .SUFFIXES:.cpp .o .cpp.o: @printf "Compiling $<... \r"; \ $(CC) -c $(CFLAGS) $(DFLAGS) $(INCLUDES) $< || echo "Error in command: $(CC) -c $(CFLAGS) $(DFLAGS) $(INCLUDES) $<" all: clean $(OBJS) #pregraph_sparse .PHONY:all clean install envTest: @test $(BIT_ERR) != 1 || sh -c 'echo "Fatal: 64bit CPU and Operating System required!";false;' pregraph_sparse: clean envTest $(OBJS) @printf "Linking... \r" #@$(CC) $(CFLAGS)$(INCLUDES) -o $(PROG) $(OBJS) $(LIBPATH) $(LIBS) $(ENTRAFLAGS) @printf "$(PROG) compilation done.\n"; clean: @rm -fr gmon.out *.o a.out *.exe *.dSYM $(PROG) *~ *.a *.so.* *.so *.dylib @printf "$(PROG) cleaning done.\n"; install: @cp $(PROG) ../bin/ @printf "$(PROG) installed at ../bin/$(PROG)\n" soapdenovo2-240+dfsg.orig/sparsePregraph/inc/0000755000000000000000000000000012177735462017751 5ustar rootrootsoapdenovo2-240+dfsg.orig/sparsePregraph/inc/sam_header.h0000644000000000000000000000125512166703654022211 0ustar rootroot#ifndef __SAM_HEADER_H__ #define __SAM_HEADER_H__ #ifdef __cplusplus extern "C" { #endif void * sam_header_parse2 ( const char * headerText ); void * sam_header_merge ( int n, const void ** dicts ); void sam_header_free ( void * header ); char * sam_header_write ( const void * headerDict ); // returns a newly allocated string char ** sam_header2list ( const void * _dict, char type[2], char key_tag[2], int * _n ); void * sam_header2tbl ( const void * dict, char type[2], char key_tag[2], char value_tag[2] ); const char * sam_tbl_get ( void * h, const char * key ); int sam_tbl_size ( void * h ); void sam_tbl_destroy ( void * h ); #ifdef __cplusplus } #endif #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/build_preArc.h0000644000000000000000000001231412166703654022512 0ustar rootroot/* * inc/build_preArc.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef _BUILD_PREARC_H #define _BUILD_PREARC_H #include "core.h" #include "global.h" #include "stdinc.h" struct edge_starter2 { struct kmer_t2 edge_kmer; uint64_t edge_id: 32, len: 6; //make sure that left always be end & right always be start edge_starter2 * next; }; struct vertex2 { struct kmer_t2 kmer_t2; edge_starter2 * left; edge_starter2 * right; vertex2 * next; }; struct vertex_hash2 { struct vertex2 ** store_pos; size_t ht_sz; }; struct preArc { unsigned int to_ed; unsigned int multiplicity; struct preArc * next; }; struct preArc_array { struct preArc ** store_pos; size_t array_sz; }; //public methods void init_vertex_hash ( vertex_hash2 * v_ht, size_t sz ); void build_vertexes ( vertex_hash2 * v_ht, int K_size, char * edge_file ); void free_vertex_hash ( vertex_hash2 * v_ht ); void init_preArc_array ( preArc_array * arc_array, size_t sz ); void build_preArc_threaded ( preArc_array * arc_arr, vertex_hash2 * v_ht, int K_size, int cut_off_len, vector *in_filenames_vt, int thread_num ); void output_preArcs ( preArc_array * arc_arr, char * outfile ); void free_preArc_array ( preArc_array * arc_array ); //local structs ... struct io_para { //char **buf0; //char **buf1; int * io_stat0; int * io_stat1; int * read_num0; int * read_num1; int * finished_arr0; int * finished_arr1; //FILE *fp; vector *in_filenames_vt; int read_buf_sz; int read_buf_len; int thread_num; }; struct process_para { //char **buf0; //char **buf1; int * io_stat0; int * io_stat1; int * read_num0; int * read_num1; int * finished_arr0; int * finished_arr1; preArc_array * preArcs;//change preArc** to preArc* for spin_lock version pthread_spinlock_t * locks; //... int thread_id; int thread_num; vertex_hash2 * v_ht; int K_size; int cut_off_len; }; void process_1read_preArc ( preArc_array * arc_arr, pthread_spinlock_t * locks, int thread_id, vertex_hash2 * v_ht, int K_size, int cut_off_len, const char * read ); //static methods static void process_edge ( vertex_hash2 * v_ht, int K_size, char * seq, int len, int type, size_t edge_id, bool bal_edge ); static vertex2 * put_vertex ( vertex_hash2 * v_ht, kmer_t2 vertex_kmer, int & is_found ); static void put_edge ( vertex2 * ver, kmer_t2 edge_kmer, bool is_left, int len, size_t edge_id ); static vertex2 * search_vertex ( vertex_hash2 * v_ht, kmer_t2 * vertex_kmer ); static void free_vertex ( vertex2 * tmp ); static void get_kmer ( const char * seq, int len, int K_size, int pos, kmer_t2 & kmer ); static void chop_kmers ( char * read, int len, int K_size, kmer_t2 * kmer_array, int kmer_array_len, int & kmer_num ); static void * run_io_thread ( void * arg ); static void * run_process_thread ( void * arg ); static void put_preArc ( preArc_array * arc_arr, size_t left_id, size_t right_id, int added_multi ); static void put_preArc_threaded ( preArc_array * arc_arr, pthread_spinlock_t * locks, size_t left_id, size_t right_id, int added_multi ); //add for solving repeat struct edge_path_buffer { unsigned int * mark_on_edge; //The mark on edge array, record the times of occurrence for each edge and it's revers complement pthread_spinlock_t * locks; //the locks for multi threads access and modification to mark_on_edge unsigned int ** path_buffer; //buffered the paths for out put, (the first unsigned int is the length of the path.) unsigned int max_path_length; // the max length for each path //set to 255 default ... unsigned long long buff_size; // the max path number the buffer can sotre unsigned long long filled_num; // the filled number of the buffer }; struct edge_path_buffer * create_edge_path_buffer ( unsigned int * mark_on_edge, pthread_spinlock_t * locks, unsigned long long buff_size, unsigned int max_path_length ); void destory_edge_path_buffer ( struct edge_path_buffer * buffer ); void clear_edge_path_buffer ( struct edge_path_buffer * buffer ); void output_edge_path_buffer ( struct edge_path_buffer * buffer, FILE * path_file ); void output_edge_path_buffer_locked ( struct edge_path_buffer * buffer, FILE * path_file, pthread_mutex_t * file_mutex ); int put_path_2_buffer ( struct edge_path_buffer * buffer, unsigned int * path ); void clear_status ( struct edge_path_buffer * buffer ); int is_full ( struct edge_path_buffer * buffer ); #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/glf.h0000644000000000000000000000346012166703654020671 0ustar rootroot#ifndef GLF_H_ #define GLF_H_ typedef struct { unsigned char ref_base: 4, dummy: 4; /** "XACMGRSVTWYHKDBN"[ref_base] gives the reference base */ unsigned char max_mapQ; /** maximum mapping quality */ unsigned char lk[10]; /** log likelihood ratio, capped at 255 */ unsigned min_lk: 8, depth: 24; /** minimum lk capped at 255, and the number of mapped reads */ } glf1_t; #include #include "bgzf.h" typedef BGZF * glfFile; #define GLF3_RTYPE_END 0 #define GLF3_RTYPE_SUB 1 #define GLF3_RTYPE_INDEL 2 typedef struct { uint8_t ref_base: 4, rtype: 4; /** "XACMGRSVTWYHKDBN"[ref_base] gives the reference base */ uint8_t rms_mapQ; /** RMS mapping quality */ uint8_t lk[10]; /** log likelihood ratio, capped at 255 */ uint32_t min_lk: 8, depth: 24; /** minimum lk capped at 255, and the number of mapped reads */ int32_t offset; /** the first base in a chromosome has offset zero. */ // for indel (lkHom1, lkHom2 and lkHet are the first three elements in lk[10]) int16_t indel_len[2]; int32_t max_len; // maximum indel len; will be modified by glf3_read1() char * indel_seq[2]; } glf3_t; typedef struct { int32_t l_text; uint8_t * text; } glf3_header_t; #ifdef __cplusplus extern "C" { #endif #define glf3_init1() ((glf3_t*)calloc(1, sizeof(glf3_t))) #define glf3_destroy1(g3) do { free((g3)->indel_seq[0]); free((g3)->indel_seq[1]); free(g3); } while (0) glf3_header_t * glf3_header_init(); glf3_header_t * glf3_header_read ( glfFile fp ); void glf3_header_write ( glfFile fp, const glf3_header_t * h ); void glf3_header_destroy ( glf3_header_t * h ); char * glf3_ref_read ( glfFile fp, int * len ); void glf3_ref_write ( glfFile fp, const char * name, int len ); int glf3_write1 ( glfFile fp, const glf3_t * g3 ); int glf3_read1 ( glfFile fp, glf3_t * g3 ); #ifdef __cplusplus } #endif #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/stdinc.h0000644000000000000000000000207312166703654021404 0ustar rootroot/* * inc/stdinc.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; soapdenovo2-240+dfsg.orig/sparsePregraph/inc/build_graph.h0000644000000000000000000000251212166703654022376 0ustar rootroot/* * inc/build_graph.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef __BUILD_GRAPH_H #define __BUILD_GRAPH_H #include "stdinc.h" #include "core.h" //for called void run_process_threaded ( struct hashtable2 * ht, pthread_spinlock_t * locks, int K_size, int gap, size_t read_num, int thrd_num, int thrd_id, int round ); void SwitchBuckets ( hashtable2 * ht2, int K_size ); void SavingSparseKmerGraph2 ( hashtable2 * ht, char * outfile ); void LoadingSparseKmerGraph2 ( hashtable2 * ht, char * outfile ); #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/knetfile.h0000644000000000000000000000314212166703654021717 0ustar rootroot#ifndef KNETFILE_H #define KNETFILE_H #include #include #ifndef _WIN32 #define netread(fd, ptr, len) read(fd, ptr, len) #define netwrite(fd, ptr, len) write(fd, ptr, len) #define netclose(fd) close(fd) #else #include #define netread(fd, ptr, len) recv(fd, ptr, len, 0) #define netwrite(fd, ptr, len) send(fd, ptr, len, 0) #define netclose(fd) closesocket(fd) #endif // FIXME: currently I/O is unbuffered #define KNF_TYPE_LOCAL 1 #define KNF_TYPE_FTP 2 #define KNF_TYPE_HTTP 3 typedef struct knetFile_s { int type, fd; int64_t offset; char * host, *port; // the following are for FTP only int ctrl_fd, pasv_ip[4], pasv_port, max_response, no_reconnect, is_ready; char * response, *retr, *size_cmd; int64_t seek_offset; // for lazy seek int64_t file_size; // the following are for HTTP only char * path, *http_host; } knetFile; #define knet_tell(fp) ((fp)->offset) #define knet_fileno(fp) ((fp)->fd) #ifdef __cplusplus extern "C" { #endif #ifdef _WIN32 int knet_win32_init(); void knet_win32_destroy(); #endif knetFile * knet_open ( const char * fn, const char * mode ); /* This only works with local files. */ knetFile * knet_dopen ( int fd, const char * mode ); /* If ->is_ready==0, this routine updates ->fd; otherwise, it simply reads from ->fd. */ off_t knet_read ( knetFile * fp, void * buf, off_t len ); /* This routine only sets ->offset and ->is_ready=0. It does not communicate with the FTP server. */ off_t knet_seek ( knetFile * fp, int64_t off, int whence ); int knet_close ( knetFile * fp ); #ifdef __cplusplus } #endif #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/razf.h0000644000000000000000000001006512166703654021062 0ustar rootroot/*- * RAZF : Random Access compressed(Z) File * Version: 1.0 * Release Date: 2008-10-27 * * Copyright 2008, Jue Ruan , Heng Li * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND 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 THE AUTHOR OR 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. */ #ifndef __RAZF_RJ_H #define __RAZF_RJ_H #include #include #include "zlib.h" #ifdef _USE_KNETFILE #include "knetfile.h" #endif #if ZLIB_VERNUM < 0x1221 #define _RZ_READONLY struct _gz_header_s; typedef struct _gz_header_s _gz_header; #define gz_header _gz_header #endif #define WINDOW_BITS 15 #ifndef RZ_BLOCK_SIZE #define RZ_BLOCK_SIZE (1<mode from HEAD to TYPE after call inflateReset */ int buf_off, buf_len; int z_err, z_eof; int seekable; /* Indice where the source is seekable */ int load_index; /* set has_index to 0 in mode 'w', then index will be discarded */ } RAZF; #ifdef __cplusplus extern "C" { #endif RAZF * razf_dopen ( int data_fd, const char * mode ); RAZF * razf_open ( const char * fn, const char * mode ); int razf_write ( RAZF * rz, const void * data, int size ); int razf_read ( RAZF * rz, void * data, int size ); int64_t razf_seek ( RAZF * rz, int64_t pos, int where ); void razf_close ( RAZF * rz ); #define razf_tell(rz) ((rz)->out) RAZF * razf_open2 ( const char * filename, const char * mode ); RAZF * razf_dopen2 ( int fd, const char * mode ); uint64_t razf_tell2 ( RAZF * rz ); int64_t razf_seek2 ( RAZF * rz, uint64_t voffset, int where ); #ifdef __cplusplus } #endif #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/build_edge.h0000644000000000000000000000725012166703654022205 0ustar rootroot/* * inc/sparse_kmer.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef _BUILD_EDGE_H #define _BUILD_EDGE_H void removeMinorTips ( struct hashtable2 * ht, int K_size, int cut_len_tip, int & tip_c ); void kmer2edges ( hashtable2 * ht, int K_size, char * outfile ); void convert ( char * sparse_edge_file, int K_size, char * output_prefix ); void RemovingWeakNodesAndEdges2 ( hashtable2 * ht, int K_size, int NodeCovTh, int EdgeCovTh, size_t * bucket_cnt, size_t * edge_cnt ); struct stacked_node2 { struct bucket2 * node; bool is_left; // change it to a byte later struct edge_node * edge; struct stacked_node2 * next; }; typedef struct preedge2 { struct stacked_node2 * from_node; struct stacked_node2 * to_node; string * full_edge; unsigned short cvg; unsigned short bal_edge: 2; } preEDGE2; // below is static methods //remove minor tips ... //void removeMinorTips(struct hashtable2 *ht,int K_size,int cut_len_tip,int &tip_c); static void mask1in1out ( hashtable2 * ht ); static int clipTipFromNode ( hashtable2 * ht, int K_size, bucket2 * node, int cut_len_tip ); static int count_left_edge_num ( bucket2 * bkt ); static int count_right_edge_num ( bucket2 * bkt ); static void dislink ( hashtable2 * ht, int K_size, stacked_node2 * from_node ); static bucket2 * lastKmer ( hashtable2 * ht, int K_size, bucket2 * node, edge_node * edge, int is_left, int & smaller ); //static bucket2* search_kmer(hashtable2 *ht,uint64_t* t_kmer, int Kmer_arr_sz); old static bucket2 * search_kmer ( hashtable2 * ht, kmer_t2 * t_kmer ); static void removeEdge ( bucket2 * node, edge_node * edge, int is_left ); static void stat_edge_num ( hashtable2 * ht ); static void stat_edge_cvg_len ( hashtable2 * ht ); static bool isSmaller2 ( uint64_t * kmer, int K_size ); //kmer2edges .... //void kmer2edges(hashtable2* ht,int K_size,char *outfile); static void make_edge ( hashtable2 * ht, int K_size, FILE * fp ); static int startEdgeFromNode ( hashtable2 * ht, int K_size, bucket2 * node, FILE * fp ); static void stringBeads ( hashtable2 * ht, int K_size, list &stack, stacked_node2 * from_node, edge_node * from_edge, int * node_c ); static void process_1stack ( hashtable2 * ht, int K_size, list &stack, FILE * fp, vector &loops_edges ); //static void get_kmer(const char * seq,int len, int K_size,int pos,uint64_t *kmer,int arr_sz ); static void output_1edge ( preEDGE2 * long_edge, int K_size, FILE * fp ); static string stack2string ( hashtable2 * ht, int K_size, list & stack ); static bool check_palindrome ( string & str ); static string revCompSeq ( const string & str ); //convert the edge fomat ... //void convert(char * sparse_edge_file,int K_size, char * output_prefix); static void convert_kmer ( uint64_t * sparse_kmer, int K_size, int arr_sz ); static uint64_t * fastReverseComp ( uint64_t * seq_arr, int seq_size, int arr_sz ); #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/kstring.h0000644000000000000000000000321012166703654021573 0ustar rootroot#ifndef KSTRING_H #define KSTRING_H #include #include #include #ifndef kroundup32 #define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) #endif #ifndef KSTRING_T #define KSTRING_T kstring_t typedef struct __kstring_t { size_t l, m; char * s; } kstring_t; #endif int ksprintf ( kstring_t * s, const char * fmt, ... ); int ksplit_core ( char * s, int delimiter, int * _max, int ** _offsets ); // calculate the auxiliary array, allocated by calloc() int * ksBM_prep ( const uint8_t * pat, int m ); /* Search pat in str and returned the list of matches. The size of the * list is returned as n_matches. _prep is the array returned by * ksBM_prep(). If it is a NULL pointer, ksBM_prep() will be called. */ int * ksBM_search ( const uint8_t * str, int n, const uint8_t * pat, int m, int * _prep, int * n_matches ); static inline int kputsn ( const char * p, int l, kstring_t * s ) { if ( s->l + l + 1 >= s->m ) { s->m = s->l + l + 2; kroundup32 ( s->m ); s->s = ( char * ) realloc ( s->s, s->m ); } strncpy ( s->s + s->l, p, l ); s->l += l; s->s[s->l] = 0; return l; } static inline int kputs ( const char * p, kstring_t * s ) { return kputsn ( p, strlen ( p ), s ); } static inline int kputc ( int c, kstring_t * s ) { if ( s->l + 1 >= s->m ) { s->m = s->l + 2; kroundup32 ( s->m ); s->s = ( char * ) realloc ( s->s, s->m ); } s->s[s->l++] = c; s->s[s->l] = 0; return c; } static inline int * ksplit ( kstring_t * s, int delimiter, int * n ) { int max = 0, *offsets = 0; *n = ksplit_core ( s->s, delimiter, &max, &offsets ); return offsets; } #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/convert_soapdenovo.h0000644000000000000000000000202012166703654024025 0ustar rootroot/* * inc/convert_soapdenovo.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef _CONVERT_SOAPDENOVO_H #define _CONVERT_SOAPDENOVO_H void convert ( char * sparse_edge_file, int K_size, char * output_prefix ); void convert_kmer ( kmer_t2 * sparse_kmer, int K_size ); #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/xcurses.h0000644000000000000000000014465012166703654021624 0ustar rootroot/* Public Domain Curses */ /* $Id: curses.h,v 1.295 2008/07/15 17:13:25 wmcbrine Exp $ */ /*----------------------------------------------------------------------* * PDCurses * *----------------------------------------------------------------------*/ #ifndef __PDCURSES__ #define __PDCURSES__ 1 /*man-start************************************************************** PDCurses definitions list: (Only define those needed) XCURSES True if compiling for X11. PDC_RGB True if you want to use RGB color definitions (Red = 1, Green = 2, Blue = 4) instead of BGR. PDC_WIDE True if building wide-character support. PDC_DLL_BUILD True if building a Win32 DLL. NCURSES_MOUSE_VERSION Use the ncurses mouse API instead of PDCurses' traditional mouse API. PDCurses portable platform definitions list: PDC_BUILD Defines API build version. PDCURSES Enables access to PDCurses-only routines. XOPEN Always true. SYSVcurses True if you are compiling for SYSV portability. BSDcurses True if you are compiling for BSD portability. **man-end****************************************************************/ #define PDC_BUILD 3401 #define PDCURSES 1 /* PDCurses-only routines */ #define XOPEN 1 /* X/Open Curses routines */ #define SYSVcurses 1 /* System V Curses routines */ #define BSDcurses 1 /* BSD Curses routines */ #define CHTYPE_LONG 1 /* size of chtype; long */ /*----------------------------------------------------------------------*/ #include #include #include /* Required by X/Open usage below */ #ifdef PDC_WIDE # include #endif #if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS) extern "C" { # define bool _bool #endif /*---------------------------------------------------------------------- * * PDCurses Manifest Constants * */ #ifndef FALSE # define FALSE 0 #endif #ifndef TRUE # define TRUE 1 #endif #ifndef NULL # define NULL (void *)0 #endif #ifndef ERR # define ERR (-1) #endif #ifndef OK # define OK 0 #endif /*---------------------------------------------------------------------- * * PDCurses Type Declarations * */ typedef unsigned char bool; /* PDCurses Boolean type */ #ifdef CHTYPE_LONG # if _LP64 typedef unsigned int chtype; # else typedef unsigned long chtype; /* 16-bit attr + 16-bit char */ # endif #else typedef unsigned short chtype; /* 8-bit attr + 8-bit char */ #endif #ifdef PDC_WIDE typedef chtype cchar_t; #endif typedef chtype attr_t; /*---------------------------------------------------------------------- * * PDCurses Mouse Interface -- SYSVR4, with extensions * */ typedef struct { int x; /* absolute column, 0 based, measured in characters */ int y; /* absolute row, 0 based, measured in characters */ short button[3]; /* state of each button */ int changes; /* flags indicating what has changed with the mouse */ } MOUSE_STATUS; #define BUTTON_RELEASED 0x0000 #define BUTTON_PRESSED 0x0001 #define BUTTON_CLICKED 0x0002 #define BUTTON_DOUBLE_CLICKED 0x0003 #define BUTTON_TRIPLE_CLICKED 0x0004 #define BUTTON_MOVED 0x0005 /* PDCurses */ #define WHEEL_SCROLLED 0x0006 /* PDCurses */ #define BUTTON_ACTION_MASK 0x0007 /* PDCurses */ #define PDC_BUTTON_SHIFT 0x0008 /* PDCurses */ #define PDC_BUTTON_CONTROL 0x0010 /* PDCurses */ #define PDC_BUTTON_ALT 0x0020 /* PDCurses */ #define BUTTON_MODIFIER_MASK 0x0038 /* PDCurses */ #define MOUSE_X_POS (Mouse_status.x) #define MOUSE_Y_POS (Mouse_status.y) /* * Bits associated with the .changes field: * 3 2 1 0 * 210987654321098765432109876543210 * 1 <- button 1 has changed * 10 <- button 2 has changed * 100 <- button 3 has changed * 1000 <- mouse has moved * 10000 <- mouse position report * 100000 <- mouse wheel up * 1000000 <- mouse wheel down */ #define PDC_MOUSE_MOVED 0x0008 #define PDC_MOUSE_POSITION 0x0010 #define PDC_MOUSE_WHEEL_UP 0x0020 #define PDC_MOUSE_WHEEL_DOWN 0x0040 #define A_BUTTON_CHANGED (Mouse_status.changes & 7) #define MOUSE_MOVED (Mouse_status.changes & PDC_MOUSE_MOVED) #define MOUSE_POS_REPORT (Mouse_status.changes & PDC_MOUSE_POSITION) #define BUTTON_CHANGED(x) (Mouse_status.changes & (1 << ((x) - 1))) #define BUTTON_STATUS(x) (Mouse_status.button[(x) - 1]) #define MOUSE_WHEEL_UP (Mouse_status.changes & PDC_MOUSE_WHEEL_UP) #define MOUSE_WHEEL_DOWN (Mouse_status.changes & PDC_MOUSE_WHEEL_DOWN) /* mouse bit-masks */ #define BUTTON1_RELEASED 0x00000001L #define BUTTON1_PRESSED 0x00000002L #define BUTTON1_CLICKED 0x00000004L #define BUTTON1_DOUBLE_CLICKED 0x00000008L #define BUTTON1_TRIPLE_CLICKED 0x00000010L #define BUTTON1_MOVED 0x00000010L /* PDCurses */ #define BUTTON2_RELEASED 0x00000020L #define BUTTON2_PRESSED 0x00000040L #define BUTTON2_CLICKED 0x00000080L #define BUTTON2_DOUBLE_CLICKED 0x00000100L #define BUTTON2_TRIPLE_CLICKED 0x00000200L #define BUTTON2_MOVED 0x00000200L /* PDCurses */ #define BUTTON3_RELEASED 0x00000400L #define BUTTON3_PRESSED 0x00000800L #define BUTTON3_CLICKED 0x00001000L #define BUTTON3_DOUBLE_CLICKED 0x00002000L #define BUTTON3_TRIPLE_CLICKED 0x00004000L #define BUTTON3_MOVED 0x00004000L /* PDCurses */ /* For the ncurses-compatible functions only, BUTTON4_PRESSED and BUTTON5_PRESSED are returned for mouse scroll wheel up and down; otherwise PDCurses doesn't support buttons 4 and 5 */ #define BUTTON4_RELEASED 0x00008000L #define BUTTON4_PRESSED 0x00010000L #define BUTTON4_CLICKED 0x00020000L #define BUTTON4_DOUBLE_CLICKED 0x00040000L #define BUTTON4_TRIPLE_CLICKED 0x00080000L #define BUTTON5_RELEASED 0x00100000L #define BUTTON5_PRESSED 0x00200000L #define BUTTON5_CLICKED 0x00400000L #define BUTTON5_DOUBLE_CLICKED 0x00800000L #define BUTTON5_TRIPLE_CLICKED 0x01000000L #define MOUSE_WHEEL_SCROLL 0x02000000L /* PDCurses */ #define BUTTON_MODIFIER_SHIFT 0x04000000L /* PDCurses */ #define BUTTON_MODIFIER_CONTROL 0x08000000L /* PDCurses */ #define BUTTON_MODIFIER_ALT 0x10000000L /* PDCurses */ #define ALL_MOUSE_EVENTS 0x1fffffffL #define REPORT_MOUSE_POSITION 0x20000000L /* ncurses mouse interface */ typedef unsigned long mmask_t; typedef struct { short id; /* unused, always 0 */ int x, y, z; /* x, y same as MOUSE_STATUS; z unused */ mmask_t bstate; /* equivalent to changes + button[], but in the same format as used for mousemask() */ } MEVENT; #ifdef NCURSES_MOUSE_VERSION # define BUTTON_SHIFT BUTTON_MODIFIER_SHIFT # define BUTTON_CONTROL BUTTON_MODIFIER_CONTROL # define BUTTON_CTRL BUTTON_MODIFIER_CONTROL # define BUTTON_ALT BUTTON_MODIFIER_ALT #else # define BUTTON_SHIFT PDC_BUTTON_SHIFT # define BUTTON_CONTROL PDC_BUTTON_CONTROL # define BUTTON_ALT PDC_BUTTON_ALT #endif /*---------------------------------------------------------------------- * * PDCurses Structure Definitions * */ typedef struct _win /* definition of a window */ { int _cury; /* current pseudo-cursor */ int _curx; int _maxy; /* max window coordinates */ int _maxx; int _begy; /* origin on screen */ int _begx; int _flags; /* window properties */ chtype _attrs; /* standard attributes and colors */ chtype _bkgd; /* background, normally blank */ bool _clear; /* causes clear at next refresh */ bool _leaveit; /* leaves cursor where it is */ bool _scroll; /* allows window scrolling */ bool _nodelay; /* input character wait flag */ bool _immed; /* immediate update flag */ bool _sync; /* synchronise window ancestors */ bool _use_keypad; /* flags keypad key mode active */ chtype ** _y; /* pointer to line pointer array */ int * _firstch; /* first changed character in line */ int * _lastch; /* last changed character in line */ int _tmarg; /* top of scrolling region */ int _bmarg; /* bottom of scrolling region */ int _delayms; /* milliseconds of delay for getch() */ int _parx, _pary; /* coords relative to parent (0,0) */ struct _win * _parent; /* subwin's pointer to parent win */ } WINDOW; /* Avoid using the SCREEN struct directly -- use the corresponding functions if possible. This struct may eventually be made private. */ typedef struct { bool alive; /* if initscr() called, and not endwin() */ bool autocr; /* if cr -> lf */ bool cbreak; /* if terminal unbuffered */ bool echo; /* if terminal echo */ bool raw_inp; /* raw input mode (v. cooked input) */ bool raw_out; /* raw output mode (7 v. 8 bits) */ bool audible; /* FALSE if the bell is visual */ bool mono; /* TRUE if current screen is mono */ bool resized; /* TRUE if TERM has been resized */ bool orig_attr; /* TRUE if we have the original colors */ short orig_fore; /* original screen foreground color */ short orig_back; /* original screen foreground color */ int cursrow; /* position of physical cursor */ int curscol; /* position of physical cursor */ int visibility; /* visibility of cursor */ int orig_cursor; /* original cursor size */ int lines; /* new value for LINES */ int cols; /* new value for COLS */ unsigned long _trap_mbe; /* trap these mouse button events */ unsigned long _map_mbe_to_key; /* map mouse buttons to slk */ int mouse_wait; /* time to wait (in ms) for a button release after a press, in order to count it as a click */ int slklines; /* lines in use by slk_init() */ WINDOW * slk_winptr; /* window for slk */ int linesrippedoff; /* lines ripped off via ripoffline() */ int linesrippedoffontop; /* lines ripped off on top via ripoffline() */ int delaytenths; /* 1/10ths second to wait block getch() for */ bool _preserve; /* TRUE if screen background to be preserved */ int _restore; /* specifies if screen background to be restored, and how */ bool save_key_modifiers; /* TRUE if each key modifiers saved with each key press */ bool return_key_modifiers; /* TRUE if modifier keys are returned as "real" keys */ bool key_code; /* TRUE if last key is a special key; used internally by get_wch() */ #ifdef XCURSES int XcurscrSize; /* size of Xcurscr shared memory block */ bool sb_on; int sb_viewport_y; int sb_viewport_x; int sb_total_y; int sb_total_x; int sb_cur_y; int sb_cur_x; #endif short line_color; /* color of line attributes - default -1 */ } SCREEN; /*---------------------------------------------------------------------- * * PDCurses External Variables * */ #ifdef PDC_DLL_BUILD # ifdef CURSES_LIBRARY # define PDCEX __declspec(dllexport) extern # else # define PDCEX __declspec(dllimport) # endif #else # define PDCEX extern #endif PDCEX int LINES; /* terminal height */ PDCEX int COLS; /* terminal width */ PDCEX WINDOW * stdscr; /* the default screen window */ PDCEX WINDOW * curscr; /* the current screen image */ PDCEX SCREEN * SP; /* curses variables */ PDCEX MOUSE_STATUS Mouse_status; PDCEX int COLORS; PDCEX int COLOR_PAIRS; PDCEX int TABSIZE; PDCEX chtype acs_map[]; /* alternate character set map */ PDCEX char ttytype[]; /* terminal name/description */ /*man-start************************************************************** PDCurses Text Attributes ======================== Originally, PDCurses used a short (16 bits) for its chtype. To include color, a number of things had to be sacrificed from the strict Unix and System V support. The main problem was fitting all character attributes and color into an unsigned char (all 8 bits!). Today, PDCurses by default uses a long (32 bits) for its chtype, as in System V. The short chtype is still available, by undefining CHTYPE_LONG and rebuilding the library. The following is the structure of a win->_attrs chtype: short form: ------------------------------------------------- |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| ------------------------------------------------- color number | attrs | character eg 'a' The available non-color attributes are bold, reverse and blink. Others have no effect. The high order char is an index into an array of physical colors (defined in color.c) -- 32 foreground/background color pairs (5 bits) plus 3 bits for other attributes. long form: ---------------------------------------------------------------------------- |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|..| 3| 2| 1| 0| ---------------------------------------------------------------------------- color number | modifiers | character eg 'a' The available non-color attributes are bold, underline, invisible, right-line, left-line, protect, reverse and blink. 256 color pairs (8 bits), 8 bits for other attributes, and 16 bits for character data. **man-end****************************************************************/ /*** Video attribute macros ***/ #define A_NORMAL (chtype)0 #ifdef CHTYPE_LONG # define A_ALTCHARSET (chtype)0x00010000 # define A_RIGHTLINE (chtype)0x00020000 # define A_LEFTLINE (chtype)0x00040000 # define A_INVIS (chtype)0x00080000 # define A_UNDERLINE (chtype)0x00100000 # define A_REVERSE (chtype)0x00200000 # define A_BLINK (chtype)0x00400000 # define A_BOLD (chtype)0x00800000 # define A_ATTRIBUTES (chtype)0xffff0000 # define A_CHARTEXT (chtype)0x0000ffff # define A_COLOR (chtype)0xff000000 # define A_ITALIC A_INVIS # define A_PROTECT (A_UNDERLINE | A_LEFTLINE | A_RIGHTLINE) # define PDC_ATTR_SHIFT 19 # define PDC_COLOR_SHIFT 24 #else # define A_BOLD (chtype)0x0100 /* X/Open */ # define A_REVERSE (chtype)0x0200 /* X/Open */ # define A_BLINK (chtype)0x0400 /* X/Open */ # define A_ATTRIBUTES (chtype)0xff00 /* X/Open */ # define A_CHARTEXT (chtype)0x00ff /* X/Open */ # define A_COLOR (chtype)0xf800 /* System V */ # define A_ALTCHARSET A_NORMAL /* X/Open */ # define A_PROTECT A_NORMAL /* X/Open */ # define A_UNDERLINE A_NORMAL /* X/Open */ # define A_LEFTLINE A_NORMAL # define A_RIGHTLINE A_NORMAL # define A_ITALIC A_NORMAL # define A_INVIS A_NORMAL # define PDC_ATTR_SHIFT 8 # define PDC_COLOR_SHIFT 11 #endif #define A_STANDOUT (A_REVERSE | A_BOLD) /* X/Open */ #define A_DIM A_NORMAL #define CHR_MSK A_CHARTEXT /* Obsolete */ #define ATR_MSK A_ATTRIBUTES /* Obsolete */ #define ATR_NRM A_NORMAL /* Obsolete */ /* For use with attr_t -- X/Open says, "these shall be distinct", so this is a non-conforming implementation. */ #define WA_ALTCHARSET A_ALTCHARSET #define WA_BLINK A_BLINK #define WA_BOLD A_BOLD #define WA_DIM A_DIM #define WA_INVIS A_INVIS #define WA_LEFT A_LEFTLINE #define WA_PROTECT A_PROTECT #define WA_REVERSE A_REVERSE #define WA_RIGHT A_RIGHTLINE #define WA_STANDOUT A_STANDOUT #define WA_UNDERLINE A_UNDERLINE #define WA_HORIZONTAL A_NORMAL #define WA_LOW A_NORMAL #define WA_TOP A_NORMAL #define WA_VERTICAL A_NORMAL /*** Alternate character set macros ***/ /* 'w' = 32-bit chtype; acs_map[] index | A_ALTCHARSET 'n' = 16-bit chtype; it gets the fallback set because no bit is available for A_ALTCHARSET */ #ifdef CHTYPE_LONG # define ACS_PICK(w, n) ((chtype)w | A_ALTCHARSET) #else # define ACS_PICK(w, n) ((chtype)n) #endif /* VT100-compatible symbols -- box chars */ #define ACS_ULCORNER ACS_PICK('l', '+') #define ACS_LLCORNER ACS_PICK('m', '+') #define ACS_URCORNER ACS_PICK('k', '+') #define ACS_LRCORNER ACS_PICK('j', '+') #define ACS_RTEE ACS_PICK('u', '+') #define ACS_LTEE ACS_PICK('t', '+') #define ACS_BTEE ACS_PICK('v', '+') #define ACS_TTEE ACS_PICK('w', '+') #define ACS_HLINE ACS_PICK('q', '-') #define ACS_VLINE ACS_PICK('x', '|') #define ACS_PLUS ACS_PICK('n', '+') /* VT100-compatible symbols -- other */ #define ACS_S1 ACS_PICK('o', '-') #define ACS_S9 ACS_PICK('s', '_') #define ACS_DIAMOND ACS_PICK('`', '+') #define ACS_CKBOARD ACS_PICK('a', ':') #define ACS_DEGREE ACS_PICK('f', '\'') #define ACS_PLMINUS ACS_PICK('g', '#') #define ACS_BULLET ACS_PICK('~', 'o') /* Teletype 5410v1 symbols -- these are defined in SysV curses, but are not well-supported by most terminals. Stick to VT100 characters for optimum portability. */ #define ACS_LARROW ACS_PICK(',', '<') #define ACS_RARROW ACS_PICK('+', '>') #define ACS_DARROW ACS_PICK('.', 'v') #define ACS_UARROW ACS_PICK('-', '^') #define ACS_BOARD ACS_PICK('h', '#') #define ACS_LANTERN ACS_PICK('i', '*') #define ACS_BLOCK ACS_PICK('0', '#') /* That goes double for these -- undocumented SysV symbols. Don't use them. */ #define ACS_S3 ACS_PICK('p', '-') #define ACS_S7 ACS_PICK('r', '-') #define ACS_LEQUAL ACS_PICK('y', '<') #define ACS_GEQUAL ACS_PICK('z', '>') #define ACS_PI ACS_PICK('{', 'n') #define ACS_NEQUAL ACS_PICK('|', '+') #define ACS_STERLING ACS_PICK('}', 'L') /* Box char aliases */ #define ACS_BSSB ACS_ULCORNER #define ACS_SSBB ACS_LLCORNER #define ACS_BBSS ACS_URCORNER #define ACS_SBBS ACS_LRCORNER #define ACS_SBSS ACS_RTEE #define ACS_SSSB ACS_LTEE #define ACS_SSBS ACS_BTEE #define ACS_BSSS ACS_TTEE #define ACS_BSBS ACS_HLINE #define ACS_SBSB ACS_VLINE #define ACS_SSSS ACS_PLUS /* cchar_t aliases */ #ifdef PDC_WIDE # define WACS_ULCORNER (&(acs_map['l'])) # define WACS_LLCORNER (&(acs_map['m'])) # define WACS_URCORNER (&(acs_map['k'])) # define WACS_LRCORNER (&(acs_map['j'])) # define WACS_RTEE (&(acs_map['u'])) # define WACS_LTEE (&(acs_map['t'])) # define WACS_BTEE (&(acs_map['v'])) # define WACS_TTEE (&(acs_map['w'])) # define WACS_HLINE (&(acs_map['q'])) # define WACS_VLINE (&(acs_map['x'])) # define WACS_PLUS (&(acs_map['n'])) # define WACS_S1 (&(acs_map['o'])) # define WACS_S9 (&(acs_map['s'])) # define WACS_DIAMOND (&(acs_map['`'])) # define WACS_CKBOARD (&(acs_map['a'])) # define WACS_DEGREE (&(acs_map['f'])) # define WACS_PLMINUS (&(acs_map['g'])) # define WACS_BULLET (&(acs_map['~'])) # define WACS_LARROW (&(acs_map[','])) # define WACS_RARROW (&(acs_map['+'])) # define WACS_DARROW (&(acs_map['.'])) # define WACS_UARROW (&(acs_map['-'])) # define WACS_BOARD (&(acs_map['h'])) # define WACS_LANTERN (&(acs_map['i'])) # define WACS_BLOCK (&(acs_map['0'])) # define WACS_S3 (&(acs_map['p'])) # define WACS_S7 (&(acs_map['r'])) # define WACS_LEQUAL (&(acs_map['y'])) # define WACS_GEQUAL (&(acs_map['z'])) # define WACS_PI (&(acs_map['{'])) # define WACS_NEQUAL (&(acs_map['|'])) # define WACS_STERLING (&(acs_map['}'])) # define WACS_BSSB WACS_ULCORNER # define WACS_SSBB WACS_LLCORNER # define WACS_BBSS WACS_URCORNER # define WACS_SBBS WACS_LRCORNER # define WACS_SBSS WACS_RTEE # define WACS_SSSB WACS_LTEE # define WACS_SSBS WACS_BTEE # define WACS_BSSS WACS_TTEE # define WACS_BSBS WACS_HLINE # define WACS_SBSB WACS_VLINE # define WACS_SSSS WACS_PLUS #endif /*** Color macros ***/ #define COLOR_BLACK 0 #ifdef PDC_RGB /* RGB */ # define COLOR_RED 1 # define COLOR_GREEN 2 # define COLOR_BLUE 4 #else /* BGR */ # define COLOR_BLUE 1 # define COLOR_GREEN 2 # define COLOR_RED 4 #endif #define COLOR_CYAN (COLOR_BLUE | COLOR_GREEN) #define COLOR_MAGENTA (COLOR_RED | COLOR_BLUE) #define COLOR_YELLOW (COLOR_RED | COLOR_GREEN) #define COLOR_WHITE 7 /*---------------------------------------------------------------------- * * Function and Keypad Key Definitions. * Many are just for compatibility. * */ #define KEY_CODE_YES 0x100 /* If get_wch() gives a key code */ #define KEY_BREAK 0x101 /* Not on PC KBD */ #define KEY_DOWN 0x102 /* Down arrow key */ #define KEY_UP 0x103 /* Up arrow key */ #define KEY_LEFT 0x104 /* Left arrow key */ #define KEY_RIGHT 0x105 /* Right arrow key */ #define KEY_HOME 0x106 /* home key */ #define KEY_BACKSPACE 0x107 /* not on pc */ #define KEY_F0 0x108 /* function keys; 64 reserved */ #define KEY_DL 0x148 /* delete line */ #define KEY_IL 0x149 /* insert line */ #define KEY_DC 0x14a /* delete character */ #define KEY_IC 0x14b /* insert char or enter ins mode */ #define KEY_EIC 0x14c /* exit insert char mode */ #define KEY_CLEAR 0x14d /* clear screen */ #define KEY_EOS 0x14e /* clear to end of screen */ #define KEY_EOL 0x14f /* clear to end of line */ #define KEY_SF 0x150 /* scroll 1 line forward */ #define KEY_SR 0x151 /* scroll 1 line back (reverse) */ #define KEY_NPAGE 0x152 /* next page */ #define KEY_PPAGE 0x153 /* previous page */ #define KEY_STAB 0x154 /* set tab */ #define KEY_CTAB 0x155 /* clear tab */ #define KEY_CATAB 0x156 /* clear all tabs */ #define KEY_ENTER 0x157 /* enter or send (unreliable) */ #define KEY_SRESET 0x158 /* soft/reset (partial/unreliable) */ #define KEY_RESET 0x159 /* reset/hard reset (unreliable) */ #define KEY_PRINT 0x15a /* print/copy */ #define KEY_LL 0x15b /* home down/bottom (lower left) */ #define KEY_ABORT 0x15c /* abort/terminate key (any) */ #define KEY_SHELP 0x15d /* short help */ #define KEY_LHELP 0x15e /* long help */ #define KEY_BTAB 0x15f /* Back tab key */ #define KEY_BEG 0x160 /* beg(inning) key */ #define KEY_CANCEL 0x161 /* cancel key */ #define KEY_CLOSE 0x162 /* close key */ #define KEY_COMMAND 0x163 /* cmd (command) key */ #define KEY_COPY 0x164 /* copy key */ #define KEY_CREATE 0x165 /* create key */ #define KEY_END 0x166 /* end key */ #define KEY_EXIT 0x167 /* exit key */ #define KEY_FIND 0x168 /* find key */ #define KEY_HELP 0x169 /* help key */ #define KEY_MARK 0x16a /* mark key */ #define KEY_MESSAGE 0x16b /* message key */ #define KEY_MOVE 0x16c /* move key */ #define KEY_NEXT 0x16d /* next object key */ #define KEY_OPEN 0x16e /* open key */ #define KEY_OPTIONS 0x16f /* options key */ #define KEY_PREVIOUS 0x170 /* previous object key */ #define KEY_REDO 0x171 /* redo key */ #define KEY_REFERENCE 0x172 /* ref(erence) key */ #define KEY_REFRESH 0x173 /* refresh key */ #define KEY_REPLACE 0x174 /* replace key */ #define KEY_RESTART 0x175 /* restart key */ #define KEY_RESUME 0x176 /* resume key */ #define KEY_SAVE 0x177 /* save key */ #define KEY_SBEG 0x178 /* shifted beginning key */ #define KEY_SCANCEL 0x179 /* shifted cancel key */ #define KEY_SCOMMAND 0x17a /* shifted command key */ #define KEY_SCOPY 0x17b /* shifted copy key */ #define KEY_SCREATE 0x17c /* shifted create key */ #define KEY_SDC 0x17d /* shifted delete char key */ #define KEY_SDL 0x17e /* shifted delete line key */ #define KEY_SELECT 0x17f /* select key */ #define KEY_SEND 0x180 /* shifted end key */ #define KEY_SEOL 0x181 /* shifted clear line key */ #define KEY_SEXIT 0x182 /* shifted exit key */ #define KEY_SFIND 0x183 /* shifted find key */ #define KEY_SHOME 0x184 /* shifted home key */ #define KEY_SIC 0x185 /* shifted input key */ #define KEY_SLEFT 0x187 /* shifted left arrow key */ #define KEY_SMESSAGE 0x188 /* shifted message key */ #define KEY_SMOVE 0x189 /* shifted move key */ #define KEY_SNEXT 0x18a /* shifted next key */ #define KEY_SOPTIONS 0x18b /* shifted options key */ #define KEY_SPREVIOUS 0x18c /* shifted prev key */ #define KEY_SPRINT 0x18d /* shifted print key */ #define KEY_SREDO 0x18e /* shifted redo key */ #define KEY_SREPLACE 0x18f /* shifted replace key */ #define KEY_SRIGHT 0x190 /* shifted right arrow */ #define KEY_SRSUME 0x191 /* shifted resume key */ #define KEY_SSAVE 0x192 /* shifted save key */ #define KEY_SSUSPEND 0x193 /* shifted suspend key */ #define KEY_SUNDO 0x194 /* shifted undo key */ #define KEY_SUSPEND 0x195 /* suspend key */ #define KEY_UNDO 0x196 /* undo key */ /* PDCurses-specific key definitions -- PC only */ #define ALT_0 0x197 #define ALT_1 0x198 #define ALT_2 0x199 #define ALT_3 0x19a #define ALT_4 0x19b #define ALT_5 0x19c #define ALT_6 0x19d #define ALT_7 0x19e #define ALT_8 0x19f #define ALT_9 0x1a0 #define ALT_A 0x1a1 #define ALT_B 0x1a2 #define ALT_C 0x1a3 #define ALT_D 0x1a4 #define ALT_E 0x1a5 #define ALT_F 0x1a6 #define ALT_G 0x1a7 #define ALT_H 0x1a8 #define ALT_I 0x1a9 #define ALT_J 0x1aa #define ALT_K 0x1ab #define ALT_L 0x1ac #define ALT_M 0x1ad #define ALT_N 0x1ae #define ALT_O 0x1af #define ALT_P 0x1b0 #define ALT_Q 0x1b1 #define ALT_R 0x1b2 #define ALT_S 0x1b3 #define ALT_T 0x1b4 #define ALT_U 0x1b5 #define ALT_V 0x1b6 #define ALT_W 0x1b7 #define ALT_X 0x1b8 #define ALT_Y 0x1b9 #define ALT_Z 0x1ba #define CTL_LEFT 0x1bb /* Control-Left-Arrow */ #define CTL_RIGHT 0x1bc #define CTL_PGUP 0x1bd #define CTL_PGDN 0x1be #define CTL_HOME 0x1bf #define CTL_END 0x1c0 #define KEY_A1 0x1c1 /* upper left on Virtual keypad */ #define KEY_A2 0x1c2 /* upper middle on Virt. keypad */ #define KEY_A3 0x1c3 /* upper right on Vir. keypad */ #define KEY_B1 0x1c4 /* middle left on Virt. keypad */ #define KEY_B2 0x1c5 /* center on Virt. keypad */ #define KEY_B3 0x1c6 /* middle right on Vir. keypad */ #define KEY_C1 0x1c7 /* lower left on Virt. keypad */ #define KEY_C2 0x1c8 /* lower middle on Virt. keypad */ #define KEY_C3 0x1c9 /* lower right on Vir. keypad */ #define PADSLASH 0x1ca /* slash on keypad */ #define PADENTER 0x1cb /* enter on keypad */ #define CTL_PADENTER 0x1cc /* ctl-enter on keypad */ #define ALT_PADENTER 0x1cd /* alt-enter on keypad */ #define PADSTOP 0x1ce /* stop on keypad */ #define PADSTAR 0x1cf /* star on keypad */ #define PADMINUS 0x1d0 /* minus on keypad */ #define PADPLUS 0x1d1 /* plus on keypad */ #define CTL_PADSTOP 0x1d2 /* ctl-stop on keypad */ #define CTL_PADCENTER 0x1d3 /* ctl-enter on keypad */ #define CTL_PADPLUS 0x1d4 /* ctl-plus on keypad */ #define CTL_PADMINUS 0x1d5 /* ctl-minus on keypad */ #define CTL_PADSLASH 0x1d6 /* ctl-slash on keypad */ #define CTL_PADSTAR 0x1d7 /* ctl-star on keypad */ #define ALT_PADPLUS 0x1d8 /* alt-plus on keypad */ #define ALT_PADMINUS 0x1d9 /* alt-minus on keypad */ #define ALT_PADSLASH 0x1da /* alt-slash on keypad */ #define ALT_PADSTAR 0x1db /* alt-star on keypad */ #define ALT_PADSTOP 0x1dc /* alt-stop on keypad */ #define CTL_INS 0x1dd /* ctl-insert */ #define ALT_DEL 0x1de /* alt-delete */ #define ALT_INS 0x1df /* alt-insert */ #define CTL_UP 0x1e0 /* ctl-up arrow */ #define CTL_DOWN 0x1e1 /* ctl-down arrow */ #define CTL_TAB 0x1e2 /* ctl-tab */ #define ALT_TAB 0x1e3 #define ALT_MINUS 0x1e4 #define ALT_EQUAL 0x1e5 #define ALT_HOME 0x1e6 #define ALT_PGUP 0x1e7 #define ALT_PGDN 0x1e8 #define ALT_END 0x1e9 #define ALT_UP 0x1ea /* alt-up arrow */ #define ALT_DOWN 0x1eb /* alt-down arrow */ #define ALT_RIGHT 0x1ec /* alt-right arrow */ #define ALT_LEFT 0x1ed /* alt-left arrow */ #define ALT_ENTER 0x1ee /* alt-enter */ #define ALT_ESC 0x1ef /* alt-escape */ #define ALT_BQUOTE 0x1f0 /* alt-back quote */ #define ALT_LBRACKET 0x1f1 /* alt-left bracket */ #define ALT_RBRACKET 0x1f2 /* alt-right bracket */ #define ALT_SEMICOLON 0x1f3 /* alt-semi-colon */ #define ALT_FQUOTE 0x1f4 /* alt-forward quote */ #define ALT_COMMA 0x1f5 /* alt-comma */ #define ALT_STOP 0x1f6 /* alt-stop */ #define ALT_FSLASH 0x1f7 /* alt-forward slash */ #define ALT_BKSP 0x1f8 /* alt-backspace */ #define CTL_BKSP 0x1f9 /* ctl-backspace */ #define PAD0 0x1fa /* keypad 0 */ #define CTL_PAD0 0x1fb /* ctl-keypad 0 */ #define CTL_PAD1 0x1fc #define CTL_PAD2 0x1fd #define CTL_PAD3 0x1fe #define CTL_PAD4 0x1ff #define CTL_PAD5 0x200 #define CTL_PAD6 0x201 #define CTL_PAD7 0x202 #define CTL_PAD8 0x203 #define CTL_PAD9 0x204 #define ALT_PAD0 0x205 /* alt-keypad 0 */ #define ALT_PAD1 0x206 #define ALT_PAD2 0x207 #define ALT_PAD3 0x208 #define ALT_PAD4 0x209 #define ALT_PAD5 0x20a #define ALT_PAD6 0x20b #define ALT_PAD7 0x20c #define ALT_PAD8 0x20d #define ALT_PAD9 0x20e #define CTL_DEL 0x20f /* clt-delete */ #define ALT_BSLASH 0x210 /* alt-back slash */ #define CTL_ENTER 0x211 /* ctl-enter */ #define SHF_PADENTER 0x212 /* shift-enter on keypad */ #define SHF_PADSLASH 0x213 /* shift-slash on keypad */ #define SHF_PADSTAR 0x214 /* shift-star on keypad */ #define SHF_PADPLUS 0x215 /* shift-plus on keypad */ #define SHF_PADMINUS 0x216 /* shift-minus on keypad */ #define SHF_UP 0x217 /* shift-up on keypad */ #define SHF_DOWN 0x218 /* shift-down on keypad */ #define SHF_IC 0x219 /* shift-insert on keypad */ #define SHF_DC 0x21a /* shift-delete on keypad */ #define KEY_MOUSE 0x21b /* "mouse" key */ #define KEY_SHIFT_L 0x21c /* Left-shift */ #define KEY_SHIFT_R 0x21d /* Right-shift */ #define KEY_CONTROL_L 0x21e /* Left-control */ #define KEY_CONTROL_R 0x21f /* Right-control */ #define KEY_ALT_L 0x220 /* Left-alt */ #define KEY_ALT_R 0x221 /* Right-alt */ #define KEY_RESIZE 0x222 /* Window resize */ #define KEY_SUP 0x223 /* Shifted up arrow */ #define KEY_SDOWN 0x224 /* Shifted down arrow */ #define KEY_MIN KEY_BREAK /* Minimum curses key value */ #define KEY_MAX KEY_SDOWN /* Maximum curses key */ #define KEY_F(n) (KEY_F0 + (n)) /*---------------------------------------------------------------------- * * PDCurses Function Declarations * */ /* Standard */ int addch ( const chtype ); int addchnstr ( const chtype *, int ); int addchstr ( const chtype * ); int addnstr ( const char *, int ); int addstr ( const char * ); int attroff ( chtype ); int attron ( chtype ); int attrset ( chtype ); int attr_get ( attr_t *, short *, void * ); int attr_off ( attr_t, void * ); int attr_on ( attr_t, void * ); int attr_set ( attr_t, short, void * ); int baudrate ( void ); int beep ( void ); int bkgd ( chtype ); void bkgdset ( chtype ); int border ( chtype, chtype, chtype, chtype, chtype, chtype, chtype, chtype ); int box ( WINDOW *, chtype, chtype ); bool can_change_color ( void ); int cbreak ( void ); int chgat ( int, attr_t, short, const void * ); int clearok ( WINDOW *, bool ); int clear ( void ); int clrtobot ( void ); int clrtoeol ( void ); int color_content ( short, short *, short *, short * ); int color_set ( short, void * ); int copywin ( const WINDOW *, WINDOW *, int, int, int, int, int, int, int ); int curs_set ( int ); int def_prog_mode ( void ); int def_shell_mode ( void ); int delay_output ( int ); int delch ( void ); int deleteln ( void ); void delscreen ( SCREEN * ); int delwin ( WINDOW * ); WINDOW * derwin ( WINDOW *, int, int, int, int ); int doupdate ( void ); WINDOW * dupwin ( WINDOW * ); int echochar ( const chtype ); int echo ( void ); int endwin ( void ); char erasechar ( void ); int erase ( void ); void filter ( void ); int flash ( void ); int flushinp ( void ); chtype getbkgd ( WINDOW * ); int getnstr ( char *, int ); int getstr ( char * ); WINDOW * getwin ( FILE * ); int halfdelay ( int ); bool has_colors ( void ); bool has_ic ( void ); bool has_il ( void ); int hline ( chtype, int ); void idcok ( WINDOW *, bool ); int idlok ( WINDOW *, bool ); void immedok ( WINDOW *, bool ); int inchnstr ( chtype *, int ); int inchstr ( chtype * ); chtype inch ( void ); int init_color ( short, short, short, short ); int init_pair ( short, short, short ); WINDOW * initscr ( void ); int innstr ( char *, int ); int insch ( chtype ); int insdelln ( int ); int insertln ( void ); int insnstr ( const char *, int ); int insstr ( const char * ); int instr ( char * ); int intrflush ( WINDOW *, bool ); bool isendwin ( void ); bool is_linetouched ( WINDOW *, int ); bool is_wintouched ( WINDOW * ); char * keyname ( int ); int keypad ( WINDOW *, bool ); char killchar ( void ); int leaveok ( WINDOW *, bool ); char * longname ( void ); int meta ( WINDOW *, bool ); int move ( int, int ); int mvaddch ( int, int, const chtype ); int mvaddchnstr ( int, int, const chtype *, int ); int mvaddchstr ( int, int, const chtype * ); int mvaddnstr ( int, int, const char *, int ); int mvaddstr ( int, int, const char * ); int mvchgat ( int, int, int, attr_t, short, const void * ); int mvcur ( int, int, int, int ); int mvdelch ( int, int ); int mvderwin ( WINDOW *, int, int ); int mvgetch ( int, int ); int mvgetnstr ( int, int, char *, int ); int mvgetstr ( int, int, char * ); int mvhline ( int, int, chtype, int ); chtype mvinch ( int, int ); int mvinchnstr ( int, int, chtype *, int ); int mvinchstr ( int, int, chtype * ); int mvinnstr ( int, int, char *, int ); int mvinsch ( int, int, chtype ); int mvinsnstr ( int, int, const char *, int ); int mvinsstr ( int, int, const char * ); int mvinstr ( int, int, char * ); int mvprintw ( int, int, const char *, ... ); int mvscanw ( int, int, const char *, ... ); int mvvline ( int, int, chtype, int ); int mvwaddchnstr ( WINDOW *, int, int, const chtype *, int ); int mvwaddchstr ( WINDOW *, int, int, const chtype * ); int mvwaddch ( WINDOW *, int, int, const chtype ); int mvwaddnstr ( WINDOW *, int, int, const char *, int ); int mvwaddstr ( WINDOW *, int, int, const char * ); int mvwchgat ( WINDOW *, int, int, int, attr_t, short, const void * ); int mvwdelch ( WINDOW *, int, int ); int mvwgetch ( WINDOW *, int, int ); int mvwgetnstr ( WINDOW *, int, int, char *, int ); int mvwgetstr ( WINDOW *, int, int, char * ); int mvwhline ( WINDOW *, int, int, chtype, int ); int mvwinchnstr ( WINDOW *, int, int, chtype *, int ); int mvwinchstr ( WINDOW *, int, int, chtype * ); chtype mvwinch ( WINDOW *, int, int ); int mvwinnstr ( WINDOW *, int, int, char *, int ); int mvwinsch ( WINDOW *, int, int, chtype ); int mvwinsnstr ( WINDOW *, int, int, const char *, int ); int mvwinsstr ( WINDOW *, int, int, const char * ); int mvwinstr ( WINDOW *, int, int, char * ); int mvwin ( WINDOW *, int, int ); int mvwprintw ( WINDOW *, int, int, const char *, ... ); int mvwscanw ( WINDOW *, int, int, const char *, ... ); int mvwvline ( WINDOW *, int, int, chtype, int ); int napms ( int ); WINDOW * newpad ( int, int ); SCREEN * newterm ( const char *, FILE *, FILE * ); WINDOW * newwin ( int, int, int, int ); int nl ( void ); int nocbreak ( void ); int nodelay ( WINDOW *, bool ); int noecho ( void ); int nonl ( void ); void noqiflush ( void ); int noraw ( void ); int notimeout ( WINDOW *, bool ); int overlay ( const WINDOW *, WINDOW * ); int overwrite ( const WINDOW *, WINDOW * ); int pair_content ( short, short *, short * ); int pechochar ( WINDOW *, chtype ); int pnoutrefresh ( WINDOW *, int, int, int, int, int, int ); int prefresh ( WINDOW *, int, int, int, int, int, int ); int printw ( const char *, ... ); int putwin ( WINDOW *, FILE * ); void qiflush ( void ); int raw ( void ); int redrawwin ( WINDOW * ); int refresh ( void ); int reset_prog_mode ( void ); int reset_shell_mode ( void ); int resetty ( void ); int ripoffline ( int, int ( * ) ( WINDOW *, int ) ); int savetty ( void ); int scanw ( const char *, ... ); int scr_dump ( const char * ); int scr_init ( const char * ); int scr_restore ( const char * ); int scr_set ( const char * ); int scrl ( int ); int scroll ( WINDOW * ); int scrollok ( WINDOW *, bool ); SCREEN * set_term ( SCREEN * ); int setscrreg ( int, int ); int slk_attroff ( const chtype ); int slk_attr_off ( const attr_t, void * ); int slk_attron ( const chtype ); int slk_attr_on ( const attr_t, void * ); int slk_attrset ( const chtype ); int slk_attr_set ( const attr_t, short, void * ); int slk_clear ( void ); int slk_color ( short ); int slk_init ( int ); char * slk_label ( int ); int slk_noutrefresh ( void ); int slk_refresh ( void ); int slk_restore ( void ); int slk_set ( int, const char *, int ); int slk_touch ( void ); int standend ( void ); int standout ( void ); int start_color ( void ); WINDOW * subpad ( WINDOW *, int, int, int, int ); WINDOW * subwin ( WINDOW *, int, int, int, int ); int syncok ( WINDOW *, bool ); chtype termattrs ( void ); attr_t term_attrs ( void ); char * termname ( void ); void timeout ( int ); int touchline ( WINDOW *, int, int ); int touchwin ( WINDOW * ); int typeahead ( int ); int untouchwin ( WINDOW * ); void use_env ( bool ); int vidattr ( chtype ); int vid_attr ( attr_t, short, void * ); int vidputs ( chtype, int ( * ) ( int ) ); int vid_puts ( attr_t, short, void *, int ( * ) ( int ) ); int vline ( chtype, int ); int vw_printw ( WINDOW *, const char *, va_list ); int vwprintw ( WINDOW *, const char *, va_list ); int vw_scanw ( WINDOW *, const char *, va_list ); int vwscanw ( WINDOW *, const char *, va_list ); int waddchnstr ( WINDOW *, const chtype *, int ); int waddchstr ( WINDOW *, const chtype * ); int waddch ( WINDOW *, const chtype ); int waddnstr ( WINDOW *, const char *, int ); int waddstr ( WINDOW *, const char * ); int wattroff ( WINDOW *, chtype ); int wattron ( WINDOW *, chtype ); int wattrset ( WINDOW *, chtype ); int wattr_get ( WINDOW *, attr_t *, short *, void * ); int wattr_off ( WINDOW *, attr_t, void * ); int wattr_on ( WINDOW *, attr_t, void * ); int wattr_set ( WINDOW *, attr_t, short, void * ); void wbkgdset ( WINDOW *, chtype ); int wbkgd ( WINDOW *, chtype ); int wborder ( WINDOW *, chtype, chtype, chtype, chtype, chtype, chtype, chtype, chtype ); int wchgat ( WINDOW *, int, attr_t, short, const void * ); int wclear ( WINDOW * ); int wclrtobot ( WINDOW * ); int wclrtoeol ( WINDOW * ); int wcolor_set ( WINDOW *, short, void * ); void wcursyncup ( WINDOW * ); int wdelch ( WINDOW * ); int wdeleteln ( WINDOW * ); int wechochar ( WINDOW *, const chtype ); int werase ( WINDOW * ); int wgetch ( WINDOW * ); int wgetnstr ( WINDOW *, char *, int ); int wgetstr ( WINDOW *, char * ); int whline ( WINDOW *, chtype, int ); int winchnstr ( WINDOW *, chtype *, int ); int winchstr ( WINDOW *, chtype * ); chtype winch ( WINDOW * ); int winnstr ( WINDOW *, char *, int ); int winsch ( WINDOW *, chtype ); int winsdelln ( WINDOW *, int ); int winsertln ( WINDOW * ); int winsnstr ( WINDOW *, const char *, int ); int winsstr ( WINDOW *, const char * ); int winstr ( WINDOW *, char * ); int wmove ( WINDOW *, int, int ); int wnoutrefresh ( WINDOW * ); int wprintw ( WINDOW *, const char *, ... ); int wredrawln ( WINDOW *, int, int ); int wrefresh ( WINDOW * ); int wscanw ( WINDOW *, const char *, ... ); int wscrl ( WINDOW *, int ); int wsetscrreg ( WINDOW *, int, int ); int wstandend ( WINDOW * ); int wstandout ( WINDOW * ); void wsyncdown ( WINDOW * ); void wsyncup ( WINDOW * ); void wtimeout ( WINDOW *, int ); int wtouchln ( WINDOW *, int, int, int ); int wvline ( WINDOW *, chtype, int ); /* Wide-character functions */ #ifdef PDC_WIDE int addnwstr ( const wchar_t *, int ); int addwstr ( const wchar_t * ); int add_wch ( const cchar_t * ); int add_wchnstr ( const cchar_t *, int ); int add_wchstr ( const cchar_t * ); int border_set ( const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t * ); int box_set ( WINDOW *, const cchar_t *, const cchar_t * ); int echo_wchar ( const cchar_t * ); int erasewchar ( wchar_t * ); int getbkgrnd ( cchar_t * ); int getcchar ( const cchar_t *, wchar_t *, attr_t *, short *, void * ); int getn_wstr ( wint_t *, int ); int get_wch ( wint_t * ); int get_wstr ( wint_t * ); int hline_set ( const cchar_t *, int ); int innwstr ( wchar_t *, int ); int ins_nwstr ( const wchar_t *, int ); int ins_wch ( const cchar_t * ); int ins_wstr ( const wchar_t * ); int inwstr ( wchar_t * ); int in_wch ( cchar_t * ); int in_wchnstr ( cchar_t *, int ); int in_wchstr ( cchar_t * ); char * key_name ( wchar_t ); int killwchar ( wchar_t * ); int mvaddnwstr ( int, int, const wchar_t *, int ); int mvaddwstr ( int, int, const wchar_t * ); int mvadd_wch ( int, int, const cchar_t * ); int mvadd_wchnstr ( int, int, const cchar_t *, int ); int mvadd_wchstr ( int, int, const cchar_t * ); int mvgetn_wstr ( int, int, wint_t *, int ); int mvget_wch ( int, int, wint_t * ); int mvget_wstr ( int, int, wint_t * ); int mvhline_set ( int, int, const cchar_t *, int ); int mvinnwstr ( int, int, wchar_t *, int ); int mvins_nwstr ( int, int, const wchar_t *, int ); int mvins_wch ( int, int, const cchar_t * ); int mvins_wstr ( int, int, const wchar_t * ); int mvinwstr ( int, int, wchar_t * ); int mvin_wch ( int, int, cchar_t * ); int mvin_wchnstr ( int, int, cchar_t *, int ); int mvin_wchstr ( int, int, cchar_t * ); int mvvline_set ( int, int, const cchar_t *, int ); int mvwaddnwstr ( WINDOW *, int, int, const wchar_t *, int ); int mvwaddwstr ( WINDOW *, int, int, const wchar_t * ); int mvwadd_wch ( WINDOW *, int, int, const cchar_t * ); int mvwadd_wchnstr ( WINDOW *, int, int, const cchar_t *, int ); int mvwadd_wchstr ( WINDOW *, int, int, const cchar_t * ); int mvwgetn_wstr ( WINDOW *, int, int, wint_t *, int ); int mvwget_wch ( WINDOW *, int, int, wint_t * ); int mvwget_wstr ( WINDOW *, int, int, wint_t * ); int mvwhline_set ( WINDOW *, int, int, const cchar_t *, int ); int mvwinnwstr ( WINDOW *, int, int, wchar_t *, int ); int mvwins_nwstr ( WINDOW *, int, int, const wchar_t *, int ); int mvwins_wch ( WINDOW *, int, int, const cchar_t * ); int mvwins_wstr ( WINDOW *, int, int, const wchar_t * ); int mvwin_wch ( WINDOW *, int, int, cchar_t * ); int mvwin_wchnstr ( WINDOW *, int, int, cchar_t *, int ); int mvwin_wchstr ( WINDOW *, int, int, cchar_t * ); int mvwinwstr ( WINDOW *, int, int, wchar_t * ); int mvwvline_set ( WINDOW *, int, int, const cchar_t *, int ); int pecho_wchar ( WINDOW *, const cchar_t * ); int setcchar ( cchar_t *, const wchar_t *, const attr_t, short, const void * ); int slk_wset ( int, const wchar_t *, int ); int unget_wch ( const wchar_t ); int vline_set ( const cchar_t *, int ); int waddnwstr ( WINDOW *, const wchar_t *, int ); int waddwstr ( WINDOW *, const wchar_t * ); int wadd_wch ( WINDOW *, const cchar_t * ); int wadd_wchnstr ( WINDOW *, const cchar_t *, int ); int wadd_wchstr ( WINDOW *, const cchar_t * ); int wbkgrnd ( WINDOW *, const cchar_t * ); void wbkgrndset ( WINDOW *, const cchar_t * ); int wborder_set ( WINDOW *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t *, const cchar_t * ); int wecho_wchar ( WINDOW *, const cchar_t * ); int wgetbkgrnd ( WINDOW *, cchar_t * ); int wgetn_wstr ( WINDOW *, wint_t *, int ); int wget_wch ( WINDOW *, wint_t * ); int wget_wstr ( WINDOW *, wint_t * ); int whline_set ( WINDOW *, const cchar_t *, int ); int winnwstr ( WINDOW *, wchar_t *, int ); int wins_nwstr ( WINDOW *, const wchar_t *, int ); int wins_wch ( WINDOW *, const cchar_t * ); int wins_wstr ( WINDOW *, const wchar_t * ); int winwstr ( WINDOW *, wchar_t * ); int win_wch ( WINDOW *, cchar_t * ); int win_wchnstr ( WINDOW *, cchar_t *, int ); int win_wchstr ( WINDOW *, cchar_t * ); wchar_t * wunctrl ( cchar_t * ); int wvline_set ( WINDOW *, const cchar_t *, int ); #endif /* Quasi-standard */ chtype getattrs ( WINDOW * ); int getbegx ( WINDOW * ); int getbegy ( WINDOW * ); int getmaxx ( WINDOW * ); int getmaxy ( WINDOW * ); int getparx ( WINDOW * ); int getpary ( WINDOW * ); int getcurx ( WINDOW * ); int getcury ( WINDOW * ); void traceoff ( void ); void traceon ( void ); char * unctrl ( chtype ); int crmode ( void ); int nocrmode ( void ); int draino ( int ); int resetterm ( void ); int fixterm ( void ); int saveterm ( void ); int setsyx ( int, int ); int mouse_set ( unsigned long ); int mouse_on ( unsigned long ); int mouse_off ( unsigned long ); int request_mouse_pos ( void ); int map_button ( unsigned long ); void wmouse_position ( WINDOW *, int *, int * ); unsigned long getmouse ( void ); unsigned long getbmap ( void ); /* ncurses */ int assume_default_colors ( int, int ); const char * curses_version ( void ); bool has_key ( int ); int use_default_colors ( void ); int wresize ( WINDOW *, int, int ); int mouseinterval ( int ); mmask_t mousemask ( mmask_t, mmask_t * ); bool mouse_trafo ( int *, int *, bool ); int nc_getmouse ( MEVENT * ); int ungetmouse ( MEVENT * ); bool wenclose ( const WINDOW *, int, int ); bool wmouse_trafo ( const WINDOW *, int *, int *, bool ); /* PDCurses */ int addrawch ( chtype ); int insrawch ( chtype ); bool is_termresized ( void ); int mvaddrawch ( int, int, chtype ); int mvdeleteln ( int, int ); int mvinsertln ( int, int ); int mvinsrawch ( int, int, chtype ); int mvwaddrawch ( WINDOW *, int, int, chtype ); int mvwdeleteln ( WINDOW *, int, int ); int mvwinsertln ( WINDOW *, int, int ); int mvwinsrawch ( WINDOW *, int, int, chtype ); int raw_output ( bool ); int resize_term ( int, int ); WINDOW * resize_window ( WINDOW *, int, int ); int waddrawch ( WINDOW *, chtype ); int winsrawch ( WINDOW *, chtype ); char wordchar ( void ); #ifdef PDC_WIDE wchar_t * slk_wlabel ( int ); #endif void PDC_debug ( const char *, ... ); int PDC_ungetch ( int ); int PDC_set_blink ( bool ); int PDC_set_line_color ( short ); void PDC_set_title ( const char * ); int PDC_clearclipboard ( void ); int PDC_freeclipboard ( char * ); int PDC_getclipboard ( char **, long * ); int PDC_setclipboard ( const char *, long ); unsigned long PDC_get_input_fd ( void ); unsigned long PDC_get_key_modifiers ( void ); int PDC_return_key_modifiers ( bool ); int PDC_save_key_modifiers ( bool ); #ifdef XCURSES WINDOW * Xinitscr ( int, char ** ); void XCursesExit ( void ); int sb_init ( void ); int sb_set_horz ( int, int, int ); int sb_set_vert ( int, int, int ); int sb_get_horz ( int *, int *, int * ); int sb_get_vert ( int *, int *, int * ); int sb_refresh ( void ); #endif /*** Functions defined as macros ***/ /* getch() and ungetch() conflict with some DOS libraries */ #define getch() wgetch(stdscr) #define ungetch(ch) PDC_ungetch(ch) #define COLOR_PAIR(n) (((chtype)(n) << PDC_COLOR_SHIFT) & A_COLOR) #define PAIR_NUMBER(n) (((n) & A_COLOR) >> PDC_COLOR_SHIFT) /* These will _only_ work as macros */ #define getbegyx(w, y, x) (y = getbegy(w), x = getbegx(w)) #define getmaxyx(w, y, x) (y = getmaxy(w), x = getmaxx(w)) #define getparyx(w, y, x) (y = getpary(w), x = getparx(w)) #define getyx(w, y, x) (y = getcury(w), x = getcurx(w)) #define getsyx(y, x) { if (curscr->_leaveit) (y)=(x)=-1; \ else getyx(curscr,(y),(x)); } #ifdef NCURSES_MOUSE_VERSION # define getmouse(x) nc_getmouse(x) #endif /* return codes from PDC_getclipboard() and PDC_setclipboard() calls */ #define PDC_CLIP_SUCCESS 0 #define PDC_CLIP_ACCESS_ERROR 1 #define PDC_CLIP_EMPTY 2 #define PDC_CLIP_MEMORY_ERROR 3 /* PDCurses key modifier masks */ #define PDC_KEY_MODIFIER_SHIFT 1 #define PDC_KEY_MODIFIER_CONTROL 2 #define PDC_KEY_MODIFIER_ALT 4 #define PDC_KEY_MODIFIER_NUMLOCK 8 #if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS) # undef bool } #endif #endif /* __PDCURSES__ */ soapdenovo2-240+dfsg.orig/sparsePregraph/inc/core.h0000644000000000000000000000635012166703654021052 0ustar rootroot/* * inc/core.h * * This file is part of SOAPdenovo. * * Part of this file is refered and modified from SparseAssembler * (See ). * */ #ifndef _CORE_H #define _CORE_H #include "stdinc.h" #ifdef _63MER_ struct kmer_t2 //use union later { uint64_t kmer[2]; }; #endif #ifdef _127MER_ struct kmer_t2 //use union later { uint64_t kmer[4]; }; #endif struct edge_node // kmer-edge the connection between sparse-kmer { uint64_t edge: 50, edge_cov: 7, len: 6, used: 1; struct edge_node * nxt_edge; }; //#pragma pack(4) // do pack(4) later struct kmer_info { //uint8_t used:1,split_left:1,split_right:1,removed:1,flip:1,marked:1,repeat:1; uint64_t used: 1, linear: 1, deleted: 1, single: 1, inEdge: 2, twin: 2, cov1: 16; //added for soapdenovo //uint16_t cov1:16; //uint32_t edge_id;//added for soapdenovo struct edge_node * left; struct edge_node * right; }; struct kmer_info_r1 { uint16_t cov1: 16; }; struct bucket2 //sparse-kmer { struct kmer_t2 kmer_t2; struct kmer_info kmer_info; bucket2 * nxt_bucket; }; struct bucket2_r1 //sparse-kmer struct for round1 , { struct kmer_t2 kmer_t2; struct kmer_info_r1 kmer_info; bucket2_r1 * nxt_bucket; }; struct hashtable2 { struct bucket2 ** store_pos; size_t ht_sz; }; struct read_t //reads bits struct ... { uint64_t read_bits[100]; int readLen; }; //function for hashtable //void Init_HT2(struct hashtable2* ht,size_t ht_sz); //bool look_up_in_a_list2_r1(struct kmer_t2 *seq,struct bucket2_r1 *** ptr); //bool look_up_in_a_list2(struct kmer_t2 *seq,struct bucket2 *** ptr); //void free_hashtable(hashtable2 *ht); inline void Init_HT2 ( struct hashtable2 * ht, size_t ht_sz ) { ht->ht_sz = ht_sz; ht->store_pos = ( struct bucket2 ** ) calloc ( ht_sz, sizeof ( struct bucket2 * ) ); for ( size_t i = 0; i < ht_sz; ++i ) { ht->store_pos[i] = NULL; } } inline bool look_up_in_a_list2_r1 ( struct kmer_t2 * seq, struct bucket2_r1 ** * ptr ) { while ( ( **ptr ) != NULL ) { if ( memcmp ( & ( ( **ptr )->kmer_t2.kmer ), & ( seq->kmer ), sizeof ( kmer_t2 ) ) == 0 ) { break; } ( *ptr ) = & ( ( **ptr )->nxt_bucket ); } return ( ( **ptr ) != NULL ); } inline bool look_up_in_a_list2 ( struct kmer_t2 * seq, struct bucket2 ** * ptr ) { while ( ( **ptr ) != NULL ) { if ( memcmp ( & ( ( **ptr )->kmer_t2.kmer ), & ( seq->kmer ), sizeof ( kmer_t2 ) ) == 0 ) { break; } ( *ptr ) = & ( ( **ptr )->nxt_bucket ); } return ( ( **ptr ) != NULL ); } inline void free_bucket ( bucket2 * tmp ) { edge_node * edge, *edge2; edge = tmp->kmer_info.left; while ( edge ) { edge2 = edge; edge = edge->nxt_edge; free ( edge ); } edge = tmp->kmer_info.right; while ( edge ) { edge2 = edge; edge = edge->nxt_edge; free ( edge ); } free ( tmp ); } inline void free_hashtable ( hashtable2 * ht ) { bucket2 * tmp, *tmp2; for ( size_t i = 0; i < ht->ht_sz; ++i ) { tmp = ( ht->store_pos ) [i]; while ( tmp ) { tmp2 = tmp; tmp = tmp->nxt_bucket; free ( tmp2 ); } } free ( ht->store_pos ); } #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/sparse_kmer.h0000644000000000000000000001711712166703654022440 0ustar rootroot/* * inc/sparse_kmer.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef _SPARSE_KMER_H #define _SPARSE_KMER_H #include "seq_util.h" inline void initKmerFilter ( int K_size, kmer_t2 * kmer_filter ) { #ifdef _63MER_ ( kmer_filter->kmer ) [0] = 0; ( kmer_filter->kmer ) [1] = 1LU; L_shift_NC ( kmer_filter->kmer, K_size * 2, 2 ); if ( K_size <= 31 ) { ( kmer_filter->kmer ) [1] -= 1; // } else { ( kmer_filter->kmer ) [0] -= 1; // K_size = 32 is also ok .. ( kmer_filter->kmer ) [1] = -1; //fff.. } #endif #ifdef _127MER_ memset ( kmer_filter->kmer, 0, sizeof ( kmer_t2 ) ); ( kmer_filter->kmer ) [3] = 1LU; L_shift_NC ( kmer_filter->kmer, K_size * 2, 4 ); if ( K_size <= 31 ) { ( kmer_filter->kmer ) [3] -= 1; } else if ( K_size <= 63 ) { ( kmer_filter->kmer ) [2] -= 1; ( kmer_filter->kmer ) [3] = -1; } else if ( K_size <= 95 ) { ( kmer_filter->kmer ) [1] -= 1; ( kmer_filter->kmer ) [2] = -1; ( kmer_filter->kmer ) [3] = -1; } else if ( K_size <= 127 ) { ( kmer_filter->kmer ) [0] -= 1; ( kmer_filter->kmer ) [1] = -1; ( kmer_filter->kmer ) [2] = -1; ( kmer_filter->kmer ) [3] = -1; } #endif } inline void kmerAnd ( kmer_t2 * k1, kmer_t2 * k2 ) //change k1 { #ifdef _63MER_ ( k1->kmer ) [0] &= ( k2->kmer ) [0]; ( k1->kmer ) [1] &= ( k2->kmer ) [1]; #endif #ifdef _127MER_ ( k1->kmer ) [0] &= ( k2->kmer ) [0]; ( k1->kmer ) [1] &= ( k2->kmer ) [1]; ( k1->kmer ) [2] &= ( k2->kmer ) [2]; ( k1->kmer ) [3] &= ( k2->kmer ) [3]; #endif } inline void kmerOr ( kmer_t2 * k1, kmer_t2 * k2 ) //change k1 { #ifdef _63MER_ ( k1->kmer ) [0] |= ( k2->kmer ) [0]; ( k1->kmer ) [1] |= ( k2->kmer ) [1]; #endif #ifdef _127MER_ ( k1->kmer ) [0] |= ( k2->kmer ) [0]; ( k1->kmer ) [1] |= ( k2->kmer ) [1]; ( k1->kmer ) [2] |= ( k2->kmer ) [2]; ( k1->kmer ) [3] |= ( k2->kmer ) [3]; #endif } inline void kmerMoveRight ( kmer_t2 * kmer, int base_num ) { #ifdef _63MER_ R_shift_NC ( kmer->kmer, base_num * 2, 2 ); #endif #ifdef _127MER_ R_shift_NC ( kmer->kmer, base_num * 2, 4 ); // has move 32 bug #endif } inline void kmerMoveLeft ( kmer_t2 * kmer, int base_num ) { #ifdef _63MER_ L_shift_NC ( kmer->kmer, base_num * 2, 2 ); #endif #ifdef _127MER_ L_shift_NC ( kmer->kmer, base_num * 2, 4 ); #endif } inline int kmerCompare ( kmer_t2 * k1, kmer_t2 * k2 ) { #ifdef _63MER_ return uint64_t_cmp ( k1->kmer, k2->kmer, 2 ); #endif #ifdef _127MER_ return uint64_t_cmp ( k1->kmer, k2->kmer, 4 ); #endif } inline void reverseCompKmer ( kmer_t2 * kmer , int K_size ) //result stored in *kmer ... { #ifdef _63MER_ get_rev_comp_seq_arr ( kmer->kmer, K_size, 2 ); #endif #ifdef _127MER_ get_rev_comp_seq_arr ( kmer->kmer, K_size, 4 ); #endif } inline bool isSmallerKmer ( kmer_t2 * kmer, int K_size ) { kmer_t2 f_kmer; f_kmer = *kmer; reverseCompKmer ( &f_kmer, K_size ); if ( kmerCompare ( kmer, &f_kmer ) < 0 ) { return 1; } return 0; } inline void get_kmer_from_seq ( const char * seq, int len, int K_size, int pos, kmer_t2 * kmer ) { if ( pos + K_size > len ) { fprintf ( stderr, "ERROR: get_kmer position is invalid!\n" ); exit ( 1 ); } int start = pos, end = pos + K_size, index; uint64_t * arr_ptr = kmer->kmer; memset ( arr_ptr, 0, sizeof ( kmer_t2 ) ); int arr_sz = sizeof ( kmer_t2 ) / sizeof ( uint64_t ); int i = 0; uint64_t tmp = 0; for ( index = start, i = 0; index < end; index++, i++ ) { switch ( seq[index] ) { case 'A': tmp = tmp << 2; break; case 'C': tmp = ( tmp << 2 ) | 1; break; case 'G': tmp = ( tmp << 2 ) | 2; break; case 'T': tmp = ( tmp << 2 ) | 3; break; case 'N': tmp = ( tmp << 2 ) | 2; //treat N as G break; default: tmp = ( tmp << 2 ) | 2; // treat unknown char as G, 'S' fprintf ( stderr, "WARNING: get_kmer_from_seq process unknown char %c\n", seq[index] ); //exit(1); } if ( ( i + 1 ) % 32 == 0 ) //tmp is full, tmp has stored 32 bases { arr_ptr[i / 32] = tmp; tmp = 0; } } if ( i != K_size ) { fprintf ( stderr, "ERROR: i %d is K_size \n", i ); } if ( K_size <= 31 ) { arr_ptr[arr_sz - 1] = tmp; } else //if(K_size%32 != 0){ //absolute ..because K is odd { int left_bits = ( 32 - K_size % 32 ) * 2; tmp = tmp << left_bits; arr_ptr[K_size / 32] = tmp; kmerMoveRight ( kmer, 32 * arr_sz - K_size ); } /* uint64_t high=0,low=0; int high_start=0,high_end=0; int low_satrt=0,low_end=0; if(K_size >= 33){ high_start = pos; high_end = pos+K_size-32; low_satrt = high_end; low_end = low_satrt + 32; }else{ high_start = high_end = pos; low_satrt = pos; low_end = pos+K_size; } //debug<<"kmer "; for(int i=high_start;ikmer ) [0], ( kmer->kmer ) [1] ); #endif #ifdef _127MER_ fprintf ( fp, "%llx %llx %llx %llx,\n", ( kmer->kmer ) [0], ( kmer->kmer ) [1], ( kmer->kmer ) [2], ( kmer->kmer ) [3] ); #endif } inline void printKmerSeq ( kmer_t2 * kmer, int K_size, FILE * fp ) //TODO printf ATCG { char str[128]; bitsarr2str ( kmer->kmer, K_size, str, sizeof ( kmer_t2 ) / sizeof ( uint64_t ) ); fprintf ( fp, "%s ,\n", str ); } #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/sam_view.h0000644000000000000000000000220612166703654021730 0ustar rootroot#ifndef SAM_VIEW_H #define SAM_VIEW_H static int g_min_mapQ = 0, g_flag_on = 0, g_flag_off = 0; static char * g_library, *g_rg; static int g_sol2sanger_tbl[128]; static void sol2sanger ( bam1_t * b ) { int l; uint8_t * qual = bam1_qual ( b ); if ( g_sol2sanger_tbl[30] == 0 ) { for ( l = 0; l != 128; ++l ) { g_sol2sanger_tbl[l] = ( int ) ( 10.0 * log ( 1.0 + pow ( 10.0, ( l - 64 + 33 ) / 10.0 ) ) / log ( 10.0 ) + .499 ); if ( g_sol2sanger_tbl[l] >= 93 ) { g_sol2sanger_tbl[l] = 93; } } } for ( l = 0; l < b->core.l_qseq; ++l ) { int q = qual[l]; if ( q > 127 ) { q = 127; } qual[l] = g_sol2sanger_tbl[q]; } } static inline int __g_skip_aln ( const bam_header_t * h, const bam1_t * b ) { if ( b->core.qual < g_min_mapQ || ( ( b->core.flag & g_flag_on ) != g_flag_on ) || ( b->core.flag & g_flag_off ) ) { return 1; } if ( g_rg ) { uint8_t * s = bam_aux_get ( b, "RG" ); if ( s && strcmp ( g_rg, ( char * ) ( s + 1 ) ) == 0 ) { return 0; } } if ( g_library ) { const char * p = bam_get_library ( ( bam_header_t * ) h, b ); return ( p && strcmp ( p, g_library ) == 0 ) ? 0 : 1; } return 0; } #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/io_func.h0000644000000000000000000000240712166703654021543 0ustar rootroot/* * inc/io_func.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef _IO_FUNC_H #define _IO_FUNC_H #include "stdinc.h" #include "global.h" struct io_para_main { int read_buf_sz; vector *in_filenames_vt; }; void sendIOWorkSignal(); void * run_io_thread_main ( void * arg ); void filter_N ( string & seq_s, int & bad_flag ); void read_lib ( vector &filenames, char * lib_file ); void * open_file_robust ( const char * filetype, const char * path, const char * mode ); #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/xcurses.h.gch0000644000000000000000001402157012166703654022364 0ustar rootrootgpch+013)dÉgOÖ¬Eh\FHÇél¤ÿÀÜKdx86-64generic64__DBL_MIN_EXP__ (-1021) __FLT_MIN__ 1.17549435e-38F __CHAR_BIT__ 8 __WCHAR_MAX__ 2147483647*__DBL_DENORM_MIN__ 4.9406564584124654e-324__FLT_EVAL_METHOD__ 0__DBL_MIN_10_EXP__ (-307)__FINITE_MATH_ONLY__ 0 __LP64__ 1 __SHRT_MAX__ 32767* __LDBL_MAX__ 1.18973149535723176502e+4932L"__UINTMAX_TYPE__ long unsigned int __linux 1__unix 1 __linux__ 1 __SCHAR_MAX__ 127__USER_LABEL_PREFIX__ __STDC_HOSTED__ 1 __DBL_DIG__ 15__FLT_EPSILON__ 1.19209290e-7F __GXX_WEAK__ 1* __LDBL_MIN__ 3.36210314311209350626e-4932L __unix__ 1__DECIMAL_DIG__ 21 __gnu_linux__ 1__LDBL_HAS_QUIET_NAN__ 1 __GNUC__ 4 __MMX__ 1# __DBL_MAX__ 1.7976931348623157e+308__DBL_HAS_INFINITY__ 1 __cplusplus 1 __DEPRECATED 1__DBL_MAX_EXP__ 1024 __SSE2_MATH__ 1 __amd64 1 __GNUG__ 4'__LONG_LONG_MAX__ 9223372036854775807LL__GXX_ABI_VERSION 1002__FLT_MIN_EXP__ (-125) __x86_64 1# __DBL_MIN__ 2.2250738585072014e-308__FLT_MIN_10_EXP__ (-37)__DBL_HAS_QUIET_NAN__ 1__REGISTER_PREFIX__  __NO_INLINE__ 1__FLT_MANT_DIG__ 24/ __VERSION__ "4.1.2 20080704 (Red Hat 4.1.2-48)"unix 1 __SIZE_TYPE__ long unsigned int __ELF__ 1 __FLT_RADIX__ 2,__LDBL_EPSILON__ 1.08420217248550443401e-19L__GNUC_RH_RELEASE__ 48__k8 1_LP64 1 __LDBL_DIG__ 18 __x86_64__ 1__FLT_HAS_QUIET_NAN__ 1__FLT_MAX_10_EXP__ 38__FLT_HAS_INFINITY__ 1linux 1 __EXCEPTIONS 1__LDBL_MANT_DIG__ 64__k8__ 1__WCHAR_TYPE__ int __FLT_DIG__ 6 __INT_MAX__ 2147483647__FLT_MAX_EXP__ 128__DBL_MANT_DIG__ 53 __WINT_TYPE__ unsigned int __SSE__ 1__LDBL_MIN_EXP__ (-16381) __amd64__ 1__LDBL_MAX_EXP__ 16384__LDBL_MAX_10_EXP__ 4932&__DBL_EPSILON__ 2.2204460492503131e-16__GNUC_PATCHLEVEL__ 2__LDBL_HAS_INFINITY__ 1#__INTMAX_MAX__ 9223372036854775807L"__FLT_DENORM_MIN__ 1.40129846e-45F __FLT_MAX__ 3.40282347e+38F __SSE2__ 1__INTMAX_TYPE__ long int__GNUC_MINOR__ 1__DBL_MAX_10_EXP__ 3081__LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L __STDC__ 1__PTRDIFF_TYPE__ long int! __LONG_MAX__ 9223372036854775807L__LDBL_MIN_10_EXP__ (-4931) __SSE_MATH__ 1__GNUC_GNU_INLINE__ 1 _GNU_SOURCE 1tÂ._0._1._10._11._12._2._3._4._5._6._7._8._9::ACS_BBSSACS_BLOCKACS_BOARDACS_BSBSACS_BSSBACS_BSSSACS_BTEEACS_BULLETACS_CKBOARDACS_DARROWACS_DEGREEACS_DIAMONDACS_GEQUALACS_HLINEACS_LANTERNACS_LARROWACS_LEQUALACS_LLCORNERACS_LRCORNERACS_LTEEACS_NEQUALACS_PIACS_PICKACS_PLMINUSACS_PLUSACS_RARROWACS_RTEEACS_S1ACS_S3ACS_S7ACS_S9ACS_SBBSACS_SBSBACS_SBSSACS_SSBBACS_SSBSACS_SSSBACS_SSSSACS_STERLINGACS_TTEEACS_UARROWACS_ULCORNERACS_URCORNERACS_VLINEALL_MOUSE_EVENTSALT_0ALT_1ALT_2ALT_3ALT_4ALT_5ALT_6ALT_7ALT_8ALT_9ALT_AALT_BALT_BKSPALT_BQUOTEALT_BSLASHALT_CALT_COMMAALT_DALT_DELALT_DOWNALT_EALT_ENDALT_ENTERALT_EQUALALT_ESCALT_FALT_FQUOTEALT_FSLASHALT_GALT_HALT_HOMEALT_IALT_INSALT_JALT_KALT_LALT_LBRACKETALT_LEFTALT_MALT_MINUSALT_NALT_OALT_PALT_PAD0ALT_PAD1ALT_PAD2ALT_PAD3ALT_PAD4ALT_PAD5ALT_PAD6ALT_PAD7ALT_PAD8ALT_PAD9ALT_PADENTERALT_PADMINUSALT_PADPLUSALT_PADSLASHALT_PADSTARALT_PADSTOPALT_PGDNALT_PGUPALT_QALT_RALT_RBRACKETALT_RIGHTALT_SALT_SEMICOLONALT_STOPALT_TALT_TABALT_UALT_UPALT_VALT_WALT_XALT_YALT_ZARGLISTATR_MSKATR_NRMA_ALTCHARSETA_ATTRIBUTESA_BLINKA_BOLDA_BUTTON_CHANGEDA_CHARTEXTA_COLORA_DIMA_INVISA_ITALICA_LEFTLINEA_NORMALA_PROTECTA_REVERSEA_RIGHTLINEA_STANDOUTA_UNDERLINEApplicationsBSDcursesBUFSIZBUTTON1_CLICKEDBUTTON1_DOUBLE_CLICKEDBUTTON1_MOVEDBUTTON1_PRESSEDBUTTON1_RELEASEDBUTTON1_TRIPLE_CLICKEDBUTTON2_CLICKEDBUTTON2_DOUBLE_CLICKEDBUTTON2_MOVEDBUTTON2_PRESSEDBUTTON2_RELEASEDBUTTON2_TRIPLE_CLICKEDBUTTON3_CLICKEDBUTTON3_DOUBLE_CLICKEDBUTTON3_MOVEDBUTTON3_PRESSEDBUTTON3_RELEASEDBUTTON3_TRIPLE_CLICKEDBUTTON4_CLICKEDBUTTON4_DOUBLE_CLICKEDBUTTON4_PRESSEDBUTTON4_RELEASEDBUTTON4_TRIPLE_CLICKEDBUTTON5_CLICKEDBUTTON5_DOUBLE_CLICKEDBUTTON5_PRESSEDBUTTON5_RELEASEDBUTTON5_TRIPLE_CLICKEDBUTTON_ACTION_MASKBUTTON_ALTBUTTON_CHANGEDBUTTON_CLICKEDBUTTON_CONTROLBUTTON_CTRLBUTTON_DOUBLE_CLICKEDBUTTON_MODIFIER_ALTBUTTON_MODIFIER_CONTROLBUTTON_MODIFIER_MASKBUTTON_MODIFIER_SHIFTBUTTON_MOVEDBUTTON_PRESSEDBUTTON_RELEASEDBUTTON_SHIFTBUTTON_STATUSBUTTON_TRIPLE_CLICKEDCC++CHR_MSKCHTYPE_LONGCOLORSCOLOR_BLACKCOLOR_BLUECOLOR_CYANCOLOR_GREENCOLOR_MAGENTACOLOR_PAIRCOLOR_PAIRSCOLOR_REDCOLOR_WHITECOLOR_YELLOWCOLSCTL_BKSPCTL_DELCTL_DOWNCTL_ENDCTL_ENTERCTL_HOMECTL_INSCTL_LEFTCTL_PAD0CTL_PAD1CTL_PAD2CTL_PAD3CTL_PAD4CTL_PAD5CTL_PAD6CTL_PAD7CTL_PAD8CTL_PAD9CTL_PADCENTERCTL_PADENTERCTL_PADMINUSCTL_PADPLUSCTL_PADSLASHCTL_PADSTARCTL_PADSTOPCTL_PGDNCTL_PGUPCTL_RIGHTCTL_TABCTL_UPCURSES_LIBRARYEOFERRFALSEFILEFILENAME_MAXFOPEN_MAXGCCGLIBC_2_0GLIBC_2_1IOV_MAXJavaKEY_A1KEY_A2KEY_A3KEY_ABORTKEY_ALT_LKEY_ALT_RKEY_B1KEY_B2KEY_B3KEY_BACKSPACEKEY_BEGKEY_BREAKKEY_BTABKEY_C1KEY_C2KEY_C3KEY_CANCELKEY_CATABKEY_CLEARKEY_CLOSEKEY_CODE_YESKEY_COMMANDKEY_CONTROL_LKEY_CONTROL_RKEY_COPYKEY_CREATEKEY_CTABKEY_DCKEY_DLKEY_DOWNKEY_EICKEY_ENDKEY_ENTERKEY_EOLKEY_EOSKEY_EXITKEY_FKEY_F0KEY_FINDKEY_HELPKEY_HOMEKEY_ICKEY_ILKEY_LEFTKEY_LHELPKEY_LLKEY_MARKKEY_MAXKEY_MESSAGEKEY_MINKEY_MOUSEKEY_MOVEKEY_NEXTKEY_NPAGEKEY_OPENKEY_OPTIONSKEY_PPAGEKEY_PREVIOUSKEY_PRINTKEY_REDOKEY_REFERENCEKEY_REFRESHKEY_REPLACEKEY_RESETKEY_RESIZEKEY_RESTARTKEY_RESUMEKEY_RIGHTKEY_SAVEKEY_SBEGKEY_SCANCELKEY_SCOMMANDKEY_SCOPYKEY_SCREATEKEY_SDCKEY_SDLKEY_SDOWNKEY_SELECTKEY_SENDKEY_SEOLKEY_SEXITKEY_SFKEY_SFINDKEY_SHELPKEY_SHIFT_LKEY_SHIFT_RKEY_SHOMEKEY_SICKEY_SLEFTKEY_SMESSAGEKEY_SMOVEKEY_SNEXTKEY_SOPTIONSKEY_SPREVIOUSKEY_SPRINTKEY_SRKEY_SREDOKEY_SREPLACEKEY_SRESETKEY_SRIGHTKEY_SRSUMEKEY_SSAVEKEY_SSUSPENDKEY_STABKEY_SUNDOKEY_SUPKEY_SUSPENDKEY_UNDOKEY_UPLINESL_ctermidL_cuseridL_tmpnamMEMBERMEVENTMOUSE_MOVEDMOUSE_POS_REPORTMOUSE_STATUSMOUSE_WHEEL_DOWNMOUSE_WHEEL_SCROLLMOUSE_WHEEL_UPMOUSE_X_POSMOUSE_Y_POSMouse_statusNCURSES_MOUSE_VERSIONNULLOKPAD0PADENTERPADMINUSPADPLUSPADSLASHPADSTARPADSTOPPAIR_NUMBERPDCEXPDCURSESPDC_ATTR_SHIFTPDC_BUILDPDC_BUTTON_ALTPDC_BUTTON_CONTROLPDC_BUTTON_SHIFTPDC_CLIP_ACCESS_ERRORPDC_CLIP_EMPTYPDC_CLIP_MEMORY_ERRORPDC_CLIP_SUCCESSPDC_COLOR_SHIFTPDC_DLL_BUILDPDC_KEY_MODIFIER_ALTPDC_KEY_MODIFIER_CONTROLPDC_KEY_MODIFIER_NUMLOCKPDC_KEY_MODIFIER_SHIFTPDC_MOUSE_MOVEDPDC_MOUSE_POSITIONPDC_MOUSE_WHEEL_DOWNPDC_MOUSE_WHEEL_UPPDC_RGBPDC_WIDEPDC_clearclipboardPDC_debugPDC_freeclipboardPDC_get_input_fdPDC_get_key_modifiersPDC_getclipboardPDC_return_key_modifiersPDC_save_key_modifiersPDC_set_blinkPDC_set_line_colorPDC_set_titlePDC_setclipboardPDC_ungetchP_tmpdirREPORT_MOUSE_POSITIONSCREENSEEK_CURSEEK_ENDSEEK_SETSHAREDSHF_DCSHF_DOWNSHF_ICSHF_PADENTERSHF_PADMINUSSHF_PADPLUSSHF_PADSLASHSHF_PADSTARSHF_UPSHLIB_COMPATSPSYSVcursesTABSIZETMP_MAXTRUETYPEWACS_BBSSWACS_BLOCKWACS_BOARDWACS_BSBSWACS_BSSBWACS_BSSSWACS_BTEEWACS_BULLETWACS_CKBOARDWACS_DARROWWACS_DEGREEWACS_DIAMONDWACS_GEQUALWACS_HLINEWACS_LANTERNWACS_LARROWWACS_LEQUALWACS_LLCORNERWACS_LRCORNERWACS_LTEEWACS_NEQUALWACS_PIWACS_PLMINUSWACS_PLUSWACS_RARROWWACS_RTEEWACS_S1WACS_S3WACS_S7WACS_S9WACS_SBBSWACS_SBSBWACS_SBSSWACS_SSBBWACS_SSBSWACS_SSSBWACS_SSSSWACS_STERLINGWACS_TTEEWACS_UARROWWACS_ULCORNERWACS_URCORNERWACS_VLINEWA_ALTCHARSETWA_BLINKWA_BOLDWA_DIMWA_HORIZONTALWA_INVISWA_LEFTWA_LOWWA_PROTECTWA_REVERSEWA_RIGHTWA_STANDOUTWA_TOPWA_UNDERLINEWA_VERTICALWCHAR_MAXWCHAR_MINWEOFWHEEL_SCROLLEDWINDOWWINNTXCURSESXCursesExitXOPENXcurscrSizeXinitscr_ANSI_H__ANSI_SOURCE_ANSI_STDARG_H__ANSI_STDDEF_H_ATFILE_SOURCE_BITS_TYPESIZES_H_BITS_TYPES_H_BITS_WCHAR_H_BSD_PTRDIFF_T__BSD_RUNE_T__BSD_RUNE_T_DEFINED__BSD_SIZE_T__BSD_SIZE_T_DEFINED__BSD_SOURCE_BSD_VA_LIST_BSD_WCHAR_T__BSD_WCHAR_T_DEFINED__Complex_Doit_Exit_FEATURES_H_FILE_OFFSET_BITS_FORTIFY_SOURCE_GCC_PTRDIFF_T_GCC_PTRDIFF_T__GCC_SIZE_T_GCC_SIZE_T__GCC_WCHAR_T_GCC_WCHAR_T__GCONV_H_GLIBCPP_USE_NAMESPACES_GLIBCPP_USE_WCHAR_T_G_ARGS_G_BUFSIZ_G_FSTAT64_G_HAVE_ATEXIT_G_HAVE_BOOL_G_HAVE_IO_FILE_OPEN_G_HAVE_IO_GETLINE_INFO_G_HAVE_LONG_DOUBLE_IO_G_HAVE_MMAP_G_HAVE_MREMAP_G_HAVE_PRINTF_FP_G_HAVE_ST_BLKSIZE_G_HAVE_SYS_CDEFS_G_HAVE_SYS_WAIT_G_IO_IO_FILE_VERSION_G_LSEEK64_G_MMAP64_G_NAMES_HAVE_UNDERSCORE_G_NEED_STDARG_H_G_OPEN64_G_USING_THUNKS_G_VTABLE_LABEL_HAS_LENGTH_G_VTABLE_LABEL_PREFIX_G_VTABLE_LABEL_PREFIX_ID_G_config_h_G_fpos64_t_G_fpos_t_G_iconv_t_G_int16_t_G_int32_t_G_off64_t_G_off_t_G_pid_t_G_size_t_G_ssize_t_G_stat64_G_uid_t_G_uint16_t_G_uint32_t_G_va_list_G_wchar_t_G_wint_t_HIDDEN_VA_LIST_IOFBF_IOLBF_IONBF_IOS_APPEND_IOS_ATEND_IOS_BIN_IOS_INPUT_IOS_NOCREATE_IOS_NOREPLACE_IOS_OUTPUT_IOS_TRUNC_IO_2_1_stderr__IO_2_1_stdin__IO_2_1_stdout__IO_BAD_SEEN_IO_BE_IO_BOOLALPHA_IO_BUFSIZ_IO_CURRENTLY_PUTTING_IO_DEC_IO_DELETE_DONT_CLOSE_IO_DONT_CLOSE_IO_EOF_SEEN_IO_ERR_SEEN_IO_FILE_IO_FILE_complete_IO_FILE_plus_IO_FIXED_IO_FLAGS2_FORTIFY_IO_FLAGS2_MMAP_IO_FLAGS2_NOTCANCEL_IO_FLAGS2_USER_WBUF_IO_HAVE_ST_BLKSIZE_IO_HAVE_SYS_WAIT_IO_HEX_IO_INTERNAL_IO_IN_BACKUP_IO_IS_APPENDING_IO_IS_FILEBUF_IO_LEFT_IO_LINE_BUF_IO_LINKED_IO_MAGIC_IO_MAGIC_MASK_IO_MTSAFE_IO_IO_NO_READS_IO_NO_WRITES_IO_OCT_IO_PENDING_OUTPUT_COUNT_IO_RIGHT_IO_SCIENTIFIC_IO_SHOWBASE_IO_SHOWPOINT_IO_SHOWPOS_IO_SKIPWS_IO_STDIO_IO_STDIO_H_IO_TIED_PUT_GET_IO_UNBUFFERED_IO_UNIFIED_JUMPTABLES_IO_UNITBUF_IO_UPPERCASE_IO_USER_BUF_IO_USER_LOCK_IO_USE_DTOA_IO_USE_OLD_IO_FILE_IO_backup_base_IO_buf_base_IO_buf_end_IO_cleanup_region_end_IO_cleanup_region_start_IO_codecvt_IO_cookie_file_IO_cookie_init_IO_cookie_io_functions_t_IO_feof_IO_feof_unlocked_IO_ferror_IO_ferror_unlocked_IO_file_flags_IO_flockfile_IO_fpos64_t_IO_fpos_t_IO_free_backup_area_IO_free_wbackup_area_IO_ftrylockfile_IO_funlockfile_IO_fwide_IO_fwide_maybe_incompatible_IO_getc_IO_getc_unlocked_IO_getwc_IO_getwc_unlocked_IO_iconv_t_IO_jump_t_IO_last_state_IO_lock_t_IO_marker_IO_off64_t_IO_off_t_IO_padn_IO_peekc_IO_peekc_locked_IO_peekc_unlocked_IO_pid_t_IO_pos_t_IO_putc_IO_putc_unlocked_IO_putwc_IO_putwc_unlocked_IO_read_base_IO_read_end_IO_read_ptr_IO_save_base_IO_save_end_IO_seekoff_IO_seekpos_IO_sgetn_IO_size_t_IO_ssize_t_IO_state_IO_stderr_IO_stdin_IO_stdin_used_IO_stdout_IO_uid_t_IO_va_list_IO_vfprintf_IO_vfscanf_IO_vfwprintf_IO_vfwscanf_IO_wide_data_IO_wint_t_IO_wpadn_IO_write_base_IO_write_end_IO_write_ptr_ISOC99_SOURCE_ISOC9X_SOURCE_LARGEFILE64_SOURCE_LARGEFILE_SOURCE_LIBC_LOOSE_KERNEL_NAMES_MACHINE_ANSI_H__OLD_STDIO_MAGIC_PARAMS_POSIX_C_SOURCE_POSIX_SOURCE_PTRDIFF_T_PTRDIFF_T__REENTRANT_RUNE_T_DECLARED_SCO_DS_SIZET__SIZE_T_SIZE_T__SIZE_T_DECLARED_SIZE_T_DEFINED_SIZE_T_DEFINED__STATBUF_ST_BLKSIZE_STAT_VER_STDARG_H_STDDEF_H_STDDEF_H__STDIO_H_STDIO_USES_IOSTREAM_SVID_SOURCE_SYS_CDEFS_H_SYS_SIZE_T_H_THREAD_SAFE_TYPE_ptrdiff_t_TYPE_size_t_TYPE_wchar_t_T_PTRDIFF_T_PTRDIFF__T_SIZE_T_SIZE__T_WCHAR_T_WCHAR__Unwind_Resume_Unwind_SjLj_Register_Unwind_SjLj_Unregister_VA_LIST_VA_LIST__VA_LIST_DEFINED_VA_LIST_T_H_WCHAR_H_WCHAR_T_WCHAR_T__WCHAR_T_DECLARED_WCHAR_T_DEFINED_WCHAR_T_DEFINED__WCHAR_T_H_WINT_T_XOPEN_SOURCE_XOPEN_SOURCE_EXTENDED__ASMNAME__ASMNAME2__ASSEMBLER____BEGIN_DECLS__BEGIN_NAMESPACE_C99__BEGIN_NAMESPACE_STD__BEOS____BLKCNT64_T_TYPE__BLKCNT_T_TYPE__BLKSIZE_T_TYPE__BOUNDED_POINTERS____BSD_NET2____BSD_VISIBLE__CLOCKID_T_TYPE__CLOCK_T_TYPE__CONCAT__CPLUSPLUS__DADDR_T_TYPE__DEV_T_TYPE__END_DECLS__END_NAMESPACE_C99__END_NAMESPACE_STD__FAVOR_BSD__FD_SETSIZE__FILE__FILE_defined__FSBLKCNT64_T_TYPE__FSBLKCNT_T_TYPE__FSFILCNT64_T_TYPE__FSFILCNT_T_TYPE__FSID_T_TYPE__FUNCTION____FreeBSD____GCONV_EMPTY_INPUT__GCONV_FULL_OUTPUT__GCONV_IGNORE_ERRORS__GCONV_ILLEGAL_DESCRIPTOR__GCONV_ILLEGAL_INPUT__GCONV_INCOMPLETE_INPUT__GCONV_INTERNAL_ERROR__GCONV_IS_LAST__GCONV_NOCONV__GCONV_NODB__GCONV_NOMEM__GCONV_OK__GID_T_TYPE__GLIBC_HAVE_LONG_LONG__GLIBC_MINOR____GLIBC_PREREQ__GLIBC____GNUC_PREREQ__GNUC_VA_LIST__GNU_LIBRARY____HAVE_COLUMN__HI____ID_T_TYPE__INO64_T_TYPE__INO_T_TYPE__INTEL_COMPILER__INT_WCHAR_T_H__KERNEL_STRICT_NAMES__KEY_T_TYPE__LDBL_COMPAT__LDBL_REDIR__LDBL_REDIR1__LDBL_REDIR1_DECL__LDBL_REDIR1_NTH__LDBL_REDIR_DECL__LDBL_REDIR_NTH__LONG_DOUBLE_MATH_OPTIONAL__MODE_T_TYPE__NLINK_T_TYPE__NO_LONG_DOUBLE_MATH__NTH__NetBSD____OFF64_T_TYPE__OFF_T_TYPE__OPTIMIZE_SIZE____OPTIMIZE____P__PDCURSES____PGI__PID_T_TYPE__PMT__PRETTY_FUNCTION____PTRDIFF_T__REDIRECT__REDIRECT_NTH__RLIM64_T_TYPE__RLIM_T_TYPE__S16_TYPE__S32_TYPE__S64_TYPE__SIZE_T__SIZE_T____SI____SLONG32_TYPE__SLONGWORD_TYPE__SQUAD_TYPE__SSIZE_T_TYPE__STDC_IEC_559_COMPLEX____STDC_IEC_559____STDC_ISO_10646____STDC_VERSION____STDDEF_H____STD_TYPE__STRICT_ANSI____STRING__SUSECONDS_T_TYPE__SWBLK_T_TYPE__SWORD_TYPE__THROW__TIMER_T_TYPE__TIME_T_TYPE__U16_TYPE__U32_TYPE__U64_TYPE__UID_T_TYPE__ULONG32_TYPE__ULONGWORD_TYPE__UNKNOWN_10646_CHAR__UQUAD_TYPE__USECONDS_T_TYPE__USE_ANSI__USE_ATFILE__USE_BSD__USE_EXTERN_INLINES__USE_FILE_OFFSET64__USE_FORTIFY_LEVEL__USE_GNU__USE_ISOC99__USE_LARGEFILE__USE_LARGEFILE64__USE_MISC__USE_POSIX__USE_POSIX199309__USE_POSIX199506__USE_POSIX2__USE_REENTRANT__USE_SVID__USE_UNIX98__USE_XOPEN__USE_XOPEN2K__USE_XOPEN_EXTENDED__USING_NAMESPACE_C99__USING_NAMESPACE_STD__UWORD_TYPE__VA_ARGS____VA_LIST__WCHAR_MAX__WCHAR_MIN__WCHAR_T__WCHAR_T____WORDSIZE__WORDSIZE_COMPAT32____386BSD________FILE_defined___int_ptrdiff_t_h___int_size_t_h___int_wchar_t_h__accept__adddf3__adddi3__addsf3__addtf3__addti3__addvdi3__addvti3__addxf3__alignof__alignof____always_inline__always_inline____anddi3__andti3__arg__args__array_type_info__array_type_info_pseudo__ashldi3__ashlti3__ashrdi3__ashrti3__asm__asm____asprintf__attribute__attribute____attribute_deprecated____attribute_format_arg____attribute_format_strfmon____attribute_malloc____attribute_noinline____attribute_pure____attribute_used____attribute_warn_unused_result____base__base_class_type_info_pseudo__base_ctor __base_dtor __blkcnt64_t__blkcnt_t__blksize_t__bos__bos0__bounded__bsdi____btowc_alias__btowc_fct__buf__bufloc__builtin__Exit__builtin___fprintf_chk__builtin___memcpy_chk__builtin___memmove_chk__builtin___mempcpy_chk__builtin___memset_chk__builtin___printf_chk__builtin___snprintf_chk__builtin___sprintf_chk__builtin___stpcpy_chk__builtin___strcat_chk__builtin___strcpy_chk__builtin___strncat_chk__builtin___strncpy_chk__builtin___vfprintf_chk__builtin___vprintf_chk__builtin___vsnprintf_chk__builtin___vsprintf_chk__builtin__exit__builtin_abort__builtin_abs__builtin_acos__builtin_acosf__builtin_acosh__builtin_acoshf__builtin_acoshl__builtin_acosl__builtin_adjust_trampoline__builtin_aggregate_incoming_address__builtin_alloca__builtin_apply__builtin_apply_args__builtin_args_info__builtin_asin__builtin_asinf__builtin_asinh__builtin_asinhf__builtin_asinhl__builtin_asinl__builtin_atan__builtin_atan2__builtin_atan2f__builtin_atan2l__builtin_atanf__builtin_atanh__builtin_atanhf__builtin_atanhl__builtin_atanl__builtin_bcmp__builtin_bcopy__builtin_bzero__builtin_cabs__builtin_cabsf__builtin_cabsl__builtin_cacos__builtin_cacosf__builtin_cacosh__builtin_cacoshf__builtin_cacoshl__builtin_cacosl__builtin_calloc__builtin_carg__builtin_cargf__builtin_cargl__builtin_casin__builtin_casinf__builtin_casinh__builtin_casinhf__builtin_casinhl__builtin_casinl__builtin_catan__builtin_catanf__builtin_catanh__builtin_catanhf__builtin_catanhl__builtin_catanl__builtin_cbrt__builtin_cbrtf__builtin_cbrtl__builtin_ccos__builtin_ccosf__builtin_ccosh__builtin_ccoshf__builtin_ccoshl__builtin_ccosl__builtin_ceil__builtin_ceilf__builtin_ceill__builtin_cexp__builtin_cexpf__builtin_cexpl__builtin_cimag__builtin_cimagf__builtin_cimagl__builtin_classify_type__builtin_clog__builtin_clog10__builtin_clog10f__builtin_clog10l__builtin_clogf__builtin_clogl__builtin_clz__builtin_clzimax__builtin_clzl__builtin_clzll__builtin_conj__builtin_conjf__builtin_conjl__builtin_constant_p__builtin_copysign__builtin_copysignf__builtin_copysignl__builtin_cos__builtin_cosf__builtin_cosh__builtin_coshf__builtin_coshl__builtin_cosl__builtin_cpow__builtin_cpowf__builtin_cpowl__builtin_cproj__builtin_cprojf__builtin_cprojl__builtin_creal__builtin_crealf__builtin_creall__builtin_csin__builtin_csinf__builtin_csinh__builtin_csinhf__builtin_csinhl__builtin_csinl__builtin_csqrt__builtin_csqrtf__builtin_csqrtl__builtin_ctan__builtin_ctanf__builtin_ctanh__builtin_ctanhf__builtin_ctanhl__builtin_ctanl__builtin_ctz__builtin_ctzimax__builtin_ctzl__builtin_ctzll__builtin_dcgettext__builtin_dgettext__builtin_drem__builtin_dremf__builtin_dreml__builtin_dwarf_cfa__builtin_dwarf_sp_column__builtin_eh_return__builtin_eh_return_data_regno__builtin_erf__builtin_erfc__builtin_erfcf__builtin_erfcl__builtin_erff__builtin_erfl__builtin_execl__builtin_execle__builtin_execlp__builtin_execv__builtin_execve__builtin_execvp__builtin_exit__builtin_exp__builtin_exp10__builtin_exp10f__builtin_exp10l__builtin_exp2__builtin_exp2f__builtin_exp2l__builtin_expect__builtin_expf__builtin_expl__builtin_expm1__builtin_expm1f__builtin_expm1l__builtin_extend_pointer__builtin_extract_return_addr__builtin_fabs__builtin_fabsf__builtin_fabsl__builtin_fdim__builtin_fdimf__builtin_fdiml__builtin_ffs__builtin_ffsimax__builtin_ffsl__builtin_ffsll__builtin_finite__builtin_finitef__builtin_finitel__builtin_floor__builtin_floorf__builtin_floorl__builtin_fma__builtin_fmaf__builtin_fmal__builtin_fmax__builtin_fmaxf__builtin_fmaxl__builtin_fmin__builtin_fminf__builtin_fminl__builtin_fmod__builtin_fmodf__builtin_fmodl__builtin_fork__builtin_fprintf__builtin_fprintf_unlocked__builtin_fputc__builtin_fputc_unlocked__builtin_fputs__builtin_fputs_unlocked__builtin_frame_address__builtin_frexp__builtin_frexpf__builtin_frexpl__builtin_frob_return_addr__builtin_fscanf__builtin_fwrite__builtin_fwrite_unlocked__builtin_gamma__builtin_gammaf__builtin_gammal__builtin_gettext__builtin_huge_val__builtin_huge_valf__builtin_huge_vall__builtin_hypot__builtin_hypotf__builtin_hypotl__builtin_ia32_addpd__builtin_ia32_addps__builtin_ia32_addsd__builtin_ia32_addss__builtin_ia32_andnpd__builtin_ia32_andnps__builtin_ia32_andpd__builtin_ia32_andps__builtin_ia32_clflush__builtin_ia32_cmpeqpd__builtin_ia32_cmpeqps__builtin_ia32_cmpeqsd__builtin_ia32_cmpeqss__builtin_ia32_cmpgepd__builtin_ia32_cmpgeps__builtin_ia32_cmpgtpd__builtin_ia32_cmpgtps__builtin_ia32_cmplepd__builtin_ia32_cmpleps__builtin_ia32_cmplesd__builtin_ia32_cmpless__builtin_ia32_cmpltpd__builtin_ia32_cmpltps__builtin_ia32_cmpltsd__builtin_ia32_cmpltss__builtin_ia32_cmpneqpd__builtin_ia32_cmpneqps__builtin_ia32_cmpneqsd__builtin_ia32_cmpneqss__builtin_ia32_cmpngepd__builtin_ia32_cmpngeps__builtin_ia32_cmpngess__builtin_ia32_cmpngtpd__builtin_ia32_cmpngtps__builtin_ia32_cmpngtss__builtin_ia32_cmpnlepd__builtin_ia32_cmpnleps__builtin_ia32_cmpnlesd__builtin_ia32_cmpnless__builtin_ia32_cmpnltpd__builtin_ia32_cmpnltps__builtin_ia32_cmpnltsd__builtin_ia32_cmpnltss__builtin_ia32_cmpordpd__builtin_ia32_cmpordps__builtin_ia32_cmpordsd__builtin_ia32_cmpordss__builtin_ia32_cmpunordpd__builtin_ia32_cmpunordps__builtin_ia32_cmpunordsd__builtin_ia32_cmpunordss__builtin_ia32_comieq__builtin_ia32_comige__builtin_ia32_comigt__builtin_ia32_comile__builtin_ia32_comilt__builtin_ia32_comineq__builtin_ia32_comisdeq__builtin_ia32_comisdge__builtin_ia32_comisdgt__builtin_ia32_comisdle__builtin_ia32_comisdlt__builtin_ia32_comisdneq__builtin_ia32_cvtdq2pd__builtin_ia32_cvtdq2ps__builtin_ia32_cvtpd2dq__builtin_ia32_cvtpd2pi__builtin_ia32_cvtpd2ps__builtin_ia32_cvtpi2pd__builtin_ia32_cvtpi2ps__builtin_ia32_cvtps2dq__builtin_ia32_cvtps2pd__builtin_ia32_cvtps2pi__builtin_ia32_cvtsd2si__builtin_ia32_cvtsd2si64__builtin_ia32_cvtsd2ss__builtin_ia32_cvtsi2sd__builtin_ia32_cvtsi2ss__builtin_ia32_cvtsi642sd__builtin_ia32_cvtsi642ss__builtin_ia32_cvtss2sd__builtin_ia32_cvtss2si__builtin_ia32_cvtss2si64__builtin_ia32_cvttpd2dq__builtin_ia32_cvttpd2pi__builtin_ia32_cvttps2dq__builtin_ia32_cvttps2pi__builtin_ia32_cvttsd2si__builtin_ia32_cvttsd2si64__builtin_ia32_cvttss2si__builtin_ia32_cvttss2si64__builtin_ia32_divpd__builtin_ia32_divps__builtin_ia32_divsd__builtin_ia32_divss__builtin_ia32_emms__builtin_ia32_ldmxcsr__builtin_ia32_lfence__builtin_ia32_loaddqu__builtin_ia32_loadhpd__builtin_ia32_loadhps__builtin_ia32_loadlpd__builtin_ia32_loadlps__builtin_ia32_loadupd__builtin_ia32_loadups__builtin_ia32_maskmovdqu__builtin_ia32_maskmovq__builtin_ia32_maxpd__builtin_ia32_maxps__builtin_ia32_maxsd__builtin_ia32_maxss__builtin_ia32_mfence__builtin_ia32_minpd__builtin_ia32_minps__builtin_ia32_minsd__builtin_ia32_minss__builtin_ia32_movhlps__builtin_ia32_movlhps__builtin_ia32_movmskpd__builtin_ia32_movmskps__builtin_ia32_movntdq__builtin_ia32_movnti__builtin_ia32_movntpd__builtin_ia32_movntps__builtin_ia32_movntq__builtin_ia32_movsd__builtin_ia32_movss__builtin_ia32_mulpd__builtin_ia32_mulps__builtin_ia32_mulsd__builtin_ia32_mulss__builtin_ia32_orpd__builtin_ia32_orps__builtin_ia32_packssdw__builtin_ia32_packssdw128__builtin_ia32_packsswb__builtin_ia32_packsswb128__builtin_ia32_packuswb__builtin_ia32_packuswb128__builtin_ia32_paddb__builtin_ia32_paddb128__builtin_ia32_paddd__builtin_ia32_paddd128__builtin_ia32_paddq__builtin_ia32_paddq128__builtin_ia32_paddsb__builtin_ia32_paddsb128__builtin_ia32_paddsw__builtin_ia32_paddsw128__builtin_ia32_paddusb__builtin_ia32_paddusb128__builtin_ia32_paddusw__builtin_ia32_paddusw128__builtin_ia32_paddw__builtin_ia32_paddw128__builtin_ia32_pand__builtin_ia32_pand128__builtin_ia32_pandn__builtin_ia32_pandn128__builtin_ia32_pavgb__builtin_ia32_pavgb128__builtin_ia32_pavgw__builtin_ia32_pavgw128__builtin_ia32_pcmpeqb__builtin_ia32_pcmpeqb128__builtin_ia32_pcmpeqd__builtin_ia32_pcmpeqd128__builtin_ia32_pcmpeqw__builtin_ia32_pcmpeqw128__builtin_ia32_pcmpgtb__builtin_ia32_pcmpgtb128__builtin_ia32_pcmpgtd__builtin_ia32_pcmpgtd128__builtin_ia32_pcmpgtw__builtin_ia32_pcmpgtw128__builtin_ia32_pmaddwd__builtin_ia32_pmaddwd128__builtin_ia32_pmaxsw__builtin_ia32_pmaxsw128__builtin_ia32_pmaxub__builtin_ia32_pmaxub128__builtin_ia32_pminsw__builtin_ia32_pminsw128__builtin_ia32_pminub__builtin_ia32_pminub128__builtin_ia32_pmovmskb__builtin_ia32_pmovmskb128__builtin_ia32_pmulhuw__builtin_ia32_pmulhuw128__builtin_ia32_pmulhw__builtin_ia32_pmulhw128__builtin_ia32_pmullw__builtin_ia32_pmullw128__builtin_ia32_pmuludq__builtin_ia32_pmuludq128__builtin_ia32_por__builtin_ia32_por128__builtin_ia32_psadbw__builtin_ia32_psadbw128__builtin_ia32_pshufd__builtin_ia32_pshufhw__builtin_ia32_pshuflw__builtin_ia32_pshufw__builtin_ia32_pslld__builtin_ia32_pslld128__builtin_ia32_pslldi128__builtin_ia32_pslldqi128__builtin_ia32_psllq__builtin_ia32_psllq128__builtin_ia32_psllqi128__builtin_ia32_psllw__builtin_ia32_psllw128__builtin_ia32_psllwi128__builtin_ia32_psrad__builtin_ia32_psrad128__builtin_ia32_psradi128__builtin_ia32_psraw__builtin_ia32_psraw128__builtin_ia32_psrawi128__builtin_ia32_psrld__builtin_ia32_psrld128__builtin_ia32_psrldi128__builtin_ia32_psrldqi128__builtin_ia32_psrlq__builtin_ia32_psrlq128__builtin_ia32_psrlqi128__builtin_ia32_psrlw__builtin_ia32_psrlw128__builtin_ia32_psrlwi128__builtin_ia32_psubb__builtin_ia32_psubb128__builtin_ia32_psubd__builtin_ia32_psubd128__builtin_ia32_psubq__builtin_ia32_psubq128__builtin_ia32_psubsb__builtin_ia32_psubsb128__builtin_ia32_psubsw__builtin_ia32_psubsw128__builtin_ia32_psubusb__builtin_ia32_psubusb128__builtin_ia32_psubusw__builtin_ia32_psubusw128__builtin_ia32_psubw__builtin_ia32_psubw128__builtin_ia32_punpckhbw__builtin_ia32_punpckhbw128__builtin_ia32_punpckhdq__builtin_ia32_punpckhdq128__builtin_ia32_punpckhqdq128__builtin_ia32_punpckhwd__builtin_ia32_punpckhwd128__builtin_ia32_punpcklbw__builtin_ia32_punpcklbw128__builtin_ia32_punpckldq__builtin_ia32_punpckldq128__builtin_ia32_punpcklqdq128__builtin_ia32_punpcklwd__builtin_ia32_punpcklwd128__builtin_ia32_pxor__builtin_ia32_pxor128__builtin_ia32_rcpps__builtin_ia32_rcpss__builtin_ia32_rsqrtps__builtin_ia32_rsqrtss__builtin_ia32_sfence__builtin_ia32_shufpd__builtin_ia32_shufps__builtin_ia32_sqrtpd__builtin_ia32_sqrtps__builtin_ia32_sqrtsd__builtin_ia32_sqrtss__builtin_ia32_stmxcsr__builtin_ia32_storedqu__builtin_ia32_storehps__builtin_ia32_storelps__builtin_ia32_storeupd__builtin_ia32_storeups__builtin_ia32_subpd__builtin_ia32_subps__builtin_ia32_subsd__builtin_ia32_subss__builtin_ia32_ucomieq__builtin_ia32_ucomige__builtin_ia32_ucomigt__builtin_ia32_ucomile__builtin_ia32_ucomilt__builtin_ia32_ucomineq__builtin_ia32_ucomisdeq__builtin_ia32_ucomisdge__builtin_ia32_ucomisdgt__builtin_ia32_ucomisdle__builtin_ia32_ucomisdlt__builtin_ia32_ucomisdneq__builtin_ia32_unpckhpd__builtin_ia32_unpckhps__builtin_ia32_unpcklpd__builtin_ia32_unpcklps__builtin_ia32_vec_ext_v2df__builtin_ia32_vec_ext_v2di__builtin_ia32_vec_ext_v2si__builtin_ia32_vec_ext_v4hi__builtin_ia32_vec_ext_v4sf__builtin_ia32_vec_ext_v4si__builtin_ia32_vec_ext_v8hi__builtin_ia32_vec_init_v2si__builtin_ia32_vec_init_v4hi__builtin_ia32_vec_init_v8qi__builtin_ia32_vec_set_v4hi__builtin_ia32_vec_set_v8hi__builtin_ia32_xorpd__builtin_ia32_xorps__builtin_ilogb__builtin_ilogbf__builtin_ilogbl__builtin_imaxabs__builtin_index__builtin_inf__builtin_inff__builtin_infl__builtin_init_dwarf_reg_size_table__builtin_init_trampoline__builtin_isalnum__builtin_isalpha__builtin_isascii__builtin_isblank__builtin_iscntrl__builtin_isdigit__builtin_isgraph__builtin_isgreater__builtin_isgreaterequal__builtin_isinf__builtin_isinff__builtin_isinfl__builtin_isless__builtin_islessequal__builtin_islessgreater__builtin_islower__builtin_isnan__builtin_isnanf__builtin_isnanl__builtin_isprint__builtin_ispunct__builtin_isspace__builtin_isunordered__builtin_isupper__builtin_iswalnum__builtin_iswalpha__builtin_iswblank__builtin_iswcntrl__builtin_iswdigit__builtin_iswgraph__builtin_iswlower__builtin_iswprint__builtin_iswpunct__builtin_iswspace__builtin_iswupper__builtin_iswxdigit__builtin_isxdigit__builtin_j0__builtin_j0f__builtin_j0l__builtin_j1__builtin_j1f__builtin_j1l__builtin_jn__builtin_jnf__builtin_jnl__builtin_labs__builtin_lceil__builtin_lceilf__builtin_lceill__builtin_ldexp__builtin_ldexpf__builtin_ldexpl__builtin_lfloor__builtin_lfloorf__builtin_lfloorl__builtin_lgamma__builtin_lgammaf__builtin_lgammal__builtin_llabs__builtin_llceil__builtin_llceilf__builtin_llceill__builtin_llfloor__builtin_llfloorf__builtin_llfloorl__builtin_llrint__builtin_llrintf__builtin_llrintl__builtin_llround__builtin_llroundf__builtin_llroundl__builtin_log__builtin_log10__builtin_log10f__builtin_log10l__builtin_log1p__builtin_log1pf__builtin_log1pl__builtin_log2__builtin_log2f__builtin_log2l__builtin_logb__builtin_logbf__builtin_logbl__builtin_logf__builtin_logl__builtin_longjmp__builtin_lrint__builtin_lrintf__builtin_lrintl__builtin_lround__builtin_lroundf__builtin_lroundl__builtin_malloc__builtin_memcmp__builtin_memcpy__builtin_memmove__builtin_mempcpy__builtin_memset__builtin_modf__builtin_modff__builtin_modfl__builtin_nan__builtin_nanf__builtin_nanl__builtin_nans__builtin_nansf__builtin_nansl__builtin_nearbyint__builtin_nearbyintf__builtin_nearbyintl__builtin_next_arg__builtin_nextafter__builtin_nextafterf__builtin_nextafterl__builtin_nexttoward__builtin_nexttowardf__builtin_nexttowardl__builtin_nonlocal_goto__builtin_object_size__builtin_offsetof__builtin_parity__builtin_parityimax__builtin_parityl__builtin_parityll__builtin_popcount__builtin_popcountimax__builtin_popcountl__builtin_popcountll__builtin_pow__builtin_pow10__builtin_pow10f__builtin_pow10l__builtin_powf__builtin_powi__builtin_powif__builtin_powil__builtin_powl__builtin_prefetch__builtin_printf__builtin_printf_unlocked__builtin_profile_func_enter__builtin_profile_func_exit__builtin_putchar__builtin_putchar_unlocked__builtin_puts__builtin_puts_unlocked__builtin_remainder__builtin_remainderf__builtin_remainderl__builtin_remquo__builtin_remquof__builtin_remquol__builtin_return__builtin_return_address__builtin_rindex__builtin_rint__builtin_rintf__builtin_rintl__builtin_round__builtin_roundf__builtin_roundl__builtin_saveregs__builtin_scalb__builtin_scalbf__builtin_scalbl__builtin_scalbln__builtin_scalblnf__builtin_scalblnl__builtin_scalbn__builtin_scalbnf__builtin_scalbnl__builtin_scanf__builtin_setjmp__builtin_signbit__builtin_signbitf__builtin_signbitl__builtin_significand__builtin_significandf__builtin_significandl__builtin_sin__builtin_sincos__builtin_sincosf__builtin_sincosl__builtin_sinf__builtin_sinh__builtin_sinhf__builtin_sinhl__builtin_sinl__builtin_snprintf__builtin_sprintf__builtin_sqrt__builtin_sqrtf__builtin_sqrtl__builtin_sscanf__builtin_stack_restore__builtin_stack_save__builtin_stdarg_start__builtin_stpcpy__builtin_stpncpy__builtin_strcasecmp__builtin_strcat__builtin_strchr__builtin_strcmp__builtin_strcpy__builtin_strcspn__builtin_strdup__builtin_strfmon__builtin_strftime__builtin_strlen__builtin_strncasecmp__builtin_strncat__builtin_strncmp__builtin_strncpy__builtin_strndup__builtin_strpbrk__builtin_strrchr__builtin_strspn__builtin_strstr__builtin_tan__builtin_tanf__builtin_tanh__builtin_tanhf__builtin_tanhl__builtin_tanl__builtin_tgamma__builtin_tgammaf__builtin_tgammal__builtin_toascii__builtin_tolower__builtin_toupper__builtin_towlower__builtin_towupper__builtin_trap__builtin_trunc__builtin_truncf__builtin_truncl__builtin_unwind_init__builtin_update_setjmp_buf__builtin_va_arg__builtin_va_arg_pack__builtin_va_arg_pack_len__builtin_va_copy__builtin_va_end__builtin_va_list__builtin_va_start__builtin_vfprintf__builtin_vfscanf__builtin_vprintf__builtin_vscanf__builtin_vsnprintf__builtin_vsprintf__builtin_vsscanf__builtin_y0__builtin_y0f__builtin_y0l__builtin_y1__builtin_y1f__builtin_y1l__builtin_yn__builtin_ynf__builtin_ynl__c__c99__caddr_t__cd__cd_in__cd_out__cfile__class_type_info__class_type_info_pseudo__clock_t__clockid_t__clzdi2__clzti2__cmpdf2__cmpdi2__cmpsf2__cmptf2__cmpti2__cmpxf2__codecvt_destr__codecvt_do_always_noconv__codecvt_do_encoding__codecvt_do_in__codecvt_do_length__codecvt_do_max_length__codecvt_do_out__codecvt_do_unshift__codecvt_error__codecvt_noconv__codecvt_ok__codecvt_partial__codecvt_result__combined__command__comp_ctor __comp_dtor __complex__complex____const__const____cookie__count__counter__cplusplus____ct __ctzdi2__ctzti2__cxa_call_unexpected__cxa_pure_virtual__cxxabiv1__cyg_profile_func_enter__cyg_profile_func_exit__daddr_t__data__declspec__deleting_dtor __delim__delimiter__delta__deprecated____dest__dev_t__dir__divdc3__divdf3__divdi3__divmoddi4__divmodti4__divsc3__divsf3__divtf3__divti3__divvdi3__divvti3__divxc3__divxf3__dst__dt __end_fct__endptr__enum_type_info__enum_type_info_pseudo__eqdf2__eqsf2__eqtf2__eqxf2__extenddftf2__extenddfxf2__extendsfdf2__extendsftf2__extendsfxf2__extendxftf2__extension____f__fct__fd__ffsdi2__ffsti2__filename__fixdfdi__fixdfhi__fixdfqi__fixdfsi__fixdfti__fixsfdi__fixsfhi__fixsfqi__fixsfsi__fixsfti__fixtfdi__fixtfhi__fixtfqi__fixtfsi__fixtfti__fixunsdfdi__fixunsdfhi__fixunsdfqi__fixunsdfsi__fixunsdfti__fixunssfdi__fixunssfhi__fixunssfqi__fixunssfsi__fixunssfti__fixunstfdi__fixunstfhi__fixunstfqi__fixunstfsi__fixunstfti__fixunsxfdi__fixunsxfhi__fixunsxfqi__fixunsxfsi__fixunsxfti__fixxfdi__fixxfhi__fixxfqi__fixxfsi__fixxfti__flags__flexarr__float128__float80__floatdidf__floatdisf__floatditf__floatdixf__floathidf__floathisf__floathitf__floathixf__floatqidf__floatqisf__floatqitf__floatqixf__floatsidf__floatsisf__floatsitf__floatsixf__floattidf__floattisf__floattitf__floattixf__fmt__fns__format__format____format_arg____fp__fprintf_chk__from_name__fsblkcnt64_t__fsblkcnt_t__fsfilcnt64_t__fsfilcnt_t__fsid_t__ftruncdf2__ftruncsf2__ftrunctf2__ftruncxf2__func____function_type_info__function_type_info_pseudo__fundamental_type_info__fundamental_type_info_pseudo__fxstat64__gconv_btowc_fct__gconv_end_fct__gconv_fct__gconv_info__gconv_init_fct__gconv_loaded_object__gconv_step__gconv_step_data__gconv_t__gconv_trans_context_fct__gconv_trans_data__gconv_trans_end_fct__gconv_trans_fct__gconv_trans_init_fct__gconv_trans_query_fct__gcov_flush__gedf2__gesf2__getdelim__getf2__gexf2__gid_t__gnuc_va_list__group__gtdf2__gtsf2__gttf2__gtxf2__gxx_personality_v0__haystack__i386____i860____ia64____id_t__imag__imag____in_chrg__init_fct__inline__inline____ino64_t__ino_t__int128_t__int16_t__int32_t__int64_t__int8_t__internal_use__intptr_t__invocation_counter__io_close_fn__io_funcs__io_read_fn__io_seek_fn__io_write_fn__iordi3__iorti3__java_boolean__java_byte__java_char__java_double__java_float__java_int__java_long__java_short__key_t__label____ledf2__len__lesf2__letf2__lexf2__lineptr__loc__locale_t__loff_t__long_double_t__lseek64__lshrdi3__lshrti3__ltdf2__ltsf2__lttf2__ltxf2__magic_cookie__malloc____max_needed_from__max_needed_to__maxdf3__maxdi3__maxlen__maxsf3__maxsize__maxtf3__maxti3__maxxf3__mbrlen__mbstate_t__mbstate_t_defined__memcpy_chk__memmove_chk__mempcpy_chk__memset_chk__min_needed_from__min_needed_to__mindf3__mindi3__minsf3__mintf3__minti3__minxf3__mmap64__moddi3__mode__mode____mode_t__modes__modname__modti3__muldc3__muldf3__muldi3__mulsc3__mulsf3__multf3__multi3__mulvdi3__mulvti3__mulxc3__mulxf3__n__nbytes__nedf2__need_FILE__need_FOPEN_MAX__need_IOV_MAX__need_NULL__need___FILE__need___va_list__need_getopt__need_iswxxx__need_mbstate_t__need_ptrdiff_t__need_size_t__need_wchar_t__need_wint_t__needle__negdf2__negdi2__negsf2__negtf2__negti2__negvdi2__negvti2__negxf2__nesf2__netf2__new__newfd__nexf2__next__nldbl___nlink_t__nmc__noinline____nonnull__nonnull____nothrow____npt__nptr__nsteps__null__nwc__obstack__off__off64_t__off_t__old__oldfd__one_cmpldi2__one_cmplti2__open64__outbuf__outbufend__overflow__p__pad1__pad2__pad3__pad4__pad5__paritydi2__parityti2__pfn__pfx__pid_t__pointer_to_member_type_info__pointer_to_member_type_info_pseudo__pointer_type_info__pointer_type_info_pseudo__popcountdi2__popcountti2__pos__powidf2__powisf2__powitf2__powixf2__printf____printf_chk__ps__ptr__ptr_t__ptrvalue__pure____pwc__qaddr_t__quad_t__read_write__real__real____reject__restrict__restrict____restrict_arr__result__rlim64_t__rlim_t__rune_t__s__s1__s2__scanf____sequent____setbits__shlib_handle__si_class_type_info__si_class_type_info_pseudo__signed__signed____size__size_t__size_t____sizeloc__snprintf_chk__socklen_t__sprintf_chk__src__ssize_t__state__stateful__statep__steps__stpcpy_chk__strcat_chk__strcpy_chk__stream__strfmon____strncat_chk__strncpy_chk__stub___kernel_cosl__stub___kernel_rem_pio2l__stub___kernel_sinl__stub___kernel_tanl__stub_bdflush__stub_chflags__stub_fattach__stub_fchflags__stub_fdetach__stub_feupdateenv__stub_getmsg__stub_gtty__stub_lchmod__stub_lutimes__stub_putmsg__stub_revoke__stub_setlogin__stub_sigreturn__stub_sstk__stub_stty__subdf3__subdi3__subsf3__subtf3__subti3__subvdi3__subvti3__subxf3__suseconds_t__svr4____swblk_t__sync_add_and_fetch__sync_add_and_fetch_1__sync_add_and_fetch_16__sync_add_and_fetch_2__sync_add_and_fetch_4__sync_add_and_fetch_8__sync_and_and_fetch__sync_and_and_fetch_1__sync_and_and_fetch_16__sync_and_and_fetch_2__sync_and_and_fetch_4__sync_and_and_fetch_8__sync_bool_compare_and_swap__sync_bool_compare_and_swap_1__sync_bool_compare_and_swap_16__sync_bool_compare_and_swap_2__sync_bool_compare_and_swap_4__sync_bool_compare_and_swap_8__sync_fetch_and_add__sync_fetch_and_add_1__sync_fetch_and_add_16__sync_fetch_and_add_2__sync_fetch_and_add_4__sync_fetch_and_add_8__sync_fetch_and_and__sync_fetch_and_and_1__sync_fetch_and_and_16__sync_fetch_and_and_2__sync_fetch_and_and_4__sync_fetch_and_and_8__sync_fetch_and_nand__sync_fetch_and_nand_1__sync_fetch_and_nand_16__sync_fetch_and_nand_2__sync_fetch_and_nand_4__sync_fetch_and_nand_8__sync_fetch_and_or__sync_fetch_and_or_1__sync_fetch_and_or_16__sync_fetch_and_or_2__sync_fetch_and_or_4__sync_fetch_and_or_8__sync_fetch_and_sub__sync_fetch_and_sub_1__sync_fetch_and_sub_16__sync_fetch_and_sub_2__sync_fetch_and_sub_4__sync_fetch_and_sub_8__sync_fetch_and_xor__sync_fetch_and_xor_1__sync_fetch_and_xor_16__sync_fetch_and_xor_2__sync_fetch_and_xor_4__sync_fetch_and_xor_8__sync_lock_release__sync_lock_release_1__sync_lock_release_16__sync_lock_release_2__sync_lock_release_4__sync_lock_release_8__sync_lock_test_and_set__sync_lock_test_and_set_1__sync_lock_test_and_set_16__sync_lock_test_and_set_2__sync_lock_test_and_set_4__sync_lock_test_and_set_8__sync_nand_and_fetch__sync_nand_and_fetch_1__sync_nand_and_fetch_16__sync_nand_and_fetch_2__sync_nand_and_fetch_4__sync_nand_and_fetch_8__sync_or_and_fetch__sync_or_and_fetch_1__sync_or_and_fetch_16__sync_or_and_fetch_2__sync_or_and_fetch_4__sync_or_and_fetch_8__sync_sub_and_fetch__sync_sub_and_fetch_1__sync_sub_and_fetch_16__sync_sub_and_fetch_2__sync_sub_and_fetch_4__sync_sub_and_fetch_8__sync_synchronize__sync_val_compare_and_swap__sync_val_compare_and_swap_1__sync_val_compare_and_swap_16__sync_val_compare_and_swap_2__sync_val_compare_and_swap_4__sync_val_compare_and_swap_8__sync_xor_and_fetch__sync_xor_and_fetch_1__sync_xor_and_fetch_16__sync_xor_and_fetch_2__sync_xor_and_fetch_4__sync_xor_and_fetch_8__sys_stdtypes_h__thread__time_t__timer_t__to_name__tp__trans__trans_context_fct__trans_end_fct__trans_fct__truncdfsf2__trunctfdf2__trunctfsf2__trunctfxf2__truncxfdf2__truncxfsf2__type_info_pseudo__typeof__typeof____u_char__u_int__u_long__u_quad_t__u_short__ucmpdi2__ucmpti2__udivdi3__udivmoddi4__udivmodti4__udivti3__uflow__uid_t__uint128_t__uint16_t__uint32_t__uint64_t__uint8_t__umaxdi3__umaxti3__umindi3__uminti3__umoddi3__umodti3__unbounded__underflow__unorddf2__unordsf2__unordtf2__unordxf2__unused____useconds_t__used____va_copy__va_list____va_list_tag__val__value__vfprintf_chk__volatile__volatile____vprintf_chk__vsnprintf_chk__vsprintf_chk__vt___vtbl_ptr_type__vtt_parm__w__warn_unused_result____warndecl__wc__wch__wchar_t____wchb__wcs__wcstod_internal__wcstof_internal__wcstol_internal__wcstol_internal_defined__wcstold_internal__wcstoll_internal__wcstoll_internal_defined__wcstoul_internal__wcstoul_internal_defined__wcstoull_internal__wcstoull_internal_defined__wctob_alias__whence__woverflow__ws__wuflow__wunderflow__wur__xordi3__xorti3_attrs_begx_begy_bkgd_blksize_bmarg_bool_ch_chain_clear_codecvt_cur_column_curx_cury_delayms_exit_fct_file_fileno_firstch_flags_flags2_fp_freeres_buf_freeres_list_freeres_size_immed_lastch_leaveit_lock_map_mbe_to_key_markers_maxx_maxy_mode_next_nodelay_offset_old_offset_parent_parx_pary_pos_preserve_restore_sbuf_scroll_shortbuf_spos_sync_sys_errlist_sys_nerr_tmarg_trap_mbe_unused2_use_keypad_vptr_vtable_offset_wch_wide_data_wide_vtable_win_yaabortabsacosacosfacoshacoshfacoshlacoslacs_mapadd_wchadd_wchnstradd_wchstraddchaddchnstraddchstraddnstraddnwstraddrawchaddstraddwstraliasaliveallocaallocatorandand_eqargsasinasinfasinhasinhfasinhlasinlasmasm_fprintfasprintfassertassume_default_colorsatanatan2atan2fatan2latanfatanhatanhfatanhlatanlattr_getattr_offattr_onattr_setattr_tattribute_hiddenattroffattronattrsetaudibleautoautocrbbad_allocbasic_iostreambasic_istreambasic_ostreambasic_stringbaudratebcmpbcopybeepbit_size_typebitandbitorbkgdbkgdsetboolborderborder_setboxbox_setbreakbstatebtowcbufbuttonbycopybyrefbzerocabscabsfcabslcacoscacosfcacoshcacoshfcacoshlcacoslcalloccan_change_colorcargcargfcarglcasecasincasinfcasinhcasinhfcasinhlcasinlcatancatanfcatanhcatanhfcatanhlcatanlcatchcbreakcbrtcbrtfcbrtlcchar_tccosccosfccoshccoshfccoshlccoslceilceilfceillcexpcexpfcexplchchangescharchar_traitschgatchtypecimagcimagfcimaglclassclearclearerrclearerr_unlockedclearokclogclog10clog10fclog10lclogfcloglcloseclrtobotclrtoeolcnamecolor_contentcolor_setcolscompatibility_aliascomplcomplex doublecomplex floatcomplex intcomplex long doubleconjconjfconjlconstconst_castcontinuecookie_close_function_tcookie_io_functions_tcookie_read_function_tcookie_seek_function_tcookie_write_function_tcopysigncopysignfcopysignlcopywincoscosfcoshcoshfcoshlcoslcpowcpowfcpowlcprojcprojfcprojlcpucrealcrealfcreallcrmodecsincsinfcsinhcsinhfcsinhlcsinlcsqrtcsqrtfcsqrtlctanctanfctanhctanhfctanhlctanlctermidcurs_setcurscolcurscrcurses_versioncursrowcuseridddcgettextdef_prog_modedef_shell_modedefaultdefinedefineddefsdelay_outputdelaytenthsdelchdeletedeletelndelscreendeltadelwindependencyderwindgettextdllexportdllimportdodoubledoupdatedprintfdrainodremdremfdremldupwindynamic_castechoecho_wcharechocharelifelseencodeendendifendwinenumeraseerasecharerasewcharerferfcerfcferfclerfferflerrorexeclexecleexeclpexecvexecveexecvpexitexpexp10exp10fexp10lexp2exp2fexp2lexpfexplexplicitexpm1expm1fexpm1lexportexprexternextern_prefixffabsfabsffabslfalsefclosefcloseallfctfdfdimfdimffdimlfdopenfeoffeof_unlockedferrorferror_unlockedfflushfflush_unlockedffsffsimaxffslffsllfgetcfgetc_unlockedfgetposfgetpos64fgetsfgets_unlockedfgetwcfgetwc_unlockedfgetwsfgetws_unlockedfilenofileno_unlockedfilterfinallyfinitefiniteffinitelfixtermflashfloatflockfilefloorfloorffloorlflushinpfmafmaffmalfmaxfmaxffmaxlfmemopenfminfminffminlfmodfmodffmodlfopenfopen64fopencookieforforkformatformat_argfp_offsetfpos64_tfpos_tfprintffprintf_unlockedfputcfputc_unlockedfputsfputs_unlockedfputwcfputwc_unlockedfputwsfputws_unlockedfreadfread_unlockedfreopenfreopen64frexpfrexpffrexplfriendfscanffseekfseekofseeko64fsetposfsetpos64ftellftelloftello64ftrylockfilefunlockfilefwidefwprintffwritefwrite_unlockedfwscanfgammagammafgammalgcc_cdiaggcc_cxxdiaggcc_diagget_wchget_wstrgetattrsgetbegxgetbegygetbegyxgetbkgdgetbkgrndgetbmapgetcgetc_unlockedgetcchargetchgetchargetchar_unlockedgetcurxgetcurygetdelimgetlinegetmaxxgetmaxygetmaxyxgetmousegetn_wstrgetnstrgetparxgetparygetparyxgetsgetstrgetsyxgettextgetwgetwcgetwc_unlockedgetwchargetwchar_unlockedgetwingetyxglobal typegotogp_offsethalfdelayhas_colorshas_ichas_ilhas_keyhlinehline_sethypothypotfhypotlididcokidentidlokififdefifndefilogbilogbfilogblimaxabsimmedokimplementationimportinin_wchin_wchnstrin_wchstrinchinchnstrinchstrincludeinclude_nextindexinit_colorinit_pairinitscrinlineinnstrinnwstrinoutins_nwstrins_wchins_wstrinschinsdellninsertlninsnstrinsrawchinsstrinstrintinterfaceintrflushinwstris_linetouchedis_termresizedis_wintouchedisalnumisalphaisasciiisblankiscntrlisdigitisendwinisgraphisinfisinffisinflislowerisnanisnanfisnanlisprintispunctisspaceisupperiswalnumiswalphaiswblankiswcntrliswdigitiswgraphiswloweriswprintiswpunctiswspaceiswupperiswxdigitisxdigitj0j0fj0lj1j1fj1ljava_exceptionsjnjnfjnlkey_codekey_namekeynamekeypadkillcharkillwcharllabsldexpldexpfldexplleaveoklgammalgammaflgammallibclineline_colorlineslinesrippedofflinesrippedoffontopllabsllrintllrintfllrintlllroundllroundfllroundlloglog10log10flog10llog1plog1pflog1pllog2log2flog2llogblogbflogbllogflogllonglong doublelong intlong long intlong long unsignedlong long unsigned intlong unsigned intlongnamelrintlrintflrintllroundlroundflroundlmachinemacromainmajmallocmap_buttonmaymbrlenmbrtowcmbsinitmbsnrtowcsmbsrtowcsmbstate_tmemcmpmemcpymemmovemempcpymemsetmetaminmmask_tmodfmodffmodflmonomouse_offmouse_onmouse_setmouse_trafomouse_waitmouseintervalmousemaskmovemsgmutablemvadd_wchmvadd_wchnstrmvadd_wchstrmvaddchmvaddchnstrmvaddchstrmvaddnstrmvaddnwstrmvaddrawchmvaddstrmvaddwstrmvchgatmvcurmvdelchmvdeletelnmvderwinmvget_wchmvget_wstrmvgetchmvgetn_wstrmvgetnstrmvgetstrmvhlinemvhline_setmvin_wchmvin_wchnstrmvin_wchstrmvinchmvinchnstrmvinchstrmvinnstrmvinnwstrmvins_nwstrmvins_wchmvins_wstrmvinschmvinsertlnmvinsnstrmvinsrawchmvinsstrmvinstrmvinwstrmvprintwmvscanwmvvlinemvvline_setmvwadd_wchmvwadd_wchnstrmvwadd_wchstrmvwaddchmvwaddchnstrmvwaddchstrmvwaddnstrmvwaddnwstrmvwaddrawchmvwaddstrmvwaddwstrmvwchgatmvwdelchmvwdeletelnmvwget_wchmvwget_wstrmvwgetchmvwgetn_wstrmvwgetnstrmvwgetstrmvwhlinemvwhline_setmvwinmvwin_wchmvwin_wchnstrmvwin_wchstrmvwinchmvwinchnstrmvwinchstrmvwinnstrmvwinnwstrmvwins_nwstrmvwins_wchmvwins_wstrmvwinschmvwinsertlnmvwinsnstrmvwinsrawchmvwinsstrmvwinstrmvwinwstrmvwprintwmvwscanwmvwvlinemvwvline_setnnamenamespacenapmsnc_getmousenearbyintnearbyintfnearbyintlneltsnewnewpadnewtermnewwinnextafternextafterfnextafterlnexttowardnexttowardfnexttowardlnlno vopsnocbreaknocrmodenodelaynoechononlnonnullnoqiflushnorawnoreturnnotnot_eqnothrownotimeoutobstackobstack_printfobstack_vprintfoffsetoffsetofonceonewayopen_memstreamopen_wmemstreamoperatoroperator alignofoperator deleteoperator delete []operator newoperator new []operator sizeofoperator!operator!=operator%operator%=operator&operator&&operator&=operator()operator*operator*=operator+operator++operator+=operator,operator-operator--operator-=operator->operator->*operator/operator/=operator::operator<operator<<operator<<=operator<=operatoroperator>=operator>>operator>>=operator>?operator>?=operator?:operator[]operator^operator^=operator__imag__operator__real__operator|operator|=operator||operator~oror_eqorig_attrorig_backorig_cursororig_foreoutoverflow_arg_areaoverlayoverwriteppackpair_contentparamspch_preprocesspclosepecho_wcharpechocharperrorpnoutrefreshpoisonpopenposixpowpow10pow10fpow10lpowfpowlpragmaprefixprefreshprintfprintf_unlockedprintwprivateprofile_func_enterprofile_func_exitprotectedprotoprotocolprotosptrptrdiff_tpublicpureputcputc_unlockedputcharputchar_unlockedputsputs_unlockedputwputwcputwc_unlockedputwcharputwchar_unlockedputwinqiflushrawraw_inpraw_outraw_outputreadredefine_extnameredrawwinrefreshreg_save_arearegisterreinterpret_castremainderremainderfremainderlremoveremquoremquofremquolrenamerenameatrequest_mouse_posresreset_prog_modereset_shell_moderesettermresettyresize_termresize_windowresizedrestrictreturnreturn_key_modifiersrewindrindexrintrintfrintlripofflineroundroundfroundlrune_tssave_key_modifierssavetermsavettysavingsbsb_cur_xsb_cur_ysb_get_horzsb_get_vertsb_initsb_onsb_refreshsb_set_horzsb_set_vertsb_total_xsb_total_ysb_viewport_xsb_viewport_yscalbscalbfscalblscalblnscalblnfscalblnlscalbnscalbnfscalbnlscanfscanwsccsscr_dumpscr_initscr_restorescr_setscrlscrollscrollokseekselectorsentinelset_offsetset_streamposset_termsetbufsetbuffersetccharsetlinebufsetscrregsetsyxsetvbufshortshort intshort unsigned intsignbitsignbitfsignbitlsignedsigned charsignificandsignificandfsignificandlsinsincossincosfsincoslsinfsinhsinhfsinhlsinlsize_tsizeofslk_attr_offslk_attr_onslk_attr_setslk_attroffslk_attronslk_attrsetslk_clearslk_colorslk_initslk_labelslk_noutrefreshslk_refreshslk_restoreslk_setslk_touchslk_winptrslk_wlabelslk_wsetslklinessnprintfspsprintfsqrtsqrtfsqrtlsscanfssize_tstandendstandoutstart_colorstat64staticstatic_caststdstderrstdinstdoutstdscrstpcpystpncpystrcasecmpstrcatstrchrstrcmpstrcpystrcspnstrdupstreambufstreammarkerstreamposstrfmonstrftimestrlenstrncasecmpstrncatstrncmpstrncpystrndupstrpbrkstrrchrstrspnstrstrstructsubpadsubwinswitchswprintfswscanfsynchronizedsyncoksys_errlistsys_nerrsystemsystem_headertantanftanhtanhftanhltanltemplatetempnamterm_attrstermattrsterminatetermnametgammatgammaftgammalthethisthrowtimeouttmtmpfiletmpfile64tmpnamtmpnam_rtoasciitolowertouchlinetouchwintouppertowlowertowuppertraceofftraceontruetrunctruncftruncltryttytypetype_infotypeaheadtypedeftypeidtypenametypeofunassertunctrlundefunget_wchungetcungetchungetmouseungetwcunionunitunknown typeunsignedunsigned charunsigned intunsigned longunsigned shortuntouchwinuse_default_colorsuse_envusingvva_argva_copyva_endva_listva_startvasprintfvdprintfvfprintfvfscanfvfwprintfvfwscanfvid_attrvid_putsvidattrvidputsvirtualvisibilityvlinevline_setvoidvolatilevprintfvscanfvsnprintfvsprintfvsscanfvswprintfvswscanfvtablevw_printwvw_scanwvwprintfvwprintwvwscanfvwscanwwwadd_wchwadd_wchnstrwadd_wchstrwaddchwaddchnstrwaddchstrwaddnstrwaddnwstrwaddrawchwaddstrwaddwstrwarningwattr_getwattr_offwattr_onwattr_setwattroffwattronwattrsetwbkgdwbkgdsetwbkgrndwbkgrndsetwborderwborder_setwchar_twchgatwclearwclrtobotwclrtoeolwcolor_setwcpcpywcpncpywcrtombwcscasecmpwcscasecmp_lwcscatwcschrwcschrnulwcscmpwcscollwcscoll_lwcscpywcscspnwcsdupwcsftimewcsftime_lwcslenwcsncasecmpwcsncasecmp_lwcsncatwcsncmpwcsncpywcsnlenwcsnrtombswcspbrkwcsrchrwcsrtombswcsspnwcsstrwcstodwcstod_lwcstofwcstof_lwcstokwcstolwcstol_lwcstoldwcstold_lwcstollwcstoll_lwcstoqwcstoulwcstoul_lwcstoullwcstoull_lwcstouqwcswcswcswidthwcsxfrmwcsxfrm_lwctobwcursyncupwcwidthwdelchwdeletelnweakweak_externwecho_wcharwechocharwenclosewerasewget_wchwget_wstrwgetbkgrndwgetchwgetn_wstrwgetnstrwgetstrwhilewhlinewhline_setwin_wchwin_wchnstrwin_wchstrwinchwinchnstrwinchstrwinnstrwinnwstrwins_nwstrwins_wchwins_wstrwinschwinsdellnwinsertlnwinsnstrwinsrawchwinsstrwinstrwint_twinwstrwmemchrwmemcmpwmemcpywmemmovewmempcpywmemsetwmouse_positionwmouse_trafowmovewnoutrefreshwordcharwprintfwprintwwredrawlnwrefreshwresizewritewscanfwscanwwscrlwsetscrregwstandendwstandoutwsyncdownwsyncupwtimeoutwtouchlnwunctrlwvlinewvline_setxx86_64xorxor_eqxyzyy0y0fy0ly1y1fy1lynynfynlzÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¶rW-º* úè,º*—©Šš©Š€úè,º*©Š ©Šðúè,º*£©Š¦©Š`ûè,º*©©Š¬©ŠJªŠWªŠbªŠÐûè,º*¯©Š²©ŠmªŠzªŠ…ªŠ?ªŠpþè,º*Ò©ŠÖ©Šàþè,º*Ý©Šá©Šýè,º*Ä©ŠÈ©Šþè,º*Ë©ŠÏ©Š°üè,º*¸©Š»©Š ýè,º*¾©ŠÁ©Š@üè,º*µ©ŠNÈ™ ùè,º*t©Š”©Špé,º*p÷è,º*×dŽŽ˜@ìè,º*U¶‰OçŒà÷è,º*31[šöè,º* Žy©ŠPÿè,º*詊б›é,º*æO©Ž‰ÿÿÿÿðêè,º*$ŒÈ¿‹`ëè,º*à ›;1@ìè,º*U¶‰C1pðè,º*Ï n1멊÷©ŠªŠàðè,º*­™T• ªŠªŠ!ªŠë©Š`ëè,º*à ›s‹Pøè,º*€©Šƒ©ŠÀøè,º*ЩЩŠ·‹0òè,º*µM´q˜ òè,º*iÓœ¨gšPñè,º*=ªŠ„ÓŽÀñè,º*n©Šp©ŠÐëè,º*ã2œá&°ìè,º*¯ ›H©Š°õè,º*2ªŠv©Š öè,º*<ªŠDš+ªŠ5ªŠ íè,º*Ћ)­˜ðóè,º*ëQÔŽÐôè,º*Å©Šÿ”`ôè,º*%´‹ïÓŽ@õè,º*Ì©ŠæÓŽóè,º*W½ÝÓŽ€óè,º*s©Š ÔŽèóšÐëè,º*ã2œÏ1ðè,º*e©Šb©ŠPïè,º*Y©ŠV©Šîè,º*êMW~”íè,º*îM˳˜îè,º*êMW~”íè,º*îM˳˜0éè,º*°˜˜Ï›ÿÿÿÿ éè,º*!1íŒÿÿÿÿêè,º*N<‹nÄ‹ÿÿÿÿ€êè,º*,1”êŽÿÿÿÿ0ùè,º*ØÐ‰M‘”÷è,º*|©Šþ™”`Ôè,º*TÛÐÒ‹`Ôè,º*TÛÐÒ‹`Ôè,º*TÛÐÒ‹`Ôè,º*TÛÐÒ‹pîè,º*Œ…Š÷›àîè,º*N©ŠK©Šðêè,º*$Œ°› L°LÀLÐLàLÀMM M°MðLMM M0M@MPM`MpM€M j.`Ê!`.à`A-€A- A-ÀA-àA-B-`n. B-@B-`B- B- n.ÀB-àB-C- C-àë-@C-`C-€C- C-ì-ÀC-àC-D- D- ì-@D-`D-€D-ÀD-` -E- E-@E-`E- e.€E- E-ÀE-àE-@î-F- F-@F-`F- ï- F-ÀF-àF-G-Àï-@G-pÜ ó-àH-I- I-@I-àô-`I-€I- I-ÀI-Ào.àI-J-ào. J- p.@J-`J-€J- J-€p.ÀJ-àJ-K- K- p.@K-`K-€K- K-q.ÀK-àK-L- L-@q.@L-`L-€L- L- q.ÀL-àL-M- M-r.@M-sÐÌ)Þ°Ü@8 «)€¦*Ы)À„*ð„*¨*P…*€…*°…*P—*°—*˜*p˜* ˜*™*0™*`™*À™*ð™*Pš*PÄ*àÄ*°š*›*à†pàP0 p€ðà`Ð@° Æ*p›* ›*œ*€Ç*`œ*œ*ðœ* *€*ÀÉ*PÊ*à*@ž*pž*О*Ÿ*`Ÿ* Í*ÀŸ*@Î*  *P *° *à * Ð*@¡* ¡*С*0¢*°ý*À¢*Ò*P£*€£*à£*@¤*p¤*Ф*¥*0Ò*0¥*¥*À¥*ð¥*P¦*°¦*§*@§*`Ò* §*Ч*0¨*`¨*¨*ð¨* ©*€©*°©*ª*°+@ª*@?)€Á&À’&p“& ”&p“& ”&Ðé'à–&¾&0Â&p¿&À¾&ÐÀ&t(ÐÊ( v+Ã&€( š*ü `Q- j.`i.`i.à1-@.€5. 6.`. 2-ÀQ- Q-€.`8.À.à.. .@.Œ&`u(ð&pž&& Ž&P&°&`‘&’&À’&p“& ”&Д&€•&€Q- Ž&°&’&p“&0–&P&`‘&À’& ”&°t( «)Ы)¬)`¬)pÁ(Â(€ª)0õ(`Â(›°™ð— v+ÐÊ(E&0¬&à¬&­&@£& ¤&¦&`§&À¨& ª&€«& Ÿ&П&à¡& ”&’&p“&À³&À#€#t( µ& °)`M"%(ëîñô÷úÿ /6<BHNQTWZ]€ƒ†‰Œ’•˜›·º½ÔÚàæ!%(,/2UX[^aemvˆ£¦©¬¯²ÕÛáçíõû       " F I J K ˆ Š Œ Ž ” š   ¤ ¦ ¨ ® ´ º ¼ ¾ À  Ä Å Ê Ð Ö Ü ô û     & ) , / 2 F L R X ^ r w z } € ƒ ‡  “ ™ ›  Ÿ ¡ Ä Å Ê Ð Ö Ü â ì õ þ  : C F I L Q W ] c i p v | ‚ ˆ Ž ” 39?EKQ‰•Ÿ¢¥¨«½ÁÄÇÊÍÐÓÖÙÜßåë0369<?BEHKNQTWZ]`cfimsy…‹‘—£©½ÀÃÆÉÌÏÒþ %+17=CIOU[^adgj“–™¼ÛÞáç;?Bku{‡Ÿ¨±ºÌ×ãü3?EK_behkž¡¤§ªÕÛáçíñô÷úý  EHKNQfnw€‰“–™œ ¡¢³·¹»½¿ÁÃÅÇÉúüþ = @ A B b c k q ¥ · æ ç è é ê ë ì ï ò ó ù ü ÿ            4 8 ; < = > ? @ A B G egikmK oq÷ ú ý                     ! " # % ' ) , / 2 5 8 ; > A D G J M O q s u w y { }   ƒ … ‡ ‰ ‹   ‘ “ • — ™ ›  Ÿ ¡ £ ¥ § 02468:<>@BDFHJLNPRTVWY[]_acsþu"%(ëîñô÷úÿ /6<BHNQTWZ]€ƒ†‰Œ’•˜›®±´·º½ÔÚàæì!%(,/2UX[^aemvˆ£¦©¬¯²ÕÛáçíõû          " F I J K L O R f l r x ~ „ ˆ Š Œ Ž ” š   ¤ ¦ ¨ ® ´ º ¼ ¾ À  Ä Å Ê Ð Ö Ü ô û     & ) , / 2 F L R X ^ r w z } € ƒ ‡  “ ™ ›  Ÿ ¡ Ä Å Ê Ð Ö Ü â ì õ þ   ( 1 : C F I L Q W ] c i p v | ‚ ˆ Ž ” š   ¦ 39?EKQvz}€ƒ†‰Œ’•Ÿ¢¥¨«½ÁÄÇÊÍÐÓÖÙÜßåëñöý -0369<?BEHKNQTWZ]`cfimsy…‹‘—£©½ÀÃÆÉÌÏÒÕØûþ %+17=CIOU[^adgj“–™¼ÃÉÏÕÛÞáäçêÿ ;?BEHkou{‡Ÿ¨±ºÃÌÑ×Ýãü39?EK_behkž¡¤§ª­ÕÛáçíñô÷úý  EHKNQfnw€‰“–™œ ¡¢³·¹»½¿ÁÃÅÇÉËôúüþ    1 6 : = @ A B C V Y \ _ b c e k q s y  ¥ « ± · ½ à æ ç è é ê ë ì ï ò ó ù ü ÿ            4 5 8 ; < = > ? @ A B C G egikmK M Q U Y ] a ¤ ¦ ª ® ² ¶ º ¾ ã ë ñ oq÷ ú ý                     ! " # % ' ) , / 2 5 8 ; > A D G J M O q s u w y { }   ƒ … ‡ ‰ ‹   ‘ “ • — ™ ›  Ÿ ¡ £ ¥ § 02468:<>@BDFHJLNPRTVWY[]_acsþu€ ˆ Œ    °  , @ 8 D T X \ ” ` h d „ l ˆ t x |  ˜   œ ¨ ¤ ¬ ¸ ˜ Ä È Ì Ð Ô `````````   $   ,  @ ( , 0 4 8 < @ D H L P T X \ ` „ d h l ˆ t x | € „ ˆ Œ | ° ´ ¸ ¼ ” Ä È Ì Ð Ô ˜ ø ü     à   ä $ ( 0 4 8 < Ø Ü œ à è ä ì ð ô D H p  Œ ” ˜  œ   ¤ ¨ ¬ L P T è X À \ ì ` d h l t p x  ð ô € ÀH-ÀH-@ˆ2 @-À@-à@-A- A-`ë- n.€ë-@A-ÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐG¼(À¼(Г)ð¼(ÐKðKL0LpÞ`L€LL Þ°ÞÐBàÞðÞ Üß ßðB@ßPßàGàGàGàGàGàGàG ½(P½(€½(°½(àKL L`ÞPLpL€ÞÞ@ÀÞÐÞPàBß`0ßp€`ß B B B B B Bà½(`n+¾(@¾(àGàÜðÜpD€DÝ D°DÀDÐDàDÝ Ý0ÝðD@ÝPÝE0E@EPE`EpE€EE E`ݰEÀEÐEpÝàEðEFF F0F@FPF`FpF€FF FÀFÐF€ÝàFðFGG G0G@GÝ ÝPG°Ý`GpG€G GÀݰGÐGàG BðGHHÐÝ H0H@HPH`HpH€HàÝ HðÝÀHÐHàHII I0I@IPI`IpI€IIÞ I°IÀIàIJJ J0JÞ `JpJ ÞJ0Þ°JÀJÐJàJðJK°B K0K@KPKÀBpK€K K@ÞPÞÀK`úÐú@û üüpýpo' d"0y,´ °Ê Ðì "îàïÀ "Ð" "Ðó õò@ù Àð€ë€ùpè°Ñð"@æàö øÏðϰÑàÚÀÛðÏPéÐ "ðÝÐÞ0Ü ÜÐÐ "€äÐåpÓáÀâàá ã@ß àÐÐÚ°ë  ÕÀÔ ÕÀÔËpÌPÍ0Î@ " çpâ!pâ!pâ!pâ!€Ö`×Ï@¡.P…*ð„*àð#0g'àg'h'@i'„'ði' j'À„'n'p“&p“&Pk'p†°l'ð«'Àn'àd"P›"€' €'¾Å€@` pPð0° Pª "Ð 0ÿPþ ÿЃ*Å!pÁ(PØ`ÛÚ×0 !P!à!!  !!!!p°.14132767801253738130730811163841111111111161111111111101611016411024111110xfffd110x20001"__vt_"112412820x100x400x1000x2000x4000x20000x40000x80001010040020001000020000400002000001000000200000002240969110x00000x00020x00030x00040x00050x00060x00070x00080x00200x00380x00100x00200x0040124'l''m''k''j''u''w''q''x''n''o''s''`''a''f''g''~'',''+''-''h''i''0''p''r''z''{''|''}'0x1000x1020x1030x1040x1060x1070x1080x1480x14a0x14b0x14d0x14e0x1500x1520x1530x1540x1560x1570x15a0x15b0x15c0x15e0x15f0x1620x1630x1640x1660x1670x16a0x16b0x16c0x16e0x16f0x1720x1730x1750x1760x1770x17a0x17b0x17d0x17e0x17f0x1830x1850x1870x1880x18c0x18e0x18f0x1900x1930x1940x1970x1980x19b0x19c0x19d0x19f0x1a00x1a30x1a40x1a50x1a70x1ab0x1ac0x1ad0x1af0x1b30x1b40x1b50x1b80x1bb0x1bc0x1be0x1bf0x1c00x1c30x1c40x1c70x1cc0x1cd0x1cf0x1d00x1d30x1d40x1d50x1d70x1d80x1db0x1dc0x1de0x1df0x1e00x1e40x1e70x1e80x1eb0x1ec0x1ee0x1ef0x1f00x1f30x1f40x1f50x1f70x1f80x1fb0x1fc0x1fd0x1ff0x2040x2050x2080x20b0x20c0x20d0x20f0x2100x2130x2140x2150x2170x2180x21c0x21f0x2200x2230x224218 С!À^À^0_cc`h0_Ðvc𔬀 € DD€ € € €R€ 0_à  ¿ à __fd41127__fmt24128getwgets110211024ftell1816381feof111pclose1cuserid134011__args16600FALSE1ERR1111200009L1611zMEVENT_attrs_clear_paryautocrraw_inpresizedcols118192810x200x800stdscr204acs_map01000100000001"/tmp"WA_LEFT2383289WA_TOPn000x00010x00087WACS_S719'+''+''+''t''v''+''-''|''+''-''_''+''\'''#''o''<''>''.''^''#'0270x1010x1050x1490x14c0x1510x1550x1580x15d0x1690x16d0x1700x1740x1790x17c0x1800x1820x1840x1890x18b0x18d0x1920x1960x1990x19e0x1a10x1a80x1aa0x1ae0x1b00x1b10x1b60x1b70x1b90x1bd0x1c10x1c60x1c80x1c90x1cb0x1ce0x1d20x1d60x1da0x1dd0x1e20x1e30x1e50x1ed0x1f20x1f60x1f90x2000x2010x2030x2060x2070x2090x20e0x2120x2160x21a0x21b0x21d12__val__uid_t__gid_t__off_t__FILE__wchtmwcsncpy__n__s1__s2__locwcsxfrmwcsdupwcschr__wcswcsrchrwcsstrwcstokwcslenwcswcswmemchrwmemcpy__ps__p__lenwcwidthwcstoqwcstouq__group__nptwcpncpyfwidewprintffwscanf__wsungetwcstat64KEY_SRKEY_BEGALT_8ALT_CALT_KALT_NALT_SALT_YKEY_B2KEY_C1KEY_Fclearokdelchhas_ilidlokinchinschinstrmvcurmvinstr1newpadnlnoechorawscanwscrl64493121subwin10111200112L1winchwmove111115get_wch"C"winwstrfixterm1has_key._0._5._6._8._101110111680x8002020040004000000020160x001010'+''+''+''+'':''v''*''#''-''-''>''n''+''L'10x14f0x1590x1600x1650x1680x1710x1780x1810x18a0x1950x19a0x1a20x1a60x1a90x1b20x1ba0x1d10x1d90x1e10x1e60x1e90x1f10x2020x2110x2190x21e0x22213rune_tmajxyzb1481002215__HI__11111_PARAMS112_pos_sposdelta__cd_in_fileno__pad42seekclose__cfileexprres_Doitlibc_IOLBFstdouttmpnam__pfx1113240x1000fmaffmalfmaxfmaxffmaxlfminfminffmodfmodffmodlfrexpfrexpffrexplgammagammafgammalhypothypotfhypotlilogbilogblj0j0fj0lj1j1fj1ljnjnfjnlldexpldexpfldexpllgammalgammaflgammalllrintllrintfllrintlllroundloglog10log10flog10llog1plog1pflog1pllog2log2flog2llogblogbflogbllogflogllrintlrintflrintllroundlroundflroundlmodfmodffmodflpowpow10pow10fpow10lpowfpowlremquoremquolrintfrintlroundroundfroundlscalbscalbfscalblscalblnscalbnscalbnf1scalbnlsignbitsinsincossincosfsinfsinhsinhfsinhlsinlsqrtsqrtfsqrtltantanftanhtanhftanhltanltgammatgammaftgammaltrunctruncfy0y0fy0ly1y1fy1lynynlcabscabsfcabslcacoscacosfcacoshcacoshfcacoshlcacoslcargcargfcarglf0x161casincasinfcasinhcasinhfcasinhlcasinlcatancatanfcatanhcatanhfcatanhlcatanlccosccosfccoshccoshfccoshlccoslcexpcexpfcexplcimagcimagfclogclogfcloglclog10clog10fconjconjfconjlcpowcpowfcpowlcprojcprojfcprojlcrealcrealfcreallcsincsinf0x1c2csinhcsinhfcsinhlcsinlcsqrtcsqrtfcsqrtlctanctanfctanhctanhfctanhlctanlbcopybzeroindexmemcmpmemcpymemmovemempcpymemsetrindexstpcpystrcatstrchrstrcmpstrcpystrcspnstrdupstrndupstrlenstrncatstrncmpstrncpystrpbrkstrrchrstrspnstrstrfprintffputcfputsfscanffwrite0x1faputcharputssprintfsscanfvfscanfvprintfvscanfvsscanfisalnumisalphaisasciiisblankiscntrlisdigitisgraphislowerisprintispunctisspaceisuppertoasciitolowertoupper0x221abortallocacallocpragmaexeclexeclpexecleexecvexecvpexecveexitffsffsimaxffslffsllforkgettextimaxabsfinitefiniteffinitelisinfisinffisinflisnanisnanfisnanllabsllabs_exit_Exit1encodein493211111wcscpy16mbsinit__mode16481ALT_4ALT_G4beeperase0x1c50x1ca0x1ea0x1fevtable053__eqsf2__eqdf2__eqxf2__nedf2__nexf2__netf2__gtsf2__gtxf2__gttf2__gesf2__gedf2__gexf2__ltsf2__ltdf2__ltxf2__lesf2__lexf2__letf2111getyx._3101'y'126€ 0x19111110x20a4_LP64cpu#cpumachine__amd64__MMX____SSE____k8__k8____linux__unixunixsystem#systemposixXOPENva_ends_SCO_DSva_list_SIZE_T_T_SIZE_SIZET_size_tssize_t_WINT_Twint_tNULLTYPEMEMBERmin__PGI__P__PMT__THROW__NTHargsx__ptr_tname__bos__bos0protoaliasprefixaparamstheelifwarningpoison0defineddoenumgotomutablepublicC'<'bufSHAREDfminlilogbfremquofrintsincosltrunclynfcimaglclog10lbcmpstpncpyabs__nesf2__modesfreopenfopen64fdopensetbufsetvbuf__size__fdprintffgetcgetcgetcharputcputwfgetsgetlineungetcfreadfseek__offrewindfseekoftellofsetposferrorperrorfalsefilenopopenctermidobstackcompl_boolTRUEchtypecchar_tattr_tbuttonchanges__realautommask_tid_win_cury_curx_maxx_begy_begx_bkgd_scroll_immed_sync_y_lastch_tmarg_bmarg_parx_parentWINDOWalivecbreakechoraw_outaudiblemonocursrowcurscollinesXCURSESsb_onSCREENPDCEXLINESCOLScurscrSPCOLORSTABSIZEttytypeA_INVISA_BLINKA_BOLDthisA_COLORA_DIMCHR_MSKATR_MSKATR_NRMWA_BOLDWA_DIMWA_LOWwACS_S1ACS_S9ACS_S3ACS_S7ACS_PIWACS_S1WACS_S3WACS_PIC++_vptr__u_int__dev_t__ino_t__pid_t__id_t__key_tFILE__count__valueWEOF__destwcsncatwcscmpwcsncmpwcscoll__swcspbrk__delim__ptrwcsnlenwmemcmpwmemsetbtowcwctobmbrtowc__pwcwcrtombmbrlen__dst__nmc__nwcwcstod__nptrwcstofwcstol__basewcstoulwcstoll__fp__argwscanfswscanfvwscanffgetwcgetwcfputwcputwcfgetwsfputws__pos__state__data__next__fctPDC_RGBKEY_UPKEY_F0KEY_DLKEY_ILKEY_DCKEY_ICKEY_EICKEY_EOSKEY_EOLKEY_LLKEY_ENDKEY_SDCKEY_SDLKEY_SICALT_0ALT_1ALT_2ALT_3ALT_5ALT_6ALT_7ALT_9ALT_BALT_DALT_EALT_HALT_IALT_JALT_LALT_MALT_OALT_PALT_QALT_RALT_TALT_UALT_VALT_XALT_ZCTL_ENDKEY_A1KEY_A2KEY_A3KEY_B1KEY_B3KEY_C2KEY_C3PADSTOPPADSTARPADPLUSCTL_INSALT_DELALT_INSCTL_TABALT_TABALT_ENDALT_UPALT_ESCPAD0CTL_DELSHF_UPSHF_ICSHF_DCKEY_SUPKEY_MINKEY_MAXaddchaddnstraddstrattroffattronattrsetattr_onbkgdsetborderboxchgatclearcopywinderwindupwinendwinfilterflashgetbkgdgetnstrgetstrgetwinhlineidcokimmedokinchstrinitscrinnstrinsnstrinsstrkeynamekeypadleaveokmetamovemvaddchmvchgatmvdelchmvgetchmvhlinemvinchmvinschmvscanwmvvlinemvwinchmvwinnewtermnewwinnodelaynonlnorawoverlayprintwputwinqiflushrefreshresettysavettyscr_setscrollslk_setsubpadsyncoktimeoutluse_envvidattrvidputsvlinevwscanwwaddchwaddstrwattronwbkgdwborderwchgatwclearwdelchwerasewgetchwgetstrwhlinewinnstrwinschwinsstrwinstrwprintwwscanwwscrlwsyncupwvlineaddwstradd_wchbox_setinnwstrins_wchin_wchwin_wchwunctrlgetbegxgetbegygetmaxxgetmaxygetparxgetparygetcurxgetcurytraceonunctrlcrmodedrainosetsyxgetbmapwresizesb_initungetch._1._2._4._7._9._11._12__flags__trans__steps__cd__SI____vt__G_ARGSARGLISTpprotos_IO_DEC_IO_HEX_next_sbufspsb_flags_chain_flags2_lock_offset__pad1__pad2__pad3_mode__buf__wreadwrite__fns__uflow_IO_BE_fp_ch_fctfpos_t_IOFBF_IONBFBUFSIZTMP_MAXIOV_MAXstdinstderrremoverename__old__oldfd__newfdtmpfiletempnam__dirfclosefflushfopenmainpackweakunit__eqtf2__gtdf2__lttf2__ledf2_PragmafgetposOKbstate_maxydefineifdefiflinesccsbitandbitoror__wchb__srcwcscatasmbreakcaseclass__wcwcscspnwcsspnforinlinereturnsigned__cstructtrytypeidtypeofwhiledefsinoutoutwcstoldwcpcpyJava__delta::__tpscanfacoshacoshlatanhcosferfcferfferflexpm1lKEY_SFALT_AALT_FALT_WCTL_UPbkgddelwin*has_ic`h0m€ € 0_napmsà inwstrwbkgrndgetchchgetsyxx86_64linux__ELF__vva_argva_copyWINNTWACS_S9fcty__c99ptrmsgcname__wur_LIBCmaymacrofdEOF_IO_OCToffsetsaving_file__pad5_wch__newincludeendifelseifndefundeferroridentimportassertonceGCCtrueandand_eqnotnot_eqor_eqxor_eq__asm__asm____const__imag__nullboolcatchcharconstdefaultdeletedoubleexportexternfloatfriendintlongnewprivateshortsizeofstaticthrowtypedefunionusingvirtualvoidwchar_tendfinallybycopybyrefoneway__ct __dt nelts__pfnstdformatmallocnonnullnothrowprintfpureno vopsstrfmonacosacosfacoshfacoslasinasinfasinhasinhfasinhlasinlatanatan2atan2fatan2latanfatanhfatanhlatanlcbrtcbrtfcbrtlceilceilfceillcoscoshcoshfcoshlcosldremdremfdremlerferfcerfclexpexp10exp10fexp10lexp2exp2fexp2lexpfexplexpm1expm1ffabsfabsffabslfdimfdimffdimlfloorfloorffloorlfmause_env__getf2xorswitchd1.19209290e-7F1.40129846e-45F214748364721474836470xFBAD00000xFFFF00000x00000001L0x00000002L0x00000004L0x00000008L0x00000010L0x00000010L0x00000040L0x00000080L0x00000100L0x00000200L0x00000200L0x00000400L0x00000800L0x00001000L0x00002000L0x00004000L0x00004000L0x00010000L0x00020000L0x00040000L0x00200000L0x00800000L0x01000000L0x02000000L0x04000000L0x08000000L0x1fffffffL0x20000000L0x000200000x000400000x000800000x002000000x004000000x008000000xffff00000x0000ffff5:&¸ (ð .,€H-€@&Ú´3Ã&ˆr¿i`È&õÀìTàî&µEÿˆ`Ž'open_memstream214748364721474836473.40282347e+38F1.17549435e-38F__whence__commandobstack_vprintfMOUSE_MOVEDBUTTON1_PRESSEDBUTTON5_PRESSED_nodelaysb_total_xsb_cur_y__declspecCOLOR_PAIRSA_ATTRIBUTESÂÿÿÿÿÿÿÿÃÿÿÿÿÿÿÿPDC_ATTR_SHIFTÅÿÿÿÿÿÿÿÆÿÿÿÿÿÿÿÇÿÿÿÿÿÿÿÈÿÿÿÿÿÿÿÉÿÿÿÿÿÿÿÍÿÿÿÿÿÿÿWA_BLINKÐÿÿÿÿÿÿÿWA_INVISÑÿÿÿÿÿÿÿÒÿÿÿÿÿÿÿÓÿÿÿÿÿÿÿÔÿÿÿÿÿÿÿÕÿÿÿÿÿÿÿÖÿÿÿÿÿÿÿ×ÿÿÿÿÿÿÿÙÿÿÿÿÿÿÿÛÿÿÿÿÿÿÿÜÿÿÿÿÿÿÿÝÿÿÿÿÿÿÿßÿÿÿÿÿÿÿàÿÿÿÿÿÿÿáÿÿÿÿÿÿÿâÿÿÿÿÿÿÿãÿÿÿÿÿÿÿäÿÿÿÿÿÿÿåÿÿÿÿÿÿÿæÿÿÿÿÿÿÿçÿÿÿÿÿÿÿèÿÿÿÿÿÿÿéÿÿÿÿÿÿÿêÿÿÿÿÿÿÿëÿÿÿÿÿÿÿACS_HLINEìÿÿÿÿÿÿÿíÿÿÿÿÿÿÿïÿÿÿÿÿÿÿðÿÿÿÿÿÿÿñÿÿÿÿÿÿÿòÿÿÿÿÿÿÿóÿÿÿÿÿÿÿôÿÿÿÿÿÿÿõÿÿÿÿÿÿÿøÿÿÿÿÿÿÿúÿÿÿÿÿÿÿûÿÿÿÿÿÿÿüÿÿÿÿÿÿÿACS_UARROWýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿACS_LANTERN     ACS_SBBS0x00000020LACS_BSBS !0x00008000L#WACS_VLINE$%&'0x00080000L0x00100000L*+0x00400000L-WACS_PLMINUS/012340x10000000L67890x00010000;<WACS_LEQUAL=0x00100000@`G- G-p¾(€¬*ÀG-àð- .0xff000000 n+!àG-!H-"`î##P .`M-€M- M-ÀM-àM-N- P-`P-€P- P-ÀP-àP-Q- Q-@Q-  @- A- À@- à@-€@€ € @@€ € @ˆßµ ±&¹¾–¾&¼=W!p¿&oÍAÇ&±¢ ª°Ç&__stub_bdflush__stub_putmsg__stub_sstk__int8_t__uint64_t__quad_t__UWORD_TYPE__S64_TYPE__DEV_T_TYPE__UID_T_TYPE__GID_T_TYPE__NLINK_T_TYPE__OFF_T_TYPE__PID_T_TYPE__BLKCNT_T_TYPE__CLOCK_T_TYPE__DADDR_T_TYPE__SSIZE_T_TYPE__time_t__swblk_t__blkcnt_t__fsblkcnt_t__ssize_t__qaddr_t__FILE_defined_IO_STDIO_H_G_config_h_BITS_WCHAR_H__WCHAR_MAXWCHAR_MAXwcsncasecmpwcsncasecmp_l__accept__haystack__btowc_aliasmbsnrtowcswcstoul_lwcstof_lwcsftime_l_GCONV_HWACS_SSSBKEY_CODE_YESKEY_RIGHTKEY_RESETKEY_ABORTKEY_CREATEKEY_REFERENCEKEY_SCANCEL&ÑzÜP,&5ì% +&/&¨‰ À/&áK@Ò`.&š›íÐ1&Õà[è 1&J)43 6&G`P7&"üç8&±‰-°8&¦‰…s`9&ÍhÞ:& w3~À:&¨°sp;&âÈ¢† <&y†Ð<&u1ô7€=&KEY_SMOVE5­±00>&‚µJžà>&f®·:?&„Mð¾@@&‘Áªð@&\ÊO  A&5‹wJPB&'›êC&KEY_SREPLACE뇴½°C&¥WF~`D&âP¥ÀE&„äÈXpF&DZô» G&KEY_SSAVELìÅÐG&KEY_SSUSPENDáÁ%]€H&f<ÂŒàI&tS}úJ&b iõ@K&omáfðK&ŠÚß L&¥«ÍÈPM&#¶sN&SöôÀ°N&Z­Ì`O&í¦¡P&&]‚ÀP&Ѝ§Ø”'ÓC)TÀ)(EÀpQ&¤¸Þá R&d‰˜ÐR&‹éLàT&lâSî@V&ì4y€ðV&ŽBo% W&ûad³PX&%±þ¶Y&äǰY&ü$GE`Z&gC¨+[&î‹°À[&g‰­²p\&’Ò‹— ]&CTL_LEFTðBÆÖÐ]&Dò–Ó0_&Vy¬à_&Š’F£`&¹µµ@a&ß2Žäða& Y b&R/–¿Pc&{´#'d&{|¯°d&Ëד)`e&3â_Yf&:Q.Àf&v u—pg&擨 h&åçùÐh&:îC0j&åÔàj&(jÍk&ð@l&â7‹‹ðl& U7 m&’oǰPn&çÖ×o&=©0è°o&…i͘`p&|e q&+†àÀq&6š;ïðP(CTL_PADSLASHxßXâpr&=îÚ s&޽ƀt&в½0u&’ã¸Çàu&ŸÒˆ°S(fíwv&QÆÿ@w&¢;¥ðw&V‚ x&y dPy&2û£z& a+š°'Ió °z&LB`{&ßá…›À|&Ày-€p}&ALT_EQUALFÌ™ú€&h ü0€&¯Ä0à€&Í÷LÔ&Åä܉@‚&e*ð‚&ôÈG P„&˜’ßh°…&÷JIì`†&TÇÌLJ&¥Ÿ% À‡&ëãpˆ&" ØÎ ‰&š@B€Š&ŠÙÀ]0‹&¢²¾@&4¹PÌ€f'˜O¾öÀš'ALT_COMMA        K r!K r!0_ _c°in0mCTL_PAD3€u@Ì!cpk ./°À 0 ° € ð € à$€ ALT_PAD5° € ALT_PAD6p à  _0_ÔŸ¹Pä'X1š”€õ'x§ð÷'ÕÄuœPú'ø%–l&BƒýÀý''&é¯`(_iB¬p (x‹¼b€ (PE7(SHF_PADPLUSÝo×ù°(iæ#(š'±¤àð$( lY­`((ÐZ†.(ýÒ08(Fñ ¢à8(¥àŒCD(“2õ@E(õ‚%ðE(ÒGÁPG(·ƒ°H({I± L(2–°¼&*ÃÒ“ÐL(2œŒ–€M(¥‡:Ÿ0N(KEY_SDOWN°ÇóÍ`T(Ãd}oZ(½XJ†°^(Ezšº b(rã –0d(a¦C³e(zö‹[@f(È®ßPh(¹i…B°i(š8‚Àk(s¤xJÐm(cw>S0o(ó%Ép(âlÀv(attr_set€ý~p›'#¾ x(ž–€y(Ô¢£aàz( Mà%Ròg"°à%s¾Q‰Ð§'Ç¥$Æâ%æGªoÀâ%PäŠT ä%çJˆÐä%øá±Æp±',E§ˆàæ%tuFßç%׺Þðè%‡¡E+Pê%GÖVë%#¾°ë%Ä¥ÃZÀí%øaMÙpî%¥²èÔ ï%âRè­Ðï%Ò½Y¼0ñ%ÒÝï_àñ%xDŽôö%EôM‰°ö%ö}PÐ&ñË{u0&$cžà&ŸF‘&erasecharûx°@ &èÜQ‹ð &Ë™ÀH° &dzÿT` &gt&®À&›p&UËM½ &›ÀÄçÐ&¸{÷à&³m{ð&ƒ±{’ &ë9m`&"*:žp&‹,pQ€&Qùxý@&ó™ð£&À¶%E°¦&is_linetouchedmvwaddnstrreset_prog_modeslk_attrsetstandendtermnamewaddchstrwechocharwinchstrwsetscrregaddnwstrgetccharkey_namekillwcharmvaddwstrmvinnwstrmvwaddnwstrmvwgetn_wstrmvwinnwstrmvwins_nwstrmvwinwstrsetccharvline_setwgetn_wstrwget_wchresettermmouseintervalmvwinsrawchXCursesExitgetbegyx0xFABC0000__va_copy_VA_LIST_T_H_STDDEF_H___USE_POSIX__ASSEMBLER__£¥š  (F,ó°°=(__used____LDBL_COMPAT__statep__nsteps__combined_G_uint32_t_IO_size_t_IO_BUFSIZ_IO_LINKED_IO_LINE_BUF_IO_USER_LOCK_IO_SHOWPOINT_IO_jump_tset_offset_IO_last_state_IO_2_1_stdin__IO_stdin__io_read_fn__nbytes__io_seek_fn__io_close_fn__read_write__wunderflow_IO_getc_IO_funlockfile_IO_vfscanf_IO_seekoff_IO_getwcSEEK_SETSEEK_CURFILENAME_MAXL_ctermidrenameat__builtin_fmax__builtin_fmaxl__builtin_fmin__builtin_fminl__builtin_fmod__builtin_fmodl__builtin_frexp__builtin_hypot__builtin_inf__builtin_inff__builtin_infl__builtin_j0__builtin_j0f__builtin_j0l__builtin_jn__builtin_jnf__builtin_jnlllroundfllroundl__builtin_log__builtin_log1p__builtin_log2f__builtin_log2l__builtin_logbf__builtin_logbl__builtin_loglACS_ULCORNER__builtin_modf__builtin_modff__builtin_modfl__builtin_nan__builtin_nanf__builtin_nanl__builtin_nans__builtin_nansf__builtin_nanslnearbyintnearbyintfnearbyintlnextafternextafterfnextafterlnexttowardnexttowardfnexttowardl__builtin_pow__builtin_powf__builtin_powil__builtin_powlremainderremainderfremainderl__builtin_rint__builtin_rintf__builtin_scalbscalblnfscalblnlsignbitfsignbitlsignificandsignificandfsignificandl__builtin_sin__builtin_sinf__builtin_sinh__builtin_sqrt__builtin_sqrtf__builtin_sqrtl__builtin_tan__builtin_tanhf__builtin_tanhl__builtin_trunc__builtin_y0__builtin_y1__builtin_y1f__builtin_cabs__builtin_cabsf__builtin_cabsl__builtin_cacos__builtin_carg__builtin_cargl__divsc3__divdc3__mulxc3__float128&ók)&__builtin_casin__builtin_catan__builtin_ccos__builtin_ccosf__builtin_ccosl__builtin_cexp__builtin_cexpl__builtin_cimag__builtin_clog__builtin_clogf__builtin_clogl__builtin_conj__builtin_conjf__builtin_cpow__builtin_creal__builtin_csin__builtin_csinf__builtin_csinh__builtin_csinl__builtin_ctanf__builtin_ctanl__builtin_bcmp__builtin_bzero__builtin_indexstrcasecmpstrncasecmp__builtin_fputcfputc_unlocked__builtin_fputsfputs_unlockedfwrite_unlockedprintf_unlocked__builtin_putsputs_unlocked__builtin_scanfsnprintfvfprintfvsnprintfvsprintfiswalnumiswalphaiswblankiswcntrliswdigitiswgraphiswloweriswprintiswpunctiswspaceiswupperiswxdigittowlowertowupper__builtin_abort__builtin_abs__builtin_apply__builtin_clz__builtin_clzl__builtin_clzll__builtin_ctzl__builtin_ctzlldcgettextdgettext__builtin_execl__builtin_execv__builtin_exit__builtin_ffs__builtin_ffsl__builtin_fork__builtin_isinf__builtin_isnan__builtin_labs__builtin_llabs__builtin_trap__builtin__exit__builtin__Exit__memcpy_chk__memmove_chk__mempcpy_chk__stpcpy_chk__strcpy_chk__strncat_chk__strncpy_chk__snprintf_chk__sprintf_chk__vsnprintf_chk__vsprintf_chk__printf_chk__vfprintf_chk__vprintf_chk__S16_TYPE__U64_TYPE__floatsidfoß:•pÊ&׫A`Þ&³&__INTMAX_TYPE__á¶ø}`'ã’‹À '2kR÷c'*DnŠ {'ƒ Igì'`@§ö”8×`A'KEY_CATABKEY_CLOSECTL_PADMINUSKEY_ALT_L__java_short__java_int__java_double__java_char__java_booleanunknown type__vtbl_ptr_type__cxxabiv1bad_alloctype_infoterminate_Unwind_Resumepch_preprocessvisibilityextern_prefixjava_exceptions__adddi3__adddf3__addtf3__addvdi3__subdi3__subti3__subsf3__subdf3__subxf3__subtf3__subvti3__mulsf3__muldf3__mulxf3__multf3__mulvdi3__mulvti3__divdi3__divti3__divsf3__divdf3__divvdi3__divvti3__udivdi3__divmoddi4__divmodti4__udivmoddi4__udivmodti4__moddi3__umodti3__ftruncsf2__ftruncdf2__ftruncxf2__ftrunctf2__anddi3__andti3__iordi3__iorti3__xorti3__ashldi3__ashrdi3__ashrti3__lshrdi3__lshrti3__mindi3__minti3__minsf3__minxf3__mintf3__maxdi3__maxti3__maxdf3__maxxf3__maxtf3__umindi3__umaxdi3__umaxti3__negti2__negdf2__negxf2__negtf2__negvdi2__one_cmpldi2__one_cmplti2__ffsdi2__clzti2__ctzdi2__ctzti2__popcountdi2__popcountti2__parityti2__cmpdi2__cmpti2__ucmpdi2__ucmpti2__cmpsf2__cmpdf2__cmptf2__unordsf2__unorddf2__unordxf2__unordtf2__powisf2__powidf2__powixf2__floatqixf__floathisf__floathidf__floathixf__floatsisf__floatsixf__floatdisf__floatdidf__floatdixf__floatditf__floattisf__floattidf__floattixf__floattitf__fixsfqi__fixsfhi__fixsfsi__fixsfti__fixdfqi__fixdfhi__fixdfsi__fixdfdi__fixdfti__fixxfqi__fixxfhi__fixxfsi__fixxfdi__fixtfhi__fixtfsi__fixtfdi__fixtfti__fixunssfqi__fixunssfsi__fixunssfdi__fixunsdfqi__fixunsdfsi__fixunsdfdi__fixunsdfti__fixunsxfqi__fixunsxfsi__fixunstfqi__fixunstfsi__fixunstfdi__fixunstfti__extendsfdf2__extendsftf2__extenddfxf2__extenddftf2__extendxftf2__truncdfsf2__truncxfsf2__trunctfsf2__truncxfdf2__setbits__STDC____TIME____DATE____FILE____BASE_FILE____cplusplus__STDC_HOSTED____GNUG____GNUC_MINOR____WCHAR_TYPE____WINT_TYPE____GXX_WEAK____DEPRECATED__SCHAR_MAX____SHRT_MAX____INT_MAX____WCHAR_MAX____CHAR_BIT____FLT_RADIX____FLT_MIN_EXP____FLT_MAX_EXP____FLT_MAX____FLT_MIN____FLT_EPSILON____DBL_DIG____DBL_MIN_EXP____DBL_MAX____DBL_MIN____DBL_EPSILON____LDBL_DIG__mvwaddwstrgetmaxyxJ´gàã&~(&±°è&­¼ƒÄ ì&®ÚŒ0ù&ÁÍà '}S0'Šû,` 'ú)Xû€'¿®3v 'èÍà'†<@'€7ï`+'ÿ´mþpà&ŠHcð2'¼žü7'__i860__²ŸAG'¬ÊH³ O'¶,hGa'8Ù÷@S'‘+/ðS'´®>ÛpY'Ð[¶@^'rˆf@å&Ÿó”©`b'œ 0pd',˜Q÷P­'+AÎ(w¢KBÐÓ'…Ýjˆð×'¡-ðâ'ãíËú=(à©'=.+¨&–Ъ&`p¾p´&é#`e Ö&B›+H€×&»8“½Ù&‘`䇰›&?®óoð¹&”5X0î&³”*;ï&[-òD@ð&C¾XÛðð&Aþ (MŸ•3P(…ªåÉð(A\»WP(D…i(ÌÍÊÞ|&®ÚK°(‚U–ö +(¸Ø‘Ð+(þ‹RíP<(õîî ?(Ãð'€B(»óÁÊàC(Ü?ÕA^( uW`(ê3ùy@q(6J/÷ðq(__DECIMAL_DIG____LDBL_MIN____VERSION____NO_INLINE____SSE2____SSE_MATH____SSE2_MATH____gnu_linux____linux____unix___GNU_SOURCE__PDCURSES__PDCURSESCHTYPE_LONG_STDARG_H_ANSI_STDARG_H___GNUC_VA_LIST__gnuc_va_listva_start__STRICT_ANSI___HIDDEN_VA_LIST_BSD_VA_LIST__VA_LIST_VA_LIST___BSD_NET2______386BSD______bsdi____sequent____FreeBSD____va_list___STDDEF_H_ANSI_STDDEF_H__STDDEF_H____need_wchar_t__need_NULL__need_wint_t__NetBSD___ANSI_H__BSD_SIZE_T__PTRDIFF_T__BSD_PTRDIFF_T__WCHAR_T__BSD_WCHAR_T__TYPE_ptrdiff_t_TYPE_size_t_TYPE_wchar_t_T_PTRDIFF__T_PTRDIFF__PTRDIFF_T_GCC_PTRDIFF_T__SIZE_T___SYS_SIZE_T_H__SIZE_T_SIZE_T_DEFINED___int_size_t_h__size_t__wchar_t____WCHAR_T___T_WCHAR__T_WCHAR_WCHAR_T_H_GCC_WCHAR_T_BSD_RUNE_T__ANSI_SOURCE_POSIX_SOURCE__BSD_VISIBLE__rune_t_GCC_PTRDIFF_T__GCC_SIZE_T__GCC_WCHAR_T_offsetof_STDIO_H__need_FILE__need___FILE__USE_ISOC99__USE_XOPEN__USE_XOPEN2K__USE_LARGEFILE__USE_BSD__USE_SVID__USE_GNU__USE_REENTRANT__FAVOR_BSD__GNUC_PREREQ_POSIX_C_SOURCE_XOPEN_SOURCE_SVID_SOURCE_ATFILE_SOURCE_ISOC9X_SOURCE_FORTIFY_SOURCE__OPTIMIZE____GLIBC____GLIBC_MINOR____GLIBC_PREREQ__i386____ia64___SYS_CDEFS_H__nothrow____CONCAT__STRING__BEGIN_DECLS__END_DECLS__ptrvalue__warndecl__flexarr__REDIRECT__malloc____pure____noinline____unused____deprecated____format_arg____format____strfmon____nonnull__always_inline__restrict_arr__LDBL_REDIR1Applicationsdependency7ŠŸ8ÀÉ&Ý£ ö Ë&2N=‰°Ý&=€”ß&J'H—Àß&Å´ P á&qÔL]€â&Tie'ä&%‚–ðå&‚òO£ æ&mªlŽPç&š€GÀ&ºæßò`é&»Â¢ê&{‘IßÀê&êE=¥pë&šyÐZÐì&Èý"€í&àÀ°ó&u.³È`ô&­¯Çõ&…»CBÀõ&%&éÉpö&ÛÅÚC ÷&u/I˜Ð÷&Ù‹uø€ø&GìYàù&»™Ï÷ú&‰8¦o@û&_Ë:%ðû&?}Ns ü&¢%LPý&âN`œ&¤@¹i&jSŽ/°þ&Ï*§‚`ÿ&ÝmZ'z{P[À'fÿwp'¨Ãrö€'#Ósà'â–ä·'«\œu Û&;lê@'nýð'cgþ÷ '9zÕP' ËI~° '¹þÝ&2DÊ ' ý p '»úÄ ' ŸÐ 'Ϋ\á0'¯ä¯à'pÌ['’¤7N@'ÒBÇð'v§-ÂP'ŒÐ'´Ç`"°'KU'»ÖáûÀ'ŽmbÚp'Y5ðW '¸¢Ð'¤ ò€'=~ìÚ'I§…Æð'ÃÁsÚ ' cõWP'ëK@''°ÊŒ1'„©Š0%'m³ 3'OZãP4'‹I\€5'æ¹°5'x_,`6'À$ À7'%ÆÆp8'rÒ>Ö 9'H-¹çÐ9'qÍš¼€:'x:%ú0;'Þ?·ˆà;'4†#<'ìµø@='UŒð='ë € >'òüw7P?'\³@@'¹ì^Ó°@'õîO T'SžEB'ÖÛ×ÀB'ÆÍŸpC'V¼u D'¹Ë&úÐO'´?—Ðe'x“$=€P' Œ+90Q'b:—àQ'­´ÈR'¨œ}l'œŒtÊPU'äM„V'™o9°V'\ñ5ïÐp'è$½Þ`W'&9äœX'Ân«aÀX']´™m œ'¢Ž°Jàr'º¯¹ Z' ü ÐZ',2ÆL0\':kÂà\'lóåU]'=ïð^'Ò{òÇ _'€P`' õIþ°a'­ááØÐá&´tbÀè&¹¼Ͱ*'€~DÀ,'¿Ð.'f+¾xà0'D?2Œ@2'М-ºÐD'œ 0°K'_ÔÞ8M'J yÑÀc'_ÔÞ8 e's»«”à}'«O~'_ÎÊÄ@'}Çýð'«O î'_ÎÊÄ †'â|kc ù'#öÏ8І'ñx0Œ ¬'ž–€‡'|ÿ30ˆ'˜˜~mÀ'+AÎp'˜˜~m ‘'ȿБ'Ʋ¾ý€’'È¿0“'Ʋ¾ýà“'Åžq ð•'~Ç –' MP—'hZ>˜'–ˆt°˜'âÕ‹e ã'volatile™…¢±`™'w9zŽPÙ'¡- Þ'~‹²u é%Ül{œ`æ'RX}p(Ÿ¬  (î™±žÐ(Ãâ¯ò€(àK€š0(A]s‹à(lc,@:(a‰ŸKð:(tSGå ;(#{Je€ &ãïÒ`>(S¢£À?(OºÇÿp@(ÏA˜ÐA({Q#ÚO(\O…ðÚ&ºZÐ4PÜ&=4¥@P(»ý Q(Xë†PR(%]J²S(i÷)Z0ã&m[¥© ú%`º·ÄÐú%C€è‰€û%8£àü%½ &K0ü% ÿ%Ù8XÚP&¯(Xñðþ%*t `ª'†`OP°&Ñv)n&Ä9 `&'Ý€×p%&†ø§à &€'& :0(& “ùÐ&&šf2œ@*&Øÿÿÿÿÿÿÿ")__uint128_t$ðn+'@ð#*`H-, H--¥.__builtin_ceilf@€__builtin_exp2aÂf0É&__cd_out__builtin_fmal__builtin_fmaxf__builtin_fminf__builtin_fmodf__builtin_gamma__builtin_j1f__builtin_lceil__builtin_ldexp__builtin_log10__builtin_log2__builtin_logf__builtin_lrint__builtin_rintl__builtin_sinhf__builtin_sinhl__builtin_sinl__builtin_tanf__builtin_y0f__builtin_y0l__builtin_y1l__muldc3__divxc3__float80__builtin_ccosh__builtin_cexpf__builtin_conjl__builtin_cpowf__builtin_cpowl__builtin_cproj__builtin_csqrt__builtin_ctan__builtin_ctanhisxdigit__builtin_ctz__builtin_ffsllžf€i&>6ÅÐs&__memset_chk__fprintf_chkpÚys€,(freopen64__magic_cookie__io_funcsfmemopensetbuffersetlinebuf__printf__vasprintf__asprintfasprintfvdprintf__scanf__getc_unlockedfgetc_unlockedputc_unlockedfgets_unlocked__getdelim__lineptr__delimitergetdelimfread_unlockedfseeko64ftello64fgetpos64fsetpos64clearerrfeof_unlockedferror_unlockedsys_nerr_sys_nerr_sys_errlistfileno_unlockedobstack_printf__obstackflockfileftrylockfilefunlockfile__need_getoptPDC_WIDE__cplusplus____CPLUSPLUSMOUSE_STATUSBUTTON_RELEASEDBUTTON_PRESSEDBUTTON_MOVEDWHEEL_SCROLLEDPDC_BUTTON_ALTMOUSE_X_POSMouse_statusMOUSE_Y_POSPDC_MOUSE_MOVEDBUTTON_CHANGEDBUTTON_STATUSMOUSE_WHEEL_UPBUTTON1_CLICKEDBUTTON1_MOVEDBUTTON2_PRESSED__imag__BUTTON2_CLICKED__inlineBUTTON2_MOVEDBUTTON3_PRESSEDBUTTON3_CLICKEDBUTTON3_MOVEDBUTTON4_PRESSEDBUTTON4_CLICKEDBUTTON5_CLICKED__typeof__BUTTON_SHIFTBUTTON_CONTROLBUTTON_CTRLBUTTON_ALT_leaveit_use_keypad_firstch_delaymsorig_attrorig_foreorig_backorig_cursor_map_mbe_to_keymouse_waitslklinesslk_winptrlinesrippedoffdelaytenths_preserve_restorekey_codeXcurscrSizesb_viewport_ysb_viewport_xsb_total_ysb_cur_xline_colorPDC_DLL_BUILDCURSES_LIBRARYdllexportdllimportA_NORMALA_ALTCHARSETA_RIGHTLINEA_LEFTLINEA_UNDERLINEA_REVERSEA_CHARTEXTA_ITALICA_PROTECTPDC_COLOR_SHIFTA_STANDOUTWA_ALTCHARSETWA_PROTECTWA_REVERSEWA_RIGHTWA_STANDOUTWA_UNDERLINEWA_HORIZONTALWA_VERTICALACS_PICKACS_LLCORNERACS_URCORNERACS_LRCORNERACS_RTEEACS_LTEEACS_BTEEACS_TTEEACS_VLINEACS_PLUSACS_DIAMONDACS_CKBOARDACS_DEGREEACS_PLMINUSACS_BULLETACS_LARROWACS_RARROWACS_DARROWACS_BOARDACS_BLOCKACS_LEQUALACS_GEQUALACS_NEQUALACS_STERLINGACS_BSSBACS_SSBBACS_BBSSACS_SBSSACS_SSSBACS_SSBSACS_BSSSACS_SBSBACS_SSSSWACS_ULCORNERWACS_LLCORNERWACS_URCORNERWACS_LRCORNERWACS_RTEEWACS_LTEEWACS_BTEEWACS_TTEEWACS_HLINEoperator deleteWACS_PLUSWACS_DIAMONDWACS_CKBOARDWACS_DEGREEWACS_BULLETWACS_LARROWWACS_RARROWWACS_DARROWWACS_UARROWWACS_BOARDWACS_LANTERNWACS_BLOCKWACS_GEQUALWACS_NEQUALWACS_STERLINGWACS_BSSBWACS_SSBBWACS_BBSSWACS_SBBSoperator/operator^basic_stringbasic_istream__base_ctor __stub_chflags__stub_fattach__stub_fchflags__stub_getmsg__stub_gtty__stub_lchmod__stub_revoke__stub_setlogin__stub_stty_BITS_TYPES_H__u_char__u_short__u_long__uint8_t__int16_t__uint16_t__int32_t__uint32_t__int64_tbit_size_type__u_quad_t__U16_TYPE__S32_TYPE__U32_TYPE__SQUAD_TYPE__UQUAD_TYPE__SWORD_TYPE__SLONG32_TYPE__ULONG32_TYPE__STD_TYPE__INO_T_TYPE__INO64_T_TYPE__MODE_T_TYPE__OFF64_T_TYPE__RLIM_T_TYPE__RLIM64_T_TYPE__ID_T_TYPE__TIME_T_TYPE__SWBLK_T_TYPE__KEY_T_TYPE__TIMER_T_TYPEasm_fprintf__FD_SETSIZE__ino64_t__mode_t__nlink_t__off64_t__clock_t__rlim_t__rlim64_t__useconds_t__suseconds_t__daddr_t__clockid_t__timer_t__blksize_t__blkcnt64_t__fsblkcnt64_t__fsfilcnt_t__fsfilcnt64_t__loff_t__caddr_t__intptr_t__socklen_t_IO_FILE_WCHAR_H__WCHAR_MIN__mbstate_tmbstate_tWCHAR_MINwcscasecmpwcscasecmp_l__locale_twcscoll_lwcsxfrm_lwcschrnul__reject__needle__maxlenwmemmovewmempcpy__mbrlen__wctob_aliasmbsrtowcswcsrtombswcsnrtombswcswidth__endptrwcstoullwcstol_lwcstoll_lwcstoull_lwcstod_l__builtin_atanhwcstold_lopen_wmemstream__bufloc__sizelocfwprintf__stream__formatswprintfvfwprintfvwprintfvswprintfvfwscanfvswscanfgetwcharputwchargetwc_unlockedfgetwc_unlockedfputwc_unlockedputwc_unlockedfgetws_unlockedfputws_unlockedwcsftime__maxsize__need_iswxxx_G_size_t_G_fpos_t_G_fpos64_t_G_ssize_t_G_off_t_G_off64_t_G_pid_t_G_uid_t_G_wchar_t_G_wint_t__GCONV_OK__GCONV_NOCONV__GCONV_NODB__GCONV_NOMEM__builtin_cosf__builtin_cosh__GCONV_IS_LAST__gconv_step__gconv_fct__gconv_end_fct__trans_fct__trans_end_fct__shlib_handle__modname__counter__from_name__to_name__btowc_fct__init_fct__end_fct__min_needed_to__max_needed_to__stateful__outbufWACS_SBSSWACS_SSBSWACS_BSSSWACS_BSBSWACS_SBSBWACS_SSSSCOLOR_BLACKCOLOR_REDCOLOR_GREENCOLOR_BLUECOLOR_CYANCOLOR_MAGENTACOLOR_YELLOWCOLOR_WHITEKEY_BREAKKEY_DOWN__builtin_expKEY_HOMEKEY_BACKSPACEKEY_CLEARKEY_NPAGEKEY_PPAGEKEY_STABKEY_CTABKEY_ENTERKEY_SRESETKEY_PRINTKEY_SHELPKEY_LHELPKEY_BTABKEY_CANCELKEY_COMMANDKEY_COPYKEY_EXITKEY_HELPKEY_MARKKEY_MESSAGEKEY_MOVEKEY_NEXTKEY_OPENKEY_OPTIONSKEY_PREVIOUSKEY_REDOKEY_REFRESHKEY_REPLACEKEY_RESTARTKEY_RESUMEKEY_SAVEKEY_SBEGKEY_SCOMMANDKEY_SCREATEKEY_SELECTKEY_SENDKEY_SEXITKEY_SFINDKEY_SHOMEKEY_SLEFTKEY_SMESSAGEKEY_SNEXTKEY_SOPTIONSKEY_SPREVIOUSKEY_SPRINTKEY_SREDOKEY_SRIGHTKEY_SUNDOKEY_SUSPENDKEY_UNDOCTL_RIGHTCTL_PGUPCTL_PGDNPADSLASHPADENTERCTL_PADENTERALT_PADENTERPADMINUSCTL_PADCENTERCTL_PADPLUSCTL_PADSTARALT_PADPLUSALT_PADMINUSALT_PADSLASHALT_PADSTARALT_PADSTOPCTL_DOWNALT_MINUS__builtin_fmafALT_HOMEALT_PGDNALT_DOWNALT_RIGHTALT_LEFTALT_ENTERALT_BQUOTEALT_LBRACKETALT_SEMICOLONALT_FQUOTEALT_STOPALT_BKSPCTL_BKSPCTL_PAD1CTL_PAD2CTL_PAD4CTL_PAD5CTL_PAD6CTL_PAD8CTL_PAD9ALT_PAD0ALT_PAD1ALT_PAD2ALT_PAD3ALT_PAD4ALT_PAD7ALT_PAD8ALT_PAD9ALT_BSLASHCTL_ENTERSHF_PADENTERSHF_PADSTARSHF_PADMINUSSHF_DOWNKEY_MOUSEKEY_SHIFT_LKEY_SHIFT_RKEY_CONTROL_LKEY_CONTROL_RKEY_ALT_Raddchnstraddchstrattr_getattr_offbaudrateclrtobotclrtoeolcolor_contentcolor_setcurs_setdef_prog_modedef_shell_modedelay_outputdeletelndelscreendoupdateechocharflushinphalfdelayhas_colorsinchnstrinit_colorinit_pairinsdellninsertlnintrflushisendwinis_wintouchedkillcharlongnamemvaddchstrmvaddnstrmvaddstrmvderwinmvgetnstrmvgetstrmvinchnstrmvinchstrmvinnstrmvinsnstrmvinsstrmvprintwmvwaddchnstrmvwaddchstrmvwaddchmvwaddstrmvwchgatmvwdelchmvwgetchmvwgetnstrmvwgetstrmvwhlinemvwinchnstrmvwinchstrmvwinnstrmvwinschmvwinsnstrmvwinsstrmvwinstrmvwprintwmvwscanwmvwvlinenocbreaknoqiflushnotimeoutoverwritepair_contentpechocharpnoutrefreshprefreshredrawwinripofflinescr_dumpscr_initscr_restorescrollokset_termsetscrregslk_attroffslk_attr_offslk_attronslk_attr_onslk_attr_setslk_clearslk_colorslk_initslk_labelslk_noutrefreshslk_refreshslk_restoreslk_touchstandoutstart_colortermattrsterm_attrstouchlinetouchwintypeaheaduntouchwinvid_attrvid_putsvw_printwvwprintwvw_scanwwaddchnstrwaddnstrwattroffwattrsetwattr_getwattr_offwattr_onwattr_setwbkgdsetwclrtobotwclrtoeolwcolor_setwcursyncupwdeletelnwgetnstrwinchnstrwinsdellnwinsertlnwinsnstrwnoutrefreshwredrawlnwrefreshwstandendwstandoutwsyncdownwtimeoutwtouchlnadd_wchnstradd_wchstrecho_wcharerasewchargetbkgrndget_wstrhline_setins_nwstrins_wstrin_wchnstrin_wchstrmvaddnwstrmvadd_wchmvadd_wchnstrmvgetn_wstrmvget_wstrmvhline_setmvins_nwstrmvins_wchmvinwstrmvin_wchmvin_wchnstrmvin_wchstrmvvline_setmvwadd_wchmvwadd_wchnstrmvwadd_wchstrmvwget_wchmvwget_wstrmvwhline_setmvwins_wchmvwins_wstrmvwin_wchmvwin_wchnstrmvwin_wchstrmvwvline_setpecho_wcharslk_wsetwaddnwstrwaddwstrwadd_wchwadd_wchnstrwadd_wchstrwbkgrndsetwborder_setwecho_wcharwgetbkgrndwget_wstrwhline_setwinnwstrwins_nwstrwins_wchwins_wstrwin_wchnstrwin_wchstrwvline_setgetattrstraceoffnocrmodesavetermmouse_setmouse_onmouse_offmap_buttonwmouse_positiongetmousecurses_versionmousemaskmouse_trafonc_getmouseungetmouseaddrawchinsrawchis_termresizedmvaddrawchmvdeletelnmvinsertlnmvinsrawchmvwaddrawchmvwdeletelnmvwinsertlnraw_outputresize_termresize_windowwaddrawchwinsrawchwordcharslk_wlabelPDC_debugPDC_ungetchPDC_set_blinkPDC_set_titleXinitscrsb_set_horzsb_get_horzsb_refreshCOLOR_PAIRPAIR_NUMBERgetparyxPDC_CLIP_EMPTY__negdi2__BEOS____outbufend__internal_use__gconv_info__gconv_t_G_iconv_t_G_int16_t__mode___G_int32_t_G_uint16_t_G_HAVE_BOOL_G_va_list_G_HAVE_MREMAP_G_OPEN64__open64_G_LSEEK64__lseek64__mmap64_G_FSTAT64__fxstat64_STAT_VER_G_BUFSIZ_IO_pos_t_IO_fpos_t_IO_fpos64_t_IO_ssize_t_IO_off_t_IO_off64_t_IO_pid_t_IO_uid_t_IO_iconv_t_IO_va_list_IO_USE_DTOA_IOS_INPUT_IOS_OUTPUT_IOS_ATEND_IOS_APPEND_IOS_TRUNC_IOS_NOCREATE_IOS_NOREPLACE_IOS_BIN_IO_MAGIC_IO_MAGIC_MASK_IO_USER_BUF_IO_NO_READS_IO_NO_WRITES_IO_EOF_SEEN_IO_ERR_SEEN_IO_IN_BACKUP_IO_IS_FILEBUF_IO_BAD_SEEN_IO_FLAGS2_MMAP_IO_SKIPWS_IO_LEFT_IO_INTERNAL_IO_SHOWBASE_IO_SHOWPOS_IO_SCIENTIFIC_IO_FIXED_IO_STDIO_IO_DONT_CLOSE_IO_MTSAFE_IO_IO_lock_t_IO_markerset_streamposstreamposstreammarkerstreambuf__codecvt_ok__codecvt_error_IO_codecvt__codecvt_destr__codecvt_do_in_IO_wide_data_IO_read_ptr_IO_read_end_IO_read_base_IO_write_base_IO_write_ptr_IO_write_end_IO_buf_base_IO_buf_end_IO_save_base_IO_backup_base_IO_save_end_IO_state_codecvt_shortbuf_wide_vtable_IO_file_flags_markers_blksize_old_offset__HAVE_COLUMN_cur_column_vtable_offset_wide_data_freeres_list_freeres_buf_freeres_size_unused2_IO_FILE_plus_IO_2_1_stdout__IO_2_1_stderr__IO_stdout_IO_stderr__cookie__io_write_fn_IO_cookie_file_IO_cookie_init__underflow__overflow__wuflow__woverflow_IO_putc_IO_feof_IO_ferror_IO_flockfile_IO_peekc_IO_vfprintf_IO_padn_IO_sgetn_IO_seekpos_IO_putwc_IO_fwideGLIBC_2_0GLIBC_2_1_IO_stdin_usedweak_extern__result_IO_vfwprintf_IO_wpadnfpos64_tSEEK_ENDP_tmpdir__need_IOV_MAXL_tmpnamL_cuserid__filenametmpfile64tmpnam_rfflush_unlockedfcloseall__java_longglobal type__addti3__addsf3__addxf3__addvti3__subvdi3__muldi3__multi3__divxf3__udivti3__modti3__umoddi3__mindf3__maxsf3__uminti3__ffsti2__clzdi2__paritydi2__cmpxf2__powitf2__floatqisf__floatqitf__floathitf__floatsitf__fixxfti__fixtfqi__fixunsdfhi__fixunsxfhi__fixunsxfdi__SIZE_TYPE____DBL_MAX_EXP__fopencookiesys_errlistBUTTON_CLICKED_trap_mbe__builtin_ilogb__builtin_j1__builtin_j1l__stub_fdetach__stub_lutimes__builtin_logb__FSID_T_TYPE__fsid_tunassert__builtin_powi__builtin_powif_Complex__alignof____func____label____thread__builtin_roundexplicitoperatorprotectedinterfaceselectoroperator&operator%operator==operator<=operator->*operator>?operator::operator|=operator?=__builtin_tanh__builtin_tanl__comp_dtor long intgp_offset__builtin_yn__builtin_ynf__builtin_ynlnoreturn__builtin_acosf__builtin_asinf_G_stat64__builtin_asinl__builtin_atan__builtin_cbrt__builtin_cbrtf__builtin_cbrtl__builtin_ceilcopysignl__builtin_coshf__builtin_cosl__builtin_drem__builtin_dreml__builtin_erf__builtin_erfc__builtin_erff__builtin_exp10__builtin_exp2l__builtin_expf__builtin_expm1__builtin_fabsl__builtin_fdiml__builtin_floorKEY_LEFTKEY_FIND__mulsc3KEY_SCOPYKEY_SEOLKEY_SRSUMECTL_HOMECTL_PADSTOPALT_PGUPALT_RBRACKETALT_FSLASHCTL_PAD0CTL_PAD7SHF_PADSLASH) o+KEY_RESIZEmvaddchnstrxcurses.h mvadd_wchstr__builtin_bcopywenclosewmouse_trafosb_set_vertsb_get_vertÀÿÿÿÿÿÿÿÁÿÿÿÿÿÿÿÄÿÿÿÿÿÿÿÊÿÿÿÿÿÿÿËÿÿÿÿÿÿÿÌÿÿÿÿÿÿÿÎÿÿÿÿÿÿÿÏÿÿÿÿÿÿÿÚÿÿÿÿÿÿÿÞÿÿÿÿÿÿÿîÿÿÿÿÿÿÿöÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿùÿÿÿÿÿÿÿþÿÿÿÿÿÿÿ(,.>?¤. Ç,"ï##  .$Àn+% H-%@H-&Ò ' ï#(`¤.)Po+*€ -+ð¿(+ À(-°¤..PÀ(.€o+  __strcat_chk@€ ¯&È€¶&‡³M:0Â&˜Œ\Íð˜&__LDBL_MAX____LP64__#machine__x86_64__x86_64__PDC_BUILDBSDcurses_VA_LIST__svr4____need_size_t_SIZE_T__PTRDIFF_T_WCHAR_Tptrdiff_t__size_t___T_SIZE__GCC_SIZE_T__INT_WCHAR_T_H_FEATURES_H__USE_POSIX2__USE_UNIX98__USE_MISC__USE_ATFILE__USE_ANSI_BSD_SOURCE_ISOC99_SOURCE_REENTRANT_THREAD_SAFE__GNU_LIBRARY____long_double_t__bounded__unbounded__ASMNAME__REDIRECT_NTH__ASMNAME2__nonnull__restrict__WORDSIZE__LDBL_REDIR__nldbl__G_HAVE_ATEXIT_G_HAVE_MMAP_G_MMAP64_G_USING_THUNKS_IO_wint_t_IO_UNBUFFERED_IO_RIGHT_IO_UPPERCASE_IO_UNITBUF_IO_BOOLALPHAèƒB0I&3aÌ‘p*(shìU&oÅ?€^&&9ÖÐ~&? Rüà‹&cpk?j_€³'SHLIB_COMPAT_IO_vfwscanfÈ×ùZP](FOPEN_MAX2 „ƒ0z(|ÿ3í%Š IYP&include_nextsystem_header__VA_ARGS____FUNCTION____alignof__attribute__attribute____complex__complex____const____extension____inline____real____restrict__restrict____signed__signed____typeof__volatile__volatile__const_castcontinuedynamic_castnamespaceregisterstatic_casttemplatetypenameunsignedimplementationprotocolsynchronizedoperator newoperator new []operator+operator-operator*operator~operator!operator++operator--operator sizeofoperator|operator<<operator>>operator!=operator<operator>operator>=operator&&operator||operator,operator->operator[]operator>=operator?:operator()allocatorchar_traitsbasic_ostreambasic_iostream__comp_ctor __base_dtor __in_chrg__vtt_parmunsigned intunsigned longlong long intshort intunsigned shortsigned charunsigned char__int128_t__va_list_tagfp_offsetreg_save_arealong doublecomplex intcomplex floatcomplex doubleformat_arggcc_diaggcc_cdiaggcc_cxxdiagsentinelstrftime__builtin_acos__builtin_acosh__builtin_acosl__builtin_asin__builtin_asinh__builtin_atan2__builtin_atanf__builtin_atanl__builtin_ceillcopysigncopysignf__builtin_cos__builtin_coshl__builtin_dremf__builtin_erfcf__builtin_erfcl__builtin_erfl__builtin_exp2f__builtin_expl__builtin_fabs__builtin_fabsf__builtin_fdim__builtin_fdimf__builtin_fmaborder_setgetn_wstrmvget_wchmvins_wstrunget_wch__builtin_pow10__java_byte__java_float__builtin_cargf__divtf3__xordi3__ashlti3__negsf2__negvti2__floatqidf__fixsfdi__fixunssfhi__fixunssfti__fixunsxfti__fixunstfhi__extendsfxf2__trunctfdf2__trunctfxf2__gcov_flush__LINE____GNUC____EXCEPTIONS__LONG_MAX____INTMAX_MAX____FLT_DIG____amd64__SYSVcurses__WCHAR_T@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@€ €€ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÐË&Î&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@/usr/lib/gcc/x86_64-redhat-linux/4.1.2/include/stdarg.h/usr/lib/gcc/x86_64-redhat-linux/4.1.2/include/stddef.h@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@€!¯°±²@f.€6%àß €f.›@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Ps(zP›"  d"G9 ލ àd" GVP›" G0G90¦!0ª-º*9Gº*Ø›o :GDº*™o @G úç,º*BGDº*Þ›o ”º*Ƥo •9Àœåžo ¡4º*s¤o ¢9 _£º*,¡o еº*6§o ‹µ9pýåžo •µ º*s¤o —µ9 ÿù¦o µº*,¡o Šº*ƨo ‹9Лåžo – º*2¨o ˜9àCù¦o £º*6¨o º*ƨo 9pCåžo   º*2¨o  9Лù¦o ! º*6¨o Š º*ƨo ‹ 9pCåžo •  º*2¨o — 9àCù¦o ¢ º*6¨o `Ê)0Í& Fº*Ƥo 9Àœåžo !4º*s¤o "90_#º*,¡o § P)' @g”°e @ý,ÿÿÿÿÿÿÿÿ €b¦ Ð ' @g5p6" ¿Ðÿ,ÿÿÿÿÿÿÿÿó€b0*' @g• f AÀý,ÿÿÿÿÿÿÿÿ@ €b1€' @g6P7" À-ÿÿÿÿÿÿÿÿ@ó08"€b2l' @g–f B€þ,ÿÿÿÿÿÿÿÿ€ €b¨ €' @g708"àd" ÀP-ÿÿÿÿÿÿÿÿ€ó€b4G' @g—g C@ÿ,ÿÿÿÿÿÿÿÿÀ €b3€' @g808" À@-ÿÿÿÿÿÿÿÿÀó€b60;' @g˜àg D-ÿÿÿÿÿÿÿÿ€b7Ð' @g99" Á-ÿÿÿÿÿÿÿÿô€9"€b8à;' @g™Ph EÀ-ÿÿÿÿÿÿÿÿ@€b5Ð' @g:€9"àd" Áð-ÿÿÿÿÿÿÿÿ@ô€b:<' @gš0i F€-ÿÿÿÿÿÿÿÿ€€b9Ð' @g;€9" ÁP(ÿÿÿÿÿÿÿÿ€ô€b<@=' @g› i Gp-ÿÿÿÿÿÿÿÿÀ€b=à' @g<`:" °(ÿÿÿÿÿÿÿÿÀôP„€b>l' @gœ€j H0-ÿÿÿÿÿÿÿÿ€b;à' @g=P„àd" Âp‚(ÿÿÿÿÿÿÿÿõ€b@ð=' @gðj I -ÿÿÿÿÿÿÿÿ@€b?à' @g>P„ Â0ƒ(ÿÿÿÿÿÿÿÿ@õ€bB >' @gž`k J°-ÿÿÿÿÿÿÿÿ€€bC ' @g?0… Ãðƒ(ÿÿÿÿÿÿÿÿ€õ …€bDP?' @gŸÐk Kà(ÿÿÿÿÿÿÿÿÀ€bA ' @g@ …àd" ð„(ÿÿÿÿÿÿÿÿÀõ€bF O' @g  m L ‚(ÿÿÿÿÿÿÿÿ€bE ' @gA … Ãp…(ÿÿÿÿÿÿÿÿö€bH@' @g¡m M`ƒ(ÿÿÿÿÿÿÿÿ@€bIð' @gBð† Ä0†(ÿÿÿÿÿÿÿÿ@öЇ€bJl' @g¢pn N „(ÿÿÿÿÿÿÿÿ€€bGð' @gCЇàd" Äð†(ÿÿÿÿÿÿÿÿ€ö€bL!' @g£àn Oðü*ÿÿÿÿÿÿÿÿÀ€bKð' @gDЇ ݇(ÿÿÿÿÿÿÿÿÀö€bNð'' @g¤Ào P ý*ÿÿÿÿÿÿÿÿ€bOP' @gE ‰ Åpˆ(ÿÿÿÿÿÿÿÿ÷Š€bP (' @g¥0p Q@ô(ÿÿÿÿÿÿÿÿ@€bMP' @gFŠàd" Å0‰(ÿÿÿÿÿÿÿÿ@÷€bRP)' @g¦€Ñ R ‡(ÿÿÿÿÿÿÿÿ€€bQP' @gGŠ Åð‰(ÿÿÿÿÿÿÿÿ€÷€bT*' @g§ p Sàý*ÿÿÿÿÿÿÿÿÀ€bVl' @g¨q T ˆ(ÿÿÿÿÿÿÿÿ€bn Pê%àõ-„Ø Pc ÿÿÿÿÿÿÿÿö@›#Wp' @g©€q U`‰(ÿÿÿÿÿÿÿÿ€€bXë%àõ-†Û Àc ÿÿÿÿÿÿÿÿ@ö #Yp' @gª`r V Š(ÿÿÿÿÿÿÿÿÀ€bfÐ&àõ- ài ÿÿÿÿÿÿÿÿù³#[p' @g«Ðr WàŠ(ÿÿÿÿÿÿÿÿ€b\°^(àõ- Pj ÿÿÿÿÿÿÿÿ@ùà´#]p' @g¬@s XЋ(ÿÿÿÿÿÿÿÿ@€bwö%àõ- h ÿÿÿÿÿÿÿÿ€ï ®#_p' @g­°s YŒ(ÿÿÿÿÿÿÿÿ€€b^Ð&àõ-' Àj ÿÿÿÿÿÿÿÿ€ù€µ#aÇ& @g®t ZP(ÿÿÿÿÿÿÿÿÀ€b` b(àõ- i ÿÿÿÿÿÿÿÿ@ö ±#c 9' @g¯u áÿÿÿÿÿÿÿÿu€bdö%àõ-  pi ÿÿÿÿÿÿÿÿÀøÀ±#eðû& @g°àu âÿÿÿÿÿÿÿÿ€àu€bZ b(àõ-¹ð e ÿÿÿÿÿÿÿÿ€ À§#g' @g±¬ ãÿÿÿÿÿÿÿÿÀ¬€bh b(àõ-ºò €e ÿÿÿÿÿÿÿÿÀö`¨#i°Ç& @g²­ äÿÿÿÿÿÿÿÿ@­€bj`È&àõ-Àó ðe ÿÿÿÿÿÿÿÿ÷kàù& @g³à­ åÿÿÿÿÿÿÿÿ€à­€bl b(àõ-Ìõ Ðf ÿÿÿÿÿÿÿÿ@÷©#mÇ&@g´P® øÿÿÿÿÿÿÿÿÀÀ®€bn`È&àõ-Íö °g ÿÿÿÿÿÿÿÿ€÷oÇ&@gµ0¯ ùÿÿÿÿÿÿÿÿ°€bp b(àõ-×ø pº ÿÿÿÿÿÿÿÿÀ÷ ©#q ú% @g¶€° †ÿÿÿÿÿÿÿÿ@€°€bb0&àõ-8 0k ÿÿÿÿÿÿÿÿÀù`·#s ú% @g·ð° Šÿÿÿÿÿÿÿÿ€ð°€bU`ô& @gHP‹ Æ‹(ÿÿÿÿÿÿÿÿÀ÷0Œ€brö%àõ-äþ h ÿÿÿÿÿÿÿÿÀ#S`ô& @gI0Œàd" Æ`Œ(ÿÿÿÿÿÿÿÿø€bv`ô& @gJ0Œ Æ€(ÿÿÿÿÿÿÿÿ@ø€by°ó& @gK ÇpŽ(ÿÿÿÿÿÿÿÿ€øð€bx°ó& @gLðàd" Ç`(ÿÿÿÿÿÿÿÿÀø€bz°ó& @gMð Ç€(ÿÿÿÿÿÿÿÿù€b|õ& @gNÐŽ È ‘(ÿÿÿÿÿÿÿÿ@ù°€b{õ& @gO°àd" ÈÀ’(ÿÿÿÿÿÿÿÿ€ù€b}õ& @gP° Èà“(ÿÿÿÿÿÿÿÿÀù€bÀß& @gQ É`ÿ*ÿÿÿÿÿÿÿÿúp‘€b~Àß& @gRp‘àd" É0•(ÿÿÿÿÿÿÿÿ@ú€b€Àß& @gSp‘ Éð•(ÿÿÿÿÿÿÿÿ€ú€b‚ß& @gTP’ ʰ–(ÿÿÿÿÿÿÿÿÀú0“€bß& @gU0“àd" Êp—(ÿÿÿÿÿÿÿÿû€bƒß& @gV0“ Ê0˜(ÿÿÿÿÿÿÿÿ@û€b… á& @gW” Ëð˜(ÿÿÿÿÿÿÿÿ€ûð”€b„ á& @gXð”àd" ˰™(ÿÿÿÿÿÿÿÿÀû€b† á& @gYð” Ë š(ÿÿÿÿÿÿÿÿü€bˆÀß& @gZ`• Ì œ(ÿÿÿÿÿÿÿÿ@ü@–€b‡Àß& @g[@–àd" Ì (ÿÿÿÿÿÿÿÿ€ü€b‰Àß& @g\@– Ì Ÿ(ÿÿÿÿÿÿÿÿÀü€b‹À7' @g] — ÍàŸ(ÿÿÿÿÿÿÿÿý˜€bŠÀ7' @g^˜àd" Íp©(ÿÿÿÿÿÿÿÿ@ý€bŒÀ7' @g_˜ ÍЩ(ÿÿÿÿÿÿÿÿ€ý€bŽ7' @g`à˜ Î0ª(ÿÿÿÿÿÿÿÿÀýÀ™€b7' @gaÀ™àd" ÎÀª(ÿÿÿÿÿÿÿÿþ€b7' @gbÀ™ Î «(ÿÿÿÿÿÿÿÿ@þ€b‘p8' @gc š Ï€«(ÿÿÿÿÿÿÿÿ€þ€›€bp8' @gd€›àd" Ϭ(ÿÿÿÿÿÿÿÿÀþ€b’p8' @ge€› Ïp¬(ÿÿÿÿÿÿÿÿÿ€b”ß& @gf`œ Ð0­(ÿÿÿÿÿÿÿÿ@ÿ@€b“ß& @gg@àd" ÐP®(ÿÿÿÿÿÿÿÿ€ÿ€bDDº*0ª-º*DDº*Ø›o D9€U™o %D9 è-D ª-º*Þ›o .D9Pl8Dº*:DDº*?Dº*@D2e9@ë›o @eº*Ø›o Aeº*™o Be9ðÊ!Qeº*Þ›o ReDº*Seº*Teº*Ueº*Dç Ðì-º*°¢o Eç  º*åžo Fç 9€‘¡o Nç àá-º*Oç º*,¡o Pç º*óo Qç º*Rç 9ï`ç º*aç º*Åç Ðì-º*°¢o Æç  º*åžo Çç 9€‘¡o Ïç àá-º*Ðç º*,¡o Ñç º*óo Òç º*Óç 9€ïâç º*ãç º*€z#ü"Àg#€h#@i#j#Àj#€k#@l#m#Àm#€n#@o#@u#g#p#Àp#€q#@r#s#Às#€t#v#Àv#€w#@x#y#Ày#@{#|#y,#08(À·-•* À ÿÿÿÿÿÿÿÿá€w%•ß& @gh@ Я(ÿÿÿÿÿÿÿÿÀÿ€bžÀß& @gi ž Ñp¯(ÿÿÿÿÿÿÿÿŸ€b–Àß& @gjŸàd" Ѱ(ÿÿÿÿÿÿÿÿ@€bŸÀß& @gkŸ Ñ`°(ÿÿÿÿÿÿÿÿ€€b¡ß& @glàŸ ÒÀ°(ÿÿÿÿÿÿÿÿÀÀ €b ß& @gmÀ àd" Ò ±(ÿÿÿÿÿÿÿÿ€b¢ß& @gnÀ  Ò€±(ÿÿÿÿÿÿÿÿ@€b¤ á& @go¢ Óà±(ÿÿÿÿÿÿÿÿ€ð¢€b£ á& @gpð¢àd" Óp²(ÿÿÿÿÿÿÿÿÀ€b¥ á& @gqð¢ Óв(ÿÿÿÿÿÿÿÿ€b§ á& @gr@¤ ÔÀ³(ÿÿÿÿÿÿÿÿ@€Ì€b¦ á& @gs€Ìàd" Ô€´(ÿÿÿÿÿÿÿÿ€€b¨ á& @gt€Ì Ô@µ(ÿÿÿÿÿÿÿÿÀ€bªÀß& @gu`Í Õ µ(ÿÿÿÿÿÿÿÿ@΀b©Àß& @gv@Îàd" Õ¶(ÿÿÿÿÿÿÿÿ@€b«Àß& @gw@Î Õ¶(ÿÿÿÿÿÿÿÿ€€bt0&àõ-;! `m ÿÿÿÿÿÿÿÿúà¹#®à&àõ-E% Ðm ÿÿÿÿÿÿÿÿ@ú`¼#¾ð&àõ-ÀX @u ÿÿÿÿÿÿÿÿÀü`Õ#° &àõ-Ï\ ðs ÿÿÿÿÿÿÿÿý Ö#¯ö%àõ-[- @n ÿÿÿÿÿÿÿÿ÷ À#²ð &àõ-c2 o ÿÿÿÿÿÿÿÿÀú@Ã#±P&àõ-Ð^ `t ÿÿÿÿÿÿÿÿ@ý€Ø#´`&àõ-Ña °u ÿÿÿÿÿÿÿÿ€ý Ù#³ð &àõ-? p ÿÿÿÿÿÿÿÿñ€É#µp&àõ-Òd v ÿÿÿÿÿÿÿÿÀý`Ú#¶À& àõ-ŠH Ë ÿÿÿÿÿÿÿÿ@ó€Î#¸p&àõ-J Àq ÿÿÿÿÿÿÿÿ€û`Ð#¹Àv(àõ-”L 0r ÿÿÿÿÿÿÿÿÀûÑ#º &àõ-¢P  r ÿÿÿÿÿÿÿÿü Ñ#»Ð&àõ-§R s ÿÿÿÿÿÿÿÿ@ü€Ó#­ß& @gxÏ Öð¶(ÿÿÿÿÿÿÿÿÀàЀb¼à&àõ-»U Ðt ÿÿÿÿÿÿÿÿ€ü Ô#¬ß& @gyàÐàd" ÖP·(ÿÿÿÿÿÿÿÿ€b½ß& @gzàÐ Ö°·(ÿÿÿÿÿÿÿÿ@€bÀ á& @g{0Ò ×@¸(ÿÿÿÿÿÿÿÿ€€Ó€b¿ á& @g|€Óàd" × ¸(ÿÿÿÿÿÿÿÿÀ€bÁ á& @g}€Ó ×¹(ÿÿÿÿÿÿÿÿ€bÃÀß& @g~ÐÔ Øð¹(ÿÿÿÿÿÿÿÿ@ Ö€bÂÀß& @g Öàd" ذº(ÿÿÿÿÿÿÿÿ€€bÄÀß& @g€ Ö Ø€Ï(ÿÿÿÿÿÿÿÿÀ€bÆß& @gp× ÙpÐ(ÿÿÿÿÿÿÿÿÀØ€bÅß& @g‚ÀØàd" Ù0Ñ(ÿÿÿÿÿÿÿÿ@€bÇß& @gƒÀØ ÙðÑ(ÿÿÿÿÿÿÿÿ€€bÉÀß& @g„€Ú Ú°Ò(ÿÿÿÿÿÿÿÿÀÐÛ€bÈÀß& @g…ÐÛàd" ÚpÓ(ÿÿÿÿÿÿÿÿ€bÊÀß& @g†ÐÛ Ú0Ô(ÿÿÿÿÿÿÿÿ@€bÌß& @g‡ Ý ÛðÔ(ÿÿÿÿÿÿÿÿ€pÞ€bËß& @gˆpÞàd" Û°Õ(ÿÿÿÿÿÿÿÿÀ€bÍß& @g‰pÞ Û Ö(ÿÿÿÿÿÿÿÿ€bÏ á& @gŠPß Ü`×(ÿÿÿÿÿÿÿÿ@0à€bÎ á& @g‹0ààd" Ü Ø(ÿÿÿÿÿÿÿÿ€€bÐ á& @gŒ0à ÜàØ(ÿÿÿÿÿÿÿÿÀ€bÒ á& @gá Ý Ù(ÿÿÿÿÿÿÿÿ`â€bÑ á& @gŽ`âàd" Ý`Ú(ÿÿÿÿÿÿÿÿ@€bÓ á& @g`â Ý Û(ÿÿÿÿÿÿÿÿ€€bÕÀß& @g°ã Þ€Û(ÿÿÿÿÿÿÿÿÀå€bÔÀß& @g‘åàd" ÞàÛ(ÿÿÿÿÿÿÿÿ€bÖÀß& @g’å Þ@Ü(ÿÿÿÿÿÿÿÿ@€bØß& @g“Pæ ßpÜ(ÿÿÿÿÿÿÿÿ€ ç€b×ß& @g” çàd" ßÐÜ(ÿÿÿÿÿÿÿÿÀ€bÙß& @g• ç ß`Ý(ÿÿÿÿÿÿÿÿ€bÛ á& @g–ðè àÀÝ(ÿÿÿÿÿÿÿÿ@@ê€bÚ á& @g—@êàd" à Þ(ÿÿÿÿÿÿÿÿ€€bÜ á& @g˜@ê à€Þ(ÿÿÿÿÿÿÿÿÀ€bÞÀß& @g™ë áß(ÿÿÿÿÿÿÿÿàì€b·pw( àõ-×f w ÿÿÿÿÿÿÿÿþ Û#ÝÀß& @gšàìàd" áÀà(ÿÿÿÿÿÿÿÿ@€bàÐ& àõ-Ùh Px ÿÿÿÿÿÿÿÿ@þ@Ü#ßÀß& @g›àì áPá(ÿÿÿÿÿÿÿÿ€€bâÐ& àõ-Ûj 0y ÿÿÿÿÿÿÿÿ€þàÜ#ãß& @gœ0î âàá(ÿÿÿÿÿÿÿÿÀ€ï€bäpw( àõ-àl z ÿÿÿÿÿÿÿÿÀþ€Ý#áß& @g€ïàd" âpâ(ÿÿÿÿÿÿÿÿ€bæÐ& àõ-án ðz ÿÿÿÿÿÿÿÿÿ Þ#åß& @gž€ï âã(ÿÿÿÿÿÿÿÿ@€bèÐ& àõ-âp Ð{ ÿÿÿÿÿÿÿÿ@ÿÀÞ#é á& @gŸÐð ãã(ÿÿÿÿÿÿÿÿ€ ò€bê€&àõ-ër °| ÿÿÿÿÿÿÿÿ€ÿ`ß#ç á& @g  òàd" ã ä(ÿÿÿÿÿÿÿÿÀ€b°"&Ð& àõ-÷x  ÿÿÿÿÿÿÿÿÀ %ë á& @g¡ ò ã°ä(ÿÿÿÿÿÿÿÿ €bîÐ& àõ-üz ð ÿÿÿÿÿÿÿÿÀMà#ïÀß& @g¢pó äå(ÿÿÿÿÿÿÿÿ@ Àô€bíÀß& @g£Àôàd" äpå(ÿÿÿÿÿÿÿÿ€ €b7  b(àõ-  „ ÿÿÿÿÿÿÿÿ@‚ $ñÀß& @g¤Àô äÐå(ÿÿÿÿÿÿÿÿÀ €bó`_( àõ- p… ÿÿÿÿÿÿÿÿ€‚Àè#ôß& @g¥ õ å0æ(ÿÿÿÿÿÿÿÿ!ðö€bõ°^(àõ-ƒ P† ÿÿÿÿÿÿÿÿÀ‚À$òß& @g¦ðöàd" åæ(ÿÿÿÿÿÿÿÿ@!€b÷°¦& àõ-"‡  ‡ ÿÿÿÿÿÿÿÿƒÀü#öß& @g§ðö åðæ(ÿÿÿÿÿÿÿÿ€!€bùЪ& àõ-&‹ `‰ ÿÿÿÿÿÿÿÿ@ƒ $ûpw( àõ-. [ ÿÿÿÿÿÿÿÿN€ $ú á& @g¨@ø æPç(ÿÿÿÿÿÿÿÿÀ!`/€buÐú% @g¸`± ‡ÿÿÿÿÿÿÿÿÀ`±€bø á& @g©`/àd" æ°ç(ÿÿÿÿÿÿÿÿÀ"€bþÐú% @g¹б ‹ÿÿÿÿÿÿÿÿб€bý á& @gª`/ æè(ÿÿÿÿÿÿÿÿ#€b€û% @gº@² ˆÿÿÿÿÿÿÿÿ@@²€bÀß& @g«@0 çpè(ÿÿÿÿÿÿÿÿ@# 1€b€û% @g»°² Œÿÿÿÿÿÿÿÿ€°²€bÿÀß& @g¬ 1àd" çÐè(ÿÿÿÿÿÿÿÿ€#€bД"PM&@gÈp´ ÿÿÿÿÿÿÿÿÀ€BÀß& @g­ 1 ç0é(ÿÿÿÿÿÿÿÿÀ#€bPM&@gÉà´ ÿÿÿÿÿÿÿÿ€Bß& @g®2 èé(ÿÿÿÿÿÿÿÿ$à2€bPM&@gÊPµ ÿÿÿÿÿÿÿÿ@€Bß& @g¯à2àd" èðé(ÿÿÿÿÿÿÿÿ@$€b PM&@gËÀµ ÿÿÿÿÿÿÿÿ€€B ß& @g°à2 èPê(ÿÿÿÿÿÿÿÿ€$€b PM&@gÌ0¶ ÿÿÿÿÿÿÿÿÀ€B  á& @g±À3 é°ê(ÿÿÿÿÿÿÿÿÀ$ 4€bPM&@gÍ ¶ ÿÿÿÿÿÿÿÿ€B  á& @g² 4àd" éë(ÿÿÿÿÿÿÿÿ%€bPM&@g΀· ÿÿÿÿÿÿÿÿ@€B á& @g³ 4 épë(ÿÿÿÿÿÿÿÿ@%€bPM&@gÏð· ÿÿÿÿÿÿÿÿ€€Bp' @g´€5 êÐë(ÿÿÿÿÿÿÿÿ€%Ð6€bP7&@gÐи ÿÿÿÿÿÿÿÿÀ€Bp' @gµÐ6àd" ê0ì(ÿÿÿÿÿÿÿÿÀ%€bP7&@gÑ@¹  ÿÿÿÿÿÿÿÿ€Bp' @g¶Ð6 êì(ÿÿÿÿÿÿÿÿ&€bP7&@gÒ°¹  ÿÿÿÿÿÿÿÿ@€BÀ' @g·°7 ëðì(ÿÿÿÿÿÿÿÿ@&9€bP7&@gÓ º  ÿÿÿÿÿÿÿÿ€€B0“"Àß& @g,p  ª*ÿÿÿÿÿÿÿÿÀ2à€bÀß& @g-ààd" «*ÿÿÿÿÿÿÿÿ3€bÀß& @g.à `«*ÿÿÿÿÿÿÿÿ@3€b!ß& @g/°c À«*ÿÿÿÿÿÿÿÿ@Oe€b ß& @g0eàd" `®*ÿÿÿÿÿÿÿÿ€3€b"ß& @g1e ð®*ÿÿÿÿÿÿÿÿÀ3€b$Àß& @g2àe P¯*ÿÿÿÿÿÿÿÿ­Pf€b#Àß& @g3Pfàd" °¯*ÿÿÿÿÿÿÿÿ4€b%Àß& @g4Pf @°*ÿÿÿÿÿÿÿÿ@4€b'ß& @g5Àf  °*ÿÿÿÿÿÿÿÿ@­0g€b&ß& @g60gàd" ±*ÿÿÿÿÿÿÿÿ€4€b(ß& @g70g `±*ÿÿÿÿÿÿÿÿÀ4€bÀ' @g¸9àd" ëPí(ÿÿÿÿÿÿÿÿ€&€bÀ' @g¹9 ë°í(ÿÿÿÿÿÿÿÿÀ&€b, ' @gºp9 ìî(ÿÿÿÿÿÿÿÿ'P:€b+ ' @g»P:àd" ìpî(ÿÿÿÿÿÿÿÿ@'€b- ' @g¼P: ìÐî(ÿÿÿÿÿÿÿÿ€'€b/ æ& @g½0; íï(ÿÿÿÿÿÿÿÿÀ'ð<€b. æ& @g¾ð<àd" íPð(ÿÿÿÿÿÿÿÿ(€b0 æ& @g¿ð< í ö(ÿÿÿÿÿÿÿÿ@(€b2ðå& @gÀÐ= î ÷(ÿÿÿÿÿÿÿÿ€(°>€b1ðå& @gÁ°>àd" îPù(ÿÿÿÿÿÿÿÿÀ(€b3ðå& @g°> îÐú(ÿÿÿÿÿÿÿÿ)€b5Pç& @gÃ? ïPü(ÿÿÿÿÿÿÿÿ@)p@€b4Pç& @gÄp@àd" ïÐý(ÿÿÿÿÿÿÿÿ€)€b6Pç& @gÅp@ ïðþ(ÿÿÿÿÿÿÿÿÀ)€b8àã& @gưi! ð)ÿÿÿÿÿÿÿÿ*0B€b7àã& @gÇ0Bàd" ð°)ÿÿÿÿÿÿÿÿ@*€b9àã& @gÈ0B ð`)ÿÿÿÿÿÿÿÿ€*€b;€â& @gÉC ñà)ÿÿÿÿÿÿÿÿÀ*ðC€b:€â& @gÊðCàd" ñ`)ÿÿÿÿÿÿÿÿ+€b<€â& @gËðC ñ )ÿÿÿÿÿÿÿÿ@+€b>àã& @gÌÐD ò )ÿÿÿÿÿÿÿÿ€+°E€b=àã& @gͰEàd" ò )ÿÿÿÿÿÿÿÿÀ+€b?àã& @gΰE ò` )ÿÿÿÿÿÿÿÿ,€bA€â& @gÏF ó°)ÿÿÿÿÿÿÿÿ@,àG€b@€â& @gÐàGàd" ó)ÿÿÿÿÿÿÿÿ€,€bB€â& @gÑàG óP)ÿÿÿÿÿÿÿÿÀ,€bDä& @gÒÀH ôÐ)ÿÿÿÿÿÿÿÿ- I€bCä& @gÓ Iàd" ôP)ÿÿÿÿÿÿÿÿ@-€bEä& @gÔ I ôð)ÿÿÿÿÿÿÿÿ€-€bGä& @gÕ€J õà)ÿÿÿÿÿÿÿÿÀ-`K€bFä& @gÖ`Kàd" õ )ÿÿÿÿÿÿÿÿ.€bHä& @g×`K õ)ÿÿÿÿÿÿÿÿî€bJ æ& @gØÐK öP)ÿÿÿÿÿÿÿÿ@. M€bI æ& @gÙ Màd" ö)ÿÿÿÿÿÿÿÿ€.€bK æ& @gÚ M ö)ÿÿÿÿÿÿÿÿÀ.€bMðå& @gÛM ÷À)ÿÿÿÿÿÿÿÿ/pN€bLðå& @gÜpNàd" ÷€)ÿÿÿÿÿÿÿÿ@/€bNðå& @gÝpN ÷p)ÿÿÿÿÿÿÿÿ€/€bPPç& @gÞPO ø0)ÿÿÿÿÿÿÿÿÀ/Œ€bOPç& @gߌàd" øð)ÿÿÿÿÿÿÿÿ0€bQPç& @gàŒ ø° )ÿÿÿÿÿÿÿÿ@0€bSàã& @gáp ùp!)ÿÿÿÿÿÿÿÿ€0PŽ€bRàã& @gâPŽàd" ù0")ÿÿÿÿÿÿÿÿÀ0€bTàã& @gãPŽ ùð")ÿÿÿÿÿÿÿÿ1€bV€â& @gä  ú°#)ÿÿÿÿÿÿÿÿÀ¬ð€bU€â& @gåðàd" ú $)ÿÿÿÿÿÿÿÿ@1€bW€â& @gæð ú`%)ÿÿÿÿÿÿÿÿ€1€bYàã& @gç@’ ûP&)ÿÿÿÿÿÿÿÿÀ1“€bXàã& @gè“àd" û')ÿÿÿÿÿÿÿÿ2€bZàã& @gé“ û°G)ÿÿÿÿÿÿÿÿ€>€b\€â& @gêà” ü H)ÿÿÿÿÿÿÿÿÀ>0–€b[€â& @gë0–àd" ü`I)ÿÿÿÿÿÿÿÿ?€b]€â& @gì0– ü ä,ÿÿÿÿÿÿÿÿ@?€b_ä& @gí— ýàJ)ÿÿÿÿÿÿÿÿ€?`˜€b^ä& @gî`˜àd" ýÐK)ÿÿÿÿÿÿÿÿÀ?€b`ä& @gï`˜ ýL)ÿÿÿÿÿÿÿÿ@€bbä& @gð š þ€M)ÿÿÿÿÿÿÿÿ@@p›€baä& @gñp›àd" þ@N)ÿÿÿÿÿÿÿÿ€@€bcä& @gòp› þ0O)ÿÿÿÿÿÿÿÿÀ@€beàã& @góÀœ ÿ0å,ÿÿÿÿÿÿÿÿAž€bdàã& @gôžàd" ÿ€P)ÿÿÿÿÿÿÿÿ@A€bfàã& @gõž ÿQ)ÿÿÿÿÿÿÿÿ€A€bh€â& @gö`Ÿ R)ÿÿÿÿÿÿÿÿÀA° €bg€â& @g÷° àd" ÀR)ÿÿÿÿÿÿÿÿB€bi€â& @gø°  °S)ÿÿÿÿÿÿÿÿ@B€bP7&@gÔº  ÿÿÿÿÿÿÿÿÀ€Bkàã& @gù¢ pT)ÿÿÿÿÿÿÿÿ€åP£€blP7&@gÕ» ÿÿÿÿÿÿÿÿ €Bjàã& @gúP£àd" U)ÿÿÿÿÿÿÿÿ€B€bnP7&@gÖà»  ÿÿÿÿÿÿÿÿ@ €Bmàã& @gûP£ €V)ÿÿÿÿÿÿÿÿÀB€bpP7&@g×P¼ ÿÿÿÿÿÿÿÿ€ €Bq€â& @gü ¤ @W)ÿÿÿÿÿÿÿÿC€¥€brP7&@gØÀ¼ ÿÿÿÿÿÿÿÿ €Bo€â& @gý€¥àd" X)ÿÿÿÿÿÿÿÿ@C€btP7&@gÙ0½ ÿÿÿÿÿÿÿÿ@ €Bs€â& @gþ€¥ ðX)ÿÿÿÿÿÿÿÿ€C€bvP7&@gÚ ½ ÿÿÿÿÿÿÿÿ€ €Bwä& @gÿЦ À[)ÿÿÿÿÿÿÿÿÀC ¨€bxP7&@gÛ¾ ÿÿÿÿÿÿÿÿÀ €Buä& @g ¨àd" €\)ÿÿÿÿÿÿÿÿD€bzP7&@gÜÐ0! ÿÿÿÿÿÿÿÿ €Byä& @g ¨ @])ÿÿÿÿÿÿÿÿ@D€b|P7&@gÝÐH" ÿÿÿÿÿÿÿÿ@ €B}ä& @gp© Ð])ÿÿÿÿÿÿÿÿ€DÀª€b~P7&@gÞP ÿÿÿÿÿÿÿÿ€ €B{ä& @gÀªàd" ^)ÿÿÿÿÿÿÿÿÀD€b€P7&@gß°I" ÿÿÿÿÿÿÿÿÀ €Bä& @gÀª P_)ÿÿÿÿÿÿÿÿE€b‚P7&@gà  ÿÿÿÿÿÿÿÿ €Bƒàã& @g¬ €_)ÿÿÿÿÿÿÿÿ€E`­€b„P7&@gá ÿÿÿÿÿÿÿÿ@ €Bàã& @g`­àd" @`)ÿÿÿÿÿÿÿÿÀE€b†P7&@gâK" ÿÿÿÿÿÿÿÿ€ €B…àã& @g`­ Ð`)ÿÿÿÿÿÿÿÿF€bˆP7&@gãàK" ÿÿÿÿÿÿÿÿÀ €B‰€â& @g°®  -ÿÿÿÿÿÿÿÿ@F°€bŠP7&@gäð ÿÿÿÿÿÿÿÿ €B‡€â& @g °àd" Àa)ÿÿÿÿÿÿÿÿ€F€bŒP7&@gå M" ÿÿÿÿÿÿÿÿ@ €B‹€â& @g ° Pb)ÿÿÿÿÿÿÿÿÀF€bŽPM&@gæ` 7ÿÿÿÿÿÿÿÿ€ €Bàã& @g P± c)ÿÿÿÿÿÿÿÿG ²€bPM&@gçN" 5ÿÿÿÿÿÿÿÿÀ €Bàã& @g  ²àd" Ðc)ÿÿÿÿÿÿÿÿ@G€b’PM&@gè@ 8ÿÿÿÿÿÿÿÿ€B‘àã& @g  ² d)ÿÿÿÿÿÿÿÿ€G€b”PM&@gé  6ÿÿÿÿÿÿÿÿ@€B•€â& @g€³ €e)ÿÿÿÿÿÿÿÿ@ïд€b–PM&@gê ‘ÿÿÿÿÿÿÿÿ€€B“€â& @gдàd" @f)ÿÿÿÿÿÿÿÿÀG€b˜PM&@gë Q" ’ÿÿÿÿÿÿÿÿÀ€B—€â& @gд g)ÿÿÿÿÿÿÿÿH€bšPM&@gì “ÿÿÿÿÿÿÿÿ€B›ä& @g ¶  Àg)ÿÿÿÿÿÿÿÿ@Hp·€bœPM&@gíp ”ÿÿÿÿÿÿÿÿ@€B™ä& @gp·àd"  €h)ÿÿÿÿÿÿÿÿ€H€bžPM&@gîà ;ÿÿÿÿÿÿÿÿ€€Bä& @gp·  i)ÿÿÿÿÿÿÿÿÀH€b PM&@gïP <ÿÿÿÿÿÿÿÿÀ€B¡ä& @gP¸   k)ÿÿÿÿÿÿÿÿI°,€b¢PM&@gðàR" =ÿÿÿÿÿÿÿÿ€BŸä& @g°,àd"  0¤(ÿÿÿÿÿÿÿÿ@I€b¤PM&@gñ0 ÿÿÿÿÿÿÿÿ@€B£ä& @g°,  @l)ÿÿÿÿÿÿÿÿ€I€b¦PM&@gò ÿÿÿÿÿÿÿÿÀ€B§àã& @g|  m)ÿÿÿÿÿÿÿÿÀI-€b¨N&@gó€ Lÿÿÿÿÿÿÿÿ€Bª°N&@gô` Mÿÿÿÿÿÿÿÿ@€B«`O&@gõ@ Nÿÿÿÿÿÿÿÿ€O€B¬P&@gö° OÿÿÿÿÿÿÿÿÀO€B­N&@g÷ TÿÿÿÿÿÿÿÿP€B®°N&@gøp  Uÿÿÿÿÿÿÿÿ@P€B¯`O&@gùà  Vÿÿÿÿÿÿÿÿ€P€B°P&@gúP! WÿÿÿÿÿÿÿÿÀP€B±N&@gû0" PÿÿÿÿÿÿÿÿQ€B²°N&@gü " Qÿÿÿÿÿÿÿÿ@Q€B³N&@gý€# Xÿÿÿÿÿÿÿÿ€Q€B´°N&@gþp` YÿÿÿÿÿÿÿÿÀQ€BµN&@gÿð# RÿÿÿÿÿÿÿÿR€B¶°N&@g^ Sÿÿÿÿÿÿÿÿ@R€B·N&@g_ Zÿÿÿÿÿÿÿÿ€R€B¸°N&@gà_ [ÿÿÿÿÿÿÿÿÀR€B¹°N&@gÀ` oÿÿÿÿÿÿÿÿS€B¥àã& @g-àd"  o)ÿÿÿÿÿÿÿÿJ€b©àã& @g-  `p)ÿÿÿÿÿÿÿÿ@J€b¼€â& @gp|  °q)ÿÿÿÿÿÿÿÿ€J.€b»€â& @g.àd"  0s)ÿÿÿÿÿÿÿÿÀJ€b½€â& @g.  p¦(ÿÿÿÿÿÿÿÿ€ï€b¿ä& @gÀ}   u)ÿÿÿÿÿÿÿÿKà.€b¾ä& @gà.àd"   w)ÿÿÿÿÿÿÿÿ@K€bÀä& @gà.  Ц(ÿÿÿÿÿÿÿÿ€K€b æ& @g P/ 0y)ÿÿÿÿÿÿÿÿÀK€bÁ æ& @g!àd" Pz)ÿÿÿÿÿÿÿÿL€bàæ& @g" p{)ÿÿÿÿÿÿÿÿ@L€bÅðå& @g#€ À§(ÿÿÿÿÿÿÿÿ€Ï00€bÄðå& @g$00àd" €})ÿÿÿÿÿÿÿÿ€L€bÆðå& @g%00  ~)ÿÿÿÿÿÿÿÿÀL€bÈPç& @g&Ѐ €¨(ÿÿÿÿÿÿÿÿM1€bÇPç& @g'1àd" €€)ÿÿÿÿÿÿÿÿ@M€bÉPç& @g(1 p)ÿÿÿÿÿÿÿÿ€M€bËàã& @g)@ À‚)ÿÿÿÿÿÿÿÿ€_`2€bÊàã& @g*`2àd" @„)ÿÿÿÿÿÿÿÿÀ_€bÌàã& @g+`2 °†)ÿÿÿÿÿÿÿÿ`€b΀â& @g,@3 p‡)ÿÿÿÿÿÿÿÿ@`°3€bÍ€â& @g-°3àd" 0ˆ)ÿÿÿÿÿÿÿÿ€`€bÏ€â& @g.°3 ðˆ)ÿÿÿÿÿÿÿÿa€bÑä& @g/‚ °‰)ÿÿÿÿÿÿÿÿ@a4€bÐä& @g04àd" pŠ)ÿÿÿÿÿÿÿÿ€a€bÒä& @g14 0‹)ÿÿÿÿÿÿÿÿÀa€bÔàã& @g25 ð‹)ÿÿÿÿÿÿÿÿ"à5€bÓàã& @g3à5àd" °Œ)ÿÿÿÿÿÿÿÿb€bÕàã& @g4à5 p)ÿÿÿÿÿÿÿÿ@b€b×€â& @g5P6 0Ž)ÿÿÿÿÿÿÿÿ€bÀ6€bÖ€â& @g6À6àd" ðŽ)ÿÿÿÿÿÿÿÿÀb€bØ€â& @g7À6 °)ÿÿÿÿÿÿÿÿc€bº°N&@g a nÿÿÿÿÿÿÿÿ@S€BÛ°N&@g€b mÿÿÿÿÿÿÿÿ€S€BÜ`O&@g`c \ÿÿÿÿÿÿÿÿÀS€BÝ`O&@g°d ]ÿÿÿÿÿÿÿÿT€BÞ`O&@gpf ^ÿÿÿÿÿÿÿÿ@T€Bß`O&@g Pg _ÿÿÿÿÿÿÿÿ€T€BàN&@g  h `ÿÿÿÿÿÿÿÿÀT€Bá°N&@g €i aÿÿÿÿÿÿÿÿU€BâN&@g `j bÿÿÿÿÿÿÿÿ@U€Bã°N&@g @k cÿÿÿÿÿÿÿÿ€U€Bä`O&@g l dÿÿÿÿÿÿÿÿÀU€BåN&@gpm eÿÿÿÿÿÿÿÿV€Bæ°N&@gÀn fÿÿÿÿÿÿÿÿ@V€Bç`O&@g o gÿÿÿÿÿÿÿÿ€V€BèN&@g€p jÿÿÿÿÿÿÿÿÀV€Bé°N&@g`q iÿÿÿÿÿÿÿÿW€BêN&@g@r lÿÿÿÿÿÿÿÿ@W€Bë°N&@g s kÿÿÿÿÿÿÿÿ€W€BìN&@gt ‚ÿÿÿÿÿÿÿÿÀW€Bí°N&@gPu ƒÿÿÿÿÿÿÿÿX€Bî`O&@gw „ÿÿÿÿÿÿÿÿ@X€BïN&@g€w …ÿÿÿÿÿÿÿÿ€X€Bð°N&@g`x †ÿÿÿÿÿÿÿÿÀX€Bñ`O&@g@y ‡ÿÿÿÿÿÿÿÿY€Bò°d&@g z ³ÿÿÿÿÿÿÿÿ@Y€Bó°d&@g{ ¹ÿÿÿÿÿÿÿÿ€Y€Bô°d&@gà{ ·ÿÿÿÿÿÿÿÿÀY€Bõ°d&@g0} µÿÿÿÿÿÿÿÿZ€Bö°d&@g ~ ´ÿÿÿÿÿÿÿÿ@Z€B÷°d&@g!ð~ ºÿÿÿÿÿÿÿÿ€Z€Bø°d&@g"Ð ¸ÿÿÿÿÿÿÿÿÀZ€Bù°d&@g#°€ ¶ÿÿÿÿÿÿÿÿ[€BÚä& @g807 p)ÿÿÿÿÿÿÿÿ@c 7€bÙä& @g9 7àd" 0‘)ÿÿÿÿÿÿÿÿ€c€bûä& @g: 7 ð‘)ÿÿÿÿÿÿÿÿÀc€býàã& @g;€8 °’)ÿÿÿÿÿÿÿÿdÐ9€büàã& @g<Ð9àd" @“)ÿÿÿÿÿÿÿÿ@d€bþàã& @g=Ð9 ”)ÿÿÿÿÿÿÿÿ€d€b€â& @g>à‘ ”)ÿÿÿÿÿÿÿÿÀd ;€bÿ€â& @g? ;àd"  •)ÿÿÿÿÿÿÿÿe€b€â& @g@ ; °•)ÿÿÿÿÿÿÿÿ@"€bä& @gA< @–)ÿÿÿÿÿÿÿÿ@eP=€bä& @gBP=àd" Ж)ÿÿÿÿÿÿÿÿ€e€bä& @gCP= °˜)ÿÿÿÿÿÿÿÿÀe€b ' @gD0> p™)ÿÿÿÿÿÿÿÿf€?€b ' @gE€?àd" 0š)ÿÿÿÿÿÿÿÿ@f€b ' @gF€? ðš)ÿÿÿÿÿÿÿÿ€f€b ð' @gGð› °›)ÿÿÿÿÿÿÿÿÀf°€bú h&@g$š »ÿÿÿÿÿÿÿÿ@[€B  h&@g%€š ¼ÿÿÿÿÿÿÿÿ€[€B  h&@g&ðš ½ÿÿÿÿÿÿÿÿÀ[€B  h&@g'`› ¾ÿÿÿÿÿÿÿÿ\€B h&@g(Л ¿ÿÿÿÿÿÿÿÿ@\€B h&@g)@œ Æÿÿÿÿÿÿÿÿ€\€B h&@g*°œ ÀÿÿÿÿÿÿÿÿÀ\€B h&@g+  Áÿÿÿÿÿÿÿÿ]€B h&@g, Âÿÿÿÿÿÿÿÿ@]€B h&@g-ž Ãÿÿÿÿÿÿÿÿ€]€B h&@g.pž ÄÿÿÿÿÿÿÿÿÀ]€B h&@g/àž Åÿÿÿÿÿÿÿÿ^€B h&@g0PŸ Èÿÿÿÿÿÿÿÿ@^€B h&@g10  Éÿÿÿÿÿÿÿÿ€^€B h&@g2   ÊÿÿÿÿÿÿÿÿÀ^€B h&@g3¡ Ïÿÿÿÿÿÿÿÿ_€Bð' @gH°àd" pœ)ÿÿÿÿÿÿÿÿg€b h&@g4€¡ Ëÿÿÿÿÿÿÿÿ@_€B ð' @gI° 0)ÿÿÿÿÿÿÿÿ@g€b h&@g5ð¡ Ìÿÿÿÿÿÿÿÿ@p€BP' @gJ@A )ÿÿÿÿÿÿÿÿ€gàÁ€b h&@g6`¢ Íÿÿÿÿÿÿÿÿ€p€BP' @gKàÁàd" Pž)ÿÿÿÿÿÿÿÿÀg€b  h&@g7Т ÎÿÿÿÿÿÿÿÿÀp€BP' @gLàÁ Ÿ)ÿÿÿÿÿÿÿÿh€b"°d&@g8@£ ßÿÿÿÿÿÿÿÿq€B#àã& @gMÀ pŸ)ÿÿÿÿÿÿÿÿ@h0Àb$°d&@g9 ¤ Ýÿÿÿÿÿÿÿÿ@q€B!àã& @gN0Ãàd" 0 )ÿÿÿÿÿÿÿÿ€h€b&°d&@g:¤ àÿÿÿÿÿÿÿÿ€q€B%àã& @gO0à À )ÿÿÿÿÿÿÿÿÀh€b(°d&@g;¥ ÞÿÿÿÿÿÿÿÿÀq€B)€â& @gPÄ €¡)ÿÿÿÿÿÿÿÿiðÄ€b*°d&@g<p¥ áÿÿÿÿÿÿÿÿr€B'€â& @gQðÄàd" @¢)ÿÿÿÿÿÿÿÿ@i€b,°d&@g=P¦ âÿÿÿÿÿÿÿÿ@r€B+€â& @gRðÄ £)ÿÿÿÿÿÿÿÿ€i€b.°d&@g>À¦ ãÿÿÿÿÿÿÿÿ€r€B/ä& @gSÐÅ ò(ÿÿÿÿÿÿÿÿÀi°Æ€b0°d&@g? § äÿÿÿÿÿÿÿÿÀr€B-ä& @gT°Æàd" P¤)ÿÿÿÿÿÿÿÿj€b2°d&@g@¨ ìÿÿÿÿÿÿÿÿs€B1ä& @gU°Æ @¥)ÿÿÿÿÿÿÿÿ@j€b4°d&@gA€¨ çÿÿÿÿÿÿÿÿ@s€B5 æ& @gVÇ  `ò(ÿÿÿÿÿÿÿÿ€jpÈ€b6°d&@gBð¨ èÿÿÿÿÿÿÿÿ€s€B3 æ& @gWpÈàd"  ¦)ÿÿÿÿÿÿÿÿÀj€b8`e&@gCЩ  ÿÿÿÿÿÿÿÿÀs€B7 æ& @gXpÈ  ¦)ÿÿÿÿÿÿÿÿk€b:f&@gD°ª  ÿÿÿÿÿÿÿÿt€B;ðå& @gYPÉ !p´)ÿÿÿÿÿÿÿÿ@k0Ê€b<Àf&@gE«  ÿÿÿÿÿÿÿÿ@t€B9ðå& @gZ0Êàd" !µ)ÿÿÿÿÿÿÿÿ€k€b>pg&@gF0- ÿÿÿÿÿÿÿÿ€t€B=ðå& @g[0Ê !µ)ÿÿÿÿÿÿÿÿÀk€b@`e&@gG¬ ÿÿÿÿÿÿÿÿÀt€BAPç& @g\€Ë " ¶)ÿÿÿÿÿÿÿÿl`Ì€bBf&@gHàò ÿÿÿÿÿÿÿÿu€B?Pç& @g]`Ìàd" "°¶)ÿÿÿÿÿÿÿÿ@l€bDÀf&@gIPó ÿÿÿÿÿÿÿÿ@u€BCPç& @g^`Ì "p·)ÿÿÿÿÿÿÿÿ€l€bFpg&@gJ0ô ÿÿÿÿÿÿÿÿ€u€BGàã& @g_@Í #`¸)ÿÿÿÿÿÿÿÿÀl ΀bH`e&@gKõ ÿÿÿÿÿÿÿÿÀu€BEàã& @g` Îàd" #P¹)ÿÿÿÿÿÿÿÿm€bJf&@gLðõ ÿÿÿÿÿÿÿÿv€BIàã& @ga Î #@º)ÿÿÿÿÿÿÿÿ@m€bL`e&@gM`ö ÿÿÿÿÿÿÿÿ@v€BM€â& @gbÏ $»)ÿÿÿÿÿÿÿÿ€màÏ€bNf&@gN°÷ ÿÿÿÿÿÿÿÿ€v€BK€â& @gcàÏàd" $½)ÿÿÿÿÿÿÿÿÀm€bP`e&@gOø ÿÿÿÿÿÿÿÿÀv€BO€â& @gdàÏ $à8)ÿÿÿÿÿÿÿÿn€bRf&@gPàù ÿÿÿÿÿÿÿÿw€BSàã& @geÀÐ %°¿)ÿÿÿÿÿÿÿÿ@n Ñ€bT`e&@gQÀú ÿÿÿÿÿÿÿÿ@w€BQàã& @gf Ñàd" %Á)ÿÿÿÿÿÿÿÿ€n€bVf&@gR û ÿÿÿÿÿÿÿÿ€w€BUàã& @gg Ñ %ðÁ)ÿÿÿÿÿÿÿÿÀn€bXf&@gS€ü 0ÿÿÿÿÿÿÿÿÀw€BY€â& @gh€Ò &Ã)ÿÿÿÿÿÿÿÿo`Ó€bW€â& @gi`Óàd" &0Ä)ÿÿÿÿÿÿÿÿŽ€b[€â& @gj`Ó &€Å)ÿÿÿÿÿÿÿÿ€Ž€b]ä& @gk@Ô 'ÐÆ)ÿÿÿÿÿÿÿÿÀŽ Õ€b\ä& @gl Õàd" ' È)ÿÿÿÿÿÿÿÿ@€b^ä& @gm Õ 'pÉ)ÿÿÿÿÿÿÿÿÀ€b`ä& @gnÖ (ðÊ)ÿÿÿÿÿÿÿÿ@àÖ€b_ä& @goàÖàd" (@Ì)ÿÿÿÿÿÿÿÿÀ€baä& @gpàÖ (àÚ)ÿÿÿÿÿÿÿÿ@‘€bcàã& @gqÀ× ) Û)ÿÿÿÿÿÿÿÿÀ‘ Ø€bbàã& @gr Øàd" )Ü)ÿÿÿÿÿÿÿÿ@’€bdàã& @gs Ø )PÝ)ÿÿÿÿÿÿÿÿ€’€bf€â& @gt€Ù *j)ÿÿÿÿÿÿÿÿÀ’`Ú€be€â& @gu`Úàd" *ß)ÿÿÿÿÿÿÿÿ“€bg€â& @gv`Ú *ðß)ÿÿÿÿÿÿÿÿ@“€biä& @gw@Û +àà)ÿÿÿÿÿÿÿÿ€“ Ü€bZf&@gT`ý /ÿÿÿÿÿÿÿÿx€Bkpg&@gU@þ ÿÿÿÿÿÿÿÿ@x€Blpg&@gV°þ ÿÿÿÿÿÿÿÿ€x€Bmpg&@gWàÓ ÿÿÿÿÿÿÿÿÀx€Bnpg&@gX ÿÿÿÿÿÿÿÿy€Bo`e&@gYà ÿÿÿÿÿÿÿÿ@y€Bpf&@gZ Ù  ÿÿÿÿÿÿÿÿ€y€Bq`e&@g[0 !ÿÿÿÿÿÿÿÿÀy€Brf&@g\  "ÿÿÿÿÿÿÿÿz€BsÀf&@g]€ #ÿÿÿÿÿÿÿÿ@z€Bt`e&@g^` $ÿÿÿÿÿÿÿÿ€z€Buf&@g_@ %ÿÿÿÿÿÿÿÿÀz€BvÀf&@g`0ã &ÿÿÿÿÿÿÿÿ{€Bw`e&@ga )ÿÿÿÿÿÿÿÿ@{€Bxf&@gb (ÿÿÿÿÿÿÿÿ€{€By`e&@gcà +ÿÿÿÿÿÿÿÿÀ{€Bzf&@gdÀ *ÿÿÿÿÿÿÿÿ|€B{`e&@ge0  Gÿÿÿÿÿÿÿÿ@|€B|f&@gf°í Hÿÿÿÿÿÿÿÿ€|€B}Àf&@gg€  IÿÿÿÿÿÿÿÿÀ|€B~pg&@ghð  Jÿÿÿÿÿÿÿÿ}€B`e&@giðò Kÿÿÿÿÿÿÿÿ@}€B€f&@gj@  Lÿÿÿÿÿÿÿÿ€}€BÀf&@gk  MÿÿÿÿÿÿÿÿÀ}€B‚pg&@glP+ Nÿÿÿÿÿÿÿÿ~€Bƒf&@gmJ ÿÿÿÿÿÿÿÿ@~€B„Àf&@gn0,  ÿÿÿÿÿÿÿÿ€~€B…f&@go-  ÿÿÿÿÿÿÿÿÀ~€B†f&@gpð- .ÿÿÿÿÿÿÿÿ€B‡Ç&@gqÐ. •ÿÿÿÿÿÿÿÿ@€Bˆ?&@gr°/ rÿÿÿÿÿÿÿÿ€€B‰@@&@gs0 sÿÿÿÿÿÿÿÿÀ€Bhä& @gx Üàd" +â)ÿÿÿÿÿÿÿÿÀ“€bjä& @gy Ü +ðâ)ÿÿÿÿÿÿÿÿ”€bŒàã& @gzÝ ,àã)ÿÿÿÿÿÿÿÿ@”àÝ€b‹àã& @g{àÝàd" ,Ðä)ÿÿÿÿÿÿÿÿ€”€bàã& @g|àÝ ,ðå)ÿÿÿÿÿÿÿÿÀ”€b€â& @g}ÀÞ -Àò(ÿÿÿÿÿÿÿÿ• ß€bŽ€â& @g~ ßàd" -Ðç)ÿÿÿÿÿÿÿÿ@•€b€â& @g ß -Àè)ÿÿÿÿÿÿÿÿ€•€b’àã& @g€€à .àé)ÿÿÿÿÿÿÿÿÀ•àF€b‘àã& @gàFàd" .Ðê)ÿÿÿÿÿÿÿÿ–€b“àã& @g‚àF .0|)ÿÿÿÿÿÿÿÿ@–€b•€â& @gƒÀG /€ì)ÿÿÿÿÿÿÿÿ€–0H€b”€â& @g„0Hàd" /pí)ÿÿÿÿÿÿÿÿÀ–€b–€â& @g…0H /0÷)ÿÿÿÿÿÿÿÿ—€b˜ä& @g† H 0À÷)ÿÿÿÿÿÿÿÿ@—I€b—ä& @g‡Iàd" 0°ø)ÿÿÿÿÿÿÿÿ€—€bŠP&@gtp1 tÿÿÿÿÿÿÿÿ€€B›?&@guàQ wÿÿÿÿÿÿÿÿ €Bœ@@&@gvP2 xÿÿÿÿÿÿÿÿ@ €BP&@gw03 yÿÿÿÿÿÿÿÿ€ €Bž?&@gx@V uÿÿÿÿÿÿÿÿÀ €BŸ@@&@gy4 vÿÿÿÿÿÿÿÿ¡€B à>&@gzð4 qÿÿÿÿÿÿÿÿ@¡€B¡0>&@g{Ð5 hÿÿÿÿÿÿÿÿ€¡€B¢ 6&@g|°6  ÿÿÿÿÿÿÿÿÀ¡€B£ 6&@g}8 !ÿÿÿÿÿÿÿÿ¢€B¤ 6&@g~p8 "ÿÿÿÿÿÿÿÿ@¢€B¥ 6&@gP9 #ÿÿÿÿÿÿÿÿ€¢€B¦ 6&@g€0: $ÿÿÿÿÿÿÿÿÀ¢€B§ 6&@g; %ÿÿÿÿÿÿÿÿ£€B¨ 6&@g‚ð; &ÿÿÿÿÿÿÿÿ@£€B© 6&@gƒe 'ÿÿÿÿÿÿÿÿ€£€BüÐ& àõ-2 Œ ÿÿÿÿÿÿÿÿ€ƒ $«pw( àõ-5‘ P ÿÿÿÿÿÿÿÿÀƒÀ $0Ø&Ù&PÜhÚ ðØ ÿÿÿÿÿÿÿÿ€…  $­°›&PÜiÝ â  ÿÿÿÿÿÿÿÿÀ…@$®ð¹&PÜjß @ä  ÿÿÿÿÿÿÿÿ†€$¯0î&PÜkâ æ  ÿÿÿÿÿÿÿÿ@†À$°@û&PÜlä `Ù ÿÿÿÿÿÿÿÿ€†À$±Ù&PÜmæ àæ  ÿÿÿÿÿÿÿÿ@N`$²Ù&PÜnè Àç  ÿÿÿÿÿÿÿÿÀ†@$³Ù&PÜoê  è  ÿÿÿÿÿÿÿÿ‡$´ï&PÜpî  _! ÿÿÿÿÿÿÿÿ@‡€$µ@ð&PÜqñ é  ÿÿÿÿÿÿÿÿ€‡`$¶@ð&PÜrô `ê  ÿÿÿÿÿÿÿÿÀ‡ $·ðð&PÜsø Ðê  ÿÿÿÿÿÿÿÿˆà$™ä& @gˆI 0@ù)ÿÿÿÿÿÿÿÿÀ—€b¸`È&PÜtù °Ú ÿÿÿÿÿÿÿÿ€Nª 6&@g„Ð< (ÿÿÿÿÿÿÿÿÀ£€B¹ä& @g‰€I 10ú)ÿÿÿÿÿÿÿÿ˜ðI€bº`È&PÜuú Û ÿÿÿÿÿÿÿÿ@ˆ» 6&@g…@= )ÿÿÿÿÿÿÿÿ¤€Bšä& @gŠðIàd" 1ðú)ÿÿÿÿÿÿÿÿ@˜€b¾ 6&@g† > *ÿÿÿÿÿÿÿÿ@¤€B¼ä& @g‹ðI 1ð—)ÿÿÿÿÿÿÿÿ€˜€bÀ 6&@g‡? +ÿÿÿÿÿÿÿÿ€¤€BÁ .' @gŒ`J 2ü)ÿÿÿÿÿÿÿÿÀ˜ÐJ€€bÂàT&@gˆà? ÑÿÿÿÿÿÿÿÿÀ¤€B¿ .' @gÐJàd" 2Ðü)ÿÿÿÿÿÿÿÿ™€€bÄàT&@g‰À@ Òÿÿÿÿÿÿÿÿ¥€Bà .' @gŽÐJ 2`ý)ÿÿÿÿÿÿÿÿ@™€€bÆàT&@gŠ A Óÿÿÿÿÿÿÿÿ@o€BÇ00' @g`† 3Àý)ÿÿÿÿÿÿÿÿ€™@K€bÈàT&@g‹0v Ôÿÿÿÿÿÿÿÿ@¥€BÅ00' @g@Kàd" 3 þ)ÿÿÿÿÿÿÿÿÀ™€bÊàT&@gŒðB Õÿÿÿÿÿÿÿÿ€¥€BÉ00' @g‘@K 3°þ)ÿÿÿÿÿÿÿÿš€bÌàT&@gÐC ÖÿÿÿÿÿÿÿÿÀ¥€BÍÀ ' @g’°K 4ÿ)ÿÿÿÿÿÿÿÿ@š L€bÎàT&@gŽ E ×ÿÿÿÿÿÿÿÿ¦€BËÀ ' @g“ Làd" 4pÿ)ÿÿÿÿÿÿÿÿ€š€bÐàT&@gF Øÿÿÿÿÿÿÿÿ€o€BÏÀ ' @g” L 4€˜)ÿÿÿÿÿÿÿÿÀš€bÒàT&@g`á Ùÿÿÿÿÿÿÿÿ@¦€BÓð^' @g•L 5`*ÿÿÿÿÿÿÿÿ›M€€bÔàT&@g‘v Úÿÿÿÿÿÿÿÿ€¦€BÑð^' @g–Màd" 5ð*ÿÿÿÿÿÿÿÿ@›€€bÖàT&@g’ ã ÛÿÿÿÿÿÿÿÿÀ¦€BÕð^' @g—M 5€*ÿÿÿÿÿÿÿÿ€›€€bØàT&@g“Àx Üÿÿÿÿÿÿÿÿ§€BÙ _' @g˜pM 6*ÿÿÿÿÿÿÿÿÀ›àM€€b× _' @g™àMàd" 6 *ÿÿÿÿÿÿÿÿœ€€bÛ _' @gšàM 60*ÿÿÿÿÿÿÿÿ@œ€€bÝP`' @g›PN 7À*ÿÿÿÿÿÿÿÿ€œÀN€bÜP`' @gœÀNàd" 7 *ÿÿÿÿÿÿÿÿÀœ€bÞP`' @gÀN 7€*ÿÿÿÿÿÿÿÿ€bàP`' @gž0O 8à*ÿÿÿÿÿÿÿÿ@ O€bßP`' @gŸ Oàd" 8p*ÿÿÿÿÿÿÿÿ€€báP`' @g  O 8Ð*ÿÿÿÿÿÿÿÿÀ€bãP`' @g¡P 9*ÿÿÿÿÿÿÿÿž€P€bâP`' @g¢€Pàd" 9`*ÿÿÿÿÿÿÿÿ@ž€bäP`' @g£€P 9À*ÿÿÿÿÿÿÿÿ€ž€bæ°a' @g¤ðP :P*ÿÿÿÿÿÿÿÿÀž`Q€bå°a' @g¥`Qàd" :°*ÿÿÿÿÿÿÿÿŸ€bç°a' @g¦`Q :*ÿÿÿÿÿÿÿÿ@Ÿ€béð^' @g§ÐQ ; *ÿÿÿÿÿÿÿÿ€Ÿ@R€€bÚ <&@g” y Iÿÿÿÿÿÿÿÿ@§€BëÐ<&@g•€z Jÿÿÿÿÿÿÿÿ€§€Bì <&@g–`{ KÿÿÿÿÿÿÿÿÀ§€Bíð@&@g—@| –ÿÿÿÿÿÿÿÿ¨€BîÉ&@g˜ } —ÿÿÿÿÿÿÿÿ@¨€Bïp;&@g™°é ,ÿÿÿÿÿÿÿÿ€¨€BðC&@gšp~ -ÿÿÿÿÿÿÿÿÀ¨€Bñ:&@g›À .ÿÿÿÿÿÿÿÿ©€BòÀ:&@gœ € /ÿÿÿÿÿÿÿÿ@©€Bó8&@g€ 0ÿÿÿÿÿÿÿÿ€©€Bô°8&@gž`‚ 1ÿÿÿÿÿÿÿÿÀ©€BõC&@gŸ@ƒ 2ÿÿÿÿÿÿÿÿª€Bö8&@g  „ 3ÿÿÿÿÿÿÿÿÀo€B÷°8&@g¡… 4ÿÿÿÿÿÿÿÿ@ª€Bø°C&@g¢à… Bÿÿÿÿÿÿÿÿ€ª€Bù`D&@g£À† 9ÿÿÿÿÿÿÿÿÀª€Bèð^' @g¨@Ràd" ;0 *ÿÿÿÿÿÿÿÿÀŸ€€bú G&@g¤Àó :ÿÿÿÿÿÿÿÿ«€Bêð^' @g©@R ;À *ÿÿÿÿÿÿÿÿ²€€büÀE&@g¥ˆ >ÿÿÿÿÿÿÿÿ@«€BýÐá& @gª` <P *ÿÿÿÿÿÿÿÿ@²°R€bþÀE&@g¦@÷ ?ÿÿÿÿÿÿÿÿ€«€BûÐá& @g«°Ràd" <° *ÿÿÿÿÿÿÿÿ€²€bpF&@g§Љ @ÿÿÿÿÿÿÿÿÀ«€BÿÐá& @g¬°R < *ÿÿÿÿÿÿÿÿÀ²€bpF&@g¨ ‹ Aÿÿÿÿÿÿÿÿ¬€B@å& @g­ S =  *ÿÿÿÿÿÿÿÿ³S€b8&@g©‹ Cÿÿÿÿÿÿÿÿ@¬€B@å& @g®Sàd" = *ÿÿÿÿÿÿÿÿ€³€b`9&@gªàŒ Dÿÿÿÿÿÿÿÿ€¬€B@å& @g¯S =` *ÿÿÿÿÿÿÿÿÀ³€b G&@g«À EÿÿÿÿÿÿÿÿÀ¬€B è& @g°T > *ÿÿÿÿÿÿÿÿ´àT€€b ÐG&@g¬ Ž Fÿÿÿÿÿÿÿÿ­€Bè& @g±àTàd" >° *ÿÿÿÿÿÿÿÿ@´€€b Ç&@g­€ ˜ÿÿÿÿÿÿÿÿ@­€B è& @g²àT >@*ÿÿÿÿÿÿÿÿ€´€€bðl&@g®` pÿÿÿÿÿÿÿÿ€­€BÐá& @g³PU ? *ÿÿÿÿÿÿÿÿÀ´ÀU€b0I&@g¯Pn ‰ÿÿÿÿÿÿÿÿÀ­€B Ðá& @g´ÀUàd" ?*ÿÿÿÿÿÿÿÿµ€b0I&@g° ’ Šÿÿÿÿÿÿÿÿ®€BÐá& @gµÀU ?`*ÿÿÿÿÿÿÿÿ@µ€b0I&@g±“ ‹ÿÿÿÿÿÿÿÿ@®€Bð^' @g¶0V @ð*ÿÿÿÿÿÿÿÿ€µ0Í€€b0I&@g²à“ Œÿÿÿÿÿÿÿÿ€®€Bð^' @g·0Íàd" @€*ÿÿÿÿÿÿÿÿÀµ€€b0I&@g³À” ÿÿÿÿÿÿÿÿÀ®€B0I&@g´€² Žÿÿÿÿÿÿÿÿp€B€=&@gµ0d ˆÿÿÿÿÿÿÿÿ@ÀB½Ù&PÜvü Û ÿÿÿÿÿÿÿÿ€ˆÀ$Pc&@g¶`³ ÿÿÿÿÿÿÿÿ€Ã€B ñ&PÜwþ ì  ÿÿÿÿÿÿÿÿÀˆ`$d&@g·@´ êÿÿÿÿÿÿÿÿÀÀB¼&PÜx Ða! ÿÿÿÿÿÿÿÿ‰$ ða&@g¸ µ ëÿÿÿÿÿÿÿÿÄ€B!Pò&PÜy í  ÿÿÿÿÿÿÿÿ@‰ !$"@a&@g¹µ íÿÿÿÿÿÿÿÿ@Ä€B#`È&PÜ{ Ê ÿÿÿÿÿÿÿÿ€‰$@a&@gºp¶ îÿÿÿÿÿÿÿÿ€Ä€B%`½&PÜ| àí  ÿÿÿÿÿÿÿÿÀ‰€#$&p\&@g»P· ÿÿÿÿÿÿÿÿÀÄ€B'ó&PÜ} Pî  ÿÿÿÿÿÿÿÿŠ`%$(°o&@g¼0¸ ÿÿÿÿÿÿÿÿÅ€B)`È&PÜ~ àÜ ÿÿÿÿÿÿÿÿ@Š* b&@g½¹ ÿÿÿÿÿÿÿÿ@Å€B+`È&PÜ PÝ ÿÿÿÿÿÿÿÿ€Š,ða&@g¾l ÿÿÿÿÿÿÿÿ€Å€B-`È&PÜ€ 0Þ ÿÿÿÿÿÿÿÿÀŠ.€H&@g¿к ÿÿÿÿÿÿÿÿ@°€B/àî&PÜ  Þ ÿÿÿÿÿÿÿÿ‹ &$0àj&@gÀ°n 4ÿÿÿÿÿÿÿÿÀÅ€B1À!'PÜ‚ €ß ÿÿÿÿÿÿÿÿ@‹ )$2k&@gÁ°» 3ÿÿÿÿÿÿÿÿÆ€B3Ð#'P܃) ðð  ÿÿÿÿÿÿÿÿÀNà$4k&@g¼ 2ÿÿÿÿÿÿÿÿ@Æ€B5`é&PÜ„+ Ðà ÿÿÿÿÿÿÿÿ€‹`/$6Pn&@gÃp½ 1ÿÿÿÿÿÿÿÿ€Æ€Bð^' @g¸0Í @ 2*ÿÿÿÿÿÿÿÿ¶€€b7`È&PÜ…, Ðñ  ÿÿÿÿÿÿÿÿÀ‹9è& @g¹Î AÀ3*ÿÿÿÿÿÿÿÿ¯ð΀€b:`È&P܆- @á ÿÿÿÿÿÿÿÿŒè& @gºðÎàd" A@5*ÿÿÿÿÿÿÿÿ@¶€€b;è& @g»ðÎ A6*ÿÿÿÿÿÿÿÿ€¶€€b>Ðá& @g¼ÐÏ B€7*ÿÿÿÿÿÿÿÿÀ¶°Ð€b=Ðá& @g½°Ðàd" Bp8*ÿÿÿÿÿÿÿÿ·€b?Ðá& @g¾°Ð B09*ÿÿÿÿÿÿÿÿ€·€bA°*' @g¿Ñ C°:*ÿÿÿÿÿÿÿÿÀ·pÒ€€b@°*' @gÀpÒàd" C<*ÿÿÿÿÿÿÿÿ¸€€bB°*' @gÁpÒ CP=*ÿÿÿÿÿÿÿÿ@¸€€bDÀ,' @gÂPÓ D >*ÿÿÿÿÿÿÿÿÀ¸ Ô€@bCÀ,' @gàÔàd" Dð?*ÿÿÿÿÿÿÿÿ¹€@bEÀ,' @gÄ Ô DA*ÿÿÿÿÿÿÿÿ@¹€@bGÐ.' @gÅ€Õ EB*ÿÿÿÿÿÿÿÿ€¹`Ö€@bFÐ.' @gÆ`Öàd" E°C*ÿÿÿÿÿÿÿÿÀ¹€@bHÐ.' @gÇ`Ö EE*ÿÿÿÿÿÿÿÿº€@b8Ðh&@gÄP¾ åÿÿÿÿÿÿÿÿ€°€BKÐh&@gÅÀ¾ æÿÿÿÿÿÿÿÿÀÆ€BL`&@gÆ ¿ éÿÿÿÿÿÿÿÿÇ€BMPX&@gÇ€À ïÿÿÿÿÿÿÿÿ@Ç€BNðV&@gÈpw ðÿÿÿÿÿÿÿÿ€Ç€BOY&@gÉ`Á ñÿÿÿÿÿÿÿÿÀ°€BP°Y&@gÊ@ òÿÿÿÿÿÿÿÿ±€BQ`Z&@gË Ã óÿÿÿÿÿÿÿÿÀÇ€BRY&@gÌÄ ôÿÿÿÿÿÿÿÿÈ€BS°Y&@gÍpÄ õÿÿÿÿÿÿÿÿ@È€BT[&@gÎPÅ öÿÿÿÿÿÿÿÿ@±€BUp\&@gÏ0Æ ùÿÿÿÿÿÿÿÿ€È€BVp\&@gÐÇ ýÿÿÿÿÿÿÿÿÀÈ€BW ]&@gÑðÇ úÿÿÿÿÿÿÿÿÉ€BX ]&@gÒðˆ þÿÿÿÿÿÿÿÿ@É€BY W&@gÓ@É ÿÿÿÿÿÿÿÿÿ€±€BZÀ[&@gÔ°É ÿÿÿÿÿÿÿÿ€É€B[ W&@gÕ Ê ÿÿÿÿÿÿÿÿÀ±€B\Ð]&@gÖË ÷ÿÿÿÿÿÿÿÿÀÉ€B]€^&@g×PÌ øÿÿÿÿÿÿÿÿÊ€B^0_&@gØ  ûÿÿÿÿÿÿÿÿ@³€B_à_&@gÙ üÿÿÿÿÿÿÿÿ@Ê€B`@V&@gÚp Oÿÿÿÿÿÿÿÿ€Ê€BaÇ&@gÛ0 QÿÿÿÿÿÿÿÿÀÊ€BbÇ&@gÜÀ PÿÿÿÿÿÿÿÿË€Bc`p&@gÝ  Gÿÿÿÿÿÿÿÿ€¯€Bdq&@gÞ Hÿÿÿÿÿÿÿÿ@Ë€Be m&@gßð ,ÿÿÿÿÿÿÿÿ€Ë€Bfo&@gàÐ -ÿÿÿÿÿÿÿÿ@·€Bgf&@gá@ 5ÿÿÿÿÿÿÿÿÀË€BhÀf&@gâ  6ÿÿÿÿÿÿÿÿ€¸€Bipg&@gã 7ÿÿÿÿÿÿÿÿÌ€BJà0' @gÈ@× F°F*ÿÿÿÿÿÿÿÿ@º Ø€€bIà0' @gÉ Øàd" FH*ÿÿÿÿÿÿÿÿ€º€€bkà0' @gÊ Ø F I*ÿÿÿÿÿÿÿÿÀº€€b<`é&P܇/ ó  ÿÿÿÿÿÿÿÿ@Œ` $m@2' @gËÙ G J*ÿÿÿÿÿÿÿÿ»PÚ€€bn`È&P܈0 °á ÿÿÿÿÿÿÿÿ€Œl@2' @gÌPÚàd" G L*ÿÿÿÿÿÿÿÿ€»€€bp`È&P܉1 â ÿÿÿÿÿÿÿÿÀŒo@2' @gÍPÚ G M*ÿÿÿÿÿÿÿÿÀ»€€br€$'PÜŠ3 ã ÿÿÿÿÿÿÿÿO0$s@å& @gÎ0Û H0N*ÿÿÿÿÿÿÿÿ¼Ü€bt`'PÜ‹5 àô  ÿÿÿÿÿÿÿÿ 0$q@å& @gÏÜàd" Hk*ÿÿÿÿÿÿÿÿ@¼€bvà%'PÜŒ; pã ÿÿÿÿÿÿÿÿ@`C$u@å& @gÐÜ Hpk*ÿÿÿÿÿÿÿÿ€¼€bx`È&PÜ< àã ÿÿÿÿÿÿÿÿ€y@2' @gÑðÜ Il*ÿÿÿÿÿÿÿÿÀ¼@Þ€€bz0'PÜŽ> Àä ÿÿÿÿÿÿÿÿÀà^$w@2' @gÒ@Þàd" IÀl*ÿÿÿÿÿÿÿÿ½€€b|Ù&PÜ@ 0å ÿÿÿÿÿÿÿÿ@Ž I${@2' @gÓ@Þ IPm*ÿÿÿÿÿÿÿÿ@½€€b~`È&PÜA pË ÿÿÿÿÿÿÿÿ@@å& @gÔ ß J°m*ÿÿÿÿÿÿÿÿ€½pà€b€`È&PÜ‘B  å ÿÿÿÿÿÿÿÿ}@å& @gÕpààd" Jn*ÿÿÿÿÿÿÿÿÀ½€b‚&'PÜ’C æ ÿÿÿÿÿÿÿÿ€@å& @gÖpà Jpn*ÿÿÿÿÿÿÿÿ@¾€b„`È&PÜ“D €æ ÿÿÿÿÿÿÿÿ…ÐD' @g×Pá K0o*ÿÿÿÿÿÿÿÿ€¾0 b†Ç&PÜ”E ðæ ÿÿÿÿÿÿÿÿ€ˆ`È&PÜ•F `ç ÿÿÿÿÿÿÿÿ‘jf&@gäà :ÿÿÿÿÿÿÿÿ@Ì€B‰`È&PÜ–G Ðç ÿÿÿÿÿÿÿÿ€‘ŠÀf&@gåÀ ;ÿÿÿÿÿÿÿÿ€Ì€BŒpg&@gæ  <ÿÿÿÿÿÿÿÿÀÌ€Bf&@gçð 8ÿÿÿÿÿÿÿÿ@»€BŽÀf&@gèÐ 9ÿÿÿÿÿÿÿÿÍ€B€i&@gé° =ÿÿÿÿÿÿÿÿ@Í€Bk&@gê@+ >ÿÿÿÿÿÿÿÿ€Í€B‘àj&@gëà ?ÿÿÿÿÿÿÿÿÀÍ€B’€i&@gìÀ  @ÿÿÿÿÿÿÿÿ¾€B“€i&@gí0! Cÿÿÿÿÿÿÿÿ΀B”k&@gî" Dÿÿÿÿÿÿÿÿ@΀B•àj&@gïð" Eÿÿÿÿÿÿÿÿ€Î€B–€i&@gðÐ# FÿÿÿÿÿÿÿÿÀ΀B—k&@gñ@$ Aÿÿÿÿÿÿÿÿ€À€B˜àj&@gò / Bÿÿÿÿÿÿÿÿ@Á€B™@l&@góà- 'ÿÿÿÿÿÿÿÿÏ€BƒÐD' @gØ0âàd" KÀo*ÿÿÿÿÿÿÿÿÀ¾€€bšP„&@gô& ƒÿÿÿÿÿÿÿÿ@Ï€B‡ÐD' @gÙ0â KPp*ÿÿÿÿÿÿÿÿ¿€€bœ°…&@gõà& „ÿÿÿÿÿÿÿÿÀÏ€Bð^' @gÚã Làp*ÿÿÿÿÿÿÿÿ@¿ð b‹€E'PÜ—I @è ÿÿÿÿÿÿÿÿ’@J$ž`†&@göP. …ÿÿÿÿÿÿÿÿЀB›ð^' @gÛðãàd" Lpq*ÿÿÿÿÿÿÿÿ€¿€€b 0F'PܘL °è ÿÿÿÿÿÿÿÿÀÑ€K$¡‡&@g÷ ( †ÿÿÿÿÿÿÿÿ@ЀBŸð^' @gÜðã Lr*ÿÿÿÿÿÿÿÿ@¯€€b£àF'PÜ™N é ÿÿÿÿÿÿÿÿ@ÒN$¤À‡&@gø€) ‡ÿÿÿÿÿÿÿÿ€Ð€B¥°*' @gÝÐä MÀr*ÿÿÿÿÿÿÿÿÀ¿ 怀b¦@H'PÜšP ê ÿÿÿÿÿÿÿÿÀÒ@O$§pˆ&@gù`* ˆÿÿÿÿÿÿÿÿÀЀB¢°*' @gÞ æàd" M s*ÿÿÿÿÿÿÿÿÀ€€b©`é&PÜ›R pê ÿÿÿÿÿÿÿÿ@Ó€P$ª ‰&@gúÀ. ‰ÿÿÿÿÿÿÿÿÑ€B¨°*' @gß æ M°s*ÿÿÿÿÿÿÿÿ@À€€b¬ðH'PÜŸU Àë ÿÿÿÿÿÿÿÿÀÓ `$­€Š&@gû°+ Šÿÿÿÿÿÿÿÿ@Ñ€B®ÐD' @gàç N0‡*ÿÿÿÿÿÿÿÿÀÀà瀀b¯ I'PÜ X `ø  ÿÿÿÿÿÿÿÿ@Ô S$°0‹&@gü`¨ Œÿÿÿÿÿÿÿÿ€Ñ€B«ÐD' @gáàçàd" NÐt*ÿÿÿÿÿÿÿÿÁ€€b²ó&PÜ¡[ 0ì ÿÿÿÿÿÿÿÿÀÔ V$³à‹&@gý K ‹ÿÿÿÿÿÿÿÿÒ€B±ÐD' @gâàç N`u*ÿÿÿÿÿÿÿÿ€Á€€bµ I'PÜ¢^  ì ÿÿÿÿÿÿÿÿ@Õ X$¶@&@gþ@© ÿÿÿÿÿÿÿÿ€Ò€B·M'@gãÀè OÿÿÿÿÿÿÿÿÀÁ é€b¸PJ'PÜ£a í ÿÿÿÿÿÿÿÿ@þÀ`$¹€f'@gÿ ª ŽÿÿÿÿÿÿÿÿÓ€B´M'@gä éàd" Oÿÿÿÿÿÿÿÿ€b»K'Pܤc €í ÿÿÿÿÿÿÿÿÖ]$ œ"€q'@gË ÿÿÿÿÿÿÿÿÔ€º x(àõ-Hå é Oÿÿÿÿÿÿÿÿ@õ‚@Õ%b¾c'PÜ¥d ðí ÿÿÿÿÿÿÿÿ€Ö¿€q'@gpÌ ÿÿÿÿÿÿÿÿ€Ô€ÀM'@gæ€ê Pÿÿÿÿÿÿÿÿ€Â`ë€bÁ`L'Pܦi `î ÿÿÿÿÿÿÿÿ× ]$Âp…' @gPÍ ÿÿÿÿÿÿÿÿÕ€½M'@gç`ëàd" PÿÿÿÿÿÿÿÿÀ€bÄÀM'Pܧm Ðî ÿÿÿÿÿÿÿÿ@×@c$Åp…' @g0Î ÿÿÿÿÿÿÿÿ€Õ€ÇpN'Pܨn @ï ÿÿÿÿÿÿÿÿ€×É0F'PÜ©q °ï ÿÿÿÿÿÿÿÿØ e$ÃM'@gè`ë PÿÿÿÿÿÿÿÿÀbË`b'@gé@ì Qÿÿÿÿÿÿÿÿ@î í€bÆ`b'@gê íàd" Qÿÿÿÿÿÿÿÿ€î€bÊÙ&Pܪs ð ÿÿÿÿÿÿÿÿ€Ø`f$̰ö%àõ-ãë í Qÿÿÿÿÿÿÿÿø‚@ª#bÎ`é&PÜ«u ñ ÿÿÿÿÿÿÿÿÙg$Ï`b'@gìî Rÿÿÿÿÿÿÿÿ€bÐ`È&Pܬv pñ ÿÿÿÿÿÿÿÿ€ÙÍ`b'@g퀄àd" Rÿÿÿÿÿÿÿÿ@ï€bÒ0î&PÜ­y àñ ÿÿÿÿÿÿÿÿÚ g$Ѱö%àõ-øî€„ Rÿÿÿÿÿÿÿÿ€õ‚`­#bÔ@û&PÜ®{ Pò ÿÿÿÿÿÿÿÿ€Úàh$ÕÀc'@gï`… SÿÿÿÿÿÿÿÿÀï@†€bÖàF'Pܯ} 0ó ÿÿÿÿÿÿÿÿÛ€i$ÓÀc'@gð@†àd" Sÿÿÿÿÿÿÿÿð€bØó&Pܰ€  ó ÿÿÿÿÿÿÿÿ€Û j$×@ &àõ-Nñ@† Sÿÿÿÿÿÿÿÿ€ú‚@¾#bÚs'PÜ´‚ Ðõ ÿÿÿÿÿÿÿÿÜÀj$ÛÀc'@gò ‡ Tÿÿÿÿÿÿÿÿ€ðˆ€bÜó&Pܵ… ÷ ÿÿÿÿÿÿÿÿ€Ü`k$ÙÀc'@góˆàd" TÿÿÿÿÿÿÿÿÀð€bÞ&'Pܶ† ø ÿÿÿÿÿÿÿÿÝÝ@ &àõ-tôˆ Tÿÿÿÿÿÿÿÿ€ò‚@È#bàó&PÜ·‰ àø ÿÿÿÿÿÿÿÿ@Ý l$á e'@gõàˆ Uÿÿÿÿÿÿÿÿ@ñÀ‰€bâ@t'P܏РÀù ÿÿÿÿÿÿÿÿÀÝß e'@göÀ‰àd" Uÿÿÿÿÿÿÿÿ€ñ€bäó&Pܹ  ú ÿÿÿÿÿÿÿÿ@Þàm$ã°ë%àõ-÷À‰ Uÿÿÿÿÿÿÿÿ€ö‚€›$bæðt'Pܺ €û ÿÿÿÿÿÿÿÿÀÞ o$è u'PÜ»” `ü ÿÿÿÿÿÿÿÿ@ß`p$é@•'Pܼ™ @ý ÿÿÿÿÿÿÿÿÀß@r$* á& @g8 g 0 +ÿÿÿÿÿÿÿÿ€­h€b) á& @g9hàd"  ²*ÿÿÿÿÿÿÿÿ5€bë á& @g:h €²*ÿÿÿÿÿÿÿÿ@5€bí á& @g;ðh ³*ÿÿÿÿÿÿÿÿÀ­`i€bì á& @g<`iàd" p³*ÿÿÿÿÿÿÿÿ€5€bî á& @g=`i À +ÿÿÿÿÿÿÿÿÀ5€bðÀß& @g>Ði €!+ÿÿÿÿÿÿÿÿ6ÀÈ€bïÀß& @g?ÀÈàd" À´*ÿÿÿÿÿÿÿÿ@6€bñÀß& @g@ÀÈ @"+ÿÿÿÿÿÿÿÿ€6€bóß& @gA@j €µ*ÿÿÿÿÿÿÿÿ®°j€bòß& @gB°jàd" àµ*ÿÿÿÿÿÿÿÿÀ6€bôß& @gC°j @¶*ÿÿÿÿÿÿÿÿ7€böÀß& @gD k À&+ÿÿÿÿÿÿÿÿ@®k€bõÀß& @gEkàd" À·*ÿÿÿÿÿÿÿÿ@7€b÷Àß& @gFk  é*ÿÿÿÿÿÿÿÿ€7€bùß& @gGl  .+ÿÿÿÿÿÿÿÿ€®àl€bøß& @gHàlàd"  º*ÿÿÿÿÿÿÿÿÀ7€bçà}'@gø Š Vÿÿÿÿÿÿÿÿòð‹€búß& @gIàl  @ï*ÿÿÿÿÿÿÿÿ8€båà}'@gùð‹àd" Vÿÿÿÿÿÿÿÿ@ò€bý á& @gJPm  Pñ*ÿÿÿÿÿÿÿÿÀ®Àm€bü` &àõ-iúð‹ Vÿÿÿÿÿÿÿÿû‚ÀÅ#bû á& @gKÀmàd"  @¼*ÿÿÿÿÿÿÿÿ@8€bà}'@gûÐŒ WÿÿÿÿÿÿÿÿÀò°€bÿ á& @gLÀm  põ*ÿÿÿÿÿÿÿÿ€8€bþà}'@gü°àd" Wÿÿÿÿÿÿÿÿó€b á& @gM n  `ö*ÿÿÿÿÿÿÿÿÀ8o€b` &àõ-ý° Wÿÿÿÿÿÿÿÿ@û‚Ì#b á& @gNoàd"  À½*ÿÿÿÿÿÿÿÿ9€b@'@gþŽ Xÿÿÿÿÿÿÿÿ€ó€b á& @gOo  p,ÿÿÿÿÿÿÿÿ@9€b@'@gÿàd" XÿÿÿÿÿÿÿÿÀó€b Àß& @gP€o  àÁ*ÿÿÿÿÿÿÿÿ¯`p€b@'àõ-M Xÿÿÿÿÿÿÿÿ@‚àŸ$bÀß& @gQ`pàd"   Â*ÿÿÿÿÿÿÿÿ€9€b @'@gp Yÿÿÿÿÿÿÿÿ@ôP€b Àß& @gR`p  `Ã*ÿÿÿÿÿÿÿÿÀ9€b @'@gPàd" Yÿÿÿÿÿÿÿÿ€ô€b ' @gSÐp  ðÃ*ÿÿÿÿÿÿÿÿ@¯@q€b@'@gP YÿÿÿÿÿÿÿÿÀô€b  ' @gT@qàd"  €Ä*ÿÿÿÿÿÿÿÿ:€b`é&@g0‘ Zÿÿÿÿÿÿÿÿõ’€b ' @gU@q  Å*ÿÿÿÿÿÿÿÿ@:€b`é&@g’àd" Zÿÿÿÿÿÿÿÿ@õ€bp ' @gV r @Å*ÿÿÿÿÿÿÿÿ€ÿðÑ€b`é&àõ-ê’ Zÿÿÿÿÿÿÿÿ@ø‚À¬#bp ' @gWðÑàd"  Å*ÿÿÿÿÿÿÿÿ€:€b`é&@gð’ [ÿÿÿÿÿÿÿÿÀõГ€b Ó'€Ô'‚'à¹`ƒ' ]9(p^P¢'à °Ú'`Ñ!0©'p]!¥'€ap¦'ÐbêPv'Pܽ þ ÿÿÿÿÿÿÿÿ@àÀt$Ç& @g0à]!àd" ÿÿÿÿÿÿÿÿ@Ö€w'Pܾ¢ ÿ ÿÿÿÿÿÿÿÿÀà v$Èàù&@g10è  ÿÿÿÿÿÿÿÿÀÖ€°w'PÜ¿¦ àÿ ÿÿÿÿÿÿÿÿ@á y$ `x'PÜÀ­ À  ÿÿÿÿÿÿÿÿÀá{$!y'PÜÁ²    ÿÿÿÿÿÿÿÿ@â ~$"ðt'Pܵ €  ÿÿÿÿÿÿÿÿÀâ €$#Ày'PÜù `  ÿÿÿÿÿÿÿÿ@ãà$$ðt'PÜļ @  ÿÿÿÿÿÿÿÿÀãÀƒ$%pz'PÜÅÁ   ÿÿÿÿÿÿÿÿ@ä…$& {'PÜÆÅ   ÿÿÿÿÿÿÿÿÀ䀇$'Ð{'PÜÇÊ à  ÿÿÿÿÿÿÿÿ@å`‰$(€|'PÜÈÍ 0  ÿÿÿÿÿÿÿÿÀåà‹$)0}'PÜÉÒ   ÿÿÿÿÿÿÿÿ@æ $*àˆ'PÜÊÖ ð  ÿÿÿÿÿÿÿÿÀæ@$p ' @gXðÑ 0Æ*ÿÿÿÿÿÿÿÿÀ:€b`é&@gГàd" [ÿÿÿÿÿÿÿÿö€b+pz'PÜËÛ Ð  ÿÿÿÿÿÿÿÿ@ç ’$,Ð ' @gYr `Æ*ÿÿÿÿÿÿÿÿ;s€b`é&àõ- Г [ÿÿÿÿÿÿÿÿ€ø‚à¯#b. u'PÜÌß °  ÿÿÿÿÿÿÿÿÀç ”$Ð ' @gZsàd" ÀÆ*ÿÿÿÿÿÿÿÿ@;€b0ð'@g °” \ÿÿÿÿÿÿÿÿ€ö•€b/Ð ' @g[s  Ç*ÿÿÿÿÿÿÿÿ€;€b-ð'@g •àd" \ÿÿÿÿÿÿÿÿÀö€b4ß& @g\ps È*ÿÿÿÿÿÿÿÿÀ;às€b3ð'àõ-T • \ÿÿÿÿÿÿÿÿ@ð‚€¿#b2ß& @g]àsàd"  È*ÿÿÿÿÿÿÿÿ<€b7ð'@g à– ]ÿÿÿÿÿÿÿÿ@÷À—€b6ß& @g^às `É*ÿÿÿÿÿÿÿÿ@<€b5ð'@gÀ—àd" ]ÿÿÿÿÿÿÿÿ€÷€b:Àß& @g_ÀM  ðÉ*ÿÿÿÿÿÿÿÿ€<Àt€b9ð'@gÀ— ]ÿÿÿÿÿÿÿÿÀ÷€b8Àß& @g`Àtàd" €Ê*ÿÿÿÿÿÿÿÿÀ<€b= †'@g€  ^ÿÿÿÿÿÿÿÿø@€b<Àß& @gaÀt àÊ*ÿÿÿÿÿÿÿÿ=€b; †'@g@àd" ^ÿÿÿÿÿÿÿÿ@ø€b@ß& @gb0u pË*ÿÿÿÿÿÿÿÿ@= u€b? †'àõ-•@ ^ÿÿÿÿÿÿÿÿÀñ‚à #b>ß& @gc uàd"  Ë*ÿÿÿÿÿÿÿÿ€=€bCІ' @g™ _`Õ*ÿÿÿÿÿÿÿÿÀøð™€bBß& @gd u Ì*ÿÿÿÿÿÿÿÿÀ=€bAІ' @gð™àd" _PÖ*ÿÿÿÿÿÿÿÿù€bF á& @gepÀ `Ì*ÿÿÿÿÿÿÿÿÀÿPÁ€bEâ% àõ-gð™ _p×*ÿÿÿÿÿÿÿÿÀ ‚à‘#bD á& @gfPÁàd" ÀÌ*ÿÿÿÿÿÿÿÿ>€bI€‡' @gК `Ø*ÿÿÿÿÿÿÿÿ€ù œ€bH á& @ggPÁ PÍ*ÿÿÿÿÿÿÿÿ@>€bG€‡' @g œàd" ` Ù*ÿÿÿÿÿÿÿÿÀù€bL á& @gh0 pÎ*ÿÿÿÿÿÿÿÿ Â€bJ á& @gi Âàd" Ï*ÿÿÿÿÿÿÿÿ@€bN á& @gj Â ÀÏ*ÿÿÿÿÿÿÿÿ8€bPÀß& @gkà °Ð*ÿÿÿÿÿÿÿÿ@8€Ã€bOÀß& @gl€Ãàd" pÑ*ÿÿÿÿÿÿÿÿ€€bQÀß& @gm€Ã P!+ÿÿÿÿÿÿÿÿ€8€bSß& @gnðà "+ÿÿÿÿÿÿÿÿ9`Ä€bRß& @go`Äàd" °è*ÿÿÿÿÿÿÿÿÀ€bTß& @gp`Ä Ðé*ÿÿÿÿÿÿÿÿ:€bV á& @gqÐÄ ê*ÿÿÿÿÿÿÿÿ@Å€bU á& @gr@Åàd" P{+ÿÿÿÿÿÿÿÿ@€bW á& @gs@Å @ì*ÿÿÿÿÿÿÿÿ€€bYÀß& @gt°Å í*ÿÿÿÿÿÿÿÿ@< Æ€bXÀß& @gu Æàd" ðí*ÿÿÿÿÿÿÿÿÀ€bZÀß& @gv Æ °î*ÿÿÿÿÿÿÿÿÞ€b\ß& @gw™  P+ÿÿÿÿÿÿÿÿ€=Æ€bK€y( àõ-P œ `°Ù*ÿÿÿÿÿÿÿÿô‚€Ö%b^0ˆ' @g a Ú*ÿÿÿÿÿÿÿÿ@úPž€bM0ˆ' @gPžàd" a0Û*ÿÿÿÿÿÿÿÿ€ú€b_í% àõ-˜Pž aÀÛ*ÿÿÿÿÿÿÿÿ€ø‚€¡#baÀ'@g0Ÿ bÿÿÿÿÿÿÿÿû €b`À'@g àd" bÿÿÿÿÿÿÿÿ@û€bbàz(àõ-W  bÿÿÿÿÿÿÿÿú‚€°#bd ‘'@gð  cÿÿÿÿÿÿÿÿÀû@¢€bc ‘'@g @¢àd" cÿÿÿÿÿÿÿÿü€bepî%àõ-£!@¢ cÿÿÿÿÿÿÿÿÀú‚À¢#bg€’'@g" £ dÿÿÿÿÿÿÿÿ€üp¤€bf€’'@g#p¤àd" dÿÿÿÿÿÿÿÿÀü€bh€’'àõ-\$p¤ dÿÿÿÿÿÿÿÿ€û‚Ù%bjà“'@g%P¥ eÿÿÿÿÿÿÿÿ@ý`õ€bià“'@g&`õàd" eÿÿÿÿÿÿÿÿ€ý€bkÐï%àõ-ª'`õ eÿÿÿÿÿÿÿÿ@ü‚ ¤#b1w'PÜÍä  ÿÿÿÿÿÿÿÿ@耖$n°w'PÜÎè p  ÿÿÿÿÿÿÿÿÀè™$o {'PÜÏì P  ÿÿÿÿÿÿÿÿ@éàš$p‰'PÜÐð 0  ÿÿÿÿÿÿÿÿÀé`$q‰'PÜÑô   ÿÿÿÿÿÿÿÿ@ê@Ÿ$rÐ{'PÜÒù ð  ÿÿÿÿÿÿÿÿÀêÀ¡$sÀ(PÜÓÿ Ð  ÿÿÿÿÿÿÿÿ@ë@¤$t@Š'PÜÔ °  ÿÿÿÿÿÿÿÿ€ë`§$uðŠ'PÜÕ   ÿÿÿÿÿÿÿÿÿà©$v ‹'PÜÖ p  ÿÿÿÿÿÿÿÿ@ì`¬$wPŒ'PÜ× P  ÿÿÿÿÿÿÿÿ€ì °$x'PÜØ À  ÿÿÿÿÿÿÿÿ@ÿ ²$yÀy'PÜÙ 0  ÿÿÿÿÿÿÿÿÀì·$zÀy'PÜÚ$    ÿÿÿÿÿÿÿÿíà¸$[ß& @gxÆàd" ð*ÿÿÿÿÿÿÿÿ€b{°'PÜÛ*   ÿÿÿÿÿÿÿÿ@íÀº$]ß& @gyÆ н,ÿÿÿÿÿÿÿÿÀ>€b}€¾'PÜÜ/ ð  ÿÿÿÿÿÿÿÿ€íà½$~ á& @gzÇ …+ÿÿÿÿÿÿÿÿ€?pÇ€b| á& @g{pÇàd" pò*ÿÿÿÿÿÿÿÿ@€b€ á& @g|pÇ °‡+ÿÿÿÿÿÿÿÿ€@€b‚ ' @g}àÇ À¾,ÿÿÿÿÿÿÿÿ€PÈ€b ' @g~PÈàd" °ô*ÿÿÿÿÿÿÿÿÀ€bƒ ' @gPÈ Œ+ÿÿÿÿÿÿÿÿ@B€b…p ' @g€@ž  P+ÿÿÿÿÿÿÿÿC0É€b„p ' @g0Éàd" ðö*ÿÿÿÿÿÿÿÿ€b†p ' @g‚0É °+ÿÿÿÿÿÿÿÿ@Œ€bˆÐ ' @gƒ É 0’+ÿÿÿÿÿÿÿÿÀDÊ€b‡Ð ' @g„Êàd" Ðø*ÿÿÿÿÿÿÿÿ@€b‰Ð ' @g…Ê ðÓ,ÿÿÿÿÿÿÿÿ€€b‹Àß& @g†€Ê —+ÿÿÿÿÿÿÿÿ€FðÊ€bŠÀß& @g‡ðÊàd" àú*ÿÿÿÿÿÿÿÿÀ€bŒÀß& @gˆðÊ 0+ÿÿÿÿÿÿÿÿ€bŽß& @g‰`Ë +ÿÿÿÿÿÿÿÿ@HÐË€bß& @gŠÐËàd" P+ÿÿÿÿÿÿÿÿ@€bß& @g‹ÐË à+ÿÿÿÿÿÿÿÿ€€b‘Àß& @gŒ@Ì  @+ÿÿÿÿÿÿÿÿJ°Ì€bÀß& @g°Ìàd"   +ÿÿÿÿÿÿÿÿÀ€b’Àß& @gްÌ  +ÿÿÿÿÿÿÿÿÀJ€b”ß& @g@1! !`+ÿÿÿÿÿÿÿÿ Í€b“ß& @g Íàd" !+ÿÿÿÿÿÿÿÿ@€b•ß& @g‘ Í !PŒ,ÿÿÿÿÿÿÿÿ€€b— á& @g’°1! " À+ÿÿÿÿÿÿÿÿÀÍ€b– á& @g“Íàd" "P+ÿÿÿÿÿÿÿÿ€b˜ á& @g”Í ",ÿÿÿÿÿÿÿÿ@€bš á& @g•Î #@Ä+ÿÿÿÿÿÿÿÿ€p΀b™ á& @g–pÎàd" #+ÿÿÿÿÿÿÿÿÀ€b› á& @g—pÎ #0È+ÿÿÿÿÿÿÿÿK€bm –' @g(@ö fP+ÿÿÿÿÿÿÿÿþ°ö€bl –' @g)°öàd" fà+ÿÿÿÿÿÿÿÿ €bžÐä% àõ-k*°ö f@+ÿÿÿÿÿÿÿÿ@ù‚À“#b P—' @g+÷ gÐ+ÿÿÿÿÿÿÿÿ@ pø€bŸP—' @g,pøàd" g0+ÿÿÿÿÿÿÿÿ€ €b¡à% àõ-_-pø g+ÿÿÿÿÿÿÿÿý‚ #b£°˜' @g.Pù hP+ÿÿÿÿÿÿÿÿ 0ú€b¢°˜' @g/0úàd" h°+ÿÿÿÿÿÿÿÿ@ €b¤àñ% àõ-¯00ú h+ÿÿÿÿÿÿÿÿÀý‚à¥#b¦`é& @g1û i +ÿÿÿÿÿÿÿÿÀ ðû€€b¥`é& @g2ðûàd" i0+ÿÿÿÿÿÿÿÿ €€b§`é& @g3ðû iÀ+ÿÿÿÿÿÿÿÿ@ €€b©`é& @g4Ðü jÝ+ÿÿÿÿÿÿÿÿ€ °ý€€b¨`é& @g5°ýàd" j°+ÿÿÿÿÿÿÿÿÀ €€bª`é& @g6°ý j@+ÿÿÿÿÿÿÿÿ €€b¬`é& @g7þ kÐ+ÿÿÿÿÿÿÿÿ@ pÿ€b ' @g˜àÎ $PÉ+ÿÿÿÿÿÿÿÿ@KPÏ€bœ ' @g™PÏàd" $€ +ÿÿÿÿÿÿÿÿ€b® ' @gšPÏ $Ð,ÿÿÿÿÿÿÿÿ@€b°p ' @g›`B  % Ì+ÿÿÿÿÿÿÿÿ€@C €b¯p ' @gœ@C àd" %  +ÿÿÿÿÿÿÿÿÀ€b±p ' @g@C  % +ÿÿÿÿÿÿÿÿ€K€b³Ð ' @gž D  &` +ÿÿÿÿÿÿÿÿÀKD €b²Ð ' @gŸD àd" &À +ÿÿÿÿÿÿÿÿ€b´Ð ' @g D  &Ž,ÿÿÿÿÿÿÿÿ@€b¶Àß& @g¡pE  'pÍ+ÿÿÿÿÿÿÿÿ€PF €bµÀß& @g¢PF àd" '  +ÿÿÿÿÿÿÿÿÀ€b·Àß& @g£PF  '`+ÿÿÿÿÿÿÿÿL€b¹Àß& @g¤0G  (À+ÿÿÿÿÿÿÿÿ  G €b¸Àß& @g¥ G àd" ( +ÿÿÿÿÿÿÿÿ@ €bºÀß& @g¦ G  (€+ÿÿÿÿÿÿÿÿ@L€b¼ß& @g§€H  )0Î+ÿÿÿÿÿÿÿÿ€ `I €bÇ& @gÀX ÿÿÿÿÿÿÿÿÀÕ€À'PÜÝ5 `  ÿÿÿÿÿÿÿÿÀí`À$¿ðÁ'PÜÞ; Ð  ÿÿÿÿÿÿÿÿ@ Ä$À`Ž'PÜß@ @  ÿÿÿÿÿÿÿÿ€@Ç$Á'PÜàD °  ÿÿÿÿÿÿÿÿÀ`Ê$°'PÜáJ   ÿÿÿÿÿÿÿÿ@Ì$ÃðŠ'PÜâO   ÿÿÿÿÿÿÿÿ@Ð$Ä ‹'PÜãU   ÿÿÿÿÿÿÿÿ€ Ó$ÅPŒ'PÜäZ p  ÿÿÿÿÿÿÿÿÀ Õ$Æ€¾'PÜå_ P  ÿÿÿÿÿÿÿÿ€×$ÇÀy'PÜæc À  ÿÿÿÿÿÿÿÿ@Ú$È0ž'PÜçh 0  ÿÿÿÿÿÿÿÿ€àÛ$Ê0ž'PÜèm    ÿÿÿÿÿÿÿÿÀÀÝ$ËÀ'PÜés   ÿÿÿÿÿÿÿÿ@à$Ì`é&PÜêu €  ÿÿÿÿÿÿÿÿ@`ã$»ß& @g¨`I àd" )@+ÿÿÿÿÿÿÿÿÀ €b«`é& @g8pÿàd" k`+ÿÿÿÿÿÿÿÿ€ €bÍàž'PÜëx ð  ÿÿÿÿÿÿÿÿ€ä$½ß& @g©`I  )P•,ÿÿÿÿÿÿÿÿ€%€b­`é& @g9pÿ kÀ+ÿÿÿÿÿÿÿÿ@‹€bП'PÜì| `  ÿÿÿÿÿÿÿÿÀ@å$Ñ á& @gª@J  *°3+ÿÿÿÿÿÿÿÿ&@?!€bÒ`é& @g:P  lP+ÿÿÿÿÿÿÿÿÀ 0 €€bÎ á& @g«@?!àd" *@4+ÿÿÿÿÿÿÿÿ€&€bÏ`é& @g;0 àd" là+ÿÿÿÿÿÿÿÿ€€bÔ á& @g¬@?! * 4+ÿÿÿÿÿÿÿÿ'€bÕ`é& @g<0  lp+ÿÿÿÿÿÿÿÿ@€€bØß& @g­K  +`5+ÿÿÿÿÿÿÿÿ€'pL €bÙ`é& @g=  m+ÿÿÿÿÿÿÿÿ€ð €€bÖß& @g®pL àd" + 6+ÿÿÿÿÿÿÿÿ(€b×`é& @g>ð àd" m+ÿÿÿÿÿÿÿÿÀ€€bÚß& @g¯pL  +°6+ÿÿÿÿÿÿÿÿ€(€bÛ`é& @g?ð  m +ÿÿÿÿÿÿÿÿ€€bÞ á& @g°PM  ,p7+ÿÿÿÿÿÿÿÿ) N €bß`é& @g@Ð  n€+ÿÿÿÿÿÿÿÿ€‹° €bÜ á& @g± N àd" ,08+ÿÿÿÿÿÿÿÿ€)€bÝ`é& @gA° àd" nÐ"+ÿÿÿÿÿÿÿÿ@€bà á& @g² N  ,ð8+ÿÿÿÿÿÿÿÿ*€bá`é& @gB°  n`#+ÿÿÿÿÿÿÿÿ€€bäÀß& @g³€O  -P9+ÿÿÿÿÿÿÿÿ€*`P €bå`é& @gC  oð#+ÿÿÿÿÿÿÿÿÀp €€bâÀß& @g´`P àd" -°9+ÿÿÿÿÿÿÿÿ+€bã`é& @gDp àd" o€$+ÿÿÿÿÿÿÿÿ€€bæÀß& @gµ`P  -`€(ÿÿÿÿÿÿÿÿ@+€bç`é& @gEp  o@%+ÿÿÿÿÿÿÿÿ@€€bêÀß& @g¶@Q  .@:+ÿÿÿÿÿÿÿÿ€+°Q €bë`é& @gFÀ  pÐ%+ÿÿÿÿÿÿÿÿ€  €€bèÀß& @g·°Q àd" . :+ÿÿÿÿÿÿÿÿÀ+€bé`é& @gG  àd" p`&+ÿÿÿÿÿÿÿÿÀ€€bí`é& @gH   p '+ÿÿÿÿÿÿÿÿ€€bð`é& @gI€  q°'+ÿÿÿÿÿÿÿÿ@` €€bï`é& @gJ` àd" q@(+ÿÿÿÿÿÿÿÿ€€€bñ`é& @gK`  q)+ÿÿÿÿÿÿÿÿÀ€€bó`é& @gL@  r)+ÿÿÿÿÿÿÿÿ €€bò`é& @gM àd" r *+ÿÿÿÿÿÿÿÿ@€€bô`é& @gN  r°*+ÿÿÿÿÿÿÿÿ€"€€bö`é& @gO  s@++ÿÿÿÿÿÿÿÿ€à €€bõ`é& @gPà àd" sÐ++ÿÿÿÿÿÿÿÿÀ€€b÷`é& @gQà  s,+ÿÿÿÿÿÿÿÿ€€bù`é& @gRÀ  t -+ÿÿÿÿÿÿÿÿ@  €€bø`é& @gS  àd" t°-+ÿÿÿÿÿÿÿÿ€€€bú`é& @gT   tp.+ÿÿÿÿÿÿÿÿÀ€€bü`é& @gU€  u/+ÿÿÿÿÿÿÿÿÀ‹` €bû`é& @gV` àd" u/+ÿÿÿÿÿÿÿÿ€bý`é& @gW`  u 0+ÿÿÿÿÿÿÿÿ@€bìÀß& @g¸°Q  .;+ÿÿÿÿÿÿÿÿ,€bÿ`é& @gX@  v°0+ÿÿÿÿÿÿÿÿ€  €bß& @g¹R  /`;+ÿÿÿÿÿÿÿÿ@,pS €bþ`é& @gY  àd" v@1+ÿÿÿÿÿÿÿÿÀ€bîß& @gºpS àd" /À;+ÿÿÿÿÿÿÿÿ€,€b`é& @gZ   vÐ1+ÿÿÿÿÿÿÿÿ€bß& @g»pS  / <+ÿÿÿÿÿÿÿÿÀ,€b`é& @g[  w2+ÿÿÿÿÿÿÿÿ@P¡ €€b á& @g¼PT  0€<+ÿÿÿÿÿÿÿÿ-ÀT €b`é& @g\P¡ àd" w 3+ÿÿÿÿÿÿÿÿ€€€b á& @g½ÀT àd" 0à<+ÿÿÿÿÿÿÿÿ@-€b`é& @g]P¡  w€N+ÿÿÿÿÿÿÿÿÀ€€b á& @g¾ÀT  0@=+ÿÿÿÿÿÿÿÿ€-€b `é& @g^0¢  xP+ÿÿÿÿÿÿÿÿ ¢ €€b Àß& @g¿ U  1À€(ÿÿÿÿÿÿÿÿÀ-€V €b `é& @g_ ¢ àd" x€Q+ÿÿÿÿÿÿÿÿ@€€b Àß& @gÀ€V àd" 1Ð=+ÿÿÿÿÿÿÿÿ.€b `é& @g` ¢  xÐR+ÿÿÿÿÿÿÿÿ€€€bÀß& @gÁ€V  10>+ÿÿÿÿÿÿÿÿ@.€bê& @ga€£  y€T+ÿÿÿÿÿÿÿÿÀ`¤ €€bß& @gÂ`W  2>+ÿÿÿÿÿÿÿÿ€ŒO!€bê& @gb`¤ àd" ypU+ÿÿÿÿÿÿÿÿ€€bß& @gÃO!àd" 2ð>+ÿÿÿÿÿÿÿÿ€.€bê& @gc`¤  yV+ÿÿÿÿÿÿÿÿ@耀bß& @gÄO! 2 (ÿÿÿÿÿÿÿÿÀ.€bê& @gd@¥  z°W+ÿÿÿÿÿÿÿÿ@ ¦ €€bµBDº*0ª-º*ºBDº*Ø›o ÀB9 è™o ÈBÉB9PlÞ›o ÓBÕBDº*ÚBº*ÛB á& @gŰX  3€?+ÿÿÿÿÿÿÿÿ/Y €bê& @ge ¦ àd" zÐX+ÿÿÿÿÿÿÿÿ€€€b á& @gÆY àd" 3à?+ÿÿÿÿÿÿÿÿ@/€bê& @gf ¦  zðY+ÿÿÿÿÿÿÿÿŒ€€b á& @gÇY  3@@+ÿÿÿÿÿÿÿÿ€/€bê& @gg§  {àZ+ÿÿÿÿÿÿÿÿÀà§ €€bß& @gÈpZ  4 @+ÿÿÿÿÿÿÿÿÀ/àZ €bß& @gÉàZ àd" 4A+ÿÿÿÿÿÿÿÿ0€b!ß& @gÊàZ  4`A+ÿÿÿÿÿÿÿÿ@0€bfÉ9€¦ño mÉ-ÀÒè,º*Ø›o oÉ9 ™o sÉ9à¿xÉ+º*Þ›o yÉ;º*XzÉ,º*{É/º*}É.º*# á& @gËÀ[  5ÀA+ÿÿÿÿÿÿÿÿ€0 \ €b" á& @gÌ \ àd" 5 B+ÿÿÿÿÿÿÿÿÀ0€b% á& @gÍ \  5€B+ÿÿÿÿÿÿÿÿ1€b'Àß& @g΀]  6ÀM+ÿÿÿÿÿÿÿÿ@1`^ €b&Àß& @gÏ`^ àd" 6PN+ÿÿÿÿÿÿÿÿ€1€b(Àß& @gÐ`^  6pO+ÿÿÿÿÿÿÿÿÀ1€bEè Ðì-º*°¢o Fè  º*åžo Gè 9€‘¡o Oè àá-º*Pè º*,¡o Qè º*óo Rè º*Sè 9ðïbè º*cè º**ß& @gÑÀÄ  7`P+ÿÿÿÿÿÿÿÿ20Å €b)ß& @gÒ0Å àd" 7PQ+ÿÿÿÿÿÿÿÿ@2€b,ß& @gÓ0Å  7@R+ÿÿÿÿÿÿÿÿ€2€b. á& @gÔ Å  80S+ÿÿÿÿÿÿÿÿÀ2Æ €b- á& @gÕÆ àd" 8PT+ÿÿÿÿÿÿÿÿ3€b/ á& @gÖÆ  8àT+ÿÿÿÿÿÿÿÿ@3€b1Àß& @g×ðÆ  9V+ÿÿÿÿÿÿÿÿ€3ÐÇ €bÓ@ 'PÜí Ð  ÿÿÿÿÿÿÿÿ ç$3`È&PÜî‚ @  ÿÿÿÿÿÿÿÿ@4`È&PÜïƒ °  ÿÿÿÿÿÿÿÿ€5ó&PÜð† °#! ÿÿÿÿÿÿÿÿÀ é$6`È&PÜñ‡ !  ÿÿÿÿÿÿÿÿ7`È&PÜòˆ !  ÿÿÿÿÿÿÿÿ@8Ç&PÜó‰ "  ÿÿÿÿÿÿÿÿ€9`È&PÜôŠ p"  ÿÿÿÿÿÿÿÿÀ:ó&PÜõ à"  ÿÿÿÿÿÿÿÿàê$;`¤'PÜö P#  ÿÿÿÿÿÿÿÿ@ ì$<`¤'PÜ÷“ À#  ÿÿÿÿÿÿÿÿ€`í$=®'PÜø— 0$  ÿÿÿÿÿÿÿÿÀ î$>°®'PÜùš  $  ÿÿÿÿÿÿÿÿ€ð$?`¯'PÜú¢ %  ÿÿÿÿÿÿÿÿ@Àñ$ê& @ghà§ àd" {\+ÿÿÿÿÿÿÿÿ€€b@`¯'PÜûª €%  ÿÿÿÿÿÿÿÿ€€õ$ ê& @già§  { ]+ÿÿÿÿÿÿÿÿÀ8€€bB°V'PÜü¬ ð%  ÿÿÿÿÿÿÿÿÀ@ù$Cê& @gjÀ¨  |@^+ÿÿÿÿÿÿÿÿ@Ü © €€bAê& @gk © àd" |`_+ÿÿÿÿÿÿÿÿ@9€€bEê& @gl ©  |P`+ÿÿÿÿÿÿÿÿ€9€€bGê& @gm€ª  }pa+ÿÿÿÿÿÿÿÿÀ9`« €€bFê& @gn`« àd" }b+ÿÿÿÿÿÿÿÿ@:€€bHê& @go`«  }°c+ÿÿÿÿÿÿÿÿ€:€€bJê& @gp°¬  ~Ðd+ÿÿÿÿÿÿÿÿÀ:­ €€bIê& @gq­ àd" ~ðe+ÿÿÿÿÿÿÿÿ;€€bKê& @gr­  ~àf+ÿÿÿÿÿÿÿÿ@;€€bMê& @gsp®  h+ÿÿÿÿÿÿÿÿ€;P¯ €€bLê& @gtP¯ àd"  i+ÿÿÿÿÿÿÿÿÀ;€€bNê& @guP¯  @j+ÿÿÿÿÿÿÿÿ<€€bPê& @gv0°  €`k+ÿÿÿÿÿÿÿÿ€Ý± €€bOê& @gw± àd" €Pl+ÿÿÿÿÿÿÿÿ€<€€b0Àß& @gØÐÇ àd" 9 W+ÿÿÿÿÿÿÿÿÀ3€b2Àß& @gÙÐÇ  9@X+ÿÿÿÿÿÿÿÿ4€bTß& @gÚ°È  :`Y+ÿÿÿÿÿÿÿÿ@4É €bSß& @gÛÉ àd" :j,ÿÿÿÿÿÿÿÿ€4€bUß& @gÜÉ  :p[+ÿÿÿÿÿÿÿÿÀ4€bW á& @gÝpÊ  ;\+ÿÿÿÿÿÿÿÿ5PË €bV á& @gÞPË àd" ;°]+ÿÿÿÿÿÿÿÿ@5€bX á& @gßPË  ;Ð^+ÿÿÿÿÿÿÿÿ€5€bZ ' @gà0Ì  <_+ÿÿÿÿÿÿÿÿÀ5 Ì €bY ' @gá Ì àd" <Àm,ÿÿÿÿÿÿÿÿ6€b[ ' @gâ Ì  <à`+ÿÿÿÿÿÿÿÿ@6€b]p ' @gãðÍ  = a+ÿÿÿÿÿÿÿÿ€6ÐÎ €b\p ' @gäÐÎ àd" =`b+ÿÿÿÿÿÿÿÿÀ6€b^p ' @gåÐÎ  = c+ÿÿÿÿÿÿÿÿ7€b`Ð ' @gæ Ð  >àc+ÿÿÿÿÿÿÿÿ@7Ñ €b_Ð ' @gçÑ àd" > d+ÿÿÿÿÿÿÿÿ€7€baÐ ' @gèÑ  >`e+ÿÿÿÿÿÿÿÿÀ7€bQê& @gx±  €pm+ÿÿÿÿÿÿÿÿÀ<€€bcÀß& @géPÒ  ?Pf+ÿÿÿÿÿÿÿÿ€L0Ó €bdê& @gyð±  0n+ÿÿÿÿÿÿÿÿÀÝ@³ €€bbÀß& @gê0Ó àd" ?pg+ÿÿÿÿÿÿÿÿÀL€bRê& @gz@³ àd" Px+ÿÿÿÿÿÿÿÿ=€€bDÀ°'PÜý¯ `&  ÿÿÿÿÿÿÿÿ àù$eÀß& @gë0Ó  ?h+ÿÿÿÿÿÿÿÿM€bfê& @g{@³   ®,ÿÿÿÿÿÿÿÿ@=€€biÇ&PÜþ° Ð&  ÿÿÿÿÿÿÿÿ@ jß& @gì€Ô  @°i+ÿÿÿÿÿÿÿÿ@M`Õ €bkê& @g| ´  ‚py+ÿÿÿÿÿÿÿÿÀ=µ €€bl`È&PÜÿ± @'  ÿÿÿÿÿÿÿÿ€ gß& @gí`Õ àd" @Ðj+ÿÿÿÿÿÿÿÿ€M€bhê& @g}µ àd" ‚z+ÿÿÿÿÿÿÿÿ>€€bo`'Pܳ °'  ÿÿÿÿÿÿÿÿÀ Às%mß& @gî`Õ  @„,ÿÿÿÿÿÿÿÿÀM€bnê& @g~µ  ‚z+ÿÿÿÿÿÿÿÿ@>€€br`È&PÜ´ (  ÿÿÿÿÿÿÿÿ!s á& @gï@Ö  Aàl+ÿÿÿÿÿÿÿÿN × €btê& @gൠ ƒ {+ÿÿÿÿÿÿÿÿ€>À¶ €€bu`È&Pܵ (  ÿÿÿÿÿÿÿÿ@!p á& @gð × àd" Apˆ+ÿÿÿÿÿÿÿÿ@N€bqê& @g€À¶ àd" ƒ°{+ÿÿÿÿÿÿÿÿ?€€bx`È&Pܶ )  ÿÿÿÿÿÿÿÿ€!v á& @gñ ×  Að¾,ÿÿÿÿÿÿÿÿ€N€bwê& @gÀ¶  ƒp|+ÿÿÿÿÿÿÿÿ@?€€b{`È&PÜ· /! ÿÿÿÿÿÿÿÿÀ!| 3' @gòØ  BPŠ+ÿÿÿÿÿÿÿÿÀNàØ €b}ê& @g‚ ·  „}+ÿÿÿÿÿÿÿÿÀ?€¸ €€b~в'Pܼ p)  ÿÿÿÿÿÿÿÿ" û$y 3' @góàØ àd" B@‹+ÿÿÿÿÿÿÿÿO€bzê& @gƒ€¸ àd" „}+ÿÿÿÿÿÿÿÿ@€€b`È&Pܽ à)  ÿÿÿÿÿÿÿÿ@" 3' @gôàØ  B0Œ+ÿÿÿÿÿÿÿÿ@O€b€ê& @g„€¸  „ð}+ÿÿÿÿÿÿÿÿ@Þ€€b„°V'PÜ¿ P*  ÿÿÿÿÿÿÿÿ€"`ü$…ð2' @gõÀÙ  C`7)ÿÿÿÿÿÿÿÿ€O Ú €b†À' @g…`¹  …€~+ÿÿÿÿÿÿÿÿ@@@º €€b‡@û&PÜÁ À*  ÿÿÿÿÿÿÿÿÀ"ý$‚ð2' @gö Ú àd" Cà+ÿÿÿÿÿÿÿÿÀO€bƒÀ' @g†@º àd" …+ÿÿÿÿÿÿÿÿÀ@€€bŠ@û&PÜ à 0+  ÿÿÿÿÿÿÿÿ# ý$ˆð2' @g÷ Ú  C+ÿÿÿÿÿÿÿÿP€b‰À' @g‡@º  …Ð+ÿÿÿÿÿÿÿÿA€€b@û&PÜ Å  +  ÿÿÿÿÿÿÿÿ@#@þ$@û&PÜ Ç ,  ÿÿÿÿÿÿÿÿ€#àþ$‘`é&PÜ É €,  ÿÿÿÿÿÿÿÿÀ#€ÿ$À' @gˆ »  †P¼,ÿÿÿÿÿÿÿÿ@A¼ €€bŒÀ' @g‰¼ àd" †À€+ÿÿÿÿÿÿÿÿ€A€€b“À' @gм  †€+ÿÿÿÿÿÿÿÿÀA€€b•Ç& @g‹༠ ‡‚+ÿÿÿÿÿÿÿÿBP½ €b”Ç& @gŒP½ àd" ‡ ‚+ÿÿÿÿÿÿÿÿ€B€b–Ç& @gP½  ‡ƒ+ÿÿÿÿÿÿÿÿÀB€b˜`é& @gŽ0¾  ˆƒ+ÿÿÿÿÿÿÿÿ@C¿ €b—`é& @g¿ àd" ˆP„+ÿÿÿÿÿÿÿÿ€C€b™`é& @g¿  ˆ@…+ÿÿÿÿÿÿÿÿÀC€b›ðS'@g‘ð¿  ‰ÿÿÿÿÿÿÿÿD€bœ°è& @g’ ú  І+ÿÿÿÿÿÿÿÿ@Dú €@bš°è& @g“ú àd" І+ÿÿÿÿÿÿÿÿ€D€@b°è& @g”ú  ŠP‡+ÿÿÿÿÿÿÿÿE€@bŸ0\'@g•û  ‹ÿÿÿÿÿÿÿÿ@E€b ðS'@g–pû  Œÿÿÿÿÿÿÿÿ€E€b¡`é&@g—ð" ÿÿÿÿÿÿÿÿÀE€bŽP4' @gø€Û  D`Ê,ÿÿÿÿÿÿÿÿ@PðÛ €b‹P4' @gùðÛ àd" D@‘+ÿÿÿÿÿÿÿÿ€P€b£P4' @gúðÛ  D`’+ÿÿÿÿÿÿÿÿÀP€b¥ ' @gûÐÜ  EpÏ,ÿÿÿÿÿÿÿÿQ°Ý €b¤ ' @gü°Ý àd" E°“+ÿÿÿÿÿÿÿÿ@Q€b¦ ' @gý°Ý  Ep”+ÿÿÿÿÿÿÿÿ€Q€b¨p ' @gþÞ  FP8)ÿÿÿÿÿÿÿÿÀQpß €b§p ' @gÿpß àd" Fð•+ÿÿÿÿÿÿÿÿR€b©p ' @gpß  F°8)ÿÿÿÿÿÿÿÿ@R€b«Ð ' @gPà  GÙ,ÿÿÿÿÿÿÿÿ€R0á €bªÐ ' @g0á àd" G˜+ÿÿÿÿÿÿÿÿÀR€b¬Ð ' @g0á  GÛ,ÿÿÿÿÿÿÿÿS€b® ' @g€â  H°™+ÿÿÿÿÿÿÿÿ@S`ã €b­ ' @g`ã àd" Hpš+ÿÿÿÿÿÿÿÿ€S€b¯ ' @g`ã  H@Þ,ÿÿÿÿÿÿÿÿÀS€b±p ' @g ! IÀß,ÿÿÿÿÿÿÿÿTp !€b¢@' @g˜àû  މ+ÿÿÿÿÿÿÿÿFPü €@bž@' @g™Pü àd" Žž+ÿÿÿÿÿÿÿÿ@F€@b³@' @gšPü  Ž-ÿÿÿÿÿÿÿÿÀF€@b’`'PÜ Ë ð,  ÿÿÿÿÿÿÿÿ$ %µÃ&@g›Àü  ÿÿÿÿÿÿÿÿG€b¶ó&PÜÎ `-  ÿÿÿÿÿÿÿÿ@$À%·ê& @gœ0ý  °Ÿ+ÿÿÿÿÿÿÿÿ@G€b¸`Ð'PÜÐ Ð-  ÿÿÿÿÿÿÿÿ€$%¹pë& @g ý  ‘@ +ÿÿÿÿÿÿÿÿ€G€bºðt'PÜÓ @.  ÿÿÿÿÿÿÿÿÀ$ %»pë& @gžþ  ’Р+ÿÿÿÿÿÿÿÿÀG€b¼Ù&PÜÕ °.  ÿÿÿÿÿÿÿÿ%à%½Ðì& @gŸ€þ  “À -ÿÿÿÿÿÿÿÿH€b¾@ð&PÜØ /  ÿÿÿÿÿÿÿÿ@%€%¿Ã& @g ðþ  ”À¡+ÿÿÿÿÿÿÿÿ€H€bÀÙ&PÜÚ /  ÿÿÿÿÿÿÿÿÀ%À%Áê& @g¡`ÿ  •P¢+ÿÿÿÿÿÿÿÿÀH€bÂ@ð&PÜÝ ðÐ! ÿÿÿÿÿÿÿÿ@&`%Ãpë& @g¢Ð" –à¢+ÿÿÿÿÿÿÿÿI€bÄÙ&PÜß 0  ÿÿÿÿÿÿÿÿÀ& %Åpë& @g£@! —p£+ÿÿÿÿÿÿÿÿ@I€bÆðð&PÜã p0  ÿÿÿÿÿÿÿÿ@'@%ÇÐì& @g¤°! ˜У+ÿÿÿÿÿÿÿÿ€I€bÈ`È&PÜä à0  ÿÿÿÿÿÿÿÿÀ'É`™' @g¥@" ™¤+ÿÿÿÿÿÿÿÿÀI!€bÊÀÑ'PÜæ P1  ÿÿÿÿÿÿÿÿ@( %´`™' @g¦!àd" ™ð¤+ÿÿÿÿÿÿÿÿ@J€bÌ`é&PÜè À1  ÿÿÿÿÿÿÿÿÀ(À %Ë`™' @g§! ™€¥+ÿÿÿÿÿÿÿÿ€Þ€bÎs'PÜê 02  ÿÿÿÿÿÿÿÿ@)` %°p ' @gp !àd" IPœ+ÿÿÿÿÿÿÿÿ@T€bÐ`È&PÜë  2  ÿÿÿÿÿÿÿÿÀ)²p ' @g p ! Iâ,ÿÿÿÿÿÿÿÿ€T€bÒ`È&PÜì 3  ÿÿÿÿÿÿÿÿ@*ÓÐ ' @g à ! JP«+ÿÿÿÿÿÿÿÿÀTP !€bÔ`È&PÜí €3  ÿÿÿÿÿÿÿÿÀ*ÑÐ ' @g P !àd" Jà«+ÿÿÿÿÿÿÿÿU€bÖpÒ'PÜñ ð3  ÿÿÿÿÿÿÿÿ€\ %ÕÐ ' @g P ! Jp¬+ÿÿÿÿÿÿÿÿ@U€bØ`È&PÜò `4  ÿÿÿÿÿÿÿÿÀ\Ù ' @g À ! KЬ+ÿÿÿÿÿÿÿÿ€U0 !€bÚ`È&PÜ ó Ð4  ÿÿÿÿÿÿÿÿ]× ' @g0 !àd" K0­+ÿÿÿÿÿÿÿÿÀU€bÜ`È&PÜ!ô @5  ÿÿÿÿÿÿÿÿ@]Û ' @g0 ! K­+ÿÿÿÿÿÿÿÿV€bÞ`È&PÜ"õ °5  ÿÿÿÿÿÿÿÿ€]ßp ' @g  ! LÀ­+ÿÿÿÿÿÿÿÿ@V !€bàà%'PÜ#û 6  ÿÿÿÿÿÿÿÿÀ] •#Ýp ' @g !àd" L ®+ÿÿÿÿÿÿÿÿ€V€bâà%'PÜ$ 6  ÿÿÿÿÿÿÿÿ^À%áp ' @g ! L€®+ÿÿÿÿÿÿÿÿÀV€bäó&PÜ% 7  ÿÿÿÿÿÿÿÿ@^@%åÐ ' @g€ ! Mà®+ÿÿÿÿÿÿÿÿWð !€bæc'PÜ& p7  ÿÿÿÿÿÿÿÿ€^ãÐ ' @gð !àd" M@¯+ÿÿÿÿÿÿÿÿ@W€bè€ê'PÜ' 2! ÿÿÿÿÿÿÿÿÀ^çÐ ' @gð ! M ¯+ÿÿÿÿÿÿÿÿ€W€bê@t'PÜ( à7  ÿÿÿÿÿÿÿÿ_ë°' @g` ! N°+ÿÿÿÿÿÿÿÿÀW°;"€bìPý&PÜ) P8  ÿÿÿÿÿÿÿÿ@_€%é°' @g°;"àd" N`°+ÿÿÿÿÿÿÿÿX€bîÀy'PÜ* 2! ÿÿÿÿÿÿÿÿ€_ %ð`'PÜ+ 09  ÿÿÿÿÿÿÿÿÀ_`%ñ`é&PÜ,  9  ÿÿÿÿÿÿÿÿ`%í°' @g°;" NÀ°+ÿÿÿÿÿÿÿÿ@X€bÏPÙ' @g¨! š@¦+ÿÿÿÿÿÿÿÿ€Jp!€bó' @gÐ ! O ±+ÿÿÿÿÿÿÿÿ€X@!€bÍPÙ' @g©p!àd" š ¦+ÿÿÿÿÿÿÿÿ@j€bï' @g@!àd" O€±+ÿÿÿÿÿÿÿÿÀX€bôPÙ' @gªp! š€†)ÿÿÿÿÿÿÿÿÀj€bõ' @g@! Oà±+ÿÿÿÿÿÿÿÿY€bø°Ç&@g«à! ›ÿÿÿÿÿÿÿÿ@€bù' @g°! P@²+ÿÿÿÿÿÿÿÿ@Y !€búÉ&@g¬À! œÿÿÿÿÿÿÿÿ€k€b÷' @g !àd" P ²+ÿÿÿÿÿÿÿÿ€Y€bü° ' @g­0! À§+ÿÿÿÿÿÿÿÿl€bû' @g ! P³+ÿÿÿÿÿÿÿÿÀY€bþ`é&@g® ! žÿÿÿÿÿÿÿÿ€l€bÿÀß& @g! Q0³+ÿÿÿÿÿÿÿÿZ!€b  Þ' @g¯! Ÿ€¨+ÿÿÿÿÿÿÿÿ@€!€býÀß& @g !àd" Q³+ÿÿÿÿÿÿÿÿ@Z€bö Þ' @g°€!àd" Ÿà¨+ÿÿÿÿÿÿÿÿ€b Àß& @g!! Qð³+ÿÿÿÿÿÿÿÿ€Z€b  Þ' @g±€! Ÿ@©+ÿÿÿÿÿÿÿÿ€m€b ß& @g"p! RP´+ÿÿÿÿÿÿÿÿÀZà!€b  Þ' @g²ð!   ©+ÿÿÿÿÿÿÿÿn`!€b ß& @g#à!àd" R°´+ÿÿÿÿÿÿÿÿ[€b  Þ' @g³`!àd"  ª+ÿÿÿÿÿÿÿÿ@n€b ß& @g$à! Rµ+ÿÿÿÿÿÿÿÿ@[€b  Þ' @g´`!  `ª+ÿÿÿÿÿÿÿÿ€n€b  á& @g%P! Spµ+ÿÿÿÿÿÿÿÿ€[À!€b ðâ' @gµ`," ¡ «+ÿÿÿÿÿÿÿÿÀn."€b  á& @g&À!àd" Sе+ÿÿÿÿÿÿÿÿÀ[€b ðâ' @g¶."àd" ¡Î+ÿÿÿÿÿÿÿÿo€b  á& @g'À! S0¶+ÿÿÿÿÿÿÿÿ\€b ðâ' @g·." ¡ª(ÿÿÿÿÿÿÿÿ@o€b pÊ& @g( ! T æ*ÿÿÿÿÿÿÿÿ@\€b ÀÉ& @g)€! U ·+ÿÿÿÿÿÿÿÿ€z€b  Ë& @g*ð! V°·+ÿÿÿÿÿÿÿÿ{€b  ' @g+`! W¸+ÿÿÿÿÿÿÿÿ@{Ð!€b  ' @g,Ð!àd" Wp¸+ÿÿÿÿÿÿÿÿ€{€b  ' @g-Ð! Wи+ÿÿÿÿÿÿÿÿÀ{€b p ' @g.ðo X0¹+ÿÿÿÿÿÿÿÿ|@!€b p ' @g/@!àd" X¹+ÿÿÿÿÿÿÿÿ@|€b p ' @g0@! X º+ÿÿÿÿÿÿÿÿ€|€b Ð ' @g1°! YàÛ+ÿÿÿÿÿÿÿÿÀ|!€b Ð ' @g2!àd" Y Ü+ÿÿÿÿÿÿÿÿ}€b Ð ' @g3! Y0Ý+ÿÿÿÿÿÿÿÿ@}€b `ô& @g4! ZÝ+ÿÿÿÿÿÿÿÿ€}p!€b `ô& @g5p!àd" ZðÝ+ÿÿÿÿÿÿÿÿÀ}€b `ô& @g6p! ZPÞ+ÿÿÿÿÿÿÿÿ~€b! °ó& @g7à! [°Þ+ÿÿÿÿÿÿÿÿ@~P!€bò`'PÜ- :  ÿÿÿÿÿÿÿÿ@` %0ë'Ù&PÜ/ `;  ÿÿÿÿÿÿÿÿ€`@%$ ðð&PÜ0 p3! ÿÿÿÿÿÿÿÿÀ`à%% ì'PÜ1 Ð;  ÿÿÿÿÿÿÿÿa`%& @í'PÜ2$ @<  ÿÿÿÿÿÿÿÿ@a %' ðH'PÜ3' °<  ÿÿÿÿÿÿÿÿ€a€%( ðí'PÜ4+ =  ÿÿÿÿÿÿÿÿÀaÀ%) ðí'PÜ5/ =  ÿÿÿÿÿÿÿÿb  %* ðí'PÜ63 >  ÿÿÿÿÿÿÿÿ@bà!%+ ðí'PÜ77 p>  ÿÿÿÿÿÿÿÿ€bÀ#%, pþ'PÜ8; P4! ÿÿÿÿÿÿÿÿÀb %%-  ÿ'PÜ9> à>  ÿÿÿÿÿÿÿÿc (%. °®'PÜ:A P?  ÿÿÿÿÿÿÿÿ@c`)%/ Ðÿ'PÜ;E À?  ÿÿÿÿÿÿÿÿ€cÀí# °' @g¸Ð! ¢ Ï+ÿÿÿÿÿÿÿÿ€o@!€b0 €(PÜ<H À4! ÿÿÿÿÿÿÿÿÀcà+% °' @g¹@!àd" ¢€Ï+ÿÿÿÿÿÿÿÿÀo€b2 °®'PÜ=K 0@  ÿÿÿÿÿÿÿÿd -%1 °' @gº@! ¢àÏ+ÿÿÿÿÿÿÿÿp€b5 °' @g»°! £ð­(ÿÿÿÿÿÿÿÿ@p !€bð0d(àõ-} Ђ ÿÿÿÿÿÿÿÿ‚ à#3 °' @g¼ !àd" £pÐ+ÿÿÿÿÿÿÿÿ€p€b6 °' @g½ ! £Я(ÿÿÿÿÿÿÿÿÀ €b9 Ð9' @g¾! ¤`Ñ+ÿÿÿÿÿÿÿÿÀp€6!€b8 Ð9' @g¿€6!àd" ¤ÀÑ+ÿÿÿÿÿÿÿÿq€b: Ð9' @gÀ€6! ¤ Ò+ÿÿÿÿÿÿÿÿ@q€b< Pý& @gÁð6! ¥€Ò+ÿÿÿÿÿÿÿÿ€q`7!€b; Pý& @gÂ`7!àd" ¥Ó+ÿÿÿÿÿÿÿÿÀq€b= Pý& @gÃ`7! ¥ Ó+ÿÿÿÿÿÿÿÿr€b? ` ' @gÄÐ7! ¦Ô+ÿÿÿÿÿÿÿÿ@r€b@ ' @gÅ@8! §`Ô+ÿÿÿÿÿÿÿÿ€r€bA ðû&@gư8! ¨ÿÿÿÿÿÿÿÿÀr€bB `é& @gÇ 9! ©ðÔ+ÿÿÿÿÿÿÿÿs:!€b °ó& @g8P!àd" [ß+ÿÿÿÿÿÿÿÿ€~€b" °ó& @g9P! [pß+ÿÿÿÿÿÿÿÿÀ~€bE õ& @g:À! \à+ÿÿÿÿÿÿÿÿàH!€bD õ& @g;àH!àd" \0à+ÿÿÿÿÿÿÿÿ@€bF õ& @g<àH! \à+ÿÿÿÿÿÿÿÿ€€bH pÊ& @g=PI! ]@Ä(ÿÿÿÿÿÿÿÿÀ€bI ÀÉ& @g>° ^€á+ÿÿÿÿÿÿÿÿ€€bJ  Ë& @g?ÀI! _â+ÿÿÿÿÿÿÿÿ@€€bK Àß& @g@ J! ` â+ÿÿÿÿÿÿÿÿ€€K!€bG Àß& @gAK!àd" `ã+ÿÿÿÿÿÿÿÿÀ€€bL Àß& @gBK! ``ã+ÿÿÿÿÿÿÿÿ€bN ß& @gC€K! aÀã+ÿÿÿÿÿÿÿÿ@`L!€bM ß& @gD`L!àd" a ä+ÿÿÿÿÿÿÿÿ€€bO ß& @gE`L! a€ä+ÿÿÿÿÿÿÿÿÀ€bQ  á& @gF`  bðË(ÿÿÿÿÿÿÿÿ‚ÐL!€bP  á& @gGÐL!àd" bå+ÿÿÿÿÿÿÿÿ@‚€b> `é& @gÈ:!àd" ©€Õ+ÿÿÿÿÿÿÿÿ@s€bC `é& @gÉ:! ©Ö+ÿÿÿÿÿÿÿÿ€s€bU Àê& @gÊà:! ªpÖ+ÿÿÿÿÿÿÿÿ€P;!€bT Àê& @gËP;!àd" ª×+ÿÿÿÿÿÿÿÿÀs€bV Àê& @gÌP;! ªp»(ÿÿÿÿÿÿÿÿt€bX Àê& @gÍÀ;! « Ø+ÿÿÿÿÿÿÿÿ@t !€b] `È& @gÔ`>!àd" ­PÛ+ÿÿÿÿÿÿÿÿv€b_ `È& @gÕ`>! ­0¼(ÿÿÿÿÿÿÿÿ@v€ba À&@gÖÐ>! ®ÿÿÿÿÿÿÿÿ€v€bb ðû&@g×°?! ¯ÿÿÿÿÿÿÿÿ€€bR  á& @gHÐL! bpå+ÿÿÿÿÿÿÿÿ€‚€bc `æ' @gØ @! °`,ÿÿÿÿÿÿÿÿÀv@!€bd Àß& @gI@M! cÐå+ÿÿÿÿÿÿÿÿÀ‚°M!€b` `æ' @gÙ@!àd" °À,ÿÿÿÿÿÿÿÿw€bS Àß& @gJ°M!àd" c0æ+ÿÿÿÿÿÿÿÿƒ€be `æ' @gÚ@! ° ,ÿÿÿÿÿÿÿÿ@w€bf Àß& @gK°M! cÎ(ÿÿÿÿÿÿÿÿ@ƒ€bi °Ý& @gÛA! ±°,ÿÿÿÿÿÿÿÿ€wpA!€bj ß& @gL N! dÀæ+ÿÿÿÿÿÿÿÿ€ƒN!€bg °Ý& @gÜpA!àd" ±@,ÿÿÿÿÿÿÿÿÀw€bh ß& @gMN!àd" d ç+ÿÿÿÿÿÿÿÿÀƒ€bk °Ý& @gÝpA! ±Ð,ÿÿÿÿÿÿÿÿx€bl ß& @gNN! d€ç+ÿÿÿÿÿÿÿÿ„€bo àù&@gÞàA! ²ÿÿÿÿÿÿÿÿ@x€bp  á& @gOpO! eàç+ÿÿÿÿÿÿÿÿ@„àO!€bq `ô& @gßPB! ³,ÿÿÿÿÿÿÿÿ€xÀB!€bn  á& @gPàO!àd" e@è+ÿÿÿÿÿÿÿÿ€„€bm `ô& @gàÀB!àd" ³ ,ÿÿÿÿÿÿÿÿÀx€br  á& @gQàO! e è+ÿÿÿÿÿÿÿÿÀ„€bs `ô& @gáÀB! ³°,ÿÿÿÿÿÿÿÿy€bv p' @gRPP! fé+ÿÿÿÿÿÿÿÿ…0Q!€bw °ó& @gâ0C! ´@ ,ÿÿÿÿÿÿÿÿ@y C!€bt p' @gS0Q!àd" f`é+ÿÿÿÿÿÿÿÿ@…€bu °ó& @gã C!àd" ´Ð ,ÿÿÿÿÿÿÿÿ€y€bx p' @gT0Q! fÀé+ÿÿÿÿÿÿÿÿ€…€by °ó& @gä C! ´` ,ÿÿÿÿÿÿÿÿÀ€b| À' @gU Q! g0Î(ÿÿÿÿÿÿÿÿÀ…€R!€b} õ& @gåD! µð ,ÿÿÿÿÿÿÿÿÀy€D!€bz À' @gV€R!àd" g€ê+ÿÿÿÿÿÿÿÿ†€b{ õ& @gæ€D!àd" µ€ ,ÿÿÿÿÿÿÿÿz€b~ À' @gW€R! gàê+ÿÿÿÿÿÿÿÿ@†€b õ& @gç€D! µ ,ÿÿÿÿÿÿÿÿ@z€b‚  ' @gX`S! h@ë+ÿÿÿÿÿÿÿÿ€†ÐS!€b€  ' @gYÐS!àd" h ë+ÿÿÿÿÿÿÿÿÀ†€b„  ' @gZÐS! h ,ÿÿÿÿÿÿÿÿ@‡€b4 °®'PÜ>N  @  ÿÿÿÿÿÿÿÿ@d`.%† pö& @g[@T! iÀ,ÿÿÿÿÿÿÿÿ€‡€b‡ °®'PÜ?Q  5! ÿÿÿÿÿÿÿÿ€d /%ˆ Àõ& @g\U! j€,ÿÿÿÿÿÿÿÿÀ‡€b‰ 0(PÜ@V A  ÿÿÿÿÿÿÿÿÀdà0%Š  ÷& @g]V! k@,ÿÿÿÿÿÿÿÿˆ€b‹ à(PÜAZ €A  ÿÿÿÿÿÿÿÿe`3%Œ  ' @g^àV! l ,ÿÿÿÿÿÿÿÿ@ˆPW!€b à(PÜB^ ðA  ÿÿÿÿÿÿÿÿ@e@5%…  ' @g_PW!àd" l,ÿÿÿÿÿÿÿÿ€ˆ€b (PÜCc ÐB  ÿÿÿÿÿÿÿÿ€e <%Ž  ' @g`PW! l`,ÿÿÿÿÿÿÿÿÀˆ€b‘ @(PÜDf °C  ÿÿÿÿÿÿÿÿÀe >%’ ð' @gaÀW! mÀ,ÿÿÿÿÿÿÿÿ‰0X!€b“ °®'PÜEi E  ÿÿÿÿÿÿÿÿfà?% ð' @gb0X!àd" m ,ÿÿÿÿÿÿÿÿ@‰€b•  &PÜGs àE  ÿÿÿÿÿÿÿÿ@f ü#” ð' @gc0X! m€,ÿÿÿÿÿÿÿÿ€‰€b— ð(PÜHy ÀF  ÿÿÿÿÿÿÿÿ€f F%˜ P' @gd X! n°,ÿÿÿÿÿÿÿÿÀ‰Y!€b™ `'PÜI{ p:! ÿÿÿÿÿÿÿÿÀf@I%– P' @geY!àd" n,ÿÿÿÿÿÿÿÿŠ€b› `'PÜJ} H  ÿÿÿÿÿÿÿÿgàI%š P' @gfY! np,ÿÿÿÿÿÿÿÿ@Š€b `'PÜK ðH  ÿÿÿÿÿÿÿÿ@g€J%ž pö& @ggðY! o0,ÿÿÿÿÿÿÿÿ€Š€bŸ  (PÜLƒ ÐI  ÿÿÿÿÿÿÿÿ€g K%¡ P(PÜM… °J  ÿÿÿÿÿÿÿÿÀgM%¢ `'PÜN‡ K  ÿÿÿÿÿÿÿÿh M%  Àõ& @ghÐZ! pÀ,ÿÿÿÿÿÿÿÿÀŠ€bƒ Ã& @gè`E! ¶  ,ÿÿÿÿÿÿÿÿÀzÐE!€b¤  ÷& @gi@[! q€,ÿÿÿÿÿÿÿÿÀŒ€b Ã& @géÐE!àd" ¶0 ,ÿÿÿÿÿÿÿÿ@€b¦ Àß& @gj°[! rà,ÿÿÿÿÿÿÿÿ]!€b¥ Ã& @gêÐE! ¶ ,ÿÿÿÿÿÿÿÿÀ€bœ Àß& @gk]!àd" r@,ÿÿÿÿÿÿÿÿ€€b© °ó& @gë@F! · ,ÿÿÿÿÿÿÿÿ@Ž G!€b¨ Àß& @gl]! r ,ÿÿÿÿÿÿÿÿŽ€b§ °ó& @gì G!àd" ·°,ÿÿÿÿÿÿÿÿÀŽ€b¬ ß& @gmy! s,ÿÿÿÿÿÿÿÿ€Žpy!€b« °ó& @gí G! ·@,ÿÿÿÿÿÿÿÿ@€bª ß& @gnpy!àd" s`,ÿÿÿÿÿÿÿÿ€b¯ õ& @gîG! ¸Ð,ÿÿÿÿÿÿÿÿÀH!€b® ß& @gopy! sÀ,ÿÿÿÿÿÿÿÿ€€b­ õ& @gïH!àd" ¸`,ÿÿÿÿÿÿÿÿ@€b²  á& @gpPz! tð,ÿÿÿÿÿÿÿÿ0{!€b± õ& @gðH! ¸ð,ÿÿÿÿÿÿÿÿÀ€b°  á& @gq0{!àd" tP,ÿÿÿÿÿÿÿÿ€€bµ Ã& @gñpH! ¹€,ÿÿÿÿÿÿÿÿ@‘ày!€b´  á& @gr0{! t°,ÿÿÿÿÿÿÿÿ‘€b³ Ã& @gòày!àd" ¹,ÿÿÿÿÿÿÿÿÀ‘€b¸ €ø& @gs|! up,ÿÿÿÿÿÿÿÿ€‘€b· Ã& @góày! ¹Ð,ÿÿÿÿÿÿÿÿ@’€bº Ð÷& @gt€|! v,ÿÿÿÿÿÿÿÿ’€b» °ó& @gôÀz! º`:,ÿÿÿÿÿÿÿÿÀ’ {!€b¼ 0ù& @gu`}! wÀ,ÿÿÿÿÿÿÿÿ€’€b¹ °ó& @gõ {!àd" º€;,ÿÿÿÿÿÿÿÿ@“€b¾ €ø& @gv@~! xP ,ÿÿÿÿÿÿÿÿ“€b½ °ó& @gö {! º<,ÿÿÿÿÿÿÿÿÀ“€bÀ Ð÷& @gw°~! y!,ÿÿÿÿÿÿÿÿ€“€bÁ õ& @g÷½ » <,ÿÿÿÿÿÿÿÿ@”ð|!€b 0ù& @gx! z !,ÿÿÿÿÿÿÿÿ”€bÄ €ø& @gyp€! { J,ÿÿÿÿÿÿÿÿ€”P!€b¶ €ø& @gzP!àd" {°J,ÿÿÿÿÿÿÿÿ•€b£ `'PÜO‰ L  ÿÿÿÿÿÿÿÿ@h@N%Å €ø& @g{P! {K,ÿÿÿÿÿÿÿÿ€•€bÇ °®'PÜPŒ àL  ÿÿÿÿÿÿÿÿ€hàN%È Ð÷& @g| ‚! |pK,ÿÿÿÿÿÿÿÿ–€ƒ!€bÉ `'PÜQŽ 0N  ÿÿÿÿÿÿÿÿÀhÀP%Æ Ð÷& @g}€ƒ!àd" |ÐK,ÿÿÿÿÿÿÿÿ€–€bË `'PÜR O  ÿÿÿÿÿÿÿÿi`Q%Ê Ð÷& @g~€ƒ! |0L,ÿÿÿÿÿÿÿÿ—€bÍ ð(PÜS” ðO  ÿÿÿÿÿÿÿÿ@iR%Î 0ù& @g`„! }L,ÿÿÿÿÿÿÿÿ€—@…!€bÏ  (PÜT— ÐP  ÿÿÿÿÿÿÿÿ€iàS%Ì 0ù& @g€@…!àd" }ðL,ÿÿÿÿÿÿÿÿ˜€bÑ P(PÜU› °F! ÿÿÿÿÿÿÿÿÀi U%Ð 0ù& @g@…! }PM,ÿÿÿÿÿÿÿÿ€˜€bÓ (PÜVŸ R  ÿÿÿÿÿÿÿÿjW%Ô €ø& @g‚ †! ~°M,ÿÿÿÿÿÿÿÿ™†!€bÕ |&PÜW¢ S  ÿÿÿÿÿÿÿÿ€j€Y%Ò €ø& @gƒ†!àd" ~N,ÿÿÿÿÿÿÿÿ€™€b× €E'PÜX¤ àS  ÿÿÿÿÿÿÿÿkÀZ%Ö €ø& @g„†! ~pN,ÿÿÿÿÿÿÿÿš€bÙ ð(PÜY¨ 0J! ÿÿÿÿÿÿÿÿ@k€Ã$Ú Ð÷& @g…p‡! p+ÿÿÿÿÿÿÿÿ€šPˆ!€bÛ °®'PÜZ« 0U  ÿÿÿÿÿÿÿÿÀkÀÉ$Ø Ð÷& @g†Pˆ!àd" O,ÿÿÿÿÿÿÿÿ›€bÝ ó&PÜ[® V  ÿÿÿÿÿÿÿÿ@l@]%Ü Ð÷& @g‡Pˆ! `O,ÿÿÿÿÿÿÿÿ€›€bß `'PÜ\° ðV  ÿÿÿÿÿÿÿÿÀl€^%¿ õ& @gøð|!àd" »0=,ÿÿÿÿÿÿÿÿÀ”€bá Ðÿ'PÜ]´ ÐW  ÿÿÿÿÿÿÿÿm _%à õ& @gùð|! »PM)ÿÿÿÿÿÿÿÿ@•€bã €(PÜ^· @X  ÿÿÿÿÿÿÿÿ@m``%ä Ã& @gúÐ}! ¼ >,ÿÿÿÿÿÿÿÿÀ•€bæ Ã& @gûР½°>,ÿÿÿÿÿÿÿÿ@–€bç Ã& @gü ! ¾p?,ÿÿÿÿÿÿÿÿÀ–€bè Ã& @gý€! ¿@,ÿÿÿÿÿÿÿÿ@—€bé Ã& @gþà€! À@,ÿÿÿÿÿÿÿÿÀ—€bê Ã& @gÿÀ! Á A,ÿÿÿÿÿÿÿÿ@˜€bë °Ý& @gƒ! €A,ÿÿÿÿÿÿÿÿÀ˜ðƒ!€bâ °Ý& @gðƒ!àd" ÂB,ÿÿÿÿÿÿÿÿ@™€bì °Ý& @gðƒ!  B,ÿÿÿÿÿÿÿÿÀ™€bî `Þ& @gЄ! Ã0C,ÿÿÿÿÿÿÿÿ@š°…!€bí `Þ& @g°…!àd" ÃÀC,ÿÿÿÿÿÿÿÿÀš€bï `Þ& @g°…! ÃPD,ÿÿÿÿÿÿÿÿ@›€bñ €' @gÒ ÄàD,ÿÿÿÿÿÿÿÿÀ›€bò °è& @g‡! ÅpE,ÿÿÿÿÿÿÿÿ@œà€@bà 0ù& @gˆÀˆ! €O,ÿÿÿÿÿÿÿÿœ ‰!€bð °è& @gààd" ÅF,ÿÿÿÿÿÿÿÿÀœ€@bÞ 0ù& @g‰ ‰!àd" €ðO,ÿÿÿÿÿÿÿÿ€œ€bó °è& @g à ÅF,ÿÿÿÿÿÿÿÿ@€@bô 0ù& @gŠ ‰! €Àd)ÿÿÿÿÿÿÿÿ€b÷ ðS'@g à‡! ÆÿÿÿÿÿÿÿÿÀ€bå  (PÜ_º Y  ÿÿÿÿÿÿÿÿÀm a%ø Àß& @g‹€Š! €P,ÿÿÿÿÿÿÿÿ€ðŠ!€bù ê& @g @Ø ÇPG,ÿÿÿÿÿÿÿÿ@ž€bú Ày'PÜ`¾ Z  ÿÿÿÿÿÿÿÿ€¯àÿ#ö Àß& @gŒðŠ!àd" àP,ÿÿÿÿÿÿÿÿž€bü pë& @g 0‰! È Z)ÿÿÿÿÿÿÿÿÀž€bý `'PÜaÀ ðR! ÿÿÿÿÿÿÿÿÀ¯€$û Àß& @gðŠ! @Q,ÿÿÿÿÿÿÿÿ€ž€bÿ pë& @g Š! É@H,ÿÿÿÿÿÿÿÿ@Ÿ€b °(PÜbà P[  ÿÿÿÿÿÿÿÿ°€c% Àß& @gŽЋ! ‚ Q,ÿÿÿÿÿÿÿÿŸ°Œ!€b Ðì& @g€Ý ÊÐH,ÿÿÿÿÿÿÿÿÀŸ€b Ày'PÜcÇ 0\  ÿÿÿÿÿÿÿÿ@° d%þ Àß& @g°Œ!àd" ‚R,ÿÿÿÿÿÿÿÿ€Ÿ€b ê& @g`‹! Ë`I,ÿÿÿÿÿÿÿÿ@ €b `'PÜdÉ ]  ÿÿÿÿÿÿÿÿ€°`e% Àß& @g°Œ! ‚`R,ÿÿÿÿÿÿÿÿ €b pë& @g@Œ! ÌðI,ÿÿÿÿÿÿÿÿÀ €b °(PÜeÌ ð]  ÿÿÿÿÿÿÿÿÀ°`$ ß& @g‘! ƒÀR,ÿÿÿÿÿÿÿÿ€ pŽ!€b pë& @gPâ ÍÀX,ÿÿÿÿÿÿÿÿ@¡€b ó&PÜfÏ Ð^  ÿÿÿÿÿÿÿÿ± f% ß& @g’pŽ!àd" ƒpi)ÿÿÿÿÿÿÿÿ¡€b Ðì& @gŽ! ÎPY,ÿÿÿÿÿÿÿÿÀ¡€b Ày'PÜgÓ @_  ÿÿÿÿÿÿÿÿ@±@g% ß& @g“pŽ! ƒPS,ÿÿÿÿÿÿÿÿ€¡€b V'@gàŽ! ϰY,ÿÿÿÿÿÿÿÿ@¢€b `'PÜhÕ `  ÿÿÿÿÿÿÿÿ€± i%  á& @g”P! „ i)ÿÿÿÿÿÿÿÿ¢À!€b àù& @gè Ð@Z,ÿÿÿÿÿÿÿÿÀ¢€b `'PÜi× `  ÿÿÿÿÿÿÿÿÀ±Ài%  á& @g•À!àd" „°S,ÿÿÿÿÿÿÿÿ€¢€b À&@g0! Ñÿÿÿÿÿÿÿÿ@£€b P(PÜjÙ a  ÿÿÿÿÿÿÿÿ² $  á& @g–À! „+ÿÿÿÿÿÿÿÿ£€b ðS'@g‘! ÒÿÿÿÿÿÿÿÿÀ£€b P(PÜkÛ pa  ÿÿÿÿÿÿÿÿ@²`j% Àß& @g— ! …j)ÿÿÿÿÿÿÿÿ€£€‘!€b €í&@g`ì Óÿÿÿÿÿÿÿÿ@¤€b  I'PÜlÞ àa  ÿÿÿÿÿÿÿÿ€²k% Àß& @g˜€‘!àd" …pT,ÿÿÿÿÿÿÿÿ¤€b!  +(PÜmã Pb  ÿÿÿÿÿÿÿÿÀ² k% Àß& @g™€‘! …p+ÿÿÿÿÿÿÿÿ€¤€b# P(PÜnç Àb  ÿÿÿÿÿÿÿÿ³ n%$ ß& @gšð‘! †U,ÿÿÿÿÿÿÿÿ¥Ð’!€b" ß& @g›Ð’!àd" †`U,ÿÿÿÿÿÿÿÿ€¥€b& ß& @gœÐ’! †0j)ÿÿÿÿÿÿÿÿ¦€b(  á& @g°“! ‡ÀU,ÿÿÿÿÿÿÿÿ€¦ ”!€b'  á& @gž ”!àd" ‡ V,ÿÿÿÿÿÿÿÿ§€b)  á& @gŸ ”! ‡€V,ÿÿÿÿÿÿÿÿ€§€b+ Àß& @g °¨! ˆ`j)ÿÿÿÿÿÿÿÿ¨©!€b* Àß& @g¡©!àd" ˆW,ÿÿÿÿÿÿÿÿ€¨€b, Àß& @g¢©! ˆpW,ÿÿÿÿÿÿÿÿ©€b. ß& @g£ª! ‰ n,ÿÿÿÿÿÿÿÿ€©pª!€b- ß& @g¤pª!àd" ‰°n,ÿÿÿÿÿÿÿÿª€b/ ß& @g¥pª! ‰po,ÿÿÿÿÿÿÿÿ€ª€b1  á& @g¦àª! Šp,ÿÿÿÿÿÿÿÿ«P«!€b0  á& @g§P«!àd" Šðp,ÿÿÿÿÿÿÿÿ€«€b PU'@g`’! ÔÿÿÿÿÿÿÿÿÀ¤€b4  ( @g@“! ÕÀ[,ÿÿÿÿÿÿÿÿ@¥ €bõ  ( @g àd" Õ \,ÿÿÿÿÿÿÿÿÀ¥€b5  ( @g  Õ€\,ÿÿÿÿÿÿÿÿ@¦€b7 €( @g ñ Öp],ÿÿÿÿÿÿÿÿÀ¦€b6 €( @gàd" ÖÐ],ÿÿÿÿÿÿÿÿ@§€b8 €( @g Ö`^,ÿÿÿÿÿÿÿÿÀ§€b: Ç& @g”! ×ð^,ÿÿÿÿÿÿÿÿ@¨€b; Ç&@g •! ØÿÿÿÿÿÿÿÿÀ¨€b< €'@g!p¸! Ùÿÿÿÿÿÿÿÿ@©€b= Ý&@g"à¸! ÚÿÿÿÿÿÿÿÿÀ©€b>  ü&@g#P¹! Ûÿÿÿÿÿÿÿÿ@ª€b? PU'@g$À¹! ÜÿÿÿÿÿÿÿÿÀª€b@ `È& @g%0º! Ý `,ÿÿÿÿÿÿÿÿ@«€€bA `È& @g& º! Þ0a,ÿÿÿÿÿÿÿÿÀ«€€bB Pý& @g'»! ßða,ÿÿÿÿÿÿÿÿ@¬€»!€b2  á& @g¨P«! Šàq,ÿÿÿÿÿÿÿÿ¬€bC Pý& @g(€»! ߀b,ÿÿÿÿÿÿÿÿ€¬€bD Àß& @g©0¬! ‹s,ÿÿÿÿÿÿÿÿ@¿ ¬!€bE Pý& @g)ð»! àc,ÿÿÿÿÿÿÿÿÀ¿`¼!€b3 Àß& @gª ¬!àd" ‹Às,ÿÿÿÿÿÿÿÿ€¿€bG Pý& @g*`¼! à c,ÿÿÿÿÿÿÿÿ@À€bF Àß& @g« ¬! ‹€t,ÿÿÿÿÿÿÿÿÀ€bI þ& @g+м! æ0d,ÿÿÿÿÿÿÿÿÀÀ€€bJ ß& @g¬­! Œu,ÿÿÿÿÿÿÿÿ€À€­!€bK 0( @g,@½! çÀd,ÿÿÿÿÿÿÿÿ@Á°£€bH ß& @g­€­!àd" Œ u,ÿÿÿÿÿÿÿÿÁ€bM 0( @g-°£ ç e,ÿÿÿÿÿÿÿÿÀÁ€bL ß& @g®€­! Œ0v,ÿÿÿÿÿÿÿÿ€Á€bO 0( @g.°½! è€e,ÿÿÿÿÿÿÿÿ@ ¾!€bP  á& @g¯ð­! Àv,ÿÿÿÿÿÿÿÿÂ`®!€bQ 0( @g/ ¾! èàe,ÿÿÿÿÿÿÿÿÀ€bN  á& @g°`®!àd" Pw,ÿÿÿÿÿÿÿÿ€Â€bS 0( @g00§ é@f,ÿÿÿÿÿÿÿÿ@þ!€bR  á& @g±`®! x,ÿÿÿÿÿÿÿÿÀbU 0( @g1¾! é f,ÿÿÿÿÿÿÿÿÀÀbV ß& @g²Ю! Ž x,ÿÿÿÿÿÿÿÿ€Ã@¯!€bW à( @g2¿! êŽ,ÿÿÿÿÿÿÿÿ@Ä «€bT ß& @g³@¯!àd" Ž`y,ÿÿÿÿÿÿÿÿÄ€bY à( @g3 « êðŽ,ÿÿÿÿÿÿÿÿÀÄ€bX ß& @g´@¯! Ž z,ÿÿÿÿÿÿÿÿ€Ä€b[ @å& @g4p¿! ëP,ÿÿÿÿÿÿÿÿ@Åà¿!€b\  á& @gµ°¯! °z,ÿÿÿÿÿÿÿÿÅ °!€b] @å& @g5à¿! ë°,ÿÿÿÿÿÿÿÿ@€€bZ  á& @g¶ °!àd" p{,ÿÿÿÿÿÿÿÿ€Å€b_ @å& @g6P! ì,ÿÿÿÿÿÿÿÿÆPÀ!€b^  á& @g· °! 0|,ÿÿÿÿÿÿÿÿÀÅ€ba @å& @g7PÀ! ì@,ÿÿÿÿÿÿÿÿ€Æ€b% €E'PÜÕé 0‚! ÿÿÿÿÿÿÿÿ@³`o%d `'PÜÖë ÀŒ  ÿÿÿÿÿÿÿÿ€³p%e `'PÜ×í 0  ÿÿÿÿÿÿÿÿÀ³ p%f `'PÜØï    ÿÿÿÿÿÿÿÿ´@q%g `'PÜÙñ Ž  ÿÿÿÿÿÿÿÿ@´àq%h `'PÜÚó €Ž  ÿÿÿÿÿÿÿÿ€´`t%i `'PÜÛõ ðŽ  ÿÿÿÿÿÿÿÿÀ´ u%j `'PÜÜ÷ `  ÿÿÿÿÿÿÿÿµàv%k `'PÜÝù Ð  ÿÿÿÿÿÿÿÿ@µ x%l Ç&PÜÞú @  ÿÿÿÿÿÿÿÿ€µm Ç&PÜßû °  ÿÿÿÿÿÿÿÿÀµn Ð+(PÜàý ‘  ÿÿÿÿÿÿÿÿ¶`y%o `È&PÜâþ ‘  ÿÿÿÿÿÿÿÿ@¶p `È&PÜãÿ ’  ÿÿÿÿÿÿÿÿ€¶b pö& @g¸±! ð|,ÿÿÿÿÿÿÿÿ@Æp±!€bq `é&PÜäp’  ÿÿÿÿÿÿÿÿÀ¶ z%` pö& @g¹p±!àd" °},ÿÿÿÿÿÿÿÿÀÆ€bs `È&PÜåà’  ÿÿÿÿÿÿÿÿ·r pö& @gºp±! @~,ÿÿÿÿÿÿÿÿ@Ç€bv Àõ& @g»€Œ ‘,ÿÿÿÿÿÿÿÿÀÇà±!€bt Àõ& @g¼à±!àd" ‘À,ÿÿÿÿÿÿÿÿ@È€bw Àõ& @g½à±! ‘€€,ÿÿÿÿÿÿÿÿÀÈ€by  ÷& @g¾P²! ’à€,ÿÿÿÿÿÿÿÿÉÀ²!€bx  ÷& @g¿À²!àd" ’ ,ÿÿÿÿÿÿÿÿ€É€bz  ÷& @gÀÀ²! ’`‚,ÿÿÿÿÿÿÿÿÊ€b| pö& @gÁ0³! “ ƒ,ÿÿÿÿÿÿÿÿ€Ê ³!€b{ pö& @g ³!àd" “àƒ,ÿÿÿÿÿÿÿÿÀÊ€b} pö& @gà³! “ „,ÿÿÿÿÿÿÿÿ@Ë€b Àõ& @gÄ ”…,ÿÿÿÿÿÿÿÿÀË´!€b~ Àõ& @gÅ´!àd" ”À…,ÿÿÿÿÿÿÿÿ@Ì€b€ Àõ& @gÆ´! ”€†,ÿÿÿÿÿÿÿÿÀÌ€b‚  ÷& @gÇ€´! •@‡,ÿÿÿÿÿÿÿÿ@Íð´!€b  ÷& @gÈð´!àd" •Ї,ÿÿÿÿÿÿÿÿÀÍ€bƒ  ÷& @gÉð´! •ˆ,ÿÿÿÿÿÿÿÿ@΀bà8(À·-, Ð ÿÿÿÿÿÿÿÿ€á€|%… 0' @gÊ`µ! – ‰,ÿÿÿÿÿÿÿÿÀÎе!€b† à8(À·-ž. ° ÿÿÿÿÿÿÿÿâÀ}%„ 0' @gËе!àd" –à‰,ÿÿÿÿÿÿÿÿ@Ï€bˆ D(À·-Ÿ1  ÿÿÿÿÿÿÿÿ€â%‡ 0' @gÌе! – Š,ÿÿÿÿÿÿÿÿÀÏ€bŠ @E(À·- 3 `å ÿÿÿÿÿÿÿÿã€%‹ €' @gÍð“ —0‹,ÿÿÿÿÿÿÿÿÐ@¶!€bŒ @E(À·-¡5 p ÿÿÿÿÿÿÿÿ€ãÀ‚%‰ €' @gÎ@¶!àd" —Й,ÿÿÿÿÿÿÿÿ€Ð€bŽ ðE(À·-¢8 P ÿÿÿÿÿÿÿÿä„% €' @gÏ@¶! —Põ)ÿÿÿÿÿÿÿÿÑ€b à8(À·-Ã: @! ÿÿÿÿÿÿÿÿ€ä€†%‘ à' @gа¶! ˜`š,ÿÿÿÿÿÿÿÿ€Ñ ·!€b’ PG(À·-Ä= °! ÿÿÿÿÿÿÿÿåÀ‡% à' @gÑ ·!àd" ˜Àš,ÿÿÿÿÿÿÿÿÒ€b” H( À·-Å? " ÿÿÿÿÿÿÿÿ€å@Š%“ à' @gÒ ·! ˜ ›,ÿÿÿÿÿÿÿÿ€Ò€b– H( À·-ÆA " ÿÿÿÿÿÿÿÿ怋%— à\' @gÓ·! ™à›,ÿÿÿÿÿÿÿÿÀÒ€b˜ à8(À·-ÈC # ÿÿÿÿÿÿÿÿ€æÀŒ%™ ]' @gÔ¸! špœ,ÿÿÿÿÿÿÿÿ@Ó€bš `I( À·-ÎE p# ÿÿÿÿÿÿÿÿçŽ%› @^' @gÕÀã! ›0,ÿÿÿÿÿÿÿÿÀÓ€bœ `I( À·-ÏG à# ÿÿÿÿÿÿÿÿ€ç@% à\' @gÖ0ä! œÀ,ÿÿÿÿÿÿÿÿ@Ô€bž H( À·-ÐI `9 ÿÿÿÿÿÿÿÿèÀ‘%Ÿ ]' @g×å! Pž,ÿÿÿÿÿÿÿÿÀÔ€b   L(À·-âN  % ÿÿÿÿÿÿÿÿ€è`’%¢ °¼&À·-äR & ÿÿÿÿÿÿÿÿéà”%c @å& @g8ÀÀ! í ,ÿÿÿÿÿÿÿÿÇ ®€b¤ @å& @g9 ® í‘,ÿÿÿÿÿÿÿÿ€Ç€b¥ @:( @g:0Á! î`‘,ÿÿÿÿÿÿÿÿÈ Á!€bu `È&PÜæP“  ÿÿÿÿÿÿÿÿ@·¦ @:( @g; Á! îÀ‘,ÿÿÿÿÿÿÿÿ€È€b§ `È&PÜçÀ“  ÿÿÿÿÿÿÿÿ€·¨ @:( @g<Â! ï ’,ÿÿÿÿÿÿÿÿ€€€Â!€b© ðt'PÜè0”  ÿÿÿÿÿÿÿÿÀ·à{%ª @:( @g=€Â! ïPö+ÿÿÿÿÿÿÿÿ@É€b« pë&PÜê  ”  ÿÿÿÿÿÿÿÿ¸`~%¬  ;( @g>ðÂ! ð“,ÿÿÿÿÿÿÿÿÀÉ`Ã!€b­ pë&PÜë p•! ÿÿÿÿÿÿÿÿ@¸ %®  ;( @g?`Ã! ðp“,ÿÿÿÿÿÿÿÿ@Ê€b¯ pë&PÜì •  ÿÿÿÿÿÿÿÿ€¸à€%° =( @g@ÐÃ! ñ”,ÿÿÿÿÿÿÿÿÀ€@Ä!€b± `È&PÜ퀕  ÿÿÿÿÿÿÿÿÀ¸² =( @gA@Ä! ñ`”,ÿÿÿÿÿÿÿÿË€b³ pë&PÜîð•  ÿÿÿÿÿÿÿÿ¹ ‚%´ À?( @gB0! òðÙ)ÿÿÿÿÿÿÿÿ€Ë°Ä!€bµ P<(PÜï`–  ÿÿÿÿÿÿÿÿ@¹`ƒ%¶ À?( @gC°Ä! ò€•,ÿÿÿÿÿÿÿÿÌ€b· °=(PÜðЖ  ÿÿÿÿÿÿÿÿ€¹¸ ÐA( @gD Å! ó@–,ÿÿÿÿÿÿÿÿ€Ì ä!€b¹ °=(PÜñ@—  ÿÿÿÿÿÿÿÿÀ¹º ÐA( @gE ä! ó –,ÿÿÿÿÿÿÿÿÍ€b» ðt'PÜõ°—  ÿÿÿÿÿÿÿÿº ‡%¼ ðÚ&@gF€å! ôÿÿÿÿÿÿÿÿ€ÍÐæ!€b½ ?(PÜö ˜  ÿÿÿÿÿÿÿÿ@º¾ ðÚ&@gGÐæ! ôÿÿÿÿÿÿÿÿ΀b¿ `È&PÜøp™  ÿÿÿÿÿÿÿÿ€ºÁ Ày'PÜùà™  ÿÿÿÿÿÿÿÿÀº ‰% `é&PÜû!Pš  ÿÿÿÿÿÿÿÿ»`%¡ @^' @gØ`æ! ž°ž,ÿÿÿÿÿÿÿÿÕ€bÄ Àß& @gÙ@ç! Ÿ@Ÿ,ÿÿÿÿÿÿÿÿ€Õ è!€b• Àß& @gÚ è!àd" ŸÐŸ,ÿÿÿÿÿÿÿÿÖ€bà €B(PÜü$Àš  ÿÿÿÿÿÿÿÿ@» Ž%Å Àß& @gÛ è! Ÿ ,ÿÿÿÿÿÿÿÿ€Ö€bÇ àC(PÜþ& ›  ÿÿÿÿÿÿÿÿ€»€%È ß& @gÜé!   ¡,ÿÿÿÿÿÿÿÿ×pé!€bÉ àC(PÜÿ(€˜! ÿÿÿÿÿÿÿÿÀ» ‘%Æ ß& @gÝpé!àd"  €¡,ÿÿÿÿÿÿÿÿ€×€bË Ù&PÜ*ðœ  ÿÿÿÿÿÿÿÿ¼`¡%Ê ß& @gÞpé!  ¢,ÿÿÿÿÿÿÿÿØ€bÍ Ù&PÜ,`  ÿÿÿÿÿÿÿÿ@¼¢%Î  á& @gßPê! ¡ ¢,ÿÿÿÿÿÿÿÿ€Ø0ë!€bÏ  u'PÜ0°ž  ÿÿÿÿÿÿÿÿ€¼ ¢%Ì  á& @gà0ë!àd" ¡0£,ÿÿÿÿÿÿÿÿÙ€bÑ ðt'PÜ 3 Ÿ  ÿÿÿÿÿÿÿÿÀ¼€¤%Ð  á& @gá0ë! ¡À£,ÿÿÿÿÿÿÿÿ€Ù€bÓ ðt'PÜ 6Ÿ  ÿÿÿÿÿÿÿÿ½À¥%Ô  ' @gâì! ¢ ¤,ÿÿÿÿÿÿÿÿÚðì!€bÕ  u'PÜ :   ÿÿÿÿÿÿÿÿ@½§%Ò  ' @gãðì!àd" ¢P¤,ÿÿÿÿÿÿÿÿ@Ú€b× ðŠ'PÜ ?p   ÿÿÿÿÿÿÿÿ€½à¨%Ö  ' @gäðì! ¢°¤,ÿÿÿÿÿÿÿÿÀÚ€bÙ Ày'PÜ Cà   ÿÿÿÿÿÿÿÿÀ½`«%Ú p ' @gåðl £¥,ÿÿÿÿÿÿÿÿÛ@î!€bÛ Ày'PÜGÀ¡  ÿÿÿÿÿÿÿÿÀ`@­%Ø p ' @gæ@î!àd" £p¥,ÿÿÿÿÿÿÿÿ€Û€bÝ ðŠ'PÜL£  ÿÿÿÿÿÿÿÿ¾ ¯%Ü p ' @gç@î! £Ð¥,ÿÿÿÿÿÿÿÿÜ€bð[(ðt'PÜPФ  ÿÿÿÿÿÿÿÿ@¾€³%à Ð ' @gè ï! ¤0¦,ÿÿÿÿÿÿÿÿÀÜð!€bÀ @P(@gH°ç! õÿÿÿÿÿÿÿÿ€Îè!€bá ^(PÜT°¥  ÿÿÿÿÿÿÿÿ€¾¶%Þ Ð ' @géð!àd" ¤¦,ÿÿÿÿÿÿÿÿÀÞ€b£ ÐL(À·-åV €& ÿÿÿÿÿÿÿÿ€éÀ–%ã @P(@gIè! õÿÿÿÿÿÿÿÿÏ€bä °®'PÜW¦  ÿÿÿÿÿÿÿÿÀ¾À¹%â Ð ' @gêð! ¤ð¦,ÿÿÿÿÿÿÿÿ߀bæ €M(À·-æZ ð& ÿÿÿÿÿÿÿÿê ˜%ç PR(@gJ —! öÿÿÿÿÿÿÿÿ€Ïàé!€bé @' @gëpð! ¥ §,ÿÿÿÿÿÿÿÿ@ßàð!€bê 0N(À·-è_ `' ÿÿÿÿÿÿÿÿ€ê€š%ë PR(@gKàé! öÿÿÿÿÿÿÿÿ€bå @' @gìàð!àd" ¥€§,ÿÿÿÿÿÿÿÿ€ß€bí `T(À·-éc Ð' ÿÿÿÿÿÿÿÿë%î 0ã&@gLÀê! ÷ÿÿÿÿÿÿÿÿ@Рë!€bì @' @gíàð! ¥à§,ÿÿÿÿÿÿÿÿÀ߀bð `I( À·-ëe @( ÿÿÿÿÿÿÿÿÀþàž%ñ 0ã&@gM ë! ÷ÿÿÿÿÿÿÿÿÀЀbò ' @gîÀñ! ¦ Ò,ÿÿÿÿÿÿÿÿà ò!€b€X(0Y( àõ-šl 0A ÿÿÿÿÿÿÿÿÀ뀟%ô l' @gN€ì! úpÀ,ÿÿÿÿÿÿÿÿ@Ñ€bï ' @gï ò!àd" ¦0Ó,ÿÿÿÿÿÿÿÿ@à€bö àY( àõ-œo €B ÿÿÿÿÿÿÿÿì  %÷ !' @gO`í! ûÐÀ,ÿÿÿÿÿÿÿÿÀÑ€bõ ' @gð ò! ¦ÀÓ,ÿÿÿÿÿÿÿÿ€à€bù @[( àõ-¢t E ÿÿÿÿÿÿÿÿÀï±%ú ð'' @gPÐí! üÁ,ÿÿÿÿÿÿÿÿ@Ò€bû Ð ' @gñ€ó! §€Ô,ÿÿÿÿÿÿÿÿÀà`ô!€bü P](àõ-«u  V ÿÿÿÿÿÿÿÿðý  (' @gQ°î! ý Â,ÿÿÿÿÿÿÿÿ‡€bø Ð ' @gò`ô!àd" §àÔ,ÿÿÿÿÿÿÿÿá€bÿ P](àõ-µv W ÿÿÿÿÿÿÿÿ@ð P)' @gRï! þ`0*ÿÿÿÿÿÿÿÿÓ€bþ Ð ' @gó`ô! §pÕ,ÿÿÿÿÿÿÿÿ@á€b `_( àõ-¹x €W ÿÿÿÿÿÿÿÿ€ð ´% *' @gSÐÌ ÿ°Â,ÿÿÿÿÿÿÿÿ€Ó€b  ' @gô°õ! ¨Ö,ÿÿÿÿÿÿÿÿ€áö!€b `_( àõ-¿z ðW ÿÿÿÿÿÿÿÿÀð`µ% l' @gTPq @Ã,ÿÿÿÿÿÿÿÿÔ€b  ' @gõö!àd" ¨Ö,ÿÿÿÿÿÿÿÿÀá€b À`( àõ-Ì} `X €¹,ÿÿÿÿÿÿÿÿñ ¶%@ !' @gUPñ!  Ã,ÿÿÿÿÿÿÿÿ€Ô€b  ' @göö! ¨ ×,ÿÿÿÿÿÿÿÿâ€b  b(àõ-Õ @Y ÿÿÿÿÿÿÿÿ@ñ ¹% ð'' @gV0ò! Ä,ÿÿÿÿÿÿÿÿ@€b Àß& @g÷p÷! ©€×,ÿÿÿÿÿÿÿÿ@âPø!€b  b(àõ-Ú °Y ÿÿÿÿÿÿÿÿ€ñ`º%  (' @gWó! Ä,ÿÿÿÿÿÿÿÿ@Õ€b  b(àõ-äƒ Z ÿÿÿÿÿÿÿÿÀñ »% P)' @gXðó! ðÄ,ÿÿÿÿÿÿÿÿÀÕ€b *' @gYÐô! PÅ,ÿÿÿÿÿÿÿÿ@Ö€b l' @gZ ö! àÅ,ÿÿÿÿÿÿÿÿÀÖ€b !' @g[÷! pÆ,ÿÿÿÿÿÿÿÿ@×€b ð'' @g\à÷! Ç,ÿÿÿÿÿÿÿÿÀ×€b  (' @g]Àø!  `Ç,ÿÿÿÿÿÿÿÿ@Ø€b P)' @g^P   È,ÿÿÿÿÿÿÿÿÀØ€b *' @g_ú!  °È,ÿÿÿÿÿÿÿÿ@Ù€b l' @g`ðú!  @É,ÿÿÿÿÿÿÿÿÀÙ€b !' @gaÐû!   É,ÿÿÿÿÿÿÿÿ€€b ð'' @gb°ü! 0Ê,ÿÿÿÿÿÿÿÿ€Ú€b  (' @gcý! Ê,ÿÿÿÿÿÿÿÿ@E€b P)' @gdpþ! ðÊ,ÿÿÿÿÿÿÿÿ@Û€b *' @gePÿ! PË,ÿÿÿÿÿÿÿÿÀÛ€b! l' @gf0" àË,ÿÿÿÿÿÿÿÿ€Ü€b" !' @gg" @Ì,ÿÿÿÿÿÿÿÿÝ€b Àß& @gøPø!àd" ©Ø,ÿÿÿÿÿÿÿÿ€â€b# ð'' @gh@‘ ÐÌ,ÿÿÿÿÿÿÿÿ@Ý€b Àß& @gùPø! © Ø,ÿÿÿÿÿÿÿÿÀâ€b%  (' @gip" `Í,ÿÿÿÿÿÿÿÿ€€b& ß& @gú0ù! ª0¾,ÿÿÿÿÿÿÿÿã ù!€b' P)' @gj0/ ðÍ,ÿÿÿÿÿÿÿÿÀ€bè °®'PÜZp§  ÿÿÿÿÿÿÿÿ¿@¼%$ ß& @gû ù!àd" ª`Ù,ÿÿÿÿÿÿÿÿ@ã€b) *' @gkÀ" PÎ,ÿÿÿÿÿÿÿÿ€b* &'PÜ[P¨  ÿÿÿÿÿÿÿÿÀÿ( ß& @gü ù! ªÀÙ,ÿÿÿÿÿÿÿÿ€ã€b, l' @gl " °Î,ÿÿÿÿÿÿÿÿ@€b- `(PÜ]ª  ÿÿÿÿÿÿÿÿÀ¾%.  á& @gý€ú! « Ú,ÿÿÿÿÿÿÿÿÀã`û!€b/ !' @gm€" Ï,ÿÿÿÿÿÿÿÿ€€b0 `é&PÜ_ðª  ÿÿÿÿÿÿÿÿ@À%+  á& @gþ`û!àd" «€Ú,ÿÿÿÿÿÿÿÿä€b2 ð'' @gn`"  Ï,ÿÿÿÿÿÿÿÿÀ€bpa(ÀÑ'PÜb ­  ÿÿÿÿÿÿÿÿ€@Á%1  á& @gÿ`û! « F*ÿÿÿÿÿÿÿÿ@ä€b5  (' @go@" Ð,ÿÿÿÿÿÿÿÿ€b6 €&PÜd®  ÿÿÿÿÿÿÿÿÀ€Â%7 p ' @g@ü! ¬@Û,ÿÿÿÿÿÿÿÿ€ä ý!€b8 P)' @gp " Ð,ÿÿÿÿÿÿÿÿ@€b9 `È&PÜ!eà®  ÿÿÿÿÿÿÿÿ4 p ' @g ý!àd" ¬ Û,ÿÿÿÿÿÿÿÿÀä€b; *' @gq!"  Ñ,ÿÿÿÿÿÿÿÿ€€b< àF'PÜ"gÀ¯  ÿÿÿÿÿÿÿÿ@ÀÃ%: p ' @g ý! ¬Ü,ÿÿÿÿÿÿÿÿå€b> l' @grP"" °Ñ,ÿÿÿÿÿÿÿÿÀ€b? @q(PÜ#j °  ÿÿÿÿÿÿÿÿ€Å%@  ' @gþ! ­@M*ÿÿÿÿÿÿÿÿ@å€bA !' @gs0#" à1*ÿÿÿÿÿÿÿÿ€bB ðq(PÜ$m€±  ÿÿÿÿÿÿÿÿÀ€Ç%C ð' @gàþ! ® Ý,ÿÿÿÿÿÿÿÿÀå€bD ð'' @gt$"  ÐÒ,ÿÿÿÿÿÿÿÿ@€bE °=(PÜ&n`²  ÿÿÿÿÿÿÿÿF P' @gÀÿ! ¯àÝ,ÿÿÿÿÿÿÿÿæ€bG  (' @gu`%" !àæ,ÿÿÿÿÿÿÿÿ€€bH °=(PÜ'o°³  ÿÿÿÿÿÿÿÿ@I Ð ' @g " ° Ì,ÿÿÿÿÿÿÿÿ@æ"€bJ P)' @gv@&" " ç,ÿÿÿÿÿÿÿÿÀ€b= Ð ' @g"àd" °ÐÞ,ÿÿÿÿÿÿÿÿ€æ€bM *' @gw'" #P¬*ÿÿÿÿÿÿÿÿ€bL Ð ' @g" °`ß,ÿÿÿÿÿÿÿÿÀæ€bP  ' @g " ±ðß,ÿÿÿÿÿÿÿÿçà"€b `È&àõ-î„ Z ÿÿÿÿÿÿÿÿòN  ' @g à"àd" ±Pà,ÿÿÿÿÿÿÿÿ@ç€bR 0d(àõ-ù‡ [ ÿÿÿÿÿÿÿÿ@òà¼%Q  ' @g à" ±PÔ,ÿÿÿÿÿÿÿÿ€ç€bT e(àõ-‹ p[ ÿÿÿÿÿÿÿÿ€ò`¿%U p ' @g P" ²àà,ÿÿÿÿÿÿÿÿÀç0"€bV 0d(àõ-Ž à[ ÿÿÿÿÿÿÿÿÀò Ã%S p ' @g 0"àd" ²@á,ÿÿÿÿÿÿÿÿè€bX e(àõ-’ `© ÿÿÿÿÿÿÿÿó Å%W p ' @g0" ² á,ÿÿÿÿÿÿÿÿ€è€bZ ðf( àõ-• P\ ÿÿÿÿÿÿÿÿ@óÀÈ%[ Ð ' @g" ³0â,ÿÿÿÿÿÿÿÿÀèð"€b\ i( àõ- ™ 0] ÿÿÿÿÿÿÿÿ€óÊ%Y Ð ' @gð"àd" ³â,ÿÿÿÿÿÿÿÿé€b^ `j( àõ-# €^ ÿÿÿÿÿÿÿÿÀóàË%] Ð ' @gð" ³ðâ,ÿÿÿÿÿÿÿÿ@é€b` pl( àõ-(  ð^ ÿÿÿÿÿÿÿÿôÀÍ%a °5' @gð@" ´Pã,ÿÿÿÿÿÿÿÿ€é°"€bb €n( àõ-/£ `_ ÿÿÿÿÿÿÿÿ@ôÏ%_ °5' @g°"àd" ´°ã,ÿÿÿÿÿÿÿÿÀé€bd ào( àõ-4¨ @` ÿÿÿÿÿÿÿÿ€ô@Ð%c °5' @g°" ´ä,ÿÿÿÿÿÿÿÿê€bf v( àõ-;¬ °` ÿÿÿÿÿÿÿÿÀôÀÒ%g 5' @g " µðå,ÿÿÿÿÿÿÿÿ@êà!"€bh pw( àõ->® ² ÿÿÿÿÿÿÿÿõ Ô%e 5' @gà!"àd" µPæ,ÿÿÿÿÿÿÿÿ€ê€bo ðè% àõ-wÑ b ÿÿÿÿÿÿÿÿ€õ ˜#i 5' @gà!" µç,ÿÿÿÿÿÿÿÿÀê€bl ðè% àõ-zÔ àb ÿÿÿÿÿÿÿÿÀõ`™#j àæ% àõ-tÎ a ÿÿÿÿÿÿÿÿ‹@–#m `6' @g0 ¶Ðç,ÿÿÿÿÿÿÿÿë #"€bO l' @gxp(" $ðè,ÿÿÿÿÿÿÿÿ@€bk `6' @g #"àd" ¶`è,ÿÿÿÿÿÿÿÿ@ë€bq !' @gyÀ)" %°é,ÿÿÿÿÿÿÿÿ€€bp `6' @g #" ¶ é,ÿÿÿÿÿÿÿÿ€ë€bs ð'' @gz *" &pê,ÿÿÿÿÿÿÿÿÀ€bt Àß& @gð$" ·àé,ÿÿÿÿÿÿÿÿÀëÐ%"€bu  (' @g{ð+" '0ë,ÿÿÿÿÿÿÿÿ€br Àß& @gÐ%"àd" · ê,ÿÿÿÿÿÿÿÿì€bw P)' @g|@-" (­*ÿÿÿÿÿÿÿÿ@€bv Àß& @gÐ%" · ¢(ÿÿÿÿÿÿÿÿ@ì€by *' @g} ." )€ì,ÿÿÿÿÿÿÿÿ€€bz ß& @g '" ¸P¢(ÿÿÿÿÿÿÿÿ€ì("€b{ l' @g~`O" *@í,ÿÿÿÿÿÿÿÿÀ€bx ß& @g("àd" ¸°ì,ÿÿÿÿÿÿÿÿÀì€b} !' @gP0" +î,ÿÿÿÿÿÿÿÿ€b| ß& @g (" ¸°¢(ÿÿÿÿÿÿÿÿí€b ð'' @g€01" ,Àî,ÿÿÿÿÿÿÿÿ@€b€  á& @g!P)" ¹0î,ÿÿÿÿÿÿÿÿ@í0*"€b  (' @g€2" -Э*ÿÿÿÿÿÿÿÿ€€b~  á& @g"0*"àd" ¹ðî,ÿÿÿÿÿÿÿÿ€í€bƒ P)' @g‚`3" .ð,ÿÿÿÿÿÿÿÿÀ€b‚  á& @g#0*" ¹€ï,ÿÿÿÿÿÿÿÿÀí€b… *' @gƒ@4" /Ðð,ÿÿÿÿÿÿÿÿ €b† Àß& @g$€+" º ð,ÿÿÿÿÿÿÿÿîÐ,"€b‡ l' @g„ 5" 0ñ,ÿÿÿÿÿÿÿÿ@ €b„ Àß& @g%Ð,"àd" ºÀñ,ÿÿÿÿÿÿÿÿ@î€b‰ !' @g…6" 1Pò,ÿÿÿÿÿÿÿÿ€ €bˆ Àß& @g&Ð," ºàò,ÿÿÿÿÿÿÿÿ€î€b‹ ð'' @g†à6" 2 ¥(ÿÿÿÿÿÿÿÿ€bŒ ß& @g'°-" »Ðó,ÿÿÿÿÿÿÿÿÀîp/"€b  (' @g‡À7" 3 ó,ÿÿÿÿÿÿÿÿÀ €bŠ ß& @g(p/"àd" »ðô,ÿÿÿÿÿÿÿÿï€b P)' @gˆ 8" 4`ô,ÿÿÿÿÿÿÿÿ €bŽ ß& @g)p/" »ö,ÿÿÿÿÿÿÿÿð€b‘ *' @g‰: 5 õ,ÿÿÿÿÿÿÿÿ@ €b’  á& @g*à/" ¼÷,ÿÿÿÿÿÿÿÿ@ðÀ0"€b“ l' @gŠð9" 6àõ,ÿÿÿÿÿÿÿÿ€ €b  á& @g+À0"àd" ¼ ø,ÿÿÿÿÿÿÿÿ€ð€b• !' @g‹Ð:" 7À®*ÿÿÿÿÿÿÿÿÀ €b”  á& @g,À0" ¼@ù,ÿÿÿÿÿÿÿÿÀð€b— ð'' @gŒ@;" 80÷,ÿÿÿÿÿÿÿÿ €b˜  ' @g-2" ½ú,ÿÿÿÿÿÿÿÿñð2"€b™  (' @gPa 9ð÷,ÿÿÿÿÿÿÿÿ@ €b–  ' @g.ð2"àd" ½ú,ÿÿÿÿÿÿÿÿ@ñ€b› P)' @gŽÀa :°ø,ÿÿÿÿÿÿÿÿ€ €bš  ' @g/ð2" ½Pû,ÿÿÿÿÿÿÿÿ€ñ€b *' @g0b ;pù,ÿÿÿÿÿÿÿÿÀ €bž p ' @g0Ð3" ¾ü,ÿÿÿÿÿÿÿÿÀñ°4"€bŸ l' @gc <à²*ÿÿÿÿÿÿÿÿ €bœ p ' @g1°4"àd" ¾Ðü,ÿÿÿÿÿÿÿÿò€b¡ !' @g‘€c =Àú,ÿÿÿÿÿÿÿÿ@ €b  p ' @g2°4" ¾ý,ÿÿÿÿÿÿÿÿ@ò€b£ ð'' @g’`d >€û,ÿÿÿÿÿÿÿÿ€ €b¤ Ð ' @g35" ¿Pþ,ÿÿÿÿÿÿÿÿ€òp6"€b¥  (' @g“Ðd ?@ü,ÿÿÿÿÿÿÿÿÀ €b¢ Ð ' @g4p6"àd" ¿ÿ,ÿÿÿÿÿÿÿÿÀò€b@¾( ½(¼(À¼(Г)ð¼(€½(P½(°½(à½(¾(`n+Ð+ ÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐG`l-º*|šo 9°ž™o  ;º*0  "9p 1456Dº*9; >;È@BDEDº*HIŽè`l-º*a›o èè9p§™o šè è;º*€ Ÿè¡è£è9€Y³è¶è·è¸èDº*»è½è Àè;¸ÂèÄèÆèÇèDº*ÊèËèj9@ë›o jº*Ø›o žjº*™o Ÿj9ðuªjº*Þ›o «j9`v¶jº*¸jDº*¹jº*»jDº*¼j½jº*¾jÒ °ý-º*°¢o Ó ðû-º*åžo Ô -º*‘¡o Õ Dº*Ù º*,¡o Ú 3º*óo Ü 9`âã °æ-º*å 9 ³ñ 0Ú-º*ó º*ö ;º*ø÷ º*T °ý-º*°¢o U ðû-º*åžo V -º*‘¡o W Dº*[ º*,¡o \ 3º*óo ^ 9`âe °æ-º*g 9´s 0Ú-º*u º*x ;º*P y º*³ °ý-º*°¢o ´ ðû-º*åžo µ Dº*‘¡o ¸ º*¹ 3º*,¡o » 9PØóo É pß-º*Ë °æ-º*Ì Dº*Ï 0Ú-º*Ð 3º*Ò 9p×Ç¢o à º*)º*â¤o )9Àœåžo !)4º*s¤o ")9ð—*) º*,¡o ,)À‰-º*é¤o -);º* /) °æ-º*2)º*3)0Ú-º*4)Dº*5)ÀÙ-º*Ç¢o 7)º*9);º*€:)f›o ;)°æ-º*¿¢o <)”)º*â¤o •)9Àœåžo ¡)4º*s¤o ¢)9€—¨)+º*,¡o ©)À‰-º*é¤o ª)Dº*ë¤o «)°æ-º*­)º*¯);º*0°),º*±)ÀÙ-º*Ç¢o z”-º*"®o zK-º*åžo ‘zº*2¨o ’zDº*ù¦o “zº*6¨o •z pØ-º*é¤o —z9Ðë¤o žz°æ-º* z º*£z9Úï¤o ²zº*| ž-º*°-º*|Dº*åžo ’|º*2¨o ”|9P ù¦o ›|º*6¨o œ|Dº*é¤o |à-º*ë¤o ž|°æ-º* |Dº*¢|Àâ-º*ï¤o ¤|9àŒ «|ÀÙ-º*Ç¢o ¬|Dº*­|º*í¤o ®|f›o } ž-º*°-º*}Dº*åžo ’}º*2¨o ”}9 ù¦o ›}º*6¨o œ}Dº*é¤o }à-º*ë¤o ž}°æ-º* }Dº*¢}Àâ-º*ï¤o ¤}9 Ž «}ÀÙ-º*Ç¢o ¬}Dº*­}º*í¤o ®}f›o ~ ž-º*°-º*~Dº*åžo ~º*2¨o ~9ð ù¦o ~º*6¨o ~Dº*é¤o ~à-º*ë¤o ~°æ-º* ~Dº*"~Àâ-º*ï¤o $~9€ +~ÀÙ-º*Ç¢o ,~Dº*-~º*í¤o .~f›o àGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGz”-º*"®o zK-º*åžo zº*2¨o z90–ù¦o zº*6¨o zpØ-º*é¤o zDº*ë¤o z°æ-º*z º* z9Úï¤o /zº*1z ÀÙ-º*Ç¢o 3z9Ð:zº*í¤o } ž-º*°-º*}Dº*åžo }º*2¨o }90Ž ù¦o }º*6¨o }Dº*é¤o }à-º*ë¤o }°æ-º* }Dº*"}Àâ-º*ï¤o $}9À +}ÀÙ-º*Ç¢o ,}Dº*-}º*í¤o .}f›o ››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››OPQR››››››››››››››››››››››››››››››››››››››››››››››››››››››››°NÐßÀNÐNàßÐMàNðNÀàMOOðß O0OpÜ@OðMPOà`ÜC`OpO à€OO0à O ß°O°pß @àPàßÀOàÐONNàO`à NPN€ßN0NpNC N€N@N°ß`NÀß0¤`´Бà†@‹Pœ@®@ 0º¡°„‚`ðð‚·`ŠЊ “0ÇÐÉÈpÅPÆðÈ€†°‹‰0¹ð‰`¦@õ!Ð"!@#!л ˆ Œ°§…À‡ …á!ðžàà¢@„0²àå ëÀíPô~0?@A›››››î#››››››››››››››ùø›››››››››››››››››››››››››››››››››9 põ,º*°¢o : 9Pêåžo A -º*‘¡o B º*C Dº*,¡o F º*óo G 3º*I 9ÐÔV º*Y º*Z Dº*] º*^ 3` 9°Õl f›o n ;H o ³ µ 9н ¾ Dº*Á Ã Å Æ Ç 9€´Ð 9 †Õ Ö Ø Ù Dº*Ü Ý 3ß 9ÐÔë 1í ¹ põ,º*°¢o º 9Pêåžo Á -º*‘¡o  º*à Dº*,¡o Æ º*óo Ç 3º*É 9ÐÔÖ º*Ù º*Ú Dº*Ý º*Þ 3à 9°Õì f›o î ;ˆï 5 8 9ðD E Dº*H J M 9à­Q S 9à­³ ÀÉè,º*µ ¶ · 9€´À 9 †Å Æ È pØ-º*É Dº*Ì Í 3Ï 9ÐÔÛ 4 °ý-º*°¢o 5 9Pêåžo < -º*‘¡o = º*> Dº*,¡o A º*óo B 3º*D 9@êN 3º*P 9ÐÔ] º*` º*a Dº*d  Ú-º*e 3f›o g 9@ê¿¢o q 3s 9°Õ 0ú-º*¶ ;· º*5 7 9@ Þè,º*A Dº*D P²-º*F ÀÉè,º*H º*I 9P™S Þè,º*U ÀÉè,º*V W Dº*Z ÀÉè,º*[ 3º*] 9@êg 3i 9ÐÔu 1º*w -°-º*°-º*9ð"!åžo º*2¨o 9°ôù¦o 3º*6¨o 9¾é¤o %à-º*ë¤o '°æ-º*(Dº*)Àâ-º*ï¤o *@}-º*+ÀÙ-º*Ç¢o ,Dº*-º*í¤o .f›o /°æ-º*¿¢o 0;€1/ Ú-º*‘9`#!–9@É âo ›º*œ9°ô¢€û-º*£Þè,º*¤Dº*¥P²-º*¦º*§º*¨Dº*©Þè,º*ªŸ-º*«/­.º*››››››››››››››››››››››››››››››››››KLMN›››››››››-›››››››››››››› R-›ÀR-ãàR-âS-á S-›.››››››››››››››››››››››››î#››.›››››››››››››› T-›@T-í`T-ì€T-ë€t.› T-››››››››››››››››››››››››ï$›››››››››››››ò››ô››››››››››››››››››››››››››››››››1›››››››››››››@V-›`V-€V- V-ÿÀV-›àV-››››››››››››››››››››››››ñ&››1››››››››››››››W-› W-›››››››››››››››››››››››››››››››››››››››››››`W-›€W-››››››››››››››››››››››››››››››››3›››››››››››››€.›@W-››››››››››››››››››››››››››››››››››››››››››› W-›ÀW-››››››››››››››››››››››››››››››››2››››››››››››››àW-›X-››››››››››››››››››››››››››››››››4››››››››››››››àZ.›w.›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››› w.›`€-›@w.›`w.››››››››››››››››››››››››››››5››››››››››Œ.›€w.›››››››››››››››››››ijkl›››››ø+››6››››››››››ÀŒ.›@.›››››››››››››››››››mnop›››››ù,››7››››››››››! `‚-› Ž.›››››››››››››››››››qrst›››››ú-››9››››››››››VUQKÀ‚-G .››››››››››››››››››››\]^›››››››››;››››››››››`_^Z ƒ-W .››››››››››››››››››››WX››››››››››:››››››››››nmlj›››››››››››››››››››››››››››››››››=››››››››››srqo››››››››››››››››››››››››››››››››››››››››››››››››.3››››››››››››››››››››››››››››››?››››››››››››››à„-›@…-òà…-ô`‘.›€x.› x.›››››››››››››››VTW››››››ò'››@›››››››››››››› -›Àˆ-›››››››››››››››››››Y]^››››››››››A›››››››››››››› ‰-›`Š-›››››››››››››››››››SUX››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››ecbhqsw|‚››››››››››››´µ¶ØÙÚÛ››››·ÜÞ››%››››››››››gd›››››››››››››››››››››››››››››››››››,››››››››››[ZYX {.WÀ{.a@|.``|._`~.› ~.›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››I››››››››››››››››À~.›à~.›.›Àë-››››››››››››››››››››››››››››K››››››››››››››››€.› .›‰-›À.››››››››››››››››››››››››››››J››››››››››››››››à.› s.›€.› €.››››››››››››››››››››››››››››M››››››››››››››››@€.› ì-›`€.›€€.››››››››››››››››››››››››››››L›››››››››››››››› €.›à€.›.› .››››››››››››››››››››››››››››R›››››››››››››››› |.›À|.›@.›`.››››››››››››››››››››››››››››/››››››››››+*)' ‹-%À‹-,€Œ-1€y.6 y.› -›››››››››››››››:;<=›››››ì!››/››››››››››››››`-› -,‘-1 z.6@’-›@ -››››››››››››››››››››››››ì!››c›››››››››››››››-27››››››››àŽ.›››››››››››››››››í"››c›››››››››››››››-27›››››››››››››››››››››››››í"››››››››››››bcde›››››››››››››››››››››››››››››››››e››››››››››››¼.¿€^.›Àz.››››››››››››››››››››››››››››››››f›››››››››››ÃÁ ^.›À^.››››››››››››››››››››››››››››››››g››››››››››››CD€—-›`{.››››››››››››››››››››››››››››››››h››››››››››››››à^.›_.››››››››››››››››››››››››››››››››i››››››››››››››€{.›š-››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››.››››››››››êéèæ@S-ä`S-í€S-ì S-ëàS-›T-›››››››››››››››BCDE›››››ï$›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››0››››››››››ñðïîàT-›U-þ U-ý@U-ü`U-›€U-›››››››››››››››FGIJ›››››ð%›››››››››››››››››››››››››››››››››››››››››››››››››0›››››››››››››› U-›ÀU-þàU-ý t.üV-› V-››››››››››››››››››››››››ð%››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››ûú››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››ó››ö››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››ST››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››¼½¾àáâã››››¿äå›››››››››››››››››››››››››››››››››››››››››››››õ››››››››››››››››››››››››››››››››››››››››››››››ö›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››ô›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››ÕÒχ„~››››È8›››››››››››››››››››››››››››››››››ÔÑ̆ƒ€}››››Åþ7›››››››››››››››››››››››››››››››››ÖÓЈ…‚››››Éü9›››››››››››››››››››››››››››››››››ÀÁÂæçèé››››Ãêë››››››››››››››››››€.› .›À.›@Ý-››››››››››››››››››››››››››››<››››››››››ihgd ƒ-aàƒ-››››››››››››››››››››YZ[›››››››››>›››››››››››››› ‘.›@„-ñ@‘.ó`„-›€„-›À„-›››››››››››››››[Z\››››››ó(›››››››››››››››› _.›à{.››››››››››››››››››››››››››››››››H›››››››››››››››› .›@.›`.›€Ù-››››››››››››››››››››››››››››8››››››››››EC@>`“-›`^.›››››››››››››››››››efgh›››››››››d›››››››››››››››Í΄›››››››››››››››››››››››››Ÿ ›››››››››››››››››››››››››››››››››››››››››››››››››ÈP&('(°'(pV( W(€X(à&  &"&°"&@Ï&ðÏ& Ð&PÑ&°Ò&`Ó&Ô&ÀÔ&pÕ&ÐÖ&0Ø&0ë'ð[(pa( r(Ps(ȵ °ý-º*°¢o ¶ 9Pêåžo ½ -º*‘¡o ¾ º*¿ Dº*,¡o  º*óo à 3º*Å 9PØÓ º*Ö º*× Dº*Ú º*Û 3Ý 90Ùê f›o ì ;ðí 6 8 9@C D Dº*G I J 9€´S 9 †W P²-º*Y ÀÉè,º*Z Dº*] ^ Þè,º*¶ ÀÉè,º*¸ ¹ 9€´Â 9 †Æ º*È É Ê pØ-º*Ë Dº*Î Ï 3Ñ 9PØÞ 1á ã ä Dº*ç è é 4 °ý-º*°¢o 5 9Pêåžo < -º*‘¡o = º*> Dº*,¡o A º*óo B 3º*D 9@êN 3º*P 9Pض º*¹ º*º Dº*½  Ú-º*¾ 3f›o À 9@ê¿¢o Ê 3Ì 90ÙÙ 0ú-º*Û ;0#Ü º*5 7 9pC Þè,º*D Dº*G P²-º*I Dº*M º*µ Ÿ-º*· Þè,º*¸ 9P™Â Ä º*Å ÀÉè,º*Æ º*Ç Dº*Ê Ë 3pØ-º*Í 9@ê× 3Ù 9PØæ 10Ú-º*é ë ì Dº*ð º*ñ ò  ”&pÁ(Â(ÐÄ(`Å(@Á(ÐÃ)Ç(`È(Pœ(À¬)Àþ+ðÈ(Ë(0ž(›(P, ­)à­)Ð0,0Ç)PÌ(Á(p†* †*°­)pý+ÀÊ)Ðý+°, ý+Ç)0þ+ðþ+.,`þ+ Ë) ÿ+Pÿ+pÌ)Í)€ÿ+PÈ)°ÿ+@,à5,6,p6,@6, 6,Ð6,07,7,7,`7,ð7,À7,P8, 8,°8,P°)€°)€8,à8, 9,0Â(€ª)0õ(pš(.,К(ÀÂ(`Â(þ+ðÂ( Ä(p0,ò*®)Å(€Æ(P½+@é*°Å)p,à(°Æ(0È(p(0.,ð›(`,€Ë)¬)þ+àÿ+Ð9,È(`Ë(à™(Ð(r,0›(à,°5,Pt,ð¬)p®)°°)9, 0,°È)ÀË(PÃ(€Ã(àÃ(ÀÅ(pÇ(`Å+ðÅ+€¢(àÆ+pÇ+ÐÇ+`È+ðÈ+€É+PÉ(Ð3,4,4, 5,ð4,À4,`4,v+ v+ÐÊ(Ðv+ ó( ª)¬) «)Ы)ð„*P…*°…*°—*p˜*(°œ(àÃ+€™( ™(¡*¢* £*àš*p,@,P“+ð., ½+ð¼+€5,P5,pà0œàZÀœðƒS„à• r Xà…@˜š •P˜ €œð›p™`” †`S0ð™°ƒƒ°bp‡ ˜ðW@a›ÀY@] –Pb ’Б `aÀ„@’°ÐS@W°€‘pb[p”Àa0…àäà‘`‡ ˜Ð]ðr`‚€^[—Ж0Wð `À•@…À” ™‡P@›^@”°–à’ ƒ‘ bð°`°˜°_ðY@V°™€@‘VXàrÀU`ZàЀ]pXàœP à€°UÀ† ^@b`•p… š œ W`[P…P€š “`˜‡p“àXàãМ•0†ð‚°‘ð– ]€à€›Pœ ‚`W _ s€™—` —‚àšbÀXðÀ€€Ðað]0™Tà„À™€‡€]™Ð〖p`‘Ð``Z ’@™pS P@`0°‚Ђð‘àY0Pa@ƒ X°€À…0a°‡ äPa ÀTX ‘@C@—@_à–`Z`™ð„0`ð U°œ€˜€ƒ0U`–T…°SP™€—€__P’p_`ƒàW S@–pœð†šP†Й0b°…p–p€0VÀaW`œÐZà—† T›0—UÀ˜À›Pš@šP‡``‚p[€WÐ… _@ Z`…™`]`ÐXð…ÀS0’@S ^ › •’`†p`ð^pš`V–V€…p‚Л°ZÐ_0CðXPV@@YðãÀ‚€À^0P à l TÐp‘Ppa ‚@‚äpTP–°Wða0•°Pà“ V0„s€€@T@ä0Z„0”`–ЄÐ Yp†p äp]àƒ’@U0‘0Xp— ”°Y…™À`äP„@œPS “€aЕðœÀ–`X`—Pƒà†ÀƒT›€b€Z°†°TU@^PC ‘ð˜0›°]ðV€V0€€šà‚°XÀ’€•P›€„К‚°VP[ÐVÀ] e°—pä ƒ0ƒ@ ðO aPY0“ Y°^ ‡aÐ`’b P— ™pƒ–ðZZ0_@X@[P`à à^€SPTÐY€U€ð UД0‡†°›W À‘ €À„rpZ€TpWp’ð’`UÐT•P•œV€Y  [Г0T`€P“ƒ C”ðSƒ €”Ð’˜ÀW`›€” b€ `b€`_ð—@_P”pV@“ÀVІ@€Ðr0] „à›ð•ð”ÀràU0‚^ ›Y°•ð“P‘p“œà’ðUÀšpY ”@„àa°’`^À—àTà_ —@^PXà`‘0š „€’ œÀ“°“ …àV€†p›БààS€`Pb—P‚p•à]Y€“ †p„0˜P_p˜Wà˜°šð_@‡”e°‡P^€X ‡0^U0–]…À€“ `𚀂ð` … Z@ZЃ˜Y`„ÀZ°äpp^_X€r˜ V`š@•“°”† –à™`“`]œÀ WP]ÀbPÐWИ0[ð€`Y a`•З°„@†à”ÐU r,«)@±)0s,°ª)°É(s,ÐÇ(ðs,àu+—)€É( É(Ð,Ä( Ç(@Ç(ðÇ), ,€1*É)0,,Pª)P*À,àË) Ì)Л*ð,à°)p)@u,0œ*`Ë+,p9,0:,:, Æ(`¼(€,Àq+@s+Àt+°r+ Ì(pp+pÄ( Ã(0 , Á(0Ë( ¨,p«)ð©)p¡*pv+€)ðò(Ð)@†*Pó(P­) ô(±)pÙ+pé* Ä+ÐÄ+Ë+ÐE) , ,°*àt,àÿ(€­)3,@9,à2,`.,@«)ðÅ(àª)ð)°Ã(€š*P;,p,ð:,0Ÿ*Å( q,0—) ž*_››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››à.Ç@‚.È`}.Éà‚.›@ƒ.›››››››››››››››››››››››››››››››››››››››››››‚.Ê}.Ë€‚.Ì€ó-›õ-›››››››››››››››››››››››››››››››››››››››››››à|.´ }.µ ‚.¶ƒ.›`ƒ.››››››››››››››››››››››››››››››››››››››››››› ‚.›`‚.›À‚.› ƒ.›€ƒ.››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››Z›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››x››››››››››››››››››››››››››››››››››››››››››››››yv›››››››››››››››››››››››››››››››››››››››››››››ut’›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››œ€.›››››››››››››››››››››››››››››››››››››››››››››› .ž /.››››››››››››››››››››››››››››››››››››››››››››››À.›à.›Ž.›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››a››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››Ï››››››››››››››››››››››››››››››››››››››››››››››Ð›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››[›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››†››››››››››››››››››››››››››››››››››››››››››››››Š„›››››››››››››››››››››››››››››››››››››››››››››qpŽ›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››\›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››Ÿ@Ž.¢`Ž.›€Ž.›››››››››››››››››››››››››››››››››››››››››››››¥.-› Ž.›››››››››››››››››››››››››››››››››››››››››››››››ÀŽ.›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››`›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››› õ-› „.›@Š.›à-.›››››››››››››››››››››››››››››››››››››››››››› ƒ.›@õ-›`Š.›àŠ.››››››››››››››››››››››››››››››››››››››››››››Àƒ.›@„.›€Š.›‹.››››››››››››››››››››››››››››››››››››››››››››àƒ.›`„.› Š.› ‹.››››››››››››››››››››››››››››››››››››››››››››„.›`õ-›ÀŠ.›..››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››b››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››@‹.›à‹.›`Œ.›.››››››››››››››››››››››››››››››››››››››››››››`‹.› ..›€Œ.›À..››››››››››››››››››››››››››››››››››››››››››››€‹.› Œ.› Œ.› .›››››››››››››››››››››››››››››››››››››››››››› ‹.›@Œ.› ..›/.››››››››››››››››››››››››››››››››››››››››››››À‹.›@..›àŒ.›`.››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››°››››››››››››››››››››››››››››››››››››››››››››¬­«››››››››››››››››››››››››››››››››››››››››››››©ª¨›››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››››À™  p 0_ _p°`RÀâ ¸!°é¿!àã!Pµp¾Pä!°,à”Ö0G"ýÐÒ!`Ž`C pʰD °ðà{à!Ðcf`”iî @%4 0°Z!- Áп %! Â!°   @TP ðž @{P_!à¾Pº!ÀVPO ²Ð}Pc @È x lP€v!`]Фðx€e 0{Pæ0FPA`Dp»ÀF"0}ðß! -"ð‹! Ž!мß Àï з0ŒJPá  ë9pÎ!€ Ðå !j`3°‚À"À!€·°$!PÛ "@ËÀåC|à_±à} žÆ ª!@L«!ÈÀ àô@1à¡ `xYPq 0" ÄÐv à °'"pôpÀ! !“ pà n`!tÀ‹@c!påЙp! ‚àŒ P ð‚ 6!ðW Ð{ ²º0î°E­00s½:"г à&!€"@!ÀyÁ€Õ àÏà«!`Á €qPÐ@× ÀÐP5!€p ûpœð#Õðpš àhPË0¼ài °æ°yp@ ÷ ÐöP¤ pðY€_p NÐD0ò@ÏP‡ð¥P²à¶ Ñ @§ z0"Ì 0 àC€ðå°  `j@kPö Àn d àKÀc €‹!@j!à“ PF"`Æ À}`ª A €‰ÐY0õ þ À–Àe`t œ!@x!``°Ù 0 `ÕÀwp Ð~!€!°!€O"0ið@ÝÐÓp4!` S #0å!2À ¤À½°= @tf t@°Ž sÀrPšÐL°m +pw P 80^ðUpH€òF —Ð  w@ê°R pT €`1!ÀÛÐ1! q@&@!ÐÐgðÙé!ðe Pë!p´°íÐì@a0.€cpu°ôÀ= ô ÐÕpíP}`ë ² `‚ púàµP¹@6 `Ð`èp§Úð``Ò!0êPéÞÀ° Pà À˜ d!ðÒÐ>@.€.@ðh!@( @¤ |ðÍP@ !à5 w<; €,"p<P6 œ !P gp‡`Q Ðw!ðq &ЊЀ †°F€ÉàHp ¸ÀO  °: ñðRðpCGеPØp¶  /"Pv08`½!¯ `yP´sàM €W PÂÐX ípÌP$ Õ!À€ÐãàNàu°û $0­! ô p®®!ñ@!°ƒ 0Üàb 0  ÝÐd Š! @"ÐJ 0aÐnÐ(p–!P’°È ‰5€¸ø°(  ~Àk`ÀÀä!`‡€|°aÐÚe ï¨p6P7@Sð!z À:‚0N"°9!°<"€ "À]@ÙÀ΀ìàx°tÀA€+M “@ì @J"à@PYðUQ šåpã!0Ù`¹pÿ!àÐ à›à/°#À,ðú ÜPn@Ú!°sPaÔð0°Õ°¹€ ¥ €0!n@à? À€þ`opÐF! Ù”@/ PpN0± @R @y°¬P °!à® Ї@^Ð!ðH"0Zw @Ð@BÐP€ÀÙÐ\ žpJÐVUà4!ï@°!€ !À ë µ0X ("€JP*"€& `š! šàúðŒpˆ!À‰! u!௠Pei à=ð”î@f05ðâ@›! mðÑ!`E`Œ! ðæ!0ÀÀ„p|àB!€ýÍÐÿði€”p½  °®pVp¯ @ÃPgPÀi0h @ Í!pà–!p5ð& `Þ ¥DÐE€K°àÜ!°±PƒÀƒ0„…á°‡ˆp‰€@) € !€Œ`p\ àÀ‘ ’€“°L@• –p—P˜`d ™€š`›°œàžÀŸ  €¡Т°£°!Ð?!°` ?P?"`ØЬ õÐêàù€©P9 p’P—!0”ÐH°  ÷!ø!àø!pÐÔ°ãPoÀóðFàVðÂ0¨Ó€UàÀí0@"öÀ>àyðwŽ!à!ð¾6@[à9`)`N`/°0»!Ðqÿ!@ °ž€G‰PÀ;@˜ €§!€@@!°j!`íÀ""€×@P"Ðz°¡pdP¸À$ ð“0›0b Wp†Ðs P /! !po!p~ ð Àp0vàéð›ÿ! ) P"àÿ!È" æ  Ä°ºP ” O ж!3!°P €« й¡àÉ0´!Ðl0˜!µ!À“ Æ  `!°ÃÐý! q€rðr à`sÐN°C"`£Ð&"ÐŽ@8p3à,€À À`’`#!@š‘¢ÀM"@G!» D"ðC H! ¿!@õ€Xª`´Pðœà†`_ P© 0QPD`•ਠP|ð˜PM"p&!@"à^!ðÔ-!]!pç à¤!°†!"0k€kðk`È °¤ÐÈ 0ïÊ 0Ã`@“ ú` ÐÎ`éÀz —0¹0+"° ¤ °! ÀŽ -°Ë°c!` Ë€¦ “ @àðþpK <0Ý0u!æ pPm!@5"àvÀÐç!О uðïð õ°`œÐ P0P!010T »@ " Þ!€Dð; €ÐP§°"€B R@D PàÙ F ð  Û ð±°]ðÜ p›p/s ðù ÕÐË!pÈ@‚0f"¹!0½`F!°G!á Q@bp;!çPÕ ò@¢! ipÜ!ðçÐþ[0°0¡€±Ÿ`OÐI" 'r!ÃÐà! Õ Àù!pn€û!)"à‰À0Ø %  «ðZ! |!P~`[!€}!@VЄ [°Þ à’pà €À €ë`:аà À_!€Fð ðÐ÷ï  ¹°80• l€Î H"pb pI!Ða°šº`ó€‡ÐK°ÇÀê@­   *@’ð€ÐU =!БÂÐ|Ðm З 0 `*!pºЋ@*0!ð!¦ð‰°á!ò09"€:"@B@â°ÅàPG  â °K pM pä€gà @Á@4HÀIw@¨PŸ ¡ Ø C@£ "@!Æ0qPù!· ú!ðz °! N"‰`T!àp `b! K!+ ]!€ `®W  È`ò àÚÀñz!À! CÀ‡ð>!@N!°ú QÀ×O!ðŠù0Ð0ý0% à„0Ñ€!ƒ à7"ÀhàË Ž ²Ð € àU i°›!pE"°Øà6Px À7ð+ÀS°S0œ À÷@‘ €ü0 ¾P,à !`õ!PyPrÒ s0y ¥PÁ!0ÕÀÒ€µ!@p‚ ¨ð9ðÈPN P;àL"P°²àœÐ @±à8 !€ `¢I õ вE!€ƒ@Ó!ÀT"zbÐ[!k3"ð¶€Æð½ —Ø@ú Ô!€¬§  ÿ€›à: ÿàDP@º0k 0r  Ó@ÿ¾`« n!` Ô!°Ì!pUð? ] ЛÐáp* PÍå@;< Áp=°è!ðËÐÌpÎÐØÀ Ð’ ºàA0 P€@,0·`U ñPÓ 0@rpW!°r<°3ð´À¦· !` °~ "À¼ æ@>PB :! ‰`=`P"ÀDðÉþ!0ô€E! †°*`,ð³ðI Àž!p0"P1" 2"š €3"npö`uд€Ñ!Ð! ìPåÐÀt!€°à!PÉà+0Ê ùÀÌ {·PêÏ P+ ðP à´K"°‰ " 0ã0ß@ °Ù gh`¶!Pi6 °D"À²Ð, ˜! `À!à|à¿ !!ÐÐ "°lPV€€ð<ô FЂ °eâ> `!ú€ú@!p£àªp? ñ €ž8 À” P2 @iðTÐÐð5 ³À¡@¶E"°€0&`90: PÄ § 0Å€¶’ ‡À|ÀîÅ¥ÐÆ ° o ðnÐ`@"°Ÿ  Í °æÀªuà"à$p!&!@w€ ÐÞÀò!€ô!— B  `@‹`pg€m€'0Îর "ç00`" àk°€ª`ƒ ŸðQ Ìðí!Ðî!ÐâP °ï!ÀàQðP"0“€a!°ðî o À"0¢ ="à¥àþ°Q"à+Pç°Ï€— PÒ€Ï`L0š`–0³@Π»!@™@©!ð !0¦!Ð! ¢mœ@ï!€`AÐ E  ±! 7À^ðÏgæ! k!°ß åú`ÑX À Ð07p¡ 0Óp‹@vÐ 0U"0Â!0Ä0-ðÅÀb 3!P»°ÆÇð… ó€>!ðØ!c›À"0J`}oàoPp ÑÐ ÀõàP!•`ø` 0—à·°%'°dÀd 00zp°@!&`¡!@ÔP£)!páÐ 2ÀÑÀ¸×à305à;!€P¦à"ÐÂpó©¬ÐA0Ð" _` à£`I" H 4``J pÔ@mpÖ`$…0« „°‘ á} ¦°Ñ@é°¢!ÀÍ@Š Pbð[ðà@„NP°Œ ; ø J Ÿ!pŒ ¡ Å0 @9! ! !`Ÿ€y@ö!PZ $" ¬p!0Ô põ x a[ð¼!ð™!q`"ð’!Ð2@”!O"0m € ðuP=à# 0Sð. öpÕ!@í=à `†`vpèð"ð8PˆöðºÌ TÐrÐ  Àð@-p0–€Q Ê ð p÷ÐC °Ð"!`4"@É °"p!j   °OàF Pì°¦ àÒ Õ P"Ø PÚ àÎ!€Ü Àá ðã Æ!ðf`ûàS"°ñàÍ`càç àqÐ#!À¥!P-0@"@+!àŸpð€– ð20äpªPÎ Ø `ã„Ðb!ã  Làè¾€o!;0ðpÅP ç="à€Àj  ƒÐé’!Г!°f`Z€£€ÖÀÆ Ç@Ý Å Y!pßð—0…pÏð=°? ã !PÆ@PU  a Ðx–!½ð6m`ü! þ!àmÀ"@~0|!Q`\A""!0"`‘"0æP/ ê0é Ð' @¾!à\°ëp•D BÐ5 ð^ "`@°àÐ {P#"0$"7 €%"î`&"`5 p €7!À¤$¦ð¦WÐ=°„`a`"í *PðPk€l €÷à-!1p[ p™à怤  Z 0"S" ¢PÝ!à¹!0l˜Pt!¶ ðv!€$1 à@PÀ³!ÓàÛðÐÐÑ0Ï`æÐ`ž ÛÀÉ`0d  á ëâð*`\@FPÅ  0Æ šÀ{!º}!ÀÜp À&!p'€!`¼à!ð1R"PÜ@"* `˜@¡Ñ!|@}0€  l@³pmàš 0‡ c Z0(!M@ðÐ$ "äëû P‰!`ñ€wx ¸ @MPÀ ‹!0, €2°©!Àµ%"00H @ƒ `°P@|  Œ0°…`„Pè  V À¬!0ð `¯!0¬ 4†ðÇ  : 0j”[ À\ à*  #À ð !pÚ epf ¶€iÀÊP&`»€º Û!O`Ï `Y "Àè  }@'"@´ p)"@» àÀ!ð`|Î!Ð0*àÅàî à‡àÄ ÀÅ Ð×àz!°½¨ *pA!p! ÈÛ`— ¡ Ü !ðÝ@À'!€çÐ< `Ä!0¤˜ÐP"4!ÀP½ pvP`a!`B"v!ÐŒ! ‡!`³ €¨+p©°¨`!Ð3°!°4 ‘!°pü €ß!Ы0ºð7!pž€ê €Ã!ðòpL"0‚ ./`¥ p1 @÷ð‘0!p«! ”0ûàw Ë 0ë°–0@Y a À´ð¡À-°â@U!0µÀu« pÁ`X н!pXÀÝ!É°ì  …ÐÛ`à""@EÀÈ!ã!ЧðA"@  "ИðÚV"`p!°u 0'`H`(À.!`+€R Ép`o €àë@ã@ëpͰv‹ +"0Í  3 p>"`ä à< œ!¹0àX,!Œ°¾!pâ¯ÐhК!ð ÀQ!€S!ð!àØðÛ€â0Á`npe!PÑ ± @ p€bÐ!ü ÐÍ@ààdp7" @Å!À°¯ð@Æà©ì𯀎Ðj°k0o°çä°¶@–0¥ r `Ð"Ï™Àš°\!0Š!ðê ðüPuÀ𤠠"€"`"‡@ "@‰ó°¸Pœ`P €á`S“ ,! F`Ó0[p "Ѐ*à. y  7  R"u0 PŠà " ì! ~Àûpq@磠äí!@! ` àð]€A"p¿ÀßGJÀŠ ® à€Â@Êб§Уàä@pŒ  ·À '0 @z @I°´  ¯€ˆ ðcÀøphp-!°ü""P! ×! hÀ#"Àÿ¸!àYðè@ à2p `åЪq@¹ÐûðE!€ pëÐ_ Pj " °îð§!pF Pò!P0ó!p>"ô!' #`î!P¶€  ð!°·!`^ å`àÔ°ö!`Π?ðì!pòÐÀຠA!à>"À9 ¾Pz0L~    €`  PÙPŒp³qP]pŠPI@:P” 0°­ @$! ÀÕðÖ •!0¶° "è ã `¿à… »ðyðáðmPwP–0/!€˜ð_!"X°ê¬°+!pt_Pâ`ìpCàÝ (!ð×ðû!` 0©°g À¯ ;.04pø!p{ðý f`V`hÀö `ÿ > @¥0"m@ÑÀo@Ä€P â!°°-ÒðÊ!àn°w€°’°Ú!`8!`·Ð+ÀØP¨0‘!€ÁðŸÐàI!`°Ê°B …°ù€; Nß! ”– ê  >ðƒ°”!Pý œ@À .`ƒPß9@hàÆÛ!°•i$À· ð0!ðëë°^PE°Â Ðp!°T0MÐ6à÷@K €{àÁÀ3@ÖÀq  ÅéÞ@¸ à°Š è ¤p€°ä€(ÐÁ  " ®М ÊÐô¼P:P"p9  ÐÙ! Ð!2P'!pR³Pª ÂÄP“ ïPÔ•@ò  jà  [•!€ Ÿ@üª! „ Ð]°³0¾Pf!Ðè„! É!ÀÀÀð~ðgPû°  äPC!€ó0D!à~  ¡0R!ps!@‡À vÄ  0P0 !Àépx !²!à²!pr° pìàìPí`™àŠP®Ð`>€¥ÐR€0=!`Ç@ªà` "ð¢_ X…  c€Óðd€ÿ @Õp2Àý Ð98 å!P!°÷R 8€ÚÐ7@Üpl!9À§à1 à³°ÀvÊ$0í xÀÔÐæ ¬H! ¹N "@Ÿ ¯pD.ÞàâpéP@á!Á€Y°¥ðJ0O þ`°Р`ß Pîô ðð`Ü "0ˆ€»àcr¤!© /"à0"ÀãðÞð "€‚°q!v 06!ðó ý ¥?÷PñÀ!àÈÖpYàÀü Œà­@q!p²!À© `7ÀàЀP° 0g!ÐB"0Ìk!Àë!@oPþ Ö ÒÐ`ÔÚ Ù`Ûð"às!ð áÜ!h àÕ!pÓ"Ôиð©€L!p”ðL!àöp%Р‡!ªàˆ!àO0×!/ð'ÐyÐÏ ûp… À† ˆ `‰ °N!`¾о@¿°¿ ÀP!àl!ðM@Íd€ ð °Í€)!ŠàjÀf!0²ð­02"-Ð-"0"T p^!€4 ®pŽ Ý`6@ˆ­ 4ðNP¡PPÀÖ!0ì!ð4   1Àl°Ó!  ð·°bÀ«° ’ < p¦ð ¾À¨´@Q" © Æ!@]ð¨Щ0÷ °ª@2!°WpÒ @¶KW!ÐQ P³!("€‘@«ð{ ¦`m  ««2p˜Ði! ùðõÐË{ ˆ`q@×à¸p,yäp¬à¬À­Ð!tàt O!À°Y s!à pý€ée!€@ Sð p.ì ­!°HM €®! ›@H@O°/ PH°I`âÀa0I@7Ðoà—ê! 9"p„ U"0 €¹ Ú`ðüÐO€Å } Ð"0?€- @<"ÐG`¸0ÒÀ•Юp±p¸Àº!b! `@²0 ) P¿´ƒ`Ê0A ‘ðô!†¼!ð$ W ˜0>Ph@ó Àþ`²à` à»® àÌà"P °2! Id! § r!°ÒÀ?"™!ÀEÒ ÐÄ!PJ!0®`¬  `Ù!`' ñ!e àíp0£ ò@æ õ°PpÇ!`©à'@\! !"ˆ!Ц@ù@Ò`!pÄ À)à ÌP8"àGÀ5!ÀHÀ¾  Òl!Ð%PÊpcàÀÌ_pæép¤! , 0 í 0™¢0  TPRpñ!Ðà˜Ðò ùà™àr ›`àÝð‡ Š0~°°!°ó ¶à!°P±`÷àE"@—èàï0;Ž ±!`{  û £!pk Ã˜ðÿ À¿ Pdàû`€@ †€ö`@g ÐÇ ‘€~‹ pù ™ p Ç' ¯`ï ª d€ uðä€=Ð;"‰ð MÀ2 `¦@¬ !`2€Ç py0t`G M@ÇÀ6`l¿°7ÀŒpÉ ÏàÐ Ë Ö 8ŠÙ {P¯ÀÚ €Ô`à!Ü µ!ÐÝ PüàJðs °iPK@Ø î ­°õ ´ÀôÀRÐ!°ÿ Áà¢0€ @ZÀÇ "°M€¿ €pO@ ð¸P‹ÿ ÀYP ç  pA!p F€†ða!à‚p·0#}@0°‹"@#À¶ÀÁ!  g! ‡ ð– PÖ! £!÷0ü€/°«°z0çP.!Àк ðÁ ¨0ú!ý`ù Ððp 0V P­€Ë`ÌС! Î0ø3pŸÀ/¬À4 &p"€…0] Ðu%T€["@p¨  –ðjPÃàõ ™ Ðï°´ Ðê È ÐÐ"Ðñ0èÀ 0Ž p€¾`ˆ0§P!:À0P Ѐ#`׀ਠà)"À*","`-"° :! €õ€’! ¿ ðšÀG €ã L ÀN ð•€!@." 0)ðnp€PÌ Ø!€™!^@þÀ!Ð@dÀˆ`zФP‘p¢ Ú ˆð}!°n `àŽ€³€€n0†Ж  h `. ÐÀÄ@¼ðÎ €î0!`Å Ñ °[ðO"°øþðñ €Ò °˜ ðépi 0e°Ûp­ÐßÂj  Е`PãÐZðo!°)Ð. »àÓ y!pz!vt`“!€" zÀ €Þ°Д€1°Ü°ð"!ßðGP !PÇð÷0K!ÐM!PÈ!Ð¥ àÙ @µp¥ðµ!àóK`Ú0ª °!@= PQ!@·!P×P™ÀC!pGÀ  D!À €åB @è!༠bÀB Pp  ð!5 ü`< P· àáÐí0n!`á@Œ@@ž ò`¤PÞð:"`;"paPàa€z aІ@ ð)!P\ *X0Ȱx!0 ð Ž  `ÍL!0€¢ðŽ`ô  K"ð0‹ { X€ ` À%p$°É pË  î f€9`w!ð¹ p ààÑ`§gð¬ÐPž! \À¹0¿  õÐkp(³Ps0xPT"ðö#À’Àæ>!(`àPÿ é!Ð:@Žpê!ç 0ñ  €u@Ì!  @³àà а 7<-ð­im)`1Ç>õù@´-µ>2÷,@-.¹>2Pø,`-.°båù,¨'P¾/ú€-. †hBÐù,`´-rÖz`ú,Ð ¿ùø.€´-rÖz û, ´-rÖzàû,PR šŠ~À´- rÖz ü,à´-äÐ&`ý, -.eUA þ,µ-òžg¢àþ,x4‡ñ µ-óžg¢ ÿ,@µ-õžg¢`-è0ðÂ0ö`µ-ùžg¢ -€µ-`‘-¸'.¨ê µ-qÐ-.9—½+À- .:—½+€-…-<—½+à-0zÒˆ4>Öðn  …-@—½+@‚(`…-7Œžrƒ(À'<'ú@.ÉÏïsÀƒ(€…-Ýá øü*±Í“i …-Þá ø@…(À…-àá øPý* †-é›ð€ý*@†-ÅsÅ@ˆ(`†-a_O‰(È'Ž €†-b_OÀ‰( †-d_O€Š(À†-h_O@‹(à†-¿ÕâÅ0Œ(Àä Lò¶‡-.<ûðŒ( ‡-Ä9Ǥ Ž(Ð' @‡-¯} 0(Ø'Ii îà'÷×ôÀÀn1 è'úƒ0 Pª¿þÿø'ù0±ü«j8#ÿ¢W` À$§îòGP± Пbª(Õ ê`± È@³ÅpR ˜ÓŽmtÍã l)Ÿ¶Áž4Àp)p± ú: ä(Ö…êm¼Áž4°t)€±+Yƒ (ˆHÒ a@ ï°z)@›-Ñ'ÊÐ{)±K¨ õ0(ŠHÒ`›-×'Ê)0mÏEäà¨(P( üBú ±_˜ˆPmA¾4 ‰)p€þBú°±'÷‡{ ¹¤ö¶Ðj«¶éRЂ(€R bÛ¿`À-sFPʃ(p±Ø…( | Ô&/À± ¯–`à-ïkóÐ…(°| °Ù%/x½8‰¥P‡(À| |+Gб ÞH7R‚-õkóˆ(Ð| Ñž0§ˆÃ8‰¥‰(à| %A6¿à±ßj‡ ‚-|!ÝPŠ(ð| áShºJîžÀŒ(} :5¿`.¿Pݰ(í ÚLgºàj†[˜–À( í Ž«hº@‚-¿PÝà(} `}Ø<ðjŒ[˜– “( Û-úE¡ã€.ëL@”(@Û-•ùck 9·f÷•(pmXõË40”)€‚- ìP–( T.ÏŸwÚk ñá¿Ð—(°í HÔM ‚-ì˜(`{ èiR· k ñá¿@š(0k ¬‡.X›( }t<³, .˜ú ž(0}ñ¦p „.9ÀÑ€Ÿ(@}6‰_ Q÷G— ©(P}L9y  .ÏëNåª(`} ¦&0»¨¸Õ—ðª(Àí4 ZìÀ.ÕëNåP«(€Û-©ÕëR¨#£¸Õ—@¬(°Ÿ#¡Ð4 ›)@k ~- ¬(p} Ñ–“Ìà.°ž €®(ø1‰*ï œ)Pk¢~-@¯(Ðíµ`"-¸  0°(}ÙX`@"-àžÀ èG°( }qûÖG€"-ÀÎBP±( Û-€†€™À"-O.Ø–6-ðžÆ èG°±(ÀÛ-ºfËô#-ÈÔB ²(ÐÖ $%ÁË@#-@P-}É%Ÿ¦~-³(@_.¢<Á`#-°}Z/OÇ€#-À} ¡òì×À#- O.Ãu™²¥¢Òšñ¬äòp 5 9xà]-@²NÖ¾ÐÑ •¯Ä¬ Å-˜††p²o%L€² tµ6½àf H´qs`(–  ê²þKÕ§ ² C†J ª)Ú7‰ è9$O@:-`‡-Ð:ŒP(€‡-lº -°(h(|Býä ‡-Ùôi€p‘(`._ŽõБ(À‡-`à‡-9º&Ü0’(°²"ï©Ðˆ-ÇXæ `ÛÛb0ÿ*`lÒÄâžp”(PŸÔa +pl˽ក–(€lˆwb`˜(`Ÿãžà+èöÿÿÿpŸ ¼B†°>)l qú":?) ˆ-­ðÇp?)@ˆ-C:ÝÝ ?)`ˆ-·©ÖÐ?)€ˆ-ôL£Ë@) ˆ-á­ðÇ0@)€. ;ÝÝ`@)ದ]Åàˆ-€©Ö@) ‰-½M£ËÀ@) (–N~ .Ç:?ýð@)@‰-__ý A)`‰-Xˆ^ý€A)€‰-Hý°A)À‰-–GýàA)à‰-p¥B)°ƒýOAŠ-Á°$R@B) Š-YERpB)@Š-RþCR B)€Š-.RÐB) Š- -RC)ÀŠ-<ñ’S0C)`³ ÑŸ¡y9« "®o yK-º*åžo yDº*2¨o yðD-º*ù¦o °rºzDýà#-àÛ-÷¡Ê$-Ð} °ç3 $-àí ./# $-`_.yÚ†žà$-ð} ³s %-~ q:3 %-ðí …ª&¬à%-Ü-ô˜8{ &-0~ ‚Õ„À&-îdxMó'-po' ´ ©+=0ø+ Ü-MD û@'-@Ü-²Ÿª”À'-î oðgì(-P~½šáP@(-`….}zA‹`(-º*E˜o Þè,º*;º*8`~ß±Çù€(-p~ ‰¹÷)-€~ Á7÷@)-~Žï•€)-€Ü-²êÊ*- Ü-Bêœö@*-ÀÜ-J²V€*-°~E€²(+-º*›˜o Þè,º*;º*° Ø4þB”ôDàÜ-Õ…“' +-1¬³U?Ф °´(º*›˜o Þè,º*;º*P`k .pµ(è$uÍ%ï Ø. 0¶(àÖg—˜Ñ@+-à4åÊÿÿpkà HÀ¶(€_.ë;Ò€+-è4–¼9 4àîg€·(À~ ‘T/HÀ+-1}ÿÿÿ$€kæ Hà·(Ð~ \SH,-ð4xaœýFèôgи(à~tÀm@,-P8=zk —.X0¹(€….ï~†€,-ø4ÞLí0Hðk0àº(Ý-ÊÔs#À,-ÐkYàkYø 99îÀ _Ÿ3‰1°Ï( _.Š.Òð--xY°[Y° = À _ø1« `Ñ( ·->n^@--µ X*gpwYwY² =À _0Ù5‰1 Ò(ð~ ¹þÿ„€--ðkYlY¶ =À _3«  Ó( Ý-×2fÉÀ--ésyàIyÀ _ k9åöH`Ô(º*™o Þè,º*;º*Ð gdy³…y@ýÀ _GÍPàÕ(@ì-á=2¶à--°k?åöHÐÖ(º*™o Þè,º*;º* MÍPPØ(`s.ùILr .-@Ù9‰1Ù(`ì-÷óa`.- ðä @ês:7« Ú(À‡ö‰ .-  w.·dNŽ;à‚-GŽ—PÛ(°à ÓÇ«à.- å  °¹G1 …LåÜ(Ї QÏÏ /- ð× ƒ·1ƒ-k8ªD ù)€ì-©&t`/- 5ß  ê/(91÷0Ý(Àì-û» /- 5é‰ù(/@ƒ-q8ªDÝ(àì-® à/- å F=¶Ç20?1÷PÞ(í-ôœÒ 0- å ت—ú2ÀkfEI°Þ( í-lž¿å`0- Àk.XvoéJ8 NŸðà(@í-á ãö€0- Àw.ú7K¹3`ƒ-β)-€á(à‡ ÒŸ:2 0- 0å DW—] @ q±ò â(`í-ú¾Éºà0- @å Ö”È" €ƒ-Ô²)-0ã(˜!U4µé 1- 5ù;N+°#q±òPä(ÀàÊSô`1- På Ã!Ù^Ðk Ê~ýàä(ð‡ 3ß’ 1- `å Bkì4HÙ å(€í-ëÅ8ù2- Ÿ ïá.Xæ( !F ÿÿ 5ˆcµA5P={Àæ(˜3™fÊíµé=x"0Ÿ õá.X ç(¨!™þ)àé xÖ ©)°!5†{¨Ðà\ŸX ¨(@T.]áu`em4˜Ï0ê uÈU¨`ø(Ø{yA l.OúÓÆÀ¯)po'€e cóü °/,àà…Z¬à2-À!ÖD`3-È!³2“ l.PŠ ðOŽù€>- ˆ Æ—kdÀl.Ø!SïºA 4-0ˆ KQïnà4-@ˆ ŒJ³ `5- 3­Ùù 5-Pˆx„¶ü 6-@ã Ccžæ ‡.ð!Ä$`6-"ÿwÃþ`ˆ u¿ûà6- U.:ØÚ$Àx-€ˆ}G+³ 7-"¶ZáÀ7-á PkHT@8-ˆ ²¡}m€8- Š (¡„7à…. í-ñ$q¿ ¹-po'ЈJêØðð*àg§ïÿ á+àˆBƒæö 9-Í &VV#°3ð,üÿÿÿ×.9p¹!šo ç.è.Dº*™o é.͉‰“w¸38öÒ~`9-ðˆ/³ˆ Í ‡8À".€s.mìÚ`8ôÿÿÿ " h îÚ-X°ä+Àd d÷ 9-‰Î­¹0Í hO á\ßà9-‰ q²0áéw„e(" ˜›> ‰ Æ‚¶ 0‰ äuÀ9-`U.5 ¨d€Õ:<õpo'0"ÜOh1 ñ*á |xâÀ;-@‰ » k`‰ö½Ÿ  -³ÿÞð *€U.= ˆ.€‰ ýæ÷aÈ3’x àÀí-‘+ÞÍ:-Ðd ¹ð :- ‰ ÐYL`:-ÀU.ûÄR`ˆ.àd wuû€:-À‰ [ÆQ}À:-Љ+¸ôÀ-º*@á «RO -º*àí-/|úø.ò§Lš`p.pÍ [ùgóÀˆ.Í -Š+k ‰.ÀÍ ÆFR~€‰.V.¼GÈLŠ.ð‰ :`³ -º*î-…¿ˆÎŠô Á î-Dš€" Š %ãÀ<-8"7F<-ÌKíÔÂ@Šðêä«`;-`á O¢Ýà:-`Š ¸~²© -º*páY½˜ >-€Š „xøùŠ 8 u²°Š ¯Re;-ÀŠ n[WG ;-Њ{þp° ;-po'€á „ ÈK€ñ*àŠ \¢à;-@" ;ǰ`<-‹1ÖJ$=-€î-TŽ>® =- ‹L2­Ý`=-Àî-–;H"A4F =-0‹òFVÀ=-po'P"x(—°ñ*X"+çù¶P‹ Œ*ô¹>-p‹ã˜ÕH`>-@î Ê”žàÝ-ï-¦°Xà`?-às.a§À>-@ï- ’å?-Àá¥ Ü ?-‹ ZÄ0@?-°‹ ’MÀ‹ :Œ[°Þ- †.Ûàcv`"¦D°‡Às-po'h"6.Ùp‹(ð‹„–’-À—-e$Q…)Œ jXêŒ ¬ŒcÃx"Ž;yÿ€"XtpyXC{àç(0Œ,­€?-àk Ê~ý@è(CˆÔJ€¹-`Úé(@Œ ËKΙàÎ-º*ðk 2â.X`é(PŒ åp—øÏ-º*h€{ ê(Ðá ƒ ¨À?-@Ÿ 8â.X€ê(`Œ "Ôëj€[-p†{@ë( Y.:"ÂÝ`Æ-€Ù YÊ~ý ë(àá ûž™àY-@V.(‹ò• ¹-x`ì(`ï-rs}@v.Ù )ò.XÀì(t.–}@ Z-@Y.„ J€Æ-¸#w‹€í( Ù /ò.Xàí(€ï-<õÓ Z-€}‹ î(ðá *àZ-l‘ãï(€Œ ƒ*§@[-¿f º*¡o Àf  º*åžo Áf ;º*ÐÂf àá-º*Í—8Uˆ£¾ÿ€ð(ŒýÔOà..lMåŠ4€ö( ï-Á±§xÀ[-[Íäî°ù(àp-®,è \-@l.]S^À0X,ÀŒ ªšœƒÀ\-¨›æ…À)ÐŒ>@Àƒ-_S^Àp )Àq-³šÀv.°æ…p )àŒ 'TÅ„-³Í¯XÀ )àï-D Ú @-`Î âÍpä »-¸š6 `)ð-XŒÝà.¹Í¯X°) â ]îàq m.À‡š6 °)ðŒ Ùá‡Àm. „-cS^À )˜¨µÿÿÈ¡æ…Ð)@lµ…ãÀ)0â ð _Y-Î ÖŽSà»-г§¾ÿ@)Àì¹ú‹40) 7Ã* `X-ØÇâåî°) ð-ƒ¨” u.Pl¿ú‹4 )  Qta @Y-@â õÖ— @-°Î Eé£þ ¼-€ãè– &à¼-Àt.|X:¿¾-°e 5ؤ—@¾-ˆ­ª’éÀe ÖÍÔÀ¾-àt.É÷RW€¿-Ðe a„¥ À-PÏÑã`Á-ðd E0çßÀu.Pä Eò{<ÏEÜàÃ-@ ŠEK`ð-ZÁ½ [-Pâ D’x`â #Ô¶¿` aÉ’”€ð-žaŸ@~.(/.¿RêpâTŽ`» ]-€™2Il ^-'ƒ ©`^- ,iDïñ-p=Åo ñ-˜Rµæ€^-e аŠ˜"Š¿þÿ _-f 'nj "»l ê`_-@4­Ë¤Q°"rK ê_-# Dº*›o ' 9À«- `•-º*™o . ¸"A¡¶ÿÀ"à3 €âçÇ[ `-Ž ;n‚¬@`-Ž ?Mò-``-@ñ-‡&rŽ0ua`ñ-}Z >.€ñ-AõóG `- ñ- ¦)À`-Ð"Ë!ñÿè3´ êàñ-•ÕòG „-ò-pë¤)a-pu ÐP½Ü ò-ÄÃÊ…â alW a-€u]¿áž â Fa¼ @a- Ž mZÿó`a-Ø"b± ê€a-ð3Dïÿÿà"k•A a-0Ž z_R•Àa-ø3[ºÿÿ`W.Ä eÚ@Ž „Áë‘àa-PŽ ^=Ïb-è"DùÐþÐì$×âž°â *”R@b-Àâ-µ?Èàx.4^c ïÐâ nÄ~`b-ø"ì_‚° ã|@ò-‡üÆB p5š²ò ®) p1›>ÿÿ&àÍâåî ) x5 í׋°lÐ Œ4à ) P#+ùÑÿ-øÞôåî`")4ɼ´é x1݃x.ˆV§À #)  g$m¹ €5õrÿÿP§)Æ/†Ð$)4·µÿÿ ˆ5Øéèÿ°§) .ŠV§ÀÀ%)#72 X#P—?È/†@') 4Ô¯çú 0æ /h¶Hà™-ô¡ËkH)€ô-: ˜x d- 5JÈÿÿIÂnRI) ô-ƒQÀd- š-ú¡Ëk J)`t.e áxàd- ˜5Íæ57AÈnRL)Àô-øåxe-X4°±ÔA `Ø >B*âB@š-ŽV§ÀÀL)@PŸY@ e- `#ov´@ Ì/†pN) ¬÷/ú‘@e- @æÏB`3ÀlAŒ4`O)0¬ÌÖÖž`e- àw.ðG–êU(Oæî°P)@¬¿AgÛ€e- €1b‰B,`š-a«À@Q)`צo>~ e-  5(†=ô(0Y3†ðR)àH..«ðËÀe- ˆ1Š•(— °ó(€š-a«ÀàS)P¬ ¬–Q‰àe- ¨5š,—.8[3†ÀU)`¬ i"¾f- °5$ÃC¤ š-mfÚl°V)p¬ ¶ë`].@;3a0X)p×ræŽF f- ˜1·×‘¤ Àš-sfÚl°-PP ‡ÃÌp@f- X8bê¨'HA3a°\)€¬ ‹éþ`f- `æ†Æž[Càš-!a«Àp])¬ÒÄ#U€f- ˆ&®$ LP_3†À^)@N-\ÉÍ f- ¸5N5qMÐl ¨ã° -`P #S¾Àf-  1é4OXʾÿp`) ¬ ­4S¾àf- À5ñÚ–±àløö”4a)°¬ dÉ¡g- pæyë¨zP`ßîîða)po'À¬ ©•ê€,, ¨1»AûQ€Ÿúö”4€b)po'Ь b dx°,, °1OCû0hßîîd)po'('ÿ £@ó*›-†ŸüÂðd)po'à¬nu¿ê0ó* €æ­H0â¨)pÄ]„ˆpf)po'pPRS57à,, Ð5äÖR ›-ŒŸüÂ0g)po'𬠧«R—ó* Ø5ý,*ÌxÊ]„ˆ°h)po'­ ý×Ñrðó*ðlþö”4@i)po'­ úõšÀ‰+ à5Íð¯)po' ­ ¿Úr€Š+ š¬)ÌÓ po'0­ ŒÝˆšÀ, è5 ®µì>p±)/ç² ê ¸1• $po'@­ 2§èrÁ,x.SW,Zpo'€P /Å–š@õ*€©-ã(¹@<,po'Plµàõ*p0Ýu6Wpo'`­ ú˜ðÐõ*ð5Á,ÿÿXe êæ¼§ÿ gPr O1×fÀg-po'`f >kÛçà},pØ i]qfp­ å÷£àg- æä,ËS_À©-L’ P>,­ Ë¿Œ@h-ø5}.Ëd`N-߯Í`h-°æ ¸ˆ)±e I.:eÕe€h-6JZ@R ­ Çþ# h-6x‹ î°­ ðƒøÀh-xçýÿÿÀ­ ´º?vàh-È1é>Vö P ú(ÅJi-6wT<[ЭµÍ  i-Ð1Þÿÿà­+wưÀ}. ÝGÜGÀ _°P ¦—`i-Àæ ¬—aÂÀ¨*`r spH,pç zrÈÈàJ.Ïýøc n-€ç sÈ顯 ¾rÈÈ0QX½¯= n-ç jkÈÈp® ‚·&àn- ç ç„bK.zò o-°ç ç„b«-+ÁÌPJ,ÀØ {rÈÈ È-ný¶€Ñ)Àç sÈÈ€®­dG}ào-Ðç ¢lÈÈ® ííÒ/ p-f Kþl£‡,àç zƒÈÈðç ðæ„b ®Q²ÄÙ p-ÐØ “ìtŒ K.¢+hÀp-à.$Ë•|àY,è nÈÈ× pð›× q- è }rÈÈÀ® î•Ó€q-À/—zÐ& Å-po'0'ÈYT,ö*po'˜ó©Ð@0ö*0è ç„bpo' …ëÿ/Ž+ «-'OÍÐZ,@è nÈÈpo'8'Q•~2 Ž+`É-“>P`pÒ)po'Ю >çl0+`è ÅmÈÈpo'à®ÔŽzÐÉ,¶-Ð4ÀÅ-pè oÈÈpo'¨Ž$Ž9P÷*è ¹lÈÈpo'¯ Bó½<€÷*à.›`ö°\,Ù ;ƒÈÈpo'@'^AÏ:°÷*ÀÉ-ûkS‰ÐÒ)po' ×qq›K0ù*°è 'óuŒpo'¯ ¿Vnù*àX.¸°`÷Æ-Àè ¿vŒpo' ¯oúâÀù*po'0¯ #HXÓðù*po'H'>Å´A ú*Ðè AsÈÈpo'`QäL¦Pú*Ðé Q°íÇpô(po'@¯ WÔ¦ÌÐÍ(àè +mÈÈpo'P¯ šF00˜+ E.Û5Mkpo'`¯ V߬ûÀ˜+ðè Wß¡kð« ‚(Ëé H$úepo'P'ší¼4à™+¬ 0±,@é F휞po'€¯ 2ó †pû* é]{æ>po'¯ )}!– û*'ÍÆüÿpo'€Q × N€Ðû*h#Óÿÿÿè1VíKÿpo'Q Z'Éõ0ü*6çà êpo'°¯Ʀã`ü*¬ ¾úb&po'À¯ ® J‘€º+0é À+Þpo'Яº¨¬°º+ 6pÕ êpo' Q •à±–àº+PÙ §@é v–'po'°Q Û¶JÈ@»+Àx.vÝý po'ð¯ ýïë »+Pé Ì¢Zpo'° Ž®´Yл+(6ì$.üpo'° (ÇÒí¼+ð1Ú¯S,ÐÞ' °VÐÇ0¼+ 'Û5xêpo'X'øá7ÿ`¼+`é ¡õ0O-f­ökr-ø1fñÿÿ86Ñ# §) €é,º*ðé,º*`ÙÃÒH€§)pé èú˜àà§)y.h™Ûä@¨)€é |Èp¨)é ÓAÁï ¨)@° ú©ó¹t-R ì§ó¹ t-@y.ótަ?, é ÃùnШ)`'iµN+`y.F`Áu©)¸pê 1øõôAh'gàApo'P° w%°½+°® ÑÅ»ê @LS‹-!‰^ýÀC)p° PIïÈR BGïÈ`‹-б$R D)€‹-"ERPD)ÀÇà‹-Ô -RàD) Œ-…rÖ@E)Ш¿þÿ m.NrÖ E)€'¹&ú`Œ-ÐNÖF) Œ-¦‘È0F)àŒ-ˆ ~èF)-F2ÄãÀF) -¸,ŽÖðF)@-qÑÙB G) ° ÙlêZ€-6Üåz€G)è¬`ê -Z"æzàG)À-çÙ@H)˜'•÷ôùà-&çÙ€k)ðN»Tú@m.çÙ@£(Ž- çÙ £(À° MëÇ— Ž- ä:Ú¤(ø–1Ò@Ž-ä:Ú`¤(`Ž- ä:ÚÀ¤(€Ž-ä:Úàk){ê Ž-° }l)ÀŽ-Å }pl)øú8úàŽ-Û­iÐl) -°¿õ`m)à°צ~h1L7Ò@R<êé¥\8Ò𰇌‚¾ HÒ°'­S,(¬¹Ò8A1¿þÿ@` ±ƒ‡Ú­ ±*xç­H»(¬ÿð'è¨ê(‚é¬`R 6v|@± ´›ØlX^ê€ ßîî¤(Y.70÷µ@Æ-ˆrï¾ÿpo)Ä©øîs)`,¯Ýþ˜Ê©øî€w) mSX°4§(((nÌA¨Ø®à})Ø1üBúÀ#Ø®à€)8(HÒ@(Óu”A°Íg¿ÿ „)H({þBú@m‡A¾4à†)¸•)ï`ˆ)h•HÒÀ›)ï Š)€›-XËÍ`‹)€Y.ó Æ-È–ÒR“àŒ) ›-ÞN&Ü )Ь­Ž )À›-äN&Üà)È#²­Ž`‘)Rñ‡`m*zäP’)² g–` Y.bÿ·Ï Ç-¯,Ø(œ¿ÿp“)@N.b™$ExÙÿ)0àfÝ%ïP•)`N.¨ª Ÿ^õË4à•)€O-ÀÝ ÛJ& 9ð °¢o ]& ðû-º*åžo ^& Dº*‘¡o a& º*èlÝ%ïP˜) O-ÔPb¾€mŒäà˜) N.zR:—ÀY.Ð6I–@Ç-ð®¿ÿ`š)ÀO-c§ß|àN.Iö[ø€„êÀŸ)¡Ð4àð(P-R"X'à16ZÒˆ¸/Œö ² 0² ßq†X(&¬ÿÈÍâÇAP²Ý c`²7p÷F°Ó ÑwŠ~p(/xx(:°3À²§ÆGˆ(¶RÆóàÓ â}`/¨*¬ÿ¨(©‰ð²­´ð@O.ö»ß Ê-åâVÃ`Ó)³\±n³¾,J ³ÉW0Ìw Ž zàQ-x–|Ã0³Œ…Ü@³G0XîP³úÍn2Ä)¬ÿ R OÅÔùp³ õ=6@wà˜s€³ ™†g~€t-°(à¦ê¸(ÿ›>po'@Ôá”tÀµ,po'³ NÏup@¾+Ë-"²:Ú Y)po' ³ òð¿+°³ ‰Ê%Àt-À³ñ®™àt-г µ›ÖË u-pw˜sà³Á#ïš`u-ð/PÏ&ÀÇ-¨"X•à^-ð³VŒð  u-`Ë-A¯:Ú°Ô)´ }P†[àu-´ (”À`†.¸œµC¤°Rù±‹¥`v-`O.iá§Ûàv- w‰’i ´ V³ÞÚš(0´[m?øÀ¿+@´ £ëPÀ+P´ @Gž…àÀ+°¢ 9l=Ý0Á)€O.BYËpÁ+`Z.Ó…¦ O.{ÉIßÂ+ÀO.Eøð¡(àO.EðÂ+àÕ 5ñÓP.&ЃڀÃ+@-2°¿õÀm)€-^¢¨² n) P.ø1Í]Ä+ -s¢¨²€n)€´µª^ Ê+À-w5àn)ÀS-œOyhpÊ+à-ƒv5@o)pè'´ °†ðË+à .`þýÏ o) é'@P.»IPÌ+-µŒèp)Pï'`P.)íz¥€Ì+xÑÑŒ¾@-wÎçÙ0p)ð'€P.×Éþ`õ+ Ì-?ßÃòàY)Ô .œM à-`-åÄp)í¿Œ¾€-U ƒèðp)po' P.Ä;jø+€ä e÷4ø€¶- -|[èÙPq)po'ÀP.„Îâðø+À-‘[èÙ€q)po'°´åz=OPù+à-Š‹·¡àq)po'àP.°»Ý‰Ðú+ ‘-Ÿ‹·¡@r)po'Q.˜ÿˆ Àû+@‘-Œ‹·¡ r)po' Q.#ßOœ€ü+0xÑŒ¾`‘-e¯·¡s)po'@Q.IÞ„ ý+@Ñ- XÜá)€‘-z¯·¡`s)po'ÀT-po'@Ì ô<Ù -,à.E%¬ÿpe Gê½mpo'PÌ hχÀ.,Üñza3ý)po'`Ì p€ê /,pÌ¿Žzpo'€Ì hóP/,è.äôMApo'Ì Ñ ô €/, Ì ’læw-0ão±%2@w-`T.—ôÔ\€w- T.Zn1à†.°Ì ¹ñ8 àw-ÀT.È:ᦠx-ÀÌ2Bmõ€x-àT.[Á1Ô x- ~-es(© ~,U.pZÅH`‡.@U.ðf‡µàx-ÐÌ ãÂ]À‡.àÌ<À2ðÌ yÖ•„` .Pã 0Œ¾iˆ.(4ýÿÿ-lÉêLž+x#ýùþÿ@Í Ÿžn s-®D“Ðày-3A 9€yY¡o ;A  º*åžo i0Íà‰. V.S˜Õ¢ - e •¸-€r.pã 5¾C€-/€“-¸:?ýÀy) “-P_ý z)À“-Iˆ^ý€z)à“- Hýàz)”-–Gý@{) ”- p¥ {)@”-²°$R|)`”-JER`|)€”-CþCR|) ..Rð|) ”-ü -RP})À”--ñ’S°})à”-;?ý~)°Фê•-_ýp~) •-‰^ýÐ~)@•-Óp¥0)`•-{±$R`)€•-ER) •- ÿCRð)À•-öñ’SP€)à•-vrÖ°€)pq ò,3Ñðd,–-øNÖ) –-?rÖ@)@–-ÁNÖ )`–-—‘ÈÐ)ð#ZP7€–-cõÿ_0‚) –-y ~è‚)­-L¡Ñf,À–-72Äãð‚)à–-©,ŽÖPƒ)—-'Üåz°ƒ) —-K"æz„)  ùÑã°¼,@—-MÏPp„) ~ ®Ãб€&-`—-‡­/QЄ)`  ¼µÑQÀŽ, —-F{ØP0…)à—-“´ÆÁÀ…)/…;±°Ë_ 9 \l¡o Î_  º*åžo Ï_ Dº*Øžo Õ_ àá-º*Î T}Æ 04fóüÿà¹-Î ¿ñÄÓº-°q ªGµâÐ, Î ¸JÝW@º-@Î %í&ëÀº-PÎ mï á»-pÎt^ݬ`»-€ÎnHР»- ${ãA`V.ð,Š ¼-à  wÊ]` - Î®ÈÙà`¼-àÎ °ÎŽ6 ½-($ ¿þÿðÎ 7v+À½-Ï žÌ}€¾-€V.ÁÞ. ¿- V.Àý¶@¿-ÏÒg¬À¿- Ï ‹.‘]À-ÀV.g¨òé À-u.•ÞQ;àV.’A!QàÀ-ã >õ´Y Á-/Þ6(Â-àe åbWsàÂ- ã ˜­–Ð Ã-€Ï Ã9DÏ`Ã-° (I¶§`¡m‚"úà–( Ï ²VLKàÃ-°ã 7SÊÄ-°Ï ›·[@Ä-ÀÏvɧ΀Ä-Àã ÚƒÇÀÄ-…&ðe kE;à/,po'àÏ °„ÔÔ0,€!(ðÏ ÚäÁ@0,0/|iê(‘R­ÿÐ ˜®Í‘8/‡0üojê Ð &Š6÷0Ð ŸºÌ‘@/y7‰*)H4ˆ<ÑПªÓÐ4@ñ(¸»*ï` )8°S+ðà›-–a§Òð )à"( u.yB$1,Ô/˜p¢)@Ð £aš01,œ-œa§Ò0£)W.žƒÍ1,Ú/˜€¤)PÐ :!Çð1,mÃÙ4p¥)@s-[î€2, Ñ3ï0¦) W.!F+ œ-!ºÑÔð¦)`Ð 8–'(_xYš0µ)pÐs(²Å€$ª Òòðq+@.'ºÑÔÀµ)@W.iCGÉ0exYš·) &.EÌ\€Â, m¿ä ·)€Ðh«ÞÅ8á¿ÿ°¹)`s-4Ä/@°m#úÝ4 º)€W.6ôL @1â7ïp½)@u.ÑúÀm%úÝ4¾)`u.DëØàP3â7ïp9)@å¶+@œ-ÇsÖPÂ)ž0GþGX2 ›Ä)Ð Ø„È`œ-ÍsÖàÅ) Ð 3Ò(s` 2 ›€È)°Ð °(sÐm)úÝ4ÐÉ)ÀÐ Tsm#h7â7ïPÚ)ÐÐ}Q¤àŸ…‡Þ4Û)àÐ ì Å;p“o8ïÀÜ)ðÐ iKÄ;€œ-çs=Ö€Ý)Ñ ·6ix%2Å›0ß)Ñ {jtü œ-ís=Ö à) Ñ IªÜC€+2Å›0â)0ÑÚýL-ðŸtÎä ã)@Ñ Äèíˆrð¿ÿ0å)PÑ ÷‚àm¶â4 æ)fpÄì;ï0è)`ÑñŽL ¸â4 é)pÑ ¢bœ@Î-,Ãìà×)€Ñ ±îóDH/‚¶*JѨ`$®`O-€Î-Ì*ÃìØ) Ñ6n”P/¤é}FHާÅe°Ñc=TX/<Â-iÀÑ TÔÓ?àÑ .Áâ2ðѽÔè`/J;Jê W.I)ÀW.Šð¡_P4GK.êP¢a-PFpÍ(h/lT6`Ï-%'$Ù)Ò qŒ´èÒ Ø.ö Ò aAè 0Ò ›Pp/¬±ÔAx/­±ÔA€/®±ÔAP¯±ÔAˆ/bÒNê@ÒuÂ@, %(PÒ k:þÐÐu, f~Y^ `v,`Ò­qÍ<€w,pÒþWŸ<Ðx,0f º6‚@Å-€Ò k»+`Å-Ò F +€Å-àW.Q$ãpo'@f ¤þ/Óàz, Ò¸}U ˜-Š'Âð…)@˜-IâÏÁ`Í)€Ð-~¦]0Ü)À.h‹ ÂÍ)PfyúD»`˜-»C;ðÍ)po'°Ò Á1B`|,€˜-²£í; Î) ˜-„9MÌ€Î)˜/±¿þÿ Ð-ùÐ`*à.{™­Ì°Î)po'pf ° bp~,À˜- =7LÏ)po'X.‰»Ð~,àó-¯Ó¦ @.à˜-—L@Ï)po' X.ò ˜20,™-»t. Ï)po'@X.c1º", ™-²ðÔ.ÀÎ(po'`X.Aû¿ð,@™-€>¢1@K) /6À`™-`Ð)po' X.ŠËHØp,È-¯ðüàM)›&ÀÒû”€Ð,ÐÒ°Ž°ƒ,@È-_Ñ… N)à}.V1æÀÐ)€f «a«`È-ÿŽðÐ)°/C÷ ê Z.¸Ï¶ Ñ)àÒ (È»Є,€È-¯/s¶ðO)¸/ÝuÃ@0…,ðÒ À— ÚP†,ÀÈ-Ò õưÑ)àÈ-'uîÄàÑ)Ó`ݦ ‡,É-œH# pQ)Ó ÷Oö;Àˆ, É-ñ±Ò)@É-/SnG@Ò)x=hÉÿ€j€É-¯À¹I S) É-¾WNS Ò)È/ÁþÿÀX.F@¥[àÅ-àÉ-_W5¢Ó)°ékÌmf0©)Ê-{Ùž‹ÐT)Ð/®ÀþÿÀé ¼úп`©)€s-|…{Ú Æ-0 QhoÀ©)P­ š“#€Àx Ç•ðé U<ÂpÙ ÙÆê 8×UÀy.—®äÙê (·Â ê Ï1Z0¯)@ê DO“Ä`¯)Pê‡9QÕ¯)0£À1 8 â-y  58³z.ƒá~ ±)@6½Qgˆ`ê 4ËH6¢ç˪0F,P6âc-,€@.¦D9_Àâ-°ÙÑíòÆX6ߊF3`6oJ•°Ð’*pꂈu€ê ")pÁh6„¯ûÿp6é¢Î2I%àÓ* ê0!I’x6JçP\,@a."þ¸ä-°ê’7¨¯^,ÀêTzÚpª*€6Rœµÿ0«*€£ ]V¯ ä-°£Û Qà·- 30@A.ø×Ra€å-€A.éP+7àå-¸ Ñ36à£{°åµ@æ-ðC ä–d æ-`4!Ê­ÿ f#8ažP‰, Ófž‹žpŠ,0ÓüŸ\ž‹,@Ó d?æ`‹,`Y.;(º‹,PÓ +„ —àÆ-ð‹,°fn&=mÇ- Œ,`Ó öÿ?~ÀÆ-Ø/ ¬ÿàY.k‰ ØàO-Àf ÙÔ°°,pÓ “Ÿ?Å ±,€Ó;Šž`²,Ó ¢ã ³,Ðf k wÿ´, Ó \´wÿµ,Z.•jÜa`µ,ÀÓ ƒr€#»‘¬_z}èÿÐÓ á}`/€u.,×A×ðÓìI‰€Z."ÕC’0Ó)Ô žéV@Ê-Ùå¬PV)Ôu©`Ê-—¡ÑâàV)`ä  —§ù€Ê-qrkºÓ) Ô fÍ™w Ê-„ãOèÀÓ)0Ô ¨’Ú†ÀÊ-ìH:ÚðÓ)@Z.»ÍEàÊ-ÙH:Ú`X)po'à/-q‰µ, Z.æH:ÚPÔ)è/7ÄÎ&`Ç- Ë-²:Ú€Ô)˜m-Ï&À….@Ë-²:ÚPY)ø/g0S@Þ-€Ë-.¯:ÚàÔ)ðfèó ¶- Ë-•N/Õ)g±Ó³ Þ-ÀZ.ƒ_Ó·€Y)PÔàô³àÞ-ÀË-LðN@Õ)`Ô‰6¹à ß-ˆå-ƒ+À3-àË-$òNpÕ)Ì-òN Õ)pÔ°dÁ Ì-ÕðN°Y)€Ôšzf@ß-@Ì-ÆðNÐÕ)0O†¾€ß-`Ì-(y©šÖ)g $o›âÀß-€Ì-gÝÃò0Ö) g ÿRì`¶-ÀÌ-0ßÃò`Ö)àÌ-ðÝÃòÖ)0{¦Š¹Í-áÝÃòÀÖ)0(Õs€à- ¶, Í-÷†C‰Z) =3Q¤Àà-P¶,@Í-gqzðÖ)0ƒP¤á-°¶,`Í-?qz ×) 02ýAà¶,€Í-0qz@Z) Ô =Ç4(04 B·,ÀÍ-áqzP×)00”êàÍ-µ–¸ €×)h44ê(8ƒêÎ-R*Ãì°×)0gyÂø\¸, Î-*,ÃìÐZ)80cŒ©9˜Æì;ïë)@0@>W8Àœ-@8'×Àë) ~ö®œÐí)àœ-F8'×`÷)¨„ö®œàø)ðm¼â4pù)°Êì;ï û)n¦ß°û)Ð#¤2ºÿý)¸ÿb»í€þ)nÀYÊ3àþ)ÀÎA$î ÿ) nÌ‘û;Ðÿ)ÈÚyUö *@n.9ê°*ÐwͯÐ*- ê`*ØIίP* -òôC°*àÀÍzö *@-™ñD0Í)èg¾‡ö*`-µ%êð*ðó㞯à*€-ÐG@*øÀÎF` *Ëq‡¤à *À-éŽ]@ *Ø#·[¤0 *à-…¸£' *pˆ ÙI Ö 7-0n C…[à *`.QÝßp*›¤0*ž-$ßß*H0é€ìë0¸,°Ô Mëö`¸,¨±™ìð¸,ÀÔÖî\È ¹,P0À¶d°¹,X0áÒ ê`0ˆ(âyº,h0´}}@º,ÐÔ¦ºm@pº,àÔ [¹;j º,p0$qÀò0»,ø#5#ã”ð»,$ðˆ° ¼,$Rv#{@½,` &¬ÿðÖ Vn²ºp-   ÏçÆ°  PÌ€ÃÀ ]‰T¦0-`Cj¸¢À-$+ƒ•’ Á*ÀˆÊîf9-$‰Ò{]@-Р ªR -ð  « üö¡ ™rqåP-¡ ­ 7t -€ ÷ ê ¡sÄç-0¡c8Ç|à„(0$ër÷ãà‡(Ò-eyŸ*@¡ ¢J…8$Kýšò”(@$ÅIÑÿ@á- ”(H$"ŒD •(æ9`!£o ïðû-º*åžo ðDº*‘¡o óº*P¡ =äð¾À•(¥ ²“˜íàø-@@.ŽLUr –(P$°ûÿ`á-À˜(p¡ fį+˜ ÙIÑÿÐ)X$°ûÿ@+`$[ýšòðž(  ÕIÑÿ°Ÿ(€¡ôMžÐ (¡ —f=€À¡( ¡ &Vi à[.ÌæõB`è)°¡ A ¯ k.!áÎLà¤,À¡] ó ¾(h$¸îm `¿(p$ ð>€À(\.‚N/€é)x$¼sÍòp+¨ ÑTODСàzÕæ0q+ˆ$ï’ê°CD#a–€&.‹lТàÂ,À [¤ÖòPr+$qz*B€r+˜$3 ùŒàÆ( $†-Ž s+€%2ŒÕtà¡oqû u+ð¡ÚÆ@€u+À0îÄ0t+¨$R^såÀ¦)¢ úí@Ê(¢ ~at Ê(`Î-Û*Ãì[) ¢pŒŠ,Ë(ÀÓ-âí) ¥ E í–Ø ž±Ìÿ@®) Î-ô§÷0[)°$èÛd|w+ÀÎ-ª @Ø)`@.bø0w+àÎ-Æý pØ)0¢ è5~•°Ì(Ï-`0  Ø)@¢ÂuàÌ( Ï-µè_³0à(¸$æ™!¡@Í(@Ï-Tç!)ÐØ)× Ãñ^ Í(¨% [€Ï-‰ U$0Ù)`¢ T'Là¶)€¯-1ÒyœÀÇ, Ï-Á—Á'`[)p¢ ža @·)ÀÏ-1ÎT%Ù)È$Ï[з)àÏ-E|ï'ÀÙ)€¢WVÁ0¸)Ð- shF*Ð$NBÃþð¸) Ð-0²Á@*ÀC Ôˆ]@Ð-½¢LÅp*ø †æžž€¹)`Ð-¹ïϬ *Ø$ˆ"«à¹)[.¹Ù´Ð* ·Õ¹gpº) [.Ø–Ñ*`#&à$KÃÝ+к)¢!›UØ ½)@[.ã²Ð0* ¢ µ¼• ˜-¼Ò´õPï)ÐC³Cf À)€~. š¥]*( û‘AÐ%©Í°ìÀÐ-Dà¥]àÝ)`[.û"…ð*À¢ Ä5íÁ)À ð'GýàÐ-o…»˜ Þ)Т Šž Â)€[.ÛæõBP*ࢠ®El„Ñ-—W5'ß)ð¢C[D¿ [.æïþ°*£ ;ÑþG Ñ-s€à)£ ±è×`°-Óå¤þpÌ,ð$áYê`Ñ-ÓXÜ á)@ ‡o{Ë€á-€Ñ-;ÏžÍ@*ø$ÂxÿÀá- Ñ-ОÍâ)P ;ôüÿàá-ÀÑ-+b  *º*o¤o ðû-º*åžo ;º*Àº*È0ööÿÿÀ¶-po'%í#Ž€Â)%¬;ê±po'%0àüàÂ)%ðÈÀM %A%<po' £ H'®C`Ä)@£wªK`â-× !  â- @.# @ûã-P£ ²ÐìV@ã-`£'çÜ ·-À@.ΡÕ: ã-à@.QX)Èàã-p£jlk ä-A.ìZ `ä-£ È“Œx€* £ ®‰°Àä-€B-aµ”<å- A.sÐÃ8@å-`A.mß­ å-àC »ÀÖ¡Àå-À£ýbÐTæ-У «Tt¨ æ- A.`ŠT˜¸-ÀA.}C.æ`æ-ð£¡Z¥¹Àæ-àA.3J@¸-B.€øæ`¸-¤ §|ô‘`ç- B. úpРç-¤­ÓCd€¸-0¤BJR¹è- D-.Û¿@è-àD-« [ ¸-P¤ ܱ¡ è-@B.ñ³ºàè-`¤NÃðc é-p¤ã9ÿ¸@é-&8…Þ`B.Yƒ4€é-€B.ÖHÐÀé-€¤ Y;o±àr- B.æhö¤ ê-¤ï²c`ê- ¤„)¬¸ ê-ÀB.„+©Àê-àB.ñEs-€F- 9 ë-D¢JcÀõ-°¤%Y¸ ö-C.¯Ó`ö- C.,™º ö- G-¿Ëàö-€G-Ë † ÷-@C.Ä6&`÷-`C.üJ‚ ÷-€C.YQ³âà÷- c.®ù‰ô ø-po'8%”tökÀÄ)@%Ýýÿÿ˜  Ð0i†XKpo'  ù™y@Æ) C.6Jÿ¤ ©tQ¤pÏ)àÑ-ôb €ã)Ф ù°^`ø- Ò-Ð<Ó=pä)à¤*ÞÚ— ø-@Ò-É–Ñå)ð¤ V^ø.`Ò-~¦]å)€Ò-ԲХ)à·&H%¹Ë­ÿ Æ)À[.øøÐ€æ)P%ÈZ!ê Ò-÷ú"…àæ)X%ÇZ!êÀ€.l/èpç)Ø04âMêÀÒ-W5'è)`%3âMêp&gI3 ù-h%|¨êàÒ-µãõBðè)p%{¨êÓ-»ˆa£*x%ê Ó-¯‡a£pê)°  ‰F@Ó-Œ‚ip*¥W]²`Ó-b `ë) \.åb Ð*Dwáù€Ó-VyŸ ì)ˆ%'‘ÊM Ó-â0*%z kê@\.˜/$ í)˜%Tûÿÿ`\.´2$î)0¥Fb0ªàÓ-¾2$0î) %T–"?€\.VmÁ`î)Ô-,YmÁî)°%îbaE \.ö$'$Àî)@¥ÒeIA Ô-p¥ª'ðî)¸%2¥[ê@Ô-èËÅ ï)¸ 3¥[ê`Ô- VMà*À%+po'È%*Üÿ¢ É)€Ô-mU$€ï) Ô-„ U$°ï)ÀÔ-å,²Áàï)Ø%¶¯]‡`*àÔ-²—Á'ð)à%åõÇÿT*à‰ Õó™€-º*Õ-"ÎT%@ð)È ž· b¤°*è%­"  ž-qàß3*Ц@Ö-º*}¦o ‹¦90–åžo ‘¦º*s¤o ’¦; º*B¯ž¤ 5*ð%ì L6@ž-Cáßð6*ø%»€íÿ Ÿ¤ 8*Ð fïPL`ž-§"S_9*P¥ Ox¦f(uïÙ`<*`¥ V½f€ž-ôß°=*p¥ …½©f0§± s ú-0P²¤P@*&œÆf ž-Z˜„_pA*&ó”Åf8(e D*€¥ †î/ŸÀž-(| ß`E*&Û¨Ùù@f:‘¤`H*Ø «›¿ÿàž-ýÏÕ7€I* × íž)hP§8ÍÒ ç-@n Khð€L*¥ÛËŸ-™„_N* ¥ L"HgN @k*°¥…o Ÿ-¹„„_ k*À¥ G¢ÜPá&iQR <-P‡Q ðl*Ð¥$ ð@Ÿ-‹…„_€m*ÀC.Vá- &e–û" û-XYR @n*ॠÃÒau`Ÿ-0¢_ n*𥠋>…3`þnðo*¦€c&€Ÿ-ØÞ–_€p*@s.”n¸Þh¦« q*àC.ñ“–“ Ÿ-Èù ß0r*¦íªùp§ ÀJ¤«`ü-p¸‘¤Ps*0Š àl@;-ÀŸ-Øú ßàs* ¦ …˜›Dx¹‘¤u* &§ã àŸ-ÏdëP`‡*0¦ D S`€1r€v*@¦ C S` -áo¶w*P¦ (pÚD  -_Ù“º€ˆ* D 'pÚDPn€{k8àˆ*0Dª —ˆŽcÅòЉ*`¦© —@ -Xêd0Š*p¦ ZfYpo'(&ÆIøYÀÍ)€¦ ›“’-€§ ù5/€Ý-¦&ßð0&Úc‹× ù-@D ã?\Ö ¦ Ôi_°¦ %Z”°§ [Lph`þ-8&»)ÕÒPÎ)pЬ™‹Þ@&«†*ÿàÎ)PÖ ØQ8H&ÄÌ0žÀ*P&øÿÿ *X&ز`à*È&u’²™ ÿ-PD K^Þß*`&@ôÎçp*0 ”DœŸÐ*h&½N*0*À¦}»µÿÀã-  @Ö-º*}¦o  90–åžo  º*s¤o  ;º*(Ц 9Ûºç`ù-Š¡@Ö-º*}¦o ‹¡90–åžo ‘¡º*s¤o ’¡; º*`KঠXØÃH`Ý- ¢@Ö-º*}¦o ¢90–åžo ¢º*s¤o ¢; º* Bð¦ ãÆR€ù-Š¢@Ö-º*}¦o ‹¢90–åžo ‘¢º*s¤o ’¢; º*0Bðh RÎÔ. £@Ö-º*}¦o £90–åžo £º*s¤o £; º*@B§ l…½Àù-Š£@Ö-º*}¦o ‹£90–åžo ‘£º*s¤o ’£; º*°K§ <1s àù- ¤@Ö-º*}¦o ¤90–åžo ¤º*s¤o ¤; º*PB ¨ Åsf@.x&„÷Ö*ú-Ф@Ö-º*}¦o ‹¤90–åžo ‘¤º*s¤o ’¤; º*`B€&ÊÒ ú- ¥@Ö-º*}¦o ¥90–åžo ¥º*s¤o ¥; º*pB`D †õ"@ú- ¦@Ö-º*}¦o ¦90–åžo ¦º*s¤o ¦; º*€B § l¡Ù`ú-&Kl,€ú- §@Ö-º*}¦o §90–åžo §º*s¤o §; º*@L@§ ©’üùàú-DÂò.oû-`§ „|jz`û-˜&¾%ÆÀç-¨&"0Éàû-°&_30É ü-Eç'8 ü-¸&xkŽ9àü-À&‘²™ ý- E‚—ª`ý-@Ö •Q8p *Ÿ»9 ý- í ¨Q8§ ¯—¬@þ- §Ëóa# Ý-À§ oê  þ-Ч %Òíàþ-ˆ ¶³™`ÿ-à§ å:`7 ÿ-ð§{î‹ìàÿ-Ð& þÿÿÿ¨ ¯7öÀ@ë-¨ h v2 .0¨”Ý•ì`.pr ^=Z8@¨rTzì€.Pz ¹j8€z uÙ^8°z ­x;·Ðz Ñ{;· Õ-z¥ª'pð)@Õ-@|ï'`*P¨äoLì .`Õ-IŠã  ð)`¨J ŸìÀ.°F þ»ßà. Õ-´ø0ñ)€Õ-²žËÐð)ÀÕ-mÐ`ñ)€¨Ô'Œì .Ø&‚¼w±@.àÕ-ÜÝþÏÀñ)à&мw±`.Ö-…I ¼ðñ)p¨ lzâï. ¨ n¡hæ .@Ö-¨;ùPò)À\.AT¥]ñ)`Ö-ÇäÊù€ò)À¨ Lg›à.à\.¾Ü°ò)Ш 2ƒ©‰.€Ö-ÚàfÜàò)ਠՓ|– . Ö-ù‰¢Üó)ð¨ 9Ty@.¨ Ì¿÷S€.ÀÖ- Æ‡Ï@ó)© =b²`.]._”0Ïpó) Ö-émæù ò) ].Š3v^ ó)© lê×€.ÀG Ò=Õ] .°¨ hÑMÀ. ‹ UHk¨×-Ÿƒ}Qô) © s>Ý×À. ×-¼Æa0ô)@×-LíÕà³)ð&ˆ¼w±.`×-¸æ¿Æ`ô)0© $F› .€×-µ¿í¯ô)@© %¼ç@. ×-Ò‹¿Àô)À×-‡â‰Qðô)P© Ч8<`.`© ^B¹€.p©bLì .Ø-¦ …0x*€©bšìà. Ø-×-… y*©ú7Kì .H8™ì`.G   ÀjÀÝ-`Ø-Mų×`{* ©…<™ìà.€Ø-Pų×À{*°©fšì . Ø-Lì³×P|*À©+bšì`.àÖ-¢ªOhÐó)ÀØ-’/´×`“*ðH ]Lìà.à©t<™ì .è&„¼w±à.ø&Ñ»w± ë-@].b l™ w*@Ø-Vv…Ðz*€].Oì³×à|* °-Ùå¤þÍ,à×-„»·: õ)@-ƒ ¹’pç,ЩbLì .ð©žfšì`.ª Ù=ï—ª 6§ß„ ª ïy_ö0ª LãOã@ª ;‡õPª þéôpª ñ´õ€ª q"KðI ßà% ª {Ñûô'y <Ð3 <°ª Ï$}ŸÀª qî1Ъ ?¡S J OÌ \ઠS¯w𪠬c‚„« ÞZg« 2¸ « wÛÅXà³-ÐÀô,@« Õ¢Z©P« æ¤ '{ <À  <K ûêK‰`« ü‹íö'È <p« aw>*€« åo+}« © ¼ô « Á õ°« ¡áºô µ ,æõÀR 4 õÀµ º ¼ôе G¼ôൠæõðµ E õ¶ ‹?Ï .¶ ¯Ãã` . ¶ mÃ\Õ .P¶ “g`À .p¶ ÷Ýfè .ÐR •ó4` .¶~9G à .à(éú¶Ø .àR ø$Xƒ  .°¶C’Y  .À¶ ú˜ô@ .è(Üö¶Ø€ .ð(rö¶ØÀ .)iö¶Ø@ .)¸÷¶Ø€ .ж áŠaq.)â·@. )xâ·€.P2Yú¶ØÀ.Àeú¶Ø.àØ-=ɳ×`~*à¶ )î©~`.ð¶ Ëä .·2bŒ à.x0í‰ìÿ·‚ôB  . ì §†;@›*0s o0q`.ps s¶3¨Àœ*€s $4:ž*0· ÆÕQ».ðÔ KF³;Ÿ*ðR /›Fƒ`.°ì Oʨ˜ðŸ*@· ­ À.()Šø¶Ø. s }z‰;¢*S €cÍn@.°sMvjš°£*Às ˜;%“0„*`· -ˆ| .Ðs€ß¶† ¦*p·§]> à.às ÞYHo„*È:Yâ·@. €· PwzŸ€.po'Õ uæÝ˜p§*@s ä>bqà.ðs 7êj“À].Í%Ï ·Ù B `.S Ò:¼³ .0)-â·à.à].€g$Ú@Ù-ÆØ—IPÛ™ûO `.À·±âX  . Ù-¸%¥Èзao à.^.…uZ„à· I˜¢¢ .ð·å†p `. ^.üFɸûnt  .àÙ-^²žŽ¸ºÁy à. ¸ PéY8 .Ú-ý“%0¸ oùU`. Ú-4cÈü@¸&ņ  . S W+£´À.`Ú-¿†+ÊP¸ Yä³á.ÀÙV.2«*€Ú-—¼íÅ`¸ âší@.ˆ6dè‡ì®*p¸ ÑZñ€.ÐêX.2 ¯*2fè‡ìà¯*@z.  "p°*6^Ñ‘ç0±*`z.& "Ð+2dÑ‘çP²*0{ OmR·àê\.2q+˜6jè‡ì ³*ðêM‘Û !+ÐÙw2Pµ*¨6ëÐì¶*ëƒw2à$+°6‘ëÐìð·* M.aç%50,+`ª ‹¼ô¸6Ÿ¥­ú0º*ÀM.gç%5 ï*À6¥¥­úp¼*p{ ˆ@·ðÙ‡w2ÀŒ+È6•ëÐìð½*Ú¾ Ûpø*Àj.VëËo¹+Ð6¼Â¶ÿÐÂ*ëà {2Ã*Ø6îõÔì°Ä* { ¬@·`l.¸46@|+€z.¾46ðï+è6ü[¼ûðÆ* ë{2PÇ*ð6"öÔìÐÈ*À{ F­È+ 2$öÔì°Ê* z.Ú«46@Ë*ø6j¼ûÐË*à{ ëÕƒ+€¸ ‹±{[à.¸‰‹ @. ¸¡'‹ €.| „Òƒ+°¸ àß .pÛ Œ¥p„`.À¸ ¬^ .@)ƒã·@.и ¢¼Ó«€.°Ö ¬œß+ด^‹ À.ð¸ 9oz„`.¹ L~„ .¹ ö–‡„à.`í Пß+ ¹ BA™„€.0¹ èˆ_À.`T ˜‹ž„ .P¹ —9@õ  .`¹ Zq@Æà .P| !DÍ+p¹ DÛ%¹@!.ðT Q2ªÀ!.¹ _c»".Û Û:’»@".€| ßú(ApU = €Å#. ¹ ;,Ä@#.°¹ öº™€#.P)²­Å $.X)³­Å€$.`)´­ÅÀ$.`n–bNêðŠ*h)µ­Å%.pn{k8P‹*À« ¹áõžcÅòŒ*ð¶­Å@%.` -ˆñ pŒ*p)·­Å %.€nÆÔyŽ*x)¸­Å&.€ -ÛÚgÇ`*€)¹­Å`&.˜™ïŒ°Ž*к­Åà&.  -Í,{Ì@*ˆ)»­Å '.°µ Ò õ  ë’0*X2íŀ'.À -½e*)Ä­ÅÀ'.n‹Œ‰ñ ‘*ØÅ­Å (.à -1Œ 뀑*˜)Æ­Å`(.¡-i—`Ø€Á* )Ç­Å (. n7…Á ”*`2È­Åà(. ¡-¥|ú‚€”*øÉ­Å ).°sI5•*¨)Ê­Å€).@¡-#¬Mp•*°)Ë­ÅÀ).`¡-¡Ú–*¸)Ì­Å *.°nŽ 0–*àÍ­Å€*.¸°ûÿð–*À)έÅÀ*.Ø(ßo°› .ˆ×îX€—*È)Ï­Å+.Àn –6HSðÒ*èЭÅ@+.Ð)Ñ­Å€+. o.~x5@Ô*Ø)Ò­ÅÀ+.ànü}¾°Ö*à)Ó­Å,.€¡-T<‰Ð×*è)Ô­Å@,.0¶ TÝí›à.À" ÐPÙ*ðÕ­Å`/. ¡-rkÝàÙ*ð)Ö­Å /.@¶ ñRó›  .Ȱ)£`Û*ø)×­Åà/.À¡-—Zúâ Ü**Ø­Å 0.ðn÷AœpÝ*h2Ù­Å`0.à¡- ©)ÐÝ**Ú­Å 0.`¶ jQpà .Ð×u¢Û ß*øÛ­Åà0.¢-_ZÁLðG+*Ü­Å 1.@v ð%ÚØ-'Hÿ`á*PWןÛ`1. ¢- >üÎðá*й Рƒ 1.à¹>"îà1.ð¹Éî 2.€¶ «˜Ip  .ø(Á÷¶Ø .)ÝŽâ·À . ].né³×Ð}* Û‹õÉ`2.Ù-x…X * *Žõ¶Øà2. Ù-í1…X™*0*õ¶Ø`3.8*Ñõ¶Ø 3.Òõ¶Øà3.@*Óõ¶Ø 4.ö¶Ø`4.H*ö¶Ø 4. · L·Òs .P*ö¶Øà4.ºÞ·èÑ 5.º±p"Á`5. º ë3IÀ5.0º o‰ß‡6.X*‹+A«`6.`*ã'A« 6.@ºíó¦Êà6.h*GÜ2« 7.°Û ¯ÑcÀ`7.Pº ˆº|À7.`º k‚UÀ8.P· d熄`.Ps Qn¸R@8.0Y B2úY 8.pº ÎcÀà8.€º j»Ì 9.º « d‘`9. º œÐ¥˜ 9.°º ¥µÉÌà9.€*¶ŸÌGà:.кÆœ·`;.ຠޝÒ <.PZ Z\þ`<.ÀÛxp­Êà<.»l­Ê =.˜*ƒYÌG`=. »ëvÊà=.`Ù-£Y^—0» þ™Ó @>.@»îšÊ€>.ÐÛ ¬¡]6À?.PÆKõw€» CËD.€[ ÓSëû`D. »l¼Ê D.àÛ IËäàD.@Ú-Øœ‘¼z´íÀF.¼{´íG.Ü|´í G. ¼}´í@`.0¼~´í€G.àz.à«460Ì*@¼¯­Ê G.7j¼ûðÌ*P¼°­ÊàG.0ë{2€Í*7(öÔì0Ï*ÚK—ãðÏ*7I¹¾ÿ Ñ* Úû”4ÐÑ*7 }êîàè*0Ú•4°x+ 7}êî€ë*@ÚƒÉãpì*(7ë¾ÿ î*07±¡÷î`ð*@멹4ðƒ+87·¡÷î ò*{.à{‰4@ˆ+Pë^Ñíõ* 6K³¶ÿð´*`ë €^¹= ÷*@{.øfû¿p-,PÚ †^¹=ù*pë ³p-X•+@7 ÿÿû*`´u{äà)(2s¿ÿ€+p´w{ä+H7u¿ÿÐ+P74&ïÀ+X7“4&ïÐÁ+pÚ{{äÀÂ+`7y¿ÿ0+€ÚHCéÀÈ+h7FeÄÿ° +`¼±­Ê H.Ð\µ­ÊI. ¼·­Ê@I.¸*i[uá`I.†-äá øÀ†(à6ö[¼ûÐÅ*ð¼ -}”¾€q.àXMK _-À*3lÄ_ÀJ.½ÄþJ@b.È*iÄ_@K.Ð*³gÄ_ÀK. ½ Õ=s} r.0½ )€Aæ`b.@½ /€Aæ€b.0Ü †âz[ÀL.Ø*Œ‡ã·àL.Ð^ 1>u„M.à*0ã· M.è*"ã·@M.¢Ñ€M.ð*.º‹ì*+vÔ’è@*0S “ÌjJÀ.0t¬± ^À½Êl* žSºÿ0*x2N½ºÿ*Pt )_|äY äYÉÀ _H+µxï!*нJwY0!* Õï"§à½ª~wY!*ð½ ÙJ,f#*€Ûß^‹ .¾ ^“¦ØN*t#§ t )<2¾¾²â£å P*0¾š¾yQ* DO+ð`Q*àtAÚ dP¾êQ*`¾ ÛëÖðQ*X+™¥rÛpS*p¾¶ª“ S*`Õfa`+ó,¡î0T*€¾?úÝ`T*h+«{6ÀT*°a Ø¥æ¸ðT* þ¶™ñ U*p+~``N*x+0©±òPU*¾»Ø?¥€U*€+f+@ àU*ˆ+gÍw @V*+©bçÌ V*€¹ ÙÉ´„€!.˜+è¥çÌW* ¾ Œ¼.F€R*°¾ “ç‡("ÃŒ +È*õÐS*0%$(ö X*°+j*;€X*À¾MrÉjY*¸+aJ¯pY*8ÞÛÿ Y*о Ö¿:0 [*ྠ½ Å \*À+<‡]*È+Æ»xÀ]*À¹ˆ'• À#.@K€VöP^*ð¾«fm±*¿cÎÕnÀ±*Ð+“ˆ“pæ*Ø+ ®¤x°²*ð"8ȰìHÈ„Vö` +¿ =Mг* ¿vaÐbÓG]E0¿ ïRáàIüƒ” ã*à+Üumå0´*@¢-”Ë?`+o "Ãݼ+è+4ãp"+`¢-2˜¯Ñ+@¿ð¡2 µ*ošÎßh`+ð+%C|ØÐæ*€¢- 9D?À+P¿ãù7Jç*ènËñà+ø+åÒìÿp¶* ¢-íé1]@+,É‚íÿ·*𻶸`+,Ë›ô?ðç*À¢-Œ 2]ð+@Ü ZÔ:°¸*øZÖ¸à+`¿ ’<–xì*à¢-ßEQ]Ðß+p¿ rx`º*­Ø+€¿ འ»*À.rd^ð+,ú!nBPô*@Lë+P—Hû`½*£-±v¢_ +,á0”Cà÷*C)À+¿,±å¯°¾* £-s¾`P+ ,//Gà¾*AæD#+ ¿ \Ô“:п*@£-¬qd#+°¿°$+(,e ‚HpÔ*М't -V†*€o.Ÿ”vjp%+0,©`÷ÃÕ*(maý&+À¿ èCÀàÖ*`£-SSQoP'+п VQËØ*0! Ø!p(+à¿YÇMðØ*€£-°l_o0)+8,èa¿I€Ù*8~9æ!P*+ð¿ ˆ-pÚ* £-Xârà*+À ¹MÛ*@&Õh%,+Xef¿IÛ*À£-”JuÀ,+ÀV…Ý*HbÓÐ'à-+@,÷~ŽU Ý*à£-å¿A• .+H,ÓÊRY@F+ c\‰NÀ/+ À ˜-°ß*¤-æEÈP0+0À ËãÃvá*P´{p1+@ÀôjÖ£ â* ¤-¦”´Õ2+àb l! ëÐã*€ò-ó¼÷>Àb-PÀ ‚áÀä*`À#ñO¦æ*pÀ v§€½+€ÀEþ« ¾+À ÅX-­@Á+Ðn;µËG Ó* À µ¥sÅà+°ÀŽÛc¬°Æ+ÀÀ !ëL¾ +ÐÀ ¿ÕdŒ +P,bÖxZÍ+àÀ Òþq@Í+ðÀ1¡­° +Á ñ¸Ÿ+Á ñ0qÎ+à„.mOE ÁŽ5¡­à+X,#lIû +0Á Œ!©ð+@Á Np¹°+PÁü™4½@C+`3Ï üpC+hýØED+`,âmZÀD+h,ÞUF°E+p4ÿÿÿàE+`Á%3 F+x¬,õ  F+x,“òÿÐF+pÁ ×Â2G+€,»m\ü0G+€Á xBj`G+ˆ,Ž~d H+Á {£G4€H+ Á ,Ž`CI+°Á ŸMÞ I+ÀÁ [›zPK+ÐÁ#™K€K+,€J•°°K+˜,ÃÒb´@L+ ,NÖènpL+€b  L+àÁ &­ÐL+¨,mÛ<Ðc,ðbžŽ-:M+R.rÏU0M+ðÁ ·L,°N+¸,Fç°@O+ˆZ%0P+Â9èc› Q+¹^z›R+  HVõS+À,Ëç¹¹ T+z8`Œ+È,s@&ðŒ+0ÂѶ¿®°Å,@½‰\ÐÆ,P ýøOÐŽ+` {=¦à`+p rD9Ë +€Â {6ˆÿ°Ë,c jƒ¦à’+ Â aŠ9Ëð’+°Â ØfªN`Ð,À ҩ¸N€Ñ,ÐÂuÍÑõ@”+à ³ GYД+ðÂà9­2•+à  M$0•+à ï*ô3@Õ,Ð,_•…€–+ à Öt$c°–+c%µì`à–+0Ãdfí`@—+@à æK÷p—+Ø,{¥ð˜+°ö |¥=)à,Y¬ª0›+Pà VæõJ`›+ csßkêÀ›+è,ïÊh¦PA)¸0]œö…€Ãý‘ m+Ã î· @+ Ã ¨Ÿ$p+ø,oÓ*Ñ +€}|ÍîÀ!--Ä/»°J)-#G»`ì+ÀÂ>ïPí+-6éé€í+Ðà (þK Ï(àÃLÕ§@î+ðÃT¯ÞPpî+-K°3 î+0c ¾N!Àï+ -a_cÏ ð+ÄÑO¶•àð+ Ä£y”°Ö(0-q „Z ñ+@Ä 3w’6Àò+PÄ °“6€ó+`Ävc“°°ó+ë2˜ 6£(pÄ ŸI“6 ô+p7@€fðÐ +€Ä $1Ü0õ+Ú8˜ 60 +x7F€fðð +8-5¡ïÀõ+ Ú ”-X +@-AØñ¤À",€7Ï-ÿÿÐ +H-åÜÑà#,°Ú\Úí+ˆ7ZüÈÿP+Ä Þç„W@$, ën"@7°+ Ä q…Wp$,02| šñp+°Ä 1Þ6V%,°ët"@7P3+ÀÄ }˜¶`%,X-wôÓÀ%,ÀÚ_ÚíÐ4+ÐÄ ܇"ð%,82]üÈÿP6+@c £Ü &,ÀëeÚíà6+ð±{2É*`-1\qÔP&,@2cüÈÿ`8+h-²òÖP) ¶ –-X 9+àÄ*‡×W@',˜7k/ÿÿà9+p-ÀžW+Ð',ÐÚžM\7:+ 7¬5¶ñÐ:+ðÄ ×hP),€l.rL(}0;+Pc$7°),¨7° °Bð;+ðÅôà),ÀQ.xL(}P<+°7¶ °B=+ˆ-~%.Ù *,ÐÿEîp=+Å r»sk+,¸7ýgÉÿ>+Å *lãl$)ÐëN\7`>+ ÅVBbJ0+,-$ê×`+,àÚN\7P?+˜-û).Ù+,È7+6¶ñ@+ø°f"À+,ðÚ3Fîp@+Ð71hÉÿ0A+ -—†P,,àë9FîA+@Å Üþ~JÐf,Ø77hÉÿPB+PÅ0G;ô0g,ÛS]\7°B+¨-Býä`g,à7aE¶ñàN+°-a=g,`c ÓG‰ÍÀg,s ªmðV€ *`Å ìRú^ðg,pÅ +û^ h,€Å „% ¶Ph,¸-êï€h,Ų„È]°h, Å–Y2J i,À-iŽÁèÐi,pcGŽ»0È-ÁãÞ°Å ÿæGîÀÅ ‰J‰@ì ù7áÓØ-,Á {ÐÅ ™ M5àÅ ‘‹L| 05ÏæîEðÅ ˆy9€c/ÚñPì ù|ȼ0983 ÆÓÐhíÆ G½ì8) ƒã·.à-±m* Æ G°]è-eó½’p3y ·xx*§EÌG :.ð-˜&Ix@Æ ‡¹µucÇuÜùp2ñYµf ;. c †U3· ™1©" .`Æ â_†°c ¶ê›xpÆ Õ.xˆ*ãrvá ;.€Æ äÚå}€Ü lW"çÆ X>*!]ÍGà;. Æ n¢¾B°Æ T˜~AÀÆ T‹ÓoÐÆ ZúÙ,»ÅC‰Ê <.H)[„ã· .ðÆ+2¼L°·†jL  .Ç ؉ë² Ç "³ó< o5ë0Ç >ŒÇêPÇ eŒ«õàc ¯1˜pÇ §Iì@€Ç ý[qÇP» R,NþÀ>.d ýNÆõÇ Ã~sŸ¨*ÑZÌG?.°Ç ¤iÕpÀÇ cBâp» êçý~€?.ÀÙ-UÈàÇ ËvæÂ d£¢™`Èdö» Ú•Žâ€n.0d Ø}çÈ ,É. Ȅߕ0È£ºq•@È bãwµPÈ €˜ fx3_gòŸ`È CLzpÈ ð̤°PU <¹„ ".À»â'®@E.È [ÄÉ‚°*8eÿ`.@d ÌÇX:Pdüñ’WðÛu´íÀE. È šnvë°È ™iлv´íàE.ÀÈt'ŠDÐÈ ûí—à»w´í F.àÈ(­JðÈ kÅe \x´í`F.@E'×ø-¯b¹Öð»y´í€F.É ~NyRÉ žùÛ.Õ×zœ É è"e.DÂ? `j,.EÂ? j,.üûq Àj, .ýûq ðj,(.û¾  k,0.ü¾ Pk,8.tE €k,@.‘tE °k,@ÉbâÐRàk,H.Fœ8ll,P.¾› >pl,X.œ"š l,PÉ ‡TÐl,`.ýïÀêm,`d ËT`î ’)H7ˆ×0m,`É¥|KÅ`m,h.b®–’m,pÉ xX•ðm,É ‰ÙW•àn, R.:“¦²@o, É ËIpÐo,°É äÁÁ°q,ÀÉ+ûþ@r,p.òL@ Ðr,@R.ù2¨,ÐɼÑ@¨,X 1×l£¹4àî*`R.Ä{ºžp¨,x.A^ˆ @*pd îÂ!ÒШ,àÉ q'—•`©,ðÉ Ô­ÇÊ wSäEÀ©, Ü¸›+ø°Ü 7ÝŽ Ê`Æ$5 ª,0Ê/?%~Pª,@ÊÝŽ³Ä {.òfû¿@-,PÊ û—zŠ€ª,`Ê °»jj°ª,pÊ þŸ+Äàª,€Ê Ê{Ó«,Ê 4?¨ˆp«, Ê éb˜h «,Xta;ˆ€3+°Ê 7GYÂЫ,@¤-›ˆàO+`iÓ“àQ+€d ¸¨Ñ¬,`¤-,Jÿÿp‹+å'•pÁ(ðº>òÃ,°å' .5dûÿp¾+è<:Íÿ@Ž+°å'•pÁ(žDòÉ,ðB:Íÿp‘+Àç'p7dûÿàÉ+PgPò’+ð'•pÁ(øN:Íÿ”+pè'•pÁ( žJY\8ð7) é'•pÁ(XA¶òP–+ €Y#À[#^#0î"@Z#[#€\#@]#À^#`gPY\8à×,àP ¾Å¬`j-^A¶ò`˜+ ~&¨.8dûÿÐ-,€½ MùÄ9ð*pg^ò ™+ ~&•pÁ(\<ÍÿК+x9dûÿ½÷j@#P*`(•pÁ(€!(•pÁ(ÐÞ'•pÁ(ø*–VÞà*Ю)$Õás+à¿4ù *à} 'W>`$-+Zäü*àÚ-÷§…¯ê*+Ï5ù`*°½ée…8°*~ ÄÇ]`%- tÞ{g +³©3ù*À_Ø«…8Ð*€0éLúÿl.¾‡‡@t L`M+P‰Ä$ôp‰ ³ˆ µ°‰Æ :-àŠ-;?ý`C)`ÚLÌ40+€ë…LÌ4€Œ,`à ™µ–æ›+pà ³·Sàœ+È«¡&ú°Ã#VÔîì+àC)¬ÿÄ DU·àÏ((-Gpñ+°¼¸­Êa.0Ä’¿”°Ðñ+м $³-Ð-àÞ ½lÙ„8 *àî-ó‰“Às.NÖdΠ>-€‹ Vé>Pà>-Û-³`ÇD0+*œFp*8 æZ®•0À$ X-7IЋ ®Ã0ÆWÍ·g`t¿·Ìà‹G¶Èp"Ck]ÿ †. ŒÖ·¢Àv-`ì .?O:Àc ¦tF'Àtšó dpì òž ½àÆ *MpŒ Õ‚é`Z-Ç j ŽÓÐc ?„0l×õŠ4€ÿ(`Ç —Ãè¬pÕö2b u¤ b@¹ ®s¢„@ .@uQxbPu-2b`u @8¼Üuí×âž u›Åâž°u”¾áž€ÕHãž Ç +F;»Àu ådg•Ðu u}h•àu ²ÿþÕ B0ÿðu Ñæ ÐÇ MÞ8ˆ"Ä·ÿÿv ñ˜×d …LCq v ±× Õ8˜zÐ&êãn.ðÇ q×åPv Ó× ž`v ÌÐ ž€v \é ž€ì Þ7C°vÖ¦b8Àvf¿c8@ð-¢óÀX-àìÓÃ}ïÐvcÜ~ïÀ{-£=¿ÆÐ,øq Fy,0emö@,|-©=¿Æà¦*`©-Ý(¹0,w Fy€,8ç~°;, |-±eסà,@|-)™_[ ¬*@!ç~`=,€|-/™_[0, ©-¾üZfÀ=, |-$•_ð,À|-õ〠,`.§Bý¸à>,à|-õãà)à©-MŸµ ?,}-„¢ÀI,ª- ÷c0@,?B¤gàJ, ª-Ö†é4À@,0ÉèÂï0j,@}-ˆvm@K, qDÏ PA,çTýL,HBñçÿ@B,`}-ˆvm`L,0q  Œ?ÐB,íTý M,P®ˆæùðC,€}-fŠ’m€M, 4W @N,@ª-d)DåE, }-F4Z­ N,`ª-¸¿dÀF,`hÄСf0O,À}-L4Z­°b) ª-˜'¾Í€G,phÊСf P,Àª-×k67àG,€h x.XPP,(ƧÿÿQ,àª-”ÃZ§I,žQÁš?pQ, .QhI,0_©ôù0R,0ÏGÐn`À-à}-K”€¥R, «-RAŽ–ðX,8‰Rk S,@«-]VÉd€Y,~-Q”€¥€S,@RkàS,`«-2…HpZ,h‘Áš?T,€«-–¯ú  Z,HŸ©ôù T,k. ¥€¥ÐT,À«-L< Â[,PIckU,à«-¿}`_0[,@~-¥€¥ +XOckPV,@qï¯2^,¬-Š®^E _,€É)1YªPn,pÏ å™> Â-€(†N~вsÑß (©‰@$.`s# ˜,˜(?ßþÊ Ö¨ð©, t.η@Û,<ðÕÎ--<ÖˆFR žÐÅ °V,x!±[`Îçèÿ@W, hÊÁš? W,hØ©ôùo,°hÐÁš? o,pÞ©ôù€q,p¼²­Ê@H.€×Æ pr,xþçèÿ t,ÀhZΚ?°t,€h¶ôùv,Ðh`Κ?v,ˆn¶ôù°w,°žÆ px,èèÿÀy,àh Æ  ˜)˜èèÿÐ{,Àñ-ÑøXà`-Àž/¹¨?|, =¡ú~,¨£1°n €,À~-ks(©°€,°©1°n‚,à~-²uD©À‚,¸ð3Ìn@„,À:–qÿ †,@-rÉêLà†,È@–qÿ0ˆ,i\ðˆ,Ð~íÿ@Š,Ø*þ'ûš, i"Î@0š,à0þ'ûðš,0i ç-.XP›,@iœ, ¬-Wít.P_,@¬-͸~€_,`¬-}K¹à_,€¬-Äæž=`, .æÀ;ó@`, ¬-wÜåÐ`,Pq«ÒÐ/a,X¹º*ê b,`qK÷=/°b,`Yß—é@c,À¬-9cRP†)à¬-ôM=`d,`.+ê£ýPe,€q 9Iý÷°e,q «úËpf, ­-¾ÖÛ’0Ž,@­-€Ÿæ , q _•¥€,à ˜%PÑ) !.¬h¿#p,€­-Üql0‘,Àq ;Ëf‘, ­-”aŽ)ð‘,Ðq ¢Àç#P’,àr.w†Š;€’,àqµiîÀ@“,`".-Êé¿ “,ðq ;)Cº0”,rÛwÚ‹ •,à­-u+p,°•,08C@8CœÀ _p*xµuá`:.`3(°.:dûÿP€,`3(•pÁ(°±&€8Ëþ@Ã)°±&•pÁ( ò-ú}üBàb-0·&¸.8Ëþ Å)0·&•pÁ(0Í&À.8ËþÊ)0Í&•pÁ(0Ù}@Ù}@Ë!  À _°Žx¯ŸV j.`j. j.`i.ài.àË\XéÅÀd.¨òÿÿÿàŽ L]å @c-Ð, p‘ž¢`c-ðŽ³‡xl€c-¸h-e c-ðâl@ç'h6dûÿ0¿+ ó-V²\V ÜFÄ0Àc-P(•pÁ(@ô-äpËÜ€„. N'¥à0Í,….[^<  Ø 5w7 x 9²[°x 7•Ö ¢œ ˜Ðx 2µ ˜àxKÝSðxÛõSy 0N9³ y‰ãS °å´¸U  Ö6;S@yõSP U´¾-X N­½-`  ¿-˜0Þž- ÐåÉa’¹0è#ê÷V8h ãðU8p —OW8€ ˆo30 0h20@^.0ðR ðå t+û ˜ ³˜î/  ¬‘í/¨ `ðî/H8<ªî/ (5’»ÿ=àC-º* ƒ*° Ø46À Ê/56¨0¦é46È Hð5°0Aúî5Ð õXð5ˆ0„² æ#š¯F+€T.7†; w-$PØl¯]îKà¶-“0-6À(- Pæ R(ÄVPi œ,`i`,r³Ô±p–,pi4ÂAð,®-²ì¶Ð–,ÐtHá d€i:ÂA€ž,p  &F±`—, -Â?Wàž, ®-ú×Ã*—,i PþüÔ , r ø¶¹éð—,À-Ö¿~ÕÀ , i ”Œ6¾°¡,0ržöÖ¨°˜,à-Ü¿~Õ@¢,@®-¨”K®P¿,°i šŒ6¾`£,@r ¶ó¤¨à¿,€-5«`ð£,`®-x,Ï¢@À,Ài ©,iÞ€¤,€®-¤`Ñâ À, ®-¥`Ñâ0Á,Ði ß­†5 ¥,€%.§`ÑâÀÁ, €-'áÎL¦,à%.«`ÑâPÂ,ài å­†5À¦,@€-.ë«P Ð+ði ì·c9°§,À&.Ïí½øpÃ,@k.؇þ@Ò,s.Ðí½øÐÃ,j & `Ó,@'.Òí½ø`Ä,€€-Þ‡þ Ô,À®-Öí½øÀ0*j , Õ,à®-G7µ Å, È5盿! j ¬T.X Õ,¯-#-€Å,èúíÿÿÀÖ, ¯-*ÒyœÆ,ì%ÇiDP×,@¯-+Òyœ Æ,ð3¯Ãþ@Ø,`¯--Òyœ0Ç, €-ǯçÐØ,øÙ6­Ù, ¯-ZûáóPÈ,à.ͯçðÙ,À¯-/Ï¢àÈ, Ù6­°Ú,à¯-2EÿâpÉ,0j % àÚ,`).3EÿâÊ,žGûÿÐÛ,°-5Eÿâ@«,À×£% 0Ü,à).9EÿâÀÊ,Ð×ÖiDÜ, °-0Ïh Ë,@j ÖiDPÝ,`*.¶ÂТ€Ë,Pj¦% Þ,@°-Òå¤þÌ,À1šÃÿ[€­ 5×lDh-€ØÃ=7ß`0 K§€Y-Ø Ñð5py ζ38ç Bç„b y «S6ðÍ Þò™å@¹-€J.tæN`m-`® +æ}O`n-ðy 1Ç'8 N-Aâî¯`o-@Q}•:d o-pÖ ŽAZ8`K.[ï Ô`p- z vj8è ¸zÈÈPQ Xë@q-àØ sÈÈðØ òqÈÈPy !_38`y X28Pè ŽnÈÈ€y ªp38y ²Z6°y _²60Ö ;l6€è vlÈÈÀy äQ8Ðy âÅ'8ày õÁ'8`Ö %Æ'8z KAZ8z šBZ8Ù ðóuŒ0z ‰f8@z Åk8 Ù vŒ`z &Ø^8pz 9Ô^8z iØ^8 z {;·Àz Ž{;·0í ¡w;·àz 3¤ö¶ðz Ø¡ö¶po'pQ fÃîÏP™+po'p¯ ŒgHÏ@û*@¦-š;Ì“ˆ+po'à¯à‡—)»+À¦-¨#4m€¢+à¦-Fã,{¤+ÀQì{A~.06€¤ê¤Gûÿß, k.ÓûÂß,€°-Õå¤þÍ,`j a¹@€à,À€-Iɸ°à,À°- (¥ Î,pj –pðpá,à°-Vtœ€Î,à€-OɸÐá,±-꫈oàÎ,€j –pðÀâ, ±-뫈o@Ï,po'°²FA¼+@±-í«ˆoÐÏ, $ýAàã,`±-ñ«ˆo0Ð, -} ¹’pä,€±-øÄ0ÀÐ,PÆ Ë®u]˜#Km@E°æ, ±-¨È;·PÑ,ÐQ Nê|‡@r-À±-T&PàÑ, Qm@EÀè,à±-U&PpÒ,àQ H·x6`r-jÓç(€é,²-W&P€æ, #Ñ ë, ²-[&P@ç,€k.x–éâ-º* j“¨´Fà¬*@²-úéè,(¡í,`²-³µ¯è,0°Y½˜О™¨´FÐí,€²-7¼?Pé,0§Pï, ²-8¼?ê,ðQ —-܆.0ØàªÐFàï,`,.:¼?Ðê,À§-~Mù|ª+8î’* ò,€,.>¼?ë,`-¸´œˆó, ,.<6ƒ ì, ¼ BÀÎ+ y.îÍ™Màó(@ör$NPõ,àk.¾´œˆpö,à,.<Þz9 í,Hür$N€ø,À²-=Þz9`î, O-±ˆ0@t-°j±´ËG ù,à²-?Þz9 ï,P¿œ%ðú,³-CÞz9°ï,.kFPʰû, ³-$( pð,X©Ø0ý,@³-öá­0ñ,€-qFPÊðý,`³-Å ðñ,`¯Øpÿ,€³-Å °ò, .qkó0- ³-Å @ó,h?8‰¥à-À³-Å ô, -'¢™ -Àj¥¶éRP-´-–|€ý€õ,@.-¢™€( ´-²>2@ö,-.³>2Ðö,8ÍyÍò°+ÀÎ Õv˜ ½-ÐÎ d„I`½-{ Ì ö¶ { ü¤ö¶@{ ôjR·P{ ÕmR·€Ö nR·Ö ã@·@ÇÍ·ÎK€{ i@·{ |@·-Íeu| ã,°{ À¬È+@í eªÈ+Ð{ Y©È+Pí ‰­È+ Ö Óƒ+ð{ qÖƒ+| ´Öƒ+ | Ÿß+0| Ÿß+ÀÖ  ›ß+ðc ùß™@| ›CÍ+pí @AÍ+`| 4@Í+p| dDÍ+€í “Y*A| o*Am.(_ýC)`° ͺ˜4@‹-âp¥ðC)@Ï g$FÍ Á-p')¡…ÿÀ.ÿCR€D)°ÇÒ ‹-Û.R°D)x'¼éA(14Üê`Ï û–tèÀÁ-Œ-ò’SE)@Œ-NÖpE)01ÕÒ84L÷(@Â-À,.„©uàì, /}(€Â-ˆ'õÒØB)¬ÿÀŒ-rõÿ_`F)'Ù &ú€° ilzÝ R =çÏ`-¹æëBPG)0R  @°° L䈠'­¿þÿ¨Ò€È ¡ÐÏ _xc,X1€*¬ÿ€•&"@g ðÿÿÿÿÿÿÿÿ %("À·-U €îÿÿÿÿÿÿÿÿ@£&"@g"°‹ÿÿÿÿÿÿÿÿ`3("À·-‰ pÆ!ÿÿÿÿÿÿÿÿå'"€..gpØ ÿÿÿÿÿÿÿÿ$@g ÿÿÿÿÿÿÿÿ@2$@g ÿÿÿÿÿÿÿÿ€2’&"@g€ÿÿÿÿÿÿÿÿ&"@g†ÿÿÿÿÿÿÿÿ’&"@g¡ÿÿÿÿÿÿÿÿp“&"@gà ÿÿÿÿÿÿÿÿÀ’&"@gP ÿÿÿÿÿÿÿÿ ”&"@gÀ ÿÿÿÿÿÿÿÿàg'"@g Oÿÿÿÿÿÿÿÿ ”&"@g0 ÿÿÿÿÿÿÿÿД&"@g   ÿÿÿÿÿÿÿÿh'"@gOÿÿÿÿÿÿÿÿ€•&"@g /"ÿÿÿÿÿÿÿÿ°&"@g `ÿÿÿÿÿÿÿÿ`‘&"@g @ÿÿÿÿÿÿÿÿ`‘&"@g° ÿÿÿÿÿÿÿÿ Ž&"@gÿÿÿÿÿÿÿÿði'"@g°_ ÿÿÿÿÿÿÿÿP&"@gÀ÷ÿÿÿÿÿÿÿÿ Ž&"@gÿÿÿÿÿÿÿÿ€s"°&"@gÿÿÿÿÿÿÿÿÀ„'"@g€Sÿÿÿÿÿÿÿÿ p'"@g PXàd"ÿÿÿÿÿÿÿÿPt"’&"@gÿÿÿÿÿÿÿÿÀv"p“&"@gÿÿÿÿÿÿÿÿw"0–&"@g ùÿÿÿÿÿÿÿÿ`x"P&"@gÿÿÿÿÿÿÿÿ0y"`‘&"@gÿÿÿÿÿÿÿÿz"À’&"@gÿÿÿÿÿÿÿÿÐz" ”&"@gÿÿÿÿÿÿÿÿ {"°t("@gàÿÿÿÿÿÿÿÿp|"Ðé'"@gÿÿÿÿÿÿÿÿ@}"à–&"@gÿÿÿÿÿÿÿÿ@®&"@g0ÿÿÿÿÿÿÿÿ ¤&"@g#‰ÿÿÿÿÿÿÿÿ¦&"@g$`ÿÿÿÿÿÿÿÿ~"E&"@g%PûÿÿÿÿÿÿÿÿP"0¬&"@g&Ðÿÿÿÿÿÿÿÿ ‚"à¬&"@g'@ÿÿÿÿÿÿÿÿð‚"­&"@g(0üÿÿÿÿÿÿÿÿ Ÿ&"@g)0¹ÿÿÿÿÿÿÿÿ`#&"àõ-„ 0‡ÿÿÿÿÿÿÿÿ¬ð®&"PÜY’ –ÿÿÿÿÿÿÿÿÀ’&0†"P°&"PÜe“ ð–ÿÿÿÿÿÿÿÿð®&°±&"PÜn” PÇ!ÿÿÿÿÿÿÿÿ°±&"PÜn• PÇ!°±&ÿÿÿÿÿÿÿÿ„ð"0Í&"PÜ@Í àîÿÿÿÿÿÿÿÿ‡"°±&"PÜsš @˜ÿÿÿÿÿÿÿÿ@Š"е&"PÜÑ› p¯ÿÿÿÿÿÿÿÿ ”&0·&"PÜÔœ  È!ÿÿÿÿÿÿÿÿ0·&"PÜÔ  È!0·&ÿÿÿÿÿÿÿÿ@„‹"0·&"PÜÙ£ 0±ÿÿÿÿÿÿÿÿà·&"PÜí¤ ¶ÿÿÿÿÿÿÿÿÀ„à·&"PÜí¥ ¶à·&ÿÿÿÿÿÿÿÿ€„€"€Ì&"Pܸ ÐÈÿÿÿÿÿÿÿÿà·&0Í&"PÜ ¹ €É!ÿÿÿÿÿÿÿÿ@…0Í&"PÜ º €É!0Í&ÿÿÿÿÿÿÿÿ…€Á&"@g*ðºÿÿÿÿÿÿÿÿÀƒ"À³&"@g+ÿÿÿÿÿÿÿÿ¦&"@gƳÿÿÿÿÿÿÿÿ”" ƒ&"@gÇ´ÿÿÿÿÿÿÿÿ0g'"@g@Nÿÿÿÿÿÿÿÿ@i'"@gpPÿÿÿÿÿÿÿÿ„'"@gPQÿÿÿÿÿÿÿÿ j'"@g Rÿÿÿÿÿÿÿÿt("@gÞ!ÿÿÿÿÿÿÿÿ¼°l'"@g ðSÿÿÿÿÿÿÿÿn'"@g ÐTÿÿÿÿÿÿÿÿàd" Ÿ&$@g °Uÿÿÿÿÿÿÿÿ€Ó°™"po'"@g pWÿÿÿÿÿÿÿÿМ'"@gP àd"ÿÿÿÿÿÿÿÿ Ó'"@g€Z`Ë(@Ë(ÿÿÿÿÿÿÿÿ°‚'"@g@\`Ë(@Ë(ÿÿÿÿÿÿÿÿ ¡'"@gP_`Ë(@Ë(ÿÿÿÿÿÿÿÿ°£'"@g  ``Ë(@Ë(ÿÿÿÿÿÿÿÿÀ¥'"@g#нp®)@à­)ÿÿÿÿÿÿÿÿ€Ô'"@g& d`Ë(@Ë(ÿÿÿÿÿÿÿÿø%"À¯+!@ÿÿÿÿÿÿÿÿÀ³& ¢"@˜&"À¯i" ÿÿÿÿÿÿÿÿø%p£"Àø%"°˜#@"ÿÿÿÿÿÿÿÿp“&@¤"pù%"°Ö$0&ÿÿÿÿÿÿÿÿ ”&¥"à´'"`.."%p°ÿÿÿÿÿÿÿÿP&à¥" F("`..#&À±ÿÿÿÿÿÿÿÿ`‘&°¦"µ'"`..$'³ÿÿÿÿÿÿÿÿÀ’&€§"@¶'"`..%(ð³ÿÿÿÿÿÿÿÿ ”&P¨"ð¶'"`..()@µÿÿÿÿÿÿÿÿ Ž&P'"@gðZ`Ë(@Ë(ÿÿÿÿÿÿÿÿð '"@g| `Ë(@Ë(ÿÿÿÿÿÿÿÿ€¨'"@g/pæ @†*@ †*ÿÿÿÿÿÿÿÿ ©" ·'"`..)*¶ÿÿÿÿÿÿÿÿP&`¬"P¸'"`..*+à·ÿÿÿÿÿÿÿÿ°&0­"¹'"`..+,À¸ÿÿÿÿÿÿÿÿ`‘&®"°¹'"`..,- ¹ÿÿÿÿÿÿÿÿ’&Ю"`º'"`..-.€ºÿÿÿÿÿÿÿÿÀ’& ¯"»'"`..//@¼ÿÿÿÿÿÿÿÿp“&p°"À»'"`..00 ½ÿÿÿÿÿÿÿÿ ”&@±"p¼'"`..81¾ÿÿÿÿÿÿÿÿp“&²" ½'"`..92à¾ÿÿÿÿÿÿÿÿ ”&à²"н'"`..‰3 êÿÿÿÿÿÿÿÿ ”&°³"0¿'"`..Š4ëÿÿÿÿÿÿÿÿÀ’&€´"à¿'"`..‹5ðëÿÿÿÿÿÿÿÿÀ’&Pµ"àN("`..Œ6@íÿÿÿÿÿÿÿÿ ”& ¶"@Á'"`..7 îÿÿÿÿÿÿÿÿ ”&ð¶" Â'"`..Ž8ïÿÿÿÿÿÿÿÿÀ’&À·"PÃ'"`..9Ðø ÿÿÿÿÿÿÿÿ ”&¸"Ä'"`..:Pðÿÿÿÿÿÿÿÿp“&`¹"°Ä'"`..‘;0ñÿÿÿÿÿÿÿÿp“&0º"`Å'"`..’<€òÿÿÿÿÿÿÿÿ’&ÐW("`..“=ÀÒ ÿÿÿÿÿÿÿÿÐW("`..“>ÀÒ ÐW(ÿÿÿÿÿÿÿÿÀ×pÊ"Ï'"`..°Pÿÿÿÿÿÿÿÿ ”&»"ÐW("`..“@`óÿÿÿÿÿÿÿÿ@¾"Æ'"`..”A@ôÿÿÿÿÿÿÿÿp“&¿"ÀÆ'"`..•Bõÿÿÿÿÿÿÿÿ ”&à¿"pÇ'"`..–Cöÿÿÿÿÿÿÿÿ ”&°À" È'"`..—DpöÿÿÿÿÿÿÿÿÀ’&€Á"ÐÈ'"`..˜EP÷ÿÿÿÿÿÿÿÿp“&PÂ"€É'"`..™F0øÿÿÿÿÿÿÿÿÀ’& Ã"0Ê'"`..šGùÿÿÿÿÿÿÿÿp“&ðÃ"àÊ'"`..œHðùÿÿÿÿÿÿÿÿ’&ÀÄ"Ë'"`..I"ÿÿÿÿÿÿÿÿp“&Å"Ðb("`..žJ°ûÿÿÿÿÿÿÿÿ’&`Æ"@Ì'"`..¡K€"ÿÿÿÿÿÿÿÿ’&0Ç"ðÌ'"`..¤LýÿÿÿÿÿÿÿÿП&È" Í'"`..§Màýÿÿÿÿÿÿÿÿp“&ÐÈ"€c("`..¬NÀþÿÿÿÿÿÿÿÿp“& É"PÎ'"`..­O !ÿÿÿÿÿÿÿÿp“&p½"°Ï'"`..±Qðÿÿÿÿÿÿÿÿ ”&@Ë"0Õ'"`..´RÐÿÿÿÿÿÿÿÿ ”&Ì"àÕ'"`..µS°ÿÿÿÿÿÿÿÿ ”&àÌ"@×'"`..·Tÿÿÿÿÿÿÿÿp“&°Í" Ø'"`..»U`"ÿÿÿÿÿÿÿÿ°Ä'€Î"`Û'"`..¼VàÿÿÿÿÿÿÿÿÚ'PÏ"Ü'"`..½WÀÿÿÿÿÿÿÿÿÀ¾& Ð"ÀÜ'"`..ÀX ÿÿÿÿÿÿÿÿp“&ðÐ"pÝ'"`..ÃY€ÿÿÿÿÿÿÿÿÀ’&ÐÞ'"À·- Z`ÿÿÿÿÿÿÿÿàÀÑ"€ß'"àõ-.[@ ÿÿÿÿÿÿÿÿÐÞ'`Ó"0à'"àõ->\Ð"ÿÿÿÿÿÿÿÿÐÞ'0Ô"àà'"°c]P,ÿÿÿÿÿÿÿÿÀ’&á'"€õ-M^ðÔ ÿÿÿÿÿÿÿÿp×"á'"€õ-M_ðÔ á'ÿÿÿÿÿÿÿÿ@Ø@â'"€õ-Pa°Ö á'ÿÿÿÿÿÿÿÿ@â'"€õ-Pb°Ö @â'ÿÿÿÿÿÿÿÿ@ÙÕ"á'"€õ-Tfÿÿÿÿÿÿÿÿå'"€..hpØ å'ÿÿÿÿÿÿÿÿÀÙPé"Ð ("`H.a¥lÿÿÿÿÿÿÿÿ (Ö'"@g*\!p«)@Á(ÿÿÿÿÿÿÿÿÙ"å'"€..kpQÿÿÿÿÿÿÿÿ°å'"€.. l0Ú ÿÿÿÿÿÿÿÿ°å'"€.. m0Ú °å'ÿÿÿÿÿÿÿÿ@Ú°Ú"à ("`H.d¨àmÿÿÿÿÿÿÿÿ0 (PÜ"°å'"€..#pPRÿÿÿÿÿÿÿÿç'"`H.%qÀÎ!ÿÿÿÿÿÿÿÿÀç'"`H.7|`Ü ÿÿÿÿÿÿÿÿpè'"`H.tbÿÿÿÿÿÿÿÿÀÛ é'"`H.’€ðbÿÿÿÿÿÿÿÿÀÜPï'"`H.AÐcÿÿÿÿÿÿÿÿð'"`H.h‚ eÿÿÿÿÿÿÿÿ@Y$àö'"`H.H‹0Äÿÿÿÿÿÿÿÿ0ö'@å"ðø'"`H.KŽÀgÿÿÿÿÿÿÿÿ@ø'æ"°û'"`H.Niÿÿÿÿÿÿÿÿû'àæ"ý'"`H.O’ðiÿÿÿÿÿÿÿÿ`ü'°ç"°("`H.X›Ðjÿÿÿÿÿÿÿÿ(€è"("`H.]¡°kÿÿÿÿÿÿÿÿ0&ÀÞ" ("`H.eª0oÿÿÿÿÿÿÿÿÐ'ð'"`H.h« eð'ÿÿÿÿÿÿÿÿÀÚÀø"À("€..8Ú°‡ÿÿÿÿÿÿÿÿ’&pè'"`H.t±bpè'ÿÿÿÿÿÿÿÿ@ÛÀë"p("€..9Ûˆÿÿÿÿÿÿÿÿ`‘& é'"`H.’Áðb é'ÿÿÿÿÿÿÿÿ@Ü`í" ("€..:Ü üÿÿÿÿÿÿÿÿÀ’&P("`H.­ÊÀƒÿÿÿÿÿÿÿÿP("`H.­ËÀƒP(ÿÿÿÿÿÿÿÿ€þ…&"À·-§Ý½ÿÿÿÿÿÿÿÿ ê"("`H.±Ï „ÿÿÿÿÿÿÿÿ`( ~&"€...Рá ÿÿÿÿÿÿÿÿ€õ" ~&"€...Ñ á  ~&ÿÿÿÿÿÿÿÿ€Ýï"Ð ("À·-±Þ€½ÿÿÿÿÿÿÿÿ Ÿ&`("€..1ÓÐã  ~&ÿÿÿÿÿÿÿÿ`("€..1ÔÐã `(ÿÿÿÿÿÿÿÿ€Þ€!("À·-·ßð½ÿÿÿÿÿÿÿÿ@ò" ~&"€..5Øð…ÿÿÿÿÿÿÿÿð÷"("€..7ÙІÿÿÿÿÿÿÿÿ°&€!("À·-·àð½€!(ÿÿÿÿÿÿÿÿß›&"À·-‘% Pÿÿÿÿÿÿÿÿà"("À·-Ëä€ÄÿÿÿÿÿÿÿÿÐÞ'"À·- é`ÐÞ'ÿÿÿÿÿÿÿÿ€ßó U("àõ-Xf 1ÿÿÿÿÿÿÿÿå'°'()("À·-i òÿÿÿÿÿÿÿÿ`(( ý"0-("À·-r €õÿÿÿÿÿÿÿÿ€,(pþ"@/("À·-z Áÿÿÿÿÿÿÿÿ.(@ÿ"ð/("À·-} øÿÿÿÿÿÿÿÿ€í&# 0("À·-‚ ùÿÿÿÿÿÿÿÿ)(à#P1("À·-ƒ Púÿÿÿÿÿÿÿÿ0-(°#2("À·-„ 0ûÿÿÿÿÿÿÿÿ@/(€#°2("À·-… üÿÿÿÿÿÿÿÿð/(`3("À·-‰ pÆ!`3(ÿÿÿÿÿÿÿÿ€àÐü"ÀU("àõ-^g Qÿÿÿÿÿÿÿÿ°å'P#`3("À·-Ž# ÿÿÿÿÿÿÿÿÿÀ#Ð6("À·-$ pÿÿÿÿÿÿÿÿ`3(€M#°Ä'€..!n P°å'0È( @`È(ÿÿÿÿÿÿÿÿpÁ(€ª)O#( `H.k­ðpð'0È( @`È(ÿÿÿÿÿÿÿÿpÁ(0È(ÀO#П& `H.m¯°rð'0È( @`È(ÿÿÿÿÿÿÿÿË(0È(R#’&`H.x´ Ùpè'€Æ(  @Á(ÿÿÿÿÿÿÿÿË(€ª)ÀR#À¾& `H.{¶Ðxpè'0È( @`È(ÿÿÿÿÿÿÿÿÁ(€ª)€S#ðø' `H.~¸zpè'0È( @`È(ÿÿÿÿÿÿÿÿpý+€ª)U#’&`H.„» }pè'€Æ(  @Á(ÿÿÿÿÿÿÿÿ ý+0È(ˆ# Ó'@g)Ö'`Ë(@Ë(ÿÿÿÿÿÿÿÿpÁ(€ª)@B# €' @g$€Ô'0È( @`È(ÿÿÿÿÿÿÿÿpÁ(€ª)€#À’& @g @®&€Æ( @Á(ÿÿÿÿÿÿÿÿpÁ(€ª)@#À’& @g@®&€Æ( @Á(ÿÿÿÿÿÿÿÿpÁ(€Æ(#П& @g €@®&0È( @`È(ÿÿÿÿÿÿÿÿpÁ(0È(П& @g!ð@®&0È( @`È(ÿÿÿÿÿÿÿÿË(€ª)àü%@g¼ ³@þ%`Ë(Ë(ÿÿÿÿÿÿÿÿpÁ(€ª)P&@g½ ³&0È( `È(ÿÿÿÿÿÿÿÿpÁ(€ª)ª'@g¾ ³@«'0È( `È(ÿÿÿÿÿÿÿÿpÁ(€ª)&@g¿ ³p&`Ë(@Ë(ÿÿÿÿÿÿÿÿpÁ(€ª)p%&@gÀ ³ &&`Ë(@Ë(ÿÿÿÿÿÿÿÿpÁ(€ª)0(&@gÁ ³à(&`Ë( Ë(ÿÿÿÿÿÿÿÿpÁ(€ª)@*&@g ³ð*&`Ë( Ë(ÿÿÿÿÿÿÿÿpÁ(€ª)P,&@gà ³°-&0È( `È(ÿÿÿÿÿÿÿÿpÁ(€ª)À/&@gÄ ³p0&0È( `È(ÿÿÿÿÿÿÿÿpÁ(€ª)Ð1&@gÅ ³€2&`Ë(Ë(ÿÿÿÿÿÿÿÿpÁ(€ª)"#à¡& @g Ó'0È( @`È(ÿÿÿÿÿÿÿÿpÁ(€ª)ÐÀ& @g Ó'0È( @`È(ÿÿÿÿÿÿÿÿpÁ(0È( Ó'@gP'`Ë(@Ë(ÿÿÿÿÿÿÿÿpÁ(€ª) Ó'@g°‚'`Ë(@Ë(ÿÿÿÿÿÿÿÿpÁ(€ª) Ó'@gð '`Ë(@Ë(ÿÿÿÿÿÿÿÿpÁ(€ª) Ó'@g ¡'`Ë(@Ë(ÿÿÿÿÿÿÿÿpÁ(€ª) Ó'@g°£'`Ë(@Ë(ÿÿÿÿÿÿÿÿpÁ(€ª)@'#’&PÜï§ À·à·&€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(€Æ((#’&PÜ𨠠¸à·&€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(0È(À(#’&PÜñ© €¹à·&€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(þ+€)#’&PÜòª `ºà·&€Æ(  @Á(ÿÿÿÿÿÿÿÿË(€ª)@*#’&PÜó« @»à·&€Æ(  @Á(ÿÿÿÿÿÿÿÿË(€Æ(+#’&PÜô¬ @âà·&€Æ(  @Á(ÿÿÿÿÿÿÿÿË(0È(À+#ð®& PÜõ­ oà·&€Æ(  @Á(ÿÿÿÿÿÿÿÿË(þ+€,#ð®& PÜö® ¼à·&€Æ(  @Á(ÿÿÿÿÿÿÿÿÁ(€ª)@-#@¹& PÜþ¯ ÐÁà·&0È( @`È(ÿÿÿÿÿÿÿÿÁ(0È(.#€«& PÜÿ° °Âà·&0È( @`È(ÿÿÿÿÿÿÿÿpý+€ª)À.#€«& Pܱ Ãà·&0È( @`È(ÿÿÿÿÿÿÿÿpý+0È(€/#’&Pܲ ~à·&€Æ(  @Á(ÿÿÿÿÿÿÿÿ ý+€ª)@0#’&Pܳ àÄà·&€Æ(  @Á(ÿÿÿÿÿÿÿÿ ý+€Æ(1#’&PÜ´ ÀÅà·&€Æ(  @Á(ÿÿÿÿÿÿÿÿ ý+0È(À1#’&Pܵ  Æà·&€Æ(  @Á(ÿÿÿÿÿÿÿÿ ý+þ+€2#’&Pܶ €Çà·&€Æ(  @Á(ÿÿÿÿÿÿÿÿ`þ+€ª) " ™& PÜ· `Èà·&0È( @`È(ÿÿÿÿÿÿÿÿ`þ+0È(4#°&PÜ» àÒ0Í& Ä( ÐÄ(ÿÿÿÿÿÿÿÿpÁ(€ª)À4#°&Pܼ ÀÓ0Í& Ä( ÐÄ(ÿÿÿÿÿÿÿÿpÁ( Ä(€5#’&Pܽ Õ0Í&€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(€Æ(@6#’&Pܾ ðÕ0Í&€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(0È(7#’&PÜ¿ ì 0Í&€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(þ+À7#’&PÜÀ ÐÖ0Í&€Æ(  @Á(ÿÿÿÿÿÿÿÿË(€ª)€8#’&PÜÁ °×0Í&€Æ(  @Á(ÿÿÿÿÿÿÿÿË(€Æ(@9#’&PÜ Ø0Í&€Æ(  @Á(ÿÿÿÿÿÿÿÿË(0È(:# ”& PÜà pÙ0Í&0È( @`È(ÿÿÿÿÿÿÿÿÁ(€ª)À:# ”& PÜ Ä ÀÚ0Í&0È( @`È(ÿÿÿÿÿÿÿÿÁ(0È(€;#’&PÜ!Å  Û0Í&€Æ(  @Á(ÿÿÿÿÿÿÿÿpý+€ª)@<#’&PÜ$Æ €Ü0Í&€Æ(  @Á(ÿÿÿÿÿÿÿÿpý+€Æ(=#àÍ& PÜ%Ç `Ý0Í&0È( @`È(ÿÿÿÿÿÿÿÿpý+0È(À=#’&PÜ&È °Þ0Í&€Æ(  @Á(ÿÿÿÿÿÿÿÿ ý+€ª)€>#’&PÜ'É ß0Í&€Æ(  @Á(ÿÿÿÿÿÿÿÿ ý+€Æ(@?#’&PÜ)Ê àà0Í&€Æ(  @Á(ÿÿÿÿÿÿÿÿ ý+0È(@#’&PÜ-Ë  â0Í&€Æ(  @Á(ÿÿÿÿÿÿÿÿ ý+þ+‘"°&PÜ?Ì pî0Í& Ä( ÐÄ(ÿÿÿÿÿÿÿÿ`þ+€ª) €' @g!À¥'0È( @`È(ÿÿÿÿÿÿÿÿË(€ª)À@# Ó'@g"À¥'`Ë(@Ë(ÿÿÿÿÿÿÿÿpÁ(€ª)p“&@g%€Ô'0È( @`È(ÿÿÿÿÿÿÿÿpÁ(0È( €' @g'Ö'0È( @`È(ÿÿÿÿÿÿÿÿË(0È( €' @g+€¨'0È( @`È(ÿÿÿÿÿÿÿÿÁ(€ª)@‡#’&@g-€¨'€Æ( @Á(ÿÿÿÿÿÿÿÿË(€ª) 19ð¼!›o 61º*Ø›o 71Dº*™o :1<19`Ec›o P1R1;ð S1Е-º*³? 9Ð Y¡o ¾?  º*åžo ¿? 9‘Øžo È? àá-º*Ê? Dº*,¡o Ì? º*óo Î? Dº*Ñ? º*M 9ð7!°¢o ^  º*åžo _ -º*‘¡o ` Dº*d º*,¡o e º*óo g Dº*j Ðì-º*ŒÆÐì-º*6§o ÆðÛ-º*åžo ŽÆ90–s¤o ”ưÝ-º*ù¦o •ÆDº*,¡o —Æ pØ-º*é¤o ™Æ9ùë¤o ¥Æ°æ-º*€J#’&€õ-N`Ðá'€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(€ª)ÀI#àà' €õ-Qc°@â'€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(€ª)@Ø"Pä'€õ-Rd @â'€Æ( @Á(ÿÿÿÿÿÿÿÿpÁ(€ª) Ö"@â'€õ-Seá'€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(€Æ( ¼"P&`..“?À¿ÐW(0È(  `È(ÿÿÿÿÿÿÿÿpÁ(€ª)ÀL#Ä'€..i På'0È( @`È(ÿÿÿÿÿÿÿÿpÁ(€ª)àÙ"á'€..jPå'0È(  `È(ÿÿÿÿÿÿÿÿpÁ(0È(ðÝ"á'€.."oP°å'0È(  `È(ÿÿÿÿÿÿÿÿpÁ(0È(À#°( `H.j¬pð'0È( @`È(ÿÿÿÿÿÿÿÿpÁ(€ª)€# ( `H.l®Ðqð'0È( @`È(ÿÿÿÿÿÿÿÿË(€ª)ðê"@( `H.n°sð'0È( @`È(ÿÿÿÿÿÿÿÿÁ(€ª)@Q#ð( `H.u²ptpè'0È( @`È(ÿÿÿÿÿÿÿÿpÁ(€ª)@#ÐÀ& `H.v³Àupè'0È( @`È(ÿÿÿÿÿÿÿÿpÁ(0È(#À¾& `H.zµðwpè'0È( @`È(ÿÿÿÿÿÿÿÿË(0È(À#àö' `H.}·°ypè'0È( @`È(ÿÿÿÿÿÿÿÿÁ(0È(@T#°û' `H.¹p{pè'0È( @`È(ÿÿÿÿÿÿÿÿpý+0È(€#ý' `H.€ºP|pè'0È( @`È(ÿÿÿÿÿÿÿÿ ý+€ª)ÀU#’&`H.…¼€~pè'€Æ(  @Á(ÿÿÿÿÿÿÿÿ ý+þ+€V#’&`H.†½`pè'€Æ(  @Á(ÿÿÿÿÿÿÿÿ`þ+€ª)X#’&`H.‡¾@€pè'€Æ(  @Á(ÿÿÿÿÿÿÿÿ`þ+€Æ(€D# Ó'@g.€¨'`Ë(@Ë(ÿÿÿÿÿÿÿÿpÁ(€ª)ÀX#’&`H.Š¿ pè'€Æ(  @Á(ÿÿÿÿÿÿÿÿ`þ+0È(ì"П& `H.ŒÀ°rpè'0È( @`È(ÿÿÿÿÿÿÿÿ€ÿ+€ª)@Z#pó' `H.“ÂÐ÷ é'0È( @`È(ÿÿÿÿÿÿÿÿpÁ(€ª)[#pó' `H.”à é'0È( @`È(ÿÿÿÿÿÿÿÿpÁ(0È(À[#’&`H.˜Ä‚ é'€Æ(  @Á(ÿÿÿÿÿÿÿÿË(€ª)€\#’&`H.œÅpú é'€Æ(  @Á(ÿÿÿÿÿÿÿÿË(€Æ(@]#’&`H. Æp‚ é'€Æ(  @Á(ÿÿÿÿÿÿÿÿË(0È(^# ( `H.¢Çà‚ é'0È( @`È(ÿÿÿÿÿÿÿÿÁ(€ª)À^#á'`H.£ÈP é'0È(  `È(ÿÿÿÿÿÿÿÿÁ(0È(0î"@( `H.§ÉPƒ é'0È( @`È(ÿÿÿÿÿÿÿÿpý+€ª)@`#pù% `H.®ÌàúP(0È( @`È(ÿÿÿÿÿÿÿÿpÁ(€ª)a#°ð' `H.¯Í0„P(0È( @`È(ÿÿÿÿÿÿÿÿpÁ(0È( ð"°(`H.°Î°rP(€ª)@pÁ(ÿÿÿÿÿÿÿÿË(€ª)d#P(€../Ò… ~&`Ë(@Ë(ÿÿÿÿÿÿÿÿpÁ(€ª)@c#P(€..2Õ…`(`Ë(@Ë(ÿÿÿÿÿÿÿÿpÁ(€ª)Pö" é'€..3Ö°r`( ,@Ðý+ÿÿÿÿÿÿÿÿË(€ª)àó"`(€..4×€… ~&,@0þ+ÿÿÿÿÿÿÿÿpÁ(€ª)€e#Љ& À·-¸á€X€!(0È( @`È(ÿÿÿÿÿÿÿÿpÁ(€ª)@f#0"( À·-¹â`¾€!(0È( @`È(ÿÿÿÿÿÿÿÿpÁ(0È(ù"’&À·-½ãо€!(€Æ(  @Á(ÿÿÿÿÿÿÿÿË(€ª)Àg#’&À·- ê@âÐÞ'€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(€ª)€h#À¾& À·-ë°ÔÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿpÁ(0È(@i#À¾& À·-ìÕÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿË(€ª)j#À¾& À·-ípÖÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿË(0È(Àj#À¾& À·-îP×ÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿÁ(€ª)€k#À¾& À·-ï0ØÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿÁ(0È(@l#À¾& À·-ðÙÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿpý+€ª)m#À¾& À·-ñðÙÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿpý+0È(Àm#À¾& À·-òÐÚÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿ ý+€ª)€n#À¾& À·-ó°ÛÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿ ý+0È(@o#À¾& À·-ôÜÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿ`þ+€ª)p#À¾& À·-õpÝÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿ`þ+0È(Àp#Љ& À·-öãÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿ€ÿ+€ª)€q#0"( À·-!÷äÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿ€ÿ+0È(@r#’&À·-#øpäÐÞ'€Æ(  @Á(ÿÿÿÿÿÿÿÿà5,€ª)s#’&À·-'ùPåÐÞ'€Æ(  @Á(ÿÿÿÿÿÿÿÿà5,€Æ(Às#Ä'À·-)úÀåÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿà5,0È(€t#`‘& À·--û0æÐÞ' Ä( ÐÄ(ÿÿÿÿÿÿÿÿ@6,€ª)@u# Ž&À·-.ü æÐÞ'`Â( Â(ÿÿÿÿÿÿÿÿ@6, Ä(v##(À·-/ýðàÐÞ'`Â( Â(ÿÿÿÿÿÿÿÿ@6,®)Àv#@$( À·-3þçÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿ@6,0È(€w#°Ä'À·-<ÿ@éÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿ7,€ª)@x#П& À·-E àëÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿ7,0È(y#П& À·-F PìÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿ`7,€ª)Ày#П& À·-G ÀìÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿ`7,0È(€z#П& À·-H 0íÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿÀ7,€ª)@{#pù% À·-I @™ÐÞ'0È( @`È(ÿÿÿÿÿÿÿÿÀ7,0È(|#’&À·-K  íÐÞ'€Æ(  @Á(ÿÿÿÿÿÿÿÿ 8,€ª)ü"ð$(À·-M îÐÞ'à,P,ÿÿÿÿÿÿÿÿ 8,€Æ(€}#4( À·-Š ðü`3(0È( @`È(ÿÿÿÿÿÿÿÿpÁ(€ª)@~#À4( À·-‹ Ðý`3(0È( @`È(ÿÿÿÿÿÿÿÿpÁ(0È(#p5( À·-Œ! `Ð`3(0È( @`È(ÿÿÿÿÿÿÿÿË(€ª) # 6( À·-" ÿ`3(0È( @`È(ÿÿÿÿÿÿÿÿË(0È(€€#’&PÜo– _°±&€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(€ª)@#’&PÜp— €_°±&€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(€Æ(‚#p´&PÜq˜ `—°±&p,ÐÃ)ÿÿÿÿÿÿÿÿpÁ(0È( ˆ"’&PÜr™ З°±&€Æ(  @Á(ÿÿÿÿÿÿÿÿË(€ª)€ƒ#°&PÜÕž à¯0·& Ä( ÐÄ(ÿÿÿÿÿÿÿÿpÁ(€ª)@„#’&PÜÖŸ _0·&€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(€Æ(…#’&PÜÖ  €_0·&€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(0È(À…#’&PÜÖ¡ P°0·&€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(þ+°Œ"е& PÜ×¢ À°0·&0È( @`È(ÿÿÿÿÿÿÿÿË(€ª)€&#’&PÜî¦ à¶à·&€Æ(  @Á(ÿÿÿÿÿÿÿÿpÁ(€ª)ÀC# €' @g,€¨'0È( @`È(ÿÿÿÿÿÿÿÿË(0È(C#’&@g(Ö'€Æ( @Á(ÿÿÿÿÿÿÿÿË(€ª)`²&! àõ-\¼ `ª0È( @`È(`²&ÿÿÿÿÿÿÿÿ$ m(! àõ-_¾ 0T"0È( @`È( m(ÿÿÿÿÿÿÿÿ`²&! àõ-_À `ª0È( @`È(`²&ÿÿÿÿÿÿÿÿ€’# m(! àõ-g 0T"0È( @`È( m(ÿÿÿÿÿÿÿÿ “#pù%! àõ-gà Po0È( @`È(pù%ÿÿÿÿÿÿÿÿÀJ(! àõ-gÄ 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ`”# m(! àõ-kÆ 0T"0È( @`È( m(ÿÿÿÿÿÿÿÿàá#pù%! àõ-kÇ Po0È( @`È(pù%ÿÿÿÿÿÿÿÿ`²&! àõ-kÉ `ª0È( @`È(`²&ÿÿÿÿÿÿÿÿà %àÍ&! PÜ#ö 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿà–#€å%! àõ-tË j0È( @`È(€å%ÿÿÿÿÿÿÿÿ€—#ÀJ(! àõ-tÌ p³0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ`²&! àõ-tÍ `ª0È( @`È(`²&ÿÿÿÿÿÿÿÿÀ˜#€å%! àõ-wÏ j0È( @`È(€å%ÿÿÿÿÿÿÿÿÀJ(! àõ-wÐ pb0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ š#€å%! àõ-zÒ j0È( @`È(€å%ÿÿÿÿÿÿÿÿ %’&!PÜ#ù €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀJ(! àõ-zÓ pb0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿà›#’&!àõ-„Õ À\€Æ( @Á(’&ÿÿÿÿÿÿÿÿ€œ#ÀJ(! àõ-„Ö pb0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ`²&! àõ-„× `ª0È( @`È(`²&ÿÿÿÿÿÿÿÿÀ#’&!àõ-†Ù À\€Æ( @Á(’&ÿÿÿÿÿÿÿÿÀJ(! àõ-†Ú pb0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿÀJ(! àõ-Ý 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ’&!PÜ$ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€Ü$’&!PÜçe €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜ* €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀJ(! àõ-•ß 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ ¢#ÀJ(! àõ-˜á 0T"0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿÀJ(! àõ-˜â 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ`£#àd(! àõ-£ä 0T"0È( @`È(àd(ÿÿÿÿÿÿÿÿ¤#ÀJ(! àõ-£å 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ`²&! àõ-£æ `ª0È( @`È(`²&ÿÿÿÿÿÿÿÿ@¥#ÀJ(! àõ-ªè 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ`²&! àõ-ªé `ª0È( @`È(`²&ÿÿÿÿÿÿÿÿ€¦#ÀJ(! àõ-¯ë 0T"0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ §#ÀJ(! àõ-¯ì 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ`²&! àõ-¯í `ª0È( @`È(`²&ÿÿÿÿÿÿÿÿ \(! àõ-¹ï ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ \(! àõ-ºñ ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ \(! àõ-Ìô ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ \(! àõ-×÷ ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿàª#’&!àõ-ãù P(€Æ( @Á(’&ÿÿÿÿÿÿÿÿ \(! àõ-ãú ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ ¬#’&!àõ-äü P(€Æ( @Á(’&ÿÿÿÿÿÿÿÿ \(! àõ-äý ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ’&!àõ-êÿ P(€Æ( @Á(’&ÿÿÿÿÿÿÿÿ®#’&!àõ-ø P(€Æ( @Á(’&ÿÿÿÿÿÿÿÿ \(! àõ-ø ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ@¯#’&!àõ- P(€Æ( @Á(’&ÿÿÿÿÿÿÿÿ \(! àõ- ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ’&!àõ- P(€Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ×%àd(! àõ-W· 0T"0È( @`È(àd(ÿÿÿÿÿÿÿÿ \(! àõ- ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ`²#’&!àõ-  Ðö€Æ( @Á(’&ÿÿÿÿÿÿÿÿ \(! àõ-  ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ ³# m(! àõ- 0T"0È( @`È( m(ÿÿÿÿÿÿÿÿ@´#’&!àõ- ЀÆ( @Á(’&ÿÿÿÿÿÿÿÿàd(! àõ- ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿÀ¾&! àõ- 0T"0È( @`È(À¾&ÿÿÿÿÿÿÿÿ ¶# m(! àõ-' 0T"0È( @`È( m(ÿÿÿÿÿÿÿÿÀ¶#’&!àõ-' ЀÆ( @Á(’&ÿÿÿÿÿÿÿÿàd(! àõ-' ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿ¸#€å%! àõ-8  k0È( @`È(€å%ÿÿÿÿÿÿÿÿ ¸#€&! àõ-8 Ð0È( @`È(€&ÿÿÿÿÿÿÿÿ@¹#’&!àõ-8 €l€Æ( @Á(’&ÿÿÿÿÿÿÿÿàd(! àõ-8 ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿ€º#€å%! àõ-;  k0È( @`È(€å%ÿÿÿÿÿÿÿÿ »#€&! àõ-; Ð0È( @`È(€&ÿÿÿÿÿÿÿÿÀ»#’&!àõ-; €l€Æ( @Á(’&ÿÿÿÿÿÿÿÿàd(! àõ-; ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿ½#€å%! àõ-E"  k0È( @`È(€å%ÿÿÿÿÿÿÿÿ ½#€&! àõ-E# Ð0È( @`È(€&ÿÿÿÿÿÿÿÿàd(! àõ-E$ ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿà¾#ÀJ(! àõ-N& 0T"0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿàd(! àõ-N' ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿÐÀ&! àõ-T) 0T"0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ Â#’&!àõ-[+ P(€Æ( @Á(’&ÿÿÿÿÿÿÿÿП&! PÜ0 0È( @`È(П&ÿÿÿÿÿÿÿÿà%П&! PÜ2! 0È( @`È(П&ÿÿÿÿÿÿÿÿ@!%ÐÀ&! PÜ5- 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ \(! àõ-[, ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿàÃ# g(! àõ-c. j0È( @`È( g(ÿÿÿÿÿÿÿÿ€Ä#pù%! àõ-c/ @±0È( @`È(pù%ÿÿÿÿÿÿÿÿ Å#pù%! àõ-c0 Ð0È( @`È(pù%ÿÿÿÿÿÿÿÿàd(! àõ-c1 ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿ`Æ# &! àõ-i3 j0È( @`È( &ÿÿÿÿÿÿÿÿÇ#pù%! àõ-i4 @±0È( @`È(pù%ÿÿÿÿÿÿÿÿ Ç#pù%! àõ-i5 Ð0È( @`È(pù%ÿÿÿÿÿÿÿÿàd(! àõ-i6 0T"0È( @`È(àd(ÿÿÿÿÿÿÿÿàÈ#ÀJ(! àõ-t8 0T"0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿàd(! àõ-t9 ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿ Ê# g(! àõ-; j0È( @`È( g(ÿÿÿÿÿÿÿÿÀÊ#pù%! àõ-< @±0È( @`È(pù%ÿÿÿÿÿÿÿÿ`Ë#pù%! àõ-= Ð0È( @`È(pù%ÿÿÿÿÿÿÿÿàd(! àõ-> ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿ Ì# &! àõ-@ j0È( @`È( &ÿÿÿÿÿÿÿÿ@Í#pù%! àõ-A @±0È( @`È(pù%ÿÿÿÿÿÿÿÿàÍ#pù%! àõ-B Ð0È( @`È(pù%ÿÿÿÿÿÿÿÿàd(! àõ-C ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿ Ï# \(! àõ-ŠE ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿÀÏ#p“&!àõ-ŠF pp0È( @`È(p“&ÿÿÿÿÿÿÿÿ’&!àõ-ŠG àp€Æ( @Á(’&ÿÿÿÿÿÿÿÿ \(! àõ-I ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ \(! àõ-”K ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ@Ò# \(! àõ-¢M ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿàÒ#Ä'!àõ-¢N pp0È( @`È(Ä'ÿÿÿÿÿÿÿÿ’&!àõ-¢O àp€Æ( @Á(’&ÿÿÿÿÿÿÿÿ \(! àõ-§Q ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿÀÔ#àd(! àõ-»S ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿ0&! àõ-»T P0È( @`È(0&ÿÿÿÿÿÿÿÿÖ# \(! àõ-ÀV ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ@&! àõ-ÀW P0È( @`È(@&ÿÿÿÿÿÿÿÿ@×# \(! àõ-ÏY ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿà×#°Ä'!àõ-ÏZ pp0È( @`È(°Ä'ÿÿÿÿÿÿÿÿ’&!àõ-Ï[ àp€Æ( @Á(’&ÿÿÿÿÿÿÿÿ \(! àõ-Ð] ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿÀÙ#àd(! àõ-Ñ_ ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿ°&! àõ-Ñ` P0È( @`È(°&ÿÿÿÿÿÿÿÿÛ# \(! àõ-Òb ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿÀ&! àõ-Òc P0È( @`È(À&ÿÿÿÿÿÿÿÿ \(! àõ-×e ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ \(! àõ-Ùg ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ \(! àõ-Ûi ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ \(! àõ-àk ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ \(! àõ-ám ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ \(! àõ-âo ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿÐÀ&! àõ-ëq 0T"0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ \(! àõ-üy ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ€$ÐÀ&! àõ-{ °ƒ0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿY/9àíšo i/j/Dº*™o k/l/Dº*m/•#ÀJ(! àõ-kÈ 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ\19¹!šo m1n1Dº*™o o1p1Dº*q1¡19ð¼!›o ·1º*Ø›o ¸1Dº*™o »1½1;º*P¾1+29`‹›o 229P¹Ø›o 72Dº*™o <2=29P¹Þ›o A2¨F9 m0ª-º*³Fº*Ø›o ´F9pí™o ÉF úç,º*ËFDº*Þ›o ÐF ª-º*«Q9@ë›o ¹Qº*Ø›o ºQº*™o »Q9`oÅQº*Þ›o ÆQ ª-º*)V9@ë›o 7Vº*Ø›o 8Vº*™o 9V9°pAVº*Þ›o BV ª-º*©Z9@ë›o ·Zº*Ø›o ¸Zº*™o ¹Z9rÁZº*Þ›o ÂZ ª-º*-[9@ë›o ;[º*Ø›o <[º*™o =[9prI[º*Þ›o J[ ª-º*/_9@ë›o =_º*Ø›o >_º*™o ?_9ÀsM_º*Þ›o N_ ª-º*s9@ë›o sº*Ø›o sº*™o s9 x6sº*Þ›o 7sð´-º*À¾&! àõ-€ 0T"0È( @`È(À¾&ÿÿÿÿÿÿÿÿõáº*Öžo öáÀÒè,º*Ø›o ÷á; º* @âàá-º*â;º* âº*óo õà 9줠o á  º*åžo á Dº*Øžo á àá-º*á Dº*ãžo á º*óo Ÿä º**¡o  ä  º*åžo ¡ä 9»Øžo ¨ä àá-º*ªä ;º* °ä º*óo ë19Ð!£o ô1ðû-º*åžo õ1Dº*‘¡o ø1º*ú1Dº*,¡o ý10Ú-º*óo Ê9 6§o ÊðÛ-º*åžo Ê<º*@ʰÝ-º*ù¦o Ê<º*0ÊpØ-º*é¤o ŠÊ9 6§o ’ÊðÛ-º*åžo “Ê<º*H–ʰÝ-º*ù¦o ˜Ê<º*Ð ›ÊpØ-º*é¤o Ë9 6§o ËðÛ-º*åžo Ë<º*P˰Ý-º*ù¦o Ë<º*Ø ËpØ-º*é¤o  *%àÍ&! PÜ;B 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGd"p Pþ€$ P'°‚'ð ' ¡'°£'À¥'Ö'€¨'[.9à¹!šo m.n.Dº*™o o.p.Dº*q.M ø`f. ~&M ð€!(П&! PÜB] 0È( @`È(П&ÿÿÿÿÿÿÿÿ A%àÍ&! PÜGj 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ$¢&! àõ-"… €ˆ0È( @`È(¢&ÿÿÿÿÿÿÿÿÀ_%ÐÀ&! PÜ]² 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿM ø°±&À¾&! PÜ_¹ 0È( @`È(À¾&ÿÿÿÿÿÿÿÿM ðà·&@b%àÍ&! PÜ`» 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÍ&! PÜa¿ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿÐÀ&! PÜb 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ $ÐÀ&! PÜkà 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿf%àÍ&! PÜeÊ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PÜfÎ €Æ( @Á(’&ÿÿÿÿÿÿÿÿàÍ&! PÜjØ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PÜlÝ €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀn%ð®&! PÜnå €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿÐÀ&! àõ-| à¥0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ \(! àõ- ~ ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿÀ¾&! àõ-‚ 0T"0È( @`È(À¾&ÿÿÿÿÿÿÿÿÀJ(! àõ-"† 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ@ $¢&! àõ-&ˆ €ˆ0È( @`È(¢&ÿÿÿÿÿÿÿÿà $ÀJ(! àõ-&‰ 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ`²&! àõ-&Š @Š0È( @`È(`²&ÿÿÿÿÿÿÿÿ \(! àõ-.Œ ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ \(! àõ-2Ž ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ \(! àõ-5 ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿM ø0·&M ø0Í&àØ&!0PÜhÙ €Æ( @Á(àØ&ÿÿÿÿÿÿÿÿà$@Ú&! PÜiÛ 0È( @`È(@Ú&ÿÿÿÿÿÿÿÿ’&!PÜiÜ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@Ú&! PÜjÞ 0È( @`È(@Ú&ÿÿÿÿÿÿÿÿ’&!PÜká €Æ( @Á(’&ÿÿÿÿÿÿÿÿÐÀ&! PÜlã 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿð®&! PÜmå €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿð®&! PÜoé €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ $$P°&! PÜ| €Æ( @Á(P°&ÿÿÿÿÿÿÿÿð®&! PÜnç €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ`*$ '! P܃ 0È( @`È( 'ÿÿÿÿÿÿÿÿ $ º&! PÜpë 0È( @`È( º&ÿÿÿÿÿÿÿÿÀ$-&! PÜpì 0È( @`È(-&ÿÿÿÿÿÿÿÿП&! PÜpí 0È( @`È(П&ÿÿÿÿÿÿÿÿ$P°&! PÜqï €Æ( @Á(P°&ÿÿÿÿÿÿÿÿП&! PÜqð 0È( @`È(П&ÿÿÿÿÿÿÿÿ@$P°&! PÜrò €Æ( @Á(P°&ÿÿÿÿÿÿÿÿП&! PÜró 0È( @`È(П&ÿÿÿÿÿÿÿÿ€$P°&! PÜsõ €Æ( @Á(P°&ÿÿÿÿÿÿÿÿ $°&!PÜsö  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿП&! PÜs÷ 0È( @`È(П&ÿÿÿÿÿÿÿÿð®&! PÜvû €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿð®&! PÜwý €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ $ð®&! PÜxÿ €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ@$ð®&! PÜx €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿà$ð®&! PÜx €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ€$ð®&! PÜx €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ $ð®&! PÜx €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿÀ$ð®&! PÜx €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ!$ð®&! PÜx €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ’&!P܇. €Æ( @Á(’&ÿÿÿÿÿÿÿÿð®&! PÜx €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ@"$àÍ&! PÜy 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿà"$ð®&! PÜy €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿð®&! PÜy €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ $’&!PÜ| €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ$$°&!PÜ|  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿP &! PÜ| 0È( @`È(P &ÿÿÿÿÿÿÿÿ&$àÍ&! PÜ} 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PÜ} €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@'$°&!PÜ  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿà'$-&! PÜ 0È( @`È(-&ÿÿÿÿÿÿÿÿ€($-&! PÜ 0È( @`È(-&ÿÿÿÿÿÿÿÿ-&! PÜ 0È( @`È(-&ÿÿÿÿÿÿÿÿÀ)$°&!PÜ‚  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿП&! PÜ‚ 0È( @`È(П&ÿÿÿÿÿÿÿÿ+$àÍ&! P܃! 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ +$’&!P܃" €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@,$’&!P܃# €Æ( @Á(’&ÿÿÿÿÿÿÿÿà,$’&!P܃$ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€-$’&!P܃% €Æ( @Á(’&ÿÿÿÿÿÿÿÿ .$’&!P܃& €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ.$’&!P܃' €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!P܃( €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜ„* €Æ( @Á(’&ÿÿÿÿÿÿÿÿÒ&! PÜŠ2 0È( @`È(Ò&ÿÿÿÿÿÿÿÿàÍ&! PÜ‹4 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿð®&! PÜK€Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ Î9 6§o ÎðÛ-º*åžo Î<º*pΰÝ-º*ù¦o Î<º*ÎpØ-º*é¤o ŠÒ9 6§o ’ÒðÛ-º*åžo “Ò<º* –Ò°Ý-º*ù¦o ˜Ò<º*P›ÒpØ-º*é¤o ŠË9 6§o ’ËðÛ-º*åžo “Ë<º*X–˰Ý-º*ù¦o ˜Ë<º*8›ËpØ-º*é¤o Ì9 6§o ÌðÛ-º*åžo Ì<º*`̰Ý-º*ù¦o Ì<º*à ÌpØ-º*é¤o ŠÌ9 6§o ’ÌðÛ-º*åžo “Ì<º*è –Ì°Ý-º*ù¦o ˜Ì<º*@›ÌpØ-º*é¤o Í9 6§o ÍðÛ-º*åžo Í<º*ð ͰÝ-º*ù¦o Í<º*HÍpØ-º*é¤o ×9 6§o ×ðÛ-º*åžo ×<º*À×°Ý-º*ù¦o ×<º*H×pØ-º*é¤o ŠÍ9 6§o ’ÍðÛ-º*åžo “Í<º*h–ͰÝ-º*ù¦o ˜Í<º*ø ›ÍpØ-º*é¤o ŠÎ9 6§o ’ÎðÛ-º*åžo “Î<º*x–ΰÝ-º*ù¦o ˜Î<º*›ÎpØ-º*é¤o Ï9 6§o ÏðÛ-º*åžo Ï<º*€Ï°Ý-º*ù¦o Ï<º*ÏpØ-º*é¤o Ñ9 6§o ÑðÛ-º*åžo Ñ<º*ˆÑ°Ý-º*ù¦o Ñ<º*ÑpØ-º*é¤o ŠÑ9 6§o ’ÑðÛ-º*åžo “Ñ<º*–ѰÝ-º*ù¦o ˜Ñ<º* ›ÑpØ-º*é¤o Ò9 6§o ÒðÛ-º*åžo Ò<º*˜Ò°Ý-º*ù¦o Ò<º*(ÒpØ-º*é¤o Ó9 6§o ÓðÛ-º*åžo Ó<º*¨Ó°Ý-º*ù¦o Ó<º*0ÓpØ-º*é¤o ŠÓ9 6§o ’ÓðÛ-º*åžo “Ó<º*°–Ó°Ý-º*ù¦o ˜Ó<º*8›ÓpØ-º*é¤o Ô9 6§o ÔðÛ-º*åžo Ô<º*¸Ô°Ý-º*ù¦o Ô<º*@ÔpØ-º*é¤o p“&!PÜ$l0È( @`È(p“&ÿÿÿÿÿÿÿÿŠ×9 6§o ’×ðÛ-º*åžo “×<º*È–×°Ý-º*ù¦o ˜×<º*P›×pØ-º*é¤o Ø9 6§o ØðÛ-º*åžo Ø<º*XذÝ-º*ù¦o Ø<º*XØpØ-º*é¤o ŠØ9 6§o ’ØðÛ-º*åžo “Ø<º*ЖذÝ-º*ù¦o ˜Ø<º*`›ØpØ-º*é¤o Ù9 6§o ÙðÛ-º*åžo Ù<º*ØÙ°Ý-º*ù¦o Ù<º*hÙpØ-º*é¤o ŠÙ9 6§o ’ÙðÛ-º*åžo “Ù<º*à–Ù°Ý-º*ù¦o ˜Ù<º*`›ÙpØ-º*é¤o Ú9 6§o ÚðÛ-º*åžo Ú<º*èÚ°Ý-º*ù¦o Ú<º*hÚpØ-º*é¤o ŠÜ9 6§o ’ÜðÛ-º*åžo “Ü<º*ð–ܰÝ-º*ù¦o ˜Ü<º*p›ÜpØ-º*é¤o Ý9 6§o ÝðÛ-º*åžo Ý<º*øÝ°Ý-º*ù¦o Ý<º*xÝpØ-º*é¤o ŠÝ9 6§o ’ÝðÛ-º*åžo “Ý<º*!–ݰÝ-º*ù¦o ˜Ý<º*p#›ÝpØ-º*é¤o ŠÞ9 6§o ’ÞðÛ-º*åžo “Þ<º*–Þ°Ý-º*ù¦o ˜Þ<º*ˆ›ÞpØ-º*é¤o ß9 6§o ßðÛ-º*åžo ß<º*ß°Ý-º*ù¦o ß<º*ßpØ-º*é¤o D$àÍ&! PÜŒ6 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ@E$’&!PÜŒ7 €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€F$’&!PÜŒ8 €Æ( @Á(’&ÿÿÿÿÿÿÿÿM øÐW(ÀG$’&!PÜŒ9 €Æ( @Á(’&ÿÿÿÿÿÿÿÿM ðÐÞ'’&!PÜŒ: €Æ( @Á(’&ÿÿÿÿÿÿÿÿM ø f.á'M ð@â'àØ&!0PÜ? €Æ( @Á(àØ&ÿÿÿÿÿÿÿÿàÍ&! PÜ—H 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿM ø°å'ÀL$À¾&! PܘJ 0È( @`È(À¾&ÿÿÿÿÿÿÿÿß"ç' €`H.'rPYÅ+ÿÿÿÿÿÿÿÿ’&!PܘK €Æ( @Á(’&ÿÿÿÿÿÿÿÿ L$ç' €`H.(sÀYÅ+ÿÿÿÿÿÿÿÿÀ¾&! PÜ™M 0È( @`È(À¾&ÿÿÿÿÿÿÿÿ`M$ç' €`H.)t0Z Æ+ÿÿÿÿÿÿÿÿ \(! PÜšO 0È( @`È( \(ÿÿÿÿÿÿÿÿ N$ç' €`H.*u Z€Æ+ÿÿÿÿÿÿÿÿ’&!PÜ›Q €Æ( @Á(’&ÿÿÿÿÿÿÿÿàO$ç' €`H.,v€[Ç+ÿÿÿÿÿÿÿÿ Q$ç' €`H.-w`\ Ç+ÿÿÿÿÿÿÿÿ’&!PÜŸT €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀQ$ç' €`H..xÐ\È+ÿÿÿÿÿÿÿÿàT$àÍ&! PÜ V 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿS$ç' €`H./y@]È+ÿÿÿÿÿÿÿÿ’&!PÜ W €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@T$ç' €`H.1z ^ É+ÿÿÿÿÿÿÿÿ`W$àÍ&! PÜ¡Y 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ€U$ç' €`H.2{p_°É+ÿÿÿÿÿÿÿÿ’&!PÜ¡Z €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀV$Àç' €`H.9}P`Ë+ÿÿÿÿÿÿÿÿàY$àÍ&! PÜ¢\ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿX$Àç' €`H.:~0aÀË+ÿÿÿÿÿÿÿÿ’&!PÜ¢] €Æ( @Á(’&ÿÿÿÿÿÿÿÿM ðpè'M ð é'’&!PÜ£` €Æ( @Á(’&ÿÿÿÿÿÿÿÿ Þ9 6§o ÞðÛ-º*åžo Þ<º*Þ°Ý-º*ù¦o Þ<º*€ÞpØ-º*é¤o ¸&! Pܤb 0È( @`È(¸&ÿÿÿÿÿÿÿÿ`a$°&!Pܦe  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿŠß9 6§o ’ßðÛ-º*åžo “ß<º*–ß°Ý-º*ù¦o ˜ß<º*˜›ßpØ-º*é¤o àÍ&! PÜŽ= 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿM øå'`R$ð®&! PÜŸS €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿÀ[$¸&! PÜ£_ 0È( @`È(¸&ÿÿÿÿÿÿÿÿb$°&!Pܦf  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿ b$°&!Pܦg  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿ°&!Pܦh  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿàc$°&!Pܧj  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿ€d$°&!Pܧk  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿ°&!Pܧl  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿÀe$À¾&! PÜ©o 0È( @`È(À¾&ÿÿÿÿÿÿÿÿ’&!PÜ©p €Æ( @Á(’&ÿÿÿÿÿÿÿÿð®&! Pܪr €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ’&!PÜ«t €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@h$ÐÀ&! PÜ­w 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ’&!PÜ­x €Æ( @Á(’&ÿÿÿÿÿÿÿÿÐÀ&! PÜ®z 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿÀ¾&! Pܯ| 0È( @`È(À¾&ÿÿÿÿÿÿÿÿ€¯$àÍ&! Pܰ~ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PÜ´ €Æ( @Á(’&ÿÿÿÿÿÿÿÿl$àÍ&! Pܵƒ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!Pܵ„ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@m$àÍ&! PÜ·‡ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PÜ·ˆ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€n$àÍ&! Pܹ‹ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PܹŒ €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀo$’&!PÜºŽ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!Pܺ €Æ( @Á(’&ÿÿÿÿÿÿÿÿq$’&!PÜ»‘ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ q$’&!PÜ»’ €Æ( @Á(’&ÿÿÿÿÿÿÿÿàØ&!0PÜ»“ €Æ( @Á(àØ&ÿÿÿÿÿÿÿÿàr$’&!Pܼ• €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€s$’&!Pܼ– €Æ( @Á(’&ÿÿÿÿÿÿÿÿ t$@Ú&! Pܼ— 0È( @`È(@Ú&ÿÿÿÿÿÿÿÿ’&!Pܼ˜ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`u$’&!Pܽ𠀯( @Á(’&ÿÿÿÿÿÿÿÿv$’&!Pܽ› €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@Ú&! Pܽœ 0È( @`È(@Ú&ÿÿÿÿÿÿÿÿ@w$’&!Pܾž €Æ( @Á(’&ÿÿÿÿÿÿÿÿàw$’&!PܾŸ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€x$ÐÀ&! Pܾ  0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ’&!Pܾ¡ €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀy$’&!PÜ¿£ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`z$’&!PÜ¿¤ €Æ( @Á(’&ÿÿÿÿÿÿÿÿÐÀ&! PÜ¿¥ 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ {$’&!PÜÀ§ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@|$’&!PÜÀ¨ €Æ( @Á(’&ÿÿÿÿÿÿÿÿà|$’&!PÜÀ© €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€}$P°&! PÜÀª €Æ( @Á(P°&ÿÿÿÿÿÿÿÿÀÎ$°&!PÜÀ«  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿÀ~$’&!PÜÁ® €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`$’&!PÜÁ¯ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€$’&!PÜÁ° €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜÁ± €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@$’&!Pܳ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜ´ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€‚$àÍ&! PÜö 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ ƒ$’&!PÜ÷ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜø €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`„$’&!PÜĺ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜÄ» €Æ( @Á(’&ÿÿÿÿÿÿÿÿ …$’&!PÜŽ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@†$’&!PÜž €Æ( @Á(’&ÿÿÿÿÿÿÿÿà†$À¾&! PÜÅ¿ 0È( @`È(À¾&ÿÿÿÿÿÿÿÿ’&!PÜÅÀ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ ˆ$’&!PÜÆ €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀˆ$’&!PÜÆà €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ¾&! PÜÆÄ 0È( @`È(À¾&ÿÿÿÿÿÿÿÿŠ$’&!PÜÇÆ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ Š$’&!PÜÇÇ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@‹$ð®&! PÜÇÈ €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ’&!PÜÇÉ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€Œ$’&!PÜÈË €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜÈÌ €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ$’&!PÜÉÎ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`Ž$’&!PÜÉÏ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ $¸&! PÜÉÐ 0È( @`È(¸&ÿÿÿÿÿÿÿÿ@‘#ÀJ(! àõ-_¿ 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ’&!PÜÉÑ €Æ( @Á(’&ÿÿÿÿÿÿÿÿà$’&!PÜÊÓ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€‘$’&!PÜÊÔ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ¸&! PÜÊÕ 0È( @`È(¸&ÿÿÿÿÿÿÿÿÀ’$’&!PÜË× €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`“$’&!PÜËØ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ”$À¾&! PÜËÙ 0È( @`È(À¾&ÿÿÿÿÿÿÿÿ’&!PÜËÚ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@•$’&!PÜÌÜ €Æ( @Á(’&ÿÿÿÿÿÿÿÿà•$’&!PÜÌÝ €Æ( @Á(’&ÿÿÿÿÿÿÿÿð®&! PÜÌÞ €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ —$’&!PÜÍà €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ—$’&!PÜÍá €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`˜$ÐÀ&! PÜÍâ 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ’&!PÜÍã €Æ( @Á(’&ÿÿÿÿÿÿÿÿ ™$’&!PÜÎå €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@š$’&!PÜÎæ €Æ( @Á(’&ÿÿÿÿÿÿÿÿÐÀ&! PÜÎç 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ œ$’&!PÜÏé €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`ž#àd(! àõ-Ü ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿÀœ$’&!PÜÏê €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ¾&! PÜÏë 0È( @`È(À¾&ÿÿÿÿÿÿÿÿž$’&!PÜÐí €Æ( @Á(’&ÿÿÿÿÿÿÿÿ ž$’&!PÜÐî €Æ( @Á(’&ÿÿÿÿÿÿÿÿÐÀ&! PÜÐï 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ€ $’&!PÜÑñ €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀJ(! àõ-M² 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ ¡$’&!PÜÑò €Æ( @Á(’&ÿÿÿÿÿÿÿÿÐÀ&! PÜÑó 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ`¢$’&!PÜÒõ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ£$’&!PÜÒö €Æ( @Á(’&ÿÿÿÿÿÿÿÿ £$ð®&! PÜÒ÷ €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ’&!PÜÒø €Æ( @Á(’&ÿÿÿÿÿÿÿÿà¤$àÍ&! PÜÓú 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ€¥$’&!PÜÓû €Æ( @Á(’&ÿÿÿÿÿÿÿÿ ¦$’&!PÜÓü €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ¦$@Ú&! PÜÓý 0È( @`È(@Ú&ÿÿÿÿÿÿÿÿ’&!PÜÓþ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ¨$àÍ&! PÜÔ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ ¨$’&!PÜÔ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@©$’&!PÜÔ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@Ú&! PÜÔ 0È( @`È(@Ú&ÿÿÿÿÿÿÿÿ€ª$àÍ&! PÜÕ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ «$’&!PÜÕ €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ«$’&!PÜÕ €Æ( @Á(’&ÿÿÿÿÿÿÿÿàØ&!0PÜÕ €Æ( @Á(àØ&ÿÿÿÿÿÿÿÿ­$àÍ&! PÜÖ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ ­$’&!PÜÖ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@®$’&!PÜÖ €Æ( @Á(’&ÿÿÿÿÿÿÿÿà®$ÐÀ&! PÜÖ 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ’&!PÜÖ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!Pܰ €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ°$àÍ&! PÜ× 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ`±$’&!PÜ× €Æ( @Á(’&ÿÿÿÿÿÿÿÿ²$’&!PÜ× €Æ( @Á(’&ÿÿÿÿÿÿÿÿÐÀ&! PÜ× 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ@³$àÍ&! PÜØ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿà³$’&!PÜØ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€´$’&!PÜØ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ µ$’&!PÜØ €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀµ$P°&! PÜØ €Æ( @Á(P°&ÿÿÿÿÿÿÿÿ`¶$°&!PÜØ  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿP &! PÜØ 0È( @`È(P &ÿÿÿÿÿÿÿÿ ·$àÍ&! PÜÙ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ@¸$’&!PÜÙ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜÙ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€¹$àÍ&! PÜÚ! 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ º$’&!PÜÚ" €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜÚ# €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`»$àÍ&! PÜÛ% 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ¼$’&!PÜÛ& €Æ( @Á(’&ÿÿÿÿÿÿÿÿ ¼$’&!PÜÛ' €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@½$À¾&! PÜÛ( 0È( @`È(À¾&ÿÿÿÿÿÿÿÿ’&!PÜÛ) €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€¾$àÍ&! PÜÜ+ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ ¿$’&!PÜÜ, €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ¿$’&!PÜÜ- €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ¾&! PÜÜ. 0È( @`È(À¾&ÿÿÿÿÿÿÿÿÁ$àÍ&! PÜÝ0 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ Á$’&!PÜÝ1 €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@Â$’&!PÜÝ2 €Æ( @Á(’&ÿÿÿÿÿÿÿÿàÂ$ð®&! PÜÝ3 €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ’&!PÜÝ4 €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`[%àÍ&! PÜY¥ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿÀÄ$àÍ&! PÜÞ6 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ`Å$’&!PÜÞ7 €Æ( @Á(’&ÿÿÿÿÿÿÿÿÆ$’&!PÜÞ8 €Æ( @Á(’&ÿÿÿÿÿÿÿÿ Æ$¸&! PÜÞ9 0È( @`È(¸&ÿÿÿÿÿÿÿÿ’&!PÜÞ: €Æ( @Á(’&ÿÿÿÿÿÿÿÿàÇ$àÍ&! PÜß< 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ€È$’&!PÜß= €Æ( @Á(’&ÿÿÿÿÿÿÿÿ É$’&!PÜß> €Æ( @Á(’&ÿÿÿÿÿÿÿÿ¸&! PÜß? 0È( @`È(¸&ÿÿÿÿÿÿÿÿ \%àÍ&! PÜZ© 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿË$àÍ&! PÜàA 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ Ë$’&!PÜàB €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜàC €Æ( @Á(’&ÿÿÿÿÿÿÿÿàÌ$àÍ&! PÜáE 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ€Í$’&!PÜáF €Æ( @Á(’&ÿÿÿÿÿÿÿÿ Î$’&!PÜáG €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`Ï$À¾&! PÜáH 0È( @`È(À¾&ÿÿÿÿÿÿÿÿP &! PÜÀ¬ 0È( @`È(P &ÿÿÿÿÿÿÿÿ’&!PÜáI €Æ( @Á(’&ÿÿÿÿÿÿÿÿ Ð$àÍ&! PÜâK 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ@Ñ$’&!PÜâL €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€Ò$’&!PÜâM €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀd%’&!PÜcÅ €Æ( @Á(’&ÿÿÿÿÿÿÿÿð®&! PÜâN €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿÀÓ$àÍ&! PÜãP 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ P%’&!PÜãQ €Æ( @Á(’&ÿÿÿÿÿÿÿÿÕ$ÐÀ&! PÜãS 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ’&!PÜãT €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@Ö$àÍ&! PÜäV 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÖ$’&!PÜäW €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@X%’&!PÜäX €Æ( @Á(’&ÿÿÿÿÿÿÿÿ Ø$àÍ&! PÜå[ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿÀØ$’&!PÜå\ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`Ù$’&!PÜå] €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ¾&! PÜå^ 0È( @`È(À¾&ÿÿÿÿÿÿÿÿ Ú$àÍ&! PÜæ` 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ@Û$’&!PÜæa €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜæb €Æ( @Á(’&ÿÿÿÿÿÿÿÿ Ÿ#àÍ&! PÜçd 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ Ý$’&!PÜçf €Æ( @Á(’&ÿÿÿÿÿÿÿÿÐÀ&! PÜçg 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ`Þ$àÍ&! PÜèi 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿß$’&!PÜèj €Æ( @Á(’&ÿÿÿÿÿÿÿÿ ß$’&!PÜèk €Æ( @Á(’&ÿÿÿÿÿÿÿÿÐÀ&! PÜèl 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿàà$àÍ&! PÜén 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ€á$’&!PÜéo €Æ( @Á(’&ÿÿÿÿÿÿÿÿ â$’&!PÜép €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀâ$ð®&! PÜéq €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ’&!PÜér €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜêt €Æ( @Á(’&ÿÿÿÿÿÿÿÿ ä$’&!PÜëv €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜëw €Æ( @Á(’&ÿÿÿÿÿÿÿÿàå$ÐÀ&! PÜìy 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ€æ$ \(! PÜìz 0È( @`È( \(ÿÿÿÿÿÿÿÿ \(! PÜì{ 0È( @`È( \(ÿÿÿÿÿÿÿÿÀç$’&!PÜí} €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`è$’&!PÜí~ €Æ( @Á(’&ÿÿÿÿÿÿÿÿé$’&!PÜí €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜí€ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@ê$àÍ&! PÜð„ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PÜð… €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€ë$àÍ&! PÜõ‹ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PÜõŒ €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀì$ '! PÜöŽ 0È( @`È( 'ÿÿÿÿÿÿÿÿàÍ&! PÜö 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿî$ '! PÜ÷‘ 0È( @`È( 'ÿÿÿÿÿÿÿÿàÍ&! PÜ÷’ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ@ï$°&!PÜø”  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿàï$-&! PÜø• 0È( @`È(-&ÿÿÿÿÿÿÿÿ-&! PÜø– 0È( @`È(-&ÿÿÿÿÿÿÿÿ ñ$àÍ&! PÜù˜ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿð®&! PÜù™ €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ`ò$àÍ&! PÜú› 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿó$’&!PÜúœ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€r%’&!PÜú €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@ô$’&!PÜúŸ €Æ( @Á(’&ÿÿÿÿÿÿÿÿàô$’&!PÜú  €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜú¡ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ ö$àÍ&! PÜû£ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿÀö$’&!PÜû¤ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ s%’&!PÜû¥ €Æ( @Á(’&ÿÿÿÿÿÿÿÿø$’&!PÜû§ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ ø$’&!PÜû¨ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜû© €Æ( @Á(’&ÿÿÿÿÿÿÿÿÐÀ&! PÜü« 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ€ú$àÍ&! PÜý­ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ \(! PÜý® 0È( @`È( \(ÿÿÿÿÿÿÿÿÀû$’&!Pܸ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ ²'! PÜ» 0È( @`È( ²'ÿÿÿÿÿÿÿÿÐÀ&! Pܾ 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿÐÀ&! PÜÀ 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿÐÀ&! PÜ  0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿÐÀ&! PÜ Ä 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿÐÀ&! PÜ Æ 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ’&!PÜ È €Æ( @Á(’&ÿÿÿÿÿÿÿÿàÍ&! PÜ Ê 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ`%àÍ&! PÜÌ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PÜÍ €Æ( @Á(’&ÿÿÿÿÿÿÿÿÒ&! PÜÏ 0È( @`È(Ò&ÿÿÿÿÿÿÿÿ@%’&!PÜÑ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜÒ €Æ( @Á(’&ÿÿÿÿÿÿÿÿàØ&!0PÜÔ €Æ( @Á(àØ&ÿÿÿÿÿÿÿÿ %Ñ'!0PÜÖ €Æ( @Á(Ñ'ÿÿÿÿÿÿÿÿП&! PÜ× 0È( @`È(П&ÿÿÿÿÿÿÿÿàØ&!0PÜÙ €Æ( @Á(àØ&ÿÿÿÿÿÿÿÿ%Ñ'!0PÜÛ €Æ( @Á(Ñ'ÿÿÿÿÿÿÿÿП&! PÜÜ 0È( @`È(П&ÿÿÿÿÿÿÿÿàØ&!0PÜÞ €Æ( @Á(àØ&ÿÿÿÿÿÿÿÿà%Ñ'!0PÜà €Æ( @Á(Ñ'ÿÿÿÿÿÿÿÿ€ %°&!PÜá  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿП&! PÜâ 0È( @`È(П&ÿÿÿÿÿÿÿÿ°&!PÜå  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿ’&!PÜç €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜé €Æ( @Á(’&ÿÿÿÿÿÿÿÿ  %’&!PÜî €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@ %ÐÀ&! PÜï 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ’&!PÜð €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€%’&!PÜ#÷ €Æ( @Á(’&ÿÿÿÿÿÿÿÿš#’&!PÜ#ø €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜ#ú €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`%àÍ&! PÜ$ü 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ%’&!PÜ$ý €Æ( @Á(’&ÿÿÿÿÿÿÿÿ %’&!PÜ$þ €Æ( @Á(’&ÿÿÿÿÿÿÿÿŸ#’&!PÜ$ÿ €Æ( @Á(’&ÿÿÿÿÿÿÿÿà%àÍ&! PÜ% 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PÜ% €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜ) €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ%àÍ&! PÜ* 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ@ #’&!PÜ* €Æ( @Á(’&ÿÿÿÿÿÿÿÿàÍ&! PÜ+ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PÜ, €Æ( @Á(’&ÿÿÿÿÿÿÿÿàÍ&! PÜ- 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿð®&! PÜ/ €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ€%P°&! PÜ0 €Æ( @Á(P°&ÿÿÿÿÿÿÿÿÀÀ#°&!PÜ0  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿ \(! àõ-÷w ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿZ09¹!šo k0l0Dº*™o m0n0Dº*o0%ð®&! PÜ1 €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿàë'! PÜ1 0È( @`È(àë'ÿÿÿÿÿÿÿÿ@%P°&! PÜ2 €Æ( @Á(P°&ÿÿÿÿÿÿÿÿ`Á#°&!PÜ2  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿàë'! PÜ2# 0È( @`È(àë'ÿÿÿÿÿÿÿÿ %ð®&! PÜ3% €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ’&!PÜ3& €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`%àÍ&! PÜ4( 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ %ÐÀ&! PÜ4) 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ`²&! PÜ4* 0È( @`È(`²&ÿÿÿÿÿÿÿÿÂ#àÍ&! PÜ5, 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ`²&! PÜ5. 0È( @`È(`²&ÿÿÿÿÿÿÿÿ€"%àÍ&! PÜ60 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ #%ÐÀ&! PÜ61 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ`²&! PÜ62 0È( @`È(`²&ÿÿÿÿÿÿÿÿ`$%àÍ&! PÜ74 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ%%ÐÀ&! PÜ75 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ`²&! PÜ76 0È( @`È(`²&ÿÿÿÿÿÿÿÿà&%àÍ&! PÜ88 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿM ðð'€'%@Ú&! PÜ89 0È( @`È(@Ú&ÿÿÿÿÿÿÿÿ’&!PÜ8: €Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ(%àÍ&! PÜ9< 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ@Ú&! PÜ9= 0È( @`È(@Ú&ÿÿÿÿÿÿÿÿ*%àÍ&! PÜ:? 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàØ&!0PÜ:@ €Æ( @Á(àØ&ÿÿÿÿÿÿÿÿ@+%ÐÀ&! PÜ;C 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ’&!PÜ;D €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€,%àÍ&! PÜ<F 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿÐÀ&! PÜ<G 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿÀ-%àÍ&! PÜ=I 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿð®&! PÜ=J €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ/%àÍ&! PÜ>L 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿð®&! PÜ>M €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ@0%àÍ&! PÜ?O 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿð®&! PÜ?P €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ€1%àÍ&! PÜ@R 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ 2% º&! PÜ@S 0È( @`È( º&ÿÿÿÿÿÿÿÿÀ2%-&! PÜ@T 0È( @`È(-&ÿÿÿÿÿÿÿÿП&! PÜ@U 0È( @`È(П&ÿÿÿÿÿÿÿÿ4%àÍ&! PÜAW 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ 4%P°&! PÜAX €Æ( @Á(P°&ÿÿÿÿÿÿÿÿП&! PÜAY 0È( @`È(П&ÿÿÿÿÿÿÿÿà5%àÍ&! PÜB[ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ€û#P°&! PÜB\ €Æ( @Á(P°&ÿÿÿÿÿÿÿÿ@#ì"ÀX#€P#@Q#R##ÀR#À#€S#@T#€#U#ÀU#€V#X#M ðP(M ð`(°ô"à"( €À·-Íå`Å@3,ÿÿÿÿÿÿÿÿ9%à"( €À·-Îæ@Æ:)ÿÿÿÿÿÿÿÿ 9%à"( €À·-Ïç Çp3,ÿÿÿÿÿÿÿÿ@:%à"( €À·-ÐèÈ 3,ÿÿÿÿÿÿÿÿÀ<%àÍ&! PÜC_ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ`=%P°&! PÜC` €Æ( @Á(P°&ÿÿÿÿÿÿÿÿ>%°&!PÜCa  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿП&! PÜCb 0È( @`È(П&ÿÿÿÿÿÿÿÿ@?%àÍ&! PÜDd 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿð®&! PÜDe €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ€@%àÍ&! PÜEg 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿð®&! PÜEh €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿÀA%ð®&! PÜGk €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ`B%ð®&! PÜGl €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿC%ð®&! PÜGm €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ C%ð®&! PÜGn €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ@D%ð®&! PÜGo €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿàD%ð®&! PÜGp €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ€E%ð®&! PÜGq €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿð®&! PÜGr €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿÀF%àÍ&! PÜHt 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ`G%’&!PÜHu €Æ( @Á(’&ÿÿÿÿÿÿÿÿH%P°&! PÜHv €Æ( @Á(P°&ÿÿÿÿÿÿÿÿ H%°&!PÜHw  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿP &! PÜHx 0È( @`È(P &ÿÿÿÿÿÿÿÿàÍ&! PÜIz 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÍ&! PÜJ| 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÍ&! PÜK~ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿÀK%àÍ&! PÜL€ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ`L%°&!PÜL  Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿП&! PÜL‚ 0È( @`È(П&ÿÿÿÿÿÿÿÿàÍ&! PÜM„ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÍ&! PÜN† 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÍ&! PÜOˆ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ€O%àÍ&! PÜPŠ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàØ&!0PÜP‹ €Æ( @Á(àØ&ÿÿÿÿÿÿÿÿ`Ô$’&!PÜãR €Æ( @Á(’&ÿÿÿÿÿÿÿÿàÍ&! PÜQ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÍ&! PÜR 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ R%àÍ&! PÜS‘ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ@S%À¾&! PÜS’ 0È( @`È(À¾&ÿÿÿÿÿÿÿÿ’&!PÜS“ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€T%àÍ&! PÜT• 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿÀ¾&! PÜT– 0È( @`È(À¾&ÿÿÿÿÿÿÿÿÀU%àÍ&! PÜU˜ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ`V%ð®&! PÜU™ €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ’&!PÜU𠀯( @Á(’&ÿÿÿÿÿÿÿÿ W%àÍ&! PÜVœ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàX%¸&! PÜV 0È( @`È(¸&ÿÿÿÿÿÿÿÿÐÀ&! PÜäY 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ’&!PÜVž €Æ( @Á(’&ÿÿÿÿÿÿÿÿ Z%àÍ&! PÜW  0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ¸&! PÜW¡ 0È( @`È(¸&ÿÿÿÿÿÿÿÿàÍ&! PÜX£ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ\%À¾&! PÜY¦ 0È( @`È(À¾&ÿÿÿÿÿÿÿÿ’&!PÜY§ €Æ( @Á(’&ÿÿÿÿÿÿÿÿð®&! PÜZª €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿà]%àÍ&! PÜ[¬ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PÜ[­ €Æ( @Á(’&ÿÿÿÿÿÿÿÿàÍ&! PÜ\¯ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ`ý#àÍ&! PÜ]± 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PÜ]³ €Æ( @Á(’&ÿÿÿÿÿÿÿÿa%àÍ&! PÜ^µ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿÐÀ&! PÜ^¶ 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ þ#àÍ&! PÜ_¸ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàb%’&!PÜ`¼ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜ`½ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ $àÍ&! PÜbÁ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÑ$àÍ&! PÜcÄ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PÜcÆ €Æ( @Á(’&ÿÿÿÿÿÿÿÿàÍ&! PÜdÈ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿÐÀ&! PÜeË 0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ$àÍ&! PÜfÍ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàg%àÍ&! PÜgÐ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ€h%’&!PÜgÑ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜgÒ €Æ( @Á(’&ÿÿÿÿÿÿÿÿàÍ&! PÜhÔ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÍ&! PÜiÖ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÍ&! PÜkÚ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ@$àÍ&! PÜlÜ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ@l%àÍ&! PÜmß 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàl%’&!PÜmà €Æ( @Á(’&ÿÿÿÿÿÿÿÿ€m%’&!PÜmá €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜmâ €Æ( @Á(’&ÿÿÿÿÿÿÿÿà$àÍ&! PÜnä 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ’&!PÜnæ €Æ( @Á(’&ÿÿÿÿÿÿÿÿàÍ&! PÜÕè 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÍ&! PÜÖê 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÍ&! PÜ×ì 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÍ&! PÜØî 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÍ&! PÜÙð 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ ó$’&!PÜúž €Æ( @Á(’&ÿÿÿÿÿÿÿÿ`÷$’&!PÜû¦ €Æ( @Á(’&ÿÿÿÿÿÿÿÿàÍ&! Pܲ 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÍ&! PÜÚò 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿM ø`3(àÍ&! PÜÛô 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿàÍ&! PÜÜö 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿÀx%€7(! À·-•& PÛ0È( @`È(€7(ÿÿÿÿÿÿÿÿàÍ&! PÜÝø 0È( @`È(àÍ&ÿÿÿÿÿÿÿÿz%’&!À·-•' €Æ( @Á(’&ÿÿÿÿÿÿÿÿð®&! PÜàü €Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ@{%П&! À·-•( pò0È( @`È(П&ÿÿÿÿÿÿÿÿ’&!PÜ䀯( @Á(’&ÿÿÿÿÿÿÿÿ`3(!À·-•) ðp«)@Á(`3(ÿÿÿÿÿÿÿÿ }%’&!PÜè€Æ( @Á(’&ÿÿÿÿÿÿÿÿ0"(! À·-+ 0È( @`È(0"(ÿÿÿÿÿÿÿÿ’&!PÜè€Æ( @Á(’&ÿÿÿÿÿÿÿÿ0"(! À·-ž- 0È( @`È(0"(ÿÿÿÿÿÿÿÿ ”&! PÜê0È( @`È( ”&ÿÿÿÿÿÿÿÿ@€%0"(! À·-Ÿ/ 0È( @`È(0"(ÿÿÿÿÿÿÿÿ ”&! PÜë 0È( @`È( ”&ÿÿÿÿÿÿÿÿ’&!À·-Ÿ0 €Æ( @Á(’&ÿÿÿÿÿÿÿÿ ”&! PÜì 0È( @`È( ”&ÿÿÿÿÿÿÿÿ0"(! À·- 2 0È( @`È(0"(ÿÿÿÿÿÿÿÿ ”&! PÜî0È( @`È( ”&ÿÿÿÿÿÿÿÿ0"(! À·-¡4 0È( @`È(0"(ÿÿÿÿÿÿÿÿ „%àÍ&! PÜï0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ@…%0"(! À·-¢6 0È( @`È(0"(ÿÿÿÿÿÿÿÿà…%€«&! PÜï0È( @`È(€«&ÿÿÿÿÿÿÿÿàà'! À·-¢7 €Æ( @Á(àà'ÿÿÿÿÿÿÿÿ€«&! PÜï0È( @`È(€«&ÿÿÿÿÿÿÿÿ0"(! À·-Ã9 àC0È( @`È(0"(ÿÿÿÿÿÿÿÿ`ˆ%’&!PÜõ€Æ( @Á(’&ÿÿÿÿÿÿÿÿ‰%’&!À·-Ä; P(€Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜõ€Æ( @Á(’&ÿÿÿÿÿÿÿÿ0"(! À·-Ä< àC0È( @`È(0"(ÿÿÿÿÿÿÿÿàŠ%àÍ&! PÜù0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ0"(! À·-Å> àC0È( @`È(0"(ÿÿÿÿÿÿÿÿ Œ%’&!PÜù€Æ( @Á(’&ÿÿÿÿÿÿÿÿ0"(! À·-Æ@ àC0È( @`È(0"(ÿÿÿÿÿÿÿÿ’&!PÜù€Æ( @Á(’&ÿÿÿÿÿÿÿÿ0"(! À·-ÈB àC0È( @`È(0"(ÿÿÿÿÿÿÿÿ’&!PÜû €Æ( @Á(’&ÿÿÿÿÿÿÿÿ0"(! À·-ÎD 0È( @`È(0"(ÿÿÿÿÿÿÿÿà%е&! PÜü"0È( @`È(е&ÿÿÿÿÿÿÿÿ0"(! À·-ÏF 0È( @`È(0"(ÿÿÿÿÿÿÿÿ A(! PÜü#0È( @`È( A(ÿÿÿÿÿÿÿÿ0C(! PÜþ%0È( @`È(0C(ÿÿÿÿÿÿÿÿ0C(! PÜÿ'0È( @`È(0C(ÿÿÿÿÿÿÿÿ0"(! À·-ÐH 0È( @`È(0"(ÿÿÿÿÿÿÿÿ“%J(! À·-âJ 0È( @`È(J(ÿÿÿÿÿÿÿÿ “%ÀJ(! À·-âK 0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ@”%`²&! À·-âL 0È( @`È(`²&ÿÿÿÿÿÿÿÿpK(! À·-âM 0È( @`È(pK(ÿÿÿÿÿÿÿÿ€•%J(! À·-äO 0È( @`È(J(ÿÿÿÿÿÿÿÿ –%ÀJ(! À·-äP 0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ`²&! À·-äQ 0È( @`È(`²&ÿÿÿÿÿÿÿÿ`—%0"(! À·-åS 0È( @`È(0"(ÿÿÿÿÿÿÿÿ˜%’&!À·-åT €Æ( @Á(’&ÿÿÿÿÿÿÿÿ@×'!À·-åU 0È( @`È(@×'ÿÿÿÿÿÿÿÿ@™%0"(! À·-æW 0È( @`È(0"(ÿÿÿÿÿÿÿÿà™%П&! À·-æX 0È( @`È(П&ÿÿÿÿÿÿÿÿpù%! À·-æY 0È( @`È(pù%ÿÿÿÿÿÿÿÿ ›%0"(! À·-è[ 0È( @`È(0"(ÿÿÿÿÿÿÿÿÀ›%°Ä'!À·-è\ 0È( @`È(°Ä'ÿÿÿÿÿÿÿÿ`œ%’&!À·-è] €Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!À·-è^ €Æ( @Á(’&ÿÿÿÿÿÿÿÿ %0"(! À·-é` 0È( @`È(0"(ÿÿÿÿÿÿÿÿ@ž%°Ä'!À·-éa 0È( @`È(°Ä'ÿÿÿÿÿÿÿÿ’&!À·-éb €Æ( @Á(’&ÿÿÿÿÿÿÿÿ0"(! À·-ëd 0È( @`È(0"(ÿÿÿÿÿÿÿÿÐÀ&! àõ-šk B0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿÀ %ÐÀ&! àõ-œm `C0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿÐÀ&! àõ-œn @D0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿð®&! PÜ)€Æ( @Á(ð®&ÿÿÿÿÿÿÿÿð®&! PÜ+€Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ@£%’&!PÜ-€Æ( @Á(’&ÿÿÿÿÿÿÿÿà£%’&!PÜ.€Æ( @Á(’&ÿÿÿÿÿÿÿÿð®&! PÜ/€Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ ¥%’&!PÜ 1€Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜ 2€Æ( @Á(’&ÿÿÿÿÿÿÿÿ`¦%’&!PÜ 4€Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜ 5€Æ( @Á(’&ÿÿÿÿÿÿÿÿ §%’&!PÜ 7€Æ( @Á(’&ÿÿÿÿÿÿÿÿ@¨%’&!PÜ 8€Æ( @Á(’&ÿÿÿÿÿÿÿÿð®&! PÜ 9€Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ€©%àÍ&! PÜ ;0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ ª%’&!PÜ <€Æ( @Á(’&ÿÿÿÿÿÿÿÿÀª%’&!PÜ =€Æ( @Á(’&ÿÿÿÿÿÿÿÿð®&! PÜ >€Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ¬%àÍ&! PÜ @0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ ¬%’&!PÜ A€Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜ B€Æ( @Á(’&ÿÿÿÿÿÿÿÿà­%àÍ&! PÜD0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ€®%’&!PÜE€Æ( @Á(’&ÿÿÿÿÿÿÿÿ’&!PÜF€Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ¯%àÍ&! PÜH0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ`°%’&!PÜI€Æ( @Á(’&ÿÿÿÿÿÿÿÿ@1$’&!PÜJ€Æ( @Á(’&ÿÿÿÿÿÿÿÿ ±%’&!àõ-¢p pF€Æ( @Á(’&ÿÿÿÿÿÿÿÿ@²%ÐÀ&! àõ-¢q `C0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿà²%’&!àõ-¢r PG€Æ( @Á(’&ÿÿÿÿÿÿÿÿÐÀ&! àõ-¢s @D0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿÀ´%’&!PÜN€Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ¾&! àõ-¹w 0T"0È( @`È(À¾&ÿÿÿÿÿÿÿÿ’&!PÜO€Æ( @Á(’&ÿÿÿÿÿÿÿÿÀ¾&! àõ-¿y 0T"0È( @`È(À¾&ÿÿÿÿÿÿÿÿ@·%àÍ&! PÜQ0È( @`È(àÍ&ÿÿÿÿÿÿÿÿà·%ÐÀ&! àõ-Ì{ ÐX0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ€¸%’&!PÜR€Æ( @Á(’&ÿÿÿÿÿÿÿÿÐÀ&! àõ-Ì| ÀŸ0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ’&!PÜS€Æ( @Á(’&ÿÿÿÿÿÿÿÿ \(! àõ-Õ~ ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ»%àÍ&! PÜU0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ \(! àõ-Ú€ ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿð®&! PÜV€Æ( @Á(ð®&ÿÿÿÿÿÿÿÿ \(! àõ-ä‚ ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿ€½%àÍ&! PÜX0È( @`È(àÍ&ÿÿÿÿÿÿÿÿ ¾%ÀJ(! àõ-ù… B0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿð®&! PÜY€Æ( @Á(ð®&ÿÿÿÿÿÿÿÿÀJ(! àõ-ù† à¥0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿÐÀ&! PÜ\0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ À%ÀJ(! àõ-ˆ B0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ’&!PÜ^€Æ( @Á(’&ÿÿÿÿÿÿÿÿàÁ%ÀJ(! àõ-‰ à¥0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ°&!PÜa Ä( ÐÄ(’&ÿÿÿÿÿÿÿÿàd(! àõ-Š ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿÐÀ&! PÜc0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ`Ä%ÀJ(! àõ-Œ B0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿÀ¾&! PÜ"f0È( @`È(À¾&ÿÿÿÿÿÿÿÿÀJ(! àõ- à¥0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ@Æ%k(! PÜ#h0È( @`È(k(ÿÿÿÿÿÿÿÿàÆ%ÀJ(! àõ- B0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿPÆ&! PÜ#i0È( @`È(PÆ&ÿÿÿÿÿÿÿÿ È%ÀJ(! àõ- à¥0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿà;$ÐÀ&! PÜ$k0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿàd(! àõ-‘ ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿ`É%’&!àõ-“ À\€Æ( @Á(’&ÿÿÿÿÿÿÿÿÐÀ&! àõ-” à¥0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ Ê% g(! àõ- –  ]0È( @`È( g(ÿÿÿÿÿÿÿÿ@Ë%ÀJ(! àõ- — à¥0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ`3(!àõ- ˜ ^p«)@Á(`3(ÿÿÿÿÿÿÿÿ€Ì%П&! àõ-#š 0T"0È( @`È(П&ÿÿÿÿÿÿÿÿ Í%pù%! àõ-#› @,0È( @`È(pù%ÿÿÿÿÿÿÿÿÐÀ&! àõ-#œ à¥0È( @`È(ÐÀ&ÿÿÿÿÿÿÿÿ`Î%k(! àõ-(ž C0È( @`È(k(ÿÿÿÿÿÿÿÿÐô'! àõ-(Ÿ pC0È( @`È(Ðô'ÿÿÿÿÿÿÿÿ Ï%àd(! àõ-/¡ ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿ m(! àõ-/¢ `»0È( @`È( m(ÿÿÿÿÿÿÿÿàÐ%àd(! àõ-4¤ ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿ€Ñ% m(! àõ-4¥ `»0È( @`È( m(ÿÿÿÿÿÿÿÿ Ò%’&!àõ-4¦ ीÆ( @Á(’&ÿÿÿÿÿÿÿÿpù%! àõ-4§ Ð0È( @`È(pù%ÿÿÿÿÿÿÿÿ`Ó%àd(! àõ-;© ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿÔ% m(! àõ-;ª `»0È( @`È( m(ÿÿÿÿÿÿÿÿpù%! àõ-;« @±0È( @`È(pù%ÿÿÿÿÿÿÿÿ \(! àõ->­ ÀD0È( @`È( \(ÿÿÿÿÿÿÿÿàÕ%àd(! àõ-H¯ ÀD0È( @`È(àd(ÿÿÿÿÿÿÿÿÀJ(! àõ-H° 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ ×% m(! àõ-P´ 0T"0È( @`È( m(ÿÿÿÿÿÿÿÿÀJ(! àõ-Pµ 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ`Ø%ÀJ(! àõ-W¸ 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ`²&! àõ-W¹ `ª0È( @`È(`²&ÿÿÿÿÿÿÿÿ#ÀJ(! àõ-\» 0E0È( @`È(ÀJ(ÿÿÿÿÿÿÿÿ’&0H*`Â(Â( +Üà%Ѓ*ÿÿÿÿÿÿÿÿ’&Ð -`Â(Â(Ý`á%°à%ÿÿÿÿÿÿÿÿ’&Ð -`Â(Â(Þ°à%Ѓ*ÿÿÿÿÿÿÿÿ’&Ð -`Â(Â(` -àâ%Ѓ*ÿÿÿÿÿÿÿÿ’& -`Â(Â(ápã%Àâ%ÿÿÿÿÿÿÿÿ’& -`Â(Â(âÀâ%Ѓ*ÿÿÿÿÿÿÿÿ’& -`Â(Â(@-ã ä%Ѓ*ÿÿÿÿÿÿÿÿ’& -`Â(Â(p-äÐä%Ѓ*ÿÿÿÿÿÿÿÿÀ¾& 0È(`È(å@ @k(ÿÿÿÿÿÿÿÿ’&°Á*`Â(Â(çp±'Ѓ*ÿÿÿÿÿÿÿÿ’&°Á*`Â(Â(ð-èàæ%Ѓ*ÿÿÿÿÿÿÿÿ’&-`Â(Â(é@è%ç%ÿÿÿÿÿÿÿÿ’&-`Â(Â(êç%Ѓ*ÿÿÿÿÿÿÿÿ’&-`Â(Â(p-ëðè%Ѓ*ÿÿÿÿÿÿÿÿÀ¾&p&*`Â(Â(,É é%ÿÿÿÿÿÿÿÿ’& a*`Â(Â(€„(ïPê%ÿÿÿÿÿÿÿÿ’& €*`Â(Â(€‡(ñë%ÿÿÿÿÿÿÿÿ’& -`Â(Â(ð*ó°ë%ÿÿÿÿÿÿÿÿ’&@€*`Â(Â(÷X'Ѓ*ÿÿÿÿÿÿÿÿ’&@€*`Â(Â(@Ú*øí%Ѓ*ÿÿÿÿÿÿÿÿ’& -`Â(Â(pþ*úÀí%ÿÿÿÿÿÿÿÿ’& -`Â(Â(õ(ûpî%ÿÿÿÿÿÿÿÿ’&8*`Â(Â((ý ï%ÿÿÿÿÿÿÿÿ’&8*`Â(Â(ð(þÐï%ÿÿÿÿÿÿÿÿ’&ðH*`Â(Â(@''Ѓ*ÿÿÿÿÿÿÿÿ’&ðH*`Â(Â(Ð)0ñ%Ѓ*ÿÿÿÿÿÿÿÿ’&ðH*`Â(Â(ÿ*àñ%Ѓ*ÿÿÿÿÿÿÿÿ¨n9@ë›o ¶nº*Ø›o ·nº*™o ¸n9@wÄnDº*Þ›o Ênð´-º*Ënº*¦y9›o ¯y9@ëØ›o ½yº*™o ¾y ·-º*¿y9yÞ›o Ðyð´-º*Ñyº*(º*â¤o (9Àœåžo !(4º*s¤o "(9ð—*( º*,¡o ,(9àé¤o ;(pß-º*”(º*â¤o •(9Àœåžo ¡(4º*s¤o ¢(9ð—ª( º*,¡o ¬(9 é¤o ¾(pß-º**º*â¤o *9Àœåžo !*4º*s¤o "*9ð—** º*,¡o ,*9žé¤o >*º*ë¤o ’&@—(`Â(Â( ö%ÿÿÿÿÿÿÿÿ’&@—(`Â(Â(‰* °ö%ÿÿÿÿÿÿÿÿŠŠÐÜ-º*"®o ‹Š9ÐGåžo ’Šº*2¨o ”ŠðD-º*ù¦o •ŠDº*6¨o –ŠpØ-º*é¤o —Š×-º*ë¤o @®& ¯&p®)à­)ç@ ¢"À³&±&ÿÿÿÿÿÿÿÿ 0È(`È(é@@@¤" Ç(ÐÇ(p“&ÿÿÿÿÿÿÿÿ 0È(`È(ê@@Ðô'¥"PÉ( É( ”&ÿÿÿÿÿÿÿÿ0¬&°“(`Â(Â( ú%ÿÿÿÿÿÿÿÿà¬&ðÿ*`Â(Â(Ðú%ÿÿÿÿÿÿÿÿ­&˜(`Â(Â(€û%ÿÿÿÿÿÿÿÿ Ž&@þ%`Ë(Ë(D€0ü%ÿÿÿÿÿÿÿÿ Ž&à©'`Ë(Ë(àü%ÿÿÿÿÿÿÿÿ Ž& 0È(`È(@@ý%ÿÿÿÿÿÿÿÿÀ#`Ë(Ë(@þ%ÿÿÿÿÿÿÿÿ’&&0È(`È(B@4&ðþ%ÿÿÿÿÿÿÿÿŒ& 0È(`È(@@pÁ(Â( ÿ%ÿÿÿÿÿÿÿÿ’& ÿ%0È(`È( P&ÿÿÿÿÿÿÿÿ€#0È(`È( &ÿÿÿÿÿÿÿÿ@£&@«'0È(`È(T@°&ÿÿÿÿÿÿÿÿД&p&`Ë(Ë(#J€@5&`&ÿÿÿÿÿÿÿÿД& ÿ%`Ë(Ë(%@&ÿÿÿÿÿÿÿÿД& 0È(`È(&@@À&ÿÿÿÿÿÿÿÿ#`Ë(Ë(#@p&ÿÿÿÿÿÿÿÿ ¤& &&`Ë(Ë((X€ &ÿÿÿÿÿÿÿÿÀ¾&p+`Â(Â(Ð&ÿÿÿÿÿÿÿÿpù% 0È(`È(@ @Ðô'ÿÿÿÿÿÿÿÿ@×'¡(`Â(Â(0&ÿÿÿÿÿÿÿÿ@×'о(`Â(Â(à&ÿÿÿÿÿÿÿÿ’&¿(`Â(Â(&ÿÿÿÿÿÿÿÿ’&¿(`Â(Â(€‹*@ &ÿÿÿÿÿÿÿÿpù%°À(`Â(Â(ð &ÿÿÿÿÿÿÿÿ P &„"Ð ( Ÿ&ÿÿÿÿÿÿÿÿ  & 0È(`È(!@@ &P &ÿÿÿÿÿÿÿÿ  & 0È(`È("@ @P &ÿÿÿÿÿÿÿÿpù%@p+`Â(Â(#° &ÿÿÿÿÿÿÿÿpù%@p+`Â(Â( *$` &ÿÿÿÿÿÿÿÿ Ÿ& ù+`Â(Â(D`ü'&ÿÿÿÿÿÿÿÿ’&`q+`Â(Â(*À&ÿÿÿÿÿÿÿÿp“& r+`Â(Â(+p&ÿÿÿÿÿÿÿÿ’&PÆ(`Â(Â(- &ÿÿÿÿÿÿÿÿÄ'ps+`Â(Â(.Ð&ÿÿÿÿÿÿÿÿU( 0È(`È(/@@0&€&ÿÿÿÿÿÿÿÿU( 0È(`È(0@ @€&ÿÿÿÿÿÿÿÿ’&Ðs+`Â(Â(1à&ÿÿÿÿÿÿÿÿL#`Ë(Ë(2"@@&Ðü"U(å'PÙ ÿÿÿÿÿÿÿÿ€_$& 0È(`È(3@@@&ÿÿÿÿÿÿÿÿ’&È(`Â(Â(4ð&ÿÿÿÿÿÿÿÿ’&t+`Â(Â(5 &ÿÿÿÿÿÿÿÿ°Ä'Pu+`Â(Â(6P&ÿÿÿÿÿÿÿÿÀU( 0È(`È(7@@°&&ÿÿÿÿÿÿÿÿÀU( 0È(`È(8@ @&ÿÿÿÿÿÿÿÿ’&°u+`Â(Â(9`&ÿÿÿÿÿÿÿÿ#`Ë(Ë(:"@À&ð#ÀU(°å'Û ÿÿÿÿÿÿÿÿàJ$& 0È(`È(;@@À&ÿÿÿÿÿÿÿÿ’&@Ê(`Â(Â(<p&ÿÿÿÿÿÿÿÿ’& ö+`Â(Â(P &ÿÿÿÿÿÿÿÿ’&à¹,`Â(Â(? b(Ѓ*ÿÿÿÿÿÿÿÿ Ÿ&Í(`Â(Â(D€&ÿÿÿÿÿÿÿÿ`( 0È(`È(K@@(0&ÿÿÿÿÿÿÿÿì’&`v.s Ðèd"€Æ(  @Á(ÿÿÿÿÿÿÿÿ`g. À& 00È(`È(E@@P!&ÀJ(ÐÀ&ÿÿÿÿÿÿÿÿÐÀ&F@ð&@&ÿÿÿÿÿÿÿÿ&G@@&ÿÿÿÿÿÿÿÿà&ð&`v.t }d"@ÿÿÿÿÿÿÿÿ€g.& 0È(`È(H@@P!&ÿÿÿÿÿÿÿÿ  &’&`v.u à~d"€Æ(  @Á(ÿÿÿÿÿÿÿÿ g."&ð&`v. v 0€d"@ÿÿÿÿÿÿÿÿÀg.`…"P $&`…"`#&ÿÿÿÿÿÿÿÿ`$`#& 0È(`È(Q@@¢&$&ÿÿÿÿÿÿÿÿŒ& 0È(`È([@@pÁ(€,À$&ÿÿÿÿÿÿÿÿ ¤& ÿ%`Ë(Ë(*@p%&ÿÿÿÿÿÿÿÿÀ#`Ë(Ë((@ &&ÿÿÿÿÿÿÿÿ@£&à(&`Ë(Ë(,V€Ð&&ÿÿÿÿÿÿÿÿŒ& 0È(`È(-@@pÁ(`Å(€'&ÿÿÿÿÿÿÿÿ@£&€'&`Ë(Ë(. 0(&ÿÿÿÿÿÿÿÿ€#`Ë(Ë(, à(&ÿÿÿÿÿÿÿÿ’&ð*&`Ë(Ë(0H€)&ÿÿÿÿÿÿÿÿ’&€'&`Ë(Ë(2 @*&ÿÿÿÿÿÿÿÿ@#`Ë(Ë(0 ð*&ÿÿÿÿÿÿÿÿ°&°-&0È(`È(4@@ +&ÿÿÿÿÿÿÿÿ°&€'&0È(`È(6P,&ÿÿÿÿÿÿÿÿ°& 0È(`È(7@@-&ÿÿÿÿÿÿÿÿ#0È(`È(4°-&ÿÿÿÿÿÿÿÿ Ž&p0&0È(`È(9>@`.&ÿÿÿÿÿÿÿÿŒ& 0È(`È(:@@pÁ(Ç(/&ÿÿÿÿÿÿÿÿ Ž&/&0È(`È(;À/&ÿÿÿÿÿÿÿÿÀ#0È(`È(9p0&ÿÿÿÿÿÿÿÿ°&€2&`Ë(Ë(=F€ 1&ÿÿÿÿÿÿÿÿ°&/&`Ë(Ë(?Ð1&ÿÿÿÿÿÿÿÿ€ #`Ë(Ë(=€2&ÿÿÿÿÿÿÿÿ €Æ(@Á(A  à3& a"@£&ÿÿÿÿÿÿÿÿ03& 0È(`È(B@@à3&ÿÿÿÿÿÿÿÿðþ% 0È(`È(C@@4&ÿÿÿÿÿÿÿÿ`& 0È(`È(D@@@5&ÿÿÿÿÿÿÿÿ€•& 0È(`È(E@@ð5&ÿÿÿÿÿÿÿÿ’& +`Â(Â(F 6&ÿÿÿÿÿÿÿÿ)&PŸ(`Â(Â(GP7&ÿÿÿÿÿÿÿÿ’& (`Â(Â(H8&ÿÿÿÿÿÿÿÿД&p (`Â(Â(I°8&ÿÿÿÿÿÿÿÿ’&  (`Â(Â(J`9&ÿÿÿÿÿÿÿÿÐ&&+`Â(Â(K:&ÿÿÿÿÿÿÿÿÐ&&°ö(`Â(Â(LÀ:&ÿÿÿÿÿÿÿÿÐ&&p÷(`Â(Â(Mp;&ÿÿÿÿÿÿÿÿ`.&0ø(`Â(Â(N <&ÿÿÿÿÿÿÿÿ +& ù(`Â(Â(OÐ<&ÿÿÿÿÿÿÿÿÐ&&àù(`Â(Â(P€=&ÿÿÿÿÿÿÿÿðþ%û(`Â(Â(Q0>&ÿÿÿÿÿÿÿÿ +&Àû(`Â(Â(Rà>&ÿÿÿÿÿÿÿÿ +&€ü(`Â(Â(S?&ÿÿÿÿÿÿÿÿðþ%@ý(`Â(Â(T@@&ÿÿÿÿÿÿÿÿ Ÿ&þ(`Â(Â(Vð@&ÿÿÿÿÿÿÿÿ Ÿ&`þ(`Â(Â(W A&ÿÿÿÿÿÿÿÿ Ÿ&X,`Â(Â(XPB&ÿÿÿÿÿÿÿÿðþ%@)`Â(Â(ZC&ÿÿÿÿÿÿÿÿ Ÿ& )`Â(Â([°C&ÿÿÿÿÿÿÿÿÐ&&ð)`Â(Â(\`D&ÿÿÿÿÿÿÿÿ’& 0È(`È($* P"E&ÿÿÿÿÿÿÿÿÐ&&P)`Â(Â(]ÀE&ÿÿÿÿÿÿÿÿ Ÿ&@)`Â(Â(^pF&ÿÿÿÿÿÿÿÿ Ÿ&0)`Â(Â(_ G&ÿÿÿÿÿÿÿÿ Ÿ&À)`Â(Â(`ÐG&ÿÿÿÿÿÿÿÿ Ÿ&°)`Â(Â(a€H&ÿÿÿÿÿÿÿÿÐ&&p)`Â(Â(b0I&ÿÿÿÿÿÿÿÿ0ü%)`Â(Â(càI&ÿÿÿÿÿÿÿÿ 1&`X,`Â(Â(dJ&ÿÿÿÿÿÿÿÿ)&)`Â(Â(e@K&ÿÿÿÿÿÿÿÿ`.&ð)`Â(Â(fðK&ÿÿÿÿÿÿÿÿ +&P)`Â(Â(g L&ÿÿÿÿÿÿÿÿÐ&&°)`Â(Â(hPM&ÿÿÿÿÿÿÿÿ`.&  )`Â(Â(iN&ÿÿÿÿÿÿÿÿ +&` )`Â(Â(j°N&ÿÿÿÿÿÿÿÿðþ% )`Â(Â(k`O&ÿÿÿÿÿÿÿÿ€•&à )`Â(Â(lP&ÿÿÿÿÿÿÿÿ€•&  )`Â(Â(mÀP&ÿÿÿÿÿÿÿÿðþ%P)`Â(Â(ppQ&ÿÿÿÿÿÿÿÿ°&0^,`Â(Â(q R&ÿÿÿÿÿÿÿÿðþ% )`Â(Â(sÐR&ÿÿÿÿÿÿÿÿ 0È(`È(t@ @0T&°" ¤&ÿÿÿÿÿÿÿÿ€S& 0È(`È(u@@0T&ÿÿÿÿÿÿÿÿ’&0)`Â(Â(vàT&ÿÿÿÿÿÿÿÿ0–&ð)`Â(Â(wU&ÿÿÿÿÿÿÿÿ Ÿ&€)`Â(Â(x@V&ÿÿÿÿÿÿÿÿÐ&&à)`Â(Â(yðV&ÿÿÿÿÿÿÿÿ)&@)`Â(Â(z W&ÿÿÿÿÿÿÿÿ & )`Â(Â({PX&ÿÿÿÿÿÿÿÿ)&)`Â(Â(|Y&ÿÿÿÿÿÿÿÿðþ%`)`Â(Â(}°Y&ÿÿÿÿÿÿÿÿÐ&&À)`Â(Â(~`Z&ÿÿÿÿÿÿÿÿ & )`Â(Â([&ÿÿÿÿÿÿÿÿ &€)`Â(Â(€À[&ÿÿÿÿÿÿÿÿ’&à)`Â(Â(p\&ÿÿÿÿÿÿÿÿД&)`Â(Â(‚ ]&ÿÿÿÿÿÿÿÿ &@)`Â(Â(ƒÐ]&ÿÿÿÿÿÿÿÿ &Ð')`Â(Â(„€^&ÿÿÿÿÿÿÿÿÐ&&0()`Â(Â(…0_&ÿÿÿÿÿÿÿÿ &()`Â(Â(†à_&ÿÿÿÿÿÿÿÿ &ð()`Â(Â(‡`&ÿÿÿÿÿÿÿÿ &€))`Â(Â(ˆ@a&ÿÿÿÿÿÿÿÿ Ÿ&*)`Â(Â(‰ða&ÿÿÿÿÿÿÿÿ Ÿ&p*)`Â(Â(Š b&ÿÿÿÿÿÿÿÿ Ÿ&Ð*)`Â(Â(‹Pc&ÿÿÿÿÿÿÿÿ &`+)`Â(Â(Œd&ÿÿÿÿÿÿÿÿ &+)`Â(Â(°d&ÿÿÿÿÿÿÿÿ0ü%ð+)`Â(Â(Ž`e&ÿÿÿÿÿÿÿÿ 1&P,)`Â(Â(f&ÿÿÿÿÿÿÿÿ)&°,)`Â(Â(Àf&ÿÿÿÿÿÿÿÿ`&-)`Â(Â(‘pg&ÿÿÿÿÿÿÿÿ`&p-)`Â(Â(’ h&ÿÿÿÿÿÿÿÿ &Ð-)`Â(Â(“Ðh&ÿÿÿÿÿÿÿÿ`&.)`Â(Â(”€i&ÿÿÿÿÿÿÿÿ`&`.)`Â(Â(•0j&ÿÿÿÿÿÿÿÿ)&ð.)`Â(Â(–àj&ÿÿÿÿÿÿÿÿ 1&P/)`Â(Â(—k&ÿÿÿÿÿÿÿÿ)&°/)`Â(Â(˜@l&ÿÿÿÿÿÿÿÿ€•&0)`Â(Â(™ðl&ÿÿÿÿÿÿÿÿ€•&p0)`Â(Â(š m&ÿÿÿÿÿÿÿÿ`&Ð0)`Â(Â(›Pn&ÿÿÿÿÿÿÿÿ`&01)`Â(Â(œo&ÿÿÿÿÿÿÿÿ’&à˜,`Â(Â(°o&ÿÿÿÿÿÿÿÿ0ü%1)`Â(Â(ž`p&ÿÿÿÿÿÿÿÿ Ÿ&À1)`Â(Â(Ÿq&ÿÿÿÿÿÿÿÿ`& 2)`Â(Â( Àq&ÿÿÿÿÿÿÿÿ`&@3)`Â(Â(¢pr&ÿÿÿÿÿÿÿÿ & 3)`Â(Â(£ s&ÿÿÿÿÿÿÿÿÐ&&4)`Â(Â(¤Ðs&ÿÿÿÿÿÿÿÿ 1&4)`Â(Â(¥€t&ÿÿÿÿÿÿÿÿ)&À4)`Â(Â(¦0u&ÿÿÿÿÿÿÿÿ`&p™,`Â(Â(§àu&ÿÿÿÿÿÿÿÿ`& 5)`Â(Â(©v&ÿÿÿÿÿÿÿÿ`&P5)`Â(Â(ª@w&ÿÿÿÿÿÿÿÿ0ü%€5)`Â(Â(«ðw&ÿÿÿÿÿÿÿÿ 1&6)`Â(Â(¬ x&ÿÿÿÿÿÿÿÿ)& 6)`Â(Â(­Py&ÿÿÿÿÿÿÿÿ’&9)`Â(Â(®z&ÿÿÿÿÿÿÿÿ`&:)`Â(Â(°°z&ÿÿÿÿÿÿÿÿ)&`Á,`Â(Â(±`{&ÿÿÿÿÿÿÿÿ’&à)`Â(Â(`|&ÿÿÿÿÿÿÿÿ)&ð:)`Â(Â(²À|&ÿÿÿÿÿÿÿÿ 1&°;)`Â(Â(³p}&ÿÿÿÿÿÿÿÿó"Àa#,0þ+_"@ð÷" ~&ðâ ÿÿÿÿÿÿÿÿ@ú# 1&<)`Â(Â(´Ð~&ÿÿÿÿÿÿÿÿ & <)`Â(Â(µ€&ÿÿÿÿÿÿÿÿÐ&&€È,`Â(Â(¶0€&ÿÿÿÿÿÿÿÿ0ü%À=)`Â(Â(ºà€&ÿÿÿÿÿÿÿÿÐ&& >)`Â(Â(»&ÿÿÿÿÿÿÿÿ +&P>)`Â(Â(¼@‚&ÿÿÿÿÿÿÿÿ`&€>)`Â(Â(½ð‚&ÿÿÿÿÿÿÿÿ `Ë(Ë(¾€$€Ð”" ƒ&ÿÿÿÿÿÿÿÿðþ%Ðw*`Â(Â(¿P„&ÿÿÿÿÿÿÿÿpñ"e pñ"…&ÿÿÿÿÿÿÿÿ`8% +&`x*`Â(Â(À°…&ÿÿÿÿÿÿÿÿ`.&Py*`Â(Â(Á`†&ÿÿÿÿÿÿÿÿ ¤&{*`Â(Â(‡&ÿÿÿÿÿÿÿÿД&*`Â(Â(ÃÀ‡&ÿÿÿÿÿÿÿÿ@£&ð{*`Â(Â(Äpˆ&ÿÿÿÿÿÿÿÿ’&€|*`Â(Â(Å ‰&ÿÿÿÿÿÿÿÿ€!( 0È(`È(h@@Љ&ÿÿÿÿÿÿÿÿ°&}*`Â(Â(Æ€Š&ÿÿÿÿÿÿÿÿ°&p}*`Â(Â(Ç0‹&ÿÿÿÿÿÿÿÿ’&~*`Â(Â(Èà‹&ÿÿÿÿÿÿÿÿ Ð 0È(`È(@@Ài"PÉ( É(Œ&ÿÿÿÿÿÿÿÿ 1&~*`Â(Â(É@&ÿÿÿÿÿÿÿÿ ð `Ë(Ë(D€P€ª)Pª)ð&ÿÿÿÿÿÿÿÿ à `Â(Â(ý%q" Á(0Â(ð¶' Ž&ÿÿÿÿÿÿÿÿ `Â(Â(pó'°r"PÃ(€Ã(`ñ'P&ÿÿÿÿÿÿÿÿ `Â(Â(À¾&€f" Ã(àÃ( À&&ÿÿÿÿÿÿÿÿ  Ä(ÐÄ(-& n"°Ã(Ä((°&ÿÿÿÿÿÿÿÿ   Ä(ÐÄ(po"ÀÅ(Å(p(`‘&ÿÿÿÿÿÿÿÿ €Æ(@Á(  €«&°e"ðÅ( Æ(À(’&ÿÿÿÿÿÿÿÿ 0€Æ(@Á(  ðh"pÇ(@Ç(Ñ'À’&ÿÿÿÿÿÿÿÿ 0È(`È( @@PÆ& h" Ç(ÐÇ(ÀÜ'p“&ÿÿÿÿÿÿÿÿ @0È(`È( @@Ài"PÉ( É(е& ”&ÿÿÿÿÿÿÿÿ 0È(`È( @@À&0l"€É(°É(Д&ÿÿÿÿÿÿÿÿ P0È(`È( @@ð5&Ðm"v+àu+€•&ÿÿÿÿÿÿÿÿ `Ë(Ë(€€`x"pv+ ¨,0–&ÿÿÿÿÿÿÿÿ €`Ë(Ë(€€ ª) ô(à–&ÿÿÿÿÿÿÿÿ 0È(`È(@@°ª)àª)—&ÿÿÿÿÿÿÿÿ@®& ¯&p®)à­)è@p£"ø%±&ÿÿÿÿÿÿÿÿt( °)`Â(Â(>ð˜&ÿÿÿÿÿÿÿÿà·& 0È(`È(h@@ ™&ÿÿÿÿÿÿÿÿП& 0È(`È(<@@Pš&ÿÿÿÿÿÿÿÿ`ú"„ €7(`ú"›&ÿÿÿÿÿÿÿÿ@v%’&À*`Â(Â(r°›&ÿÿÿÿÿÿÿÿ@£&&*`Â(Â(l`œ&ÿÿÿÿÿÿÿÿ ¤&@&*`Â(Â(m&ÿÿÿÿÿÿÿÿП&P*`Â(Â(RÀ&ÿÿÿÿÿÿÿÿ `Ë(Ë(D€«)@«)pž&ÿÿÿÿÿÿÿÿП&„"  & Ÿ&ÿÿÿÿÿÿÿÿ Ÿ& 0¬)0È(`È(@@Pš& g(П&ÿÿÿÿÿÿÿÿ’&°‚*`Â(Â(`Ù)ñ€ &ÿÿÿÿÿÿÿÿà¡& Ÿ&ÿÿÿÿÿÿÿÿ0¡& 0È(`È(@@Pk'à¡&ÿÿÿÿÿÿÿÿ`#& 0È(`È(R@ @$&ÿÿÿÿÿÿÿÿ €Æ(@Á(  `§& a"03&@£&ÿÿÿÿÿÿÿÿ’&€¼)`Â(Â(SP¥&ð£&ÿÿÿÿÿÿÿÿ 0È(`È(@ @À¨&°"€S& ¤&ÿÿÿÿÿÿÿÿ’&€¼)`Â(Â(Tð£&Ѓ*ÿÿÿÿÿÿÿÿ `Ë(Ë(P"€ ª&€€"¦&ÿÿÿÿÿÿÿÿ’&€¼)`Â(Â(@½)U°¦&Ѓ*ÿÿÿÿÿÿÿÿ@£& 0È(`È( @@`§&ÿÿÿÿÿÿÿÿ’& ¿)`Â(Â(Vp©&¨&ÿÿÿÿÿÿÿÿ ¤& 0È(`È(!@@À¨&ÿÿÿÿÿÿÿÿ’& ¿)`Â(Â(W¨&Ѓ*ÿÿÿÿÿÿÿÿ¦& 0È(`È("@@ ª&ÿÿÿÿÿÿÿÿ’& ¿)`Â(Â(@À)XЪ&Ѓ*ÿÿÿÿÿÿÿÿ’& 0È(`È(#@@pK(€«&ÿÿÿÿÿÿÿÿ@£& 0È(`È(%0 ‚"0¬&ÿÿÿÿÿÿÿÿ ¤& `Ë(Ë(&2@ð‚"à¬&ÿÿÿÿÿÿÿÿ¦& p«)Á('4€Àƒ"­&ÿÿÿÿÿÿÿÿà~"À#p®)à­)(@`²&à~"@®&ÿÿÿÿÿÿÿÿ€ñ# €Æ(@Á(^  ¸&0†"pÇ(@Ç( (À’&ÿÿÿÿÿÿÿÿŒ& 0È(`È()@@pÁ(pÁ( ¯&ÿÿÿÿÿÿÿÿ €Æ(@Á(_   º&‡"pÇ(@Ç(ð®&À’&ÿÿÿÿÿÿÿÿ@®& ¯&p®)à­)*@@˜&±&ÿÿÿÿÿÿÿÿЇ"À#à,P,`" @Š"°±&ÀÇ!ÿÿÿÿÿÿÿÿþ#@®& 0È(`È(+@@`²&ÿÿÿÿÿÿÿÿŒ& 0È(`È(a@@pÁ(ÐÄ(³&ÿÿÿÿÿÿÿÿ@®& ¯&p®)à­),@0“"±&ÿÿÿÿÿÿÿÿ°&³&p,ÐÃ)bp´&ÿÿÿÿÿÿÿÿ Ÿ& 0È(`È(-@@П&ÿÿÿÿÿÿÿÿ 0È(`È(c@@ A(‹"PÉ( É(àÕ' ”&ÿÿÿÿÿÿÿÿŒ& 0È(`È(.@@pÁ(P°)€¶&ÿÿÿÿÿÿÿÿà‹"À‚#p®)à­)d"@0C(€"0·&É!ÿÿÿÿÿÿÿÿ` $PŽ"€†#ð,€ÿ+e"@ ™&PŽ"p"'à·&Ð!ÿÿÿÿÿÿÿÿ@ÿ#ð®& 0È(`È(f@@@¹&¸&ÿÿÿÿÿÿÿÿ¸& 0È(`È(g@@@¹&ÿÿÿÿÿÿÿÿ’& *`Â(Â(sð¹&ÿÿÿÿÿÿÿÿP°& 0È(`È(y@@ º&ÿÿÿÿÿÿÿÿ é' 0È(`È(4@@P»&ÿÿÿÿÿÿÿÿ’&ð*`Â(Â(‚¼&ÿÿÿÿÿÿÿÿ’&±,`Â(Â(°¼&ÿÿÿÿÿÿÿÿ’&*`Â(Â(…`½&ÿÿÿÿÿÿÿÿ&€¶&€­)€°)/¾&ÿÿÿÿÿÿÿÿ& 0È(`È(0@@k( m(À¾&ÿÿÿÿÿÿÿÿ’&€¶&Ð)à°)1 p¿&ÿÿÿÿÿÿÿÿ `Â(Â(2ÐÀ&€f" Ã(àÃ(&ÿÿÿÿÿÿÿÿ À& 0È(`È(3@@ Å&&ÐÀ&ÿÿÿÿÿÿÿÿ €Æ(@Á(4  àÂ&`’"±)ð)€Á&ÿÿÿÿÿÿÿÿ€Á&€¶&Ð)à°)5 0Â&ÿÿÿÿÿÿÿÿ€Á& 0È(`È(6@@àÂ&ÿÿÿÿÿÿÿÿ’&`Â(Â(7Ã&ÿÿÿÿÿÿÿÿ8ðÄ&„"0¡& Ÿ&ÿÿÿÿÿÿÿÿ@Ä& 0È(`È(9@@ðÄ&ÿÿÿÿÿÿÿÿÐÀ& 0È(`È(:@@À( Å&ÿÿÿÿÿÿÿÿp“& 0È(`È(;@@PÆ&ÿÿÿÿÿÿÿÿ Ÿ& °)`Â(Â(=Ç&ÿÿÿÿÿÿÿÿП& °)`Â(Â(?°Ç&ÿÿÿÿÿÿÿÿ’& °)`Â(Â(@`È&ÿÿÿÿÿÿÿÿÀ’& °)`Â(Â(BÉ&ÿÿÿÿÿÿÿÿ@£& °)`Â(Â(CÀÉ&ÿÿÿÿÿÿÿÿ ¤& °)`Â(Â(DpÊ&ÿÿÿÿÿÿÿÿ¦& °)`Â(Â(E Ë&ÿÿÿÿÿÿÿÿ@*#+#À.# "€†#€&#@'#(#À(#€)#À+#€,#@-#.#€/#@0#1#À1#€2#PŽ"€†#ð,€ÿ+i"@àÍ&ð"à·&Ð!ÿÿÿÿÿÿÿÿ@ÿ#À"@3#À,Pÿ+j"@Ò&p‰"0Í&ðÉ!ÿÿÿÿÿÿÿÿ $€Ì& 0È(`È(k@@àÍ&ÿÿÿÿÿÿÿÿ@3#4#À4#€5#7#À7#€8#@9#:#À:#€;#@<#=#À=#€>#@?#@#@6#‘"p‰"’&PÜRÎ Ðòd"€Æ(  @Á(ÿÿÿÿÿÿÿÿàg.@Ï&’&PÜSÏ °ód"€Æ(  @Á(ÿÿÿÿÿÿÿÿh.ðÏ&àÍ& PÜTÐ ²d"0È( @`È(ÿÿÿÿÿÿÿÿ h. Ð&àÍ& PÜUÑ ôd"0È( @`È(ÿÿÿÿÿÿÿÿ@h.0Í& 0È(`È(l@@Ò&ÿÿÿÿÿÿÿÿPÑ&Ò& PÜVÒ õd"0È( @`È(ÿÿÿÿÿÿÿÿ`h.°Ò&°±&PÜWÓ  œd"à, P,ÿÿÿÿÿÿÿÿ€h.`Ó&’&PÜXÔ põd"€Æ(  @Á(ÿÿÿÿÿÿÿÿ h.Ô&’&PÜYÕ Pöd"€Æ(  @Á(ÿÿÿÿÿÿÿÿÀh.ÀÔ&’&PÜZÖ Àöd"€Æ(  @Á(ÿÿÿÿÿÿÿÿàh.ð®&m Ö&ÿÿÿÿÿÿÿÿpÕ& Ö&PÜ[× 0÷d" ÿÿÿÿÿÿÿÿi.&n€×&ÿÿÿÿÿÿÿÿÐÖ&€×&PÜ\Ø  ÷d"ÿÿÿÿÿÿÿÿ i. 0€Æ(@Á(o  @Ú&0†"pÇ(@Ç(P°&À’&ÿÿÿÿÿÿÿÿ’&`*`Â(Â(pÙ&ÿÿÿÿÿÿÿÿàØ& 0È(`È(q@@@Ú&ÿÿÿÿÿÿÿÿ’& ‚*`Â(Â(0—,þðÚ&ÿÿÿÿÿÿÿÿ ”&°(*`Â(Â({ Û&ÿÿÿÿÿÿÿÿ’& €*`Â(Â( Ú)PÜ&ÿÿÿÿÿÿÿÿ Ÿ&À**`Â(Â(Ý&ÿÿÿÿÿÿÿÿp“&б)`Â(Â(F°Ý&ÿÿÿÿÿÿÿÿД&²)`Â(Â(G`Þ&ÿÿÿÿÿÿÿÿ@£&0²)`Â(Â(Iß&ÿÿÿÿÿÿÿÿ ¤&`²)`Â(Â(JÀß&ÿÿÿÿÿÿÿÿ’&B*`Â(Â(¨pà&ÿÿÿÿÿÿÿÿ¦&²)`Â(Â(K á&ÿÿÿÿÿÿÿÿÀ¾&'*`Â(Â( *Ðá&ÿÿÿÿÿÿÿÿ0¬&À²)`Â(Â(L€â&ÿÿÿÿÿÿÿÿ’& a*`Â(Â(°¿, 0ã&ÿÿÿÿÿÿÿÿà¬&ð²)`Â(Â(Màã&ÿÿÿÿÿÿÿÿ­& ³)`Â(Â(Nä&ÿÿÿÿÿÿÿÿÀ¾&à@*`Â(Â(p *@å&ÿÿÿÿÿÿÿÿ@£&P³)`Â(Â(Oðå&ÿÿÿÿÿÿÿÿ ¤&€³)`Â(Â(P æ&ÿÿÿÿÿÿÿÿ¦&°³)`Â(Â(QPç&ÿÿÿÿÿÿÿÿ’&ð'*`Â(Â(ð * è&ÿÿÿÿÿÿÿÿП&°*`Â(Â(S€q'°è&ÿÿÿÿÿÿÿÿ’& *`Â(Â(Tàë'`é&ÿÿÿÿÿÿÿÿ’&p *`Â(Â(Uê&ÿÿÿÿÿÿÿÿ’&Ð *`Â(Â(VÀê&ÿÿÿÿÿÿÿÿ’&€õ)`Â(Â(Wpë&ÿÿÿÿÿÿÿÿ’&`!*`Â(Â(X ì&ÿÿÿÿÿÿÿÿ’&À!*`Â(Â(YÐì&ÿÿÿÿÿÿÿÿ’&€"*`Â(Â(\°2(€í&ÿÿÿÿÿÿÿÿ’&€*`Â(Â(t0î&ÿÿÿÿÿÿÿÿ’&ð!*`Â(Â(Šàî&ÿÿÿÿÿÿÿÿ’&*`Â(Â(zï&ÿÿÿÿÿÿÿÿ’&P*`Â(Â({@ð&ÿÿÿÿÿÿÿÿ’&@*`Â(Â(}ðð&ÿÿÿÿÿÿÿÿ Ÿ&ñ)`Â(Â( ñ&ÿÿÿÿÿÿÿÿ’& *`Â(Â(ƒPò&ÿÿÿÿÿÿÿÿ’&à*`Â(Â(† ²'ó&ÿÿÿÿÿÿÿÿ’&à"*`Â(Â(]°ó&ÿÿÿÿÿÿÿÿ’&@#*`Â(Â(^`ô&ÿÿÿÿÿÿÿÿ’& #*`Â(Â(_õ&ÿÿÿÿÿÿÿÿp“&$*`Â(Â(`Àõ&ÿÿÿÿÿÿÿÿp“&0$*`Â(Â(apö&ÿÿÿÿÿÿÿÿp“&`$*`Â(Â(b ÷&ÿÿÿÿÿÿÿÿД&$*`Â(Â(cÐ÷&ÿÿÿÿÿÿÿÿД&À$*`Â(Â(d€ø&ÿÿÿÿÿÿÿÿД&ð$*`Â(Â(e0ù&ÿÿÿÿÿÿÿÿ Ÿ& %*`Â(Â(fÐ'p…'àù&ÿÿÿÿÿÿÿÿ ”&àõ)`Â(Â(gú&ÿÿÿÿÿÿÿÿ’&P%*`Â(Â(h0Y(@û&ÿÿÿÿÿÿÿÿП&€%*`Â(Â(iðû&ÿÿÿÿÿÿÿÿ Ÿ&°%*`Â(Â(j ü&ÿÿÿÿÿÿÿÿ Ÿ&à%*`Â(Â(kPý&ÿÿÿÿÿÿÿÿ ”&<*`Â(Â( þ&ÿÿÿÿÿÿÿÿ¦&ö)`Â(Â(n°þ&ÿÿÿÿÿÿÿÿÀ¾&p&*`Â(Â(o`ÿ&ÿÿÿÿÿÿÿÿp“& &*`Â(Â(p'ÿÿÿÿÿÿÿÿÀ’&Ð&*`Â(Â(rÀ'ÿÿÿÿÿÿÿÿ Ÿ&'*`Â(Â(sp'ÿÿÿÿÿÿÿÿ Ÿ&0'*`Â(Â(t 'ÿÿÿÿÿÿÿÿàù& 0È(`È(v@@ (Ð'ÿÿÿÿÿÿÿÿ Ÿ&`'*`Â(Â(w€'ÿÿÿÿÿÿÿÿÀ¾&'*`Â(Â(x0'ÿÿÿÿÿÿÿÿ’&ð'*`Â(Â(yàY(à'ÿÿÿÿÿÿÿÿÀ¾&P(*`Â(Â(zÀ`('ÿÿÿÿÿÿÿÿÀ¾&)*`Â(Â(|@'ÿÿÿÿÿÿÿÿÀ¾&p)*`Â(Â(}ð'ÿÿÿÿÿÿÿÿ’&Ð)*`Â(Â(~ 'ÿÿÿÿÿÿÿÿ’&0**`Â(Â(P'ÿÿÿÿÿÿÿÿp"' 0È(`È(@@ 'ÿÿÿÿÿÿÿÿ Ÿ&`**`Â(Â(€° 'ÿÿÿÿÿÿÿÿp“& +*`Â(Â(‚` 'ÿÿÿÿÿÿÿÿ’&€+*`Â(Â(ƒ 'ÿÿÿÿÿÿÿÿ Ÿ&à+*`Â(Â(„À 'ÿÿÿÿÿÿÿÿ@£&@,*`Â(Â(…p 'ÿÿÿÿÿÿÿÿ ¤& ,*`Â(Â(† 'ÿÿÿÿÿÿÿÿ¦&-*`Â(Â(‡Ð 'ÿÿÿÿÿÿÿÿ@£&0-*`Â(Â(ˆ€'ÿÿÿÿÿÿÿÿ ¤&-*`Â(Â(‰0'ÿÿÿÿÿÿÿÿ¦&ð-*`Â(Â(Šà'ÿÿÿÿÿÿÿÿ@£&P.*`Â(Â(‹'ÿÿÿÿÿÿÿÿ ¤&°.*`Â(Â(Œ@'ÿÿÿÿÿÿÿÿ@£&/*`Â(Â(ð'ÿÿÿÿÿÿÿÿ ¤&p/*`Â(Â(Ž 'ÿÿÿÿÿÿÿÿ¦&Ð/*`Â(Â(P'ÿÿÿÿÿÿÿÿ@£&@2*`Â(Â('ÿÿÿÿÿÿÿÿ ¤&Ð2*`Â(Â(‘°'ÿÿÿÿÿÿÿÿ’& R*`Â(Â(–`'ÿÿÿÿÿÿÿÿ¦&00*`Â(Â(’'ÿÿÿÿÿÿÿÿ@£&ð3*`Â(Â(“À'ÿÿÿÿÿÿÿÿ ¤&à4*`Â(Â(”p'ÿÿÿÿÿÿÿÿ¦&p5*`Â(Â(• 'ÿÿÿÿÿÿÿÿ@£&06*`Â(Â(–Ð'ÿÿÿÿÿÿÿÿ ¤&À6*`Â(Â(—€'ÿÿÿÿÿÿÿÿàÍ&T*`Â(Â(™0'ÿÿÿÿÿÿÿÿ¦&P7*`Â(Â(˜à'ÿÿÿÿÿÿÿÿ’&8*`Â(Â(™'ÿÿÿÿÿÿÿÿП&0*`Â(Â(š@'ÿÿÿÿÿÿÿÿ0¬&9*`Â(Â(›ð'ÿÿÿÿÿÿÿÿà¬&À9*`Â(Â(œ 'ÿÿÿÿÿÿÿÿ­&€:*`Â(Â(P'ÿÿÿÿÿÿÿÿ Ÿ&@;*`Â(Â(ž'ÿÿÿÿÿÿÿÿ’&Ð;*`Â(Â(Ÿ°'ÿÿÿÿÿÿÿÿП&ÐD*`Â(Â(«` 'ÿÿÿÿÿÿÿÿP& =*`Â(Â(¡!'ÿÿÿÿÿÿÿÿ’&p#*`Â(Â(‹À!'ÿÿÿÿÿÿÿÿ€†#ð,€ÿ+Œ"@ 'ð"€Ì&à·&Ð!ÿÿÿÿÿÿÿÿ@ÿ#’&0H*`Â(Â(®{( #'ÿÿÿÿÿÿÿÿ’&ÀN*`Â(Â(ŽÐ#'ÿÿÿÿÿÿÿÿ Ÿ&ÀQ*`Â(Â(•€$'ÿÿÿÿÿÿÿÿÀ¾&0K*`Â(Â(±0%'ÿÿÿÿÿÿÿÿàÍ&PR*`Â(Â(—à%'ÿÿÿÿÿÿÿÿ& °)`Â(Â(&'ÿÿÿÿÿÿÿÿ’&ðH*`Â(Â(¯€ð%@''ÿÿÿÿÿÿÿÿ`‘& 1*`Â(Â(¢ð''ÿÿÿÿÿÿÿÿÀ’&p>*`Â(Â(£ ('ÿÿÿÿÿÿÿÿ ”&0?*`Â(Â(¤P)'ÿÿÿÿÿÿÿÿà–&À?*`Â(Â(¥*'ÿÿÿÿÿÿÿÿ ”&°(*`Â(Â(P:*°*'ÿÿÿÿÿÿÿÿt(0*`Â(Â(¦`+'ÿÿÿÿÿÿÿÿÀ¾&à@*`Â(Â(§,'ÿÿÿÿÿÿÿÿÀ¾&p&*`Â(Â(@>*À,'ÿÿÿÿÿÿÿÿП&P1*`Â(Â(©p-'ÿÿÿÿÿÿÿÿ’&àC*`Â(Â(ª .'ÿÿÿÿÿÿÿÿÀ¾&p)*`Â(Â(0B*Ð.'ÿÿÿÿÿÿÿÿ Ÿ&ðE*`Â(Â(¬€/'ÿÿÿÿÿÿÿÿ Ÿ&@G*`Â(Â(­00'ÿÿÿÿÿÿÿÿ ”&àõ)`Â(Â(PF*!à0'ÿÿÿÿÿÿÿÿ’&J*`Â(Â(°1'ÿÿÿÿÿÿÿÿ’&B*`Â(Â(@J*$@2'ÿÿÿÿÿÿÿÿ@£&PL*`Â(Â(²ð2'ÿÿÿÿÿÿÿÿ ¤&pM*`Â(Â(³ 3'ÿÿÿÿÿÿÿÿ¦&0Z*`Â(Â(´P4'ÿÿÿÿÿÿÿÿ@£&P[*`Â(Â(µ5'ÿÿÿÿÿÿÿÿ ¤&p\*`Â(Â(¶°5'ÿÿÿÿÿÿÿÿ¦&`]*`Â(Â(·`6'ÿÿÿÿÿÿÿÿ Ÿ& ^*`Â(Â(¸7'ÿÿÿÿÿÿÿÿ Ÿ&°^*`Â(Â(¹À7'ÿÿÿÿÿÿÿÿ Ÿ&@_*`Â(Â(ºp8'ÿÿÿÿÿÿÿÿ Ÿ&`*`Â(Â(» 9'ÿÿÿÿÿÿÿÿ’&`*`Â(Â(¼Ð9'ÿÿÿÿÿÿÿÿ’& a*`Â(Â(½€:'ÿÿÿÿÿÿÿÿt(àa*`Â(Â(¿0;'ÿÿÿÿÿÿÿÿt(pb*`Â(Â(Àà;'ÿÿÿÿÿÿÿÿt(àg*`Â(Â(Á<'ÿÿÿÿÿÿÿÿt(`c*`Â(Â(Â@='ÿÿÿÿÿÿÿÿP&ðc*`Â(Â(Ãð='ÿÿÿÿÿÿÿÿ`‘&Pd*`Â(Â(Ä >'ÿÿÿÿÿÿÿÿÀ’&e*`Â(Â(ÅP?'ÿÿÿÿÿÿÿÿà–&f*`Â(Â(Ç@'ÿÿÿÿÿÿÿÿ ”&Àf*`Â(Â(ɰ@'ÿÿÿÿÿÿÿÿ’&€g*`Â(Â(Ê`A'ÿÿÿÿÿÿÿÿП&0i*`Â(Â(ÌB'ÿÿÿÿÿÿÿÿП&ði*`Â(Â(ÍÀB'ÿÿÿÿÿÿÿÿÀ¾&°j*`Â(Â(ÎpC'ÿÿÿÿÿÿÿÿ’&‡*`Â(Â(Ï D'ÿÿÿÿÿÿÿÿÀ¾&P(*`Â(Â(o*0ÐD'ÿÿÿÿÿÿÿÿð®&°U*`Â(Â(¢€E'ÿÿÿÿÿÿÿÿ’&V*`Â(Â(£0F'ÿÿÿÿÿÿÿÿ’&pV*`Â(Â(¤àF'ÿÿÿÿÿÿÿÿt(àd*`Â(Â(¾G'ÿÿÿÿÿÿÿÿàÍ&ÐV*`Â(Â(¥@H'ÿÿÿÿÿÿÿÿ’&0W*`Â(Â(§ðH'ÿÿÿÿÿÿÿÿ Ÿ&W*`Â(Â(¨ I'ÿÿÿÿÿÿÿÿ’&°X*`Â(Â(«PJ'ÿÿÿÿÿÿÿÿ’&@Y*`Â(Â(¬K'ÿÿÿÿÿÿÿÿ’&@˜*`Â(Â(Àu*<°K'ÿÿÿÿÿÿÿÿ’&PX*`Â(Â(®`L'ÿÿÿÿÿÿÿÿ’& -`Â(Â(ðu*=M'ÿÿÿÿÿÿÿÿ’&€[*`Â(Â(¯ÀM'ÿÿÿÿÿÿÿÿàÍ& °)`Â(Â(°pN'ÿÿÿÿÿÿÿÿ ”&pe*`Â(Â(Æ O'ÿÿÿÿÿÿÿÿ Ÿ&ð«*`Â(Â(ÐÐO'ÿÿÿÿÿÿÿÿt( ‹*`Â(Â(Ò€P'ÿÿÿÿÿÿÿÿ’&ÐŒ*`Â(Â(Ó0Q'ÿÿÿÿÿÿÿÿt(p*`Â(Â(ÔàQ'ÿÿÿÿÿÿÿÿ Ÿ&°‘*`Â(Â(ÕR'ÿÿÿÿÿÿÿÿ Ÿ&À“*`Â(Â(Ö@S'ÿÿÿÿÿÿÿÿП&`Â(Â(ÙðS'ÿÿÿÿÿÿÿÿ ”&ph*`Â(Â(Ë T'ÿÿÿÿÿÿÿÿ Ÿ&À–*`Â(Â(ÚPU'ÿÿÿÿÿÿÿÿ Ÿ& —*`Â(Â(ÛV'ÿÿÿÿÿÿÿÿ’&P*`Â(Â(ܰV'ÿÿÿÿÿÿÿÿ’&à*`Â(Â(ÞÐx(`W'ÿÿÿÿÿÿÿÿ’&@€*`Â(Â(ß`ì%X'ÿÿÿÿÿÿÿÿ’& €*`Â(Â(àÀX'ÿÿÿÿÿÿÿÿ’& ‚*`Â(Â(ãpY'ÿÿÿÿÿÿÿÿ’&°‚*`Â(Â(ä Z'ÿÿÿÿÿÿÿÿ’&`¢*`Â(Â(åÐZ'ÿÿÿÿÿÿÿÿl' 0È(`È(æ@@€['ÿÿÿÿÿÿÿÿП&„*`Â(Â(ç0\'ÿÿÿÿÿÿÿÿ ¤&@&*`Â(Â(°›,èà\'ÿÿÿÿÿÿÿÿ@£&&*`Â(Â(@œ,é]'ÿÿÿÿÿÿÿÿ¦&ö)`Â(Â(,ê@^'ÿÿÿÿÿÿÿÿÀ¾&)*`Â(Â(0*îð^'ÿÿÿÿÿÿÿÿ’&àC*`Â(Â(à*ñ _'ÿÿÿÿÿÿÿÿП&P1*`Â(Â(*ôP`'ÿÿÿÿÿÿÿÿ Ÿ&u*`Â(Â(Èa'ÿÿÿÿÿÿÿÿП&ÐD*`Â(Â( *ý°a'ÿÿÿÿÿÿÿÿ’&@—(`Â(Â(‰*H`b'ÿÿÿÿÿÿÿÿð®& °)`Â(Â(­c'ÿÿÿÿÿÿÿÿ’&¿(`Â(Â(€‹*NÀc'ÿÿÿÿÿÿÿÿ’&@˜*`Â(Â(*Tpd'ÿÿÿÿÿÿÿÿ’& -`Â(Â(ð*U e'ÿÿÿÿÿÿÿÿ’&@‰*`Â(Â(ÑÐe'ÿÿÿÿÿÿÿÿ +&à—*`Â(Â(Ê€f'ÿÿÿÿÿÿÿÿ À`Â(Â(Ë •"@±)àš*0g'ÿÿÿÿÿÿÿÿ  Ä(ÐÄ(Ìj"€š*Л*àg'ÿÿÿÿÿÿÿÿ €Æ(@Á(Í  m"0œ*P*h'ÿÿÿÿÿÿÿÿ 0È(`È(Î@@p–"°* ž*@i'ÿÿÿÿÿÿÿÿ 0È(`È(Ð@ @àq"ði'ÿÿÿÿÿÿÿÿ   Ä(ÐÄ(ј"¡*0Ÿ* j'ÿÿÿÿÿÿÿÿà¡& 0È(`È(Ó@@Pk'ÿÿÿÿÿÿÿÿ Ÿ&`Â(Â(×€['l'ÿÿÿÿÿÿÿÿ°l'×°l'°l'°™"°l'ÿÿÿÿÿÿÿÿ’&`Â(Â(Øn'`m'ÿÿÿÿÿÿÿÿ`m' 0È(`È(Ù@@Àn'€š"n'ÿÿÿÿÿÿÿÿn' 0È(`È(Û@@Àn'ÿÿÿÿÿÿÿÿÝ œ"po'ÿÿÿÿÿÿÿÿðu"Þ ðu" p'àd"ÿÿÿÿÿÿÿÿ ò#’&@˜*`Â(Â(ÝÐp'ÿÿÿÿÿÿÿÿП&°*`Â(Â(à°è& …*ÿÿÿÿÿÿÿÿ `Ë(Ë(D€«)@«)0r'ÿÿÿÿÿÿÿÿp“&*`Â(Â(âàr'ÿÿÿÿÿÿÿÿÀ¾&´*`Â(Â(¹s'ÿÿÿÿÿÿÿÿÀ¾& °)`Â(Â(½@t'ÿÿÿÿÿÿÿÿ’& ¶*`Â(Â(¿ðt'ÿÿÿÿÿÿÿÿ’&`ç*`Â(Â(À u'ÿÿÿÿÿÿÿÿ’&à¸*`Â(Â(ÂPv'ÿÿÿÿÿÿÿÿ’& ì*`Â(Â(Ãw'ÿÿÿÿÿÿÿÿ’&º*`Â(Â(İw'ÿÿÿÿÿÿÿÿ’&P»*`Â(Â(Å`x'ÿÿÿÿÿÿÿÿ’& ¼*`Â(Â(Æy'ÿÿÿÿÿÿÿÿ’& ¾*`Â(Â(ÈÀy'ÿÿÿÿÿÿÿÿ’&¿*`Â(Â(Êpz'ÿÿÿÿÿÿÿÿ’&À*`Â(Â(Ë {'ÿÿÿÿÿÿÿÿ’&À*`Â(Â(ÌÐ{'ÿÿÿÿÿÿÿÿð®&ÐÔ*`Â(Â(Í€|'ÿÿÿÿÿÿÿÿ’&ðÕ*`Â(Â(Î0}'ÿÿÿÿÿÿÿÿ ”&@p+`Â(Â( *Zà}'ÿÿÿÿÿÿÿÿ’&P*`Â(Â(à‘*`~'ÿÿÿÿÿÿÿÿ’&P*`Â(Â(’*a@'ÿÿÿÿÿÿÿÿ’&P%*`Â(Â(`–*lð'ÿÿÿÿÿÿÿÿ€' 0È(`È(ã@@ €'ÿÿÿÿÿÿÿÿð©"À"#`Ë(Ë(å @ð©"‚'P'ÿÿÿÿÿÿÿÿô#À"#`Ë(Ë(æ @ð©"P'ÿÿÿÿÿÿÿÿô#ž"€##`Ë(Ë(ç @ž"`ƒ'°‚'ÿÿÿÿÿÿÿÿ ô#€##`Ë(Ë(è @ž"°‚'ÿÿÿÿÿÿÿÿ ô# €Æ(@Á(Ï  @—"„'ÿÿÿÿÿÿÿÿ °`Â(Â(Ò u"¢* £*À„'ÿÿÿÿÿÿÿÿ Ÿ& %*`Â(Â(Öàù&Ѓ*ÿÿÿÿÿÿÿÿ’&P*`Â(Â(€Ó*s †'ÿÿÿÿÿÿÿÿ’&*`Â(Â(Õ*yІ'ÿÿÿÿÿÿÿÿ’&à*`Â(Â(`Ø*€‡'ÿÿÿÿÿÿÿÿ’&@€*`Â(Â(@Ú*…0ˆ'ÿÿÿÿÿÿÿÿ’&×*`Â(Â(Ïàˆ'ÿÿÿÿÿÿÿÿ’&ðÛ*`Â(Â(Õ‰'ÿÿÿÿÿÿÿÿ’&PH+`Â(Â(Ù@Š'ÿÿÿÿÿÿÿÿ’&0á*`Â(Â(ÚðŠ'ÿÿÿÿÿÿÿÿ’&€â*`Â(Â(Û ‹'ÿÿÿÿÿÿÿÿ’&ä*`Â(Â(ÜPŒ'ÿÿÿÿÿÿÿÿ’&ðä*`Â(Â(Ý'ÿÿÿÿÿÿÿÿ’&о+`Â(Â(à°'ÿÿÿÿÿÿÿÿ’&@Ê+`Â(Â(ä`Ž'ÿÿÿÿÿÿÿÿð®&@ +`Â(Â(å'ÿÿÿÿÿÿÿÿ’& -`Â(Â(àÜ*‹À'ÿÿÿÿÿÿÿÿ’&J*`Â(Â(Þ*p'ÿÿÿÿÿÿÿÿ’& -`Â(Â(0Þ*‘ ‘'ÿÿÿÿÿÿÿÿ’&8*`Â(Â(àß*–Б'ÿÿÿÿÿÿÿÿ’&8*`Â(Â(@à*—€’'ÿÿÿÿÿÿÿÿ’&8*`Â(Â(Pâ*œ0“'ÿÿÿÿÿÿÿÿ’&8*`Â(Â(°â*à“'ÿÿÿÿÿÿÿÿðþ% )`Â(Â(n”'ÿÿÿÿÿÿÿÿ’&€è*`Â(Â(Á@•'ÿÿÿÿÿÿÿÿ’&€g*`Â(Â(À+¢ð•'ÿÿÿÿÿÿÿÿ’&€g*`Â(Â( +£ –'ÿÿÿÿÿÿÿÿ’&0H*`Â(Â( +©P—'ÿÿÿÿÿÿÿÿ’&ðH*`Â(Â(ð+®˜'ÿÿÿÿÿÿÿÿ’&ðH*`Â(Â( +¯°˜'ÿÿÿÿÿÿÿÿÀ¾&0K*`Â(Â(`¤+µ`™'ÿÿÿÿÿÿÿÿŒ& 0È(`È(n@@pÁ(›(š'ÿÿÿÿÿÿÿÿn'Ú@ð«'Àš'ÿÿÿÿÿÿÿÿ’& -`Â(Â(Ïp›'ÿÿÿÿÿÿÿÿ’&*`Â(Â(á œ'ÿÿÿÿÿÿÿÿðœ"á ðœ"€'М'àd"ÿÿÿÿÿÿÿÿÀò#â  €'ðœ"М'àd"ÿÿÿÿÿÿÿÿÀò#’&Ð+`Â(Â(ì0ž'ÿÿÿÿÿÿÿÿàÍ& C+`Â(Â(ðàž'ÿÿÿÿÿÿÿÿÒ&0D+`Â(Â(ñŸ'ÿÿÿÿÿÿÿÿàÍ&ðD+`Â(Â(ò@ 'ÿÿÿÿÿÿÿÿÀª"@$#`Ë(Ë(é @Àª"9(ð 'ÿÿÿÿÿÿÿÿ@õ#`Ÿ"%#`Ë(Ë(ë @`Ÿ"P¢' ¡'ÿÿÿÿÿÿÿÿàõ#%#`Ë(Ë(ì @`Ÿ" ¡'ÿÿÿÿÿÿÿÿàõ#”'º*â¤o •'9Àœåžo ¡'4º*s¤o ¢'9ð—ª' º*,¡o ¬';º*¸ ­'pß-º*0 "À%#`Ë(Ë(í @0 "¥'°£'ÿÿÿÿÿÿÿÿ€ö#’&G+`Â(Â(û`¤'ÿÿÿÿÿÿÿÿÀ%#`Ë(Ë(î @0 "°£'ÿÿÿÿÿÿÿÿ€ö#¡"€A#p®)à­)ï @¡"p¦'À¥'ÿÿÿÿÿÿÿÿ ÷#€A#p®)à­)ð @¡"À¥'ÿÿÿÿÿÿÿÿ ÷#”*º*â¤o •*9Àœåžo ¡*4º*s¤o ¢*9ð—ª* º*,¡o ¬*9Àé¤o À*º*ë¤o ’&Ð -`Â(Â(PÁ*ßЧ'Ѓ*ÿÿÿÿÿÿÿÿ«"@W#@†* †*ô @«"0©'€¨'ÿÿÿÿÿÿÿÿù#@W#@†* †*õ @«"€¨'ÿÿÿÿÿÿÿÿù#Œ& 0È(`È(@@pÁ(ðÈ(à©'ÿÿÿÿÿÿÿÿ@£& ÿ%0È(`È(! ª'ÿÿÿÿÿÿÿÿ@#0È(`È( @«'ÿÿÿÿÿÿÿÿn'Ü@Àš'ÿÿÿÿÿÿÿÿ’&à*`Â(Â(0Ø*~ ¬'ÿÿÿÿÿÿÿÿ’&@€*`Â(Â(Ú*„P­'ÿÿÿÿÿÿÿÿ’&X,`Â(Â(ý®'ÿÿÿÿÿÿÿÿ’&@I+`Â(Â(þ°®'ÿÿÿÿÿÿÿÿ’&ÐI+`Â(Â(ÿ`¯'ÿÿÿÿÿÿÿÿ0ü% ¿,`Â(Â(¯°'ÿÿÿÿÿÿÿÿ’&àK+`Â(Â(À°'ÿÿÿÿÿÿÿÿ’&°Á*`Â(Â(æ0æ%p±'ÿÿÿÿÿÿÿÿó& 0È(`È( @@ ²'ÿÿÿÿÿÿÿÿ’&M+`Â(Â( в'ÿÿÿÿÿÿÿÿ& ÿ% Ä(ÐÄ(ì0´'€³'ÿÿÿÿÿÿÿÿ À& ÿ% Ä(ÐÄ(퀳'ÿÿÿÿÿÿÿÿ `Â(Â(îà¥"PÃ(€Ã(P&ÿÿÿÿÿÿÿÿ €Æ(@Á(ð  €§"pÇ(@Ç(À’&ÿÿÿÿÿÿÿÿ 0È(`È(ñ@@P¨"PÉ( É(pù% ”&ÿÿÿÿÿÿÿÿ `Â(Â(ò ©" Á(0Â( Ž&ÿÿÿÿÿÿÿÿ `Â(Â(ó`¬"PÃ(€Ã(à´'P&ÿÿÿÿÿÿÿÿ  Ä(ÐÄ(ô0­"°Ã(Ä(°&ÿÿÿÿÿÿÿÿ  Ä(ÐÄ(õ®"ÀÅ(Å( F(`‘&ÿÿÿÿÿÿÿÿ €Æ(@Á(ö  Ю"ðÅ( Æ(’&ÿÿÿÿÿÿÿÿ €Æ(@Á(÷   ¯"pÇ(@Ç(µ'À’&ÿÿÿÿÿÿÿÿ 0È(`È(ø@@p°" Ç(ÐÇ(Àø%p“&ÿÿÿÿÿÿÿÿ 0È(`È(ù@@@±"PÉ( É(@¶' ”&ÿÿÿÿÿÿÿÿ 0È(`È(ú@@Ú'²" Ç(ÐÇ(»'p“&ÿÿÿÿÿÿÿÿ 0È(`È(û@@à²"PÉ( É(À»' ”&ÿÿÿÿÿÿÿÿ 0È(`È(ü@@°³"PÉ( É( ½' ”&ÿÿÿÿÿÿÿÿ’&àŒ,`Â(Â(ှ'ÿÿÿÿÿÿÿÿ €Æ(@Á(ý  €´"pÇ(@Ç(`º'À’&ÿÿÿÿÿÿÿÿ €Æ(@Á(þ  Pµ"pÇ(@Ç(0¿'À’&ÿÿÿÿÿÿÿÿ’&+`Â(Â(âÀ'ÿÿÿÿÿÿÿÿ 0È(`È(@@ð¶"PÉ( É(àN( ”&ÿÿÿÿÿÿÿÿ’&@Ç+`Â(Â(ãðÁ'ÿÿÿÿÿÿÿÿ €Æ(@Á(  À·"pÇ(@Ç(à¿'À’&ÿÿÿÿÿÿÿÿ 0È(`È(@@¸"PÉ( É(@Á' ”&ÿÿÿÿÿÿÿÿ 0È(`È(@@`¹" Ç(ÐÇ(p¼'p“&ÿÿÿÿÿÿÿÿ 0È(`È(@@à-(0º" Ç(ÐÇ(Ä'p“&ÿÿÿÿÿÿÿÿ €Æ(@Á(  »"ðÅ( Æ(°¹'’&ÿÿÿÿÿÿÿÿ 0È(`È( @@¿" Ç(ÐÇ(°Ä'p“&ÿÿÿÿÿÿÿÿ 0È(`È( @@à¿"PÉ( É(PÃ' ”&ÿÿÿÿÿÿÿÿ 0È(`È( @@°À"PÉ( É(ÀÆ' ”&ÿÿÿÿÿÿÿÿ €Æ(@Á(   €Á"pÇ(@Ç( Â'À’&ÿÿÿÿÿÿÿÿ 0È(`È( @@PÂ" Ç(ÐÇ(Æ'p“&ÿÿÿÿÿÿÿÿ €Æ(@Á(  Ã"pÇ(@Ç( È'À’&ÿÿÿÿÿÿÿÿ 0È(`È(@@ðÃ" Ç(ÐÇ(ÐÈ'p“&ÿÿÿÿÿÿÿÿ €Æ(@Á(  ÀÄ"ðÅ( Æ(`Å'’&ÿÿÿÿÿÿÿÿ 0È(`È(@@Å" Ç(ÐÇ(0Ê'p“&ÿÿÿÿÿÿÿÿ €Æ(@Á(  0Ç"ðÅ( Æ(Ðb(’&ÿÿÿÿÿÿÿÿ Ÿ& 0È(`È(@@È" µ&П&ÿÿÿÿÿÿÿÿ 0È(`È(@@ÐÈ" Ç(ÐÇ(Ë'p“&ÿÿÿÿÿÿÿÿ 0È(`È(@@pÊ" Ç(ÐÇ(€c(p“&ÿÿÿÿÿÿÿÿ 0È(`È(@@p½"PÉ( É(pÇ' ”&ÿÿÿÿÿÿÿÿ 0È(`È(@@@Ë"PÉ( É(Ï' ”&ÿÿÿÿÿÿÿÿÒ&@Æ,`Â(Â(`Ð'ÿÿÿÿÿÿÿÿ 0€Æ(@Á(  ‡"pÇ(@Ç(àØ&À’&ÿÿÿÿÿÿÿÿ’&ðÐ,`Â(Â( ÀÑ'ÿÿÿÿÿÿÿÿ’&ÐÕ,`Â(Â(&pÒ'ÿÿÿÿÿÿÿÿÀ"@!#`Ë(Ë(ä"@À" Ó'ÿÿÿÿÿÿÿÿ`ó#’&0H*`Â(Â(p+¨ÐÓ'ÿÿÿÿÿÿÿÿС"#`Ë(Ë(ñ"@С"€Ô'ÿÿÿÿÿÿÿÿÀ÷# 0È(`È(@@Ì"PÉ( É(°Ï' ”&ÿÿÿÿÿÿÿÿ 0È(`È(@@àÌ"PÉ( É(0Õ' ”&ÿÿÿÿÿÿÿÿ€Û"@#p«)Á(ò @€Û"°Ú'Ö'ÿÿÿÿÿÿÿÿ`ø# 0È(`È(@@°Í" Ç(ÐÇ(PÎ'p“&ÿÿÿÿÿÿÿÿÀ¾&P(*`Â(Â(à¥+ºð×'ÿÿÿÿÿÿÿÿ 0È(`È(@@€Î" Ç(ÐÇ(@×'p“&ÿÿÿÿÿÿÿÿÀ¾&P(*`Â(Â(¦+»PÙ'ÿÿÿÿÿÿÿÿp¼' 0È(`È(@@`Û'Ú'ÿÿÿÿÿÿÿÿ@#p«)Á(ó @€Û"Ö'ÿÿÿÿÿÿÿÿ`ø#p¼' 0È(`È(@@PÏ"Ú'ÿÿÿÿÿÿÿÿ& 0È(`È( @@ Ð"À¾&ÿÿÿÿÿÿÿÿ 0È(`È(!@@ðÐ" Ç(ÐÇ( Ø'p“&ÿÿÿÿÿÿÿÿ €Æ(@Á("  ÀÑ"pÇ(@Ç(€É'À’&ÿÿÿÿÿÿÿÿ’&@€*`Â(Â(P¨+À Þ'ÿÿÿÿÿÿÿÿÒ"g#3,à8,#"@0"(Ò"0à'ÐÞ'å ÿÿÿÿÿÿÿÿ G$Ò"g#3,à8,$"@ \(`Ó"ÐÞ'å ÿÿÿÿÿÿÿÿ G$Ò"g#3,à8,%"@0Ô"€ß'ÐÞ'å ÿÿÿÿÿÿÿÿ G$ €Æ(@Á(&  Õ"pÇ(@Ç(pÝ'À’&ÿÿÿÿÿÿÿÿÐÕ"@H#0È(`È('"  (Ù"á'ÐÕ ÿÿÿÿÿÿÿÿ`H$p×"I#€Æ(@Á((" p×"@â'× á'ÿÿÿÿÿÿÿÿI$’&@€*`Â(Â(0€(Æðâ'ÿÿÿÿÿÿÿÿÀ¾&0K*`Â(Â(0¤+´ ã'ÿÿÿÿÿÿÿÿ&€'&€Æ(@Á(*Pä'ÿÿÿÿÿÿÿÿ@c"L#`Ë(Ë(+"@PÜ"&å'PÙ ÿÿÿÿÿÿÿÿ€_$ Ý"#`Ë(Ë(,"@ß"&°å'Û ÿÿÿÿÿÿÿÿàJ$À¾&p&*`Â(Â(0,Ê`æ'ÿÿÿÿÿÿÿÿ`à" ¿+€Æ(@Á(-  `à"pé* Ä+ç'ÿÿÿÿÿÿÿÿ0á" à¢(€Æ(@Á(.  0á"ÐÄ+Ë+Àç'ÿÿÿÿÿÿÿÿâ"€P#`Ë+°ÿ+/"@°ð'â"pè' Þ ÿÿÿÿÿÿÿÿ€Z$Ðâ"€Y# ,Ðý+0"@P»&Ðâ" é'ß ÿÿÿÿÿÿÿÿ [$ `Ë(Ë(€€Pó(ð©)Ðé'ÿÿÿÿÿÿÿÿP°& °)`Â(Â(/€ê'ÿÿÿÿÿÿÿÿ# ’& PÜ. €: d"€Æ( @Á(€Q-ÿÿÿÿÿÿÿÿ@i. i.€: `é& 0È(`È(9@@àë'ÿÿÿÿÿÿÿÿ’&ðÎ(`Â(Â(:ì'ÿÿÿÿÿÿÿÿ’&ì+`Â(Â(<@í'ÿÿÿÿÿÿÿÿ’&°í+`Â(Â(>ðí'ÿÿÿÿÿÿÿÿ’&P*`Â(Â(PÓ*r î'ÿÿÿÿÿÿÿÿ ã"1 ð( ã"Pï'ÿÿÿÿÿÿÿÿ D$pä"@N#@†* †*2"@@(pä"ð'@Ý ÿÿÿÿÿÿÿÿ@&%pè' 0È(`È(3@@°ð'ÿÿÿÿÿÿÿÿ 0`Â(Â(5ò'°r"PÃ(€Ã( ·'P&ÿÿÿÿÿÿÿÿ`ñ' 0È(`È(6@@Àò'ò'ÿÿÿÿÿÿÿÿò' 0È(`È(7@@Àò'ÿÿÿÿÿÿÿÿP& 0È(`È(8@@ ô'pó'ÿÿÿÿÿÿÿÿpó' 0È(`È(9@@ ô'ÿÿÿÿÿÿÿÿpù% 0È(`È(:@@€&Ðô'ÿÿÿÿÿÿÿÿ’&õ+`Â(Â(;0ö'€õ'ÿÿÿÿÿÿÿÿ€õ' 0È(`È(<@@àö'0ö'ÿÿÿÿÿÿÿÿ€õ' 0È(`È(=@@@å"0ö'ÿÿÿÿÿÿÿÿàà'`ø+`Â(Â(>@ø'÷'ÿÿÿÿÿÿÿÿ÷' 0È(`È(?@@ðø'@ø'ÿÿÿÿÿÿÿÿ÷' 0È(`È(@@@æ"@ø'ÿÿÿÿÿÿÿÿ’&*`Â(Â( Ô*x ù'ÿÿÿÿÿÿÿÿ’&Àø+`Â(Â(Aû'Pú'ÿÿÿÿÿÿÿÿPú' 0È(`È(B@@°û'û'ÿÿÿÿÿÿÿÿPú' 0È(`È(C@@àæ"û'ÿÿÿÿÿÿÿÿ& 0È(`È(E@@ý'`ü'ÿÿÿÿÿÿÿÿ& 0È(`È(F@@°ç"`ü'ÿÿÿÿÿÿÿÿ’&€ù+`Â(Â(G(Àý'ÿÿÿÿÿÿÿÿ’&Ðî+`Â(Â(Bpþ'ÿÿÿÿÿÿÿÿ’&`ï+`Â(Â(C ÿ'ÿÿÿÿÿÿÿÿ’&Pð+`Â(Â(EÐÿ'ÿÿÿÿÿÿÿÿ’&ñ+`Â(Â(F€(ÿÿÿÿÿÿÿÿ’&ò+`Â(Â(J0(ÿÿÿÿÿÿÿÿ’&ðò+`Â(Â(Kà(ÿÿÿÿÿÿÿÿ’&àó+`Â(Â(M(ÿÿÿÿÿÿÿÿ Ÿ&Ðô+`Â(Â(N@(ÿÿÿÿÿÿÿÿ’&ð",`Â(Â(Qð(ÿÿÿÿÿÿÿÿ’&)`Â(Â(U (ÿÿÿÿÿÿÿÿ Ÿ&0%,`Â(Â(VP(ÿÿÿÿÿÿÿÿÀý' 0È(`È(H@@°((ÿÿÿÿÿÿÿÿÀý' 0È(`È(I@@€è"(ÿÿÿÿÿÿÿÿ’&û+`Â(Â(J0&`(ÿÿÿÿÿÿÿÿ`( 0È(`È(L@@Pé"0&ÿÿÿÿÿÿÿÿ Å& 0È(`È(M@@À(ÿÿÿÿÿÿÿÿ’&ðû+`Â(Â(N (p (ÿÿÿÿÿÿÿÿp ( 0È(`È(O@@Ð ( (ÿÿÿÿÿÿÿÿp ( 0È(`È(P@@°Ú" (ÿÿÿÿÿÿÿÿ’&°ü+`Â(Â(Q0 (€ (ÿÿÿÿÿÿÿÿ€ ( 0È(`È(R@@à (0 (ÿÿÿÿÿÿÿÿ€ ( 0È(`È(S@@ÀÞ"0 (ÿÿÿÿÿÿÿÿàù& 0È(`È(U@@ ê"Ð'ÿÿÿÿÿÿÿÿð' 0È(`È(V@@@(ÿÿÿÿÿÿÿÿPï' 0È(`È(W@@ð(ÿÿÿÿÿÿÿÿá' 0È(`È(X@@ (ÿÿÿÿÿÿÿÿÐï"€_#`Ë(Ë(Y"@`(Ðï"P(Ð!ÿÿÿÿÿÿÿÿ 7% é'Z@(ÿÿÿÿÿÿÿÿ é'À$&€ª)pÁ(\@°(ÿÿÿÿÿÿÿÿP( 0È(`È(]@@(`(ÿÿÿÿÿÿÿÿP( 0È(`È(^@@@ò"`(ÿÿÿÿÿÿÿÿ’&Þ*`Â(Â(ØÀ(ÿÿÿÿÿÿÿÿp“&*`Â(Â(`[,Ïp(ÿÿÿÿÿÿÿÿp“&*`Â(Â([,Ð (ÿÿÿÿÿÿÿÿ ”&ph*`Â(Â(à\,ÕÐ(ÿÿÿÿÿÿÿÿ ”&ph*`Â(Â(@],Ö€(ÿÿÿÿÿÿÿÿП&0i*`Â(Â(d,Û0(ÿÿÿÿÿÿÿÿП&ði*`Â(Â(`Ž,áà(ÿÿÿÿÿÿÿÿ’&J*`Â(Â(€Ü*Š(ÿÿÿÿÿÿÿÿЍ0Ú-º*}¦o ‹¨9üåžo —¨ º*s¤o ™¨9Ðúù¦o ¤¨ º*,¡o ¦¨9ðùé¤o ±¨º*ë¤o ’&°&,`Â(Â(\ð(ÿÿÿÿÿÿÿÿ’&p',`Â(Â(] (ÿÿÿÿÿÿÿÿ’&(,`Â(Â(^P(ÿÿÿÿÿÿÿÿ’&À(,`Â(Â(_(ÿÿÿÿÿÿÿÿ’&ð+,`Â(Â(k°(ÿÿÿÿÿÿÿÿ€õ"€b#,0þ+`"@€õ"`(°ä  ~&ÿÿÿÿÿÿÿÿÀ7%  Ä(ÐÄ(aÀø"°Ã(Ä(P¸'°&ÿÿÿÿÿÿÿÿ €Æ(@Á(b  Àë"ðÅ( Æ(@Ì'’&ÿÿÿÿÿÿÿÿ  Ä(ÐÄ(c`í"ÀÅ(Å(¹'`‘&ÿÿÿÿÿÿÿÿ €Æ(@Á(d  ï"pÇ(@Ç(àà'À’&ÿÿÿÿÿÿÿÿf@$(°ô"@Ä& Ÿ&ÿÿÿÿÿÿÿÿ ÷"Àd#p®)à­)g"@Љ& ÷"€!( å ÿÿÿÿÿÿÿÿàú#ÐÞ' 0È(`È(i@@J(0"(ÿÿÿÿÿÿÿÿ0û" `1,€Æ(@Á(j  0û"`.,à2,à"(ÿÿÿÿÿÿÿÿ& ¯&`Â(Â(l#(ÿÿÿÿÿÿÿÿÐ ( 0È(`È(m@@@$(ÿÿÿÿÿÿÿÿ&š'à,P,oð$(ÿÿÿÿÿÿÿÿÐ`"p Ð`" %(ÿÿÿÿÿÿÿÿ€;%à:% %(À·-W ðîd"ÿÿÿÿÿÿÿÿ f.P&( %(À·-X `ïd"ÿÿÿÿÿÿÿÿÀf.'( %(À·-Y Ðïd"ÿÿÿÿÿÿÿÿàf.@×'ðy,`Â(Â(q 0(`((ÿÿÿÿÿÿÿÿ@×'ðy,`Â(Â(r4( ý"`((ÿÿÿÿÿÿÿÿ°&ð )`Â(Â(oÀ)(ÿÿÿÿÿÿÿÿ°& †)`Â(Â(rp*(ÿÿÿÿÿÿÿÿ’&àh,`Â(Â(v +(ÿÿÿÿÿÿÿÿÀ¾&@l,`Â(Â(ƒÐ+(ÿÿÿÿÿÿÿÿ@×'@{,`Â(Â(sP1(€,(ÿÿÿÿÿÿÿÿ@×'@{,`Â(Â(tÀ4(pþ"€,(ÿÿÿÿÿÿÿÿ°Ä' 0È(`È(u@@à-(ÿÿÿÿÿÿÿÿ’&À|,`Â(Â(v2(.(ÿÿÿÿÿÿÿÿ’&À|,`Â(Â(wp5(@ÿ".(ÿÿÿÿÿÿÿÿ’&€"*`Â(Â(y 6(#€í&ÿÿÿÿÿÿÿÿ@×'ðy,`Â(Â(zà#)(`((ÿÿÿÿÿÿÿÿ@×'@{,`Â(Â({°#0-(€,(ÿÿÿÿÿÿÿÿ’&À|,`Â(Â(|€#@/(.(ÿÿÿÿÿÿÿÿ’&€"*`Â(Â(}P#ð/(€í&ÿÿÿÿÿÿÿÿpb"À|#p«)Á(~"@À#Ð6(`3(àÆ!ÿÿÿÿÿÿÿÿu%)( 0È(`È(@@4(ÿÿÿÿÿÿÿÿ0-( 0È(`È(€@@À4(ÿÿÿÿÿÿÿÿ@/( 0È(`È(@@p5(ÿÿÿÿÿÿÿÿð/( 0È(`È(‚@@ 6(ÿÿÿÿÿÿÿÿpb"À|#p«)Á(ƒ"@#`3(àÆ!ÿÿÿÿÿÿÿÿu%›& 0È(`È(…@@€7(ÿÿÿÿÿÿÿÿ Ÿ&0‚,`Â(Â(†08(ÿÿÿÿÿÿÿÿ’&p„,`Â(Â(‰H(à8(ÿÿÿÿÿÿÿÿ@$#`Ë(Ë(ê @Àª"ð 'ÿÿÿÿÿÿÿÿ@õ#À¾&°j*`Â(Â( Ô)é@:(ÿÿÿÿÿÿÿÿ’&`¢*`Â(Â(°’,íð:(ÿÿÿÿÿÿÿÿ’&`¢*`Â(Â(à’,î ;(ÿÿÿÿÿÿÿÿ Ÿ&0p,`Â(Â(P<(ÿÿÿÿÿÿÿÿ’&°‚*`Â(Â(Г,ò=(ÿÿÿÿÿÿÿÿ ”& °)`Â(Â(‘°=(ÿÿÿÿÿÿÿÿ’&ÐŒ*`Â(Â(À”,õ`>(ÿÿÿÿÿÿÿÿÐÀ& °)`Â(Â(”?(ÿÿÿÿÿÿÿÿ’&ÐŒ*`Â(Â(ð”,öÀ?(ÿÿÿÿÿÿÿÿ’&@‰*`Â(Â(à•,ùp@(ÿÿÿÿÿÿÿÿе& 0È(`È(˜@@ A(ÿÿÿÿÿÿÿÿ’&@‰*`Â(Â(–,úÐA(ÿÿÿÿÿÿÿÿе&©,`Â(Â(™€B(ÿÿÿÿÿÿÿÿ0·& 0È(`È(š@@0C(ÿÿÿÿÿÿÿÿ’&©,`Â(Â(›àC(ÿÿÿÿÿÿÿÿ’&…,`Â(Â(‹D(ÿÿÿÿÿÿÿÿàà'°†,`Â(Â(Œ@E(ÿÿÿÿÿÿÿÿàà'ˆ,`Â(Â(ŽðE(ÿÿÿÿÿÿÿÿ  Ä(ÐÄ(ï°¦"ÀÅ(Å(`‘&ÿÿÿÿÿÿÿÿ’&°‰,`Â(Â(PG(ÿÿÿÿÿÿÿÿ’&p„,`Â(Â(’à8(Ѓ*ÿÿÿÿÿÿÿÿ Ÿ&À‹,`Â(Â(•`I(°H(ÿÿÿÿÿÿÿÿ Ÿ&À‹,`Â(Â(–°H(Ѓ*ÿÿÿÿÿÿÿÿÐÞ' 0È(`È(™@ @0"(ÿÿÿÿÿÿÿÿ À& 0È(`È(š@ @ÐÀ&ÿÿÿÿÿÿÿÿ’& 0È(`È(›@ @€«&ÿÿÿÿÿÿÿÿ’&`¯,`Â(Â(œ L(ÿÿÿÿÿÿÿÿ@×'б,`Â(Â(žÐL(ÿÿÿÿÿÿÿÿpù%²,`Â(Â(Ÿ€M(ÿÿÿÿÿÿÿÿ°Ä'P³,`Â(Â( 0N(ÿÿÿÿÿÿÿÿ 0È(`È(ÿ@@ ¶"PÉ( É(н' ”&ÿÿÿÿÿÿÿÿ’& ‚*`Â(Â(—,ýO(ÿÿÿÿÿÿÿÿ’& €*`Â(Â(À—,@P(ÿÿÿÿÿÿÿÿ`&™,`Â(Â(¡ðP(ÿÿÿÿÿÿÿÿ’&‡*`Â(Â(P˜, Q(ÿÿÿÿÿÿÿÿ’&‡*`Â(Â(€˜,PR(ÿÿÿÿÿÿÿÿ’& a*`Â(Â(€¿, S(ÿÿÿÿÿÿÿÿ)&ð4)`Â(Â(¨°S(ÿÿÿÿÿÿÿÿ°Ä'p´,`Â(Â(¡`T(ÿÿÿÿÿÿÿÿ@c"L#`Ë(Ë(£"@€&Ðü"å'PÙ ÿÿÿÿÿÿÿÿ€_$ Ý"#`Ë(Ë(¤"@&ð#°å'Û ÿÿÿÿÿÿÿÿàJ$ð#0"( àõ-Žh >d"0È( @`È(ÿÿÿÿÿÿÿÿg.pV(0"( àõ-i p?d"0È( @`È(ÿÿÿÿÿÿÿÿ g.л"@K#0È(`È(" @¾"ÐW( Ó ÿÿÿÿÿÿÿÿàE$ W(0"( àõ-j P@d"0È( @`È(ÿÿÿÿÿÿÿÿ@g.’&P%*`Â(Â(¦@û&Ѓ*ÿÿÿÿÿÿÿÿ’&ð'*`Â(Â(¨à'Ѓ*ÿÿÿÿÿÿÿÿ’&@·,`Â(Â(©@[(Z(ÿÿÿÿÿÿÿÿ’&@·,`Â(Â(ªZ(Ѓ*ÿÿÿÿÿÿÿÿß ’& PÜMð£ d"€Æ( @Á(€Q-ÿÿÿÿÿÿÿÿÀi.€ß' 0È(`È(«@@àd( \(ÿÿÿÿÿÿÿÿ \( °)`Â(Â(¬P](ÿÿÿÿÿÿÿÿàÍ&¬,`Â(Â(¨^(ÿÿÿÿÿÿÿÿÀ¾&À¸,`Â(Â(®`_(°^(ÿÿÿÿÿÿÿÿÀ¾&À¸,`Â(Â(¯°^(Ѓ*ÿÿÿÿÿÿÿÿ Ÿ&à­,`Â(Â(¬`(ÿÿÿÿÿÿÿÿÀ¾&P(*`Â(Â(²'Ѓ*ÿÿÿÿÿÿÿÿ3 ’& PÜ`Ы d"€Æ( @Á(€Q-ÿÿÿÿÿÿÿÿj.’&à¹,`Â(Â(³Ð& b(ÿÿÿÿÿÿÿÿ €Æ(@Á(  `Æ"ðÅ( Æ(àÊ'’&ÿÿÿÿÿÿÿÿ 0È(`È(@@ É" Ç(ÐÇ( Í'p“&ÿÿÿÿÿÿÿÿ \(к,`Â(Â(·0d(ÿÿÿÿÿÿÿÿ€ß' 0È(`È(¸@ @ \(ÿÿÿÿÿÿÿÿ \(`»,`Â(Â(¹e(ÿÿÿÿÿÿÿÿ \(à¼,`Â(Â(¼ðf(@f(ÿÿÿÿÿÿÿÿ \(à¼,`Â(Â(½@f(Ѓ*ÿÿÿÿÿÿÿÿ Ÿ& 0È(`È(¾@ @ðÌ'П&ÿÿÿÿÿÿÿÿ \(p½,`Â(Â(¿i(Ph(ÿÿÿÿÿÿÿÿ \(p½,`Â(Â(ÀPh(Ѓ*ÿÿÿÿÿÿÿÿ \( -`Â(Â(Á`j(°i(ÿÿÿÿÿÿÿÿ \( -`Â(Â(°i(Ѓ*ÿÿÿÿÿÿÿÿÀ¾& 0È(`È(Ã@@€å%k(ÿÿÿÿÿÿÿÿ \(`-`Â(Â(Äpl(Àk(ÿÿÿÿÿÿÿÿ \(`-`Â(Â(ÅÀk(Ѓ*ÿÿÿÿÿÿÿÿ& 0È(`È(Æ@ @Ü'À¾&ÿÿÿÿÿÿÿÿ Ÿ&ð-`Â(Â(Ç€n(Ðm(ÿÿÿÿÿÿÿÿ Ÿ&ð-`Â(Â(ÈÐm(Ѓ*ÿÿÿÿÿÿÿÿ’&P-`Â(Â(Éào(0o(ÿÿÿÿÿÿÿÿ’&P-`Â(Â(Ê0o(Ѓ*ÿÿÿÿÿÿÿÿ Ÿ&p-`Â(Â(Ëv(p(ÿÿÿÿÿÿÿÿ’&€°,`Â(Â(²@q(ÿÿÿÿÿÿÿÿ’&`ë,`Â(Â(³ðq(ÿÿÿÿÿÿÿÿK ’& PÜ(p´ d"€Æ( @Á(€Q-ÿÿÿÿÿÿÿÿ@j. r(’& PÜ)qpµ d"€Æ( @Á(€Q-ÿÿÿÿÿÿÿÿ€j. ``Â(Â(à˜" v+ÐÊ(t(ÿÿÿÿÿÿÿÿ p`Ë(Ë(€€p|" ó(ðò(°t(ÿÿÿÿÿÿÿÿ Ð0È(`È(@@°ª)àª)`u(ÿÿÿÿÿÿÿÿ Ÿ&p-`Â(Â(Ìp(Ѓ*ÿÿÿÿÿÿÿÿ Ÿ&0 -`Â(Â(Ípw(Àv(ÿÿÿÿÿÿÿÿ Ÿ&0 -`Â(Â(ÎÀv(Ѓ*ÿÿÿÿÿÿÿÿ’& -`Â(Â(ðu*Ð x(ÿÿÿÿÿÿÿÿ’&à*`Â(Â(Ô`W'Ѓ*ÿÿÿÿÿÿÿÿ’&à*`Â(Â(`Ø*Õ€y(Ѓ*ÿÿÿÿÿÿÿÿ’& -`Â(Â(Ö0z(ÿÿÿÿÿÿÿÿ’& -`Â(Â(àÜ*×àz(ÿÿÿÿÿÿÿÿ’&0H*`Â(Â(Û #'Ѓ*ÿÿÿÿÿÿÿÿ Ÿ&€°À„* á      ?   A€ H   ‚(C J   E L   G€ ÐuÀ- X P„(I P  †(ð„*K P…*  …( aM€ T   †(O Ðu`†( Z Q W   S€ Y   Ј(U [   v ] à† °Š( _ Õ" x€  à†a Œ(   ‹(y c à†  ( z @Ž(Ы)à† «)Ž( e {€ à†g ( Ðu þ*ÐŽ(| °â*Ðu þ*à†i  ( k }  «)à†m @‘( o ~€ q à† °)@£&`’( ’(@£&’( ð’(@£&à†P“(@£&€“( h € u j € l  Àÿ* ¤&Д(‚ n  p ƒ   r „€  —(’&  °) \(—(… €+¦&  † w  ’&€‡€ ’&€ ð&€‡ L$ P™(ˆ ð&€ ð&€‰ ð&€ŸÐŒ&€`›(`ð&€OÀ›( Œ&€ Š€ ’&€Ð’&€àœ(`ð&€G@( ð&€€œ(‹ Œ&€Ð °) \(`ž(`\ Àž( Ð+Ð&&Œ ^   °)Ð&&€  °)Ð&& °)`.&b 0¡(k(`¡(Ðô'¡(’& °) \(t S$   À’&€ ÐÊ+P`Ë+± ¬ Э p£(`® У( ¯ °k)§ ° Рð¤(`ÐÐo)` q)`ÐÐ t) Ð@x) Ã à†à†9€´Ηo 9 `§( 9ð‘Ηo 9 º* 9€÷à†P¨( à†Ì 9P¹›o "º*¦9ð‘›o «90‰ @ (Ž    €   `ª(‘  ’  “€ c9€´Žo l9 Ø›o  °«(”  • ÐЬ(`­( –€ Э(` f¥9ð‘Žo k¥9 Ø›o À­( `­(ž а®(`à®( Ÿ   €    ¯(¡  ¢  £€  ð°(¤  ¥  ¦€ gÈ9P¹ño lÈÀÒè,º*Ø›o  ²(§  ¨ 0Ð`³(`³( ©€ Ð ´(`P´( ð³(ª Ðà´(`µ( «  ¬€  е(­ @   ½  ¿€   ·(À  Á à† Â€  p¸(à  Ä Ð`¹(`à†¹( Å€ ÐPº(`€º(  º(Æ ÐV  `×+ à† Ù+   Œ&€è!€!€!€!€A€A€A€ÐGÐGÐGÐG® ¿(k(0¿(Ðô' °) \(¯ À¿(ÐÀ& °) \(¼(¼(¼(¼( ½( ½( ½( ½(À¼(À¼(À¼(À¼(² àÀ(П&°o+pù%Œ&€ Œ&€Œ&€ Ž&€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿG €  p+pù% Ž&€ð&€Œ&€ð&€ð&€&€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿP&€P&€ÿ°&€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ&€°&€ÿðà+ ð&€ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð&€Œ&€ð&€ °)’&Œ&€`‘&€ÿÿ`‘&€’&€€ÿÿÿÿÿÿÿÿÿÿÿÿ’&€ÿÿÿàr+ \(ð&€ ð&€?» Œ&€À’&€ÿÿÿÿÀ’&€p“&€€ÿÿÿÿÿÿÿÿp“&€ÿÿÿÿÿÿÿ`t+ \(ð&€@Œ&€ð&€ðt+°Ä'Œ&€ ”&€ÿÿÿÿÿÿÿÿ ”&€Ð”&€€ÿÿÿÿÿÿÿÿД&€ÿÿÿÿÿÿÿ °)&µ pÊ( \( °)À&· t(€à ð&€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð&€€Œ&€ð&€ÿ Œ&€ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŒ&€ –+`è ê  °)ÐÀ&ì à&   &  Ã"   à†Ps( X 0ì+ð®&)  »(`PÏ( Ç -  ÐÐ(`@Ð( È€ ÐÐÐ(`Ñ(  Ð(É ÐÑ(`ÀÑ( Ê ÐPÒ(`€Ò( Ë€ ÐÓ(`@Ó( àÒ(Ì ÐÐÓ(`Ô( Í ÐÔ(`ÀÔ( Î€ ÐPÕ(`€Õ(  Õ(Ï 4  Ð@Ö(`pÖ( Ð Ð×(`0×( Ñ€ ÐÀ×(`ð×( ×(Ò Ð€Ø(`°Ø( Ó Ð@Ù(`pÙ( Ô€ ÐÚ(`0Ú( ÐÙ(Õ ÐÀÚ(`ðÚ( Ö  ×€  °Û(Ø   Ú€  "4.1.2 20080704 (Red Hat 4.1.2-48)" Ü(Û  Ü  Ý€  ðÝ(Þ  ß à†àÞ( á€ à†@÷+ð®& °)P& ú+ ô'î 0û+ò'ð&€8pß( @ß(ã à† á( å à†°á( ç€ à†@â( â(é à†Ðâ( ë à†`ã( í€ à†ðã( Àã(ï à†€ä( ñ  ò€  @å(ô  ö  ø€  `æ(ú  ý  ÿ€  €ç(    €   è(      €  Àé(     €  àê(    €  ì(    +€   í(,  -  .€  @î(/  0 Ð0ï(``ï( 1€ Ððï(` ð( Àï(2 à† `)`% @Ÿ)`Ðà†£) à†0ò( Pæ)`ò( °t(€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ°t(€Ðé'€€€f"€f" Pg" Ðm"  n"  °r" à–&€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿš  ¤  ð&€þ* d0Þ*Ðu`õ(ÐÀõ(`ðõ(  °)’&3 ÷(Ð&&Ð °)Д&àö(`Ð÷(Ð&&@÷(  °)ðþ%4€ Àø( +&P" Ð °) +&ø(`€ù(ðþ%ðø(  °)ðþ%ø(5 @ú(Ð&&Рú(Ð&&ú(` °)’&pú( `û( +&6  °) +&Ð ü( +&û(` °)’&ðû( àü( +&7€  °)€•&Рý(ðþ%ý(` °)€•&pý(  °)À’&°ü(8 Àþ(À’&Ð °)À’&ÐW, ‘(ð„*°ÿ(À’&9  °)À’&ð&€OÐ °)Ð&&)`0)`.&ð&€ p) )`.&:€  °)À¾&Ð °)à3&À)`à)Ð&&ð&€? )  °)4&`); Ð)4&Œ&€'Ð °)Ð&& )`)`§&)  °)Ð&&P)ð5&€Á&€ÿÿÿÐ °)€•& )`)@5&€)  °)`&=€  °)Ð&&ÐÐuÐþ* °)0ü% )`0)  °))&@)>  °)`.&Ð °) +& )`@ )Ð&& €)  °)Ð&&?  )`.&Ð °)`.&Ð )`À ) +&0 )  °) +&@€ € )ðþ%Ð °)ðþ%P )`@ )€•&° )  °)€•&ð )A  )€•&Ð],€•&Ð )`0 )  °)°&B  °)ðþ%Ð °)ðþ% )`€) Ä  C€  °)°&а_,°&p)`Ð) ) &)D  °) &Ð`a,0–&À)` )  °)à¡&E  °))&Ð °)Ð&&)` °))&p)  °) &F€  °) &Ð °) &)` °)ðþ%ð)  °)Ð&&0)G  °) & °) &p) & °)’&`",ð®&d º*9€÷ž(’& °)Ð&& $,àÍ&@æ*`À) H Í  Ѐ)`°) I€ Ð@)`p) )J и˜Dº*0ª-º*½˜Dº*Ø›o )``) K Ðð)` ) L€ а)`à) €)M Ðã›9` Žo é›9 Ø›o p)`Ð) N Ð`)`) O€ Ð )`P) ð)P €),àÍ&Ð)`@) Q ÐÐ)`) R€ Ð)`À) `)S ÐP )`€ ) T Ð!)`@!) U€ ÐÐ!)`")  !)V Ð")`À") W ÐP#)`€#) X€ á  Ð@$)`p$) à#)Y Ð%)`0%) @‚+˜ Z Ðð%)` &) [€ а&)`à&) €&)\ Ðp')`() & °)Д&`()Ð&& °) &À() & °)Ð&& )) &P)) & °)’&°)) & °)0T&  @*)À¨& °) & *)€«& °)’&+)0ü%0+)0ü% °)À¾& °)0T&À+) & °) & ,)0ü% °)0ü%€,) 1& °) 1&à,))& °))&@-)`& °)`& -) & °) & °) &0.)`& °)’&.)`&À.)`& °)’& /))& °)’&€/) 1& °)’&à/) 1& °) 1&@0)`.& °)`.& 0)ðþ% °)ðþ%1)0ü% °)0ü%`1))& °))& °)ÐÀ&ð1)À¾& °)0ü%P2)`&€2)À’& °)À’&à2)`&3)À’& °)À’&p3)`& °)0ü%@™, & °) &04)Ð&&`4)Ð&& °)Ð&& °)0ü% °)0ü% °) 1& °) 1& °))&°5)0ü%à5)0ü% °)’&@6) 1&p6) 1& °)’&Ð6))&7))& °)’&Œ+`07) à†¸)`© ÐÓ, à†€8) ¾) @9)`& °)`&À)Y Ð9)0ü% °)0ü%0:)`&`:)`& °)`&à"(€ °))& ;))&€;))&Ð °)`&à;) 1&ÀÄ, 1&@<) 1&p<) 1& °))&Ð<) &=) & °)0ü%`=)Ð&& °)0ü%ä ð=)0ü% °)’& °) +& °)Ð&& °)`&”"”" ¦&Д"Д" à>) ƒ&            î   l n p r t v x z | ~ € ‚ „ † ˆ Š Œ Ž  ’ ” ð&€ – ˜ š œ ž   ¢ ¤ ¦  ') ¨ ] ª Ð@ä, ^€ ÐI)`0I) ÐH)_ ÐÀI)`` ÐPJ)`$  €J) a€ Z ÐpK)` K) K)b Ð0L)``L) c n Ðä,`=,  M) d€ p 0l*`N) °M)e r ÐÐN)`O) f Ðg€ v Ð P)`PP) ÀO)h Ð`å, i z РQ)`ÐQ) j€ Ð`R)`R) 0R)k ~ ÐPS)`€S) m ÐT)`@T) o€ ‚ ÐU)`à†0U)  T)q ÐðU)`…  V) s † Ðå, u€ РW)`ÐW) pW)w Š `Àå,`ÀX) œ ž ¢ ¦ ª Â È Ê °G, Ò Ö Ú ò Ð`- {€ Ð \)`P\) ð[)} Ðà\)`])  Ѐ- € Ð0^)``^) ^)ƒ Ðð^)` _)  - ‡€ Ðà_)``) °_)‰ Ð- ‹ € Ð`a)`a) 0a) ÐÐ- ‘ ô  -`àb) “€ Ðpc)` c) @c)• Ð0d)``d)  — Ð e)`Pe) ™€ Ðàe)`f) °e)› Рf)`Ðf)  Ð`g)`g) Ÿ€ Ð h)`Ph) ðg)¡ ÐÒ* £    €    Þ) ÐÀj)`ðj) __builtin_init_dwarf_reg_size_table« ¥€ ± ² P¥( ³ © ´ µ €¥(`¶ 0m) · »€ ¸ й Pn)`º °n) Û ðm)¼ Ü ÐÝ Þ °¥( ß ½ à Ðá â à¥( ã ¾€ ä Ðå pr)`æ Ðr) ç r)¿ è é @¦(`ê ë À ì í  ¦(`î @u) ï Á€ ð Ðñ `v)`ò Àv) ó v) ô Ðõ àw)`ö ÷ ø ù 0§( ú Ä€   à†  ðy)   y)Å  à† {)  Æ  ë)   Ç€  à†  })  À|)È  à† @~)  É    Ê€   à†"  €) $ À)Ë & ( °¨( * , Ð. ‚)`0 `‚) 2 Í€ 4 Ð6 €ƒ)`8 àƒ) :  ƒ)Î < Ð> …)`@ B D @)°&K   `…) Ï Ї)`@‡) Ð€ ÐЇ)`ˆ)  ‡)Ñ Ðˆ)`Àˆ) Ò ÐP‰)`€‰) Ó€ Њ)`@Š) à‰)Ô ÐЊ)`‹) Õ Ћ)`À‹) Ö€ ÐPŒ)`€Œ)  Œ)× Ð)`@) Ø ÐÐ)`Ž) Ù€ ÐŽ)`ÀŽ) `Ž)Ú ÐP)`€) û Ð)`@) ü€ ÐÐ)`‘)  )ý Б)`À‘) u  þ à†€’) ÿ€ à†“) à’) à† “)  à†`”) € à†ð”) À”) à†€•)  à†–) € à† –) ÷)`ð&€€Ðð&€À %(P&(€û) ^  p–)  °ð(  Й)`@™) € ÐЙ)`š)  ™)  К)`Àš)   ÐP›)`€›) € М)`@œ) à›) ÐМ)`) Ðñ( !€ Ðð)` ž) À)# аž)`àž) Ðpñ( '€ ÐП)` )  Ÿ))  ñ(` ) + Ð ¡)`P¡) -€ Ðà¡)`¢) °¡)/ Р¢)`Т) 1 Ð`£)`3€ Ðð£)` ¤) À£)5 а¤)`$ à¤) 7 9€ à†Ð¥)  ¥); à†`¦) ° = àd" °e"  h"  h" ðh" ðh" Ài" `k" 0l"  n" po" @p" q" `x" p|" Ðé'€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿà–&€ð&€ÿÿÿÿÿÿÿÿð&€—&€€ÿÿÿÿÿÿÿÿ—&€ÿÿÿÿÿÿÿ0r'€øÿÿÿÿÿÿÿ0r'€ÿÿÿÿÿÿÿÿð&€’&€’&€’&€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ`¬)П&€ð&€_Œ&€ ð&€¿Œ&€ð&€ð&€HŒ&€/Œ&€ð&€â ð&€À a" __pointer_to_member_type_info_pseudo°" €€"  ‚" ð‚" Àƒ" „"  Ÿ&Œ&€ÈŒ&€Éð&€ÉŒ&€$€Á&€€ÿÿÿÿÿÿÿÿÿÿÿÿ0g'€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ`’"`’" 0“"  °)p“& °)Д& °)@£& °) ¤& °)¦& °)0¬& °)à¬& °)­& °)0¬& °)à¬& °)­&”  ,`à†@´) ?€ à†д)  ´)A à†`µ) C à†ðµ) E€ à†€¶) "& P¶)G °"& 7) I î Ðð À7) K€ Ð7  À¸)` ¹) ó ¸)M õ  8)`º) ÷ O `…" л)`À»)ð„*0») P…*Q€ `») aÐà¼)$&P¼)`ÐÀ&°¼) Ðu ¼)ð»)S ù Ðн)``¾)ð„* «)U 0¾) aЀ¿)$&ð¾)`à¿)ÐÀ&P¿)  °)`²&W€ ÐuÀ¾)Ðû pÀ)`ÐÀ) ü Ы `Á)`ÀÁ) ¬ [ 0†" P;)`‡" °Â) Ї" \€ ÐŒ&€ Ã)`Ä) @Š" pÃ)] ‹" Ðà‹" ðÄ)`PÅ) ð&€/^ Ѐ" Æ)`PŽ" pÆ) _€ Œ&€ÐŒ&€D`Ç)`ð&€ ÀÇ) Œ&€gÇ)` ð&€àÐð&€àÈ)`@É) ð" a À" Ð0Í&€É!0Í&0Ê)`Œ&€4Ê) Œ&€Rb€ ð&€RÐð&€Ï°Ë)`Ì) Œ&€Yð&€ÿð&€øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŒ&€_ä F H p‰" J L @Ï& N P ðÏ& R T  Ð& V k l m o q s t u c  w x y { | }  €  ƒ „ ‡ ˆ ‰ P›  Ÿ   ¡ £ ¤ ¥ § ¨ © » ¾ À Ä Æ Ì Î Ð Ô Ø ë ì í ï ð ñ 0Ò*ó ô  0¢*PË)c ЀÚ)`°Ú) d Ð@Û)`pÛ) e€ Ðü Ü)``Ü) ÐÛ)f ÐðÜ)` Ý) g Ð °Ý)`h€ Ð pÞ)`ÐÞ) @Þ)i Ð  `ß)`Àß) j Ð Pà)`°à)  ‹€ Ð pá)`Ðá) @á)Œ Ð `â)`Àâ)  Ð Pã)`°ã) Ž€ Ð @ä)` ä)   ä) Ð" `å)`Àå)  Ð&  °)’&( ‘€ Ð* @ç)` ç) , ç)’ . ¦(`è) 0 “ Ð2 Pé)`°é) ”€ Ð6 @ê)` ê) ê)• ÐK 0ë)`– ÐM ðë)`Pì) —€ ÐO àì)`@í) P °ì)˜ Q R S T U V W Y Z [ \ ] ^ _ a b  °)ð®&c d e f g h i j Š Œ  Ž   ‘ ’ “ • – — ˜ ™   °) ”&à† °)ÐÀ& °)ÐÀ&à† °)’&à†ÐÐö)`÷) ™ З) š€  °) µ&ÐPø)`€ø) ð÷)¹ `—)`ù) ¼ Ù ÐÐù)`ú) ¿€ Ðú)`Àú) `ú)Á ÐPû)`à `àû) Å€ Ø € ` ü) @ü)Ç `0ý) É  Ë€   °)¦&ðý)Í  Ï  Ñ€  @ÿ)Ó Õ `P* ×€ `À* *Ù `P* Û PX) Ü€ `p* @*Ý `* Þ P ß€  ð*à  á  â€    *ã   å€  0*æ  ç P è€  €*é  ê `p* û€ ` * Ð*ý ` * ÿ P €  € *   P €  Ð *     `PÀ *  € `€ * P * `*   €  Ð*   `À* € `P*  *9 `õ ö ÷ ø ù ú þ   PÑ&  °Ò&   `Ó&  Ô& ÀÔ&  pÕ&  ÐÖ&  0Ø&  °)ð®&­ °æ)@Ú&®  °)@Ú&¯ °*ÐÀ& °)’&° 4 ± 8 ² L ³ N ´ À* º&ð*-& °)П&µ €*P°& °)П&¶ X · p*P°& *°& °)П&¸ º ½ `    *ð®&P*ð®&€*ð®&°*ð®&à*ð®&*ð®&@*ð®& °)ð®&! Ð*àÍ&*ð®& °)ð®&# % À*’&ð*P°& *°& °)P & °)À’&'  °) ”&@ *àÍ& °)’& °)’& °)À’&)  °)p“&+ -  °)Д&/  °)€•& "*°&P"*-&°"*-& °)П& °)-& °)@£&1  °) ¤&Ð#*°& °)¦& °)П& °)@£& °) ¤& °)¦& °)@£& °) ¤& °)¦& °)П& °)ÐÀ& °)П& °)`²& °)’& °)ÐÀ& °)ÐÀ& °)ÐÀ& °)П& °)À’& °)ðÄ& °)Pš&pö)П&À'*À¾& °)ÐÀ& (*ÐÀ& °)ÐÀ&€(*ÐÀ& °)ÐÀ&à(*ÐÀ& °)ÐÀ&@)*ÐÀ& °)’& )*ÐÀ& °) ”&**ÐÀ& °) µ& ø)’&**p“& °)П&ð**`²& °)`²&P+*p“& °)p“&°+*П& °)ÐÀ&,*П& °) ”&p,*@£& °)@£&Ð,* ¤& °) ¤&Pþ)¦&`-*@£& °)`§&À-* ¤& °)À¨& .*¦& °) ª&€.*@£& °)¦&à.* ¤& °)¦&@/*@£& °)’& /* ¤& °)’&2*¦&°@*PÆ&3*¦& Ð8* ”&  `>*ðÄ&PC*П&ð&€`ÀH*ÐÀ&  °)’&p2*@£& °)€«&à* 03* ¤&;  °)€«&` °)€«&`3* P4*’&=€  °)@£&`v 5*’& °) ¤&€4* Ð5*’& 4*>  °)¦&``6*@£& °)p“&6*  7* ¤&?  °)p“&°7*¦&  °)p“&@€ @8*ÐÀ& °)`²& à7*A  °) ”&`9*0¬&  °)0¬&B  :*à¬&` °)à¬&Pà:*­&ð9*  °)­&C€  ;*П&` °)П&0<*ÐÀ&p;*  °) Å&;*D ð<*à¡&°O*’& °)’&€=*ðÄ&ð0*  °)P&E à °)`‘&PÐ>*ðÄ&à=*  °)À’&F€ ?*ðÄ&à °) ”& @*ðÄ&`?*  °)à–&?*G à °)PÆ&@A*À¾&€@*  A*ÐÀ&H  °) ”&à`B*ÐÀ&PÀB*ÐÀ&ÐA*  °) ”&I€ à€C*à¡& °) ”& C* @D*à¡&ðB*J  D*à¡&à °) ”&0E*П&pD* E*’&k  °) ”&`€F*П& PàF*’&ÀE*  °)’&l€  G*à¡&`ÐG*П& °) ”&pG* °1*À¾&G*m ` °)`²&PI*ÐÀ&H* °I*ÐÀ&o  °)`²&`pJ* µ&PÐJ*ÐÀ&àI*  °)`²&q€ K*ÐÀ&`ðK*ÐÀ&Ð °)’&`K* °L*@£&K*s M*@£&` °)@£&`Ü, ÐM* ¤&àL* ÐY* ¤&u  ˆ 3 ðN* ' O*àÍ&PO*’&€O*’&À<*’&àO*’&P*’& °)’& °)’&5 7 : < n p r  °)Ò&t  °)àÍ&°R*àÍ&¬ àR*’&S*’&@S*’& °)’&x z ¯  °)àÍ&| ~ € ‚ „ † ‰ ‹  °)àÍ&  @P*À¾&£  °)À¾&¦  °) \(© `W*ð®& °)’&ÀW*àÍ& °)’&² µ Z*°&¸ àX*¸& °)’&»  °)¸&¾ Á  °) ¤&`Z*°&Z*¦&ÀZ*°&ðZ*¦& °)°& °)¦&Ä °[*@£&à[*°&\*@£&@\*°& °)€«& °)°&Ð\* ¤&Ç 0]* ¤&É  °)€«&]*¦&ð]*¦&Ê  °)€«&€^*@£&Î p_*`§&à^* ¤&_*À¨& °)À¨& _*¦& °)`§&Ð_* ª& °) ª&0`*П&``*П& °)П&À`*ÐÀ&ð`* Å& °) Å&Pa*’&€a*ÐÀ& °)`²&Ài*P&b*ðÄ&@b*`‘& °)`‘& b*ðÄ&Ðb*À’& °)À’&0c* ”& °) ”&c*ðÄ&Àc*à–& °)à–&€j*ðÄ& °)P&€d*ðÄ&°d*`‘& °)`‘&°a*ðÄ&@e*ðÄ&r*À’& e*ðÄ&Ðe* ”& °) ”&0f*ðÄ&`f*à–& °)à–&Pv*П&ðf*à¡& g* ”&Pg* ”& °) µ&°g*À¾&h* ”&c*ðÄ&@h*ÐÀ& °)`²& h*À¾&Ðh* ”&i*ÐÀ& °)à¡&`i*П&i*à¡&€s* ”& °)P& j*П&@t*’& °) ”& d*P&°v*À¾&w€  àj*y  { `Ðk* Ð}€ `l* `l* ` m*   ƒ€  àm*…  ‡ `PÐn* ›€ `o* `o* ` p* Ÿ `°p* ¢€ `@q* q*¥ `Ðq* ¨ ` °)À’&`r* `ðr* І*®  °) ”&‡* ± `Pj* ”&´€ ` t* pt*· `0u* f*Ð'0¢*Àu*P¨*½€  °)À’& v*À àv*ÐÀ&@w* ”&à  °) ”&À‡*’&š x*’& °)’&œ x*°&Àx*°&ðx*°& °)°&ž €y*&°y*&ày*&z*&@z*&pz*& z*& °)&¡ 0{* & °)’&¤  °)’&§  |*Ð&& °)’&ª °|*)& °)’&­ @}* 1& °)’& }* +& °)’&³ 0~*ðþ% °)’&¶ À~* 1&ð~*°& °)’&¹ ÐÀ&°*°& °)’&€*À¾&ÐÀ&p€*ÐÀ&ÐÀ&Ѐ*’&ÐÀ&0*À¾&`* ”&ÐÀ&À*À¾&ð* ”&ÐÀ&P‚* µ&€‚*’&ÐÀ&à‚*À¾&ƒ*’&@ƒ* ”&ÐÀ&¤*’&à˜"à˜" `¥*€['°™"  °) ”&P›" Ы)’&€ p'’&€P…*’&€È ðœ"€ ð&€@Œ&€'Œ&€(«€ `t* º pw* µ&ð‡*ÐÀ& °)`²&Æ€ °ˆ*П& ˆ*Ë ÀÃ*À’&Ì P ‰*À¾&Í€ Š*’&p‰*Ï `Š* ”&Ñ ÀŠ*ÐÀ&Ó€  °)`²&Š*Õ Ë*p“&× PÙ€ @Œ*p“&°‹*Û Î*PÆ&Ý ß€ 0*À¾& Œ*á À* ”&ã `¨*PŽ*’&*P¨*å€ €Ž* ”&àŽ*ÐÀ& Ž*ç  °)`²&{*`&ü *p“&Pþ€ `*p“&Ð* À*p“& ®*p“&€ ð*  °)PÆ& @’*Ð'à *à‘*PÀ„* ’*П& € “*À’&p’*  0“*p“&°*p“&° € ð“*Ð'P”*П&“* °”*À’& @•*p“&€ à”* Е*p“& -€ `´*p“& •*0 3 P5€ `²&–*7 à¡&°…*9 ’&€€* +&°—*И* µ&’&€p˜*ÐÀ&€¦*Ы)¨*Ы)€¦*ð„*¼ €…*ð„*€¦*P…*p“&€P—*P…*àg'€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€¦*°—*0g'€ ˜*°—* •"  p›*à†àg'€ÿp›*`h'€€ÿÿÿÿÿÿÿÿÿÿÿÿp›*0p›*àj" p›*°Ph'€ÿÿÿPÀ„*@i'€€ÿÿÿÿÿÿÿÿp›*°À„*m" p›*Pp›*PÀ„*@i'€ÿÿÿÿÿÿÿp›*P¨*p›*P€…* j'€ÿÿp›*PP—*p–" @ž*à†@—" @ž*à™*àq" €*P *0™* j'€`™*ð&€?ÀÉ*@¡*О*@¡*˜" À™*ð¢*À¾&À„'€Ðž*0¢*pƒ* ”&À„'€PÊ*Ò*Ÿ*Ò* u" Pš* ¤* ”&PÊ*à£*Ÿ*à£*ÐÀ&PÄ*`Ÿ*Ф*`Ÿ*0Ò*`„*П&°š* Í*¥*›*€š"  Í*ð¥* «)™*@´  €*°¦*0™*@ œ" `™*@ÀÉ* §*ð„*О* §*À™*@ÀÉ*`¨*¿ О*`¨*ð™* Ÿ* ©*Pš* Å Ÿ*°©*О*p¨*   €  Ъ*!  "  Pˆ*Ð'¼   àGàGàGàGB  |   H  K   ,` P‘*PÆ&#€  0®*$   %  &€  €¯*'  °)p“& (  )€  а**  Ð Ò ì€  ð±*í  Ö   ï€  @³*ð Ú  °)’&Ü  °)p“&ò€  ´*ó à ô  õ€  °µ*ö  æ ж*’& °)’&è ø€ Ð`·*`·* 0·*ù P¸*’&€¸*@Ú& °)’&ê ¹*’&@¹*’& °)@Ú&û€ Р¹*`й* p¹*ý  Àº*’&ðº*’& °)ÐÀ&  €»*’&@ò*’&€ Ðà»*`¼* °»* м*’&½*’&0½*’& °)’&" €  ½*  P¾*àÍ&€¾*’& °)’&$ % @¿*’&p¿*’& ¿*À¾& °)’&& 0À*’&`À*’& °)À¾&ÀÀ*’&ðÀ*’&Ô*ð®&d  Ðu  - `-k(`ù*  € Ð@Â*`pÂ* Â* ÐÃ*`0Ã*   °)À’& € €¦*°…*  Ä* ˜*°…*  €  pÅ*, Р 2€  Æ*4  6 œ*ÐаÇ*`àÇ* Ð@È*`pÈ* à+: ÐÉ*`0É* < P¨* >€ P€…*  Ê*@  à‹*p“&B   @+F  H  J€  Ì*L p›*P˜* N аÍ*` °)PÆ&@ž*`àÍ* O€ Ð +  Î*P Ð`Ï*`Ï* Q €*à *ÐPÐ*`€Ð* R€ ÐÑ*`@Ñ* àÐ*S T ð™*àÄ*€*@§*àh)`;€ ÀÒ*= ? @§*PÓ*PÀ„*A€ °Ó*C  °)’&E ( à£*0Õ*’& Ô*P€…* °)’& ) G€ àB+’&€Ö*¸&  °)’&ÀÕ*I * @×*’& ×*’&  °)¸&K + 0¢*0Ø*P¨* M€ .  ÀØ*^ 1  _ `¨*Ú*P¨*n  `€ o  ÐÚ*a p  PÜ*’&b °Ü*’&@¡*ÐÀ&€Ü*P¨*q c€ @Ý*d r e  §*Þ*P¨*f€ ÀÞ*àÍ&ðÞ*’&Pß*’&`Þ*g €ß*@Ú& °)’&t P *pà*’&àß*PÀ„*Ðà*’&i€  °)@Ú&u á*àÍ& à*j ðJ+’& °)ð®&k v °¦*àâ*àÍ&Pâ*PÀ„*@ã*’&l€ ð×+’& °)’&ã*m w 0ä*àÍ&`ä*’&ä*’& °)ÐÀ&x  å*àÍ&På*’&€å*’&°å*’&ÀS+P°& °)P &y ÐÔ ¶+ â ä @v+`Ð(+’& °)ð®&U€ é Ð è*` ¸*’&Pè* Àç*V `w+`ð&€(ç'€é* Àw+  Ð!,`Ð0ê* X€ `ê*`Ð ë*`Àê*Y аë*` àë* Z 0í*’&à†Ðì* Àí*’&[€ à†Pî*ÐÀ&í* `í*\  °)’&à†€î* ] à†02+ |€ ÿ à†Ðï* Ðpï*~ à†0ð*` ¢" p£" Àð* @¤" ¥" € ð&€Ðò*’&Ð…+ àñ*‚ `ó*P°&€§" P¨" Àó*°&`¬"  °)P &0­" „€ ! à†€ô* ð‰+` ô*… @±" àô* ²" à²" °³" €´"  ‡€ à†Àö* ö*ˆ `¹" 0º" »" # л" Š€   à† ø* @ø*‹ @¾" à“+`¿" à¿" °À" €Á" PÂ" €  2,`°ú* €ú*Ž 0Ç" È" ÐÈ"  É" pÊ" p½" @Ë" N '   R V ÀÉ*0¢* @þ*ð„* «)Ðu`õ(à( d ÿ( d +ÐuÐþ*s   °) ¤&ÿ* ¤&`•( ¤&þ  °)¦&P¥+¦&pž*pÀ„* ` f 0)À¾&`)Ð&& °)Ð&&Pö(Ð&& š+ ÐÀ¹+ € Ðð+` + À+‘ Ðp»+ ’  “€  p+”  •   ¾+— °À+À¾&™€  °+’& °)À¾& @+àÍ&0Å+’&œ€ Р+`Ð+ p+ +’&À+’&ð+¸& °)’&À ¯€  P +°  °)¸&Á °Ì+àÍ&²€  p +³  ´  µ€   +¶ · ÐP +`Ä ¸€ à†Ð@ +`p + à +¹ Å  Í+`0+ º  »€  ð+¼  ½ Ç Î€  +Ñ È +àÍ&0+’&+’&ž ÐÀ&Ò*Ê À+P€…* Ÿ€ Ë  €+   @¡*p+P¨* ¢€  +£  ¤  §*ð+P¨* ¥€  €+¦  § `p+ ¨€ `+ Ð+© `+ ª `«€ `€+ P+¬ `+  à† + Ï€ à†0+ +Ò @â+ Õ ` + ×€ `°+ €+Ù `@+ Û `Ð+ Ý€ ``+ 0+ß `ð+ á ðé+ ã€ 8€  D€  )  ë ÐÎ*` Ø Р +`ñ ð +  Ð°!+`à!+  Þ à† "+ °+å à†0#+ ç `À#+ é€ `P$+  $+ë ÷ `%+ í ` %+ ï€ `0&+ &+ð 0ç* `ð&+ ñ `€'+ ò€ `(+ à'+ó `ç*’& (+ ô ``)+ õ€ `ð)+ À)+ö `€*+ ÷ `++ ø€ ` ++ p++ù ú ``,+ ú `ð,+ û€ `€-+ P-+ü ðê* `@.+ ý à†Ð.+ þ€ à†`/+ 0/+ÿ à†ð/+  à†€0+ € à†1+ à0+ à† 1+   +```2+  € `ð2+ Ô À2+   `Ö€  4+Ø  Ú Ð5+`05+ Ü€ ÐÀ5+`ð5+ 5+Þ ð-`€6+ à Ð7+`@7+ â€ ÐÐ7+`8+  7+ä Ð8+`À8+ æ  è€  €9+ê ì  î€  p:+    €  ;+     €  °<+    €   =+    €  À>+   €  °?+  !  "€  Ð@+#  %  &€  ðA+'  (  Ö*’&à†Ì Í ÐC+’& °)’&Ð `D+ÐÀ&D+ \( °) \(Ó  E+’&PE+’&€E+’& °)’&3 4 5 s 6 7 8 9 : ; ÀG+ ' °)àÍ&h < à*àÍ&= àH+-& °)-&> pI+àÍ& °)ð®&? J+àÍ&0J+’&`J+’&J+’&ÀJ+’& K+’&Àá*’& °)’&@ B D L+àÍ& °) \(i l o r x { ~  N+’& )€  °) ²' à3+  ðM+*   „  `,  O+ ‡  € -€ `Š  ðP+ ÀP+. P+   `/ pR+    0€ àå*°&`‘  ðS+ €  `2 U+ à†°T+  U+ `S€ 0V+ à† ÀV+ ``V+T PW+ à†€ àW+ `U pX+ à†X+ Y+ `V€ Y+ à†  `ÀY+W €Z+ à†A€ [+ `X  [+ à†@[+C 0\+ `Y€ À\+ à†E P]+ `ð\+Z à]+ à†F€ p^+ `[ _+   ^+G \€ ` `+ ð_+] H  `^ a+  I€ _€ ` 0b+ b+` Ða+J  `a Pc+  K b€ ` pd+ @d+c L€  `e e+ 0e+M `Î( `g€ €f+ à†N g+ `°f+j  g+ à†O€ 0h+ `m Àh+ à†`h+P Pi+ `p€ ài+ à†Q pj+ `j+s k+ à†R€ `v ðk+ à†Àk+d €l+ `y€ m+ à†f `n+ A€àGàGàGàGÐGÐGÐGÐGàGàGàGàGÐGÐGÐGÐGàGàGàGàGP½(P½(P½(P½(ào+pù% °) \(³ Â(P &ð&€øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐp+pù% °) \(î ¶ q+ \(0Å(p“&Œ&€þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸  °) \(¹ º ð&€àÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿs+Ä' °)’&Œ&€üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ °) \(¼ t+ \( °)€&¾  °)@&ÀÈ( \(Œ&€øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ °)’&±  °) \(´ àÉ( \(€•&€ÿÿÿÿÿÿÿÿ€•&€Ð0–&€€t(€t(€ÿä æ ÐÐw+`h€ ` x+ ðw+k W `n `@y+ q€ `Ðy+  y+t ``z+ w `ðz+ Pë* `€{+ @´,} ` |+ € `Ð|+ ƒ€ ``}+ 0}+† ¸, ‰ `P~+ Œ€ `à~+ °~+ `Ðp+ “ `”€ `€+ `€+• `ï*  + – 0à+ —€ 0p‚+ 0Ђ+ ™ à†`ƒ+ š€ € à† „+ à†Àƒ+› à†€„+ à„+ œ àà† …+ ž€ à`†+ 0†+Ÿ àà†ð†+    ‡+ ¡ ¢ ƒ  m+ à†@m+| ¾, à† Ю" Љ+` Š+ Ю" ‚€ ÐàŠ+`‹+ °Š+… Р‹+`-, Ћ+ ’ Ð ¶ ‹€ 0Ä, Ð€+`°+ Pµ"  +Ž Ð ¶" ¼ ðÇ, ð¶" ¾ Ð+`à†À ¸" ¤€ ð+ Ðà+`‘+ €+¥ à†ÐÆ  ‘+ ÀÍ, ¦ à†È §€ `u(€à†€“+ Ð “+¨ Î Ò, à†Ð Ò Ô ª€ Œ à†À•+ Ð`•+« Ø Ú Ü €Ì( Þ à ­€ à†З+ ðÃ"  —+® à†ÀÄ" â ¯ Å" à†€™+ `Æ" °€ à†@š+ 04,`š+± à†æ è ê ì Ñ€ à† œ+ ð›+Ó à†ð ñ ò #  0ë' 0ë'ÐGH º*€  ´€ à`ž+ 0ž+µ à· ¹ à†€Ÿ+ » à† + ½ à†  + ¿ à†Á à†¡+ Ã à† ¢+ Å à†°¢+ Ç à†@£+ à† £+ Ë p¨*0¤+P¨* Í€  À¤+Ï P+¦& ô p¨*à¥+P¨* ö€  p¦+ø ú ü þ 0§+     °  €  °¨+       €  Щ+     Õ à† ðª+ ×€ à†°«+ €«+Ù à†@¬+ Û  Ý€  ­+ß   ã€  ð­+å  ç  é€  ¯+ë  í  ï€  0°+ó  õ  ÷€  P±+ù  û  ý€  p²+ÿ    €  `³+       €  €´+       €   µ+     à†  à†ð¶+   à†€·+     €  @¸+       €  `+``¹+     Ì" àÌ" °Í" €Î" PÏ" °+` Ð" ðÐ" ÀÑ" Ò" `Ó" 0Ô" ÐÕ" `u(€`u(€ð&€'z Ù" @c" –€ PÜ"  Ý" { `¿+àÍ&ß" `à" °Œ,’&ð¿+PYÅ+`M$ €À+ÀYÅ+  N$ Á+0Z Æ+ °)’&àO$  Á+ Z€Æ+}  Q$ 0Â+€[Ç+ +š ÀQ$ Â+`\ Ç+€+’& Ã+Ð\È+› @T$ °Ã+@]È+ЀU$ pÄ+ ^ É+’&€ ÀV$ @, p_°É+ç'€Àç'€ç'€ÀÅ+’&À’&€ç'€PÆ+ð®&À’&€ç'€ °)’&ç'€¿ À’&€ç'€`+àÍ&À’&€ç'€À’&€ç'€´) À’&€ç'€® À’&€ç'€ À’&€ ç'€ 0á" X$  Ê+àÍ&@Y$ 0Ë+’&0aÀË+Àç'€à +’&ð&€@Àç'€Àç'€â"  Ðâ"  ã" àÌ+’& °)’& à € + Ð__builtin_aggregate_incoming_addressÆ   €  `Î+  1   3 €  PÏ+5   6  8 €  ì  @Ð+9  ¡ :   ; €  Ñ+<   =  0³( > € 0àÒ+ °Ò+?  0pÓ+ à†ÐÓ+ A  ¸( B  C  À¹( T € à†PÕ+  Õ+U  à†àÕ+ à†@Ö+ W € à†ÐÖ+  Ö+X  à†Y  à†pã*ÐÀ&À×+ Z € à†€Ø+ PØ+[   »( \  ð&€€à†] € à†Ú+ ÐÙ+^  à†Ú+ _  ` €   Û+a  b   c   € e   @Ü+   +      €  ÀÝ+!   "   D €  àÞ+E   F  ­   ÐÁ(H   I  à†J  à†Pá+ K  à†àá+ à†L   M €  Ðâ+N   O   P €  ðã+Q   R  S €  àä+d   f   h €  æ+j  l   n €  ðæ+p   r   t €  è+v   x   z €  0é+|   à†~  € €  Pê+‚   „   … €  pë+†  %   °)àë'&  Àì+P°&ðì+°& í+П& °)àë''  (  àí+àÍ&î+ÐÀ& °)`²&*  +  ,  ï+àÍ&0ï+@Ú& °)’&ï+àÍ& °)@Ú&.  / /  €ð+àÍ&°ð+ÐÀ& °)’&0  @ñ+àÍ& °)ÐÀ&2  ‡  ‰  0ò+àÍ&`ò+ º&ò+-& °)П&‹   ó+àÍ&Pó+P°& °)П&    ô+àÍ&@ô+P°&pô+°& °)П&‘  õ+àÍ& °)ð®&“  pä" ðõ+°ð'•  €ö+P»&°ö+àÍ& àö+Àò' ß(ð®&÷+ò'p÷+ ô' ÷+ð®&Ð÷+Ðô'0",ð®&ø+’& °)’&@å" Ðß(°ð'æ"  °)°ð'àæ"  °)°ð'°ç" °ù+°ð'àù+P»&ú+П&@ú+ò'pú+Àò'à(ò' °)Ðô'€è" `à(П&`û+ò'û+pó' °)pó'Pé"  ü+ÐÀ&Pü+À( °)Ðô'°Ú" àü+Pš& °)ÐÀ&ÀÞ"  ê" Œ&€0Œ&€@Œ&€8ð&€`Œ&€HŒ&€Pð&€ Œ&€ Œ&€LŒ&€TŒ&€XŒ&€`Œ&€hð&€hð&€Œ&€oð&€0ð&€Àð&€ð&€@ð&€€ð&€Pð&€ ð&€Àð&€ð&€ÿŒ&€Œ&€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŒ&€?ð&€ Ðï" `u(€`u(€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð&€__attribute_warn_unused_result__pÀ„*,PÀ„* g €  ,i   k  à†€, m € à†, à,o  à† , q  s  à†`, u € à†ð, À,w  à†€, y  à† , { € à†  , p ,}  à†0 ,   à†À ,  € à†P ,  ,ƒ  à†à , ¥  à†p , § € à† , Ð ,©  Ðñ( «  à†ð , ­ € à†€, P,¯  à†, ±  à† , ³ € à†0, ,µ  à†À, ·  à†P, ¹ € à†à, °,»  à† p, ˆ  ½  Ð`,`, Š  Ð ,`P, Œ  Ðà,`, Ž    €  Ð,’   ”   – €  ð,˜    œ €  à,ž      ÐÐ,`, Ð`,`, ¦  Ð ,`P, ¨   ª €  ,¬   ®   ° €  0,²    ¶ €   ,¸   º  Ð,`@, Ð ,`Ð, ¾  Ð`,`, À  Р­*   а ,`à , Ð@!,`p!, Ð9ð‘Ηo 9  )ð®&",ð®& °)ð®&—   #,àÍ&P#,’&€#,P°&°#,°& °)P &™  ›    Ÿ  Ð$,°& °)П&¡   °)àÍ&¢  #Dº*›o (Dº*£  Ç  É  Ë   5+ Óè,º*›o !5, àè,º*Ø›o à&,àÍ&',À¾& °)’&Ï   ',àÍ& °)À¾&Ñ  0(,àÍ&`(,ð®& °)’&Ó  ð(,àÍ& ),¸& °)’&Õ   °)¸&×  Ù  f¦9ð‘Žo k¦9 Ø›o Û  è§9€´Žo ñ§9 Ø›o Ý  d¨9ð‘Žo i¨9 Ø›o ß  ã  å  ú  ý   ,,àÍ&ÐÀ&  à¥" °¦"  ©" à†† ‰ @ò" ó" ð&€ð&€Hà"(€Œ&€Oð÷" `u(€Àø" Àë" `í" ï" pñ" °ô"  ÷" ð&€ð&€ßŒ&€0û" 9% À1,`Å@3, 9% P2,@Æ:)@:% а2, Çp3,à:% È 3,à"(€ð&€Àà"(€à"(€à"(€ ”&€ ”&€Ð ”&€< ”&€ ”&€ ”&€ ”&€`u(€`u(€ð&€§Œ&€pŒ&€tŒ&€€Œ&€xŒ&€‚Œ&€ƒŒ&€Œ&€ˆŒ&€ Œ&€˜Œ&€°Œ&€¨Œ&€ÀŒ&€¸Œ&€ÐŒ&€ÄŒ&€Øð&€Øð&€ÿð&€€Œ&€ßð&€pà†ð&€ :, ð&€À¿ € ð&€à†ð&€ ;, À:,Á  à†à;, à  à†p<, â € à†=, Ð<,ä  à†æ  à†ð=, ç  à†€>, è  `" à†@?, é  à†Ð?, ê  à†`@, ë  à†ð@, ì  `U) í € à†àA, °A,î  à†pB, ï  à†C, ð € à†C, `C,ñ  à† D, ò  0°D, ó  à@E, õ € àÐE,  E,÷  à`F, ù  ü  à† G, ÿ  à†  à†H,   à† H,   à†0I,   Å   +    Æ €  €J,È   Ê   Ì €   K,Î   Ð   Ò €  ÀL,Ô   Ö   Ø €  àM,Ú   Ü  Þ €  ÐN,à    ö €  ÀO,ø  û   þ €  °P,       €  ÐQ,       € ðR,      Ði)    " €  @T,$  &   ' €  0U,(   * €  ðU,+   ,  - €  àV,.   /  þ(`Pÿ(à¡&<  °) 1&°H+°&C+   à† Y,   Ð  0Z,       4  5  °©*`[,P€…* 6 €  ð[,7   8   ©* °)’&à\,P€…* 9 €   ],:   °)°& ;  0À^, <  =  >   °)°&?  @  A  `p`, B  `a,  °)0–&C  0Àa, E  0Pb, G  0àb, I  0pc, u `d, M  P O   Q   S   U   W     S+1                 !  i,àÍ&@i,’&pi,’& °)’&#  %   Z+ d  e  f  g  h  i  j  k  l  m  n   °)ð®&o  p  q  s  §  ©  «   ­   ¯  0 €  ±  €n,1  ³   2  µ   Àp,àÍ&3 € ð&€Pq,€«& ð&€@ °)€«&`p,D  ·   ð&€¹  F  ð&€À»   ð&€H € ð&€@ ð&€€`s,J  ð&€° L  ð&€ ð&€?N €  Ð`" pu,P   P&( R   P&( %(À·-WT €  '(  w,V  À—) %('( '( %(À·-Xðv,X   °'( Z € àw, %(°'( °'( %(À·-Y@x,y,\  Pz,П& €z,À¾& °)pù%  ý" ` €  {,П& |,ÐÀ&{,b   °)pù% pþ" r   },П& €},à-(t €  °)’& @ÿ" P},v   # w  à#  °# x € €#  P# `,y  pb"  z   À# { € #  `ú" @,|  ‚,€7( ð‚,’&}  Pƒ,П&  °)`3(~ €   k+ €ƒ,   °)0"( †   ˆ   € ð…,0"(  °)’&`…,‚  Š    °)0"(ƒ  Œ   „ € Ž   `ˆ,0"(p‡,…   °)àà'   ‡   ’  ‰ € Š,’&  °)0"(€‰,‹  ”     –   ˜  š   °)0"(œ  ž   ˜ ð+’&`Â+àÍ& PÃ+` Ð  Y  P [   ]   _   a    ¤   ¥   ¦   ¨   ª   ¬  ®  ð¥*°’,P˜* °   ²  `Ù)PP—* ´   ¶  ¥*À”,P˜*¸    º  Ф*à•,PP—* ¼   ¾  à£*—,P€…*À  ã   Ú)P¨*ç  ë  Ò*P˜,P€…*î   °)0ü%°2)`&Ð3) & °)0ü% €   ™,‘  “   • €  š,—   ™  à†P€›, ›  P°õ)   à†PМ, Ÿ  à†, ¡  à† ž, Ä  @ö) Å  à†Ÿ, Æ € à† Ÿ, pŸ,È  ð&€Àÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿà†` , Ê  à†ð , Ì €  ö) P¡,Î  à†à¡, Ð  à†p¢, Ò € à†£, Т,Ô  à†£, Ö    pü)Ú   Ü   Þ €  @¥,à   â   å €  `¦,é    ï €  P§,ò   ½  ¿  Á  0–&€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿà  0©,е& °) A(Ç   °)0C(É  Ë  Í  Ï  Ñ  Ó  Õ  ×    Ù  Û  Ý  ß  ð[( á  À¬,àÍ&ð¬,’& °)’&ä  è  *  -  ÐÀ&0  3  pa( àx+ 6     9  À¯,0"(<  ð¯,ÐÀ&P°,`²&?   °)€«&à°,k(¢   °)PÆ&@±,0"(p±,ÐÀ& °)`²&£  ²,0"(0²,’& °)@×'æ  À²,0"(ð²,П& °)pù%ê  €³,0"(°³,°Ä'à³,’& °)’&í  z€  ´,0"(д,°Ä' °)’&ð  º* 9°ó  Ðü" ð# 0µ,º* 9pV(  W( ðµ,º* 9p€X( ö  ù  p·,’& ·,ÐÀ&з,’& °)ÐÀ&ü  ÿ    ` °)À¾&    @˜Dº*0ª-º*E˜Dº*Ø›o @o   °) \(      R  »,ÐÀ& °)ÐÀ&T  »,ÐÀ&À»,ÐÀ& °) \(V  X  0€+ è9ð‘Žo í9 Ø›o Z  ½,’& °)ÐÀ&\   ½,П&@-ÐÀ&ð*   ³ à ˆ+ 0‰+  9)0ü%ñ  @¡*€¿,P¨*ô   ¯" ÷   ú   p°" ý  ðÁ,)&   À:))&        ˆ        à†    °) 1&      ¸     °)Ò&   º     ÐGÐGÐGÐG  pŽ+`   0=)Ð&&   £     À·"    À+     !   "    #   %    '  Ä  )  Б+` ,   /   2   5  À’+  8   ;  Ê  >   °)°& A  Ì  D  à†õ  G    ø €  Ó,û  à†  ”+ þ     €  °Ô,  Ö    `Ö,’&  € ðÖ,ÐÀ& 0Ö,   °)’&    $ € ¬  °×,&  à† (  pØ, + €  0Ù,.   1   4 €  PÚ,7  :  ˜+  = €  pÛ,@   C  ÀK*`F  ÐÀÜ,`ðÜ, I  ЀÝ,`°Ý, L  ›+ N € ²  pÞ,P  à† Q  0ß,  S €   à,U  W   Y €  á,[   ]  °œ+  _ €  `â,a   c   e €  €ã,g   pH)`i  ðI) ÐO)`å, àP)`W)`Рk €  J   æ,m    M  p    O  r €  q  0è,t    s  v    u  x €   w  @ê,z   Àë,ÐÀ&y   °)p“&E  {  ~ €   }  Pì,€    r(   ‚      „ €   ƒ  î,†   …  ˆ   à†‡  @ð,  Š € ‰  à† `ñ, ‹  ñ,Œ   à†  €ò, Ž    à† pó, ‘   €  à†“  ô,  0ô,’  •  à† °õ, —  ”  à†™   ö,  – € ›  à† À÷,   `÷,˜   à†Ÿ  àø,  š  ¡   œ € £    0ú,ž  ¥       §    ¢ € 0   pü,¤  2   ¦  4   ¨ € 6   °þ,1 8   3 :   5€ <   y ð-7 >   9 @   [)`;€ B   -= D  F ðž+  °)`3(^  Ð-П&-pù% °)ÐÀ&`  -k( °)Ðô'b   - \( °)À¾&°- \( ])`à-À¾&-’& °)pù%f   - \(Ð-À¾& °)pù%h   °) \(j  ð - \(0¡+ ÐÀ&P - \(€ -ÐÀ& °)`²&… Ðà -`p -P…*°…*@ - a -À¾&0 -pù%ÐÀ&Õ*Ðu  -À -P…* «) - a€ -À¾&É ° -pù%à -ÐÀ& °)`²& `)`Ðuð - +Ðuð -Ð-ð„* «) - aÐÀ-ÐÀ&0-` °)`²&Ðu-- o  °-ð„*P…*€- a@-k(ÐÀ&Ðuà-l   b)`n  `-ð„* «)Ð0- aÐ) ÐwA) 0xA) 0xA" ¼(¼(9223372036854775807LL9223372036854775807L1.7976931348623157e+3082.2250738585072014e-3082.2204460492503131e-164.9406564584124654e-3243.36210314311209350626e-4932L1.08420217248550443401e-19L3.64519953188247460253e-4951Là!-; "- ;h `"- ; "-;`à"-;@! #-;¸P¥.", #-9 Ηo §(ð§(¡.@$-;º*€$-;º*p À$-;º*h%-;º*À@%-;º*x €%-;º*À%-; º*pC&-;º*`@-`&-N.Î s} ;º*  - &-; º*€Cà&-;º*  '-;º*À -`'-;º*( '-;º*Èà'-;º*ˆ  (-;º*P!0ï ÐÆ (-;º* à(-;º*@ )-;º*C`)-;º* C )-;º*@à)-;º*@ *-;º*¨ `*-;º*H *-;º*H à*-;º*ÐÀÊðÌ`+-;º*¸  +-;º*Xà+-;º*à - ,-;º*!-`,-;º* !- ,-;º*@!-à,-;º*` --;º*h`--;º*˜ --;º*È ÝÀß) }A@.-;º*p€.-;º*€À.-;º*¨/-;º*€@-@/-;º*`!-€/-;º*€!-À/-;º* !-0-;º*¸@0-;º*xHPÀ0-?#º*Ý(1-;º*ˆ@1- ;º*à€1- ;º*€À1-;º*à ) pA@2-) }A;º*À€2- ;º*èÀ2- ;º*h!3- ;º*à @3-;º*è €3- ;º*ˆ ;º*à3- ;º*p! 4-;º*ð;º*€4-;º*ð À4- ;º*È5-;º*è @5- ;º* €5- ;º*øÀ5- ;º*x!6- ;º*˜@6- ;º* €6-;º*˜À6- ;º*€!7-5B;º*@7-ÄÚ; €7-Ä×; àl.Dà7-ÄÝ;  8-D]; `8-ÄÝ;Р8-D];°XD& 2Ä& `D* [ ù#D. hàÄ.  [@á#D/ °[À%D0 À[€â#D1 ˜2ÄT  2ÄW pÄZ xÄ] €Ä` ˆ`€ à€ ¨2à ˜à‚  `± °`² ¸ಠ!`³ Àà³ È`´ Ðà´ ¸2`É ØàÉ À2`Ê (!àÊ à`Ë È2àË è`Ì ðàÌ Ð2`Í øàÍ `Î  àÎ Ø2`Ï  àÏ 0!`Ð  àÐ àÒ ( `ï 0 àï 8 `ð à2àð @ `ñ P `ò X `ó è2àó ` `ô ð2àô h `õ p àõ x `ö  ?- J J;º*¸à?- U !U;º*Àø2Œ… àm.Œ• ¤–;º*Ð9223372036854775807L1.18973149535723176502e+4932L" @" @" @" @" @55" @99" " " " " " " "" PDC_MOUSE_POSITION" " " """"" " """"""" BUTTON2_DOUBLE_CLICKED" BUTTON2_TRIPLE_CLICKED" " !!" """ ##" %%" &&" ''" ((" **" ++" ,,"--BUTTON5_RELEASED"//"00"11"22MOUSE_WHEEL_SCROLL"44ÐGÐGBUTTON_MODIFIER_SHIFTàGàGÐGÐGÐGÐGàGàGÐGÐGàGàG ½( ½(À¼(À¼(P½(P½(" ''' @-' @-' @-' @-' @-' @-' @-'  @-'  @-'  @-' @-' @-' @-' @-' @-' @-' @-' @-' @-' @-' @-' @-' @-' @-'  @-'! @-'" @-'$ @-'% @-'& @-'' @-') @-'* @-'+ @-', @-'. @-" " " " " " Ep ;º*¸__stub_sigreturn__SLONGWORD_TYPEG~ ;º*(__SUSECONDS_T_TYPEÄ„ ;º*( † ;º*8 ____FILE_defined__mbstate_t_definedĉ ;º*@ Å-±À  __wcstold_internal__wcstol_internal_defined__wcstoul_internal_defined ( ±(  __wcstoll_internal_defined" __wcstoull_internal_defined" " " " " " " %%" && àµ-€Q-) @^.A) tAputwchar_unlocked) ÕA) ÕA) €tA) 0ÕA) tA)  tA) @ÕA) ÕA) €tA) 0ÕA) °tA) ÀtA) ÐtA) àtA__GCONV_IGNORE_ERRORS) ðtA) uA) PÕA) uA) ÐtA) àtA) uA__gconv_trans_end_fct) `ÕA) pÕA) uA) 0uA) @uA) PuA) `uA) puA) uA) @uA) PuA) €uA) uA)  uA) °uA) €ÕA) ÐìA) ÀuA) ÐuA) ÕA) ðuA) vA) vA) vA) 0vA)  ÕAcan_change_color¦—;º*à€X-Œ˜ ¤˜;º*8 ­™;º*èàX-Œš ªš;º*Ø Y-Œ› ¢›;º*H `Y-Œœ £œ;º* Y-Œ ¥;º*à"°;º*àu. ² (´;º*ð@Z- ¶ (¶;º*ø€Z- º "º;º*ÀZ- » ,»;º*[-Œ» ¤»;º*X  v.Œ¼ `[-Œ½ ¦½;º*@v.Œ¾ ¦Ã;º*à[-ŒÅ ¨Å;º*`  \-ŒÉ ¡É;º*h `\-ŒË  Ë;º* €v.ŒÍ  v.ŒÏ à\-ŒÑ  Ñ;º**Ü;º*(@]-ŒÞ ®Þ;º* €]- à )à;º*x À]-Œä ¥ä;º*8^-Œæ Ÿæ;º* @^- ç %ç;º*(à[¼  è €7. ì À^-Œù ¢ù;º*Hà¡.Œ € 0^  ˆ @_-  Dº*›o €_-Œ ¡Dº*›o ð[%,  ˜ à_-Œ ¢Dº*©(  @©(Œ 0¢.  €`-Œ ¢.pÏè,º*›o 3Œ( ¨ °  ) ¸ Œ) È 3Œ* Ð Œ- Ø  . à Œ. 3@E# 1 è  ã#Œ1 \Àã# 2 €&, 5 b-ŒB  cpkàò3`ä#ŒF \€! G å#ŒQ @æ#ŒZ àæ# [ €ç# _ ð ˜ e  0\¾  j  ø ò%Œn è#Œr @ó%Œy   † àc-P¹,˜ cpkàò0ä0)”˜ cpkàò@\ ¥.”™ PDC_set_line_colorPDC_getclipboard ·³ 7´ ( ·´ 0 7µ 8 ·µ H!7¶ @ ·¶ H 7· P ·· X 7¸ ` ·¸ (37¹ p 7º x ·º € 7» ˆ ·» 037¼ ·¼ 837½ g-š  ± ;º*X`g-¤ /¤;º*` g-𤠏¤;º*h )Λ Т.Nœ h-Μ ãœ9 Žo à«(N €¼,Î ð¥.Nž ®(N¥ £.Î¥ *,N¦ p£.Φ @i-N§ h§9 Žo Ð*,N¨ @¦.Ψ Ài-N¸ i¸;º*ˆ j-κ åº9àÆño @j-N» e»9`Ãño €j-λ å»9`Ãño Àj-N¼ e¼9 Åño k-μ ç¼9àÆño @k-N½ f½9`Ãño €k-ν ç½9 Èño Àk-N¾ e¾9@Äño l-ξ ç¾9Æño @l-N¿ e¿9"ño €l-ο æ¿9 Åño Àl-NÀ hÀ9àÆño m-ÎÀ èÀ9@Äño @m-NÁ iÁ9Æño €m-ÎÁ éÁ9 Åño Àm-N kÂ9àÆño n-ΠéÂ9 Åño @n-Nà kÃ9àÆño €n-Îà äÃ9`Ãño Àn-NÄ gÄ9@Äño o-ÎÄ æÄ9@Äño @o-NÅ iÅ9`Ãño €o-ÎÅ êÅ9@Äño Ào-NÆ gÆ9"ño p-ÎÆ çÆ9@Äño @p-NÇ eÇ9"ño €p-ÎÇ èÇ9"ño @²(NÈ q-ÎÈ __USE_FILE_OFFSET64èÈ9@Äño $NÉ `q-ÎÉ çÉ9ÀÇño  q-NË eË;º*p__USE_FORTIFY_LEVEL!ö;º*P ~.û ˜ þ     s-ˆ ”&;º*(__USE_EXTERN_INLINES0; º*°Hê-ó5ë-ó:_G_HAVE_ST_BLKSIZE__codecvt_noconv__codecvt_do_encoding_IO_getwc_unlocked;º*€¨ Å ÷à;º*ˆ`é#àá À£.`â `t-ûî ï;º* t-y %y9P&[Ÿo @†.’~ u- $9pð[Ÿo @u-’ ¦9Pñ[Ÿo €u-€ $€9 ò[Ÿo Àu-’€ ¤€90ë[Ÿo v- &9»[Ÿo @v-‚ %‚9°W[Ÿo €v-’Ž ¤Ž;º*˜ãÙ 9à€¤ o P\ê#Õà   ê#ä  w-—4  ­4 ;º*¨`w-—6  ¯6 ;º*ˆÀ†.7  Àw-—7  ±7 ;º*x-—8  «8 9`K¡o @x-—9  ²9 ;º*!-: ;º*¸@‡.—:  àn.;   ‡.<  @o.=  __builtin_gammaf__builtin_gammal__builtin_huge_val__builtin_huge_valf«> 9°Y¡o __builtin_huge_vall__builtin_ilogbfÀ‘A  __builtin_ilogbl*B ;º*ð ¹C ;º*  o.D  __builtin_lceilf__builtin_lceill__builtin_ldexpf7E ?º*À__builtin_ldexpl__builtin_lfloor__builtin_lfloorfºE 9€”l¡o __builtin_lfloorl__builtin_lgamma__builtin_lgammaf²G Dº*l¡o __builtin_lgammal__builtin_llceil__builtin_llceilfÄJ 9Ql¡o __builtin_llceill__builtin_llfloor__builtin_llfloorf__builtin_llfloorl__builtin_llrintàp.±K  __builtin_llrintf__builtin_llrintl__builtin_llround__builtin_llroundf__builtin_llroundl__builtin_log10f__builtin_log10lDM 9PSl¡o __builtin_log1plÆM 9ÀSl¡o FO 9†l¡o __builtin_lrintf__builtin_lrintl__builtin_lround__builtin_lroundf Š.1P  __builtin_lroundlÅP 9P’l¡o ¹-±Q  __builtin_nearbyint__builtin_nearbyintf__builtin_nearbyintl__builtin_nextafter__builtin_nextafterl__builtin_nexttoward) `vA__builtin_nexttowardl__builtin_pow10f__builtin_remainderf__builtin_remainderl__builtin_remquo__builtin_remquof__builtin_remquol__builtin_roundf__builtin_scalbl__builtin_scalblnf__builtin_scalbn__builtin_scalbnf__builtin_scalbnl__builtin_signbit__builtin_signbitl) àìA__builtin_significandf__builtin_significandl) àvA__builtin_tgamma__builtin_tgammaf) ðvA__builtin_tgammal__builtin_truncf__builtin_truncl) wA__builtin_cacosh) wA__builtin_cacoshf__builtin_cacosl) @wA) ÀÕA) `wAÀ  * ) pwA) €wA__sync_val_compare_and_swap_4__sync_val_compare_and_swap_8) wA__sync_val_compare_and_swap_16__sync_lock_test_and_set_1__sync_lock_test_and_set_2__sync_lock_test_and_set_4) ÐÕA__sync_lock_test_and_set_8__sync_lock_test_and_set_16__sync_lock_release__sync_lock_release_1__sync_lock_release_2__sync_lock_release_4__sync_lock_release_8__sync_lock_release_16__sync_synchronize__builtin_init_trampoline__builtin_adjust_trampoline__builtin_nonlocal_goto__builtin_stack_save__builtin_stack_restoreprofile_func_enter__builtin_profile_func_exitprofile_func_exit__builtin_ia32_addps__builtin_ia32_subps__builtin_ia32_mulps__builtin_ia32_divps__builtin_ia32_addss) àÕA__builtin_ia32_mulss) ˆ A__builtin_ia32_divss__builtin_ia32_cmpltps__builtin_ia32_cmpleps__builtin_ia32_cmpgtps) àwA__builtin_ia32_cmpgeps__builtin_ia32_cmpunordps__builtin_ia32_cmpneqps__builtin_ia32_cmpnltps__builtin_ia32_cmpnleps) ðwA__builtin_ia32_cmpngtps__builtin_ia32_cmpngeps__builtin_ia32_cmpordps__builtin_ia32_cmpeqss__builtin_ia32_cmpless) ðËA__builtin_ia32_cmpunordss__builtin_ia32_cmpneqss__builtin_ia32_cmpnltss__builtin_ia32_cmpngtss) xA__builtin_ia32_cmpngess__builtin_ia32_cmpordss__builtin_ia32_minps__builtin_ia32_maxps__builtin_ia32_maxss) íA__builtin_ia32_andps__builtin_ia32_andnps__builtin_ia32_orps__builtin_ia32_xorps__builtin_ia32_movss__builtin_ia32_movhlps__builtin_ia32_movlhps__builtin_ia32_unpckhps__builtin_ia32_unpcklps__builtin_ia32_paddb__builtin_ia32_paddw__builtin_ia32_paddq__builtin_ia32_psubb__builtin_ia32_psubw__builtin_ia32_psubd__builtin_ia32_psubq__builtin_ia32_paddsb__builtin_ia32_paddsw__builtin_ia32_psubsb__builtin_ia32_psubsw__builtin_ia32_paddusb__builtin_ia32_paddusw) @xA__builtin_ia32_psubusb__builtin_ia32_psubusw__builtin_ia32_pmullw__builtin_ia32_pmulhw__builtin_ia32_pand) íA__builtin_ia32_pandn__builtin_ia32_por__builtin_ia32_pxor__builtin_ia32_pavgb__builtin_ia32_pavgw__builtin_ia32_pcmpeqb) íA__builtin_ia32_pcmpeqw__builtin_ia32_pcmpeqd__builtin_ia32_pcmpgtb__builtin_ia32_pcmpgtw__builtin_ia32_pmaxub__builtin_ia32_pmaxsw__builtin_ia32_pminub__builtin_ia32_pminsw__builtin_ia32_punpckhbw) xA__builtin_ia32_punpckhdq__builtin_ia32_punpcklbw__builtin_ia32_punpckldq__builtin_ia32_addpd__builtin_ia32_subpd__builtin_ia32_mulpd__builtin_ia32_divpd__builtin_ia32_divsd) PxA__builtin_ia32_cmpeqpd__builtin_ia32_cmpltpd__builtin_ia32_cmplepd__builtin_ia32_cmpgtpd__builtin_ia32_cmpgepd__builtin_ia32_cmpunordpd__builtin_ia32_cmpneqpd__builtin_ia32_cmpnltpd__builtin_ia32_cmpnlepd__builtin_ia32_cmpngepd__builtin_ia32_cmpordpd__builtin_ia32_cmpeqsd__builtin_ia32_cmpltsd__builtin_ia32_cmplesd__builtin_ia32_cmpunordsd__builtin_ia32_cmpneqsd__builtin_ia32_cmpnltsd__builtin_ia32_cmpnlesd__builtin_ia32_cmpordsd__builtin_ia32_minpd__builtin_ia32_maxpd__builtin_ia32_minsd__builtin_ia32_maxsd__builtin_ia32_andpd__builtin_ia32_andnpd__builtin_ia32_orpd__builtin_ia32_xorpd__builtin_ia32_movsd__builtin_ia32_unpckhpd__builtin_ia32_unpcklpd__builtin_ia32_paddb128__builtin_ia32_paddw128) xA__builtin_ia32_paddd128__builtin_ia32_paddq128__builtin_ia32_psubb128__builtin_ia32_cvttsd2si64__builtin_ia32_psubw128__builtin_ia32_psubd128__builtin_ia32_paddsb128__builtin_ia32_paddsw128__builtin_ia32_psubsb128__builtin_ia32_paddusb128__builtin_ia32_paddusw128__builtin_ia32_psubusb128__builtin_ia32_psubusw128__builtin_ia32_pmullw128__builtin_ia32_pmulhw128__builtin_ia32_pand128__builtin_ia32_pandn128__builtin_ia32_por128__builtin_casinhf) ÐxA__builtin_casinhl__builtin_casinl__builtin_catanf__builtin_catanh__builtin_catanhf__builtin_catanhl__builtin_catanl__builtin_ccoshf__builtin_ccoshl__builtin_cimagf__builtin_cimagl__builtin_clog10__builtin_clog10f__builtin_clog10l__builtin_cprojf__builtin_cprojl__builtin_crealf__builtin_csinhf__builtin_csinhl__builtin_csqrtf__builtin_csqrtl__builtin_ctanhf__builtin_ctanhl__builtin_memcpy__builtin_memmove__builtin_mempcpy__builtin_memset__builtin_rindex__builtin_stpcpy__builtin_stpncpy__builtin_strcasecmp__builtin_strchr__builtin_strcmp__builtin_strcpy__builtin_strcspn__builtin_strdup__builtin_strndup__builtin_strlen__builtin_strncasecmp__builtin_strncat__builtin_strncmp__builtin_strncpy__builtin_strpbrk__builtin_strrchr__builtin_strspn__builtin_strstr__builtin_fprintf__builtin_fprintf_unlockedfprintf_unlocked__builtin_fputc_unlocked__builtin_fputs_unlocked__builtin_fscanf__builtin_fwrite__builtin_fwrite_unlocked__builtin_printf__builtin_printf_unlocked__builtin_putchar__builtin_putchar_unlockedputchar_unlocked__builtin_sprintf__builtin_sscanf__builtin_vfprintf__builtin_vfscanf__builtin_vprintf__builtin_vscanf__builtin_vsnprintf__builtin_vsprintf__builtin_vsscanf__builtin_isalnum__builtin_isalpha__builtin_isascii__builtin_iscntrl__builtin_isdigit__builtin_isgraph__builtin_isprint__builtin_ispunct__builtin_isspace__builtin_isupper__builtin_isxdigit__builtin_toascii__builtin_tolower__builtin_toupper__builtin_iswalnum__builtin_iswalpha__builtin_iswblank__builtin_iswcntrl__builtin_iswdigit__builtin_iswgraph__builtin_iswprint__builtin_iswpunct__builtin_iswspace__builtin_iswupper__builtin_iswxdigit__builtin_towlower__builtin_towupper__builtin_alloca__builtin_apply_args__builtin_args_info__builtin_calloc__builtin_clzimax__builtin_constant_p__builtin_ctzimax__builtin_dcgettext__builtin_dgettext__builtin_dwarf_cfa__builtin_dwarf_sp_column__builtin_eh_return__builtin_eh_return_data_regno__builtin_execlp__builtin_execle__builtin_execvp__builtin_execve__builtin_extend_pointer__builtin_extract_return_addr__builtin_frob_return_addr__builtin_gettext__builtin_imaxabs__builtin_finite__builtin_finitef__builtin_finitel__builtin_isinff__builtin_isinfl__builtin_isnanf__builtin_isnanl__builtin_isgreater__builtin_isgreaterequal__builtin_islessequal__builtin_islessgreater__builtin_isunordered__builtin_malloc__builtin_next_arg__builtin_parity__builtin_parityimax__builtin_parityl__builtin_popcount__builtin_popcountl__builtin_popcountll__builtin_prefetch__builtin_return_address__builtin_saveregs__builtin_setjmp__builtin_stdarg_start__builtin_strfmon__builtin_unwind_init__builtin_update_setjmp_buf__builtin_va_copy__builtin_va_end__builtin_va_start__builtin_va_arg_pack_len__builtin_object_size__builtin___memcpy_chk__builtin___mempcpy_chk__builtin___memset_chk__builtin___stpcpy_chk__builtin___strcat_chk__builtin___strncat_chk__builtin___strncpy_chk__builtin___vsnprintf_chk__builtin___vsprintf_chk__builtin___fprintf_chk__builtin___printf_chk__builtin___vprintf_chk__sync_fetch_and_add__sync_fetch_and_add_1__sync_fetch_and_add_2__sync_fetch_and_sub_8__sync_fetch_and_sub_16__sync_fetch_and_or__sync_fetch_and_or_1__sync_fetch_and_or_2__sync_fetch_and_or_4__sync_fetch_and_or_8__sync_fetch_and_or_16__sync_fetch_and_and__sync_fetch_and_and_1__sync_fetch_and_and_4__sync_fetch_and_and_16__sync_fetch_and_xor_1__sync_fetch_and_xor_2__sync_fetch_and_xor_4__sync_fetch_and_xor_8__sync_fetch_and_xor_16__sync_fetch_and_nand__sync_fetch_and_nand_1__sync_fetch_and_nand_2__sync_fetch_and_nand_4__sync_fetch_and_nand_8__sync_fetch_and_nand_16__sync_add_and_fetch__sync_add_and_fetch_1__sync_add_and_fetch_2__sync_add_and_fetch_4__sync_add_and_fetch_8__sync_add_and_fetch_16__sync_sub_and_fetch__sync_sub_and_fetch_1__sync_sub_and_fetch_2__sync_or_and_fetch_2__sync_or_and_fetch_4__sync_or_and_fetch_8__sync_or_and_fetch_16__sync_and_and_fetch__sync_and_and_fetch_1__sync_and_and_fetch_2__sync_and_and_fetch_4__sync_and_and_fetch_8__sync_and_and_fetch_16__sync_xor_and_fetch__sync_xor_and_fetch_1__sync_xor_and_fetch_4__sync_nand_and_fetch_1__sync_nand_and_fetch_2__sync_nand_and_fetch_4__sync_nand_and_fetch_8__sync_nand_and_fetch_16__sync_bool_compare_and_swap_1__sync_bool_compare_and_swap_2__sync_bool_compare_and_swap_4__sync_bool_compare_and_swap_8__sync_bool_compare_and_swap_16__sync_val_compare_and_swap__FSFILCNT_T_TYPEreg_equiv_memory_loc_IO_getc_unlocked€Þ-Ka  Þd ?º*h à-Ëy  `à-K}  ý;º*¸â-s__FLT_MAX_10_EXP__;º*Ѐã-ó”;º*ø”;º*;º*__LDBL_MANT_DIG__/usr/include/libio.hàä-ó$ §'s*-; º*p@ç-ó-@ç-s.àç-s0€è-ó14; º* A:; º*€AÅQ 9@Wl¡o ¸ ±S `¹-±U  ÈU 9`l¡o À ଱_  À¹-±c  Ñc ;º*È<±f  º-1n  En ;º*°`º-±n  Æn ;º*Ø º-1o  Eo ;º*ààº-±o  Æo ;º*ø  N-1p  @»-±p  Èp ;º*Ѐ»-1q  Iq ;º*ØÀ»-±q  Ãq ;º*è¼-±u  Äu ; º*@@@¼-1v  Kv ; º*°d€¼-±v  Év ; º*P@À¼-1w  Gw ;º* ½-±w  Éw ;º*ð@½-1x  Gx ;º*Ø€½-±x  Èx ;º*À ….1y  à½-±y  Çy ;º*  ¾-1z  Pz ;º*`¾-±z  Åz ;º*È ¾-1{  H{ ;º*à¾-±{  Ç{ ;º* ¿-1|  K| ;º*`¿-±|  Ð| ;º*  ¿-1}  K} ;º*àà¿-±}  É} ;º* €N-1~  @À-±~  È~ ;º*0€À-±  Ê ;º*8ÀÀ-1€  O€ ;º* Á-1‚  O‚ ;º*à@Á-±ƒ  Ń ;º*!€Á-1„  C„ ;º*ÐÀN-±„  àÁ-1…  G… ;º*@ Â-±…  Â… ;º*Ø`Â-1†  B† ;º*HàN-±†  ÀÂ-1‡  G‡ ;º*PÃ-±‡  ȇ ;º*à@Ã-1ˆ  Hˆ ;º*X€Ã-±ˆ  ƈ ;º*`ÀÃ-1‰  I‰ ;º*h@O-±‰  Ä-1Š  FŠ ;º*p`Ä-±Š  ÄŠ ;º*è Ä-1‹  I‹ ;º*xàÄ-±‹  È‹ ;º*€ÉÀ 9`⢢o @31Ï ™1ç š±ç +1è p\ÀF#1  È  ± $ Ð  1 ' €\° 1 1 H3 ± ( \¸ ± 0 Ø À ±  à  1  P3Ä 1  è à<1&  ð ø ±&   1'  X! ±'   \ 1(  €Ç-KW  [W ;º*X ÛW ;º*è Þ-KX  __builtin_ia32_pxor128__builtin_ia32_pavgb128__builtin_ia32_pavgw128__builtin_ia32_pcmpeqb128__builtin_ia32_pcmpeqd128__builtin_ia32_pcmpgtw128__builtin_ia32_pcmpgtd128__builtin_ia32_pmaxub128__builtin_ia32_pmaxsw128__builtin_ia32_pminub128__builtin_ia32_pminsw128__builtin_ia32_punpckhbw128__builtin_ia32_punpckhwd128__builtin_ia32_punpckhdq128__builtin_ia32_punpckhqdq128__builtin_ia32_punpcklbw128__builtin_ia32_punpcklwd128__builtin_ia32_punpckldq128__builtin_ia32_packsswb128__builtin_ia32_packssdw128__builtin_ia32_packuswb128__builtin_ia32_pmulhuw128__builtin_ia32_emms__builtin_ia32_psllw__builtin_ia32_pslld__builtin_ia32_psrlw__builtin_ia32_psrld__builtin_ia32_psrlq__builtin_ia32_psraw__builtin_ia32_psrad__builtin_ia32_pshufw__builtin_ia32_comieq__builtin_ia32_comilt__builtin_ia32_comile__builtin_ia32_comigt__builtin_ia32_comige__builtin_ia32_comineq__builtin_ia32_ucomieq__builtin_ia32_ucomilt__builtin_ia32_ucomile__builtin_ia32_ucomigt__builtin_ia32_ucomige__builtin_ia32_ucomineq__builtin_ia32_comisdeq__builtin_ia32_comisdlt__builtin_ia32_comisdle__builtin_ia32_comisdgt__builtin_ia32_comisdge__builtin_ia32_comisdneq__builtin_ia32_ucomisdeq__builtin_ia32_ucomisdlt__builtin_ia32_ucomisdle__builtin_ia32_ucomisdgt__builtin_ia32_ucomisdge__builtin_ia32_ucomisdneq__builtin_ia32_packsswb__builtin_ia32_packssdw__builtin_ia32_packuswb__builtin_ia32_ldmxcsr__builtin_ia32_stmxcsr__builtin_ia32_cvtpi2ps__builtin_ia32_cvtps2pi__builtin_ia32_cvtsi2ss__builtin_ia32_cvtsi642ss__builtin_ia32_cvtss2si__builtin_ia32_cvtss2si64__builtin_ia32_cvttps2pi__builtin_ia32_cvttss2si__builtin_ia32_cvttss2si64__builtin_ia32_storeups__builtin_ia32_loadlps__builtin_ia32_storelps__builtin_ia32_pmovmskb__builtin_ia32_movntq__builtin_ia32_psadbw__builtin_ia32_rcpps__builtin_ia32_rcpss__builtin_ia32_rsqrtps__builtin_ia32_rsqrtss__builtin_ia32_sqrtps__builtin_ia32_sqrtss__builtin_ia32_shufps__builtin_ia32_maskmovdqu__builtin_ia32_loadupd__builtin_ia32_storeupd__builtin_ia32_loadhpd__builtin_ia32_movmskpd__builtin_ia32_movnti__builtin_ia32_movntdq__builtin_ia32_pshuflw__builtin_ia32_pshufhw__builtin_ia32_psadbw128__builtin_ia32_sqrtpd__builtin_ia32_shufpd__builtin_ia32_cvtdq2pd__builtin_ia32_cvtdq2ps__builtin_ia32_cvtpd2ps__builtin_ia32_cvttpd2pi__builtin_ia32_cvtsd2si__builtin_ia32_cvttsd2si__builtin_ia32_cvtsd2si64__builtin_ia32_cvtps2dq__builtin_ia32_cvtps2pd__builtin_ia32_cvttps2dq__builtin_ia32_cvtsi2sd__builtin_ia32_cvtsi642sd__builtin_ia32_cvtsd2ss__builtin_ia32_cvtss2sd__builtin_ia32_clflush__builtin_ia32_lfence__builtin_ia32_mfence__builtin_ia32_loaddqu__builtin_ia32_pmuludq__builtin_ia32_pmuludq128__builtin_ia32_psllw128__builtin_ia32_pslld128__builtin_ia32_psllq128__builtin_ia32_psrld128__builtin_ia32_psrlq128__builtin_ia32_psraw128__builtin_ia32_psllwi128__builtin_ia32_pslldi128__builtin_ia32_psllqi128__builtin_ia32_psrldqi128__builtin_ia32_psrlwi128__builtin_ia32_psrldi128__builtin_ia32_psrlqi128__builtin_ia32_psrawi128__builtin_ia32_psradi128__builtin_ia32_vec_init_v2si__builtin_ia32_vec_init_v4hi__builtin_ia32_vec_init_v8qi__builtin_ia32_vec_ext_v2df__builtin_ia32_vec_ext_v2di__builtin_ia32_vec_ext_v4sf__builtin_ia32_vec_ext_v8hi__builtin_ia32_vec_ext_v2si__builtin_ia32_vec_set_v8hi__builtin_ia32_vec_set_v4hi__fundamental_type_info_pseudo__fundamental_type_info) x A__array_type_info_pseudo__function_type_info_pseudo__enum_type_info_pseudo__class_type_info_pseudo__class_type_info__si_class_type_info_pseudo__si_class_type_info__base_class_type_info_pseudo__pointer_type_info_pseudo__pointer_to_member_type_info__cxa_call_unexpectedredefine_extname_Unwind_SjLj_Register_Unwind_SjLj_Unregister__cyg_profile_func_enter__INCLUDE_LEVEL____GNUC_PATCHLEVEL____GNUC_RH_RELEASE____UINTMAX_TYPE____LONG_LONG_MAX____FLT_EVAL_METHOD____FLT_MANT_DIG____FLT_DENORM_MIN____FLT_HAS_INFINITY____FLT_HAS_QUIET_NAN____DBL_MANT_DIG____DBL_MIN_10_EXP____DBL_HAS_INFINITY____LDBL_MIN_EXP__) 0ÖA@úó¡àý-s½@þ-s¾À=$sØH àñ @@-Œ– [X ;º*˜`Þ-ËZ  ÜZ 9à˜£o ]a ;º*ÀÞ-Ëa  Ýa ;º*` ß-Kb  ]b ;º* @¶-Ëd  `ß-Kw  ^w ;º* ß-Ëw  Ýw ;º*x àß-Kx  bx ;º*¨ày ;º*°@à-Kz  `z ;º*€ _} ;º* à-Óƒ  ⃠9°>£o àà-S„  c„ 9?£o á-Ó„  ã„ 9p@£o 0 `fÓ À\@ë#Ó1  á-sûƒû;º*˜  ¶-óü0•óÿ€;º*  @â-ó;º*È€â-s”;º*¨ ·-óàâ-s”;º*Ø ã-ó;º*à`ã-s”;º*è;º*ð@·-s€øóŸ`·-s€·-ó@ä-s”;º*€ä-ó;º*%ó"s%;º*°  å-s%”%;º*`å-ó%&;º* €r-s&£'s'ðó%ó' ô%s(X3Æ ó( 8 È s)  Põ%ó)€æ-s,”,; º*`@ ¸-ó,àæ-s-”-; º*€@.; º*@@û-ó©”.; º* @€ç-ó./; º*°@Àr-ó/€û-óµ”0; º*À@ è-ó01; º*Ð@`è-s1”1; º*à@2; º*ð@Àè-s2”2; º*Aé-s3”3; º*AÀ¸-ó3`é-s4”4; º*0A é-ó45; º*@Aàé-s5”5; º*PA6; º*`A@ê-ó89; º*ÐI€ê-s9”9; º*pAà¸-ó9àê-s:”:; º*A;; º*@J õ-ó;€ì#sÊ" @66" @88 B$sÞ) ˜0A" ""__LDBL_MIN_10_EXP____LDBL_MAX_10_EXP____LDBL_EPSILON__) ¸ A__LDBL_DENORM_MIN____LDBL_HAS_INFINITY____LDBL_HAS_QUIET_NAN____REGISTER_PREFIX____USER_LABEL_PREFIX____GNUC_GNU_INLINE____FINITE_MATH_ONLY____need___va_list_VA_LIST_DEFINED__need_ptrdiff_t__sys_stdtypes_h_MACHINE_ANSI_H_" ))_SIZE_T_DEFINED__BSD_SIZE_T_DEFINED__SIZE_T_DECLARED_BSD_WCHAR_T_DEFINED__BSD_RUNE_T_DEFINED__WCHAR_T_DECLARED"..___int_wchar_t_h__USE_POSIX199309__USE_XOPEN_EXTENDED__USE_LARGEFILE64"33__KERNEL_STRICT_NAMES_LOOSE_KERNEL_NAMES_XOPEN_SOURCE_EXTENDED_LARGEFILE64_SOURCE_LARGEFILE_SOURCE__STDC_IEC_559____STDC_IEC_559_COMPLEX____STDC_ISO_10646__àGàG__INTEL_COMPILER__GLIBC_HAVE_LONG_LONG_GLIBCPP_USE_NAMESPACES__BEGIN_NAMESPACE_STD__END_NAMESPACE_STD__USING_NAMESPACE_STD__BEGIN_NAMESPACE_C99__END_NAMESPACE_C99__USING_NAMESPACE_C99__BOUNDED_POINTERS____attribute_malloc____attribute_used____attribute_noinline____attribute_deprecated____attribute_format_arg____attribute_format_strfmon____warn_unused_result__' @-__always_inline____WORDSIZE_COMPAT32) 0zA__LONG_DOUBLE_MATH_OPTIONAL__NO_LONG_DOUBLE_MATH__LDBL_REDIR1_NTH__LDBL_REDIR_NTH__LDBL_REDIR1_DECL__LDBL_REDIR_DECL__OPTIMIZE_SIZE____stub___kernel_cosl__stub___kernel_rem_pio2l__stub___kernel_tanl' @-) pzA)  zA) ðzA) {A/usr/include/wchar.h<; º*PJö-s</usr/include/stdio.h”<; º* A@ö-ó<=; º*€J€ö-s=”=; º*°AÀö-ó=>; º*ÀA÷-ó>?; º*ÐA@÷-s?”?; º*àA€÷-ó?@; º*ðAÀ÷-s@”@; º*Kø-sA”A; º*B@ø-óAB; º*B€ø-óK L9p›}¦o Àø-sLŒL9°}¦o ù-óL M9à›}¦o @ù-ó‚ƒ9`‹}¦o `ùs¡ ûs¢üó¢àüs£Àýó£ÿs¤ðÿó¤Ðó¥€Îs¦ ó¦Àú-ó§ ¨9º}¦o @(s¨ û-s©©;º*È  ª;º*8€"sµ ¶90ø6§o Àû-ó¶ ·9`6§o ü-s·Š·9€6§o @ü-ó· ¸90ø6§o €ü-sºŠº9ù6§o Àü-óº »9Àþ6§o ý-s»Š»9 ÿ6§o @ý-ó» ¼96§o €ý-s¼м9º6§o Àý-ó¼ ½9Ðú6§o н9°6§o þ-ó½ ¾9pý6§o о9ðù6§o €þ-ó¾ ¿96§o Àþ-s¿Š¿9ü6§o ÿ-sÀŠÀ90ø6§o @ÿ-óÀ Á90ø6§o €ÿ-sÁŠÁ90ø6§o Àÿ-óÁ Â90ø6§o à\€G#sÆ àë#óÉ í#óÊ 3$sËÀ3$óË`4$sÌ5$óÌ@6$sÍà1$óÍà6$s΀7$óÎ 8$óÐÀ8$sÑ`9$óÑ€2$sÒ:$óÒ :$sÓ@;$óÓ 5$óÖ€<$s× =$ó×`>$óØ?$sÙ ?$óÙ@@$sÜà@$óÜ€A$sÝ`\$óÝÀB$óÞ@^$sßÀ.sáŠá9°û6§o .óá â9P 6§o @.sâŠâ9À 6§o €.óâ ã9Pþ6§o __builtin_frexpf__builtin_frexpl__builtin_pow10l__builtin_scalbf__builtin_scalbln__builtin_scalblnl__builtin_signbitf__builtin_significand__builtin_sincosf__builtin_sincosl__builtin_cacoshl__sync_val_compare_and_swap_1__sync_val_compare_and_swap_2__sync_lock_test_and_set__builtin_profile_func_enter__builtin_ia32_subss__builtin_ia32_cmpeqps__builtin_ia32_cmpnless.sãŠã90 6§o @.óã ä96§o €.säŠä9 6§o À.óä å96§o .såŠå9p6§o @.óå æ9`6§o €.sæŠæ906§o À.sŠ;º*p .ó ;º* @ .sŠ;º*x€ .ó ;º* #s€#ó$s @ .s ) ptAŠ ;º*€€ .ó ;º* À .ó ;º*ˆ .sŠ;º*(@ .ó ;º*0€ .sŠ;º*8À .ó ;º*__builtin_ia32_pmulhuw .sŠ;º*@` .ó ;º*H  .sŠ;º*Pà .sŠ;º*X .ó ;º*˜` .sŠ;º*`  .ó ;º*hà .sŠ;º*  .ó ;º*p`.sŠ;º*x .ó ;º*¨à.sŠ;º*€@.ó__builtin_ia32_punpckhwd ;º*¨€.sŠ;º*ˆÀ.ó ;º*.sŠ;º*˜@.ó ;º*°€.sŠ;º* À.ó ;º*¨__builtin_ia32_addsd@.s__builtin_ia32_subsdŠ;º*¸ .ó__builtin_ia32_mulsd ;º*°à.sŠ;º*° .ó ;º*¸À-.s€.ó ;º*ÀÀ.sŠ;º*È .ó) tA ;º*Ð`.s Š ;º*¸À.ó __builtin_ia32_cmpngtpd !;º*ð.s!Š!;º*Ø@.ó! ";º*à€.s"Š";º*èÀ.ó" #;º*À.s#Š#;º*ð@.ó# $;º*ø€.s$Š$;º*ÈÀ.ó$ %;º*È.s%Š%;º*@.ó% &;º*€.s&Š&;º*À.ó& ';º*Ð.s'Š';º*@.ó' (;º* €.s(Š(;º*Ø€.ó(__builtin_ia32_psubq128__builtin_ia32_psubsw128__builtin_casinf__builtin_casinh__builtin_creall__builtin_strcat) àuA__builtin_puts_unlocked__builtin_isblank__builtin_iswlower__builtin_expect__builtin_ffsimax__builtin_frame_address__builtin_isless );º*Ð__builtin_longjmpà.s)Š);º*( .ó) *;º*0`.s*Š*;º*àÀ.ó*__builtin_parityll +;º*8.s+Š+;º*@__builtin_popcountimax`.ó+ ,;º*H .s,Š,;º*Ø.ó,__builtin_return -;º*è@.s-Š-;º*P€.ó- .;º*XÀ.s.Š.;º*ð__builtin_strftime .ó. /;º*``.s/Š/;º*h .ó/ 0;º*pà.s0Š0;º*ø@.ó0__builtin_va_arg_pack 1;º*à€.s1Š1;º*À.ó1 2;º*x.s2Š2;º*@.ó2 3;º*€__builtin___memmove_chk .ó3 4;º*ˆà.s4Š4;º* .ó4 5;º*€ .s5€y-—>  Š5;º*èÀ .ó5 6;º*!.s6Š6;º*˜__builtin___strcpy_chk`!.ó6 7;º*  !.s7Š7;º* à!.ó7 8;º*¨ ".s8Š8;º*°€".ó8__builtin___sprintf_chk 9;º*`!à".s9`\F#—?  Š9;º*( #.ó9 :;º*¸`#.s:Š:;º*À #.ó: ;;º*ð$.s; z-B  Š;;º*0`$.s=__builtin___vfprintf_chkŠ=;º*È $.ó= >;º*Ðà$.s>Š>;º*8 %.ó> ?;º*ø`%.s?Š?;º*Ø__sync_fetch_and_add_4À%.ó? @;º*à__sync_fetch_and_add_8@&.s@__sync_fetch_and_add_16Š@;º*è &.ó@__sync_fetch_and_sub A;º*@__sync_fetch_and_sub_1'.sAŠA;º*ð`'.óA__sync_fetch_and_sub_4 B;º*ø '.sBŠB;º*H(.óB@ˆ.—D  C;º*@(.sCŠC;º*€(.óC D;º*À(.sDŠD;º*).óD E;º*@).sEŠE;º*__sync_fetch_and_and_2 ).óE F;º*P*.sF__sync_fetch_and_and_8ŠF;º*@*.óF G;º*X__sync_fetch_and_xor *.sGŠG;º* à*.óG H;º*( +.sHŠH;º*0`+.óH I;º*` +.sIŠI;º*8à+.óI J;º*h ,.sJŠJ;º*p@/.óJ__sync_sub_and_fetch_4__sync_sub_and_fetch_8__sync_sub_and_fetch_16__sync_or_and_fetch__sync_or_and_fetch_1__sync_xor_and_fetch_2 ~-1M  __sync_xor_and_fetch_8__sync_xor_and_fetch_16__sync_nand_and_fetch__sync_bool_compare_and_swapŠ;º*À) ÖA)  {A)  ÖA) |A/usr/include/bits/types.h/usr/include/_G_config.h) ÀÖA) píA [-ŒÃ ) `|A)  |A K;º*€/.sKŠK;º*@À/.óK L;º*H0.sLŠL;º*P@0.óL M;º*x€0.sMŠM;º*€À0.óM N;º*X1.sNŠN;º*ˆ@1.óN O;º* €1.óO P;º*`À1.sPŠP;º*h2.óP Q;º*@2.sQŠQ;º*p€2.óQ R;º*xÀ2.sRŠR;º*€3.sSŠS;º*˜@3.óS T;º*H€3.sTŠT;º*ˆÀ3.óT U;º*4.sUŠU;º* @4.óU V;º* €4.sVŠV;º*˜À4.óV W;º*¨5.sWŠW;º*°@5.sXŠX;º*  5.óX) àA Y;º*¸à5.sYŠY;º* @6.óY) ÐA Z;º*¨€6.sZŠZ;º*ÀÀ6.óZ [;º*°7.s[Š[;º*¸@7.ó[ \;º*( 7.s\-ì;º*@Š\;º*Èà7.ó\ ];º*À 8.s]Š];º*È€8.ó])  .A ^;º*ÐÀ8.s^Š^;º*Ð9.ó^ _;º*Ø@9.s_Š_;º*à€9.ó_ `;º*0À9.s`Š`;º*Ø:.ó` a;º*è@:.saŠa;º*ð€:.óa b;º*àÀ:.sbŠb;º*ø;.ób c;º*@;.scŠc;º*€;.óc d;º*8À;.sdŠd;º*è<.ód e;º*ð@<.seŠe;º*€<.óe f;º*øÀ<.sfŠf;º*@=.óf g;º*@=.sgŠg;º* €=.óg h;º*HÀ=.shŠh;º*( >.óh i;º*(   ( `>.siŠi;º*0 >.ói j;º*à>.sjŠj;º*8 ?.ój k;º*@`?.skŠk;º*H ?.ók l;º*PÀ_.slcpkàò  w d-€¢.™ getchar_unlockedclearerr_unlockedBUTTON_DOUBLE_CLICKEDBUTTON_TRIPLE_CLICKEDBUTTON_ACTION_MASKPDC_BUTTON_SHIFTBUTTON_MODIFIER_MASKPDC_MOUSE_WHEEL_UPPDC_MOUSE_WHEEL_DOWNA_BUTTON_CHANGEDMOUSE_POS_REPORTMOUSE_WHEEL_DOWNBUTTON1_RELEASEDBUTTON1_DOUBLE_CLICKEDBUTTON1_TRIPLE_CLICKEDBUTTON2_RELEASEDBUTTON3_RELEASEDBUTTON3_DOUBLE_CLICKEDBUTTON3_TRIPLE_CLICKEDBUTTON4_RELEASEDBUTTON4_DOUBLE_CLICKEDBUTTON4_TRIPLE_CLICKEDBUTTON5_DOUBLE_CLICKEDBUTTON5_TRIPLE_CLICKEDBUTTON_MODIFIER_CONTROLBUTTON_MODIFIER_ALTALL_MOUSE_EVENTSNCURSES_MOUSE_VERSIONlinesrippedoffontopreturn_key_modifiers D.ól m;º*PŠm;º*X€D.óm n;º*`ÀD.snŠn;º*E.ón o;º*hà_.so`E.óo p;º*Šp;º*¨ `.sqF.óq r;º*€@F.srŠr;º*ˆÀn.ór F.ssŠs;º*àF.ós t;º* À„.st@G.ót u;º*XŠu;º*0``.óuÀG.óv w;º* H.swŠw;º*8€`.ów `.sx/usr/include/gconv.h H.óx y;º*HÀ`.sy__stub_feupdateenv I.óy z;º*°à`.óz€I.s|Š|;º*È__ULONGWORD_TYPEàI.s~Š~;º*X_BITS_TYPESIZES_HÀa.ó~Š;º*à__BLKCNT64_T_TYPE__FSBLKCNT_T_TYPE__FSBLKCNT64_T_TYPE@r.ó€__FSFILCNT64_T_TYPE__USECONDS_T_TYPEŠ;º*ø€K.ó__CLOCKID_T_TYPE ‚;º*h__BLKSIZE_T_TYPEàK.s‚Š‚;º*hŠƒ;º*pŠ„;º*xŠ…;º*€L.ó… †;º*І;º*hàb.ó†c.s‡€}.ó‡ ….óˆ`M.s‰Љ9P×"®o @ `÷%sŠ __builtin_asinhf__builtin_asinhlh3Ê sz  p  _0_ d.óƒ__wcstod_internal__wcstof_internale.ó„__wcstol_internal@e.ó†__wcstoul_internal__wcstoll_internal__wcstoull_internalgetwchar_unlocked__UNKNOWN_10646_CHAR__GCONV_EMPTY_INPUT__GCONV_FULL_OUTPUT__GCONV_ILLEGAL_INPUT__GCONV_INCOMPLETE_INPUT__GCONV_ILLEGAL_DESCRIPTOR__GCONV_INTERNAL_ERROR__gconv_step_data__gconv_loaded_object__gconv_trans_data__gconv_btowc_fct__gconv_init_fct__gconv_trans_fct__gconv_trans_context_fct__gconv_trans_query_fct__gconv_trans_init_fct__trans_context_fct__min_needed_from__max_needed_from__builtin_exp10l__builtin_floorlreset_shell_moderequest_mouse_posassume_default_colorsuse_default_colorsPDC_clearclipboardPDC_freeclipboardPDC_setclipboardPDC_get_input_fdPDC_get_key_modifiersPDC_return_key_modifiersPDC_save_key_modifiersPDC_CLIP_SUCCESSPDC_CLIP_MEMORY_ERRORPDC_KEY_MODIFIER_SHIFTPDC_KEY_MODIFIER_CONTROLPDC_KEY_MODIFIER_ALTPDC_KEY_MODIFIER_NUMLOCK__cyg_profile_func_exit__invocation_counter_G_HAVE_SYS_CDEFS_G_HAVE_SYS_WAIT_G_NEED_STDARG_H_G_HAVE_PRINTF_FP_G_HAVE_LONG_DOUBLE_IO_G_HAVE_IO_FILE_OPEN_G_HAVE_IO_GETLINE_INFO_G_IO_IO_FILE_VERSION_STATBUF_ST_BLKSIZE_G_NAMES_HAVE_UNDERSCORE_G_VTABLE_LABEL_HAS_LENGTH_G_VTABLE_LABEL_PREFIX_G_VTABLE_LABEL_PREFIX_ID_IO_HAVE_SYS_WAIT_IO_HAVE_ST_BLKSIZE_IO_UNIFIED_JUMPTABLES_OLD_STDIO_MAGIC_IO_TIED_PUT_GET_IO_CURRENTLY_PUTTING_IO_FLAGS2_NOTCANCEL_IO_FLAGS2_USER_WBUF__codecvt_partial_GLIBCPP_USE_WCHAR_T__codecvt_do_out__codecvt_do_unshift__codecvt_do_always_noconv_IO_USE_OLD_IO_FILE_IO_FILE_completeattribute_hiddencookie_read_function_tcookie_write_function_tcookie_seek_function_tcookie_close_function_t_IO_cookie_io_functions_tcookie_io_functions_t_IO_peekc_unlocked_IO_putc_unlocked_IO_putwc_unlocked_IO_feof_unlocked_IO_ferror_unlocked_IO_peekc_locked_IO_PENDING_OUTPUT_COUNT_IO_ftrylockfile_IO_cleanup_region_start_IO_cleanup_region_end_IO_free_backup_area__builtin_ia32_pcmpgtb128_IO_free_wbackup_area__need_FOPEN_MAX__builtin_ia32_punpcklqdq128__builtin_ia32_psllq__builtin_ia32_pmaddwd) °ÕA__builtin_ia32_maskmovq__builtin_ia32_loadups__builtin_ia32_loadhps__builtin_ia32_movmskps__builtin_ia32_movntps__builtin_ia32_sfence__builtin_ia32_loadlpd__builtin_ia32_movntpd__builtin_ia32_pshufd__builtin_ia32_sqrtsd__builtin_ia32_cvtpd2dq__builtin_ia32_cvtpd2pi__builtin_ia32_cvttpd2dq__builtin_ia32_cvtpi2pd__builtin_ia32_storedqu__builtin_ia32_psrlw128__builtin_ia32_psrad128__builtin_ia32_pslldqi128__builtin_ia32_pmaddwd128h ·¹ __builtin_ia32_vec_ext_v4si__builtin_ia32_vec_ext_v4hi__cxa_pure_virtual__type_info_pseudo__array_type_info__function_type_info__gxx_personality_v0) `xA) pxA) ÖA) €xA) °xA) ÀxA) yA__PTRDIFF_TYPE____GXX_ABI_VERSION__DBL_MAX_10_EXP____DBL_HAS_QUIET_NAN__Šl;º*Šo;º*p€E.spŠq;º*x`G.su v;º*˜ x;º*@Šx;º*¨Šy;º*ˆ! {;º*À a.s{Š{;º*PPDC_BUTTON_CONTROL };º*Рa.s}Š};º*` ;º*Øb.ó €;º*è r.s€ K.sÀr.óƒ L.s„@….ó„@L.s… ‡;º*xЇ;º*REPORT_MOUSE_POSITIONH À½ sx X Ô óy  c.Ì s| p  _0_àc.Ö ó| p  _0_ d.Ð ó} p  _0_ð\ ó~! €d.sƒ•ƒ;º*@ „;º*€àd.s„•„;º*(…;º*ˆ" $$‡;º*0€e.s‡•‡;º*ˆÀe.ó‡ˆ;º*!f.sˆ•ˆ;º*8ÀØ°Ö @â'ÞÐã `(0ë'ài.) ø,0ë'' ‚€i.Ð+ð[(`i. j.pa(ài.`j. r( j. j.Ps(`j.__builtin_hypotf__builtin_hypotl__builtin_log1pf__builtin_nextafterf__builtin_nexttowardf_STDIO_USES_IOSTREAM__need_mbstate_t__builtin_remainder__builtin_offsetof__builtin_roundloperator__imag__complex long double__builtin_cacosf__builtin_atan2f__builtin_exp10f 3-@4-];¨__builtin_ia32_cmpltss__builtin_ia32_minss__builtin_ia32_paddd__builtin_ia32_pcmpgtd__builtin_ia32_punpcklwd`‰.Œ‡ Ð[º ŒŒ ¥•;º*¨@X-Œ— " @77__builtin_memcmp" @D.sm" s;º*0 7; ;º*°PDC_CLIP_ACCESS_ERROR__builtin_snprintf6= ;º*¸*? 9p Y¡o __builtin_islower;D ;º*È'  @-'  @-@p.sz' @-Šz;º*¸° à{-—G  ' @-' @-`a.ó|ÇK 9pRl¡o ' @-EL 9ÐOl¡o '# @-`~-±M  @J.s'( @-À‰.±N  __builtin_classify_type'- @-Š€;º*` ;º*ðÌO 9 â!l¡o `-±P  L.sƒ „;º*__builtin___snprintf_chk__sync_fetch_and_sub_2)   Asave_key_modifiers__LDBL_MAX_EXP____STDC_VERSION_____int_ptrdiff_t_h_WCHAR_T_DEFINED__WCHAR_T_DEFINED__USE_POSIX199506_FILE_OFFSET_BITS__attribute_pure____stub___kernel_sinl) ðtA) 0uA_IO_DELETE_DONT_CLOSE_IO_IS_APPENDING_IO_FLAGS2_FORTIFY__codecvt_result__codecvt_do_length__codecvt_do_max_length_IO_fwide_maybe_incompatible X-Œ™ ÀY- ° #²;º*èZ- ´ ©¼;º*¦¾;º*/usr/include/bits/sys_errlist.h¡Í;º*p £Ï;º*]- Ü 'Þ;º*0) @vA) PvA) pvA) €vA)  vA__PRETTY_FUNCTION____builtin_va_argreinterpret_castcompatibility_aliasoperator delete []operator alignofoperator__real__) °wA) ÀwA__deleting_dtor à?.—ŒC  long unsigned intlong long unsigned intlong long unsignedshort unsigned int) xA) xAoverflow_arg_area å# V __builtin_va_list) xA__builtin_acoshf__builtin_acoshl__builtin_atan2l__builtin_atanhf) ðÕA__builtin_atanhl__builtin_copysign__builtin_copysignf__builtin_copysignl)  xA) ÖA) àxA) ðxA) yA__builtin_expm1f__builtin_expm1l) yA) 0yA__builtin_floorf) PyA) `yA) ÀyA) àyA) ðyA L.s†) zA ˆ;º* P ð¾óx p*,Χ __builtin_ia32_pcmpeqw128àq-ö #û;º*xàv. Þ ) ÖA__builtin_ia32_storehps) @yA) P A) X A) ` A) è#A) h A) p A) € A)  0A) A) ˜ A) ¨ A) H8A) ° A) À A) ¨0A) È A__builtin_ia32_pmovmskb128) °0A) Ð A) Ø A) pyA) €yA) yA)  yA) °yA) @ÖA) íA) PÖA) ÐyA) `ÖA) prA) zA) pÖA) zA) @zA) PzA) `zA) €zA) zA) °zA) ÀzA) 0íA) ÐzA) àzA) {A) {A  3š __builtin_sincosŠt;º*(__enum_type_info__pointer_type_infoGy ;º*ø …;º*p__FLT_MIN_10_EXP____DBL_DENORM_MIN__ ‰90§"®o  Ç-ËW  ¨à± às-àà _RUNE_T_DECLARED¦~9°[Ÿo €†.’ ¥9p,[Ÿo  v-ÕÙ  27 ;º*à ‡.8  18 ;º*Ð`x-:  ¯: ;º*è €‡.—;  µ; ;º*À8< ;º*˜à‡.>  *> 9`ŽY¡o `o.?  @z-—C  °D ;º*¨àz-E  `{-—E  `|-±J  àˆ.1K  EK 9Ql¡o q.1L  @‰.±L  ÆL 9àRl¡o  ‡;º*Ø ‰.1N  DN 9 Tl¡o ÄN 9ðUl¡o €~-1O  `r.±O  NP 9p‘l¡o ) 0{A) @{A) P{A) `{A) €ÖA) p{A) €{A) {A) °{A) @íA) À{A) Ð{A) PíA) à{A) vA) ð{A) |A) |A) °ÖA) 0|A) °vA) `íA) @|A) P|A) ÀvA) p|A) €|A) €íA) |A) °|A) À|A) ÐvA) Ð|A) à|A) ð|A) íA)  íA) ˆA) ÈA) ðìA) ØA) ðA)  «-A) wA) Û-A) @Û-A) `Û-A) T.A) °íA€. €À. ;8!‘.;°) 0wA) PwA)  wAÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGÐGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàGàG9ð‘Ηo 9€´"9  9À«›o ¦§`•-º*™o $9`‹›o +?º*8/-`•-º*™o D™Dº*0ª-º*I™Dº*Ø›o O™9€U™o cœ9€´Žo lœ9` Ø›o rœ9 ™o æ¥9€´Žo ï¥9ð‘Ø›o ô¥9 ™o æ¦9€´Žo ï¦9ð‘Ø›o ô¦9 ™o uâº*Öžo vâ; º*0@€â º*Øžo àGàGàGàGàGàGàGàGÐGÐGÐGÐGÐGÐGÐGÐG¼(¼(¼(¼(¼(¼(¼(¼( ½( ½( ½( ½( ½( ½( ½( ½(9ð‘Ηo 9€´9 ¼™Dº*0ª-º*Á™Dº*Ø›o Ç™9€U™o hž9€´Žo qž9ð‘Ø›o vž9 ™o ä¨9€´Žo í¨9ð‘Ø›o ò¨9 ™o å Š yp êΡ©ÌfŒ /1Dêk@Æ–$ûf¸‰UXçsOi>ŽhüÉ}˜çÐ$¡ K®<Ês»ÓVk~ Tß8;7ÆvRnbUOšÂt;2n¥Ò¯Tã÷2ÄääK,ü]’’N¨ƒô-6\É8aÉÕ^¼‹åæ‘3ø\d_~*fD‚ò8«]+#ÍËdÝ»´}ïup ;\ÑÚ‘¿±Kçmjæú;s—1Ó™tuj8ò(-íÞ ¯0Rž·p½ô§Ü‚ÁeŸCd´v÷p^=?¯Wa¿va­µn¬E­^‡­ÃV÷þ7ùØ¿OGº-BSê€ñãA—k‹ÖÈy÷ºKˆ•B #Ùk8«šÝÉòˆÑJº8‘K—ʧÑê ¯’‹#PQâÚŒÓìVÕnßû£‘/…MˆU`vì§XSÒsoapdenovo2-240+dfsg.orig/sparsePregraph/inc/multi_threads.h0000644000000000000000000000270712166703653022767 0ustar rootroot/* * inc/multi_threads.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef _MULTI_THREADS_H #define _MULTI_THREADS_H #include "stdinc.h" typedef struct parameter { unsigned char threadID; struct hashtable2 * ht; struct preArc_array * preArcs; //for building preArc ... struct vertex_hash2 * v_ht; //for building preArc ... int cut_off_len; int K_size; int gap; unsigned char * mainSignal; unsigned char * selfSignal; } PARAMETER; void creatThrds ( pthread_t * threads, PARAMETER * paras ); void * threadRoutine ( void * para ); void thread_wait ( pthread_t * threads ); void sendWorkSignal ( unsigned char SIG, unsigned char * thrdSignals ); #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/faidx.h0000644000000000000000000000622412166703653021214 0ustar rootroot/* The MIT License Copyright (c) 2008 Genome Research Ltd (GRL). Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* Contact: Heng Li */ #ifndef FAIDX_H #define FAIDX_H /*! @header Index FASTA files and extract subsequence. @copyright The Wellcome Trust Sanger Institute. */ struct __faidx_t; typedef struct __faidx_t faidx_t; #ifdef __cplusplus extern "C" { #endif /*! @abstract Build index for a FASTA or razip compressed FASTA file. @param fn FASTA file name @return 0 on success; or -1 on failure @discussion File "fn.fai" will be generated. */ int fai_build ( const char * fn ); /*! @abstract Distroy a faidx_t struct. @param fai Pointer to the struct to be destroyed */ void fai_destroy ( faidx_t * fai ); /*! @abstract Load index from "fn.fai". @param fn File name of the FASTA file */ faidx_t * fai_load ( const char * fn ); /*! @abstract Fetch the sequence in a region. @param fai Pointer to the faidx_t struct @param reg Region in the format "chr2:20,000-30,000" @param len Length of the region @return Pointer to the sequence; null on failure @discussion The returned sequence is allocated by malloc family and should be destroyed by end users by calling free() on it. */ char * fai_fetch ( const faidx_t * fai, const char * reg, int * len ); /*! @abstract Fetch the number of sequences. @param fai Pointer to the faidx_t struct @return The number of sequences */ int faidx_fetch_nseq ( const faidx_t * fai ); /*! @abstract Fetch the sequence in a region. @param fai Pointer to the faidx_t struct @param c_name Region name @param p_beg_i Beginning position number (zero-based) @param p_end_i End position number (zero-based) @param len Length of the region @return Pointer to the sequence; null on failure @discussion The returned sequence is allocated by malloc family and should be destroyed by end users by calling free() on it. */ char * faidx_fetch_seq ( const faidx_t * fai, char * c_name, int p_beg_i, int p_end_i, int * len ); #ifdef __cplusplus } #endif #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/global.h0000644000000000000000000000447112166703653021363 0ustar rootroot/* * inc/global.h * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #ifndef _GLOBAL_H #define _GLOBAL_H #include "stdinc.h" #include "io_func.h" #ifdef __APPLE__ #include "spinLock.h" #endif //the definitions @see global.cpp extern char shortrdsfile[256];//in lib file extern char graphfile[256];//out prefix extern int NodeCovTh; extern int EdgeCovTh;//BE :build edge ,BPA:build preArc extern int K_size; extern int gap; extern uint64_t GenomeSize; extern int solve; // solve reapeat or not extern int run_mode; extern int thrd_num_s; extern size_t * edge_cnt_total ; //used int lock strategy extern size_t * bucket_count_total ; //used in lock strategy //for io thread @see io_func.h extern string * seq_t; extern int io_ready; extern int read_num; extern string * read_buf0; extern string * read_buf1; extern int io_stat0; //must be one, if io_stat0 =0 ,the io thread will work immediately extern int io_stat1; extern size_t reads_all_num; extern int max_rd_len; extern int min_rd_len; //for the lock strategy ... extern pthread_spinlock_t * locks; extern unsigned int * mark_on_edge; extern pthread_spinlock_t * s_locks; extern struct edge_path_buffer ** path_buffer; extern unsigned long long buff_size; extern unsigned int max_path_length; //max_path_length-1 is the real max path length, because the first int of buffer record the path length extern FILE * mark_fp ; // extern FILE * path_fp ; // extern pthread_mutex_t file_lock;// extern int debug; #endif soapdenovo2-240+dfsg.orig/sparsePregraph/inc/seq_util.h0000644000000000000000000002425512166703653021752 0ustar rootroot/* * inc/seq_util.h * * This file is part of SOAPdenovo. * * Part of this file is refered and modified from SparseAssembler * (See ). * */ #ifndef _SEQ_UTIL_H #define _SEQ_UTIL_H #include "stdinc.h" #include "core.h" extern inline void Init_Read ( string & seq, struct read_t & read ); extern inline uint64_t * str2bitsarr ( const char * c_str, int len, uint64_t * b_str, int arr_sz ); extern inline char * bitsarr2str ( uint64_t * b_seq, int len, char * c_str, int arr_sz ); extern inline void get_sub_arr ( uint64_t * bitsarr_in, int bitsarr_len, int begin_pos, int sub_sz, uint64_t * bitsarr_out ); extern inline void L_shift_NC ( uint64_t * bitsarr, int shift_sz, int arr_sz ); extern inline void R_shift_NC ( uint64_t * bitsarr, int shift_sz, int arr_sz ); extern inline int uint64_t_cmp ( uint64_t * A, uint64_t * B, int Kmer_arr_sz ); extern inline uint64_t * get_rev_comp_seq_arr ( uint64_t * seq_arr, int seq_size, int arr_sz ); extern inline uint64_t get_rev_comp_seq ( uint64_t seq, int seq_size ); extern inline uint64_t MurmurHash64A ( const void * key, int len, unsigned int seed ); inline void Init_Read ( string & seq, struct read_t & read ) { read.readLen = ( int ) seq.size(); int Read_arr_sz = read.readLen / 32 + 1; int rem = read.readLen % 32; if ( rem == 0 ) {Read_arr_sz--;} str2bitsarr ( seq.c_str(), ( int ) seq.size(), read.read_bits, Read_arr_sz ); } inline uint64_t * str2bitsarr ( const char * c_str, int len, uint64_t * b_str, int arr_sz ) { for ( int k = 0; k < arr_sz; ++k ) { b_str[k] = 0; } int arr_sz_needed = len / 32 + 1; int rem = len % 32; if ( rem == 0 ) {arr_sz_needed--;} int beg_arr_idx = arr_sz - arr_sz_needed; if ( rem == 0 && arr_sz_needed > 0 ) {rem = 32;} for ( int k = 0; k < len; k++ ) { if ( rem == 0 ) {beg_arr_idx++; rem = 32;} switch ( c_str[k] ) { case ( 'A' ) : case ( 'a' ) : case ( '0' ) : b_str[beg_arr_idx] <<= 2; rem--; break; case ( 'C' ) : case ( 'c' ) : case ( '1' ) : b_str[beg_arr_idx] <<= 2; ++b_str[beg_arr_idx]; rem--; break; case 'G': case 'g': case '2': b_str[beg_arr_idx] <<= 1; ++b_str[beg_arr_idx]; b_str[beg_arr_idx] <<= 1; rem--; break; case 'T': case 't': case '3': b_str[beg_arr_idx] <<= 1; ++b_str[beg_arr_idx]; b_str[beg_arr_idx] <<= 1; ++b_str[beg_arr_idx]; rem--; break; default: return b_str; } } return b_str; } inline char * bitsarr2str ( uint64_t * b_seq, int len, char * c_str, int arr_sz ) { int tot_bits = arr_sz * 64; for ( int i = 0; i < len; ++i ) { uint64_t temp, temp2[100]; for ( int k = 0; k < arr_sz; ++k ) { temp2[k] = b_seq[k]; } L_shift_NC ( temp2, tot_bits - ( len - i ) * 2, arr_sz ); R_shift_NC ( temp2, tot_bits - 2, arr_sz ); temp = temp2[arr_sz - 1]; switch ( temp ) { case 0: c_str[i] = 'A'; break; case 1: c_str[i] = 'C'; break; case 2: c_str[i] = 'G'; break; case 3: c_str[i] = 'T'; break; } } c_str[len] = '\0'; return c_str; } inline void get_sub_arr ( uint64_t * bitsarr_in, int bitsarr_len, int begin_pos, int sub_sz, uint64_t * bitsarr_out ) { if ( bitsarr_len < sub_sz ) {cout << "Error! Input kmer too short." << bitsarr_len << " " << sub_sz << endl; return;} int arr_sz_in = bitsarr_len / 32 + 1; int rem = bitsarr_len % 32; if ( rem == 0 ) {arr_sz_in--;} int arr_sz_out = sub_sz / 32 + 1; if ( sub_sz % 32 == 0 ) {arr_sz_out--;} uint64_t temp_arr[10]; memset ( temp_arr, 0, sizeof ( temp_arr ) ); memset ( bitsarr_out, 0, sizeof ( uint64_t ) *arr_sz_out ); int rem2 = ( 32 - rem + begin_pos ) % 32; int block_beg = ( 32 - rem + begin_pos ) / 32; if ( rem == 0 ) {block_beg--;} int rem3 = ( 32 - rem + begin_pos + sub_sz ) % 32; int block_end = ( 32 - rem + begin_pos + sub_sz ) / 32; if ( rem3 != 0 ) {rem3 = 32 - rem3;} else { block_end--; } if ( rem == 0 ) {block_end--;} int orig_sz = ( block_end - block_beg + 1 ); memcpy ( temp_arr, &bitsarr_in[block_beg], orig_sz * sizeof ( uint64_t ) ); L_shift_NC ( temp_arr, rem2 * 2, orig_sz ); R_shift_NC ( temp_arr, ( rem2 + rem3 ) % 32 * 2, arr_sz_out ); memcpy ( bitsarr_out, temp_arr, arr_sz_out * sizeof ( uint64_t ) ); } inline void L_shift_NC ( uint64_t * bitsarr, int shift_sz, int arr_sz ) { uint64_t temp_arr[100]; for ( int i = 0; i < arr_sz; ++i ) { temp_arr[i] = 0; } int jmp = shift_sz / 64; int offset = shift_sz % 64; for ( int i = 0; i < arr_sz; ++i ) { if ( i + jmp + 1 < arr_sz ) { uint64_t tt = 0; if ( offset == 0 ) { tt = 0; } else { tt = ( bitsarr[i + jmp + 1] >> ( 64 - offset ) ); } temp_arr[i] = ( ( bitsarr[i + jmp] << offset ) | tt ); } if ( i + jmp + 1 == arr_sz ) {temp_arr[i] = bitsarr[i + jmp] << offset;} if ( i + jmp + 1 > arr_sz ) {temp_arr[i] = 0;} } for ( int i = 0; i < arr_sz; ++i ) { bitsarr[i] = temp_arr[i]; } } inline void R_shift_NC ( uint64_t * bitsarr, int shift_sz, int arr_sz ) { uint64_t temp_arr[100]; for ( int i = 0; i < arr_sz; ++i ) { temp_arr[i] = 0; } int jmp = shift_sz / 64; int offset = shift_sz % 64; if ( offset == 0 ) //to fix the move 64bit bug { for ( int i = arr_sz - 1; i >= 0; --i ) { if ( i - jmp > 0 ) {temp_arr[i] = bitsarr[i - jmp];} if ( i - jmp == 0 ) {temp_arr[i] = bitsarr[i - jmp];} if ( i - jmp < 0 ) {temp_arr[i] = 0;} } } else { for ( int i = arr_sz - 1; i >= 0; --i ) { if ( i - jmp > 0 ) {temp_arr[i] = ( bitsarr[i - jmp] >> offset ) | ( bitsarr[i - jmp - 1] << ( 64 - offset ) );} if ( i - jmp == 0 ) {temp_arr[i] = ( bitsarr[i - jmp] >> offset );} if ( i - jmp < 0 ) {temp_arr[i] = 0;} } } for ( int i = 0; i < arr_sz; ++i ) { bitsarr[i] = temp_arr[i]; } } inline int uint64_t_cmp ( uint64_t * A, uint64_t * B, int Kmer_arr_sz ) { int flag = 0; for ( int jj = 0; jj < Kmer_arr_sz; ++jj ) { if ( A[jj] > B[jj] ) { flag = 1; break; } if ( A[jj] < B[jj] ) { flag = -1; break; } if ( A[jj] == B[jj] ) { continue; } } return flag; } //for 63mer inline uint64_t * get_rev_comp_seq_arr ( uint64_t * seq_arr, int seq_size, int arr_sz ) { if ( seq_size < 32 && arr_sz == 2 ) { seq_arr[1] = get_rev_comp_seq ( seq_arr[1], seq_size ); if ( seq_arr[0] != 0 ) { fprintf ( stderr, "ERROR: in get_rev_comp_seq_arr \n" ); exit ( -1 ); } return seq_arr; } int tot_bits = arr_sz * 64; for ( int i = 0; i < arr_sz; ++i ) { seq_arr[i] = ~seq_arr[i]; seq_arr[i] = ( ( seq_arr[i] & 0x3333333333333333 ) << 2 ) | ( ( seq_arr[i] & 0xCCCCCCCCCCCCCCCC ) >> 2 ); seq_arr[i] = ( ( seq_arr[i] & 0x0F0F0F0F0F0F0F0F ) << 4 ) | ( ( seq_arr[i] & 0xF0F0F0F0F0F0F0F0 ) >> 4 ); seq_arr[i] = ( ( seq_arr[i] & 0x00FF00FF00FF00FF ) << 8 ) | ( ( seq_arr[i] & 0xFF00FF00FF00FF00 ) >> 8 ); seq_arr[i] = ( ( seq_arr[i] & 0x0000FFFF0000FFFF ) << 16 ) | ( ( seq_arr[i] & 0xFFFF0000FFFF0000 ) >> 16 ); seq_arr[i] = ( ( seq_arr[i] & 0x00000000FFFFFFFF ) << 32 ) | ( ( seq_arr[i] & 0xFFFFFFFF00000000 ) >> 32 ); } int j = 0, k = arr_sz - 1; for ( ; j < k; ++j, --k ) { uint64_t temp; temp = seq_arr[j]; seq_arr[j] = seq_arr[k]; seq_arr[k] = temp; } R_shift_NC ( seq_arr, tot_bits - ( seq_size * 2 ), arr_sz ); return seq_arr; } inline uint64_t get_rev_comp_seq ( uint64_t seq, int seq_size ) { seq = ~seq; seq = ( ( seq & 0x3333333333333333 ) << 2 ) | ( ( seq & 0xCCCCCCCCCCCCCCCC ) >> 2 ); seq = ( ( seq & 0x0F0F0F0F0F0F0F0F ) << 4 ) | ( ( seq & 0xF0F0F0F0F0F0F0F0 ) >> 4 ); seq = ( ( seq & 0x00FF00FF00FF00FF ) << 8 ) | ( ( seq & 0xFF00FF00FF00FF00 ) >> 8 ); seq = ( ( seq & 0x0000FFFF0000FFFF ) << 16 ) | ( ( seq & 0xFFFF0000FFFF0000 ) >> 16 ); seq = ( ( seq & 0x00000000FFFFFFFF ) << 32 ) | ( ( seq & 0xFFFFFFFF00000000 ) >> 32 ); return seq >> ( 64 - ( seq_size * 2 ) ); } //for 64bit platform inline uint64_t MurmurHash64A ( const void * key, int len, unsigned int seed ) { const uint64_t m = 0xc6a4a7935bd1e995; const int r = 47; uint64_t h = seed ^ ( len * m ); const uint64_t * data = ( const uint64_t * ) key; const uint64_t * end = data + ( len / 8 ); while ( data != end ) { uint64_t k = *data++; k *= m; k ^= k >> r; k *= m; h ^= k; h *= m; } const unsigned char * data2 = ( const unsigned char * ) data; switch ( len & 7 ) { case 7: h ^= uint64_t ( data2[6] ) << 48; case 6: h ^= uint64_t ( data2[5] ) << 40; case 5: h ^= uint64_t ( data2[4] ) << 32; case 4: h ^= uint64_t ( data2[3] ) << 24; case 3: h ^= uint64_t ( data2[2] ) << 16; case 2: h ^= uint64_t ( data2[1] ) << 8; case 1: h ^= uint64_t ( data2[0] ); h *= m; }; h ^= h >> r; h *= m; h ^= h >> r; return h; } //for 32bit platform inline uint64_t MurmurHash64B ( const void * key, int len, unsigned int seed ) { const unsigned int m = 0x5bd1e995; const int r = 24; unsigned int h1 = seed ^ len; unsigned int h2 = 0; const unsigned int * data = ( const unsigned int * ) key; while ( len >= 8 ) { unsigned int k1 = *data++; k1 *= m; k1 ^= k1 >> r; k1 *= m; h1 *= m; h1 ^= k1; len -= 4; unsigned int k2 = *data++; k2 *= m; k2 ^= k2 >> r; k2 *= m; h2 *= m; h2 ^= k2; len -= 4; } if ( len >= 4 ) { unsigned int k1 = *data++; k1 *= m; k1 ^= k1 >> r; k1 *= m; h1 *= m; h1 ^= k1; len -= 4; } switch ( len ) { case 3: h2 ^= ( ( unsigned char * ) data ) [2] << 16; case 2: h2 ^= ( ( unsigned char * ) data ) [1] << 8; case 1: h2 ^= ( ( unsigned char * ) data ) [0]; h2 *= m; }; h1 ^= h2 >> 18; h1 *= m; h2 ^= h1 >> 22; h2 *= m; h1 ^= h2 >> 17; h1 *= m; h2 ^= h1 >> 19; h2 *= m; uint64_t h = h1; h = ( h << 32 ) | h2; return h; } #endif soapdenovo2-240+dfsg.orig/sparsePregraph/convert_soapdenovo.cpp0000644000000000000000000002633112166703653023621 0ustar rootroot/* * convert_soapdenovo.cpp * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "global.h" #include "stdinc.h" #include "core.h" #include "convert_soapdenovo.h" #include "sparse_kmer.h" #include "zlib.h" // can be optimized ... /************************************************* Function: convert_kmer Description: convert sparse kmer to soapdenovo format .. A 0 A 0 C 1 --> C 1 T 3 T 2 G 2 G 3 Input: 1. sparse_kmer: sparse-kmer 2. K_size: kmer size Output: 1. sparse_kmer soapdenovo format kmer Return: None. *************************************************/ void convert_kmer ( kmer_t2 * sparse_kmer, int K_size ) { uint64_t tmp, tmp_res; int i, j, index, arr_sz, base; index = K_size / 32; arr_sz = sizeof ( kmer_t2 ) / sizeof ( uint64_t ); for ( i = 0; i <= index; i++ ) { tmp = ( sparse_kmer->kmer ) [arr_sz - 1 - i]; tmp_res = 0; for ( j = 0; j < 32; j++ ) { base = tmp & 3; switch ( base ) { case 0 : break; case 1 : tmp_res |= ( 1LLU << 2 * j ); break; case 2: tmp_res |= ( 3LLU << 2 * j ); break; case 3: tmp_res |= ( 2LLU << 2 * j ); break; } tmp = tmp >> 2; } ( sparse_kmer->kmer ) [arr_sz - 1 - i] = tmp_res; } /* uint64_t high=0,low=0; int chr; if(K_size>=33){ for(int i=0;i>2; } for(int i=0;i<32;++i){ chr = sparse_kmer[1] & 3; switch(chr){ case 0: break; case 1: low|=(1LLU << 2 * i); break; case 2: low|=(3LLU << 2 * i); break; case 3: low|=(2LLU << 2 * i); break; } sparse_kmer[1] = sparse_kmer[1]>>2; } }else{ for(int i=0;i>2; } } sparse_kmer[0] = high; sparse_kmer[1] = low; */ } /************************************************* Function: fastReverseComp Description: fastReverseComp soapdenovo format kmer Input: 1. kmer2: soapdenovo fomat kmer 2. seq_size: kmer size Output: 1. kmer2: reversed compliment kmer Return: None. *************************************************/ static void fastReverseComp ( kmer_t2 * kmer2, int seq_size ) { int arr_sz; uint64_t * seq_arr; arr_sz = sizeof ( kmer_t2 ) / sizeof ( uint64_t ); //= 2 or 4 seq_arr = kmer2->kmer; int tot_bits = arr_sz * 64; for ( int i = 0; i < arr_sz; ++i ) { seq_arr[i] ^= 0xAAAAAAAAAAAAAAAALLU; seq_arr[i] = ( ( seq_arr[i] & 0x3333333333333333 ) << 2 ) | ( ( seq_arr[i] & 0xCCCCCCCCCCCCCCCC ) >> 2 ); seq_arr[i] = ( ( seq_arr[i] & 0x0F0F0F0F0F0F0F0F ) << 4 ) | ( ( seq_arr[i] & 0xF0F0F0F0F0F0F0F0 ) >> 4 ); seq_arr[i] = ( ( seq_arr[i] & 0x00FF00FF00FF00FF ) << 8 ) | ( ( seq_arr[i] & 0xFF00FF00FF00FF00 ) >> 8 ); seq_arr[i] = ( ( seq_arr[i] & 0x0000FFFF0000FFFF ) << 16 ) | ( ( seq_arr[i] & 0xFFFF0000FFFF0000 ) >> 16 ); seq_arr[i] = ( ( seq_arr[i] & 0x00000000FFFFFFFF ) << 32 ) | ( ( seq_arr[i] & 0xFFFFFFFF00000000 ) >> 32 ); } int j = 0, k = arr_sz - 1; for ( ; j < k; ++j, --k ) { uint64_t temp; temp = seq_arr[j]; seq_arr[j] = seq_arr[k]; seq_arr[k] = temp; } R_shift_NC ( seq_arr, tot_bits - ( seq_size * 2 ), arr_sz ); } struct classcomp { bool operator() ( const kmer_t2 & t1, const kmer_t2 & t2 ) const { int Kmer_arr_sz = sizeof ( kmer_t2 ) / sizeof ( uint64_t ); for ( int jj = 0; jj < Kmer_arr_sz; ++jj ) { if ( ( t1.kmer ) [jj] < ( t2.kmer ) [jj] ) { return 1; } else if ( ( t1.kmer ) [jj] > ( t2.kmer ) [jj] ) { return 0; } continue; } return 0; /* old if((t1.kmer)[0] < (t2.kmer)[0]){ return 1; }else if((t1.kmer)[0] == (t2.kmer)[0]){ return (t1.kmer)[1] < (t2.kmer)[1]; }else{ return 0; }*/ } }; /************************************************* Function: convert Description: converts *.sparse.edge to *.edge.gz *.vertex Input: 1. sparse_edge_file: sparse edge file 2. K_size: kmer size 3. output_prefix output prefix Output: None. Return: None. *************************************************/ void convert ( char * sparse_edge_file, int K_size, char * output_prefix ) { if ( run_mode != 0 ) { char temp[256]; sprintf ( temp, "%s.preGraphBasic", output_prefix ); FILE * fp = fopen ( temp, "r" ); char line[1024]; fgets ( line, 1024, fp ); fgets ( line, 1024, fp ); fgets ( line, 1024, fp ); fclose ( fp ); sscanf ( line, "%s %d %s %d", temp, &max_rd_len, temp, &min_rd_len ); } FILE * fin, *fout2, *fout3; fin = fopen ( sparse_edge_file, "r" ); gzFile fout; char temp[256]; sprintf ( temp, "%s.edge.gz", output_prefix ); fout = gzopen ( temp, "w" ); //fout= fopen(temp, "w");//edge //write as gzip file sprintf ( temp, "%s.vertex", output_prefix ); fout2 = fopen ( temp, "w" ); sprintf ( temp, "%s.preGraphBasic", output_prefix ); fout3 = fopen ( temp, "w" ); if ( !fin || !fout || !fout2 || !fout3 ) { fprintf ( stderr, "can't open file %s\n", sparse_edge_file ); exit ( 1 ); } //cout << "right 0"< vertex_nodes; size_t edge_counter = 0, vertex_counter = 0; int j = 0; //cout << "right 1"<' ) //get one edge length, from vertex, to vertex,cvg,bal { edge_counter++; #ifdef _63MER_ sscanf ( line + 7, "%d,%llx %llx,%llx %llx,cvg %d,%d", &edge_len, & ( from_kmer.kmer ) [0], & ( from_kmer.kmer ) [1], & ( to_kmer.kmer ) [0], & ( to_kmer.kmer ) [1], &cvg, &bal_ed ); // from_kmer to_kmer is of no use here #endif #ifdef _127MER_ sscanf ( line + 7, "%d,%llx %llx %llx %llx,%llx %llx %llx %llx,cvg %d,%d", &edge_len, & ( from_kmer.kmer ) [0], & ( from_kmer.kmer ) [1], & ( from_kmer.kmer ) [2], & ( from_kmer.kmer ) [3], & ( to_kmer.kmer ) [0], & ( to_kmer.kmer ) [1], & ( to_kmer.kmer ) [2], & ( to_kmer.kmer ) [3], &cvg, &bal_ed ); // from_kmer to_kmer is of no use here #endif if ( edge_len == 1 ) { cvg = 0; } else { cvg *= 10; } convert_kmer ( &from_kmer, K_size ); convert_kmer ( &to_kmer, K_size ); #ifdef _63MER_ gzprintf ( fout, ">length %d,%llx %llx,%llx %llx,cvg %d,%d\n", edge_len, ( from_kmer.kmer ) [0], ( from_kmer.kmer ) [1], ( to_kmer.kmer ) [0], ( to_kmer.kmer ) [1], cvg, bal_ed ); #endif #ifdef _127MER_ gzprintf ( fout, ">length %d,%llx %llx %llx %llx,%llx %llx %llx %llx,cvg %d,%d\n", edge_len, ( from_kmer.kmer ) [0], ( from_kmer.kmer ) [1], ( from_kmer.kmer ) [2], ( from_kmer.kmer ) [3], ( to_kmer.kmer ) [0], ( to_kmer.kmer ) [1], ( to_kmer.kmer ) [2], ( to_kmer.kmer ) [3], cvg, bal_ed ); #endif if ( bal_ed ) { edge_counter++; } kmer_t2 f_kmer = from_kmer; fastReverseComp ( &f_kmer, K_size ); if ( kmerCompare ( &f_kmer, &from_kmer ) < 0 ) { from_kmer = f_kmer; } vertex_nodes[from_kmer]++; f_kmer = to_kmer; fastReverseComp ( &f_kmer, K_size ); if ( kmerCompare ( &f_kmer, &to_kmer ) < 0 ) { to_kmer = f_kmer; } vertex_nodes[to_kmer]++; start = 1; j = 0; } else { //print the sequence if ( start == 1 ) { //skip the first kmer int len = strlen ( line ); if ( line[len - 1] == '\n' ) { line[len - 1] == '\0'; len --; } for ( int i = K_size; i < len; i++ ) { j++; gzprintf ( fout, "%c", line[i] ); if ( j % 100 == 0 ) { gzprintf ( fout, "\n" ); } } edge_len -= ( len - K_size ); if ( edge_len == 0 && j % 100 != 0 ) { gzprintf ( fout, "\n" ); } start = 2; } else //start = 2 { if ( line[0] == '\n' ) { continue; } int len = strlen ( line ); if ( line[len - 1] == '\n' ) { line[len - 1] == '\0'; len --; } for ( int i = 0; i < len; i++ ) { j++; gzprintf ( fout, "%c", line[i] ); if ( j % 100 == 0 ) { gzprintf ( fout, "\n" ); } } edge_len -= len; if ( edge_len == 0 && j % 100 != 0 ) { gzprintf ( fout, "\n" ); } } } } //fprintf(stderr,"size of map: %llu\n",vertex_nodes.size()); map::iterator it; for ( it = vertex_nodes.begin(); it != vertex_nodes.end(); ++it ) { vertex_counter++; #ifdef _63MER_ fprintf ( fout2, "%llx %llx ", ( ( *it ).first.kmer ) [0], ( ( *it ).first.kmer ) [1] ); #endif #ifdef _127MER_ fprintf ( fout2, "%llx %llx %llx %llx ", ( ( *it ).first.kmer ) [0], ( ( *it ).first.kmer ) [1], ( ( *it ).first.kmer ) [2], ( ( *it ).first.kmer ) [3] ); #endif if ( vertex_counter % 8 == 0 ) { fprintf ( fout2, "\n" ); } } fprintf ( fout3, "VERTEX %lu K %d\n", vertex_counter, K_size ); fprintf ( fout3, "EDGEs %lu\n", edge_counter ); fprintf ( stderr, "%llu edges and %llu vertexes constructed.\n", edge_counter, vertex_counter ); fprintf ( fout3, "MaxReadLen %d MinReadLen %d MaxNameLen 256\n", max_rd_len, min_rd_len ); fclose ( fin ); gzclose ( fout ); fclose ( fout2 ); fclose ( fout3 ); } soapdenovo2-240+dfsg.orig/sparsePregraph/change.log0000644000000000000000000000066712166703653021134 0ustar rootroot1.change the edge node old: struct edge_node { uint64_t edge£º50£¬edge_cov:7,len:6,used:1£» struct edge_node *nxt_edge; }; now: struct edge_node { uint64_t edge; uint64_t edge_cov:7,len:6,used:1,deleted:1; struct edge_node *nxt_edge; }; so, the LoadGraph... function can't work when performed on an old hash data set. 2. support bam format 3. support -R 4. support 127mer 5. build vertex K_size -> gap . soapdenovo2-240+dfsg.orig/sparsePregraph/main.cpp0000644000000000000000000000046312166703653020626 0ustar rootroot#include #include extern "C" int call_pregraph_sparse ( int argc, char ** argv ); int main ( int argc, char ** argv ) { fprintf ( stderr, "\nVersion 1.0.3: released on July 13th, 2012\nCompile %s\t%s\n\n", __DATE__, __TIME__ ); call_pregraph_sparse ( argc, argv ); } soapdenovo2-240+dfsg.orig/sparsePregraph/build_edge.cpp0000644000000000000000000011074512166703653021772 0ustar rootroot/* * build_edge.cpp * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "core.h" #include "stdinc.h" #include "build_edge.h" #include "seq_util.h" #include "zlib.h" #include "sparse_kmer.h" /************************************************* Function: RemovingWeakNodesAndEdges2 Description: 1. Removes the nodes whose frequencies are not greater than threadhold NodeCovTh. 2. Removes the kmer-edges (the connections between nodes) whose frequencies are not greater than threadhold EdgeCovTh. Some statistics function here temporarily added. Input: 1. ht: the graph hash table 2. K_size: kmer size 3. NodeCovTh: the threadhold for removing low coverage nodes 4. EdgeCovTh: the threadhold for removing low coverage kmer-edges 5. bucket_cnt: the current bucket number 6. edge_cnt: the current kmer-edge number Output: 1. bucket_cnt: the bucket number after removing weak nodes and kmer-edges 2. edge_cnt: the kmer-edge number after removing weak nodes and kmer-edges Return: None. *************************************************/ void RemovingWeakNodesAndEdges2 ( hashtable2 * ht, int K_size, int NodeCovTh, int EdgeCovTh, size_t * bucket_cnt, size_t * edge_cnt ) { stat_edge_num ( ht ); stat_edge_cvg_len ( ht ); int Removed_Nodes_cnt = 0, Removed_Edges_cnt = 0; bucket2 * bktptr = NULL, *bktptr_tmp = NULL; bucket2 ** bktp2p = NULL; edge_node * edge_ptr = NULL, *next_edge = NULL, *edge_tmp = NULL; int smaller; fprintf ( stderr, "Start to remove weak nodes and kmer-edges.\n" ); /* for(size_t i=0;iht_sz;++i) { bktptr=ht->store_pos[i]; while(bktptr!=NULL) { if(bktptr->kmer_info.cov1==0)printf("zero\n"); bktptr=bktptr->nxt_bucket; } }*/ //removing weak nodes for ( size_t i = 0; i < ht->ht_sz; ++i ) { bktptr = ht->store_pos[i]; while ( bktptr != NULL ) { if ( bktptr->kmer_info.cov1 <= NodeCovTh ) { bktptr->kmer_info.deleted = 1; Removed_Nodes_cnt++; edge_ptr = bktptr->kmer_info.right; while ( edge_ptr ) { edge_ptr->used = 1; edge_ptr = edge_ptr->nxt_edge; Removed_Edges_cnt++; } edge_ptr = bktptr->kmer_info.left; while ( edge_ptr ) { edge_ptr->used = 1; edge_ptr = edge_ptr->nxt_edge; Removed_Edges_cnt++; } } bktptr = bktptr->nxt_bucket; } } //removing dead edges for ( size_t i = 0; i < ht->ht_sz; ++i ) { bktptr = ht->store_pos[i]; while ( bktptr != NULL ) { edge_ptr = bktptr->kmer_info.right; while ( edge_ptr ) { if ( edge_ptr->edge_cov <= EdgeCovTh ) { edge_ptr->used = 1; //becasuse the cvg of edges is symmetrial, so it's ok Removed_Edges_cnt++; } else { bktptr_tmp = lastKmer ( ht, K_size, bktptr, edge_ptr, 0, smaller ); if ( !bktptr_tmp ) { fprintf ( stderr, "ERROR: to node not found error!\n" ); exit ( -1 ); } if ( bktptr_tmp ->kmer_info.deleted ) { edge_ptr->used = 1; Removed_Edges_cnt++; } } edge_ptr = edge_ptr->nxt_edge; } edge_ptr = bktptr->kmer_info.left; while ( edge_ptr ) { if ( edge_ptr->edge_cov <= EdgeCovTh ) { edge_ptr->used = 1; //becasuse the cvg of edges is symmetrial, so it's ok Removed_Edges_cnt++; } else { bktptr_tmp = lastKmer ( ht, K_size, bktptr, edge_ptr, 1, smaller ); if ( !bktptr_tmp ) { fprintf ( stderr, "ERROR: to node not found error! \n" ); exit ( -1 ); } if ( bktptr_tmp ->kmer_info.deleted ) { edge_ptr->used = 1; Removed_Edges_cnt++; } } edge_ptr = edge_ptr->nxt_edge; } bktptr = bktptr->nxt_bucket; } } for ( size_t i = 0; i < ht->ht_sz; ++i ) { bktptr = ht->store_pos[i]; bktp2p = & ( ht->store_pos[i] ); while ( bktptr != NULL ) { edge_ptr = bktptr->kmer_info.right; while ( edge_ptr ) { next_edge = edge_ptr->nxt_edge; if ( edge_ptr->used ) { removeEdge ( bktptr, edge_ptr, 0 ); //Removed_Edges_cnt2++; } edge_ptr = next_edge; } edge_ptr = bktptr->kmer_info.left; while ( edge_ptr ) { next_edge = edge_ptr->nxt_edge; if ( edge_ptr->used ) { removeEdge ( bktptr, edge_ptr, 1 ); //Removed_Edges_cnt2++; } edge_ptr = next_edge; } bktptr_tmp = bktptr->nxt_bucket; if ( bktptr->kmer_info.deleted ) { free ( bktptr ); ( *bktp2p ) = bktptr_tmp; //Removed_Nodes_cnt2++; } else { bktp2p = & ( bktptr->nxt_bucket ); } bktptr = bktptr_tmp; } } fprintf ( stderr, "%llu nodes removed.\n", Removed_Nodes_cnt ); fprintf ( stderr, "%llu edges removed.\n", Removed_Edges_cnt ); fprintf ( stderr, "\n" ); ( *bucket_cnt ) -= Removed_Nodes_cnt; ( *edge_cnt ) -= Removed_Edges_cnt; } /************************************************* Function: removeMinorTips Description: Removes minor tips whose length are not longer than a threadhold usually set to 2*Kmer. Input: 1. ht: the graph hash table 2. K_size: kmer size 3. cut_len_tip: the threadhold for tips' length Output: 1. tip_c: useless Return: None. *************************************************/ void removeMinorTips ( struct hashtable2 * ht, int K_size, int cut_len_tip, int & tip_c ) { mask1in1out ( ht ); bucket2 * bktptr = NULL; size_t flag = 1; size_t total = 0; int j = 0; while ( flag ) { flag = 0; for ( size_t i = 0; i < ht->ht_sz; ++i ) { bktptr = ht->store_pos[i]; while ( bktptr != NULL ) { flag += clipTipFromNode ( ht, K_size, bktptr, cut_len_tip ); bktptr = bktptr->nxt_bucket; } } j++; if ( flag ) { fprintf ( stderr, "%llu tips removed in cycle %d.\n\n", flag, j ); total += flag; } else { fprintf ( stderr, "Total %llu tips removed.\n", total ); } if ( flag ) { mask1in1out ( ht ); } } } /************************************************* Function: mask1in1out Description: Marks "1 in 1 out" node linear. Input: 1. ht: the graph hashtable Output: None. Return: None. *************************************************/ static void mask1in1out ( hashtable2 * ht ) { size_t total = 0, linear = 0; static int call_times; call_times++; for ( size_t i = 0; i < ht->ht_sz; ++i ) { struct bucket2 * bkt_ptr = ht->store_pos[i]; while ( bkt_ptr ) { total++;//for stat if ( ( bkt_ptr->kmer_info.left != NULL && bkt_ptr->kmer_info.left->nxt_edge == NULL ) && ( bkt_ptr->kmer_info.right != NULL && bkt_ptr->kmer_info.right->nxt_edge == NULL ) ) { bkt_ptr->kmer_info.linear = 1; linear++;//for stat } else { bkt_ptr->kmer_info.linear = 0; } bkt_ptr = bkt_ptr->nxt_bucket; } } //fprintf(stderr,"Masking linear nodes, times: %d\n",call_times); fprintf ( stderr, "Total nodes number: %llu\n", total ); fprintf ( stderr, "Linear nodes number: %llu\n", linear ); } /************************************************* Function: clipTipFromNode Description: Removes tips from an end node. Input: 1. ht: the graph hashtable 2. K_size: the kmer size 3. node: the tips starting node 4. cut_len_tip: the threadhold of tips' length Output: None. Return: 1 if clips a tip successfully. *************************************************/ static int clipTipFromNode ( hashtable2 * ht, int K_size, bucket2 * node, int cut_len_tip ) //only for remove minor tips { //linear return 0 if ( node->kmer_info.linear || node->kmer_info.deleted ) { return 0; } // for not linear int in_num, out_num; int sum_edge_len = 0; int smaller; bool is_left; bool pre_is_left; edge_node * edge0; in_num = count_left_edge_num ( node ); out_num = count_right_edge_num ( node ); if ( in_num == 0 && out_num == 1 ) { is_left = 0; } else if ( in_num == 1 && out_num == 0 ) { is_left = 1; } else { return 0; } if ( is_left ) { edge0 = node->kmer_info.left; } else { edge0 = node->kmer_info.right; } bucket2 * next, *pre_node; pre_node = node; next = lastKmer ( ht, K_size, node, edge0, is_left, smaller ); while ( next->kmer_info.linear ) { if ( sum_edge_len > cut_len_tip ) { return 0; } is_left = ! ( is_left ^ smaller ); if ( is_left ) { edge0 = next->kmer_info.left; } else { edge0 = next->kmer_info.right; } sum_edge_len += edge0->len + 1; pre_node = next; next = lastKmer ( ht, K_size, next, edge0, is_left, smaller ); if ( !next ) { fprintf ( stderr, "ERROR: linear edge not found error !\n" ); exit ( -1 ); } } pre_is_left = is_left; is_left = ( is_left ^ smaller ); //back check orientation... in_num = count_left_edge_num ( next ); out_num = count_right_edge_num ( next ); if ( is_left ) //check the last node left branch or not { if ( in_num == 1 ) { return 0; } else if ( in_num > 1 ) { edge_node * edge1 = NULL, * temp_edge = NULL; bucket2 * temp_bucket = NULL; int max_cvg = 0, single_cvg = 0, temp_smaller; temp_edge = next->kmer_info.left; while ( temp_edge ) { single_cvg = temp_edge->edge_cov; if ( single_cvg > max_cvg ) { max_cvg = single_cvg; } if ( !edge1 ) { temp_bucket = lastKmer ( ht, K_size, next, temp_edge, 1, temp_smaller ); if ( !temp_bucket ) { fprintf ( stderr, "ERROR: edge to NULL found error ! a\n" ); exit ( 1 ); } if ( pre_node == temp_bucket ) { edge1 = temp_edge; } } temp_edge = temp_edge->nxt_edge; } if ( !edge1 ) { fprintf ( stderr, "ERROR: edge to node not found error ! b\n" ); exit ( 1 ); } if ( edge1->edge_cov < max_cvg ) { removeEdge ( next, edge1, 1 ); removeEdge ( pre_node, edge0, pre_is_left ); node->kmer_info.deleted = 1; pre_node->kmer_info.deleted = 1; return 1; } else { return 0; } } else { fprintf ( stderr, "ERROR: left tips oritation error or edge not found error ! a\n" ); exit ( -1 ); } } else { if ( out_num == 1 ) { return 0; } else if ( out_num > 1 ) { edge_node * edge1 = NULL, * temp_edge = NULL; bucket2 * temp_bucket = NULL; int max_cvg = 0, single_cvg = 0, temp_smaller; //ok change it to a edge_remove thred_hold locally later //or only if it is the least cvg ->remove it temp_edge = next->kmer_info.right; while ( temp_edge ) { single_cvg = temp_edge->edge_cov; if ( single_cvg > max_cvg ) { max_cvg = single_cvg; } if ( !edge1 ) { temp_bucket = lastKmer ( ht, K_size, next, temp_edge, 0, temp_smaller ); if ( !temp_bucket ) { fprintf ( stderr, "ERROR: edge to NULL found, error ! b\n" ); exit ( -1 ); } if ( pre_node == temp_bucket ) { edge1 = temp_edge; } } temp_edge = temp_edge->nxt_edge; } if ( !edge1 ) { fprintf ( stderr, "ERROR: edge to node not found error ! e\n" ); exit ( 1 ); } if ( edge1->edge_cov < max_cvg ) { removeEdge ( next, edge1, 0 ); removeEdge ( pre_node, edge0, pre_is_left ); node->kmer_info.deleted = 1; pre_node->kmer_info.deleted = 1; return 1; } else { return 0; } } else { fprintf ( stderr, "ERROR: right tips oritation error or edge not found error! b\n" ); exit ( -1 ); } } } static int count_left_edge_num ( bucket2 * bkt ) //63 127 same { int ret = 0; if ( bkt ) { edge_node * left_edge = bkt->kmer_info.left; while ( left_edge ) { ret++; left_edge = left_edge->nxt_edge; } } return ret; } static int count_right_edge_num ( bucket2 * bkt ) //63 127 same { int ret = 0; if ( bkt ) { edge_node * right_edge = bkt->kmer_info.right; while ( right_edge ) { ret++; right_edge = right_edge->nxt_edge; } } return ret; } /************************************************* Function: lastKmer Description: Searches the node that a node's kmer-edge end with. Input: 1. ht: the graph hashtable 2. K_size: kmer size 3. node: the node whose kmer-edge will be searched 4. edge: the kmer-edge 5. is_left: whether the kmer-edge on the node's left side Output: 1. smaller: whether the searched result, a kmer is smaller than its reversed complement Return: A pointer to the found node. Null if not found. *************************************************/ static bucket2 * lastKmer ( hashtable2 * ht, int K_size, bucket2 * node, edge_node * edge, int is_left, int & smaller ) //NEW { if ( !node || !edge ) { return NULL; } kmer_t2 t_kmer, f_kmer; t_kmer = node->kmer_t2; kmer_t2 edge_seq; memset ( edge_seq.kmer, 0, sizeof ( edge_seq ) ); ( edge_seq.kmer ) [sizeof ( edge_seq ) / sizeof ( uint64_t ) - 1] = edge->edge; int edge_len = edge->len + 1; if ( edge_len > K_size ) { fprintf ( stderr, "ERROR: g value should be no great than kmer size!\n" ); exit ( -1 ); } kmer_t2 KMER_FILTER; initKmerFilter ( K_size, &KMER_FILTER ); if ( is_left ) //left edge { kmerMoveRight ( &t_kmer, edge_len ); kmerMoveLeft ( &edge_seq, K_size - edge_len ); kmerOr ( &t_kmer, &edge_seq ); kmerAnd ( &t_kmer, &KMER_FILTER ); } else { kmerMoveLeft ( &t_kmer, edge_len ); kmerOr ( &t_kmer, &edge_seq ); kmerAnd ( &t_kmer, &KMER_FILTER ); } f_kmer = t_kmer; reverseCompKmer ( &f_kmer, K_size ); if ( kmerCompare ( &t_kmer, &f_kmer ) > 0 ) { t_kmer = f_kmer; smaller = 0; } else { smaller = 1; } return search_kmer ( ht, &t_kmer ); } static bucket2 * search_kmer ( hashtable2 * ht, kmer_t2 * t_kmer ) { uint64_t hv = MurmurHash64A ( t_kmer, sizeof ( kmer_t2 ), 0 ); size_t hash_idx = ( size_t ) ( hv % ht->ht_sz ); bucket2 * starter = ht->store_pos[hash_idx]; while ( starter ) { if ( kmerCompare ( & ( starter->kmer_t2 ), t_kmer ) == 0 ) { return starter; } starter = starter->nxt_bucket; } return NULL; } static void removeEdge ( bucket2 * node, edge_node * edge, int is_left ) // remove only one side ... //63 127 same ... { edge_node * pre_edge = NULL, *cur_edge = NULL, *nxt_edge = NULL; if ( !node || !edge ) { return ; } if ( is_left ) { cur_edge = node->kmer_info.left; if ( cur_edge == NULL ) { return ; } if ( cur_edge == edge ) { nxt_edge = cur_edge->nxt_edge; free ( cur_edge ); cur_edge = NULL; node->kmer_info.left = nxt_edge; return ; } } else { cur_edge = node->kmer_info.right; if ( cur_edge == NULL ) { return ; } if ( cur_edge == edge ) { nxt_edge = cur_edge->nxt_edge; free ( cur_edge ); cur_edge = NULL; node->kmer_info.right = nxt_edge; return ; } } pre_edge = cur_edge; cur_edge = cur_edge->nxt_edge; while ( cur_edge ) { if ( cur_edge == edge ) { break; } pre_edge = cur_edge; cur_edge = cur_edge->nxt_edge; } if ( cur_edge ) { nxt_edge = cur_edge->nxt_edge; free ( cur_edge ); cur_edge = NULL; pre_edge->nxt_edge = nxt_edge; } } static void stat_edge_num ( hashtable2 * ht ) //63 127 same { int l_num = 0, r_num = 0; size_t total_edge_num = 0, total_node_num = 0; bucket2 * bkt = NULL; map edge_num_map; for ( size_t i = 0; i < ht->ht_sz; i++ ) { bkt = ht->store_pos[i]; while ( bkt ) { total_node_num++; l_num = count_left_edge_num ( bkt ); r_num = count_right_edge_num ( bkt ); total_edge_num += ( l_num + r_num ); edge_num_map[l_num]++; edge_num_map[r_num]++; bkt = bkt->nxt_bucket; } } ofstream o_edge_num ( "edge_num_stat.txt" ); o_edge_num << "Total nodes number:" << total_node_num << endl; o_edge_num << "Total kmer-edges number:" << total_edge_num << endl; o_edge_num << "Average kmer-edges number per node:" << ( double ) total_edge_num / total_node_num << endl; o_edge_num << "The frequence of kmer-edges number on a node's one side as below :" << endl; map::iterator it; for ( it = edge_num_map.begin(); it != edge_num_map.end(); ++it ) { o_edge_num << it->first << "\t" << it->second << endl; } o_edge_num.close(); } static void stat_edge_cvg_len ( hashtable2 * ht ) { map edge_cvg_map; map edge_len_map; bucket2 * bkt = NULL; edge_node * temp_edge = NULL; for ( size_t i = 0; i < ht->ht_sz; i++ ) { bkt = ht->store_pos[i]; while ( bkt ) { //left temp_edge = bkt->kmer_info.left; while ( temp_edge ) { edge_cvg_map[temp_edge->edge_cov]++; edge_len_map[temp_edge->len]++; temp_edge = temp_edge->nxt_edge; } //right temp_edge = bkt->kmer_info.right; while ( temp_edge ) { edge_cvg_map[temp_edge->edge_cov]++; edge_len_map[temp_edge->len]++; temp_edge = temp_edge->nxt_edge; } bkt = bkt->nxt_bucket; } } ofstream o_edge_cvg ( "edge_cvg_stat.txt" ); ofstream o_edge_len ( "edge_len_stat.txt" ); map::iterator it; for ( it = edge_cvg_map.begin(); it != edge_cvg_map.end(); ++it ) { o_edge_cvg << it->first << "\t" << it->second << endl; } for ( it = edge_len_map.begin(); it != edge_len_map.end(); ++it ) { o_edge_len << it->first << "\t" << it->second << endl; } o_edge_cvg.close(); o_edge_len.close(); } /************************************************* Function: kmer2edges Description: This is the main function for building edges by compacting the linear nodes. Input: 1. ht: the graph hashtable 2. K_size: kmer size 3. out_file: the name of output file containing edges sequence Output: None. Return: None. *************************************************/ void kmer2edges ( hashtable2 * ht, int K_size, char * outfile ) { FILE * fp; char temp[256]; sprintf ( temp, "%s", outfile ); fp = fopen ( temp, "w" ); if ( fp == NULL ) { fprintf ( stderr, "ERROR: Can't create file %s. \n", temp ); exit ( -1 ); } make_edge ( ht, K_size, fp ); fclose ( fp ); } static void make_edge ( hashtable2 * ht, int K_size, FILE * fp ) //63 127 same { bucket2 * bktptr; for ( size_t i = 0; i < ht->ht_sz; ++i ) { bktptr = ht->store_pos[i]; while ( bktptr != NULL ) { startEdgeFromNode ( ht, K_size, bktptr, fp ); bktptr = bktptr->nxt_bucket; } } } /************************************************* Function: startEdgeFromNode Description: Constructs edges from a branched node or end node. for every branch (left , right) 1. Puts the linear node into a stack 2. Checks the edge to be built form the stack are plalindrome or not 3. Builds an edge by merge the linear nodes Input: 1. ht: the graph hashtable 2. K_size: kmer size 3. fp: the file pointer for writing out edge sequences Output: None. Return: Zero. *************************************************/ static int startEdgeFromNode ( hashtable2 * ht, int K_size, bucket2 * node, FILE * fp ) { static size_t call_times; call_times++; if ( node->kmer_info.linear || node->kmer_info.deleted ) { return 0;//linear node ... } int left, right; left = count_left_edge_num ( node ); right = count_right_edge_num ( node ); if ( left == 0 && right == 0 ) { return 0; //it's a dead node } list stack; edge_node * t_edge = NULL, *t_next = NULL; stacked_node2 * t_stacked_node = NULL; vector loops_edges; int node_c; //for right edge t_edge = node->kmer_info.right; while ( t_edge ) { if ( t_edge->used == 1 ) { t_edge = t_edge->nxt_edge; continue; } t_stacked_node = ( stacked_node2 * ) malloc ( sizeof ( stacked_node2 ) ); t_stacked_node->node = node; t_stacked_node->is_left = 0; t_stacked_node->edge = t_edge; t_stacked_node->next = NULL; stack.push_back ( t_stacked_node ); t_edge->used = 1; stringBeads ( ht, K_size, stack, t_stacked_node, t_edge, &node_c ); process_1stack ( ht, K_size, stack, fp, loops_edges ); t_next = t_edge->nxt_edge;//because this procedure will remove the edge t_edge dislink ( ht, K_size, stack.front() ); if ( stack.size() > 2 ) { stack.pop_back();//change the stack if ( stack.back() && stack.size() > 1 ) //last but second node { dislink ( ht, K_size, stack.back() ); } } stacked_node2 * head, *tmp_node; head = stack.front(); while ( head ) { tmp_node = head; free ( tmp_node ); head = head->next; } stack.clear(); t_edge = t_next; } //for left edge t_edge = node->kmer_info.left; while ( t_edge ) { if ( t_edge->used == 1 ) { t_edge = t_edge->nxt_edge; continue; } t_stacked_node = ( stacked_node2 * ) malloc ( sizeof ( stacked_node2 ) ); t_stacked_node->node = node; t_stacked_node->is_left = 1; t_stacked_node->edge = t_edge; t_stacked_node->next = NULL; stack.push_back ( t_stacked_node ); t_edge->used = 1; stringBeads ( ht, K_size, stack, t_stacked_node, t_edge, &node_c ); // process_1stack ( ht, K_size, stack, fp, loops_edges ); t_next = t_edge->nxt_edge;//because this procedure will remove the edge t_edge dislink ( ht, K_size, stack.front() ); if ( stack.size() > 2 ) { stack.pop_back();//change the stack if ( stack.back() && stack.size() > 1 ) //last but second node { dislink ( ht, K_size, stack.back() ); } } //debug<<"before free stack"<next; } stack.clear(); t_edge = t_next; } if ( loops_edges.size() > 0 ) { //fprintf(stderr,"loops_edges size %llu\n",loops_edges.size()); int i, j, size; bool need_output; size = loops_edges.size(); need_output = 1; //bool debug = 0; for ( i = 0; i < size; i++ ) { string seq = * ( loops_edges[i].full_edge ); string rc_seq = revCompSeq ( seq ); /* if(seq.compare("AATTGGACGTGAGAGCAAATTGTATTGAGCATACAATTTGCTCTCACGTCCAATT") == 0) { fprintf(stderr,"in loops_edges %d %s\n",i,seq.c_str()); debug = 1; } if(seq.compare("AATTGGACGTGAGAGCAAATTGTATGCTCAATACAATTTGCTCTCACGTCCAATT") == 0) { fprintf(stderr,"in loops_edges %d %s\n",i,seq.c_str()); debug = 1; } if(debug ){ fprintf(stderr, "%d %s\n",i,seq.c_str()); fprintf(stderr, "%d %s\n",i,rc_seq.c_str()); }*/ for ( j = i + 1; j < size; j++ ) { string cur_seq = * ( loops_edges[j].full_edge ); if ( seq.compare ( cur_seq ) == 0 ) { fprintf ( stderr, "ERROR: two equal loop edge sequence from same node, this should not happen!\n" ); fprintf ( stderr, "%s\n", seq.c_str() ); exit ( -1 ); } if ( rc_seq.compare ( cur_seq ) == 0 ) { fprintf ( stderr, "INFO: two loop edge sequence are reversed complemental!\n" ); fprintf ( stderr, "%s\n", seq.c_str() ); fprintf ( stderr, "%s\n", rc_seq.c_str() ); need_output = 0; loops_edges[j].cvg += loops_edges[i].cvg; break; } } if ( need_output ) { output_1edge ( &loops_edges[i], K_size, fp ); //fprintf(stderr,"need output %d %s\n",i,seq.c_str()); } delete ( loops_edges[i].full_edge ); need_output = 1; } } return 0; } /************************************************* Function: stringBeads Description: Puts the linear nodes into a stack. Input: 1. ht: the graph hashtalbe 2. K_size: kmer size 3. stack: a stack 4. from_node: the starting node of the stack 5. from_edge: the kmer-edge of the first node 6. node_c: useless Output: None. Return: None. *************************************************/ static void stringBeads ( hashtable2 * ht, int K_size, list &stack, stacked_node2 * from_node, edge_node * from_edge, int * node_c ) { static size_t call_times; call_times++; bucket2 * t_bucket = from_node->node; edge_node * t_edge = from_edge; stacked_node2 * t_stacked_node = from_node; int is_left = from_node->is_left; int t_smaller; t_edge->used = 1; t_bucket = lastKmer ( ht, K_size, t_bucket, t_edge, is_left, t_smaller ); if ( !t_bucket ) { fprintf ( stderr, "ERROR: to node not found in stringBeads()\n" ); exit ( -1 ); } while ( t_bucket && t_bucket->kmer_info.linear ) { t_stacked_node = ( stacked_node2 * ) malloc ( sizeof ( stacked_node2 ) ); t_stacked_node->node = t_bucket; is_left = ! ( is_left ^ t_smaller ); t_stacked_node->is_left = is_left; if ( is_left ) { t_stacked_node->edge = t_bucket->kmer_info.left; } else { t_stacked_node->edge = t_bucket->kmer_info.right; } t_stacked_node->next = NULL; ( ( stacked_node2 * ) stack.back() )->next = t_stacked_node; stack.push_back ( t_stacked_node ); t_stacked_node->edge->used = 1; t_bucket = lastKmer ( ht, K_size, t_bucket, t_stacked_node->edge, is_left, t_smaller ); } if ( t_bucket ) //should be always true for end node .. { t_stacked_node = ( stacked_node2 * ) malloc ( sizeof ( stacked_node2 ) ); t_stacked_node->node = t_bucket; is_left = ! ( is_left ^ t_smaller ); t_stacked_node->is_left = is_left; t_stacked_node->edge = NULL; t_stacked_node->next = NULL; ( ( stacked_node2 * ) stack.back() )->next = t_stacked_node; stack.push_back ( t_stacked_node ); } } //for debug static void pirntStack ( list &stack ) { static int times = 0; fprintf ( stderr, "call times %d \n ", times++ ); stacked_node2 * ptr = stack.front(); while ( ptr ) { printKmer ( & ( ptr->node->kmer_t2 ), stderr ); if ( ptr->edge ) { fprintf ( stderr, "%llx , %d ,", ptr->edge->edge, ptr->is_left ); } fprintf ( stderr, "->" ); ptr = ptr->next; } fprintf ( stderr, "\n" ); } /************************************************* Function: process_1stack Description: Processes the nodes in one stack 1. Compacts the nodes to an edge 2. Checks palindrome 3. Calculates coverage Input: 1. ht: the graph hashtable 2. K_size: kmer size 3. stack: the stack 4. fp: the file pointer for writing Output: None. Return: None. *************************************************/ static void process_1stack ( hashtable2 * ht, int K_size, list &stack, FILE * fp, vector &loops_edges ) { static size_t edge_c;// edge id static preEDGE2 long_edge_buf; preEDGE2 loops; int TipLenTh = 3 * K_size; //orig 100 int TipCovTh = 5; if ( stack.size() < 2 ) { fprintf ( stderr, "only %llu nodes in the stack \n", stack.size() ); exit ( -1 ); } else { //palindrome check string full_edge = stack2string ( ht, K_size, stack ); //when output skip the first kmer first stacked_node2 * test = stack.front(); bool palindrome = check_palindrome ( full_edge ); int bal_edge = !palindrome; stacked_node2 * from_node = stack.front(); stacked_node2 * to_node = stack.back(); long_edge_buf.from_node = from_node; long_edge_buf.to_node = to_node; long_edge_buf.full_edge = &full_edge; long_edge_buf.bal_edge = bal_edge; uint64_t symbol = 0; //cvg stat edge_c++; if ( stack.size() == 2 ) { long_edge_buf.cvg = from_node->edge->edge_cov; } else { stacked_node2 * nd_tmp = from_node; while ( nd_tmp && nd_tmp->edge ) { symbol += nd_tmp->edge->edge_cov * ( nd_tmp->edge->len + 1 ); nd_tmp = nd_tmp->next; } int cvg = symbol / ( full_edge.size() - K_size ); long_edge_buf.cvg = cvg; } int from_left, from_right, to_left, to_right; from_left = count_left_edge_num ( from_node->node ); from_right = count_right_edge_num ( from_node->node ); to_left = count_left_edge_num ( to_node->node ); to_right = count_right_edge_num ( to_node->node ); //tips control if ( ( ( from_left + from_right == 1 ) && ( to_left + to_right == 1 ) && ( full_edge.size() < TipLenTh ) ) || ( ( ( from_left + from_right == 1 ) || ( to_left + to_right == 1 ) ) && ( full_edge.size() < TipLenTh ) && long_edge_buf.cvg < TipCovTh ) ) //tips args { //if(full_edge.size()node,long_edge_buf.to_node->node); } if(bug_seq.compare("AATTGGACGTGAGAGCAAATTGTATGCTCAATACAATTTGCTCTCACGTCCAATT") == 0) { fprintf(stderr,"%s\n",bug_seq.c_str()); fprintf(stderr,"from %llx to %llx \n",long_edge_buf.from_node->node,long_edge_buf.to_node->node); }*/ //debug end if ( long_edge_buf.from_node->node == long_edge_buf.to_node->node ) { loops = long_edge_buf; loops.full_edge = new string ( * ( long_edge_buf.full_edge ) ); loops_edges.push_back ( loops ); } else { //output edge output_1edge ( &long_edge_buf, K_size, fp ); } } edge_c += bal_edge; } } // WARNING: the kmer atcg is different from soapdenovo's represent static void output_1edge ( preEDGE2 * long_edge, int K_size, FILE * fp ) { fprintf ( fp, ">length %d,", long_edge->full_edge->size() - K_size ); const char * seq = long_edge->full_edge->c_str(); //uint64_t from_kmer[2],to_kmer[2]; kmer_t2 from_kmer, to_kmer; get_kmer_from_seq ( seq, long_edge->full_edge->size() , K_size, 0, &from_kmer ); get_kmer_from_seq ( seq, long_edge->full_edge->size() , K_size, long_edge->full_edge->size() - K_size, &to_kmer ); uint64_t * from, *to; from = from_kmer.kmer; to = to_kmer.kmer; #ifdef _63MER_ fprintf ( fp, "%llx %llx,", from[0], from[1] ); fprintf ( fp, "%llx %llx,", to[0], to[1] ); #endif #ifdef _127MER_ fprintf ( fp, "%llx %llx %llx %llx,", from[0], from[1], from[2], from[3] ); fprintf ( fp, "%llx %llx %llx %llx,", to[0], to[1], to[2], to[3] ); #endif fprintf ( fp, "cvg %d,%d\n", long_edge->cvg, long_edge->bal_edge ); fprintf ( fp, "%s", seq ); fprintf ( fp, "\n" ); } /************************************************* Function: dislink Description: Marks the kmer-edges between "form_node" and "form_node->next" used. Input: 1. ht: the graph hashtable 2. K_size: kmer size 3. from_node: the first node of a stack Output: None. Return: None. *************************************************/ static void dislink ( hashtable2 * ht, int K_size, stacked_node2 * from_node ) { from_node->edge->used = 1; int from_edge_len = from_node->edge->len; int smaller; if ( from_node->next ) { stacked_node2 * from_next = from_node->next; if ( from_next->node == from_node->node && from_next->is_left != from_node->is_left ) { return ; } if ( from_next->is_left ) //remove right edge { if ( from_next->node->kmer_info.linear ) { bucket2 * node_tmp = lastKmer ( ht, K_size, from_next->node, from_next->node->kmer_info.right, 0, smaller ); if ( node_tmp == from_node->node ) { from_next->node->kmer_info.right->used = 1; } else { fprintf ( stderr, "ERROR: to node not found in dislink()\n" ); } } else { edge_node * edge_tmp = from_next->node->kmer_info.right; while ( edge_tmp ) { bucket2 * node_tmp = lastKmer ( ht, K_size, from_next->node, edge_tmp, 0, smaller ); if ( node_tmp == from_node->node && edge_tmp->len == from_edge_len ) //there may be two or more edges between two nodes { edge_tmp->used = 1; break; } edge_tmp = edge_tmp->nxt_edge; } if ( !edge_tmp ) { fprintf ( stderr, "ERROR: to node not found in dislink()\n" ); } } } else // remove left edge { if ( from_next->node->kmer_info.linear ) { bucket2 * node_tmp = lastKmer ( ht, K_size, from_next->node, from_next->node->kmer_info.left, 1, smaller ); if ( node_tmp == from_node->node ) { from_next->node->kmer_info.left ->used = 1; } else { fprintf ( stderr, "ERROR: to node not found in dislink()\n" ); } } else { edge_node * edge_tmp = from_next->node->kmer_info.left; while ( edge_tmp ) { bucket2 * node_tmp = lastKmer ( ht, K_size, from_next->node, edge_tmp, 1, smaller ); if ( node_tmp == from_node->node && edge_tmp->len == from_edge_len ) { edge_tmp->used = 1; break; } edge_tmp = edge_tmp->nxt_edge; } if ( !edge_tmp ) { fprintf ( stderr, "ERROR: to node not found in dislink()\n" ); } } } } } /************************************************* Function: stack2string Description: Compacts the nodes in the stack to a sequence. Input: 1. ht: the graph hashtable 2. K_size: kmer size 3. stack: the stack for processing Output: None. Return: The compacted string, namely the edge sequence. *************************************************/ //63 127 differ, fixed static string stack2string ( hashtable2 * ht, int K_size, list & stack ) { static size_t call_times; call_times++; string full_edge; stacked_node2 * t_stack_node = stack.front(); char tmp[1024]; uint64_t bits[2]; kmer_t2 tmp_kmer = ( t_stack_node->node->kmer_t2 ); if ( t_stack_node->is_left ) { reverseCompKmer ( &tmp_kmer, K_size ); } else { } bitsarr2str ( tmp_kmer.kmer, K_size, tmp, sizeof ( kmer_t2 ) / sizeof ( uint64_t ) ); full_edge.append ( tmp ); //put first node while ( t_stack_node ) { if ( t_stack_node->edge ) { if ( t_stack_node->is_left ) { bits[0] = get_rev_comp_seq ( t_stack_node->edge->edge, t_stack_node->edge->len + 1 ); bitsarr2str ( bits, t_stack_node->edge->len + 1, tmp, 1 ); full_edge.append ( tmp ); } else { bits[0] = t_stack_node->edge->edge; bitsarr2str ( bits, t_stack_node->edge->len + 1, tmp, 1 ); full_edge.append ( tmp ); } } t_stack_node = t_stack_node->next; } return full_edge; } static bool check_palindrome ( string & str ) //63 127 same { size_t size = str.size(); size_t mid = ( size / 2 ) + 1; for ( size_t i = 0; i < mid; ++i ) { switch ( str[i] ) { case 'A': if ( str[size - i - 1] != 'T' ) { return 0; } break; case 'C': if ( str[size - i - 1] != 'G' ) { return 0; } break; case 'T': if ( str[size - i - 1] != 'A' ) { return 0; } break; case 'G': if ( str[size - i - 1] != 'C' ) { return 0; } break; } } return 1; } static string revCompSeq ( const string & str ) { string rc_seq; size_t size = str.size(); for ( int i = size - 1; i >= 0; i-- ) { switch ( str[i] ) { case 'A': rc_seq.push_back ( 'T' ); break; case 'C': rc_seq.push_back ( 'G' ); break; case 'T': rc_seq.push_back ( 'A' ); break; case 'G': rc_seq.push_back ( 'C' ); break; } } return rc_seq; } soapdenovo2-240+dfsg.orig/sparsePregraph/multi_threads.cpp0000644000000000000000000000576312166703653022556 0ustar rootroot/* * multi_threads.cpp * * Copyright (c) 2008-2012 BGI-Shenzhen . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "multi_threads.h" #include "global.h" #include "build_graph.h" #include "stdinc.h" #include "build_preArc.h" void creatThrds ( pthread_t * threads, PARAMETER * paras ) { unsigned char i; int temp; for ( i = 0; i < thrd_num_s; i++ ) { if ( ( temp = pthread_create ( &threads[i], NULL, threadRoutine, & ( paras[i] ) ) ) != 0 ) { fprintf ( stderr, "ERROR: create threads failed.\n" ); exit ( 1 ); } } //fprintf(stderr,"%d work threads created.\n",thrd_num_s); fprintf ( stderr, "%d work threads initialized.\n", thrd_num_s ); } void * threadRoutine ( void * para ) { PARAMETER * prm; int i; unsigned char id; prm = ( PARAMETER * ) para; id = prm->threadID; struct hashtable2 * ht = prm->ht; int K_size = prm->K_size; int gap = prm->gap; while ( 1 ) { if ( * ( prm->selfSignal ) == 3 ) { * ( prm->selfSignal ) = 0; break; } else if ( * ( prm->selfSignal ) == 10 ) { run_process_threaded ( ht, locks, K_size, gap, read_num, thrd_num_s, prm->threadID, 1 ); * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 11 ) { run_process_threaded ( ht, locks, K_size, gap, read_num, thrd_num_s, prm->threadID, 2 ); * ( prm->selfSignal ) = 0; } else if ( * ( prm->selfSignal ) == 12 ) { for ( int i = prm->threadID ; i < read_num; i += thrd_num_s ) { int bad_flag = 0; filter_N ( seq_t[i], bad_flag ); if ( bad_flag ) {seq_t[i].clear(); continue;} process_1read_preArc ( prm->preArcs, locks, prm->threadID, prm->v_ht, K_size, prm->cut_off_len, seq_t[i].c_str() ); } * ( prm->selfSignal ) = 0; } usleep ( 1 ); } } void thread_wait ( pthread_t * threads ) { int i; for ( i = 0; i < thrd_num_s; i++ ) if ( threads[i] != 0 ) { pthread_join ( threads[i], NULL ); } } void sendWorkSignal ( unsigned char SIG, unsigned char * thrdSignals ) { int t; for ( t = 0; t < thrd_num_s; t++ ) { thrdSignals[t + 1] = SIG; } while ( 1 ) { usleep ( 10 ); for ( t = 0; t < thrd_num_s; t++ ) if ( thrdSignals[t + 1] ) { break; } if ( t == thrd_num_s ) { break; } } } soapdenovo2-240+dfsg.orig/VERSION0000644000000000000000000000001212166703670015245 0ustar rootroot2.04-r240 soapdenovo2-240+dfsg.orig/Makefile0000644000000000000000000000414312166705330015641 0ustar rootrootCC = g++ ifdef debug CFLAGS= -O0 -g -fomit-frame-pointer else CFLAGS= -O4 -fomit-frame-pointer endif SUBDIRS = sparsePregraph standardPregraph PROG= SOAPdenovo-63mer SOAPdenovo-127mer INCLUDES= -I./sparsePregraph/inc -I./standardPregraph/inc LIBPATH= -L/lib64 -L/usr/lib64 -L./sparsePregraph/inc -L./standardPregraph/inc LIBS= -pthread -lz -lm EXTRA_FLAGS= BIT_ERR = 0 ifeq (,$(findstring $(shell uname -m), x86_64 ppc64 ia64)) BIT_ERR = 1 endif ifneq (,$(findstring Linux,$(shell uname))) EXTRA_FLAGS += -Wl,--hash-style=both LIBS += -lbam -lrt endif ifneq (,$(findstring Unix,$(shell uname))) EXTRA_FLAGS += -Wl,--hash-style=both LIBS += -lbam -lrt endif ifneq (,$(findstring Darwin,$(shell uname))) LIBS += -lbammac endif ifneq (,$(findstring $(shell uname -m), x86_64)) CFLAGS += -m64 endif ifneq (,$(findstring $(shell uname -m), ia64)) CFLAGS += endif ifneq (,$(findstring $(shell uname -m), ppc64)) CFLAGS += -mpowerpc64 endif all: SOAPdenovo-63mer SOAPdenovo-127mer ifdef debug SOAPdenovo-63mer: @cd sparsePregraph;make 63mer=1 debug=1;cd ..; @cd standardPregraph;make 63mer=1 debug=1;cd ..; @$(CC) sparsePregraph/*.o standardPregraph/*.o $(LIBPATH) $(LIBS) $(EXTRA_FLAGS) -o SOAPdenovo-63mer SOAPdenovo-127mer: @cd sparsePregraph;make 127mer=1 debug=1;cd ..; @cd standardPregraph;make 127mer=1 debug=1;cd ..; @$(CC) sparsePregraph/*.o standardPregraph/*.o $(LIBPATH) $(LIBS) $(EXTRA_FLAGS) -o SOAPdenovo-127mer clean: @cd sparsePregraph;make clean;cd ..; @cd standardPregraph;make clean;cd ..; @rm SOAPdenovo-63mer SOAPdenovo-127mer -f else SOAPdenovo-63mer: @cd sparsePregraph;make 63mer=1;cd ..; @cd standardPregraph;make 63mer=1;cd ..; @$(CC) sparsePregraph/*.o standardPregraph/*.o $(LIBPATH) $(LIBS) $(EXTRA_FLAGS) -o SOAPdenovo-63mer SOAPdenovo-127mer: @cd sparsePregraph;make 127mer=1;cd ..; @cd standardPregraph;make 127mer=1;cd ..; @$(CC) sparsePregraph/*.o standardPregraph/*.o $(LIBPATH) $(LIBS) $(EXTRA_FLAGS) -o SOAPdenovo-127mer clean: @cd sparsePregraph;make clean;cd ..; @cd standardPregraph;make clean;cd ..; @rm SOAPdenovo-63mer SOAPdenovo-127mer -f endif soapdenovo2-240+dfsg.orig/MANUAL0000644000000000000000000004050312166703653015107 0ustar rootroot Manual of SOAPdenovo-V2.04 Ruibang Luo, 2012-7-10 Zhenyu Li, 2012-7-10 ********************************************************** Introduction SOAPdenovo is a novel short-read assembly method that can build a de novo draft assembly for the human-sized genomes. The program is specially designed to assemble Illumina GA short reads. It creates new opportunities for building reference sequences and carrying out accurate analyses of unexplored genomes in a cost effective way. ************ System Requirement SOAPdenovo aims for large plant and animal genomes, although it also works well on bacteria and fungi genomes. It runs on 64-bit Linux system with a minimum of 5G physical memory. For big genomes like human, about 150 GB memory would be required. ************ Update Log 1) 63mer and 127mer versions were merged. 2) A new module named "sparse-pregraph" was added which can reduce considerable computational comsumption. 3) "Multi-kmer" method was introduced in "contig" step which allows the utilization of the advantages of small and large kmer. 4) Algorithm of scaffolding was improved to get longer and more accuracy scaffolds. 5) AIO (Asynchronous Input/Output) was introduced to boost the performance of reading files. 6) Information for visualization purpose was available after scaffolding. 7) Several bugs fixed. ************ Installation 1. You can download the pre-compiled binary according to your platform, unpack using "tar -zxf ${destination folder} download.tgz" and execute directly. 2. Or download the source code, unpack to ${destination folder} with the method above, and compile by using GNU make with command "make" at ${destination folder}/SOAPdenovo-V2.04. Then install executable to ${destination folder}/SOAPdenovo-V2.04/bin using "make install" ************ How to use it 1. Configuration file For big genome projects with deep sequencing, the data is usually organized as multiple read sequence files generated from multiple libraries. The configuration file tells the assembler where to find these files and the relevant information. "example.config" is an example of such a file. The configuration file has a section for global information, and then multiple library sections. Right now only "max_rd_len" is included in the global information section. Any read longer than max_rd_len will be cut to this length. The library information and the information of sequencing data generated from the library should be organized in the corresponding library section. Each library section starts with tag [LIB] and includes the following items: 1) avg_ins This value indicates the average insert size of this library or the peak value position in the insert size distribution figure. 2) reverse_seq This option takes value 0 or 1. It tells the assembler if the read sequences need to be complementarily reversed. Illumima GA produces two types of paired-end libraries: a) forward-reverse, generated from fragmented DNA ends with typical insert size less than 500 bp; b) reverse-forward, generated from circularizing libraries with typical insert size greater than 2 Kb. The parameter "reverse_seq" should be set to indicate this: 0, forward-reverse; 1, reverse-forward. 3) asm_flags This indicator decides in which part(s) the reads are used. It takes value 1(only contig assembly), 2 (only scaffold assembly), 3(both contig and scaffold assembly), or 4 (only gap closure). 4) rd_len_cutof The assembler will cut the reads from the current library to this length. 5) rank It takes integer values and decides in which order the reads are used for scaffold assembly. Libraries with the same "rank" are used at the same time during scaffold assembly. 6) pair_num_cutoff This parameter is the cutoff value of pair number for a reliable connection between two contigs or pre-scaffolds. The minimum number for paired-end reads and mate-pair reads is 3 and 5 respectively. 7) map_len This takes effect in the "map" step and is the minimun alignment length between a read and a contig required for a reliable read location. The minimum length for paired-end reads and mate-pair reads is 32 and 35 respectively. The assembler accepts read file in three kinds of formats: FASTA, FASTQ and BAM. Mate-pair relationship could be indicated in two ways: two sequence files with reads in the same order belonging to a pair, or two adjacent reads in a single file (FASTA only) belonging to a pair. If a read in bam file fails platform/vendor quality checks(the flag field 0x0200 is set), itself and it's paired read would be ignored. In the configuration file single end files are indicated by "f=/path/filename" or "q=/pah/filename" for fasta or fastq formats separately. Paired reads in two fasta sequence files are indicated by "f1=" and "f2=". While paired reads in two fastq sequences files are indicated by "q1=" and "q2=". Paired reads in a single fasta sequence file is indicated by "p=" item. Reads in bam sequence files is indicated by "b=". All the above items in each library section are optional. The assembler assigns default values for most of them. If you are not sure how to set a parameter, you can remove it from your configuration file. 2. Get it started Once the configuration file is available, a typical way to run the assembler is: ${bin} all -s config_file -K 63 -R -o graph_prefix 1>ass.log 2>ass.err User can also choose to run the assembly process step by step as: step1: ${bin} pregraph -s config_file -K 63 -R -o graph_prefix 1>pregraph.log 2>pregraph.err OR ${bin} sparse_pregraph -s config_file -K 63 -z 5000000000 -R -o graph_prefix 1>pregraph.log 2>pregraph.err step2: ${bin} contig -g graph_prefix -R 1>contig.log 2>contig.err step3: ${bin} map -s config_file -g graph_prefix 1>map.log 2>map.err step4: ${bin} scaff -g graph_prefix -F 1>scaff.log 2>scaff.err 3.Options 3.1 Options for all (pregraph-contig-map-scaff) -s configFile: the config file of solexa reads -o outputGraph: prefix of output graph file name -K kmer(min 13, max 63/127): kmer size, [23] -p n_cpu: number of cpu for use, [8] -a initMemoryAssumption: memory assumption initialized to avoid further reallocation, unit G, [0] -d KmerFreqCutoff: kmers with frequency no larger than KmerFreqCutoff will be deleted, [0] -R (optional) resolve repeats by reads, [NO] -D EdgeCovCutoff: edges with coverage no larger than EdgeCovCutoff will be deleted, [1] -M mergeLevel(min 0, max 3): the strength of merging similar sequences during contiging, [1] -m max k when using multi kmer -e weight to filter arc when linearize two edges(default 0) -r (optional) keep available read(*.read) -E (optional) merge clean bubble before iterate -f (optional) output gap related reads in map step for using SRkgf to fill gap, [NO] -k kmer_R2C(min 13, max 63): kmer size used for mapping read to contig, [K] -F (optional) fill gaps in scaffold, [NO] -u (optional) un-mask contigs with high/low coverage before scaffolding, [mask] -w (optional) keep contigs weakly connected to other contigs in scaffold, [NO] -G gapLenDiff: allowed length difference between estimated and filled gap, [50] -L minContigLen: shortest contig for scaffolding, [K+2] -c minContigCvg: minimum contig coverage (c*avgCvg), contigs shorter than 100bp with coverage smaller than c*avgCvg will be masked before scaffolding unless -u is set, [0.1] -C maxContigCvg: maximum contig coverage (C*avgCvg), contigs with coverage larger than C*avgCvg or contigs shorter than 100bp with coverage larger than 0.8*C*avgCvg will be masked before scaffolding unless -u is set, [2] -b insertSizeUpperBound: (b*avg_ins) will be used as upper bound of insert size for large insert size ( > 1000) when handling pair-end connections between contigs if b is set to larger than 1, [1.5] -B bubbleCoverage: remove contig with lower cvoerage in bubble structure if both contigs' coverage are smaller than bubbleCoverage*avgCvg, [0.6] -N genomeSize: genome size for statistics, [0] -V (optional) output visualization information of assembly, [NO] 3.2 Options for sparse_pregraph Usage: ./SOAPdenovo2 sparse_pregraph -s configFile -K kmer -z genomeSize -o outputGraph [-g maxKmerEdgeLength -d kmerFreqCutoff -e kmerEdgeFreqCutoff -R -r runMode -p n_cpu] -s configFile: the config file of solexa reads -K kmer(min 13, max 63/127): kmer size, [23] -g maxKmerEdgeLength(min 1, max 25): number of skipped intermediate kmers, [15] -z genomeSize(mandatory): estimated genome size -d kmerFreqCutoff: delete kmers with frequency no larger than,[1] -e kmerEdgeFreqCutoff: delete kmers' related edge with frequency no larger than [1] -R (optional) output extra information for resolving repeats in contig step, [NO] -r runMode: 0 build graph & build edge and preArc, 1 load graph by prefix & build edge and preArc, 2 build graph only, 3 build edges only, 4 build preArcs only [0] -p n_cpu: number of cpu for use,[8] -o outputGraph: prefix of output graph file name 4. Output files 4.1 These files are output as assembly results: a. *.contig contig sequences without using mate pair information. b. *.scafSeq scaffold sequences (final contig sequences can be extracted by breaking down scaffold sequences at gap regions). 4.2 There are some other files that provide useful information for advanced users, which are listed in Appendix B. 5. FAQ 5.1 How to set K-mer size? The program accepts odd numbers between 13 and 31. Larger K-mers would have higher rate of uniqueness in the genome and would make the graph simpler, but it requires deep sequencing depth and longer read length to guarantee the overlap at any genomic location. The sparse pregraph module usually needs 2-10bp smaller kmer length to achieve the same performance as the original pregraph module. 5.2 How to set genome size(-z) for sparse pregraph module? The -z parameter for sparse pregraph should be set a litter larger than the real genome size, it is used to allocate memory. 5.3 How to set library rank? SOAPdenovo will use the pair-end libraries with insert size from smaller to larger to construct scaffolds. Libraries with the same rank would be used at the same time. For example, in a dataset of a human genome, we set five ranks for five libraries with insert size 200-bp, 500-bp, 2-Kb, 5-Kb and 10-Kb, separately. It is desired that the pairs in each rank provide adequate physical coverage of the genome. ************ APPENDIX A: an example.config #maximal read length max_rd_len=100 [LIB] #average insert size avg_ins=200 #if sequence needs to be reversed reverse_seq=0 #in which part(s) the reads are used asm_flags=3 #use only first 100 bps of each read rd_len_cutoff=100 #in which order the reads are used while scaffolding rank=1 # cutoff of pair number for a reliable connection (at least 3 for short insert size) pair_num_cutoff=3 #minimum aligned length to contigs for a reliable read location (at least 32 for short insert size) map_len=32 #a pair of fastq file, read 1 file should always be followed by read 2 file q1=/path/**LIBNAMEA**/fastq1_read_1.fq q2=/path/**LIBNAMEA**/fastq1_read_2.fq #another pair of fastq file, read 1 file should always be followed by read 2 file q1=/path/**LIBNAMEA**/fastq2_read_1.fq q2=/path/**LIBNAMEA**/fastq2_read_2.fq #a pair of fasta file, read 1 file should always be followed by read 2 file f1=/path/**LIBNAMEA**/fasta1_read_1.fa f2=/path/**LIBNAMEA**/fasta1_read_2.fa #another pair of fasta file, read 1 file should always be followed by read 2 file f1=/path/**LIBNAMEA**/fasta2_read_1.fa f2=/path/**LIBNAMEA**/fasta2_read_2.fa #fastq file for single reads q=/path/**LIBNAMEA**/fastq1_read_single.fq #another fastq file for single reads q=/path/**LIBNAMEA**/fastq2_read_single.fq #fasta file for single reads f=/path/**LIBNAMEA**/fasta1_read_single.fa #another fasta file for single reads f=/path/**LIBNAMEA**/fasta2_read_single.fa #a single fasta file for paired reads p=/path/**LIBNAMEA**/pairs1_in_one_file.fa #another single fasta file for paired reads p=/path/**LIBNAMEA**/pairs2_in_one_file.fa #bam file for single or paired reads, reads 1 in paired reads file should always be followed by reads 2 # NOTE: If a read in bam file fails platform/vendor quality checks(the flag field 0x0200 is set), itself and it's paired read would be ignored. b=/path/**LIBNAMEA**/reads1_in_file.bam #another bam file for single or paired reads b=/path/**LIBNAMEA**/reads2_in_file.bam [LIB] avg_ins=2000 reverse_seq=1 asm_flags=2 rank=2 # cutoff of pair number for a reliable connection (at least 5 for large insert size) pair_num_cutoff=5 #minimum aligned length to contigs for a reliable read location (at least 35 for large insert size) map_len=35 q1=/path/**LIBNAMEB**/fastq_read_1.fq q2=/path/**LIBNAMEB**/fastq_read_2.fq f1=/path/**LIBNAMEA**/fasta_read_1.fa f2=/path/**LIBNAMEA**/fasta_read_2.fa p=/path/**LIBNAMEA**/pairs_in_one_file.fa b=/path/**LIBNAMEA**/reads_in_file.bam ************ Appendix B: output files 1. Output files from the command "pregraph" a. *.kmerFreq Each row shows the number of Kmers with a frequency equals the row number. Note that those peaks of frequencies which are the integral multiple of 63 are due to the data structure. b. *.edge Each record gives the information of an edge in the pre-graph: length, Kmers on both ends, average kmer coverage, whether it's reverse-complementarily identical and the sequence. c. *.markOnEdge & *.path These two files are for using reads to solve small repeats. e. *.preArc Connections between edges which are established by the read paths. f. *.vertex Kmers at the ends of edges. g. *.preGraphBasic Some basic information about the pre-graph: number of vertex, K value, number of edges, maximum read length etc. 2. Output files from the command "contig" a. *.contig Contig information: corresponding edge index, length, kmer coverage, whether it's tip and the sequence. Either a contig or its reverse complementry counterpart is included. Each reverse complementary contig index is indicated in the *.ContigIndex file. b. *.Arc Arcs coming out of each edge and their corresponding coverage by reads c. *.updated.edge Some information for each edge in graph: length, Kmers at both ends, index difference between the reverse-complementary edge and this one. d. *.ContigIndex Each record gives information about each contig in the *.contig: it's edge index, length, the index difference between its reverse-complementary counterpart and itself. 3. Output files from the command "map" a. *.peGrads Information for each clone library: insert-size, read index upper bound, rank and pair number cutoff for a reliable link. This file can be revised manually for scaffolding tuning. b. *.readOnContig Reads' locations on contigs. Here contigs are referred by their edge index. Howerver about half of them are not listed in the *.contig file for their reverse-complementary counterparts are included already. c. *.readInGap This file includes reads that could be located in gaps between contigs. This information will be used to close gaps in scaffolds if "-F" is set. 4. Output files from the command "scaff" a. *.newContigIndex Contigs are sorted according their length before scaffolding. Their new index are listed in this file. This is useful if one wants to corresponds contigs in *.contig with those in *.links. b. *.links Links between contigs which are established by read pairs. New index are used. c. *.scaf_gap Contigs in gaps found by contig graph outputted by the contiging procedure. Here new index are used. d. *.scaf Contigs for each scaffold: contig index (concordant to index in *.contig), approximate start position on scaffold, orientation, contig length, and its links to others contigs. e. *.gapSeq Gap sequences between contigs. f. *.scafSeq Sequences of each scaffolds. g. *.contigPosInscaff Contigs' positions in each scaffold. h. *.bubbleInScaff Contigs that form bubble structures in scaffolds. Every two contigs form a bubble and the contig with higher coverage will be kept in scaffold. i. *.scafStatistics Statistic information of final scaffold and contig. soapdenovo2-240+dfsg.orig/INSTALL0000644000000000000000000000070012166703653015233 0ustar rootroot Installation of SOAPdenovo-V2.04 Ruibang Luo, 2012-7-10 Zhenyu Li, 2012-7-10 ******************************************************************** Pre-configurated Makefile was designed to handle most circumstances. ************ MAKE ************ Type "make" at root of unpacked folder. Type "make debug=1" at root of npacked folder to compile the debug version. ************ CLEAN ************ Type "make clean" at root of unpacked folder. soapdenovo2-240+dfsg.orig/LICENSE0000644000000000000000000010451312166703653015216 0ustar rootroot GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . soapdenovo2-240+dfsg.orig/update.log0000644000000000000000000000727012166704063016174 0ustar rootrootr240 | 2013-07-09 11:30:03 +0800 (Tue, 09 Jul 2013) Fix a bug in reading files in 'map' step. This bug might lead to seg fault. ------------------------------------------------------------------------ r239 | 2013-06-26 09:41:39 +0800 (Wed, 26 Jun 2013) 1) Fix the bug of reading fasta file in map step. This bug was introduced when fixing a bug of reading fastq file in r238. ------------------------------------------------------------------------ r224 - r238 | 2013-06-13 1) Fix a serious bug in 'map' step of version r223. This bug can lead to incorrect pairing of PE reads in LIB of even order, e.g., the 2nd LIB, the 4th LIB and so on...And these affected LIBs may not contribute to the construction of scaffold. 2) Merge 'standPregraph' and 'sparsePregraph'. Now, there are only two executable programs: SOAPdenovo-63mer and SOAPdenovo-127mer. User can choose to use 'pregraph' for standard Kmer graph or 'sparse_pregraph' for sparse Kmer graph. 3) Add an option for debug version compilation. User can use 'make debug=1' to obtain programs for debug. 4) Fix a bug in sorting edges in 'contig' step. 5) Fix a bug in reading files when using multi-kmer. Now the 'max_read_length' will change according to the LIB being red. ------------------------------------------------------------------------ r223 | 2012-12-28 10:11:43 +0800 (Fri, 28 Dec 2012) Fix the problem that parameter k doesn't work when k is larger than 63 for 127mer version. ------------------------------------------------------------------------ r222 | 2012-12-21 14:45:49 +0800 (Fri, 21 Dec 2012) 1) Change some codes so that program can handle reads longer than 5000. 2) Add a new perl script which can seperate singletons from scaffolds in *.scafSeq file. ------------------------------------------------------------------------ r221 | 2012-12-07 14:27:02 +0800 (Fri, 07 Dec 2012) Fix a bug in reading files which might cause zombie process. ------------------------------------------------------------------------ r220 | 2012-11-26 10:09:45 +0800 (Mon, 26 Nov 2012) Fix bug in aio that the buffer was not enough for fq for long reads. ------------------------------------------------------------------------ r219 | 2012-11-08 12:58:45 +0800 (Thu, 08 Nov 2012) Fix a bug that using -r 1 will casuse the infomation loss of MaxReadLen and MinReadLen in *.preGraphBasic file in pregraph_sparse module. ------------------------------------------------------------------------ r218 | 2012-11-08 11:04:54 +0800 (Thu, 08 Nov 2012) Output palindrome sequence only once now instead of twice before in pregraph_sparse module. ------------------------------------------------------------------------ r217 | 2012-11-01 13:09:50 +0800 (Thu, 01 Nov 2012) Fix bug in scaffolding which may lead to scaffold consisting of none or only one contig. ------------------------------------------------------------------------ r216 | 2012-10-31 14:53:29 +0800 (Wed, 31 Oct 2012) Fix a bug of 'pregraph-sparse' which may lead to segmentation fault in 'contig' step if option -R is set and there are reads longer than 100bp. ------------------------------------------------------------------------ r215 | 2012-10-16 18:53:28 +0800 (Tue, 16 Oct 2012) Fix a bug of aio which happens rarely in 'pregraph' step when there are reads shorter than Kmer. ------------------------------------------------------------------------ r214 | 2012-10-08 15:58:09 +0800 (Mon, 08 Oct 2012) Modify usage description of '-V'. ------------------------------------------------------------------------ r213 | 2012-09-29 09:24:32 +0800 (Sat, 29 Sep 2012) Fix a bug which might happen in 'contig' step if the 'pregraph-sparse' is used to replace the regular 'pregraph'.