home
about
news
download
doc
source
systems
tests
bugs
contact
IMP Reference Guide
2.14.0
The Integrative Modeling Platform
IMP Manual
Reference Guide
Tutorial Index
Modules
Classes
Examples
include
IMP
version 2.14.0
decorator_macros.h
Go to the documentation of this file.
1
/**
2
* \file IMP/decorator_macros.h
3
* \brief Various general useful macros for IMP.
4
*
5
* Copyright 2007-2020 IMP Inventors. All rights reserved.
6
*
7
*/
8
9
#ifndef IMPKERNEL_DECORATOR_MACROS_H
10
#define IMPKERNEL_DECORATOR_MACROS_H
11
#include <IMP/kernel_config.h>
12
#include "
particle_index.h
"
13
#include "
Particle.h
"
14
#include "
Decorator.h
"
15
#include <
IMP/check_macros.h
>
16
#include <
IMP/log_macros.h
>
17
#include <
IMP/showable_macros.h
>
18
#include <
IMP/warning_macros.h
>
19
20
21
22
/** Implement the needed methods for a decorator based on
23
- setup_particle()
24
- get_is_setup()
25
methods that you provide.
26
*/
27
#define IMP_DECORATOR_METHODS(Name, Parent) \
28
public: \
29
/* Should be private but SWIG accesses it through the
30
comparison
31
macros*/
IMP_NO_DOXYGEN( \
32
typedef Parent ParentDecorator); \
33
Name() : Parent() {} \
34
Name(::IMP::Model *m, ::IMP::ParticleIndex id) \
35
: Parent(m, id) { \
36
IMP_INTERNAL_CHECK( \
37
get_is_setup(m, id), \
38
"Particle " << m->get_particle_name(id) \
39
<< " missing required attributes for decorator " \
40
<< #Name); \
41
} \
42
explicit Name(const IMP::ParticleAdaptor &d) : Parent(d) { \
43
IMP_INTERNAL_CHECK( \
44
get_is_setup(d.get_model(), d.get_particle_index()), \
45
"Particle " << d.get_model()->get_particle_name( \
46
d.get_particle_index()) \
47
<< " missing required attributes for decorator " \
48
<< #Name); \
49
} \
50
static bool get_is_setup(const IMP::ParticleAdaptor &p) { \
51
return get_is_setup(p.get_model(), p.get_particle_index()); \
52
} \
53
IMP_SHOWABLE(Name)
54
55
56
57
/** Implement the needed methods for a decorator based on
58
- setup_particle()
59
- get_is_setup()
60
methods that you provide.
61
*/
62
#define IMP_DECORATOR_WITH_TRAITS_METHODS(Name, Parent, TraitsType, \
63
traits_name, default_traits) \
64
private: \
65
TraitsType traits_; \
66
\
67
public: \
68
typedef TraitsType DecoratorTraits; \
69
const DecoratorTraits &get_decorator_traits() const { return traits_; } \
70
static const DecoratorTraits &get_default_decorator_traits() { \
71
static TraitsType dt = default_traits; \
72
return dt; \
73
} \
74
/* Should be private but SWIG accesses it through the
75
comparison
76
macros*/
IMP_NO_DOXYGEN( \
77
typedef Parent ParentDecorator); \
78
IMP_NO_DOXYGEN(typedef boost::true_type DecoratorHasTraits); \
79
Name() : Parent() {} \
80
Name(::IMP::Model *m, ::IMP::ParticleIndex id, \
81
const TraitsType &tr = default_traits) \
82
: Parent(m, id), traits_(tr) { \
83
IMP_INTERNAL_CHECK( \
84
get_is_setup(m, id, tr), \
85
"Particle " << m->get_particle_name(id) \
86
<< " missing required attributes for decorator " \
87
<< #Name); \
88
} \
89
explicit Name(const IMP::ParticleAdaptor &d, \
90
const TraitsType &tr = default_traits) \
91
: Parent(d), traits_(tr) { \
92
IMP_INTERNAL_CHECK( \
93
get_is_setup(d.get_model(), d.get_particle_index(), tr), \
94
"Particle " << d.get_model()->get_particle_name( \
95
d.get_particle_index()) \
96
<< " missing required attributes for decorator " \
97
<< #Name); \
98
} \
99
static bool get_is_setup(const IMP::ParticleAdaptor &p, \
100
const TraitsType &tr = default_traits) { \
101
return get_is_setup(p.get_model(), p.get_particle_index(), tr); \
102
} \
103
IMP_SHOWABLE(Name)
104
105
/** Decorators need to be able to be set up from Particles, ParticleIndexes
106
and other Decorators. To help keep things uniform, we provide macros
107
to declare the setup functions. These macros expect that an appropriate
108
`do_setup_particle(Model *, ParticleIndex, args...)` function is
109
defined.
110
*/
111
#define IMP_DECORATOR_SETUP_0(Name) \
112
/** Setup the particle so it can be used with this decorator. */
\
113
static Name setup_particle(Model *m, ParticleIndex pi) { \
114
IMP_USAGE_CHECK(!get_is_setup(m, pi), \
115
"Particle " << m->get_particle_name(pi) \
116
<< " already set up as " << #Name); \
117
do_setup_particle(m, pi); \
118
return Name(m, pi); \
119
} \
120
static Name setup_particle(IMP::ParticleAdaptor decorator) { \
121
return setup_particle(decorator.get_model(), \
122
decorator.get_particle_index()); \
123
}
124
/** \see IMP_DECORATOR_SETUP_0() */
125
#define IMP_DECORATOR_SETUP_1(Name, FirstArgumentType, first_argument_name) \
126
/** Setup the particle so that it can be used with this decorator */
\
127
static Name setup_particle(Model *m, ParticleIndex pi, \
128
FirstArgumentType first_argument_name) { \
129
IMP_USAGE_CHECK(!get_is_setup(m, pi), \
130
"Particle " << m->get_particle_name(pi) \
131
<< " already set up as " << #Name); \
132
do_setup_particle(m, pi, first_argument_name); \
133
return Name(m, pi); \
134
} \
135
/** \see setup_particle(m, pi, first_argument_name) */
\
136
static Name setup_particle(IMP::ParticleAdaptor decorator, \
137
FirstArgumentType first_argument_name) { \
138
return setup_particle(decorator.get_model(), \
139
decorator.get_particle_index(), \
140
first_argument_name); \
141
}
142
143
/** \see IMP_DECORATOR_SETUP_0() */
144
#define IMP_DECORATOR_SETUP_2(Name, FirstArgumentType, first_argument_name, \
145
SecondArgumentType, second_argument_name) \
146
/** Setup the particle so it can be used with this decorator. */
\
147
static Name setup_particle(Model *m, ParticleIndex pi, \
148
FirstArgumentType first_argument_name, \
149
SecondArgumentType second_argument_name) { \
150
IMP_USAGE_CHECK(!get_is_setup(m, pi), \
151
"Particle " << m->get_particle_name(pi) \
152
<< " already set up as " << #Name); \
153
do_setup_particle(m, pi, first_argument_name, second_argument_name); \
154
return Name(m, pi); \
155
} \
156
static Name setup_particle(IMP::ParticleAdaptor decorator, \
157
FirstArgumentType first_argument_name, \
158
SecondArgumentType second_argument_name) { \
159
return setup_particle(decorator.get_model(), \
160
decorator.get_particle_index(), first_argument_name, \
161
second_argument_name); \
162
}
163
/** \see IMP_DECORATOR_SETUP_0() */
164
#define IMP_DECORATOR_SETUP_3(Name, FirstArgumentType, first_argument_name, \
165
SecondArgumentType, second_argument_name, \
166
ThirdArgumentType, third_argument_name) \
167
/** Setup the particle so it can be used with this decorator. */
\
168
static Name setup_particle(Model *m, ParticleIndex pi, \
169
FirstArgumentType first_argument_name, \
170
SecondArgumentType second_argument_name, \
171
ThirdArgumentType third_argument_name) { \
172
IMP_USAGE_CHECK(!get_is_setup(m, pi), \
173
"Particle " << m->get_particle_name(pi) \
174
<< " already set up as " << #Name); \
175
do_setup_particle(m, pi, first_argument_name, second_argument_name, \
176
third_argument_name); \
177
return Name(m, pi); \
178
} \
179
static Name setup_particle(IMP::ParticleAdaptor decorator, \
180
FirstArgumentType first_argument_name, \
181
SecondArgumentType second_argument_name, \
182
ThirdArgumentType third_argument_name) { \
183
return setup_particle(decorator.get_model(), \
184
decorator.get_particle_index(), first_argument_name, \
185
second_argument_name, third_argument_name); \
186
}
187
/** \see IMP_DECORATOR_SETUP_0() */
188
#define IMP_DECORATOR_SETUP_4(Name, FirstArgumentType, first_argument_name, \
189
SecondArgumentType, second_argument_name, \
190
ThirdArgumentType, third_argument_name, \
191
FourthArgumentType, fourth_argument_name) \
192
/** Setup the particle so it can be used with this decorator. */
\
193
static Name setup_particle(Model *m, ParticleIndex pi, \
194
FirstArgumentType first_argument_name, \
195
SecondArgumentType second_argument_name, \
196
ThirdArgumentType third_argument_name, \
197
FourthArgumentType fourth_argument_name) { \
198
IMP_USAGE_CHECK(!get_is_setup(m, pi), \
199
"Particle " << m->get_particle_name(pi) \
200
<< " already set up as " << #Name); \
201
do_setup_particle(m, pi, first_argument_name, second_argument_name, \
202
third_argument_name, fourth_argument_name); \
203
return Name(m, pi); \
204
} \
205
static Name setup_particle(IMP::ParticleAdaptor decorator, \
206
FirstArgumentType first_argument_name, \
207
SecondArgumentType second_argument_name, \
208
ThirdArgumentType third_argument_name, \
209
FourthArgumentType fourth_argument_name) { \
210
return setup_particle(decorator.get_model(), \
211
decorator.get_particle_index(), first_argument_name, \
212
second_argument_name, third_argument_name, \
213
fourth_argument_name); \
214
}
215
216
/** \see IMP_DECORATOR_SETUP_0() */
217
#define IMP_DECORATOR_SETUP_5(Name, \
218
FirstArgumentType, first_argument_name, \
219
SecondArgumentType, second_argument_name, \
220
ThirdArgumentType, third_argument_name, \
221
FourthArgumentType, fourth_argument_name, \
222
FifthArgumentType, fifth_argument_name) \
223
/** Setup the particle so it can be used with this decorator. */
\
224
static Name setup_particle(Model *m, ParticleIndex pi, \
225
FirstArgumentType first_argument_name, \
226
SecondArgumentType second_argument_name, \
227
ThirdArgumentType third_argument_name, \
228
FourthArgumentType fourth_argument_name, \
229
FifthArgumentType fifth_argument_name) { \
230
IMP_USAGE_CHECK(!get_is_setup(m, pi), \
231
"Particle " << m->get_particle_name(pi) \
232
<< " already set up as " << #Name); \
233
do_setup_particle(m, pi, first_argument_name, second_argument_name, \
234
third_argument_name, fourth_argument_name, \
235
fifth_argument_name); \
236
return Name(m, pi); \
237
} \
238
static Name setup_particle(IMP::ParticleAdaptor decorator, \
239
FirstArgumentType first_argument_name, \
240
SecondArgumentType second_argument_name, \
241
ThirdArgumentType third_argument_name, \
242
FourthArgumentType fourth_argument_name, \
243
FifthArgumentType fifth_argument_name) { \
244
return setup_particle(decorator.get_model(), \
245
decorator.get_particle_index(), first_argument_name, \
246
second_argument_name, third_argument_name, \
247
fourth_argument_name, fifth_argument_name); \
248
}
249
250
/** Decorators need to be able to be set up from Particles, ParticleIndexes
251
and other Decorators. To help keep things uniform, we provide macros
252
to declare the setup functions. These macros expect that an appropriate
253
`do_setup_particle(Model *, ParticleIndex, args...)` function is
254
defined. But any docs needed before the macro invocation.
255
*/
256
#define IMP_DECORATOR_TRAITS_SETUP_0(Name) \
257
/** Setup the particle so it can be used with this decorator. */
\
258
static Name setup_particle( \
259
Model *m, ParticleIndex pi, \
260
DecoratorTraits tr = get_default_decorator_traits()) { \
261
do_setup_particle(m, pi, tr); \
262
return Name(m, pi, tr); \
263
} \
264
static Name setup_particle( \
265
IMP::ParticleAdaptor d, \
266
DecoratorTraits tr = get_default_decorator_traits()) { \
267
do_setup_particle(d.get_model(), d.get_particle_index(), tr); \
268
return Name(d.get_model(), d.get_particle_index(), tr); \
269
}
270
/** \see IMP_DECORATOR_TRAITS_SETUP_0() */
271
#define IMP_DECORATOR_TRAITS_SETUP_1(Name, FirstArgumentType, \
272
first_argument_name) \
273
static Name setup_particle( \
274
Model *m, ParticleIndex pi, \
275
FirstArgumentType first_argument_name, \
276
DecoratorTraits tr = get_default_decorator_traits()) { \
277
do_setup_particle(m, pi, first_argument_name, tr); \
278
return Name(m, pi, tr); \
279
} \
280
static Name setup_particle( \
281
IMP::ParticleAdaptor d, FirstArgumentType first_argument_name, \
282
DecoratorTraits tr = get_default_decorator_traits()) { \
283
do_setup_particle(d.get_model(), d.get_particle_index(), \
284
first_argument_name, tr); \
285
return Name(d.get_model(), d.get_particle_index(), tr); \
286
}
287
/** \see IMP_DECORATOR_TRAITS_SETUP_0() */
288
#define IMP_DECORATOR_TRAITS_SETUP_2(Name, FirstArgumentType, \
289
first_argument_name, SecondArgumentType, \
290
second_argument_name) \
291
static Name setup_particle( \
292
Model *m, ParticleIndex pi, \
293
FirstArgumentType first_argument_name, \
294
SecondArgumentType second_argument_name, \
295
DecoratorTraits tr = get_default_decorator_traits()) { \
296
do_setup_particle(m, pi, first_argument_name, second_argument_name, tr); \
297
return Name(m, pi, tr); \
298
} \
299
static Name setup_particle( \
300
IMP::ParticleAdaptor d, FirstArgumentType first_argument_name, \
301
SecondArgumentType second_argument_name, \
302
DecoratorTraits tr = get_default_decorator_traits()) { \
303
do_setup_particle(d.get_model(), d.get_particle_index(), \
304
first_argument_name, second_argument_name, tr); \
305
return Name(d.get_model(), d.get_particle_index(), tr); \
306
}
307
308
//! Perform actions dependent on whether a particle has an attribute.
309
/** A common pattern is to check if a particle has a particular attribute,
310
do one thing if it does and another if it does not. This macro implements
311
that pattern. It requires that the method get_particle_index() return the
312
particle being used.
313
314
\param[in] AttributeKey The key for the attribute
315
\param[in] Type The type for the attribute ("Int", "Float", "String")
316
\param[in] has_action The action to take if the Particle has the attribute.
317
The attribute value is stored in the variable VALUE.
318
\param[in] not_has_action The action to take if the Particle does not have
319
the attribute.
320
\see IMP_DECORATOR_GET()
321
\see IMP_DECORATOR_GET_SET()
322
323
*/
324
#define IMP_DECORATOR_GET(AttributeKey, Type, has_action, not_has_action) \
325
do { \
326
if (get_model()->get_has_attribute(AttributeKey, get_particle_index())) { \
327
Type VALUE = \
328
get_model()->get_attribute(AttributeKey, get_particle_index()); \
329
has_action; \
330
} else { \
331
not_has_action; \
332
} \
333
} while (false)
334
335
//! Set an attribute, creating it if it does not already exist.
336
/** Another common pattern is to have an assumed value if the attribute
337
is not there. Then, you sometimes need to set the value whether it
338
is there or not.
339
\see IMP_DECORATOR_GET()
340
\see IMP_DECORATOR_GET_SET()
341
*/
342
#define IMP_DECORATOR_SET(AttributeKey, value) \
343
do { \
344
if (get_model()->get_has_attribute(AttributeKey, get_particle_index())) { \
345
get_model()->set_attribute(AttributeKey, get_particle_index(), value); \
346
} else { \
347
get_model()->add_attribute(AttributeKey, get_particle_index(), value); \
348
} \
349
} while (false)
350
351
//! Define methods for getting and setting a particular simple field
352
/** This macro defines methods to get and set a particular attribute.
353
354
\param[in] name The lower case name of the attribute
355
\param[in] AttributeKey The AttributeKey object controlling
356
the attribute.
357
\param[in] Type The type of the attribute (upper case).
358
\param[in] ReturnType The type to return from the get.
359
\see IMP_DECORATOR_GET()
360
\see IMP_DECORATOR_SET()
361
*/
362
#define IMP_DECORATOR_GET_SET(name, AttributeKey, Type, ReturnType) \
363
/** returns the value of the name attribute */
\
364
ReturnType get_##name() const { \
365
return static_cast<ReturnType> \
366
(get_model()->get_attribute(AttributeKey, get_particle_index())); \
367
} \
368
/** sets the value of the name attribute to t */
\
369
void set_##name(ReturnType t) { \
370
get_model()->set_attribute(AttributeKey, get_particle_index(), t); \
371
} \
372
IMP_REQUIRE_SEMICOLON_CLASS(getset##name)
373
374
//! Define methods for getting and setting an optional simple field.
375
/** See IMP_DECORATOR_GET_SET(). The difference is that here you can provide
376
a default value to use if the decorator does not have the attribute.
377
378
\param[in] name The lower case name of the attribute
379
\param[in] AttributeKey The expression to get the required attribute key.
380
\param[in] Type The type of the attribute (upper case).
381
\param[in] ReturnType The type to return from the get.
382
\param[in] default_value The value returned if the attribute is missing.
383
*/
384
#define IMP_DECORATOR_GET_SET_OPT(name, AttributeKey, Type, ReturnType, \
385
default_value) \
386
/** returns the value of the name attribute, or default_value if \
387
the name attribute is missing */
\
388
ReturnType get_##name() const { \
389
IMP_DECORATOR_GET(AttributeKey, Type, \
390
return static_cast<ReturnType>(VALUE), \
391
return default_value); \
392
} \
393
/** sets the name attribute to t */
\
394
void set_##name(ReturnType t) { IMP_DECORATOR_SET(AttributeKey, t); } \
395
IMP_REQUIRE_SEMICOLON_CLASS(getset_##name)
396
397
#define IMP_DECORATORS_DECL(Name, PluralName) \
398
class Name; \
399
typedef IMP::Vector<Name> PluralName
400
401
#ifndef IMP_DOXYGEN
402
#define IMP_DECORATORS_DEF(Name, PluralName) \
403
/* needed so there is no ambiguity with operator->*/
\
404
inline std::ostream &operator<<(std::ostream &out, Name n) { \
405
n.show(out); \
406
return out; \
407
}
408
#else
409
#define IMP_DECORATORS_DEF(Name, PluralName)
410
#endif
411
412
//! Define the types for storing sets of decorators
413
/** The macro defines the types PluralName and PluralNameTemp.
414
Parent is unused and remains for backward compatibility
415
*/
416
#define IMP_DECORATORS(Name, PluralName, Parent) \
417
IMP_DECORATORS_DECL(Name, PluralName); \
418
IMP_DECORATORS_DEF(Name, PluralName)
419
420
//! Define the types for storing sets of decorators
421
/** The macro defines the types PluralName and PluralNameTemp.
422
*/
423
#define IMP_DECORATORS_WITH_TRAITS(Name, PluralName, Parent) \
424
/* needed so there is no ambiguity with operator->*/
\
425
inline std::ostream &operator<<(std::ostream &out, Name n) { \
426
n.show(out); \
427
return out; \
428
} \
429
typedef IMP::Vector<Name> PluralName
430
431
432
/**
433
Declares Decorator methods that allows (privately) setting a constraint
434
and publicly getting that constraint
435
*/
436
#define IMP_CONSTRAINT_DECORATOR_DECL(Name) \
437
private: \
438
static ObjectKey get_constraint_key(); \
439
/** set a constraint associated with this decorator that applies 'before'
440
and 'after' before and after evaluation. The constraint is added as
441
a model ScoreState. If before and after are Null, the constraint is
442
reset and removed from the model list of score states.
443
*/
\
444
static void set_constraint(SingletonModifier* before, \
445
SingletonDerivativeModifier* after, Model* m, \
446
ParticleIndex pi); \
447
\
448
public: \
449
Constraint* get_constraint() const { \
450
return dynamic_cast<Constraint*>( \
451
get_particle()->get_value(get_constraint_key())); \
452
} \
453
IMP_REQUIRE_SEMICOLON_CLASS(constraint)
454
455
/**
456
Defines Decorator methods that allows (privately) setting a constraint
457
and publicly getting that constraint. The constraint is added as a
458
score state to the model.
459
*/
460
#define IMP_CONSTRAINT_DECORATOR_DEF(Name) \
461
ObjectKey Name::get_constraint_key() { \
462
static ObjectKey ret(#Name " score state"); \
463
return ret; \
464
} \
465
void Name::set_constraint(SingletonModifier* before, \
466
SingletonDerivativeModifier* after, Model* m, \
467
ParticleIndex pi) { \
468
if (!after && !before) { \
469
if (m->get_has_attribute(get_constraint_key(), pi)) { \
470
m->remove_score_state(dynamic_cast<ScoreState*>( \
471
m->get_attribute(get_constraint_key(), pi))); \
472
m->remove_attribute(get_constraint_key(), pi); \
473
} \
474
} else { \
475
Constraint* ss = new core::SingletonConstraint( \
476
before, after, m, pi, \
477
std::string(#Name "updater for ") + m->get_particle_name(pi)); \
478
m->add_attribute(get_constraint_key(), pi, ss); \
479
m->add_score_state(ss); \
480
} \
481
} \
482
IMP_REQUIRE_SEMICOLON_NAMESPACE
483
484
485
/** Register a function that can be used to check that the particle
486
is valid with respect to the decorator. The function should take
487
a Particle* as an argument and return a bool. It should throw
488
an exception if something is wrong.
489
490
This macro should only be used in a .cpp file.
491
*/
492
#define IMP_CHECK_DECORATOR(Name, function) \
493
IMP::internal::ParticleCheck Name##pc(Name::get_is_setup, function);
494
495
496
//! Create a decorator that computes some sort of summary info on a set
497
/** Examples include a centroid or a cover for a set of particles.
498
499
\param[in] Name The name for the decorator
500
\param[in] Parent the parent decorator type
501
\param[in] Members the way to pass a set of particles in
502
\param[in] SetupDoc extra documentation for setup
503
*/
504
#define IMP_SUMMARIZE_DECORATOR_DECL(Name, Parent, Members, SetupDoc) \
505
class IMPCOREEXPORT Name : public Parent { \
506
IMP_CONSTRAINT_DECORATOR_DECL(Name); \
507
private: \
508
/** Sets up Name over particles in pis */
\
509
static void do_setup_particle(Model *m, ParticleIndex pi, \
510
const ParticleIndexes &pis); \
511
/** Sets up Name over particles passed by applying the refiner
512
over the particle pi
513
*/
\
514
static void do_setup_particle(Model *m, ParticleIndex pi, \
515
Refiner *ref); \
516
\
517
public: \
518
IMP_DECORATOR_METHODS(Name, Parent); \
519
/** Sets up Name over members, and constrains Name to be
520
computed before model evaluation and to propagate derivatives
521
following model evaluation.
522
SetupDoc
523
*/
\
524
IMP_DECORATOR_SETUP_1(Name, ParticleIndexesAdaptor, members); \
525
/** Sets up Name over particles passed by applying the refiner
526
over the particle pi, and constrains Name to be computed before
527
model evaluation and to propagate derivatives following model
528
evaluation.
529
SetupDoc
530
*/
\
531
IMP_DECORATOR_SETUP_1(Name, Refiner *, refiner); \
532
static bool get_is_setup(Model *m, ParticleIndex pi) { \
533
return m->get_has_attribute(get_constraint_key(), pi); \
534
} \
535
IMP_NO_DOXYGEN(typedef boost::false_type DecoratorHasTraits); \
536
\
537
private: \
538
/* hide set methods*/
\
539
void set_coordinates() {}; \
540
void set_coordinates_are_optimized() const {} \
541
void set_coordinate() const {} \
542
void set_radius() const {} \
543
}; \
544
IMP_DECORATORS(Name, Name##s, Parent##s)
545
546
547
/** \see IMP_SUMMARIZE_DECORATOR_DECL()
548
\param[in] Name The name for the decorator
549
\param[in] Parent the parent decorator type
550
\param[in] Members the way to pass a set of particles in
551
\param[in] create_pre_modifier the statements to create the
552
SingletonModifier which computes the summary info,
553
using refiner 'ref'
554
\param[in] create_post_modifier a SingletonDerivativeModifier for
555
the derivatives of the summary back to its members,
556
using refiner 'ref'
557
*/
558
#define IMP_SUMMARIZE_DECORATOR_DEF(Name, Parent, Members, \
559
create_pre_modifier, \
560
create_post_modifier) \
561
void Name::do_setup_particle(Model *m, ParticleIndex pi, \
562
const ParticleIndexes &pis) { \
563
Refiner *ref = new FixedRefiner(IMP::get_particles(m, pis)); \
564
SingletonModifier* pre_mod = create_pre_modifier; \
565
SingletonDerivativeModifier* post_mod = create_post_modifier; \
566
if (!Parent::get_is_setup(m, pi)) Parent::setup_particle(m, pi); \
567
set_constraint(pre_mod, post_mod, m, pi); \
568
} \
569
\
570
void Name::do_setup_particle(Model *m, ParticleIndex pi, \
571
Refiner *ref) { \
572
SingletonModifier* pre_mod = create_pre_modifier; \
573
SingletonDerivativeModifier* post_mod = create_post_modifier; \
574
if (!Parent::get_is_setup(m, pi)) Parent::setup_particle(m, pi); \
575
set_constraint(pre_mod, post_mod, m, pi); \
576
} \
577
\
578
void Name::show(std::ostream &out) const { \
579
out << #Name << " at " << static_cast<Parent>(*this); \
580
} \
581
IMP_CONSTRAINT_DECORATOR_DEF(Name)
582
583
#endif
/* IMPKERNEL_DECORATOR_MACROS_H */
Decorator.h
The base class for decorators.
particle_index.h
Various general useful functions for IMP.
warning_macros.h
Various general useful macros for IMP.
log_macros.h
Logging and error reporting support.
Particle.h
Classes to handle individual model particles. (Note that implementation of inline functions is in int...
check_macros.h
Exception definitions and assertions.
showable_macros.h
Various general useful macros for IMP.