Clipper
nxmap.h
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_ = &map; index_ = 0; }
00138       Map_reference_index( const NXmap_base& map, const Coord_grid& pos )
00139         { map_ = &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_ = &map; }
00183       Map_reference_coord( const NXmap_base& map, const Coord_grid& pos )
00184         { map_ = &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