5 * Created by Sarah Westcott on 1/23/09.
6 * Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
10 #include "readtreecommand.h"
12 //**********************************************************************************************************************
13 vector<string> ReadTreeCommand::getValidParameters(){
15 string Array[] = {"tree","group","name","outputdir","inputdir"};
16 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
20 m->errorOut(e, "ReadTreeCommand", "getValidParameters");
24 //**********************************************************************************************************************
25 vector<string> ReadTreeCommand::getRequiredParameters(){
27 string Array[] = {"tree"};
28 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
32 m->errorOut(e, "ReadTreeCommand", "getRequiredParameters");
36 //**********************************************************************************************************************
37 vector<string> ReadTreeCommand::getRequiredFiles(){
39 vector<string> myArray;
43 m->errorOut(e, "ReadTreeCommand", "getRequiredFiles");
47 //**********************************************************************************************************************
48 ReadTreeCommand::ReadTreeCommand(string option) {
50 globaldata = GlobalData::getInstance();
53 //allow user to run help
54 if(option == "help") { help(); abort = true; }
57 //valid paramters for this command
58 string Array[] = {"tree","group","name","outputdir","inputdir"};
59 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
61 OptionParser parser(option);
62 map<string, string> parameters = parser.getParameters();
64 ValidParameters validParameter;
65 map<string, string>::iterator it;
67 //check to make sure all parameters are valid for command
68 for (it = parameters.begin(); it != parameters.end(); it++) {
69 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) { abort = true; }
72 globaldata->newRead();
74 //if the user changes the input directory command factory will send this info to us in the output parameter
75 string inputDir = validParameter.validFile(parameters, "inputdir", false);
76 if (inputDir == "not found"){ inputDir = ""; }
79 it = parameters.find("tree");
80 //user has given a template file
81 if(it != parameters.end()){
82 path = m->hasPath(it->second);
83 //if the user has not given a path then, add inputdir. else leave path alone.
84 if (path == "") { parameters["tree"] = inputDir + it->second; }
87 it = parameters.find("group");
88 //user has given a template file
89 if(it != parameters.end()){
90 path = m->hasPath(it->second);
91 //if the user has not given a path then, add inputdir. else leave path alone.
92 if (path == "") { parameters["group"] = inputDir + it->second; }
95 it = parameters.find("name");
96 //user has given a template file
97 if(it != parameters.end()){
98 path = m->hasPath(it->second);
99 //if the user has not given a path then, add inputdir. else leave path alone.
100 if (path == "") { parameters["name"] = inputDir + it->second; }
106 //check for required parameters
107 treefile = validParameter.validFile(parameters, "tree", true);
108 if (treefile == "not open") { abort = true; }
109 else if (treefile == "not found") { treefile = ""; m->mothurOut("tree is a required parameter for the read.tree command."); m->mothurOutEndLine(); abort = true; }
110 else { globaldata->setTreeFile(treefile); globaldata->setFormat("tree"); }
112 groupfile = validParameter.validFile(parameters, "group", true);
113 if (groupfile == "not open") { abort = true; }
114 else if (groupfile == "not found") {
117 m->mothurOut("You have not provided a group file. I am assumming all sequence are from the same group."); m->mothurOutEndLine();
119 if (treefile != "") { Tree* tree = new Tree(treefile); delete tree; } //extracts names from tree to make faked out groupmap
121 globaldata->setGroupFile(groupfile);
122 //read in group map info.
123 treeMap = new TreeMap();
124 for (int i = 0; i < globaldata->Treenames.size(); i++) { treeMap->addSeq(globaldata->Treenames[i], "Group1"); }
125 globaldata->gTreemap = treeMap;
128 globaldata->setGroupFile(groupfile);
129 //read in group map info.
130 treeMap = new TreeMap(groupfile);
132 globaldata->gTreemap = treeMap;
135 namefile = validParameter.validFile(parameters, "name", true);
136 if (namefile == "not open") { abort = true; }
137 else if (namefile == "not found") { namefile = ""; }
138 else { readNamesFile(); }
140 if (abort == false) {
142 read = new ReadNewickTree(filename);
147 catch(exception& e) {
148 m->errorOut(e, "ReadTreeCommand", "ReadTreeCommand");
152 //**********************************************************************************************************************
154 void ReadTreeCommand::help(){
156 m->mothurOut("The read.tree command must be run before you execute a unifrac.weighted, unifrac.unweighted. \n");
157 m->mothurOut("It also must be run before using the parsimony command, unless you are using the randomtree parameter.\n");
158 m->mothurOut("The read.tree command parameters are tree, group and name.\n");
159 m->mothurOut("The read.tree command should be in the following format: read.tree(tree=yourTreeFile, group=yourGroupFile).\n");
160 m->mothurOut("The tree and group parameters are both required, if no group file is given then one group is assumed.\n");
161 m->mothurOut("The name parameter allows you to enter a namefile.\n");
162 m->mothurOut("Note: No spaces between parameter labels (i.e. tree), '=' and parameters (i.e.yourTreefile).\n\n");
164 catch(exception& e) {
165 m->errorOut(e, "ReadTreeCommand", "help");
170 //**********************************************************************************************************************
172 ReadTreeCommand::~ReadTreeCommand(){
173 if (abort == false) { delete read; }
176 //**********************************************************************************************************************
178 int ReadTreeCommand::execute(){
181 if (abort == true) { return 0; }
185 readOk = read->read();
187 if (readOk != 0) { m->mothurOut("Read Terminated."); m->mothurOutEndLine(); globaldata->gTree.clear(); delete globaldata->gTreemap; return 0; }
189 vector<Tree*> T = globaldata->gTree;
191 //assemble users trees
192 for (int i = 0; i < T.size(); i++) {
193 if (m->control_pressed) {
194 for (int i = 0; i < T.size(); i++) { delete T[i]; }
195 globaldata->gTree.clear();
196 delete globaldata->gTreemap;
200 T[i]->assembleTree();
204 //if you provide a namefile we will use the numNames in the namefile as long as the number of unique match the tree names size.
206 if (namefile != "") {
207 if (numUniquesInName == globaldata->Treenames.size()) { numNamesInTree = nameMap.size(); }
208 else { numNamesInTree = globaldata->Treenames.size(); }
209 }else { numNamesInTree = globaldata->Treenames.size(); }
212 //output any names that are in group file but not in tree
213 if (numNamesInTree < treeMap->getNumSeqs()) {
214 for (int i = 0; i < treeMap->namesOfSeqs.size(); i++) {
215 //is that name in the tree?
217 for (int j = 0; j < globaldata->Treenames.size(); j++) {
218 if (treeMap->namesOfSeqs[i] == globaldata->Treenames[j]) { break; } //found it
222 if (m->control_pressed) {
223 for (int i = 0; i < T.size(); i++) { delete T[i]; }
224 globaldata->gTree.clear();
225 delete globaldata->gTreemap;
229 //then you did not find it so report it
230 if (count == globaldata->Treenames.size()) {
231 //if it is in your namefile then don't remove
232 map<string, string>::iterator it = nameMap.find(treeMap->namesOfSeqs[i]);
234 if (it == nameMap.end()) {
235 m->mothurOut(treeMap->namesOfSeqs[i] + " is in your groupfile and not in your tree. It will be disregarded."); m->mothurOutEndLine();
236 treeMap->removeSeq(treeMap->namesOfSeqs[i]);
237 i--; //need this because removeSeq removes name from namesOfSeqs
242 globaldata->gTreemap = treeMap;
247 catch(exception& e) {
248 m->errorOut(e, "ReadTreeCommand", "execute");
252 /*****************************************************************/
253 int ReadTreeCommand::readNamesFile() {
255 globaldata->names.clear();
256 numUniquesInName = 0;
259 m->openInputFile(namefile, in);
261 string first, second;
262 map<string, string>::iterator itNames;
265 in >> first >> second; m->gobble(in);
269 itNames = globaldata->names.find(first);
270 if (itNames == globaldata->names.end()) {
271 globaldata->names[first] = second;
273 //we need a list of names in your namefile to use above when removing extra seqs above so we don't remove them
274 vector<string> dupNames;
275 m->splitAtComma(second, dupNames);
277 for (int i = 0; i < dupNames.size(); i++) { nameMap[dupNames[i]] = dupNames[i]; if ((groupfile == "") && (i != 0)) { globaldata->gTreemap->addSeq(dupNames[i], "Group1"); } }
278 }else { m->mothurOut(first + " has already been seen in namefile, disregarding names file."); m->mothurOutEndLine(); in.close(); globaldata->names.clear(); namefile = ""; return 1; }
284 catch(exception& e) {
285 m->errorOut(e, "ReadTreeCommand", "readNamesFile");
290 //**********************************************************************************************************************