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