| Home | Trees | Indices | Help |
|---|
|
|
object --+
|
??.instance --+
|
HierarchicalDataMap
A data map designed to help create hierarchies with complicated
shared data requirements.
To explain what exactly this class is supposed to do, consider the
following mover hierarchy (which comes from the loop modeling framework and
was the actual motivation for this code):
<pre>
A ~
| ~
+-------+------+------+------+ ~
| | | | | ~
B C D E F ~
/ \ / \ / \ ~
G H I J K L ~
| | / /|\ ~
M N O P Q R ~
</pre>
To explain this diagram a little, each letter corresponds to a mover. The
movers are mostly of different classes, although they all inherit from the
same abstract base class. This whole hierarchy is constructed by A. When
A.apply() is called, it calls B.apply(), C.apply(), D.apply(), E.apply(),
and F.apply() in that order. When B.apply() is called, it calls G.apply()
and H.apply(), and so on. If you are interested in seeing exactly how this
hierarchy is implemented, here are the classes the letters correspond to:
A. protocols::loop_modeling::LoopModeler
B. protocols::loop_modeling::utilities::PrepareForCentroid
C. protocols::loop_modeling::LoopBuilder
D. protocols::loop_modeling::LoopProtocol
E. protocols::loop_modeling::utilities::PrepareForFullatom
F. protocols::loop_modeling::LoopProtocol
G. protocols::kinematic_closure::KicMover
H. protocols::loop_modeling::refiners::MinimizationRefiner
I. protocols::loop_modeling::utilities::LoopMoverGroup
J. protocols::loop_modeling::utilities::LoopMoverGroup
K. protocols::loop_modeling::utilities::LoopMoverGroup
L. protocols::loop_modeling::utilities::LoopMoverGroup
M. protocols::kinematic_closure::KicMover
N. protocols::loop_modeling::refiners::MinimizationRefiner
O. protocols::kinematic_closure::KicMover
P. protocols::loop_modeling::refiners::RepackingRefiner
Q. protocols::loop_modeling::refiners::RotamerTrialsRefiner
R. protocols::loop_modeling::refiners::MinimizationRefiner
This hierarchy had the following shared data requirements:
1. Everything in the hierarchy has to share a loops object.
2. A has to know about centroid and fullatom score functions.
3. B, D, and all their children have to use the centroid score function.
4. F and all its children have to use the fullatom score function.
5. A has to provide a default task factory to all its children.
6. Only P and Q have any use for a task factory, and they may want to
override the default provided by A.
Many of these requirements have a similar form: movers higher in the
hierarchy must be able to provide default attributes to all their children,
and movers lower in the hierarchy must be able to override those defaults.
This class supports that pattern by being a data map that asks its parent
for missing values.
More specifically, this class stores two pieces of information: a DataMap
and a pointer to a parent HierarchicalDataMap. The DataMap provides the
basic attribute lookup capability: it's just a string to owning pointer
map. The parent pointer allows the HierarchicalDataMap to recursively
access default values from parent maps for key that aren't in it's own
DataMap.
Going back to the example hierarchy above: A needs to provide a default
task factory that P and Q can override. To accomplish this, we start by
giving all the objects in the hierarchy HierarchicalDataMap objects that
have been properly connected to their parents. Then A sets the default
"task_ops" attribute in it's own HierarchicalDataMap as soon as it's
constructed. P and Q provide convenience methods like get_task_ops() and
set_task_ops() to allow the "task_ops" field of their HierarchicalDataMaps
to be accessed publicly. Since the data maps in P and Q are connected to A
via L and F, the attributes stored in A will serve as defaults for P and Q.
It's worth noting that in this example, it is also possible to get the
right behavior by putting a task operations data member in the shared base
class. However, this is a poor solution for two reasons. The first is
that it requires many classes that have no need for task operations to have
a task operations attribute. Second, it requires that you write the
default logic for each attribute that needs it, which is a duplication of
effort. Using HierarchicalDataMap addresses both of these problems.
When using this class to help build a hierarchy like the one illustrated
above, you might find it useful to move public accessor methods (like
get_task_ops() and set_task_ops() in P and Q) into a reusable mixin class.
This takes a little bit of C++ template magic, because you have to use the
"curiously recurring template pattern" (CRTP). But you can see how this
works by looking at protocols::loop_modeling::RepackingLoopMover (P in the
example) and protocols::loop_modeling::utilites::TaskFactoryMixin (the
mixin class).
|
|||
|
|||
|
|||
|
|||
|
|||
|
Inherited from Inherited from |
|||
|
|||
__instance_size__ = 32
|
|||
|
|||
|
Inherited from |
|||
|
|||
__init__( (object)arg1) -> None :
C++ signature :
void __init__(_object*)
__init__( (object)arg1, (HierarchicalDataMap)) -> None :
A data map designed to help create hierarchies with complicated
shared data requirements.
To explain what exactly this class is supposed to do, consider the
following mover hierarchy (which comes from the loop modeling framework and
was the actual motivation for this code):
<pre>
A ~
| ~
+-------+------+------+------+ ~
| | | | | ~
B C D E F ~
/ \ / \ / \ ~
G H I J K L ~
| | / /|\ ~
M N O P Q R ~
</pre>
To explain this diagram a little, each letter corresponds to a mover. The
movers are mostly of different classes, although they all inherit from the
same abstract base class. This whole hierarchy is constructed by A. When
A.apply() is called, it calls B.apply(), C.apply(), D.apply(), E.apply(),
and F.apply() in that order. When B.apply() is called, it calls G.apply()
and H.apply(), and so on. If you are interested in seeing exactly how this
hierarchy is implemented, here are the classes the letters correspond to:
A. protocols::loop_modeling::LoopModeler
B. protocols::loop_modeling::utilities::PrepareForCentroid
C. protocols::loop_modeling::LoopBuilder
D. protocols::loop_modeling::LoopProtocol
E. protocols::loop_modeling::utilities::PrepareForFullatom
F. protocols::loop_modeling::LoopProtocol
G. protocols::kinematic_closure::KicMover
H. protocols::loop_modeling::refiners::MinimizationRefiner
I. protocols::loop_modeling::utilities::LoopMoverGroup
J. protocols::loop_modeling::utilities::LoopMoverGroup
K. protocols::loop_modeling::utilities::LoopMoverGroup
L. protocols::loop_modeling::utilities::LoopMoverGroup
M. protocols::kinematic_closure::KicMover
N. protocols::loop_modeling::refiners::MinimizationRefiner
O. protocols::kinematic_closure::KicMover
P. protocols::loop_modeling::refiners::RepackingRefiner
Q. protocols::loop_modeling::refiners::RotamerTrialsRefiner
R. protocols::loop_modeling::refiners::MinimizationRefiner
This hierarchy had the following shared data requirements:
1. Everything in the hierarchy has to share a loops object.
2. A has to know about centroid and fullatom score functions.
3. B, D, and all their children have to use the centroid score function.
4. F and all its children have to use the fullatom score function.
5. A has to provide a default task factory to all its children.
6. Only P and Q have any use for a task factory, and they may want to
override the default provided by A.
Many of these requirements have a similar form: movers higher in the
hierarchy must be able to provide default attributes to all their children,
and movers lower in the hierarchy must be able to override those defaults.
This class supports that pattern by being a data map that asks its parent
for missing values.
More specifically, this class stores two pieces of information: a DataMap
and a pointer to a parent HierarchicalDataMap. The DataMap provides the
basic attribute lookup capability: it's just a string to owning pointer
map. The parent pointer allows the HierarchicalDataMap to recursively
access default values from parent maps for key that aren't in it's own
DataMap.
Going back to the example hierarchy above: A needs to provide a default
task factory that P and Q can override. To accomplish this, we start by
giving all the objects in the hierarchy HierarchicalDataMap objects that
have been properly connected to their parents. Then A sets the default
"task_ops" attribute in it's own HierarchicalDataMap as soon as it's
constructed. P and Q provide convenience methods like get_task_ops() and
set_task_ops() to allow the "task_ops" field of their HierarchicalDataMaps
to be accessed publicly. Since the data maps in P and Q are connected to A
via L and F, the attributes stored in A will serve as defaults for P and Q.
It's worth noting that in this example, it is also possible to get the
right behavior by putting a task operations data member in the shared base
class. However, this is a poor solution for two reasons. The first is
that it requires many classes that have no need for task operations to have
a task operations attribute. Second, it requires that you write the
default logic for each attribute that needs it, which is a duplication of
effort. Using HierarchicalDataMap addresses both of these problems.
When using this class to help build a hierarchy like the one illustrated
above, you might find it useful to move public accessor methods (like
get_task_ops() and set_task_ops() in P and Q) into a reusable mixin class.
This takes a little bit of C++ template magic, because you have to use the
"curiously recurring template pattern" (CRTP). But you can see how this
works by looking at protocols::loop_modeling::RepackingLoopMover (P in the
example) and protocols::loop_modeling::utilites::TaskFactoryMixin (the
mixin class).
C++ signature :
void __init__(_object*,basic::datacache::HierarchicalDataMap)
|
helper for pickle
|
set_parent( (HierarchicalDataMap)arg1, (HierarchicalDataMapCAP)parent) -> None :
Set a parent for this data map.
If a key is requested and not found in this data map, the search
will continue (recursively) in the parent. Having a parent is optional.
C++ signature :
void set_parent(basic::datacache::HierarchicalDataMap {lvalue},boost::weak_ptr<basic::datacache::HierarchicalDataMap const>)
|
unset_parent( (HierarchicalDataMap)arg1) -> None :
Unset the parent for this data map.
When a data map doesn't have a parent, it will only return keys
it is holding itself. Having a parent is optional.
C++ signature :
void unset_parent(basic::datacache::HierarchicalDataMap {lvalue})
|
| Home | Trees | Indices | Help |
|---|
| Generated by Epydoc 3.0.1 on Sat Jun 6 00:11:01 2015 | http://epydoc.sourceforge.net |