Exemplo n.º 1
0
int CAlignmentRefiner::Run(void)
{
    CCdd cdd;
    unsigned int alWidth;
    unsigned int nBlocksFromAU;
    string message;

    // Get arguments
    CArgs args = GetArgs();
    string fname, err;
    string basename = args["o"].AsString() + "_", suffix = ".cn3"; 

    // Stream to results file, if provided, or cout
    // (NOTE: "x_lg" is just a workaround for bug in SUN WorkShop 5.1 compiler)
    ostream* x_lg = args["details"] ? &args["details"].AsOutputFile() : &cout;
    ostream& detailsStream = *x_lg;

    SetDiagStream(x_lg); // send all diagnostic messages to the same stream

    //  Set to info level here, not in main, to avoid info messages about missing log files.
    SetDiagPostLevel(eDiag_Info);

    // Set up details stream first...
    if (args["details"]) {
        string str;
        detailsStream << args.Print(str) << endl << endl;
        detailsStream << string(72, '=') << endl;
        detailsStream.precision(2);
//        if (args["qd"]) m_quietDetails = true;
    }

    // Get initial alignment (in a Cdd blob) from the input file;
    // convert to an AlignmentUtility object.

    if (!ReadCD(args["i"].AsString(), &cdd)) {
        ERROR_MESSAGE_CL("error reading CD from input file " << args["i"].AsString());
        return eRefinerResultCantReadCD;
    }

    AlignmentUtility* au = new AlignmentUtility(cdd.GetSequences(), cdd.GetSeqannot());
    const BlockMultipleAlignment* bma = (au && au->Okay()) ? au->GetBlockMultipleAlignment() : NULL;
    if (!bma) {
        delete au;
        ERROR_MESSAGE_CL("Found invalid alignment in CD " << args["i"].AsString());
        return eRefinerResultAlignmentUtilityError;
    }

    nBlocksFromAU = bma->NAlignedBlocks();
    alWidth       = bma->AlignmentWidth();

    TERSE_INFO_MESSAGE_CL("\nRows in alignment:  " << bma->NRows());
    TERSE_INFO_MESSAGE_CL("Alignment width  :  " << alWidth);
    TERSE_INFO_MESSAGE_CL("Number of Aligned Blocks after IBM:  " << nBlocksFromAU << "\n");

    
    //  Some general parameters...

    m_nTrials = (unsigned) args["n"].AsInteger();
    m_nCycles = args["nc"].AsInteger();
    m_scoreDeviationThreshold = args["convScoreChange"].AsDouble();

    m_quietMode = (args["q"]);
    //  if (m_quietMode) SetDiagPostLevel(eDiag_Error);   


    //  Fill out data structure for leave-one-out parameters
    //  LOO is performed unless -no_LOO option used

    RefinerResultCode looParamResult = ExtractLOOArgs(nBlocksFromAU, message);
    if (looParamResult != eRefinerResultOK) {
        ERROR_MESSAGE_CL(message);
        return looParamResult;
    }

    //  If using a fixed selection order based on row-scores of the
    //  initial alignment, no need to do multiple trials.
    if (m_nTrials > 1 && m_loo.selectorCode != eRandomSelectionOrder) {
        m_nTrials = 1;
        WARNING_MESSAGE_CL("For deterministic row-selection order, multiple trials are redundant.\nSetting number of trials to one and continuing.\n");
    }

    //EchoSettings(detailsStream, true, false);

    //  Fill out data structure for block editing parameters.  
    //  By default, edit blocks -- must explicitly skip with the -be_fix option.
    RefinerResultCode beParamResult = ExtractBEArgs(nBlocksFromAU, message);
    if (beParamResult != eRefinerResultOK) {
        ERROR_MESSAGE_CL(message);
        return beParamResult;
    }

    //EchoSettings(detailsStream, false, true);
    EchoSettings(detailsStream, true, true);

    if (!m_blockEdit.editBlocks && !m_loo.doLOO) {
        ERROR_MESSAGE_CL("Nothing will happen as both LOO and block editing have been disabled.  Stopping");
        return eRefinerResultInconsistentArgumentCombination;
    }


    //  Perform the refinement...

    TRACE_MESSAGE_CL("Entering refiner engine...\n");

    CBMARefinerEngine refinerEngine(m_loo, m_blockEdit, m_nCycles, m_nTrials, true, !m_quietMode, m_scoreDeviationThreshold);
    RefinerResultCode result = refinerEngine.Refine(au, &detailsStream);


    //  Output final statistics and refined alignments
    //  Get results from all trials; use reverse iterator to get them
    //  out of the map in order of highest to lowest score.


    unsigned int n = 0;
    unsigned int trial;
    unsigned int nToWrite = (m_nTrials > 1) ? args["nout"].AsInteger() : 1;

    const RefinedAlignments& optimizedAlignments = refinerEngine.GetAllResults();
    RefinedAlignmentsRevCIt rcit = optimizedAlignments.rbegin(), rend = optimizedAlignments.rend();

    if (rcit != rend) {
        detailsStream << endl << endl << "Original Alignment Score = " << refinerEngine.GetInitialScore() << endl;
        detailsStream << endl << "Best Refined Alignments (in descending score order)\n\n";
    } else {
        detailsStream << endl << "No Refined Alignments found (?)\n\n";
    }

    for (; rcit != rend; ++rcit, ++n) {
        trial = rcit->second.iteration;
        if (rcit->second.au == NULL) {
            detailsStream << "Problem in trial " << trial << " -> no refined alignment available." << endl << endl;
            continue;
        }

        detailsStream << "Alignment " << n << ":  Score = " << rcit->first << " (trial " << trial << ")" << endl;
        if (n < nToWrite) {
            err.erase();
            cdd.SetSeqannot() = rcit->second.au->GetSeqAnnots();

            // write output as a CD in a new file
            fname = basename + NStr::UIntToString(n) + "_trial" + NStr::UIntToString(trial) + suffix;
            detailsStream << "    (written to file '" << fname << "')";
            if (!WriteASNToFile(fname.c_str(), cdd, args["ob"].HasValue(), &err)) {
                ERROR_MESSAGE_CL("error writing output file " << fname);
            }
        }
        detailsStream << endl;
    }

    //  Destructor of RefinerEngine cleans up map of optimized alignments
    //  once it goes out of scope.
//    delete au;
//    delete auOriginal;

    if (args["details"]) args["details"].CloseFile();
    return result;

}