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