VIRCAM Pipeline  2.3.10
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 
48 static void medsig(int *hist, int ist, int itarg, float *med, float *sig);
49 
63 /*---------------------------------------------------------------------------*/
106 /*---------------------------------------------------------------------------*/
107 
108 extern 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 
318 static 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 $
363 Revision 1.4 2015/09/15 14:13:26 jim
364 Fixed problem with illegal memory read
365 
366 Revision 1.3 2015/09/11 09:27:53 jim
367 Fixed some problems with the docs
368 
369 Revision 1.2 2015/08/07 13:06:54 jim
370 Fixed copyright to ESO
371 
372 Revision 1.1.1.1 2015/06/12 10:44:32 jim
373 Initial import
374 
375 Revision 1.6 2015/03/12 09:16:51 jim
376 Modified to remove some compiler moans
377 
378 Revision 1.5 2015/01/29 11:45:43 jim
379 modified comments
380 
381 Revision 1.4 2015/01/09 12:13:15 jim
382 *** empty log message ***
383 
384 Revision 1.3 2014/04/09 11:08:21 jim
385 Get rid of a couple of compiler moans
386 
387 Revision 1.2 2014/04/09 09:09:51 jim
388 Detabbed
389 
390 Revision 1.1 2014/03/26 15:26:28 jim
391 New 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