/* Function: p7_emit_FancyConsensus() * Synopsis: Emit a fancier consensus with upper/lower case and N/X's. * Incept: SRE, Fri May 14 09:33:10 2010 [Janelia] * * Purpose: Generate a consensus sequence for model <hmm>, consisting * of the maximum probability residue in each match state; * store this sequence in text-mode <sq> provided by the caller. * * If the probability of the consensus residue is less than * <min_lower>, show an ``any'' residue (N or X) instead. * If the probability of the consensus residue is $\geq$ * <min_lower> and less than <min_upper>, show the residue * as lower case; if it is $\geq$ <min_upper>, show it as * upper case. * * Returns: <eslOK> on success. * * Throws: <eslEINVAL> if the <sq> isn't in text mode. * * Xref: SRE:J6/59. */ int p7_emit_FancyConsensus(const P7_HMM *hmm, float min_lower, float min_upper, ESL_SQ *sq) { int k, x; float p; char c; int status; if (! esl_sq_IsText(sq)) ESL_EXCEPTION(eslEINVAL, "p7_emit_FancyConsensus() expects a text-mode <sq>"); if ((status = esl_sq_GrowTo(sq, hmm->M)) != eslOK) return status; for (k = 1; k <= hmm->M; k++) { if (hmm->mm && hmm->mm[k] == 'm') { //masked position, spit out the degenerate code if ((status = esl_sq_CAddResidue(sq, tolower(esl_abc_CGetUnknown(hmm->abc))) ) != eslOK) return status; } else { p = esl_vec_FMax( hmm->mat[k], hmm->abc->K); x = esl_vec_FArgMax(hmm->mat[k], hmm->abc->K); if (p < min_lower) c = tolower(esl_abc_CGetUnknown(hmm->abc)); else if (p >= min_upper) c = toupper(hmm->abc->sym[x]); else c = tolower(hmm->abc->sym[x]); if ((status = esl_sq_CAddResidue(sq, c)) != eslOK) return status; } } if ((status = esl_sq_CAddResidue(sq, '\0')) != eslOK) return status; return eslOK; }
/* Function: p7_oprofile_GetSSVEmissionScoreArray() * Synopsis: Retrieve MSV residue emission scores from a * profile into an array * * Purpose: Extract an implicitly 2D array of 8-bit int MSV residue * emission scores from a profile <om>. <arr> must * be allocated by the calling function to be of size * ( om->abc->Kp * ( om->M + 1 )), and indexing into the array * is done as [om->abc->Kp * i + c ] for character c at * position i. * * In the dummy implementation, we need to convert from the * float emission probabilities to 8-bit int scores. Conversion * is based on code from the function mf_conversion in impl_sse's * p7_oprofile.c * * Args: <om> - profile, containing emission information * <arr> - preallocated array into which scores will be placed * * Returns: <eslOK> on success. * * Throws: (no abnormal error conditions) */ int p7_oprofile_GetSSVEmissionScoreArray(const P7_OPROFILE *om, uint8_t *arr ) { int M = om->M; /* length of the query */ int i, j; float x; float max = 0.0; float scale; uint8_t bias; /* scale and bias required for float->8bit conversion */ scale = 3.0 / eslCONST_LOG2; /* scores in units of third-bits */ for (i = 0; i < om->abc->K; i++) max = ESL_MAX(max, esl_vec_FMax(om->rsc[i], (M+1)*2)); max = -1.0f * roundf(scale * -1.0 * max); //based on unbiased_byteify bias = (max > 255.) ? 255 : (uint8_t) max; for (i = 1; i <= om->M; i++) { for (j=0; j<om->abc->Kp; j++) { //based on p7_oprofile's biased_byteify() x = -1.0f * roundf(scale * om->rsc[j][(i) * p7P_NR + p7P_MSC]); arr[i*om->abc->Kp + j] = (x > 255. - bias) ? 255 : (uint8_t) (x + bias); } } return eslOK; }
float esl_vec_FLogSum(float *vec, int n) { int x; float max, sum; max = esl_vec_FMax(vec, n); sum = 0.0; for (x = 0; x < n; x++) if (vec[x] > max - 50.) sum += expf(vec[x] - max); sum = logf(sum) + max; return sum; }