OMEGA Pipeline Reference Manual  1.0.5
omega_catalog.c
1 /* $Id: omega_catalog.c,v 1.9 2012-05-30 12:08:03 agabasch Exp $
2  *
3  * This file is part of the OMEGA Pipeline
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: agabasch $
23  * $Date: 2012-05-30 12:08:03 $
24  * $Revision: 1.9 $
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 <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <math.h>
40 
41 #include "omega_catalog.h"
42 #include "omega_dfs.h"
43 #include "omega_pfits.h"
44 #include "omega_utils.h"
45 
59 /*----------------------------------------------------------------------------*/
62 /*-----------------------------------------------------------------------------
63  Static Functions
64  -----------------------------------------------------------------------------*/
65 
66 static float kselect(float *a, int n, int k) {
67  while (n > 1) {
68  int i = 0, j = n - 1;
69  float x = a[j/2], w;
70 
71  do {
72  while (a[i] < x) i++;
73  while (a[j] > x) j--;
74  if (i < j) {
75  w = a[i]; a[i] = a[j]; a[j] = w;
76  } else {
77  if (i == j) i++;
78  break;
79  }
80  } while (++i <= --j);
81 
82  if (k < i)
83  n = i;
84  else {
85  a += i; n -= i; k -= i;
86  }
87  }
88 
89  return a[0];
90 }
91 
92 static float omega_med(float *data, unsigned char *bpm, long npts) {
93  int i,j,is_even,ilevel;
94  float *buf,value;
95 
96  /* If there is not BPM, then just do a straight forward median */
97 
98  buf = cpl_malloc(npts*sizeof(*buf));
99  if (bpm == NULL) {
100  is_even = !(npts & 1);
101  memmove((char *)buf,(char *)data,npts*sizeof(float));
102  if (is_even) {
103  ilevel = npts/2 - 1;
104  value = kselect(buf,npts,ilevel);
105  ilevel = npts/2;
106  value = 0.5*(value + kselect(buf,npts,ilevel));
107  } else {
108  ilevel = npts/2;
109  value = kselect(buf,npts,ilevel);
110  }
111 
112  /* Otherwise get rid of the dodgy values and then do the median */
113 
114  } else {
115  j = 0;
116  for (i = 0; i < npts; i++) {
117  if (bpm[i] == 0)
118  buf[j++] = data[i];
119  }
120  if (j == 0) {
121  cpl_free(buf);
122  value = CX_MAXFLOAT;
123  return(value);
124  }
125  is_even = !(j & 1);
126  if (is_even) {
127  ilevel = j/2 - 1;
128  value = kselect(buf,j,ilevel);
129  ilevel = j/2;
130  value = 0.5*(value + kselect(buf,j,ilevel));
131  } else {
132  ilevel = j/2;
133  value = kselect(buf,j,ilevel);
134  }
135  }
136  cpl_free(buf);
137  return(value);
138 }
139 
140 static void omega_medmad(float *data, unsigned char *bpm, long np, float *med,
141  float *mad) {
142  int i;
143  float *work;
144 
145  /* First find the median value */
146 
147  *med = omega_med(data,bpm,np);
148 
149  /* Now work out the MAD. Start by getting a bit of workspace and filling
150  it with absolute residuals */
151 
152  work = cpl_malloc(np*sizeof(*work));
153  for (i = 0; i < np; i++)
154  work[i] = (float)fabs((double)(data[i] - *med));
155 
156  /* Now get the median value of the absolute deviations */
157 
158  *mad = omega_med(work,bpm,np);
159 
160  /* Tidy and exit */
161 
162  cpl_free(work);
163 }
164 
165 static int omega_fndmatch(float x, float y, float *xlist, float *ylist,
166  int nlist, float err)
167 {
168  int isp,ifp,index,i;
169  float errsq,errmin,dx,dy,poserr;
170 
171  /* Find lower limit index */
172 
173  isp = 0;
174  ifp = nlist - 1;
175  errsq = err*err;
176  index = (isp + ifp)/2;
177  while (ifp-isp >= 2) {
178  if (ylist[index] < y - err) {
179  isp = index;
180  index = (index+ifp)/2;
181  } else if (ylist[index] > y - err) {
182  ifp = index;
183  index = (index+isp)/2;
184  } else {
185  isp = index;
186  break;
187  }
188  }
189 
190  /* Now find nearest one within limit */
191 
192  index = -1;
193  errmin = errsq;
194  for (i = isp; i < nlist; i++) {
195  if (ylist[i] > y+err)
196  break;
197  dx = x - xlist[i];
198  dy = y - ylist[i];
199  poserr = dx*dx + dy*dy;
200  if (poserr < errsq) {
201  if (poserr <= errmin) {
202  index = i;
203  errmin = poserr;
204  }
205  }
206  }
207  return(index);
208 }
209 
210 
211 /*-----------------------------------------------------------------------------*/
225 /*------------------------------------------------------------------------------*/
226 int omega_get_coverage(cpl_propertylist *plist, int fudge, cpl_matrix *from, double *ra1,
227  double *ra2, double *dec1, double *dec2)
228 {
229 
230  cpl_wcs *wcs;
231  double ra,dec,dra,ddec,boxfudge,min_4q,max_1q;
232  int first_quad=0,fourth_quad=0, ns=0;
233  long i=0,naxes[2];
234  cpl_matrix *to=NULL;
235  cpl_array *status = NULL;
236 
237  /* Initialise these in case of failure later*/
238 
239  *ra1 = 0.0;
240  *ra2 = 0.0;
241  *dec1 = 0.0;
242  *dec2 = 0.0;
243 
244  /* Grab the WCS info from the property list */
245  wcs = cpl_wcs_new_from_propertylist(plist);
246  if(wcs == NULL){
247  cpl_msg_error(cpl_func,"Cannot create wcs. %s",cpl_error_get_message());
248  return -1;
249  }
250 
251  /* Get the size of the data array */
252  naxes[0] = (long)cpl_propertylist_get_int(plist, "NAXIS1");
253  naxes[1] = (long)cpl_propertylist_get_int(plist, "NAXIS2");
254 
255  /* Find the RA and Dec limits of the image */
256 
257  *ra1 = 370.0;
258  *ra2 = -370.0;
259  *dec1 = 95.0;
260  *dec2 = -95.0;
261  first_quad = 0;
262  fourth_quad = 0;
263  min_4q = 370.0;
264  max_1q = 0.0;
265 
266  cpl_wcs_convert(wcs, from, &to, &status, CPL_WCS_PHYS2WORLD);
267  freearray(status);
268  ns = cpl_matrix_get_nrow(to);
269 
270  for(i=0; i<ns; i++){
271  ra = (double)cpl_matrix_get(to, i, 0);
272  dec = (double)cpl_matrix_get(to, i, 1);
273  if (ra >= 0.0 && ra <= 90.0) {
274  first_quad = 1;
275  max_1q = omega_max(ra,max_1q);
276  }
277  else if (ra >= 270.0 && ra <= 360.0) {
278  fourth_quad = 1;
279  min_4q = omega_min((ra-360.0),min_4q);
280  }
281 
282  *ra1 = omega_min(*ra1,ra);
283  *ra2 = omega_max(*ra2,ra);
284  *dec1 = omega_min(*dec1,dec);
285  *dec2 = omega_max(*dec2,dec);
286  }
287 
288 /* for (j = 1; j < naxes[1]; j += 10) {
289  j = min(j,naxes[1]);
290  y = (double)j;
291  for (i = 1; i < naxes[0]; i += 10) {
292  i = min(i,naxes[0]);
293  x = (double)i;
294  vircam_xytoradec(wcs,x,y,&ra,&dec);
295  if (ra >= 0.0 && ra <= 90.0) {
296  first_quad = 1;
297  max_1q = max(ra,max_1q);
298  } else if (ra >= 270.0 && ra <= 360.0) {
299  fourth_quad = 1;
300  min_4q = min((ra-360.0),min_4q);
301  }
302  *ra1 = min(*ra1,ra);
303  *ra2 = max(*ra2,ra);
304  *dec1 = min(*dec1,dec);
305  *dec2 = max(*dec2,dec);
306  }
307  }*/
308  freewcs(wcs);
309 
310  /* Now have a look to see if you had RA values in both the first and
311  fourth quadrants. If you have, then make the minimum RA a negative
312  value. This will be the signal to the caller that you have the
313  wraparound... */
314 
315  if (first_quad && fourth_quad) {
316  *ra1 = min_4q;
317  *ra2 = max_1q;
318  }
319 
320  /* Pad out search a bit */
321 
322  if (fudge) {
323  boxfudge = 0.01*(float)fudge;
324  dra = 0.5*boxfudge*(*ra2 - *ra1);
325  *ra1 -= dra;
326  *ra2 += dra;
327  ddec = 0.5*boxfudge*(*dec2 - *dec1);
328  *dec1 -= ddec;
329  *dec2 += ddec;
330  }
331 
332  freematrix(to);
333 
334  /* Exit */
335 
336  return 0;
337 }
338 
339 /*------------------------------------------------------------------------------*/
351 /*--------------------------------------------------------------------------------*/
352 /*Note: adapted from vircam pipeline*/
353 int omega_matchstds(cpl_table *objtab, cpl_table *stdstab, float srad,
354  cpl_table **outtab)
355 {
356 
357  char *colname;
358  int nobj,nstd,ngrid,ngrid2,ibest,ig,jg,nmatch,k,*matches,jm,l,dont,null;
359  float *xstd,*ystd,*xobj,*yobj,aveden,errlim,xoffbest,yoffbest,*xoffs;
360  float *yoffs,x,y,x2,y2,r2,x1,y1,r1,xoffmed,sigx,yoffmed,sigy,xoff,yoff;
361  cpl_propertylist *p;
362  cpl_table *mstds;
363 
364  *outtab = NULL;
365 
366  /* Check the size of each of the tables */
367  nobj = cpl_table_get_nrow(objtab);
368  nstd = cpl_table_get_nrow(stdstab);
369  if (nobj == 0) {
370  cpl_msg_error(cpl_func,"Object table has no rows");
371  return -1;
372  }
373  else if (nstd == 0) {
374  cpl_msg_error(cpl_func,"Standards RA/DEC table has no rows");
375  return -1;
376  }
377 
378  /* Get the x,y coordinates for each table */
379  xobj = cpl_table_get_data_float(objtab,"X_IMAGE");
380  yobj = cpl_table_get_data_float(objtab,"Y_IMAGE");
381  xstd = cpl_table_get_data_float(stdstab,"xpredict");
382  ystd = cpl_table_get_data_float(stdstab,"ypredict");
383  if (xstd == NULL || ystd == NULL || xobj == NULL || yobj == NULL){
384  cpl_msg_error(cpl_func,"NULL input data");
385  return -1;
386  }
387 
388  /* Calculate the error limit and the number of grid points */
389  aveden = (float)nstd/(float)(NX*NY);
390  errlim = 1.0/sqrt(4.0*CPL_MATH_PI*aveden);
391  errlim = omega_min(errlim,5.0);
392  ngrid = (int)(srad/errlim);
393  ngrid = (ngrid/2)*2 + 1;
394  ngrid = omega_max(5,omega_min(NGRIDMAX,ngrid));
395  ngrid2 = ngrid/2 + 1;
396 
397  /* Now search for the best solution */
398  ibest = 0;
399  xoffbest = 0.0;
400  yoffbest = 0.0;
401  for (ig = -ngrid2; ig <= ngrid2; ig++) {
402  xoff = (float)ig*errlim*CPL_MATH_SQRT2;
403  for (jg = -ngrid2; jg <= ngrid2; jg++) {
404  yoff = (float)jg*errlim*CPL_MATH_SQRT2;
405  nmatch = 0;
406  for (k = 0; k < nobj; k++) {
407  x = xobj[k] + xoff;
408  y = yobj[k] + yoff;
409  if (omega_fndmatch(x,y,xstd,ystd,nstd,errlim) > -1)
410  nmatch++;
411  }
412  if (nmatch > ibest) {
413  ibest = nmatch;
414  xoffbest = xoff;
415  yoffbest = yoff;
416  }
417  }
418  }
419 
420  /* Now allocate some workspace so that you can calculate a good median
421  coordinate difference */
422  xoffs = cpl_malloc(nstd*sizeof(*xoffs));
423  yoffs = cpl_malloc(nstd*sizeof(*yoffs));
424  matches = cpl_malloc(nstd*sizeof(*matches));
425  for (k = 0; k < nstd; k++)
426  matches[k] = -1;
427 
428  /* Now get the best matches */
429  nmatch = 0;
430  for (k = 0; k < nstd; k++) {
431  x = xstd[k] - xoffbest;
432  y = ystd[k] - yoffbest;
433  jm = omega_fndmatch(x,y,xobj,yobj,nobj,errlim);
434  if (jm > -1) {
435  dont = 0;
436  x2 = xobj[jm] - x;
437  y2 = yobj[jm] - y;
438  r2 = sqrt(x2*x2 + y2*y2);
439  for (l = 0; l < nstd; l++) {
440  if (matches[l] == jm) {
441  x1 = xobj[jm] - (xstd[l] - xoffbest);
442  y1 = yobj[jm] - (ystd[l] - yoffbest);
443  r1 = sqrt(x1*x1 + y1*y1);
444  if (r2 < r1)
445  matches[l] = -1;
446  else
447  dont = 1;
448  break;
449  }
450  }
451  if (dont == 0)
452  matches[k] = jm;
453  }
454  }
455 
456  /* Now get the coordinate difference for the best matches */
457  for (k = 0; k < nstd; k++) {
458  jm = matches[k];
459  if (jm != -1) {
460  xoffs[nmatch] = xobj[jm] - xstd[k];
461  yoffs[nmatch] = yobj[jm] - ystd[k];
462  nmatch++;
463  }
464  }
465  if (nmatch == 0) {
466  xoffmed = 0.0;
467  sigx = 1.0;
468  yoffmed = 0.0;
469  sigy = 1.0;
470  } else {
471  omega_medmad(xoffs,NULL,nmatch,&xoffmed,&sigx);
472  sigx *= 1.48;
473  omega_medmad(yoffs,NULL,nmatch,&yoffmed,&sigy);
474  sigy *= 1.48;
475  }
476 
477  /* Now go through one final time with a reduced error box and get
478  the final matches */
479  errlim = 3.0*omega_max(sigx,sigy);
480  for (k = 0; k < nstd; k++)
481  matches[k] = -1;
482  for (k = 0; k < nstd; k++) {
483  x = xstd[k] + xoffmed;
484  y = ystd[k] + yoffmed;
485  jm = omega_fndmatch(x,y,xobj,yobj,nobj,errlim);
486  if (jm > -1) {
487  dont = 0;
488  x2 = xobj[jm] - x;
489  y2 = yobj[jm] - y;
490  r2 = sqrt(x2*x2 + y2*y2);
491  for (l = 0; l < nstd; l++) {
492  if (matches[l] == jm) {
493  x1 = xobj[jm] - (xstd[l] + xoffmed);
494  y1 = yobj[jm] - (ystd[l] + yoffmed);
495  r1 = sqrt(x1*x1 + y1*y1);
496  if (r2 < r1)
497  matches[l] = -1;
498  else
499  dont = 1;
500 /* break; */
501  }
502  }
503  if (dont == 0)
504  matches[k] = jm;
505  }
506  }
507  jm = matches[1];
508 
509  /* Make a copy of the standards table and add all the columns from the
510  object catalogue to it. Ingore the RA and DEC columns in the catalogue
511  as the standards table will already have these.*/
512 
513  mstds = cpl_table_duplicate(stdstab);
514  colname = (char *)cpl_table_get_column_name(objtab);
515  while (colname != NULL) {
516  if (strcmp(colname,"X_WORLD") && strcmp(colname,"Y_WORLD"))
517  cpl_table_new_column(mstds,colname,
518  cpl_table_get_column_type(objtab,colname));
519 
520  colname = (char *)cpl_table_get_column_name(NULL);
521  }
522  cpl_table_unselect_all(mstds);
523 
524  /* Now go through and find the matches. */
525 
526  for (k = 0; k < nstd; k++) {
527  jm = matches[k];
528  if (jm != -1) {
529  colname = (char *)cpl_table_get_column_name(objtab);
530  while (colname != NULL) {
531  if (!strcmp(colname,"X_WORLD") || !strcmp(colname,"Y_WORLD")) {
532  colname = (char *)cpl_table_get_column_name(NULL);
533  continue;
534  }
535  null = 0;
536  switch (cpl_table_get_column_type(objtab,colname)) {
537  case CPL_TYPE_INT:
538  cpl_table_set_int(mstds,colname,k,
539  cpl_table_get_int(objtab,colname,jm,
540  &null));
541  break;
542  case CPL_TYPE_FLOAT:
543  cpl_table_set_float(mstds,colname,k,
544  cpl_table_get_float(objtab,colname,jm,
545  &null));
546  break;
547  case CPL_TYPE_DOUBLE:
548  cpl_table_set_double(mstds,colname,k,
549  cpl_table_get_double(objtab,colname,
550  jm,&null));
551  break;
552  default:
553  cpl_table_set_float(mstds,colname,k,
554  cpl_table_get_float(objtab,colname,jm,
555  &null));
556  break;
557  }
558  colname = (char *)cpl_table_get_column_name(NULL);
559  }
560  cpl_table_select_row(mstds,k);
561  }
562  }
563 
564  /* Now extract the selected rows into the output table */
565 
566  *outtab = cpl_table_extract_selected(mstds);
567  cpl_table_delete(mstds);
568 
569  /* Tidy up */
570 
571  cpl_free(matches);
572  cpl_free(xoffs);
573  cpl_free(yoffs);
574 
575  return 0;
576 }
577 /*-------------------------------------------------------------------------*/
594  /*--------------------------------------------------------------------------*/
595 cpl_table *omega_get_usnoa_table(const cpl_frame *catalog, cpl_vector *coords, int *nstds)
596 {
597  int number = 0;
598  int i = 0;
599 // int irow = 0;
600  double ramin = 0.0;
601  double ramax = 0.0;
602  double decmin = 0.0;
603  double decmax = 0.0;
604  char *pathname = NULL;
605 // const char *name = NULL;
606 // char *tname = NULL;
607  cpl_table *table = NULL;
608  cpl_table *extracted;
609  cpl_table *all;
610 
611  /* Load master usnoa2 table */
612  table = cpl_table_load(cpl_frame_get_filename(catalog), 1, 0);
613  if( table == NULL){
614  return NULL;
615  }
616 
617  /* Get pathname */
618  pathname = omega_get_pathname(cpl_frame_get_filename(catalog));
619 
620  /* Get coordinates of desired region */
621  ramin = cpl_vector_get(coords, 0);
622  ramax = cpl_vector_get(coords, 1);
623  decmin = cpl_vector_get(coords, 2);
624  decmax = cpl_vector_get(coords, 3);
625 
626  /* Select the fits tables that fall into the desired region */
627  cpl_table_select_all(table);
628  cpl_table_and_selected_double(table,"Dec_max",CPL_NOT_LESS_THAN,decmin);
629  number = cpl_table_and_selected_double(table,"Dec_min",CPL_NOT_GREATER_THAN,decmax);
630  if(number == 0){
631  freetable(table);
632  return NULL;
633  }
634 
635  extracted = cpl_table_extract_selected(table);
636  freetable(table);
637 
638  /* Merge the tables into one after selecting */
639  for(i=0; i<number; i++){
640  const char *name = cpl_table_get_string(extracted,"USNOA2_CAT",i);
641  char *tname = cpl_sprintf("%s/%s",pathname,name);
642  cpl_table *t = cpl_table_load(tname, 1, 0);
643 
644  /* Select stars falling in RA range */
645  cpl_table_select_all(t);
646  cpl_table_and_selected_double(t, "RA2000",CPL_NOT_LESS_THAN, ramin);
647  cpl_table_and_selected_double(t, "RA2000", CPL_NOT_GREATER_THAN, ramax);
648 
649  /* Select stars falling in DEC range */
650  cpl_table_and_selected_double(t, "Dec2000", CPL_NOT_LESS_THAN, decmin);
651  int number = cpl_table_and_selected_double(t, "Dec2000", CPL_NOT_GREATER_THAN, decmax);
652  if (number <= 0) {
653  freetable(t);
654  freespace(tname);
655  freetable(extracted);
656  return NULL;
657  }
658 
659  /* Extract selected stars */
660  cpl_table *ext = cpl_table_extract_selected(t);
661  if(i==0){
662  all = cpl_table_new(0);
663  cpl_table_copy_structure(all, ext);
664  }
665 
666  int irow = cpl_table_get_nrow(all);
667 
668  cpl_table_insert(all, ext, irow+1);
669  freetable(ext);
670  freetable(t);
671  freespace(tname);
672  }
673 
674  *nstds = cpl_table_get_nrow(all);
675  // printf("n=%d",nstds);
676 
677  freetable(extracted);
678 
679  return all;
680 }
681 
682 /*-------------------------------------------------------------------------*/
700  /*--------------------------------------------------------------------------*/
701 cpl_table *omega_get_stds_table(const char *stdcat, cpl_vector *coords, int *nstds)
702 {
703  int number = 0;
704  double ramin = 0.0;
705  double ramax = 0.0;
706  double decmin = 0.0;
707  double decmax = 0.0;
708  cpl_table *table = NULL;
709  cpl_table *extracted;
710 
711  /* Load reference std table */
712  table = cpl_table_load(stdcat, 1, 0);
713  if( table == NULL){
714  cpl_msg_warning(cpl_func,"Cannot load reference catalogue %s",stdcat);
715  return NULL;
716  }
717 
718  /* Get coordinates of desired region */
719  ramin = cpl_vector_get(coords, 0);
720  ramax = cpl_vector_get(coords, 1);
721  decmin = cpl_vector_get(coords, 2);
722  decmax = cpl_vector_get(coords, 3);
723 
724  /* Select the stars that fall into the desired region */
725  cpl_table_select_all(table);
726 
727  cpl_table_and_selected_double(table,"Dec",CPL_NOT_LESS_THAN,decmin);
728 
729  cpl_table_and_selected_double(table,"Dec",CPL_NOT_GREATER_THAN,decmax);
730 
731  cpl_table_and_selected_double(table,"Ra",CPL_NOT_LESS_THAN,ramin);
732 
733  number = cpl_table_and_selected_double(table,"Ra",CPL_NOT_GREATER_THAN,ramax);
734 
735  if(number <= 0){
736  cpl_msg_debug(cpl_func,"There are no stars in catalogue in given region");
737  freetable(table);
738  return NULL;
739  }
740 
741  extracted = cpl_table_extract_selected(table);
742  freetable(table);
743 
744  *nstds = cpl_table_get_nrow(extracted);
745 
746 
747  return extracted;
748 }
749 
750 
766 cpl_table *omega_filter_table_int(cpl_table *src, const char *col, cpl_table_select_operator operator,
767  int value, int *nsrc)
768 {
769  cpl_table *out;
770 
771  if(cpl_table_has_column(src, col) != 1)
772  return NULL;
773 
774  if(cpl_table_get_column_type(src, col) != CPL_TYPE_INT)
775  return NULL;
776 
777  cpl_table_unselect_all(src);
778  cpl_table_or_selected_int(src, col, operator, value);
779  out = cpl_table_extract_selected(src);
780  *nsrc = cpl_table_get_nrow(out);
781 
782  return out;
783 
784 }
785 
786 /*-------------------------------------------------------------------------*/
800 cpl_table *omega_filter_table_double(cpl_table *src, const char *col, cpl_table_select_operator operator,
801  double value, int *nsrc)
802 {
803  cpl_table *out;
804 
805  if(cpl_table_has_column(src, col) != 1)
806  return NULL;
807 
808  if(cpl_table_get_column_type(src, col) != CPL_TYPE_DOUBLE)
809  return NULL;
810 
811  cpl_table_unselect_all(src);
812  cpl_table_or_selected_double(src, col, operator, value);
813  out = cpl_table_extract_selected(src);
814  *nsrc = cpl_table_get_nrow(out);
815 
816  return out;
817 
818 }
819 
820 /*-------------------------------------------------------------------------*/
834 cpl_table *omega_filter_table_string(cpl_table *src, const char *col, cpl_table_select_operator operator,
835  const char *value, int *nsrc)
836 {
837  cpl_table *out;
838 
839  if(cpl_table_has_column(src, col) != 1)
840  return NULL;
841 
842  if(cpl_table_get_column_type(src, col) != CPL_TYPE_STRING)
843  return NULL;
844 
845  cpl_table_unselect_all(src);
846  cpl_table_or_selected_string(src, col, operator, value);
847  out = cpl_table_extract_selected(src);
848  *nsrc = cpl_table_get_nrow(out);
849 
850  return out;
851 
852 }
853 
854 /*-------------------------------------------------------------------------*/
868 cpl_table *omega_filter_table_float(cpl_table *src, const char *col, cpl_table_select_operator operator,
869  float value, int *nsrc)
870 {
871  cpl_table *out;
872 
873  if(cpl_table_has_column(src, col) != 1)
874  return NULL;
875 
876  if(cpl_table_get_column_type(src, col) != CPL_TYPE_FLOAT)
877  return NULL;
878 
879  cpl_table_unselect_all(src);
880  cpl_table_or_selected_float(src, col, operator, value);
881  out = cpl_table_extract_selected(src);
882  *nsrc = cpl_table_get_nrow(out);
883 
884  return out;
885 
886 }
887 
898 cpl_table *omega_science_catalogue(const char *sci, const char *conf, double zeropoint_final, cpl_parameterlist *pars)
899 {
900  int i = 0;
901  int nsources = 0;
902  int npars = 0;
903  cpl_size lastextension=0;
904  double cat_thre = 1.0;
905  char *cmd = NULL;
906  const char *path = NULL;
907  const char *sex_conf = NULL;
908  const char *sex_conv = NULL;
909  const char *sex_nnw = NULL;
910  const char *sex_par = NULL;
911  const char *text = NULL;
912  const char *srcs = "omega_sci_cat.fits";
913 
914  cpl_table *table, *sources;
915  cpl_parameter *par;
916 
917 
918  /* Get parameters */
919  npars = cpl_parameterlist_get_size(pars);
920  par = cpl_parameterlist_get_first(pars);
921 
922  for(i=0; i<npars; i++) {
923  text = cpl_parameter_get_alias(par, CPL_PARAMETER_MODE_CLI);
924  if(strcmp("bin-path", text) == 0) {
925  path = cpl_parameter_get_string(par) ;
926  }
927  else if(strcmp("sex-config", text) == 0) {
928  sex_conf = cpl_parameter_get_string(par) ;
929  }
930  else if(strcmp("sex-conv", text) == 0) {
931  sex_conv = cpl_parameter_get_string(par) ;
932  }
933  else if(strcmp("sex-param", text) == 0) {
934  sex_par = cpl_parameter_get_string(par) ;
935  }
936  else if(strcmp("sex-nnw", text) == 0) {
937  sex_nnw = cpl_parameter_get_string(par) ;
938  }
939  else if(strcmp("cat-thre", text) == 0){
940  cat_thre = cpl_parameter_get_double(par);
941  }
942  par = cpl_parameterlist_get_next(pars);
943 
944  }
945 
946  cpl_msg_debug(cpl_func,"zeropoint_final: %f",zeropoint_final);
947 
948 
949  /* Create catalog of sources from image */
950  cmd = cpl_sprintf("%s/sex %s -c %s -PARAMETERS_NAME %s -FILTER_NAME %s -STARNNW_NAME %s "
951  "-FILTER Y -DETECT_THRESH %g -ANALYSIS_THRESH %g "
952  "-WEIGHT_TYPE MAP_WEIGHT -WEIGHT_IMAGE %s -CATALOG_TYPE FITS_1.0 -CATALOG_NAME %s -MAG_ZEROPOINT %g "
953  "-BACKPHOTO_TYPE LOCAL",
954  path,
955  sci,
956  sex_conf,
957  sex_par,
958  sex_conv,
959  sex_nnw,
960  cat_thre,
961  cat_thre,
962  conf,
963  srcs,
964  zeropoint_final);
965 
966  cpl_msg_debug(cpl_func,"Sextractor call: %s",cmd);
967 
968  if (system(cmd) != 0) {
969  cpl_msg_debug(cpl_func,"Failed to create catalogue using Sextractor");
970  freespace(cmd);
971  return NULL;
972  }
973  freespace(cmd);
974 
975  lastextension=cpl_fits_count_extensions(srcs);
976  table = cpl_table_load(srcs, lastextension, 0);
977  if((table == NULL) || (cpl_table_get_nrow(table) <= 0)){
978  cpl_msg_debug(cpl_func,"Science catalogue table is empty or NULL");
979  return NULL;
980  }
981 
982  /* Filter for FLAGS = 0 */
983  sources = omega_filter_table_int(table, "FLAGS", CPL_EQUAL_TO, 0, &nsources);
984 
985  freetable(table);
986 
987 
988  return sources;
989 }
990 
993 /*
994  * Alternative matching function for tests
995  *
996  */
997 cpl_table * wcscor_matchstds(cpl_table *objtab, cpl_table *stdstab, float srad)
998 {
999 
1000  int i = 0;
1001  int j = 0;
1002  int k = 0;
1003  int nobj, nstd;
1004  float *xobj;
1005  float *yobj;
1006  float *xstd;
1007  float *ystd;
1008  const char *colname;
1009  cpl_table *matches, *temp;
1010  cpl_propertylist *p;
1011 
1012  nobj = cpl_table_get_nrow(objtab);
1013  nstd = cpl_table_get_nrow(stdstab);
1014  if (nobj == 0) {
1015  cpl_msg_warning(cpl_func,"Object table has no rows");
1016  } else if (nstd == 0) {
1017  cpl_msg_warning(cpl_func,"Reference standards table has no rows");
1018  }
1019 
1020 /* First, sort the two tables by the Y coordinate */
1021 /* p = cpl_propertylist_new();
1022  cpl_propertylist_append_bool(p,"Y_IMAGE",0);
1023  if (cpl_table_sort(objtab,p) != CPL_ERROR_NONE) {
1024  cpl_msg_error(cpl_func,"Cannot sort sources table");
1025  cpl_propertylist_delete(p);
1026  return NULL;
1027  }
1028  cpl_propertylist_erase(p,"Y_IMAGE");
1029  cpl_propertylist_append_bool(p,"ypredict",0);
1030  if (cpl_table_sort(stdstab,p) != CPL_ERROR_NONE) {
1031  cpl_msg_error(cpl_func,"Cannot sort stds table");
1032  cpl_propertylist_delete(p);
1033  return NULL;
1034  }
1035  cpl_propertylist_delete(p);
1036 */
1037  cpl_table_unselect_all(objtab);
1038  cpl_table_unselect_all(stdstab);
1039 
1040  /* Get columns data */
1041  xobj = cpl_table_get_data_float(objtab,"X_IMAGE");
1042  xstd = cpl_table_get_data_float(stdstab, "xpredict");
1043  yobj = cpl_table_get_data_float(objtab,"Y_IMAGE");
1044  ystd = cpl_table_get_data_float(stdstab, "ypredict");
1045 // ra = cpl_table_get_data_double(stdstab, "RA2000");
1046 // dec = cpl_table_get_data_double(stdstab, "Dec2000");
1047 
1048  if (xstd == NULL || ystd == NULL || xobj == NULL || yobj == NULL){
1049  cpl_msg_error(cpl_func,"Fatal error in wcscor_matchstds");
1050  return NULL;
1051  }
1052 
1053  k = 0;
1054 
1055  for (i=0; i<nobj; i++){
1056  for(j=0; j<nstd; j++){
1057  if((xstd[j] <= xobj[i] +srad) && (xstd[j] >= xobj[i] -srad) &&
1058  (ystd[j] <= yobj[i] +srad) && (ystd[j] >= yobj[i] -srad)) {
1059  cpl_table_select_row(stdstab, j);
1060  cpl_table_select_row(objtab, i);
1061  k++;
1062 
1063  break;
1064  }
1065  }
1066  }
1067 
1068  matches = cpl_table_extract_selected(stdstab);
1069  temp = cpl_table_extract_selected(objtab);
1070  for (i=0; i<cpl_table_get_ncol(temp); i++){
1071  colname = cpl_table_get_column_name(temp);
1072  cpl_table_move_column(matches, colname, temp);
1073  }
1074 
1075 
1076  return matches;
1077 }