00001 #ifndef CCTBX_MAPTBX_ABSTRACT_MAP_H
00002 #define CCTBX_MAPTBX_ABSTRACT_MAP_H
00003
00004 #include<scitbx/array_family/flex_types.h>
00005 #include<cctbx/uctbx.h>
00006 #include<cctbx/maptbx/coordinate_transformers.h>
00007 #include<cctbx/maptbx/mapper.h>
00008 #include<cctbx/maptbx/generic_grid.h>
00009 #include<cctbx/maptbx/map_out_of_bounds.h>
00010 #include<vector>
00011 #include<cmath>
00012
00013 #include<iostream>
00014
00015 namespace cctbx {
00016
00017 namespace maptbx {
00018
00019 template < typename FloatType, typename IntType >
00020 class basic_map {
00021 public:
00022 static const std::size_t corners_8 = 8;
00023 typedef generic_grid<void,FloatType,IntType> grid_intf_type;
00024 typedef chiltbx::handle::handle<grid_intf_type> grid_handle_type;
00025 typedef fractional<FloatType> frac_type;
00026 typedef cartesian<FloatType> cart_type;
00027 typedef grid_point<IntType> grid_type;
00028 typedef scitbx::vec3<FloatType> vec3_type;
00029 typedef af::tiny<IntType,dimension_3> tin3_type;
00030 typedef scitbx::mat3<FloatType> mat3_type;
00031 typedef maptbx::transform<frac_type,grid_type> f2g_type;
00032 typedef maptbx::transform<frac_type,cart_type> f2c_type;
00033 typedef maptbx::transform<grid_type,frac_type> g2f_type;
00034 typedef maptbx::transform<cart_type,frac_type> c2f_type;
00035 typedef maptbx::transform<cart_type,grid_type> c2g_type;
00036 typedef maptbx::transform<grid_type,cart_type> g2c_type;
00037 typedef out_of_bounds<void,FloatType,IntType> out_of_bounds_type;
00038 typedef chiltbx::handle::handle<out_of_bounds_type> out_of_handle_type;
00039
00040 typedef std::vector<grid_type> grid_list_type;
00041 typedef std::vector<frac_type> frac_list_type;
00042 typedef af::tiny<FloatType,2> weight_pair_type;
00043 typedef af::tiny<weight_pair_type,3> weight_pairs_type;
00044 typedef maptbx::basic_mapper<void,FloatType,IntType> basic_mapper;
00045 typedef af::tiny<grid_type,2> grid_pair_type;
00046
00047 typedef af::ref<FloatType, af::flex_grid<> > flex_grid_ref;
00048 typedef af::const_ref<FloatType, af::flex_grid<> > const_flex_grid_ref;
00049 typedef af::c_grid_padded<dimension_3> c_grid_3;
00050 typedef af::ref<FloatType, c_grid_3> c_grid_ref;
00051 typedef af::const_ref<FloatType, c_grid_3 > const_c_grid_ref;
00052
00053 typedef cctbx::uctbx::unit_cell tbx_unit_cell;
00054
00055 typedef cctbx::maptbx::unit_cell unit_cell_tag;
00056
00057 basic_map (
00058 asu const&,
00059 af::versa<FloatType, af::flex_grid<> > const& data,
00060 tbx_space_group const& space_group,
00061 cdsa::float_asu<FloatType> const& fasu,
00062 tin3_type const& extents,
00063 mat3_type const& matrix,
00064 out_of_handle_type const& h_out_of,
00065 tbx_unit_cell const& unitcell,
00066 FloatType const& min_distance_sym_equiv=0.5,
00067 bool assert_min_distance_sym_equiv=true )
00068 : out_of_handle_(h_out_of) {
00069 this->set_grid_handle( data,
00070 space_group,
00071 fasu,
00072 extents,
00073 min_distance_sym_equiv,
00074 assert_min_distance_sym_equiv);
00075 this->rebuild_transformers(extents,matrix);
00076 this->unit_cell_ = unitcell;
00077 }
00078 basic_map (
00079 unit_cell_tag const&,
00080 af::versa<FloatType, af::flex_grid<> > const& data,
00081 tin3_type const& extents,
00082 mat3_type const& matrix,
00083 out_of_handle_type const& h_out_of,
00084 tbx_unit_cell const& unitcell )
00085 : out_of_handle_(h_out_of) {
00086 this->set_grid_handle(data);
00087 this->rebuild_transformers(extents,matrix);
00088 this->unit_cell_ = unitcell;
00089 }
00090 basic_map (
00091 unit_cell_tag const&,
00092 af::versa<FloatType, af::c_grid_padded<dimension_3> > const& data,
00093 tin3_type const& extents,
00094 mat3_type const& matrix,
00095 out_of_handle_type const& h_out_of,
00096 tbx_unit_cell const& unitcell )
00097 : out_of_handle_(h_out_of) {
00098 this->set_grid_handle(data);
00099 this->rebuild_transformers(extents,matrix);
00100 this->unit_cell_ = unitcell;
00101 }
00102 basic_map (
00103 non_symmetric const&,
00104 af::versa<FloatType, af::flex_grid<> > const& data,
00105 tin3_type const& extents,
00106 mat3_type const& matrix,
00107 out_of_handle_type const& h_out_of,
00108 tbx_unit_cell const& unitcell )
00109 : out_of_handle_(h_out_of) {
00110 this->set_grid_handle(data,extents);
00111 this->rebuild_transformers(extents,matrix);
00112 this->unit_cell_ = unitcell;
00113 }
00114 basic_map ( basic_map const& bm ) {
00115 this->grid_handle_ = bm.grid_handle_;
00116 this->out_of_handle_ = bm.out_of_handle_;
00117 this->rebuild_transformers(bm.extents_,bm.matrix_);
00118 this->unit_cell_ = bm.unit_cell_;
00119 }
00120 basic_map& operator = ( basic_map const& bm ) {
00121 if ( this == &bm )
00122 return *this;
00123 this->grid_handle_ = bm.grid_handle_;
00124 this->out_of_handle_ = bm.out_of_handle_;
00125 this->rebuild_transformers(bm.extents_,bm.matrix_);
00126 this->unit_cell_ = bm.unit_cell_;
00127 return *this;
00128 }
00129 void rebuild_transformers ( tin3_type const& extents, mat3_type const& matrix ) {
00130 this->extents_ = extents;
00131 this->matrix_ = matrix;
00132 this->frac2grid_ = f2g_type(this->extents_);
00133 this->grid2frac_ = this->frac2grid_.inverse();
00134 this->frac2cart_ = f2c_type(this->matrix_);
00135 this->cart2frac_ = this->frac2cart_.inverse();
00136 this->cart2grid_ = c2g_type(this->cart2frac_,this->frac2grid_);
00137 this->grid2cart_ = g2c_type(this->grid2frac_,this->frac2cart_);
00138 }
00139 af::tiny<IntType,dimension_3> origin () const {
00140 return this->grid_handle_->origin();
00141 }
00142 af::tiny<IntType,dimension_3> last () const {
00143 return this->grid_handle_->last();
00144 }
00145 af::tiny<IntType,dimension_3> focus () const {
00146 return this->grid_handle_->focus();
00147 }
00148 af::tiny<IntType,dimension_3> all () const {
00149 return this->grid_handle_->all();
00150 }
00151 FloatType grid_value ( grid_point<IntType> const& coordinate ) const {
00152
00153 return this->grid_handle_->get_value(coordinate);
00154 }
00155 void set_grid_value ( grid_point<IntType> const& coordinate, FloatType const& F ) {
00156 this->grid_handle_->set_value(coordinate,F);
00157 }
00158 FloatType get_cart_value ( cart_type const& coordinate ) const {
00159 return this->base_get_value( this->cart2frac_(coordinate) );
00160 }
00161 af::shared<FloatType>
00162 get_cart_values ( af::const_ref<scitbx::vec3<FloatType> > const& coordinates ) const {
00163 af::shared<FloatType> result(coordinates.size());
00164 for ( std::size_t i=0; i<coordinates.size(); ++i )
00165 result[i] = this->get_cart_value(coordinates[i]);
00166 return result;
00167 }
00168 FloatType get_frac_value ( frac_type const& coordinate ) const {
00169 return this->base_get_value(coordinate);
00170 }
00171 af::shared<FloatType>
00172 get_frac_values ( af::const_ref<scitbx::vec3<FloatType> > const& coordinates ) const {
00173 af::shared<FloatType> result(coordinates.size());
00174 for ( std::size_t i=0; i<coordinates.size(); ++i )
00175 result[i] = this->get_frac_value(coordinates[i]);
00176 return result;
00177 }
00178 FloatType get_grid_value ( grid_type const& coordinate ) const {
00179 grid_type gcoord = this->remap_coordinate(coordinate);
00180 if ( this->grid_handle_->is_inside(gcoord) )
00181 return this->grid_handle_->get_value(gcoord);
00182 else
00183 try {
00184 return this->out_of_handle_->retry(
00185 *this->grid_handle_.const_get_raw(),
00186 this->grid2frac_,
00187 this->grid2frac_(gcoord));
00188 } catch ( FloatType const& result ) {
00189 return result;
00190 }
00191 }
00192 af::shared<FloatType>
00193 get_grid_values ( af::const_ref<scitbx::vec3<IntType> > const& coordinates ) const {
00194 af::shared<FloatType> result(coordinates.size());
00195 for ( std::size_t i=0; i<result.size(); ++i )
00196 result[i] = this->get_grid_value(coordinates[i]);
00197 return result;
00198 }
00199 FloatType get_value ( cart_type const& coordinate ) const {
00200 return this->get_cart_value(coordinate);
00201 }
00202 FloatType get_value ( frac_type const& coordinate ) const {
00203 return this->get_frac_value(coordinate);
00204 }
00205 FloatType get_value ( grid_type const& coordinate ) const {
00206 return this->get_grid_value(coordinate);
00207 }
00208 template < typename CoordType >
00209 FloatType operator [] ( CoordType const& coordinate ) const {
00210 return this->get_value(coordinate);
00211 }
00212 template < typename CoordType >
00213 af::shared<FloatType> operator [] ( af::const_ref<CoordType> const& coordinates ) const {
00214 af::shared<FloatType> result(coordinates.size());
00215 for ( std::size_t i=0; i<result.size(); ++i )
00216 result[i] = (*this)[coordinates[i]];
00217 return result;
00218 }
00219 frac_type remap_frac_coordinate ( frac_type const& coordinate ) const {
00220 frac_type result = this->grid_handle_->remap(coordinate).mapped_coordinate;
00221 return result;
00222 }
00223 cart_type remap_cart_coordinate ( cart_type const& coordinate ) const {
00224 frac_type fcoord = this->cart2frac_(coordinate);
00225 fcoord = this->grid_handle_->remap(fcoord).mapped_coordinate;
00226 return this->frac2cart_(fcoord);
00227 }
00228 grid_type remap_grid_coordinate ( grid_type const& coordinate ) const {
00229 frac_type fcoord = this->grid2frac_(coordinate);
00230 fcoord = this->grid_handle_->remap(fcoord).mapped_coordinate;
00231 return this->frac2grid_(fcoord);
00232 }
00233 frac_type remap_coordinate ( frac_type const& coordinate ) const {
00234 return this->remap_frac_coordinate(coordinate);
00235 }
00236 cart_type remap_coordinate ( cart_type const& coordinate ) const {
00237 return this->remap_cart_coordinate(coordinate);
00238 }
00239 grid_type remap_coordinate ( grid_type const& coordinate ) const {
00240 return this->remap_grid_coordinate(coordinate);
00241 }
00242 grid_type frac_nearest_grid_point ( frac_type const& coordinate ) const {
00243 return this->remap_coordinate(this->frac2grid_(coordinate));
00244 }
00245 grid_type cart_nearest_grid_point ( cart_type const& coordinate ) const {
00246 return this->remap_coordinate(this->cart2grid_(coordinate));
00247 }
00248 grid_type nearest_grid_point ( frac_type const& coordinate ) const {
00249 return this->frac_nearest_grid_point(coordinate);
00250 }
00251 grid_type nearest_grid_point ( cart_type const& coordinate ) const {
00252 return this->cart_nearest_grid_point(coordinate);
00253 }
00254 grid_type nearest_grid_point ( grid_type const& coordinate ) const {
00255 return this->remap_coordinate(coordinate);
00256 }
00257 FloatType frac_value_at_nearest_grid_point ( frac_type const& coordinate ) const {
00258 return this->value_at_nearest_grid_point(coordinate);
00259 }
00260 FloatType cart_value_at_nearest_grid_point ( cart_type const& coordinate ) const {
00261 return this->value_at_nearest_grid_point(coordinate);
00262 }
00263 template < typename CoordType >
00264 FloatType value_at_nearest_grid_point ( CoordType const& coordinate ) const {
00265 return this->grid_handle_->get_value( this->nearest_grid_point(coordinate) );
00266 }
00267 g2f_type grid_to_frac () const {
00268 return this->grid2frac_;
00269 }
00270 c2f_type cart_to_frac () const {
00271 return this->cart2frac_;
00272 }
00273 f2g_type frac_to_grid () const {
00274 return this->frac2grid_;
00275 }
00276 f2c_type frac_to_cart () const {
00277 return this->frac2cart_;
00278 }
00279 g2c_type grid_to_cart () const {
00280 return this->grid2cart_;
00281 }
00282 c2g_type cart_to_grid () const {
00283 return this->cart2grid_;
00284 }
00285 basic_mapper remap ( frac_type const& coordinate ) const {
00286 return this->grid_handle_->remap(coordinate);
00287 }
00288 bool is_inside ( grid_point<IntType> const& coordinate ) const {
00289 return this->grid_handle_->is_inside(coordinate);
00290 }
00291 bool is_inside ( fractional<FloatType> const& coordinate ) const {
00292 return this->grid_handle_->is_inside(coordinate);
00293 }
00294 bool is_inside ( cartesian<FloatType> const& coordinate ) const {
00295 return this->grid_handle_->is_inside( this->cart2frac_(coordinate) );
00296 }
00297 grid_type get_corner000 ( frac_type const& coordinate ) const {
00298 return this->frac2grid_.floor_transform(coordinate);
00299 }
00300 grid_list_type get_corners ( grid_type const& corner000 ) const {
00301 grid_list_type corners(corners_8,corner000);
00302 std::size_t index = 0;
00303 for ( std::size_t i=0; i<2; ++i )
00304 for ( std::size_t j=0; j<2; ++j )
00305 for ( std::size_t k=0; k<2; ++k, ++index ) {
00306 corners[index][0] += (1==i?0:1);
00307 corners[index][1] += (1==j?0:1);
00308 corners[index][2] += (1==k?0:1);
00309 }
00310 return corners;
00311 }
00312 weight_pairs_type
00313 get_weights ( grid_type const& corner000, frac_type const& coordinate ) const {
00314
00315 scitbx::vec3<FloatType> g_coordinate = this->frac2grid_.strange_transform(coordinate);
00316
00317
00318 weight_pairs_type result(weight_pair_type(0.0,0.0),
00319 weight_pair_type(0.0,0.0),
00320 weight_pair_type(0.0,0.0));
00321
00322 for ( std::size_t i=0; i<dimension_3; ++i ) {
00323 result[i][0] = g_coordinate[i] - corner000[i];
00324 result[i][1] = 1 - result[i][0];
00325 }
00326
00327 return result;
00328 }
00329 FloatType base_get_value ( frac_type const& coordinate ) const {
00330
00331
00332 grid_type corner000 = this->get_corner000(coordinate);
00333 grid_list_type corners = this->get_corners(corner000);
00334
00335 weight_pairs_type weights = this->get_weights(corner000,coordinate);
00336
00337 CCTBX_ASSERT(corners.size()==corners_8);
00338
00339
00340
00341 FloatType result = 0;
00342 std::size_t index = 0;
00343 for ( std::size_t i=0; i<2; ++i )
00344 for ( std::size_t j=0; j<2; ++j )
00345 for ( std::size_t k=0; k<2; ++k, ++index ) {
00346 result += this->get_grid_value(corners[index])
00347 *weights[0][i]*weights[1][j]*weights[2][k];
00348 }
00349
00350 return result;
00351 }
00352 void set_grid_handle (
00353 af::versa<FloatType, af::flex_grid<> > const& data,
00354 tbx_space_group const& space_group,
00355 cdsa::float_asu<FloatType> const& fasu,
00356 af::tiny<IntType,dimension_3> const& grid_len,
00357 FloatType const& min_distance_sym_equiv=0.5,
00358 bool assert_min_distance_sym_equiv=true ) {
00359 this->grid_handle_
00360 = generic_grid<asu,FloatType,IntType>(
00361 data,space_group,fasu,grid_len,
00362 min_distance_sym_equiv,
00363 assert_min_distance_sym_equiv);
00364 }
00365 void set_grid_handle ( af::versa<FloatType,af::flex_grid<> > const& data ) {
00366 this->grid_handle_ = generic_grid<unit_cell_tag,FloatType,IntType>(data);
00367 }
00368 void set_grid_handle (
00369 af::versa<FloatType, af::c_grid_padded<dimension_3> > const& data ) {
00370 this->grid_handle_ = generic_grid<unit_cell_tag,FloatType,IntType>(data);
00371 }
00372 void set_grid_handle (
00373 af::versa<FloatType,af::flex_grid<> > const& data,
00374 af::tiny<IntType,dimension_3> const& grid_len ) {
00375 this->grid_handle_
00376 = generic_grid<non_symmetric,FloatType,IntType>(data,grid_len);
00377 }
00378 void set_grid_handle ( grid_handle_type const& handle ) {
00379 this->grid_handle_ = handle;
00380 }
00381 void set_out_of_bounds_handle ( out_of_handle_type const& handle ) {
00382 this->out_of_handle_ = handle;
00383 }
00384 tin3_type extents () const {
00385 return this->extents_;
00386 }
00387 tbx_unit_cell unit_cell () const {
00388 return this->unit_cell_;
00389 }
00390 private:
00391 f2g_type frac2grid_;
00392 f2c_type frac2cart_;
00393 g2f_type grid2frac_;
00394 c2f_type cart2frac_;
00395 c2g_type cart2grid_;
00396 g2c_type grid2cart_;
00397 tin3_type extents_;
00398 mat3_type matrix_;
00399 grid_handle_type grid_handle_;
00400 out_of_handle_type out_of_handle_;
00401 tbx_unit_cell unit_cell_;
00402 };
00403
00404 }
00405
00406 }
00407
00408 #endif//CCTBX_MAPTBX_ABSTRACT_MAP_H