Delete unneeded directory
[jabaws.git] / website / archive / binaries / mac / src / clustalo / src / clustal / hhalign_wrapper.c
diff --git a/website/archive/binaries/mac/src/clustalo/src/clustal/hhalign_wrapper.c b/website/archive/binaries/mac/src/clustalo/src/clustal/hhalign_wrapper.c
deleted file mode 100644 (file)
index 637edb0..0000000
+++ /dev/null
@@ -1,1122 +0,0 @@
-/* -*- mode: c; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-
-/*********************************************************************
- * Clustal Omega - Multiple sequence alignment
- *
- * Copyright (C) 2010 University College Dublin
- *
- * Clustal-Omega 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.
- *
- * This file is part of Clustal-Omega.
- *
- ********************************************************************/
-
-/*
- *  RCS $Id: hhalign_wrapper.c 256 2011-06-23 13:57:28Z fabian $
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <ctype.h>
-
-#include "seq.h"
-#include "tree.h"
-#include "progress.h"
-#include "hhalign/general.h"
-#include "hhalign/hhfunc.h"
-#include "hhalign/hhalign.h"
-
-/* up to this level (from leaf) will background HMM info be applied */
-#define APPLY_BG_HMM_UP_TO_TREE_DEPTH 10
-
-#define TIMING 0
-
-#define TRACE 0
-
-/**
- * @brief get rid of unknown residues
- *
- * @note HHalignWrapper can be entered in 2 different ways: (i) all
- * sequences are un-aligned (ii) there are 2 (aligned) profiles.  in
- * the un-aligned case (i) the sequences come straight from Squid,
- * that is, they have been sanitised, all non-alphabetic residues 
- * have been rendered as X's. In profile mode (ii) one profile may 
- * have been produced internally. In that case residues may have 
- * been translated back into their 'native' form, that is, they may
- * contain un-sanitised residues. These will cause trouble  during
- * alignment
- * FS, r213->214
- */
-void
-SanitiseUnknown(mseq_t *mseq)
-{
-
-    int iS; /* iterator for sequence */
-    int iR; /* iterator for residue */
-    int iLen; /* length of sequence */
-    char *pcRes = NULL;
-
-
-    for (iS = 0; iS < mseq->nseqs; iS++){
-
-        for (pcRes = mseq->seq[iS]; '\0' != *pcRes; pcRes++){
-
-            if (isgap(*pcRes)){
-                continue;
-            }
-
-            if (mseq->seqtype==SEQTYPE_PROTEIN) {
-                if (NULL == strchr(AMINO_ALPHABET, toupper(*pcRes))) {
-                    *pcRes = AMINOACID_ANY;
-                }
-            } else if (mseq->seqtype==SEQTYPE_DNA) {
-                if (NULL == strchr(DNA_ALPHABET, toupper(*pcRes))) {
-                    *pcRes = NUCLEOTIDE_ANY;
-                }
-            } else if (mseq->seqtype==SEQTYPE_RNA) {
-                if (NULL == strchr(RNA_ALPHABET, toupper(*pcRes))) {
-                    *pcRes = NUCLEOTIDE_ANY;
-                }
-            }
-
-        } /* !EO String */
-
-    } /* 0 <= iS < mseq->nseqs */
-
-    return;
-
-} /*** end:  SanitiseUnknown()  ***/
-
-/**
- * @brief translate unknown residues back to ambiguity codes;
- * hhalign translates ambiguity codes (B,Z) into unknown residue (X).
- * we still have the original (un-aligned) residue information,
- * by iterating along the original and aligned sequences we can
- * reconstruct where codes have been changed and restore them
- * to their original value
- *
- * @param[in,out] mseq
- * sequence/profile data, mseq->seq [in,out] is changed to conform
- * with mseq->orig_seq [in]
- *
- */
-void
-TranslateUnknown2Ambiguity(mseq_t *mseq)
-{
-
-    int iS; /* iterator for sequence */
-    int iR, iRo; /* iterator for residue (original) */
-    int iChange, iCase, iAmbi; /* counts how many replacements */
-    static int siOffset = 'a' - 'A';
-
-    for (iS = 0; iS < mseq->nseqs; iS++){
-
-        iR = iRo = 0;
-        iChange = iCase = iAmbi = 0;
-
-        while(('\0' != mseq->seq[iS][iR]) &&
-              ('\0' != mseq->orig_seq[iS][iRo])) {
-
-            /* skip gaps in aligned sequences */
-            while(isgap(mseq->seq[iS][iR])) {
-                iR++;
-            } /* was gap in unaligned seq
-               * this should probably not happen */
-            while(isgap(mseq->orig_seq[iS][iRo])) {
-                iRo++;
-            } /* was gap in aligned seq */
-
-            /* check if we reached the end of the sequence after
-             * skipping the gaps */
-            if ( ('\0' == mseq->seq[iS][iR]) ||
-                 ('\0' == mseq->orig_seq[iS][iRo]) ){
-                break;
-            }
-
-
-            if (mseq->seq[iS][iR] != mseq->orig_seq[iS][iRo]){
-                /* FIXME: count replacements, discard case changes */
-                iChange++;
-                if ( (mseq->seq[iS][iR] == mseq->orig_seq[iS][iRo]+siOffset) ||
-                     (mseq->seq[iS][iR] == mseq->orig_seq[iS][iRo]-siOffset) ){
-                    iCase++;
-                }
-                else {
-                    iAmbi++;
-                }
-#if TRACE
-                Log(&rLog, LOG_FORCED_DEBUG, "seq=%d, pos=(%d:%d), (%c:%c)",
-                     iS, iR, iRo,
-                     mseq->seq[iS][iR], mseq->orig_seq[iS][iRo]);
-#endif
-                mseq->seq[iS][iR] = mseq->orig_seq[iS][iRo];
-            }
-
-            iR++;
-            iRo++;
-
-        } /* !EO seq */
-
-        Log(&rLog, LOG_DEBUG,
-             "in seq %d re-translated %d residue codes (%d true, %d case)",
-             iS, iChange, iAmbi, iCase);
-
-        /* assert that both sequences (un/aligned) have terminated */
-        /* skip gaps in aligned sequences */
-        while(isgap(mseq->seq[iS][iR])) {
-            iR++;
-        } /* was gap in unaligned seq
-           * this should probably not happen */
-        while(isgap(mseq->orig_seq[iS][iRo])) {
-            iRo++;
-        } /* was gap in aligned seq */
-
-
-        if ( ('\0' != mseq->seq[iS][iR]) ||
-             ('\0' != mseq->orig_seq[iS][iRo]) ){
-
-            Log(&rLog, LOG_FATAL, "inconsistency in un/aligned sequence %d\n>%s\n>%s\n",
-                  iS, mseq->seq[iS], mseq->orig_seq[iS]);
-        }
-
-    } /* 0 <= iS < mseq->nseqs */
-
-} /*** end: TranslateUnknown2Ambiguity() ***/
-
-
-/**
- * @brief re-attach leading and trailing gaps to alignment
- *
- * @param[in,out] prMSeq,
- * alignment structure (at this stage there should be no un-aligned sequences)
- * @param[in] iProfProfSeparator
- * gives sizes of input profiles, -1 if no input-profiles but un-aligned sequences
- *
- * @note leading and tailing profile columns 
- * that only contain gaps have no effect on the alignment 
- * and are removed during the alignment. if they are 
- * encountered a warning message is printed to screen.
- * some users like to preserve these gap columns
- * FS, r213->214
- */
-void
-ReAttachLeadingGaps(mseq_t *prMSeq, int  iProfProfSeparator)
-{
-
-    int i, j;
-    int iSize1 = 0; /* #seqs in 1st profile */
-    int iSize2 = 0; /* #seqs in 2nd profile */
-    int iPPS   = iProfProfSeparator;
-    int iLeadO1  = 0; /* leading  gaps in 1st seq of 1st profile */
-    int iLeadO2  = 0; /* leading  gaps in 1st seq of 2nd profile */
-    int iLeadA1  = 0; /* leading  gaps in 1st seq of final alignment */
-    int iLeadA2  = 0; /* leading  gaps in PPS seq of final alignment */
-    int iTrailO1 = 0; /* trailing gaps in 1st seq of 1st profile */
-    int iTrailO2 = 0; /* trailing gaps in 1st seq of 2nd profile */
-    int iTrailA1 = 0; /* trailing gaps in 1st seq of final alignment */
-    int iTrailA2 = 0; /* trailing gaps in PPS seq of final alignment */
-    int iLen  = 0; /* length of final alignment */
-    int iLen1 = 0; /* length of 1st profile */
-    int iLen2 = 0; /* length of 2nd profile */
-    int iCutHead = 0; /* make up truncation at head */
-    int iCutTail = 0; /* make up truncation at tail */
-    char *pcIter = NULL;
-
-    if (-1 == iProfProfSeparator){
-        return;
-    }
-    else {
-        assert(prMSeq->aligned);
-        assert(prMSeq->nseqs > iProfProfSeparator);
-    }
-    iSize1 = iProfProfSeparator;
-    iSize2 = prMSeq->nseqs - iProfProfSeparator;
-    iLen  = strlen(prMSeq->seq[0]);
-    iLen1 = strlen(prMSeq->orig_seq[0]);
-    iLen2 = strlen(prMSeq->orig_seq[iPPS]);
-
-    /* count leading/trailing gaps in 1st sequence of 1st/2nd profile and final alignmant */
-    for (iLeadO1  = 0, pcIter =  prMSeq->orig_seq[0];             isgap(*pcIter); pcIter++, iLeadO1++);
-    for (iLeadO2  = 0, pcIter =  prMSeq->orig_seq[iPPS];          isgap(*pcIter); pcIter++, iLeadO2++);
-    for (iLeadA1  = 0, pcIter =  prMSeq->seq[0];                  isgap(*pcIter); pcIter++, iLeadA1++);
-    for (iLeadA2  = 0, pcIter =  prMSeq->seq[iPPS];               isgap(*pcIter); pcIter++, iLeadA2++);
-    for (iTrailO1 = 0, pcIter = &prMSeq->orig_seq[0][iLen1-1];    isgap(*pcIter); pcIter--, iTrailO1++);
-    for (iTrailO2 = 0, pcIter = &prMSeq->orig_seq[iPPS][iLen2-1]; isgap(*pcIter); pcIter--, iTrailO2++);
-    for (iTrailA1 = 0, pcIter = &prMSeq->seq[0][iLen-1];          isgap(*pcIter); pcIter--, iTrailA1++);
-    for (iTrailA2 = 0, pcIter = &prMSeq->seq[iPPS][iLen-1];       isgap(*pcIter); pcIter--, iTrailA2++);
-
-
-    /* turn leading/trailing gaps into truncation */
-    iLeadO1  = iLeadO1  > iLeadA1  ? iLeadO1-iLeadA1   : 0;
-    iLeadO2  = iLeadO2  > iLeadA2  ? iLeadO2-iLeadA2   : 0;
-    iTrailO1 = iTrailO1 > iTrailA1 ? iTrailO1-iTrailA1 : 0;
-    iTrailO2 = iTrailO2 > iTrailA2 ? iTrailO2-iTrailA2 : 0;
-    iCutHead = iLeadO1  > iLeadO2  ? iLeadO1  : iLeadO2;
-    iCutTail = iTrailO1 > iTrailO2 ? iTrailO1 : iTrailO2;
-
-    /* re-allocate and shift memory */
-    if ( (iCutHead > 0) || (iCutTail > 0) ){ /* skip if no re-attachment, FS, r244 -> r245 */
-        for (i = 0; i < prMSeq->nseqs; i++){
-            
-            CKREALLOC(prMSeq->seq[i], iLen+iCutHead+iCutTail+2);
-            if (iCutHead > 0){ /* skip if no re-attachment, FS, r244 -> r245 */
-                memmove(prMSeq->seq[i]+iCutHead, prMSeq->seq[i], iLen);
-            }
-            for (j = 0; j < iCutHead; j++){
-                prMSeq->seq[i][j] = '-';
-            }
-            for (j = iLen+iCutHead; j < iLen+iCutHead+iCutTail; j++){
-                prMSeq->seq[i][j] = '-';
-            }
-            prMSeq->seq[i][j] = '\0';
-        }
-    } /* (iCutHead > 0) || (iCutTail > 0) */
-
-} /***  end: ReAttachLeadingGaps()  ***/
-
-/**
- * @brief reallocate enough memory for alignment and
- * attach sequence pointers to profiles
- *
- * @param[in,out] mseq
- * sequence/profile data, increase memory for sequences in profiles
- * @param[out] ppcProfile1
- * pointers to sequencese in 1st profile
- * @param[out] ppcProfile2
- * pointers to sequencese in 2nd profile
- * @param[out] pdWeightsL
- * weights (normalised to 1.0) for sequences in left  profile
- * @param[out] pdWeightsR
- * weights (normalised to 1.0) for sequences in right profile
- * @param[in] pdSeqWeights
- * weights for _all_ sequences in alignment
- * @param[in] iLeafCountL
- * number of sequences in 1st profile
- * @param[in] piLeafListL
- * array of integer IDs of sequences in 1st profile
- * @param[in] iLeafCountR
- * number of sequences in 2nd profile
- * @param[in] piLeafListR
- * array of integer IDs of sequences in 2nd profile
- *
- */
-void
-PrepareAlignment(mseq_t *mseq, char **ppcProfile1, char **ppcProfile2,
-                 double *pdWeightsL, double *pdWeightsR, double *pdSeqWeights,
-                 int iLeafCountL, int *piLeafListL,
-                 int iLeafCountR, int *piLeafListR)
-{
-
-    int iLenL = 0; /* length of 1st profile */
-    int iLenR = 0; /* length of 2nd profile */
-    int iMaxLen = 0; /* maximum possible length of alignment */
-    int i; /* aux */
-    double dWeight = 0.00;
-    double dWeightInv = 0.00;
-
-    assert(NULL!=mseq);
-    assert(NULL!=ppcProfile1);
-    assert(NULL!=ppcProfile2);
-    assert(NULL!=piLeafListL);
-    assert(NULL!=piLeafListR);
-
-    /* get length of profiles,
-     * in a profile all sequences should have same length so only look at 1st
-     */
-    iLenL = strlen(mseq->seq[piLeafListL[0]]);
-    iLenR = strlen(mseq->seq[piLeafListR[0]]);
-    iMaxLen = iLenL + iLenR + 1;
-
-    /* reallocate enough memory for sequences in alignment (for adding
-     * gaps)
-     */
-    for (i = 0; i < iLeafCountL; i++){
-        mseq->seq[piLeafListL[i]] =
-            CKREALLOC(mseq->seq[piLeafListL[i]], iMaxLen);
-    }
-    for (i = 0; i < iLeafCountR; i++){
-        mseq->seq[piLeafListR[i]] =
-            CKREALLOC(mseq->seq[piLeafListR[i]], iMaxLen);
-    }
-
-    /* attach sequences to profiles
-     */
-    for (i = 0; i < iLeafCountL; i++){
-        ppcProfile1[i] = mseq->seq[piLeafListL[i]];
-    }
-    ppcProfile1[i] = NULL;
-
-    for (i = 0; i < iLeafCountR; i++){
-        ppcProfile2[i] = mseq->seq[piLeafListR[i]];
-    }
-    ppcProfile2[i] = NULL;
-
-
-    /* remove terminal 'X' for single sequences:
-     * it is a quirk of hhalign() to delete 2 individual sequences
-     * if 2 terminal X's meet during alignment,
-     * just replace (one of) them.
-     * this can be undone at the end.
-     * profiles -consisting of more than 1 sequence-
-     * appear to be all-right.
-     * there seems to be no problem with B's and Z's
-     */
-    if ( (1 == iLeafCountL) && (1 == iLeafCountR) ){
-
-        if ( ('X' == ppcProfile1[0][0]) && ('X' == ppcProfile2[0][0]) ){
-#define NOTX 'N'
-            ppcProfile1[0][0] = NOTX; /* FIXME: arbitrary assignment */
-            ppcProfile2[0][0] = NOTX; /* FIXME: arbitrary assignment */
-        }
-        if ( ('X' == ppcProfile1[0][iLenL-1]) && ('X' == ppcProfile2[0][iLenR-1]) ){
-            ppcProfile1[0][iLenL-1] = NOTX; /* FIXME: arbitrary assignment */
-            ppcProfile2[0][iLenR-1] = NOTX; /* FIXME: arbitrary assignment */
-        }
-    }
-
-    /* obtain sequence weights
-     */
-    if (NULL != pdSeqWeights){
-
-        dWeight = 0.00;
-        for (i = 0; i < iLeafCountL; i++){
-            register double dAux = pdSeqWeights[piLeafListL[i]];
-#ifndef NDEBUG
-            if (dAux <= 0.00){
-                Log(&rLog, LOG_DEBUG, "seq-weight %d = %f", piLeafListL[i], dAux);
-            }
-#endif
-            pdWeightsL[i] = dAux;
-            dWeight      += dAux;
-        } /* 0 <= i < iLeafCountL */
-        dWeightInv = 1.00 / dWeight;
-        for (i = 0; i < iLeafCountL; i++){
-            pdWeightsL[i] *= dWeightInv;
-        }
-
-        dWeight = 0.00;
-        for (i = 0; i < iLeafCountR; i++){
-            register double dAux = pdSeqWeights[piLeafListR[i]];
-#ifndef NDEBUG
-            if (dAux <= 0.00){
-                Log(&rLog, LOG_DEBUG, "seq-weight %d = %f", piLeafListR[i], dAux);
-            }
-#endif
-            pdWeightsR[i] = dAux;
-            dWeight      += dAux;
-        } /* 0 <= i < iLeafCountL */
-        dWeightInv = 1.00 / dWeight;
-        for (i = 0; i < iLeafCountR; i++){
-            pdWeightsR[i] *= dWeightInv;
-        }
-    } /* (NULL != pdSeqWeights) */
-    else {
-        pdWeightsL[0] = pdWeightsR[0] = -1.00;
-    }
-
-#if TRACE
-    for (i = 0; i < iLeafCountL; i++){
-        Log(&rLog, LOG_FORCED_DEBUG, "ppcProfile1[%d/%d] pointing to mseq %d = %s",
-                  i, iLeafCountR, piLeafListL[i], ppcProfile1[i]);
-    }
-    for (i = 0; i < iLeafCountR; i++){
-        Log(&rLog, LOG_FORCED_DEBUG, "ppcProfile2[%d/%d] pointing to mseq %d = %s",
-                  i, iLeafCountR, piLeafListR[i], ppcProfile2[i]);
-    }
-#endif
-    
-    return;
-
-} /*** end: PrepareAlignment() ***/
-
-
-/**
- * @brief wrapper for hhalign. This is a frontend function to
- * the ported hhalign code.
- *
- * @param[in,out] prMSeq
- * holds the unaligned sequences [in] and the final alignment [out]
- * @param[in] piOrderLR
- * holds order in which sequences/profiles are to be aligned,
- * even elements specify left nodes, odd elements right nodes,
- * if even and odd are same then it is a leaf
- * @param[in] pdSeqWeights
- * Weight per sequence. No weights used if NULL
- * @param[in] iNodeCount
- * number of nodes in tree, piOrderLR has 2*iNodeCount elements
- * @param[in] prHMMList
- * List of background HMMs (transition/emission probabilities)
- * @param[in] iHMMCount
- * Number of input background HMMs
- * @param[in] iProfProfSeparator
- * Gives the number of sequences in the first profile, if in
- * profile/profile alignment mode (iNodeCount==3). That assumes mseqs
- * holds the sequences of profile 1 and profile 2.
- * @param[in] rHhalignPara
- * various parameters read from commandline
- *
- * @return score of the alignment FIXME what is this?
- *
- * @note complex function. could use some simplification, more and
- * documentation and a struct'uring of piOrderLR
- * 
- * @note HHalignWrapper can be entered in 2 different ways:
- * (i) all sequences are un-aligned (ii) there are 2 (aligned) profiles.
- * in the un-aligned case (i) the sequences come straight from Squid, 
- * that is, they have been sanitised, all non-alphabetic residues 
- * have been rendered as X's. In profile mode (ii) one profile may 
- * have been produced internally. In that case residues may have 
- * been translated back into their 'native' form, that is, they 
- * may contain un-sanitised residues. These will cause trouble 
- * during alignment
- *
- * @note: introduced argument hhalign_para rHhalignPara; FS, r240 -> r241
- * @note: if hhalign() fails then try with Viterbi by setting MAC-RAM=0; FS, r241 -> r243
- */
-
-double
-HHalignWrapper(mseq_t *prMSeq, int *piOrderLR,
-               double *pdSeqWeights, int iNodeCount,
-               hmm_light *prHMMList, int iHMMCount,
-               int iProfProfSeparator, hhalign_para rHhalignPara)
-{
-    int iN; /* node iterator */
-    int *piLeafCount = NULL; /* number of leaves beneath a certain node */
-    int **ppiLeafList = NULL; /* list of leaves beneath a certain node */
-    char **ppcProfile1 = NULL; /* pointer to sequences in profile */
-    char **ppcProfile2 = NULL; /* pointer to sequences in profile */
-    char *pcReprsnt1 = NULL; /* representative of HMM aligned to left */
-    char *pcReprsnt2 = NULL; /* representative of HMM aligned to right */
-    char **ppcReprsnt1 = &pcReprsnt1; /* representative of HMM aligned to L */
-    char **ppcReprsnt2 = &pcReprsnt2; /* representative of HMM aligned to R */
-    char *pcConsens1 = NULL; /* copy of  left sequence */
-    char *pcConsens2 = NULL; /* copy of right sequence */
-    char **ppcCopy1 = /*&pcCopy1*/NULL; /* copy of  left sequences */
-    char **ppcCopy2 = /*&pcCopy2*/NULL; /* copy of right sequences */
-    double *pdScores = NULL; /* alignment scores (seq/HMM) */
-    double dScore = 0.0; /* alignment score (seq/HMM) */
-    int iAux_FS = 0;
-    char zcAux[10000] = {0};
-    char zcError[10000] = {0};
-    int i; /* aux */
-    progress_t *prProgress;
-    int iAlnLen; /* alignment length */
-    double *pdWeightsL = NULL; /* sequence weights of left  profile */
-    double *pdWeightsR = NULL; /* sequence weights of right profile */
-    int iMergeNodeCounter = 0;
-    hmm_light *prHMM = NULL;
-    bool bPrintCR = (rLog.iLogLevelEnabled<=LOG_VERBOSE) ? FALSE : TRUE;
-#if TIMING
-    char zcStopwatchMsg[1024];
-    Stopwatch_t *stopwatch = StopwatchCreate();
-    StopwatchZero(stopwatch);
-    StopwatchStart(stopwatch);
-#endif
-    
-    
-    if (NULL != prHMMList) {
-        if (iHMMCount>1) {
-            Log(&rLog, LOG_WARN, "FIXME: Using only first of %u HMMs (needs implementation)", iHMMCount);
-        }
-        prHMM = &(prHMMList[0]);
-    } else {
-        /* FIXME: prHMM not allowed to be NULL and therefore pseudo allocated here */
-        prHMM = (hmm_light *) CKCALLOC(1, sizeof(hmm_light));
-    }
-    
-    assert(NULL!=prMSeq);
-    
-    if (NULL==piOrderLR) {
-        assert(3==iNodeCount);
-    }
-    SanitiseUnknown(prMSeq);
-
-    /* hhalign was not made for DNA/RNA. So warn if sequences are not
-     * protein
-     */
-    if (SEQTYPE_PROTEIN != prMSeq->seqtype) {
-        Log(&rLog, LOG_WARN, "Sequence type is %s. HHalign has only been tested on protein.",
-             SeqTypeToStr(prMSeq->seqtype));
-    }
-
-    /* hhalign produces funny results if sequences contain gaps, so
-     * dealign. Only way to use alignment info is to use it as a
-     * background HMM
-     */
-    if (TRUE == prMSeq->aligned) {
-        Log(&rLog, LOG_DEBUG, "Dealigning aligned sequences (inside %s)", __FUNCTION__);
-        DealignMSeq(prMSeq);
-    }
-
-#if TRACE
-    Log(&rLog, LOG_FORCED_DEBUG, "iNodeCount = %d", iNodeCount);
-#endif
-
-    
-    /* allocate top-level memory for leaf tracking arrays and profiles,
-     * and sequence weights*/
-    piLeafCount = CKCALLOC(iNodeCount, sizeof(int));
-    ppiLeafList = CKCALLOC(iNodeCount, sizeof(int *));
-    ppcProfile1 = CKCALLOC(prMSeq->nseqs*2-1, sizeof(char *));
-    ppcProfile2 = CKCALLOC(prMSeq->nseqs*2-1, sizeof(char *));
-    pdScores    = CKCALLOC(iNodeCount, sizeof(double));
-    pdWeightsL  = CKCALLOC(iNodeCount, sizeof(double));
-    pdWeightsR  = CKCALLOC(iNodeCount, sizeof(double));
-
-    NewProgress(&prProgress, LogGetFP(&rLog, LOG_INFO),
-                "Progressive alignment progress", bPrintCR);
-
-    
-    /* Profile-profile alignment? Then setup piLeafCount and
-     * piLeafList here. FIXME this is just an awful haaaack
-     */
-    if (iNodeCount==3 && NULL==piOrderLR) {
-        int iSizeProf1 = iProfProfSeparator;
-        int iSizeProf2 = prMSeq->nseqs - iProfProfSeparator;
-
-        piLeafCount[0] = iSizeProf1;
-        ppiLeafList[0] = (int *)CKMALLOC(iSizeProf1 * sizeof(int));
-        for (i=0;i<iSizeProf1;i++) {
-            ppiLeafList[0][i] = i;
-        }
-        piLeafCount[1] = iSizeProf2;
-        ppiLeafList[1] = (int *)CKMALLOC(iSizeProf2 * sizeof(int));
-        for (i=0;i<iSizeProf2;i++) {
-            ppiLeafList[1][i] = i+iSizeProf1;
-        }
-        
-        /* awful hack inside an awful hack: we had to setup piLeafCount
-         * and piLeafList outside the node iteration. this which is
-         * normally done at leaf level inside the node iteration. to
-         * avoid overwriting the already setup vars set...
-         */
-        iNodeCount=1;
-
-        piOrderLR =  (int *)CKCALLOC(DIFF_NODE, sizeof(int));
-        piOrderLR[LEFT_NODE] = 0;
-        piOrderLR[RGHT_NODE] = 1;
-        piOrderLR[PRNT_NODE] = 2;
-    }
-    
-
-
-    iMergeNodeCounter = 0;
-    for (iN = 0; iN < iNodeCount; iN++){
-
-        register int riAux = DIFF_NODE * iN;
-
-        /*LOG_DEBUG("node %d ", iN);*/
-
-        if (piOrderLR[riAux+LEFT_NODE] == piOrderLR[riAux+RGHT_NODE]){
-
-            register int riLeaf = piOrderLR[riAux+LEFT_NODE];
-#if TRACE
-            if (NULL == pdSeqWeights) {
-                Log(&rLog, LOG_FORCED_DEBUG, "node %d is a leaf with entry %d (seq %s)",
-                          iN, riLeaf, prMSeq->sqinfo[riLeaf].name);
-            } else {
-                Log(&rLog, LOG_FORCED_DEBUG, "node %d is a leaf with entry %d  (seq %s) and weight %f",
-                          iN, riLeaf, prMSeq->sqinfo[riLeaf].name, pdSeqWeights[riLeaf]);
-            }
-#endif
-            /* left/right entry same, this is a leaf */
-            piLeafCount[piOrderLR[riAux+PRNT_NODE]] = 1; /* number of leaves is '1' */
-            ppiLeafList[piOrderLR[riAux+PRNT_NODE]] = (int *)CKMALLOC(1 * sizeof(int));
-            ppiLeafList[piOrderLR[riAux+PRNT_NODE]][0] = riLeaf;
-
-        } /* was a leaf */
-        else {
-            int iL, iR, iP; /* ID of left/right nodes, parent */
-            int i, j; /* aux */
-
-            Log(&rLog, LOG_DEBUG,
-                "merge profiles at node %d", iN, piOrderLR[riAux]);
-
-            /* iNodeCount - prMSeq->nseqs = total # of merge-nodes 
-             * unless in profile/profile alignment mode
-             */
-            if (1 == iNodeCount) {
-                ProgressLog(prProgress, ++iMergeNodeCounter,
-                            1, FALSE);
-            } else {
-                ProgressLog(prProgress, ++iMergeNodeCounter,
-                            iNodeCount - prMSeq->nseqs, FALSE);                
-            }
-
-            /* left/right entry are not same, this is a merge node */
-            iL = piOrderLR[riAux+LEFT_NODE];
-            iR = piOrderLR[riAux+RGHT_NODE];
-            iP = piOrderLR[riAux+PRNT_NODE];
-            piLeafCount[iP] = piLeafCount[iL] + piLeafCount[iR];
-            ppiLeafList[iP] = (int *)CKMALLOC(piLeafCount[iP] * sizeof(int));
-
-            for (i = j = 0; i < piLeafCount[iL]; i++, j++){
-                ppiLeafList[iP][j] = ppiLeafList[iL][i];
-            }
-            for (i = 0; i < piLeafCount[iR]; i++, j++){
-                ppiLeafList[iP][j] = ppiLeafList[iR][i];
-            }
-
-            /* prepare simulation arena:
-             * - make sure enough memory in sequences
-             * - attach sequence pointers to profiles
-             */
-            /* idea: switch template and query according to nseq? */
-
-            PrepareAlignment(prMSeq, ppcProfile1, ppcProfile2,
-                             pdWeightsL, pdWeightsR, pdSeqWeights,
-                             piLeafCount[iL], ppiLeafList[iL],
-                             piLeafCount[iR], ppiLeafList[iR]);
-            if (rLog.iLogLevelEnabled <= LOG_DEBUG){
-                int i;
-                FILE *fp = LogGetFP(&rLog, LOG_DEBUG);
-                Log(&rLog, LOG_DEBUG, "merging profiles %d & %d", iL, iR);
-                for (i = 0; i < piLeafCount[iL]; i++){
-                    fprintf(fp, "L/#=%3d (ID=%3d, w=%f): %s\n",
-                           i, ppiLeafList[iL][i], pdWeightsL[i], ppcProfile1[i]);
-                }
-                for (i = 0; i < piLeafCount[iR]; i++){
-                    fprintf(fp, "R/#=%3d (ID=%3d, w=%f): %s\n",
-                           i, ppiLeafList[iR][i], pdWeightsR[i], ppcProfile2[i]);
-                }
-            }
-
-
-            
-            /* align individual sequences to HMM;
-             * - use representative sequence to get gapping
-             * - create copies of both, individual/representative sequences
-             *   as we don't want to introduce gaps into original
-             *
-             * FIXME: representative sequence is crutch, should use
-             * full HMM but that does not seem to work at all
-             * -- try harder! Fail better!
-             */
-            if ( (piLeafCount[iL] <= APPLY_BG_HMM_UP_TO_TREE_DEPTH) && (0 != prHMM->L) ){
-                int i, j;
-                pcReprsnt1 = CKCALLOC(prHMM->L+strlen(ppcProfile1[0])+1, sizeof(char));
-                for (i = 0; i < prHMM->L; i++){
-                    pcReprsnt1[i] = prHMM->seq[prHMM->ncons][i+1];
-                }
-                ppcCopy1 = CKCALLOC(piLeafCount[iL], sizeof(char *));
-                for (j = 0; j < piLeafCount[iL]; j++){
-                    ppcCopy1[j] = CKCALLOC(prHMM->L+strlen(ppcProfile1[0])+1, sizeof(char));
-                    for (i = 0; i < (int) strlen(ppcProfile1[0]); i++){
-                        ppcCopy1[j][i] = ppcProfile1[j][i];
-                    }
-                }
-
-                {
-                    /* the size of the elements in the forward/backward matrices 
-                       depends very much on the lengths of the profiles _and_ 
-                       in which position (1st/2nd) the longer/shorter profile/HMM is.
-                       the matrix elements can easily exceed the size of a (long?) double
-                       if the longer profile/HMM is associated with the query (q) and the 
-                       shorter with the target (t). 
-                       FIXME: however, pseudo-count adding may also depend on position, 
-                       this is only really tested for the HMM being in the 1st position (q)
-                       MUST TEST THIS MORE THOROUGHLY
-
-                       this switch appears to be most easily (although unelegantly) 
-                       effected here. Don't want to do it (upstairs) in PrepareAlignment() 
-                       because it might jumble up the nodes. Don't want to do it in hhalign() 
-                       either because ppcProfile1/2 and q/t may be used independently.
-                       FS, r236 -> r237
-                    */
-                    int iLenA = strlen(ppcCopy1[0]);
-                    int iLenH = prHMM->L;
-                    int iHHret = 0;
-                    
-                    if (iLenH < iLenA){
-                        iHHret = hhalign(ppcReprsnt1, 0/* only one representative seq*/, NULL,
-                                         ppcCopy1, piLeafCount[iL], pdWeightsL,
-                                         &dScore, prHMM,
-                                         NULL, NULL, NULL, NULL,
-                                         rHhalignPara, 
-                                         iAux_FS++, /* DEBUG ARGUMENT */
-                                         zcAux, zcError);
-                    }
-                    else {
-                        iHHret = hhalign(ppcCopy1, piLeafCount[iL], pdWeightsL,
-                                         ppcReprsnt1, 0/* only one representative seq*/, NULL,
-                                         &dScore, prHMM,
-                                         NULL, NULL, NULL, NULL,
-                                         rHhalignPara, 
-                                         iAux_FS++, /* DEBUG ARGUMENT */
-                                         zcAux, zcError);
-                    }
-                    if (0 != iHHret){ /* FS, r255 -> */
-                        fprintf(stderr, "%s:%s:%d: (not essential) HMM pre-alignment failed, error %d, \n"
-                                "\t#=%d (len=%d), lead-seq=%s, len(HMM)=%d\tCARRY ON REGARDLESS\n", 
-                                __FUNCTION__, __FILE__, __LINE__, iHHret, 
-                                piLeafCount[iL], (int)strlen(ppcCopy1[0]), prMSeq->sqinfo[ppiLeafList[iL][0]].name, (int)strlen(ppcReprsnt1[0]));
-                    }
-                }
-                pdScores[ppiLeafList[iL][0]] = dScore;
-#if 0
-                printf("score: %f\nL: %s\nH: %s\n",
-                       dScore, ppcCopy1[0], ppcReprsnt1[0]);
-#endif
-                /* assemble 'consensus';
-                 * this is not a real consensus, it is more a gap indicator,
-                 * for each position it consists of residues/gaps in the 1st sequences,
-                 * or a residue (if any) of the other sequences.
-                 * it only contains a gap if all sequences of the profile
-                 * have a gap at this position
-                 */
-                pcConsens1 = CKCALLOC(prHMM->L+strlen(ppcProfile1[0])+1, sizeof(char));
-                for (i = 0; i < prHMM->L; i++){
-                    for (j = 0, pcConsens1[i] = '-'; (j < piLeafCount[iL]) && ('-' == pcConsens1[i]); j++){
-                        pcConsens1[i] = ppcCopy1[j][i];
-                    }
-                }
-#if 0
-                for (j = 0; (j < piLeafCount[iL]); j++){
-                    printf("L%d:%s\n", j, ppcCopy1[j]);
-                }
-                printf("LC:%s\n", pcConsens1);
-#endif
-            } /* ( (1 == piLeafCount[iL]) && (0 != prHMM->L) ) */
-
-            if ( (piLeafCount[iR] <= APPLY_BG_HMM_UP_TO_TREE_DEPTH) && (0 != prHMM->L) ){
-                int i, j;
-
-                pcReprsnt2 = CKCALLOC(prHMM->L+strlen(ppcProfile2[0])+1, sizeof(char));
-                for (i = 0; i < prHMM->L; i++){
-                    pcReprsnt2[i] = prHMM->seq[prHMM->ncons][i+1];
-                }
-                ppcCopy2 = CKCALLOC(piLeafCount[iR], sizeof(char *));
-                for (j = 0; j < piLeafCount[iR]; j++){
-                    ppcCopy2[j] = CKCALLOC(prHMM->L+strlen(ppcProfile2[0])+1, sizeof(char));
-                    for (i = 0; i < (int) strlen(ppcProfile2[0]); i++){
-                        ppcCopy2[j][i] = ppcProfile2[j][i];
-                    }
-                }
-
-                {
-                    /* the size of the elements in the forward/backward matrices 
-                       depends very much on the lengths of the profiles _and_ 
-                       in which position (1st/2nd) the longer/shorter profile/HMM is.
-                       the matrix elements can easily exceed the size of a (long?) double
-                       if the longer profile/HMM is associated with the query (q) and the 
-                       shorter with the target (t). 
-                       FIXME: however, pseudo-count adding may also depend on position, 
-                       this is only really tested for the HMM being in the 1st position (q)
-                       MUST TEST THIS MORE THOROUGHLY
-                       
-                       this switch appears to be most easily (although unelegantly) 
-                       effected here. Don't want to do it (upstairs) in PrepareAlignment() 
-                       because it might jumble up the nodes. Don't want to do it in hhalign() 
-                       either because ppcProfile1/2 and q/t may be used independently.
-                       FS, r236 -> r237
-                    */
-                    int iLenA = strlen(ppcCopy2[0]);
-                    int iLenH = prHMM->L;
-                    int iHHret = 0;
-
-                    if (iLenH < iLenA){
-                        iHHret = hhalign(ppcReprsnt2, 0/* only one representative seq */, NULL,
-                                         ppcCopy2,    piLeafCount[iR], pdWeightsR,
-                                         &dScore, prHMM,
-                                         NULL, NULL, NULL, NULL,
-                                         rHhalignPara, 
-                                         iAux_FS++, /* DEBUG ARGUMENT */
-                                         zcAux, zcError);
-                    }
-                    else {
-                        iHHret = hhalign(ppcCopy2,    piLeafCount[iR], pdWeightsR,
-                                         ppcReprsnt2, 0/* only one representative seq */, NULL,
-                                         &dScore, prHMM,
-                                         NULL, NULL, NULL, NULL,
-                                         rHhalignPara, 
-                                         iAux_FS++, /* DEBUG ARGUMENT */
-                                         zcAux, zcError);
-                    }
-                    if (0 != iHHret){ /* FS, r255 -> */
-                        fprintf(stderr, "%s:%s:%d: (not essential) HMM pre-alignment failed, error %d, \n"
-                                "\t#=%d (len=%d), lead-seq=%s, len(HMM)=%d\tCARRY ON REGARDLESS\n", 
-                                __FUNCTION__, __FILE__, __LINE__, iHHret, 
-                                piLeafCount[iR], (int)strlen(ppcCopy2[0]), prMSeq->sqinfo[ppiLeafList[iR][0]].name, (int)strlen(ppcReprsnt2[0]));
-                    }
-                }
-                pdScores[ppiLeafList[iR][0]] = dScore;
-#if 0
-                printf("H: %s\nR: %s\nscore: %f\n",
-                       ppcReprsnt2[0], ppcCopy2[0], dScore);
-#endif
-                /* assemble 'consensus';
-                 * this is not a real consensus, it is more a gap indicator,
-                 * for each position it consists of residues/gaps in the 1st sequences,
-                 * or a residue (if any) of the other sequences.
-                 * it only contains a gap if all sequences of the profile
-                 * have a gap at this position
-                 */
-                pcConsens2 = CKCALLOC(prHMM->L+strlen(ppcProfile2[0])+1, sizeof(char));
-                for (i = 0; i < prHMM->L; i++){
-                    for (j = 0, pcConsens2[i] = '-'; (j < piLeafCount[iR]) && ('-' == pcConsens2[i]); j++){
-                        pcConsens2[i] = ppcCopy2[j][i];
-                    }
-                }
-#if 0
-                for (j = 0; (j < piLeafCount[iR]); j++){
-                    printf("R%d:%s\n", j, ppcCopy2[j]);
-                }
-                printf("RC:%s\n", pcConsens2);
-#endif
-            } /*  ( (1 == piLeafCount[iR]) && (0 != prHMM->L) ) */
-
-            
-
-            /* do alignment here (before free)
-             */
-            {
-                /* the size of the elements in the forward/backward matrices 
-                   depends very much on the lengths of the profiles _and_ 
-                   in which position (1st/2nd) the longer/shorter profile is.
-                   the matrix elements can easily exceed the size of a (long?) double
-                   if the longer profile is associated with the query (q) and the 
-                   shorter with the target (t). 
-                   this switch appears to be most easily (although unelegantly) 
-                   effected here. Don't want to do it (upstairs) in PrepareAlignment() 
-                   because it might jumble up the nodes. Don't want to do it in hhalign() 
-                   either because ppcProfile1/2 and q/t may be used independently.
-                   FS, r228 -> 229
-                 */
-                int iLen1 = strlen(ppcProfile1[0]);
-                int iLen2 = strlen(ppcProfile2[0]);
-                /* potential problem with empty profiles, FS, r249 -> r250 */
-                if ( (0 == iLen1) || (0 == iLen2) ){
-                    Log(&rLog, LOG_FATAL, "strlen(prof1)=%d, strlen(prof2)=%d -- nothing to align\n", 
-                        iLen1, iLen2);
-                }
-                   
-
-                if (iLen1 < iLen2){
-                    int iHHret = 0;
-                    int iOldMacRam = rHhalignPara.iMacRamMB;
-                    iHHret = hhalign(ppcProfile1, piLeafCount[iL], pdWeightsL,
-                                     ppcProfile2, piLeafCount[iR], pdWeightsR,
-                                     &dScore, prHMM,
-                                     pcConsens1, pcReprsnt1,
-                                     pcConsens2, pcReprsnt2,
-                                     rHhalignPara, 
-                                     iAux_FS++, /* DEBUG ARGUMENT */
-                                     zcAux, zcError);
-
-                    if (RETURN_OK != iHHret){ /* FS, r241 -> */
-                        fprintf(stderr, 
-                                "%s:%s:%d: problem in alignment (profile sizes: %d + %d) (%s + %s), forcing Viterbi\n"
-                                "\thh-error-code=%d (mac-ram=%d)\n",
-                                __FUNCTION__, __FILE__, __LINE__, piLeafCount[iL], piLeafCount[iR],
-                                prMSeq->sqinfo[ppiLeafList[iL][0]].name, prMSeq->sqinfo[ppiLeafList[iR][0]].name,
-                                iHHret, rHhalignPara.iMacRamMB);
-                        /* at this stage hhalign() has failed, 
-                           the only thing we can do (easily) is to re-run it in Viterbi mode, 
-                           for this set MAC-RAM=0, set it back to its original value after 2nd try. 
-                           FS, r241 -> r243 */
-                        if (RETURN_FROM_MAC == iHHret){
-                            /* Note: the default way to run hhalign() is to initially select MAC 
-                               by giving it all the memory it needs. MAC may fail due to overflow (repeats?).
-                               alternatively, the problem may be (genuinely) too big for MAC.
-                               in thses cases it is legitimate to switch to Viterbi. 
-                               However, selecting Viterbi from the outset is an abuse (abomination!), 
-                               should this 1st invocation of Viterbi fail, then we (FS) will overrule 
-                               the user and hammer the system with a massive memory request. 
-                               (Jos 2:19) If anyone goes outside your house into the street, 
-                               his blood will be on his own head; we will not be responsible. FS, r246 -> r247 */
-                            rHhalignPara.iMacRamMB = 0;
-                        }
-                        else {
-                            rHhalignPara.iMacRamMB = REALLY_BIG_MEMORY_MB;
-                        }
-
-                        iHHret = hhalign(ppcProfile1, piLeafCount[iL], pdWeightsL,
-                                         ppcProfile2, piLeafCount[iR], pdWeightsR,
-                                         &dScore, prHMM,
-                                         pcConsens1, pcReprsnt1,
-                                         pcConsens2, pcReprsnt2,
-                                         rHhalignPara, 
-                                         iAux_FS++, /* DEBUG ARGUMENT */
-                                         zcAux, zcError);
-                        if (RETURN_OK != iHHret){ /* at this stage hhalign() has failed twice, 
-                                             1st time MAC, 2nd time Viterbi, don't know what to do else. FS, r241 -> r243 */
-                            fprintf(stderr, "%s:%s:%d: problem in alignment, even Viterbi did not work\n"
-                                    "\thh-error-code=%d (mac-ram=%d)\n",
-                                    __FUNCTION__, __FILE__, __LINE__, iHHret, rHhalignPara.iMacRamMB);
-                            Log(&rLog, LOG_FATAL, "could not perform alignment -- bailing out\n");
-                        }
-                        else {
-                            fprintf(stderr, "%s:%s:%d: 2nd attempt worked", __FUNCTION__, __FILE__, __LINE__);
-                        }
-                        rHhalignPara.iMacRamMB = iOldMacRam; 
-                    } /* 1st invocation failed */
-
-                } /* 1st profile was shorter than 2nd */
-                else {
-                    int iHHret = 0;
-                    int iOldMacRam = rHhalignPara.iMacRamMB;
-                    iHHret = hhalign(ppcProfile2, piLeafCount[iR], pdWeightsR,
-                                     ppcProfile1, piLeafCount[iL], pdWeightsL,
-                                     &dScore, prHMM,
-                                     pcConsens2, pcReprsnt2,
-                                     pcConsens1, pcReprsnt1,
-                                     rHhalignPara, 
-                                     iAux_FS++, /* DEBUG ARGUMENT */
-                                     zcAux, zcError);
-
-                    if (RETURN_OK != iHHret){ /* FS, r241 -> r243 */
-                        fprintf(stderr, 
-                                "%s:%s:%d: problem in alignment (profile sizes: %d + %d) (%s + %s), forcing Viterbi\n"
-                                "\thh-error-code=%d (mac-ram=%d)\n",
-                                __FUNCTION__, __FILE__, __LINE__, piLeafCount[iL], piLeafCount[iR],
-                                prMSeq->sqinfo[ppiLeafList[iL][0]].name, prMSeq->sqinfo[ppiLeafList[iR][0]].name,
-                                iHHret, rHhalignPara.iMacRamMB);
-                        /* at this stage hhalign() has failed, 
-                           the only thing we can do (easily) is to re-run it in Viterbi mode, 
-                           for this set MAC-RAM=0, set it back to its original value after 2nd try. 
-                           FS, r241 -> r243 */
-                        if (RETURN_FROM_MAC == iHHret){
-                            /* see above */
-                            rHhalignPara.iMacRamMB = 0;
-                        }
-                        else {
-                            rHhalignPara.iMacRamMB = REALLY_BIG_MEMORY_MB;
-                        }
-
-                        iHHret = hhalign(ppcProfile2, piLeafCount[iR], pdWeightsR,
-                                         ppcProfile1, piLeafCount[iL], pdWeightsL,
-                                         &dScore, prHMM,
-                                         pcConsens2, pcReprsnt2,
-                                         pcConsens1, pcReprsnt1,
-                                         rHhalignPara, 
-                                         iAux_FS++, /* DEBUG ARGUMENT */
-                                         zcAux, zcError);
-                        if (RETURN_OK != iHHret){ /* at this stage hhalign() has failed twice, 
-                                             1st time MAC, 2nd time Viterbi, don't know what to do else. FS, r241 -> r243 */
-                            fprintf(stderr, "%s:%s:%d: problem in alignment, even Viterbi did not work\n"
-                                    "\thh-error-code=%d (mac-ram=%d)\n",
-                                    __FUNCTION__, __FILE__, __LINE__, iHHret, rHhalignPara.iMacRamMB);
-                            Log(&rLog, LOG_FATAL, "could not perform alignment -- bailing out\n");
-                        }
-                        else {
-                            fprintf(stderr, "%s:%s:%d: 2nd attempt worked", __FUNCTION__, __FILE__, __LINE__);
-                        }
-                        rHhalignPara.iMacRamMB = iOldMacRam; 
-                    } /* 1st invocation failed */
-
-                } /* 2nd profile was shorter than 1st */
-                
-            }
-            /* free left/right node lists,
-             * after alignment left/right profiles no longer needed
-             */
-            if (NULL != ppcCopy1){
-                int i;
-                for (i = 0; i <  piLeafCount[iL]; i++){
-                    CKFREE(ppcCopy1[i]);
-                }
-                CKFREE(ppcCopy1);
-                CKFREE(pcReprsnt1);
-                CKFREE(pcConsens1);
-            }
-            if (NULL != ppcCopy2){
-                int i;
-                for (i = 0; i <  piLeafCount[iR]; i++){
-                    CKFREE(ppcCopy2[i]);
-                }
-                CKFREE(ppcCopy2);
-                CKFREE(pcReprsnt2);
-                CKFREE(pcConsens2);
-            }
-            ppiLeafList[iL] = CKFREE(ppiLeafList[iL]);
-            ppiLeafList[iR] = CKFREE(ppiLeafList[iR]);
-            piLeafCount[iL] = piLeafCount[iR] = 0;
-
-        } /* was a merge node */
-
-        if (rLog.iLogLevelEnabled <= LOG_DEBUG){
-            int i, j;
-            FILE *fp = LogGetFP(&rLog, LOG_DEBUG);
-            for (i = 0; i < iNodeCount; i++){
-                if (0 == piLeafCount[i]){
-                    continue;
-                }
-                fprintf(fp, "node %3d, #leaves=%d:\t", i, piLeafCount[i]);
-                for (j = 0; ppiLeafList && (j < piLeafCount[i]); j++){
-                    fprintf(fp, "%d,", ppiLeafList[i][j]);
-                }
-                fprintf(fp, "\n");
-            }
-        }
-
-
-    } /* 0 <= iN < iNodeCount */
-    ProgressDone(prProgress);
-
-
-    /* check length and set length info
-     */
-    iAlnLen = strlen(prMSeq->seq[0]);
-    for (i=0; i<prMSeq->nseqs; i++) {
-#if 0
-        Log(&rLog, LOG_FORCED_DEBUG, "seq no %d: name %s; len %d; %s",
-                  i, prMSeq->sqinfo[i].name, strlen(prMSeq->seq[i]), prMSeq->seq[i]);
-#endif
-        
-#ifndef NDEBUG
-        assert(iAlnLen == strlen(prMSeq->seq[i]));
-#endif
-        prMSeq->sqinfo[i].len = iAlnLen;
-    }
-    prMSeq->aligned = TRUE;
-
-
-    if (rLog.iLogLevelEnabled <= LOG_DEBUG){
-        if (0 != prHMM->L){
-            int i;
-            Log(&rLog, LOG_DEBUG, "Alignment scores with HMM:");
-            for (i = 0; /*pdScores[i] > 0.0*/i < prMSeq->nseqs; i++){
-                Log(&rLog, LOG_DEBUG, "%2d:\t%f\n", i, pdScores[i]);
-            }
-        }
-    }
-
-
-    /** translate back ambiguity residues
-     * hhalign translates ambiguity codes (B,Z) into unknown residues (X).
-     * as we still have the original input we can substitute them back
-     */
-    TranslateUnknown2Ambiguity(prMSeq);
-    ReAttachLeadingGaps(prMSeq, iProfProfSeparator);
-
-    if (NULL == prHMMList){
-        CKFREE(prHMM);
-    }
-    CKFREE(ppcProfile2);
-    CKFREE(ppcProfile1);
-    CKFREE(ppiLeafList[piOrderLR[DIFF_NODE*(iNodeCount-1)+PRNT_NODE]]);
-    CKFREE(ppiLeafList);
-    CKFREE(piLeafCount);
-    CKFREE(pdScores);
-    FreeProgress(&prProgress);
-    CKFREE(pdWeightsL);
-    CKFREE(pdWeightsR);
-
-#if TIMING
-    StopwatchStop(stopwatch);
-    StopwatchDisplay(stdout, "Total time for HHalignWrapper():" , stopwatch);
-    StopwatchFree(stopwatch);
-#endif
-
-    return dScore; /* FIXME alternative: return averaged pdScores */
-
-}
-/***   end: HHalignWrapper() ***/