00001 #ifndef CCTBX_MAPTBX_COPY_H
00002 #define CCTBX_MAPTBX_COPY_H
00003
00004 #include <cctbx/maptbx/accessors/c_grid_padded_p1.h>
00005 #include <scitbx/array_family/accessors/c_grid_padded.h>
00006 #include <scitbx/array_family/accessors/c_grid.h>
00007 #include <scitbx/array_family/versa.h>
00008 #include <scitbx/array_family/loops.h>
00009 #include <cctbx/error.h>
00010 #include <cctbx/import_scitbx_af.h>
00011 #include <cassert>
00012
00013 namespace cctbx { namespace maptbx {
00014
00015 template <typename FloatType,
00016 typename IndexType>
00017 af::versa<FloatType, af::flex_grid<IndexType> >
00018 copy(af::const_ref<FloatType, af::flex_grid<IndexType> > const& map,
00019 af::flex_grid<IndexType> const& result_grid)
00020 {
00021 CCTBX_ASSERT(map.accessor().origin().all_eq(result_grid.origin()));
00022 CCTBX_ASSERT(map.accessor().focus().all_eq(result_grid.focus()));
00023 typedef af::flex_grid<IndexType> f_g;
00024 typedef af::versa<FloatType, f_g> result_type;
00025 f_g m0 = map.accessor().shift_origin();
00026 f_g r0 = result_grid.shift_origin();
00027 assert(m0.focus().all_eq(r0.focus()));
00028 if (!m0.is_padded() && !r0.is_padded()) {
00029 result_type result;
00030 result.as_base_array().assign(map.begin(), map.end());
00031 result.resize(result_grid);
00032 return result;
00033 }
00034 af::nested_loop<IndexType> loop(m0.focus());
00035 result_type result(result_grid);
00036 FloatType* r_begin = result.begin();
00037 for (IndexType const& pt = loop(); !loop.over(); loop.incr()) {
00038 r_begin[r0(pt)] = map[m0(pt)];
00039 }
00040 return result;
00041 }
00042
00043 template <typename ElementType>
00044 void
00045 copy(
00046 af::const_ref<ElementType, af::c_grid_padded<3> > const& source,
00047 af::ref<ElementType, af::c_grid<3> > const& target)
00048 {
00049 CCTBX_ASSERT(target.accessor().all_eq(source.accessor().focus()));
00050 typename af::c_grid_padded<3>::index_type n = target.accessor();
00051 typename af::c_grid_padded<3>::index_type i;
00052 std::size_t j = 0;
00053 for(i[0]=0;i[0]<n[0];i[0]++)
00054 for(i[1]=0;i[1]<n[1];i[1]++)
00055 for(i[2]=0;i[2]<n[2];i[2]++, j++) {
00056 target[j] = source(i);
00057 }
00058 }
00059
00060 template <typename FloatType>
00061 af::versa<FloatType, af::flex_grid<> >
00062 copy(
00063 af::const_ref<FloatType, c_grid_padded_p1<3> > const& map_unit_cell,
00064 af::int3 const& first,
00065 af::int3 const& last)
00066 {
00067 CCTBX_ASSERT(first.all_le(last));
00068 af::flex_grid_default_index_type first_(af::adapt(first));
00069 af::flex_grid_default_index_type last_(af::adapt(last));
00070 af::versa<FloatType, af::flex_grid<> > result(
00071 af::flex_grid<>(first_, last_, false));
00072 FloatType* out_ptr = result.begin();
00073 typename c_grid_padded_p1<3>::index_type out_pt;
00074 for (out_pt[0] = first[0]; out_pt[0] <= last[0]; out_pt[0]++) {
00075 for (out_pt[1] = first[1]; out_pt[1] <= last[1]; out_pt[1]++) {
00076 for (out_pt[2] = first[2]; out_pt[2] <= last[2]; out_pt[2]++) {
00077 *out_ptr++ = static_cast<FloatType>(map_unit_cell(out_pt));
00078 }}}
00079 return result;
00080 }
00081
00082 template <
00083 typename ElementType,
00084 typename IndexType>
00085 void
00086 unpad_in_place(
00087 ElementType* map_begin,
00088 IndexType const& all,
00089 IndexType const& focus)
00090 {
00091 CCTBX_ASSERT(focus[0] == all[0]);
00092 CCTBX_ASSERT(focus[1] == all[1]);
00093 CCTBX_ASSERT(focus[2] <= all[2]);
00094 typedef typename IndexType::value_type i_v_t;
00095 const i_v_t n0 = focus[0];
00096 const i_v_t n1 = focus[1];
00097 const i_v_t n2 = focus[2];
00098 const i_v_t d2 = all[2] - n2;
00099 if (d2 == 0) return;
00100 ElementType* target = map_begin + n2;
00101 const ElementType* source = target + d2;
00102 for(i_v_t i01=1;i01<n0*n1;i01++) {
00103 for(i_v_t i2=0;i2<n2;i2++) *target++ = *source++;
00104 source += d2;
00105 }
00106 }
00107
00108 template <typename ElementType>
00109 void
00110 unpad_in_place(
00111 af::versa<ElementType, af::flex_grid<> >& map)
00112 {
00113 CCTBX_ASSERT(map.accessor().nd() == 3);
00114 CCTBX_ASSERT(map.accessor().is_0_based());
00115 unpad_in_place(map.begin(), map.accessor().all(), map.accessor().focus());
00116 map = af::versa<ElementType, af::flex_grid<> >(
00117 map, af::flex_grid<>(map.accessor().focus()));
00118 }
00119
00120 }}
00121
00122 #endif // CCTBX_MAPTBX_COPY_H