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