IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ticket #481: psUtils.c

File psUtils.c, 11.5 KB (added by eugene, 21 years ago)

prototype pslib code

Line 
1# include "psphot.h"
2
3static psHash *timers = NULL;
4
5// start/restart a named timer
6bool psTimerStart (char *name) {
7
8 psTime *start;
9
10 if (timers == NULL) timers = psHashAlloc (16);
11
12 start = psTimeGetTime (PS_TIME_UTC);
13
14 psHashAdd (timers, name, start);
15
16 return (TRUE);
17}
18
19// get current elapsed time on named timer
20psF64 psTimerMark (char *name) {
21
22 psTime *start;
23 psTime *mark;
24 psF64 delta;
25
26 if (timers == NULL) return (0);
27
28 start = psHashLookup (timers, name);
29 if (start == NULL) return (0);
30
31 mark = psTimeGetTime (PS_TIME_UTC);
32 delta = psTimeDelta (mark, start);
33 return (delta);
34}
35
36// we have log levels 1 (Error), 2 (Warning), 3 (Info), 4 (Details), 5 (Minutiae)
37// 2 = default, -v = 3, -vv = 4, -vvv = 5
38psS32 psLogArguments (int *argc, char **argv) {
39
40 int N, level;
41
42 // default log level is 2
43 level = 2;
44
45 // set in order, so that -vvv overrides -vv overrides -v
46 if ((N = get_argument (*argc, argv, "-v"))) {
47 remove_argument (N, argc, argv);
48 level = 3;
49 }
50 if ((N = get_argument (*argc, argv, "-vv"))) {
51 remove_argument (N, argc, argv);
52 level = 4;
53 }
54 if ((N = get_argument (*argc, argv, "-vvv"))) {
55 remove_argument (N, argc, argv);
56 level = 5;
57 }
58
59 if ((N = get_argument (*argc, argv, "-logfmt"))) {
60 if (*argc < N + 2) {
61 psAbort ("psLogArguments", "USAGE: -logfmt (format)");
62 }
63 remove_argument (N, argc, argv);
64 psLogSetFormat (argv[N]); // XXX EAM : this function should return an error if the log format is invalid
65 remove_argument (N, argc, argv);
66 }
67
68 // set the level, return the level
69 psLogSetLevel (level);
70 return (level);
71}
72
73// set trace levels by facility
74psS32 psTraceArguments (int *argc, char **argv) {
75
76 int N;
77
78 // argument format is: -trace (facil) (level)
79 while ((N = get_argument (*argc, argv, "-trace"))) {
80 if (*argc < N + 3) {
81 psAbort ("psTraceArguments", "USAGE: -trace (facility) (level)");
82 }
83 remove_argument (N, argc, argv);
84 psTraceSetLevel (argv[N], atoi(argv[N+1]));
85 remove_argument (N, argc, argv);
86 remove_argument (N, argc, argv);
87 }
88 if ((N = get_argument (*argc, argv, "-trace-levels"))) {
89 psTracePrintLevels ();
90 exit (2);
91 }
92 return (TRUE);
93}
94
95// find the location of the specified argument
96int psArgumentGet (int argc, char **argv, char *arg) {
97
98 int i;
99
100 for (i = 0; i < argc; i++) {
101 if (!strcmp(argv[i], arg))
102 return (i);
103 }
104
105 return ((int)NULL);
106}
107
108// remove the specified argument (by location)
109int psArgumentRemove (int N, int *argc, char **argv) {
110
111 int i;
112
113 if ((N != (int)NULL) && (N != 0)) {
114 (*argc)--;
115 for (i = N; i < *argc; i++) {
116 argv[i] = argv[i+1];
117 }
118 }
119
120 return (N);
121}
122
123// find the location of the specified argument
124int get_argument (int argc, char **argv, char *arg) {
125
126 int i;
127
128 for (i = 0; i < argc; i++) {
129 if (!strcmp(argv[i], arg))
130 return (i);
131 }
132
133 return ((int)NULL);
134}
135
136// remove the specified argument (by location)
137int remove_argument (int N, int *argc, char **argv) {
138
139 int i;
140
141 if ((N != (int)NULL) && (N != 0)) {
142 (*argc)--;
143 for (i = N; i < *argc; i++) {
144 argv[i] = argv[i+1];
145 }
146 }
147
148 return (N);
149}
150
151// alternate implementation of this function from pmObjects.c
152psVector *psGetRowVectorFromImage(psImage *image,
153 psU32 row)
154{
155 PS_IMAGE_CHECK_NULL(image, NULL);
156 PS_IMAGE_CHECK_TYPE(image, PS_TYPE_F32, NULL);
157
158 psVector *tmpVector = psVectorAlloc(image->numCols, PS_TYPE_F32);
159 memcpy (tmpVector->data.F32, image->data.F32[row], image->numCols*sizeof(psF32));
160 return(tmpVector);
161}
162
163// extract config informatin from config data or from image header, if specified
164psF32 pmConfigLookupF32 (bool *status, psMetadata *config, psMetadata *header, char *name) {
165
166 char *source;
167 char *keyword;
168 psF32 value;
169 psMetadataItem *item;
170
171 // look for the entry in the config collection
172 item = psMetadataLookup (config, name);
173 if (item == NULL) {
174 psLogMsg ("pmConfigLookupF32", 2, "no key %s in config data, trying as header keyword", name);
175 value = psMetadataLookupF32 (status, header, name);
176 if (*status == false) {
177 psAbort ("pmConfigLookupF32", "no key %s in header", name);
178 }
179 *status = true;
180 return (value);
181 }
182
183 // I'm either expecting a string, with the name "HD:keyword"...
184 if (item->type == PS_META_STR) {
185 source = item->data.V;
186 if (!strncasecmp (source, "HD:", 3)) {
187 keyword = &source[3];
188 value = psMetadataLookupF32 (status, header, keyword);
189 if (*status == false) {
190 psAbort ("pmConfigLookupF32", "no key %s in config", name);
191 }
192 *status = true;
193 return (value);
194 }
195 }
196
197 // ... or a value (F32?)
198 if (item->type == PS_META_F32) {
199 value = item->data.F32;
200 return (value);
201 }
202
203 *status = false;
204 psError(PS_ERR_UNKNOWN, true, "invalid item");
205 return (0);
206}
207
208void psImageSmooth (psImage *image, float sigma, float Nsigma) {
209
210 int Nx, Ny, Npixel, Nrange;
211 float factor, g, s;
212 psVector *temp;
213
214 // relevant terms
215 Nrange = sigma*Nsigma + 0.5;
216 Npixel = 2*Nrange + 1;
217 factor = -0.5/(sigma*sigma);
218
219 Nx = image->numCols;
220 Ny = image->numRows;
221
222 // generate gaussian
223 psVector *gaussnorm = psVectorAlloc (Npixel, PS_TYPE_F32);
224 for (int i = -Nrange; i < Nrange + 1; i++) {
225 gaussnorm->data.F32[i+Nrange] = exp (factor*i*i);
226 }
227 psF32 *gauss = &gaussnorm->data.F32[Nrange];
228
229 // smooth in X direction
230 temp = psVectorAlloc (Nx, PS_TYPE_F32);
231 for (int j = 0; j < Ny; j++) {
232 psF32 *vi = image->data.F32[j];
233 psF32 *vo = temp->data.F32;
234 for (int i = 0; i < Nx; i++) {
235 g = s = 0;
236 for (int n = -Nrange; n < Nrange + 1; n++) {
237 if (i+n < 0) continue;
238 if (i+n >= Nx) continue;
239 s += gauss[n]*vi[i+n];
240 g += gauss[n];
241 }
242 vo[i] = s / g;
243 }
244 memcpy (image->data.F32[j], temp->data.F32, Nx*sizeof(psF32));
245 }
246 psFree (temp);
247
248 // smooth in Y direction
249 temp = psVectorAlloc (image->numRows, PS_TYPE_F32);
250 for (int i = 0; i < Nx; i++) {
251 psF32 *vo = temp->data.F32;
252 psF32 **vi = image->data.F32;
253 for (int j = 0; j < Ny; j++) {
254 g = s = 0;
255 for (int n = -Nrange; n < Nrange + 1; n++) {
256 if (j+n < 0) continue;
257 if (j+n >= Ny) continue;
258 s += gauss[n]*vi[j+n][i];
259 g += gauss[n];
260 }
261 vo[j] = s / g;
262 }
263 // replace temp in image
264 for (int j = 0; j < Ny; j++) {
265 vi[j][i] = vo[j];
266 }
267 }
268 psFree (temp);
269 psFree (gaussnorm);
270}
271
272bool psImageInit (psImage *image,...) {
273
274 va_list argp;
275 psU8 vU8;
276 psF32 vF32;
277 psF64 vF64;
278
279 if (image == NULL) return (false);
280
281 va_start (argp, image);
282
283 switch (image->type.type) {
284 case PS_TYPE_U8:
285 vU8 = va_arg (argp, psU32);
286
287 for (int iy = 0; iy < image->numRows; iy++) {
288 for (int ix = 0; ix < image->numCols; ix++) {
289 image->data.U8[iy][ix] = vU8;
290 }
291 }
292 break;
293
294 case PS_TYPE_F32:
295 vF32 = va_arg (argp, psF64);
296
297 for (int iy = 0; iy < image->numRows; iy++) {
298 for (int ix = 0; ix < image->numCols; ix++) {
299 image->data.F32[iy][ix] = vF32;
300 }
301 }
302 return (true);
303
304 case PS_TYPE_F64:
305 vF64 = va_arg (argp, psF64);
306
307 for (int iy = 0; iy < image->numRows; iy++) {
308 for (int ix = 0; ix < image->numCols; ix++) {
309 image->data.F64[iy][ix] = vF64;
310 }
311 }
312 return (true);
313
314 default:
315 psAbort ("psphot.psUtils", "datatype %d not defined in psImageInit\n", image->type);
316 return (false);
317 }
318 return (false);
319}
320
321// define a square region centered on the given coordinate
322psRegion *psRegionSquare (psF32 x, psF32 y, psF32 radius) {
323 psRegion *region;
324 region = psRegionAlloc (x - radius, x + radius + 1,
325 y - radius, y + radius + 1);
326 return (region);
327}
328
329// set actual region based on image parameters:
330// compensate for negative upper limits
331// XXX this is inconsistent: the coordindates should always be in the parent
332// frame, which means the negative values should subtract from Nx,Ny of
333// the parent, not the child. but, we don't carry the dimensions of the
334// parent in the psImage container. for now, us the child Nx,Ny
335// force range to be on this subimage
336// XXX EAM : this needs to be changes to use psRegion rather than psRegion*
337psRegion *psRegionForImage (psRegion *out, psImage *image, psRegion *in) {
338
339 // x0,y0, x1,y1 are in *parent* units
340
341 if (out == NULL) {
342 out = psRegionAlloc(in->x0, in->x1, in->y0, in->y1);
343 } else {
344 *out = *in;
345 }
346 // XXX these are probably wrong (see above)
347 if (out->x1 <= 0) {
348 out->x1 = image->col0 + image->numCols + out->x1;
349 }
350 if (out->y1 <= 0) {
351 out->y1 = image->row0 + image->numRows + out->y1;
352 }
353
354 // force the lower-limits to be on the child
355 out->x0 = PS_MAX(image->col0, out->x0);
356 out->y0 = PS_MAX(image->row0, out->y0);
357
358 // force the upper-limits to be on the child
359 out->x1 = PS_MIN(image->col0 + image->numCols, out->x1);
360 out->y1 = PS_MIN(image->row0 + image->numRows, out->y1);
361 return (out);
362}
363
364// mask the area contained by the region
365// the region is defined wrt the parent image
366void psImageMaskRegion (psImage *image, psRegion *region, bool logical_and, int maskValue) {
367
368 for (int iy = 0; iy < image->numRows; iy++) {
369 for (int ix = 0; ix < image->numCols; ix++) {
370 if (ix + image->col0 < region->x0) continue;
371 if (ix + image->col0 >= region->x1) continue;
372 if (iy + image->row0 < region->y0) continue;
373 if (iy + image->row0 >= region->y1) continue;
374 if (logical_and) {
375 image->data.U8[iy][ix] &= maskValue;
376 } else {
377 image->data.U8[iy][ix] |= maskValue;
378 }
379 }
380 }
381}
382
383// mask the area not contained by the region
384// the region is defined wrt the parent image
385void psImageKeepRegion (psImage *image, psRegion *region, bool logical_and, int maskValue) {
386
387 for (int iy = 0; iy < image->numRows; iy++) {
388 for (int ix = 0; ix < image->numCols; ix++) {
389 if (ix + image->col0 < region->x0) goto maskit;
390 if (ix + image->col0 >= region->x1) goto maskit;
391 if (iy + image->row0 < region->y0) goto maskit;
392 if (iy + image->row0 >= region->y1) goto maskit;
393 continue;
394 maskit:
395 if (logical_and) {
396 image->data.U8[iy][ix] &= maskValue;
397 } else {
398 image->data.U8[iy][ix] |= maskValue;
399 }
400 }
401 }
402}
403
404// mask the area contained by the region
405// the region is defined wrt the parent image
406void psImageMaskCircle (psImage *image, double x, double y, double radius, bool logical_and, int maskValue) {
407
408 double dx, dy, r2, R2;
409
410 R2 = PS_SQR(radius);
411
412 for (int iy = 0; iy < image->numRows; iy++) {
413 for (int ix = 0; ix < image->numCols; ix++) {
414 dx = ix + image->col0 - x;
415 dy = iy + image->row0 - y;
416 r2 = PS_SQR(dx) + PS_SQR(dy);
417 if (r2 > R2) continue;
418 if (logical_and) {
419 image->data.U8[iy][ix] &= maskValue;
420 } else {
421 image->data.U8[iy][ix] |= maskValue;
422 }
423 }
424 }
425}
426
427// mask the area contained by the region
428// the region is defined wrt the parent image
429void psImageKeepCircle (psImage *image, double x, double y, double radius, bool logical_and, int maskValue) {
430
431 double dx, dy, r2, R2;
432
433 R2 = PS_SQR(radius);
434
435 for (int iy = 0; iy < image->numRows; iy++) {
436 for (int ix = 0; ix < image->numCols; ix++) {
437 dx = ix + image->col0 - x;
438 dy = iy + image->row0 - y;
439 r2 = PS_SQR(dx) + PS_SQR(dy);
440 if (r2 < R2) continue;
441 if (logical_and) {
442 image->data.U8[iy][ix] &= maskValue;
443 } else {
444 image->data.U8[iy][ix] |= maskValue;
445 }
446 }
447 }
448}
449
450psVector *psVectorCreate (double lower, double upper, double delta, psElemType type) {
451
452 int nBin = (upper - lower) / delta;
453
454 psVector *out = psVectorAlloc (nBin, type);
455
456 for (int i = 0; i < nBin; i++) {
457 out->data.F64[i] = lower + i * delta;
458 }
459
460 return (out);
461}