Clipper
|
00001 00004 //C Copyright (C) 2000-2006 Kevin Cowtan and University of York 00005 //L 00006 //L This library is free software and is distributed under the terms 00007 //L and conditions of version 2.1 of the GNU Lesser General Public 00008 //L Licence (LGPL) with the following additional clause: 00009 //L 00010 //L `You may also combine or link a "work that uses the Library" to 00011 //L produce a work containing portions of the Library, and distribute 00012 //L that work under terms of your choice, provided that you give 00013 //L prominent notice with each copy of the work that the specified 00014 //L version of the Library is used in it, and that you include or 00015 //L provide public access to the complete corresponding 00016 //L machine-readable source code for the Library including whatever 00017 //L changes were used in the work. (i.e. If you make changes to the 00018 //L Library you must distribute those, but you do not need to 00019 //L distribute source or object code to those portions of the work 00020 //L not covered by this licence.)' 00021 //L 00022 //L Note that this clause grants an additional right and does not impose 00023 //L any additional restriction, and so does not affect compatibility 00024 //L with the GNU General Public Licence (GPL). If you wish to negotiate 00025 //L other terms, please contact the maintainer. 00026 //L 00027 //L You can redistribute it and/or modify the library under the terms of 00028 //L the GNU Lesser General Public License as published by the Free Software 00029 //L Foundation; either version 2.1 of the License, or (at your option) any 00030 //L later version. 00031 //L 00032 //L This library is distributed in the hope that it will be useful, but 00033 //L WITHOUT ANY WARRANTY; without even the implied warranty of 00034 //L MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00035 //L Lesser General Public License for more details. 00036 //L 00037 //L You should have received a copy of the CCP4 licence and/or GNU 00038 //L Lesser General Public License along with this library; if not, write 00039 //L to the CCP4 Secretary, Daresbury Laboratory, Warrington WA4 4AD, UK. 00040 //L The GNU Lesser General Public can also be obtained by writing to the 00041 //L Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 00042 //L MA 02111-1307 USA 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 //-- Datatype_base(); 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 // Coordinate reference types 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 // generic methods 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 // clipper2 members 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 // type specific methods 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 // data access methods: by HKL_reference_index 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 // data access methods: by HKL_reference_coord 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 // data access methods: by index 00287 const T& operator[] (const int& index) const { return list[index]; } 00289 T& operator[] (const int& index) { return list[index]; } 00290 00291 // data access methods: by hkl 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 // COMPUTATION OPERATORS 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 // inherited functions lists for documentation purposes 00311 //-- const HKL_info& base_hkl_info() const; 00312 //-- const Cell& base_cell() const; 00313 //-- const ftype invresolsq(const int& index) const; 00314 //-- const Range<ftype> invresolsq_range() const; 00315 //-- const int num_obs() const; 00316 //-- HKL_reference_index first() const; 00317 //-- HKL_reference_index first_data() const; 00318 //-- HKL_reference_index& next_data( HKL_reference_index& ih ) const; 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 // members 00329 std::vector<T> list; 00330 }; 00331 00332 00333 00334 00335 00336 00337 00338 // Template implementations 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 } // namespace clipper 00564 00565 #endif