2 * chimeracheckcommand.cpp
5 * Created by westcott on 3/31/10.
6 * Copyright 2010 Schloss Lab. All rights reserved.
10 #include "chimeracheckcommand.h"
11 #include "referencedb.h"
13 //**********************************************************************************************************************
14 vector<string> ChimeraCheckCommand::setParameters(){
16 CommandParameter ptemplate("reference", "InputTypes", "", "", "none", "none", "none","",false,true,true); parameters.push_back(ptemplate);
17 CommandParameter pfasta("fasta", "InputTypes", "", "", "none", "none", "none","chimera",false,true,true); parameters.push_back(pfasta);
18 CommandParameter pname("name", "InputTypes", "", "", "none", "none", "none","",false,false,true); parameters.push_back(pname);
19 CommandParameter psvg("svg", "Boolean", "", "F", "", "", "","",false,false); parameters.push_back(psvg);
20 CommandParameter pincrement("increment", "Number", "", "10", "", "", "","",false,false); parameters.push_back(pincrement);
21 CommandParameter pksize("ksize", "Number", "", "7", "", "", "","",false,false); parameters.push_back(pksize);
22 CommandParameter pprocessors("processors", "Number", "", "1", "", "", "","",false,false,true); parameters.push_back(pprocessors);
23 CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
24 CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);
25 CommandParameter psave("save", "Boolean", "", "F", "", "", "","",false,false); parameters.push_back(psave);
27 vector<string> myArray;
28 for (int i = 0; i < parameters.size(); i++) { myArray.push_back(parameters[i].name); }
32 m->errorOut(e, "ChimeraCheckCommand", "setParameters");
36 //**********************************************************************************************************************
37 string ChimeraCheckCommand::getHelpString(){
39 string helpString = "";
40 helpString += "The chimera.check command reads a fastafile and referencefile and outputs potentially chimeric sequences.\n";
41 helpString += "This command was created using the algorythms described in CHIMERA_CHECK version 2.7 written by Niels Larsen. \n";
42 helpString += "The chimera.check command parameters are fasta, reference, processors, ksize, increment, svg and name.\n";
43 helpString += "The fasta parameter allows you to enter the fasta file containing your potentially chimeric sequences, and is required unless you have a valid current fasta file. \n";
44 helpString += "You may enter multiple fasta files by separating their names with dashes. ie. fasta=abrecovery.fasta-amzon.fasta \n";
45 helpString += "The reference parameter allows you to enter a reference file containing known non-chimeric sequences, and is required. \n";
46 helpString += "The processors parameter allows you to specify how many processors you would like to use. The default is 1. \n";
48 helpString += "When using MPI, the processors parameter is set to the number of MPI processes running. \n";
50 helpString += "The increment parameter allows you to specify how far you move each window while finding chimeric sequences, default is 10.\n";
51 helpString += "The ksize parameter allows you to input kmersize, default is 7. \n";
52 helpString += "The svg parameter allows you to specify whether or not you would like a svg file outputted for each query sequence, default is False.\n";
53 helpString += "The name parameter allows you to enter a file containing names of sequences you would like .svg files for.\n";
54 helpString += "You may enter multiple name files by separating their names with dashes. ie. fasta=abrecovery.svg.names-amzon.svg.names \n";
55 helpString += "If the save parameter is set to true the reference sequences will be saved in memory, to clear them later you can use the clear.memory command. Default=f.";
56 helpString += "The chimera.check command should be in the following format: \n";
57 helpString += "chimera.check(fasta=yourFastaFile, reference=yourTemplateFile, processors=yourProcessors, ksize=yourKmerSize) \n";
58 helpString += "Example: chimera.check(fasta=AD.fasta, reference=core_set_aligned,imputed.fasta, processors=4, ksize=8) \n";
59 helpString += "Note: No spaces between parameter labels (i.e. fasta), '=' and parameters (i.e.yourFastaFile).\n";
63 m->errorOut(e, "ChimeraCheckCommand", "getHelpString");
67 //**********************************************************************************************************************
68 string ChimeraCheckCommand::getOutputPattern(string type) {
72 if (type == "chimera") { pattern = "[filename],chimeracheck.chimeras"; }
73 else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true; }
78 m->errorOut(e, "ChimeraCheckCommand", "getOutputPattern");
82 //**********************************************************************************************************************
83 ChimeraCheckCommand::ChimeraCheckCommand(){
85 abort = true; calledHelp = true;
87 vector<string> tempOutNames;
88 outputTypes["chimera"] = tempOutNames;
91 m->errorOut(e, "ChimeraCheckCommand", "ChimeraCheckCommand");
95 //***************************************************************************************************************
96 ChimeraCheckCommand::ChimeraCheckCommand(string option) {
98 abort = false; calledHelp = false;
99 ReferenceDB* rdb = ReferenceDB::getInstance();
101 //allow user to run help
102 if(option == "help") { help(); abort = true; calledHelp = true; }
103 else if(option == "citation") { citation(); abort = true; calledHelp = true;}
106 vector<string> myArray = setParameters();
108 OptionParser parser(option);
109 map<string,string> parameters = parser.getParameters();
111 ValidParameters validParameter("chimera.check");
112 map<string,string>::iterator it;
114 //check to make sure all parameters are valid for command
115 for (it = parameters.begin(); it != parameters.end(); it++) {
116 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) { abort = true; }
119 vector<string> tempOutNames;
120 outputTypes["chimera"] = tempOutNames;
122 //if the user changes the input directory command factory will send this info to us in the output parameter
123 string inputDir = validParameter.validFile(parameters, "inputdir", false);
124 if (inputDir == "not found"){ inputDir = ""; }
126 it = parameters.find("reference");
127 //user has given a template file
128 if(it != parameters.end()){
129 string path = m->hasPath(it->second);
130 //if the user has not given a path then, add inputdir. else leave path alone.
131 if (path == "") { parameters["reference"] = inputDir + it->second; }
135 //check for required parameters
136 fastafile = validParameter.validFile(parameters, "fasta", false);
137 if (fastafile == "not found") {
138 //if there is a current fasta file, use it
139 string filename = m->getFastaFile();
140 if (filename != "") { fastaFileNames.push_back(filename); m->mothurOut("Using " + filename + " as input file for the fasta parameter."); m->mothurOutEndLine(); }
141 else { m->mothurOut("You have no current fastafile and the fasta parameter is required."); m->mothurOutEndLine(); abort = true; }
143 m->splitAtDash(fastafile, fastaFileNames);
145 //go through files and make sure they are good, if not, then disregard them
146 for (int i = 0; i < fastaFileNames.size(); i++) {
149 if (fastaFileNames[i] == "current") {
150 fastaFileNames[i] = m->getFastaFile();
151 if (fastaFileNames[i] != "") { m->mothurOut("Using " + fastaFileNames[i] + " as input file for the fasta parameter where you had given current."); m->mothurOutEndLine(); }
153 m->mothurOut("You have no current fastafile, ignoring current."); m->mothurOutEndLine(); ignore=true;
154 //erase from file list
155 fastaFileNames.erase(fastaFileNames.begin()+i);
163 if (inputDir != "") {
164 string path = m->hasPath(fastaFileNames[i]);
165 //if the user has not given a path then, add inputdir. else leave path alone.
166 if (path == "") { fastaFileNames[i] = inputDir + fastaFileNames[i]; }
172 ableToOpen = m->openInputFile(fastaFileNames[i], in, "noerror");
174 //if you can't open it, try default location
175 if (ableToOpen == 1) {
176 if (m->getDefaultPath() != "") { //default path is set
177 string tryPath = m->getDefaultPath() + m->getSimpleName(fastaFileNames[i]);
178 m->mothurOut("Unable to open " + fastaFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();
180 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
182 fastaFileNames[i] = tryPath;
186 //if you can't open it, try default location
187 if (ableToOpen == 1) {
188 if (m->getOutputDir() != "") { //default path is set
189 string tryPath = m->getOutputDir() + m->getSimpleName(fastaFileNames[i]);
190 m->mothurOut("Unable to open " + fastaFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();
192 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
194 fastaFileNames[i] = tryPath;
200 if (ableToOpen == 1) {
201 m->mothurOut("Unable to open " + fastaFileNames[i] +". It will be disregarded."); m->mothurOutEndLine();
202 //erase from file list
203 fastaFileNames.erase(fastaFileNames.begin()+i);
206 m->setFastaFile(fastaFileNames[i]);
211 //make sure there is at least one valid file left
212 if (fastaFileNames.size() == 0) { m->mothurOut("no valid files."); m->mothurOutEndLine(); abort = true; }
215 //if the user changes the output directory command factory will send this info to us in the output parameter
216 outputDir = validParameter.validFile(parameters, "outputdir", false); if (outputDir == "not found"){ outputDir = ""; }
218 namefile = validParameter.validFile(parameters, "name", false);
219 if (namefile == "not found") { namefile = ""; }
221 m->splitAtDash(namefile, nameFileNames);
223 //go through files and make sure they are good, if not, then disregard them
224 for (int i = 0; i < nameFileNames.size(); i++) {
227 if (nameFileNames[i] == "current") {
228 nameFileNames[i] = m->getNameFile();
229 if (nameFileNames[i] != "") { m->mothurOut("Using " + nameFileNames[i] + " as input file for the name parameter where you had given current."); m->mothurOutEndLine(); }
231 m->mothurOut("You have no current namefile, ignoring current."); m->mothurOutEndLine(); ignore=true;
232 //erase from file list
233 nameFileNames.erase(nameFileNames.begin()+i);
240 if (inputDir != "") {
241 string path = m->hasPath(nameFileNames[i]);
242 //if the user has not given a path then, add inputdir. else leave path alone.
243 if (path == "") { nameFileNames[i] = inputDir + nameFileNames[i]; }
249 ableToOpen = m->openInputFile(nameFileNames[i], in, "noerror");
251 //if you can't open it, try default location
252 if (ableToOpen == 1) {
253 if (m->getDefaultPath() != "") { //default path is set
254 string tryPath = m->getDefaultPath() + m->getSimpleName(nameFileNames[i]);
255 m->mothurOut("Unable to open " + nameFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();
257 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
259 nameFileNames[i] = tryPath;
263 //if you can't open it, try default location
264 if (ableToOpen == 1) {
265 if (m->getOutputDir() != "") { //default path is set
266 string tryPath = m->getOutputDir() + m->getSimpleName(nameFileNames[i]);
267 m->mothurOut("Unable to open " + nameFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();
269 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
271 nameFileNames[i] = tryPath;
277 if (ableToOpen == 1) {
278 m->mothurOut("Unable to open " + nameFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine();
279 //erase from file list
280 nameFileNames.erase(nameFileNames.begin()+i);
283 m->setNameFile(nameFileNames[i]);
288 //make sure there is at least one valid file left
289 if (nameFileNames.size() != 0) {
290 if (nameFileNames.size() != fastaFileNames.size()) {
291 m->mothurOut("Different number of valid name files and fasta files, aborting command."); m->mothurOutEndLine();
297 string temp = validParameter.validFile(parameters, "processors", false); if (temp == "not found"){ temp = m->getProcessors(); }
298 m->setProcessors(temp);
299 m->mothurConvert(temp, processors);
301 temp = validParameter.validFile(parameters, "save", false); if (temp == "not found"){ temp = "f"; }
302 save = m->isTrue(temp);
304 if (save) { //clear out old references
308 //this has to go after save so that if the user sets save=t and provides no reference we abort
309 templatefile = validParameter.validFile(parameters, "reference", true);
310 if (templatefile == "not found") {
311 //check for saved reference sequences
312 if (rdb->referenceSeqs.size() != 0) {
313 templatefile = "saved";
315 m->mothurOut("[ERROR]: You don't have any saved reference sequences and the reference parameter is a required.");
316 m->mothurOutEndLine();
319 }else if (templatefile == "not open") { abort = true; }
320 else { if (save) { rdb->setSavedReference(templatefile); } }
323 temp = validParameter.validFile(parameters, "ksize", false); if (temp == "not found") { temp = "7"; }
324 m->mothurConvert(temp, ksize);
326 temp = validParameter.validFile(parameters, "svg", false); if (temp == "not found") { temp = "F"; }
327 svg = m->isTrue(temp);
328 if (nameFileNames.size() != 0) { svg = true; }
330 temp = validParameter.validFile(parameters, "increment", false); if (temp == "not found") { temp = "10"; }
331 m->mothurConvert(temp, increment);
334 catch(exception& e) {
335 m->errorOut(e, "ChimeraCheckCommand", "ChimeraCheckCommand");
339 //***************************************************************************************************************
341 int ChimeraCheckCommand::execute(){
344 if (abort == true) { if (calledHelp) { return 0; } return 2; }
346 for (int i = 0; i < fastaFileNames.size(); i++) {
348 m->mothurOut("Checking sequences from " + fastaFileNames[i] + " ..." ); m->mothurOutEndLine();
350 int start = time(NULL);
352 string thisNameFile = "";
353 if (nameFileNames.size() != 0) { thisNameFile = nameFileNames[i]; }
355 chimera = new ChimeraCheckRDP(fastaFileNames[i], templatefile, thisNameFile, svg, increment, ksize, outputDir);
357 if (m->control_pressed) { delete chimera; return 0; }
359 if (outputDir == "") { outputDir = m->hasPath(fastaFileNames[i]); }//if user entered a file with a path then preserve it
360 map<string, string> variables;
361 variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(fastaFileNames[i]));
362 string outputFileName = getOutputFileName("chimera", variables);
363 outputNames.push_back(outputFileName); outputTypes["chimera"].push_back(outputFileName);
367 int pid, numSeqsPerProcessor;
369 vector<unsigned long long> MPIPos;
372 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
373 MPI_Comm_size(MPI_COMM_WORLD, &processors);
378 int outMode=MPI_MODE_CREATE|MPI_MODE_WRONLY;
379 int inMode=MPI_MODE_RDONLY;
381 char outFilename[1024];
382 strcpy(outFilename, outputFileName.c_str());
384 char inFileName[1024];
385 strcpy(inFileName, fastaFileNames[i].c_str());
387 MPI_File_open(MPI_COMM_WORLD, inFileName, inMode, MPI_INFO_NULL, &inMPI); //comm, filename, mode, info, filepointer
388 MPI_File_open(MPI_COMM_WORLD, outFilename, outMode, MPI_INFO_NULL, &outMPI);
390 if (m->control_pressed) { MPI_File_close(&inMPI); MPI_File_close(&outMPI); for (int j = 0; j < outputNames.size(); j++) { m->mothurRemove(outputNames[j]); } outputTypes.clear(); delete chimera; return 0; }
392 if (pid == 0) { //you are the root process
393 MPIPos = m->setFilePosFasta(fastaFileNames[i], numSeqs); //fills MPIPos, returns numSeqs
395 //send file positions to all processes
396 for(int j = 1; j < processors; j++) {
397 MPI_Send(&numSeqs, 1, MPI_INT, j, tag, MPI_COMM_WORLD);
398 MPI_Send(&MPIPos[0], (numSeqs+1), MPI_LONG, j, tag, MPI_COMM_WORLD);
401 //figure out how many sequences you have to align
402 numSeqsPerProcessor = numSeqs / processors;
403 int startIndex = pid * numSeqsPerProcessor;
404 if(pid == (processors - 1)){ numSeqsPerProcessor = numSeqs - pid * numSeqsPerProcessor; }
408 driverMPI(startIndex, numSeqsPerProcessor, inMPI, outMPI, MPIPos);
410 if (m->control_pressed) { MPI_File_close(&inMPI); MPI_File_close(&outMPI); for (int j = 0; j < outputNames.size(); j++) { m->mothurRemove(outputNames[j]); } outputTypes.clear(); delete chimera; return 0; }
413 for(int j = 1; j < processors; j++) {
415 MPI_Recv(buf, 5, MPI_CHAR, j, tag, MPI_COMM_WORLD, &status);
417 }else{ //you are a child process
418 MPI_Recv(&numSeqs, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
419 MPIPos.resize(numSeqs+1);
420 MPI_Recv(&MPIPos[0], (numSeqs+1), MPI_LONG, 0, tag, MPI_COMM_WORLD, &status);
422 //figure out how many sequences you have to align
423 numSeqsPerProcessor = numSeqs / processors;
424 int startIndex = pid * numSeqsPerProcessor;
425 if(pid == (processors - 1)){ numSeqsPerProcessor = numSeqs - pid * numSeqsPerProcessor; }
428 driverMPI(startIndex, numSeqsPerProcessor, inMPI, outMPI, MPIPos);
430 if (m->control_pressed) { MPI_File_close(&inMPI); MPI_File_close(&outMPI); for (int j = 0; j < outputNames.size(); j++) { m->mothurRemove(outputNames[j]); } outputTypes.clear(); delete chimera; return 0; }
432 //tell parent you are done.
435 MPI_Send(buf, 5, MPI_CHAR, 0, tag, MPI_COMM_WORLD);
439 MPI_File_close(&inMPI);
440 MPI_File_close(&outMPI);
441 MPI_Barrier(MPI_COMM_WORLD); //make everyone wait - just in case
447 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
448 vector<unsigned long long> positions = m->divideFile(fastaFileNames[i], processors);
450 for (int s = 0; s < (positions.size()-1); s++) {
451 lines.push_back(new linePair(positions[s], positions[(s+1)]));
455 numSeqs = driver(lines[0], outputFileName, fastaFileNames[i]);
457 if (m->control_pressed) { for (int j = 0; j < outputNames.size(); j++) { m->mothurRemove(outputNames[j]); } for (int j = 0; j < lines.size(); j++) { delete lines[j]; } outputTypes.clear(); lines.clear(); delete chimera; return 0; }
460 processIDS.resize(0);
462 numSeqs = createProcesses(outputFileName, fastaFileNames[i]);
464 rename((outputFileName + toString(processIDS[0]) + ".temp").c_str(), outputFileName.c_str());
466 //append output files
467 for(int j=1;j<processors;j++){
468 m->appendFiles((outputFileName + toString(processIDS[j]) + ".temp"), outputFileName);
469 m->mothurRemove((outputFileName + toString(processIDS[j]) + ".temp"));
472 if (m->control_pressed) {
473 for (int j = 0; j < outputNames.size(); j++) { m->mothurRemove(outputNames[j]); } outputTypes.clear();
474 for (int j = 0; j < lines.size(); j++) { delete lines[j]; } lines.clear();
481 lines.push_back(new linePair(0, 1000));
482 numSeqs = driver(lines[0], outputFileName, fastaFileNames[i]);
484 if (m->control_pressed) { for (int j = 0; j < lines.size(); j++) { delete lines[j]; } lines.clear(); for (int j = 0; j < outputNames.size(); j++) { m->mothurRemove(outputNames[j]); } outputTypes.clear(); delete chimera; return 0; }
488 for (int j = 0; j < lines.size(); j++) { delete lines[j]; } lines.clear();
490 m->mothurOutEndLine(); m->mothurOut("This method does not determine if a sequence is chimeric, but allows you to make that determination based on the IS values."); m->mothurOutEndLine();
491 m->mothurOutEndLine(); m->mothurOut("It took " + toString(time(NULL) - start) + " secs to check " + toString(numSeqs) + " sequences."); m->mothurOutEndLine(); m->mothurOutEndLine();
495 m->mothurOutEndLine();
496 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
497 for (int i = 0; i < outputNames.size(); i++) { m->mothurOut(outputNames[i]); m->mothurOutEndLine(); }
498 m->mothurOutEndLine();
503 catch(exception& e) {
504 m->errorOut(e, "ChimeraCheckCommand", "execute");
508 //**********************************************************************************************************************
510 int ChimeraCheckCommand::driver(linePair* filePos, string outputFName, string filename){
513 m->openOutputFile(outputFName, out);
518 m->openInputFile(filename, inFASTA);
520 inFASTA.seekg(filePos->start);
527 if (m->control_pressed) { return 1; }
529 Sequence* candidateSeq = new Sequence(inFASTA); m->gobble(inFASTA);
531 if (candidateSeq->getName() != "") { //incase there is a commented sequence at the end of a file
533 chimera->getChimeras(candidateSeq);
535 if (m->control_pressed) { delete candidateSeq; return 1; }
538 chimera->print(out, out2);
542 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
543 unsigned long long pos = inFASTA.tellg();
544 if ((pos == -1) || (pos >= filePos->end)) { break; }
546 if (inFASTA.eof()) { break; }
550 if((count) % 100 == 0){ m->mothurOut("Processing sequence: " + toString(count)); m->mothurOutEndLine(); }
554 if((count) % 100 != 0){ m->mothurOut("Processing sequence: " + toString(count)); m->mothurOutEndLine(); }
561 catch(exception& e) {
562 m->errorOut(e, "ChimeraCheckCommand", "driver");
566 //**********************************************************************************************************************
568 int ChimeraCheckCommand::driverMPI(int start, int num, MPI_File& inMPI, MPI_File& outMPI, vector<unsigned long long>& MPIPos){
573 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
575 for(int i=0;i<num;i++){
577 if (m->control_pressed) { return 0; }
580 int length = MPIPos[start+i+1] - MPIPos[start+i];
582 char* buf4 = new char[length];
583 MPI_File_read_at(inMPI, MPIPos[start+i], buf4, length, MPI_CHAR, &status);
585 string tempBuf = buf4;
586 if (tempBuf.length() > length) { tempBuf = tempBuf.substr(0, length); }
587 istringstream iss (tempBuf,istringstream::in);
590 Sequence* candidateSeq = new Sequence(iss); m->gobble(iss);
592 if (candidateSeq->getName() != "") { //incase there is a commented sequence at the end of a file
594 chimera->getChimeras(candidateSeq);
597 chimera->print(outMPI, outAccMPI);
602 if((i+1) % 100 == 0){ cout << "Processing sequence: " << (i+1) << endl; m->mothurOutJustToLog("Processing sequence: " + toString(i+1) + "\n"); }
605 if(num % 100 != 0){ cout << "Processing sequence: " << num << endl; m->mothurOutJustToLog("Processing sequence: " + toString(num) + "\n"); }
609 catch(exception& e) {
610 m->errorOut(e, "ChimeraCheckCommand", "driverMPI");
616 /**************************************************************************************************/
618 int ChimeraCheckCommand::createProcesses(string outputFileName, string filename) {
620 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
624 //loop through and create all the processes you want
625 while (process != processors) {
629 processIDS.push_back(pid); //create map from line number to pid so you can append files in correct order later
632 num = driver(lines[process], outputFileName + toString(getpid()) + ".temp", filename);
634 //pass numSeqs to parent
636 string tempFile = outputFileName + toString(getpid()) + ".num.temp";
637 m->openOutputFile(tempFile, out);
643 m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine();
644 for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
649 //force parent to wait until all the processes are done
650 for (int i=0;i<processors;i++) {
651 int temp = processIDS[i];
655 for (int i = 0; i < processIDS.size(); i++) {
657 string tempFile = outputFileName + toString(processIDS[i]) + ".num.temp";
658 m->openInputFile(tempFile, in);
659 if (!in.eof()) { int tempNum = 0; in >> tempNum; num += tempNum; }
660 in.close(); m->mothurRemove(tempFile);
666 catch(exception& e) {
667 m->errorOut(e, "ChimeraCheckCommand", "createProcesses");
671 /**************************************************************************************************/