IMP logo
IMP Reference Guide  2.20.2
The Integrative Modeling Platform
simple_links.h
Go to the documentation of this file.
1 /**
2  * \file IMP/rmf/simple_links.h
3  * \brief Manage links between IMP objects and RMF nodes.
4  *
5  * Copyright 2007-2022 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPRMF_SIMPLE_LINKS_H
10 #define IMPRMF_SIMPLE_LINKS_H
11 
12 #include <IMP/rmf/rmf_config.h>
13 #include "links.h"
14 #include "associations.h"
15 #include <IMP/Object.h>
16 #include <IMP/Pointer.h>
17 #include <IMP/object_macros.h>
18 #include <IMP/log_macros.h>
19 #include <IMP/Model.h>
20 #include <RMF/RestoreCurrentFrame.h>
21 #include <RMF/SetCurrentFrame.h>
22 #include <RMF/names.h>
23 #include <RMF/decorators.h>
24 
25 IMPRMF_BEGIN_NAMESPACE
26 
27 /** Manage a link between an IMP object and an RMF node.
28 
29  \unstable{SimpleLoadLink}
30 */
31 template <class O>
32 class SimpleLoadLink : public LoadLink {
33  Vector<Pointer<O> > os_;
34  RMF::NodeIDs nhs_;
35 
36  protected:
37  virtual void do_load_one(RMF::NodeConstHandle nh, O *o) = 0;
38  void do_load(RMF::FileConstHandle fh) override {
40  for (unsigned int i = 0; i < os_.size(); ++i) {
41  IMP_LOG_VERBOSE("Loading " << fh.get_node(nhs_[i]) << std::endl);
42  do_load_one(fh.get_node(nhs_[i]), os_[i]);
43  }
44  }
45  virtual void do_add_link(O *, RMF::NodeConstHandle) {};
46  void add_link(O *o, RMF::NodeConstHandle nh) {
47  os_.push_back(o);
48  nhs_.push_back(nh.get_id());
49  set_association(nh, o, true);
50  }
51  virtual bool get_is(RMF::NodeConstHandle nh) const = 0;
52  virtual O *do_create(RMF::NodeConstHandle) { IMP_FAILURE("Wrong create"); }
53  virtual O *do_create(RMF::NodeConstHandle, Model *) {
54  IMP_FAILURE("Wrong create");
55  }
56  SimpleLoadLink(std::string name) : LoadLink(name) {}
57 
58  public:
59  /** Create all the entities under the passed root.*/
60  Vector<Pointer<O> > create(RMF::NodeConstHandle rt) {
62  IMP_LOG_TERSE("Creating IMP objects from " << rt << std::endl);
63  RMF::SetCurrentFrame sf(rt.get_file(), RMF::FrameID(0));
64  RMF::NodeConstHandles ch = rt.get_children();
65  Vector<Pointer<O> > ret;
66  for (unsigned int i = 0; i < ch.size(); ++i) {
67  IMP_LOG_VERBOSE("Checking " << ch[i] << std::endl);
68  if (get_is(ch[i])) {
69  IMP_LOG_VERBOSE("Adding " << ch[i] << std::endl);
70  Pointer<O> o = do_create(ch[i]);
71  add_link(o, ch[i]);
72  ret.push_back(o);
73  o->set_was_used(true);
74  }
75  }
76  return ret;
77  }
78 
79  /** Create all the entities under the passed root.*/
80  Vector<Pointer<O> > create(RMF::NodeConstHandle rt,
81  Model *m) {
83  IMP_LOG_TERSE("Creating Model objects from " << rt << std::endl);
84  RMF::SetCurrentFrame sf(rt.get_file(), RMF::FrameID(0));
85  RMF::NodeConstHandles ch = rt.get_children();
86  Vector<Pointer<O> > ret;
87  for (unsigned int i = 0; i < ch.size(); ++i) {
88  IMP_LOG_VERBOSE("Checking " << ch[i] << std::endl);
89  if (get_is(ch[i])) {
90  IMP_LOG_VERBOSE("Adding " << ch[i] << std::endl);
91  Pointer<O> o = do_create(ch[i], m);
92  add_link(o, ch[i]);
93  ret.push_back(o);
94  o->set_was_used(true);
95  }
96  }
97  return ret;
98  }
99 
100  void link(RMF::NodeConstHandle rt,
101  const Vector<Pointer<O> > &ps) {
103  IMP_LOG_TERSE("Linking " << rt << " to " << ps << std::endl);
104 
105  RMF::RestoreCurrentFrame sf(rt.get_file());
106  set_was_used(true);
107  RMF::NodeConstHandles chs = rt.get_children();
108  RMF::NodeConstHandles matching_chs;
109  for(RMF::NodeConstHandle ch : rt.get_children()) {
110  IMP_LOG_VERBOSE("Checking " << ch << std::endl);
111  if (get_is(ch)) matching_chs.push_back(ch);
112  }
113  if (matching_chs.size() != ps.size()) {
114  IMP_THROW("Founding " << matching_chs.size() << " matching nodes "
115  << "but passed " << ps.size() << " to match with.",
117  }
118  for (unsigned int i = 0; i < matching_chs.size(); ++i) {
119  IMP_LOG_VERBOSE("Linking " << matching_chs[i] << std::endl);
120  add_link(ps[i], matching_chs[i]);
121  ps[i]->set_was_used(true);
122  do_add_link(ps[i], matching_chs[i]);
123  }
124  }
125 };
126 
127 /** Manage a link between an IMP object and an RMF node.
128 
129  \unstable{SimpleSaveLink}
130 */
131 template <class O>
132 class SimpleSaveLink : public SaveLink {
133  Vector<Pointer<O> > os_;
134  RMF::NodeIDs nhs_;
135 
136  protected:
137  virtual void do_save_one(O *o, RMF::NodeHandle nh) = 0;
138  void do_save(RMF::FileHandle fh) override {
139  for (unsigned int i = 0; i < os_.size(); ++i) {
140  IMP_LOG_VERBOSE("Saving to " << fh.get_node(nhs_[i]) << std::endl);
141 
142  os_[i]->set_was_used(true);
143  IMP_LOG_VERBOSE("Saving " << Showable(os_[i]) << std::endl);
144  do_save_one(os_[i], fh.get_node(nhs_[i]));
145  }
146  }
147  virtual void do_add(O *o, RMF::NodeHandle c) { add_link(o, c); }
148  virtual RMF::NodeType get_type(O *o) const = 0;
149  void add_link(O *o, RMF::NodeConstHandle nh) {
150  os_.push_back(o);
151  nhs_.push_back(nh.get_id());
152  set_association(nh, o, true);
153  }
154  SimpleSaveLink(std::string name) : SaveLink(name) {}
155 
156  public:
157  void add(RMF::NodeHandle parent, const Vector<Pointer<O> > &os) {
159  IMP_LOG_TERSE("Adding " << os << " to rmf" << std::endl);
160  RMF::FileHandle file = parent.get_file();
161  RMF::decorator::AliasFactory af(file);
162  for (unsigned int i = 0; i < os.size(); ++i) {
163  std::string nicename = RMF::get_as_node_name(os[i]->get_name());
164  if (get_has_associated_node(file, os[i])) {
165  RMF::NodeHandle c = parent.add_child(nicename, RMF::ALIAS);
166  af.get(c).set_aliased(get_node_from_association(file, os[i]));
167  } else {
168  RMF::NodeHandle c = parent.add_child(nicename, get_type(os[i]));
169  do_add(os[i], c);
170  os[i]->set_was_used(true);
171  }
172  }
173  }
174 };
175 
176 IMPRMF_END_NAMESPACE
177 
178 #endif /* IMPRMF_SIMPLE_LINKS_H */
Helper macros for implementing IMP Objects.
#define IMP_FAILURE(message)
A runtime failure for IMP.
Definition: check_macros.h:72
#define IMP_OBJECT_LOG
Set the log level to the object's log level.
Definition: log_macros.h:284
Storage of a model, its restraints, constraints and particles.
#define IMP_LOG_VERBOSE(expr)
Definition: log_macros.h:83
A more IMP-like version of the std::vector.
Definition: Vector.h:42
#define IMP_LOG_TERSE(expr)
Definition: log_macros.h:72
A smart pointer to a reference counted object.
Definition: Pointer.h:87
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:86
Logging and error reporting support.
#define IMP_THROW(message, exception_name)
Throw an exception with a message.
Definition: check_macros.h:50
Track associations between an RMF file and native objects.
A nullptr-initialized pointer to an IMP Object.
A shared base class to help in debugging and things.
An exception for an invalid value being passed to IMP.
Definition: exception.h:136
Helper class to aid in output of IMP classes to streams.
Definition: Showable.h:25