00001 #ifndef CCTBX_MILLER_ASU_H
00002 #define CCTBX_MILLER_ASU_H
00003
00004 #include <cctbx/miller/sym_equiv.h>
00005 #include <cctbx/sgtbx/reciprocal_space_asu.h>
00006
00007 namespace cctbx { namespace miller {
00008
00014 class index_table_layout_adaptor : public sym_equiv_index
00015 {
00016 public:
00018 index_table_layout_adaptor() {}
00019
00021
00023 index<>
00024 h() const { return h_; }
00025
00029 std::size_t
00030 i_column() const { return i_column_; }
00031
00032 private:
00033 friend class asym_index;
00034
00035 index_table_layout_adaptor(
00036 sym_equiv_index const& eq,
00037 bool conj_h,
00038 bool f_minus_column,
00039 bool conj_f)
00040 :
00041 sym_equiv_index(eq), i_column_(0)
00042 {
00043 h_ = hr_;
00044 if (conj_h) h_ = -h_;
00045 if (f_minus_column) i_column_ = 1;
00046 friedel_flag_ = conj_f;
00047 }
00048
00049 index<> h_;
00050 std::size_t i_column_;
00051 };
00052
00054
00075 class asym_index : public sym_equiv_index
00076 {
00077 public:
00079 asym_index() {}
00080
00082
00087 asym_index(sgtbx::space_group const& space_group,
00088 sgtbx::reciprocal_space::asu const& asu,
00089 index<> const& h);
00090
00098 asym_index(sgtbx::space_group const& space_group,
00099 index<> const& h);
00100
00109 asym_index(sym_equiv_indices const& h_eq);
00110
00112
00127 index_table_layout_adaptor
00128 one_column(bool anomalous_flag) const
00129 {
00130 if (!anomalous_flag) {
00131 return index_table_layout_adaptor(*this,
00132 friedel_flag_, false, friedel_flag_);
00133 }
00134 return index_table_layout_adaptor(*this, false, false, false);
00135 }
00136
00138
00149 index_table_layout_adaptor
00150 two_column(bool anomalous_flag) const
00151 {
00152 if (!anomalous_flag) {
00153 return index_table_layout_adaptor(*this,
00154 friedel_flag_, false, friedel_flag_);
00155 }
00156 return index_table_layout_adaptor(*this,
00157 friedel_flag_, friedel_flag_, false);
00158 }
00159 };
00160
00161 namespace data_classes {
00162
00163 struct scalar_type {};
00164 struct complex_type {};
00165 struct hendrickson_lattman_type {};
00166 struct phase_type {};
00167
00168 }
00169
00170 template <typename DataClass>
00171 struct map_to_asu_policy;
00172
00173 template <>
00174 struct map_to_asu_policy<data_classes::scalar_type>
00175 {
00176 template <typename ValueType>
00177 static
00178 void
00179 eq(index_table_layout_adaptor const& , ValueType& , bool)
00180 {
00181 }
00182 };
00183
00184 template <>
00185 struct map_to_asu_policy<data_classes::complex_type>
00186 {
00187 template <typename ValueType>
00188 static
00189 void
00190 eq(index_table_layout_adaptor const& ila, ValueType& value, bool)
00191 {
00192 value = ila.complex_eq(value);
00193 }
00194 };
00195
00196 template <>
00197 struct map_to_asu_policy<data_classes::hendrickson_lattman_type>
00198 {
00199 template <typename ValueType>
00200 static
00201 void
00202 eq(index_table_layout_adaptor const& ila, ValueType& value, bool)
00203 {
00204 value = ila.hendrickson_lattman_eq(value);
00205 }
00206 };
00207
00208 template <>
00209 struct map_to_asu_policy<data_classes::phase_type>
00210 {
00211 template <typename ValueType>
00212 static
00213 void
00214 eq(index_table_layout_adaptor const& ila, ValueType& value, bool deg)
00215 {
00216 value = ila.phase_eq(value, deg);
00217 }
00218 };
00219
00220 template <> struct map_to_asu_policy<double>
00221 : map_to_asu_policy<data_classes::scalar_type> {};
00222
00223 template <> struct map_to_asu_policy<std::complex<double> >
00224 : map_to_asu_policy<data_classes::complex_type> {};
00225
00226 template <> struct map_to_asu_policy<hendrickson_lattman<> >
00227 : map_to_asu_policy<data_classes::hendrickson_lattman_type> {};
00228
00229 namespace detail {
00230
00231 template <typename ValueType,
00232 typename PolicySelectType>
00233 void
00234 map_to_asu(
00235 sgtbx::space_group_type const& sg_type,
00236 bool anomalous_flag,
00237 af::ref<index<> > const& miller_indices,
00238 af::ref<ValueType> const& data,
00239 bool deg)
00240 {
00241 CCTBX_ASSERT(miller_indices.size() == data.size());
00242 sgtbx::reciprocal_space::asu asu(sg_type);
00243 sgtbx::space_group const& sg = sg_type.group();
00244 for(std::size_t i=0;i<miller_indices.size();i++) {
00245 asym_index ai(sg, asu, miller_indices[i]);
00246 index_table_layout_adaptor ila = ai.one_column(anomalous_flag);
00247 miller_indices[i] = ila.h();
00248 map_to_asu_policy<PolicySelectType>::eq(ila, data[i], deg);
00249 }
00250 }
00251
00252 }
00253
00254 void
00255 map_to_asu(
00256 sgtbx::space_group_type const& sg_type,
00257 bool anomalous_flag,
00258 af::ref<index<> > const& miller_indices);
00259
00260 template <typename ValueType>
00261 void
00262 map_to_asu(
00263 sgtbx::space_group_type const& sg_type,
00264 bool anomalous_flag,
00265 af::ref<index<> > const& miller_indices,
00266 af::ref<ValueType> const& data)
00267 {
00268 detail::map_to_asu<ValueType, ValueType>(
00269 sg_type, anomalous_flag, miller_indices, data, false);
00270 }
00271
00272 template <typename ValueType>
00273 void
00274 map_to_asu(
00275 sgtbx::space_group_type const& sg_type,
00276 bool anomalous_flag,
00277 af::ref<index<> > const& miller_indices,
00278 af::ref<ValueType> const& data,
00279 bool deg)
00280 {
00281 detail::map_to_asu<ValueType, data_classes::phase_type>(
00282 sg_type, anomalous_flag, miller_indices, data, deg);
00283 }
00284
00285 bool
00286 is_unique_set_under_symmetry(
00287 sgtbx::space_group_type const& space_group_type,
00288 bool anomalous_flag,
00289 af::const_ref<index<> > const& miller_indices);
00290
00291 af::shared<std::size_t>
00292 unique_under_symmetry_selection(
00293 sgtbx::space_group_type const& space_group_type,
00294 bool anomalous_flag,
00295 af::const_ref<index<> > const& miller_indices);
00296
00297 }}
00298
00299 #endif // CCTBX_MILLER_ASU_H