/*
    Theseus - maximum likelihood superpositioning of macromolecular structures

    Copyright (C) 2004-2015 Douglas L. Theobald

    This file is part of THESEUS.

    THESEUS 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 3 of
    the License, or (at your option) any later version.

    THESEUS is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public
    License along with THESEUS in the file 'COPYING'. If not, see
    <http://www.gnu.org/licenses/>.

    -/_|:|_|_\-
*/

#ifndef STRUCTALIGN_SEEN
#define STRUCTALIGN_SEEN

#include <float.h>
#include <pthread.h>
#include "dssplite.h"
#include "pdbMalloc.h"
#include "DLTutils.h"
#include "msa.h"


typedef struct NWalgo_
{
    int             fraglen;
    int             distance;
    int             blosum;
    int             gap;
    int             gapzeron;
    int             logodds;
    int             bayes;
    int             bayespost;
    int             passes;
    int             global;
    int             center_ca;
    int             KA;
    int             dsspflag;
    int             raw_charge;
    int             corder;
    int             procrustes;
    int             convert;
    int             angles; /* flag to fill by aa psi/phi angle differences */
    double          open;   /* gap open penalty */
    double          extend; /* gap extension penalty, in terms of the fraction of the open penalty */
                            /* e.g., default for BLAST blosum62 would be 1/11 = 0.0909 */
    double          pi_g, pi_m;
    double          align_dist;
} NWalgo;


typedef struct NWtable_
{
    char            outfile_name[FILENAME_MAX];
    char            file1_name[FILENAME_MAX], file2_name[FILENAME_MAX];
    char           *msa_filename;

    int             cindex;

    double        **vmat; /* variance of pair, RMSD^2 */

    double        **smat; /* dynamic running match score */
    double        **fmat; /* pairwise scores */
    double        **gmat; /* 1.0 if gap closed, 0.0 if opened */
    char          **pmat; /* 'l', 'u', or 'd' -- left, up, or diagonal */

    Cds            *cds0, *cds1;
    PDBCds         *pdbc0, *pdbc1;
    int             nx, ny;     /* dimensions of mat */
    int           **alignment;  /* the full traceback alignment */
    int           **align_nogap;
    double         *align_score;
    int             alignlen;   /* length of the alignment, including gaps */
    double          stddev_var; /* the std dev of the average variance */
    double          cutoff;     /* # stddevs allowed for alt alignment scores */
    double          nw_score;
    double          gappen;
    double          Kplus, Evalue, RelEnt;
    int             mini, minj; /* for Smith-Waterman local alignment traceback start */
    int             maxi, maxj;
    char           *ss0, *ss1;
    NWalgo         *algo;
    MSA            *msa;
} NWtable;


typedef struct
{
    int             ii;
    int             iPartner;
    PDBCdsArray    *pdbA;
    int             iCommon;
    CdsArray       *cdsA, *nwcdsA;
    NWtable       **nwTableA;
    int             thrdnum;
} SAData;


extern char aa1[];
extern char aa3[];
extern char ss1[];
extern double s_dssp8[8][8];
extern double s_simple[20][20];
extern double s_simpler[20][20];
extern double s_hsdm[20][20];
extern double s_blosum30[20][20];
extern double s_blosum35[20][20];
extern double s_blosum40[20][20];
extern double s_blosum50[20][20];
extern double s_blosum62[20][20];
extern double s_blosum100[20][20];


void
GetNWCds(CdsArray *nwcdsA, CdsArray *cdsA);

CdsArray
*GetNWCdsSel(const PDBCdsArray *pdbA);

void
StructAlign(PDBCdsArray *pdbA, int iCommon, CdsArray *cdsA, NWtable **nwTableA);

void
StructAlignPth(PDBCdsArray *pdbA, int iCommon, CdsArray *cdsA, NWtable **nwTableA, SAData **sa_data, const int thrdnum);

void
NWscore(NWtable *nw_table);

void
NWscoreTh(NWtable *nw_table);

void
NWtraceback(NWtable *nw_table);

void
NWtracebackTh(NWtable *nw_table);

void
PrintVars(NWtable *nw_table);

void
PrintScores(NWtable *nw_table);

void
PrintSumScores(NWtable *nw_table);

void
PrintTraceback(NWtable *nw_table);

NWtable
*NWinit(void);

void
NWalloc(NWtable *nw_table, int nx, int ny);

void
NWdestroy(NWtable **nw_table_ptr);

NWalgo
*NWalgoInit(void);

char
aa3toaa1(char *aa3_s);

char
*aa1toaa3(char aa1_c);

#endif
