1
/*! \file lib/hkl_datatypes.h
2
Fundamental data types for the clipper libraries
4
//C Copyright (C) 2000-2006 Kevin Cowtan and University of York
6
//L This library is free software and is distributed under the terms
7
//L and conditions of version 2.1 of the GNU Lesser General Public
8
//L Licence (LGPL) with the following additional clause:
10
//L `You may also combine or link a "work that uses the Library" to
11
//L produce a work containing portions of the Library, and distribute
12
//L that work under terms of your choice, provided that you give
13
//L prominent notice with each copy of the work that the specified
14
//L version of the Library is used in it, and that you include or
15
//L provide public access to the complete corresponding
16
//L machine-readable source code for the Library including whatever
17
//L changes were used in the work. (i.e. If you make changes to the
18
//L Library you must distribute those, but you do not need to
19
//L distribute source or object code to those portions of the work
20
//L not covered by this licence.)'
22
//L Note that this clause grants an additional right and does not impose
23
//L any additional restriction, and so does not affect compatibility
24
//L with the GNU General Public Licence (GPL). If you wish to negotiate
25
//L other terms, please contact the maintainer.
27
//L You can redistribute it and/or modify the library under the terms of
28
//L the GNU Lesser General Public License as published by the Free Software
29
//L Foundation; either version 2.1 of the License, or (at your option) any
32
//L This library is distributed in the hope that it will be useful, but
33
//L WITHOUT ANY WARRANTY; without even the implied warranty of
34
//L MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35
//L Lesser General Public License for more details.
37
//L You should have received a copy of the CCP4 licence and/or GNU
38
//L Lesser General Public License along with this library; if not, write
39
//L to the CCP4 Secretary, Daresbury Laboratory, Warrington WA4 4AD, UK.
40
//L The GNU Lesser General Public can also be obtained by writing to the
41
//L Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
45
#ifndef CLIPPER_HKL_DATATYPES
46
#define CLIPPER_HKL_DATATYPES
55
// Now define some actual datatypes
61
//! Reflection data type: I + sigI
62
/*! Note that I_sigI also has methods for returning I_pl(),
63
sigI_pl(), I_mi, sigI_mi(), so you can use this type in any
64
template type where you would use I_sigI_ano. */
65
template<class dtype> class I_sigI : private Datatype_base
68
I_sigI() { Util::set_null(I_); Util::set_null(sigI_); }
69
I_sigI( const dtype& I, const dtype& sigI ) : I_(I), sigI_(sigI) {}
70
void set_null() { Util::set_null(I_); Util::set_null(sigI_); }
71
static String type() { return "I_sigI"; }
73
void shift_phase(const ftype& dphi) {}
74
bool missing() const { return (Util::is_nan(I_) || Util::is_nan(sigI_)); }
75
static int data_size() { return 2; }
76
static String data_names() { return "I sigI"; }
77
void data_export( xtype array[] ) const
78
{ array[0] = I(); array[1] = sigI(); }
79
void data_import( const xtype array[] )
80
{ I() = array[0]; sigI() = array[1]; }
81
//! this type is scalable - apply magnitude scale factor
82
void scale(const ftype& s) { I_ *= (s*s); sigI_ *= (s*s); }
84
const dtype& I() const { return I_; } //<! read access
85
const dtype& sigI() const { return sigI_; } //<! read access
86
dtype& I() { return I_; } //<! write access
87
dtype& sigI() { return sigI_; } //<! write access
88
// anomalous-type accessors
89
const dtype& I_pl() const { return I_; } //<! read access as anom
90
const dtype& sigI_pl() const { return sigI_; } //<! read access as anom
91
const dtype& I_mi() const { return I_; } //<! read access as anom
92
const dtype& sigI_mi() const { return sigI_; } //<! read access as anom
93
dtype cov() const { return 1.0; } //<! read access as anom
98
//! Reflection data type: I(+) I(+) sigI(+) sigI(-) cov+-
99
/*! Note that I_sigI_ano also has methods for returning I(),
100
sigI(), so you can use this type in any template type where you
102
template<class dtype> class I_sigI_ano : private Datatype_base
104
I_sigI_ano() { set_null(); }
105
void set_null() { Util::set_null(I_pl_); Util::set_null(I_mi_); Util::set_null(sigI_pl_); Util::set_null(sigI_mi_); Util::set_null(cov_); }
106
static String type() { return "I_sigI_ano"; }
107
void friedel() { dtype I=I_pl_; I_pl_=I_mi_; I_mi_=I;
108
I=sigI_pl_; sigI_pl_=sigI_mi_; sigI_mi_=I; }
109
void shift_phase(const ftype& dphi) {}
110
bool missing() const { return (Util::is_nan(I_pl_) && Util::is_nan(I_mi_)); }
111
static int data_size() { return 5; }
112
static String data_names() { return "I+ sigI+ I- sigI- covI+-"; }
113
void data_export( xtype a[] ) const { a[0] = I_pl(); a[1] = sigI_pl(); a[2] = I_mi(); a[3] = sigI_mi(); a[4] = cov(); }
114
void data_import( const xtype a[] ) { I_pl() = a[0]; sigI_pl() = a[1]; I_mi() = a[2]; sigI_mi() = a[3]; cov() = a[4]; }
115
//! this type is scalable - apply magnitude scale factor
116
void scale(const ftype& s) { I_pl_ *= (s*s); sigI_pl_ *= (s*s); I_mi_ *= (s*s); sigI_mi_ *= (s*s); cov_ *= (s*s); }
118
const dtype& I_pl() const { return I_pl_; } //<! read access
119
const dtype& sigI_pl() const { return sigI_pl_; } //<! read access
120
const dtype& I_mi() const { return I_mi_; } //<! read access
121
const dtype& sigI_mi() const { return sigI_mi_; } //<! read access
122
const dtype& cov() const { return cov_; } //<! read access
123
dtype& I_pl() { return I_pl_; } //<! write access
124
dtype& sigI_pl() { return sigI_pl_; } //<! write access
125
dtype& I_mi() { return I_mi_; } //<! write access
126
dtype& sigI_mi() { return sigI_mi_; } //<! write access
127
dtype& cov() { return cov_; } //<! write access
128
// nonanomalous-type accessors
129
dtype I() const { return Util::mean(I_pl_,I_mi_); } //<! read access as simple
130
dtype sigI() const { return Util::sig_mean(sigI_pl_,sigI_mi_,cov_); } //<! read access as simple
132
dtype I_pl_, I_mi_, sigI_pl_, sigI_mi_, cov_;
135
//! Reflection data type: F + sigF
136
/*! Note that F_sigF also has methods for returning f_pl(),
137
sigf_pl(), f_mi, sigf_mi(), so you can use this type in any
138
template type where you would use F_sigF_ano. */
139
template<class dtype> class F_sigF : private Datatype_base
142
F_sigF() { Util::set_null(f_); Util::set_null(sigf_); }
143
F_sigF( const dtype& f, const dtype& sigf ) : f_(f), sigf_(sigf) {}
144
void set_null() { Util::set_null(f_); Util::set_null(sigf_); }
145
static String type() { return "F_sigF"; }
147
void shift_phase(const ftype& dphi) {}
148
bool missing() const { return (Util::is_nan(f_) || Util::is_nan(sigf_)); }
149
static int data_size() { return 2; }
150
static String data_names() { return "F sigF"; }
151
void data_export( xtype array[] ) const
152
{ array[0] = f(); array[1] = sigf(); }
153
void data_import( const xtype array[] )
154
{ f() = array[0]; sigf() = array[1]; }
155
//! this type is scalable - apply magnitude scale factor
156
void scale(const ftype& s) { f_ *= s; sigf_ *= s; }
158
const dtype& f() const { return f_; } //<! read access
159
const dtype& sigf() const { return sigf_; } //<! read access
160
dtype& f() { return f_; } //<! write access
161
dtype& sigf() { return sigf_; } //<! write access
162
// anomalous-type accessors
163
const dtype& f_pl() const { return f_; } //<! read access as anom
164
const dtype& sigf_pl() const { return sigf_; } //<! read access as anom
165
const dtype& f_mi() const { return f_; } //<! read access as anom
166
const dtype& sigf_mi() const { return sigf_; } //<! read access as anom
167
dtype cov() const { return 1.0; } //<! read access as anom
172
//! Reflection data type: F(+) F(+) sigF(+) sigF(-) cov+-
173
/*! Note that F_sigF_ano also has methods for returning f(),
174
sigf(), so you can use this type in any template type where you
176
template<class dtype> class F_sigF_ano : private Datatype_base
178
F_sigF_ano() { set_null(); }
179
void set_null() { Util::set_null(f_pl_); Util::set_null(f_mi_); Util::set_null(sigf_pl_); Util::set_null(sigf_mi_); Util::set_null(cov_); }
180
static String type() { return "F_sigF_ano"; }
181
void friedel() { dtype f=f_pl_; f_pl_=f_mi_; f_mi_=f;
182
f=sigf_pl_; sigf_pl_=sigf_mi_; sigf_mi_=f; }
183
void shift_phase(const ftype& dphi) {}
184
bool missing() const { return (Util::is_nan(f_pl_) && Util::is_nan(f_mi_)); }
185
static int data_size() { return 5; }
186
static String data_names() { return "F+ sigF+ F- sigF- covF+-"; }
187
void data_export( xtype a[] ) const { a[0] = f_pl(); a[1] = sigf_pl(); a[2] = f_mi(); a[3] = sigf_mi(); a[4] = cov(); }
188
void data_import( const xtype a[] ) { f_pl() = a[0]; sigf_pl() = a[1]; f_mi() = a[2]; sigf_mi() = a[3]; cov() = a[4]; }
189
//! this type is scalable - apply magnitude scale factor
190
void scale(const ftype& s) { f_pl_ *= s; sigf_pl_ *= s; f_mi_ *= s; sigf_mi_ *= s; cov_ *= (s*s); }
192
const dtype& f_pl() const { return f_pl_; } //<! read access
193
const dtype& sigf_pl() const { return sigf_pl_; } //<! read access
194
const dtype& f_mi() const { return f_mi_; } //<! read access
195
const dtype& sigf_mi() const { return sigf_mi_; } //<! read access
196
const dtype& cov() const { return cov_; } //<! read access
197
dtype& f_pl() { return f_pl_; } //<! write access
198
dtype& sigf_pl() { return sigf_pl_; } //<! write access
199
dtype& f_mi() { return f_mi_; } //<! write access
200
dtype& sigf_mi() { return sigf_mi_; } //<! write access
201
dtype& cov() { return cov_; } //<! write access
202
// nonanomalous-type accessors
203
dtype f() const { return Util::mean(f_pl_,f_mi_); } //<! read access as simple
204
dtype sigf() const { return Util::sig_mean(sigf_pl_,sigf_mi_,cov_); } //<! read access as simple
206
dtype f_pl_, f_mi_, sigf_pl_, sigf_mi_, cov_;
209
//! Reflection data type: E + sigE
210
/*! This is not strictly a type for storing E values, but rather a
211
type for storing any sturcture factor magnitude-like quantity
212
which has already had a symmetry enhancement factor (epsilon)
213
removed from it. E's are most commonly stored in this form,
214
wheras F's and U's are not. You can compute corrected F's from
215
uncorrected F's using:
217
clipper::HKL_data<clipper::data32::F_sigF> fsigf;
218
clipper::HKL_data<clipper::data32::E_sigE> esige;
219
esige.compute( fsigf, clipper::data32::Compute_EsigE_from_FsigF() );
222
template<class dtype> class E_sigE : private Datatype_base
225
E_sigE() { Util::set_null(E_); Util::set_null(sigE_); }
226
E_sigE( const dtype& E, const dtype& sigE ) : E_(E), sigE_(sigE) {}
227
void set_null() { Util::set_null(E_); Util::set_null(sigE_); }
228
static String type() { return "E_sigE"; }
230
void shift_phase(const ftype& dphi) {}
231
bool missing() const { return (Util::is_nan(E_) || Util::is_nan(sigE_)); }
232
static int data_size() { return 2; }
233
static String data_names() { return "E sigE"; }
234
void data_export( xtype array[] ) const
235
{ array[0] = E(); array[1] = sigE(); }
236
void data_import( const xtype array[] )
237
{ E() = array[0]; sigE() = array[1]; }
238
//! this type is scalable - apply magnitude scale factor
239
void scale(const ftype& s) { E_ *= s; sigE_ *= s; }
241
const dtype& E() const { return E_; } //<! read access
242
const dtype& sigE() const { return sigE_; } //<! read access
243
dtype& E() { return E_; } //<! write access
244
dtype& sigE() { return sigE_; } //<! write access
245
// anomalous-type accessors
246
const dtype& E_pl() const { return E_; } //<! read access as anom
247
const dtype& sigE_pl() const { return sigE_; } //<! read access as anom
248
const dtype& E_mi() const { return E_; } //<! read access as anom
249
const dtype& sigE_mi() const { return sigE_; } //<! read access as anom
250
dtype cov() const { return 1.0; } //<! read access as anom
255
//! Reflection data type: E(+) E(+) sigE(+) sigE(-) cov+-
256
/*! see datatypes::E_sigE */
257
template<class dtype> class E_sigE_ano : private Datatype_base
259
E_sigE_ano() { set_null(); }
260
void set_null() { Util::set_null(E_pl_); Util::set_null(E_mi_); Util::set_null(sigE_pl_); Util::set_null(sigE_mi_); Util::set_null(cov_); }
261
static String type() { return "E_sigE_ano"; }
262
void friedel() { dtype e=E_pl_; E_pl_=E_mi_; E_mi_=e;
263
e=sigE_pl_; sigE_pl_=sigE_mi_; sigE_mi_=e; }
264
void shift_phase(const ftype& dphi) {}
265
bool missing() const { return (Util::is_nan(E_pl_) && Util::is_nan(E_mi_)); }
266
static int data_size() { return 5; }
267
static String data_names() { return "E+ sigE+ E- sigE- covE+-"; }
268
void data_export( xtype a[] ) const { a[0] = E_pl(); a[1] = sigE_pl(); a[2] = E_mi(); a[3] = sigE_mi(); a[4] = cov(); }
269
void data_import( const xtype a[] ) { E_pl() = a[0]; sigE_pl() = a[1]; E_mi() = a[2]; sigE_mi() = a[3]; cov() = a[4]; }
270
//! this type is scalable - apply magnitude scale factor
271
void scale(const ftype& s) { E_pl_ *= s; sigE_pl_ *= s; E_mi_ *= s; sigE_mi_ *= s; cov_ *= (s*s); }
273
const dtype& E_pl() const { return E_pl_; } //<! read access
274
const dtype& sigE_pl() const { return sigE_pl_; } //<! read access
275
const dtype& E_mi() const { return E_mi_; } //<! read access
276
const dtype& sigE_mi() const { return sigE_mi_; } //<! read access
277
const dtype& cov() const { return cov_; } //<! read access
278
dtype& E_pl() { return E_pl_; } //<! write access
279
dtype& sigE_pl() { return sigE_pl_; } //<! write access
280
dtype& E_mi() { return E_mi_; } //<! write access
281
dtype& sigE_mi() { return sigE_mi_; } //<! write access
282
dtype& cov() { return cov_; } //<! write access
283
// nonanomalous-type accessors
284
dtype E() const { return Util::mean(E_pl_,E_mi_); } //<! read access as simple
285
dtype sigE() const { return Util::sig_mean(sigE_pl_,sigE_mi_,cov_); } //<! read access as simple
287
dtype E_pl_, E_mi_, sigE_pl_, sigE_mi_, cov_;
290
//! Reflection data type: F + phi model or map coeff (e.g. Fcalc, Fbest)
291
template<class dtype> class F_phi : private Datatype_base
294
F_phi() { Util::set_null(f_); Util::set_null(phi_); }
295
F_phi( const dtype& f, const dtype& phi ) : f_(f), phi_(phi) {}
296
void set_null() { Util::set_null(f_); Util::set_null(phi_); }
297
static String type() { return "F_phi"; }
299
{ if (!Util::is_nan(phi_)) phi_=-phi_; }
300
void shift_phase(const ftype& dphi)
301
{ if (!Util::is_nan(phi_)) phi_+=dphi; }
303
{ return (Util::is_nan(f_) || Util::is_nan(phi_)); }
304
static int data_size() { return 2; }
305
static String data_names() { return "F phi"; }
306
void data_export( xtype array[] ) const
307
{ array[0] = f(); array[1] = phi(); }
308
void data_import( const xtype array[] )
309
{ f() = array[0]; phi() = array[1]; }
310
//! this type is scalable - apply magnitude scale factor
311
void scale(const ftype& s) { f_ *= s; }
313
const dtype& f() const { return f_; } //<! read access
314
const dtype& phi() const { return phi_; } //<! read access
315
dtype& f() { return f_; } //<! write access
316
dtype& phi() { return phi_; } //<! write access
318
dtype a() const { return f_ * cos( phi_ ); }
320
dtype b() const { return f_ * sin( phi_ ); }
321
//! convert from complex
322
F_phi(const std::complex<dtype> c) { f_=std::abs(c); phi_=std::arg(c); }
323
//! convert to complex
324
operator std::complex<dtype>() const { return std::polar(f_, phi_); }
325
//! resolve along phase direction
326
dtype resolve(const dtype phi) { return f_ * cos( phi_ - phi ); }
327
//! tidy up so that real part is positive and phase 0...twopi
328
const F_phi<dtype>& norm() { if ( f_ < 0.0 ) { f_ = -f_; phi_ += Util::pi(); } phi_ = Util::mod( phi_, Util::twopi() ); return *this; }
333
//! Reflection data type: best phi + fom
334
template<class dtype> class Phi_fom : private Datatype_base
337
Phi_fom() { Util::set_null(phi_); Util::set_null(fom_); }
338
Phi_fom( const dtype& phi, const dtype& fom ) : phi_(phi), fom_(fom) {}
339
void set_null() { Util::set_null(phi_); Util::set_null(fom_); }
340
static String type() { return "Phi_fom"; }
342
{ if (!Util::is_nan(phi_)) phi_=-phi_; }
343
void shift_phase(const ftype& dphi)
344
{ if (!Util::is_nan(phi_)) phi_+=dphi; }
346
{ return (Util::is_nan(phi_) || Util::is_nan(fom_)); }
347
static int data_size() { return 2; }
348
static String data_names() { return "phi fom"; }
349
void data_export( xtype array[] ) const
350
{ array[0] = phi(); array[1] = fom(); }
351
void data_import( const xtype array[] )
352
{ phi() = array[0]; fom() = array[1]; }
354
const dtype& phi() const { return phi_; } //<! read access
355
const dtype& fom() const { return fom_; } //<! read access
356
dtype& phi() { return phi_; } //<! write access
357
dtype& fom() { return fom_; } //<! write access
362
//! Reflection data type: Hendrickson-Lattman coeff
363
template<class dtype> class ABCD : private Datatype_base
366
ABCD() { Util::set_null(a_); Util::set_null(b_); Util::set_null(c_); Util::set_null(d_); }
367
ABCD( const dtype& a, const dtype& b, const dtype& c, const dtype& d ) : a_(a), b_(b), c_(c), d_(d) {}
368
void set_null() { Util::set_null(a_); Util::set_null(b_); Util::set_null(c_); Util::set_null(d_); }
369
static String type() { return "ABCD"; }
370
void friedel() { if ( !missing() ) { b_=-b_; d_=-d_; } }
371
void shift_phase(const ftype& dphi)
375
dtype a1, b1, c1, d1;
378
a1 = a_*cosd - b_*sind;
379
b1 = a_*sind + b_*cosd;
380
cosd = cos(2.0*dphi);
381
sind = sin(2.0*dphi);
382
c1 = c_*cosd - d_*sind;
383
d1 = c_*sind + d_*cosd;
384
a_ = a1; b_ = b1; c_ = c1; d_ = d1;
387
bool missing() const { return (Util::is_nan(a_) || Util::is_nan(b_) || Util::is_nan(c_) || Util::is_nan(d_)); }
388
static int data_size() { return 4; }
389
static String data_names() { return "A B C D"; }
390
void data_export( xtype array[] ) const
391
{ array[0] = a(); array[1] = b(); array[2] = c(); array[3] = d(); }
392
void data_import( const xtype array[] )
393
{ a() = array[0]; b() = array[1]; c() = array[2]; d() = array[3]; }
395
const dtype& a() const { return a_; } //<! read access
396
const dtype& b() const { return b_; } //<! read access
397
const dtype& c() const { return c_; } //<! read access
398
const dtype& d() const { return d_; } //<! read access
399
dtype& a() { return a_; } //<! write access
400
dtype& b() { return b_; } //<! write access
401
dtype& c() { return c_; } //<! write access
402
dtype& d() { return d_; } //<! write access
407
//! Reflection data type: Free-R flag
408
class Flag : private Datatype_base
411
Flag() { flag_ = -1; }
412
explicit Flag( const int& flag ) : flag_(flag) {}
413
void set_null() { flag_ = -1; }
414
static String type() { return "Flag"; }
416
void shift_phase(const ftype& dphi) {}
417
bool missing() const { return (flag_ < 0); }
418
static int data_size() { return 1; }
419
static String data_names() { return "flag"; }
420
void data_export( xtype array[] ) const
421
{ array[0] = xtype(flag()); }
422
void data_import( const xtype array[] )
423
{ flag() = int(array[0]); }
425
const int& flag() const { return flag_; } //<! read access
426
int& flag() { return flag_; } //<! write access
431
//! Reflection data type: boolean (false = missing)
432
class Flag_bool : private Datatype_base
435
Flag_bool() : flag_(false) {}
436
void set_null() { flag_ = false; }
437
static String type() { return "Flag_bool"; }
439
void shift_phase(const ftype& dphi) {}
440
bool missing() const { return (!flag_); }
441
static int data_size() { return 1; }
442
static String data_names() { return "flag"; }
443
void data_export( xtype array[] ) const
444
{ array[0] = xtype(flag()); }
445
void data_import( const xtype array[] )
446
{ flag() = bool(array[0]); }
448
const bool& flag() const { return flag_; } //<! read access
449
bool& flag() { return flag_; } //<! write access
459
typedef clipper::datatypes::I_sigI<ftype32> I_sigI; //!< datatype
460
typedef clipper::datatypes::I_sigI_ano<ftype32> I_sigI_ano; //!< datatype
461
typedef clipper::datatypes::F_sigF<ftype32> F_sigF; //!< datatype
462
typedef clipper::datatypes::F_sigF_ano<ftype32> F_sigF_ano; //!< datatype
463
typedef clipper::datatypes::E_sigE<ftype32> E_sigE; //!< datatype
464
typedef clipper::datatypes::F_phi<ftype32> F_phi; //!< datatype
465
typedef clipper::datatypes::Phi_fom<ftype32> Phi_fom; //!< datatype
466
typedef clipper::datatypes::ABCD<ftype32> ABCD; //!< datatype
467
typedef clipper::datatypes::Flag Flag; //!< datatype
468
typedef clipper::datatypes::Flag_bool Flag_bool; //!< datatype
473
typedef clipper::datatypes::I_sigI<ftype64> I_sigI; //!< datatype
474
typedef clipper::datatypes::I_sigI_ano<ftype64> I_sigI_ano; //!< datatype
475
typedef clipper::datatypes::F_sigF<ftype64> F_sigF; //!< datatype
476
typedef clipper::datatypes::F_sigF_ano<ftype64> F_sigF_ano; //!< datatype
477
typedef clipper::datatypes::E_sigE<ftype64> E_sigE; //!< datatype
478
typedef clipper::datatypes::F_phi<ftype64> F_phi; //!< datatype
479
typedef clipper::datatypes::Phi_fom<ftype64> Phi_fom; //!< datatype
480
typedef clipper::datatypes::ABCD<ftype64> ABCD; //!< datatype
481
typedef clipper::datatypes::Flag Flag; //!< datatype
482
typedef clipper::datatypes::Flag_bool Flag_bool; //!< datatype
487
} // namespace clipper