/********************************************************************************************************
 * QRNA - Comparative analysis of biological sequences 
 *         with pair hidden Markov models, pair stochastic context-free
 *        grammars, and probabilistic evolutionary  models.
 *       
 * Version 2.0.0 (JUN 2003)
 *
 * Copyright (C) 2000-2003 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.
 ***********************************************************************************************************/

/* evolrnascorealign.c
 *
 * ER, Mon Aug 16 13:25:52 CDT 2004 [St. Louis at work, Coro with Maribel]
 * 
 * score of a given alignment with the rnamodel
 * 
 * calculates:
 *             log2[P(seqX, seqY, \pi^{given} | rnamodel) /  P(seqX, seqY, \pi^{given} | nullmodel)]
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>

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

#ifdef MEMDEBUG
#include "dbmalloc.h"
#endif

static double scorewithRNA_onepass(FILE *ofp, SQINFO sqinfoX, int *sX, SQINFO sqinfoY, int *sY, char *gss, int start, int L, 
				   struct emodel_s *emodel, struct othdpd_s *othdp, 
				   struct rnamtx_s *mtx, double *sc, double *vp,
				   int *ret_scfg_status, int cyk, int fastintloop, int logodds, int do_nus, int parse, int traceback);



/* Function: EvolScoreWithRNA()
 * Date:     ER,  Mon Aug 16 13:26:30 CDT 2004 [St. Louis at work, Coro with Maribel]
 *
 * Purpose:  Score an ungapped sequence alignment with RNA model.
 *           Sums over all possible structures. Zuker-like algorithm
 *
 */
void
EvolScoreWithRNA(FILE *ofp, SQINFO sqinfoX, int *seqX, SQINFO sqinfoY, int *seqY, char *gss, int start, int L, 
		 struct emodel_s *emodel, struct othdpd_s *othdp, struct rnascfg_s *mx, struct sc2_s *rnasc,
		 int *ret_scfg_status, int *ret_scfgrv_status, int cyk, int fastintloop, int logodds, 
		 int do_nus, int ones, int parse, int traceback)
{
  int *reqX, *reqY;                /* reverse complements */

  rnasc->pl = scorewithRNA_onepass(ofp, sqinfoX, seqX, sqinfoY, seqY, gss, start, L, emodel, othdp,
				   mx->in, mx->sc, mx->vp, 
				   ret_scfg_status, cyk, fastintloop, logodds, do_nus, parse, traceback);
  
 /* revcomp */
  reqX = (int *) MallocOrDie(sizeof(int) * L);
  reqY = (int *) MallocOrDie(sizeof(int) * L);
  RevComp(reqX, seqX+start, L);
  RevComp(reqY, seqY+start, L);

  if (!ones) {
    if (sqinfoX.flags & SQINFO_SS) gss = RevSS(gss+start, L);
    
    rnasc->mn = scorewithRNA_onepass(ofp, sqinfoX, reqX, sqinfoY, reqY, gss, start, L, emodel, othdp,
				     mx->inrv, mx->sc, mx->vp, 
				     ret_scfgrv_status, cyk, fastintloop, logodds, do_nus, parse, traceback);

    free(reqX);
    free(reqY);
  }
  else  rnasc->mn = 0.0;

}

/* Function: scorewithRNA_onepass()
 * Date:     ER, Mon Aug 16 13:27:06 CDT 2004 [St. Louis at work, Coro with Maribel]
 *
 * Purpose:  Score an ungapped sequence alignment with RNA model.
 *           Sums over all possible structures. Zuker-like algorithm
 *
 */
double
scorewithRNA_onepass(FILE *ofp, SQINFO sqinfoX, int *sX, SQINFO sqinfoY, int *sY, char *gss, int start, int L, 
		     struct emodel_s *emodel, struct othdpd_s *othdp, 
		     struct rnamtx_s *mtx, double *sc, double *vp,
		     int *ret_scfg_status, int cyk, int fastintloop, int logodds, int do_nus, int parse, int traceback)
{
  int     scfg_status;
  int    *ct;
  double  score;

  scfg_status = *ret_scfg_status;

  if (parse) KHS2ct (gss+start, L, FALSE, &ct);

  if (!scfg_status) {
    if (!cyk) {
      if (!parse)
      scfg_status = InsideRNA(ofp, sqinfoX, sX, sqinfoY, sY, start, L, emodel->rna, emodel->null,
			      othdp, mtx, sc, vp, do_nus, fastintloop, logodds);
      else
	scfg_status = InsideParseRNA(ofp, sqinfoX, sX, sqinfoY, sY, ct, start, L, emodel->rna, emodel->null,
				     othdp, mtx, sc, vp, do_nus, logodds);
    }
    else 
      if (!parse)
	scfg_status = CYKRNA(ofp, sqinfoX, sX, sqinfoY, sY, start, L, emodel->rna, emodel->null,
			     othdp, mtx, vp, logodds, do_nus, traceback);
      else
	scfg_status = CYKParseRNA(ofp, sqinfoX, sX, sqinfoY, sY, ct, start, L, emodel->rna, emodel->null,
				  othdp, mtx, vp, logodds, do_nus, traceback);
  }
  
  score = ScoreWithOTH(ofp, sX, sY, start, 0, emodel->rna->ROB, FALSE) 
    + emodel->rna->t[TROBRNA]
    + mtx->wx[L-1][L-1]  
    + emodel->rna->t[TRNAROE] 
    + ScoreWithOTH(ofp, sX, sY, L-1, 0, emodel->rna->ROE, FALSE);

  *ret_scfg_status = scfg_status;

  if (parse) free (ct);

  return score;
}
















