BlockReaderList NxsReader::FindAllBlocksByTitleNoPrioritization(const BlockReaderList & chosenBlockList, const char *title) { BlockReaderList found; if (chosenBlockList.empty() || title == NULL) { found = chosenBlockList; } else { bool emptyTitle = strlen(title) == 0; for (BlockReaderList::const_iterator cblIt = chosenBlockList.begin(); cblIt != chosenBlockList.end(); ++cblIt) { NxsBlock * b = *cblIt; std::vector<std::string> v = this->GetAllTitlesForBlock(b); for (std::vector<std::string>::const_iterator vIt = v.begin(); vIt != v.end(); ++vIt) { const std::string & n = *vIt; if ((emptyTitle && n.empty()) || (NxsString::case_insensitive_equals(title, n.c_str()))) { found.push_back(b); break; } } } } return found; }
BlockReaderList NxsReader::FindAllBlocksByTitle(const BlockReaderList & chosenBlockList, const char *title) { BlockReaderList found = FindAllBlocksByTitleNoPrioritization(chosenBlockList, title); if (found.empty()) { return found; } map<int, BlockReaderList> byPriority; for (BlockReaderList::const_iterator fIt = found.begin(); fIt != found.end(); ++fIt) { NxsBlock * b = *fIt; int priority = GetBlockPriority(b); byPriority[priority].push_back(b); } NCL_ASSERT(!byPriority.empty()); return byPriority.rbegin()->second; }
/*! \returns a NxsBlock from `chosenBlockList` with a Title that matches `title`. In the event of ties, the most recently read block is returned. If `title` is NULL, then any block is considered a match. On output *nMatches will be the number of matches (if `nMatches` is not NULL). NULL will be returned if there are no matches. */ NxsBlock *NxsReader::FindBlockByTitle(const BlockReaderList & chosenBlockList, const char *title, unsigned *nMatches) { BlockReaderList found = FindAllBlocksByTitle(chosenBlockList, title); if (found.empty()) { if (nMatches) { *nMatches = 0; } return NULL; } if (nMatches) { *nMatches = (unsigned)found.size(); } return (NxsBlock *) found.back(); }
void BullShell::ExecGetTrees(const GetTreesOpts & gto) { errormsg.clear(); BlockReaderList blocks = getBlocksFromFile(gto.filename, true); if (blocks.empty()) { errormsg << "No Trees Block found in " << gto.filename; throw XBull(errormsg); } unsigned ntreesInFile = 0; const unsigned ntreesBlocks = blocks.size(); vector<NxsTreesBlockAPI *> trBlocks; for (BlockReaderList::iterator b = blocks.begin(); b != blocks.end(); ++b) { NxsTreesBlockAPI *tb = (NxsTreesBlockAPI *)(*b); trBlocks.push_back(tb); assert(tb); ntreesInFile += tb->GetNumTrees(); } if (ntreesInFile < 1) { errormsg << "No Trees found in " << gto.filename; throw XBull(errormsg); } const unsigned toTree = (unsigned) (gto.toTree < 0 ? 0 : gto.toTree); const unsigned fromTree = (unsigned) (gto.fromTree < 0 ? ntreesInFile - 1 : gto.fromTree); if (fromTree > toTree) { errormsg << "Cant get Trees from " << fromTree << " to " << toTree; throw XBull( errormsg); } // Store the specified trees // these trees are deleted in the for loop if there is an error, otherwise // they are put under the control of the kernel vector<Tree *> treesToBeAdded; vector<NxsTreesBlockAPI *>::const_iterator tbIt = trBlocks.begin(); NxsTreesBlockAPI * currTB = *tbIt; unsigned nTreesInThisBlock = currTB->GetNumTrees(); int nleftInThisBlock = (int) nTreesInThisBlock; for (unsigned i = 0; i < toTree; i++, --nleftInThisBlock) { while (nleftInThisBlock < 1) { ++tbIt; assert(tbIt != trBlocks.end()); currTB = *tbIt; nTreesInThisBlock = currTB->GetNumTrees(); nleftInThisBlock = (int) nTreesInThisBlock; } if (i >= fromTree) { const std::string newick = currTB->GetTranslatedTreeDescription((unsigned)(nTreesInThisBlock - nleftInThisBlock)); Tree * temptree = new Tree(newick, gto.storeBrLensFromFile); if (!temptree->IsGood()) { for (unsigned j = 0; j < i - fromTree; j++) delete treesToBeAdded[j]; errormsg << "Problem Reading Tree Description of " << currTB->GetTreeName(i); delete temptree; throw XBull(errormsg); } std::string s = currTB->GetTreeName(i); ToUpper(s); temptree->SetName(s); treesToBeAdded.push_back(temptree); } } ioObject.message.clear(); ioObject.message << (int)(toTree - fromTree) << " trees read from " << ntreesBlocks << " TREES block(s) in " << gto.filename; ioObject.printMessage(BullIO::STATUS_MSG_LEVEL); assert(gto.mode <= 7 && gto.mode >= 0); kernel.updateTrees(treesToBeAdded, UpdateMode(gto.mode)); for (BlockReaderList::iterator b = blocks.begin(); b != blocks.end(); ++b) { if (*b != this) delete *b; } }