]> git.donarmstrong.com Git - mothur.git/blob - parsimony.cpp
removed various build warnings
[mothur.git] / parsimony.cpp
1 /*
2  *  parsimony.cpp
3  *  Mothur
4  *
5  *  Created by Sarah Westcott on 1/26/09.
6  *  Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
7  *
8  */
9
10 #include "parsimony.h"
11
12 /**************************************************************************************************/
13
14 EstOutput Parsimony::getValues(Tree* t, int p, string o) {
15         try {
16                 globaldata = GlobalData::getInstance();
17                 processors = p;
18                 outputDir = o;
19                 
20                 //if the users enters no groups then give them the score of all groups
21                 int numGroups = globaldata->Groups.size();
22                 
23                 //calculate number of comparsions
24                 int numComp = 0;
25                 vector< vector<string> > namesOfGroupCombos;
26                 for (int r=0; r<numGroups; r++) { 
27                         for (int l = r+1; l < numGroups; l++) {
28                                 numComp++;
29                                 vector<string> groups; groups.push_back(globaldata->Groups[r]); groups.push_back(globaldata->Groups[l]);
30                                 //cout << globaldata->Groups[r] << '\t' << globaldata->Groups[l] << endl;
31                                 namesOfGroupCombos.push_back(groups);
32                         }
33                 }
34
35                 //numComp+1 for AB, AC, BC, ABC
36                 if (numComp != 1) {
37                         vector<string> groups;
38                         if (numGroups == 0) {
39                                 //get score for all users groups
40                                 for (int i = 0; i < tmap->namesOfGroups.size(); i++) {
41                                         if (tmap->namesOfGroups[i] != "xxx") {
42                                                 groups.push_back(tmap->namesOfGroups[i]);
43                                                 //cout << tmap->namesOfGroups[i] << endl;
44                                         }
45                                 }
46                                 namesOfGroupCombos.push_back(groups);
47                         }else {
48                                 for (int i = 0; i < globaldata->Groups.size(); i++) {
49                                         groups.push_back(globaldata->Groups[i]);
50                                         //cout << globaldata->Groups[i] << endl;
51                                 }
52                                 namesOfGroupCombos.push_back(groups);
53                         }
54                 }
55                 
56         #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
57                 if(processors == 1){
58                         data = driver(t, namesOfGroupCombos, 0, namesOfGroupCombos.size());
59                 }else{
60                         lines.clear();
61                         int numPairs = namesOfGroupCombos.size();
62                         
63                         int numPairsPerProcessor = numPairs / processors;
64                         
65                         for (int i = 0; i < processors; i++) {
66                                 int startPos = i * numPairsPerProcessor;
67                                 
68                                 if(i == processors - 1){
69                                         numPairsPerProcessor = numPairs - i * numPairsPerProcessor;
70                                 }
71                                 
72                                 lines.push_back(linePair(startPos, numPairsPerProcessor));
73                         }
74                         
75                         data = createProcesses(t, namesOfGroupCombos);
76                 }
77         #else
78                 data = driver(t, namesOfGroupCombos, 0, namesOfGroupCombos.size());
79         #endif
80                 
81                 return data;
82                 
83         }
84         catch(exception& e) {
85                 m->errorOut(e, "Parsimony", "getValues");
86                 exit(1);
87         }
88 }
89 /**************************************************************************************************/
90
91 EstOutput Parsimony::createProcesses(Tree* t, vector< vector<string> > namesOfGroupCombos) {
92         try {
93 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
94                 int process = 1;
95                 vector<int> processIDS;
96                 
97                 EstOutput results;
98                 
99                 //loop through and create all the processes you want
100                 while (process != processors) {
101                         int pid = fork();
102                         
103                         if (pid > 0) {
104                                 processIDS.push_back(pid);  //create map from line number to pid so you can append files in correct order later
105                                 process++;
106                         }else if (pid == 0){
107                                 EstOutput myresults;
108                                 myresults = driver(t, namesOfGroupCombos, lines[process].start, lines[process].num);
109                                 
110                                 if (m->control_pressed) { exit(0); }
111                                 
112                                 //pass numSeqs to parent
113                                 ofstream out;
114                                 string tempFile = outputDir + toString(getpid()) + ".pars.results.temp";
115                                 m->openOutputFile(tempFile, out);
116                                 out << myresults.size() << endl;
117                                 for (int i = 0; i < myresults.size(); i++) {  out << myresults[i] << '\t';  } out << endl;
118                                 out.close();
119                                 
120                                 exit(0);
121                         }else { 
122                                 m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
123                                 for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
124                                 exit(0); 
125                         }
126                 }
127                 
128                 results = driver(t, namesOfGroupCombos, lines[0].start, lines[0].num);
129                 
130                 //force parent to wait until all the processes are done
131                 for (int i=0;i<processIDS.size();i++) { 
132                         int temp = processIDS[i];
133                         wait(&temp);
134                 }
135                 
136                 if (m->control_pressed) { return results; }
137                         
138                 //get data created by processes
139                 for (int i=0;i<processIDS.size();i++) { 
140                         ifstream in;
141                         string s = outputDir + toString(processIDS[i]) + ".pars.results.temp";
142                         m->openInputFile(s, in);
143                         
144                         //get scores
145                         if (!in.eof()) {
146                                 int num;
147                                 in >> num; m->gobble(in);
148                                 
149                                 if (m->control_pressed) { break; }
150                                 
151                                 double w; 
152                                 for (int j = 0; j < num; j++) {
153                                         in >> w;
154                                         results.push_back(w);
155                                 }
156                                 m->gobble(in);
157                         }
158                         in.close();
159                         remove(s.c_str());
160                 }
161                 
162                 return results;
163 #endif          
164         }
165         catch(exception& e) {
166                 m->errorOut(e, "Parsimony", "createProcesses");
167                 exit(1);
168         }
169 }
170 /**************************************************************************************************/
171 EstOutput Parsimony::driver(Tree* t, vector< vector<string> > namesOfGroupCombos, int start, int num) { 
172         try {
173                 
174                 EstOutput results; results.resize(num);
175                 
176                 Tree* copyTree = new Tree();
177                 int count = 0;
178                 
179                 for (int h = start; h < (start+num); h++) {
180                                         
181                         if (m->control_pressed) { delete copyTree; return results; }
182         
183                         int score = 0;
184                         
185                         //groups in this combo
186                         vector<string> groups = namesOfGroupCombos[h];
187                         
188                         //copy users tree so that you can redo pgroups 
189                         copyTree->getCopy(t);
190                         
191                         //create pgroups that reflect the groups the user want to use
192                         for(int i=copyTree->getNumLeaves();i<copyTree->getNumNodes();i++){
193                                 copyTree->tree[i].pGroups = (copyTree->mergeUserGroups(i, groups));
194                         }
195                         
196                         for(int i=copyTree->getNumLeaves();i<copyTree->getNumNodes();i++){
197                                 
198                                 if (m->control_pressed) { return data; }
199                                 
200                                 int lc = copyTree->tree[i].getLChild();
201                                 int rc = copyTree->tree[i].getRChild();
202                                 
203                                 int iSize = copyTree->tree[i].pGroups.size();
204                                 int rcSize = copyTree->tree[rc].pGroups.size();
205                                 int lcSize = copyTree->tree[lc].pGroups.size();
206                                 
207                                 //if isize are 0 then that branch is to be ignored
208                                 if (iSize == 0) { }
209                                 else if ((rcSize == 0) || (lcSize == 0)) { }
210                                 //if you have more groups than either of your kids then theres been a change.
211                                 else if(iSize > rcSize || iSize > lcSize){
212                                         score++;
213                                 }
214                         } 
215                         
216                         results[count] = score;
217                         count++;
218                 }
219                                         
220                 delete copyTree;
221                         
222                 return results; 
223         }
224         catch(exception& e) {
225                 m->errorOut(e, "Parsimony", "driver");
226                 exit(1);
227         }
228 }
229
230 /**************************************************************************************************/
231