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_NXMAP 00046 #define CLIPPER_NXMAP 00047 00048 00049 #include "derivs.h" 00050 00051 00052 namespace clipper 00053 { 00054 00056 00066 class NXmap_base 00067 { 00068 public: 00070 bool is_null() const; 00071 00073 const Grid& grid() const { return grid_; } 00075 const RTop<>& operator_orth_grid() const { return rt_orth_grid; } 00077 const RTop<>& operator_grid_orth() const { return rt_grid_orth; } 00079 00081 inline Coord_orth coord_orth( const Coord_map& cm ) const 00082 { return Coord_orth( rt_grid_orth*cm ); } 00084 00086 inline Coord_map coord_map( const Coord_orth& co ) const 00087 { return Coord_map ( rt_orth_grid*co ); } 00088 00090 bool in_map( const Coord_grid& pos ) const { return grid_.in_grid( pos ); } 00092 template<class I> bool in_map( const Coord_map& cm ) const; 00093 00095 int multiplicity( const Coord_grid& ) const { return 1; } 00096 00098 00102 class Map_reference_base 00103 { 00104 public: 00106 inline const NXmap_base& base_nxmap() const { return *map_; } 00108 inline const int& index() const { return index_; } 00110 inline bool last() const { return ( index_ >= map_->grid_.size() ); } 00111 protected: 00113 const NXmap_base* map_; 00115 int index_; 00116 }; 00117 00119 00129 class Map_reference_index : public Map_reference_base 00130 { 00131 public: 00133 Map_reference_index() {} 00135 explicit Map_reference_index( const NXmap_base& map ) 00136 { map_ = ↦ index_ = 0; } 00138 Map_reference_index( const NXmap_base& map, const Coord_grid& pos ) 00139 { map_ = ↦ index_ = map_->grid_.index( pos ); } 00141 inline Coord_grid coord() const 00142 { return map_->grid_.deindex(index_); } 00144 inline const Coord_orth coord_orth() const 00145 { return map_->coord_orth( coord().coord_map() ); } 00147 inline Map_reference_index& set_coord( const Coord_grid& pos ) 00148 { index_ = map_->grid_.index( pos ); return *this; } 00150 inline Map_reference_index& next() { index_++; return *this; } 00152 /* Use for e.g. peak search. Valid for -1 <= du/dv/dw <= 1 only. 00153 \param du/dv/dw Coordinate offset. \return Map index. */ 00154 inline int index_offset(const int& du,const int& dv,const int& dw) const { 00155 return index_ + du*map_->du + dv*map_->dv + dw*map_->dw; 00156 } 00157 // inherited functions listed for documentation purposes 00158 //-- const NXmap_base& base_nxmap() const; 00159 //-- const int& index() const; 00160 //-- bool last() const; 00161 }; 00162 00164 00174 class Map_reference_coord : public NXmap_base::Map_reference_base 00175 { 00176 public: 00178 Map_reference_coord() {} 00180 explicit Map_reference_coord( const NXmap_base& map ) 00181 { map_ = ↦ } 00183 Map_reference_coord( const NXmap_base& map, const Coord_grid& pos ) 00184 { map_ = ↦ set_coord( pos ); } 00186 inline Coord_grid coord() const { return pos_; } 00188 inline const Coord_orth coord_orth() const 00189 { return map_->coord_orth( coord().coord_map() ); } 00191 inline Map_reference_coord& set_coord( const Coord_grid& pos ) 00192 { pos_ = pos; index_ = map_->grid_.index( pos_ ); return *this; } 00194 00195 inline Map_reference_coord& next() { 00196 index_++; 00197 pos_ = map_->grid_.deindex(index_); 00198 return *this; 00199 } 00200 // Increment u,v,w 00201 inline Map_reference_coord& next_u() { pos_.u()++; index_ += map_->du; return *this; } 00202 inline Map_reference_coord& next_v() { pos_.v()++; index_ += map_->dv; return *this; } 00203 inline Map_reference_coord& next_w() { pos_.w()++; index_ += map_->dw; return *this; } 00204 inline Map_reference_coord& prev_u() { pos_.u()--; index_ -= map_->du; return *this; } 00205 inline Map_reference_coord& prev_v() { pos_.v()--; index_ -= map_->dv; return *this; } 00206 inline Map_reference_coord& prev_w() { pos_.w()--; index_ -= map_->dw; return *this; } 00207 00208 inline Map_reference_coord& operator =( const Coord_grid& pos ) 00209 { return set_coord( pos ); } 00210 // inherited functions listed for documentation purposes 00211 //-- const NXmap_base& base_nxmap() const; 00212 //-- const int& index() const; 00213 //-- bool last() const; 00214 protected: 00216 Coord_grid pos_; 00217 }; 00218 00220 Map_reference_index first() const { return Map_reference_index( *this ); } 00222 Map_reference_coord first_coord() const { return Map_reference_coord( *this ); } 00223 00224 protected: 00225 Grid grid_; 00226 RTop<> rt_orth_grid; 00227 RTop<> rt_grid_orth; 00228 int du, dv, dw; 00229 00231 NXmap_base(); 00233 void init( const Grid& grid, const RTop<>& rt ); 00235 void init( const Cell& cell, const Grid_sampling& grid, const Grid_range& grid_extent ); 00236 00237 friend class NXmap_base::Map_reference_base; 00238 friend class NXmap_base::Map_reference_index; 00239 friend class NXmap_base::Map_reference_coord; 00240 }; 00241 00242 00243 00244 00246 00260 template<class T> class NXmap : public NXmap_base 00261 { 00262 public: 00264 NXmap() {} 00266 NXmap( const Grid& grid, const RTop<>& rt ); 00268 NXmap( const Cell& cell, const Grid_sampling& grid, const Grid_range& grid_extent ); 00270 void init( const Grid& grid, const RTop<>& rt ); 00272 void init( const Cell& cell, const Grid_sampling& grid, const Grid_range& grid_extent ); 00273 00275 inline const T& operator[] (const NXmap_base::Map_reference_index i) const 00276 { return list[i.index()]; } 00278 inline T& operator[] (const NXmap_base::Map_reference_index i) 00279 { return list[i.index()]; } 00280 00282 inline const T& operator[] (const NXmap_base::Map_reference_coord i) const 00283 { return list[i.index()]; } 00285 inline T& operator[] (const NXmap_base::Map_reference_coord i) 00286 { return list[i.index()]; } 00287 00289 inline const T& get_data( const Coord_grid& pos ) const 00290 { return list[ grid_.index( pos ) ]; } 00292 inline void set_data( const Coord_grid& pos, const T& val ) 00293 { list[ grid_.index( pos ) ] = val; } 00294 00296 template<class I> T interp( const Coord_map& pos ) const; 00298 template<class I> void interp_grad( const Coord_map& pos, T& val, Grad_map<T>& grad ) const; 00300 template<class I> void interp_curv( const Coord_map& pos, T& val, Grad_map<T>& grad, Curv_map<T>& curv ) const; 00301 00302 // inherited functions listed for documentation purposes 00303 //-- const Grid& grid() const; 00304 //-- const RTop<> operator_orth_grid() const; 00305 //-- const RTop<> operator_grid_orth() const; 00306 //-- const Coord_orth coord_orth( const Coord_map& cg ) const; 00307 //-- const Coord_map coord_map ( const Coord_orth& co ) const; 00308 //-- const Map_reference_index first(); 00309 //-- const Map_reference_coord first_coord(); 00310 00312 const T& operator =( const T& value ); 00314 const NXmap<T>& operator +=( const NXmap<T>& other ); 00316 const NXmap<T>& operator -=( const NXmap<T>& other ); 00317 00318 private: 00319 std::vector<T> list; 00320 }; 00321 00322 00323 00324 // template fucntion definitions 00325 00330 template<class I> bool NXmap_base::in_map( const Coord_map& cm ) const 00331 { return I::can_interp( *this, cm ); } 00332 00338 template<class T> NXmap<T>::NXmap( const Grid& grid, const RTop<>& rt ) 00339 { init( grid, rt ); } 00340 00348 template<class T> NXmap<T>::NXmap( const Cell& cell, const Grid_sampling& grid, const Grid_range& grid_extent ) 00349 { init( cell, grid, grid_extent ); } 00350 00356 template<class T> void NXmap<T>::init( const Grid& grid, const RTop<>& rt ) 00357 { NXmap_base::init( grid, rt ); list.resize( grid.size() ); } 00358 00366 template<class T> void NXmap<T>::init( const Cell& cell, const Grid_sampling& grid, const Grid_range& grid_extent ) 00367 { NXmap_base::init( cell, grid, grid_extent ); list.resize( grid_extent.size() ); } 00368 00369 00376 template<class T> template<class I> T NXmap<T>::interp( const Coord_map& pos ) const 00377 { 00378 T val; 00379 I::interp( *this, pos, val ); 00380 return val; 00381 } 00382 00383 00393 template<class T> template<class I> void NXmap<T>::interp_grad( const Coord_map& pos, T& val, Grad_map<T>& grad ) const 00394 { 00395 I::interp_grad( *this, pos, val, grad ); 00396 } 00397 00398 00408 template<class T> template<class I> void NXmap<T>::interp_curv( const Coord_map& pos, T& val, Grad_map<T>& grad, Curv_map<T>& curv ) const 00409 { 00410 I::interp_curv( *this, pos, val, grad, curv ); 00411 } 00412 00413 00416 template<class T> const T& NXmap<T>::operator =( const T& value ) 00417 { 00418 // copy value into map 00419 Map_reference_index im; 00420 for ( im = first(); !im.last(); im.next() ) list[im.index()] = value; 00421 return value; 00422 } 00423 00424 00426 template<class T> const NXmap<T>& NXmap<T>::operator +=( const NXmap<T>& other ) 00427 { 00428 if ( grid() != other.grid() ) 00429 Message::message( Message_fatal( "NXmap: map mismatch in +=" ) ); 00430 Map_reference_index im; 00431 for ( im = first(); !im.last(); im.next() ) list[im.index()] += other[im]; 00432 return (*this); 00433 } 00434 00436 template<class T> const NXmap<T>& NXmap<T>::operator -=( const NXmap<T>& other ) 00437 { 00438 if ( grid() != other.grid() ) 00439 Message::message( Message_fatal( "NXmap: map mismatch in -=" ) ); 00440 Map_reference_index im; 00441 for ( im = first(); !im.last(); im.next() ) list[im.index()] -= other[im]; 00442 return (*this); 00443 } 00444 00445 00446 } // namespace clipper 00447 00448 #endif