00001 #ifndef CCTBX_CUMULATIVE_INTENSITY_DISTRIBUTION_H
00002 #define CCTBX_CUMULATIVE_INTENSITY_DISTRIBUTION_H
00003
00004 #include <scitbx/array_family/shared.h>
00005 #include <cctbx/miller.h>
00006
00007 namespace cctbx {
00008
00009 template <typename FloatType>
00010 struct bin
00011 {
00012
00013 bin(FloatType z_min_, FloatType z_max_) {
00014 count = 0;
00015 z_min = z_min_;
00016 z_max = z_max_;
00017 }
00018 int count;
00019 FloatType z_min;
00020 FloatType z_max;
00021 };
00022
00023 template <typename FloatType>
00024 class cumulative_intensity
00025
00026 {
00027 public:
00029 cumulative_intensity(
00030 af::const_ref<FloatType> const &f_sq,
00031 af::const_ref<FloatType> const &d_spacings,
00032 af::const_ref<FloatType> const &mean_f_sq_,
00033 af::const_ref<FloatType> const &bin_d_max_,
00034 af::shared<miller::index<> > const &indices)
00035 :
00036 mean_f_sq(mean_f_sq_),
00037 bin_d_max(bin_d_max_)
00038 {
00039 CCTBX_ASSERT(f_sq.size() == d_spacings.size());
00040 CCTBX_ASSERT(f_sq.size() == indices.size());
00041 CCTBX_ASSERT(mean_f_sq.size() == bin_d_max.size());
00042
00043 const int n_bins = get_bin_count();
00044 af::shared<bin<FloatType> > binner;
00045
00046 for(int i=0;i<n_bins;) {
00047 FloatType z_min = i/FloatType(n_bins);
00048 FloatType z_max = ++i/FloatType(n_bins);
00049 binner.push_back(bin<FloatType>(z_min, z_max));
00050 }
00051
00052 for(std::size_t i=0;i<indices.size();i++) {
00053 miller::index<> const &h = indices[i];
00054 FloatType i_over_mean_i = f_sq[i]/get_mean_f_sq(d_spacings[i]);
00055
00056 for(std::size_t j=0;j<binner.size();j++) {
00057 FloatType const &z = i_over_mean_i;
00058 if (z < binner[j].z_max && z > binner[j].z_min) {
00059 binner[j].count ++;
00060 break;
00061 }
00062 }
00063 }
00064
00065 FloatType cumulative_total = 0.0;
00066 for(std::size_t i=0;i<binner.size();i++) {
00067 x_.push_back(binner[i].z_max);
00068 cumulative_total += binner[i].count;
00069 y_.push_back(cumulative_total/FloatType(f_sq.size()));
00070 }
00071 }
00072
00073 inline const af::shared<FloatType>& x() const { return x_; }
00074 inline const af::shared<FloatType>& y() const { return y_; }
00075
00076 private:
00077 inline int get_bin_count() const { return mean_f_sq.size(); }
00078
00079 FloatType get_mean_f_sq(FloatType const &d_spacing) const {
00080 for(std::size_t i=0;i<get_bin_count();i++) {
00081 if (d_spacing >= bin_d_max[i])
00082 return mean_f_sq[i];
00083 }
00084 throw std::runtime_error(
00085 "Unexpected d spacing, no bin found");
00086 }
00087
00088
00089 af::shared<FloatType> x_;
00090 af::shared<FloatType> y_;
00091
00092 af::const_ref<FloatType> mean_f_sq;
00093 af::const_ref<FloatType> bin_d_max;
00094 };
00095 }
00096
00097 #endif