37#include "catalogue/casu_utils.h"
38#include "catalogue/casu_fits.h"
39#include "casu_stats.h"
48#define DATAMIN -1000.0
49#define DATAMAX 65535.0
63static void twodfilt(
float *data,
unsigned char *bpm,
int nx,
int ny,
64 int medfilt,
int linfilt,
int niter,
int axis,
65 int twod,
int takeout_sky,
int inorm,
int wantback,
66 float signeg,
float sigpos,
float **backmap);
67static void bfilt_1d(
float *data,
unsigned char *bpm,
int nx,
int ny,
68 int filt,
int stat,
int axis);
69static void bfilt_2d(
float *data,
unsigned char *bpmcopy,
int nx,
int ny,
71static void docols_2(
float *data,
unsigned char *bpm,
float *dbuf,
72 unsigned char *bbuf,
int nx,
int ny,
int filter,
74static void dorows_2(
float *data,
unsigned char *bpm,
float *dbuf,
75 unsigned char *bbuf,
int nx,
int ny,
int filter,
77static void dostat(
float *data,
unsigned char *bpm,
unsigned char *goodval,
78 int npts,
int nfilt,
int whichstat);
79static void wraparound(
float *data,
unsigned char *bpm,
int npts,
int nfilt,
80 int whichstat,
float **ybuf,
unsigned char **ybbuf,
82static void medavg(
float *array,
unsigned char *bpm,
int *ipoint,
int npix,
83 int whichstat,
int newl, nextlast *nl,
float *outval,
84 unsigned char *outbp);
85static void quickie(
float *array,
unsigned char *iarray,
int *iarray2,
87static void sortm(
float *a1,
unsigned char *a2,
int *a3,
int n);
88static void plugholes(
float *data,
unsigned char *bpm,
int nx);
155 int linfilt,
int niter,
int axis,
int twod,
156 int takeout_sky,
int norm,
int wantback,
157 float signeg,
float sigpos, casu_fits **backmap,
161 float *data,*backdata,*bdata;
164 const char *fctid =
"casu_nebuliser";
169 if (*status != CASU_OK)
175 nx = cpl_image_get_size_x(im);
176 ny = cpl_image_get_size_y(im);
177 data = cpl_image_get_data_float(im);
183 bpm = cpl_calloc(npts,
sizeof(
unsigned char));
184 if (inconf != NULL) {
186 if (cpl_image_get_size_x(im) != nx || cpl_image_get_size_y(im) != ny) {
187 cpl_msg_error(fctid,
"Image and conf map dimensions don't match");
191 cdata = cpl_image_get_data(im);
192 for (i = 0; i < npts; i++)
193 bpm[i] = (cdata[i] == 0);
198 twodfilt(data,bpm,nx,ny,medfilt,linfilt,niter,axis,twod,takeout_sky,norm,
199 wantback,signeg,sigpos,&backdata);
205 "ESO DRS NEBULISED",1);
208 "Nebuliser has been used on this image");
216 bdata = cpl_image_get_data_float(im);
217 memmove(bdata,backdata,npts*
sizeof(
float));
275static void twodfilt(
float *data,
unsigned char *bpm,
int nx,
int ny,
276 int medfilt,
int linfilt,
int niter,
int axis,
277 int twod,
int takeout_sky,
int inorm,
int wantback,
278 float signeg,
float sigpos,
float **backmap) {
279 int i,iter,nter,nmask;
281 float *buffer,*orig,*orig_sm,*work,medsky,sigsky,rescale,lthr,hthr;
283 unsigned char *bpmcopy;
289 buffer = cpl_malloc(3*nn*
sizeof(*buffer));
293 memmove((
char *)orig,(
char *)data,nn*
sizeof(*data));
294 memmove((
char *)orig_sm,(
char *)data,nn*
sizeof(*data));
295 memmove((
char *)work,(
char *)data,nn*
sizeof(*data));
300 bpmcopy = cpl_calloc(nn,
sizeof(*bpmcopy));
301 for (i = 0; i < nn; i++)
302 bpmcopy[i] = (bpm[i] ? 1 : 0);
306 if (niter > 1 && medfilt > 10) {
307 bfilt_1d(orig_sm,bpmcopy,nx,ny,5,MEDIANCALC,axis);
308 bfilt_1d(orig_sm,bpmcopy,nx,ny,3,MEANCALC,axis);
313 for (iter = 1; iter <= niter; iter++) {
315 memmove((
char *)data,(
char *)orig,nn*
sizeof(*data));
321 bfilt_1d(data,bpmcopy,nx,ny,medfilt,MEDIANCALC,axis);
323 bfilt_2d(data,bpmcopy,nx,ny,medfilt,MEDIANCALC);
330 for (i = 0; i < nn; i++)
331 work[i] = orig_sm[i] - data[i];
336 casu_qmedsig(work,bpmcopy,nn,3.0,3,DATAMIN,DATAMAX,&medsky,&sigsky);
339 while (sigsky < 2.5 && nter < 16) {
341 for (i = 0; i < nn; i++)
343 casu_qmedsig(work,bpmcopy,nn,3.0,3,DATAMIN,DATAMAX,&medsky,
347 rescale = (float)pow(2.0,(
double)nter);
348 for (i = 0; i < nn; i++)
353 lthr = -signeg*sigsky;
354 hthr = sigpos*sigsky;
359 for (i = 0; i < nn; i++) {
362 diff = work[i] - medsky;
363 if (diff > hthr || diff < lthr) {
375 bfilt_1d(data,bpm,nx,ny,linfilt,MEANCALC,axis);
377 bfilt_2d(data,bpm,nx,ny,linfilt,MEANCALC);
382 casu_qmedsig(orig,bpmcopy,nn,3.0,3,DATAMIN,DATAMAX,&medsky,&sigsky);
389 *backmap = cpl_malloc(nn*
sizeof(**backmap));
390 for (i = 0; i < nn; i++)
391 (*backmap)[i] = data[i];
399 for (i = 0; i < nn; i++)
400 data[i] = orig[i] - data[i] + medsky;
402 for (i = 0; i < nn; i++)
403 data[i] = orig[i]/max(1.0,data[i]);
442static void bfilt_1d(
float *data,
unsigned char *bpm,
int nx,
int ny,
443 int filt,
int stat,
int axis) {
452 dbuf = cpl_malloc(nbuf*
sizeof(*dbuf));
453 bbuf = cpl_malloc(nbuf*
sizeof(*bbuf));
459 dorows_2(data,bpm,dbuf,bbuf,nx,ny,filt,stat);
460 docols_2(data,bpm,dbuf,bbuf,nx,ny,filt,stat);
462 docols_2(data,bpm,dbuf,bbuf,nx,ny,filt,stat);
463 dorows_2(data,bpm,dbuf,bbuf,nx,ny,filt,stat);
499static void bfilt_2d(
float *data,
unsigned char *bpmcopy,
int nx,
int ny,
500 int filt,
int stat) {
501 float *dbuf,*outmap,value,*om;
502 unsigned char *outbpm,*ob;
503 int nbuf,j,i,nf2,nalloc,jj,ii,ind,ind1,j1old,j2old,i1old,i2old;
511 nalloc = (2*filt+1)*(2*filt+1);
512 dbuf = cpl_malloc(nalloc*
sizeof(*dbuf));
513 outmap = cpl_malloc(nx*ny*
sizeof(*outmap));
514 outbpm = cpl_malloc(nx*ny*
sizeof(*outbpm));
518 for (j = 0; j < ny; j++) {
519 for (i = 0; i < nx; i++) {
521 for (jj = j - nf2; jj <= j + nf2; jj++) {
522 if (jj < 0 || jj >= ny)
525 for (ii = i - nf2; ii <= i + nf2; ii++) {
526 if (ii < 0 || ii >= nx)
531 dbuf[nbuf++] = data[ind];
543 for (jj = j - filt; jj <= j + filt; jj++) {
544 if (jj < 0 || jj >= ny || (jj >= j1old && jj <= j2old))
547 for (ii = i - filt; ii <= i + filt; ii++) {
548 if (ii < 0 || ii >= nx || (ii >= i1old && ii <= i2old))
553 dbuf[nbuf++] = data[ind];
563 if (stat == MEDIANCALC)
564 value =
casu_med(dbuf,NULL,(
long)nbuf);
570 outmap[ind] = -1000.0;
579 for (j = 0; j < ny; j++) {
583 for (i = 0; i < nx; i++)
584 data[j*nx+i] = om[i];
628static void docols_2(
float *data,
unsigned char *bpm,
float *dbuf,
629 unsigned char *bbuf,
int nx,
int ny,
int filter,
633 unsigned char *goodval,*b;
639 assert(ny*
sizeof(*goodval) < PTRDIFF_MAX);
640 goodval = cpl_malloc((
size_t)ny*
sizeof(*goodval));
641 t = cpl_malloc(ny*
sizeof(*t));
642 b = cpl_malloc(ny*
sizeof(*b));
643 for (k = 0; k < nx; k++) {
644 memset((
char *)goodval,0,ny);
646 for (j = 0; j < ny; j++) {
648 if (bpm[indx] == 0) {
649 dbuf[nn] = data[indx];
653 dostat(dbuf,bbuf,goodval,nn,filter,stat);
655 for (j = 0; j < ny; j++) {
657 if (bpm[indx] == 0) {
667 for (j = 0; j < ny; j++) {
710static void dorows_2(
float *data,
unsigned char *bpm,
float *dbuf,
711 unsigned char *bbuf,
int nx,
int ny,
int filter,
715 unsigned char *goodval,*b;
721 goodval = cpl_malloc(nx*
sizeof(*goodval));
722 t = cpl_malloc(nx*
sizeof(*t));
723 b = cpl_malloc(nx*
sizeof(*b));
724 for (k = 0; k < ny; k++) {
725 memset((
char *)goodval,0,nx);
727 for (j = 0; j < nx; j++) {
731 dbuf[nn] = data[indx];
734 dostat(dbuf,bbuf,goodval,nn,filter,stat);
736 for (j = 0; j < nx; j++) {
738 if (bpm[indx] == 0) {
747 for (j = 0; j < nx; j++) {
787static void dostat(
float *data,
unsigned char *bpm,
unsigned char *goodval,
788 int npts,
int nfilt,
int whichstat) {
789 int nbuf,jl,jh,j,*ipoint,ifree,i;
790 unsigned char *ybbuf,*barray,bval;
792 float *ybuf,*darray,val;
796 if (npts < nfilt || npts < 10)
801 if ((nfilt/2)*2 == nfilt)
806 wraparound(data,bpm,npts,nfilt,whichstat,&ybuf,&ybbuf,&nbuf);
810 darray = cpl_malloc(nfilt*
sizeof(*darray));
811 barray = cpl_malloc(nfilt*
sizeof(*barray));
812 ipoint = cpl_malloc(nfilt*
sizeof(*ipoint));
813 memmove((
char *)darray,(
char *)ybuf,nfilt*
sizeof(*ybuf));
814 memmove((
char *)barray,(
char *)ybbuf,nfilt*
sizeof(*ybbuf));
815 for (j = 0; j < nfilt; j++)
818 medavg(darray,barray,ipoint,nfilt,whichstat,-1,&nl,&val,&bval);
823 jh = nfilt + npts - 2;
824 for (j = jl; j <= jh; j++) {
825 for (i = 0; i < nfilt; i++) {
826 if (ipoint[i] == 0) {
828 ipoint[i] = nfilt - 1;
829 nl.lastval = darray[ifree];
832 if (barray[ifree] == 0) {
836 darray[ifree] = ybuf[j];
837 barray[ifree] = ybbuf[j];
838 nl.nextval = darray[ifree];
841 if (barray[ifree] == 0) {
848 medavg(darray,barray,ipoint,nfilt,whichstat,ifree,&nl,&val,&bval);
851 goodval[j-jl+1] = bval;
895static void wraparound(
float *data,
unsigned char *bpm,
int npts,
int nfilt,
896 int whichstat,
float **ybuf,
unsigned char **ybbuf,
899 float *darray,xmns,xmnf;
900 int i1,ilow,i,*ipoint;
901 unsigned char *barray,bxmns,bxmnf;
907 ilow = max(3,nfilt/4);
908 ilow = (ilow/2)*2 + 1;
912 darray = cpl_malloc(nfilt*
sizeof(*darray));
913 barray = cpl_malloc(nfilt*
sizeof(*barray));
914 ipoint = cpl_calloc(nfilt,
sizeof(*ipoint));
916 *ybuf = cpl_malloc(*nbuf*
sizeof(
float));
917 *ybbuf = cpl_malloc(*nbuf*
sizeof(
unsigned char));
921 memmove((
char *)darray,(
char *)data,ilow*
sizeof(*data));
922 memmove((
char *)barray,(
char *)bpm,ilow*
sizeof(*bpm));
923 medavg(darray,barray,ipoint,ilow,whichstat,-1,&nl,&xmns,&bxmns);
924 memmove((
char *)darray,(
char *)(data+npts-ilow),ilow*
sizeof(*data));
925 memmove((
char *)barray,(
char *)(bpm+npts-ilow),ilow*
sizeof(*bpm));
926 medavg(darray,barray,ipoint,ilow,whichstat,-1,&nl,&xmnf,&bxmnf);
927 for (i = 0; i < i1; i++) {
929 (*ybuf)[i] = 2.0*xmns - data[i1+ilow-i-1];
930 (*ybbuf)[i] = bpm[i1+ilow-i-1];
932 (*ybuf)[i] = data[i1+ilow-i-1];
936 (*ybuf)[npts+i1+i] = 2.0*xmnf - data[npts-i-ilow-1];
937 (*ybbuf)[npts+i1+i] = bpm[npts-i-ilow-1];
939 (*ybuf)[npts+i1+i] = data[npts-i-ilow-1];
940 (*ybbuf)[npts+i1+i] = 1;
946 memmove((
char *)(*ybuf+i1),data,npts*
sizeof(*data));
947 memmove((
char *)(*ybbuf+i1),bpm,npts*
sizeof(*bpm));
990static void medavg(
float *array,
unsigned char *bpm,
int *ipoint,
int npix,
991 int whichstat,
int newl, nextlast *nl,
float *outval,
992 unsigned char *outbp) {
1001 if (whichstat == MEDIANCALC) {
1003 sortm(array,bpm,ipoint,npix);
1005 quickie(array,bpm,ipoint,newl,npix);
1008 assert((
size_t)npix*
sizeof(*buf) < PTRDIFF_MAX);
1009 buf = cpl_malloc(npix*
sizeof(*buf));
1014 for (i = 0; i < npix; i++) {
1020 }
else if (whichstat == MEANCALC) {
1025 for (i = 0; i < npix; i++) {
1027 nl->sum += array[i];
1034 nl->sum += (nl->nextw*nl->nextval - nl->lastw*nl->lastval);
1035 nl->sumw += (nl->nextw - nl->lastw);
1036 nl->naver += (nl->nextc - nl->lastc);
1046 if (whichstat == MEDIANCALC)
1052 if (whichstat == MEDIANCALC) {
1055 }
else if (whichstat == MEANCALC)
1056 *outval = (nl->sum)/(nl->sumw);
1089static void quickie(
float *array,
unsigned char *iarray,
int *iarray2,
1090 int lll,
int narray) {
1100 for (i = 0; i < narray; i++) {
1101 if (i != lll && test <= array[i]) {
1113 for (i = 0; i < npt; i++) {
1114 array[lll-i] = array[lll-i-1];
1115 iarray[lll-i] = iarray[lll-i-1];
1116 iarray2[lll-i] = iarray2[lll-i-1];
1125 for (i = 0; i < npt; i++) {
1126 array[lll+i] = array[lll+i+1];
1127 iarray[lll+i] = iarray[lll+i+1];
1128 iarray2[lll+i] = iarray2[lll+i+1];
1161static void sortm(
float *a1,
unsigned char *a2,
int *a3,
int n) {
1162 int iii,ii,i,ifin,j,b3;
1169 iii = min(n,(3*iii)/4 - 1);
1174 for (ii = 0; ii < ifin; ii++) {
1177 if (a1[i] > a1[j]) {
1187 if (i < 0 || a1[i] <= b1)
1220static void plugholes(
float *data,
unsigned char *bpm,
int nx) {
1221 int i,ifirst,ilast,i1,i2,j;
1222 float nc,d1,d2,t1,t2,slope;
1227 while (i < nx && bpm[i] != 0)
1239 while (i >= 0 && bpm[i] != 0)
1247 while (i <= ilast) {
1256 nc = (float)(i2 - i1 + 1);
1259 for (j = i1+1; j <= i2-1; j++) {
1260 t1 = 1.0 - (float)(j - i1)/nc;
1262 data[j] = t1*d1 + t2*d2;
1269 slope = data[ifirst+1] - data[ifirst];
1270 for (j = 0; j < ifirst; j++)
1271 data[j] = slope*(
float)(j - ifirst) + data[ifirst];
1276 if (ilast < nx - 1) {
1277 slope = data[ilast] - data[ilast-1];
1278 for (j = ilast; j < nx; j++)
1279 data[j] = slope*(
float)(j - ilast) + data[ilast];
cpl_image * casu_fits_get_image(casu_fits *p)
casu_fits * casu_fits_duplicate(casu_fits *in)
cpl_propertylist * casu_fits_get_ehu(casu_fits *p)
int casu_nebuliser(casu_fits *infile, casu_fits *inconf, int medfilt, int linfilt, int niter, int axis, int twod, int takeout_sky, int norm, int wantback, float signeg, float sigpos, casu_fits **backmap, int *status)
Remove small scale background variations.
float casu_med(float *data, unsigned char *bpm, long npts)
void casu_qmedsig(float *data, unsigned char *bpm, long npts, float thresh, int niter, float lowv, float highv, float *median, float *sigma)
float casu_mean(float *data, unsigned char *bpm, long npts)