]> git.donarmstrong.com Git - mothur.git/blob - unweighted.cpp
removed various build warnings
[mothur.git] / unweighted.cpp
1 /*
2  *  unweighted.cpp
3  *  Mothur
4  *
5  *  Created by Sarah Westcott on 2/9/09.
6  *  Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
7  *
8  */
9
10 #include "unweighted.h"
11
12 /**************************************************************************************************/
13
14 EstOutput Unweighted::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 = 0; l < r; l++) {
28                                 numComp++;
29                                 vector<string> groups; groups.push_back(globaldata->Groups[r]); groups.push_back(globaldata->Groups[l]);
30                                 namesOfGroupCombos.push_back(groups);
31                         }
32                 }
33                 
34                 if (numComp != 1) {
35                         vector<string> groups;
36                         if (numGroups == 0) {
37                                 //get score for all users groups
38                                 for (int i = 0; i < tmap->namesOfGroups.size(); i++) {
39                                         if (tmap->namesOfGroups[i] != "xxx") {
40                                                 groups.push_back(tmap->namesOfGroups[i]);
41                                         }
42                                 }
43                                 namesOfGroupCombos.push_back(groups);
44                         }else {
45                                 for (int i = 0; i < globaldata->Groups.size(); i++) {
46                                         groups.push_back(globaldata->Groups[i]);
47                                 }
48                                 namesOfGroupCombos.push_back(groups);
49                         }
50                 }
51
52                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
53                         if(processors == 1){
54                                 data = driver(t, namesOfGroupCombos, 0, namesOfGroupCombos.size());
55                         }else{
56                                 int numPairs = namesOfGroupCombos.size();
57                                 
58                                 int numPairsPerProcessor = numPairs / processors;
59                                 
60                                 for (int i = 0; i < processors; i++) {
61                                         int startPos = i * numPairsPerProcessor;
62                         
63                                         if(i == processors - 1){
64                                                 numPairsPerProcessor = numPairs - i * numPairsPerProcessor;
65                                         }
66                 
67                                         lines.push_back(linePair(startPos, numPairsPerProcessor));
68                                 }
69
70                                 data = createProcesses(t, namesOfGroupCombos);
71                                 lines.clear();
72                         }
73                 #else
74                         data = driver(t, namesOfGroupCombos, 0, namesOfGroupCombos.size());
75                 #endif
76                 
77                 return data;
78         }
79         catch(exception& e) {
80                 m->errorOut(e, "Unweighted", "getValues");
81                 exit(1);
82         }
83 }
84 /**************************************************************************************************/
85
86 EstOutput Unweighted::createProcesses(Tree* t, vector< vector<string> > namesOfGroupCombos) {
87         try {
88 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
89                 int process = 1;
90                 vector<int> processIDS;
91                 
92                 EstOutput results;
93                 
94                 //loop through and create all the processes you want
95                 while (process != processors) {
96                         int pid = fork();
97                         
98                         if (pid > 0) {
99                                 processIDS.push_back(pid);  //create map from line number to pid so you can append files in correct order later
100                                 process++;
101                         }else if (pid == 0){
102                                 EstOutput myresults;
103                                 myresults = driver(t, namesOfGroupCombos, lines[process].start, lines[process].num);
104                                 
105                                 if (m->control_pressed) { exit(0); }
106                                 
107                                 m->mothurOut("Merging results."); m->mothurOutEndLine();
108                                 
109                                 //pass numSeqs to parent
110                                 ofstream out;
111                                 string tempFile = outputDir + toString(getpid()) + ".unweighted.results.temp";
112                                 m->openOutputFile(tempFile, out);
113                                 out << myresults.size() << endl;
114                                 for (int i = 0; i < myresults.size(); i++) {  out << myresults[i] << '\t';  } out << endl;
115                                 out.close();
116                                 
117                                 exit(0);
118                         }else { 
119                                 m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
120                                 for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
121                                 exit(0); 
122                         }
123                 }
124                 
125                 results = driver(t, namesOfGroupCombos, lines[0].start, lines[0].num);
126                 
127                 //force parent to wait until all the processes are done
128                 for (int i=0;i<(processors-1);i++) { 
129                         int temp = processIDS[i];
130                         wait(&temp);
131                 }
132                 
133                 if (m->control_pressed) { return results; }
134                 
135                 //get data created by processes
136                 for (int i=0;i<(processors-1);i++) { 
137                         ifstream in;
138                         string s = outputDir + toString(processIDS[i]) + ".unweighted.results.temp";
139                         m->openInputFile(s, in);
140                         
141                         //get quantiles
142                         if (!in.eof()) {
143                                 int num;
144                                 in >> num; m->gobble(in);
145                                 
146                                 if (m->control_pressed) { break; }
147                                 
148                                 double w; 
149                                 for (int j = 0; j < num; j++) {
150                                         in >> w;
151                                         results.push_back(w);
152                                 }
153                                 m->gobble(in);
154                         }
155                         in.close();
156                         remove(s.c_str());
157                 }
158                 
159                 m->mothurOut("DONE."); m->mothurOutEndLine(); m->mothurOutEndLine();
160                 
161                 return results;
162 #endif          
163         }
164         catch(exception& e) {
165                 m->errorOut(e, "Unweighted", "createProcesses");
166                 exit(1);
167         }
168 }
169 /**************************************************************************************************/
170 EstOutput Unweighted::driver(Tree* t, vector< vector<string> > namesOfGroupCombos, int start, int num) { 
171  try {
172                 
173                 EstOutput results; results.resize(num);
174                 
175                 int count = 0;
176                 int numLeaves = t->getNumLeaves();
177                 int total = num;
178                 int twentyPercent = (total * 0.20);
179                 if (twentyPercent == 0) { twentyPercent = 1; }
180                 
181                 
182                 for (int h = start; h < (start+num); h++) {
183         //cout << namesOfGroupCombos[h][0] << '\t' << namesOfGroupCombos[h][1] << endl;         
184                         if (m->control_pressed) { return results; }
185                 
186                         double UniqueBL=0.0000;  //a branch length is unique if it's chidren are from the same group
187                         double totalBL = 0.00;  //all branch lengths
188                         double UW = 0.00;               //Unweighted Value = UniqueBL / totalBL;
189                         map<int, double> tempTotals; //maps node to total Branch Length
190                         map<int, int> nodePcountSize; //maps node to pcountSize
191                         map<int, int>::iterator itCount;
192                                 
193                         for(int i=0;i<t->getNumNodes();i++){
194                         
195                                 if (m->control_pressed) {  return data; }
196                                 
197                                 //pcountSize = 0, they are from a branch that is entirely from a group the user doesn't want
198                                 //pcountSize = 2, not unique to one group
199                                 //pcountSize = 1, unique to one group
200                                 
201                                 int pcountSize = 0;
202                                 for (int j = 0; j < namesOfGroupCombos[h].size(); j++) {
203                                         map<string, int>::iterator itGroup = t->tree[i].pcount.find(namesOfGroupCombos[h][j]);
204                                         if (itGroup != t->tree[i].pcount.end()) { pcountSize++; if (pcountSize > 1) { break; } } 
205                                 }
206
207                                 nodePcountSize[i] = pcountSize;
208                                 
209                                 //cout << i << '\t' << t->tree[i].getName() << " br = " << abs(t->tree[i].getBranchLength()) << '\t';           
210                                 if (pcountSize == 0) { }
211                                 else if ((t->tree[i].getBranchLength() != -1) && (pcountSize == 1)) {  UniqueBL += abs(t->tree[i].getBranchLength()); }
212                                 
213                                 //if you are a leaf from a users group add to total
214                                 if (i < numLeaves) {
215                                         if ((t->tree[i].getBranchLength() != -1) && pcountSize != 0) { 
216                                         //cout << "added to total" << endl; 
217                                                 totalBL += abs(t->tree[i].getBranchLength()); 
218                                         }
219                                         tempTotals[i] = 0.0;  //we don't care about you, or we have already added you
220                                 }else{ //if you are not a leaf 
221                                         //do both your chidren have have descendants from the users groups? 
222                                         int lc = t->tree[i].getLChild();
223                                         int rc = t->tree[i].getRChild();
224                                         
225                                         //if yes, add your childrens tempTotals
226                                         if ((nodePcountSize[lc] != 0) && (nodePcountSize[rc] != 0)) {
227                                                 totalBL += tempTotals[lc] + tempTotals[rc]; 
228                                                 //cout << "added to total " << tempTotals[lc] << '\t' << tempTotals[rc] << endl;
229                                                 if (t->tree[i].getBranchLength() != -1) {
230                                                         tempTotals[i] = abs(t->tree[i].getBranchLength());
231                                                 }else {
232                                                         tempTotals[i] = 0.0;
233                                                 }
234                                         }else if ((nodePcountSize[lc] == 0) && (nodePcountSize[rc] == 0)) { tempTotals[i] = 0.0;  //we don't care about you
235                                         }else { //if no, your tempTotal is your childrens temp totals + your branch length
236                                                 tempTotals[i] = tempTotals[lc] + tempTotals[rc] + abs(t->tree[i].getBranchLength()); 
237                                         }
238                                         //cout << "temptotal = "<< tempTotals[i] << endl;
239                                 }
240
241                         }
242         //cout << UniqueBL << '\t' << totalBL << endl;          
243                         UW = (UniqueBL / totalBL);  
244         
245                         if (isnan(UW) || isinf(UW)) { UW = 0; }
246         
247                         results[count] = UW;
248                         count++;
249
250                         //report progress
251                         if((count % twentyPercent) == 0) {      float tempOut = (count / (float)total); if (isnan(tempOut) || isinf(tempOut)) { tempOut = 0.0; } m->mothurOut("Percentage complete: " + toString((int(tempOut) * 100.0))); m->mothurOutEndLine();       }
252                 }
253                 
254                 //report progress
255                 if((count % twentyPercent) != 0) {      float tempOut = (count / (float)total); if (isnan(tempOut) || isinf(tempOut)) { tempOut = 0.0; } m->mothurOut("Percentage complete: " + toString((int(tempOut) * 100.0))); m->mothurOutEndLine();       }
256                 
257                 return results; 
258         }
259         catch(exception& e) {
260                 m->errorOut(e, "Unweighted", "driver");
261                 exit(1);
262         }
263 }
264 /**************************************************************************************************/
265
266 EstOutput Unweighted::getValues(Tree* t, string groupA, string groupB, int p, string o) { 
267  try {
268                 globaldata = GlobalData::getInstance();
269                 processors = p;
270                 outputDir = o;
271                 
272                 
273                 //if the users enters no groups then give them the score of all groups
274                 int numGroups = globaldata->Groups.size();
275                 
276                 //calculate number of comparsions
277                 int numComp = 0;
278                 vector< vector<string> > namesOfGroupCombos;
279                 for (int r=0; r<numGroups; r++) { 
280                         for (int l = 0; l < r; l++) {
281                                 numComp++;
282                                 vector<string> groups; groups.push_back(globaldata->Groups[r]); groups.push_back(globaldata->Groups[l]);
283                                 namesOfGroupCombos.push_back(groups);
284                         }
285                 }
286                 
287                 if (numComp != 1) {
288                         vector<string> groups;
289                         if (numGroups == 0) {
290                                 //get score for all users groups
291                                 for (int i = 0; i < tmap->namesOfGroups.size(); i++) {
292                                         if (tmap->namesOfGroups[i] != "xxx") {
293                                                 groups.push_back(tmap->namesOfGroups[i]);
294                                         }
295                                 }
296                                 namesOfGroupCombos.push_back(groups);
297                         }else {
298                                 for (int i = 0; i < globaldata->Groups.size(); i++) {
299                                         groups.push_back(globaldata->Groups[i]);
300                                 }
301                                 namesOfGroupCombos.push_back(groups);
302                         }
303                 }
304
305                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
306                         if(processors == 1){
307                                 data = driver(t, namesOfGroupCombos, 0, namesOfGroupCombos.size(), true);
308                         }else{
309                                 int numPairs = namesOfGroupCombos.size();
310                                 
311                                 int numPairsPerProcessor = numPairs / processors;
312                                 
313                                 for (int i = 0; i < processors; i++) {
314                                         int startPos = i * numPairsPerProcessor;
315                                         if(i == processors - 1){
316                                                 numPairsPerProcessor = numPairs - i * numPairsPerProcessor;
317                                         }
318                                         lines.push_back(linePair(startPos, numPairsPerProcessor));
319                                 }
320
321                                 data = createProcesses(t, namesOfGroupCombos, true);
322                                 
323                                 lines.clear();
324                         }
325                 #else
326                         data = driver(t, namesOfGroupCombos, 0, namesOfGroupCombos.size(), true);
327                 #endif
328         
329                 return data;
330         }
331         catch(exception& e) {
332                 m->errorOut(e, "Unweighted", "getValues");
333                 exit(1);
334         }
335 }
336 /**************************************************************************************************/
337
338 EstOutput Unweighted::createProcesses(Tree* t, vector< vector<string> > namesOfGroupCombos, bool usingGroups) {
339         try {
340 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
341                 int process = 1;
342                 vector<int> processIDS;
343                 
344                 EstOutput results;
345                 
346                 //loop through and create all the processes you want
347                 while (process != processors) {
348                         int pid = fork();
349                         
350                         if (pid > 0) {
351                                 processIDS.push_back(pid);  //create map from line number to pid so you can append files in correct order later
352                                 process++;
353                         }else if (pid == 0){
354                                 EstOutput myresults;
355                                 myresults = driver(t, namesOfGroupCombos, lines[process].start, lines[process].num, usingGroups);
356                                 
357                                 if (m->control_pressed) { exit(0); }
358                                 
359                                 //pass numSeqs to parent
360                                 ofstream out;
361                                 string tempFile = outputDir + toString(getpid()) + ".unweighted.results.temp";
362                                 m->openOutputFile(tempFile, out);
363                                 out << myresults.size() << endl;
364                                 for (int i = 0; i < myresults.size(); i++) {  out << myresults[i] << '\t';  } out << endl;
365                                 out.close();
366                                 
367                                 exit(0);
368                         }else { 
369                                 m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
370                                 for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
371                                 exit(0); 
372                         }
373                 }
374                 
375                 results = driver(t, namesOfGroupCombos, lines[0].start, lines[0].num, usingGroups);
376                 
377                 //force parent to wait until all the processes are done
378                 for (int i=0;i<(processors-1);i++) { 
379                         int temp = processIDS[i];
380                         wait(&temp);
381                 }
382                 
383                 if (m->control_pressed) { return results; }
384                 
385                 //get data created by processes
386                 for (int i=0;i<(processors-1);i++) { 
387                         ifstream in;
388                         string s = outputDir + toString(processIDS[i]) + ".unweighted.results.temp";
389                         m->openInputFile(s, in);
390                         
391                         //get quantiles
392                         if (!in.eof()) {
393                                 int num;
394                                 in >> num; m->gobble(in);
395                                 
396                                 if (m->control_pressed) { break; }
397                                 
398                                 double w; 
399                                 for (int j = 0; j < num; j++) {
400                                         in >> w;
401                                         results.push_back(w);
402                                 }
403                                 m->gobble(in);
404                         }
405                         in.close();
406                         remove(s.c_str());
407                 }
408                 
409                 return results;
410 #endif          
411         }
412         catch(exception& e) {
413                 m->errorOut(e, "Unweighted", "createProcesses");
414                 exit(1);
415         }
416 }
417 /**************************************************************************************************/
418 EstOutput Unweighted::driver(Tree* t, vector< vector<string> > namesOfGroupCombos, int start, int num, bool usingGroups) { 
419  try {
420                 
421                 EstOutput results; results.resize(num);
422                 
423                 int count = 0;
424                 int numLeaves = t->getNumLeaves();
425                 
426                 Tree* copyTree = new Tree;
427                 
428                 for (int h = start; h < (start+num); h++) {
429                 
430                         if (m->control_pressed) { return results; }
431                 
432                         //copy random tree passed in
433                         copyTree->getCopy(t);
434                                 
435                         //swap labels in the groups you want to compare
436                         copyTree->assembleRandomUnifracTree(namesOfGroupCombos[h]);
437                         
438                         double UniqueBL=0.0000;  //a branch length is unique if it's chidren are from the same group
439                         double totalBL = 0.00;  //all branch lengths
440                         double UW = 0.00;               //Unweighted Value = UniqueBL / totalBL;
441                         map<int, double> tempTotals; //maps node to total Branch Length
442                         map<int, int> nodePcountSize; //maps node to pcountSize
443                                 
444                         for(int i=0;i<copyTree->getNumNodes();i++){
445                         
446                                 if (m->control_pressed) {  return data; }
447                                 
448                                 //pcountSize = 0, they are from a branch that is entirely from a group the user doesn't want
449                                 //pcountSize = 2, not unique to one group
450                                 //pcountSize = 1, unique to one group
451                                 
452                                 int pcountSize = 0;
453                                 for (int j = 0; j < namesOfGroupCombos[h].size(); j++) {
454                                         map<string, int>::iterator itGroup = copyTree->tree[i].pcount.find(namesOfGroupCombos[h][j]);
455                                         if (itGroup != copyTree->tree[i].pcount.end()) { pcountSize++; if (pcountSize > 1) { break; } } 
456                                 }
457                                 
458                                 nodePcountSize[i] = pcountSize;
459                         
460                                 if (pcountSize == 0) { }
461                                 else if ((copyTree->tree[i].getBranchLength() != -1) && (pcountSize == 1)) {  UniqueBL += abs(copyTree->tree[i].getBranchLength());      }
462                                 
463                                 //if you are a leaf from a users group add to total
464                                 if (i < numLeaves) {
465                                         if ((copyTree->tree[i].getBranchLength() != -1) && pcountSize != 0) { 
466                                                 totalBL += abs(copyTree->tree[i].getBranchLength()); 
467                                         }
468                                         tempTotals[i] = 0.0;  //we don't care about you, or we have already added you
469                                 }else{ //if you are not a leaf 
470                                         //do both your chidren have have descendants from the users groups? 
471                                         int lc = copyTree->tree[i].getLChild();
472                                         int rc = copyTree->tree[i].getRChild();
473                                         
474                                         //if yes, add your childrens tempTotals
475                                         if ((nodePcountSize[lc] != 0) && (nodePcountSize[rc] != 0)) {
476                                                 totalBL += tempTotals[lc] + tempTotals[rc]; 
477                                                 
478                                                 if (copyTree->tree[i].getBranchLength() != -1) {
479                                                         tempTotals[i] = abs(copyTree->tree[i].getBranchLength());
480                                                 }else {
481                                                         tempTotals[i] = 0.0;
482                                                 }
483                                         }else if ((nodePcountSize[lc] == 0) && (nodePcountSize[rc] == 0)) { tempTotals[i] = 0.0;  //we don't care about you
484                                         }else { //if no, your tempTotal is your childrens temp totals + your branch length
485                                                 tempTotals[i] = tempTotals[lc] + tempTotals[rc] + abs(copyTree->tree[i].getBranchLength()); 
486                                         }
487                                         
488                                 }
489
490                         }
491                 
492                         UW = (UniqueBL / totalBL);  
493         
494                         if (isnan(UW) || isinf(UW)) { UW = 0; }
495         
496                         results[count] = UW;
497                         count++;
498
499                 }
500                 
501                 delete copyTree;
502                 
503                 return results; 
504         }
505         catch(exception& e) {
506                 m->errorOut(e, "Unweighted", "driver");
507                 exit(1);
508         }
509 }
510 /**************************************************************************************************/
511
512