int fera___init(struct descriptor_s *niddsc_ptr, InInitStruct *setup ) { int status=1; int num_dig; int num_mem; #define return_on_error(f,retstatus) if (!((status = f) & 1)) return retstatus; last_nid = 0; /* Reset the controler */ return_on_error(DevCamChk(CamPiow(setup->cntrl_name,0,9,0,16,0),&one,&one),status); /* setup the digitizers */ if((num_dig = NElements(setup->head_nid + FERA_N_DIG_NAME))) { int i; for(i=0; i<num_dig; i++) { char *name = ArrayRef(setup->head_nid + FERA_N_DIG_NAME, i); if(name) { static short ecl_cam = 0x2400; return_on_error(DevCamChk(CamPiow(name,0,9,0,16,0),&one,&one),status); /* reset digitizer */ return_on_error(DevCamChk(CamPiow(name,0,16, &ecl_cam, 16, 0),&one,&one),status); /* goto ECL/CAM mode */ } else { status = FERA$_DIGNOTSTRARRAY; break; } } } else status = FERA$_NODIG; /* setup the memory modules */ if (status&1) { if ((num_mem = NElements(setup->head_nid + FERA_N_MEM_NAME)) ) { int i; for(i=0; i<num_mem; i++) { char *name = ArrayRef(setup->head_nid + FERA_N_MEM_NAME, i); if(name) { return_on_error(DevCamChk(CamPiow(name, 1, 17, &one, 16, 0),&one,&one),status); return_on_error(DevCamChk(CamPiow(name, 0, 24, 0, 16, 0),&one,&one),status); return_on_error(DevCamChk(CamPiow(name, 0, 17, &zero, 16, 0),&one,&one),status); return_on_error(DevCamChk(CamPiow(name, 1, 17, &three, 16, 0),&one,&one),status); } else { status = FERA$_MEMNOTSTRARRAY; break; } } } else status = FERA$_NOMEM; } /* Reset the controler */ return_on_error(DevCamChk(CamPiow(setup->cntrl_name, 0, 9, 0, 16, 0),&one,&one),status); return status; }
int add_vector(GapIO *io, char *V, int level) { int err; int vector; int freerec; GVectors v; /* allocate vector name */ v.name = allocate(io,GT_Text); err = TextWrite(io,v.name,V,strlen(V)); v.level = level; /* find new vector number */ vector = ++io->db.Nvectors; ArrayRef(io->vectors,vector-1); /* add vector to list */ arr(GCardinal,io->vectors,vector-1) = freerec = allocate(io,GT_Vectors); err = GT_Write(io,freerec,&v,sizeof(v),GT_Vectors); /* write array */ err = ArrayDelay(io, io->db.vectors, io->db.Nvectors, io->vectors); /* write db */ DBDelayWrite(io); return vector; }
int add_clone(GapIO *io, char *CN, char *CV) { int err; int clone; int freerec; GClones c; /* find vector record */ c.vector = find_vector(io,CV); if (!c.vector) c.vector = add_vector(io,CV,1); /* allocate clone name */ c.name = allocate(io,GT_Text); err = TextWrite(io,c.name,CN,strlen(CN)); /* find new clone number */ clone = ++io->db.Nclones; ArrayRef(io->clones,clone-1); /* add clone to list */ arr(GCardinal,io->clones,clone-1) = freerec = allocate(io,GT_Clones); err = GT_Write(io,freerec,&c,sizeof(c),GT_Clones); /* write array */ err = ArrayDelay(io, io->db.clones, io->db.Nclones, io->clones); /* write db */ DBDelayWrite(io); return clone; }
/* * Adds a contig to a scaffold array. * Gap size, type and evidence refer to the gap between this and the * "previous" contig - ie the last in the scaffold. More complex * scaffold manipulations will be handled elsewhere. * * Set these fields to 0 if you do not know them. * * Returns 0 on success * -1 on failure */ int scaffold_add(GapIO *io, tg_rec scaffold, tg_rec contig, int gap_size, int gap_type, int evidence) { scaffold_t *f; contig_t *c; scaffold_member_t *m; int i; /* Check if this contig is in a scaffold, if so remove now */ c = cache_search(io, GT_Contig, contig); if (c->scaffold) scaffold_remove(io, c->scaffold, contig); if (!(f = cache_search(io, GT_Scaffold, scaffold))) return -1; /* Check if it already exists */ for (i = 0; i < ArrayMax(f->contig); i++) { m = arrp(scaffold_member_t, f->contig, i); if (m->rec == contig) return 0; } /* Append */ f = cache_rw(io, f); m = ArrayRef(f->contig, ArrayMax(f->contig)); // extend m->rec = contig; m->gap_size = ArrayMax(f->contig) > 1 ? gap_size : 0; m->gap_type = gap_type; m->evidence = evidence; /* Update the contig record too */ c = cache_search(io, GT_Contig, contig); c = cache_rw(io, c); c->scaffold = scaffold; #if 0 /* Add a scaffold link to the contig graph too */ if (ArrayMax(f->contig) >= 2) { m = arrp(scaffold_member_t, f->contig, ArrayMax(f->contig)-2); contig_link_t lnk; lnk.rec1 = contig; lnk.rec2 = m->rec; /* Best guess */ lnk.pos1 = 0; lnk.end1 = 1; lnk.pos2 = 0; lnk.end2 = 0; lnk.orientation = 0; lnk.size = 100; lnk.type = CLINK_TYPE_SCAFFOLD; lnk.score = 0; contig_add_link(io, &lnk); } #endif return 0; }
/* * Translates a Read structure and an Experiment file. * The Read structure is left unchanged. * * Returns: * A pointer to an allocated Exp_info structure upon success. * NULL upon failure. */ Exp_info *read2exp(Read *read, char *EN) { Exp_info *e; char *t = trace_type_int2str(read->format), *p; int l = strlen(EN)+1; char *sq; int i; static char valid_bases[256]; static int valid_setup = 0; if (!valid_setup) { for (i = 0; i < 256; i++) valid_bases[i] = '-'; /* IUBC codes */ for (sq = "acgturymkswbdhvnACGTURYMKSWBDHVN"; *sq; sq++) valid_bases[(unsigned)*sq] = *sq; valid_setup = 1; } if (NULL == (e = exp_create_info())) return NULL; /* Copy original exp file if present */ if (read->orig_trace && read->orig_trace_format == TT_EXP) { int i, j, k; Exp_info *re = (Exp_info *)read->orig_trace; for (i = 0; i < MAXIMUM_EFLTS; i++) { if (EFLT_SQ == i || EFLT_QL == i || EFLT_QR == i) continue; if (0 == (k = exp_Nentries(re, i))) continue; e->Nentries[i] = k; ArrayRef(e->entries[i], e->Nentries[i]); for (j = 0; j < k; j++) { arr(char *, e->entries[i], j) = strdup(arr(char *, re->entries[i], j)); } } /* Otherwise create our EN, ID, LN and LT lines */ } else {
GView g_new_view(GDB *gdb) /* * allocate a new view */ { GView i; i = gdb->free_view; if (i==-1) { (void)ArrayRef(gdb->view,gdb->Nview); i = gdb->Nview++; } else { /* adjust freetree */ gdb->free_view = arr(View,gdb->view,i).next; } arr(View,gdb->view,i).next = -1; arr(View,gdb->view,i).flags = G_VIEW_NEW; arr(View,gdb->view,i).lcache.rec = -1; return i; }
GDB *g_open_database_(char *fns[], GCardinal Nfns, int read_only) /* * Open a database with a given file name */ { GDB *gdb; GCardinal i; /* check arguments */ if (fns==NULL) { (void) gerr_set(GERR_INVALID_ARGUMENTS); return NULL; } if (NULL == (gdb = g_new_gdb())) return NULL; /* * initialise data structs for clients */ gdb->Nclient = G_MAX_CLIENTS; if ( (gdb->client = ArrayCreate(sizeof(Client),gdb->Nclient)) == NULL ) { g_free_gdb(gdb); (void)gerr_set(GERR_OUT_OF_MEMORY); return NULL; } (void)ArrayRef(gdb->client,gdb->Nclient-1); for (i=0;i<gdb->Nclient;i++) arr(Client,gdb->client,i).id = -1; /* * Open the file (now only 1 file allowed, we ignore the rest) */ gdb->gfile = g_open_file(fns[0], read_only); if (NULL == gdb->gfile) { g_free_gdb(gdb); /* g_open_file sets gerrnum */ return NULL; } /* * allocate views - assume using Gap4, which locks all records. * FIXME: Changed to have max 1000 views at startup. It's reallocated * as we go anyway. */ gdb->Nview = 1000 < gdb->gfile->header.num_records ? 1000 : gdb->gfile->header.num_records; if ( (gdb->view = ArrayCreate(sizeof(View),gdb->Nview)) == NULL ) { g_free_gdb(gdb); (void)gerr_set(GERR_OUT_OF_MEMORY); return NULL; } (void)ArrayRef(gdb->view,gdb->Nview-1); /* initialise views */ for(i=0;i<gdb->Nview;i++) { arr(View,gdb->view,i).next = (i-1); arr(View,gdb->view,i).flags = G_VIEW_NEW; } gdb->free_view = gdb->Nview-1; return gdb; }
Exp_info *exp_read_staden_info(mFILE *fp, char *filename) /* * Read a staden file into an Exp_info data structure */ { Exp_info *e; char *seq; char *fn; /* find last / in filename */ for(fn=filename+strlen(filename)-1;fn>filename && *fn!='/';fn--); if (*fn=='/') fn++; if ( (e = exp_create_info()) != NULL ) { char line[128]; /* an upper limit for the file size */ int max_seq_size = file_size(filename); int left, right, len, i; int lineno; int formatIsBap; int CS_from, CS_to; int SR; CS_from = CS_to = SR = 0; /*ID*/ (void)ArrayRef(e->entries[EFLT_ID],e->Nentries[EFLT_ID]++); exp_get_entry(e,EFLT_ID) = (char *)strdup(fn); /*EN*/ (void)ArrayRef(e->entries[EFLT_EN],e->Nentries[EFLT_EN]++); exp_get_entry(e,EFLT_EN) = (char *)strdup(fn); /*CC*/ (void)ArrayRef(e->entries[EFLT_CC],e->Nentries[EFLT_CC]++); exp_get_entry(e,EFLT_CC) = (char *)strdup("Created from a staden format sequence assembly file"); seq = (char *) xmalloc(max_seq_size+1); if (!seq) return NULL; left = 0; right = 0; len = 0; lineno = 0; formatIsBap = 1; while (mfgets(line,sizeof(line),fp)!=NULL) { char *s; lineno++; if (lineno == 1) { int pos, ret; char *cp; /* * This maybe a fasta format file. */ if (line[0] == '>') { if (cp = strchr(line, ' ')) *cp = 0; if (cp = strchr(line, '\t')) *cp = 0; if (cp = strchr(line, '\n')) *cp = 0; exp_set_entry(e, EFLT_ID, strdup(line+1)); exp_set_entry(e, EFLT_EN, strdup(line+1)); continue; } /* * This maybe a file created from 'output consensus', * in which case it'll have the Staden format style of: * " <-----T2.00047----->" header on the first line. * * We strip this off. Argh - why don't Suns have the * ANSI function memmove() ? */ ret = sscanf(line, " <%*18s>%n", &pos); if (ret && pos == 21) { int i, e = sizeof(line)-21; for (i=0; i < e; i++) line[i] = line[i+21]; /* memmove((void *)line, * (void *)(line + 21), * sizeof(line)-21); */ } } if (line[0] == ';') { /******************************************** * Title line parsing *******************************************/ if (lineno==1 && !(line[1] == ';' || line[1] == '<' || line[1] == '>') ) { /* format of line is: * <ln> ::= ;<i6><i6><i6><c4><c+> * <i6> ::= <s><s><s><s><s><d> | ... <d><d><d><d><d><d> * <c4> ::= <C><C><C><s> * <c+> ::= <a><c+> | <a> * <a> is [a-zA-Z0-9.] * <s> is ' ' * <d> is [0-9] * <C> is [A-Z] */ int d; if (sscanf(line,";%6d%6d%6d",&d,&d,&d)==3 && strlen(line)>23) { /* trim off trailing white space */ trim_white_space(line+23); /*LN*/ (void)ArrayRef(e->entries[EFLT_LN],e->Nentries[EFLT_LN]++); exp_get_entry(e,EFLT_LN) = (char *)strdup(line+23); line[23]='\0'; /*LT*/ (void)ArrayRef(e->entries[EFLT_LT],e->Nentries[EFLT_LT]++); /* trim off trace type white space */ trim_white_space(line+19); exp_get_entry(e,EFLT_LT) = (char *)strdup(line+19); } } else if (formatIsBap) { switch (line[1]) { case '<': for(s=&line[2];*s;s++) { if(!isspace(*s) && isprint(*s)) seq[left++] = *s; } break; case '>': for(s=&line[2];*s;s++) { if(!isspace(*s) && isprint(*s)) seq[max_seq_size-right++] = *s; } break; case ';': /*TG*/ #if 0 trim_white_space(line); (void)ArrayRef(e->entries[EFLT_TG],e->Nentries[EFLT_TG]++); /* convert format from Staden format to * Experiment file format */ { char *cp; int pos, len; char type[5]; cp = (char *)xmalloc(strlen(line)+20); if (cp == NULL) break; sscanf(line, ";;%4s %6d %6d", type, &pos, &len); /* * Need to add 'left' to each start position * in tag. ASSUMPTION: 'left' has already been * defined. Ie that the ;< lines are before * any ;; lines. */ pos += left; values2tag(cp, type, pos, pos + len - 1, 2, &line[20]); exp_get_entry(e,EFLT_TG) = cp; } if (strncmp(line+2,"IGNC",4)==0 || strncmp(line+2,"CVEC",4)==0) { CS_from = atoi(&line[2+4+1]); } else if (strncmp(line+2,"IGNS",4)== 0 || strncmp(line+2,"SVEC",4)== 0) { SR = 1; } #endif break; default: break; } } } else { /******************************************** * The actual sequence bit *******************************************/ formatIsBap = 0; /* turn off title line parsing stuff */ for (s=line;*s;s++) { if(!isspace(*s) && isprint(*s)) seq[left+len++] = *s; } } } /* * The right cutoff has been stashed into the end of the array * Move to correct place */ for(i=(max_seq_size-(left+len))/2;i>=0;i--) { char temp; /* swap */ temp = seq[left+len+i]; seq[left+len+i] = seq[max_seq_size-i]; seq[max_seq_size-i] = temp; } /* null terminate */ seq[left+len+right] = '\0'; /*SQ*/ (void)ArrayRef(e->entries[EFLT_SQ],e->Nentries[EFLT_SQ]++); exp_get_entry(e,EFLT_SQ) = seq; /*SL*/ sprintf(line,"%d",left); (void)ArrayRef(e->entries[EFLT_SL],e->Nentries[EFLT_SL]++); exp_get_entry(e,EFLT_SL) = (char *)strdup(line); /*SR*/ if (SR) { sprintf(line,"%d",left+len+1); (void)ArrayRef(e->entries[EFLT_SR],e->Nentries[EFLT_SR]++); exp_get_entry(e,EFLT_SR) = (char *)strdup(line); } /*CS*/ if (CS_from) { if (CS_from == 1) { CS_to = left; } else { CS_from = left + len + 1; CS_to = left + len + right; } sprintf(line,"%d..%d",CS_from,CS_to); (void)ArrayRef(e->entries[EFLT_CS],e->Nentries[EFLT_CS]++); exp_get_entry(e,EFLT_CS) = (char *)strdup(line); } /*QR*/ if (!SR && !CS_from) { sprintf(line,"%d",left+len+1); (void)ArrayRef(e->entries[EFLT_QR],e->Nentries[EFLT_QR]++); exp_get_entry(e,EFLT_QR) = (char *)strdup(line); } #if 0 /*TG*/ { int i; /* need to add LEFT to each start position in tag */ for(i=0;i<e->Nentries[EFLT_TG];i++) { sprintf(line,"%4.4s %6d%s", arr(char *,e->entries[EFLT_TG],i), atoi(arr(char *,e->entries[EFLT_TG],i)+5)+left, arr(char *,e->entries[EFLT_TG],i)+11); xfree(arr(char *,e->entries[EFLT_TG],i)); arr(char *,e->entries[EFLT_TG],i) = (char *)strdup(line); } } #endif }
/* * A recursive break contig function. * bin_num The current bin being moved or split. * pos The contig break point. * offset The absolute positional offset of this bin in original contig * pleft The parent bin/contig record num in the left new contig * pright The parent bin/contig record num in the right new contig * child_no 0 or 1 - whether this bin is the left/right child of its parent */ static int break_contig_recurse(GapIO *io, HacheTable *h, contig_t *cl, contig_t *cr, tg_rec bin_num, int pos, int offset, int level, tg_rec pleft, tg_rec pright, int child_no, int complement) { int i, j, f_a, f_b; tg_rec rbin; bin_index_t *bin = get_bin(io, bin_num), *bin_dup ; //int bin_min, bin_max; int nseqs; tg_rec opright; /* old pright, needed if we revert back */ cache_incr(io, bin); if (bin->flags & BIN_COMPLEMENTED) { complement ^= 1; } if (complement) { f_a = -1; f_b = offset + bin->size-1; } else { f_a = +1; f_b = offset; } printf("%*sBreak offset %d pos %d => test bin %"PRIrec": %d..%d\n", level*4, "", offset, pos, bin->rec, NMIN(bin->start_used, bin->end_used), NMAX(bin->start_used, bin->end_used)); bin = cache_rw(io, bin); nseqs = bin->nseqs; bin->nseqs = 0; /* Invalidate any cached data */ bin_invalidate_track(io, bin, TRACK_ALL); if (bin->flags & BIN_CONS_VALID) { bin->flags |= BIN_BIN_UPDATED; bin->flags &= ~BIN_CONS_VALID; } //bin_min = bin->rng ? NMIN(bin->start_used, bin->end_used) : offset; //bin_max = bin->rng ? NMAX(bin->start_used, bin->end_used) : offset; /* * Add to right parent if this bin is to the right of pos, * or if the used portion is to the right and we have no left child. * * FIXME: Not a valid assumption! * The used portion of a bin is not a placeholder for the used portion * of all the the children beneath it. Therefore if the used portion of * this bin is > pos (and we have no left child) it still doesn't mean * that the absolute positions of the used portion of the right child * won't be < pos. */ if (offset >= pos /*|| (bin_min >= pos && !bin->child[0])*/) { printf("%*sADD_TO_RIGHT pl=%"PRIrec" pr=%"PRIrec"\n", level*4, "", pleft, pright); if (0 != break_contig_move_bin(io, bin, cl, pleft, cr, pright, child_no)) return -1; bin_incr_nseq(io, bin, nseqs); cache_decr(io, bin); return 0; } /* * Add to left parent if this bin is entirely to the left of pos, * or if the used portion is to the left and we have no right child. */ if (offset + bin->size < pos /*|| (bin_max < pos && !bin->child[1])*/) { printf("%*sADD_TO_LEFT\n", level*4, ""); //if (0 != break_contig_move_bin(io, bin, cr, pright, cl, pleft, child_no)) //return -1; bin_incr_nseq(io, bin, nseqs); cache_decr(io, bin); return 0; } /* * Nominally the bin overlaps both left and right and so needs duplicating. * There are cases though at the roots of our trees where duplicating is * unnecessary as it leads to empty bins at the root. In this case * we skip creating a duplicate for the right, or alternatively steal * the left root bin and use that instead. * * Similarly the range_t array will either be left where it is, moved to * the right contig, or split in half (creating a new one for the right). * * FIXED: always need this. Eg: * * |-------------empty--------------| * |----------------|---------------| * |--------|-------|--------|------| * ^ * | * break here * * In this case we need to duplicate the parent as it overlaps the left * bin, which may (or may not) have data that needs to end up in the right * hand contig. Just duplicate for now and free later on if needed. */ if (1 /* always! */ || pright != cr->rec || (bin->rng && NMAX(bin->start_used, bin->end_used) >= pos)) { //printf("NMAX=%d >= %d\n", NMAX(bin->start_used, bin->end_used), pos); rbin = 0; /* Possibly steal left contig's bin */ if (pleft == cl->rec && NMIN(bin->start_used, bin->end_used) >= pos) { #if 0 /* Currently this doesn't always work */ if (bin->child[1]) { bin_index_t *ch = get_bin(io, bin->child[1]); if (NMIN(ch->pos, ch->pos + ch->size-1) >= pos) { rbin = cl->bin; cl->bin = bin->child[0]; } } #else pleft = bin->rec; #endif } else { pleft = bin->rec; } /* Create new bin, or use root of contig if it's unused so far */ if (!rbin && pright == cr->rec) { rbin = cr->bin; } /* Otherwise we genuingly need a duplicate */ if (!rbin) rbin = bin_new(io, 0, 0, 0, GT_Bin); /* Initialise with duplicate values from left bin */ bin_dup = get_bin(io, rbin); bin_dup = cache_rw(io, bin_dup); bin_dup->size = bin->size; bin_dup->pos = bin->pos; bin_dup->parent = pright; bin_dup->parent_type = (pright == cr->rec ? GT_Contig : GT_Bin); bin_dup->flags = bin->flags | BIN_BIN_UPDATED; bin_dup->start_used = bin->start_used; bin_dup->end_used = bin->end_used; /* * Shift bin to offset if it's the contig root. * It'll be shifted back by the correct amount later. */ if (pright == cr->rec) { printf("moving root bin to offset=%d comp=%d\n", offset, complement); bin_dup->pos = offset; } printf("%*sCreated dup for right, rec %"PRIrec"\n", level*4,"", bin_dup->rec); break_contig_move_bin(io, bin_dup, cl, 0, cr, pright, child_no); opright = pright; pright = bin_dup->rec; } else { bin_dup = NULL; pleft = bin->rec; } if (!bin->rng) { /* Empty bin */ printf("%*sEMPTY range\n", level*4, ""); bin->start_used = bin->end_used = 0; bin->flags |= BIN_BIN_UPDATED; if (bin_dup) { bin_dup->start_used = bin_dup->end_used = 0; bin_dup->flags |= BIN_BIN_UPDATED; } } else if (NMIN(bin->start_used, bin->end_used) >= pos) { /* Move range to right contig */ printf("%*sDUP %"PRIrec", MOVE Array to right\n", level*4, "", bin_dup->rec); bin_dup->rng = bin->rng; bin_dup->rng_rec = bin->rng_rec; bin_dup->rng_free = bin->rng_free; if (bin_dup->rng_rec) bin_dup->flags |= BIN_RANGE_UPDATED; if (bin->rec != bin_dup->rec) { bin->rng = NULL; bin->rng_rec = 0; bin->rng_free = -1; bin->flags |= BIN_BIN_UPDATED; } bin->start_used = bin->end_used = 0; break_contig_reparent_seqs(io, bin_dup); if (bin_dup->rng) { int n = ArrayMax(bin_dup->rng); for (i = j = 0; i < n; i++) { range_t *r = arrp(range_t, bin_dup->rng, i), *r2; if (r->flags & GRANGE_FLAG_UNUSED) continue; if ((r->flags & GRANGE_FLAG_ISMASK) != GRANGE_FLAG_ISANNO) { HacheData hd; hd.i = 1; HacheTableAdd(h, (char *)&r->rec, sizeof(r->rec), hd,NULL); j++; } } bin_incr_nseq(io, bin_dup, j); } } else if (NMAX(bin->start_used, bin->end_used) < pos) { /* Range array already in left contig, so do nothing */ printf("%*sMOVE Array to left\n", level*4, ""); if (bin_dup) bin_dup->start_used = bin_dup->end_used = 0; if (bin->rng) { int n = ArrayMax(bin->rng); for (i = j = 0; i < n; i++) { range_t *r = arrp(range_t, bin->rng, i); if (r->flags & GRANGE_FLAG_UNUSED) continue; if ((r->flags & GRANGE_FLAG_ISMASK) != GRANGE_FLAG_ISANNO) { HacheData hd; hd.i = 0; HacheTableAdd(h, (char *)&r->rec, sizeof(r->rec), hd,NULL); j++; } } bin_incr_nseq(io, bin, j); } } else { /* Range array covers pos, so split in two */ int n, nl = 0, nr = 0; int lmin = bin->size, lmax = 0, rmin = bin->size, rmax = 0; printf("%*sDUP %"PRIrec", SPLIT array\n", level*4, "", bin_dup->rec); bin->flags |= BIN_RANGE_UPDATED; bin_dup->flags |= BIN_RANGE_UPDATED; bin_dup->rng = ArrayCreate(sizeof(range_t), 0); bin_dup->rng_free = -1; /* Pass 1 - hash sequences */ n = ArrayMax(bin->rng); for (i = 0; i < n; i++) { range_t *r = arrp(range_t, bin->rng, i); int cstart; /* clipped sequence positions */ seq_t *s; if (r->flags & GRANGE_FLAG_UNUSED) continue; if ((r->flags & GRANGE_FLAG_ISMASK) == GRANGE_FLAG_ISANNO) continue; s = (seq_t *)cache_search(io, GT_Seq, r->rec); if ((s->len < 0) ^ complement) { cstart = NMAX(r->start, r->end) - (s->right-1); } else { cstart = NMIN(r->start, r->end) + s->left-1; } if (cstart >= pos) { HacheData hd; hd.i = 1; HacheTableAdd(h, (char *)&r->rec, sizeof(r->rec), hd, NULL); } else { HacheData hd; hd.i = 0; HacheTableAdd(h, (char *)&r->rec, sizeof(r->rec), hd, NULL); } } /* Pass 2 - do the moving of anno/seqs */ n = ArrayMax(bin->rng); for (i = j = 0; i < n; i++) { range_t *r = arrp(range_t, bin->rng, i), *r2; int cstart; /* clipped sequence positions */ if (r->flags & GRANGE_FLAG_UNUSED) continue; if ((r->flags & GRANGE_FLAG_ISMASK) == GRANGE_FLAG_ISANNO) { cstart = NMAX(r->start, r->end); } else { seq_t *s = (seq_t *)cache_search(io, GT_Seq, r->rec); if ((s->len < 0) ^ complement) { cstart = NMAX(r->start, r->end) - (s->right-1); } else { cstart = NMIN(r->start, r->end) + s->left-1; } } if (cstart >= pos && ((r->flags & GRANGE_FLAG_ISMASK) == GRANGE_FLAG_ISANNO)) { anno_ele_t *a = (anno_ele_t *)cache_search(io, GT_AnnoEle, r->rec); /* If it's an annotation on a sequence < pos then we * still don't move. * * FIXME: we have no guarantee that the sequence being * annotated is in the same bin as this annotation, as * they may be different sizes and end up in different * bins. (Should we enforce anno always in same bin as seq? * If so, consensus annos fit anywhere?) */ if (a->obj_type == GT_Seq) { HacheItem *hi = HacheTableSearch(h, (char *)&r->pair_rec, sizeof(r->pair_rec)); if (hi) { if (hi->data.i == 0) cstart = pos-1; } else { puts("FIXME: annotation for seq in unknown place - " "work out correct location and move if needed."); } } } if (cstart >= pos) { r2 = (range_t *)ArrayRef(bin_dup->rng, ArrayMax(bin_dup->rng)); *r2 = *r; if (rmin > r->start) rmin = r->start; if (rmin > r->end) rmin = r->end; if (rmax < r->start) rmax = r->start; if (rmax < r->end) rmax = r->end; if ((r->flags & GRANGE_FLAG_ISMASK) == GRANGE_FLAG_ISSEQ) nr++; } else { if (lmin > r->start) lmin = r->start; if (lmin > r->end) lmin = r->end; if (lmax < r->start) lmax = r->start; if (lmax < r->end) lmax = r->end; if (j != i) { r2 = arrp(range_t, bin->rng, j); *r2 = *r; } j++; if ((r->flags & GRANGE_FLAG_ISMASK) == GRANGE_FLAG_ISSEQ) nl++; } } bin_incr_nseq(io, bin, nl); bin_incr_nseq(io, bin_dup, nr); ArrayMax(bin->rng) = j; #if 0 /* * Right now this causes problems, but I'm not sure why. Try again * after we've fixed the bin->nseqs issues and other deallocation * woes. */ if (ArrayMax(bin_dup->rng) == 0 && bin_dup->parent_type == GT_Bin) { /* We didn't need it afterall! Odd. */ bin_index_t *pb; printf("Purging bin %d that we didn't need afterall\n", bin_dup->rec); cache_rec_deallocate(io, GT_Bin, bin_dup->rec); pb = cache_search(io, GT_Bin, bin_dup->parent); if (pb->child[0] == bin_dup->rec) pb->child[0] = 0; if (pb->child[1] == bin_dup->rec) pb->child[1] = 0; bin_dup = NULL; pright = opright; } #endif if (bin_dup) break_contig_reparent_seqs(io, bin_dup); if (lmin < lmax) { bin->start_used = lmin; bin->end_used = lmax; } else { /* No data left in bin */ bin->start_used = 0; bin->end_used = 0; } printf("%*sLeft=>%d..%d right=>%d..%d\n", level*4, "", lmin, lmax, rmin, rmax); if (bin_dup) { if (rmin < rmax) { bin_dup->start_used = rmin; bin_dup->end_used = rmax; } else { /* No data moved in bin */ bin_dup->start_used = 0; bin_dup->end_used = 0; } } } /* Recurse */ for (i = 0; i < 2; i++) { bin_index_t *ch; if (!bin->child[i]) continue; ch = get_bin(io, bin->child[i]); if (0 != break_contig_recurse(io, h, cl, cr, bin->child[i], pos, NMIN(ch->pos, ch->pos + ch->size-1), level+1, pleft, pright, i, complement)) return -1; } cache_decr(io, bin); // if (bin_dup) // cache_decr(io, bin_dup); return 0; }
/* * Dumps a G database in an ASCII readable form. Modelled around the start * of the g_open_file() routine. */ void g_dump_file(char *fn) { GFile *gfile = NULL; char fnaux[1024]; AuxIndex aux_ind; int i; #define ABORT(E)\ {\ g_free_gfile(gfile); \ gfile = NULL; \ (void)gerr_set(E); \ perror("ABORT"); \ return; \ } /* check file name isn't too long */ if (strlen(fn) + strlen(G_AUX_SUFFIX) >= sizeof(fnaux)) ABORT(GERR_NAME_TOO_LONG); strcpy(fnaux, fn); strcat(fnaux, G_AUX_SUFFIX); /* allocate new data structure - GFile */ gfile = g_new_gfile(); if (gfile == NULL) ABORT(GERR_OUT_OF_MEMORY); /* set file name */ if ((gfile->fname = (char *)xmalloc(strlen(fn)+1)) != NULL) strcpy(gfile->fname, fn); /* open file and its aux */ /* LOW LEVEL IO HERE */ if ((gfile->fd = open(fn, O_RDONLY)) == -1) ABORT(GERR_OPENING_FILE); /* LOW LEVEL IO HERE */ if ((gfile->fdaux = open(fnaux, O_RDONLY)) == -1) ABORT(GERR_OPENING_FILE); /* LOW LEVEL IO HERE */ if (-1 == lseek(gfile->fdaux, 0, 0)) ABORT(GERR_SEEK_ERROR); if (g_read_aux_header(gfile->fdaux, &gfile->header)) ABORT(GERR_READ_ERROR); printf("** \n"); printf("** Opening file %s\n",fn); printf("** file_size = %"PRIGImage"\n", gfile->header.file_size); printf("** block_size = %"PRIGCardinal"\n", gfile->header.block_size); printf("** num_records = %"PRIGCardinal"\n", gfile->header.num_records); printf("** max_records = %"PRIGCardinal"\n", gfile->header.max_records); printf("** last_time = %"PRIGCardinal"\n", gfile->header.last_time); printf("** flags = %"PRIGHFlags"\n", gfile->header.flags); printf("** \n"); /* allocate index */ gfile->Nidx = gfile->header.num_records; if ((gfile->idx = ArrayCreate(sizeof(Index), gfile->Nidx)) == NULL ) ABORT(GERR_OUT_OF_MEMORY); (void) ArrayRef(gfile->idx, gfile->Nidx-1); for(i = 0; i < gfile->Nidx; i++) arr(Index, gfile->idx, i).flags = G_INDEX_NEW; /* read aux index and initialise */ /* LOW LEVEL IO HERE */ if (-1 == lseek(gfile->fdaux, sizeof(AuxHeader), 0)) ABORT(GERR_SEEK_ERROR); /* force Array.max field to be updated */ (void)ArrayRef(gfile->idx, gfile->header.num_records-1); printf("global_time %08x\n", gfile->header.last_time); for (i = 0; i < gfile->header.num_records; i++) { char buf[MAX_BUF]; int toggle, len, len_r; /* Load index for this record */ if (g_read_aux_index(gfile->fdaux, &aux_ind)) ABORT(GERR_READ_ERROR); /* Compute toggle */ toggle = g_toggle_state(gfile->header.last_time, &aux_ind); /* LOW LEVEL IO HERE */ if (-1 == lseek(gfile->fd, aux_ind.image[toggle], 0)) ABORT(GERR_SEEK_ERROR); len = MIN(aux_ind.used[toggle], MAX_BUF); /* LOW LEVEL IO HERE */ if (-1 == (len_r = read(gfile->fd, buf, len))) ABORT(GERR_READ_ERROR); if (len_r != len) { fprintf(stderr, "WARNING: Read too short. Requested %d, got %d\n", len, len_r); } printf("record %05d pos %020"PRIGImage" len %08d : %08x", i, aux_ind.image[toggle], aux_ind.used[toggle], (((((buf[0] << 8) + buf[1]) << 8) + buf[2]) << 8) + buf[3]); if (len > 4) printf(" %c%c%c%c%c%c%c%c\n", isprint(buf[4])?buf[4]:'.', isprint(buf[5])?buf[5]:'.', isprint(buf[6])?buf[6]:'.', isprint(buf[7])?buf[7]:'.', isprint(buf[8])?buf[8]:'.', isprint(buf[9])?buf[9]:'.', isprint(buf[10])?buf[10]:'.', isprint(buf[11])?buf[11]:'.'); else putchar('\n'); } #undef ABORT g_free_gfile(gfile); return; }
int fera___store(struct descriptor_s *niddsc_ptr, InStoreStruct *setup) { int mem_status = 1; int put_status = 1; int status; int num_dig; int num_mem; int i; int num_chan; int total_data; int *num_pts; unsigned short *buffer; int ind; #define return_on_error(f,retstatus) if (!((status = f) & 1)) return retstatus; last_nid = 0; num_dig = NElements(setup->head_nid + FERA_N_DIG_NAME); if (num_dig == 0) return FERA$_NODIG; num_chan = num_dig*16; total_data = 0; num_mem = NElements(setup->head_nid+FERA_N_MEM_NAME); if (num_mem == 0) return FERA$_NOMEM; num_pts = malloc(sizeof(int)*num_mem); for(i=0; i<num_mem; i++) { char *name = ArrayRef(setup->head_nid+FERA_N_MEM_NAME, i); num_pts[i] = 0; if (name) { return_on_error(DevCamChk(CamPiow(name, 1, 17, &one, 16, 0),&one,&one),status); return_on_error(DevCamChk(CamPiow(name, 0, 2, &num_pts[i], 16, 0),&one,&one),status); if (num_pts[i] >= 16*1024) { num_pts[i] = 16*1024; if (i==num_mem-1) mem_status = FERA$_OVER_RUN; } total_data += num_pts[i]; } } if (total_data % num_chan != 0) { status = FERA$_PHASE_LOST; return status; } buffer = malloc(total_data*sizeof(short)); for (i=0,ind=0; i< num_mem; ind+=num_pts[i],i++) { if (num_pts[i]) { char *name = ArrayRef(setup->head_nid+FERA_N_MEM_NAME, i); if (name) { return_on_error(DevCamChk(CamQstopw(name, 0, 2, num_pts[i], &buffer[ind], 16, 0), &one, &one), status) } } } status = Unpack(&buffer, num_pts, num_mem, num_chan, total_data/num_chan); if ((status&1) || (status == FERA$_CONFUSED) || (status == FERA$_OVERFLOW)) put_status = Put(buffer, total_data/num_chan, num_chan, setup->head_nid + FERA_N_EXT_CLOCK, setup->head_nid +FERA_N_OUTPUT); free(buffer); return (put_status &1) ? ((status&1) ? mem_status : status) : put_status; }