21 #include <odindata/data.h>
22 #include <odindata/utils.h>
24 #include <odinpara/ldrfilter.h>
38 GriddingPoint(
const TinyVector<float,N_rank>& c=0.0,
float w=1.0) : coord(c), weight(w) {}
40 TinyVector<float,N_rank> coord;
51 template<
typename T,
int N_rank>
70 Array<float,N_rank>
init(
const TinyVector<int,N_rank>& dst_shape,
const TinyVector<float,N_rank>& dst_extent,
72 const LDRfilter& kernel,
float kernel_diameter);
80 template<
int N_rank_in>
81 Array<T,N_rank>
operator () (
const Array<T,N_rank_in>& src,
unsigned int offset=0)
const;
85 TinyVector<int,N_rank> shape;
88 STD_vector< STD_vector< STD_pair<TinyVector<int,N_rank>,
float> > > recipe;
95 template <
typename T,
int N_rank>
96 Array<float,N_rank>
Gridding<T,N_rank>::init(
const TinyVector<int,N_rank>& dst_shape,
const TinyVector<float,N_rank>& dst_extent,
98 const LDRfilter& kernel,
float kernel_diameter) {
103 unsigned int nsrc=src_coords.size();
105 ODINLOG(odinlog,normalDebug) <<
"nsrc/kernel/kernel_diameter=" << nsrc <<
"/" << kernel.get_function_name() <<
"/" << kernel_diameter << STD_endl;
110 Array<float,N_rank> weight_sum(dst_shape);
113 TinyVector<float,N_rank> dst_step=dst_extent/dst_shape;
114 ODINLOG(odinlog,normalDebug) <<
"dst_step=" << dst_step << STD_endl;
116 TinyVector<float,N_rank> kernel_extent;
117 for(
int irank=0; irank<N_rank; irank++) {
118 if(dst_step(irank)>0.0) kernel_extent(irank)=kernel_diameter/dst_step(irank);
119 else kernel_extent(irank)=0.0;
121 ODINLOG(odinlog,normalDebug) <<
"kernel_extent=" << kernel_extent << STD_endl;
123 TinyVector<float,N_rank> offset=0.5*(dst_shape-1.0);
126 for(
unsigned int isrc=0; isrc<nsrc; isrc++) {
130 TinyVector<float,N_rank> root;
131 for(
int irank=0; irank<N_rank; irank++) {
132 if(dst_step(irank)>0.0) root(irank)=point.coord(irank)/dst_step(irank);
133 else root(irank)=0.0;
136 ODINLOG(odinlog,normalDebug) <<
"root=" << root << STD_endl;
138 TinyVector<int,N_rank> lowindex=(root-0.5*kernel_extent)+0.5;
139 TinyVector<int,N_rank> uppindex=(root+0.5*kernel_extent);
140 ODINLOG(odinlog,normalDebug) <<
"lowindex/uppindex=" << lowindex <<
"/" << uppindex << STD_endl;
143 TinyVector<int,N_rank> neighbours=uppindex-lowindex+1;
144 ODINLOG(odinlog,normalDebug) <<
"neighbours=" << neighbours << STD_endl;
147 STD_vector<STD_pair<TinyVector<int,N_rank>,
float> >& dstvec=recipe[isrc];
149 for(
int ineighb=0; ineighb<product(neighbours); ineighb++) {
150 TinyVector<int,N_rank> neighb_index=index2extent(neighbours, ineighb);
153 TinyVector<int,N_rank> index=lowindex+neighb_index;
155 for(
int i=0; i<N_rank; i++) {
156 if(index(i)<0) ongrid=
false;
157 if(index(i)>=dst_shape(i)) ongrid=
false;
162 TinyVector<float,N_rank> diff=(root-index)*dst_step;
163 float radius=sqrt(sum(diff*diff))/(0.5*kernel_diameter);
164 float weight=point.weight*kernel.calculate(radius);
165 if(weight>=0.0) dstvec.push_back(STD_pair<TinyVector<int,N_rank>,
float>(index,weight));
170 for(
unsigned int idst=0; idst<dstvec.size(); idst++) {
171 weight_sum(dstvec[idst].first)+=dstvec[idst].second;
178 for(
unsigned int isrc=0; isrc<nsrc; isrc++) {
179 STD_vector< STD_pair<TinyVector<int,N_rank>,
float> >& dstvec=recipe[isrc];
180 for(
unsigned int idst=0; idst<dstvec.size(); idst++) {
181 STD_pair<TinyVector<int,N_rank>,
float>& weightpair=dstvec[idst];
182 float weightsum=weight_sum(weightpair.first);
183 if(weightsum>0.0) weightpair.second/=weightsum;
192 template <
typename T,
int N_rank>
193 template<
int N_rank_in>
196 Array<T,N_rank> result;
198 unsigned int nsrc=src.size();
199 if((offset+nsrc)>recipe.size()) {
200 ODINLOG(odinlog,errorLog) <<
"Max index of src=" << offset+nsrc <<
" exceeds recipe.size()=" << recipe.size() << STD_endl;
204 result.resize(shape);
207 for(
unsigned int isrc=0; isrc<nsrc; isrc++) {
208 const STD_vector< STD_pair<TinyVector<int,N_rank>,
float> >& dstvec=recipe[offset+isrc];
209 for(
unsigned int idst=0; idst<dstvec.size(); idst++) {
210 const STD_pair<TinyVector<int,N_rank>,
float>& weightpair=dstvec[idst];
211 result(weightpair.first) += weightpair.second * src(index2extent(src.shape(),isrc));
226 template<
typename T,
int N_rank,
bool OnPixelRot=false>
236 CoordTransformation(
const TinyVector<int,N_rank>& shape,
const TinyMatrix<float,N_rank,N_rank>& rotation,
const TinyVector<float,N_rank>& offset,
float kernel_size=2.5);
241 Array<T,N_rank>
operator () (
const Array<T,N_rank>& A)
const;
244 TinyVector<int,N_rank> shape_cache;
250 template <
typename T,
int N_rank,
bool OnPixelRot>
252 : shape_cache(shape) {
253 Log<OdinData> odinlog(
"CoordTransformation",
"CoordTransformation");
255 int nsrc=product(shape);
256 STD_vector<GriddingPoint<N_rank> > src_coords(nsrc);
257 ODINLOG(odinlog,normalDebug) <<
"N_rank/nsrc=" << N_rank <<
"/" << nsrc << STD_endl;
259 TinyVector<float,N_rank> extent_half;
260 if(OnPixelRot) extent_half=shape/2;
261 else extent_half=0.5*(shape-1);
262 TinyVector<int,N_rank> index;
263 TinyVector<float,N_rank> findex;
264 for(
int isrc=0; isrc<nsrc; isrc++) {
265 index=index2extent(shape, isrc);
268 findex=index-extent_half;
269 src_coords[isrc].coord=rotation*findex+offset;
271 ODINLOG(odinlog,normalDebug) <<
"source done" << STD_endl;
275 gridkernel.set_function(
"Gauss");
276 gridder.init(shape, shape, src_coords, gridkernel, kernel_size);
282 template <
typename T,
int N_rank,
bool OnPixelRot>
285 if(A.shape()!=shape_cache) {
286 ODINLOG(odinlog,errorLog) <<
"Shape mismatch" << STD_endl;
Array< float, N_rank > init(const TinyVector< int, N_rank > &dst_shape, const TinyVector< float, N_rank > &dst_extent, const STD_vector< GriddingPoint< N_rank > > &src_coords, const LDRfilter &kernel, float kernel_diameter)
Array< T, N_rank > operator()(const Array< T, N_rank > &A) const
CoordTransformation(const TinyVector< int, N_rank > &shape, const TinyMatrix< float, N_rank, N_rank > &rotation, const TinyVector< float, N_rank > &offset, float kernel_size=2.5)
Array< T, N_rank > operator()(const Array< T, N_rank_in > &src, unsigned int offset=0) const