Changeset 660

Show
Ignore:
Timestamp:
10/06/08 14:22:43 (2 months ago)
Author:
mdroe
Message:

Lots of fixes, mainly to SIP support

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/pywcs/pywcs/_docutil.py

    r643 r660  
     1# Copyright (C) 2008 Association of Universities for Research in 
     2# Astronomy (AURA) 
     3# 
     4# Redistribution and use in source and binary forms, with or without 
     5# modification, are permitted provided that the following conditions 
     6# are met: 
     7# 
     8#     1. Redistributions of source code must retain the above 
     9#       copyright notice, this list of conditions and the following 
     10#       disclaimer. 
     11# 
     12#     2. Redistributions in binary form must reproduce the above 
     13#       copyright notice, this list of conditions and the following 
     14#       disclaimer in the documentation and/or other materials 
     15#       provided with the distribution. 
     16# 
     17#     3. The name of AURA and its representatives may not be used to 
     18#       endorse or promote products derived from this software without 
     19#       specific prior written permission. 
     20# 
     21# THIS SOFTWARE IS PROVIDED BY AURA ``AS IS'' AND ANY EXPRESS OR 
     22# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
     23# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
     24# ARE DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT, 
     25# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
     26# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
     27# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
     28# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
     29# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
     30# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
     31# OF THE POSSIBILITY OF SUCH DAMAGE. 
     32 
     33""" 
     34pywcs-specific utilities for generating boilerplate in docstrings. 
     35""" 
     36 
    137def _fix(content, indent=0): 
    238    lines = content.split('\n') 
  • trunk/pywcs/pywcs/pywcs.py

    r652 r660  
    201201 
    202202            m = int(header["A_ORDER"]) 
    203             a = numpy.zeros((m+1, m+1)
     203            a = numpy.zeros((m+1, m+1), numpy.double
    204204            for i in range(m+1): 
    205205                for j in range(m-i+1): 
     
    207207 
    208208            m = int(header["B_ORDER"]) 
    209             b = numpy.zeros((m+1, m+1)
     209            b = numpy.zeros((m+1, m+1), numpy.double
    210210            for i in range(m+1): 
    211211                for j in range(m-i+1): 
     
    226226 
    227227            m = int(header["AP_ORDER"]) 
    228             ap = numpy.zeros((m+1, m+1)
     228            ap = numpy.zeros((m+1, m+1), numpy.double
    229229            for i in range(m+1): 
    230230                for j in range(m-i+1): 
     
    232232 
    233233            m = int(header["BP_ORDER"]) 
    234             bp = numpy.zeros((m+1, m+1)
     234            bp = numpy.zeros((m+1, m+1), numpy.double
    235235            for i in range(m+1): 
    236236                for j in range(m-i+1): 
     
    247247            return None 
    248248 
    249         return Sip(a, b, ap, bp, self.wcs.crpix) 
     249        if not header.has_key("CRPIX1") or not header.has_key("CRPIX2"): 
     250            raise ValueError( 
     251                "Header has SIP keywords without CRPIX keywords") 
     252 
     253        crpix1 = header.get("CRPIX1") 
     254        crpix2 = header.get("CRPIX2") 
     255 
     256        return Sip(a, b, ap, bp, (crpix1, crpix2)) 
    250257 
    251258    def _array_converter(self, func, *args): 
     
    341348 
    342349    def wcs_pix2sky_fits(self, *args): 
    343         return self._array_converter(lambda x: self.wcs.p2s(x)['world'], *args) 
     350        return self._array_converter(lambda x: self.wcs.p2s_fits(x)['world'], *args) 
    344351    wcs_pix2sky_fits.__doc__ = """ 
    345352        wcs_pix2sky_fits(*args) -> sky 
     
    351358        if self.wcs is None: 
    352359            raise ValueError("No basic WCS settings were created.") 
    353         return self._array_converter(lambda x: self.wcs.s2p(x)['pixel'], *args) 
     360        return self._array_converter(lambda x: self.wcs.s2p(x)['pixcrd'], *args) 
    354361    wcs_sky2pix.__doc__ = """ 
    355362        wcs_sky2pix(*args) -> pixel 
     
    379386        if self.wcs is None: 
    380387            raise ValueError("No basic WCS settings were created.") 
    381         return self._array_converter(lambda x: self.wcs.s2p_fits(x)['pixel'], 
     388        return self._array_converter(lambda x: self.wcs.s2p_fits(x)['pixcrd'], 
    382389                                     *args) 
    383390    wcs_sky2pix_fits.__doc__ = """ 
  • trunk/pywcs/setup.py

    r654 r660  
    123123 
    124124###################################################################### 
    125 # DISTUTILS SETUP 
    126 if USE_ASSERTS: 
    127     define_macros = [('DEBUG', None)] 
    128     undef_macros = [('NDEBUG')] 
    129 else: 
    130     define_macros = [('NDEBUG', None)] 
    131     undef_macros = [('DEBUG')] 
    132  
     125# PYWCS-SPECIFIC AND WRAPPER SOURCE FILES 
    133126PYWCS_SOURCES = [ # List of pywcs files to compile 
    134127    'distortion.c', 
     
    142135    'wcslib_wrap.c'] 
    143136PYWCS_SOURCES = [join('src', x) for x in PYWCS_SOURCES] 
     137 
     138###################################################################### 
     139# DISTUTILS SETUP 
     140if USE_ASSERTS: 
     141    define_macros = [('DEBUG', None)] 
     142    undef_macros = [('NDEBUG')] 
     143    extra_compile_args = ["-fno-inline"] 
     144else: 
     145    # Define ECHO as nothing to prevent spurious newlines from 
     146    # printing within the libwcs parser 
     147    define_macros = [('NDEBUG', None), ('ECHO', None)] 
     148    undef_macros = [('DEBUG')] 
     149    extra_compile_args = [] 
    144150 
    145151setup(name="pywcs", 
     
    159165                    ], 
    160166                  define_macros=define_macros, 
    161                   undef_macros=undef_macros 
     167                  undef_macros=undef_macros, 
     168                  extra_compile_args=extra_compile_args 
    162169                  ) 
    163170        ] 
  • trunk/pywcs/src/distortion.c

    r643 r660  
    7171static inline float 
    7272get_dist( 
    73     const distortion_lookup_t *lookup, 
     73    const distortion_lookup_t *lookup, 
    7474    const unsigned int coord[NAXES]) { 
    7575  unsigned int cropped[NAXES]; 
     
    8989static inline double 
    9090image_coord_to_distortion_coord( 
    91     const distortion_lookup_t *lookup, 
     91    const distortion_lookup_t *lookup, 
    9292    const unsigned int axis, 
    9393    const double img) { 
     
    101101      lookup->crpix[axis]); 
    102102 
    103   if (result < 0.0) 
     103  if (result < 0.0) { 
    104104    result = 0.0; 
    105   else if (result >= lookup->naxis[axis]) 
     105  } else if (result >= lookup->naxis[axis]) { 
    106106    result = lookup->naxis[axis] - 1.0; 
     107  } 
    107108 
    108109  return result; 
     
    115116static inline void 
    116117image_coords_to_distortion_coords( 
    117     const distortion_lookup_t *lookup, 
     118    const distortion_lookup_t *lookup, 
    118119    const double img[NAXES], 
    119120    /* Output parameters */ 
     
    172173      coord[1] = dist_ifloor[1] + k; 
    173174      result += (double)get_dist(lookup, coord) * \ 
    174                 calculate_weight(dist_weight[0], l, dist_weight[1], k); 
     175        calculate_weight(dist_weight[0], l, dist_weight[1], k); 
    175176    } 
    176177  } 
  • trunk/pywcs/src/pipeline.c

    r644 r660  
    4646  pipeline->cpdis[1] = NULL; 
    4747  pipeline->wcs = NULL; 
     48 
     49  /* Temporary buffers */ 
     50  pipeline->alloc_ncoord = 0; 
     51  pipeline->alloc_nelem = 0; 
     52  pipeline->tmp = NULL; 
     53  pipeline->imgcrd = NULL; 
     54  pipeline->phi = NULL; 
     55  pipeline->theta = NULL; 
     56  pipeline->stat = NULL; 
    4857} 
    4958 
     
    6069} 
    6170 
     71static void 
     72pipeline_free_tmp(pipeline_t* pipeline) { 
     73  /* Free all temporary buffers and reset pointers to NULL */ 
     74  free(pipeline->tmp); 
     75  pipeline->tmp = NULL; 
     76  free(pipeline->imgcrd); 
     77  pipeline->imgcrd = NULL; 
     78  free(pipeline->phi); 
     79  pipeline->phi = NULL; 
     80  free(pipeline->theta); 
     81  pipeline->theta = NULL; 
     82  free(pipeline->stat); 
     83  pipeline->stat = NULL; 
     84} 
     85 
     86void 
     87pipeline_free(pipeline_t* pipeline) { 
     88  pipeline_free_tmp(pipeline); 
     89} 
     90 
     91static int 
     92pipeline_realloc( 
     93    pipeline_t* pipeline, 
     94    unsigned int ncoord, 
     95    unsigned int nelem) { 
     96  if (pipeline->alloc_ncoord < ncoord || pipeline->alloc_nelem < nelem) { 
     97    pipeline_free_tmp(pipeline); 
     98 
     99    pipeline->alloc_ncoord = ncoord; 
     100    pipeline->alloc_nelem = nelem; 
     101 
     102    pipeline->imgcrd = malloc(ncoord * nelem * sizeof(double)); 
     103    if (pipeline->imgcrd == NULL) { 
     104      goto out_of_memory; 
     105    } 
     106 
     107    pipeline->phi = malloc(ncoord * sizeof(double)); 
     108    if (pipeline->phi == NULL) { 
     109      goto out_of_memory; 
     110    } 
     111 
     112    pipeline->theta = malloc(ncoord * sizeof(double)); 
     113    if (pipeline->theta == NULL) { 
     114      goto out_of_memory; 
     115    } 
     116 
     117    pipeline->stat = malloc(ncoord * nelem * sizeof(int)); 
     118    if (pipeline->stat == NULL) { 
     119      goto out_of_memory; 
     120    } 
     121 
     122    pipeline->tmp = malloc(ncoord * nelem * sizeof(double)); 
     123    if (pipeline->tmp == NULL) { 
     124      goto out_of_memory; 
     125    } 
     126  } 
     127 
     128  return 0; 
     129 
     130 out_of_memory: 
     131  pipeline->alloc_nelem = 0; 
     132  pipeline->alloc_ncoord = 0; 
     133  pipeline_free_tmp(pipeline); 
     134  return 2; 
     135} 
     136 
    62137int 
    63138pipeline_all_pixel2world( 
     
    67142    const double* pixcrd /* [ncoord][nelem] */, 
    68143    double* world /* [ncoord][nelem] */) { 
    69   double*       tmp        = NULL; 
    70   double*       imgcrd     = NULL; 
    71   double*       phi        = NULL; 
    72   double*       theta      = NULL; 
    73   int*          stat       = NULL; 
    74144  const double* wcs_input  = NULL; 
    75145  double*       wcs_output = NULL; 
     
    90160 
    91161  if (has_wcs) { 
    92     imgcrd = malloc(ncoord * nelem * sizeof(double)); 
    93     if (imgcrd == NULL) { 
    94       status = 2; 
    95       goto pipeline_pixel2world_exit; 
    96     } 
    97  
    98     phi = malloc(ncoord * sizeof(double)); 
    99     if (phi == NULL) { 
    100       status = 2; 
    101       goto pipeline_pixel2world_exit; 
    102     } 
    103  
    104     theta = malloc(ncoord * sizeof(double)); 
    105     if (theta == NULL) { 
    106       status = 2; 
    107       goto pipeline_pixel2world_exit; 
    108     } 
    109  
    110     stat = malloc(ncoord * nelem * sizeof(int)); 
    111     if (stat == NULL) { 
    112       status = 2; 
    113       goto pipeline_pixel2world_exit; 
     162    status = pipeline_realloc((pipeline_t*)pipeline, ncoord, nelem); 
     163    if (status != 0) { 
     164      goto exit; 
    114165    } 
    115166 
    116167    if (has_sip || has_p4) { 
    117       tmp = malloc(ncoord * nelem * sizeof(double)); 
    118       if (tmp == NULL) { 
    119         status = 2; 
    120         goto pipeline_pixel2world_exit; 
     168      status = pipeline_pix2foc(pipeline, ncoord, nelem, pixcrd, pipeline->tmp); 
     169      if (status != 0) { 
     170        goto exit; 
    121171      } 
    122172 
    123       status = pipeline_pix2foc(pipeline, ncoord, nelem, pixcrd, tmp); 
    124       if (status != 0) { 
    125         goto pipeline_pixel2world_exit; 
    126       } 
    127  
    128       wcs_input = tmp; 
     173      wcs_input = pipeline->tmp; 
    129174      wcs_output = world; 
    130175    } else { 
     
    134179 
    135180    status = wcsp2s(pipeline->wcs, ncoord, nelem, 
    136                     wcs_input, imgcrd, phi, theta, wcs_output, stat); 
     181                    wcs_input, pipeline->imgcrd, pipeline->phi, 
     182                    pipeline->theta, wcs_output, pipeline->stat); 
    137183  } else { 
    138184    if (has_sip || has_p4) { 
     
    141187  } 
    142188 
    143  pipeline_pixel2world_exit: 
    144   free(tmp); 
    145   free(imgcrd); 
    146   free(phi); 
    147   free(theta); 
    148   free(stat); 
    149  
     189 exit: 
     190  /* We don't have any cleanup at the moment */ 
    150191  return status; 
    151192} 
     
    197238    status = sip_pix2foc(pipeline->sip, 2, ncoord, sip_input, sip_output); 
    198239    if (status) { 
    199       goto pipeline_pix2foc_exit; 
     240      goto exit; 
    200241    } 
    201242  } 
     
    204245    status = p4_pix2foc(2, (void*)pipeline->cpdis, ncoord, p4_input, p4_output); 
    205246    if (status) { 
    206       goto pipeline_pix2foc_exit; 
    207     } 
    208   } 
    209  
    210  pipeline_pix2foc_exit: 
     247      goto exit; 
     248    } 
     249  } 
     250 
     251 exit: 
    211252  /* We don't have any cleanup at the moment */ 
    212  
    213253  return status; 
    214254} 
  • trunk/pywcs/src/pipeline.h

    r644 r660  
    4646  distortion_lookup_t* cpdis[2]; 
    4747  struct wcsprm* wcs; 
     48 
     49  /* Temporary buffers for performing calculations */ 
     50  unsigned int alloc_ncoord; 
     51  unsigned int alloc_nelem; 
     52  double* tmp; 
     53  double* imgcrd; 
     54  double* phi; 
     55  double* theta; 
     56  int* stat; 
    4857} pipeline_t; 
    4958 
     
    6473    distortion_lookup_t* cpdis[2], 
    6574    struct wcsprm* wcs); 
     75 
     76/** 
     77Free all the temporary buffers of a pipeline_t.  It does not free 
     78the underlying sip_t, distortion_lookup_t or wcsprm objects. 
     79*/ 
     80void 
     81pipeline_free( 
     82    pipeline_t* pipeline); 
    6683 
    6784/** 
  • trunk/pywcs/src/pywcs.c

    r653 r660  
    6666 */ 
    6767 
     68static int 
     69PyWcs_traverse(PyWcs* self, visitproc visit, void* arg) { 
     70  Py_VISIT(self->py_sip); 
     71  Py_VISIT(self->py_distortion_lookup[0]); 
     72  Py_VISIT(self->py_distortion_lookup[1]); 
     73  Py_VISIT(self->py_wcsprm); 
     74 
     75  return 0; 
     76} 
     77 
    6878static void 
    6979PyWcs_dealloc(PyWcs* self) { 
     
    7282  Py_XDECREF(self->py_distortion_lookup[1]); 
    7383  Py_XDECREF(self->py_wcsprm); 
     84  pipeline_free(&self->x); 
    7485  self->ob_type->tp_free((PyObject*)self); 
    7586} 
     
    169180  world = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(pixcrd), PyArray_DOUBLE); 
    170181  if (world == NULL) { 
    171     goto _exit; 
     182    goto exit; 
    172183  } 
    173184 
    174185  /* Adjust pixel coordinates to be 1-based */ 
    175   if (do_shift) 
     186  if (do_shift) { 
    176187    offset_array(pixcrd, 1.0); 
     188  } 
    177189 
    178190  /* Make the call */ 
     
    185197  wcsprm_c2python(self->x.wcs); 
    186198  /* Adjust pixel coordinates back to 0-based */ 
    187   if (do_shift) 
     199  if (do_shift) { 
    188200    offset_array(pixcrd, -1.0); 
    189  
    190  _exit: 
     201  } 
     202 
     203 exit: 
    191204  Py_XDECREF(pixcrd); 
    192205 
    193206  if (status == 0 || status == 8) { 
    194207    return (PyObject*)world; 
    195   } else if (status > 0 && status < WCS_ERRMSG_MAX) { 
    196     PyErr_SetString(*wcs_errexc[status], wcsp2s_errmsg[status]); 
    197     return NULL; 
    198   } else if (status == -1) { 
    199     return NULL; 
    200208  } else { 
    201     PyErr_SetString(PyExc_RuntimeError, 
    202                     "Unknown error occurred.  Something is seriously wrong."); 
    203     return NULL; 
     209    Py_DECREF(world); 
     210    if (status > 0 && status < WCS_ERRMSG_MAX) { 
     211      PyErr_SetString(*wcs_errexc[status], wcsp2s_errmsg[status]); 
     212      return NULL; 
     213    } else if (status == -1) { 
     214      return NULL; 
     215    } else { 
     216      PyErr_SetString(PyExc_RuntimeError, 
     217                      "Unknown error occurred.  Something is seriously wrong."); 
     218      return NULL; 
     219    } 
    204220  } 
    205221} 
     
    233249  if (PyArray_DIM(pixcrd, 1) != NAXES) { 
    234250    PyErr_SetString(PyExc_ValueError, "Pixel array must be an Nx2 array"); 
    235     goto _exit; 
     251    goto exit; 
    236252  } 
    237253 
    238254  foccrd = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(pixcrd), PyArray_DOUBLE); 
    239255  if (foccrd == NULL) { 
    240     goto _exit; 
     256    status = 2; 
     257    goto exit; 
    241258  } 
    242259 
     
    248265                      PyArray_DATA(pixcrd), PyArray_DATA(foccrd)); 
    249266 
    250   if (status) { 
    251     Py_XDECREF(foccrd); 
    252     goto _exit; 
    253   } 
    254  
    255267  if (do_shift) { 
    256268    offset_array(pixcrd, -1.0); 
    257269  } 
    258270 
    259  _exit: 
     271 exit: 
    260272 
    261273  Py_XDECREF(pixcrd); 
    262274 
    263   if (status == 0 || status == 8) { 
     275  if (status == 0) { 
    264276    return (PyObject*)foccrd; 
    265   } else if (status > 0 && status < WCS_ERRMSG_MAX) { 
    266     PyErr_SetString(*wcs_errexc[status], wcsp2s_errmsg[status]); 
    267     return NULL; 
    268   } else if (status == -1) { 
    269     return NULL; 
    270277  } else { 
    271     PyErr_SetString(PyExc_RuntimeError, 
    272                     "Unknown error occurred.  Something is seriously wrong."); 
    273     return NULL; 
     278    Py_XDECREF(foccrd); 
     279    if (status > 0 && status < WCS_ERRMSG_MAX) { 
     280      PyErr_SetString(*wcs_errexc[status], wcsp2s_errmsg[status]); 
     281      return NULL; 
     282    } else if (status == -1) { 
     283      return NULL; 
     284    } else { 
     285      PyErr_SetString(PyExc_RuntimeError, 
     286                      "Unknown error occurred.  Something is seriously wrong."); 
     287      return NULL; 
     288    } 
    274289  } 
    275290} 
     
    282297static PyObject* 
    283298PyWcs_p4_pix2foc_fits(PyWcs* self, PyObject* arg, PyObject* kwds) { 
    284   return PyWcs_p4_pix2foc_generic(self, arg, 1); 
     299  return PyWcs_p4_pix2foc_generic(self, arg, 0); 
    285300} 
    286301 
     
    316331                            (double*)PyArray_DATA(foccrd)); 
    317332 
    318   if (status) { 
    319     Py_DECREF(foccrd); 
    320     goto _exit; 
    321   } 
    322  
    323333  if (do_shift) { 
    324334    offset_array(pixcrd, -1.0); 
     
    329339  Py_XDECREF(pixcrd); 
    330340 
    331   if (status == 0 || status == 8) { 
     341  if (status == 0) { 
    332342    return (PyObject*)foccrd; 
    333   } else if (status > 0 && status < WCS_ERRMSG_MAX) { 
    334     PyErr_SetString(*wcs_errexc[status], wcsp2s_errmsg[status]); 
    335     return NULL; 
    336   } else if (status == -1) { 
    337     return NULL; 
    338343  } else { 
    339     PyErr_SetString(PyExc_RuntimeError, 
    340                     "Unknown error occurred.  Something is seriously wrong."); 
    341     return NULL; 
     344    Py_XDECREF(foccrd); 
     345    if (status > 0 && status < WCS_ERRMSG_MAX) { 
     346      PyErr_SetString(*wcs_errexc[status], wcsp2s_errmsg[status]); 
     347      return NULL; 
     348    } else if (status == -1) { 
     349      return NULL; 
     350    } else { 
     351      PyErr_SetString(PyExc_RuntimeError, 
     352                      "Unknown error occurred.  Something is seriously wrong."); 
     353      return NULL; 
     354    } 
    342355  } 
    343356} 
     
    350363static PyObject* 
    351364PyWcs_pix2foc_fits(PyWcs* self, PyObject* arg, PyObject* kwds) { 
    352   return PyWcs_pix2foc_generic(self, arg, 1); 
     365  return PyWcs_pix2foc_generic(self, arg, 0); 
    353366} 
    354367 
  • trunk/pywcs/src/sip.c

    r643 r660  
    4141#include <string.h> 
    4242 
    43 void sip_clear(sip_t* sip) { 
     43void 
     44sip_clear(sip_t* sip) { 
    4445  assert(sip); 
    4546 
     
    5253  sip->bp_order = 0; 
    5354  sip->bp = NULL; 
     55  sip->crpix[0] = 0.0; 
     56  sip->crpix[1] = 0.0; 
     57  sip->scratch = NULL; 
    5458} 
    5559 
     
    6266    const unsigned int bp_order, const double* bp, 
    6367    const double crpix[2]) { 
    64   int status = 0; 
    65   size_t a_size = 0; 
    66   size_t b_size = 0; 
    67   size_t ap_size = 0; 
    68   size_t bp_size = 0; 
    69   unsigned int scratch_sizes[4]; 
    70   size_t i; 
     68  unsigned int a_size       = 0; 
     69  unsigned int b_size       = 0; 
     70  unsigned int ap_size      = 0; 
     71  unsigned int bp_size      = 0; 
    7172  unsigned int scratch_size = 0; 
     73  int          status       = 0; 
    7274 
    7375  assert(sip); 
    74   assert(sip->a == NULL); 
    75   assert(sip->b == NULL); 
    76   assert(sip->ap == NULL); 
    77   assert(sip->bp == NULL); 
    78  
    79   if (!((a == NULL) ^ (b == NULL)) || 
    80       !((ap == NULL) ^ (bp == NULL))) { 
     76  sip_clear(sip); 
     77 
     78  /* We we have one of A/B or AP/BP, we must have both. */ 
     79  if (((a == NULL) ^ (b == NULL)) || 
     80      ((ap == NULL) ^ (bp == NULL))) { 
    8181    return 6; 
    8282  } 
     
    8888    if (sip->a == NULL) { 
    8989      status = 2; 
    90       goto sip_init_exit; 
     90      goto exit; 
    9191    } 
    9292    memcpy(sip->a, a, a_size); 
     93    if (a_order > scratch_size) { 
     94      scratch_size = a_order; 
     95    } 
    9396 
    9497    sip->b_order = b_order; 
     
    97100    if (sip->b == NULL) { 
    98101      status = 2; 
    99       goto sip_init_exit; 
     102      goto exit; 
    100103    } 
    101104    memcpy(sip->b, b, b_size); 
     105    if (b_order > scratch_size) { 
     106      scratch_size = b_order; 
     107    } 
    102108  } 
    103109 
     
    108114    if (sip->ap == NULL) { 
    109115      status = 2; 
    110       goto sip_init_exit; 
     116      goto exit; 
    111117    } 
    112118    memcpy(sip->ap, ap, ap_size); 
     119    if (ap_order > scratch_size) { 
     120      scratch_size = ap_order; 
     121    } 
    113122 
    114123    sip->bp_order = bp_order; 
     
    117126    if (sip->bp == NULL) { 
    118127      status = 2; 
    119       goto sip_init_exit; 
     128      goto exit; 
    120129    } 
    121130    memcpy(sip->bp, bp, bp_size); 
     131    if (bp_order > scratch_size) { 
     132      scratch_size = bp_order; 
     133    } 
     134  } 
     135 
     136  if (scratch_size > 0) { 
     137    scratch_size = (scratch_size + 1) * sizeof(double); 
     138    sip->scratch = malloc(scratch_size); 
     139    if (sip->scratch == NULL) { 
     140      status = 2; 
     141      goto exit; 
     142    } 
    122143  } 
    123144 
     
    125146  sip->crpix[1] = crpix[1]; 
    126147 
    127   /* Find the maximum order to create for our scratch memory space */ 
    128   scratch_sizes[0] = a_order + 1; 
    129   scratch_sizes[1] = b_order + 1; 
    130   scratch_sizes[2] = ap_order + 1; 
    131   scratch_sizes[3] = bp_order + 1; 
    132   for (i = 0; i < 4; ++i) { 
    133     if (scratch_size > scratch_sizes[i]) { 
    134       scratch_size = scratch_sizes[i]; 
    135     } 
    136   } 
    137  
    138   sip->scratch = malloc(scratch_size * sizeof(double)); 
    139   if (sip->scratch == NULL) { 
    140     status = 2; 
    141     goto sip_init_exit; 
    142   } 
    143  
    144  sip_init_exit: 
     148 exit: 
    145149  if (status != 0) { 
    146150    sip_free(sip); 
     
    168172    const unsigned int order, 
    169173    const double* matrix, 
    170     const unsigned int x, 
    171     const unsigned int y) { 
    172   assert(x <= order); 
    173   assert(y <= order); 
    174  
    175   return matrix[y * (order + 1) + x]; 
     174    const int x, 
     175    const int y) { 
     176  int index; 
     177  assert(x >= 0 && x <= order); 
     178  assert(y >= 0 && y <= order); 
     179  index = x * (order + 1) + y; 
     180  assert(index >= 0 && index < (order + 1) * (order + 1)); 
     181 
     182  return matrix[index]; 
    176183} 
    177184 
     
    180187    const unsigned int naxes, 
    181188    const unsigned int nelem, 
    182     const unsigned int a_order
     189    const unsigned int m
    183190    const double* a, 
    184     const unsigned int b_order
     191    const unsigned int n
    185192    const double* b, 
    186193    const double crpix[2], 
     
    188195    const double* input /* [NAXES][nelem] */, 
    189196    double* output /* [NAXES][nelem] */) { 
    190   size_t i, j, k; 
     197  int i, j, k; 
    191198  double x, y, tmp_x, tmp_y; 
    192199  double sum; 
     
    199206  assert(output); 
    200207 
    201   if (a == NULL || b == NULL) { 
     208  /* Avoid segfaults */ 
     209  if (input == NULL || output == NULL || tmp == NULL || crpix == NULL) { 
     210    return 1; 
     211  } 
     212 
     213  /* If we have one, we must have both... */ 
     214  if ((a == NULL) ^ (b == NULL)) { 
    202215    return 6; 
    203216  } 
    204217 
    205   if (input == NULL || output == NULL) { 
    206     return 1; 
     218  /* If no distortion, just copy values */ 
     219  if (a == NULL /* && b == NULL ... implied */) { 
     220    for (i = 0; i < nelem; ++i) { 
     221      output[i << 1] = input[i << 1]; 
     222      output[(i << 1) + 1] = input[(i << 1) + 1]; 
     223    } 
     224    return 0; 
    207225  } 
    208226 
    209227  for (i = 0; i < nelem; ++i) { 
    210     x = input[i << 1] + 1.0
    211     y = input[(i << 1) + 1] + 1.0
    212  
    213     tmp_x = crpix[0] - x
    214     tmp_y = crpix[1] - y
    215  
    216     for (j = 0; j <= a_order; ++j) { 
    217       tmp[j] = lu(a_order, a, a_order - j, j); 
    218       for (k = j - 1; k >= 0; --k) { 
    219         tmp[j] = tmp_y * tmp[j] + lu(a_order, a, a_order - j, k); 
     228    x = input[i << 1]
     229    y = input[(i << 1) + 1]
     230 
     231    tmp_x = x - crpix[0]
     232    tmp_y = y - crpix[1]
     233 
     234    for (j = 0; j <= m; ++j) { 
     235      tmp[j] = lu(m, a, m-j, j); 
     236      for (k = j-1; k >= 0; --k) { 
     237        tmp[j] = (tmp_y * tmp[j]) + lu(m, a, m-j, k); 
    220238      } 
    221239    } 
    222240 
     241    /* Don't know why this loop is convoluted */ 
    223242    sum = tmp[0]; 
    224     for (i = a_order; i > 0; --i) { 
    225       sum = tmp_x * sum + tmp[a_order - i + 1]; 
     243    for (j = m; j > 0; --j) { 
     244      sum = tmp_x * sum + tmp[m - j + 1]; 
    226245    } 
    227246    output[i << 1] = sum + x; 
    228247 
    229     for (j = 0; j <= b_order; ++j) { 
    230       tmp[j] = lu(b_order, b, b_order - j, j); 
    231       for (k = j - 1; k >= 0; --k) { 
    232         tmp[j] = tmp_y * tmp[j] + lu(b_order, b, b_order - j, k); 
     248    for (j = 0; j <= n; ++j) { 
     249      tmp[j] = lu(n, b, n-j, j); 
     250      for (k = j-1; k >= 0; --k) { 
     251        tmp[j] = tmp_y * tmp[j] + lu(n, b, n-j, k); 
    233252      } 
    234253    } 
    235254 
     255    /* Don't know why this loop is convoluted */ 
    236256    sum = tmp[0]; 
    237     for (i = b_order; i > 0; --i) { 
    238       sum = tmp_x * sum + tmp[b_order - i + 1]; 
     257    for (j = n; j > 0; --j) { 
     258      sum = tmp_x * sum + tmp[n - j + 1]; 
    239259    } 
    240260    output[(i << 1) + 1] = sum + y; 
     
    259279                     sip->b_order, sip->b, 
    260280                     sip->crpix, 
    261                      sip->scratch, 
     281                     (double *)sip->scratch, 
    262282                     pix, foc); 
    263283} 
     
    278298                     sip->bp_order, sip->bp, 
    279299                     sip->crpix, 
    280                      sip->scratch, 
     300                     (double *)sip->scratch, 
    281301                     foc, pix); 
    282302} 
  • trunk/pywcs/src/sip.h

    r643 r660  
    4040typedef struct { 
    4141  unsigned int a_order; 
    42   double* a; /* [a_order+1][a_order+1] */ 
     42  double* a; 
    4343  unsigned int b_order; 
    44   double* b; /* [b_order+1][b_order+1] */ 
     44  double* b; 
    4545  unsigned int ap_order; 
    46   double* ap; /* [ap_order+1][ap_order+1] */ 
     46  double* ap; 
    4747  unsigned int bp_order; 
    48   double* bp; /* [bp_order+1][bp_order+1] */ 
     48  double* bp; 
    4949  double crpix[2]; 
    5050  double* scratch; 
  • trunk/pywcs/src/sip_wrap.c

    r652 r660  
    3737#include "sip_wrap.h" 
    3838#include "docstrings.h" 
     39#include "wcs.h" 
    3940 
    4041static void 
     
    5657 
    5758static int 
    58 convert_matrix(PyObject* pyobj, PyArrayObject** array) { 
    59   *array = (PyArrayObject*)PyArray_ContiguousFromAny(pyobj, PyArray_DOUBLE, 2, 2); 
     59convert_matrix( 
     60    PyObject* pyobj, 
     61    PyArrayObject** array, 
     62    double** data, 
     63    size_t* order) { 
     64  if (pyobj == Py_None) { 
     65    *array = NULL; 
     66    *data = NULL; 
     67    *order = 0; 
     68    return 0; 
     69  } 
     70 
     71  *array = (PyArrayObject*)PyArray_ContiguousFromAny( 
     72      pyobj, PyArray_DOUBLE, 2, 2); 
    6073  if (*array == NULL) 
    6174    return -1; 
     
    6679    return -1; 
    6780  } 
     81 
     82  *data = (double*)PyArray_DATA(*array); 
     83  *order = PyArray_DIM(*array, 0) - 1; 
    6884 
    6985  return 0; 
     
    8298  PyArrayObject* bp       = NULL; 
    8399  PyArrayObject* crpix    = NULL; 
    84   int            result   = 0; 
     100  double*        a_data   = NULL; 
     101  double*        b_data   = NULL; 
     102  double*        ap_data  = NULL; 
     103  double*        bp_data  = NULL; 
     104  size_t         a_order  = 0; 
     105  size_t         b_order  = 0; 
     106  size_t         ap_order = 0; 
     107  size_t         bp_order = 0; 
     108  int            status   = -1; 
    85109 
    86110  if (!PyArg_ParseTuple(args, "OOOOO:Sip.__init__", 
     
    89113  } 
    90114 
    91   if (convert_matrix(py_a, &a) || 
    92       convert_matrix(py_b, &b) || 
    93       convert_matrix(py_ap, &ap) || 
    94       convert_matrix(py_bp, &bp)) { 
    95     result = -1; 
    96     goto PySip_init_exit; 
     115  if (convert_matrix(py_a, &a, &a_data, &a_order) || 
     116      convert_matrix(py_b, &b, &b_data, &b_order) || 
     117      convert_matrix(py_ap, &ap, &ap_data, &ap_order) || 
     118      convert_matrix(py_bp, &bp, &bp_data, &bp_order)) { 
     119    goto exit; 
    97120  } 
    98121 
     
    100123                                                    1, 1); 
    101124  if (crpix == NULL) { 
    102     result = -1; 
    103     goto PySip_init_exit; 
     125    goto exit; 
    104126  } 
    105127 
    106128  if (PyArray_DIM(crpix, 0) != 2) { 
    107     PyErr_SetString(PyExc_ValueError, 
    108                     "CRPIX wrong length"); 
    109     result = -1; 
    110     goto PySip_init_exit; 
    111   } 
    112  
    113   if (sip_init(&self->x, 
    114                PyArray_DIM(a, 0) - 1, PyArray_DATA(a), 
    115                PyArray_DIM(b, 0) - 1, PyArray_DATA(b), 
    116                PyArray_DIM(ap, 0) - 1, PyArray_DATA(ap), 
    117                PyArray_DIM(bp, 0) - 1, PyArray_DATA(bp), 
    118                PyArray_DATA(crpix))) { 
    119     result = -1; 
    120     goto PySip_init_exit; 
    121   } 
    122  
    123  PySip_init_exit: 
     129    PyErr_SetString(PyExc_ValueError, "CRPIX wrong length"); 
     130    goto exit; 
     131  } 
     132 
     133  status = sip_init(&self->x, 
     134                    a_order, a_data, 
     135                    b_order, b_data, 
     136                    ap_order, ap_data, 
     137                    bp_order, bp_data, 
     138                    PyArray_DATA(crpix)); 
     139 
     140 exit: 
    124141  Py_XDECREF(a); 
    125142  Py_XDECREF(b); 
     
    128145  Py_XDECREF(crpix); 
    129146 
    130   return result; 
     147  if (status == 0) { 
     148    return 0; 
     149  } else if (status > 0 && status < WCS_ERRMSG_MAX) { 
     150    PyErr_SetString(*wcs_errexc[status], wcsp2s_errmsg[status]); 
     151    return -1; 
     152  } else if (status == -1) { 
     153    return -1; 
     154  } else { 
     155    PyErr_SetString(PyExc_RuntimeError, 
     156                    "Unknown error occurred.  Something is seriously wrong."); 
     157    return -1; 
     158  } 
    131159} 
    132160 
     
    135163  PyArrayObject* pixcrd = NULL; 
    136164  PyArrayObject* foccrd = NULL; 
    137   PyObject* result = NULL; 
     165  int            status = -1; 
     166 
     167  if (self->x.a == NULL || self->x.b == NULL) { 
     168    PyErr_SetString( 
     169        PyExc_ValueError, 
     170        "SIP object does not have coefficients for pix2foc transformation (A and B)"); 
     171    return NULL; 
     172  } 
    138173 
    139174  pixcrd = (PyArrayObject*)PyArray_ContiguousFromAny(arg, PyArray_DOUBLE, 2, 2); 
    140175  if (pixcrd == NULL) { 
    141     goto _exit; 
     176    goto exit; 
    142177  } 
    143178 
    144179  if (PyArray_DIM(pixcrd, 1) != 2) { 
    145180    PyErr_SetString(PyExc_ValueError, "Pixel array must be an Nx2 array"); 
    146     goto _exit; 
     181    goto exit; 
    147182  } 
    148183 
     
    150185                                             PyArray_DOUBLE); 
    151186  if (foccrd == NULL) { 
    152     goto _exit; 
    153   } 
    154  
    155   if (do_shift) 
     187    status = 2; 
     188    goto exit; 
     189  } 
     190 
     191  if (do_shift) { 
    156192    offset_array(pixcrd, 1.0); 
    157  
    158   if (sip_pix2foc(&self->x, 
    159                   PyArray_DIM(pixcrd, 0), 
    160                   PyArray_DIM(pixcrd, 1), 
    161                   (double*)PyArray_DATA(pixcrd), 
    162                   (double*)PyArray_DATA(foccrd))) { 
    163     PyErr_SetString(PyExc_RuntimeError, "Error correcting distortion"); 
     193  } 
     194