00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifndef CLIPPER_HKL_DATA
00046 #define CLIPPER_HKL_DATA
00047
00048
00049 #include "hkl_info.h"
00050
00051
00052 namespace clipper
00053 {
00054
00055 class HKL_data_cachekey
00056 {
00057 public:
00058 HKL_data_cachekey( const Spgr_descr& spgr_descr, const Cell& cell_descr, const HKL_sampling& hkl_sam ) : spgr_descr_(spgr_descr), cell_descr_(cell_descr), hkl_sampling_(hkl_sam) {}
00059 const Spgr_descr& spgr_descr() const { return spgr_descr_; }
00060 const Cell_descr& cell_descr() const { return cell_descr_; }
00061 const HKL_sampling& hkl_sampling() const { return hkl_sampling_; }
00062 private:
00063 Spgr_descr spgr_descr_;
00064 Cell_descr cell_descr_;
00065 HKL_sampling hkl_sampling_;
00066 };
00067
00068 class HKL_data_cacheobj : public HKL_info
00069 {
00070 public:
00071 HKL_data_cacheobj( const HKL_data_cachekey& hkl_data_cachekey );
00072 bool matches( const HKL_data_cachekey& hkl_data_cachekey ) const;
00073 String format() const;
00074 private:
00075 HKL_data_cachekey key;
00076 };
00077
00078
00080
00102 class Datatype_base
00103 {
00104 protected:
00106
00108 void set_null();
00110 static String type();
00112 void friedel();
00114 void shift_phase(const ftype& dphi);
00116 bool missing() const;
00118 static int data_size();
00120 static String data_names();
00122 void data_export( xtype array[] ) const;
00124 void data_import( const xtype array[] );
00125 };
00126
00127
00129
00135 class HKL_data_base
00136 {
00137 public:
00138
00140 typedef HKL_info::HKL_reference_index HKL_reference_index;
00142 typedef HKL_info::HKL_reference_coord HKL_reference_coord;
00143
00145 virtual void init( const HKL_info& hkl_info, const Cell& cell );
00147 virtual void init( const Spacegroup& spacegroup, const Cell& cell, const HKL_sampling& hkl_sampling );
00148
00149
00151 bool is_null() const;
00152
00154 const HKL_info& base_hkl_info() const { return *parent_hkl_info; }
00156 const Cell& base_cell() const { return *parent_cell; }
00157
00159 const Spacegroup& spacegroup() const { return spacegroup_; }
00161 const Cell& cell() const { return cell_; }
00163 const Resolution& resolution() const { return resolution_; }
00165 const HKL_sampling& hkl_sampling() const { return hkl_sampling_; }
00167 const HKL_info& hkl_info() const { return *parent_hkl_info; }
00168
00170 ftype invresolsq( const int& index ) const;
00172 Range<ftype> invresolsq_range() const;
00174 int num_obs() const;
00175
00177 virtual void update() = 0;
00179 virtual String type() const = 0;
00181 virtual bool missing(const int& index) const = 0;
00183 virtual void set_null(const int& index) = 0;
00185 virtual int data_size() const = 0;
00187 virtual String data_names() const = 0;
00189 virtual void data_export( const HKL& hkl, xtype array[] ) const = 0;
00191 virtual void data_import( const HKL& hkl, const xtype array[] ) = 0;
00193 virtual void mask(const HKL_data_base& mask) = 0;
00194
00196 HKL_reference_index first() const;
00198 HKL_reference_index first_data() const;
00200 HKL_reference_index& next_data( HKL_reference_index& ih ) const;
00201
00202 void debug() const;
00203
00204 protected:
00205 const HKL_info* parent_hkl_info;
00206 const Cell* parent_cell;
00207 bool cell_matches_parent;
00208
00209
00210 ObjectCache<HKL_data_cacheobj>::Reference cacheref;
00211 Spacegroup spacegroup_;
00212 Cell cell_;
00213 HKL_sampling hkl_sampling_;
00214 Resolution resolution_;
00215
00217 HKL_data_base();
00219 virtual ~HKL_data_base() {}
00220 };
00221
00222
00224
00231 template<class T> class HKL_data : public HKL_data_base
00232 {
00233 public:
00235 HKL_data() {}
00237 explicit HKL_data( const HKL_info& hkl_info );
00239 HKL_data( const HKL_info& hkl_info, const Cell& cell );
00241 HKL_data( const Spacegroup& spacegroup, const Cell& cell, const HKL_sampling& hkl_sampling );
00242
00244 void init( const HKL_info& hkl_info, const Cell& cell );
00246 void init( const Spacegroup& spacegroup, const Cell& cell, const HKL_sampling& hkl_sampling );
00248 void update();
00249
00250
00251 String type() const { return T::type(); }
00252 bool missing(const int& index) const { return list[index].missing(); }
00253 void set_null(const int& index) { list[index].set_null(); }
00254 int data_size() const { return T::data_size(); }
00255 String data_names() const { return T::data_names(); }
00256 void data_export( const HKL& hkl, xtype array[] ) const
00257 { T datum; get_data( hkl, datum ); datum.data_export( array ); }
00258 void data_import( const HKL& hkl, const xtype array[] )
00259 { T datum; datum.data_import( array ); set_data( hkl, datum ); }
00260 void mask(const HKL_data_base& mask);
00261
00262
00264 const T& operator[] (const HKL_info::HKL_reference_index& i) const
00265 { return list[i.index()]; }
00267 T& operator[] (const HKL_info::HKL_reference_index& i)
00268 { return list[i.index()]; }
00269
00270
00272 T operator[] (const HKL_info::HKL_reference_coord& ih) const;
00274 bool get_data(const HKL_info::HKL_reference_coord& ih, T& data) const;
00276 bool set_data(const HKL_info::HKL_reference_coord& ih, const T& data);
00277
00278
00280 const T& operator[] (const int& index) const { return list[index]; }
00282 T& operator[] (const int& index) { return list[index]; }
00283
00284
00286 T operator[] (const HKL& hkl) const;
00288 bool get_data(const HKL& hkl, T& data) const;
00290 bool set_data(const HKL& hkl, const T& data);
00291
00292
00294 template<class C> void compute( const C& op )
00295 { for (HKL_info::HKL_reference_index ih=parent_hkl_info->first(); !ih.last(); ih.next()) list[ih.index()] = op( ih ); }
00297 template<class S, class C> void compute( const HKL_data<S>& src, const C& op )
00298 { for (HKL_info::HKL_reference_index ih=parent_hkl_info->first(); !ih.last(); ih.next()) list[ih.index()] = op( ih, src[ih] ); }
00300 template<class S1, class S2, class C> void compute( const HKL_data<S1>& src1, const HKL_data<S2>& src2, const C& op )
00301 { for (HKL_info::HKL_reference_index ih=parent_hkl_info->first(); !ih.last(); ih.next()) list[ih.index()] = op( ih, src1[ih], src2[ih] ); }
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00314 HKL_data<T>& operator =( const HKL_data<T>& other );
00316 HKL_data<T>& operator =( const T& value );
00317
00318 void debug() const;
00319
00320 protected:
00321
00322 std::vector<T> list;
00323 };
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 ftype HKL_info::HKL_reference_base::invresolsq( const HKL_data_base& hkldata ) const
00334 { return hkldata.invresolsq( index_ ); }
00335
00338 template<class T> HKL_data<T>::HKL_data( const HKL_info& hkl_info )
00339 {
00340 init( hkl_info, hkl_info.cell() );
00341 }
00342
00346 template<class T> HKL_data<T>::HKL_data( const HKL_info& hkl_info, const Cell& cell )
00347 {
00348 init( hkl_info, cell );
00349 }
00350
00355 template<class T> HKL_data<T>::HKL_data( const Spacegroup& spacegroup, const Cell& cell, const HKL_sampling& hkl_sampling )
00356 {
00357 init( spacegroup, cell, hkl_sampling );
00358 }
00359
00363 template<class T> void HKL_data<T>::init( const HKL_info& hkl_info, const Cell& cell )
00364 {
00365 HKL_data_base::init( hkl_info, cell );
00366 update();
00367 }
00368
00373 template<class T> void HKL_data<T>::init( const Spacegroup& spacegroup, const Cell& cell, const HKL_sampling& hkl_sampling )
00374 {
00375 HKL_data_base::init( spacegroup, cell, hkl_sampling );
00376 update();
00377 }
00378
00380 template<class T> void HKL_data<T>::update()
00381 {
00382 if ( parent_hkl_info != NULL ) {
00383 T null; null.set_null();
00384 list.resize( parent_hkl_info->num_reflections(), null );
00385 }
00386 }
00387
00392 template<class T> void HKL_data<T>::mask(const HKL_data_base& mask)
00393 {
00394 T null; null.set_null();
00395 for ( int i = 0; i < list.size(); i++ )
00396 if ( mask.missing(i) ) list[i] = null;
00397 }
00398
00404 template<class T> T HKL_data<T>::operator[] (const HKL_info::HKL_reference_coord& ih) const
00405 {
00406 if ( ih.index() < 0 ) { T null; null.set_null(); return null; }
00407 T data = list[ih.index()];
00408 if ( ih.friedel() ) data.friedel();
00409 data.shift_phase( -ih.hkl().sym_phase_shift( parent_hkl_info->spacegroup().symop(ih.sym()) ) );
00410 return data;
00411 }
00412
00419 template<class T> bool HKL_data<T>::get_data(const HKL_info::HKL_reference_coord& ih, T& data) const
00420 {
00421 if ( ih.index() < 0 ) { data.set_null(); return false; }
00422 data = list[ih.index()];
00423 if ( ih.friedel() ) data.friedel();
00424 data.shift_phase( -ih.hkl().sym_phase_shift( parent_hkl_info->spacegroup().symop(ih.sym()) ) );
00425 return true;
00426 }
00427
00434 template<class T> bool HKL_data<T>::set_data(const HKL_info::HKL_reference_coord& ih, const T& data)
00435 {
00436 if ( ih.index() < 0 ) return false;
00437 T& ldata = list[ih.index()];
00438 ldata = data;
00439 ldata.shift_phase( ih.hkl().sym_phase_shift( parent_hkl_info->spacegroup().symop(ih.sym()) ) );
00440 if ( ih.friedel() ) ldata.friedel();
00441 return true;
00442 }
00443
00449 template<class T> T HKL_data<T>::operator[] (const HKL& hkl) const
00450 {
00451 int index, sym; bool friedel;
00452
00453 index = parent_hkl_info->index_of( parent_hkl_info->
00454 find_sym(hkl, sym, friedel) );
00455 if ( index < 0 ) { T null; null.set_null(); return null; }
00456 T data = list[index];
00457 if (friedel) data.friedel();
00458 data.shift_phase( -hkl.sym_phase_shift( parent_hkl_info->spacegroup().symop(sym) ) );
00459 return data;
00460 }
00461
00468 template<class T> bool HKL_data<T>::get_data(const HKL& hkl, T& data) const
00469 {
00470 int index, sym; bool friedel;
00471
00472 index = parent_hkl_info->index_of( parent_hkl_info->
00473 find_sym(hkl, sym, friedel) );
00474 if ( index < 0 ) { data.set_null(); return false; }
00475 data = list[index];
00476 if (friedel) data.friedel();
00477 data.shift_phase( -hkl.sym_phase_shift(parent_hkl_info->spacegroup().symop(sym)) );
00478 return true;
00479 }
00480
00487 template<class T> bool HKL_data<T>::set_data(const HKL& hkl, const T& data_)
00488 {
00489 int index, sym; bool friedel;
00490 index = parent_hkl_info->index_of( parent_hkl_info->
00491 find_sym(hkl, sym, friedel) );
00492 if ( index < 0 ) { return false; }
00493 T& ldata = list[index];
00494 ldata = data_;
00495 ldata.shift_phase( hkl.sym_phase_shift(parent_hkl_info->spacegroup().symop(sym)) );
00496 if (friedel) ldata.friedel();
00497 return true;
00498 }
00499
00500
00508 template<class T> HKL_data<T>& HKL_data<T>::operator =( const HKL_data<T>& other )
00509 {
00510 if ( parent_hkl_info == NULL ) {
00511 *this = other;
00512 } else {
00513 if ( parent_hkl_info != other.parent_hkl_info )
00514 Message::message( Message_fatal( "HKL_data<T>: mismatched parent HKL_info is assignment" ) );
00515 list = other.list;
00516 }
00517 return *this;
00518 }
00519
00520
00523 template<class T> HKL_data<T>& HKL_data<T>::operator =( const T& value )
00524 {
00525 for ( int i = 0; i < list.size(); i++ ) list[i] = value;
00526 return *this;
00527 }
00528
00529
00530 template<class T> void HKL_data<T>::debug() const
00531 {
00532 HKL_data_base::debug();
00533 std::cout << "Size " << list.size() << "\n";
00534 }
00535
00536
00537 }
00538
00539 #endif