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_cacheobj : public HKL_info
00056 {
00057 public:
00058 class Key
00059 {
00060 public:
00061 Key( 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) {}
00062 const Spgr_descr& spgr_descr() const { return spgr_descr_; }
00063 const Cell_descr& cell_descr() const { return cell_descr_; }
00064 const HKL_sampling& hkl_sampling() const { return hkl_sampling_; }
00065 private:
00066 Spgr_descr spgr_descr_;
00067 Cell_descr cell_descr_;
00068 HKL_sampling hkl_sampling_;
00069 };
00070
00071 HKL_data_cacheobj( const Key& hkl_data_cachekey );
00072 bool matches( const Key& hkl_data_cachekey ) const;
00073 String format() const;
00074 static Mutex mutex;
00075 private:
00076 Key key;
00077 };
00078
00079
00081
00103 class Datatype_base
00104 {
00105 protected:
00107
00109 void set_null();
00111 static String type();
00113 void friedel();
00115 void shift_phase(const ftype& dphi);
00117 bool missing() const;
00119 static int data_size();
00121 static String data_names();
00123 void data_export( xtype array[] ) const;
00125 void data_import( const xtype array[] );
00126 };
00127
00128
00130
00136 class HKL_data_base
00137 {
00138 public:
00139
00141 typedef HKL_info::HKL_reference_index HKL_reference_index;
00143 typedef HKL_info::HKL_reference_coord HKL_reference_coord;
00144
00146 virtual void init( const HKL_info& hkl_info, const Cell& cell );
00148 virtual void init( const HKL_data_base& hkl_data );
00150 virtual void init( const Spacegroup& spacegroup, const Cell& cell, const HKL_sampling& hkl_sampling );
00151
00152
00154 bool is_null() const;
00155
00157 const HKL_info& base_hkl_info() const { return *parent_hkl_info; }
00159 const Cell& base_cell() const { return *parent_cell; }
00160
00162 const Spacegroup& spacegroup() const { return spacegroup_; }
00164 const Cell& cell() const { return cell_; }
00166 const Resolution& resolution() const { return resolution_; }
00168 const HKL_sampling& hkl_sampling() const { return hkl_sampling_; }
00170 const HKL_info& hkl_info() const { return *parent_hkl_info; }
00171
00173 ftype invresolsq( const int& index ) const;
00175 Range<ftype> invresolsq_range() const;
00177 int num_obs() const;
00178
00180 virtual void update() = 0;
00182 virtual String type() const = 0;
00184 virtual bool missing(const int& index) const = 0;
00186 virtual void set_null(const int& index) = 0;
00188 virtual int data_size() const = 0;
00190 virtual String data_names() const = 0;
00192 virtual void data_export( const HKL& hkl, xtype array[] ) const = 0;
00194 virtual void data_import( const HKL& hkl, const xtype array[] ) = 0;
00196 virtual void mask(const HKL_data_base& mask) = 0;
00197
00199 HKL_reference_index first() const;
00201 HKL_reference_index first_data() const;
00203 HKL_reference_index& next_data( HKL_reference_index& ih ) const;
00204
00205 void debug() const;
00206
00207 protected:
00208 const HKL_info* parent_hkl_info;
00209 const Cell* parent_cell;
00210 bool cell_matches_parent;
00211
00212
00213 ObjectCache<HKL_data_cacheobj>::Reference cacheref;
00214 Spacegroup spacegroup_;
00215 Cell cell_;
00216 HKL_sampling hkl_sampling_;
00217 Resolution resolution_;
00218
00220 HKL_data_base();
00222 virtual ~HKL_data_base() {}
00223 };
00224
00225
00227
00234 template<class T> class HKL_data : public HKL_data_base
00235 {
00236 public:
00238 HKL_data() {}
00240 explicit HKL_data( const HKL_info& hkl_info );
00242 HKL_data( const HKL_info& hkl_info, const Cell& cell );
00244 HKL_data( const Spacegroup& spacegroup, const Cell& cell, const HKL_sampling& hkl_sampling );
00246 explicit HKL_data( const HKL_data_base& hkl_data );
00247
00249 void init( const HKL_info& hkl_info, const Cell& cell );
00251 void init( const Spacegroup& spacegroup, const Cell& cell, const HKL_sampling& hkl_sampling );
00253 void init( const HKL_data_base& hkl_data );
00255 void update();
00256
00257
00258 String type() const { return T::type(); }
00259 bool missing(const int& index) const { return list[index].missing(); }
00260 void set_null(const int& index) { list[index].set_null(); }
00261 int data_size() const { return T::data_size(); }
00262 String data_names() const { return T::data_names(); }
00263 void data_export( const HKL& hkl, xtype array[] ) const
00264 { T datum; get_data( hkl, datum ); datum.data_export( array ); }
00265 void data_import( const HKL& hkl, const xtype array[] )
00266 { T datum; datum.data_import( array ); set_data( hkl, datum ); }
00267 void mask(const HKL_data_base& mask);
00268
00269
00271 const T& operator[] (const HKL_info::HKL_reference_index& i) const
00272 { return list[i.index()]; }
00274 T& operator[] (const HKL_info::HKL_reference_index& i)
00275 { return list[i.index()]; }
00276
00277
00279 T operator[] (const HKL_info::HKL_reference_coord& ih) const;
00281 bool get_data(const HKL_info::HKL_reference_coord& ih, T& data) const;
00283 bool set_data(const HKL_info::HKL_reference_coord& ih, const T& data);
00284
00285
00287 const T& operator[] (const int& index) const { return list[index]; }
00289 T& operator[] (const int& index) { return list[index]; }
00290
00291
00293 T operator[] (const HKL& hkl) const;
00295 bool get_data(const HKL& hkl, T& data) const;
00297 bool set_data(const HKL& hkl, const T& data);
00298
00299
00301 template<class C> void compute( const C& op )
00302 { for (HKL_info::HKL_reference_index ih=parent_hkl_info->first(); !ih.last(); ih.next()) list[ih.index()] = op( ih ); }
00304 template<class S, class C> void compute( const HKL_data<S>& src, const C& op )
00305 { for (HKL_info::HKL_reference_index ih=parent_hkl_info->first(); !ih.last(); ih.next()) list[ih.index()] = op( ih, src[ih] ); }
00307 template<class S1, class S2, class C> void compute( const HKL_data<S1>& src1, const HKL_data<S2>& src2, const C& op )
00308 { for (HKL_info::HKL_reference_index ih=parent_hkl_info->first(); !ih.last(); ih.next()) list[ih.index()] = op( ih, src1[ih], src2[ih] ); }
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00321 HKL_data<T>& operator =( const HKL_data<T>& other );
00323 HKL_data<T>& operator =( const T& value );
00324
00325 void debug() const;
00326
00327 protected:
00328
00329 std::vector<T> list;
00330 };
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 ftype HKL_info::HKL_reference_base::invresolsq( const HKL_data_base& hkldata ) const
00341 { return hkldata.invresolsq( index_ ); }
00342
00345 template<class T> HKL_data<T>::HKL_data( const HKL_info& hkl_info )
00346 {
00347 init( hkl_info, hkl_info.cell() );
00348 }
00349
00353 template<class T> HKL_data<T>::HKL_data( const HKL_info& hkl_info, const Cell& cell )
00354 {
00355 init( hkl_info, cell );
00356 }
00357
00362 template<class T> HKL_data<T>::HKL_data( const Spacegroup& spacegroup, const Cell& cell, const HKL_sampling& hkl_sampling )
00363 {
00364 init( spacegroup, cell, hkl_sampling );
00365 }
00366
00371 template<class T> HKL_data<T>::HKL_data( const HKL_data_base& hkl_data )
00372 {
00373 init( hkl_data );
00374 }
00375
00379 template<class T> void HKL_data<T>::init( const HKL_info& hkl_info, const Cell& cell )
00380 {
00381 HKL_data_base::init( hkl_info, cell );
00382 update();
00383 }
00384
00389 template<class T> void HKL_data<T>::init( const Spacegroup& spacegroup, const Cell& cell, const HKL_sampling& hkl_sampling )
00390 {
00391 HKL_data_base::init( spacegroup, cell, hkl_sampling );
00392 update();
00393 }
00394
00399 template<class T> void HKL_data<T>::init( const HKL_data_base& hkl_data )
00400 {
00401 HKL_data_base::init( hkl_data );
00402 update();
00403 }
00404
00406 template<class T> void HKL_data<T>::update()
00407 {
00408 if ( parent_hkl_info != NULL ) {
00409 T null; null.set_null();
00410 list.resize( parent_hkl_info->num_reflections(), null );
00411 }
00412 }
00413
00418 template<class T> void HKL_data<T>::mask(const HKL_data_base& mask)
00419 {
00420 T null; null.set_null();
00421 for ( int i = 0; i < list.size(); i++ )
00422 if ( mask.missing(i) ) list[i] = null;
00423 }
00424
00430 template<class T> T HKL_data<T>::operator[] (const HKL_info::HKL_reference_coord& ih) const
00431 {
00432 if ( ih.index() < 0 ) { T null; null.set_null(); return null; }
00433 T data = list[ih.index()];
00434 if ( ih.friedel() ) data.friedel();
00435 data.shift_phase( -ih.hkl().sym_phase_shift( parent_hkl_info->spacegroup().symop(ih.sym()) ) );
00436 return data;
00437 }
00438
00445 template<class T> bool HKL_data<T>::get_data(const HKL_info::HKL_reference_coord& ih, T& data) const
00446 {
00447 if ( ih.index() < 0 ) { data.set_null(); return false; }
00448 data = list[ih.index()];
00449 if ( ih.friedel() ) data.friedel();
00450 data.shift_phase( -ih.hkl().sym_phase_shift( parent_hkl_info->spacegroup().symop(ih.sym()) ) );
00451 return true;
00452 }
00453
00460 template<class T> bool HKL_data<T>::set_data(const HKL_info::HKL_reference_coord& ih, const T& data)
00461 {
00462 if ( ih.index() < 0 ) return false;
00463 T& ldata = list[ih.index()];
00464 ldata = data;
00465 ldata.shift_phase( ih.hkl().sym_phase_shift( parent_hkl_info->spacegroup().symop(ih.sym()) ) );
00466 if ( ih.friedel() ) ldata.friedel();
00467 return true;
00468 }
00469
00475 template<class T> T HKL_data<T>::operator[] (const HKL& hkl) const
00476 {
00477 int index, sym; bool friedel;
00478
00479 index = parent_hkl_info->index_of( parent_hkl_info->
00480 find_sym(hkl, sym, friedel) );
00481 if ( index < 0 ) { T null; null.set_null(); return null; }
00482 T data = list[index];
00483 if (friedel) data.friedel();
00484 data.shift_phase( -hkl.sym_phase_shift( parent_hkl_info->spacegroup().symop(sym) ) );
00485 return data;
00486 }
00487
00494 template<class T> bool HKL_data<T>::get_data(const HKL& hkl, T& data) const
00495 {
00496 int index, sym; bool friedel;
00497
00498 index = parent_hkl_info->index_of( parent_hkl_info->
00499 find_sym(hkl, sym, friedel) );
00500 if ( index < 0 ) { data.set_null(); return false; }
00501 data = list[index];
00502 if (friedel) data.friedel();
00503 data.shift_phase( -hkl.sym_phase_shift(parent_hkl_info->spacegroup().symop(sym)) );
00504 return true;
00505 }
00506
00513 template<class T> bool HKL_data<T>::set_data(const HKL& hkl, const T& data_)
00514 {
00515 int index, sym; bool friedel;
00516 index = parent_hkl_info->index_of( parent_hkl_info->
00517 find_sym(hkl, sym, friedel) );
00518 if ( index < 0 ) { return false; }
00519 T& ldata = list[index];
00520 ldata = data_;
00521 ldata.shift_phase( hkl.sym_phase_shift(parent_hkl_info->spacegroup().symop(sym)) );
00522 if (friedel) ldata.friedel();
00523 return true;
00524 }
00525
00526
00534 template<class T> HKL_data<T>& HKL_data<T>::operator =( const HKL_data<T>& other )
00535 {
00536 if ( parent_hkl_info == NULL ) {
00537 init( other );
00538 } else {
00539 if ( parent_hkl_info != other.parent_hkl_info )
00540 Message::message( Message_fatal( "HKL_data<T>: mismatched parent HKL_info is assignment" ) );
00541 }
00542 list = other.list;
00543 return *this;
00544 }
00545
00546
00549 template<class T> HKL_data<T>& HKL_data<T>::operator =( const T& value )
00550 {
00551 for ( int i = 0; i < list.size(); i++ ) list[i] = value;
00552 return *this;
00553 }
00554
00555
00556 template<class T> void HKL_data<T>::debug() const
00557 {
00558 HKL_data_base::debug();
00559 std::cout << "Size " << list.size() << "\n";
00560 }
00561
00562
00563 }
00564
00565 #endif