DETMON Pipeline Reference Manual  1.3.0
irplib_cat.c
1 /* $Id: irplib_cat.c,v 1.10 2009-12-01 12:34:25 cgarcia Exp $
2  *
3  * This file is part of the irplib package
4  * Copyright (C) 2002,2003 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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: cgarcia $
23  * $Date: 2009-12-01 12:34:25 $
24  * $Revision: 1.10 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include <libgen.h>
37 #include <math.h>
38 #include <cpl.h>
39 
40 #include "irplib_cat.h"
41 #include "irplib_wcs.h"
42 
43 #define FILENAME_SZBUF 1024
44 
45 /*----------------------------------------------------------------------------*/
49 /*----------------------------------------------------------------------------*/
50 
53 /*---------------------------------------------------------------------------*/
72 /*---------------------------------------------------------------------------*/
73 
75 (const cpl_frame * master_index,
76  char ** catpath,
77  char ** catname)
78 {
79  cpl_propertylist * p;
80  char * fname;
81  int status = CPL_ERROR_NONE;
82 
83  /* Initialise a few things */
84  *catpath = NULL;
85  *catname = NULL;
86 
87  /* First get the full path to the index file and make sure it exists */
88  fname = cpl_strdup(cpl_frame_get_filename(master_index));
89  if (access((const char *)fname,R_OK) != 0)
90  {
91  cpl_msg_error(__func__,"Can't access index file %s",fname);
92  cpl_free(fname);
93  return CPL_ERROR_FILE_IO;
94  }
95  *catpath = cpl_strdup(dirname(fname));
96 
97  /* Try to load the propertylist. If it is not possible signal a fatal
98  error since this probably means the whole file is messed up */
99  if ((p = cpl_propertylist_load(cpl_frame_get_filename(master_index),0)) == NULL)
100  {
101  cpl_msg_error(__func__,"Can't load index file header %s",fname);
102  cpl_free(*catpath);
103  cpl_free(fname);
104  return CPL_ERROR_FILE_IO;
105  }
106 
107  /* If there is a catalogue name in the header then send it back. If there
108  isn't then give a default name and send a warning */
109  if (cpl_propertylist_has(p,"CATNAME"))
110  {
111  *catname = cpl_strdup(cpl_propertylist_get_string(p,"CATNAME"));
112  status = CPL_ERROR_NONE;
113  } else {
114  const char * unk = "unknown";
115  *catname = cpl_strdup(unk);
116  cpl_msg_warning(__func__,"Property CATNAME not in index file header %s",
117  fname);
118  }
119 
120  /* Free and return */
121  cpl_free(fname);
122  cpl_propertylist_delete(p);
123  return(status);
124 }
125 
126 
127 
128 /*---------------------------------------------------------------------------*/
151 /*---------------------------------------------------------------------------*/
152 
153 cpl_error_code irplib_cat_get_image_limits
154 (const cpl_wcs * wcs,
155  float ext_search,
156  double * ra1,
157  double * ra2,
158  double * dec1,
159  double * dec2)
160 {
161  double min_4q;
162  double max_1q;
163  int first_quad;
164  int fourth_quad;
165  const int * naxes;
166  long j;
167  const cpl_array * a;
168 
169  /* Initialise these in case of failure later*/
170  *ra1 = 0.0;
171  *ra2 = 0.0;
172  *dec1 = 0.0;
173  *dec2 = 0.0;
174 
175  /* Grab the WCS info from the property list */
176  if (wcs == NULL)
177  return CPL_ERROR_DATA_NOT_FOUND;
178 
179  /* Get the size of the data array */
180 
181  a = cpl_wcs_get_image_dims(wcs);
182  if(a == NULL)
183  return CPL_ERROR_ILLEGAL_INPUT;
184  naxes = cpl_array_get_data_int_const(a);
185 
186  /* Find the RA and Dec limits of the image */
187 
188  *ra1 = 370.0;
189  *ra2 = -370.0;
190  *dec1 = 95.0;
191  *dec2 = -95.0;
192  first_quad = 0;
193  fourth_quad = 0;
194  min_4q = 370.0;
195  max_1q = 0.0;
196  for (j = 1; j < naxes[1]; j += 10) {
197  long i;
198  double y = (double)j;
199  for (i = 1; i < naxes[0]; i += 10) {
200  double ra, dec;
201  double x = (double)i;
202  irplib_wcs_xytoradec(wcs,x,y,&ra,&dec);
203  if (ra >= 0.0 && ra <= 90.0) {
204  first_quad = 1;
205  if(ra > max_1q)
206  max_1q = ra;
207  } else if (ra >= 270.0 && ra <= 360.0) {
208  fourth_quad = 1;
209  if(ra - 360.0 < min_4q)
210  min_4q = ra - 360.0;
211  }
212  if(ra < *ra1)
213  *ra1 = ra;
214  if(ra > *ra2)
215  *ra2 = ra;
216  if(dec < *dec1)
217  *dec1 = dec;
218  if(dec > *dec2)
219  *dec2 = dec;
220  }
221  }
222 
223  /* Now have a look to see if you had RA values in both the first and
224  fourth quadrants. If you have, then make the minimum RA a negative
225  value. This will be the signal to the caller that you have the
226  wraparound... */
227 
228  if (first_quad && fourth_quad) {
229  *ra1 = min_4q;
230  *ra2 = max_1q;
231  }
232 
233  /* Pad out search a bit */
234  if (ext_search)
235  {
236  double dra, ddec;
237  dra = 0.5*ext_search*(*ra2 - *ra1);
238  *ra1 -= dra;
239  *ra2 += dra;
240  ddec = 0.5*ext_search*(*dec2 - *dec1);
241  *dec1 -= ddec;
242  *dec2 += ddec;
243  }
244 
245  /* Exit */
246  return CPL_ERROR_NONE;
247 }
248 
249 /*---------------------------------------------------------------------------*/
273 /*---------------------------------------------------------------------------*/
274 
275 cpl_table * irplib_2mass_extract
276 (char *path,
277  float ramin,
278  float ramax,
279  float decmin,
280  float decmax)
281 {
282  cpl_table *t,*s;
283  cpl_table *out;
284  int i,nrows,start,finish,first_index,last_index,irow,init,j;
285  int wrap,iwrap;
286  float dectest,ratest,ramin_wrap,ramax_wrap;
287  char fullname[FILENAME_SZBUF];
288  cpl_array *a;
289  const char *deccol[] = {"Dec"};
290  cpl_propertylist *p;
291 
292  /* Create an output table */
293 
294  out = cpl_table_new(0);
295  init = 1;
296 
297  /* Create a cpl array */
298 
299  /* deccol will NOT be modified */
300  a = cpl_array_wrap_string((char **)deccol,1);
301 
302  /* Is there a wrap around problem? */
303 
304  wrap = (ramin < 0.0 && ramax > 0.0) ? 2 : 1;
305 
306  /* Loop for each query. If there is a wrap around problem then we need 2
307  queries. If not, then we only need 1 */
308 
309  for (iwrap = 0; iwrap < wrap; iwrap++) {
310  int first_index_ra,last_index_ra;
311 
312  if (wrap == 2) {
313  if (iwrap == 0) {
314  ramin_wrap = ramin + 360.0;
315  ramax_wrap = 360.0;
316  } else {
317  ramin_wrap = 0.000001;
318  ramax_wrap = ramax;
319  }
320  } else {
321  ramin_wrap = ramin;
322  ramax_wrap = ramax;
323  }
324 
325  /* Find out where in the index to look */
326 
327  first_index_ra = (int)ramin_wrap;
328  last_index_ra = (int)ramax_wrap;
329  if(last_index_ra > 359)
330  last_index_ra = 359;
331 
332  /* Look at the min and max RA and decide which files need to be
333  opened. */
334 
335  for (i = first_index_ra; i <= last_index_ra; i++)
336  {
337 
338  /* Ok, we've found one that needs opening. Read the file with
339  the relevant CPL call */
340 
341  (void)snprintf(fullname,FILENAME_SZBUF,"%s/npsc%03d.fits",path,i);
342 
343  /* Read the propertylist so that you know how many rows there
344  are in the table */
345 
346  p = cpl_propertylist_load(fullname,1);
347  if (p == NULL)
348  {
349  cpl_error_set_message_macro(__func__,CPL_ERROR_DATA_NOT_FOUND,
350  __FILE__, __LINE__, "2mass file %s missing",fullname);
351  cpl_table_delete(out);
352  cpl_array_unwrap(a);
353  return(NULL);
354  }
355  nrows = cpl_propertylist_get_int(p, "NAXIS2");
356  cpl_propertylist_delete(p);
357 
358  /* Load various rows until you find the Dec range that you
359  have specified. First the minimum Dec */
360 
361  start = 0;
362  finish = nrows;
363  first_index = nrows/2;
364  while (finish - start >= 2)
365  {
366  t = cpl_table_load_window(fullname, 1, 0, a, first_index, 1);
367  dectest = cpl_table_get_float(t, "Dec", 0, NULL);
368  cpl_table_delete(t);
369  if (dectest < decmin)
370  {
371  start = first_index;
372  first_index = (first_index + finish)/2;
373  }
374  else
375  {
376  finish = first_index;
377  first_index = (first_index + start)/2;
378  }
379  }
380 
381  /* Load various rows until you find the Dec range that you
382  have specified. Now the maximum Dec */
383 
384  start = first_index;
385  finish = nrows;
386  last_index = start + (finish - start)/2;
387  while (finish - start >= 2)
388  {
389  t = cpl_table_load_window(fullname, 1, 0, a, last_index, 1);
390  dectest = cpl_table_get_float(t, "Dec", 0, NULL);
391  cpl_table_delete(t);
392  if (dectest < decmax)
393  {
394  start = last_index;
395  last_index = (last_index + finish)/2;
396  }
397  else
398  {
399  finish = last_index;
400  last_index = (last_index + start)/2;
401  }
402  }
403  if (last_index < first_index)
404  last_index = first_index;
405 
406  /* Ok now now load all the rows in the relevant dec limits */
407 
408  nrows = last_index - first_index + 1;
409  if ((t = cpl_table_load_window(fullname, 1, 0, NULL, first_index,
410  nrows)) == NULL)
411  {
412  cpl_error_set_message_macro(__func__,CPL_ERROR_DATA_NOT_FOUND,
413  __FILE__, __LINE__, "Error in subset of 2mass file %s ",
414  fullname);
415  cpl_table_delete(out);
416  cpl_array_unwrap(a);
417  return (NULL);
418  }
419  cpl_table_unselect_all(t);
420 
421  /* Right, we now know what range of rows to search. Go through
422  these and pick the ones that are in the correct range of RA.
423  If a row qualifies, then 'select' it. */
424 
425  for (j = 0; j < nrows; j++)
426  {
427  ratest = cpl_table_get_float(t, "RA", j, NULL);
428  if (cpl_error_get_code() != CPL_ERROR_NONE)
429  {
430  cpl_error_set_message_macro(__func__,CPL_ERROR_DATA_NOT_FOUND,
431  __FILE__, __LINE__, "No RA column in 2mass file %s",
432  fullname);
433  cpl_table_delete(t);
434  cpl_array_unwrap(a);
435  cpl_table_delete(out);
436  return (NULL);
437  }
438  if (ratest >= ramin_wrap && ratest <= ramax_wrap)
439  cpl_table_select_row(t, j);
440  }
441 
442  /* Extract the rows that have been selected now and append them
443  onto the output table */
444 
445  s = cpl_table_extract_selected(t);
446  if (init == 1)
447  {
448  cpl_table_copy_structure(out, t);
449  init = 0;
450  }
451  irow = cpl_table_get_nrow(out) + 1;
452  cpl_table_insert(out, s, irow);
453 
454  /* Tidy up */
455 
456  cpl_table_delete(t);
457  cpl_table_delete(s);
458  }
459  }
460 
461  /* Ok, now just return the table and get out of here */
462 
463  cpl_array_unwrap(a);
464  return(out);
465 }
cpl_error_code irplib_cat_get_image_limits(const cpl_wcs *wcs, float ext_search, double *ra1, double *ra2, double *dec1, double *dec2)
Get coverage in ra, dec of a frame.
Definition: irplib_cat.c:154
cpl_table * irplib_2mass_extract(char *path, float ramin, float ramax, float decmin, float decmax)
Extract standards from the 2mass catalogue.
Definition: irplib_cat.c:276
int irplib_2mass_get_catpars(const cpl_frame *master_index, char **catpath, char **catname)
Find the name of the standard catalogue being used and its location.
Definition: irplib_cat.c:75