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_COORDS 00046 #define CLIPPER_COORDS 00047 00048 00049 #include "cell.h" 00050 #include "spacegroup.h" 00051 #include "clipper_stats.h" 00052 00053 00054 namespace clipper 00055 { 00056 // forward definitions 00057 class Grid; class Grid_sampling; class Grid_range; 00058 class Coord_grid; class Coord_map; 00059 class Coord_reci_frac; class Coord_reci_orth; 00060 class Coord_frac; class Coord_orth; 00061 class U_aniso_frac; class U_aniso_orth; 00062 00063 00065 00068 class Resolution 00069 { 00070 public: 00071 inline Resolution() : resol(0.0) {} 00072 explicit Resolution( const ftype& resol_ ); 00073 void init( const ftype& resol_ ); 00074 const ftype& limit() const; 00075 ftype invresolsq_limit() const; 00076 bool is_null() const; 00077 private: 00078 ftype resol; 00079 }; 00080 00081 00083 00086 class HKL_class 00087 { 00088 public: 00090 inline HKL_class() { epsilon_ = 0; allowed_ = 255; } 00092 HKL_class( const Spacegroup& spgr, const HKL& hkl ); 00094 inline ftype epsilon() const { return ftype(epsilon_); } 00096 inline ftype epsilonc() const 00097 { if ( centric() ) return 2.0*ftype(epsilon_); 00098 else return ftype(epsilon_); } 00100 inline ftype allowed() const { return ftype(allowed_) * (Util::pi()/12.0); } 00101 inline bool centric() const { return allowed_ != 255; } 00102 inline bool sys_abs() const { return epsilon_ == 0; } 00103 private: 00104 unsigned char epsilon_, allowed_; 00105 }; 00106 00107 00109 00112 class RTop_orth : public RTop<> 00113 { 00114 public: 00116 inline RTop_orth() {} 00118 inline explicit RTop_orth( const RTop<>& o ) : RTop<>( o ) {} 00120 inline explicit RTop_orth( const Mat33<>& r ) : RTop<>( r ) {} 00122 inline RTop_orth( const Mat33<>& r, const Vec3<>& t ) : RTop<>( r, t ) {} 00124 RTop_orth( const std::vector<Coord_orth>& src, const std::vector<Coord_orth>& tgt ); 00126 RTop_orth( const std::vector<Coord_orth>& src, const std::vector<Coord_orth>& tgt, const std::vector<ftype>& wgt ); 00128 template<class T> RTop_orth( const T& src, const T& tgt ); 00130 RTop_frac rtop_frac( const Cell& cell ) const; 00132 RTop_orth inverse() const; 00134 Coord_orth axis_coordinate_near( const Coord_orth& centre ) const; 00136 Coord_orth screw_translation() const; 00138 static RTop_orth identity(); 00140 static RTop_orth null(); 00141 }; 00142 00143 00145 class HKL : public Vec3<int> 00146 { 00147 public: 00148 inline HKL() {} 00149 inline explicit HKL( const Vec3<int>& v ) : 00150 Vec3<int>( v ) {} 00151 inline HKL( const int& h, const int& k, const int& l ) : 00152 Vec3<int>( h, k, l ) {} 00153 inline const int& h() const { return (*this)[0]; } 00154 inline const int& k() const { return (*this)[1]; } 00155 inline const int& l() const { return (*this)[2]; } 00156 inline int& h() { return (*this)[0]; } 00157 inline int& k() { return (*this)[1]; } 00158 inline int& l() { return (*this)[2]; } 00159 00160 inline ftype invresolsq( const Cell& cell ) const; 00162 inline Coord_reci_frac coord_reci_frac() const; 00164 inline Coord_reci_orth coord_reci_orth( const Cell& cell ) const; 00166 inline HKL transform( const Symop& op ) const; 00168 inline HKL transform( const Isymop& op ) const; 00170 inline ftype sym_phase_shift( const Symop& op ) const; 00171 String format() const; 00172 friend inline HKL operator -(const HKL& h1) 00173 { return HKL( -h1.h(), -h1.k(), -h1.l() ); } 00174 friend inline HKL operator +(const HKL& h1, const HKL& h2) 00175 { return HKL( h1.h()+h2.h(), h1.k()+h2.k(), h1.l()+h2.l() ); } 00176 friend inline HKL operator -(const HKL& h1, const HKL& h2) 00177 { return HKL( h1.h()-h2.h(), h1.k()-h2.k(), h1.l()-h2.l() ); } 00178 friend inline HKL operator *(const int& s, const HKL& h1) 00179 { return HKL( s*h1.h(), s*h1.k(), s*h1.l() ); } 00180 friend inline HKL operator *(const Isymop& op, const HKL& h1) 00181 { return HKL( h1 * op.rot() ); } 00182 }; 00183 00184 00186 class Coord_reci_orth : public Vec3<> 00187 { 00188 public: 00189 inline Coord_reci_orth() {} 00190 inline explicit Coord_reci_orth( const Vec3<>& v ) : 00191 Vec3<>( v ) {} 00192 inline Coord_reci_orth( const ftype& xs, const ftype& ys, const ftype& zs ) : Vec3<>( xs, ys, zs ) {} 00193 inline const ftype& xs() const { return (*this)[0]; } 00194 inline const ftype& ys() const { return (*this)[1]; } 00195 inline const ftype& zs() const { return (*this)[2]; } 00196 00197 inline ftype invresolsq() const; 00199 inline Coord_reci_frac coord_reci_frac( const Cell& cell ) const; 00201 inline Coord_reci_orth transform( const RTop_orth& op ) const 00202 { return Coord_reci_orth( (*this) * op.rot() ); } 00203 String format() const; 00204 }; 00205 00206 00208 class Coord_reci_frac : public Vec3<> 00209 { 00210 public: 00211 inline Coord_reci_frac() {} 00212 inline explicit Coord_reci_frac( const Vec3<>& v ) : 00213 Vec3<>( v ) {} 00214 inline Coord_reci_frac( const ftype& us, const ftype& vs, const ftype& ws ) : Vec3<>( us, vs, ws ) {} 00215 00216 inline Coord_reci_frac( const HKL& hkl ) : 00217 Vec3<>( ftype(hkl[0]), ftype(hkl[1]), ftype(hkl[2]) ) {} 00219 inline HKL hkl() const 00220 { return HKL( Util::intr(us()), Util::intr(vs()), Util::intr(ws()) ); } 00222 inline ftype invresolsq( const Cell& cell ) const; 00223 inline const ftype& us() const { return (*this)[0]; } 00224 inline const ftype& vs() const { return (*this)[1]; } 00225 inline const ftype& ws() const { return (*this)[2]; } 00226 00227 inline Coord_reci_orth coord_reci_orth( const Cell& cell ) const; 00229 inline Coord_reci_frac transform( const RTop_frac& op ) const 00230 { return Coord_reci_frac( (*this) * op.rot() ); } 00231 String format() const; 00232 }; 00233 00234 00236 class Coord_grid : public Vec3<int> 00237 { 00238 public: 00239 inline Coord_grid() {} 00240 00241 inline explicit Coord_grid( const Vec3<int> v ) : Vec3<int>( v ) {} 00243 inline Coord_grid( const int& u, const int& v, const int& w ) : 00244 Vec3<int>(u,v,w) {} 00246 inline Coord_grid( const Grid& g, const int& index ) 00247 { deindex( g, index ); } 00248 inline const int& u() const { return (*this)[0]; } 00249 inline const int& v() const { return (*this)[1]; } 00250 inline const int& w() const { return (*this)[2]; } 00251 inline int& u() { return (*this)[0]; } 00252 inline int& v() { return (*this)[1]; } 00253 inline int& w() { return (*this)[2]; } 00254 00256 inline Coord_map coord_map() const; 00258 inline Coord_frac coord_frac( const Grid_sampling& g ) const; 00260 inline Coord_grid transform( const Isymop& op ) const 00261 { return op * (*this); } 00262 00264 inline Coord_grid unit( const Grid_sampling& g ) const; 00265 00267 00268 inline const Coord_grid& next( const Grid& g ); 00270 00271 inline const Coord_grid& next( const Grid_range& g ); 00273 inline bool last( const Grid& g ) const; 00275 inline bool last( const Grid_range& g ) const; 00277 inline int index( const Grid& g ) const; 00279 inline void deindex( const Grid& g, const int& index ); 00280 // grid indexing operator 00281 //inline int index( const Grid_range& g ) const; 00282 // grid deindexing operator 00283 //inline void deindex( const Grid_range& g, const int& index ); 00284 00285 String format() const; 00286 friend inline Coord_grid operator -(const Coord_grid& r1) 00287 { return ( Coord_grid( -r1.u(), -r1.v(), -r1.w() ) ); } 00288 friend inline Coord_grid operator +(const Coord_grid& r1, const Coord_grid& r2) { return ( Coord_grid( r1.u()+r2.u(), r1.v()+r2.v(), r1.w()+r2.w() ) ); } 00289 friend inline Coord_grid operator -(const Coord_grid& r1, const Coord_grid& r2) { return ( Coord_grid( r1.u()-r2.u(), r1.v()-r2.v(), r1.w()-r2.w() ) ); } 00290 friend inline Coord_grid operator *(const int& s, const Coord_grid& r1) 00291 { return ( Coord_grid( s*r1.u(), s*r1.v(), s*r1.w() ) ); } 00292 friend inline int operator == (const Coord_grid& r1, const Coord_grid& r2) 00293 { return (r1.u()==r2.u() && r1.v()==r2.v() && r1.w()==r2.w()); } 00294 friend inline int operator != (const Coord_grid& r1, const Coord_grid& r2) 00295 { return (r1.u()!=r2.u() || r1.v()!=r2.v() || r1.w()!=r2.w()); } 00296 friend inline Coord_grid operator *(const Isymop& op, const Coord_grid& r1) 00297 { return Coord_grid( op.rot() * r1 + op.trn() ); } 00298 }; 00299 00300 00302 class Coord_orth : public Vec3<> 00303 { 00304 public: 00305 inline Coord_orth() {} 00306 inline explicit Coord_orth( const Vec3<>& v ) : 00307 Vec3<>( v ) {} 00308 inline Coord_orth( const ftype& x, const ftype& y, const ftype& z ) : 00309 Vec3<>( x, y, z ) {} 00310 00311 Coord_orth( const Coord_orth& x1, const Coord_orth& x2, const Coord_orth& x3, const ftype& length, const ftype& angle, const ftype& torsion ); 00312 inline const ftype& x() const { return (*this)[0]; } 00313 inline const ftype& y() const { return (*this)[1]; } 00314 inline const ftype& z() const { return (*this)[2]; } 00315 00316 inline ftype lengthsq() const; 00318 inline Coord_frac coord_frac( const Cell& cell ) const; 00320 inline Coord_orth transform( const RTop_orth& op ) const 00321 { return op*(*this); } 00322 String format() const; 00323 00324 static ftype length( const Coord_orth& x1, const Coord_orth& x2); 00326 static ftype angle( const Coord_orth& x1, const Coord_orth& x2, 00327 const Coord_orth& x3); 00329 static ftype torsion( const Coord_orth& x1, const Coord_orth& x2, 00330 const Coord_orth& x3, const Coord_orth& x4); 00331 friend inline Coord_orth operator -(const Coord_orth& x1) 00332 { return Coord_orth( -x1.x(), -x1.y(), -x1.z() ); } 00333 friend inline Coord_orth operator +(const Coord_orth& x1, const Coord_orth& x2) { return Coord_orth( x1.x()+x2.x(), x1.y()+x2.y(), x1.z()+x2.z() ); } 00334 friend inline Coord_orth operator -(const Coord_orth& x1, const Coord_orth& x2) { return Coord_orth( x1.x()-x2.x(), x1.y()-x2.y(), x1.z()-x2.z() ); } 00335 friend inline Coord_orth operator *(const ftype& s, const Coord_orth& x1) 00336 { return Coord_orth( s*x1.x(), s*x1.y(), s*x1.z() ); } 00337 friend inline Coord_orth operator *(const RTop_orth& op, const Coord_orth& x1) { return Coord_orth( op.rot() * x1 + op.trn() ); } 00338 }; 00339 00340 00342 class Coord_frac : public Vec3<> 00343 { 00344 public: 00345 inline Coord_frac() {} 00346 inline explicit Coord_frac( const Vec3<>& v ) : 00347 Vec3<>( v ) {} 00348 inline Coord_frac( const ftype& u, const ftype& v, const ftype& w ) : 00349 Vec3<>( u, v, w ) {} 00350 inline const ftype& u() const { return (*this)[0]; } 00351 inline const ftype& v() const { return (*this)[1]; } 00352 inline const ftype& w() const { return (*this)[2]; } 00353 00354 inline ftype lengthsq( const Cell& cell ) const; 00356 inline Coord_orth coord_orth( const Cell& cell ) const; 00358 inline Coord_map coord_map( const Grid& g ) const; 00360 inline Coord_grid coord_grid( const Grid& g ) const; 00362 inline Coord_frac transform( const RTop_frac& op ) const 00363 { return op*(*this); } 00365 inline Coord_frac lattice_copy_zero() const 00366 { return Coord_frac(u()-rint(u()),v()-rint(v()),w()-rint(w())); } 00368 inline Coord_frac lattice_copy_unit() const 00369 { return Coord_frac(u()-floor(u()),v()-floor(v()),w()-floor(w())); } 00371 inline Coord_frac lattice_copy_near(const Coord_frac& n) const 00372 { return (*this-n).lattice_copy_zero()+n; } 00374 Coord_frac symmetry_copy_near(const Spacegroup& spgr, const Cell& cell, const Coord_frac& n) const; 00375 String format() const; 00376 friend inline Coord_frac operator -(const Coord_frac& u1) 00377 { return Coord_frac( -u1.u(), -u1.v(), -u1.w() ); } 00378 friend inline Coord_frac operator +(const Coord_frac& u1, const Coord_frac& u2) { return Coord_frac( u1.u()+u2.u(), u1.v()+u2.v(), u1.w()+u2.w() ); } 00379 friend inline Coord_frac operator -(const Coord_frac& u1, const Coord_frac& u2) { return Coord_frac( u1.u()-u2.u(), u1.v()-u2.v(), u1.w()-u2.w() ); } 00380 friend inline Coord_frac operator *(const ftype& s, const Coord_frac& u1) 00381 { return Coord_frac( s*u1.u(), s*u1.v(), s*u1.w() ); } 00382 friend inline Coord_frac operator *(const RTop_frac& op, const Coord_frac& x1) { return Coord_frac( op.rot() * x1 + op.trn() ); } 00383 }; 00384 00385 00387 class Coord_map : public Vec3<> 00388 { 00389 public: 00390 inline Coord_map() {} 00391 00392 inline explicit Coord_map( const Vec3<>& v ) : 00393 Vec3<>( v ) {} 00395 inline explicit Coord_map( const Coord_grid& c ) : 00396 Vec3<>( ftype(c[0]), ftype(c[1]), ftype(c[2]) ) {} 00398 inline Coord_map( const ftype& u, const ftype& v, const ftype& w ) : 00399 Vec3<>( u, v, w ) {} 00401 inline Coord_frac coord_frac( const Grid& g ) const; 00403 inline Coord_grid coord_grid() const { return Coord_grid( Util::intr((*this)[0]), Util::intr((*this)[1]), Util::intr((*this)[2]) ); } 00405 inline Coord_grid floor() const { return Coord_grid( Util::intf((*this)[0]), Util::intf((*this)[1]), Util::intf((*this)[2]) ); } 00407 inline Coord_grid ceil() const { return Coord_grid( Util::intc((*this)[0]), Util::intc((*this)[1]), Util::intc((*this)[2]) ); } 00408 inline const ftype& u() const { return (*this)[0]; } 00409 inline const ftype& v() const { return (*this)[1]; } 00410 inline const ftype& w() const { return (*this)[2]; } 00411 String format() const; 00412 friend inline Coord_map operator -(const Coord_map& u1) 00413 { return Coord_map( -u1.u(), -u1.v(), -u1.w() ); } 00414 friend inline Coord_map operator +(const Coord_map& u1, const Coord_map& u2) 00415 { return Coord_map( u1.u()+u2.u(), u1.v()+u2.v(), u1.w()+u2.w() ); } 00416 friend inline Coord_map operator -(const Coord_map& u1, const Coord_map& u2) 00417 { return Coord_map( u1.u()-u2.u(), u1.v()-u2.v(), u1.w()-u2.w() ); } 00418 friend inline Coord_map operator *(const ftype& s, const Coord_map& u1) 00419 { return Coord_map( s*u1.u(), s*u1.v(), s*u1.w() ); } 00420 }; 00421 00422 00424 00426 class U_aniso_orth : public Mat33sym<> 00427 { 00428 public: 00430 inline U_aniso_orth() {}; 00432 inline explicit U_aniso_orth( const Mat33sym<>& m ) : Mat33sym<>(m) {} 00434 inline explicit U_aniso_orth( const ftype& u ) : 00435 Mat33sym<>( u, u, u, 0.0, 0.0, 0.0 ) {} 00437 U_aniso_orth( const ftype& u11, const ftype& u22, const ftype& u33, 00438 const ftype& u12, const ftype& u13, const ftype& u23 ) : 00439 Mat33sym<>( u11, u22, u33, u12, u13, u23 ) {} 00441 ftype u_iso() const; 00443 U_aniso_frac u_aniso_frac( const Cell& cell ) const; 00445 U_aniso_orth transform( const RTop_orth& op ) const; 00446 friend U_aniso_orth operator +(const U_aniso_orth& u1, const U_aniso_orth& u2) { return U_aniso_orth( u1.mat00()+u2.mat00(), u1.mat11()+u2.mat11(), u1.mat22()+u2.mat22(), u1.mat01()+u2.mat01(), u1.mat02()+u2.mat02(), u1.mat12()+u2.mat12() ); } 00447 friend U_aniso_orth operator -(const U_aniso_orth& u) { return U_aniso_orth( -u.mat00(), -u.mat11(), -u.mat22(), -u.mat01(), -u.mat02(), -u.mat12() ); } 00448 friend U_aniso_orth operator *(const ftype& s, const U_aniso_orth& u) { return U_aniso_orth( s*u.mat00(), s*u.mat11(), s*u.mat22(), s*u.mat01(), s*u.mat02(), s*u.mat12() ); } 00449 }; 00450 00451 00453 00455 class U_aniso_frac : public Mat33sym<> 00456 { 00457 public: 00459 inline U_aniso_frac() {}; 00461 inline explicit U_aniso_frac( const Mat33sym<>& m ) : Mat33sym<>(m) {} 00463 U_aniso_frac( const ftype& u11, const ftype& u22, const ftype& u33, 00464 const ftype& u12, const ftype& u13, const ftype& u23 ) : 00465 Mat33sym<>( u11, u22, u33, u12, u13, u23 ) {} 00467 U_aniso_orth u_aniso_orth( const Cell& cell ) const; 00469 U_aniso_frac transform( const RTop_frac& op ) const; 00470 friend U_aniso_frac operator +(const U_aniso_frac& u1, const U_aniso_frac& u2) { return U_aniso_frac( u1.mat00()+u2.mat00(), u1.mat11()+u2.mat11(), u1.mat22()+u2.mat22(), u1.mat01()+u2.mat01(), u1.mat02()+u2.mat02(), u1.mat12()+u2.mat12() ); } 00471 friend U_aniso_frac operator -(const U_aniso_frac& u) { return U_aniso_frac( -u.mat00(), -u.mat11(), -u.mat22(), -u.mat01(), -u.mat02(), -u.mat12() ); } 00472 friend U_aniso_frac operator *(const ftype& s, const U_aniso_frac& u) { return U_aniso_frac( s*u.mat00(), s*u.mat11(), s*u.mat22(), s*u.mat01(), s*u.mat02(), s*u.mat12() ); } 00473 }; 00474 00475 00477 00479 class Grid : public Vec3<int> 00480 { 00481 public: 00482 inline Grid() {} 00483 inline Grid( const int& nu, const int& nv, const int& nw ) : 00484 Vec3<int>( nu, nv, nw ) {} 00485 inline const int& nu() const { return (*this)[0]; } 00486 inline const int& nv() const { return (*this)[1]; } 00487 inline const int& nw() const { return (*this)[2]; } 00488 00489 inline int size() const { return nu()*nv()*nw(); } 00491 inline bool in_grid( Coord_grid g ) const { return (g.u() >= 0 && g.u() < nu() && g.v() >= 0 && g.v() < nv() && g.w() >= 0 && g.w() < nw()); } 00492 00494 inline int index( const Coord_grid& c ) const { return c.index(*this); } 00496 inline Coord_grid deindex( const int& index ) const { return Coord_grid( *this, index ); } 00497 String format() const; 00498 void debug() const; 00499 }; 00500 00501 00503 00515 class Grid_sampling : public Grid 00516 { 00517 public: 00519 inline Grid_sampling() : Grid(Grid(0,0,0)) {} 00521 inline Grid_sampling( const int& nu, const int& nv, const int& nw ) : 00522 Grid( nu, nv, nw ) {} 00524 Grid_sampling( const Spacegroup& spacegroup, const Cell& cell, const Resolution& resol, const ftype rate = 1.5 ); 00526 void init( const Spacegroup& spacegroup, const Cell& cell, const Resolution& resol, const ftype rate = 1.5 ); 00527 00529 Mat33<> matrix_grid_frac() const; 00531 Mat33<> matrix_frac_grid() const; 00532 00534 bool is_null() const; 00535 00536 // inherited functions listed for documentation purposes 00537 //-- const int& nu() const; 00538 //-- const int& nv() const; 00539 //-- const int& nw() const; 00540 //-- int size() const; 00541 //-- int index( const Coord_grid& c ) const; 00542 //-- Coord_grid deindex( const int& index ) const; 00543 //-- const String format() const; 00544 }; 00545 00546 00548 00552 class HKL_sampling 00553 { 00554 public: 00556 HKL_sampling(); 00557 00558 HKL_sampling( const Cell& cell, const Resolution& resolution ); 00560 HKL hkl_limit() const; 00562 Resolution resolution( const Cell& cell ) const; 00564 inline bool in_resolution( const HKL& h ) const 00565 { return ( m00*itype64(h.h()*h.h()) + m11*itype64(h.k()*h.k()) + 00566 m22*itype64(h.l()*h.l()) + m01*itype64(h.h()*h.k()) + 00567 m02*itype64(h.h()*h.l()) + m12*itype64(h.k()*h.l()) ) 00568 <= ( sqrt_limit_value*sqrt_limit_value ); } 00570 bool is_null() const; 00571 String format() const; 00572 friend inline int operator == (const HKL_sampling& h1, const HKL_sampling& h2) 00573 { return ( h1.m00==h2.m00 && h1.m11==h2.m11 && h1.m22==h2.m22 && 00574 h1.m01==h2.m01 && h1.m02==h2.m02 && h1.m12==h2.m12 ); } 00575 private: 00576 static itype64 sqrt_limit_value; 00577 itype64 m00, m11, m22, m01, m02, m12; 00578 }; 00579 00580 00582 00584 class Grid_range : public Grid 00585 { 00586 public: 00588 inline Grid_range() {} 00590 Grid_range( const Coord_grid& min, const Coord_grid& max ); 00592 Grid_range( const Grid& grid, const Coord_frac& min, const Coord_frac& max ); 00594 Grid_range( const Cell& cell, const Grid& grid, const ftype& radius ); 00596 const Coord_grid& min() const { return min_; } 00598 const Coord_grid& max() const { return max_; } 00600 void add_border( const int b ); 00602 bool in_grid( Coord_grid g ) const { return (g.u() >= min_.u() && g.u() <= max_.u() && g.v() >= min_.v() && g.v() <= max_.v() && g.w() >= min_.w() && g.w() <= max_.w()); } 00603 00605 int index( const Coord_grid& c ) const { return (c - min_).index(*this); } 00607 Coord_grid deindex( const int& index ) const { return Coord_grid( *this, index ) + min_; } 00608 private: 00609 Coord_grid min_, max_; 00610 }; 00612 typedef Grid_range Grid_map; 00613 00614 00616 00620 class Atom 00621 { 00622 public: 00624 Atom() {} 00626 template<class T> Atom( const T& atom ) : element_(atom.element()), coord_orth_(atom.coord_orth()), u_aniso_orth_(atom.u_aniso_orth()) , occupancy_(atom.occupancy()), u_iso_(atom.u_iso()){} 00628 const String& element() const { return element_; } 00630 const Coord_orth& coord_orth() const { return coord_orth_; } 00632 const ftype& occupancy() const { return occupancy_; } 00634 const ftype& u_iso() const { return u_iso_; } 00636 const U_aniso_orth& u_aniso_orth() const { return u_aniso_orth_; } 00637 void set_element( const String& s ); 00638 void set_coord_orth( const Coord_orth& s ); 00639 void set_occupancy( const ftype& s ); 00640 void set_u_iso( const ftype& s ); 00641 void set_u_aniso_orth( const U_aniso_orth& s ); 00642 00643 void transform( const RTop_orth rt ); 00645 bool is_null() const { return coord_orth_.is_null(); } 00647 static Atom null(); 00648 private: 00649 String element_; 00650 Coord_orth coord_orth_; 00651 U_aniso_orth u_aniso_orth_; 00652 ftype occupancy_, u_iso_; 00653 }; 00654 00655 00657 00662 class Atom_list : public std::vector<Atom> 00663 { 00664 public: 00666 Atom_list() {} 00668 Atom_list( const std::vector<Atom>& list ) : std::vector<Atom>( list ) {} 00670 template<class T> Atom_list( const T& list ) { for ( int i = 0; i < list.size(); i++ ) push_back( Atom( list[i] ) ); } 00671 }; 00672 00673 00674 // some template function definitions 00675 00683 template<class T> RTop_orth::RTop_orth( const T& src, const T& tgt ) 00684 { 00685 std::vector<Coord_orth> vsrc( src.size() ); 00686 std::vector<Coord_orth> vtgt( tgt.size() ); 00687 for ( int i = 0; i < src.size(); i++ ) vsrc[i] = src[i].coord_orth(); 00688 for ( int i = 0; i < tgt.size(); i++ ) vtgt[i] = tgt[i].coord_orth(); 00689 (*this) = RTop_orth( vsrc, vtgt ); 00690 } 00691 00692 // some inline function definitions 00696 HKL HKL::transform( const Symop& op ) const 00697 { return Coord_reci_frac(*this).transform(op).hkl(); } 00701 HKL HKL::transform( const Isymop& op ) const 00702 { return op*(*this); } 00707 ftype HKL::sym_phase_shift( const Symop& op ) const 00708 { return -Util::twopi()*( Coord_reci_frac(*this) * op.trn() ); } 00709 00713 const Coord_grid& Coord_grid::next( const Grid& g ) 00714 { w()++; if ( w() >= g.nw() ) { w() = 0; v()++; if ( v() >= g.nv() ) { v() = 0; u()++; } } return *this; } 00718 const Coord_grid& Coord_grid::next( const Grid_range& g ) 00719 { w()++; if ( w() > g.max().w() ) { w() = g.min().w(); v()++; if ( v() > g.max().v() ) { v() = g.min().v(); u()++; } } return *this; } 00723 bool Coord_grid::last( const Grid& g ) const 00724 { return ( u() >= g.nu() ); } 00728 bool Coord_grid::last( const Grid_range& g ) const 00729 { return ( u() > g.max().u() ); } 00734 int Coord_grid::index( const Grid& g ) const 00735 { return ( u()*g.nv() + v() )*g.nw() + w(); } 00740 void Coord_grid::deindex( const Grid& g, const int& index ) 00741 { u() = index/(g.nv()*g.nw()); v() = (index/g.nw()) % g.nv(); w() = (index) % g.nw(); } 00742 00744 Coord_grid Coord_grid::unit( const Grid_sampling& g ) const 00745 { return Coord_grid( Util::mod(u(), g.nu()), Util::mod(v(), g.nv()), Util::mod(w(), g.nw()) ); } 00747 Coord_map Coord_grid::coord_map() const 00748 { return Coord_map( *this ); } 00752 Coord_frac Coord_grid::coord_frac( const Grid_sampling& g ) const 00753 { return Coord_frac( ftype(u())/ftype(g.nu()), ftype(v())/ftype(g.nv()), ftype(w())/ftype(g.nw()) ); } 00754 00757 ftype HKL::invresolsq( const Cell& cell ) const 00758 { return cell.metric_reci().lengthsq( Coord_reci_frac( *this ) ); } 00760 Coord_reci_frac HKL::coord_reci_frac() const 00761 { return Coord_reci_frac( *this ); } 00763 Coord_reci_orth HKL::coord_reci_orth( const Cell& cell ) const 00764 { return coord_reci_frac().coord_reci_orth( cell ); } 00766 ftype Coord_reci_orth::invresolsq() const 00767 { return xs()*xs() + ys()*ys() + zs()*zs(); } 00769 Coord_reci_frac Coord_reci_orth::coord_reci_frac( const Cell& cell ) const 00770 { return Coord_reci_frac( (*this) * cell.matrix_orth() ); } 00772 ftype Coord_reci_frac::invresolsq( const Cell& cell ) const 00773 { return cell.metric_reci().lengthsq( *this ); } 00775 Coord_reci_orth Coord_reci_frac::coord_reci_orth( const Cell& cell ) const 00776 { return Coord_reci_orth( (*this) * cell.matrix_frac() ); } 00777 00779 ftype Coord_orth::lengthsq() const 00780 { return x()*x()+y()*y()+z()*z(); } 00782 Coord_frac Coord_orth::coord_frac( const Cell& cell ) const 00783 { return Coord_frac( cell.matrix_frac() * (*this) ); } 00785 ftype Coord_frac::lengthsq( const Cell& cell ) const 00786 { return cell.metric_real().lengthsq( *this ); } 00788 Coord_orth Coord_frac::coord_orth( const Cell& cell ) const 00789 { return Coord_orth( cell.matrix_orth() * (*this) ); } 00791 Coord_map Coord_frac::coord_map( const Grid& g ) const 00792 { return Coord_map( u()*ftype(g.nu()), v()*ftype(g.nv()), w()*ftype(g.nw()) ); } 00794 Coord_grid Coord_frac::coord_grid( const Grid& g ) const 00795 { return Coord_grid( Util::intr(u()*ftype(g.nu())), Util::intr(v()*ftype(g.nv())), Util::intr(w()*ftype(g.nw())) ); } 00797 Coord_frac Coord_map::coord_frac( const Grid& g ) const 00798 { return Coord_frac( u()/ftype(g.nu()), v()/ftype(g.nv()), w()/ftype(g.nw()) ); } 00799 00800 } // namespace clipper 00801 00802 #endif