+
+ for (int s = 0; s < candidateFileNames.size(); s++) {
+ if (m->control_pressed) { outputTypes.clear(); return 0; }
+
+ m->mothurOut("Aligning sequences from " + candidateFileNames[s] + " ..." ); m->mothurOutEndLine();
+
+ if (outputDir == "") { outputDir += m->hasPath(candidateFileNames[s]); }
+ string alignFileName = outputDir + m->getRootName(m->getSimpleName(candidateFileNames[s])) + "align";
+ string reportFileName = outputDir + m->getRootName(m->getSimpleName(candidateFileNames[s])) + "align.report";
+ string accnosFileName = outputDir + m->getRootName(m->getSimpleName(candidateFileNames[s])) + "flip.accnos";
+ bool hasAccnos = true;
+
+ int numFastaSeqs = 0;
+ for (int i = 0; i < lines.size(); i++) { delete lines[i]; } lines.clear();
+ int start = time(NULL);
+
+#ifdef USE_MPI
+ int pid, numSeqsPerProcessor;
+ int tag = 2001;
+ vector<unsigned long int> MPIPos;
+ MPIWroteAccnos = false;
+
+ MPI_Status status;
+ MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
+ MPI_Comm_size(MPI_COMM_WORLD, &processors);
+
+ MPI_File inMPI;
+ MPI_File outMPIAlign;
+ MPI_File outMPIReport;
+ MPI_File outMPIAccnos;
+
+ int outMode=MPI_MODE_CREATE|MPI_MODE_WRONLY;
+ int inMode=MPI_MODE_RDONLY;
+
+ char outAlignFilename[1024];
+ strcpy(outAlignFilename, alignFileName.c_str());
+
+ char outReportFilename[1024];
+ strcpy(outReportFilename, reportFileName.c_str());
+
+ char outAccnosFilename[1024];
+ strcpy(outAccnosFilename, accnosFileName.c_str());
+
+ char inFileName[1024];
+ strcpy(inFileName, candidateFileNames[s].c_str());
+
+ MPI_File_open(MPI_COMM_WORLD, inFileName, inMode, MPI_INFO_NULL, &inMPI); //comm, filename, mode, info, filepointer
+ MPI_File_open(MPI_COMM_WORLD, outAlignFilename, outMode, MPI_INFO_NULL, &outMPIAlign);
+ MPI_File_open(MPI_COMM_WORLD, outReportFilename, outMode, MPI_INFO_NULL, &outMPIReport);
+ MPI_File_open(MPI_COMM_WORLD, outAccnosFilename, outMode, MPI_INFO_NULL, &outMPIAccnos);
+
+ if (m->control_pressed) { MPI_File_close(&inMPI); MPI_File_close(&outMPIAlign); MPI_File_close(&outMPIReport); MPI_File_close(&outMPIAccnos); outputTypes.clear(); return 0; }
+
+ if (pid == 0) { //you are the root process
+
+ MPIPos = m->setFilePosFasta(candidateFileNames[s], numFastaSeqs); //fills MPIPos, returns numSeqs
+
+ //send file positions to all processes
+ for(int i = 1; i < processors; i++) {
+ MPI_Send(&numFastaSeqs, 1, MPI_INT, i, tag, MPI_COMM_WORLD);
+ MPI_Send(&MPIPos[0], (numFastaSeqs+1), MPI_LONG, i, tag, MPI_COMM_WORLD);
+ }
+
+ //figure out how many sequences you have to align
+ numSeqsPerProcessor = numFastaSeqs / processors;
+ int startIndex = pid * numSeqsPerProcessor;
+ if(pid == (processors - 1)){ numSeqsPerProcessor = numFastaSeqs - pid * numSeqsPerProcessor; }
+
+ //align your part
+ driverMPI(startIndex, numSeqsPerProcessor, inMPI, outMPIAlign, outMPIReport, outMPIAccnos, MPIPos);
+
+ if (m->control_pressed) { MPI_File_close(&inMPI); MPI_File_close(&outMPIAlign); MPI_File_close(&outMPIReport); MPI_File_close(&outMPIAccnos); outputTypes.clear(); return 0; }
+
+ for (int i = 1; i < processors; i++) {
+ bool tempResult;
+ MPI_Recv(&tempResult, 1, MPI_INT, i, tag, MPI_COMM_WORLD, &status);
+ if (tempResult != 0) { MPIWroteAccnos = true; }
+ }
+ }else{ //you are a child process
+ MPI_Recv(&numFastaSeqs, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
+ MPIPos.resize(numFastaSeqs+1);
+ MPI_Recv(&MPIPos[0], (numFastaSeqs+1), MPI_LONG, 0, tag, MPI_COMM_WORLD, &status);
+
+
+ //figure out how many sequences you have to align
+ numSeqsPerProcessor = numFastaSeqs / processors;
+ int startIndex = pid * numSeqsPerProcessor;
+ if(pid == (processors - 1)){ numSeqsPerProcessor = numFastaSeqs - pid * numSeqsPerProcessor; }
+
+
+ //align your part
+ driverMPI(startIndex, numSeqsPerProcessor, inMPI, outMPIAlign, outMPIReport, outMPIAccnos, MPIPos);
+
+ if (m->control_pressed) { MPI_File_close(&inMPI); MPI_File_close(&outMPIAlign); MPI_File_close(&outMPIReport); MPI_File_close(&outMPIAccnos); outputTypes.clear(); return 0; }
+
+ MPI_Send(&MPIWroteAccnos, 1, MPI_INT, 0, tag, MPI_COMM_WORLD);
+ }
+
+ //close files
+ MPI_File_close(&inMPI);
+ MPI_File_close(&outMPIAlign);
+ MPI_File_close(&outMPIReport);
+ MPI_File_close(&outMPIAccnos);
+
+ //delete accnos file if blank
+ if (pid == 0) {
+ //delete accnos file if its blank else report to user
+ if (MPIWroteAccnos) {
+ m->mothurOut("Some of you sequences generated alignments that eliminated too many bases, a list is provided in " + accnosFileName + ".");
+ if (!flip) {
+ m->mothurOut(" If you set the flip parameter to true mothur will try aligning the reverse compliment as well.");
+ }else{ m->mothurOut(" If the reverse compliment proved to be better it was reported."); }
+ m->mothurOutEndLine();
+ }else {
+ //MPI_Info info;
+ //MPI_File_delete(outAccnosFilename, info);
+ hasAccnos = false;
+ remove(accnosFileName.c_str());
+ }
+ }
+
+#else
+
+ vector<unsigned long int> positions = m->divideFile(candidateFileNames[s], processors);
+ for (int i = 0; i < (positions.size()-1); i++) {
+ lines.push_back(new linePair(positions[i], positions[(i+1)]));
+ }
+ #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
+ if(processors == 1){
+ numFastaSeqs = driver(lines[0], alignFileName, reportFileName, accnosFileName, candidateFileNames[s]);
+
+ if (m->control_pressed) { remove(accnosFileName.c_str()); remove(alignFileName.c_str()); remove(reportFileName.c_str()); outputTypes.clear(); return 0; }
+
+ //delete accnos file if its blank else report to user
+ if (m->isBlank(accnosFileName)) { remove(accnosFileName.c_str()); hasAccnos = false; }
+ else {
+ m->mothurOut("Some of you sequences generated alignments that eliminated too many bases, a list is provided in " + accnosFileName + ".");
+ if (!flip) {
+ m->mothurOut(" If you set the flip parameter to true mothur will try aligning the reverse compliment as well.");
+ }else{ m->mothurOut(" If the reverse compliment proved to be better it was reported."); }
+ m->mothurOutEndLine();
+ }
+ }else{
+ processIDS.resize(0);
+
+ numFastaSeqs = createProcesses(alignFileName, reportFileName, accnosFileName, candidateFileNames[s]);
+
+ rename((alignFileName + toString(processIDS[0]) + ".temp").c_str(), alignFileName.c_str());
+ rename((reportFileName + toString(processIDS[0]) + ".temp").c_str(), reportFileName.c_str());
+
+ //append alignment and report files
+ for(int i=1;i<processors;i++){
+ appendAlignFiles((alignFileName + toString(processIDS[i]) + ".temp"), alignFileName);
+ remove((alignFileName + toString(processIDS[i]) + ".temp").c_str());
+
+ appendReportFiles((reportFileName + toString(processIDS[i]) + ".temp"), reportFileName);
+ remove((reportFileName + toString(processIDS[i]) + ".temp").c_str());
+ }
+
+ vector<string> nonBlankAccnosFiles;
+ //delete blank accnos files generated with multiple processes
+ for(int i=0;i<processors;i++){
+ if (!(m->isBlank(accnosFileName + toString(processIDS[i]) + ".temp"))) {
+ nonBlankAccnosFiles.push_back(accnosFileName + toString(processIDS[i]) + ".temp");
+ }else { remove((accnosFileName + toString(processIDS[i]) + ".temp").c_str()); }
+ }
+
+ //append accnos files
+ if (nonBlankAccnosFiles.size() != 0) {
+ rename(nonBlankAccnosFiles[0].c_str(), accnosFileName.c_str());
+
+ for (int h=1; h < nonBlankAccnosFiles.size(); h++) {
+ appendAlignFiles(nonBlankAccnosFiles[h], accnosFileName);
+ remove(nonBlankAccnosFiles[h].c_str());
+ }
+ m->mothurOut("Some of you sequences generated alignments that eliminated too many bases, a list is provided in " + accnosFileName + ".");
+ if (!flip) {
+ m->mothurOut(" If you set the flip parameter to true mothur will try aligning the reverse compliment as well.");
+ }else{ m->mothurOut(" If the reverse compliment proved to be better it was reported."); }
+ m->mothurOutEndLine();
+ }else{ hasAccnos = false; }
+
+ if (m->control_pressed) { remove(accnosFileName.c_str()); remove(alignFileName.c_str()); remove(reportFileName.c_str()); outputTypes.clear(); return 0; }
+ }
+ #else
+ numFastaSeqs = driver(lines[0], alignFileName, reportFileName, accnosFileName, candidateFileNames[s]);
+
+ if (m->control_pressed) { remove(accnosFileName.c_str()); remove(alignFileName.c_str()); remove(reportFileName.c_str()); outputTypes.clear(); return 0; }
+
+ //delete accnos file if its blank else report to user
+ if (m->isBlank(accnosFileName)) { remove(accnosFileName.c_str()); hasAccnos = false; }
+ else {
+ m->mothurOut("Some of you sequences generated alignments that eliminated too many bases, a list is provided in " + accnosFileName + ".");
+ if (!flip) {
+ m->mothurOut(" If you set the flip parameter to true mothur will try aligning the reverse compliment as well.");
+ }else{ m->mothurOut(" If the reverse compliment proved to be better it was reported."); }
+ m->mothurOutEndLine();
+ }
+
+ #endif
+
+#endif
+
+
+ #ifdef USE_MPI
+ MPI_Comm_rank(MPI_COMM_WORLD, &pid);
+
+ if (pid == 0) { //only one process should output to screen
+ #endif
+
+ outputNames.push_back(alignFileName); outputTypes["fasta"].push_back(alignFileName);
+ outputNames.push_back(reportFileName); outputTypes["alignreport"].push_back(reportFileName);
+ if (hasAccnos) { outputNames.push_back(accnosFileName); outputTypes["accnos"].push_back(accnosFileName); }
+
+ #ifdef USE_MPI
+ }
+ #endif
+
+ m->mothurOut("It took " + toString(time(NULL) - start) + " secs to align " + toString(numFastaSeqs) + " sequences.");
+ m->mothurOutEndLine();
+ m->mothurOutEndLine();