From db4977a40953d0628f11cfc90d0f153edc5db048 Mon Sep 17 00:00:00 2001
From: Ben Webb <ben@salilab.org>
Date: Wed, 11 Mar 2020 13:12:40 -0700
Subject: [PATCH] Add metadata to RMF output

---
 include/GaussianEMRestraint.h | 18 ++++++++++++++++++
 pyext/src/restraint.py        |  2 ++
 src/GaussianEMRestraint.cpp   | 23 ++++++++++++++++++++++-
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/include/GaussianEMRestraint.h b/include/GaussianEMRestraint.h
index 8f49094..58908d6 100755
--- a/include/GaussianEMRestraint.h
+++ b/include/GaussianEMRestraint.h
@@ -104,6 +104,15 @@ class IMPBAYESIANEMEXPORT GaussianEMRestraint : public Restraint
     return exp(-unprotected_evaluate(NULL));
   }
 
+  //! Set the filename corresponding to the density GMM particles
+  /** If the density GMM particles were read from a file, this method
+      can be used to tell the restraint so that it can track this
+      information back to the original EM density file, which is useful
+      for deposition. */
+  void set_density_filename(std::string density_fn) {
+    density_fn_ = get_absolute_path(density_fn);
+  }
+
   //! Pre-calculate the density-density and model-model scores
   /** This is automatically called by the constructor.
       You only need to call it manually if you change Gaussian variances
@@ -129,9 +138,17 @@ class IMPBAYESIANEMEXPORT GaussianEMRestraint : public Restraint
     const IMP_OVERRIDE;
   virtual IMP::ModelObjectsTemp do_get_inputs() const IMP_OVERRIDE;
   void show(std::ostream &out) const { out << "GEM restraint"; }
+
+  //! \return Information for writing to RMF files
+  RestraintInfo *get_static_info() const IMP_OVERRIDE;
+
+  //! \return Information for writing to RMF files
+  RestraintInfo *get_dynamic_info() const IMP_OVERRIDE;
+
   IMP_OBJECT_METHODS(GaussianEMRestraint);
 
  private:
+  double model_cutoff_dist_, density_cutoff_dist_;
   ParticleIndexes model_ps_;
   ParticleIndexes density_ps_;
   ParticleIndex global_sigma_;
@@ -148,6 +165,7 @@ class IMPBAYESIANEMEXPORT GaussianEMRestraint : public Restraint
   ParticleIndexes slope_ps_; //experiment
   std::map<ParticleIndex,Float> map_score_dd_;
   Float cached_score_term_; 
+  std::string density_fn_;
 
   //variables needed to tabulate the exponential
   Floats exp_grid_;
diff --git a/pyext/src/restraint.py b/pyext/src/restraint.py
index 3de2f06..02e1a18 100755
--- a/pyext/src/restraint.py
+++ b/pyext/src/restraint.py
@@ -181,6 +181,8 @@ class GaussianEMRestraintWrapper(object):
             cutoff_dist_model_data,
             slope,
             update_model, backbone_slope)
+        if target_fn != '':
+            self.gaussianEM_restraint.set_density_filename(target_fn)
 
         print('done EM setup')
         self.rs = IMP.RestraintSet(self.m, 'GaussianEMRestraint')
diff --git a/src/GaussianEMRestraint.cpp b/src/GaussianEMRestraint.cpp
index 732359e..ab49a55 100755
--- a/src/GaussianEMRestraint.cpp
+++ b/src/GaussianEMRestraint.cpp
@@ -26,7 +26,9 @@ GaussianEMRestraint::GaussianEMRestraint(Model *mdl, ParticleIndexes model_ps,
                                          Float density_cutoff_dist, Float slope,
                                          bool update_model, bool backbone_slope,
                                          std::string name)
-    : Restraint(mdl, name), model_ps_(model_ps), density_ps_(density_ps),
+    : Restraint(mdl, name), model_cutoff_dist_(model_cutoff_dist),
+      density_cutoff_dist_(density_cutoff_dist),
+      model_ps_(model_ps), density_ps_(density_ps),
       global_sigma_(global_sigma), slope_(slope), update_model_(update_model) {
 
   msize_ = model_ps.size();
@@ -281,4 +283,23 @@ ModelObjectsTemp GaussianEMRestraint::do_get_inputs() const {
   return ret;
 }
 
+RestraintInfo *GaussianEMRestraint::get_static_info() const {
+  IMP_NEW(RestraintInfo, ri, ());
+  ri->add_string("type", "IMP.bayesianem.GaussianEMRestraint");
+  if (!density_fn_.empty()) {
+    ri->add_filename("filename", density_fn_);
+  }
+  ri->add_float("model cutoff", model_cutoff_dist_);
+  ri->add_float("density cutoff", density_cutoff_dist_);
+  return ri.release();
+}
+
+RestraintInfo *GaussianEMRestraint::get_dynamic_info() const {
+  IMP_NEW(RestraintInfo, ri, ());
+  Float scale = IMP::isd::Scale(get_model(), global_sigma_).get_scale();
+  ri->add_float("global sigma", scale);
+  ri->add_float("score", get_last_score());
+  return ri.release();
+}
+
 IMPBAYESIANEM_END_NAMESPACE
-- 
GitLab