/***************************************************************************
                          pairfold.h  -  description
                             -------------------
    begin                : Thu Apr 11 2002
    copyright            : (C) 2002 by Mirela Andronescu
    email                : andrones@cs.ubc.ca
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/


#ifndef PAIRFOLD_H
#define PAIRFOLD_H

#include "constants.h"
#include "init.h"


double pairfold_mfe (char *sequence1, char *sequence2, char *structure);
// PRE:  The function init_data has been called; 2 sequences are given.
//       If you want the structure, then the space for structure has to be allocated
//       Otherwise structure should be NULL. 
// POST: Returns the minimum free energy, and the structure, unless it's NULL.
//       structure will contain the MFE structure. If structure is NULL from the beginning,
//         the structure is not computed, which may be a bit cheaper.

double pairfold_mfe_nointra (char *sequence1, char *sequence2, char *structure, int max_internal_loop_size);
// PRE:  The function init_data has been called; 2 sequences are given.
//       If you want the structure, then the space for structure has to be allocated
//       Otherwise structure should be NULL. 
// POST: Finds the minimum free energy structure, but where no intra-molecular interactions are allowed.
//       Thus, only intermolecular interaction between sequence1 and sequence2 are allowed. This means
//         that multi-loops and external loop with more than 1 branch can't possibly exist.
//       Returns the MFE.
//       structure will contain the MFE structure. If structure is NULL from the beginning,
//         the structure is not computed, which may be a bit cheaper.


double pairfold_simplified (char *sequence1, char *sequence2, char *structure);
// PRE:  The function init_data has been called; 2 sequences are given
// POST: Folds the 2 sequences, considering only stacked pairs and hairpin loops.

long pairfold_ordered_suboptimals (char *sequence1, char *sequence2, int number, char structures[][MAXSLEN], double energies[]);
// returns the "number" lowest FE structures and their energies, after 2*number structures have been
//     generated and reordered


int pairfold_ordered_suboptimals_range (char *sequence1, char *sequence2, double energy_range, char structures[][MAXSLEN], double energies[]);
// input: sequence1, sequence2, energy range
// output: structures, energies
// returns: number of structures that were found between the predicted MFE and MFE + energy_range


void pairfold_unordered_suboptimals (char *sequence1, char *sequence2, int number, char structures[][MAXSLEN], double energies[]);

int simfold_slow_unordered_suboptimals (char *sequence, int number, char structures[][MAXSLEN], double energies[]);

double calc_FE_complementary (char *sequence);
// PRE:  The function init_data has been called
// POST: Calculates the free energy of this sequence, folded with its perfect
//       complement, assuming that they pair perfectly.

double calc_FE_almost_complementary (char *sequence1, char *sequence2,
    int num_unpaired_right, int num_unpaired_left);
// PRE:  The function init_data has been called; 2 sequences are given;
//       the number of unpaired base on the right side (i.e. at the 3' side of
//       the first sequence); same for the left side (i.e. at the 5' end at
//       the first seq)
//       e.g. 2, 1 corresponds to .(((((.. ..))))).
// POST: Returns the FE. Replaces mismatches with internal loops

double calc_Tm_from_structure (char *sequence1, char *sequence2, char *structure, double energy,
    double temperature, double target_conc1, double target_conc2, int self_comp, double salt_conc);
// PRE:  A structure has been calculated and is given as input;
//       "temperature" is the temperature at which "structure" was found
// POST: Returns the melting temperature of the given sequences, when folded into
//       "structure".
// Note: If "temperature" is not 37, you have to call init_data before calling this
//       function, and then to call init_data with the original temperature

double calc_Tm_complementary (char* sequence, 
    double target_conc1, double target_conc2, double salt_conc);
// PRE:  The function init_data has been called
// POST: Calculates the melting temperature of this sequence, folded with its perfect
//       complement, assuming that they pair perfectly.
//       This function uses the parameters for free energy at 37 and enthalpy, and computes
//       entropy from the formula  

double calc_Tm_complementary_with_entropy_santalucia_2004 (char* sequence, 
    double target_conc1, double target_conc2, double salt_conc);
// PRE:  The function init_data has been called
// POST: Calculates the melting temperature of this sequence, folded with its perfect
//       complement, assuming that they pair perfectly.
//       This function uses entropy and enthalpy parameters directly, and it uses the values
//       from the paper [Santalucia 2004]. 

double simfold_slow (char *sequence, char *structure);
// PRE:  The space for sequence and structure is already allocated
// POST: fold a single sequence - this is slower than simfold from simfold software

double free_energy_pairfold (char *sequence1, char *sequence2, char *structure);
// !!! structure should not be sth like "...(((..)))", but a variable!!!
// POST: Return the free energy of sequences when folded into structure

double free_energy_pairfold_always_dangle (char *sequence1, char *sequence2, char *structure);
// POST: Return the free energy of sequences when folded into structure
// calculate the free energy, when the dangling energies are always added

double enthalpy_pairfold (char *sequence1, char *sequence2, char *structure);
// POST: Return the enthalpy for a pair, when we know the structure

double calc_entropy (double energy, double enthalpy, double temperature);
// POST: Return the entropy, as a function of energy, enthalpy and the given temperature
// Note: If "temperature" is not 37, you have to call init_data before calling this
//       function, and then to call init_data with the original temperature


double calc_Tm (double enthalpy, double entropy, double target_conc1, double target_conc2,
    int self_comp, double salt_conc);
// POST: Return melting temperature, when we know enthalpy and entropy
    



#endif
