Beispiel #1
1
static int difference_clip_contig(GapIO *io, int contig, int start, int end,
				int *old_start, int *old_end, int add_tags)
{
    int rnum;
    int win_len = 31;
    double disfract = 0.25;
    char *seq;
    int win_len2;
    int start2, end2, length2;
    int i, i_end, j;
    char *con;
    int count, worst_count;
    int lowest_dis, lowest_pos;
    int score, highest_score, highest_pos;
    int new_left, new_right;
    GReadings r;
    int nbases = 0;
    
    win_len2 = win_len / 2;

    /* Get consensus sequence */
    if (NULL == (con = (char *)xmalloc(io_clength(io, contig)+1)))
	return -1;
    calc_consensus(contig, 1, io_clength(io, contig), CON_SUM,
		   con, NULL,  NULL, NULL,
		   consensus_cutoff, quality_cutoff,
		   database_info, (void *)io);
    

    /* Find start reading */
    for (rnum = io_clnbr(io, contig);
	 io_relpos(io, rnum) < start;
	 rnum = io_rnbr(io, rnum))
	;

    /* Loop through readings up to 'end' position */
    for (; rnum && io_relpos(io, rnum) <= end; rnum = io_rnbr(io, rnum)) {
	/*
	 * Find segment with the lowest difference count, averaged
	 * over 'win_len' bases.
	 */
	io_aread_seq(io, rnum, &length2, &start2, &end2, &seq, NULL, NULL, 0);
	if (length2 < win_len) {
	    if (seq) xfree(seq);
	    continue;
	}

	count = 0;
	worst_count = 0;

	if (win_len > end2 - start2) {
	    if (seq) xfree(seq);
	    continue; /* too short to compare over win_len */
	}

	for (j = io_relpos(io, rnum) - 1, i = start2;
	     i < start2 + win_len && i < end2 - 1; i++, j++) {
	    if (!same_char(seq[i], con[j]))
		count++;
	}
	i_end = end2 - 2 - win_len2;
	lowest_dis = count;
	lowest_pos = start2 + win_len2;
	for (i = start2 + win_len2, j = io_relpos(io, rnum) - 1 + win_len2;
	     i < i_end; i++, j++) {
	    if (count < lowest_dis) {
		lowest_dis = count;
		lowest_pos = i;
	    }
	    if (count > worst_count)
		worst_count = count;
	    count -= !same_char(seq[i-win_len2], con[j-win_len2]);
	    count += !same_char(seq[i+win_len2+1], con[j+win_len2+1]);
	}

	if (worst_count < disfract * win_len) {
	    if (seq) xfree(seq);
	    continue;
	}

	gel_read(io, rnum, r);

	/*
	 * Work outwards from lowest_pos in both directions finding the
	 * location where the alignment score is highest. We used a fixed
	 * score/penalty system.
	 */
	score = highest_score = 0;
	highest_pos = lowest_pos;
	for (j = io_relpos(io, rnum) - 1 + lowest_pos - start2, i = lowest_pos;
	     i < r.end - 1; i++, j++) {
	    if (same_char(seq[i], con[j]))
		score += SCORE_MATCH;
	    else
		score += SCORE_MISMATCH;
	    if (score > highest_score) {
		highest_score = score;
		highest_pos = i;
	    }
	}
	/* printf("Read %d: Best match at %d, extend R to %d (score %d)\n",
	       rnum, lowest_pos, highest_pos, highest_score); */
	new_right = highest_pos + 2;

	score = highest_score = 0;
	highest_pos = lowest_pos;
	for (j = io_relpos(io, rnum) - 1 + lowest_pos - start2, i = lowest_pos;
	     i >= r.start; i--, j--) {
	    if (same_char(seq[i], con[j]))
		score += SCORE_MATCH;
	    else
		score += SCORE_MISMATCH;
	    if (score > highest_score) {
		highest_score = score;
		highest_pos = i;
	    }
	}
	/* printf("Read %d: Best match at %d, extend L to %d (score %d)\n",
	       rnum, lowest_pos, highest_pos, highest_score); */
	new_left = highest_pos;

	if (new_right < new_left + 2)
	    new_right = new_left + 2;
	
	/* Tag the change */
	if (add_tags && new_left != r.start) {
	    char buf[100];
	    int tag_st;

	    if (r.sense) {
		tag_st = r.length - new_left + 1;
	    } else {
		tag_st = r.start + 1;
	    }
	    sprintf(buf, "Difference clipped from old start at %d\n", r.start);
	    insert_NEW_tag(io, rnum, tag_st, new_left - r.start, "DIFF",
			   buf, 2);
	}

	if (add_tags && new_right != r.end) {
	    char buf[100];
	    int tag_st;

	    if (r.sense) {
		tag_st = r.length - r.end + 2;
	    } else {
		tag_st = new_right;
	    }
	    sprintf(buf, "Difference clipped from old end at %d\n", r.end);
	    insert_NEW_tag(io, rnum, tag_st, r.end - new_right, "DIFF",
			   buf, 2);
	}

	/* Update reading positions/length */
	gel_read(io, rnum, r);
	r.position += new_left - r.start;
	old_start[rnum] = r.start;
	old_end[rnum] = r.end;
	r.start = new_left;
	r.end = new_right;
	nbases += r.sequence_length - (r.end - r.start - 1);
	r.sequence_length = r.end - r.start - 1;
	gel_write(io, rnum, r);
	io_relpos(io, rnum) = r.position;
	io_length(io, rnum) = r.sense ? -r.sequence_length : r.sequence_length;

	if (seq) xfree(seq);
    }

    xfree(con);
    return nbases;
}
Beispiel #2
0
int MaplistCallback(const char *pName, int IsDir, int DirType, void *pUser)
{
	int l = str_length(pName);
	if(l < 4 || IsDir || str_comp(pName+l-4, ".map") != 0)
		return 0;

	char aBuf[128];
	str_format(aBuf, sizeof(aBuf), "maps/%s", pName);
	if(!s_pEngineMap->Load(aBuf))
		return 0;

	unsigned MapCrc = s_pEngineMap->Crc();
	s_pEngineMap->Unload();

	IOHANDLE MapFile = s_pStorage->OpenFile(aBuf, IOFLAG_READ, DirType);
	unsigned MapSize = io_length(MapFile);
	io_close(MapFile);

	char aMapName[8];
	str_copy(aMapName, pName, min((int)sizeof(aMapName),l-3));

	str_format(aBuf, sizeof(aBuf), "\t{\"%s\", {0x%02x, 0x%02x, 0x%02x, 0x%02x}, {0x%02x, 0x%02x, 0x%02x, 0x%02x}},\n", aMapName,
		(MapCrc>>24)&0xff, (MapCrc>>16)&0xff, (MapCrc>>8)&0xff, MapCrc&0xff,
		(MapSize>>24)&0xff, (MapSize>>16)&0xff, (MapSize>>8)&0xff, MapSize&0xff);
	io_write(s_File, aBuf, str_length(aBuf));

	return 0;
}
Beispiel #3
0
/*
 * Finds the readings covering a specific consensus base
 *
 * Arguments:
 *	io		Gap IO handle
 *	contig		Contig number
 *	pos		Contig position
 *
 * Returns:
 *	A malloc array of integer reading numbers. It is up to the caller
 *	to free this array with xfree.
 *	NULL for failure
 */
int *seqs_at_pos(GapIO *io, int contig, int pos) {
    int rnum;
    int *seqs = xmalloc(8 * sizeof(int)); /* 7 seqs plus 0 terminator */
    int seqs_dim = 8;
    int count = 0;

    if (!seqs)
	return NULL;

    for (rnum = io_clnbr(io, contig); rnum; rnum = io_rnbr(io, rnum)) {
	if (io_relpos(io, rnum) + ABS(io_length(io, rnum)) - 1 < pos)
	    continue;
	if (io_relpos(io, rnum) > pos)
	    break;
	if (count >= seqs_dim-1 /* -term */) {
	    seqs_dim *= 2;
	    if (NULL == (seqs = xrealloc(seqs, seqs_dim * sizeof(int))))
		return NULL;
	}
	seqs[count++] = rnum;
    }
    seqs[count++] = 0;

    return seqs;
}
Beispiel #4
0
CServerBrowser::CServerBrowser()
{
	m_pMasterServer = 0;
	m_ppServerlist = 0;
	m_pSortedServerlist = 0;

	m_NumFavoriteServers = 0;

	mem_zero(m_aServerlistIp, sizeof(m_aServerlistIp));

	m_pFirstReqServer = 0; // request list
	m_pLastReqServer = 0;
	m_NumRequests = 0;

	m_NeedRefresh = 0;

	m_NumSortedServers = 0;
	m_NumSortedServersCapacity = 0;
	m_NumServers = 0;
	m_NumServerCapacity = 0;

	m_Sorthash = 0;
	m_aFilterString[0] = 0;
	m_aFilterGametypeString[0] = 0;

	// the token is to keep server refresh separated from each other
	m_CurrentToken = 1;

	m_ServerlistType = 0;
	m_BroadcastTime = 0;

	m_LastSort = 0;

    //Load recent servers
    char aFilePath[1024];
    fs_storage_path("Teeworlds", aFilePath, sizeof(aFilePath));
    str_append(aFilePath, "/recent.cfg", sizeof(aFilePath));
    IOHANDLE RecentFile = io_open(aFilePath, IOFLAG_READ);
    if (RecentFile)
    {
        io_read(RecentFile, m_aRecentServers, io_length(RecentFile));
        m_NumRecentServers = io_length(RecentFile) / sizeof(NETADDR);
        io_close(RecentFile);
    }

}
Beispiel #5
0
bool CLocalizationDatabase::Load(const char *pFilename, IStorage *pStorage, IConsole *pConsole)
{
    // empty string means unload
    if(pFilename[0] == 0)
    {
        m_Strings.clear();
        m_CurrentVersion = 0;
        return true;
    }

    // read file data into buffer
    IOHANDLE File = pStorage->OpenFile(pFilename, IOFLAG_READ, IStorage::TYPE_ALL);
    if(!File)
        return false;
    int FileSize = (int)io_length(File);
    char *pFileData = (char *)mem_alloc(FileSize+1, 1);
    io_read(File, pFileData, FileSize);
    pFileData[FileSize] = 0;
    io_close(File);

    // init
    char aBuf[64];
    str_format(aBuf, sizeof(aBuf), "loaded '%s'", pFilename);
    pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "localization", aBuf);
    m_Strings.clear();

    // parse json data
    json_settings JsonSettings;
    mem_zero(&JsonSettings, sizeof(JsonSettings));
    char aError[256];
    json_value *pJsonData = json_parse_ex(&JsonSettings, pFileData, aError);
    if(pJsonData == 0)
    {
        pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, pFilename, aError);
        mem_free(pFileData);
        return false;
    }

    // extract data
    const json_value &rStart = (*pJsonData)["translated strings"];
    if(rStart.type == json_array)
    {
        for(unsigned i = 0; i < rStart.u.array.length; ++i)
            AddString((const char *)rStart[i]["or"], (const char *)rStart[i]["tr"]);
    }

    // clean up
    json_value_free(pJsonData);
    mem_free(pFileData);
    m_CurrentVersion = ++m_VersionCounter;
    return true;
}
Beispiel #6
0
int CSound::LoadWV(const char *pFilename)
{
	// don't waste memory on sound when we are stress testing
	if(g_Config.m_DbgStress)
		return -1;

	// no need to load sound when we are running with no sound
	if(!m_SoundEnabled)
		return -1;

	if(!m_pStorage)
		return -1;

	ms_File = m_pStorage->OpenFile(pFilename, IOFLAG_READ, IStorageTW::TYPE_ALL);
	if(!ms_File)
	{
		dbg_msg("sound/wv", "failed to open file. filename='%s'", pFilename);
		return -1;
	}

	int SampleID = AllocID();
	if(SampleID < 0)
		return -1;

	// read the whole file into memory
	int DataSize = io_length(ms_File);

	if(DataSize <= 0)
	{
		io_close(ms_File);
		dbg_msg("sound/wv", "failed to open file. filename='%s'", pFilename);
		return -1;
	}

	char *pData = new char[DataSize];
	io_read(ms_File, pData, DataSize);

	SampleID = DecodeWV(SampleID, pData, DataSize);

	delete[] pData;
	io_close(ms_File);
	ms_File = NULL;

	if(g_Config.m_Debug)
		dbg_msg("sound/wv", "loaded %s", pFilename);

	RateConvert(SampleID);
	return SampleID;
}
Beispiel #7
0
int
pre_assemble(int handle,
	     int num_readings,
	     char **reading_array)
{
    GapIO *io;
    int ngels;
    int nconts;
    int idbsiz;
    int *relpg;
    int *lngthg;
    int *lnbr;
    int *rnbr;

    if (NULL == (io = io_handle(&handle))) return -1;

    /* initialise fortran arrays */
    idbsiz = io_dbsize(io);
    relpg = &io_relpos(io,1);
    lngthg = &io_length(io,1);
    lnbr  = &io_lnbr(io,1);
    rnbr = &io_rnbr(io,1);
    
    if (-1 == load_preassembled(io, num_readings, reading_array)) {
	verror(ERR_WARN, "enter_preassembled", "failed");
    }
    
    update_fortran_arrays(handle, &ngels, &nconts, &idbsiz,
			  relpg, lngthg, lnbr, rnbr);
/*    
    dbchek_(handle, relpg, lngthg, lnbr, rnbr, idm, idbsiz, ngels, nconts,
	    &ierr);
*/
    if (db_check(io) != 0) {
	verror(ERR_FATAL, "enter_preassembled",
	       "The database is now inconsistent.\n"
	       "You may wish to revert to a copy or to disassemble the newly "
	       "assembled contig.");
    }

    flush2t(io);
    return 0;
} /* end pre_assemble */
Beispiel #8
0
static n_object * object_end_or_find(n_object * object, n_string name)
{
    n_object * previous_object = 0L;
    n_uint     hash = math_hash((n_byte *)name, io_length(name, STRING_BLOCK_SIZE));
    if (object == 0L)
    {
        return 0L;
    }
    
    do
    {
        if (hash == object->name_hash)
        {
            return previous_object;
        }
        previous_object = object;
        object = object->primitive.next;
    }while (object);
    return previous_object;
}
Beispiel #9
0
static n_object * obj_get(n_object * object, n_string name)
{
    n_object * set_object;
    n_int      string_length = io_length(name, STRING_BLOCK_SIZE);
    n_uint     hash = math_hash((n_byte *)name, string_length);
    
    if (object == 0L)
    {
        object = object_new();
    }
    if (object_type(&object->primitive) == OBJECT_EMPTY)
    {
        set_object = object;
    }
    else
    {
        n_object * previous_object = object_end_or_find(object, name);
        if (previous_object == 0L)
        {
            set_object = object;
        }
        else
        {
            set_object = previous_object->primitive.next;
            if (set_object == 0L)
            {
                set_object = object_new();
            }
            previous_object->primitive.next = set_object;
        }
    }
    
    set_object->name = name;
    set_object->name_hash = hash;
    
    return set_object;
}
Beispiel #10
0
void ReadServerList()
{
	mem_zero(m_aServerList, sizeof(m_aServerList));

	IOHANDLE File = io_open("serverlist.json", IOFLAG_READ);
	if (!File)
		return;

	int PlainLength = io_length(File);
	char aPlain[16384];

	io_read(File, aPlain, sizeof(aPlain));
	io_close(File);

	// compress
	uLongf DstLen = DDNETLIST_SIZE;

	if (compress((Bytef*)m_aServerList, &DstLen, (Bytef*)aPlain, PlainLength) == Z_OK)
	{
		m_ServerListLoaded = true;
		m_ServerListPlainLength = PlainLength;
		m_ServerListCompLength = DstLen;
	}
}
Beispiel #11
0
int CMain::ReadConfig()
{
	// read and parse config
	IOHANDLE File = io_open(m_Config.m_aConfigFile, IOFLAG_READ);
	if(!File)
	{
		dbg_msg("main", "Couldn't open %s", m_Config.m_aConfigFile);
		return 1;
	}
	int FileSize = (int)io_length(File);
	char *pFileData = (char *)mem_alloc(FileSize + 1, 1);

	io_read(File, pFileData, FileSize);
	pFileData[FileSize] = 0;
	io_close(File);

	// parse json data
	json_settings JsonSettings;
	mem_zero(&JsonSettings, sizeof(JsonSettings));
	char aError[256];
	json_value *pJsonData = json_parse_ex(&JsonSettings, pFileData, strlen(pFileData), aError);
	if(!pJsonData)
	{
		dbg_msg("main", "JSON Error in file %s: %s", m_Config.m_aConfigFile, aError);
		mem_free(pFileData);
		return 1;
	}

	// reset clients
	for(int i = 0; i < NET_MAX_CLIENTS; i++)
	{
		if(!Client(i)->m_Active || !Client(i)->m_Connected)
			continue;

		m_Server.Network()->Drop(Client(i)->m_ClientNetID, "Server reloading...");
	}
	mem_zero(m_aClients, sizeof(m_aClients));
	for(int i = 0; i < NET_MAX_CLIENTS; i++)
		m_aClients[i].m_ClientNetID = -1;

	// extract data
	int ID = 0;
	const json_value &rStart = (*pJsonData)["servers"];
	if(rStart.type == json_array)
	{
		for(unsigned i = 0; i < rStart.u.array.length; i++)
		{
			if(ID < 0 || ID >= NET_MAX_CLIENTS)
				continue;

			Client(ID)->m_Active = true;
			Client(ID)->m_Disabled = rStart[i]["disabled"].u.boolean;
			str_copy(Client(ID)->m_aName, rStart[i]["name"].u.string.ptr, sizeof(Client(ID)->m_aName));
			str_copy(Client(ID)->m_aUsername, rStart[i]["username"].u.string.ptr, sizeof(Client(ID)->m_aUsername));
			str_copy(Client(ID)->m_aType, rStart[i]["type"].u.string.ptr, sizeof(Client(ID)->m_aType));
			str_copy(Client(ID)->m_aHost, rStart[i]["host"].u.string.ptr, sizeof(Client(ID)->m_aHost));
			str_copy(Client(ID)->m_aLocation, rStart[i]["location"].u.string.ptr, sizeof(Client(ID)->m_aLocation));
			str_copy(Client(ID)->m_aPassword, rStart[i]["password"].u.string.ptr, sizeof(Client(ID)->m_aPassword));

			if(m_Config.m_Verbose)
			{
				if(Client(ID)->m_Disabled)
					dbg_msg("main", "[#%d: Name: \"%s\", Username: \"%s\", Type: \"%s\", Host: \"%s\", Location: \"%s\", Password: \"%s\"]",
						ID, Client(ID)->m_aName, Client(ID)->m_aUsername, Client(ID)->m_aType, Client(ID)->m_aHost, Client(ID)->m_aLocation, Client(ID)->m_aPassword);
				else
					dbg_msg("main", "#%d: Name: \"%s\", Username: \"%s\", Type: \"%s\", Host: \"%s\", Location: \"%s\", Password: \"%s\"",
						ID, Client(ID)->m_aName, Client(ID)->m_aUsername, Client(ID)->m_aType, Client(ID)->m_aHost, Client(ID)->m_aLocation, Client(ID)->m_aPassword);

			}
			ID++;
		}
	}

	// clean up
	json_value_free(pJsonData);
	mem_free(pFileData);

	// tell clients to reload the page
	m_JSONUpdateThreadData.m_ReloadRequired = 2;

	return 0;
}
Beispiel #12
0
/*
 * Finds holes in contigs (gaps where no sequence covers a region) and extends
 * the highest quality segment over that hole. old_start and old_end contain
 * the previous start and end quality clips. We make sure that we never extend
 * beyond these, even if it gives good quality. The reason for this is two
 * fold. Firstly it means we no the data is aligned that far (and hence save
 * ourselves a lot of work), and secondly it avoids worrying about vector tags.
 *
 * Our strategy, once we've found a hole, is to find all the readings that
 * extend over this hole from the left side and the right side. For these
 * readings we produce an array of length `size of hole' of the accumulated
 * expected number of errors to extend to that position in the hole.
 * Next, for each position in the hole, we pick the lowest error total from
 * readings from the left side of the hole and the lowest from the right side
 * and add these together. This gives us an estimated number of errors in the
 * consensus that we would create by extending these two readings to fill the
 * hole. The optimal solution is then the lowest summation; we have one sum
 * per position in the hole - ie `size of hole').
 */
static void fix_holes(GapIO *io, int contig, int *old_start, int *old_end)
{
    int rnum;
    int hole_start = 2, hole_end, hole_size;
    int left_count, right_count;
    int *left_rnums, *right_rnums, left_rnums_size, right_rnums_size;
    double **left_errs, **right_errs, *left_errs2, *right_errs2;
    int i;
    int max_len = find_max_gel_len(io, contig, 0)+10;
    GReadings r;

    left_rnums_size = right_rnums_size = 16;
    if (NULL == (left_rnums = xmalloc(left_rnums_size * sizeof(int))))
	return;
    if (NULL == (right_rnums = xmalloc(right_rnums_size * sizeof(int))))
	return;

    /* Find holes */
    for (rnum = io_clnbr(io, contig); rnum; rnum = io_rnbr(io, rnum)) {
	if (io_relpos(io, rnum) >= hole_start) {
	    hole_end = io_relpos(io, rnum) - 1;
	    hole_size = hole_end - hole_start + 1;
	    vmessage("Hole from %d to %d:", hole_start, hole_end);

	    /* Find overlapping left reads */
	    left_count = right_count = 0;
	    for (i = io_lnbr(io, rnum);
		 i && io_relpos(io, i) > hole_start - max_len;
		 i = io_lnbr(io, i)) {
		gel_read(io, i, r);
		if (r.position - r.start + old_end[i] - 1 > hole_start) {
		    left_rnums[left_count++] = i;
		    if (left_count >= left_rnums_size) {
			left_rnums_size *= 2;
			left_rnums = xrealloc(left_rnums,
					      left_rnums_size * sizeof(int));
			if (NULL == left_rnums)
			    return;
		    }
		}
	    }

	    /* Find overlapping right reads */
	    for (i = rnum;
		 i && io_relpos(io, i) < hole_start + max_len;
		 i = io_rnbr(io, i)) {
		gel_read(io, i, r);
		if (r.position - r.start + old_start[i] <= hole_end) {
		    right_rnums[right_count++] = i;
		    if (right_count >= right_rnums_size) {
			right_rnums_size *= 2;
			right_rnums = xrealloc(right_rnums,
					       right_rnums_size * sizeof(int));
			if (NULL == right_rnums)
			    return;
		    }
		}
	    }

	    if (left_count == 0 && right_count == 0) {
		verror(ERR_WARN, "quality_clip", "Hole in contig");
		continue;
	    }

	    /* Alloc accumulated error rate arrays - one per overlapping seq */
	    left_errs = (double **)xmalloc(left_count*sizeof(*left_errs)+1);
	    right_errs = (double **)xmalloc(right_count*sizeof(*right_errs)+1);
	    left_errs2 = (double *)xmalloc(left_count * hole_size *
					   sizeof(*left_errs2) + 1);
	    right_errs2 = (double *)xmalloc(right_count * hole_size *
					    sizeof(*right_errs2) + 1);
	    if (NULL == left_errs || NULL == right_errs ||
		NULL == left_errs2 || NULL == right_errs2)
		return;

	    for (i = 0; i < left_count; i++)
		left_errs[i] = left_errs2 + i * hole_size;
	    for (i = 0; i < right_count; i++)
		right_errs[i] = right_errs2 + i * hole_size;

	    /* Fill the accumulated error rate arrays */
	    for (i = 0; i < left_count; i++) {
		get_acc_errs_l(io, left_errs[i], left_rnums[i],
			       old_end[left_rnums[i]],
			       hole_start, hole_end);
	    }
	    for (i = 0; i < right_count; i++) {
		get_acc_errs_r(io, right_errs[i], right_rnums[i],
			       old_start[right_rnums[i]],
			       hole_start, hole_end);
	    }

	    /* Find the best left and right extensions and adjust them */
	    adjust_extensions(io, hole_start, hole_end,
			      left_errs, left_rnums, left_count,
			      right_errs, right_rnums, right_count);

	    xfree(left_errs);
	    xfree(right_errs);
	    xfree(left_errs2);
	    xfree(right_errs2);
	}

	if (io_relpos(io, rnum) + ABS(io_length(io, rnum)) > hole_start)
	    hole_start = io_relpos(io, rnum) + ABS(io_length(io, rnum));
    }

    xfree(left_rnums);
    xfree(right_rnums);
}
Beispiel #13
0
static void adjust_extensions(GapIO *io, int hole_start, int hole_end,
			      double **left_errs, int *left_rnums,
			      int left_count,
			      double **right_errs, int *right_rnums,
			      int right_count)
{
    int i;
    int h;
    int best_left, best_right;
    int best_hole_left, best_hole_right, best_hole_pos;
    double best_left_val, best_right_val, best_hole_val;
    GReadings r;
    int hole_size = hole_end - hole_start + 1;
    int ext_len;

    /*
     * Brute force search through all possible 'joint' positions in the hole
     * (unless either left_count or right_count is 0)
     */
    if (left_count && right_count) {
	best_hole_val = 1e20;
	best_hole_left = best_hole_right = best_hole_pos = 0;
	for (h = 0; h < hole_size; h++) {
	    best_left_val = best_right_val = 1e10;
	    best_left = best_right = 0;
	    
	    /* Pick left and right extension with fewest errors */
	    for (i = 0; i < left_count; i++) {
		if (left_errs[i][h] < best_left_val) {
		    best_left_val = left_errs[i][h];
		    best_left = i;
		}
	    }
	    for (i = 0; i < right_count; i++) {
		if (right_errs[i][h] < best_right_val) {
		    best_right_val = right_errs[i][h];
		    best_right = i;
		}
	    }
	    
	    if (best_left_val + best_right_val < best_hole_val) {
		best_hole_val = best_left_val + best_right_val;
		best_hole_left = best_left;
		best_hole_right = best_right;
		best_hole_pos = h;
	    }
	}

    } else if (left_count == 0) {
	/* Pick best right only */
	h = 0;
	best_hole_right = 0;
	best_right_val = 1e10;
	
	if (hole_size != 0) {
	    for (i = 0; i < right_count; i++) {
		if (right_errs[i][h] <  best_right_val) {
		    best_right_val = right_errs[i][h];
		    best_right = i;
		}
	    }
	} else {
	    best_right = 0;
	}

	best_hole_val = best_right_val;
	best_hole_pos = -1;

    } else {
	/* Pick best left only */
	h = hole_end - hole_start;
	best_hole_left = 0;
	best_left_val = 1e10;

	if (hole_size != 0) {
	    for (i = 0; i < left_count; i++) {
		if (left_errs[i][h] < best_left_val) {
		    best_left_val = left_errs[i][h];
		    best_left = i;
		}
	    }
	} else {
	    best_left = 0;
	}

	best_hole_val = best_left_val;
	best_hole_pos = hole_end - hole_start + 1;
    }

    if (left_count && right_count)
	vmessage(" extend #%d and #%d with %f expected errors\n",
		 left_rnums[best_hole_left], right_rnums[best_hole_right],
		 best_hole_val);
    else if (left_count)
	vmessage(" extend #%d with %f expected errors\n",
		 left_rnums[best_hole_left], best_hole_val);
    else
	vmessage(" extend #%d with %f expected errors\n",
		 right_rnums[best_hole_right], best_hole_val);

    if (left_count) {
	gel_read(io, left_rnums[best_hole_left], r);
	ext_len = best_hole_pos + hole_start -
	    (r.position + r.sequence_length) + 1;
	r.end += ext_len;
	r.sequence_length += ext_len;
	gel_write(io, left_rnums[best_hole_left], r);
	io_length(io, left_rnums[best_hole_left]) =
	    r.sense ? -r.sequence_length : r.sequence_length;
    }

    if (right_count) {
	gel_read(io, right_rnums[best_hole_right], r);
	ext_len = hole_size - best_hole_pos + r.position - hole_end - 1;
	r.start -= ext_len;
	r.position -= ext_len;
	r.sequence_length += ext_len;
	gel_write(io, right_rnums[best_hole_right], r);
	io_relpos(io, right_rnums[best_hole_right]) = r.position;
	io_length(io, right_rnums[best_hole_right]) =
	    r.sense ? -r.sequence_length : r.sequence_length;
    }
}
Beispiel #14
0
/*
 * Perform quality clipping on an individual contig.
 * This identifies low quality regions at the ends of contigs and clips them
 *
 * Note that this can produce holes, which need to be fixed by the fix_holes()
 * function, and can also reorder the readings.
 */
static int quality_clip_contig(GapIO *io, int contig, int start, int end,
			       int qual_avg, int *old_start, int *old_end)
{
    int rnum;
    int win_len = 31; /* odd num */
    int i, i_end;
    int left, right;
    GReadings r;
    int1 *conf = NULL;
    int conf_alloc = 10000; /* realloced as needed */
    int total;
    int qual_tot, win_len2;
    
    qual_tot = win_len * qual_avg;
    win_len2 = win_len / 2;

    if (NULL == (conf = (int1 *)xmalloc(conf_alloc)))
	return -1;

    /* Find start reading */
    for (rnum = io_clnbr(io, contig);
	 io_relpos(io, rnum) < start;
	 rnum = io_rnbr(io, rnum))
	;

    /*
     * Loop through readings up to 'end' position.
     * The leftmost and rightmost sequences need to be treated specially
     * as we do not want to clip these. Doing so will change the length of the
     * consensus. Doing that means that we need to deal with consensus tags
     * (shifting, clipping and deleting them).
     */
    for (; rnum && io_relpos(io, rnum) <= end; rnum = io_rnbr(io, rnum)) {
	/* Find left and right clip points */
	gel_read(io, rnum, r);
	if (r.length < win_len)
	    continue;

	/* Realloc conf if necessary */
	if (r.length > conf_alloc) {
	    int1 *conf2;
	    conf_alloc = r.length + 100;
	    conf2 = (int1 *)xrealloc(conf, conf_alloc);
	    if (!conf2) {
		xfree(conf);
		return -1;
	    }
	    conf = conf2;
	}

	if (DataRead(io, r.confidence, conf, r.length * sizeof(*conf),
		     sizeof(*conf)))
	    continue;

	/* Clip left by quality */
	if (rnum != io_clnbr(io, contig)) {
	    total = 0;
	    for (i = 0; i < win_len; i++)
		total += conf[i];

	    if (total > qual_tot) {
		i = r.start;
	    } else {
		i_end = r.length - win_len2 - 1;
		i = win_len2 + 1;
		do {
		    total += conf[i + win_len2] - conf[i - win_len2 - 1];
		    i++;
		} while (total < qual_tot && i < i_end);
		i--;
	    }
	    left = MAX(i, r.start);
	} else {
	    left = r.start;
	}

	/* Clip right by quality */
	if (r.position + r.sequence_length <= io_clength(io, contig)) {
	    total = 0;
	    for (i = 0; i < win_len; i++)
		total += conf[r.length - i - 1];
	    
	    if (total > qual_tot) {
		i = r.end;
	    } else {
		i = r.length - win_len2 - 2;
		i_end = win_len2 + 1;
		do {
		    total += conf[i - win_len2] - conf[i + win_len2 + 1];
		    i--;
		} while (total < qual_tot && i > i_end);
		i++;
	    }
	    right = MIN(i, r.end);
	} else {
	    right = r.end;
	}

	if (left >= r.end - 1)
	    left = r.end - 2;
	if (right <= r.start + 1)
	    right = r.start + 2;

	if (right < left + 2)
	    right = left + 2;

	/* printf("Gel %d: L %d->%d    R %d->%d\n",
	       rnum, r.start, left, r.end, right); */

	r.position += left - r.start;
	old_start[rnum] = r.start;
	old_end[rnum] = r.end;
	r.start = left;
	r.end = right;
	r.sequence_length = r.end - r.start - 1;

	gel_write(io, rnum, r);
	io_relpos(io, rnum) = r.position;
	io_length(io, rnum) = r.sense ? -r.sequence_length : r.sequence_length;
    }

    xfree(conf);
    return 0;
}
Beispiel #15
0
/*
 * Joins contig 'lnconr' to contig 'lnconl' at offset 'relx', producing a
 * new contig in place of 'lnconl'.
 * The old 'lnconr' is removed.
 *
 * Returns 0 for success, -1 for error (currently never)
 */
int dojoin(GapIO *io, int lnconl, int lnconr, int relx) {
    int gl_r = io_crnbr(io, lnconl);
    int gl_l;
    int gr_l = io_clnbr(io, lnconr);
    int i, len, right = 0;
    f_int tmp;
    GContigs c;
    reg_length rl;
    reg_join rj;

    /* Shift readings in lnconr by relx */
    io_relpos(io, gr_l) = relx+1;
    i = gr_l;
    while (i = io_rnbr(io, i)) {
	io_relpos(io, i) += relx;
    }

    /* Linkup ends of contigs (but not yet in correct left to right order) */
    io_lnbr(io, gr_l) = gl_r;
    io_rnbr(io, gl_r) = gr_l;

    /* Call MERGE() to shuffle the links to the correct order */
    tmp = io_dbsize(io) - lnconl;
    merge_(&io_relpos(io,1), &io_length(io,1), &io_lnbr(io,1), &io_rnbr(io,1),
	   &tmp, &io_dbsize(io));

    /* MERGE() doesn't save the readings, so do that ourselves */
    for (right = i = io_clnbr(io, lnconl); i; right = i, i = io_rnbr(io, i)) {
	GReadings r;

	gel_read(io, i, r);
	r.left = io_lnbr(io, i);
	r.right = io_rnbr(io, i);
	r.position = io_relpos(io, i);
	gel_write(io, i, r);
    }

    /* merge contig annotation lists and update contig length */
    merge_contig_tags(io, lnconl, lnconr, relx);

    /* merge note lists */
    merge_contig_notes(io, lnconr, lnconl);

    contig_read(io, lnconr, c);
    len = c.length + relx;

    contig_read(io, lnconl, c);
    if (c.length < len)
	c.length = len;
    c.right = right;
    contig_write(io, lnconl, c);
    io_clength(io, lnconl) = c.length;
    io_crnbr(io, lnconl) = c.right;

    /*
     * The order of notifications here is crucial.
     *
     * We need to firstly notify the right contig that it's been joined to
     * the left contig.
     *
     * Merge the contig registration lists (copy right into left).
     *
     * Then we delete the right contig. Note that this may imply that the
     * left contig number changes, so we convert to a gel number during the
     * duration of this call.
     *
     * Finally we then tell the left contig that it's length has changed.
     */

    /* Notify right of join */
    rj.job = REG_JOIN_TO;
    rj.contig = lnconl;
    rj.offset = relx;
    contig_notify(io, lnconr, (reg_data *)&rj);

    /* Merge lists */
    contig_register_join(io, lnconr, lnconl);
        
    /* Delete old contig (lnconr) */
    gl_l = io_clnbr(io, lnconl);
    io_delete_contig(io, lnconr);
    lnconl = rnumtocnum(io, gl_l);

    /* Notify left of join */
    rl.job = REG_LENGTH;
    rl.length = c.length;
    contig_notify(io, lnconl, (reg_data *)&rl);

    flush2t(io);

    return 0;
}
Beispiel #16
0
/*
 * Links a reading into a contig at a specified position, updating the
 * necessary information to maintain consistency.
 *
 * A positon <= 0 implies that this reading should go leftwards of the first
 * reading in this  contig. In this case we shift everything else rightwards.
 *
 * Returns 0 for success, -1 for failure.
 */
int link_reading(GapIO *io, int from_rnum, int rnum,
		 int contig, int position) {
    GContigs c;
    GReadings r, rt;
    int right = 0, left = 0;

    if (gel_read(io, rnum, r) || contig_read(io, contig, c))
	return -1;

    io_relpos(io, rnum) = r.position = position;

    /*
     * Chain left/right from anchor seq looking for a suitable place to insert.
     */
    if (from_rnum == 0)
	from_rnum = io_clnbr(io, contig);
    if (position >= io_relpos(io, from_rnum)) {
	left = io_lnbr(io, from_rnum);
	for (right = from_rnum; right; right = io_rnbr(io, right)) {
	    if (io_relpos(io, right) > position)
		break;
	    left = right;
	}
    } else {
	right = io_rnbr(io, from_rnum);
	for (left = from_rnum; left; left = io_lnbr(io, left)) {
	    if (io_relpos(io, left) <= position)
		break;
	    right = left;
	}
    }

    /*
     * Link the neighbours
     */
    if (left) {
	gel_read(io, left, rt);
	io_rnbr(io, left) = rt.right = rnum;
	gel_write(io, left, rt);
    } else {
	io_clnbr(io, contig) = c.left = rnum;
    }

    io_lnbr(io, rnum) = r.left = left;

    if (right) {
	gel_read(io, right, rt);
	io_lnbr(io, right) = rt.left = rnum;
	gel_write(io, right, rt);
    } else {
	io_crnbr(io, contig) = c.right = rnum;
    }

    io_rnbr(io, rnum) = r.right = right;

    /*
     * If this reading gets added onto the left end of a contig then
     * we need to shift all other readings right.
     */
    if (position < 1) {
	io_relpos(io, rnum) = r.position = 1;

	for (; right; right = io_rnbr(io, right)) {
	    gel_read(io, right, rt);
	    io_relpos(io, right) = rt.position = rt.position - position + 1;
	    gel_write(io, right, rt);
	}

	/* We also need to shift all tags right */
	shift_contig_tags(io, contig, 0, -position + 1);
    }

    /*
     * Update contig length. This is trivial when we've simply added a reading
     * somewhere in a contig other than the start, otherwise we need to
     * rescan.
     */
    if (position < 1) {
	int len = 0, end;

	for (right = io_clnbr(io, contig); right; right = io_rnbr(io, right)) {
	    end = io_relpos(io, right) + ABS(io_length(io, right));
	    if (end > len)
		len = end;
	}

	io_clength(io, contig) = c.length = len - 1;
    } else {
	if (r.sequence_length + r.position - 1 > c.length) {
	    io_clength(io, contig) = r.sequence_length + r.position - 1;
	    c.length = r.sequence_length + r.position - 1;
	}
    }

    /*
     * Write back
     */
    if (gel_write(io, rnum, r) || contig_write(io, contig, c))
	return -1;

    return 0;
}
Beispiel #17
0
char *assemble_direct(GapIO *io, int display, double max_mism,
		      char *inlist, int do_alignments, int enter_all) {
    consen_info *ci = NULL;
    SeqInfo *si;
    int ierr;
    char *file;
    int name, dir, pos, tol, maxpads = 25;
    int contig, rnum;
    align_info *ai;
    char *rname;
    int old_clen, count = 1;
    void *dl;
    char *res;
    
    dl = alloc_dlist();

    if (do_alignments)
	/* Calculate consensus */
	if (NULL == (ci = all_consensus(io, consensus_cutoff)))
	    return NULL;

    /* Loop around each input file */
    if (-1 == set_active_list(inlist))
        return NULL;
    while (file = get_active_list_item()) {
	UpdateTextOutput();
	vmessage("Processing number %8d: %s\n", count++, file);
	
	/*
	 * The last argument controls whether to set the QL/QR based on
	 * SL/SR. "1" disables SL/SR use, which is what we need when copying
	 * data in generated by extract_seq. FIXME: this could break things
	 * for other data sources though, unless explicit QL/QR values have
	 * been used.
	 */
	if (NULL == (si = read_sequence_details(file, 1))) {
	    verror(ERR_WARN, "directed_assembly", "couldn't read '%s'", file);
	    add_to_dlist(dl, file);
	    vmessage("  failed\n");
	    continue;
	}
	if (si->start < 0)
	    si->start = 0;
	if (si->end > si->length+1)
	    si->end = si->length+1;

	if (si->end - si->start <= 1 || si->length < 1) {
	    verror(ERR_WARN, "directed assembly", "sequence '%s' too short",
		   file);
	    add_to_dlist(dl, file);
	    freeSeqInfo(si);
	    vmessage("  failed\n");
	    continue;
	}

	if (NULL == (rname = read_sequence_name(si))) {
	    verror(ERR_WARN, "directed_assembly", "no name found for '%s'",
		   file);
	    add_to_dlist(dl, file);
	    freeSeqInfo(si);
	    vmessage("  failed\n");
	    continue;
	}

	/* FIXME: perform caching of names (also template and vector names) */
	if (get_gel_num(io, rname, GGN_NAME) > 0) {
	    verror(ERR_WARN, "directed_assembly",
		   "reading '%s' already exists", rname);
	    add_to_dlist(dl, file);
	    vmessage("  failed\n");
	    freeSeqInfo(si);
	    continue;
	}

	if (exp_Nentries(si->e, EFLT_AP) == 0) {
	    verror(ERR_WARN, "directed_assembly", "no AP line in '%s'", file);
	    add_to_dlist(dl, file);
	    vmessage("  failed\n");
	    freeSeqInfo(si);
	    continue;
	}

	if (0 != AP_parse(io, rname, exp_get_entry(si->e, EFLT_AP),
			  &name, &dir, &pos, &contig, &tol)) {
	    verror(ERR_WARN, "directed_assembly", "invalid AP line in '%s'.",
		   file);
	    name = 0;

	    if (!enter_all) {
		verror(ERR_WARN, "directed_assembly",
		       "invalid AP line in '%s'", file);
		add_to_dlist(dl, file);
		vmessage("  failed\n");
		freeSeqInfo(si);
		continue;
	    }
	}

	ai = NULL;

	if (name != 0) {
	    if (tol >= 0 && do_alignments) {
		/* Align with existing contig */
		ai = assemble_align(io, si, ci, contig, &pos, dir, tol,
				    display, maxpads, max_mism, &ierr);
		if (NULL == ai) {
		    if (ierr == 2) {
			vmessage("  Percentage mismatch is too high\n");
			name = 0;
		    } else if (ierr == 3) {
			vmessage("  Reading does not overlap\n");
			name = 0;
		    } else if (ierr == 4) {
			vmessage("  Reading does not overlap "
				 "within tolerance\n");
			name = 0;
		    } else {
			verror(ERR_WARN, "directed_assembly",
			       "failed to align reading '%s'", file);
			name = 0;
		    }

		    if (!enter_all) {
			add_to_dlist(dl, file);
			freeSeqInfo(si);
			continue;
		    }
		}
	    }
	}

	if (name == 0) {
	    /* new contig */
	    vmessage("  Creating new contig\n");
	    if (-1 == io_init_contig(io, NumContigs(io)+1))
		return NULL;

	    contig=NumContigs(io);
	    io_clnbr(io, contig) = 0;
	    io_crnbr(io, contig) = 0;
	    io_clength(io, contig) = 0;
	    pos = 0;
	}

	old_clen = io_clength(io, contig);
	if (-1 == (rnum = enter_reading(io, si, dir, ai, contig, pos)))
	    return NULL;
	
	if (-1 == link_reading(io, name, rnum, contig, pos))
	    return NULL;

	freeSeqInfo(si);
	if (ai) {
	    xfree(ai->res);
	    xfree(ai);
	}

	if (do_alignments) {
	    if (-1 == recalc_consensus(io, ci, contig, pos,
				       ABS(io_length(io, rnum)),
				       old_clen, io_clength(io, contig))) {
		verror(ERR_WARN, "directed_assembly",
		       "failed to recalculate consensus - quitting");
		return NULL;
	    }
	}
    }

    remove_contig_holes_all(io);

    flush2t(io);
    if (do_alignments)
	free_all_consensus(ci);

    res = strdup(read_dlist(dl));
    free_dlist(dl);

    return res;
}
Beispiel #18
0
/*
 * Takes a multiple alignment and updates the on-disk data structures to
 * match. This needs to correct confidence values, original positions and
 * tags too.
 */
void update_io(GapIO *io, int cnum, MALIGN *malign) {
    GContigs c;
    GReadings r, lastr;
    CONTIGL *cl;
    int lastrnum = 0;
    int rnum;

    contig_read(io, cnum, c);
    for (cl = malign->contigl; cl; cl = cl->next) {
	char *seq;

	rnum = cl->id;
	gel_read(io, rnum, r);
	seq = TextAllocRead(io, r.sequence);

	/* Link this->left and this->left->right. Save this->left */
	io_lnbr(io, rnum) = lastrnum;
	r.left = lastrnum;
	if (lastrnum) {
	    io_rnbr(io, lastrnum) = rnum;
	    lastr.right = rnum;
	    gel_write(io, lastrnum, lastr);
	} else {
	    io_clnbr(io, cnum) = rnum;
	    c.left = rnum;
	}

	/* Check if sequence has changed. If so assign a new one */
	if (memcmp(seq+r.start, cl->mseg->seq, cl->mseg->length) != 0) {
	    int newlen = r.start + (r.length+1 - r.end) + cl->mseg->length;
	    int i, j, np;
	    int1 *conf;
	    int2 *opos;
	    char *newseq  = (char *)malloc(newlen+1);
	    int1 *newconf = (int1 *)malloc(newlen+1);
	    int2 *newopos = (int2 *)malloc((newlen+1)*2);

	    conf = DataAllocRead(io, r.confidence,     1);
	    opos = DataAllocRead(io, r.orig_positions, 2);

	    /* Copy from 1 to r.start (base coords) */
	    for (j = 0; j < r.start; j++) {
		newseq[j]  = seq[j];
		newconf[j] = conf[j];
		newopos[j] = opos[j];
	    }
	    memcpy(&newseq[j], cl->mseg->seq, cl->mseg->length);

	    /*
	     * Step through both old and new sequences working out how
	     * they differ. This will (*should*) be entire pad movements.
	     * i = index to old seq
	     * j = index to new seq
	     * np = number of pads added minus removed from old seq.
	     */
	    np = 0;
	    for (i = j; i < r.length && j < r.start + cl->mseg->length;) {
		if (toupper(newseq[j]) == toupper(seq[i]) ||
		    (seq[i] == '.' && newseq[j] == 'N')) {
		    newconf[j] = conf[i];
		    newopos[j] = opos[i];
		    i++, j++;
		    continue;
		}

		/* Pad removed */
		if (seq[i] == '*') {
		    i++;
		    if (io_length(io, rnum) < 0) {
			tag_shift_for_delete(io, rnum, r.length - i + 1);
		    } else {
			tag_shift_for_delete(io, rnum, i+np--);
		    }
		    continue;
		}

		/* Pad created */
		if (newseq[j] == '*') {
		    int k;
		    int cl = 0, cr = 0;
		    for (k = i-1; k >= 0; k--) {
			if (seq[k] != '*') {
			    cl = conf[k];
			    break;
			}
		    }
		    for (k = i+1; k < r.length; k++) {
			if (seq[k] != '*') {
			    cr = conf[k];
			    break;
			}
		    }
		    newconf[j] = MIN(cl, cr); /* min conf of neighbours */
		    newopos[j] = 0;
		    j++;
		    if (io_length(io, rnum) < 0) {
			tag_shift_for_insert(io, rnum, r.length - i + 1);
		    } else {
			tag_shift_for_insert(io, rnum, i+ ++np);
		    }
		    continue;
		}

		fprintf(stderr, "Alignment introduced non-pad character");
		abort();
	    }

	    /* Pads previously at the end of the reading & now removed */
	    for (; i < r.start + r.sequence_length;) {
		if (seq[i] == '*') {
		    i++;
		    if (io_length(io, rnum) < 0) {
			tag_shift_for_delete(io, rnum, r.length - i + 1);
		    } else {
			tag_shift_for_delete(io, rnum, i+np--);
		    }
		} else {
		    /* Error: clipped data that wasn't a pad */
		    abort();
		}
	    }

	    /* Should only be pads remaining in newseq, if anything */
	    for (; j < r.start + cl->mseg->length; j++) {
		if (newseq[j] != '*') {
		    fprintf(stderr, "Alignment introduced non-pad character");
		    abort();
		}
		newconf[j] = 0;
		newopos[j] = 0;
	    }

	    /* Same for remaining data in seq - only pads */
	    for (; i < r.end-1; i++) {
		if (seq[i] != '*') {
		    fprintf(stderr, "Alignment skipped non-pad character");
		    abort();
		}
	    }

	    /* Append on the right hand cutoff data */
	    for (; i < r.length; i++, j++) {
		newseq[j]  = seq[i];
		newconf[j] = conf[i];
		newopos[j] = opos[i];
	    }
	    if (j != newlen) {
		abort();
	    }
	    r.length = j;

	    TextWrite(io, r.sequence,       newseq,  r.length);
	    DataWrite(io, r.confidence,     newconf, r.length, 1);
	    DataWrite(io, r.orig_positions, newopos, r.length * 2, 2);

	    xfree(conf);
	    xfree(newconf);
	    xfree(opos);
	    xfree(newopos);
	    xfree(newseq);
	}

	r.position = cl->mseg->offset + 1;
	r.sequence_length = cl->mseg->length;
	r.end = r.start + r.sequence_length + 1;
	
	lastr = r;
	lastrnum = rnum;

	io_relpos(io, rnum) = r.position;
	io_length(io, rnum) = io_length(io, rnum) < 0 ? -r.sequence_length
	                                              : +r.sequence_length;
	xfree(seq);
    }

    if (lastrnum) {
	io_rnbr(io, lastrnum) = 0;
	lastr.right = 0;
	gel_write(io, lastrnum, lastr);
    }

    c.length = malign->length;
    c.right = lastrnum;
    io_clength(io, cnum) = c.left;
    io_crnbr(io, cnum) = c.right;
    contig_write(io, cnum, c);

    io_clength(io, cnum) = c.length;

    update_consensus_tags(io, cnum, malign);
}
Beispiel #19
0
int CSkins::SkinScan(const char *pName, int IsDir, int DirType, void *pUser)
{
	int l = str_length(pName);
	if(l < 5 || IsDir || str_comp(pName+l-5, ".json") != 0)
		return 0;

	CSkins *pSelf = (CSkins *)pUser;

	// read file data into buffer
	char aBuf[512];
	str_format(aBuf, sizeof(aBuf), "skins/%s", pName);
	IOHANDLE File = pSelf->Storage()->OpenFile(aBuf, IOFLAG_READ, IStorage::TYPE_ALL);
	if(!File)
		return 0;
	int FileSize = (int)io_length(File);
	char *pFileData = (char *)mem_alloc(FileSize, 1);
	io_read(File, pFileData, FileSize);
	io_close(File);

	// init
	CSkin Skin = pSelf->m_DummySkin;
	str_copy(Skin.m_aName, pName, min((int)sizeof(Skin.m_aName),l-4));
	if(pSelf->Find(Skin.m_aName, true) != -1)
		return 0;
	bool SpecialSkin = pName[0] == 'x' && pName[1] == '_';

	// parse json data
	json_settings JsonSettings;
	mem_zero(&JsonSettings, sizeof(JsonSettings));
	char aError[256];
	json_value *pJsonData = json_parse_ex(&JsonSettings, pFileData, FileSize, aError);
	mem_free(pFileData);

	if(pJsonData == 0)
	{
		pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, aBuf, aError);
		return 0;
	}

	// extract data
	const json_value &rStart = (*pJsonData)["skin"];
	if(rStart.type == json_object)
	{
		for(int PartIndex = 0; PartIndex < NUM_SKINPARTS; ++PartIndex)
		{
			const json_value &rPart = rStart[(const char *)ms_apSkinPartNames[PartIndex]];
			if(rPart.type != json_object)
				continue;

			// filename
			const json_value &rFilename = rPart["filename"];
			if(rFilename.type == json_string)
			{
				int SkinPart = pSelf->FindSkinPart(PartIndex, (const char *)rFilename, SpecialSkin);
				if(SkinPart > -1)
					Skin.m_apParts[PartIndex] = pSelf->GetSkinPart(PartIndex, SkinPart);
			}

			// use custom colors
			bool UseCustomColors = false;
			const json_value &rColour = rPart["custom_colors"];
			if(rColour.type == json_string)
			{
				UseCustomColors = str_comp((const char *)rColour, "true") == 0;
			}
			Skin.m_aUseCustomColors[PartIndex] = UseCustomColors;

			// color components
			if(!UseCustomColors)
				continue;

			for(int i = 0; i < NUM_COLOR_COMPONENTS; i++)
			{
				if(PartIndex != SKINPART_MARKING && i == 3)
					continue;

				const json_value &rComponent = rPart[(const char *)ms_apColorComponents[i]];
				if(rComponent.type == json_integer)
				{
					switch(i)
					{
					case 0: Skin.m_aPartColors[PartIndex] = (Skin.m_aPartColors[PartIndex]&0xFF00FFFF) | (rComponent.u.integer << 16); break;
					case 1:	Skin.m_aPartColors[PartIndex] = (Skin.m_aPartColors[PartIndex]&0xFFFF00FF) | (rComponent.u.integer << 8); break;
					case 2: Skin.m_aPartColors[PartIndex] = (Skin.m_aPartColors[PartIndex]&0xFFFFFF00) | rComponent.u.integer; break;
					case 3: Skin.m_aPartColors[PartIndex] = (Skin.m_aPartColors[PartIndex]&0x00FFFFFF) | (rComponent.u.integer << 24); break;
					}
				}
			}
		}
	}

	// clean up
	json_value_free(pJsonData);

	// set skin data
	Skin.m_Flags = SpecialSkin ? SKINFLAG_SPECIAL : 0;
	if(DirType != IStorage::TYPE_SAVE)
		Skin.m_Flags |= SKINFLAG_STANDARD;
	if(g_Config.m_Debug)
	{
		str_format(aBuf, sizeof(aBuf), "load skin %s", Skin.m_aName);
		pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "skins", aBuf);
	}
	pSelf->m_aSkins.add(Skin);

	return 0;
}
Beispiel #20
0
/*
 * Enters a reading. This does not perform any linking of neighbours and
 * updating of the contig. If an alignment buffer 'res' is non NULL then
 * it is used as a list of edits. See the calign() code for details of
 * the format for this buffer.
 *
 * It does however edit and enter the tags (on both the reading and
 * consensus).
 *
 * Returns reading number for success, -1 for failure.
 */
int enter_reading(GapIO *io, SeqInfo *si, int comp, align_info *ai,
		  int contig, int position) {
    GReadings r;
    int reading;
    char *name;
    int start, end, length, alength;
    char *seq = NULL;
    int1 *conf = NULL;
    int2 *opos = NULL;
    anno_info *anno_r, *anno_c;
    int anno_rl, anno_cl;
    int retcode = -1;
    int i;

    /*
     * Allocate
     */
    io_init_reading(io, NumReadings(io)+1);
    reading = NumReadings(io);


    /*
     * Write the reading name
     */
    if (NULL == (name = read_sequence_name(si)))
	goto end;
    write_rname(io, reading, name);


    /*
     * length, start, end, sense
     */
    length = si->length;
    start = si->start;
    end = si->end;
    alength = length + 100;

    /* Allocate temporary buffers */
    seq = (char *)xmalloc(alength * sizeof(*seq));
    conf = (int1 *)xmalloc(alength * sizeof(*conf));
    opos = (int2 *)xmalloc(alength * sizeof(*opos));
    if (!seq || !conf || !opos)
	goto end;
    
    /*
     * Obtain the sequence, original positions, and confidence values.
     */
    strcpy(seq, exp_get_entry(si->e, EFLT_SQ));
    SeqInfo_opos(si, opos, length);
    SeqInfo_conf(si, conf, length);


    /*
     * Complement if necessary
     */
    if (comp)
	io_complement_seq(&length, &start, &end, seq, conf, opos);


    /*
     * Load the tags into memory
     */
    anno_r = create_anno_list(si, EFLT_TG, &anno_rl, length);
    anno_c = create_anno_list(si, EFLT_TC, &anno_cl, 0);
    
    /*
     * Edit the sequence, consensus and tags
     */
    if (ai)
	edit_sequence(io, ai, &alength, &length, &start, &end,
		      &seq, &conf, &opos, contig,
		      comp, anno_r, anno_rl, anno_c, anno_cl);


    /*
     * write sequence to file
     */
    if (io_write_seq(io, reading, &length, &start, &end, seq, conf, opos)) {
	verror(ERR_WARN, "enter_reading",
	       "Problem writing new sequence to database: %s", name);
	return -1;
    }
    /* Shouldn't this be in io_write_seq? */
    gel_read(io, reading, r);
    r.sequence_length = end - start - 1;
    if (comp) {
	io_length(io, reading) = -r.sequence_length;
	r.sense = GAP_SENSE_REVERSE;
    } else {
	io_length(io, reading) = r.sequence_length;
	r.sense = GAP_SENSE_ORIGINAL;
    }
    gel_write(io, reading, r);


    /*
     * write raw data info
     */
    if (exp_Nentries(si->e, EFLT_LT) &&
	exp_Nentries(si->e, EFLT_LN)) {
	if (io_write_rd(io,
			reading,
			exp_get_entry(si->e, EFLT_LN),
			strlen(exp_get_entry(si->e, EFLT_LN)),
			exp_get_entry(si->e, EFLT_LT),
			strlen(exp_get_entry(si->e, EFLT_LT)))) {
	    verror(ERR_WARN, "enter_reading",
		   "Problem writing raw data information to database: %s",
		   name);
	    return -1;
	}
    }

    /*
     * Write the tag data
     */
    write_anno_list(io, anno_r, anno_rl, reading, 0, comp,
		    start, end, length);
    write_anno_list(io, anno_c, anno_cl, -contig, position-1-r.start,
		    comp, start, end, length);
    free_anno_list(anno_r, anno_rl);
    free_anno_list(anno_c, anno_cl);


    /*
     * Add NoTes
     */
    for(i = 0; i < exp_Nentries(si->e, EFLT_NT); i++) {
	create_note_for_gel(io, reading,
			    arr(char *, si->e->entries[EFLT_NT], i));
    }

    /*
     * write everything else
     */
    retcode = add_seq_details(io, reading, si) ? -1 : reading;

 end:
    if (seq)
	xfree(seq);
    if (conf)
	xfree(conf);
    if (opos)
	xfree(opos);

    return retcode;
}
/*
 * Match callback.
 * 'obj' is a match contained within the check assembly list.
 */
void *checkass_obj_func(int job, void *jdata, obj_checkass *obj,
			mobj_checkass *ca) {
    static char buf[80];
    obj_cs *cs;
    int cs_id;

    cs_id = type_to_result(ca->io, REG_TYPE_CONTIGSEL, 0);
    cs = result_data(ca->io, cs_id);

    switch(job) {
    case OBJ_LIST_OPERATIONS:
	return "Information\0Hide\0Invoke contig editor *\0"
	    "SEPARATOR\0Remove\0";

    case OBJ_INVOKE_OPERATION:
	switch(*((int *)jdata)) {
	case 0: /* Information */
	    vfuncgroup(1, "2D plot matches");
	case -1: /* Information from results manager */
	    start_message();
	    vmessage("check_assembly match:\n");
	    vmessage("    From contig %s(#%"PRIrec") at %d\n",
		     get_contig_name(ca->io, ABS(obj->c1)),
		     io_clnbr(ca->io, ABS(obj->c1)), obj->pos1);
	    vmessage("    With contig %s(#%"PRIrec") at %d\n",
		     get_contig_name(ca->io, ABS(obj->c2)),
		     io_clnbr(ca->io, ABS(obj->c2)), obj->pos2);
	    vmessage("    Length %d, mismatch %2.2f%%\n\n",
		     obj->length, ((float)obj->score)/10000);
	    end_message(cs->window);
	    break;

	case 1: /* Hide */
	    obj_hide(GetInterp(), cs->window, obj,
		     (mobj_repeat *)ca, csplot_hash);
	    break;

	case -2: /* default */
	case 2: /* Invoke contig editor */ {
	    tg_rec cnum, llino;
	    int pos;

	    obj->flags |= OBJ_FLAG_VISITED;
	    ca->current = obj - ca->match;
	    Tcl_VarEval(GetInterp(), "CSLastUsed ", CPtr2Tcl(ca), NULL);

	    cnum  = abs(obj->c1);
	    llino = obj->read;
	    pos   = obj->pos1 - io_relpos(ca->io, llino);
	    if (pos < 1)
		pos = 1;
	    if (pos > ABS(io_length(ca->io, llino)))
		pos = ABS(io_length(ca->io, llino));

//	    if ((id = editor_available(cnum, 1)) != -1) {
//		move_editor(id, llino, pos);
//	    } else {
		edit_contig(ca->io, cnum, llino, pos);
//	    }
	    break;
	}

	case 3: /* Remove */
	    obj_remove(GetInterp(), cs->window, obj,
		       (mobj_repeat *)ca, csplot_hash);
	    break;

        }
        break;

    case OBJ_GET_BRIEF:
	sprintf(buf,
		"check_assembly: #%"PRIrec"@%d len %d, mis %2.2f%%",
		obj->read, obj->pos1, obj->length, ((float)obj->score)/10000);
	return buf;
    }

    return NULL;
}
Beispiel #22
0
/*
 * Perform quality clipping on an individual contig based on runs of Ns.
 * The idea is to clip of sections that are left in by phrap due to flukey
 * matches (an N match scores zero, so will not be rejected unless there are
 * other mismatches).
 *
 * Note that this can produce holes, which need to be fixed by the fix_holes()
 * function, and can also reorder the readings.
 */
static int N_clip_contig(GapIO *io, int contig, int start, int end,
			 int *old_start, int *old_end)
{
    int rnum;
    int i;
    int left, right;
    GReadings r;
    int scoretab[256];
    
    /* Find start reading */
    for (rnum = io_clnbr(io, contig);
	 io_relpos(io, rnum) < start;
	 rnum = io_rnbr(io, rnum))
	;

    for (i = 0; i < 256; i++) {
	scoretab[i] = 0; /* K, R, Y, etc */
    }
    scoretab['N'] = scoretab['n'] = scoretab['-'] = 1;
    scoretab['A'] = scoretab['a'] = -1;
    scoretab['C'] = scoretab['c'] = -1;
    scoretab['G'] = scoretab['g'] = -1;
    scoretab['T'] = scoretab['t'] = -1;

    /*
     * Loop through readings up to 'end' position.
     * The leftmost and rightmost sequences need to be treated specially
     * as we do not want to clip these. Doing so will change the length of the
     * consensus. Doing that means that we need to deal with consensus tags
     * (shifting, clipping and deleting them).
     */
    for (; rnum && io_relpos(io, rnum) <= end; rnum = io_rnbr(io, rnum)) {
	char *seq;

	gel_read(io, rnum, r);
	io_aread_seq(io, rnum, NULL, NULL, NULL,
			 &seq, NULL, NULL, 0);

	/* Clip left */
	if (rnum != io_clnbr(io, contig)) {
	    int score = 0, best_score = 0, best_pos = -1;
	    
	    for (i = r.start; i < r.end-1 && score >= -10; i++) {
		score += scoretab[(unsigned char)seq[i]];
		if (best_score <= score) {
		    best_score = score;
		    best_pos = i;
		}
	    }
	    left = (best_pos != -1) ? best_pos+1 : r.start;
	} else {
	    left = r.start;
	}

	/* Clip right */
	if (rnum != io_crnbr(io, contig)) {
	    int score = 0, best_score = 0, best_pos = -1;
	    
	    for (i = r.end-2; i >= r.start && score >= -10; i--) {
		score += scoretab[(unsigned char)seq[i]];
		if (best_score <= score) {
		    best_score = score;
		    best_pos = i;
		}
	    }
	    right = (best_pos != -1) ? best_pos+1 : r.end;
	} else {
	    right = r.end;
	}

	if (left >= r.end - 1)
	    left = r.end - 2;
	if (right <= r.start + 1)
	    right = r.start + 2;

	if (right < left + 2)
	    right = left + 2;

	if (r.start < left)
	    vmessage("Read #%d: clipping %d base%s from left end\n",
		     rnum, left-r.start, left-r.start ? "s" : "");

	if (r.end > right)
	    vmessage("Read #%d: clipping %d base%s from right end\n",
		     rnum, r.end - right, r.end - right  ? "s" : "");

	/*
	printf("Gel %d: L %d->%d    R %d->%d\n",
	       rnum, r.start, left, r.end, right);
	*/

	r.position += left - r.start;
	old_start[rnum] = r.start;
	old_end[rnum] = r.end;
	r.start = left;
	r.end = right;
	r.sequence_length = r.end - r.start - 1;

	gel_write(io, rnum, r);
	io_relpos(io, rnum) = r.position;
	io_length(io, rnum) = r.sense ? -r.sequence_length : r.sequence_length;

	xfree(seq);
    }

    return 0;
}
Beispiel #23
0
void CCountryFlags::LoadCountryflagsIndexfile()
{
	// read file data into buffer
	const char *pFilename = "countryflags/index.json";
	IOHANDLE File = Storage()->OpenFile(pFilename, IOFLAG_READ, IStorage::TYPE_ALL);
	if(!File)
	{
		Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "countryflags", "couldn't open index file");
		return;
	}
	int FileSize = (int)io_length(File);
	char *pFileData = (char *)mem_alloc(FileSize, 1);
	io_read(File, pFileData, FileSize);
	io_close(File);

	// parse json data
	json_settings JsonSettings;
	mem_zero(&JsonSettings, sizeof(JsonSettings));
	char aError[256];
	json_value *pJsonData = json_parse_ex(&JsonSettings, pFileData, FileSize, aError);
	mem_free(pFileData);

	if(pJsonData == 0)
	{
		Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, pFilename, aError);
		return;
	}

	// extract data
	const json_value &rInit = (*pJsonData)["country codes"];
	if(rInit.type == json_object)
	{
		enum
		{
			NUM_INDICES = 2,
		};
		const char *paIndices[NUM_INDICES] = {"custom", "ISO 3166-1"};
		for(int Index = 0; Index < NUM_INDICES; ++Index)
		{
			const json_value &rStart = rInit[(const char *)paIndices[Index]];
			if(rStart.type == json_array)
			{
				for(unsigned i = 0; i < rStart.u.array.length; ++i)
				{
					char aBuf[64];

					// validate country code
					int CountryCode = (json_int_t)rStart[i]["code"];
					if(CountryCode < CODE_LB || CountryCode > CODE_UB)
					{
						str_format(aBuf, sizeof(aBuf), "country code '%i' not within valid code range [%i..%i]", CountryCode, CODE_LB, CODE_UB);
						Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "countryflags", aBuf);
						continue;
					}

					// add entry
					const char *pCountryName = rStart[i]["id"];
					CCountryFlag CountryFlag;
					CountryFlag.m_CountryCode = CountryCode;
					str_copy(CountryFlag.m_aCountryCodeString, pCountryName, sizeof(CountryFlag.m_aCountryCodeString));
					if(g_Config.m_ClLoadCountryFlags)
					{
						// load the graphic file
						CImageInfo Info;
						str_format(aBuf, sizeof(aBuf), "countryflags/%s.png", pCountryName);
						if(!Graphics()->LoadPNG(&Info, aBuf, IStorage::TYPE_ALL))
						{
							char aMsg[64];
							str_format(aMsg, sizeof(aMsg), "failed to load '%s'", aBuf);
							Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "countryflags", aMsg);
							continue;
						}
						CountryFlag.m_Texture = Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0);
						mem_free(Info.m_pData);
					}
					m_aCountryFlags.add_unsorted(CountryFlag);

					// print message
					if(g_Config.m_Debug)
					{
						str_format(aBuf, sizeof(aBuf), "loaded country flag '%s'", pCountryName);
						Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "countryflags", aBuf);
					}
				}
			}
		}
	}

	// clean up
	json_value_free(pJsonData);
	m_aCountryFlags.sort_range();

	// find index of default item
	int DefaultIndex = 0, Index = 0;
	for(sorted_array<CCountryFlag>::range r = m_aCountryFlags.all(); !r.empty(); r.pop_front(), ++Index)
		if(r.front().m_CountryCode == -1)
		{
			DefaultIndex = Index;
			break;
		}

	// init LUT
	if(DefaultIndex != 0)
		for(int i = 0; i < CODE_RANGE; ++i)
			m_CodeIndexLUT[i] = DefaultIndex;
	else
		mem_zero(m_CodeIndexLUT, sizeof(m_CodeIndexLUT));
	for(int i = 0; i < m_aCountryFlags.size(); ++i)
		m_CodeIndexLUT[max(0, (m_aCountryFlags[i].m_CountryCode-CODE_LB)%CODE_RANGE)] = i;
}