void move(pen *p, int dir) { switch (dir) { case LEFT: move_absolute(p, p->x - 1, p->y); break; case RIGHT: move_absolute(p, p->x + 1, p->y); break; case UP: move_absolute(p, p->x, p->y - 1); break; case DOWN: move_absolute(p, p->x, p->y + 1); break; default: break; } }
static void fill_x (FILE *fp, Genomicpos_T startpos, Genomicpos_T endpos, bool uncompressedp, int index1part) { Genomicpos_T total; if (uncompressedp == true) { move_absolute(fp,startpos); total = endpos - startpos; while (total > WRITEBLOCK) { fwrite(Empty,sizeof(char),WRITEBLOCK,fp); total -= WRITEBLOCK; } if (total > 0) { fwrite(Empty,sizeof(char),total,fp); } } else { Compress_update_file(/*nbadchars*/0,fp,NULL,startpos,endpos,index1part); } return; }
/* Puts reference genome into refgenome_fp (assume compressed), and puts alternate strain sequences into altstrain_iit. */ static void genome_write_memory (FILE *refgenome_fp, FILE *input, IIT_T contig_iit, IIT_T altstrain_iit, UINT4 *genomecomp, unsigned int nuint4, char *fileroot) { char Buffer[BUFFERSIZE], Complement[BUFFERSIZE], *segment; char *accession, *p; Genomicpos_T leftposition, rightposition, startposition, endposition, truelength, maxposition = 0, currposition = 0; int contigtype; bool revcompp; #ifdef ALTSTRAIN int altstrain_index, altstrain_offset; #endif int nbadchars = 0; int ncontigs = 0; while (fgets(Buffer,BUFFERSIZE,input) != NULL) { if (Buffer[0] == '>') { /* HEADER */ accession = parse_accession(Buffer); find_positions(&revcompp,&leftposition,&rightposition,&startposition,&endposition, &truelength,&contigtype,accession,contig_iit); if (++ncontigs < 50) { if (revcompp == true) { fprintf(stderr,"Writing contig %s to universal coordinates %u..%u in genome %s\n", accession,startposition,endposition,fileroot); } else { fprintf(stderr,"Writing contig %s to universal coordinates %u..%u in genome %s\n", accession,startposition+1U,endposition+1U,fileroot); } } else if (ncontigs == 50) { fprintf(stderr,"More than 50 contigs. Will stop printing messages\n"); } if (contigtype > 0) { #ifdef ALTSTRAIN fprintf(stderr," (alternate strain %s)",IIT_typestring(altstrain_iit,contigtype)); #endif } FREE(accession); if (contigtype > 0) { #ifdef ALTSTRAIN /* Initialize file pointer for alternate strain */ altstrain_index = IIT_get_exact(altstrain_iit,/*divstring*/NULL,leftposition,rightposition,contigtype); if (revcompp == true) { altstrain_offset = rightposition + 1U - leftposition; } else { altstrain_offset = 0; } debug(printf("Setting altstrain_offset to be %d\n",altstrain_offset)); #endif } /* Handles case where true length is greater than provided coordinates. This needs to be after call to IIT_get_exact */ if (leftposition + truelength - 1U > rightposition) { debug(fprintf(stderr,"Extending endposition for truelength of %u\n",truelength)); rightposition = leftposition + truelength; if (revcompp == true) { endposition = startposition - truelength; } else { endposition = startposition + truelength; } } /* In both cases, set file pointer for reference strain, although we won't write sequence of alternate strain. For an alternate strain, ensure that we fill the reference strain with sufficient X's. */ if (startposition > maxposition) { /* Start beyond end of file */ debug(printf("Filling with X's from %u to %u-1\n",maxposition,startposition)); fill_x_memory(genomecomp,maxposition,startposition); if (contigtype > 0) { #ifdef ALTSTRAIN fill_x_memory(genomecomp,leftposition,rightposition + 1); maxposition = currposition = rightposition + 1; #endif } else { maxposition = rightposition; currposition = startposition; } } else { /* Start within file */ if (contigtype > 0) { #ifdef ALTSTRAIN if (rightposition + 1 > maxposition) { debug(printf("Filling with X's from %u to %u-1\n",maxposition,rightposition+1)); fill_x_memory(genomecomp,maxposition,rightposition + 1); maxposition = currposition = rightposition + 1; } #endif } else { debug(printf("Moving to %u\n",startposition)); currposition = startposition; } } } else { /* SEQUENCE */ if ((p = rindex(Buffer,'\n')) != NULL) { *p = '\0'; } if ((p = rindex(Buffer,CONTROLM)) != NULL) { *p = '\0'; } if (revcompp == true) { make_complement_buffered(Complement,Buffer,strlen(Buffer)); segment = Complement; } else { segment = Buffer; } if (contigtype > 0) { #ifdef ALTSTRAIN /* Write alternate strain */ if (revcompp == true) { altstrain_offset -= strlen(segment); debug(printf("Writing alternate strain at %u\n",altstrain_offset)); IIT_backfill_sequence(altstrain_iit,altstrain_index,altstrain_offset,segment); } else { debug(printf("Writing alternate strain at %u\n",altstrain_offset)); IIT_backfill_sequence(altstrain_iit,altstrain_index,altstrain_offset,segment); altstrain_offset += strlen(segment); } #endif } else { /* Write reference strain */ if (revcompp == true) { debug(printf("Filling with sequence from %u-1 to %u\n",currposition,currposition-strlen(segment))); currposition -= strlen(segment); nbadchars = Compress_update_memory(nbadchars,genomecomp,segment,currposition,currposition+strlen(segment)); } else { debug(printf("Filling with sequence from %u to %u-1\n",currposition,currposition+strlen(segment))); nbadchars = Compress_update_memory(nbadchars,genomecomp,segment,currposition,currposition+strlen(segment)); currposition += strlen(segment); if (currposition > maxposition) { maxposition = currposition; } } } } } move_absolute(refgenome_fp,0U); FWRITE_UINTS(genomecomp,nuint4,refgenome_fp); fprintf(stderr,"A total of %d non-ACGTNX characters were seen in the genome.\n",nbadchars); return; }
/* Permits arbitrary ASCII characters. Useful for storing numeric data */ static void genome_writeraw_file (FILE *refgenome_fp, FILE *input, IIT_T contig_iit, IIT_T altstrain_iit, char *fileroot, int index1part) { char Buffer[BUFFERSIZE], Reverse[BUFFERSIZE], *segment; char *accession, c; Genomicpos_T leftposition, rightposition, startposition, endposition, truelength, maxposition = 0, currposition = 0; int contigtype; int strlength; int i; bool revcompp; #ifdef ALTSTRAIN int altstrain_index, altstrain_offset; #endif int ncontigs = 0; for (i = 0; i < WRITEBLOCK; i++) { Empty[i] = 0; } while (fgets(Buffer,BUFFERSIZE,input) != NULL) { if (Buffer[0] != '>') { fprintf(stderr,"Expecting to see a new FASTA entry\n"); fprintf(stderr,"Instead, saw %d (%c)\n",(int) Buffer[0],Buffer[0]); exit(9); } else { /* HEADER */ accession = parse_accession(Buffer); find_positions(&revcompp,&leftposition,&rightposition,&startposition,&endposition, &truelength,&contigtype,accession,contig_iit); if (++ncontigs < 50) { if (revcompp == true) { fprintf(stderr,"Writing contig %s to universal coordinates %u..%u in genome %s\n", accession,startposition,endposition,fileroot); } else { fprintf(stderr,"Writing contig %s to universal coordinates %u..%u in genome %s\n", accession,startposition+1U,endposition+1U,fileroot); } } else if (ncontigs == 50) { fprintf(stderr,"More than 50 contigs. Will stop printing messages\n"); } if (contigtype > 0) { #ifdef ALTSTRAIN fprintf(stderr," (alternate strain %s)",IIT_typestring(altstrain_iit,contigtype)); #endif } FREE(accession); if (contigtype > 0) { #ifdef ALTSTRAIN /* Initialize file pointer for alternate strain */ altstrain_index = IIT_get_exact(altstrain_iit,/*divstring*/NULL,leftposition,rightposition,contigtype); if (revcompp == true) { altstrain_offset = rightposition + 1U - leftposition; } else { altstrain_offset = 0; } debug(printf("Setting altstrain_offset to be %d\n",altstrain_offset)); #endif } /* Handles case where true length is greater than provided coordinates. This needs to be after call to IIT_get_exact */ if (leftposition + truelength - 1U > rightposition) { debug(fprintf(stderr,"Extending endposition for truelength of %u\n",truelength)); rightposition = leftposition + truelength; if (revcompp == true) { endposition = startposition - truelength; } else { endposition = startposition + truelength; } } /* In both cases, set file pointer for reference strain, although we won't write sequence of alternate strain. For an alternate strain, ensure that we fill the reference strain with sufficient X's. */ if (startposition > maxposition) { /* Start beyond end of file */ debug(printf("Filling with zeroes from %u to %u-1\n",maxposition,startposition)); fill_zero(refgenome_fp,maxposition,startposition,/*uncompressedp*/true,index1part); if (contigtype > 0) { #ifdef ALTSTRAIN fill_zero(refgenome_fp,leftposition,rightposition + 1,/*uncompressedp*/true,index1part); maxposition = currposition = rightposition + 1; #endif } else { maxposition = rightposition; currposition = startposition; } } else { /* Start within file */ if (contigtype > 0) { #ifdef ALTSTRAIN if (rightposition + 1 > maxposition) { debug(printf("Filling with zeroes from %u to %u-1\n",maxposition,rightposition+1)); fill_zero(refgenome_fp,maxposition,rightposition + 1,/*uncompressedp*/true,index1part); maxposition = currposition = rightposition + 1; } #endif } else { debug(printf("Moving to %u\n",startposition)); move_absolute(refgenome_fp,startposition); currposition = startposition; } } /* SEQUENCE */ fprintf(stderr,"Processing %u characters\n",truelength); while (truelength > 0) { if (truelength > BUFFERSIZE) { if ((strlength = fread(Buffer,sizeof(char),BUFFERSIZE,input)) < BUFFERSIZE) { fprintf(stderr,"Expecting %u more characters, but saw end of file\n",truelength); exit(9); } truelength -= BUFFERSIZE; } else { if ((strlength = fread(Buffer,sizeof(char),truelength,input)) < truelength) { fprintf(stderr,"Expecting %u more characters, but saw end of file\n",truelength); exit(9); } truelength = 0; } if (revcompp == true) { make_reverse_buffered(Reverse,Buffer,strlength); segment = Reverse; } else { segment = Buffer; } if (contigtype > 0) { #ifdef ALTSTRAING /* Write alternate strain. It is likely that IIT commands will fail because they depend on \0 to terminate the segment. */ if (revcompp == true) { altstrain_offset -= strlength; debug(printf("Writing alternate strain at %u\n",altstrain_offset)); IIT_backfill_sequence(altstrain_iit,altstrain_index,altstrain_offset,segment); } else { debug(printf("Writing alternate strain at %u\n",altstrain_offset)); IIT_backfill_sequence(altstrain_iit,altstrain_index,altstrain_offset,segment); altstrain_offset += strlength; } #endif } else { /* Write reference strain */ if (revcompp == true) { debug(printf("Filling with sequence from %u-1 to %u\n",currposition,currposition-strlength)); currposition -= strlength; fwrite(segment,sizeof(char),strlength,refgenome_fp); } else { debug(printf("Filling with sequence from %u to %u-1\n",currposition,currposition+strlength)); fwrite(segment,sizeof(char),strlength,refgenome_fp); currposition += strlength; if (currposition > maxposition) { maxposition = currposition; } } } } if ((c = fgetc(input)) != EOF && c != '\n') { fprintf(stderr,"Expecting linefeed at end of sequence. Saw %d instead\n", c); exit(9); } } } return; }
void *do_hilbert(void *t) { hilbert * hil = ((thread_data *)t)->hil; pen *p = ((thread_data *)t)->p ; int order = ((thread_data *)t)->order; int type = ((thread_data *)t)->type; assert(order > 0); if(order == 1) { switch (type) { case A: mark(hil, p); move(p, LEFT); mark(hil, p); move(p, LEFT); mark(hil, p); move(p, DOWN); mark(hil, p); move(p, DOWN); mark(hil, p); move(p, RIGHT); mark(hil, p); move(p, RIGHT); mark(hil, p); break; case B: mark(hil, p); move(p, UP); mark(hil, p); move(p, UP); mark(hil, p); move(p, RIGHT); mark(hil, p); move(p, RIGHT); mark(hil, p); move(p, DOWN); mark(hil, p); move(p, DOWN); mark(hil, p); break; case C: mark(hil, p); move(p, RIGHT); mark(hil, p); move(p, RIGHT); mark(hil, p); move(p, UP); mark(hil, p); move(p, UP); mark(hil, p); move(p, LEFT); mark(hil, p); move(p, LEFT); mark(hil, p); break; case D: mark(hil, p); move(p, DOWN); mark(hil, p); move(p, DOWN); mark(hil, p); move(p, LEFT); mark(hil, p); move(p, LEFT); mark(hil, p); move(p, UP); mark(hil, p); move(p, UP); mark(hil, p); break; default: fprintf(stderr, "Unknown hilbert type: %d", type); break; } // switch } // if else { pthread_t thread[4]; pthread_attr_t attr; thread_data *ta[4]; pen *start = malloc(sizeof(pen)); pen *p2 = malloc(sizeof(pen)); pen *p3 = malloc(sizeof(pen)); pen *p4 = malloc(sizeof(pen)); start->x = p->x; start->y = p->y; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); switch (type) { case A: ta[0] = malloc(sizeof(thread_data)); set_thread_data(ta[0], hil, p, order - 1, D); pthread_create(&thread[0], &attr, do_hilbert, (void *)ta[0]); // 1st worker thread move_absolute(p2, start->x - hilbert_size(order - 1), start->y); mark(hil, p2); move(p2, LEFT); ta[1] = malloc(sizeof(thread_data)); set_thread_data(ta[1], hil, p2, order - 1, A); pthread_create(&thread[1], &attr, do_hilbert, (void *)ta[1]); // 2nd worker thread move_absolute(p3, start->x - hilbert_size(order - 1) - 1, start->y + hilbert_size(order - 1)); mark(hil, p3); move(p3, DOWN); ta[2] = malloc(sizeof(thread_data)); set_thread_data(ta[2], hil, p3, order - 1, A); pthread_create(&thread[2], &attr, do_hilbert, (void *)ta[2]); // 3rd worker thread move_absolute(p4, start->x - hilbert_size(order - 1), start->y + 2 * hilbert_size(order - 1)); mark(hil, p4); move(p4, RIGHT); ta[3] = malloc(sizeof(thread_data)); set_thread_data(ta[3], hil, p4, order - 1, B); pthread_create(&thread[3], &attr, do_hilbert, (void *)ta[3]); pthread_join(thread[0], NULL); pthread_join(thread[1], NULL); pthread_join(thread[2], NULL); pthread_join(thread[3], NULL); break; case B: ta[0] = malloc(sizeof(thread_data)); set_thread_data(ta[0], hil, p, order - 1, C); pthread_create(&thread[0], &attr, do_hilbert, (void *)ta[0]); // 1st worker thread move_absolute(p2, start->x, start->y - hilbert_size(order - 1)); mark(hil, p2); move(p2, UP); ta[1] = malloc(sizeof(thread_data)); set_thread_data(ta[1], hil, p2, order - 1, B); pthread_create(&thread[1], &attr, do_hilbert, (void *)ta[1]); // 2nd worker thread move_absolute(p3, start->x + hilbert_size(order - 1), start->y - hilbert_size(order - 1) - 1); mark(hil, p3); move(p3, RIGHT); ta[2] = malloc(sizeof(thread_data)); set_thread_data(ta[2], hil, p3, order - 1, B); pthread_create(&thread[2], &attr, do_hilbert, (void *)ta[2]); // 3rd worker thread move_absolute(p4, start->x + 2 * hilbert_size(order - 1), start->y - hilbert_size(order - 1)); mark(hil, p4); move(p4, DOWN); ta[3] = malloc(sizeof(thread_data)); set_thread_data(ta[3], hil, p4, order - 1, A); pthread_create(&thread[3], &attr, do_hilbert, (void *)ta[3]); pthread_join(thread[0], NULL); pthread_join(thread[1], NULL); pthread_join(thread[2], NULL); pthread_join(thread[3], NULL); break; case C: ta[0] = malloc(sizeof(thread_data)); set_thread_data(ta[0], hil, p, order - 1, B); pthread_create(&thread[0], &attr, do_hilbert, (void *)ta[0]); // 1st worker thread move_absolute(p2, start->x + hilbert_size(order - 1), start->y); mark(hil, p2); move(p2, RIGHT); ta[1] = malloc(sizeof(thread_data)); set_thread_data(ta[1], hil, p2, order - 1, C); pthread_create(&thread[1], &attr, do_hilbert, (void *)ta[1]); // 2nd worker thread move_absolute(p3, start->x + hilbert_size(order - 1) + 1, start->y - hilbert_size(order - 1)); mark(hil, p3); move(p3, UP); ta[2] = malloc(sizeof(thread_data)); set_thread_data(ta[2], hil, p3, order - 1, C); pthread_create(&thread[2], &attr, do_hilbert, (void *)ta[2]); // 3rd worker thread move_absolute(p4, start->x + hilbert_size(order - 1), start->y - 2 * hilbert_size(order - 1)); mark(hil, p4); move(p4, LEFT); ta[3] = malloc(sizeof(thread_data)); set_thread_data(ta[3], hil, p4, order - 1, D); pthread_create(&thread[3], &attr, do_hilbert, (void *)ta[3]); pthread_join(thread[0], NULL); pthread_join(thread[1], NULL); pthread_join(thread[2], NULL); pthread_join(thread[3], NULL); break; case D: ta[0] = malloc(sizeof(thread_data)); set_thread_data(ta[0], hil, p, order - 1, A); pthread_create(&thread[0], &attr, do_hilbert, (void *)ta[0]); // 1st worker thread move_absolute(p2, start->x, start->y + hilbert_size(order - 1)); mark(hil, p2); move(p2, DOWN); ta[1] = malloc(sizeof(thread_data)); set_thread_data(ta[1], hil, p2, order - 1, D); pthread_create(&thread[1], &attr, do_hilbert, (void *)ta[1]); // 2nd worker thread move_absolute(p3, start->x - hilbert_size(order - 1), start->y + hilbert_size(order - 1) + 1); mark(hil, p3); move(p3, LEFT); ta[2] = malloc(sizeof(thread_data)); set_thread_data(ta[2], hil, p3, order - 1, D); pthread_create(&thread[2], &attr, do_hilbert, (void *)ta[2]); // 3rd worker thread move_absolute(p4, start->x - 2 * hilbert_size(order - 1), start->y + hilbert_size(order - 1)); mark(hil, p4); move(p4, UP); ta[3] = malloc(sizeof(thread_data)); set_thread_data(ta[3], hil, p4, order - 1, C); pthread_create(&thread[3], &attr, do_hilbert, (void *)ta[3]); pthread_join(thread[0], NULL); pthread_join(thread[1], NULL); pthread_join(thread[2], NULL); pthread_join(thread[3], NULL); break; default: fprintf(stderr, "Unknown hilbert type: %d", type); break; } // switch free(start); free(p2); free(p3); free(p4); } // else pthread_exit(NULL); }