/* Function: p7_checkptmx_DumpFBRow() * Synopsis: Dump one row from fwd or bck version of the matrix. * * Purpose: Dump current row <dpc> of forward or backward calculations from * DP matrix <ox> for diagnostics. The index <rowi> is used * as a row label, along with an additional free-text label * <pfx>. (The checkpointed backward implementation * interleaves backward row calculations with recalculated * fwd rows, both of which it is dumping; they need to be * labeled something like "fwd" and "bck" to distinguish * them in the debugging dump.) */ int p7_checkptmx_DumpFBRow(P7_CHECKPTMX *ox, int rowi, __m128 *dpc, char *pfx) { union { __m128 v; float x[p7_VNF]; } u; float *v = NULL; /* */ int Q = ox->Qf; int M = ox->M; float *xc = (float *) (dpc + Q*p7C_NSCELLS); int logify = (ox->dump_flags & p7_SHOW_LOG) ? TRUE : FALSE; int maxpfx = ox->dump_maxpfx; int width = ox->dump_width; int precision = ox->dump_precision; int k,q,z; int status; ESL_ALLOC(v, sizeof(float) * ( (Q*p7_VNF) + 1)); v[0] = 0.; /* Line 1. M cells: unpack, unstripe, print */ for (q = 0; q < Q; q++) { u.v = P7C_MQ(dpc, q); for (z = 0; z < p7_VNF; z++) v[q+Q*z+1] = u.x[z]; } fprintf(ox->dfp, "%*s %3d M", maxpfx, pfx, rowi); for (k = 0; k <= M; k++) fprintf(ox->dfp, " %*.*f", width, precision, (logify ? esl_logf(v[k]) : v[k])); /* a static analyzer may complain about v[k] being uninitialized * if it isn't smart enough to see that M,Q are linked. */ /* Line 1 end: Specials */ for (z = 0; z < p7C_NXCELLS; z++) fprintf(ox->dfp, " %*.*f", width, precision, (logify ? esl_logf(xc[z]) : xc[z])); fputc('\n', ox->dfp); /* Line 2: I cells: unpack, unstripe, print */ for (q = 0; q < Q; q++) { u.v = P7C_IQ(dpc, q); for (z = 0; z < p7_VNF; z++) v[q+Q*z+1] = u.x[z]; } fprintf(ox->dfp, "%*s %3d I", maxpfx, pfx, rowi); for (k = 0; k <= M; k++) fprintf(ox->dfp, " %*.*f", width, precision, (logify ? esl_logf(v[k]) : v[k])); fputc('\n', ox->dfp); /* Line 3. D cells: unpack, unstripe, print */ for (q = 0; q < Q; q++) { u.v = P7C_DQ(dpc, q); for (z = 0; z < p7_VNF; z++) v[q+Q*z+1] = u.x[z]; } fprintf(ox->dfp, "%*s %3d D", maxpfx, pfx, rowi); for (k = 0; k <= M; k++) fprintf(ox->dfp, " %*.*f", width, precision, (logify ? esl_logf(v[k]) : v[k])); fputc('\n', ox->dfp); fputc('\n', ox->dfp); free(v); return eslOK; ERROR: if (v) free(v); return status; }
/* Function: p7_null3_score() * * Purpose: Calculate a correction (in log_2 odds) to be applied * to a sequence, using a null model based on the * composition of the target sequence. * The null model is constructed /post hoc/ as the * distribution of the target sequence; if the target * sequence is 40% A, 5% C, 5% G, 40% T, then the null * model is (0.4, 0.05, 0.05, 0.4). This function is * based heavily on Infernal's ScoreCorrectionNull3(), * with two important changes: * - it leaves the log2 conversion from NATS to BITS * for the calling function. * - it doesn't include the omega score modifier * (based on prior probability of using the null3 * model), again leaving this to the calling function. * * Args: abc - alphabet for hit (only used to get alphabet size) * dsq - the sequence the hit resides in * tr - trace of the alignment, used to find the match states * (non-match chars are ignored in computing freq, not used if NULL) * start - start position of hit in dsq * stop - end position of hit in dsq * bg - background, used for the default null model's emission freq * ret_sc - RETURN: the correction to the score (in NATS); * caller subtracts this from hit score to get * corrected score. * Return: void, ret_sc: the log-odds score correction (in NATS). */ void p7_null3_score(const ESL_ALPHABET *abc, const ESL_DSQ *dsq, P7_TRACE *tr, int start, int stop, P7_BG *bg, float *ret_sc) { float score = 0.; int status; int i; float *freq; int dir; int tr_pos; ESL_ALLOC(freq, sizeof(float) * abc->K); esl_vec_FSet(freq, abc->K, 0.0); /* contract check */ if(abc == NULL) esl_exception(eslEINVAL, FALSE, __FILE__, __LINE__, "p7_null3_score() alphabet is NULL.%s\n", ""); if(dsq == NULL) esl_exception(eslEINVAL, FALSE, __FILE__, __LINE__, "p7_null3_score() dsq alphabet is NULL.%s\n", ""); if(abc->type != eslRNA && abc->type != eslDNA) esl_exception(eslEINVAL, FALSE, __FILE__, __LINE__, "p7_null3_score() expects alphabet of RNA or DNA.%s\n", ""); dir = start < stop ? 1 : -1; if (tr != NULL) { /* skip the parts of the trace that precede the first match state */ tr_pos = 2; i = start; while (tr->st[tr_pos] != p7T_M) { if (tr->st[tr_pos] == p7T_N) i += dir; tr_pos++; } /* tally frequencies from characters hitting match state*/ while (tr->st[tr_pos] != p7T_E) { if (tr->st[tr_pos] == p7T_M) { if(esl_abc_XIsGap(abc, dsq[i])) esl_exception(eslEINVAL, FALSE, __FILE__, __LINE__, "in p7_null3_score(), res %d is a gap!%s\n", ""); esl_abc_FCount(abc, freq, dsq[i], 1.); } if (tr->st[tr_pos] != p7T_D ) i += dir; tr_pos++; } } else { /* tally frequencies from the full envelope */ for (i=ESL_MIN(start,stop); i <= ESL_MAX(start,stop); i++) { if(esl_abc_XIsGap(abc, dsq[i])) esl_exception(eslEINVAL, FALSE, __FILE__, __LINE__, "in p7_null3_score(), res %d is a gap!%s\n", ""); esl_abc_FCount(abc, freq, dsq[i], 1.); } } esl_vec_FNorm(freq, abc->K); /* now compute score modifier (nats) - note: even with tr!=NULL, this includes the unmatched characters*/ for (i = 0; i < abc->K; i++) score += freq[i]==0 ? 0.0 : esl_logf( freq[i]/bg->f[i] ) * freq[i] * ( (stop-start)*dir +1) ; /* Return the correction to the bit score. */ score = p7_FLogsum(0., score); *ret_sc = score; return; ERROR: esl_exception(eslEINVAL, FALSE, __FILE__, __LINE__, "p7_null3_score() memory allocation error.%s\n", ""); return; /* never reached */ }