]> git.donarmstrong.com Git - mothur.git/blob - matrixoutputcommand.cpp
added smart distance feature and optimized all commands using line by line processing
[mothur.git] / matrixoutputcommand.cpp
1 /*
2  *  matrixoutputcommand.cpp
3  *  Mothur
4  *
5  *  Created by Sarah Westcott on 5/20/09.
6  *  Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
7  *
8  */
9
10 #include "matrixoutputcommand.h"
11 #include "sharedjabund.h"
12 #include "sharedsorabund.h"
13 #include "sharedjclass.h"
14 #include "sharedsorclass.h"
15 #include "sharedjest.h"
16 #include "sharedsorest.h"
17 #include "sharedthetayc.h"
18 #include "sharedthetan.h"
19 #include "sharedmorisitahorn.h"
20 #include "sharedbraycurtis.h"
21
22
23 //**********************************************************************************************************************
24
25 MatrixOutputCommand::MatrixOutputCommand(){
26         try {
27                 globaldata = GlobalData::getInstance();
28                 validCalculator = new ValidCalculators();
29                         
30                 int i;
31                 for (i=0; i<globaldata->Estimators.size(); i++) {
32                         if (validCalculator->isValidCalculator("matrix", globaldata->Estimators[i]) == true) { 
33                                 if (globaldata->Estimators[i] == "jabund") {    
34                                         matrixCalculators.push_back(new JAbund());
35                                 }else if (globaldata->Estimators[i] == "sorabund") { 
36                                         matrixCalculators.push_back(new SorAbund());
37                                 }else if (globaldata->Estimators[i] == "jclass") { 
38                                         matrixCalculators.push_back(new Jclass());
39                                 }else if (globaldata->Estimators[i] == "sorclass") { 
40                                         matrixCalculators.push_back(new SorClass());
41                                 }else if (globaldata->Estimators[i] == "jest") { 
42                                         matrixCalculators.push_back(new Jest());
43                                 }else if (globaldata->Estimators[i] == "sorest") { 
44                                         matrixCalculators.push_back(new SorEst());
45                                 }else if (globaldata->Estimators[i] == "thetayc") { 
46                                         matrixCalculators.push_back(new ThetaYC());
47                                 }else if (globaldata->Estimators[i] == "thetan") { 
48                                         matrixCalculators.push_back(new ThetaN());
49                                 }else if (globaldata->Estimators[i] == "morisitahorn") { 
50                                         matrixCalculators.push_back(new MorHorn());
51                                 }else if (globaldata->Estimators[i] == "braycurtis") { 
52                                         matrixCalculators.push_back(new BrayCurtis());
53                                 }
54                         }
55                 }
56                 
57                 //reset calc for next command
58                 globaldata->setCalc("");
59
60         }
61         catch(exception& e) {
62                 cout << "Standard Error: " << e.what() << " has occurred in the MatrixOutputCommand class Function MatrixOutputCommand. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
63                 exit(1);
64         }
65         catch(...) {
66                 cout << "An unknown error has occurred in the MatrixOutputCommand class function MatrixOutputCommand. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
67                 exit(1);
68         }       
69 }
70 //**********************************************************************************************************************
71
72 MatrixOutputCommand::~MatrixOutputCommand(){
73         delete input;
74         delete read;
75 }
76
77 //**********************************************************************************************************************
78
79 int MatrixOutputCommand::execute(){
80         try {
81                 int count = 1;  
82                                 
83                 //if the users entered no valid calculators don't execute command
84                 if (matrixCalculators.size() == 0) { cout << "No valid calculators." << endl; return 0; }
85
86                 //you have groups
87                 read = new ReadOTUFile(globaldata->inputFileName);      
88                 read->read(&*globaldata); 
89                         
90                 input = globaldata->ginput;
91                 lookup = input->getSharedRAbundVectors();
92                 vector<SharedRAbundVector*> lastLookup = lookup;
93                 
94                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
95                 set<string> processedLabels;
96                 set<string> userLabels = globaldata->labels;
97                                 
98                 if (lookup.size() < 2) { cout << "You have not provided enough valid groups.  I cannot run the command." << endl; return 0;}
99                 
100                 numGroups = globaldata->Groups.size();
101                                 
102                 //as long as you are not at the end of the file or done wih the lines you want
103                 while((lookup[0] != NULL) && ((globaldata->allLines == 1) || (userLabels.size() != 0))) {
104                 
105                         if(globaldata->allLines == 1 || globaldata->lines.count(count) == 1 || globaldata->labels.count(lookup[0]->getLabel()) == 1){                   
106                                 cout << lookup[0]->getLabel() << '\t' << count << endl;
107                                 process(lookup);
108                                 
109                                 processedLabels.insert(lookup[0]->getLabel());
110                                 userLabels.erase(lookup[0]->getLabel());
111                         }
112                         
113                         if ((anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLookup[0]->getLabel()) != 1)) {
114                                 cout << lastLookup[0]->getLabel() << '\t' << count << endl;
115                                 process(lastLookup);
116                                 
117                                 processedLabels.insert(lastLookup[0]->getLabel());
118                                 userLabels.erase(lastLookup[0]->getLabel());
119                         }
120
121                         //prevent memory leak
122                         if (count != 1) { for (int i = 0; i < lastLookup.size(); i++) {  delete lastLookup[i];  } }
123                         lastLookup = lookup;                    
124                         
125                         //get next line to process
126                         lookup = input->getSharedRAbundVectors();
127                         count++;
128                 }
129                 
130                 //output error messages about any remaining user labels
131                 set<string>::iterator it;
132                 bool needToRun = false;
133                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  
134                         cout << "Your file does not include the label "<< *it; 
135                         if (processedLabels.count(lastLookup[0]->getLabel()) != 1) {
136                                 cout << ". I will use " << lastLookup[0]->getLabel() << "." << endl;
137                                 needToRun = true;
138                         }else {
139                                 cout << ". Please refer to " << lastLookup[0]->getLabel() << "." << endl;
140                         }
141                 }
142                 
143                 //run last line if you need to
144                 if (needToRun == true)  {
145                         cout << lastLookup[0]->getLabel() << '\t' << count << endl;
146                         process(lastLookup);            
147                 }
148                 
149                 for (int i = 0; i < lastLookup.size(); i++) {  delete lastLookup[i];  }
150
151                 
152                 //reset groups parameter
153                 globaldata->Groups.clear();  globaldata->setGroups("");
154
155                 return 0;
156         }
157         catch(exception& e) {
158                 cout << "Standard Error: " << e.what() << " has occurred in the MatrixOutputCommand class Function execute. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
159                 exit(1);
160         }
161         catch(...) {
162                 cout << "An unknown error has occurred in the MatrixOutputCommand class function execute. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
163                 exit(1);
164         }               
165 }
166 /***********************************************************/
167 void MatrixOutputCommand::printSims(ostream& out) {
168         try {
169                 
170                 //output column headers
171                 out << simMatrix.size() << endl;
172                 
173                 for (int m = 0; m < simMatrix.size(); m++)      {
174                         out << lookup[m]->getGroup() << '\t';
175                         for (int n = 0; n < m; n++)     {
176                                 out << simMatrix[m][n] << '\t'; 
177                         }
178                         out << endl;
179                 }
180
181         }
182         catch(exception& e) {
183                 cout << "Standard Error: " << e.what() << " has occurred in the MatrixOutputCommand class Function printSims. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
184                 exit(1);
185         }
186         catch(...) {
187                 cout << "An unknown error has occurred in the MatrixOutputCommand class function printSims. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
188                 exit(1);
189         }               
190 }
191 /***********************************************************/
192 void MatrixOutputCommand::process(vector<SharedRAbundVector*> thisLookup){
193         try {
194         
195                                 EstOutput data;
196                                 vector<SharedRAbundVector*> subset;
197
198                                 //for each calculator                                                                                           
199                                 for(int i = 0 ; i < matrixCalculators.size(); i++) {
200                                         
201                                         //initialize simMatrix
202                                         simMatrix.clear();
203                                         simMatrix.resize(numGroups);
204                                         for (int m = 0; m < simMatrix.size(); m++)      {
205                                                 for (int j = 0; j < simMatrix.size(); j++)      {
206                                                         simMatrix[m].push_back(0.0);
207                                                 }
208                                         }
209                                 
210                                         for (int k = 0; k < thisLookup.size(); k++) { 
211                                                 for (int l = k; l < thisLookup.size(); l++) {
212                                                         if (k != l) { //we dont need to similiarity of a groups to itself
213                                                                 //get estimated similarity between 2 groups
214                                                                 
215                                                                 subset.clear(); //clear out old pair of sharedrabunds
216                                                                 //add new pair of sharedrabunds
217                                                                 subset.push_back(thisLookup[k]); subset.push_back(thisLookup[l]); 
218                                                                 
219                                                                 data = matrixCalculators[i]->getValues(subset); //saves the calculator outputs
220                                                                 //save values in similarity matrix
221                                                                 simMatrix[k][l] = 1.0 - data[0];  //convert similiarity to distance
222                                                                 simMatrix[l][k] = 1.0 - data[0];  //convert similiarity to distance
223                                                         }
224                                                 }
225                                         }
226                                         
227                                         exportFileName = getRootName(globaldata->inputFileName) + matrixCalculators[i]->getName() + "." + thisLookup[0]->getLabel() + ".dist";
228                                         openOutputFile(exportFileName, out);
229                                         printSims(out);
230                                         out.close();
231                                         
232                                 }
233
234         
235                 
236         }
237         catch(exception& e) {
238                 cout << "Standard Error: " << e.what() << " has occurred in the MatrixOutputCommand class Function process. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
239                 exit(1);
240         }
241         catch(...) {
242                 cout << "An unknown error has occurred in the MatrixOutputCommand class function process. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
243                 exit(1);
244         }               
245 }
246 /***********************************************************/
247
248
249