VIRCAM Pipeline 2.3.15
casu_backmap.c
1/* $Id: casu_backmap.c,v 1.4 2015/09/15 14:13:26 jim Exp $
2 *
3 * This file is part of the CASU Pipeline utilities
4 * Copyright (C) 2015 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * $Author: jim $
23 * $Date: 2015/09/15 14:13:26 $
24 * $Revision: 1.4 $
25 * $Name: $
26 */
27
28/* Includes */
29
30#ifdef HAVE_CONFIG_H
31#include <config.h>
32#endif
33
34#include <string.h>
35
36#include "casu_mods.h"
37#include "catalogue/casu_utils.h"
38#include "catalogue/casu_fits.h"
39#include "casu_filt.h"
40#include "casu_stats.h"
41
42/* Set up some global histogramming parameters */
43
44#define MAXHIST 66536
45#define MINHISTVAL -1000
46#define MAXHISTVAL 65535
47
48static void medsig(int *hist, int ist, int itarg, float *med, float *sig);
49
63/*---------------------------------------------------------------------------*/
106/*---------------------------------------------------------------------------*/
107
108extern int casu_backmap(float *map, cpl_binary *bpm, int nx, int ny,
109 int nbsize, float *avback, float **skymap,
110 int *status) {
111 float fracx,fracy,skymed,sigma,skymedc,sigmac,fnbsize,dely,delx;
112 float t1,t2,*bvals;
113 int ifracx,ifracy,nbsizx,nbsizy,nbx,nby,npixstripe,l,i,ll;
114 int isquare,ilev,j,iclip,mcpix,iloop,irej,nbsizo2,kk,k,iby,ibyp1,ibx,ibxp1;
115 int *shist,**hist,*nnp,jj1,jj2,jj3,jj4,npts,ind;
116 unsigned char *badmask;
117
118 /* Do some preliminary checking...*/
119
120 *skymap = NULL;
121 *avback = 0.0;
122 if (*status != CASU_OK)
123 return(*status);
124 if (map == NULL || bpm == NULL)
125 FATAL_ERROR
126 npts = nx*ny;
127 if (npts <= 0)
128 FATAL_ERROR
129 for (j = 0; j < npts; j++)
130 if (bpm[j] == 0)
131 break;
132 if (j == npts)
133 FATAL_ERROR
134 if (nbsize <= 0)
135 FATAL_ERROR
136
137 /* Check to see if nbsize is close to exact divisor */
138
139 fracx = ((float)nx)/((float)nbsize);
140 fracy = ((float)ny)/((float)nbsize);
141 ifracx = (int)(fracx + 0.1);
142 ifracy = (int)(fracy + 0.1);
143 nbsizx = nx/ifracx;
144 nbsizy = ny/ifracy;
145 nbsize = max(casu_nint(0.9*nbsize),min(nbsize,min(nbsizx,nbsizy)));
146 nbsize = min(nx,min(ny,nbsize)); /* trap for small maps */
147
148 /* Divide the map into partitions */
149
150 nbx = nx/nbsize;
151 nby = ny/nbsize;
152 npixstripe = nbsize*nx;
153
154 /* Get histogram workspace if you can */
155
156 hist = cpl_malloc(nbx*sizeof(int *));
157 for (l = 0; l < nbx; l++)
158 hist[l] = cpl_malloc(MAXHIST*sizeof(int));
159
160 /* Same for background values array and for a bad mask */
161
162 bvals = cpl_malloc(nbx*nby*sizeof(float *));
163 badmask = cpl_calloc(nbx*nby,sizeof(unsigned char *));
164
165 /* Finally a counter array */
166
167 nnp = cpl_malloc(nbx*sizeof(int));
168
169 /* Loop for each row of background squares. Start by initialising
170 the accumulators and histograms */
171
172 for (l = 0; l < nby; l++) {
173 memset((char *)nnp,0,nbx*sizeof(*nnp));
174 for (i = 0; i < nbx; i++)
175 memset((char *)hist[i],0,MAXHIST*sizeof(int));
176
177 /* Skim through the data in this stripe. Find out which square each
178 belongs to and add it it to the relevant histogram */
179
180 ll = l*npixstripe;
181 for (i = 0; i < npixstripe; i++) {
182 ind = ll + i;
183 if (ind >= npts)
184 break;
185 if (bpm[ind] == 0) {
186 isquare = (int)((float)(i % nx)/(float)nbsize);
187 isquare = min(nbx-1,max(0,isquare));
188 ilev = min(MAXHISTVAL,max(MINHISTVAL,casu_nint(map[ind])));
189 hist[isquare][ilev-MINHISTVAL] += 1;
190 nnp[isquare] += 1;
191 }
192 }
193
194 /* Only do background estimation if enough pixels */
195
196 for (j = 0; j < nbx; j++) {
197 jj1 = l*nbx + j;
198 if (nnp[j] > 0.25*nbsize*nbsize) {
199 shist = hist[j];
200 medsig(shist,MINHISTVAL-1,nnp[j],&skymed,&sigma);
201
202 /* Do an iterative 3-sigma upper clip to give a more robust
203 estimator */
204
205 iclip = MAXHISTVAL;
206 mcpix = nnp[j];
207 skymedc = skymed;
208 sigmac = sigma;
209 for (iloop = 0; iloop < 3; iloop++) {
210 irej = 0;
211 for (i = casu_nint(skymedc+3.0*sigmac); i <= iclip; i++)
212 irej += shist[i-MINHISTVAL];
213 if (irej == 0)
214 break;
215 iclip = casu_nint(skymedc+3.0*sigmac) - 1;
216 mcpix = mcpix - irej;
217 medsig(shist,MINHISTVAL-1,mcpix,&skymedc,
218 &sigmac);
219 }
220 bvals[jj1] = skymedc;
221 badmask[jj1] = 0;
222 } else {
223 bvals[jj1] = -1000.0;
224 badmask[jj1] = 1;
225 }
226 }
227
228 }
229
230 /* Filter raw background values */
231
232 casu_bfilt(bvals,badmask,nbx,nby,3,MEDIANCALC,1);
233
234 /* Compute average background level */
235
236 *avback = casu_med(bvals,badmask,(long)(nbx*nby));
237 freespace(badmask);
238
239 /* OK now create a sky map */
240
241 *skymap = cpl_malloc(nx*ny*sizeof(float));
242 nbsizo2 = nbsize/2;
243 fnbsize = 1.0/((float)nbsize);
244 for (k = 0; k < ny; k++) {
245 kk = k*nx;
246
247 /* Nearest background pixel vertically */
248
249 iby = (k + 1 + nbsizo2)/nbsize;
250 ibyp1 = iby + 1;
251 iby = min(nby,max(1,iby));
252 ibyp1 = min(nby,ibyp1);
253 dely = (k + 1 - nbsize*iby + nbsizo2)*fnbsize;
254
255 for (j = 0; j < nx; j++) {
256
257 /* nearest background pixel across */
258
259 ibx = (j + 1 + nbsizo2)/nbsize;
260 ibxp1 = ibx + 1;
261 ibx = min(nbx,max(1,ibx));
262 ibxp1 = min(nbx,ibxp1);
263 delx = (j + 1 - nbsize*ibx + nbsizo2)*fnbsize;
264 jj1 = (iby-1)*nbx + ibx - 1;
265 jj2 = (ibyp1-1)*nbx + ibx - 1;
266 jj3 = (iby-1)*nbx + ibxp1 - 1;
267 jj4 = (ibyp1-1)*nbx + ibxp1 - 1;
268
269 /* bilinear interpolation to find background */
270
271 t1 = (1.0 - dely)*bvals[jj1] + dely*bvals[jj2];
272 t2 = (1.0 - dely)*bvals[jj3] + dely*bvals[jj4];
273 (*skymap)[kk+j] = (1.0 - delx)*t1 + delx*t2;
274 }
275 }
276
277 /* Free some workspace */
278
279 for (l = 0; l < nbx; l++)
280 freespace(hist[l]);
281 freespace(hist);
282 freespace(bvals);
283 freespace(nnp);
284 return(CASU_OK);
285}
286
287/*---------------------------------------------------------------------------*/
316/*---------------------------------------------------------------------------*/
317
318static void medsig(int *hist, int ist, int itarg, float *med, float *sig) {
319 int isum, medata,indx;
320 float ffrac,sigmed;
321
322 /* The median. We start in the lowest allowable bin defined by 'ist'.
323 We then continue summing up until we have reached just over
324 half the allowed contributions defined by 'itarg'. */
325
326 isum = 0;
327 medata = ist;
328 indx = medata - MINHISTVAL;
329 while (isum <= (itarg+1)/2 && indx < MAXHIST - 1) {
330 medata++;
331 indx = medata - MINHISTVAL;
332 isum += hist[indx];
333 }
334 ffrac = (float)(isum - (itarg+1)/2)/(float)hist[medata-MINHISTVAL];
335 *med = (float)medata - ffrac + 0.5;
336
337 /* The sigma. We start in the lowest allowable bin defined by 'ist'.
338 We then continue summing up until we have reached just over
339 3/4 of the allowed contributions defined by 'itarg'. The sigma
340 is defined as 1.48* the distance from this third quartile to the
341 median point. A minimal value is also included. */
342
343 isum = 0;
344 medata = ist;
345 indx = medata - MINHISTVAL;
346 while (isum <= (itarg+3)/4 && indx < MAXHIST - 1) {
347 medata++;
348 indx = medata - MINHISTVAL;
349 isum += hist[indx];
350 }
351 ffrac = (float)(isum - (itarg+3)/4)/(float)hist[medata-MINHISTVAL];
352 sigmed = (float)medata - ffrac + 0.5;
353 *sig = 1.48*(*med - sigmed);
354 *sig = max(2.5,*sig);
355}
356
357
360/*
361
362$Log: casu_backmap.c,v $
363Revision 1.4 2015/09/15 14:13:26 jim
364Fixed problem with illegal memory read
365
366Revision 1.3 2015/09/11 09:27:53 jim
367Fixed some problems with the docs
368
369Revision 1.2 2015/08/07 13:06:54 jim
370Fixed copyright to ESO
371
372Revision 1.1.1.1 2015/06/12 10:44:32 jim
373Initial import
374
375Revision 1.6 2015/03/12 09:16:51 jim
376Modified to remove some compiler moans
377
378Revision 1.5 2015/01/29 11:45:43 jim
379modified comments
380
381Revision 1.4 2015/01/09 12:13:15 jim
382*** empty log message ***
383
384Revision 1.3 2014/04/09 11:08:21 jim
385Get rid of a couple of compiler moans
386
387Revision 1.2 2014/04/09 09:09:51 jim
388Detabbed
389
390Revision 1.1 2014/03/26 15:26:28 jim
391New entry
392
393
394*/
int casu_backmap(float *map, cpl_binary *bpm, int nx, int ny, int nbsize, float *avback, float **skymap, int *status)
Model background of an image.
Definition: casu_backmap.c:108
float casu_med(float *data, unsigned char *bpm, long npts)
Definition: casu_stats.c:89