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