public software.sextractor

[/] [trunk/] [src/] [wcs/] [tnx.c] - Blame information for rev 235

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 bertin
/*
2 233 bertin
*                               tnx.c
3 2 bertin
*
4 233 bertin
* Manage the TNX astrometric format (from IRAF)
5 2 bertin
*
6 233 bertin
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7 2 bertin
*
8 233 bertin
*       This file part of:      AstrOmatic WCS library
9 2 bertin
*
10 235 bertin
*       Copyright:              (C) 2000-2010 Emmanuel Bertin -- IAP/CNRS/UPMC
11 2 bertin
*
12 233 bertin
*       License:                GNU General Public License
13
*
14
*       AstrOmatic software is free software: you can redistribute it and/or
15
*       modify it under the terms of the GNU General Public License as
16
*       published by the Free Software Foundation, either version 3 of the
17
*       License, or (at your option) any later version.
18
*       AstrOmatic software is distributed in the hope that it will be useful,
19
*       but WITHOUT ANY WARRANTY; without even the implied warranty of
20
*       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
*       GNU General Public License for more details.
22
*       You should have received a copy of the GNU General Public License
23
*       along with AstrOmatic software.
24
*       If not, see <http://www.gnu.org/licenses/>.
25
*
26
*       Last modified:          10/10/2010
27
*
28
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
29 2 bertin
 
30
#ifdef HAVE_CONFIG_H
31
#include        "config.h"
32
#endif
33
 
34
#ifdef HAVE_MATHIMF_H
35
#include <mathimf.h>
36
#else
37
#include <math.h>
38
#endif
39
#include        <stdio.h>
40
#include        <stdlib.h>
41
#include        <string.h>
42
 
43
#include        "tnx.h"
44
 
45
/******* read_tnxaxis *********************************************************
46
PROTO   tnxaxisstruct *read_tnxaxis(char *tnxstr)
47
PURPOSE Read a TNX axis mapping structure.
48
INPUT   String containing the TNX info.
49
OUTPUT  TNXAXIS structure if OK, or NULL in case of error.
50
NOTES   -.
51
AUTHOR  E. Bertin (IAP)
52 10 bertin
VERSION 04/07/2006
53 2 bertin
 ***/
54
 
55
tnxaxisstruct   *read_tnxaxis(char *tnxstr)
56
 
57
  {
58
   tnxaxisstruct        *tnxaxis;
59 7 bertin
   char         *pstr, *ptr;
60 2 bertin
   double       min, max;
61
   int          i, order;
62
 
63
  if ((pstr=strpbrk(tnxstr, "1234567890-+.")))
64
    {
65
    if (!(tnxaxis=malloc(sizeof(tnxaxisstruct))))
66
      return NULL;
67 9 bertin
    tnxaxis->type = (int)(atof(strtok_r(pstr, " ", &ptr))+0.5);
68 7 bertin
    tnxaxis->xorder = (pstr=strtok_r(NULL, " ", &ptr))?
69
                        (int)(atof(pstr)+0.5) : 0;
70
    tnxaxis->yorder = (pstr=strtok_r(NULL, " ", &ptr))?
71
                        (int)(atof(pstr)+0.5) : 0;
72
    tnxaxis->xterms = (pstr=strtok_r(NULL, " ", &ptr))?
73
                        (int)(atof(pstr)+0.5) : 0;
74
    min = (pstr=strtok_r(NULL, " ", &ptr))? atof(pstr) : 0.0;
75
    max = (pstr=strtok_r(NULL, " ", &ptr))? atof(pstr) : 0.0;
76 2 bertin
    if (max <= min)
77
      return NULL;
78
    tnxaxis->xrange = 2.0 / (max - min);
79
    tnxaxis->xmaxmin =  - (max + min) / 2.0;
80 7 bertin
    min = (pstr=strtok_r(NULL, " ", &ptr))? atof(pstr) : 0.0;
81
    max = (pstr=strtok_r(NULL, " ", &ptr))? atof(pstr) : 0.0;
82 2 bertin
    if (max <= min)
83
      return NULL;
84
    tnxaxis->yrange = 2.0 / (max - min);
85
    tnxaxis->ymaxmin =  - (max + min) / 2.0;
86
    switch (tnxaxis->xterms)
87
      {
88
      case TNX_XNONE:
89
        tnxaxis->ncoeff = tnxaxis->xorder + tnxaxis->yorder - 1;
90
        break;
91
      case TNX_XHALF:
92
        order = tnxaxis->xorder<tnxaxis->yorder?
93
                        tnxaxis->xorder : tnxaxis->yorder;
94
        tnxaxis->ncoeff = tnxaxis->xorder*tnxaxis->yorder - order*(order-1)/2;
95
        break;
96
      case TNX_XFULL:
97
        tnxaxis->ncoeff = tnxaxis->xorder * tnxaxis->yorder;
98
        break;
99
      default:
100
        return NULL;
101
      }
102
/*-- Now read the mapping coefficients */
103
    if (!(tnxaxis->coeff=malloc(tnxaxis->ncoeff*sizeof(double))))
104
      return NULL;
105 9 bertin
    for (i=0; i<tnxaxis->ncoeff && (pstr=strtok_r(NULL, " ", &ptr)); i++)
106 2 bertin
      tnxaxis->coeff[i] = atof(pstr);
107
    if (i!=tnxaxis->ncoeff)
108
      return NULL;
109
    if (!(tnxaxis->xbasis=malloc(tnxaxis->xorder*sizeof(double))))
110
      return NULL;
111
    if (!(tnxaxis->ybasis=malloc(tnxaxis->yorder*sizeof(double))))
112
      return NULL;
113
    return tnxaxis;
114
    }
115
  else
116
    return NULL;
117
  }
118
 
119
 
120
/******* copy_tnxaxis *********************************************************
121
PROTO   tnxaxisstruct *copy_tnxaxis(tnxaxisstruct *axis)
122
PURPOSE Copy a TNX axis mapping structure.
123
INPUT   TNXAXIS structure pointer.
124
OUTPUT  -.
125
NOTES   -.
126
AUTHOR  E. Bertin (IAP)
127
VERSION 28/11/2003
128
 ***/
129
 
130
tnxaxisstruct   *copy_tnxaxis(tnxaxisstruct *axis)
131
 
132
  {
133
   tnxaxisstruct        *tnxaxis;
134
   int                  i;
135
 
136
  if (axis)
137
    {
138
    if (!axis->ncoeff)
139
      return NULL;
140
    if (!(tnxaxis=malloc(sizeof(tnxaxisstruct))))
141
      return NULL;
142
    *tnxaxis = *axis;
143
    if (!(tnxaxis->coeff=malloc(tnxaxis->ncoeff*sizeof(double))))
144
      return NULL;
145
    for (i=0; i<tnxaxis->ncoeff; i++)
146
      tnxaxis->coeff[i] = axis->coeff[i];
147
    if (!(tnxaxis->xbasis=malloc(tnxaxis->xorder*sizeof(double))))
148
      return NULL;
149
    for (i=0; i<tnxaxis->xorder; i++)
150
      tnxaxis->xbasis[i] = axis->xbasis[i];
151
    if (!(tnxaxis->ybasis=malloc(tnxaxis->yorder*sizeof(double))))
152
      return NULL;
153
    for (i=0; i<tnxaxis->yorder; i++)
154
      tnxaxis->ybasis[i] = axis->ybasis[i];
155
    return tnxaxis;
156
    }
157
 
158
  return NULL;
159
  }
160
 
161
 
162
/******* free_tnxaxis *********************************************************
163
PROTO   void free_tnxaxis(tnxaxisstruct *axis)
164
PURPOSE Free a TNX axis mapping structure.
165
INPUT   TNXAXIS structure pointer.
166
OUTPUT  -.
167
NOTES   -.
168
AUTHOR  E. Bertin (IAP)
169
VERSION 09/04/2000
170
 ***/
171
 
172
void    free_tnxaxis(tnxaxisstruct *axis)
173
 
174
  {
175
  if (axis)
176
    {
177
 
178
    free(axis->coeff);
179
    free(axis->xbasis);
180
    free(axis->ybasis);
181
    free(axis);
182
    }
183
 
184
  return;
185
  }
186
 
187
 
188
/******* raw_to_tnxaxis *******************************************************
189
PROTO   double raw_to_tnxaxis(tnxaxisstruct *axis, double x, double y)
190
PURPOSE Compute the correction value on a TNX axis at current position.
191
INPUT   TNXAXIS structure pointer,
192
        x coordinate,
193
        y coordinate.
194
OUTPUT  Value on the TNXaxis.
195
NOTES   -.
196
AUTHOR  E. Bertin (IAP)
197
VERSION 11/04/2000
198
 ***/
199
 
200
double  raw_to_tnxaxis(tnxaxisstruct *axis, double x, double y)
201
 
202
  {
203
   double       *xbasis, *ybasis,*coeff,
204
                norm, accum, val;
205
   int          i, j, xorder,xorder0,yorder,maxorder,xterms;
206
 
207
  xbasis = axis->xbasis;
208
  ybasis = axis->ybasis;
209
  xorder = axis->xorder;
210
  yorder = axis->yorder;
211
  xterms = axis->xterms;
212
 
213
  switch (axis->type)
214
    {
215
    case TNX_CHEBYSHEV:
216
      xbasis[0] = 1.0;
217
      if (xorder > 1)
218
        {
219
        xbasis[1] = norm = (x + axis->xmaxmin)*axis->xrange;
220
        if (xorder > 2)
221
          for (i = 2; i < xorder; i++)
222
            xbasis[i] = 2.0*norm*xbasis[i-1] - xbasis[i-2];
223
        }
224
      ybasis[0] = 1.0;
225
      if (yorder > 1)
226
        {
227
        ybasis[1] = norm = (y + axis->ymaxmin)*axis->yrange;
228
        if (yorder > 2)
229
          for (i = 2; i < yorder; i++)
230
            ybasis[i] = 2.0*norm*xbasis[i-1] - ybasis[i-2];
231
        }
232
      break;
233
 
234
    case TNX_LEGENDRE:
235
      xbasis[0] = 1.0;
236
      if (xorder > 1)
237
        {
238
        xbasis[1] = norm = (x + axis->xmaxmin)*axis->xrange;
239
        if (xorder > 2)
240
          for (i = 2; (j=i) < xorder; i++)
241
            xbasis[i] = ((2.0*j - 3.0) * norm * xbasis[i-1] -
242
                       (j - 2.0) * xbasis[i-2]) / (j - 1.0);
243
        }
244
      ybasis[0] = 1.0;
245
      if (yorder > 1)
246
        {
247
        ybasis[1] = norm = (y + axis->ymaxmin)*axis->yrange;
248
        if (yorder > 2)
249
          for (i = 2; (j=i) < xorder; i++)
250
            ybasis[i] = ((2.0*j - 3.0) * norm * ybasis[i-1] -
251
                       (j - 2.0) * ybasis[i-2]) / (j - 1.0);
252
        }
253
      break;
254
 
255
    case TNX_POLYNOMIAL:
256
      xbasis[0] = 1.0;
257
      if (xorder > 1)
258
        {
259
        xbasis[1] = x;
260
        if (xorder > 2)
261
          for (i = 2; i < xorder; i++)
262
            xbasis[i] = x * xbasis[i-1];
263
        }
264
      ybasis[0] = 1.0;
265
      if (yorder > 1)
266
        {
267
        ybasis[1] = y;
268
        if (yorder > 2)
269
          for (i = 2; i < yorder; i++)
270
            ybasis[i] = y * ybasis[i-1];
271
        }
272
      break;
273
 
274
    default:
275
      return 0.0;
276
    }
277
 
278
/* Loop over y basis functions */
279
  maxorder = xorder > yorder ? xorder : yorder;
280
  xorder0 = xorder;
281
  coeff = axis->coeff;
282
  val = 0.0;
283
  for (i = 0; i<yorder; i++)
284
    {
285
/*-- Loop over the x basis functions */
286
    accum = 0.0;
287
    xbasis = axis->xbasis;
288
    for (j = xorder; j--;)
289
      accum += *(coeff++) * *(xbasis++);
290
    val += accum**(ybasis++);
291
 
292
/*-- Elements of the coefficient vector where neither k = 1 or i = 1
293
           are not calculated if sf->xterms = no. */
294
    if (xterms == TNX_XNONE)
295
      xorder = 1;
296
    else if (xterms == TNX_XHALF && (i + 1 + xorder0) > maxorder)
297
      xorder--;
298
    }
299
 
300
  return val;
301
  }
302
 
303