~mok0/clipper/trunk

« back to all changes in this revision

Viewing changes to clipper/core/hkl_datatypes.h

  • Committer: Morten Kjeldgaard
  • Date: 2011-02-09 21:25:56 UTC
  • Revision ID: mok@bioxray.dk-20110209212556-3zbon5ukh4zf3x00
Tags: 2.0.3
versionĀ 2.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*! \file lib/hkl_datatypes.h
 
2
    Fundamental data types for the clipper libraries
 
3
*/
 
4
//C Copyright (C) 2000-2006 Kevin Cowtan and University of York
 
5
//L
 
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:
 
9
//L
 
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.)'
 
21
//L
 
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.
 
26
//L
 
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
 
30
//L  later version.
 
31
//L
 
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.
 
36
//L
 
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,
 
42
//L  MA 02111-1307 USA
 
43
 
 
44
 
 
45
#ifndef CLIPPER_HKL_DATATYPES
 
46
#define CLIPPER_HKL_DATATYPES
 
47
 
 
48
#include <complex>
 
49
#include "hkl_data.h"
 
50
 
 
51
 
 
52
namespace clipper
 
53
{
 
54
 
 
55
  // Now define some actual datatypes
 
56
 
 
57
 
 
58
  namespace datatypes
 
59
  {
 
60
 
 
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
 
66
    {
 
67
    public:
 
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"; }
 
72
      void friedel() {}
 
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); }
 
83
      // accessors
 
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
 
94
    private:
 
95
      dtype I_,sigI_;
 
96
    };
 
97
 
 
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
 
101
      would use I_sigI. */
 
102
    template<class dtype> class I_sigI_ano : private Datatype_base
 
103
    { public:
 
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); }
 
117
      // accessors
 
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
 
131
    private:
 
132
      dtype I_pl_, I_mi_, sigI_pl_, sigI_mi_, cov_;
 
133
    };
 
134
 
 
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
 
140
    {
 
141
    public:
 
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"; }
 
146
      void friedel() {}
 
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; }
 
157
      // accessors
 
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
 
168
    private:
 
169
      dtype f_,sigf_;
 
170
    };
 
171
 
 
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
 
175
      would use F_sigF. */
 
176
    template<class dtype> class F_sigF_ano : private Datatype_base
 
177
    { public:
 
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); }
 
191
      // accessors
 
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
 
205
    private:
 
206
      dtype f_pl_, f_mi_, sigf_pl_, sigf_mi_, cov_;
 
207
    };
 
208
 
 
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:
 
216
      \code
 
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() );
 
220
      \endcode
 
221
    */
 
222
    template<class dtype> class E_sigE : private Datatype_base
 
223
    {
 
224
    public:
 
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"; }
 
229
      void friedel() {}
 
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; }
 
240
      // accessors
 
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
 
251
    private:
 
252
      dtype E_,sigE_;
 
253
    };
 
254
 
 
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
 
258
    { public:
 
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); }
 
272
      // accessors
 
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
 
286
    private:
 
287
      dtype E_pl_, E_mi_, sigE_pl_, sigE_mi_, cov_;
 
288
    };
 
289
 
 
290
    //! Reflection data type: F + phi model or map coeff (e.g. Fcalc, Fbest)
 
291
    template<class dtype> class F_phi : private Datatype_base
 
292
    {
 
293
    public:
 
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"; }
 
298
      void friedel()
 
299
        { if (!Util::is_nan(phi_)) phi_=-phi_; }
 
300
      void shift_phase(const ftype& dphi)
 
301
        { if (!Util::is_nan(phi_)) phi_+=dphi; }
 
302
      bool missing() const
 
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; }
 
312
      // accessors
 
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
 
317
      //! read real part
 
318
      dtype a() const { return f_ * cos( phi_ ); }
 
319
      //! read imag part
 
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; }
 
329
    private:
 
330
      dtype f_,phi_;
 
331
    };
 
332
 
 
333
    //! Reflection data type: best phi + fom
 
334
    template<class dtype> class Phi_fom : private Datatype_base
 
335
    {
 
336
    public:
 
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"; }
 
341
      void friedel()
 
342
        { if (!Util::is_nan(phi_)) phi_=-phi_; }
 
343
      void shift_phase(const ftype& dphi)
 
344
        { if (!Util::is_nan(phi_)) phi_+=dphi; }
 
345
      bool missing() const
 
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]; }
 
353
      // accessors
 
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
 
358
    private:
 
359
      dtype phi_,fom_;
 
360
    };
 
361
 
 
362
    //! Reflection data type: Hendrickson-Lattman coeff
 
363
    template<class dtype> class ABCD : private Datatype_base
 
364
    {
 
365
    public:
 
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)
 
372
      {
 
373
        if ( !missing() ) {
 
374
          ftype cosd,sind;
 
375
          dtype a1, b1, c1, d1;
 
376
          cosd = cos(dphi);
 
377
          sind = sin(dphi);
 
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;
 
385
        }
 
386
      }
 
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]; }
 
394
      // accessors
 
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
 
403
    private:
 
404
      dtype a_,b_,c_,d_;
 
405
    };
 
406
 
 
407
    //! Reflection data type: Free-R flag
 
408
    class Flag : private Datatype_base
 
409
    {
 
410
    public:
 
411
      Flag() { flag_ = -1; }
 
412
      explicit Flag( const int& flag ) : flag_(flag) {}
 
413
      void set_null() { flag_ = -1; }
 
414
      static String type() { return "Flag"; }
 
415
      void friedel() {}
 
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]); }
 
424
      // accessors
 
425
      const int& flag() const { return flag_; }  //<! read access
 
426
      int& flag() { return flag_; }  //<! write access
 
427
    private:
 
428
      int flag_;
 
429
    };
 
430
 
 
431
    //! Reflection data type: boolean (false = missing)
 
432
    class Flag_bool : private Datatype_base
 
433
    {
 
434
    public:
 
435
      Flag_bool() : flag_(false) {}
 
436
      void set_null() { flag_ = false; }
 
437
      static String type() { return "Flag_bool"; }
 
438
      void friedel() {}
 
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]); }
 
447
      // accessors
 
448
      const bool& flag() const { return flag_; }  //<! read access
 
449
      bool& flag() { return flag_; }  //<! write access
 
450
    private:
 
451
      bool flag_;
 
452
    };
 
453
 
 
454
  }
 
455
 
 
456
 
 
457
  namespace data32
 
458
  {
 
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
 
469
  }
 
470
 
 
471
  namespace data64
 
472
  {
 
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
 
483
  }
 
484
 
 
485
 
 
486
 
 
487
} // namespace clipper
 
488
 
 
489
#endif