26#include <boost/lexical_cast.hpp>
50 cout <<
"begin to calculate inverse monte carlo parameters\n";
52 throw runtime_error(
"error, can not have --do-imc and --include-intra");
55 cout <<
"begin to calculate distribution functions\n";
57 cout <<
"# of bonded interactions: " <<
bonded_.size() << endl;
58 cout <<
"# of non-bonded interactions: " <<
nonbonded_.size() << endl;
61 throw std::runtime_error(
62 "No interactions defined in options xml-file - nothing to be done");
91 string name = prop->get(
"name").value();
101 beads1.
Generate(*top, prop->get(
"type1").value());
102 beads2.
Generate(*top, prop->get(
"type2").value());
103 beads3.
Generate(*top, prop->get(
"type3").value());
105 if (beads1.
size() == 0) {
106 throw std::runtime_error(
107 "Topology does not have beads of type \"" +
108 prop->get(
"type1").value() +
110 "This was specified in type1 of interaction \"" +
113 if (beads2.
size() == 0) {
114 throw std::runtime_error(
115 "Topology does not have beads of type \"" +
116 prop->get(
"type2").value() +
118 "This was specified in type2 of interaction \"" +
121 if (beads3.
size() == 0) {
122 throw std::runtime_error(
123 "Topology does not have beads of type \"" +
124 prop->get(
"type3").value() +
126 "This was specified in type3 of interaction \"" +
135 if (max > max_dist) {
136 throw std::runtime_error(
"The max of interaction \"" + name +
137 "\" bigger is than half the box.");
143 beads1.
Generate(*top, prop->get(
"type1").value());
144 beads2.
Generate(*top, prop->get(
"type2").value());
146 if (beads1.
size() == 0) {
147 throw std::runtime_error(
148 "Topology does not have beads of type \"" +
149 prop->get(
"type1").value() +
151 "This was specified in type1 of interaction \"" +
154 if (beads2.
size() == 0) {
155 throw std::runtime_error(
156 "Topology does not have beads of type \"" +
157 prop->get(
"type2").value() +
159 "This was specified in type2 of interaction \"" +
164 if (prop->get(
"type1").value() == prop->get(
"type2").value()) {
173 string name = prop->get(
"name").value();
176 throw std::runtime_error(
177 "Bonded interaction '" + name +
178 "' defined in options xml-file, but not in topology - check name "
179 "definition in the mapping file again");
186 string name = p->
get(
"name").
value();
189 group = p->
get(
"inverse.imc.group").
value();
196 std::make_pair(name, std::make_unique<interaction_t>()));
199 if (group !=
"none") {
208 i->
max_ = p->
get(
"max_intra").
as<
double>();
252 throw std::runtime_error(
253 "no frames were processed. Please check your input");
278 inter.second->average_.Clear();
279 if (inter.second->force_) {
280 inter.second->average_force_.Clear();
284 group.second->corr_.setZero();
304 string name = prop->
get(
"name").
value();
309 current_hists_[i.
index_].Clear();
310 current_hists_force_[i.
index_].Clear();
312 bool gridsearch =
true;
314 if (imc_->options_.exists(
"cg.nbsearch")) {
315 if (imc_->options_.get(
"cg.nbsearch").as<
string>() ==
"grid") {
317 }
else if (imc_->options_.get(
"cg.nbsearch").as<
string>() ==
"simple") {
320 throw std::runtime_error(
"cg.nbsearch invalid, can be grid or simple");
335 std::unique_ptr<NBList_3Body> nb;
340 nb = std::make_unique<NBList_3Body>();
343 nb->setCutoff(i.
cut_);
353 nb->Generate(beads1,
true);
358 nb->Generate(beads1, beads2,
true);
366 nb->Generate(beads1, beads2, beads3,
true);
369 for (
auto &triple : *nb) {
370 Eigen::Vector3d rij = triple->r12();
371 Eigen::Vector3d rik = triple->r13();
372 double var = std::acos(rij.dot(rik) /
373 sqrt(rij.squaredNorm() * rik.squaredNorm()));
374 current_hists_[i.
index_].Process(var);
388 std::unique_ptr<NBList> nb;
390 nb = std::unique_ptr<NBList>(
new NBListGrid());
392 nb = std::unique_ptr<NBList>(
new NBListGrid());
403 nb->Generate(beads1, !(imc_->include_intra_));
405 nb->Generate(beads1, beads2, !(imc_->include_intra_));
411 std::unique_ptr<NBList> nb_force;
413 nb_force = std::unique_ptr<NBList>(
new NBListGrid());
415 nb_force = std::unique_ptr<NBList>(
new NBListGrid());
422 nb_force->Generate(beads1);
424 nb_force->Generate(beads1, beads2);
429 for (
auto &pair : *nb_force) {
430 Eigen::Vector3d F2 = pair->second()->getF();
431 Eigen::Vector3d F1 = pair->first()->getF();
432 Eigen::Vector3d r12 = pair->r();
434 double var = pair->dist();
435 double scale = 0.5 * (F2 - F1).dot(r12);
436 current_hists_force_[i.
index_].Process(var, scale);
446 string name = prop->
get(
"name").
value();
451 current_hists_[i.
index_].Clear();
455 double v = ic->EvaluateVar(*top);
456 current_hists_[i.
index_].Process(v);
463 map<string, std::unique_ptr<group_t> >::iterator iter;
467 groups_.insert(std::make_pair(name, std::make_unique<group_t>()));
468 return success.first->second.get();
470 return (*iter).second.get();
478 map<string, group_t *>::iterator group_iter;
484 auto &grp = group.second;
487 auto &interactions = grp->interactions_;
489 votca::Index n = std::accumulate(interactions.begin(), interactions.end(),
491 return j + i->average_.getNBins();
498 M = Eigen::MatrixXd::Zero(n, n);
510 pair_matrix corr = M.block(offset_i, offset_j, n1, n2);
512 grp->pairs_.push_back(
513 pair_t(interactions[i], interactions[j], offset_i, offset_j, corr));
528 auto &grp = group.second;
530 for (
auto &pair : grp->pairs_) {
531 Eigen::VectorXd &a = worker->
current_hists_[pair.i1_->index_].data().y();
532 Eigen::VectorXd &b = worker->
current_hists_[pair.i2_->index_].data().y();
535 M = ((((double)
nframes_ - 1.0) * M) + a * b.transpose()) /
543 map<string, interaction_t *>::iterator iter;
550 auto &interaction = pair.second;
556 if (interaction->force_) {
557 force = interaction->average_force_.data();
561 if (!interaction->is_bonded_) {
563 if (interaction->threebody_) {
565 double norm = dist.
y().cwiseAbs().sum();
568 interaction->norm_ * dist.
y() / (norm * interaction->step_);
573 if (!interaction->threebody_) {
579 if (dist.
y()[i] != 0) {
580 force.
y()[i] /= dist.
y()[i];
591 double x1 = dist.
x()[i] - 0.5 * interaction->step_;
592 double x2 = x1 + interaction->step_;
597 (4. / 3. * M_PI * (x2 * x2 * x2 - x1 * x1 * x1));
604 double norm = dist.
y().cwiseAbs().sum();
606 dist.
y() = interaction->norm_ * dist.
y() / (norm * interaction->step_);
610 dist.
Save((pair.first) + suffix);
611 cout <<
"written " << (pair.first) + suffix <<
"\n";
614 if (interaction->force_) {
615 force.
Save((pair.first) +
".force.new");
616 cout <<
"written " << (pair.first) +
".force.new"
633 map<string, group_t *>::iterator group_iter;
637 auto &grp = group.second;
638 string grp_name = group.first;
650 vector<std::pair<std::string, votca::tools::RangeParser> >
660 Eigen::VectorBlock<Eigen::VectorXd> sub_dS =
664 Eigen::VectorBlock<Eigen::VectorXd> sub_r =
677 ranges.push_back(std::pair<std::string, votca::tools::RangeParser>(
678 ic->
p_->
get(
"name").
as<
string>(), rp));
688 for (
pair_t &pair : grp->pairs_) {
703 M = -(M - a * b.transpose());
705 gmc.block(j, i, n2, n1) = M.transpose().eval();
716 Eigen::VectorBlock<Eigen::VectorXd> &dS) {
717 const string &name = interaction->
p_->
get(
"name").
as<
string>();
720 target.
Load(name +
".dist.tgt");
724 double x1 = target.x()[i] - 0.5 * interaction->
step_;
725 double x2 = x1 + interaction->
step_;
731 (4. / 3. * M_PI * (x2 * x2 * x2 - x1 * x1 * x1));
734 target.y() = (1.0 / interaction->
norm_) * target.y();
736 if (target.y().size() != interaction->
average_.
data().
y().size()) {
737 throw std::runtime_error(
738 "number of grid points in target does not match the grid");
752 auto &grp = group.second;
753 string grp_name = group.first;
754 list<interaction_t *>::iterator iter;
761 Eigen::VectorXd dS(n);
762 Eigen::VectorXd r(n);
765 vector<votca::Index> sizes;
766 vector<string> names;
772 Eigen::VectorBlock<Eigen::VectorXd> sub_dS =
776 Eigen::VectorBlock<Eigen::VectorXd> sub_r =
786 names.push_back(ic->
p_->
get(
"name").
as<
string>());
794 string name_dS = grp_name + suffix +
".S";
795 out_dS.open(name_dS);
796 out_dS << setprecision(8);
798 throw runtime_error(
string(
"error, cannot open file ") + name_dS);
802 out_dS << r[i] <<
" " << dS[i] << endl;
806 cout <<
"written " << name_dS << endl;
810 string name_cor = grp_name + suffix +
".cor";
811 out_cor.open(name_cor);
812 out_cor << setprecision(8);
815 throw runtime_error(
string(
"error, cannot open file ") + name_cor);
820 out_cor << grp->corr_(i, j) <<
" ";
825 cout <<
"written " << name_cor << endl;
831 auto worker = std::make_unique<Imc::Worker>();
837 auto &i = interaction.second;
838 worker->current_hists_[i->index_].Initialize(
839 i->average_.getMin(), i->average_.getMax(), i->average_.getNBins());
841 if (interaction.second->force_) {
842 worker->current_hists_force_[i->index_].Initialize(
843 i->average_force_.getMin(), i->average_force_.getMax(),
844 i->average_force_.getNBins());
854 map<string, interaction_t *>::iterator ic_iter;
860 auto &i = interaction.second;
861 i->average_.data().y() =
862 (((double)
nframes_ - 1.0) * i->average_.data().y() +
867 i->average_force_.data().y() =
868 (((double)
nframes_ - 1.0) * i->average_force_.data().y() +
882 string suffix = string(
"_") + boost::lexical_cast<string>(
nblock_) +
Index Generate(Topology &top, const std::string &select)
Select all beads of type "select".
Worker, derived from Thread, does the work.
bool FoundPair(Bead *, Bead *, const Eigen::Vector3d &, const double dist)
votca::tools::HistogramNew & hist_
bool FoundPair(Bead *b1, Bead *, const Eigen::Vector3d &, const double dist)
IMCNBSearchHandler(votca::tools::HistogramNew *hist)
void EvalConfiguration(Topology *top, Topology *top_atom) override
evaluate current conformation
std::vector< tools::HistogramNew > current_hists_
void DoNonbonded(Topology *top)
process non-bonded interactions for given frame
std::vector< tools::HistogramNew > current_hists_force_
void DoBonded(Topology *top)
process bonded interactions for given frame
Eigen::MatrixXd group_matrix
interaction_t * AddInteraction(tools::Property *p, bool is_bonded)
create a new interaction entry based on given options
votca::Index block_length_
std::unique_ptr< CsgApplication::Worker > ForkWorker()
void WriteIMCData(const std::string &suffix="")
void EndEvaluate()
end coarse graining a trajectory
tools::Average< double > avg_vol_
tools::Property options_
the options parsed from cg definition file
void InitializeGroups()
initializes the group structs after interactions were added
std::map< std::string, std::unique_ptr< group_t > > groups_
map group-name to group
std::vector< tools::Property * > nonbonded_
list of non-bonded interactions
std::map< std::string, std::unique_ptr< interaction_t > > interactions_
map interaction-name to interaction
void MergeWorker(CsgApplication::Worker *worker_)
void DoCorrelations(Imc::Worker *worker)
update the correlations after interations were processed
bool processed_some_frames_
std::vector< tools::Property * > bonded_
list of bonded interactions
void WriteDist(const std::string &suffix="")
void BeginEvaluate(Topology *top, Topology *top_atom)
begin coarse graining a trajectory
void CalcDeltaS(interaction_t *interaction, Eigen::VectorBlock< Eigen::VectorXd > &dS)
void WriteIMCBlock(const std::string &suffix)
void LoadOptions(const std::string &file)
load cg definitions file
Eigen::Block< group_matrix > pair_matrix
group_t * getGroup(const std::string &name)
get group by name, creates one if it doesn't exist
base class for all interactions
topology of the whole system
std::vector< Interaction * > InteractionsInGroup(const std::string &group)
double ShortestBoxSize() const
return the shortest box size
void imcio_write_dS(const std::string &file, const tools::Table &dS, const std::list< Index > *list=nullptr)
void imcio_write_index(const std::string &file, const std::vector< std::pair< std::string, tools::RangeParser > > &ranges)
void imcio_write_matrix(const std::string &file, const Eigen::MatrixXd &gmc, const std::list< Index > *list=nullptr)
base class for all analysis tools
struct to store collected information for groups (e.g. crosscorrelations)
std::vector< interaction_t * > interactions_
struct to store collected information for interactions
tools::HistogramNew average_
tools::HistogramNew average_force_