home
about
news
download
doc
source
systems
tests
bugs
contact
IMP Reference Guide
2.13.0
The Integrative Modeling Platform
IMP Manual
Reference Guide
Tutorial Index
Modules
Classes
Examples
include
IMP
version 2.13.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
/** Decorators need to be able to be set up from Particles, ParticleIndexes
217
and other Decorators. To help keep things uniform, we provide macros
218
to declare the setup functions. These macros expect that an appropriate
219
`do_setup_particle(Model *, ParticleIndex, args...)` function is
220
defined. But any docs needed before the macro invocation.
221
*/
222
#define IMP_DECORATOR_TRAITS_SETUP_0(Name) \
223
/** Setup the particle so it can be used with this decorator. */
\
224
static Name setup_particle( \
225
Model *m, ParticleIndex pi, \
226
DecoratorTraits tr = get_default_decorator_traits()) { \
227
do_setup_particle(m, pi, tr); \
228
return Name(m, pi, tr); \
229
} \
230
static Name setup_particle( \
231
IMP::ParticleAdaptor d, \
232
DecoratorTraits tr = get_default_decorator_traits()) { \
233
do_setup_particle(d.get_model(), d.get_particle_index(), tr); \
234
return Name(d.get_model(), d.get_particle_index(), tr); \
235
}
236
/** \see IMP_DECORATOR_TRAITS_SETUP_0() */
237
#define IMP_DECORATOR_TRAITS_SETUP_1(Name, FirstArgumentType, \
238
first_argument_name) \
239
static Name setup_particle( \
240
Model *m, ParticleIndex pi, \
241
FirstArgumentType first_argument_name, \
242
DecoratorTraits tr = get_default_decorator_traits()) { \
243
do_setup_particle(m, pi, first_argument_name, tr); \
244
return Name(m, pi, tr); \
245
} \
246
static Name setup_particle( \
247
IMP::ParticleAdaptor d, FirstArgumentType first_argument_name, \
248
DecoratorTraits tr = get_default_decorator_traits()) { \
249
do_setup_particle(d.get_model(), d.get_particle_index(), \
250
first_argument_name, tr); \
251
return Name(d.get_model(), d.get_particle_index(), tr); \
252
}
253
/** \see IMP_DECORATOR_TRAITS_SETUP_0() */
254
#define IMP_DECORATOR_TRAITS_SETUP_2(Name, FirstArgumentType, \
255
first_argument_name, SecondArgumentType, \
256
second_argument_name) \
257
static Name setup_particle( \
258
Model *m, ParticleIndex pi, \
259
FirstArgumentType first_argument_name, \
260
SecondArgumentType second_argument_name, \
261
DecoratorTraits tr = get_default_decorator_traits()) { \
262
do_setup_particle(m, pi, first_argument_name, second_argument_name, tr); \
263
return Name(m, pi, tr); \
264
} \
265
static Name setup_particle( \
266
IMP::ParticleAdaptor d, FirstArgumentType first_argument_name, \
267
SecondArgumentType second_argument_name, \
268
DecoratorTraits tr = get_default_decorator_traits()) { \
269
do_setup_particle(d.get_model(), d.get_particle_index(), \
270
first_argument_name, second_argument_name, tr); \
271
return Name(d.get_model(), d.get_particle_index(), tr); \
272
}
273
274
//! Perform actions dependent on whether a particle has an attribute.
275
/** A common pattern is to check if a particle has a particular attribute,
276
do one thing if it does and another if it does not. This macro implements
277
that pattern. It requires that the method get_particle_index() return the
278
particle being used.
279
280
\param[in] AttributeKey The key for the attribute
281
\param[in] Type The type for the attribute ("Int", "Float", "String")
282
\param[in] has_action The action to take if the Particle has the attribute.
283
The attribute value is stored in the variable VALUE.
284
\param[in] not_has_action The action to take if the Particle does not have
285
the attribute.
286
\see IMP_DECORATOR_GET()
287
\see IMP_DECORATOR_GET_SET()
288
289
*/
290
#define IMP_DECORATOR_GET(AttributeKey, Type, has_action, not_has_action) \
291
do { \
292
if (get_model()->get_has_attribute(AttributeKey, get_particle_index())) { \
293
Type VALUE = \
294
get_model()->get_attribute(AttributeKey, get_particle_index()); \
295
has_action; \
296
} else { \
297
not_has_action; \
298
} \
299
} while (false)
300
301
//! Set an attribute, creating it if it does not already exist.
302
/** Another common pattern is to have an assumed value if the attribute
303
is not there. Then, you sometimes need to set the value whether it
304
is there or not.
305
\see IMP_DECORATOR_GET()
306
\see IMP_DECORATOR_GET_SET()
307
*/
308
#define IMP_DECORATOR_SET(AttributeKey, value) \
309
do { \
310
if (get_model()->get_has_attribute(AttributeKey, get_particle_index())) { \
311
get_model()->set_attribute(AttributeKey, get_particle_index(), value); \
312
} else { \
313
get_model()->add_attribute(AttributeKey, get_particle_index(), value); \
314
} \
315
} while (false)
316
317
//! Define methods for getting and setting a particular simple field
318
/** This macro defines methods to get and set a particular attribute.
319
320
\param[in] name The lower case name of the attribute
321
\param[in] AttributeKey The AttributeKey object controlling
322
the attribute.
323
\param[in] Type The type of the attribute (upper case).
324
\param[in] ReturnType The type to return from the get.
325
\see IMP_DECORATOR_GET()
326
\see IMP_DECORATOR_SET()
327
*/
328
#define IMP_DECORATOR_GET_SET(name, AttributeKey, Type, ReturnType) \
329
/** returns the value of the name attribute */
\
330
ReturnType get_##name() const { \
331
return static_cast<ReturnType> \
332
(get_model()->get_attribute(AttributeKey, get_particle_index())); \
333
} \
334
/** sets the value of the name attribute to t */
\
335
void set_##name(ReturnType t) { \
336
get_model()->set_attribute(AttributeKey, get_particle_index(), t); \
337
} \
338
IMP_REQUIRE_SEMICOLON_CLASS(getset##name)
339
340
//! Define methods for getting and setting an optional simple field.
341
/** See IMP_DECORATOR_GET_SET(). The difference is that here you can provide
342
a default value to use if the decorator does not have the attribute.
343
344
\param[in] name The lower case name of the attribute
345
\param[in] AttributeKey The expression to get the required attribute key.
346
\param[in] Type The type of the attribute (upper case).
347
\param[in] ReturnType The type to return from the get.
348
\param[in] default_value The value returned if the attribute is missing.
349
*/
350
#define IMP_DECORATOR_GET_SET_OPT(name, AttributeKey, Type, ReturnType, \
351
default_value) \
352
/** returns the value of the name attribute, or default_value if \
353
the name attribute is missing */
\
354
ReturnType get_##name() const { \
355
IMP_DECORATOR_GET(AttributeKey, Type, \
356
return static_cast<ReturnType>(VALUE), \
357
return default_value); \
358
} \
359
/** sets the name attribute to t */
\
360
void set_##name(ReturnType t) { IMP_DECORATOR_SET(AttributeKey, t); } \
361
IMP_REQUIRE_SEMICOLON_CLASS(getset_##name)
362
363
#define IMP_DECORATORS_DECL(Name, PluralName) \
364
class Name; \
365
typedef IMP::Vector<Name> PluralName
366
367
#ifndef IMP_DOXYGEN
368
#define IMP_DECORATORS_DEF(Name, PluralName) \
369
/* needed so there is no ambiguity with operator->*/
\
370
inline std::ostream &operator<<(std::ostream &out, Name n) { \
371
n.show(out); \
372
return out; \
373
}
374
#else
375
#define IMP_DECORATORS_DEF(Name, PluralName)
376
#endif
377
378
//! Define the types for storing sets of decorators
379
/** The macro defines the types PluralName and PluralNameTemp.
380
Parent is unused and remains for backward compatibility
381
*/
382
#define IMP_DECORATORS(Name, PluralName, Parent) \
383
IMP_DECORATORS_DECL(Name, PluralName); \
384
IMP_DECORATORS_DEF(Name, PluralName)
385
386
//! Define the types for storing sets of decorators
387
/** The macro defines the types PluralName and PluralNameTemp.
388
*/
389
#define IMP_DECORATORS_WITH_TRAITS(Name, PluralName, Parent) \
390
/* needed so there is no ambiguity with operator->*/
\
391
inline std::ostream &operator<<(std::ostream &out, Name n) { \
392
n.show(out); \
393
return out; \
394
} \
395
typedef IMP::Vector<Name> PluralName
396
397
398
/**
399
Declares Decorator methods that allows (privately) setting a constraint
400
and publicly getting that constraint
401
*/
402
#define IMP_CONSTRAINT_DECORATOR_DECL(Name) \
403
private: \
404
static ObjectKey get_constraint_key(); \
405
/** set a constraint associated with this decorator that applies 'before'
406
and 'after' before and after evaluation. The constraint is added as
407
a model ScoreState. If before and after are Null, the constraint is
408
reset and removed from the model list of score states.
409
*/
\
410
static void set_constraint(SingletonModifier* before, \
411
SingletonDerivativeModifier* after, Model* m, \
412
ParticleIndex pi); \
413
\
414
public: \
415
Constraint* get_constraint() const { \
416
return dynamic_cast<Constraint*>( \
417
get_particle()->get_value(get_constraint_key())); \
418
} \
419
IMP_REQUIRE_SEMICOLON_CLASS(constraint)
420
421
/**
422
Defines Decorator methods that allows (privately) setting a constraint
423
and publicly getting that constraint. The constraint is added as a
424
score state to the model.
425
*/
426
#define IMP_CONSTRAINT_DECORATOR_DEF(Name) \
427
ObjectKey Name::get_constraint_key() { \
428
static ObjectKey ret(#Name " score state"); \
429
return ret; \
430
} \
431
void Name::set_constraint(SingletonModifier* before, \
432
SingletonDerivativeModifier* after, Model* m, \
433
ParticleIndex pi) { \
434
if (!after && !before) { \
435
if (m->get_has_attribute(get_constraint_key(), pi)) { \
436
m->remove_score_state(dynamic_cast<ScoreState*>( \
437
m->get_attribute(get_constraint_key(), pi))); \
438
m->remove_attribute(get_constraint_key(), pi); \
439
} \
440
} else { \
441
Constraint* ss = new core::SingletonConstraint( \
442
before, after, m, pi, \
443
std::string(#Name "updater for ") + m->get_particle_name(pi)); \
444
m->add_attribute(get_constraint_key(), pi, ss); \
445
m->add_score_state(ss); \
446
} \
447
} \
448
IMP_REQUIRE_SEMICOLON_NAMESPACE
449
450
451
/** Register a function that can be used to check that the particle
452
is valid with respect to the decorator. The function should take
453
a Particle* as an argument and return a bool. It should throw
454
an exception if something is wrong.
455
456
This macro should only be used in a .cpp file.
457
*/
458
#define IMP_CHECK_DECORATOR(Name, function) \
459
IMP::internal::ParticleCheck Name##pc(Name::get_is_setup, function);
460
461
462
//! Create a decorator that computes some sort of summary info on a set
463
/** Examples include a centroid or a cover for a set of particles.
464
465
\param[in] Name The name for the decorator
466
\param[in] Parent the parent decorator type
467
\param[in] Members the way to pass a set of particles in
468
\param[in] SetupDoc extra documentation for setup
469
*/
470
#define IMP_SUMMARIZE_DECORATOR_DECL(Name, Parent, Members, SetupDoc) \
471
class IMPCOREEXPORT Name : public Parent { \
472
IMP_CONSTRAINT_DECORATOR_DECL(Name); \
473
private: \
474
/** Sets up Name over particles in pis */
\
475
static void do_setup_particle(Model *m, ParticleIndex pi, \
476
const ParticleIndexes &pis); \
477
/** Sets up Name over particles passed by applying the refiner
478
over the particle pi
479
*/
\
480
static void do_setup_particle(Model *m, ParticleIndex pi, \
481
Refiner *ref); \
482
\
483
public: \
484
IMP_DECORATOR_METHODS(Name, Parent); \
485
/** Sets up Name over members, and constrains Name to be
486
computed before model evaluation and to propagate derivatives
487
following model evaluation.
488
SetupDoc
489
*/
\
490
IMP_DECORATOR_SETUP_1(Name, ParticleIndexesAdaptor, members); \
491
/** Sets up Name over particles passed by applying the refiner
492
over the particle pi, and constrains Name to be computed before
493
model evaluation and to propagate derivatives following model
494
evaluation.
495
SetupDoc
496
*/
\
497
IMP_DECORATOR_SETUP_1(Name, Refiner *, refiner); \
498
static bool get_is_setup(Model *m, ParticleIndex pi) { \
499
return m->get_has_attribute(get_constraint_key(), pi); \
500
} \
501
IMP_NO_DOXYGEN(typedef boost::false_type DecoratorHasTraits); \
502
\
503
private: \
504
/* hide set methods*/
\
505
void set_coordinates() {}; \
506
void set_coordinates_are_optimized() const {} \
507
void set_coordinate() const {} \
508
void set_radius() const {} \
509
}; \
510
IMP_DECORATORS(Name, Name##s, Parent##s)
511
512
513
/** \see IMP_SUMMARIZE_DECORATOR_DECL()
514
\param[in] Name The name for the decorator
515
\param[in] Parent the parent decorator type
516
\param[in] Members the way to pass a set of particles in
517
\param[in] create_pre_modifier the statements to create the
518
SingletonModifier which computes the summary info,
519
using refiner 'ref'
520
\param[in] create_post_modifier a SingletonDerivativeModifier for
521
the derivatives of the summary back to its members,
522
using refiner 'ref'
523
*/
524
#define IMP_SUMMARIZE_DECORATOR_DEF(Name, Parent, Members, \
525
create_pre_modifier, \
526
create_post_modifier) \
527
void Name::do_setup_particle(Model *m, ParticleIndex pi, \
528
const ParticleIndexes &pis) { \
529
Refiner *ref = new FixedRefiner(IMP::get_particles(m, pis)); \
530
SingletonModifier* pre_mod = create_pre_modifier; \
531
SingletonDerivativeModifier* post_mod = create_post_modifier; \
532
if (!Parent::get_is_setup(m, pi)) Parent::setup_particle(m, pi); \
533
set_constraint(pre_mod, post_mod, m, pi); \
534
} \
535
\
536
void Name::do_setup_particle(Model *m, ParticleIndex pi, \
537
Refiner *ref) { \
538
SingletonModifier* pre_mod = create_pre_modifier; \
539
SingletonDerivativeModifier* post_mod = create_post_modifier; \
540
if (!Parent::get_is_setup(m, pi)) Parent::setup_particle(m, pi); \
541
set_constraint(pre_mod, post_mod, m, pi); \
542
} \
543
\
544
void Name::show(std::ostream &out) const { \
545
out << #Name << " at " << static_cast<Parent>(*this); \
546
} \
547
IMP_CONSTRAINT_DECORATOR_DEF(Name)
548
549
#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.