/* Function: cp9_Clone() * Date: EPN, Thu Dec 1 10:30:18 2011 * Purpose: Clone a CP9 HMM CP9_t object */ CP9_t * cp9_Clone(CP9_t *cp9) { CP9_t *cp9dup = NULL; int status; if ((cp9dup = AllocCPlan9(cp9->M, cp9->abc)) == NULL) return NULL; if ((status = cp9_Copy(cp9, cp9dup)) != eslOK) goto ERROR; return cp9dup; ERROR: FreeCPlan9(cp9dup); return NULL; }
/* Function: CP9_2sub_cp9() * EPN 09.24.06 * * Purpose: Given a template CM Plan 9 HMM, build a sub-model that * models only a subset of the consensus columns of the * original alignment. This requires a bit of care for * the initial and final node of the sub CP9, and * straightforward copying of parameters for the rest. * * The new CP9 is constructed in Global Needleman/Wunsch * mode. The orig_hmm MUST be in global mode. THIS IS * CHECKED FOR IN A VERY FRAGILE MANNER! * * The approach here is to allocate and fill the new * sub CP9. There might be a better way - transforming * the original CP9 into the new sub CP9 using a method * involving pointer rearrangement, but I'm not sure * how to do this. * * Args: orig_hmm - the CP9 model w/ data-dep prob's valid * ret_sub_hmm - the new sub CP9 hmm, allocated here, must * be freed by caller. * spos - first consensus column modelled by original * CP9 HMM the sub CP9 HMM models. * epos - final consensus column modelled by original * CP9 HMM the sub CP9 HMM models. * orig_phi - the 2D phi array for the original CP9 HMM. * Return: (void) * HMM probabilities are modified. */ void CP9_2sub_cp9(CP9_t *orig_hmm, CP9_t **ret_sub_hmm, int spos, int epos, double **orig_phi) { CP9_t *sub_hmm; int i, x; int orig_pos; sub_hmm = AllocCPlan9((epos-spos+1), orig_hmm->abc); for(x = 0; x < MAXABET; x++) { sub_hmm->null[x] = orig_hmm->null[x]; } /* No special (*x* states in Plan 7) states in CM Plan 9 */ /* First we just copy the parameters for spos..epos from the template HMM. * This is *slightly* wasteful, as we'll overwrite a few of these later. */ for(i = 0; i <= (epos-spos+1); i++) { orig_pos = i + spos - 1; if(i > 0) { for(x = 0; x < MAXABET; x++) { sub_hmm->mat[i][x] = orig_hmm->mat[orig_pos][x]; sub_hmm->msc[x][i] = orig_hmm->msc[x][orig_pos]; } sub_hmm->begin[i] = orig_hmm->begin[orig_pos]; sub_hmm->end[i] = orig_hmm->end[orig_pos]; sub_hmm->bsc[i] = orig_hmm->bsc[orig_pos]; sub_hmm->esc[i] = orig_hmm->esc[orig_pos]; if((i > 1) && ((0. - sub_hmm->begin[i] > 0.00000001) || (sub_hmm->begin[i] - 0. > 0.00000001))) { cm_Fail("ERROR in cp9_2sub_cp9() is original CP9 HMM not in global (NW) mode? i: %d\n", i); } } for(x = 0; x < MAXABET; x++) { sub_hmm->ins[i][x] = orig_hmm->ins[orig_pos][x]; sub_hmm->isc[x][i] = orig_hmm->isc[x][orig_pos]; } for(x = 0; x < cp9_NTRANS; x++) { sub_hmm->t[i][x] = orig_hmm->t[orig_pos][x]; sub_hmm->tsc[x][i] = orig_hmm->tsc[x][orig_pos]; } } /* Make the necessary modifications. */ CP9_reconfig2sub(sub_hmm, spos, epos, 1, sub_hmm->M, orig_phi); sub_hmm->el_self = orig_hmm->el_self; sub_hmm->el_selfsc = orig_hmm->el_selfsc; sub_hmm->flags |= CPLAN9_HASBITS; /* raise the log-odds ready flag */ *ret_sub_hmm = sub_hmm; return; }