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