IMP  2.2.0
The Integrative Modeling Platform
simple_links.h
Go to the documentation of this file.
1 /**
2  * \file IMP/rmf/simple_links.h
3  * \brief Handle read/write of kernel::Model data from/to files.
4  *
5  * Copyright 2007-2014 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/base/Object.h>
16 #include <IMP/base/Pointer.h>
17 #include <IMP/base/object_macros.h>
18 #include <IMP/base/log_macros.h>
19 #include <IMP/kernel/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 {
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) {
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, kernel::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  base::Vector<base::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();
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  base::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  base::Vector<base::Pointer<O> > create(RMF::NodeConstHandle rt,
81  kernel::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();
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  base::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 base::Vector<base::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  IMP_FOREACH(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.",
116  ValueException);
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 {
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) {
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 base::Vector<base::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 */
A nullptr-initialized pointer to an IMP Object.
A smart pointer to a reference counted object.
Definition: base/Pointer.h:87
#define IMP_LOG_TERSE(expr)
Logging and error reporting support.
Storage of a model, its restraints, constraints and particles.
#define IMP_OBJECT_LOG
Set the log level to the object's log level.
Handle read/write of kernel::Model data from/to files.
#define IMP_THROW(message, exception_name)
Throw an exception with a message.
Various general useful macros for IMP.
#define IMP_FAILURE(message)
A runtime failure for IMP.
A shared base class to help in debugging and things.
#define IMP_LOG_VERBOSE(expr)
Class for storing model, its restraints, constraints, and particles.
Definition: kernel/Model.h:72