IMP  2.1.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-2013 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/SetCurrentFrame.h>
21 #include <RMF/names.h>
22 #include <RMF/decorators.h>
23 
24 IMPRMF_BEGIN_NAMESPACE
25 
26 /** Manage a link between an IMP object and an RMF node.
27 
28  \unstable{SimpleLoadLink}
29 */
30 template <class O>
31 class SimpleLoadLink : public LoadLink {
33  RMF::NodeIDs nhs_;
34 
35  protected:
36  virtual void do_load_one(RMF::NodeConstHandle nh, O *o) = 0;
37  void do_load(RMF::FileConstHandle fh) {
39  for (unsigned int i = 0; i < os_.size(); ++i) {
40  IMP_LOG_VERBOSE("Loading " << fh.get_node(nhs_[i]) << std::endl);
41  do_load_one(fh.get_node(nhs_[i]), os_[i]);
42  }
43  }
44  virtual void do_add_link(O *, RMF::NodeConstHandle) {};
45  void add_link(O *o, RMF::NodeConstHandle nh) {
46  os_.push_back(o);
47  nhs_.push_back(nh.get_id());
48  set_association(nh, o, true);
49  }
50  virtual bool get_is(RMF::NodeConstHandle nh) const = 0;
51  virtual O *do_create(RMF::NodeConstHandle nh) {IMP_FAILURE("Wrong create");}
52  virtual O *do_create(RMF::NodeConstHandle nh, kernel::Model *m) {
53  IMP_FAILURE("Wrong create");
54  }
55  SimpleLoadLink(std::string name) : LoadLink(name) {}
56 
57  public:
58  /** Create all the entities under the passed root.*/
59  base::Vector<base::Pointer<O> > create(RMF::NodeConstHandle rt) {
61  IMP_LOG_TERSE("Creating IMP objects from " << rt << std::endl);
62  RMF::SetCurrentFrame sf(rt.get_file(), RMF::ALL_FRAMES);
63  RMF::NodeConstHandles ch = rt.get_children();
65  for (unsigned int i = 0; i < ch.size(); ++i) {
66  IMP_LOG_VERBOSE("Checking " << ch[i] << std::endl);
67  if (get_is(ch[i])) {
68  IMP_LOG_VERBOSE("Adding " << ch[i] << std::endl);
69  base::Pointer<O> o = do_create(ch[i]);
70  add_link(o, ch[i]);
71  ret.push_back(o);
72  o->set_was_used(true);
73  }
74  }
75  return ret;
76  }
77 
78  /** Create all the entities under the passed root.*/
79  base::Vector<base::Pointer<O> > create(RMF::NodeConstHandle rt,
80  kernel::Model *m) {
82  IMP_LOG_TERSE("Creating Model objects from " << rt << std::endl);
83  RMF::SetCurrentFrame sf(rt.get_file(), RMF::ALL_FRAMES);
84  RMF::NodeConstHandles ch = rt.get_children();
86  for (unsigned int i = 0; i < ch.size(); ++i) {
87  IMP_LOG_VERBOSE("Checking " << ch[i] << std::endl);
88  if (get_is(ch[i])) {
89  IMP_LOG_VERBOSE("Adding " << ch[i] << std::endl);
90  base::Pointer<O> o = do_create(ch[i], m);
91  add_link(o, ch[i]);
92  ret.push_back(o);
93  o->set_was_used(true);
94  }
95  }
96  return ret;
97  }
98 
99  void link(RMF::NodeConstHandle rt,
100  const base::Vector<base::Pointer<O> > &ps) {
102  IMP_LOG_TERSE("Linking " << rt << " to " << ps << std::endl);
103 
104  RMF::SetCurrentFrame sf(rt.get_file(), RMF::ALL_FRAMES);
105  set_was_used(true);
106  RMF::NodeConstHandles ch = rt.get_children();
107  int links = 0;
108  for (unsigned int i = 0; i < ch.size(); ++i) {
109  IMP_LOG_VERBOSE("Checking " << ch[i] << std::endl);
110  if (get_is(ch[i])) {
111  IMP_LOG_VERBOSE("Linking " << ch[i] << std::endl);
112  if (ps.size() <= static_cast<unsigned int>(links)) {
113  IMP_THROW("There are too many matching hierarchies in the rmf to "
114  << "link against " << ps,
115  ValueException);
116  }
117  add_link(ps[links], ch[i]);
118  ps[links]->set_was_used(true);
119  do_add_link(ps[links], ch[i]);
120  ++links;
121  }
122  }
123  IMP_USAGE_CHECK(os_.size() == nhs_.size(),
124  "Didn't find enough matching things.");
125  IMP_USAGE_CHECK(links == static_cast<int>(ps.size()),
126  "Didn't find enough matching things. Found "
127  << links << " wanted " << ps.size());
128  }
129 };
130 
131 /** Manage a link between an IMP object and an RMF node.
132 
133  \unstable{SimpleSaveLink}
134 */
135 template <class O>
136 class SimpleSaveLink : public SaveLink {
138  RMF::NodeIDs nhs_;
139 
140  protected:
141  virtual void do_save_one(O *o, RMF::NodeHandle nh) = 0;
142  void do_save(RMF::FileHandle fh) {
143  for (unsigned int i = 0; i < os_.size(); ++i) {
144  IMP_LOG_VERBOSE("Saving to " << fh.get_node(nhs_[i]) << std::endl);
145 
146  os_[i]->set_was_used(true);
147  IMP_LOG_VERBOSE("Saving " << Showable(os_[i]) << std::endl);
148  do_save_one(os_[i], fh.get_node(nhs_[i]));
149  }
150  }
151  virtual void do_add(O *o, RMF::NodeHandle c) { add_link(o, c); }
152  virtual RMF::NodeType get_type(O *o) const = 0;
153  void add_link(O *o, RMF::NodeConstHandle nh) {
154  os_.push_back(o);
155  nhs_.push_back(nh.get_id());
156  set_association(nh, o, true);
157  }
158  SimpleSaveLink(std::string name) : SaveLink(name) {}
159 
160  public:
161  void add(RMF::NodeHandle parent, const base::Vector<base::Pointer<O> > &os) {
163  IMP_LOG_TERSE("Adding " << os << " to rmf" << std::endl);
164  RMF::FileHandle file = parent.get_file();
165  RMF::AliasFactory af(file);
166  RMF::SetCurrentFrame sf(parent.get_file(), RMF::ALL_FRAMES);
167  for (unsigned int i = 0; i < os.size(); ++i) {
168  std::string nicename = RMF::get_as_node_name(os[i]->get_name());
169  if (get_has_associated_node(file, os[i])) {
170  RMF::NodeHandle c = parent.add_child(nicename, RMF::ALIAS);
171  af.get(c).set_aliased(get_node_from_association(file, os[i]));
172  } else {
173  RMF::NodeHandle c = parent.add_child(nicename, get_type(os[i]));
174  do_add(os[i], c);
175  os[i]->set_was_used(true);
176  }
177  }
178  }
179 };
180 
181 IMPRMF_END_NAMESPACE
182 
183 #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_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
#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&#39;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.