+int PhyloDiversityCommand::createProcesses(vector<int>& procIters, Tree* t, map< string, vector<float> >& div, map<string, vector<float> >& sumDiv, int numIters, int increment, vector<int>& randomLeaf, set<int>& numSampledList, ofstream& outCollect, ofstream& outSum){
+ try {
+ #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
+ int process = 1;
+
+ vector<int> processIDS;
+ map< string, vector<float> >::iterator itSum;
+
+ //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, div, sumDiv, procIters[process], increment, randomLeaf, numSampledList, outCollect, outSum, false);
+
+ string outTemp = outputDir + toString(getpid()) + ".sumDiv.temp";
+ ofstream out;
+ m->openOutputFile(outTemp, out);
+
+ //output the sumDIversity
+ for (itSum = sumDiv.begin(); itSum != sumDiv.end(); itSum++) {
+ out << itSum->first << '\t' << (itSum->second).size() << '\t';
+ for (int k = 0; k < (itSum->second).size(); k++) {
+ out << (itSum->second)[k] << '\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, div, sumDiv, procIters[0], increment, randomLeaf, numSampledList, outCollect, outSum, true);
+
+ //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++) {
+
+ //input the sumDIversity
+ string inTemp = outputDir + toString(processIDS[i]) + ".sumDiv.temp";
+ ifstream in;
+ m->openInputFile(inTemp, in);
+
+ //output the sumDIversity
+ for (int j = 0; j < sumDiv.size(); j++) {
+ string group = "";
+ int size = 0;
+
+ in >> group >> size; m->gobble(in);
+
+ for (int k = 0; k < size; k++) {
+ float tempVal;
+ in >> tempVal;
+
+ sumDiv[group][k] += tempVal;
+ }
+ m->gobble(in);
+ }
+
+ in.close();
+ m->mothurRemove(inTemp);
+ }
+
+#endif
+
+ return 0;
+
+ }
+ catch(exception& e) {
+ m->errorOut(e, "PhyloDiversityCommand", "createProcesses");
+ exit(1);
+ }
+}
+//**********************************************************************************************************************
+int PhyloDiversityCommand::driver(Tree* t, map< string, vector<float> >& div, map<string, vector<float> >& sumDiv, int numIters, int increment, vector<int>& randomLeaf, set<int>& numSampledList, ofstream& outCollect, ofstream& outSum, bool doSumCollect){
+ try {
+ int numLeafNodes = randomLeaf.size();
+ vector<string> mGroups = m->getGroups();
+
+ for (int l = 0; l < numIters; l++) {
+ random_shuffle(randomLeaf.begin(), randomLeaf.end());
+
+ //initialize counts
+ map<string, int> counts;
+ map< string, set<int> > countedBranch;
+ for (int j = 0; j < mGroups.size(); j++) { counts[mGroups[j]] = 0; countedBranch[mGroups[j]].insert(-2); } //add dummy index to initialize countedBranch sets
+
+ for(int k = 0; k < numLeafNodes; k++){
+
+ if (m->control_pressed) { return 0; }
+
+ //calc branch length of randomLeaf k
+ vector<float> br = calcBranchLength(t, randomLeaf[k], countedBranch);
+
+ //for each group in the groups update the total branch length accounting for the names file
+ vector<string> groups = t->tree[randomLeaf[k]].getGroup();
+
+ for (int j = 0; j < groups.size(); j++) {
+ int numSeqsInGroupJ = 0;
+ map<string, int>::iterator it;
+ it = t->tree[randomLeaf[k]].pcount.find(groups[j]);
+ if (it != t->tree[randomLeaf[k]].pcount.end()) { //this leaf node contains seqs from group j
+ numSeqsInGroupJ = it->second;
+ }
+
+ if (numSeqsInGroupJ != 0) { div[groups[j]][(counts[groups[j]]+1)] = div[groups[j]][counts[groups[j]]] + br[j]; }
+
+ for (int s = (counts[groups[j]]+2); s <= (counts[groups[j]]+numSeqsInGroupJ); s++) {
+ div[groups[j]][s] = div[groups[j]][s-1]; //update counts, but don't add in redundant branch lengths
+ }
+ counts[groups[j]] += numSeqsInGroupJ;
+ }
+ }
+
+ if (rarefy) {
+ //add this diversity to the sum
+ for (int j = 0; j < mGroups.size(); j++) {
+ for (int g = 0; g < div[mGroups[j]].size(); g++) {
+ sumDiv[mGroups[j]][g] += div[mGroups[j]][g];
+ }
+ }
+ }
+
+ if ((collect) && (l == 0) && doSumCollect) { printData(numSampledList, div, outCollect, 1); }
+ if ((summary) && (l == 0) && doSumCollect) { printSumData(div, outSum, 1); }
+ }
+
+ return 0;
+
+ }
+ catch(exception& e) {
+ m->errorOut(e, "PhyloDiversityCommand", "driver");
+ exit(1);
+ }
+}
+
+//**********************************************************************************************************************
+
+void PhyloDiversityCommand::printSumData(map< string, vector<float> >& div, ofstream& out, int numIters){
+ try {
+
+ out << "Groups\tnumSampled\tphyloDiversity" << endl;
+
+ out.setf(ios::fixed, ios::floatfield); out.setf(ios::showpoint);
+
+ vector<string> mGroups = m->getGroups();
+ for (int j = 0; j < mGroups.size(); j++) {
+ int numSampled = (div[mGroups[j]].size()-1);
+ out << mGroups[j] << '\t' << numSampled << '\t';
+
+
+ float score;
+ if (scale) { score = (div[mGroups[j]][numSampled] / (float)numIters) / (float)numSampled; }
+ else { score = div[mGroups[j]][numSampled] / (float)numIters; }
+
+ out << setprecision(4) << score << endl;
+ }
+
+ out.close();
+
+ }
+ catch(exception& e) {
+ m->errorOut(e, "PhyloDiversityCommand", "printSumData");
+ exit(1);
+ }
+}
+//**********************************************************************************************************************