/********************************************************************************************************
 * QRNA - Comparative analysis of biological sequences 
 *         with pair hidden Markov models, pair stochastic context-free
 *        grammars, and probabilistic evolutionary  models.
 *       
 * Version 2.0.3 (MAY 2004)
 *
 * Copyright (C) 2000-2004 Howard Hughes Medical Institute/Washington University School of Medicine
 * All Rights Reserved
 * 
 *     This source code is distributed under the terms of the
 *     GNU General Public License. See the files COPYING and LICENSE
 *     for details.
 ***********************************************************************************************************/

/* evolrnamodel.c
 * 
 *
 * ER, Mon May 17 10:03:12 CDT 2004 [STL, at work with Coro]
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <time.h>

#include "funcs.h"
#include "evolfuncs.h"
#include "globals.h"
#include "squid.h"
#include "structs.h"

/* Function: ConstructRNAModel()
 * Date:     ER, Tue Jun  8 13:30:43 CDT 1999 [St. Louis]
 *
 * Modified: ER, JUL 24 2002 [St. Louis]
 *
 * Modified: ER, Thu Jan 16 16:59:19 CST 2003 [St. Louis]
 *
 *
 * Purpose:  Build the RNA model from the null model under
 *           certain simplifying assumptions; namely, that
 *           P(x1 y1 x2 y2) = P(x1 y1) P (x2 y2) P(x1 x2) / (P(x1) P(x2))
 *
 * Args:     pammodel[64][64]
 *           cfg      -- the file with the SCFG model
 *           rnamodel -- pointer to alloc'ed rnamodel
 *
 * Returns:  void
 *           fills in rnamodel
 */
void
EvolConstructRNAModel(struct psubs_s    *mutpxy_star, 
		      struct psubs_s    *mut5pxy_star, 
		      struct psubs_s    *mutpxy_rna_unpaired_star, 
		      struct psubs_s    *mut5pxy_rna_unpaired_star, 
		      struct psubs_s    *mut5pxy_rna_loop_star, 
		      struct psubs_s    *mutpxy_rna_paired_star,   
		      struct psubs_s    *mut5pxy_rna_paired_star, 
		      struct pnonsubs_s *pair5prob_star, 
		      struct psubs_s    *riboprob_star, 
		      double ***cfg_node,
		      int win, double tfactor, struct rnamodel_s *rna, struct nullmodel_s *null, 
		      double *targetfreq, int changefreq, int use_ribo_oldrna, int pedantic, int verbose)
{
  struct psubs_s    *mut5pxy_rna_paired;     /* for paired positions   */
  struct psubs_s    *mut5pxy_rna_unpaired;   /* for unpaired positions */
  struct psubs_s    *mut5pxy_rna_loop;       /* for  positions in loops */
  struct pnonsubs_s *pair5prob;
  struct psubs_s    *riboprob;
  struct psubs_s    *ribo5prob;
  struct pnonsubs_s *ribomutcond;
  struct pnonsubs_s *ribo5mutcond;
  double             sum;                      /* For normalization purposes +*/
  int                idx;                      /* Index for transition prob's              +*/
  int                i,j;                      /* Symbols for emission prob's              +*/
  int                len;                      /* Length of a loop (< MAXRNALOOP)          +*/
  double             ave_len_ROB;             /* expected length of the other models */
  double             ave_len_ROE;
  double             ave_len_ROJ;
  double             ave_len_ROB_zero;             /* expected length of the other models */
  double             ave_len_ROE_zero;
  double             ave_len_ROJ_zero;
  double             ave_len_ROB_infty;             /* expected length of the other models */
  double             ave_len_ROE_infty;
  double             ave_len_ROJ_infty;
  double             ave_len_Rloop;
  double             is1_ave,  is1_sd;
  double             is2b_ave, is2b_sd;
  double             is2i_ave, is2i_sd;
  double             p, logp;
  double             corr;
  int                geo_len;
  int                islog;
  
  if (verbose) printf("Construct RNA model at time = %.4f\n", tfactor);

  /* the oth model has a paramente tau that set the invers of the average length generated by those models
   * This is how I set them as a few percentages of the length under analysis.
   */
  ave_len_ROB_zero = EXP2(0.70*LOG2((double)win));
  ave_len_ROE_zero = EXP2(0.70*LOG2((double)win));
  ave_len_ROJ_zero = EXP2(0.70*LOG2((double)win));

  ave_len_ROB       = EXP2(1.00*LOG2(ave_len_ROB_zero));
  ave_len_ROE       = EXP2(1.00*LOG2(ave_len_ROE_zero));
  ave_len_ROJ       = EXP2(1.00*LOG2(ave_len_ROJ_zero));

  ave_len_ROB_infty = EXP2(1.00*LOG2(ave_len_ROB_zero));
  ave_len_ROE_infty = EXP2(1.00*LOG2(ave_len_ROE_zero));
  ave_len_ROJ_infty = EXP2(1.00*LOG2(ave_len_ROJ_zero));

  if (verbose) printf("\nConstruct ROB model at time = %.4f\n", tfactor);
  EvolConstructOTHModel(mutpxy_star, ROBparam, ROBparam_zero, ROBparam_infty, ave_len_ROB, ave_len_ROB_zero, ave_len_ROB_infty, tfactor, 
			targetfreq, changefreq, rna->ROB, pedantic, FALSE);
  if (verbose) printf("\nConstruct ROJ model at time = %.4f\n", tfactor);
  EvolConstructOTHModel(mutpxy_star, ROJparam, ROJparam_zero, ROJparam_infty, ave_len_ROJ, ave_len_ROJ_zero, ave_len_ROJ_infty, tfactor, 
			targetfreq, changefreq, rna->ROJ, pedantic, FALSE);
  if (verbose) printf("\nConstruct ROE model at time = %.4f\n", tfactor);
  EvolConstructOTHModel(mutpxy_star, ROEparam, ROEparam_zero, ROEparam_infty, ave_len_ROE, ave_len_ROE_zero, ave_len_ROE_infty, tfactor, 
			targetfreq, changefreq, rna->ROE, pedantic, FALSE);
  
  ave_len_Rloop = 15.0;
  EvolConstructOTHModel(mutpxy_rna_unpaired_star, Rloopparam, Rloopparam_zero, Rloopparam_infty, ave_len_Rloop, ave_len_Rloop, ave_len_Rloop, tfactor, 
			targetfreq, changefreq, rna->pi2->Rloop, pedantic, FALSE);
  
/* 24 JUL 02
  *
  * For the HHM-part of the RNA model,
  * the evolutionary RNA model is as follows:
  *
  *       - A 2x2 matrix for transitions T                RNA     ROE                          
  *                                               ROB  |  psi    1-psi |
  *                                       T =          |               |
  *                                               RNA  | 1-eta    eta  |
  * 
  *
  *               at t=0                               |  1        0   |
  *                                       T_0 =        |               |
  *                                                    |  0        1   |
  *
  *              parametric family:      T = exp [tA]
  *
  */
  if (verbose) printf("\nTransitions\n");
  RNAmodelTransitionProbabilities(tfactor, rna, pedantic, verbose);

  /* ******************
   * EVOLVE emissions
   * *******************/
  if (verbose) printf("\nmut5pxy_rna_unpaired_star\n");
  EvolMut5Probs (mut5pxy_rna_unpaired_star, tfactor, &mut5pxy_rna_unpaired, targetfreq, changefreq, pedantic, verbose);
  if (verbose) printf("\nmut5pxy_rna_loop_star\n");
  EvolMut5Probs (mut5pxy_rna_loop_star, tfactor, &mut5pxy_rna_loop, targetfreq, changefreq, pedantic, verbose);
  if (verbose) printf("\nmut5pxy_rna_paired_star\n");
  EvolMut5Probs (mut5pxy_rna_paired_star,   tfactor, &mut5pxy_rna_paired,   targetfreq, changefreq, pedantic, verbose);
  EvolPair5Probs(pair5prob_star,            tfactor, &pair5prob,            targetfreq, changefreq, pedantic, verbose);

  if (verbose) {
    fprintf(stdout, "\nmut5pxy_rna_unpaired (t=%f) 5x5 probabilities\n", mut5pxy_rna_paired->time);
    PrintProbs(stdout, mut5pxy_rna_unpaired->P, mut5pxy_rna_unpaired->L);
    fprintf(stdout, "mut5pxy_rna_unpaired 5x5 rate\n");
    PrintProbs(stdout, mut5pxy_rna_unpaired->Rate, mut5pxy_rna_unpaired->L);
    fprintf(stdout, "mut5pxy_rna_unpaired 5x5 Q_0\n");
    PrintProbs(stdout, mut5pxy_rna_unpaired->Qnought, mut5pxy_rna_unpaired->L);
    fprintf(stdout, "mut5pxy_rna_unpaired marginals\n");
    PrintVectorProbs(stdout, mut5pxy_rna_unpaired->pm, mut5pxy_rna_unpaired->L);

    fprintf(stdout, "\nmut5pxy_rna_loop (t=%f) 5x5 probabilities\n", mut5pxy_rna_paired->time);
    PrintProbs(stdout, mut5pxy_rna_loop->P, mut5pxy_rna_loop->L);
    fprintf(stdout, "mut5pxy_rna_loop 5x5 rate\n");
    PrintProbs(stdout, mut5pxy_rna_loop->Rate, mut5pxy_rna_loop->L);
    fprintf(stdout, "mut5pxy_rna_loop 5x5 Q_0\n");
    PrintProbs(stdout, mut5pxy_rna_loop->Qnought, mut5pxy_rna_loop->L);
    fprintf(stdout, "mut5pxy_rna_loop marginals\n");
    PrintVectorProbs(stdout, mut5pxy_rna_loop->pm, mut5pxy_rna_loop->L);

    fprintf(stdout, "\nmut5pxy_rna_paired (t=%f) 5x5 probabilities\n", mut5pxy_rna_paired->time);
    PrintProbs(stdout, mut5pxy_rna_paired->P, mut5pxy_rna_paired->L);
    fprintf(stdout, "mut5pxy_rna_paired 5x5 rate\n");
    PrintProbs(stdout, mut5pxy_rna_paired->Rate, mut5pxy_rna_paired->L);
    fprintf(stdout, "mut5pxy_rna_paired 5x5 Q_0\n");
    PrintProbs(stdout, mut5pxy_rna_paired->Qnought, mut5pxy_rna_paired->L);
    fprintf(stdout, "mut5pxy_rna_paired marginals\n");
    PrintVectorProbs(stdout, mut5pxy_rna_paired->pm, mut5pxy_rna_paired->L);

    fprintf(stdout, "\npair5prob (t=%f) 5x5 probabilities\n", tfactor);
    PrintProbs(stdout, pair5prob->P, pair5prob->L);
    fprintf(stdout, "pair5prob 5x5 ratel matrix\n");
    PrintProbs(stdout, pair5prob->Ratel, pair5prob->L);
    fprintf(stdout, "pair5prob 5x5 rater matrix\n");
    PrintProbs(stdout, pair5prob->Rater, pair5prob->L);
    fprintf(stdout, "pair5prob L-MARG (t=%f) 5x5 probabilities\n", tfactor);
    PrintVectorProbs(stdout, pair5prob->pml, pair5prob->L);
    fprintf(stdout, "pair5prob R-MARG (t=%f) 5x5 probabilities\n", tfactor);
    PrintVectorProbs(stdout, pair5prob->pmr, pair5prob->L);
  }
  
  if (!use_ribo_oldrna) {
    /* Evolve the 16x16 riboprob_star->Q Pair conditional probabilities    
     */
    EvolRIBOProbs(riboprob_star, tfactor, &riboprob, targetfreq, changefreq, pedantic, verbose);
    
    if (verbose) {
      DExp2(riboprob_star->P, riboprob_star->L*riboprob_star->L);
      fprintf(stdout, "RIBO(i,j, t*) probabilities\n");
      PrintProbs(stdout, riboprob_star->P, riboprob_star->L);
      EvolCalculateRIBOProbsCummulative(stdout, riboprob_star->L, riboprob_star->P, FALSE);
      DLog2(riboprob_star->P, riboprob_star->L*riboprob_star->L);
      
      fprintf(stdout, "\nRIBO (i,j, t=%f) Joint probabilities\n", riboprob->time);
      DExp2(riboprob->P, riboprob->L*riboprob->L);
      PrintProbs(stdout, riboprob->P, riboprob->L);
      EvolCalculateRIBOProbsCummulative(stdout, riboprob->L, riboprob->P, FALSE);
      DLog2(riboprob->P, riboprob->L*riboprob->L);
      
      fprintf(stdout, "Q(i|j, t=%f) conditional probabilities\n", riboprob->time);
      DExp2(riboprob->Q, riboprob->L*riboprob->L);
      PrintProbs(stdout, riboprob->Q, riboprob->L);
      DLog2(riboprob->Q, riboprob->L*riboprob->L);
      
      fprintf(stdout, "Rate matrix\n");
      PrintProbs(stdout, riboprob->Rate, riboprob->L);

      fprintf(stdout, "pm(i) marginal probabilities\n");
      PrintProbs(stdout, riboprob->pm, sqrt(riboprob->L));
      
      /* calculate Mutation Conditionals and Marginals */
      islog = FALSE;
      ribomutcond = EvolComputeRIBOMutConditionalsAndMarginals(stdout, riboprob, islog, verbose);
      FreeNonSubsProbs(ribomutcond);
    }
    
    /* 
     * ribo5prob at t --- Here we  put everything together: we add the gaps
     */
    EvolAddGapsRIBO5Probs(riboprob, mut5pxy_rna_paired, pair5prob, &ribo5prob, targetfreq, verbose);
  }
  else  
    EvolRIBO5Probs_OldMethod(riboprob_star, mut5pxy_rna_paired, pair5prob, &ribo5prob, verbose);
  
  if (verbose) {
    fprintf(stdout, "\nRIBO5 (i,j, t=%f) Joint probabilities\n", ribo5prob->time);
    PrintProbs(stdout, ribo5prob->P, ribo5prob->L);
    fprintf(stdout, "Q5(i|j, t=%f) conditional probabilities\n", ribo5prob->time);
    PrintProbs(stdout, ribo5prob->Q, ribo5prob->L);
    fprintf(stdout, "pm(i) marginal probabilities\n");
    PrintProbs(stdout, ribo5prob->pm, sqrt(ribo5prob->L));

    /* calculate Mutation Conditionals and Marginals */
    islog = FALSE;
    ribo5mutcond = EvolComputeRIBOMutConditionalsAndMarginals(stdout, ribo5prob, islog, verbose);
    FreeNonSubsProbs(ribo5mutcond);
   }

  /* PI2 model
   */
  /* Trnasition probabilities from the training set
   */
  rna->pi2->v->t1  = 0.;
  rna->pi2->v->t2s = 0.;
  rna->pi2->v->t2b = 0.;
  rna->pi2->v->t2i = 0.;
  rna->pi2->v->t3  = 0.;

  for (idx = 0; idx < Idx[V]; idx++) {
    rna->pi2->v->t1  += EXP2(cfg_node[V][idx][dpcS1  - DpNodeidx[V]]);

    rna->pi2->v->t2s += EXP2(cfg_node[V][idx][dpcS2S - DpNodeidx[V]]);
    rna->pi2->v->t2b += EXP2(cfg_node[V][idx][dpcS2B - DpNodeidx[V]]);
    rna->pi2->v->t2i += EXP2(cfg_node[V][idx][dpcS2I - DpNodeidx[V]]);
    rna->pi2->v->t3  += EXP2(cfg_node[V][idx][dpcMV  - DpNodeidx[V]]);
  }
  rna->pi2->v->t1  /= Idx[V];
  rna->pi2->v->t2s /= Idx[V];
  rna->pi2->v->t2b /= Idx[V];
  rna->pi2->v->t2i /= Idx[V];
  rna->pi2->v->t3  /= Idx[V];

  sum = rna->pi2->v->t1+rna->pi2->v->t2s+rna->pi2->v->t2b+rna->pi2->v->t2i+rna->pi2->v->t3;
  if (sum > 2.0-accuracy || sum < accuracy)
    Die ("pi2->v transtitions don't add up to one (sum_v = %f)\n", sum);
  if (verbose) printf("V: %f %f %f %f %f\n", rna->pi2->v->t1, rna->pi2->v->t2s, rna->pi2->v->t2b, rna->pi2->v->t2i, rna->pi2->v->t3);
  
  /* tie L and R emission
   */
  rna->pi2->w->tl = EXP2(cfg_node[W][0][dpcL   - DpNodeidx[W]]);
  rna->pi2->w->tr = EXP2(cfg_node[W][0][dpcR   - DpNodeidx[W]]);
  rna->pi2->w->tl = 0.5 * (rna->pi2->w->tl + rna->pi2->w->tr);
  rna->pi2->w->tr = rna->pi2->w->tl;
  rna->pi2->w->tv = EXP2(cfg_node[W][0][dpcP   - DpNodeidx[W]]);
  rna->pi2->w->tw = EXP2(cfg_node[W][0][dpcBW  - DpNodeidx[W]]);

  sum = rna->pi2->w->tl + rna->pi2->w->tr + rna->pi2->w->tv + rna->pi2->w->tw;
  if (sum > 2.0-accuracy || sum < accuracy)
    Die ("pi2->w transtitions don't add up to one (sum_w = %f)\n", sum);
  if (verbose) printf("W: %f %f %f %f\n", rna->pi2->w->tl, rna->pi2->w->tr, rna->pi2->w->tv, rna->pi2->w->tw);
  
  rna->pi2->wb->tl = EXP2(cfg_node[WB][0][dpcL  - DpNodeidx[WB]]);
  rna->pi2->wb->tr = EXP2(cfg_node[WB][0][dpcR  - DpNodeidx[WB]]);
  rna->pi2->wb->tl = 0.5 * (rna->pi2->wb->tl+rna->pi2->wb->tr);
  rna->pi2->wb->tr = rna->pi2->wb->tl;
  rna->pi2->wb->tv = EXP2(cfg_node[WB][0][dpcP  - DpNodeidx[WB]]);
  rna->pi2->wb->tw = EXP2(cfg_node[WB][0][dpcBW - DpNodeidx[WB]]);

  if (verbose) {
    printf("v->t1 %f\n",  rna->pi2->v->t1);
    printf("v->t2s %f\n",  rna->pi2->v->t2s);
    printf("v->t2b %f\n",  rna->pi2->v->t2b);
    printf("v->t2i %f\n",  rna->pi2->v->t2i);
    printf("v->t3 %f\n",  rna->pi2->v->t3);
    printf("w->tl %f\n",  rna->pi2->w->tl);
    printf("w->tr %f\n",  rna->pi2->w->tr);
    printf("w->tv %f\n",  rna->pi2->w->tv);
    printf("w->tw %f\n",  rna->pi2->w->tw);
    printf("wb->tl %f\n",  rna->pi2->wb->tl);
    printf("wb->tr %f\n",  rna->pi2->wb->tr);
    printf("wb->tv %f\n",  rna->pi2->wb->tv);
    printf("wb->tw %f\n",  rna->pi2->wb->tw);
  }

  sum = rna->pi2->wb->tl + rna->pi2->wb->tr + rna->pi2->wb->tv + rna->pi2->wb->tw;
  if (sum > 2.0-accuracy || sum < accuracy)
    Die ("pi2->wb transtitions don't add up to one (sum_wb = %f)\n", sum);
  if (verbose) printf("WB: %f %f %f %f\n", rna->pi2->wb->tl, rna->pi2->wb->tr, rna->pi2->wb->tv, rna->pi2->wb->tw);

   /* this is a hack. 
   * The contribution of  IS1, IS2 seems to work better if I substitute
   * 
   *   tn[l] --> tn[l]*(1-\eta)^l / sum_{l'}(tn[l']*(1-\eta)^l'
   *
   * in this way, larger lengths get a lower probability
   */
  p = 0.15; /* so we assume that the average loop is about 6 or 7 nts */
  logp = LOG2(p);
  corr = LOG2(1.0-p); 

  geo_len = (int) (0.50*MAXRNALOOP);

  for (len = 0; len < MAXRNALOOP; len++) {
    if (len > 3) {
      if (len < geo_len) 
	rna->pi2->is1->tn[len] = EXP2(cfg_node[IS1][0][dpcLEN(len)-DpNodeidx[IS1]]);
      else                  
	rna->pi2->is1->tn[len] = EXP2(cfg_node[IS1][0][dpcLEN(len)-DpNodeidx[IS1]] + ((double)len-1.)*logp + corr);
    }
    else         
      rna->pi2->is1->tn[len] = 0.0;
  }
  DNorm(rna->pi2->is1->tn, MAXRNALOOP);
  if (verbose) {
    printf("HAIRPIN LOOPS\n");
    for (len = 0; len < MAXRNALOOP; len++) 
      printf("d=%d %f %f\n", len, rna->pi2->is1->tn[len], LOG2(rna->pi2->is1->tn[len]));
  }
  
  for (len = 0; len < MAXRNALOOP; len++) 
    if (len > 2) {
     if (len < geo_len) 
       rna->pi2->is2b->tn[len] = EXP2(cfg_node[IS2B][0][dpcLEN(len)-DpNodeidx[IS2B]]);
     else          
       rna->pi2->is2b->tn[len] = EXP2(cfg_node[IS2B][0][dpcLEN(len)-DpNodeidx[IS2B]] + ((double)len-2.)*logp+corr);
    }
    else         
      rna->pi2->is2b->tn[len] = 0.0;
  DNorm(rna->pi2->is2b->tn, MAXRNALOOP);
  if (verbose) {
    printf("\nBULGE LOOPS\n");
    for (len = 0; len < MAXRNALOOP; len++) 
      printf("d=%d %f %f\n", len, rna->pi2->is2b->tn[len], LOG2(rna->pi2->is2b->tn[len]));
  }

  for (len = 0; len < MAXRNALOOP; len++) 
    if (len > 3) {
     if (len < geo_len) 
       rna->pi2->is2i->tn[len] = EXP2(cfg_node[IS2I][0][dpcLEN(len)-DpNodeidx[IS2I]]);
     else          
       rna->pi2->is2i->tn[len] = EXP2(cfg_node[IS2I][0][dpcLEN(len)-DpNodeidx[IS2I]] + ((double)len-2.)*logp+corr);
    }
    else         
      rna->pi2->is2i->tn[len] = 0.0;
  DNorm(rna->pi2->is2i->tn, MAXRNALOOP);
  if (verbose) {
    printf("\nINTERNAL LOOPS\n");
    for (len = 0; len < MAXRNALOOP; len++) 
      printf("d=%d %f %f\n", len, rna->pi2->is2i->tn[len], LOG2(rna->pi2->is2i->tn[len]));
  }

 /* 24 SEP 02
  *
  * The evolutionary SCFG model is as follows:
  *
  */
  SCFGTransitionProbabilities(win, tfactor, rna->pi2, pedantic, verbose);


				/* copy singlets */
  for (i = 0; i < 25; i++) {
    rna->pi2->w->pl[i]    = mut5pxy_rna_unpaired->P[i];
    rna->pi2->w->pr[i]    = mut5pxy_rna_unpaired->P[i];
    rna->pi2->wb->pl[i]   = mut5pxy_rna_unpaired->P[i];
    rna->pi2->wb->pr[i]   = mut5pxy_rna_unpaired->P[i];
    rna->pi2->is1->ps[i]  = mut5pxy_rna_loop->P[i];
    rna->pi2->is2b->ps[i] = mut5pxy_rna_loop->P[i];
    rna->pi2->is2i->ps[i] = mut5pxy_rna_loop->P[i];
  }
  
                                   /* assign the pair probabilities */
  for (i = 0; i < 25; i++)
    for (j = 0; j < 25; j++) {
	  rna->pi2->v->pp [i][j] = ribo5prob->P[i*25+j];  
	  rna->pi2->w->pp [i][j] = ribo5prob->P[i*25+j];  
	  rna->pi2->wb->pp[i][j] = ribo5prob->P[i*25+j];
    }  
 
  /* NUS model
   */
  rna->nus->tl = 0.1; 
  rna->nus->tr = 0.1; 
  rna->nus->tv = 0.7;
  rna->nus->tw = 0.095;
  rna->nus->te = 0.005;

  sum = rna->nus->tl + rna->nus->tr + rna->nus->tv + rna->nus->tw + rna->nus->te;
  if (sum > 1.02 || sum < 0.998) 
    Die ("nus->w transtitions don't add up to one (sum_w = %f)\n", sum);

  for (i = 0; i < 25; i++) {
    rna->nus->p[i] = rna->pi2->wb->pl[i];

    for (j = 0; j < 25; j++)
      rna->nus->pp[i][j] = rna->pi2->v->pp[i][j];
  }

  /* check prob's add up to one
   */
  CheckRNAProbs(rna);

  /* convert to Log2 form
   */
  RNAToLog2(rna, null);

  /* Print Transition Probabilities if asked for it
   */
  if (verbose) PrintRNATrProbs(rna);
  if (verbose) PrintRNAModel(rna);

  /* Calculate loop statistics if asked for it
   */
  if (verbose) {
    fprintf(stdout, "IS1 loops\n");
    DistributionLogMeanVar(rna->pi2->is1->tn, MAXRNALOOP, &is1_ave, &is1_sd);
    fprintf(stdout, "av = %f sd = %f\n", is1_ave, is1_sd);
    PrintVectorProbs(stdout, rna->pi2->is1->tn, MAXRNALOOP);
 
    fprintf(stdout, "IS2B loops\n");
    DistributionLogMeanVar(rna->pi2->is2b->tn, MAXRNALOOP, &is2b_ave, &is2b_sd);
    fprintf(stdout, "av = %f sd = %f\n", is2b_ave, is2b_sd);
    PrintVectorProbs(stdout, rna->pi2->is2b->tn, MAXRNALOOP);

    fprintf(stdout, "IS2I loops\n");
    DistributionLogMeanVar(rna->pi2->is2i->tn, MAXRNALOOP, &is2i_ave, &is2i_sd);
    fprintf(stdout, "av = %f sd = %f\n", is2i_ave, is2i_sd);
    PrintVectorProbs(stdout, rna->pi2->is2i->tn, MAXRNALOOP);
  }

  FreeSubsProbs(mut5pxy_rna_unpaired);
  FreeSubsProbs(mut5pxy_rna_loop);
  FreeSubsProbs(mut5pxy_rna_paired);
  FreeNonSubsProbs(pair5prob);
  if (!use_ribo_oldrna) {
    FreeSubsProbs(riboprob);
    FreeSubsProbs(ribo5prob);
  }
  else {  
    FreeSubsProbs(ribo5prob);
  }
  
  if (verbose) printf("DONE, RNA model at time = %.4f\n", tfactor);

}
