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