예제 #1
0
파일: fera.c 프로젝트: LucyScott/mdsplus
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
/*
 * 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;
}
예제 #5
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 {
예제 #6
0
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;

}
예제 #7
0
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;
}
예제 #8
0
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
    }
예제 #9
0
/*
 * 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;
}
예제 #10
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;
}
예제 #11
0
파일: fera.c 프로젝트: LucyScott/mdsplus
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;
}