+}
+//**********************************************************************************************************************
+vector<float> IndicatorCommand::driver(vector< vector<SharedRAbundFloatVector*> >& groupings, map< vector<int>, vector<int> > groupingsMap, int num, vector<float> indicatorValues, int numIters){
+ try {
+ vector<float> pvalues;
+ pvalues.resize(indicatorValues.size(), 0);
+ vector<string> notUsedGroupings; //we dont care about the grouping for the pvalues since they are randomized, but we need to pass the function something to make it work.
+
+ for(int i=0;i<numIters;i++){
+ if (m->control_pressed) { break; }
+ groupingsMap = randomizeGroupings(groupings, num);
+ vector<float> randomIndicatorValues = getValues(groupings, notUsedGroupings, groupingsMap);
+
+ for (int j = 0; j < indicatorValues.size(); j++) {
+ if (randomIndicatorValues[j] >= indicatorValues[j]) { pvalues[j]++; }
+ }
+ }
+
+ return pvalues;
+
+ }catch(exception& e) {
+ m->errorOut(e, "IndicatorCommand", "driver");
+ exit(1);
+ }
+}
+//**********************************************************************************************************************
+vector<float> IndicatorCommand::getPValues(vector< vector<SharedRAbundFloatVector*> >& groupings, map< vector<int>, vector<int> > groupingsMap, int num, vector<float> indicatorValues){
+ try {
+ vector<float> pvalues;
+
+#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
+ if(processors == 1){
+ pvalues = driver(groupings, groupingsMap, num, indicatorValues, iters);
+ for (int i = 0; i < pvalues.size(); i++) { pvalues[i] /= (double)iters; }
+ }else{
+
+ //divide iters between processors
+ int numItersPerProcessor = iters / processors;
+
+ vector<int> processIDS;
+ int process = 1;
+ int num = 0;
+
+ //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){
+ pvalues = driver(groupings, groupingsMap, num, indicatorValues, numItersPerProcessor);
+
+ //pass pvalues to parent
+ ofstream out;
+ string tempFile = toString(getpid()) + ".pvalues.temp";
+ m->openOutputFile(tempFile, out);
+
+ //pass values
+ for (int i = 0; i < pvalues.size(); i++) {
+ out << pvalues[i] << '\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);
+ }
+ }
+
+ //do my part
+ //special case for last processor in case it doesn't divide evenly
+ numItersPerProcessor = iters - ((processors-1) * numItersPerProcessor);
+ pvalues = driver(groupings, groupingsMap, num, indicatorValues, numItersPerProcessor);
+
+ //force parent to wait until all the processes are done
+ for (int i=0;i<processIDS.size();i++) {
+ int temp = processIDS[i];
+ wait(&temp);
+ }
+
+ //combine results
+ for (int i = 0; i < processIDS.size(); i++) {
+ ifstream in;
+ string tempFile = toString(processIDS[i]) + ".pvalues.temp";
+ m->openInputFile(tempFile, in);
+
+ ////// to do ///////////
+ int numTemp; numTemp = 0;
+ for (int j = 0; j < pvalues.size(); j++) {
+ in >> numTemp; m->gobble(in);
+ pvalues[j] += numTemp;
+ }
+ in.close(); m->mothurRemove(tempFile);
+ }
+ for (int i = 0; i < pvalues.size(); i++) { pvalues[i] /= (double)iters; }
+ }
+#else
+ pvalues = driver(groupings, groupingsMap, num, indicatorValues, iters);
+ for (int i = 0; i < pvalues.size(); i++) { pvalues[i] /= (double)iters; }
+#endif
+
+ return pvalues;
+ }
+ catch(exception& e) {
+ m->errorOut(e, "IndicatorCommand", "getPValues");
+ exit(1);
+ }
+}
+
+//**********************************************************************************************************************
+//same as above, just data type difference
+vector<float> IndicatorCommand::driver(vector< vector<SharedRAbundVector*> >& groupings, map< vector<int>, vector<int> > groupingsMap, int num, vector<float> indicatorValues, int numIters){
+ try {
+ vector<float> pvalues;
+ pvalues.resize(indicatorValues.size(), 0);
+ vector<string> notUsedGroupings; //we dont care about the grouping for the pvalues since they are randomized, but we need to pass the function something to make it work.
+
+ for(int i=0;i<numIters;i++){
+ if (m->control_pressed) { break; }
+ groupingsMap = randomizeGroupings(groupings, num);
+ vector<float> randomIndicatorValues = getValues(groupings, notUsedGroupings, groupingsMap);
+
+ for (int j = 0; j < indicatorValues.size(); j++) {
+ if (randomIndicatorValues[j] >= indicatorValues[j]) { pvalues[j]++; }
+ }
+ }
+
+ return pvalues;
+
+ }catch(exception& e) {
+ m->errorOut(e, "IndicatorCommand", "driver");
+ exit(1);
+ }
+}
+//**********************************************************************************************************************
+//same as above, just data type difference
+vector<float> IndicatorCommand::getPValues(vector< vector<SharedRAbundVector*> >& groupings, map< vector<int>, vector<int> > groupingsMap, int num, vector<float> indicatorValues){
+ try {
+ vector<float> pvalues;
+
+#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
+ if(processors == 1){
+ pvalues = driver(groupings, groupingsMap, num, indicatorValues, iters);
+ for (int i = 0; i < pvalues.size(); i++) { pvalues[i] /= (double)iters; }
+ }else{
+
+ //divide iters between processors
+ int numItersPerProcessor = iters / processors;
+
+ vector<int> processIDS;
+ int process = 1;
+
+ //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){
+ pvalues = driver(groupings, groupingsMap, num, indicatorValues, numItersPerProcessor);
+
+ //pass pvalues to parent
+ ofstream out;
+ string tempFile = toString(getpid()) + ".pvalues.temp";
+ m->openOutputFile(tempFile, out);
+
+ //pass values
+ for (int i = 0; i < pvalues.size(); i++) {
+ out << pvalues[i] << '\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);
+ }
+ }
+
+ //do my part
+ //special case for last processor in case it doesn't divide evenly
+ numItersPerProcessor = iters - ((processors-1) * numItersPerProcessor);
+ pvalues = driver(groupings, groupingsMap, num, indicatorValues, numItersPerProcessor);
+
+ //force parent to wait until all the processes are done
+ for (int i=0;i<processIDS.size();i++) {
+ int temp = processIDS[i];
+ wait(&temp);
+ }
+
+ //combine results
+ for (int i = 0; i < processIDS.size(); i++) {
+ ifstream in;
+ string tempFile = toString(processIDS[i]) + ".pvalues.temp";
+ m->openInputFile(tempFile, in);
+
+ ////// to do ///////////
+ int numTemp; numTemp = 0;
+ for (int j = 0; j < pvalues.size(); j++) {
+ in >> numTemp; m->gobble(in);
+ pvalues[j] += numTemp;
+ }
+ in.close(); m->mothurRemove(tempFile);
+ }
+ for (int i = 0; i < pvalues.size(); i++) { pvalues[i] /= (double)iters; }
+ }
+#else
+ pvalues = driver(groupings, groupingsMap, num, indicatorValues, iters);
+ for (int i = 0; i < pvalues.size(); i++) { pvalues[i] /= (double)iters; }
+#endif
+
+ return pvalues;
+ }
+ catch(exception& e) {
+ m->errorOut(e, "IndicatorCommand", "getPValues");
+ exit(1);
+ }
+}
+//**********************************************************************************************************************
+//swap groups between groupings, in essence randomizing the second column of the design file
+map< vector<int>, vector<int> > IndicatorCommand::randomizeGroupings(vector< vector<SharedRAbundVector*> >& groupings, int numLookupGroups){
+ try {
+
+ map< vector<int>, vector<int> > randomGroupings;
+
+ for (int i = 0; i < numLookupGroups; i++) {
+ if (m->control_pressed) {break;}
+
+ //get random groups to swap to switch with
+ //generate random int between 0 and groupings.size()-1
+ int z = m->getRandomIndex(groupings.size()-1);
+ int x = m->getRandomIndex(groupings.size()-1);
+ int a = m->getRandomIndex(groupings[z].size()-1);
+ int b = m->getRandomIndex(groupings[x].size()-1);
+ //cout << i << '\t' << z << '\t' << x << '\t' << a << '\t' << b << endl;
+ //if ((z < 0) || (z > 1) || x<0 || x>1 || a <0 || a>groupings[z].size()-1 || b<0 || b>groupings[x].size()-1) { cout << "probelm" << i << '\t' << z << '\t' << x << '\t' << a << '\t' << b << endl; }
+
+ vector<int> from;
+ vector<int> to;
+
+ from.push_back(z); from.push_back(a);
+ to.push_back(x); to.push_back(b);
+
+ randomGroupings[from] = to;
+ }
+ //cout << "done" << endl;
+ return randomGroupings;
+ }
+ catch(exception& e) {
+ m->errorOut(e, "IndicatorCommand", "randomizeGroupings");
+ exit(1);
+ }
+}
+//**********************************************************************************************************************
+//swap groups between groupings, in essence randomizing the second column of the design file
+map< vector<int>, vector<int> > IndicatorCommand::randomizeGroupings(vector< vector<SharedRAbundFloatVector*> >& groupings, int numLookupGroups){
+ try {
+
+ map< vector<int>, vector<int> > randomGroupings;
+
+ for (int i = 0; i < numLookupGroups; i++) {
+
+ //get random groups to swap to switch with
+ //generate random int between 0 and groupings.size()-1
+ int z = m->getRandomIndex(groupings.size()-1);
+ int x = m->getRandomIndex(groupings.size()-1);
+ int a = m->getRandomIndex(groupings[z].size()-1);
+ int b = m->getRandomIndex(groupings[x].size()-1);
+ //cout << i << '\t' << z << '\t' << x << '\t' << a << '\t' << b << endl;
+
+ vector<int> from;
+ vector<int> to;
+
+ from.push_back(z); from.push_back(a);
+ to.push_back(x); to.push_back(b);
+
+ randomGroupings[from] = to;
+ }
+
+ return randomGroupings;
+ }
+ catch(exception& e) {
+ m->errorOut(e, "IndicatorCommand", "randomizeGroupings");
+ exit(1);
+ }
+}
+