+/**************************************************************************************************/
+
+int UnifracWeightedCommand::createProcesses(Tree* t, vector< vector<string> > namesOfGroupCombos, vector< vector<double> >& scores) {
+ try {
+#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
+ int process = 1;
+ vector<int> processIDS;
+
+ EstOutput results;
+
+ //loop through and create all the processes you want
+ while (process != processors) {
+ int pid = fork();
+
+ if (pid > 0) {
+ processIDS.push_back(pid); //create map from line number to pid so you can append files in correct order later
+ process++;
+ }else if (pid == 0){
+ driver(t, namesOfGroupCombos, lines[process].start, lines[process].num, scores);
+
+ //pass numSeqs to parent
+ ofstream out;
+ string tempFile = outputDir + toString(getpid()) + ".weightedcommand.results.temp";
+ m->openOutputFile(tempFile, out);
+ for (int i = lines[process].start; i < (lines[process].start + lines[process].num); i++) { out << scores[i][(scores[i].size()-1)] << '\t'; } out << endl;
+ out.close();
+
+ exit(0);
+ }else {
+ m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine();
+ for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
+ exit(0);
+ }
+ }
+
+ driver(t, namesOfGroupCombos, lines[0].start, lines[0].num, scores);
+
+ //force parent to wait until all the processes are done
+ for (int i=0;i<(processors-1);i++) {
+ int temp = processIDS[i];
+ wait(&temp);
+ }
+
+ //get data created by processes
+ for (int i=0;i<(processors-1);i++) {
+
+ ifstream in;
+ string s = outputDir + toString(processIDS[i]) + ".weightedcommand.results.temp";
+ m->openInputFile(s, in);
+
+ double tempScore;
+ for (int j = lines[(i+1)].start; j < (lines[(i+1)].start + lines[(i+1)].num); j++) { in >> tempScore; scores[j].push_back(tempScore); }
+ in.close();
+ remove(s.c_str());
+ }
+
+ return 0;
+#endif
+ }
+ catch(exception& e) {
+ m->errorOut(e, "UnifracWeightedCommand", "createProcesses");
+ exit(1);
+ }
+}
+
+/**************************************************************************************************/
+int UnifracWeightedCommand::driver(Tree* t, vector< vector<string> > namesOfGroupCombos, int start, int num, vector< vector<double> >& scores) {
+ try {
+ Tree* randT = new Tree();
+
+ for (int h = start; h < (start+num); h++) {
+
+ if (m->control_pressed) { return 0; }
+
+ //initialize weighted score
+ string groupA = namesOfGroupCombos[h][0];
+ string groupB = namesOfGroupCombos[h][1];
+
+ //copy T[i]'s info.
+ randT->getCopy(t);
+
+ //create a random tree with same topology as T[i], but different labels
+ randT->assembleRandomUnifracTree(groupA, groupB);
+
+ if (m->control_pressed) { delete randT; return 0; }
+
+ //get wscore of random tree
+ EstOutput randomData = weighted->getValues(randT, groupA, groupB);
+
+ if (m->control_pressed) { delete randT; return 0; }
+
+ //save scores
+ scores[h].push_back(randomData[0]);
+ }
+
+ delete randT;
+
+ return 0;
+
+ }
+ catch(exception& e) {
+ m->errorOut(e, "UnifracWeightedCommand", "driver");
+ exit(1);
+ }
+}