+}
+//**********************************************************************************************************************
+#ifdef USE_MPI
+int AlignCommand::driverMPI(int start, int num, MPI_File& inMPI, MPI_File& alignFile, MPI_File& reportFile, MPI_File& accnosFile, vector<long>& MPIPos){
+ try {
+ string outputString = "";
+ MPI_Status statusReport;
+ MPI_Status statusAlign;
+ MPI_Status statusAccnos;
+ MPI_Status status;
+ int pid;
+ MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
+
+ NastReport report;
+
+ if (pid == 0) {
+ outputString = report.getHeaders();
+ int length = outputString.length();
+ char buf[length];
+ strcpy(buf, outputString.c_str());
+
+ MPI_File_write_shared(reportFile, buf, length, MPI_CHAR, &statusReport);
+ }
+
+ for(int i=0;i<num;i++){
+
+ if (m->control_pressed) { return 0; }
+
+ //read next sequence
+ int length = MPIPos[start+i+1] - MPIPos[start+i];
+ char buf4[length];
+ MPI_File_read_at(inMPI, MPIPos[start+i], buf4, length, MPI_CHAR, &status);
+
+ string tempBuf = buf4;
+ if (tempBuf.length() > length) { tempBuf = tempBuf.substr(0, length); }
+ istringstream iss (tempBuf,istringstream::in);
+
+ Sequence* candidateSeq = new Sequence(iss);
+ int origNumBases = candidateSeq->getNumBases();
+ string originalUnaligned = candidateSeq->getUnaligned();
+ int numBasesNeeded = origNumBases * threshold;
+
+ if (candidateSeq->getName() != "") { //incase there is a commented sequence at the end of a file
+ if (candidateSeq->getUnaligned().length() > alignment->getnRows()) {
+ alignment->resize(candidateSeq->getUnaligned().length()+1);
+ }
+
+ Sequence temp = templateDB->findClosestSequence(candidateSeq);
+ Sequence* templateSeq = &temp;
+
+ float searchScore = templateDB->getSearchScore();
+
+ Nast* nast = new Nast(alignment, candidateSeq, templateSeq);
+ Sequence* copy;
+
+ Nast* nast2;
+ bool needToDeleteCopy = false; //this is needed in case you have you enter the ifs below
+ //since nast does not make a copy of hte sequence passed, and it is used by the reporter below
+ //you can't delete the copy sequence til after you report, but you may choose not to create it in the first place
+ //so this bool tells you if you need to delete it
+
+ //if there is a possibility that this sequence should be reversed
+ if (candidateSeq->getNumBases() < numBasesNeeded) {
+
+ string wasBetter = "";
+ //if the user wants you to try the reverse
+ if (flip) {
+ //get reverse compliment
+ copy = new Sequence(candidateSeq->getName(), originalUnaligned);
+ copy->reverseComplement();
+
+ //rerun alignment
+ Sequence temp2 = templateDB->findClosestSequence(copy);
+ Sequence* templateSeq2 = &temp2;
+
+ searchScore = templateDB->getSearchScore();
+
+ nast2 = new Nast(alignment, copy, templateSeq2);
+
+ //check if any better
+ if (copy->getNumBases() > candidateSeq->getNumBases()) {
+ candidateSeq->setAligned(copy->getAligned()); //use reverse compliments alignment since its better
+ templateSeq = templateSeq2;
+ delete nast;
+ nast = nast2;
+ needToDeleteCopy = true;
+ }else{
+ wasBetter = "\treverse complement did NOT produce a better alignment, please check sequence.";
+ delete nast2;
+ delete copy;
+ }
+ }
+
+ //create accnos file with names
+ outputString = candidateSeq->getName() + wasBetter + "\n";
+
+ //send results to parent
+ int length = outputString.length();
+ char buf[length];
+ strcpy(buf, outputString.c_str());
+
+ MPI_File_write_shared(accnosFile, buf, length, MPI_CHAR, &statusAccnos);
+ MPIWroteAccnos = true;
+ }
+
+ report.setCandidate(candidateSeq);
+ report.setTemplate(templateSeq);
+ report.setSearchParameters(search, searchScore);
+ report.setAlignmentParameters(align, alignment);
+ report.setNastParameters(*nast);
+
+ outputString = ">" + candidateSeq->getName() + "\n" + candidateSeq->getAligned() + "\n";
+
+ //send results to parent
+ int length = outputString.length();
+ char buf2[length];
+ strcpy(buf2, outputString.c_str());
+
+ MPI_File_write_shared(alignFile, buf2, length, MPI_CHAR, &statusAlign);
+
+ outputString = report.getReport();
+
+ //send results to parent
+ length = outputString.length();
+ char buf3[length];
+ strcpy(buf3, outputString.c_str());
+
+ MPI_File_write_shared(reportFile, buf3, length, MPI_CHAR, &statusReport);
+
+ delete nast;
+ if (needToDeleteCopy) { delete copy; }
+ }
+ delete candidateSeq;
+
+ //report progress
+ if((i+1) % 100 == 0){ cout << (toString(i+1)) << endl; }
+ }
+ //report progress
+ if((num) % 100 != 0){ cout << (toString(num)) << endl; }
+
+ return 1;
+ }
+ catch(exception& e) {
+ m->errorOut(e, "AlignCommand", "driverMPI");
+ exit(1);
+ }
+}
+#endif
+/**************************************************************************************************/
+
+int AlignCommand::createProcesses(string alignFileName, string reportFileName, string accnosFName, string filename) {
+ try {
+#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
+ int process = 0;
+ int exitCommand = 1;
+ // processIDS.resize(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){
+ exitCommand = driver(lines[process], alignFileName + toString(getpid()) + ".temp", reportFileName + toString(getpid()) + ".temp", accnosFName + toString(getpid()) + ".temp", filename);
+ exit(0);
+ }else { m->mothurOut("unable to spawn the necessary processes."); m->mothurOutEndLine(); exit(0); }
+ }
+
+ //force parent to wait until all the processes are done
+ for (int i=0;i<processors;i++) {
+ int temp = processIDS[i];
+ wait(&temp);
+ }
+
+ return exitCommand;
+#endif
+ }
+ catch(exception& e) {
+ m->errorOut(e, "AlignCommand", "createProcesses");
+ exit(1);
+ }
+}
+
+/**************************************************************************************************/
+
+void AlignCommand::appendAlignFiles(string temp, string filename) {
+ try{
+
+ ofstream output;
+ ifstream input;
+ openOutputFileAppend(filename, output);
+ openInputFile(temp, input);
+
+ while(char c = input.get()){
+ if(input.eof()) { break; }
+ else { output << c; }
+ }
+
+ input.close();
+ output.close();
+ }
+ catch(exception& e) {
+ m->errorOut(e, "AlignCommand", "appendAlignFiles");