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; } }