예제 #1
0
파일: converter.cpp 프로젝트: jimallman/ncl
bool substituteSafeTaxaLabels(PublicNexusReader &nexusReader, std::string filepath, bool evenTrivial)
{
    std::ostream * outStrPtr = 0L;
    std::ofstream outStream;
    const unsigned nTaxaBlocks = nexusReader.GetNumTaxaBlocks();
    bool someChanged = false;
    std::set<std::string> safeNameSet;
    try
    {
        for (unsigned t = 0; t < nTaxaBlocks; ++t)
        {
            NxsTaxaBlock * tb = nexusReader.GetTaxaBlock(t);
            std::vector<std::string> safeLabelsVec;

            bool changed = constructSafeLabels(*tb, &safeLabelsVec, safeNameSet);
            someChanged = someChanged | changed;
            if (changed || evenTrivial)
            {
                if (outStrPtr == 0L)
                {
                    outStream.open(filepath.c_str());
                    if (!outStream.good())
                    {
                        NxsString eMessage;
                        eMessage << "Could not open the file \"" << filepath << "\"";
                        throw NxsException(eMessage);
                    }
                    outStrPtr = &outStream;
                    outStream << "#NEXUS\n";
                }
                tb->WriteAsNexus(*outStrPtr);
                std::vector<NxsString> oldNameVec;
                const unsigned numTaxa = tb->GetNTaxTotal();
                for (unsigned i = 0; i < numTaxa; ++i)
                {
                    NxsString oldName = tb->GetTaxonLabel(i);
                    oldNameVec.push_back(oldName);
                    NxsString newName;
                    newName << safeLabelsVec[i];
                    tb->ChangeTaxonLabel(i, newName);
                }
                NxsString title;
                title << tb->GetTitle();
                NxsString nt;
                nt << "Renamed " << title;
                tb->SetTitle(nt, false);
                tb->WriteAsNexus(*outStrPtr);

                // We can't just create a TaxaAssociationBlock instance here,
                //  and call WriteAsNexus because it first and second taxa block pointers
                //  would refer to the same instance...
                NxsString taTitle;
                taTitle << "Renaming " << title;
                *outStrPtr << "BEGIN TaxaAssociation;\n  Title " << NxsString::GetEscaped(taTitle) << " ;\n";
                *outStrPtr << "  Taxa " << NxsString::GetEscaped(title) << " , " << NxsString::GetEscaped(nt) << " ;\n";
                *outStrPtr << "  Associates ";
                for (unsigned i = 0; i < numTaxa; ++i)
                {
                    if (i > 0)
                        *outStrPtr << " ,\n    ";
                    *outStrPtr <<  NxsString::GetEscaped(oldNameVec[i]) << " / " << NxsString::GetEscaped(safeLabelsVec[i]);
                }
                *outStrPtr << " ;\nEND;\n" ;
            }
        }
    }
    catch (...)
    {
        if (outStrPtr != 0L)
            outStream.close();
        throw;
    }

    if (outStrPtr != 0L)
        outStream.close();
    return someChanged;
}