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