00001
00002 #ifndef CCTBX_MAPTBX_MAPPER_H
00003 #define CCTBX_MAPTBX_MAPPER_H
00004
00005 #include<chiltbx/handle.h>
00006 #include<scitbx/math/utils.h>
00007 #include<scitbx/array_family/misc_functions.h>
00008 #include<cctbx/crystal/direct_space_asu.h>
00009 #include<cctbx/sgtbx/space_group.h>
00010 #include<cctbx/maptbx/coordinate_transformers.h>
00011
00012 namespace cctbx {
00013
00014 namespace maptbx {
00015
00016 typedef sgtbx::space_group tbx_space_group;
00017 namespace cdsa = crystal::direct_space_asu;
00018
00019 struct non_symmetric {};
00020 struct unit_cell {};
00021 struct asu {};
00022
00023
00024 template < typename Tag,
00025 typename FloatType,
00026 typename IntType > struct basic_mapper;
00027
00028 template < typename FloatType, typename IntType >
00029 struct basic_mapper<void,FloatType,IntType> {
00030 basic_mapper ( fractional<FloatType> const& coord,
00031 grid_point<IntType> const& ushft,
00032 IntType const& symop )
00033 : mapped_coordinate(coord)
00034 , unit_shift(ushft)
00035 , symmetry_operation(symop) {
00036 }
00037 basic_mapper () {}
00038 fractional<FloatType> mapped_coordinate;
00039 grid_point<IntType> unit_shift;
00040 IntType symmetry_operation;
00041 };
00042
00043
00044 template < typename FloatType, typename IntType >
00045 struct basic_mapper<non_symmetric,FloatType,IntType>
00046 : basic_mapper<void,FloatType,IntType> {
00047 basic_mapper ( fractional<FloatType> const& coord ) {
00048 this->mapped_coordinate = coord;
00049 this->unit_shift = grid_point<IntType>(0,0,0);
00050 this->symmetry_operation = IntType(-1);
00051 }
00052 };
00053
00054
00055 template < typename FloatType, typename IntType >
00056 struct basic_mapper<unit_cell,FloatType,IntType>
00057 : basic_mapper<void,FloatType,IntType> {
00058 typedef scitbx::math::float_int_conversions<FloatType,IntType> fic;
00059 basic_mapper ( fractional<FloatType> const& coord ) {
00060 for ( std::size_t i=0; i<dimension_3; ++i ) {
00061 this->mapped_coordinate[i] = scitbx::fn::fmod_positive(coord[i],FloatType(1));
00062 this->unit_shift[i] = IntType( fic::ifloor(coord[i]-this->mapped_coordinate[i]) );
00063 }
00064 this->symmetry_operation = -1;
00065 }
00066 };
00067
00068
00069 template < typename FloatType, typename IntType >
00070 struct basic_mapper<asu,FloatType,IntType>
00071 : basic_mapper<void,FloatType,IntType> {
00072 basic_mapper ( fractional<FloatType> const& coord,
00073 tbx_space_group const& space_group,
00074 cdsa::float_asu<FloatType> const& asu,
00075 FloatType const& min_distance_sym_equiv=0.5,
00076 bool assert_min_distance_sym_equiv=true ) {
00077
00078 sgtbx::site_symmetry sitesym(
00079 asu.unit_cell(),
00080 space_group,
00081 coord,
00082 min_distance_sym_equiv,
00083 assert_min_distance_sym_equiv);
00084
00085 sgtbx::sym_equiv_sites<FloatType> equiv_sites(sitesym);
00086
00087 af::const_ref<typename sgtbx::sym_equiv_sites<FloatType>::coor_t>
00088 coordinates = equiv_sites.coordinates().const_ref();
00089 af::const_ref<std::size_t>
00090 sym_op_indices = equiv_sites.sym_op_indices().const_ref();
00091
00092 for ( std::size_t i_sym_eq=0; i_sym_eq<coordinates.size(); ++i_sym_eq ) {
00093
00094 scitbx::vec3<FloatType> const& site = coordinates[i_sym_eq];
00095
00096
00097 scitbx::vec3<IntType> unit_shifts_min;
00098 scitbx::vec3<IntType> unit_shifts_max;
00099 for(std::size_t i=0;i<3;i++) {
00100 unit_shifts_min[i] = scitbx::math::iceil(
00101 asu.box_min()[i] - site[i]
00102 - 2*asu.is_inside_epsilon());
00103 unit_shifts_max[i] = scitbx::math::ifloor(
00104 asu.box_max()[i] - site[i]
00105 + 2*asu.is_inside_epsilon());
00106 }
00107
00108 scitbx::vec3<IntType> u;
00109 scitbx::vec3<FloatType> mapped_site;
00110
00111
00112
00113 for(u[0]=unit_shifts_min[0];u[0]<=unit_shifts_max[0];u[0]++) {
00114 mapped_site[0] = site[0] + u[0];
00115 for(u[1]=unit_shifts_min[1];u[1]<=unit_shifts_max[1];u[1]++) {
00116 mapped_site[1] = site[1] + u[1];
00117 for(u[2]=unit_shifts_min[2];u[2]<=unit_shifts_max[2];u[2]++) {
00118 mapped_site[2] = site[2] + u[2];
00119 if ( asu.is_inside(mapped_site) ) {
00120 this->symmetry_operation = sym_op_indices[i_sym_eq];
00121 this->unit_shift = u;
00122 this->mapped_coordinate = mapped_site;
00123 return;
00124 }
00125 }
00126 }
00127 }
00128 }
00129
00130
00131 throw error("basic_mapper<asu>: asu symmetry mapping failed internally.");
00132 }
00133 };
00134
00135 template < typename SymmetryType,
00136 typename FloatType,
00137 typename IntType > struct mapper_factory;
00138
00139 template < typename FloatType, typename IntType >
00140 struct mapper_factory<void,FloatType,IntType> {
00141 typedef basic_mapper<void,FloatType,IntType> mapper_type;
00142 typedef mapper_factory<void,FloatType,IntType> factory_type;
00143 typedef chiltbx::handle::handle<factory_type> factory_handle;
00144 virtual factory_handle as_handle () const = 0;
00145 virtual mapper_type map ( fractional<FloatType> const& ) const = 0;
00146 };
00147
00148 template < typename FactoryType > struct mapper_factory_types;
00149 template < typename SymmetryType, typename FloatType, typename IntType >
00150 struct mapper_factory_types< mapper_factory<SymmetryType,FloatType,IntType> > {
00151 typedef SymmetryType symmetry_type;
00152 typedef FloatType float_type;
00153 typedef IntType int_type;
00154 };
00155
00156
00157 template < typename SymmetryType,
00158 typename FloatType,
00159 typename IntType >
00160 struct mapper_factory : public mapper_factory<void,FloatType,IntType> {
00161 typedef basic_mapper<SymmetryType,FloatType,IntType> basic_mapper_type;
00162 typedef basic_mapper<void,FloatType,IntType> mapper_type;
00163
00164 mapper_factory () {}
00165
00166 virtual mapper_type map ( fractional<FloatType> const& coordinate ) const {
00167 basic_mapper_type bmt(coordinate);
00168 return mapper_type( bmt.mapped_coordinate,
00169 bmt.unit_shift,
00170 bmt.symmetry_operation);
00171 }
00172
00173 typedef mapper_factory<void,FloatType,IntType> factory_type;
00174 typedef chiltbx::handle::handle<factory_type> factory_handle;
00175 virtual factory_handle as_handle () const {
00176 return factory_handle(*this);
00177 }
00178 };
00179
00180
00181 template < typename FloatType, typename IntType >
00182 struct mapper_factory<asu,FloatType,IntType>
00183 : public mapper_factory<void,FloatType,IntType> {
00184 typedef basic_mapper<asu,FloatType,IntType> basic_mapper_type;
00185 typedef basic_mapper<void,FloatType,IntType> mapper_type;
00186
00187 mapper_factory () {}
00188
00189 mapper_factory ( tbx_space_group const& space_group,
00190 cdsa::float_asu<FloatType> const& asu,
00191 FloatType const& min_distance_sym_equiv=0.5,
00192 bool assert_min_distance_sym_equiv=true )
00193 : space_group_(space_group)
00194 , asu_(asu)
00195 , min_distance_sym_equiv_(min_distance_sym_equiv)
00196 , assert_min_distance_sym_equiv_(assert_min_distance_sym_equiv) {}
00197
00198 virtual mapper_type map ( fractional<FloatType> const& coordinate ) const {
00199 basic_mapper_type bmt(coordinate,
00200 this->space_group_,
00201 this->asu_,
00202 this->min_distance_sym_equiv_,
00203 this->assert_min_distance_sym_equiv_);
00204 return mapper_type( bmt.mapped_coordinate,
00205 bmt.unit_shift,
00206 bmt.symmetry_operation);
00207 }
00208
00209 typedef mapper_factory<void,FloatType,IntType> factory_type;
00210 typedef chiltbx::handle::handle<factory_type> factory_handle;
00211 virtual factory_handle as_handle () const {
00212 return factory_handle(*this);
00213 }
00214
00215 tbx_space_group space_group_;
00216 cdsa::float_asu<FloatType> asu_;
00217 FloatType min_distance_sym_equiv_;
00218 bool assert_min_distance_sym_equiv_;
00219 };
00220
00221
00222 template < typename ToFracType, typename FactoryType, typename FromFracType >
00223 typename transformer_types<FromFracType>::to_type
00224 transformer_mapper ( ToFracType const& to_frac,
00225 FactoryType const& factory,
00226 FromFracType const& from_frac,
00227 typename transformer_types<ToFracType>::from_type const& coordinate ) {
00228 return from_frac(factory.map(to_frac(coordinate)).mapped_coordinate);
00229 }
00230
00231
00232
00233
00234 template < typename ToFracType, typename FactoryType, typename FromFracType >
00235 struct transformer_mapper_factory {
00236 typedef typename transformer_types<ToFracType>::from_type from_type;
00237 typedef typename transformer_types<ToFracType>::to_type frac_type;
00238 typedef typename transformer_types<FromFracType>::to_type to_type;
00239
00240 transformer_mapper_factory () {}
00241
00242 transformer_mapper_factory (
00243 ToFracType const& tofrac,
00244 FactoryType const& fac,
00245 FromFracType const& fromfrac )
00246 : to_frac_(tofrac)
00247 , factory_(fac)
00248 , from_frac_(fromfrac) {
00249 }
00250
00251 to_type map ( from_type const& coordinate ) const {
00252 return this->from_frac_(
00253 this->factory_.map(
00254 this->to_frac_(coordinate)).mapped_coordinate);
00255 }
00256
00257 ToFracType to_frac_;
00258 FactoryType factory_;
00259 FromFracType from_frac_;
00260 };
00261
00262 }
00263
00264 }
00265
00266 #endif//CCTBX_MAPTBX_MAPPER_H