/** Print the population fraction of the entire simulation for each state and * each residue */ void ProtTraj::PrintProtPop(string const& fname) { // Set up the table of populations, initializing everything to zero vector<StateCount> pop_counts; // Now loop through every state and every residue, building pop_counts for (Cpin::ResIterator rit = cpin_->begin(); rit != cpin_->end(); rit++) { StateCount newstate; newstate.nstates = 0; for (int i = 0; i < rit->numStates(); i++) { newstate.state_cnt.push_back(0ll); newstate.prot_cnt.push_back(rit->numProtons(i)); newstate.nstates++; } pop_counts.push_back(newstate); } // Now loop through the entire trajectory, building the population list for (int i = 1; i < nframes_ + 1; i++) { ProtVector curst = statelist_[i]; for (int j = 0; j < nres_; j++) pop_counts[j].state_cnt[ statelist_[i][j] ] += 1ll; } // Now print out the population counts ofstream fp(fname.c_str()); if (!fp.is_open()) throw FileIOError("Could not open " + fname + " for writing!"); // Get the max number of states int maxst = cpin_->getResidues()[0].numStates(); for (Cpin::ResIterator rit = cpin_->begin(); rit != cpin_->end(); rit++) maxst = MAX(maxst, rit->numStates()); // Write the header fp << right << fixed << setw(17) << "Residue Number" << " "; for (int i = 0; i < maxst; i++) fp << setw(9) << "State" << setw(3) << i << ' '; fp << endl << setfill('-') << setw(maxst*13+18) << '-' << endl; // Now loop through every residue and print out the populations for (int i = 0; i < nres_; i++) { stringstream iss; iss << "Residue: " << cpin_->getResidues()[i].getResname() << " " << cpin_->getResidues()[i].getResnum(); fp << setfill(' ') << left << setw(17) << iss.str() << " "; for (int j = 0; j < pop_counts[i].nstates; j++) { double pop = (double) pop_counts[i].state_cnt[j] / (double) nframes_; fp << setprecision(6) << setw(8) << pop << " (" << pop_counts[i].prot_cnt[j] << ") "; } fp << endl; } fp.close(); }
/// Prints a cumulative running average time series of the desired property void ProtTraj::PrintCumulative(string const& fname, const int interval, const bool print_prot, const bool print_pka) { // Open up the file and write a header ofstream fp(fname.c_str()); if (!fp.is_open()) throw FileIOError("Could not open " + fname + " for writing!"); fp << fixed << "#Time step "; for (Cpin::ResIterator rit = cpin_->begin(); rit != cpin_->end(); rit++) { stringstream iss; iss << rit->getResname() << " " << rit->getResnum(); fp << setw(8) << iss.str() << " "; } fp << " Total Avg. Prot." << endl; // Now go through the trajectory vector<long long int> nprot(nres_, 0ll); long long int totprot = 0ll; int c = 0; // simple counter for (int i = 1; i < nframes_ + 1; i++) { { // scope this int j = 0; for (Cpin::ResIterator rit = cpin_->begin(); rit != cpin_->end(); rit++) { long long int protadd = (long long int) (rit->isProtonated(statelist_[i][j])); nprot[j] += protadd; totprot += (long long int) rit->numProtons(statelist_[i][j]); j++; } } if (c * time_step_ >= interval) { c = 0; // Now we print a point int j = 0; fp << setw(10) << (i-1)*time_step_ << " "; for (Cpin::ResIterator rit = cpin_->begin(); rit != cpin_->end(); rit++) { double fracprot = (double)nprot[j] / (double)(i+1); if (print_prot) { // We want the fraction protonated fp << setprecision(5) << setw(8) << fracprot << " "; }else if (print_pka) { // We want the pKa double pKa = pH_ - log10( (1.0 - fracprot) / fracprot ); fp << setprecision(4) << setw(8) << pKa << " "; }else { // We want the fraction deprotonated fp << setprecision(5) << setw(8) << 1.0-fracprot << " "; } j++; } double fracprot = (double)totprot / (double)i; fp << setprecision(6) << setw(17) << fracprot << endl; } c++; // heh } fp.close(); return; }
/// Print the rolling/running average time series with a given window void ProtTraj::PrintRunningAvg(const int window, const int interval, string const& fname, const bool print_prot, const bool print_pka) { const int halfwin = window / (2 * time_step_); // Open the file for writing and print a header ofstream fp(fname.c_str()); if (!fp.is_open()) throw FileIOError("Could not open " + fname + " for writing!"); fp << fixed << "#Time step "; for (Cpin::ResIterator rit = cpin_->begin(); rit != cpin_->end(); rit++) { stringstream iss; iss << rit->getResname() << " " << rit->getResnum(); fp << setw(8) << iss.str() << " "; } fp << " Total Avg. Prot." << endl; for (int i = 1; i < nframes_ + 1; i+= interval/time_step_) { vector<long long int> nprot(nres_, 0ll); long long int totprot = 0ll; // Loop over all frames we should include here for (int j = MAX(0, i-halfwin); j < MIN(nframes_, i+halfwin); j++) { // Loop over every residue int k = 0; for (Cpin::ResIterator rit = cpin_->begin(); rit != cpin_->end(); rit++) { long long int protadd = (long long int) (rit->isProtonated(statelist_[j][k])); nprot[k] += protadd; totprot += (long long int) rit->numProtons(statelist_[j][k]); k++; } } // Print this frame to the output file int j = 0; int n = MIN(nframes_, i+halfwin) - MAX(0, i-halfwin); fp << setw(10) << time_step_*i << " "; for (Cpin::ResIterator rit = cpin_->begin(); rit != cpin_->end(); rit++) { double fracprot = (double)nprot[j] / (double)n; if (print_prot) { // We want the fraction protonated fp << setprecision(5) << setw(8) << fracprot << " "; }else if (print_pka) { // We want the pKa double pKa = pH_ - log10( (1.0 - fracprot) / fracprot ); fp << setprecision(4) << setw(8) << pKa << " "; }else { // We want the fraction deprotonated fp << setprecision(5) << setw(8) << 1.0-fracprot << " "; } j++; } double fracprot = (double)totprot / (double)n; fp << setprecision(6) << setw(17) << fracprot << endl; } fp.close(); return; }
/// Print a time series of the desired properties in 'chunks' of the simulation void ProtTraj::PrintChunks(const int window, string const& fname, const bool print_prot, const bool print_pka) { // Open up the file and write a header (set fixed precision) ofstream fp(fname.c_str()); if (!fp.is_open()) throw FileIOError("Could not open " + fname + " for writing!"); fp << fixed << "#Time step "; for (Cpin::ResIterator rit = cpin_->begin(); rit != cpin_->end(); rit++) { stringstream iss; iss << rit->getResname() << " " << rit->getResnum(); fp << setw(8) << iss.str() << " "; } fp << " Total Avg. Prot." << endl; int interval = window / time_step_; int first = 0; while (first < nframes_+1) { vector<long long int> nprot(nres_, 0ll); long long int totprot = 0ll; int last = MIN(nframes_+1, first + interval); for (int i = first; i < last; i++) { int j = 0; for (Cpin::ResIterator rit = cpin_->begin(); rit != cpin_->end(); rit++) { long long int protadd = (long long int) (rit->isProtonated(statelist_[i][j])); nprot[j] += protadd; totprot += (long long int) rit->numProtons(statelist_[i][j]); j++; } } // Now write the information int j = 0; fp << setw(10) << time_step_*(first + interval / 2) << " "; for (Cpin::ResIterator rit = cpin_->begin(); rit != cpin_->end(); rit++) { double fracprot = (double)nprot[j] / (double)(last - first); if (print_prot) { // We want the fraction protonated fp << setprecision(5) << setw(8) << fracprot << " "; }else if (print_pka) { // We want the pKa double pKa = pH_ - log10( (1.0 - fracprot) / fracprot ); fp << setprecision(4) << setw(8) << pKa << " "; }else { // We want the fraction deprotonated fp << setprecision(5) << setw(8) << 1.0-fracprot << " "; } j++; } double fracprot = (double)totprot/(double)(last - first); fp << setprecision(6) << setw(17) << fracprot << endl; first += interval; } // Now that I'm here (and done), close the file fp.close(); return; }
/// Prints the calcpka-style output void ProtTraj::PrintCalcpka(ostream& fd, const int start) { // First calculate the statistics vector<long long int> nprot(nres_, 0ll); vector<int> transitions(nres_, 0); long long int totprot = 0ll; // Start with the first point, but skip it in the iteration last_point_ = statelist_[start]; for (int i = start + 1; i < nframes_ + 1; i++) { int j = 0; for (Cpin::ResIterator rit = cpin_->begin(); rit != cpin_->end(); rit++) { transitions[j] += (int) (rit->isProtonated(last_point_[j]) != rit->isProtonated(statelist_[i][j])); long long int protadd = (long long int) (rit->isProtonated(statelist_[i][j])); nprot[j] += protadd; totprot += (long long int) rit->numProtons(statelist_[i][j]); j++; } // Reassign the last point to the current one before incrementing last_point_ = statelist_[i]; } // Now do the printing fd.precision(3); fd << fixed; fd << "Solvent pH is " << setw(8) << pH_ << endl; int i = 0; for (Cpin::ResIterator rit = cpin_->begin(); rit != cpin_->end(); rit++) { double pKa = pH_ - log10( (double) (nframes_-nprot[i]) / (double) nprot[i] ); float offset = (float) pKa - pH_; fd << setw(3) << rit->getResname() << " " << setw(4) << left << rit->getResnum() << ": Offset " << right << setw(6) << offset << " Pred " << setw(6) << pKa << " Frac Prot " << setw(5) << (double) nprot[i] / (double) nframes_ << " Transitions " << setw(9) << transitions[i] << endl; i++; } fd << endl << "Average total molecular protonation: " << setw(7) << (double)totprot / (double)nframes_ << endl; return; }
int main(int argc, char**argv) { // Set up the command-line options and parse them CLOptions clopt = CLOptions(argc, argv); if (clopt.Parse()) return 1; // Check the input if (clopt.CheckInput()) { cerr << "Error: Input errors detected! See messages above." << endl; return 1; } // test_clopt(clopt); /* Uncomment to test command-line parsing */ int nres = 0; // number of residues (for consistency tests) /* Set up the cpin and print some diagnostic information (only necessary if * we're not fixing REMD files */ Cpin my_cpin; if (clopt.REMDPrefix().empty()) { if ( clopt.Cpin().empty() ) { #ifdef REDOX cerr << "Error: No cein file provided!" << endl; #else cerr << "Error: No cpin file provided!" << endl; #endif return 1; } if ( my_cpin.Parse(clopt.Cpin()) ) return 1; nres = (int) my_cpin.getTrescnt(); if (nres <= 0) { cerr << "Error: Did not detect any residues in " << clopt.Cpin() << endl; return 1; } if (clopt.Debug()) { cout << "There are " << nres << " titratable residues defined in " << my_cpin.getFilename() << ":" << endl; cout << "They are:" << endl; for (Cpin::ResIterator it = my_cpin.begin(); it != my_cpin.end(); it++) { cout << "\t" << setw(3) << it->getResname() << left << " " << setw(3) << it->getResnum() << " (" << it->numStates() << " states) [ "; for (int j = 0; j < it->numStates(); j++) { #ifdef REDOX if (it->isProtonated(j)) cout << "R "; else cout << "O "; #else if (it->isProtonated(j)) cout << "P "; else cout << "D "; #endif } cout << "]" << endl; } } } // if clopt.REMDPrefix().empty() // Set up the cpouts CpoutList cpouts; for (CLOptions::cpout_iterator it = clopt.begin(); it != clopt.end(); it++) { CpoutFile c = CpoutFile(&my_cpin, *it); // Skip over invalid cpouts if (!c.Valid()) { #ifdef REDOX cerr << "Error: Ceout file " << *it << " is invalid! Skipping." << endl; #else cerr << "Error: Cpout file " << *it << " is invalid! Skipping." << endl; #endif continue; } // For REMD fixing where a cpin is unnecessary, make sure all cpouts have // the same number of residues, so set nres to the first cpout's Nres if (nres <= 0) nres = c.Nres(); // Skip over cpouts with a residue mismatch if (c.Nres() != nres) { #ifdef REDOX cerr << "Error: Ceout file " << *it << " has " << c.Nres() << #else cerr << "Error: Cpout file " << *it << " has " << c.Nres() << #endif " residues. I expected " << my_cpin.getTrescnt() << ". Skipping." << endl; continue; } if (clopt.Debug()) #ifdef REDOX cout << "Added [[ " << *it << " ]] to ceout list." << endl; #else cout << "Added [[ " << *it << " ]] to cpout list." << endl; #endif cpouts.push_back(c); } if (clopt.Debug()) #ifdef REDOX cout << "Analyzing " << clopt.Cpouts().size() << " ceouts." << endl; if (cpouts.size() != clopt.Cpouts().size()) { cerr << "Error: Number of Ceout files " << cpouts.size() << #else cout << "Analyzing " << clopt.Cpouts().size() << " cpouts." << endl; if (cpouts.size() != clopt.Cpouts().size()) { cerr << "Error: Number of Cpout files " << cpouts.size() << #endif " does not equal number specified: " << clopt.Cpouts().size() << endl; return 1; } // Special-case REMD re-ordering if (!clopt.REMDPrefix().empty()) return sort_remd_files(cpouts, clopt.REMDPrefix(), clopt.Overwrite()); #ifdef REDOX ProtTraj stats = ProtTraj(&my_cpin, cpouts[0].pH(), cpouts[0].GetRecord(), cpouts[0].Temperature()); #else ProtTraj stats = ProtTraj(&my_cpin, cpouts[0].pH(), cpouts[0].GetRecord()); #endif for (cpout_iterator it = cpouts.begin(); it != cpouts.end(); it++) { // If we are here, then warn if we are about to use a REMD file if (!clopt.Expert()) it->WarnRemd(); stats.LoadCpout(*it); } // Do the normal calcpka-style output if requested if (clopt.Calcpka()) { if (clopt.Output().empty()) stats.PrintCalcpka(cout); else { ofstream fd; fd.open(clopt.Output().c_str()); stats.PrintCalcpka(fd); fd.close(); } } // Do chunk analysis if (clopt.ChunkWindow() > 0) stats.PrintChunks(clopt.ChunkWindow(), clopt.ChunkOutput(), clopt.PrintProtonated() && !clopt.pKa(), clopt.pKa()); // Do cumulative analysis if (clopt.doCumulative()) stats.PrintCumulative(clopt.CumulativeOutput(), clopt.Interval(), clopt.PrintProtonated() && !clopt.pKa(), clopt.pKa()); // Do running averages if (clopt.RunningAvgWindow() > 0) stats.PrintRunningAvg(clopt.RunningAvgWindow(), clopt.Interval(), clopt.RunningAvgOutput(), clopt.PrintProtonated() && !clopt.pKa(), clopt.pKa()); // Do protonation fraction dump if (clopt.Population().size() > 0) stats.PrintProtPop(clopt.Population()); // Do conditional probabilities if (clopt.CondProbs().size() > 0) { for (CLOptions::prob_iterator it = clopt.condbegin(); it != clopt.condend(); it++) if (it->Set(my_cpin) == ConditionalProb::ERR) { cerr << "Quitting due to errors above." << endl; return 1; } stats.PrintCondProb(clopt.ConditionalOutput(), clopt.CondProbs()); } // Do conditional probability time series (we already set the conditional // probabilities above, so no need to do it again) if (clopt.CondProbs().size() > 0 && !clopt.ConditionalChunkOut().empty()) stats.PrintCondTimeseries(clopt.ConditionalChunkOut(), clopt.Interval(), clopt.CondProbs()); if (clopt.Debug()) cout << "All done!" << endl; return 0; }