IMP  2.0.1
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 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 <RMF/SetCurrentFrame.h>
20 #include <RMF/names.h>
21 #include <RMF/decorators.h>
22 
23 IMPRMF_BEGIN_NAMESPACE
24 
25 template <class O>
26 class SimpleLoadLink: public LoadLink {
27  base::Vector<base::Pointer<O> > os_;
28  RMF::NodeIDs nhs_;
29  IMP_PROTECTED_METHOD(virtual void, do_load_one, ( RMF::NodeConstHandle nh,
30  O *o),
31  ,=0);
33  do_load,
34  (RMF::FileConstHandle fh),,
35  {
36  for (unsigned int i=0; i< os_.size(); ++i) {
37  do_load_one(fh.get_node_from_id(nhs_[i]), os_[i]);
38  }
39  });
40  IMP_PROTECTED_METHOD(virtual void, do_add_link, (O *, RMF::NodeConstHandle),
41  ,{});
42  IMP_PROTECTED_METHOD(void, add_link,(O *o, RMF::NodeConstHandle nh), ,
43  {
44  os_.push_back(o);
45  nhs_.push_back(nh.get_id());
46  set_association(nh, o, true);
47  });
48  IMP_PROTECTED_METHOD(virtual bool, get_is,(RMF::NodeConstHandle nh),
49  const,=0);
50  IMP_PROTECTED_METHOD(virtual O*, do_create,
51  (RMF::NodeConstHandle nh), ,=0);
52  IMP_PROTECTED_CONSTRUCTOR(SimpleLoadLink, (std::string name),
53  : LoadLink(name){});
54 public:
55  /** Create all the entities under the passed root.*/
56  base::Vector<base::Pointer<O> > create(RMF::NodeConstHandle rt) {
58  RMF::SetCurrentFrame sf(rt.get_file(), 0);
59  RMF::NodeConstHandles ch= rt.get_children();
60  base::Vector<base::Pointer<O> > ret;
61  for (unsigned int i=0; i< ch.size(); ++i) {
62  IMP_LOG_VERBOSE( "Checking " << ch[i] << std::endl);
63  if (get_is(ch[i])) {
64  IMP_LOG_VERBOSE( "Adding " << ch[i] << std::endl);
65  base::Pointer<O> o=do_create(ch[i]);
66  add_link(o, ch[i]);
67  ret.push_back(o);
68  o->set_was_used(true);
69  }
70  }
71  return ret;
72  }
73  void link(RMF::NodeConstHandle rt,
74  const base::Vector<base::Pointer<O> > &ps) {
76  RMF::SetCurrentFrame sf(rt.get_file(), 0);
77  set_was_used(true);
78  RMF::NodeConstHandles ch= rt.get_children();
79  int links=0;
80  for (unsigned int i=0; i< ch.size(); ++i) {
81  IMP_LOG_VERBOSE( "Checking " << ch[i] << std::endl);
82  if (get_is(ch[i])) {
83  IMP_LOG_VERBOSE( "Linking " << ch[i] << std::endl);
84  if (ps.size() <= static_cast<unsigned int>(links)) {
85  IMP_THROW("There are too many matching hierarchies in the rmf to "
86  << "link against " << ps, ValueException);
87  }
88  add_link(ps[links], ch[i]);
89  ps[links]->set_was_used(true);
90  do_add_link(ps[links], ch[i]);
91  ++links;
92  }
93  }
94  IMP_USAGE_CHECK(os_.size()==nhs_.size(),
95  "Didn't find enough matching things.");
96  IMP_USAGE_CHECK(links==static_cast<int>(ps.size()),
97  "Didn't find enough matching things. Found "
98  << links << " wanted " << ps.size());
99  }
100 
101 };
102 
103 
104 template <class O>
105 class SimpleSaveLink: public SaveLink {
106  base::Vector<base::Pointer<O> > os_;
107  RMF::NodeIDs nhs_;
108  protected:
109  virtual void do_save_one(O *o,
110  RMF::NodeHandle nh) = 0;
111  void do_save(RMF::FileHandle fh) {
112  for (unsigned int i=0; i< os_.size(); ++i) {
113  os_[i]->set_was_used(true);
114  IMP_LOG_VERBOSE( "Saving " << Showable(os_[i])
115  << std::endl);
116  do_save_one(os_[i], fh.get_node_from_id(nhs_[i]));
117  }
118  }
119  virtual void do_add(O *o, RMF::NodeHandle c) {
120  add_link(o, c);
121  }
122  virtual RMF::NodeType get_type(O*o) const = 0;
123  void add_link(O *o, RMF::NodeConstHandle nh) {
124  os_.push_back(o);
125  nhs_.push_back(nh.get_id());
126  set_association(nh, o, true);
127  }
128  SimpleSaveLink(std::string name): SaveLink(name) {}
129  public:
130  void add(RMF::NodeHandle parent,
131  const base::Vector<base::Pointer<O> > &os) {
133  RMF::FileHandle file = parent.get_file();
134  RMF::AliasFactory af(file);
135  RMF::SetCurrentFrame sf(parent.get_file(), RMF::ALL_FRAMES);
136  for (unsigned int i=0; i< os.size(); ++i) {
137  std::string nicename= RMF::get_as_node_name(os[i]->get_name());
138  if (get_has_associated_node(file, os[i])) {
139  RMF::NodeHandle c= parent.add_child(nicename,
140  RMF::ALIAS);
141  af.get(c).set_aliased(get_node_from_association(file, os[i]));
142  } else {
143  RMF::NodeHandle c= parent.add_child(nicename,
144  get_type(os[i]));
145  do_add(os[i], c);
146  os[i]->set_was_used(true);
147  }
148  }
149  }
150 };
151 
152 IMPRMF_END_NAMESPACE
153 
154 #endif /* IMPRMF_SIMPLE_LINKS_H */