]> git.donarmstrong.com Git - mothur.git/blob - bayesian.cpp
Merge remote-tracking branch 'mothur/master'
[mothur.git] / bayesian.cpp
1 /*
2  *  bayesian.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 11/3/09.
6  *  Copyright 2009 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "bayesian.h"
11 #include "kmer.hpp"
12 #include "phylosummary.h"
13 #include "referencedb.h"
14 /**************************************************************************************************/
15 Bayesian::Bayesian(string tfile, string tempFile, string method, int ksize, int cutoff, int i, int tid, bool f) : 
16 Classify(), kmerSize(ksize), confidenceThreshold(cutoff), iters(i) {
17         try {
18                 ReferenceDB* rdb = ReferenceDB::getInstance();
19                 
20                 threadID = tid;
21                 flip = f;
22                 string baseName = tempFile;
23                         
24                 if (baseName == "saved") { baseName = rdb->getSavedReference(); }
25                 
26                 string baseTName = tfile;
27                 if (baseTName == "saved") { baseTName = rdb->getSavedTaxonomy(); }
28                 
29                 /************calculate the probablity that each word will be in a specific taxonomy*************/
30                 string tfileroot = baseTName.substr(0,baseTName.find_last_of(".")+1);
31                 string tempfileroot = m->getRootName(m->getSimpleName(baseName));
32                 string phyloTreeName = tfileroot + "tree.train";
33                 string phyloTreeSumName = tfileroot + "tree.sum";
34                 string probFileName = tfileroot + tempfileroot + char('0'+ kmerSize) + "mer.prob";
35                 string probFileName2 = tfileroot + tempfileroot + char('0'+ kmerSize) + "mer.numNonZero";
36                 
37                 ofstream out;
38                 ofstream out2;
39                 
40                 ifstream phyloTreeTest(phyloTreeName.c_str());
41                 ifstream probFileTest2(probFileName2.c_str());
42                 ifstream probFileTest(probFileName.c_str());
43                 ifstream probFileTest3(phyloTreeSumName.c_str());
44                 
45                 int start = time(NULL);
46                 
47                 //if they are there make sure they were created after this release date
48                 bool FilesGood = false;
49                 if(probFileTest && probFileTest2 && phyloTreeTest && probFileTest3){
50                         FilesGood = checkReleaseDate(probFileTest, probFileTest2, phyloTreeTest, probFileTest3);
51                 }
52                 
53                 //if you want to save, but you dont need to calculate then just read
54                 if (rdb->save && probFileTest && probFileTest2 && phyloTreeTest && probFileTest3 && FilesGood && (tempFile != "saved")) {  
55                         ifstream saveIn;
56                         m->openInputFile(tempFile, saveIn);
57                         
58                         while (!saveIn.eof()) {
59                                 Sequence temp(saveIn);
60                                 m->gobble(saveIn);
61                                 
62                                 rdb->referenceSeqs.push_back(temp); 
63                         }
64                         saveIn.close();                 
65                 }
66                 
67                 if(probFileTest && probFileTest2 && phyloTreeTest && probFileTest3 && FilesGood){       
68                         if (tempFile == "saved") { m->mothurOutEndLine();  m->mothurOut("Using sequences from " + rdb->getSavedReference() + " that are saved in memory.");     m->mothurOutEndLine(); }
69                         
70                         m->mothurOut("Reading template taxonomy...     "); cout.flush();
71                         
72                         phyloTree = new PhyloTree(phyloTreeTest, phyloTreeName);
73                         
74                         m->mothurOut("DONE."); m->mothurOutEndLine();
75                         
76                         genusNodes = phyloTree->getGenusNodes(); 
77                         genusTotals = phyloTree->getGenusTotals();
78                         
79                         if (tfile == "saved") { 
80                                 m->mothurOutEndLine();  m->mothurOut("Using probabilties from " + rdb->getSavedTaxonomy() + " that are saved in memory...    ");        cout.flush();; 
81                                 wordGenusProb = rdb->wordGenusProb;
82                                 WordPairDiffArr = rdb->WordPairDiffArr;
83                         }else {
84                                 m->mothurOut("Reading template probabilities...     "); cout.flush();
85                                 readProbFile(probFileTest, probFileTest2, probFileName, probFileName2);
86                         }       
87                         
88                         //save probabilities
89                         if (rdb->save) { rdb->wordGenusProb = wordGenusProb; rdb->WordPairDiffArr = WordPairDiffArr; }
90                 }else{
91                 
92                         //create search database and names vector
93                         generateDatabaseAndNames(tfile, tempFile, method, ksize, 0.0, 0.0, 0.0, 0.0);
94                         
95                         //prevents errors caused by creating shortcut files if you had an error in the sanity check.
96                         if (m->control_pressed) {  m->mothurRemove(phyloTreeName);  m->mothurRemove(probFileName); m->mothurRemove(probFileName2); }
97                         else{ 
98                                 genusNodes = phyloTree->getGenusNodes(); 
99                                 genusTotals = phyloTree->getGenusTotals();
100                                 
101                                 m->mothurOut("Calculating template taxonomy tree...     "); cout.flush();
102                                 
103                                 phyloTree->printTreeNodes(phyloTreeName);
104                                                         
105                                 m->mothurOut("DONE."); m->mothurOutEndLine();
106                                 
107                                 m->mothurOut("Calculating template probabilities...     "); cout.flush();
108                                 
109                                 numKmers = database->getMaxKmer() + 1;
110                         
111                                 //initialze probabilities
112                                 wordGenusProb.resize(numKmers);
113                                 WordPairDiffArr.resize(numKmers);
114                         
115                                 for (int j = 0; j < wordGenusProb.size(); j++) {        wordGenusProb[j].resize(genusNodes.size());             }
116                     ofstream out;
117                                 ofstream out2;
118                                 
119                                 #ifdef USE_MPI
120                                         int pid;
121                                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
122
123                                         if (pid == 0) {  
124                                 #endif
125
126                                 
127                                 m->openOutputFile(probFileName, out);
128                                 
129                                 //output mothur version
130                                 out << "#" << m->getVersion() << endl;
131                                 
132                                 out << numKmers << endl;
133                                 
134                                 m->openOutputFile(probFileName2, out2);
135                                 
136                                 //output mothur version
137                                 out2 << "#" << m->getVersion() << endl;
138                                 
139                                 #ifdef USE_MPI
140                                         }
141                                 #endif
142
143                                 
144                                 //for each word
145                                 for (int i = 0; i < numKmers; i++) {
146                                         if (m->control_pressed) {  break; }
147                                         
148                                         #ifdef USE_MPI
149                                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
150
151                                                 if (pid == 0) {  
152                                         #endif
153
154                                         out << i << '\t';
155                                         
156                                         #ifdef USE_MPI
157                                                 }
158                                         #endif
159                                         
160                                         vector<int> seqsWithWordi = database->getSequencesWithKmer(i);
161                                         
162                                         map<int, int> count;
163                                         for (int k = 0; k < genusNodes.size(); k++) {  count[genusNodes[k]] = 0;  }                     
164                                                         
165                                         //for each sequence with that word
166                                         for (int j = 0; j < seqsWithWordi.size(); j++) {
167                                                 int temp = phyloTree->getIndex(names[seqsWithWordi[j]]);
168                                                 count[temp]++;  //increment count of seq in this genus who have this word
169                                         }
170                                         
171                                         //probabilityInTemplate = (# of seqs with that word in template + 0.50) / (total number of seqs in template + 1);
172                                         float probabilityInTemplate = (seqsWithWordi.size() + 0.50) / (float) (names.size() + 1);
173                                         diffPair tempProb(log(probabilityInTemplate), 0.0);
174                                         WordPairDiffArr[i] = tempProb;
175                                                 
176                                         int numNotZero = 0;
177                                         for (int k = 0; k < genusNodes.size(); k++) {
178                                                 //probabilityInThisTaxonomy = (# of seqs with that word in this taxonomy + probabilityInTemplate) / (total number of seqs in this taxonomy + 1);
179                                                 
180                                                 
181                                                 wordGenusProb[i][k] = log((count[genusNodes[k]] + probabilityInTemplate) / (float) (genusTotals[k] + 1));  
182                                                                         
183                                                 if (count[genusNodes[k]] != 0) { 
184                                                         #ifdef USE_MPI
185                                                                 int pid;
186                                                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
187                                                 
188                                                                 if (pid == 0) {  
189                                                         #endif
190
191                                                         out << k << '\t' << wordGenusProb[i][k] << '\t' ; 
192                                                         
193                                                         #ifdef USE_MPI
194                                                                 }
195                                                         #endif
196
197                                                         numNotZero++;  
198                                                 }
199                                         }
200                                         
201                                         #ifdef USE_MPI
202                                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
203                                 
204                                                 if (pid == 0) {  
205                                         #endif
206                                         
207                                         out << endl;
208                                         out2 << probabilityInTemplate << '\t' << numNotZero << '\t' << log(probabilityInTemplate) << endl;
209                                         
210                                         #ifdef USE_MPI
211                                                 }
212                                         #endif
213                                 }
214                                 
215                                 #ifdef USE_MPI
216                                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
217                                 
218                                         if (pid == 0) {  
219                                 #endif
220                                 
221                                 out.close();
222                                 out2.close();
223                                 
224                                 #ifdef USE_MPI
225                                         }
226                                 #endif
227                                 
228                                 //read in new phylotree with less info. - its faster
229                                 ifstream phyloTreeTest(phyloTreeName.c_str());
230                                 delete phyloTree;
231                                 
232                                 phyloTree = new PhyloTree(phyloTreeTest, phyloTreeName);
233                                 
234                                 //save probabilities
235                                 if (rdb->save) { rdb->wordGenusProb = wordGenusProb; rdb->WordPairDiffArr = WordPairDiffArr; }
236                         }
237                 }
238                 
239                 generateWordPairDiffArr();
240                 
241                 //save probabilities
242                 if (rdb->save) { rdb->wordGenusProb = wordGenusProb; rdb->WordPairDiffArr = WordPairDiffArr; }
243                 
244                 m->mothurOut("DONE."); m->mothurOutEndLine();
245                 m->mothurOut("It took " + toString(time(NULL) - start) + " seconds get probabilities. "); m->mothurOutEndLine();
246         }
247         catch(exception& e) {
248                 m->errorOut(e, "Bayesian", "Bayesian");
249                 exit(1);
250         }
251 }
252 /**************************************************************************************************/
253 Bayesian::~Bayesian() {
254         try {
255                 
256                  delete phyloTree; 
257                  if (database != NULL) {  delete database; }
258         }
259         catch(exception& e) {
260                 m->errorOut(e, "Bayesian", "~Bayesian");
261                 exit(1);
262         }
263 }
264
265 /**************************************************************************************************/
266 string Bayesian::getTaxonomy(Sequence* seq) {
267         try {
268                 string tax = "";
269                 Kmer kmer(kmerSize);
270                 flipped = false;
271                 
272                 //get words contained in query
273                 //getKmerString returns a string where the index in the string is hte kmer number 
274                 //and the character at that index can be converted to be the number of times that kmer was seen
275                 string queryKmerString = kmer.getKmerString(seq->getUnaligned()); 
276                 
277                 vector<int> queryKmers;
278                 for (int i = 0; i < queryKmerString.length()-1; i++) {  // the -1 is to ignore any kmer with an N in it
279                         if (queryKmerString[i] != '!') { //this kmer is in the query
280                                 queryKmers.push_back(i);
281                         }
282                 }
283                 
284                 //if user wants to test reverse compliment and its reversed use that instead
285                 if (flip) {     
286                         if (isReversed(queryKmers)) { 
287                                 flipped = true;
288                                 seq->reverseComplement(); 
289                                 queryKmerString = kmer.getKmerString(seq->getUnaligned()); 
290                                 queryKmers.clear();
291                                 for (int i = 0; i < queryKmerString.length()-1; i++) {  // the -1 is to ignore any kmer with an N in it
292                                         if (queryKmerString[i] != '!') { //this kmer is in the query
293                                                 queryKmers.push_back(i);
294                                         }
295                                 }
296                         }  
297                 }
298                 
299                 if (queryKmers.size() == 0) {  m->mothurOut(seq->getName() + "is bad."); m->mothurOutEndLine(); simpleTax = "unknown;";  return "unknown;"; }
300                 
301                 
302                 int index = getMostProbableTaxonomy(queryKmers);
303                 
304                 if (m->control_pressed) { return tax; }
305                                         
306                 //bootstrap - to set confidenceScore
307                 int numToSelect = queryKmers.size() / 8;
308         
309                 tax = bootstrapResults(queryKmers, index, numToSelect);
310                 
311                 return tax;     
312         }
313         catch(exception& e) {
314                 m->errorOut(e, "Bayesian", "getTaxonomy");
315                 exit(1);
316         }
317 }
318 /**************************************************************************************************/
319 string Bayesian::bootstrapResults(vector<int> kmers, int tax, int numToSelect) {
320         try {
321                                 
322                 map<int, int> confidenceScores; 
323                 
324                 //initialize confidences to 0 
325                 int seqIndex = tax;
326                 TaxNode seq = phyloTree->get(tax);
327                 confidenceScores[tax] = 0;
328                 
329                 while (seq.level != 0) { //while you are not at the root
330                         seqIndex = seq.parent;
331                         confidenceScores[seqIndex] = 0;
332                         seq = phyloTree->get(seq.parent);
333                 }
334                                 
335                 map<int, int>::iterator itBoot;
336                 map<int, int>::iterator itBoot2;
337                 map<int, int>::iterator itConvert;
338                         
339                 for (int i = 0; i < iters; i++) {
340                         if (m->control_pressed) { return "control"; }
341                         
342                         vector<int> temp;
343                         for (int j = 0; j < numToSelect; j++) {
344                                 int index = int(rand() % kmers.size());
345                                 
346                                 //add word to temp
347                                 temp.push_back(kmers[index]);
348                         }
349                         
350                         //get taxonomy
351                         int newTax = getMostProbableTaxonomy(temp);
352                         //int newTax = 1;
353                         TaxNode taxonomyTemp = phyloTree->get(newTax);
354                         
355                         //add to confidence results
356                         while (taxonomyTemp.level != 0) { //while you are not at the root
357                                 itBoot2 = confidenceScores.find(newTax); //is this a classification we already have a count on
358                                 
359                                 if (itBoot2 != confidenceScores.end()) { //this is a classification we need a confidence for
360                                         (itBoot2->second)++;
361                                 }
362                                 
363                                 newTax = taxonomyTemp.parent;
364                                 taxonomyTemp = phyloTree->get(newTax);
365                         }
366         
367                 }
368                 
369                 string confidenceTax = "";
370                 simpleTax = "";
371                 
372                 int seqTaxIndex = tax;
373                 TaxNode seqTax = phyloTree->get(tax);
374                 
375                 while (seqTax.level != 0) { //while you are not at the root
376                                         
377                                 itBoot2 = confidenceScores.find(seqTaxIndex); //is this a classification we already have a count on
378                                 
379                                 int confidence = 0;
380                                 if (itBoot2 != confidenceScores.end()) { //already in confidence scores
381                                         confidence = itBoot2->second;
382                                 }
383                                 
384                                 if (((confidence/(float)iters) * 100) >= confidenceThreshold) {
385                                         confidenceTax = seqTax.name + "(" + toString(((confidence/(float)iters) * 100)) + ");" + confidenceTax;
386                                         simpleTax = seqTax.name + ";" + simpleTax;
387                                 }
388                                 
389                                 seqTaxIndex = seqTax.parent;
390                                 seqTax = phyloTree->get(seqTax.parent);
391                 }
392                 
393                 if (confidenceTax == "") { confidenceTax = "unknown;"; simpleTax = "unknown;";  }
394         
395                 return confidenceTax;
396                 
397         }
398         catch(exception& e) {
399                 m->errorOut(e, "Bayesian", "bootstrapResults");
400                 exit(1);
401         }
402 }
403 /**************************************************************************************************/
404 int Bayesian::getMostProbableTaxonomy(vector<int> queryKmer) {
405         try {
406                 int indexofGenus = 0;
407                 
408                 double maxProbability = -1000000.0;
409                 //find taxonomy with highest probability that this sequence is from it
410                 
411                 
412 //              cout << genusNodes.size() << endl;
413                 
414                 
415                 for (int k = 0; k < genusNodes.size(); k++) {
416                         //for each taxonomy calc its probability
417                         
418                         double prob = 0.0000;
419                         for (int i = 0; i < queryKmer.size(); i++) {
420                                 prob += wordGenusProb[queryKmer[i]][k];
421                         }
422                         
423 //                      cout << phyloTree->get(genusNodes[k]).name << '\t' << prob << endl;
424
425                         //is this the taxonomy with the greatest probability?
426                         if (prob > maxProbability) { 
427                                 indexofGenus = genusNodes[k];
428                                 maxProbability = prob;
429                         }
430                 }
431                 
432                         
433                 return indexofGenus;
434         }
435         catch(exception& e) {
436                 m->errorOut(e, "Bayesian", "getMostProbableTaxonomy");
437                 exit(1);
438         }
439 }
440 //********************************************************************************************************************
441 //if it is more probable that the reverse compliment kmers are in the template, then we assume the sequence is reversed.
442 bool Bayesian::isReversed(vector<int>& queryKmers){
443         try{
444                 bool reversed = false;
445                 float prob = 0;
446                 float reverseProb = 0;
447                  
448         for (int i = 0; i < queryKmers.size(); i++){
449             int kmer = queryKmers[i];
450             if (kmer >= 0){
451                 prob += WordPairDiffArr[kmer].prob;
452                                 reverseProb += WordPairDiffArr[kmer].reverseProb;
453             }
454         }
455                 
456         if (reverseProb > prob){ reversed = true; }
457         
458                 return reversed;
459         }
460         catch(exception& e) {
461                 m->errorOut(e, "Bayesian", "isReversed");
462                 exit(1);
463         }
464 }
465 //********************************************************************************************************************
466 int Bayesian::generateWordPairDiffArr(){
467         try{
468                 Kmer kmer(kmerSize);
469                 for (int i = 0; i < WordPairDiffArr.size(); i++) {
470                         int reversedWord = kmer.getReverseKmerNumber(i);
471                         WordPairDiffArr[i].reverseProb = WordPairDiffArr[reversedWord].prob;
472                 }
473                 
474                 return 0;
475         }catch(exception& e) {
476                 m->errorOut(e, "Bayesian", "generateWordPairDiffArr");
477                 exit(1);
478         }
479 }
480 /*************************************************************************************************
481 map<string, int> Bayesian::parseTaxMap(string newTax) {
482         try{
483         
484                 map<string, int> parsed;
485                 
486                 newTax = newTax.substr(0, newTax.length()-1);  //get rid of last ';'
487         
488                 //parse taxonomy
489                 string individual;
490                 while (newTax.find_first_of(';') != -1) {
491                         individual = newTax.substr(0,newTax.find_first_of(';'));
492                         newTax = newTax.substr(newTax.find_first_of(';')+1, newTax.length());
493                         parsed[individual] = 1;
494                 }
495                 
496                 //get last one
497                 parsed[newTax] = 1;
498
499                 return parsed;
500                 
501         }
502         catch(exception& e) {
503                 m->errorOut(e, "Bayesian", "parseTax");
504                 exit(1);
505         }
506 }
507 **************************************************************************************************/
508 void Bayesian::readProbFile(ifstream& in, ifstream& inNum, string inName, string inNumName) {
509         try{
510                 
511                 #ifdef USE_MPI
512                         
513                         int pid, num, num2, processors;
514                         vector<unsigned long long> positions;
515                         vector<unsigned long long> positions2;
516                         
517                         MPI_Status status; 
518                         MPI_File inMPI;
519                         MPI_File inMPI2;
520                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
521                         MPI_Comm_size(MPI_COMM_WORLD, &processors);
522                         int tag = 2001;
523
524                         char inFileName[1024];
525                         strcpy(inFileName, inNumName.c_str());
526                         
527                         char inFileName2[1024];
528                         strcpy(inFileName2, inName.c_str());
529
530                         MPI_File_open(MPI_COMM_WORLD, inFileName, MPI_MODE_RDONLY, MPI_INFO_NULL, &inMPI);  //comm, filename, mode, info, filepointer
531                         MPI_File_open(MPI_COMM_WORLD, inFileName2, MPI_MODE_RDONLY, MPI_INFO_NULL, &inMPI2);  //comm, filename, mode, info, filepointer
532
533                         if (pid == 0) {
534                                 positions = m->setFilePosEachLine(inNumName, num);
535                                 positions2 = m->setFilePosEachLine(inName, num2);
536                                 
537                                 for(int i = 1; i < processors; i++) { 
538                                         MPI_Send(&num, 1, MPI_INT, i, tag, MPI_COMM_WORLD);
539                                         MPI_Send(&positions[0], (num+1), MPI_LONG, i, tag, MPI_COMM_WORLD);
540                                         
541                                         MPI_Send(&num2, 1, MPI_INT, i, tag, MPI_COMM_WORLD);
542                                         MPI_Send(&positions2[0], (num2+1), MPI_LONG, i, tag, MPI_COMM_WORLD);
543                                 }
544
545                         }else{
546                                 MPI_Recv(&num, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
547                                 positions.resize(num+1);
548                                 MPI_Recv(&positions[0], (num+1), MPI_LONG, 0, tag, MPI_COMM_WORLD, &status);
549                                 
550                                 MPI_Recv(&num2, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
551                                 positions2.resize(num2+1);
552                                 MPI_Recv(&positions2[0], (num2+1), MPI_LONG, 0, tag, MPI_COMM_WORLD, &status);
553                         }
554                         
555                         //read version
556                         int length = positions2[1] - positions2[0];
557                         char* buf5 = new char[length];
558
559                         MPI_File_read_at(inMPI2, positions2[0], buf5, length, MPI_CHAR, &status);
560                         delete buf5;
561
562                         //read numKmers
563                         length = positions2[2] - positions2[1];
564                         char* buf = new char[length];
565
566                         MPI_File_read_at(inMPI2, positions2[1], buf, length, MPI_CHAR, &status);
567
568                         string tempBuf = buf;
569                         if (tempBuf.length() > length) { tempBuf = tempBuf.substr(0, length); }
570                         delete buf;
571
572                         istringstream iss (tempBuf,istringstream::in);
573                         iss >> numKmers;  
574                         
575                         //initialze probabilities
576                         wordGenusProb.resize(numKmers);
577                         
578                         for (int j = 0; j < wordGenusProb.size(); j++) {        wordGenusProb[j].resize(genusNodes.size());             }
579                         
580                         int kmer, name;  
581                         vector<int> numbers; numbers.resize(numKmers);
582                         float prob;
583                         vector<float> zeroCountProb; zeroCountProb.resize(numKmers);
584                         WordPairDiffArr.resize(numKmers);
585                         
586                         //read version
587                         length = positions[1] - positions[0];
588                         char* buf6 = new char[length];
589
590                         MPI_File_read_at(inMPI2, positions[0], buf6, length, MPI_CHAR, &status);
591                         delete buf6;
592                         
593                         //read file 
594                         for(int i=1;i<num;i++){
595                                 //read next sequence
596                                 length = positions[i+1] - positions[i];
597                                 char* buf4 = new char[length];
598
599                                 MPI_File_read_at(inMPI, positions[i], buf4, length, MPI_CHAR, &status);
600
601                                 tempBuf = buf4;
602                                 if (tempBuf.length() > length) { tempBuf = tempBuf.substr(0, length); }
603                                 delete buf4;
604
605                                 istringstream iss (tempBuf,istringstream::in);
606                                 float probTemp;
607                                 iss >> zeroCountProb[i] >> numbers[i] >> probTemp; 
608                                 WordPairDiffArr[i].prob = probTemp;
609
610                         }
611                         
612                         MPI_File_close(&inMPI);
613                         
614                         for(int i=2;i<num2;i++){
615                                 //read next sequence
616                                 length = positions2[i+1] - positions2[i];
617                                 char* buf4 = new char[length];
618
619                                 MPI_File_read_at(inMPI2, positions2[i], buf4, length, MPI_CHAR, &status);
620
621                                 tempBuf = buf4;
622                                 if (tempBuf.length() > length) { tempBuf = tempBuf.substr(0, length); }
623                                 delete buf4;
624
625                                 istringstream iss (tempBuf,istringstream::in);
626                                 
627                                 iss >> kmer;
628                                 
629                                 //set them all to zero value
630                                 for (int i = 0; i < genusNodes.size(); i++) {
631                                         wordGenusProb[kmer][i] = log(zeroCountProb[kmer] / (float) (genusTotals[i]+1));
632                                 }
633                                 
634                                 //get probs for nonzero values
635                                 for (int i = 0; i < numbers[kmer]; i++) {
636                                         iss >> name >> prob;
637                                         wordGenusProb[kmer][name] = prob;
638                                 }
639                                 
640                         }
641                         MPI_File_close(&inMPI2);
642                         MPI_Barrier(MPI_COMM_WORLD); //make everyone wait - just in case
643                 #else
644                         //read version
645                         string line = m->getline(in); m->gobble(in);
646                         
647                         in >> numKmers; m->gobble(in);
648                         //cout << threadID << '\t' << line << '\t' << numKmers << &in << '\t' << &inNum << '\t' << genusNodes.size() << endl;
649                         //initialze probabilities
650                         wordGenusProb.resize(numKmers);
651                         
652                         for (int j = 0; j < wordGenusProb.size(); j++) {        wordGenusProb[j].resize(genusNodes.size());             }
653                         
654                         int kmer, name, count;  count = 0;
655                         vector<int> num; num.resize(numKmers);
656                         float prob;
657                         vector<float> zeroCountProb; zeroCountProb.resize(numKmers);    
658                         WordPairDiffArr.resize(numKmers);
659                         
660                         //read version
661                         string line2 = m->getline(inNum); m->gobble(inNum);
662                         float probTemp;
663                 //cout << threadID << '\t' << line2 << '\t' << this << endl;    
664                         while (inNum) {
665                                 inNum >> zeroCountProb[count] >> num[count] >> probTemp; 
666                                 WordPairDiffArr[count].prob = probTemp;
667                                 count++;
668                                 m->gobble(inNum);
669                                 //cout << threadID << '\t' << count << endl;
670                         }
671                         inNum.close();
672                 //cout << threadID << '\t' << "here1 " << &wordGenusProb << '\t' << &num << endl; //
673                 //cout << threadID << '\t' << &genusTotals << '\t' << endl; 
674                 //cout << threadID << '\t' << genusNodes.size() << endl;
675                         while(in) {
676                                 in >> kmer;
677                         //cout << threadID << '\t' << kmer << endl;
678                                 //set them all to zero value
679                                 for (int i = 0; i < genusNodes.size(); i++) {
680                                         wordGenusProb[kmer][i] = log(zeroCountProb[kmer] / (float) (genusTotals[i]+1));
681                                 }
682                         //cout << threadID << '\t' << num[kmer] << "here" << endl;      
683                                 //get probs for nonzero values
684                                 for (int i = 0; i < num[kmer]; i++) {
685                                         in >> name >> prob;
686                                         wordGenusProb[kmer][name] = prob;
687                                 }
688                                 
689                                 m->gobble(in);
690                         }
691                         in.close();
692                 //cout << threadID << '\t' << "here" << endl;   
693                 #endif
694         }
695         catch(exception& e) {
696                 m->errorOut(e, "Bayesian", "readProbFile");
697                 exit(1);
698         }
699 }
700 /**************************************************************************************************/
701 bool Bayesian::checkReleaseDate(ifstream& file1, ifstream& file2, ifstream& file3, ifstream& file4) {
702         try {
703                 
704                 bool good = true;
705                 
706                 vector<string> lines;
707                 lines.push_back(m->getline(file1));  
708                 lines.push_back(m->getline(file2)); 
709                 lines.push_back(m->getline(file3)); 
710                 lines.push_back(m->getline(file4)); 
711
712                 //before we added this check
713                 if ((lines[0][0] != '#') || (lines[1][0] != '#') || (lines[2][0] != '#') || (lines[3][0] != '#')) {  good = false;  }
714                 else {
715                         //rip off #
716                         for (int i = 0; i < lines.size(); i++) { lines[i] = lines[i].substr(1);  }
717                         
718                         //get mothurs current version
719                         string version = m->getVersion();
720                         
721                         vector<string> versionVector;
722                         m->splitAtChar(version, versionVector, '.');
723                         
724                         //check each files version
725                         for (int i = 0; i < lines.size(); i++) { 
726                                 vector<string> linesVector;
727                                 m->splitAtChar(lines[i], linesVector, '.');
728                         
729                                 if (versionVector.size() != linesVector.size()) { good = false; break; }
730                                 else {
731                                         for (int j = 0; j < versionVector.size(); j++) {
732                                                 int num1, num2;
733                                                 convert(versionVector[j], num1);
734                                                 convert(linesVector[j], num2);
735                                                 
736                                                 //if mothurs version is newer than this files version, then we want to remake it
737                                                 if (num1 > num2) {  good = false; break;  }
738                                         }
739                                 }
740                                 
741                                 if (!good) { break; }
742                         }
743                 }
744                 
745                 if (!good) {  file1.close(); file2.close(); file3.close(); file4.close();  }
746                 else { file1.seekg(0);  file2.seekg(0);  file3.seekg(0);  file4.seekg(0);  }
747                 
748                 return good;
749         }
750         catch(exception& e) {
751                 m->errorOut(e, "Bayesian", "checkReleaseDate");
752                 exit(1);
753         }
754 }
755 /**************************************************************************************************/
756
757
758
759
760
761