/*************************************************
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 );
		}
	}
}
Beispiel #2
0
int read_file_and_draw()
{
    Vertex *N0 , *N1 , *N2;
    double x,y,z;
    double max_x,max_y,max_z;
    double min_x,min_y,min_z;
    FILE *input;
    char title[50];
    int vertex_number;
    int draw_times;
    int i;
    int point_count;
    int node0,node1,node2;
    int start_node;
    max_x = 0;
    max_y = 0;
    max_z = 0;
    min_x = 0;
    min_y = 0;
    min_z = 0;
    
    input = fopen ("data.txt","r");
    fscanf(input,"%s",title);      // read Vertices
    if( stricmp(title,"Vertices") != 0 ) //the first line is not Vertices
    {
         fprintf(stderr,"Input file syntax error!\n"); 
         return -1;  
    }
    fscanf(input,"%d",&vertex_number);
    for( i = 0 ; i < vertex_number ; i++ )
    {
         fscanf(input,"%lf%lf%lf",&x,&y,&z);
         insert_vertex_point(x,y,-z);
         
         if ( x > max_x )
            max_x = x;     
         else if ( x < min_x )
            min_x = x;
         if ( y > max_y )
            max_y = y;
         else if ( y < min_y )
            min_y = y;
         if ( z > max_z )
            max_z = z;
         else if ( z < min_z )
            min_z = z;
    }
    //Normalization
    Normalization( max_x , max_y , min_x , min_y , max_z , min_z);
    
    while( fscanf(input,"%s",title)  == 1 )
    {
         if( strcmp(title,"Line_segment") == 0)
         {
            fscanf( input , "%d" ,&draw_times );
            for( i = 0 ; i < draw_times ; i++ )
            {
                fscanf(input,"%d",&node0);
                fscanf(input,"%d",&node1);
                N0 = search_vertex(node0);
                N1 = search_vertex(node1);
                draw_line( N0->x , N0->y , N0->z , N1->x , N1->y , N1->z );
            }                              
         }
         
         else if( stricmp(title,"Line_strip") == 0 )
         {
            fscanf( input , "%d" ,&draw_times );
            fscanf(input,"%d",&node0);
            for( i = 0 ; i < draw_times ; i++ )
            {
                fscanf(input,"%d",&node1);
                N0 = search_vertex(node0);
                N1 = search_vertex(node1);
                draw_line( N0->x , N0->y , N0->z , N1->x , N1->y , N1->z );
                node0 = node1;
            }               
         }
         
         else if( stricmp(title,"Line_loop") == 0 )
         {
            fscanf( input , "%d" ,&draw_times );
            fscanf(input,"%d",&node0);
            start_node = node0;
            for( i = 0 ; i < draw_times -1; i++ )
            {
               fscanf(input,"%d",&node1);
               N0 = search_vertex(node0);
               N1 = search_vertex(node1);
               draw_line( N0->x , N0->y , N0->z , N1->x , N1->y , N1->z );
               node0 = node1;
            }
            N1 = search_vertex(start_node);
            N0 = search_vertex(node0);
            draw_line( N0->x , N0->y , N0->z , N1->x , N1->y , N1->z );
         }
         
         else if( stricmp(title,"Triangle_fan") == 0)
         {
            fscanf( input , "%d" ,&draw_times );
            fscanf( input , "%d" , &node0 );
            fscanf( input , "%d" , &node1 );  
            N0 = search_vertex(node0);     // point A
            N1 = search_vertex(node1);     // point B
            start_node = node1; 
            for( i = 0 ; i < draw_times ; i++ )
            {
               fscanf( input , "%d" , &node2 ); 
               N2 = search_vertex(node2); // point C
               draw_triangle(N0->x,N0->y,N0->z,N1->x,N1->y,N1->z,N2->x,N2->y,N2->z);
               N1 = N2;
            }
              
         }
         
         else if (stricmp(title,"Triangle_list") == 0 )
         {
            fscanf( input , "%d" ,&draw_times );
            for( i = 0 ; i < draw_times ; i++ )
            {
               fscanf( input , "%d" , &node0 );
               fscanf( input , "%d" , &node1 ); 
               fscanf( input , "%d" , &node2 );
               N0 = search_vertex(node0);     // point A
               N1 = search_vertex(node1);     // point B
               N2 = search_vertex(node2);     // point C
               insert_trangle(N0,N1,N2);
               draw_triangle(N0->x,N0->y,N0->z,N1->x,N1->y,N1->z,N2->x,N2->y,N2->z);
            }
            //sort_trangle_node(draw_times)
            SORT = 1;
            trangle_number =  draw_times;             
         }
         
         else if( stricmp(title,"Triangle_strip") == 0 )
         {
            fscanf( input , "%d" ,&draw_times );
            fscanf( input , "%d" , &node0 );
            fscanf( input , "%d" , &node1 ); 
            N0 = search_vertex(node0);     // point A
            N1 = search_vertex(node1);     // point B
            for( i = 0 ; i < draw_times ; i++ )
            {
               fscanf( input , "%d" , &node2 );
               N2 = search_vertex(node2);     // point C
               draw_triangle(N0->x,N0->y,N0->z,N1->x,N1->y,N1->z,N2->x,N2->y,N2->z);
               N0 = N1;
               N1 = N2;  
            }
              
         }
    }
    //printf("%lf ,%lf , %lf\n",end_vertex_point->x,end_vertex_point->y,end_vertex_point->z);
    //system("pause");
}