Files
sicspsi/rebin.c
koennecke fc94ead280 - Fixes to make SL6 work
- New NeXus libraries
- Added new raw binary transfer mode for mass data
- Added a check script option to configurable virtual motor
2012-03-29 08:41:06 +00:00

155 lines
3.8 KiB
C

/**
* This is a couple of functions to do rebinning. This is neeeded when
* you have a number of data points with random coordinates and you wish to
* get this back onto a regular grid for better handling.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, May 2007
*/
#include <math.h>
#include "rebin.h"
/*---------------------------------------------------------------------------*/
static int checkPoint(pNXDS target, double x, double y)
{
int maxx, maxy;
maxx = getNXDatasetDim(target, 0);
maxy = getNXDatasetDim(target, 1);
if (x < .0 || y < .0 || x > maxx - 1 || y > maxy - 1) {
return 0;
}
return 1;
}
/*--------------------------------------------------------------------------*/
static void addNXDatasetValue(pNXDS target, int64_t iPos[], double value)
{
double val;
val = value + getNXDatasetValue(target, iPos);
putNXDatasetValue(target, iPos, val);
}
/*---------------------------------------------------------------------------*/
static void roundPoint(pNXDS target, double x, double y, double value)
{
int64_t iDim[2];
iDim[0] = (int) floor(x + .5);
iDim[1] = (int) floor(y + 0.5);
addNXDatasetValue(target, iDim, value);
}
/*----------------------------------------------------------------------------
* I am using the squares here, no need to do the sqrt which would give the
* actual distance.
* ---------------------------------------------------------------------------*/
static double dist(double x1, double y1, double x2, double y2)
{
double dx, dy;
dx = x1 - x2;
dy = y1 - y2;
return dx * dx + dy * dy;
}
/*-----------------------------------------------------------------------------
* This tries to distribute value over all of the four neighbouring points
* weighted with the distance to them.
-------------------------------------------------------------------------------*/
static void distribute(pNXDS target, double x, double y, double value)
{
double lldist, lrdist, uldist, urdist, totalDist, ix, iy, frac;
int64_t iPos[2];
ix = floor(x);
iy = floor(y);
lldist = dist(x, y, ix, iy);
if (lldist < .01) {
iPos[0] = ix;
iPos[1] = iy;
addNXDatasetValue(target, iPos, value);
return;
}
ix += 1;
lrdist = dist(x, y, ix, iy);
if (lrdist < .01) {
iPos[0] = ix;
iPos[1] = iy;
addNXDatasetValue(target, iPos, value);
return;
}
iy += 1;
urdist = dist(x, y, ix, iy);
if (urdist < .01) {
iPos[0] = ix;
iPos[1] = iy;
addNXDatasetValue(target, iPos, value);
return;
}
ix = floor(x);
uldist = dist(x, y, ix, iy);
if (uldist < .01) {
iPos[0] = ix;
iPos[1] = iy;
addNXDatasetValue(target, iPos, value);
return;
}
lldist = 1. / lldist;
lrdist = 1. / lrdist;
urdist = 1. / urdist;
uldist = 1. / uldist;
totalDist = lldist + lrdist + urdist + uldist;
if (totalDist < .01) {
iPos[0] = (int) floor(x);
iPos[1] = (int) floor(y);
addNXDatasetValue(target, iPos, value);
return;
}
iPos[0] = (int) floor(x);
iPos[1] = (int) floor(y);
frac = (lldist / totalDist) * value;
addNXDatasetValue(target, iPos, frac);
iPos[0] += 1;
frac = (lrdist / totalDist) * value;
addNXDatasetValue(target, iPos, frac);
iPos[1] += 1;
frac = (urdist / totalDist) * value;
addNXDatasetValue(target, iPos, frac);
iPos[0] = (int) floor(x);
frac = (uldist / totalDist) * value;
addNXDatasetValue(target, iPos, frac);
}
/*---------------------------------------------------------------------------*/
int rebinPoint2D(pNXDS target, double x, double y, double value,
int method)
{
if (!checkPoint(target, x, y)) {
return 0;
}
switch (method) {
case TRILINEAR:
distribute(target, x, y, value);
break;
case ROUND:
roundPoint(target, x, y, value);
break;
default:
return 0;
}
return 1;
}