00001 #ifndef CCTBX_XRAY_STRUCTURE_FACTORS_SIMPLE_H
00002 #define CCTBX_XRAY_STRUCTURE_FACTORS_SIMPLE_H
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00011
00012 #include <cctbx/xray/scattering_type_registry.h>
00013 #include <cctbx/sgtbx/miller_ops.h>
00014
00015 namespace cctbx { namespace xray { namespace structure_factors {
00016
00017 template <typename ScattererType=scatterer<> >
00018 struct simple_one_h_one_scatterer
00019 {
00020 typedef typename ScattererType::float_type float_type;
00021
00022 simple_one_h_one_scatterer(
00023 sgtbx::space_group const& space_group,
00024 miller::index<> const& h,
00025 float_type d_star_sq,
00026 ScattererType const& scatterer,
00027 float_type f0)
00028 :
00029 f_calc(0,0)
00030 {
00031 using scitbx::constants::two_pi;
00032 typedef float_type f_t;
00033 typedef std::complex<f_t> c_t;
00034 f_t dw;
00035 for(std::size_t i_smx=0;i_smx<space_group.order_z();i_smx++) {
00036 sgtbx::rt_mx s = space_group(i_smx);
00037 miller::index<> hr = h * s.r();
00038 f_t hrx = hr * scatterer.site;
00039 f_t ht = f_t(h * s.t()) / space_group.t_den();
00040 f_t phase = two_pi * (hrx + ht);
00041 c_t e_j_phase(std::cos(phase), std::sin(phase));
00042 dw = 1.0;
00043 if (scatterer.flags.use_u_aniso()) {
00044 dw *= adptbx::debye_waller_factor_u_star(hr, scatterer.u_star);
00045 }
00046 if (scatterer.flags.use_u_iso()) {
00047 dw *= adptbx::debye_waller_factor_u_iso(d_star_sq/4, scatterer.u_iso);
00048 }
00049 f_calc += e_j_phase * dw;
00050 }
00051 f_calc *= (f0 + c_t(scatterer.fp, scatterer.fdp)) * scatterer.weight();
00052 }
00053
00054 std::complex<float_type> f_calc;
00055 };
00056
00057 template <typename ScattererType=scatterer<> >
00058 class simple
00059 {
00060 public:
00061 typedef ScattererType scatterer_type;
00062 typedef typename ScattererType::float_type float_type;
00063
00064 simple() {}
00065
00066 simple(
00067 uctbx::unit_cell const& unit_cell,
00068 sgtbx::space_group const& space_group,
00069 af::const_ref<miller::index<> > const& miller_indices,
00070 af::const_ref<ScattererType> const& scatterers,
00071 xray::scattering_type_registry const& scattering_type_registry)
00072 {
00073 f_calc_.reserve(miller_indices.size());
00074 af::shared<std::size_t>
00075 scattering_type_indices_memory
00076 = scattering_type_registry.unique_indices(scatterers);
00077 af::const_ref<std::size_t>
00078 scattering_type_indices = scattering_type_indices_memory.const_ref();
00079 for(std::size_t i=0;i<miller_indices.size();i++) {
00080 miller::index<> h = miller_indices[i];
00081 double d_star_sq = unit_cell.d_star_sq(h);
00082 af::shared<double>
00083 form_factors_memory
00084 = scattering_type_registry.unique_form_factors_at_d_star_sq(
00085 d_star_sq);
00086 af::const_ref<double> form_factors = form_factors_memory.const_ref();
00087 std::complex<float_type> f_calc(0,0);
00088 for(std::size_t i_sc=0;i_sc<scatterers.size();i_sc++) {
00089 float_type f0 = form_factors[scattering_type_indices[i_sc]];
00090 f_calc += simple_one_h_one_scatterer<ScattererType>(
00091 space_group,
00092 h,
00093 d_star_sq,
00094 scatterers[i_sc],
00095 f0).f_calc;
00096 }
00097 f_calc_.push_back(f_calc);
00098 }
00099 }
00100
00101 af::shared<std::complex<float_type> >
00102 f_calc() const { return f_calc_; }
00103
00104 protected:
00105 af::shared<std::complex<float_type> > f_calc_;
00106 };
00107
00108 }}}
00109
00110 #endif // DOXYGEN_SHOULD_SKIP_THIS
00111
00112 #endif // CCTBX_XRAY_STRUCTURE_FACTORS_SIMPLE_H