IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ticket #204: conflat2.c

File conflat2.c, 9.2 KB (added by Paul Price, 22 years ago)

conflat2 by John Tonry

Line 
1/* Program to convolve an unbinned flatfield with an OT shift pattern */
2/*
3 * Syntax: conflat2 <infile> <otfile> <outfile>
4 *
5 * options: conflat2 <> <> <> [-b -v N -z 2l -r 2l -t time -yswap]
6 *
7 * Assumes: unbinned flatfield *with* bias strip of width 32
8 *
9 * Examples:
10
11 conflat2 sumflat.fits f_ot.103 conflat.103 [normal usage]
12
13 Suppress diagnostic output:
14
15 conflat2 sumflat.fits f_ot.103 conflat.103 -v 0
16
17 Bias subtraction of (short) image flat.067:
18
19 conflat2 flat.067 f_ot.103 conflat.103
20
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <math.h>
26
27static char rcsid[] = "$Id: conflat2.c,v 1.3 2003/12/21 14:51:25 jt Exp $";
28
29#define MIN(a,b) (((a) < (b)) ? (a) : (b))
30#define MAX(a,b) (((a) > (b)) ? (a) : (b))
31#define ABS(a) (((a) > 0) ? (a) : -(a))
32#define NINT(x) (x<0?(int)((x)-0.5):(int)((x)+0.5))
33
34#define NAMP 4
35#define MAXOT 100000 /* Max number of OT shifts */
36#define MAXKERNEL 10000 /* Max number of distinct shift locations */
37
38/* #define TWO15 32768 /* Scale factor for time */
39#define TWO15 1 /* Scale factor for time */
40
41#define FULLX 4096 /* Unbinned x size */
42#define FULLY 4104 /* Unbinned y size */
43#define STDBIAS 32 /* Normal bias count */
44
45struct shiftstruct {
46 int dx[2*NAMP];
47 int dy[2*NAMP];
48} shift[MAXOT];
49
50struct regionstruct {
51 int sx;
52 int sy;
53 int nx;
54 int ny;
55} regbox[2*NAMP] = {
56 0, 0, 2048, 516,
57 0, 516, 2048, 1536,
58 0, 3588, 2048, 516,
59 0, 2052, 2048, 1536,
60 2048, 0, 2048, 516,
61 2048, 516, 2048, 1536,
62 2048, 3588, 2048, 516,
63 2048, 2052, 2048, 1536};
64
65struct regionstruct biasbox[NAMP] = {
66 4096, 0, 32, 2052,
67 4096, 2052, 32, 2052,
68 4128, 0, 32, 2052,
69 4128, 2052, 32, 2052};
70
71int bias[NAMP];
72
73double time[MAXOT];
74
75double exposure[MAXKERNEL];
76double texp[MAXKERNEL];
77int dx[MAXKERNEL], dy[MAXKERNEL];
78int zero[2*NAMP]={0,0,0,0,0,0,0,0};
79
80double atof();
81
82main(int argc, char **argv)
83{
84 int i, j, k, nx, ny, nz, iter, minx, miny, maxx, maxy, nkernel;
85 int mx, my, sx, sy;
86 int ccd, upper, region=7, sig, yswap=0, verbose=2, dobias=0;
87 char flatname[256], otname[256], outname[256], line[256], version[256];
88 char *head;
89 float *data, *sum;
90 double inttime=0.0, scale, bb, t;
91 FILE *fp;
92
93 if (argc<3) {
94 fprintf(stderr, "Syntax: conflat2 <infile> <otfile> <outfile> flags\n");
95 fprintf(stderr, " flags include -v {0|1|2} for verbosity (def: 2)\n");
96 fprintf(stderr, " -b to do bias subtraction (def: no)\n");
97 exit(1);
98 }
99
100 strcpy(flatname, argv[1]); argc--; argv++;
101 strcpy(otname, argv[1]); argc--; argv++;
102 strcpy(outname, argv[1]); argc--; argv++;
103
104/* Basically I hope that all of these arguments are not wanted. They
105 * are mostly here to patch up bugs in the past
106 */
107
108/* Parse the arguments */
109 for(i=1; i<argc; i++) {
110
111/* verbose? (-v) */
112 if (strcmp(argv[i], "-v") == 0) {
113 verbose = atoi(argv[++i]);
114 continue;
115 }
116
117/* bias subtract? (-b) */
118 if (strcmp(argv[i], "-b") == 0) {
119 dobias = 1;
120 continue;
121 }
122
123/* region? (-r) */
124 if (strcmp(argv[i], "-r") == 0) {
125 ccd = atoi(argv[++i]);
126 upper = argv[i][1] == 'u';
127 region = ccd * 2 + (upper?1:0);
128 continue;
129 }
130
131/* zero shift region? (-z) */
132 if (strcmp(argv[i], "-z") == 0) {
133 ccd = atoi(argv[++i]);
134 upper = argv[i][1] == 'u';
135 zero[2*ccd + (upper?1:0)] = 1;
136 continue;
137 }
138
139/* time? (-t) */
140 if (strcmp(argv[i], "-t") == 0) {
141 inttime = atof(argv[++i]);
142 continue;
143 }
144
145 }
146
147 sscanf(rcsid, "%*s %*s %s",version); /* Get version number */
148 if(verbose >= 1) printf("conflat2 v%s\n", version);
149
150/* Read in flatfield image */
151 if(rfitsreal(&head, &nx, &ny, &data, flatname) != 0) {
152 fprintf(stderr, "Error reading %s\n", flatname);
153 }
154
155/* A few sanity checks, obviously can be relaxed */
156 if(verbose >= 2) {
157 printf("%s read, nx=%d ny=%d \n", flatname, nx, ny);
158 }
159 if(nx != FULLX+2*STDBIAS || ny != FULLY) {
160 fprintf(stderr, "conflat2 only works on unbinned images, size = %d x %d\n",
161 nx, ny);
162 exit(1);
163 }
164
165/* Allocate memory for the destination image */
166 sum = (float *)calloc(nx*ny, sizeof(float));
167
168/* Get the bias levels */
169 if(dobias) {
170 for(i=0; i<NAMP; i++) {
171 bias[i] = medcount(biasbox[i].sx, biasbox[i].sy,
172 biasbox[i].nx, biasbox[i].ny, nx, data, &sig);
173 sprintf(line, "CCD%dBIAS", i);
174 rfitshead(head, line, &bb);
175 if(ABS(bias[0]) > 200 && ABS(bias[0]-bb) > 200) {
176 fprintf(stderr, "Bias %d at %d is strange, should be %.0f",
177 i, bias[i], bb);
178 fprintf(stderr, "Did you compile fitsio.c with the right byte swap?");
179 }
180 }
181 if(verbose >= 1) {
182 printf("Bias levels at %5d %5d %5d %5d\n",
183 bias[0], bias[1], bias[2], bias[3]);
184 }
185 } else {
186 bias[0] = bias[1] = bias[2] = bias[3] = 0;
187 }
188
189/* Get the shift data */
190 if( (fp = fopen(otname, "r")) == NULL) {
191 fprintf(stderr, "Can't read OT file '%s'\n", otname);
192 exit(1);
193 }
194
195 fgets(line, 256, fp);
196 minx = miny = maxx = maxy = 0;
197 nkernel = 0;
198 for(nz=0; nz<MAXOT; nz++) {
199 if(fgets(line, 256, fp) == NULL) break;
200 sscanf(line, "%d %lf %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", &iter, &time[nz],
201 &shift[nz].dx[0],&shift[nz].dy[0],
202 &shift[nz].dx[1],&shift[nz].dy[1],
203 &shift[nz].dx[2],&shift[nz].dy[2],
204 &shift[nz].dx[3],&shift[nz].dy[3],
205 &shift[nz].dx[4],&shift[nz].dy[4],
206 &shift[nz].dx[5],&shift[nz].dy[5],
207 &shift[nz].dx[6],&shift[nz].dy[6],
208 &shift[nz].dx[7],&shift[nz].dy[7]);
209 for(i=0; i<2*NAMP; i++) {
210 minx = MIN(minx, shift[nz].dx[i]);
211 miny = MIN(miny, shift[nz].dy[i]);
212 maxx = MAX(maxx, shift[nz].dx[i]);
213 maxy = MAX(maxy, shift[nz].dy[i]);
214 }
215 }
216 if(inttime == 0.0) inttime = 2*time[nz-1] - time[nz-2];
217 if(verbose >= 1) {
218 printf("%s read, nz=%d, x=[%d,%d], y=[%d,%d]\n",
219 otname, nz, minx,maxx, miny,maxy);
220 }
221/* For each region perform the shifts */
222 for(region=0; region<8; region++) {
223 if(!zero[region]) {
224 for(k=0, nkernel=0; k<nz; k++) {
225 for(j=0; j<nkernel; j++) {
226 if(-(shift[k].dx[region] - shift[nz-1].dx[region]) == dx[j] &&
227 -(shift[k].dy[region] - shift[nz-1].dy[region]) == dy[j]) break;
228 }
229 if(j == nkernel) {
230 dx[j] = -(shift[k].dx[region] - shift[nz-1].dx[region]);
231 dy[j] = -(shift[k].dy[region] - shift[nz-1].dy[region]);
232 exposure[j] = 0.0;
233 nkernel++;
234 if(nkernel >= MAXKERNEL) {
235 fprintf(stderr, "nkernel exceeds MAXKERNEL; something's very wrong\n");
236 fprintf(stderr, "proceeding, but it's probably going to be junk\n");
237 nkernel = MAXKERNEL-1;
238 }
239 }
240 exposure[j] += (time[k] - (k==0 ? 0.0 : time[k-1])) / inttime;
241 if(k == nz-1) exposure[j] += (inttime - time[nz-1]) / inttime;
242 }
243 } else {
244 nkernel = 1;
245 dx[0] = dy[0] = 0;
246 exposure[0] = 1.0;
247 }
248
249 if(verbose >= 2) {
250 printf("region %d: %3d distinct kernel entries, time = %.3f\n",
251 region, nkernel, inttime);
252 }
253 for(j=0; j<nkernel; j++) texp[j] = exposure[j] * TWO15;
254
255 mx = regbox[region].nx;
256 my = regbox[region].ny;
257 sx = regbox[region].sx;
258 sy = regbox[region].sy;
259
260 for(i=0; i<mx*my; i++) sum[i] = 0.0;
261
262 for(t=0.0, j=0; j<nkernel; j++) {
263 adder(mx,my,nx, &data[sx+sy*nx],
264 mx,my,mx, sum,
265 dx[j], (((region/2)&1)&&yswap?-1:1)*dy[j],
266 texp[j]);
267 if(verbose >= 2) {
268 t += texp[j];
269 printf("\r%7d %8.1f %8.3f %10.1f", j, data[sx+sy*nx+mx/2+(my/2)*nx],
270 t, sum[mx/2+(my/2)*mx]/TWO15);
271 fflush(stdout);
272 }
273 }
274 if(verbose >= 2) printf("\n");
275
276 scale = 1.0 / TWO15;
277 for(j=0; j<my; j++) {
278 for(i=0; i<mx; i++) {
279 data[sx+sy*nx+i+j*nx] = scale*sum[i+j*mx] - bias[region/2];
280 }
281 }
282 }
283/* Write floating, convolved FITS file */
284 chfitshead(&i, head, "BITPIX ", NULL, -32, 0.0);
285 wfitsreal(head, data, outname);
286}
287
288
289/* Adder adds src of size/stride (nx,ny,np) into dest of size/stride
290 * (mx,my,mp), offset by (dx,dy) and multiplied by weight wgt
291 */
292adder(int nx, int ny, int np, float *src,
293 int mx, int my, int mp, float *dest, int dx, int dy, double wgt)
294{
295 int j;
296 register int count;
297 register float *sp; /* Source pointer */
298 register float *dp; /* Destination pointer */
299 if(wgt <= 0) return(0);
300
301 for(j=0; j<ny; j++) {
302 if(j+dy < 0 || j+dy > my-1) continue;
303 sp = src + j*np;
304 dp = dest + (j+dy)*mp;
305 if(dx < 0) sp -= dx;
306 else dp += dx;
307 count = MIN(nx+dx, mx) - MAX(dx, 0);
308 while(count--) *dp++ += *sp++ * wgt;
309 }
310 return(0);
311}
312
313
314/* Return a median derived from counting the specified subarray */
315medcount(int sx, int sy, int nx, int ny, int nsx, float *data, int *sig)
316{
317 int i, j, k, ntot, median;
318 int buf[65536];
319
320 for(i=0; i<65536; i++) buf[i] = 0;
321 for(j=sy, ntot=0; j<sy+ny; j++) {
322 for(i=sx; i<sx+nx; i++) {
323 if(data[i+nsx*j] >= -0.5 && data[i+nsx*j] <= 65535.9) {
324 k = (int)data[i+nsx*j];
325 buf[k]++;
326 ntot++;
327 }
328 }
329 }
330 for(median=1, i=j=0; median<65536; median++) {
331 i += buf[median];
332 if(i < ntot/6) j = median;
333 if(i > ntot/2) break;
334 }
335 *sig = MAX(median-j, 1);
336
337 return(median);
338}