UVES Pipeline Reference Manual  5.4.6
uves_extract_profile.c
1 /* *
2  * This file is part of the ESO UVES Pipeline *
3  * Copyright (C) 2004,2005 European Southern Observatory *
4  * *
5  * This library is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the Free Software *
17  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA *
18  * */
19 
20 /*
21  * $Author: amodigli $
22  * $Date: 2010-09-24 09:32:03 $
23  * $Revision: 1.6 $
24  * $Name: not supported by cvs2svn $
25  * $Log: not supported by cvs2svn $
26  * Revision 1.4 2010/02/13 12:22:31 amodigli
27  * removed inlines (let's do work to compiler)
28  *
29  * Revision 1.3 2007/08/30 07:56:54 amodigli
30  * fixed some doxygen warnings
31  *
32  * Revision 1.2 2007/06/06 08:17:33 amodigli
33  * replace tab with 4 spaces
34  *
35  * Revision 1.1 2007/05/02 13:43:46 jmlarsen
36  * Added source
37  *
38  * Revision 1.141 2007/04/26 06:55:35 amodigli
39  * fixed mem leak adding uves_free_image(&spectrum_order)
40  *
41  * Revision 1.140 2007/04/24 12:50:29 jmlarsen
42  * Replaced cpl_propertylist -> uves_propertylist which is much faster
43  *
44  * Revision 1.139 2007/04/24 09:40:37 jmlarsen
45  * Removed deprecated irplib_string_concatenate_all
46  *
47  * Revision 1.138 2007/04/20 14:44:20 jmlarsen
48  * Implemented QC parameter to measure small scale ripples
49  *
50  * Revision 1.137 2007/04/12 12:00:35 jmlarsen
51  * Added testing code
52  *
53  * Revision 1.136 2007/04/10 11:34:14 jmlarsen
54  * Removed debug message
55  *
56  * Revision 1.135 2007/04/10 08:05:49 jmlarsen
57  * Disabled optimization (reduced kappa-sigma iterations, caught by unit test)
58  *
59  * Revision 1.134 2007/04/10 07:23:20 jmlarsen
60  * Added commented out code to spline interpolate virtually resampled profile
61  *
62  * Revision 1.133 2007/03/28 11:38:38 jmlarsen
63  * Removed dead code
64  *
65  * Revision 1.132 2007/03/19 15:12:14 jmlarsen
66  * Optimization: use doubles rather than zero deg. poly.
67  *
68  * Revision 1.131 2007/03/19 13:50:18 jmlarsen
69  * Fixed serious bug happening when object is at +-15 pixels
70  *
71  * Revision 1.130 2007/03/15 12:33:37 jmlarsen
72  * Minor message change
73  *
74  * Revision 1.129 2007/03/13 15:33:30 jmlarsen
75  * Use autodegree polynomials for virtual profile, not zero degree
76  *
77  * Revision 1.128 2007/03/05 10:16:37 jmlarsen
78  * Support slope parameter in 1d fitting
79  *
80  * Revision 1.127 2007/02/26 13:29:40 jmlarsen
81  * Don't use Gauss-Legendre 3 point interpolation, for efficiency
82  *
83  * Revision 1.126 2007/02/26 11:55:47 jmlarsen
84  * Renamed and generalized function uves_raise_to_median() -> uves_raise_to_median_frac()
85  *
86  * Revision 1.125 2007/02/22 15:33:56 jmlarsen
87  * Optimization: use double's rather than constant 2d polynomials
88  *
89  * Revision 1.124 2007/02/09 13:37:06 jmlarsen
90  * Added bug in 2d extraction mode
91  *
92  * Revision 1.123 2007/02/09 08:14:16 jmlarsen
93  * Do not use CPL_PIXEL_MAXVAL which works only for integer images
94  *
95  * Revision 1.122 2007/02/08 07:33:56 jmlarsen
96  * Added doc
97  *
98  * Revision 1.121 2007/01/31 13:10:33 jmlarsen
99  * Changed message
100  *
101  * Revision 1.120 2007/01/29 12:09:42 jmlarsen
102  * Compute QC parameters (pos, fwhm, s/n) also for simple extraction
103  *
104  * Revision 1.119 2007/01/26 13:49:43 jmlarsen
105  * Fixed sky subtraction residuals for optimal sky subtraction
106  *
107  * Revision 1.118 2007/01/15 08:46:01 jmlarsen
108  * Made more robust against extended objects
109  *
110  * Revision 1.117 2007/01/05 07:22:07 jmlarsen
111  * Eliminated compiler warnings
112  *
113  * Revision 1.116 2007/01/04 13:55:21 jmlarsen
114  * Implemented order-by-order object tracing (disabled)
115  *
116  * Revision 1.115 2006/12/08 07:41:43 jmlarsen
117  * Minor doc. change
118  *
119  * Revision 1.114 2006/11/16 09:48:30 jmlarsen
120  * Renamed data type position -> uves_iterate_position, for namespace reasons
121  *
122  * Revision 1.113 2006/11/15 15:02:14 jmlarsen
123  * Implemented const safe workarounds for CPL functions
124  *
125  * Revision 1.111 2006/11/15 14:04:08 jmlarsen
126  * Removed non-const version of parameterlist_get_first/last/next which is already
127  * in CPL, added const-safe wrapper, unwrapper and deallocator functions
128  *
129  * Revision 1.110 2006/11/08 14:04:34 jmlarsen
130  * Implemented flag to select sky subtraction method
131  *
132  * Revision 1.109 2006/11/06 15:19:41 jmlarsen
133  * Removed unused include directives
134  *
135  * Revision 1.108 2006/10/31 09:14:58 jmlarsen
136  * Man page doc fix
137  *
138  * Revision 1.107 2006/10/02 08:34:40 jmlarsen
139  * Do not recompute variance in last iteration
140  *
141  * Revision 1.106 2006/09/27 15:08:45 jmlarsen
142  * Fixed doc. bug
143  *
144  * Revision 1.105 2006/09/27 13:08:49 jmlarsen
145  * Use dynamic memory allocation to store bad pixels
146  *
147  * Revision 1.104 2006/09/20 12:53:57 jmlarsen
148  * Replaced stringcat functions with uves_sprintf()
149  *
150  * Revision 1.103 2006/09/20 07:25:30 jmlarsen
151  * Doc. bug fix
152  *
153  * Revision 1.102 2006/09/19 14:29:05 jmlarsen
154  * Measure object position QC parameter from bottom of slit
155  *
156  * Revision 1.101 2006/09/19 07:15:35 jmlarsen
157  * Added chip to argument list of uves_extract()
158  *
159  * Revision 1.100 2006/09/11 14:19:28 jmlarsen
160  * Updated documentation
161  *
162  * Revision 1.99 2006/09/11 13:57:46 jmlarsen
163  * Remove usage of cpl_image_set after getting bpm pointer
164  *
165  * Revision 1.98 2006/09/08 14:02:34 jmlarsen
166  * Simplified code by using iterators, sky subtraction much optimized
167  *
168  * Revision 1.97 2006/09/06 15:35:51 jmlarsen
169  * Changed indentations
170  *
171  * Revision 1.96 2006/09/06 14:50:23 jmlarsen
172  * Worked on code to globally measure spatial profile
173  *
174  * Revision 1.95 2006/09/01 13:56:46 jmlarsen
175  * Added commented out code (alternative way of measuring spatial profile)
176  *
177  * Revision 1.94 2006/08/23 15:08:56 jmlarsen
178  * Improved plot of spatial profile
179  *
180  * Revision 1.93 2006/08/23 09:33:03 jmlarsen
181  * Renamed local variables shadowing POSIX reserved names
182  *
183  * Revision 1.92 2006/08/22 15:35:48 jmlarsen
184  * Auto-select profile method based on S/N estimate
185  *
186  * Revision 1.91 2006/08/22 14:20:56 jmlarsen
187  * Implemented simultaneous optimal extraction of obj+sky
188  *
189  * Revision 1.90 2006/08/17 14:40:06 jmlarsen
190  * Added missing documentation
191  *
192  * Revision 1.89 2006/08/17 14:11:25 jmlarsen
193  * Use assure_mem macro to check for memory allocation failure
194  *
195  * Revision 1.88 2006/08/17 13:59:11 jmlarsen
196  * Removed CPL2 const bug workaround
197  *
198  * Revision 1.87 2006/08/17 13:56:52 jmlarsen
199  * Reduced max line length
200  *
201  * Revision 1.86 2006/08/17 09:17:42 jmlarsen
202  * Removed CPL2 code
203  *
204  * Revision 1.85 2006/08/14 12:16:31 jmlarsen
205  * Moved defines to top of file
206  *
207  * Revision 1.84 2006/08/11 14:56:05 amodigli
208  * removed Doxygen warnings
209  *
210  * Revision 1.83 2006/08/11 09:20:06 jmlarsen
211  * Implemented workaround for slow cpl_image_set
212  *
213  * Revision 1.82 2006/08/10 10:49:28 jmlarsen
214  * Removed workaround for cpl_image_get_bpm
215  *
216  * Revision 1.81 2006/08/08 11:02:43 jmlarsen
217  * Make temporary copy of image bad pixel map
218  *
219  * Revision 1.80 2006/08/08 08:19:17 amodigli
220  * update to CPL3
221  *
222  * Revision 1.79 2006/08/07 11:35:35 jmlarsen
223  * Disabled parameter environment variable mode
224  *
225  * Revision 1.78 2006/07/14 12:21:36 jmlarsen
226  * Take bad pixels into account in sky subtraction
227  *
228  * Revision 1.77 2006/07/03 13:01:22 jmlarsen
229  * Use analytical-fit sky subtraction method to improve S/N, use a
230  * global model of chi square
231  *
232  * Revision 1.76 2006/06/16 08:23:04 jmlarsen
233  * Added comment
234  *
235  * Revision 1.75 2006/06/05 08:51:55 amodigli
236  * cleaned some warnings from static checks
237  *
238  * Revision 1.74 2006/06/02 06:41:59 jmlarsen
239  * Added missing error code
240  *
241  * Revision 1.73 2006/06/01 14:43:17 jmlarsen
242  * Added missing documentation
243  *
244  * Revision 1.72 2006/05/16 12:13:07 amodigli
245  * added QC log
246  *
247  * Revision 1.71 2006/05/15 08:15:52 jmlarsen
248  * Changed default kappa to 10.0
249  *
250  * Revision 1.70 2006/05/15 07:21:50 jmlarsen
251  * Changed default kappa 3.5 -> 5.0
252  *
253  * Revision 1.69 2006/05/12 15:04:09 jmlarsen
254  * Changed gauss/moffat/virtual profile measuring methods to use
255  * global polynomials (rather than one polynomial per order)
256  *
257  * Revision 1.68 2006/04/24 09:21:18 jmlarsen
258  * Implemented virtual resampling algorithm
259  *
260  * Revision 1.67 2006/04/10 12:36:35 jmlarsen
261  * Fixed bug that caused extraction to halt if an order is completely
262  * outside an image
263  *
264  * Revision 1.66 2006/04/07 12:29:21 jmlarsen
265  * Bugfix: in opt_evaluate_profile
266  *
267  * Revision 1.65 2006/04/07 07:10:12 jmlarsen
268  * Use Gauss-Legendre rather than Simpson for profile integration
269  *
270  * Revision 1.64 2006/04/06 11:49:24 jmlarsen
271  * Minor msg change
272  *
273  * Revision 1.63 2006/04/06 08:36:40 jmlarsen
274  * Re-factored optimal extraction, added loop to measure
275  * profile until high statistics is achieved
276  *
277  * Revision 1.62 2006/03/24 14:46:39 jmlarsen
278  * Doc. bugfix
279  *
280  * Revision 1.61 2006/03/24 14:17:37 jmlarsen
281  * Mirror input image before/after extraction
282  *
283  * Revision 1.60 2006/03/03 13:54:11 jmlarsen
284  * Changed syntax of check macro
285  *
286  * Revision 1.59 2006/02/28 09:15:22 jmlarsen
287  * Minor update
288  *
289  * Revision 1.58 2006/02/15 13:19:15 jmlarsen
290  * Reduced source code max. line length
291  *
292  * Revision 1.57 2006/01/25 16:13:20 jmlarsen
293  * Changed interface of gauss.fitting routine
294  *
295  * Revision 1.56 2006/01/12 15:41:14 jmlarsen
296  * Moved gauss. fitting to irplib
297  *
298  * Revision 1.55 2005/12/20 16:10:32 jmlarsen
299  * Added some documentation
300  *
301  * Revision 1.54 2005/12/19 16:17:56 jmlarsen
302  * Replaced bool -> int
303  *
304  */
305 
306 #ifdef HAVE_CONFIG_H
307 # include <config.h>
308 #endif
309 
310 /*----------------------------------------------------------------------------*/
317 /*----------------------------------------------------------------------------*/
318 
319 /*-----------------------------------------------------------------------------
320  Includes
321  -----------------------------------------------------------------------------*/
322 
323 #include <uves_extract_profile.h>
324 
325 #include <uves_extract_iterate.h>
326 #include <uves_error.h>
327 
328 /*-----------------------------------------------------------------------------
329  Implementation
330  -----------------------------------------------------------------------------*/
331 
332 uves_extract_profile *
333 uves_extract_profile_new_constant(double slit_length)
334 {
335  uves_extract_profile *p = NULL; /* Result */
336 
337  p = cpl_malloc(sizeof(uves_extract_profile));
338 
339  p->constant = true;
340  p->slit_length = slit_length;
341 
342  /* remaining members not used */
343 
344  return p;
345 }
346 
347 /*----------------------------------------------------------------------------*/
366 /*----------------------------------------------------------------------------*/
367 uves_extract_profile *
368 uves_extract_profile_new(int (*f) (const double x[], const double a[], double *result),
369  int (*dfda)(const double x[], const double a[], double result[]),
370  int M,
371  double slit_length,
372  int sampling_factor)
373 {
374  uves_extract_profile *p = NULL; /* Result */
375 
376  p = cpl_malloc(sizeof(uves_extract_profile));
377 
378  p->constant = false;
379  p->f = f;
380 
381  if (f != NULL)
382  {
383  /* Zero resampling */
384  p->dfda = dfda;
385  p->M = M;
386 #if ORDER_PER_ORDER
387  p->y0 = cpl_calloc(sizeof(polynomial *), 100); /* 1 poly. per order */
388  p->sigma = cpl_calloc(sizeof(polynomial *), 100);
389  p->red_chisq = cpl_calloc(sizeof(polynomial *), 100);
390 #else
391  p->y0 = NULL;
392  p->sigma = NULL;
393  p->red_chisq = NULL;
394 #endif
395  /* Not used */
396  p->spatial_bins = 0;
397  p->slit_length = 0;
398  p->sampling_factor = 0;
399  p->is_zero_degree = NULL;
400  p->dy_poly = NULL;
401  p->dy_double = NULL;
402  p->current_profile = NULL;
403  p->current_ypos = NULL;
404  p->current_interpolated = NULL;
405  }
406  else
407  {
408  /* Virtual resampling */
409  p->spatial_bins = uves_extract_profile_get_nbins(slit_length, sampling_factor);
410  p->slit_length = slit_length;
411  p->sampling_factor = sampling_factor;
412  p->spatial_bins = uves_extract_profile_get_nbins(slit_length, sampling_factor);
413  p->is_zero_degree = cpl_calloc(p->spatial_bins, sizeof(bool));
414  p->dy_poly = cpl_calloc(p->spatial_bins, sizeof(polynomial *));
415  p->dy_double = cpl_calloc(p->spatial_bins, sizeof(double));
416  p->current_profile = cpl_calloc(p->spatial_bins, sizeof(double));
417  p->current_ypos = cpl_calloc(p->spatial_bins, sizeof(double));
418  p->current_interpolated = cpl_calloc(slit_length + 3, sizeof(double));
419 
420  /* Not used */
421  p->dfda = NULL;
422  p->M = 0;
423  p->y0 = NULL;
424  p->sigma = NULL;
425  }
426 
427  return p;
428 }
429 
430 
431 /*----------------------------------------------------------------------------*/
438 /*----------------------------------------------------------------------------*/
439 
440 void
441 uves_extract_profile_delete(uves_extract_profile **p)
442 {
443  if (*p == NULL) return;
444 
445  if ((*p)->constant)
446  {
447  /* nothing to clean */
448  }
449  else if((*p)->f != NULL)
450  {
451 #if ORDER_PER_ORDER
452 /* Then leak some memory */
453 #else
454  uves_polynomial_delete(&((*p)->y0));
455  uves_polynomial_delete(&((*p)->sigma));
456  uves_polynomial_delete(&((*p)->red_chisq));
457 #endif
458  }
459  else
460  {
461  /* Virtual resampling */
462  int i;
463  for (i = 0; i < (*p)->spatial_bins; i++)
464  {
465  uves_polynomial_delete(& ((*p)->dy_poly[i]) );
466  }
467  cpl_free((*p)->is_zero_degree);
468  cpl_free((*p)->dy_poly);
469  cpl_free((*p)->dy_double);
470  cpl_free((*p)->current_profile);
471  cpl_free((*p)->current_ypos);
472  cpl_free((*p)->current_interpolated);
473  }
474 
475  cpl_free(*p);
476  *p = NULL;
477 }
478 
479 /*----------------------------------------------------------------------------*/
486 /*----------------------------------------------------------------------------*/
487 int
488 uves_extract_profile_get_nbins(double slit_length, int sampling_factor)
489 {
490  return uves_round_double(slit_length + 3) * sampling_factor;
491 }
492 
493 /*----------------------------------------------------------------------------*/
504 /*----------------------------------------------------------------------------*/
505 double
506 uves_extract_profile_get_y(uves_iterate_position *pos,
507  double bin,
508  int sampling_factor)
509 {
510  return bin*1.0/sampling_factor + (pos->ycenter - pos->sg.length/2 - 1);
511 }
512 
513 /*----------------------------------------------------------------------------*/
524 /*----------------------------------------------------------------------------*/
525 double
526 uves_extract_profile_get_bin(const uves_iterate_position *pos,
527  int sampling_factor)
528 {
529  return sampling_factor*(pos->y - (pos->ycenter - pos->sg.length/2 - 1));
530 }
531 
532 /*----------------------------------------------------------------------------*/
550 /*----------------------------------------------------------------------------*/
551 void
552 uves_extract_profile_set(const uves_extract_profile *p,
553  uves_iterate_position *pos,
554  int *warnings)
555 {
556  if (p->constant) {
557  ((uves_extract_profile *)p)->current_area = pos->yhigh - pos->ylow + 1;
558  }
559  else if (p->f != NULL)
560  /* Zero */
561  {
562  double min_sigma = 0.1;
563 
564  /* const cast: The profile itself doesn't change */
565 #if ORDER_PER_ORDER
566  check( ((uves_extract_profile *)p)->current_y0 =
567  pos->ycenter + uves_polynomial_evaluate_1d(p->y0[pos->order-pos->minorder],
568  pos->x),
569  "Error evaluating polynomial");
570 #else
571  check( ((uves_extract_profile *)p)->current_y0 =
572  pos->ycenter + uves_polynomial_evaluate_2d(p->y0, pos->x, pos->order),
573  "Error evaluating polynomial");
574 #endif
575 
576 #if ORDER_PER_ORDER
577  check( ((uves_extract_profile *)p)->current_sigma =
578  uves_polynomial_evaluate_1d(p->sigma[pos->order-pos->minorder], pos->x),
579  "Error evaluating polynomial");
580 #else
581  check( ((uves_extract_profile *)p)->current_sigma =
582  uves_polynomial_evaluate_2d(p->sigma, pos->x, pos->order),
583  "Error evaluating polynomial");
584 #endif
585 
586  /* Make sure that the inferred
587  * sigma is always 0.1 pixel or more.
588  * Smaller values are unrealistic (undersampled profile) and cause
589  * numerical problems (~zero profile area), anyway.
590  */
591 
592  if (p->current_sigma < min_sigma)
593  {
594  /* Print only 1 warning per order */
595  if (warnings != NULL && *warnings == 0)
596  {
597  (*warnings)++;
598  uves_msg_warning("Inferred spatial profile width (one sigma) is only "
599  "%e pixels at (order, x) = (%d, %d). "
600  "Setting sigma = %.2f pixels",
601  p->current_sigma, pos->order, pos->x, min_sigma);
602  }
603 
604  ((uves_extract_profile *)p)->current_sigma = min_sigma;
605  }
606 
607  /* If the profile is well sampled, the 'area' calculated
608  below would be 1, but for undersampled profiles (sigma
609  much less than 1 pixel) the
610  result might differ substantially. Therefore, compute
611  the actual sum, and use the correction factor
612  later in uves_extract_profile_evaluate().
613 
614  The empirical area depends critically upon
615  the fractional part of y, so we must do it for every bin.
616  */
617  {
618  double area = 0;
619 
620  ((uves_extract_profile *)p)->current_area = 1;
621 
622  area = 0;
623  for (pos->y = pos->ylow; pos->y <= pos->yhigh; pos->y++)
624  {
625  /* For analytical profiles the results of
626  uves_extract_profile_evaluate()
627  may range from 1e-300 to ~1
628 
629  Such a large range (300 orders of magnitude) is a
630  source of problems in the weighted extraction of flat-fields,
631  where the resulting flux may end up being only ~1e-300,
632  which is "unphysical" and causes infinities after division.
633 
634  To always stay on the middle of the road, one might
635  decide to approximate small values of the profile to zero,
636  for example all values less than 1e-10
637 
638  And this would be the place to do it:
639  */
640  area += uves_extract_profile_evaluate(p, pos);
641  }
642 
643  /* This will not work: if (area > 0)
644  If area is very close to zero, we can still get inf.
645  when computing 1/current_area.
646 
647  Therefore set the limit to something much larger than machine
648  precision, and much less than 1.
649  */
650  if (area > 1e-10)
651  {
652  ((uves_extract_profile *)p)->current_area = area;
653  }
654  else
655  /* Well... the profile must be zero everywhere.
656  To avoid dividing by zero, set the area to something else */
657  {
658  ((uves_extract_profile *)p)->current_area = 1;
659  }
660  }
661  }
662  else
663  /* Virtual */
664  {
665  int i;
666  double sum = 0;
667 
668  for (i = 0; i < p->spatial_bins; i++)
669  {
670  double prof;
671  if (p->is_zero_degree[i])
672  {
673  prof = uves_max_double(0, p->dy_double[i]);
674  }
675  else
676  {
677  /* This is slow */
678  prof = uves_max_double(
679  0, uves_polynomial_evaluate_2d(p->dy_poly[i],
680  pos->x,
681  pos->order));
682  }
683 
684  p->current_ypos[i] = uves_extract_profile_get_y(pos, i, p->sampling_factor);
685  p->current_profile[i] = prof;
686  sum += prof;
687  }
688 
689  /* Interpolate profile at the positions needed, enforce normalization */
690  i = 0;
691  sum = 0;
692  for (pos->y = pos->ylow; pos->y <= pos->yhigh; pos->y++)
693  {
694  double pint; /* interpolated value */
695  if (false)
696  /* Nearest bin interpolation (steps, for testing purposes only): */
697  {
698  double bin = uves_extract_profile_get_bin(pos, p->sampling_factor);
699  pint = p->current_profile[uves_round_double(bin)];
700  }
701  else if (true)
702  /* Linear interpolation */
703  /* Interpolate linearly, flux-conserving between two nearest bins
704  *
705  * |-----|--|
706  * bl b bu
707  *
708  * (bl = bin_lower (integer),
709  * bu = bin_upper (integer),
710  * b = bin (floating))
711  *
712  * interpolated = (bu-b)*prof(bl) + (b-bl)*prof(bu)
713  */
714  {
715  double bin = uves_extract_profile_get_bin(pos,
716  p->sampling_factor);
717 
718  int bin_lower = (int) bin;
719  int bin_upper = bin_lower + 1;
720 
721  double prof_lower = p->current_profile[bin_lower];
722  double prof_upper = p->current_profile[bin_upper];
723 
724  double weight = bin_upper - bin;
725 
726  pint = weight*prof_lower + (1-weight)*prof_upper;
727  }
728  else
729  {
730  pint = uves_spline_hermite(
731  pos->y, /* Where to interpolate */
732  p->current_ypos, p->current_profile, /* Function */
733  p->spatial_bins,
734  &i);
735  }
736 
737  p->current_interpolated[pos->y - pos->ylow] = pint;
738  sum += pint;
739  }
740 
741  if ( !(sum > 0) )
742  {
743  /* In the exceptional case when sum == 0,
744  do linear extraction */
745  sum = 1;
746  }
747 
748  for (pos->y = pos->ylow; pos->y <= pos->yhigh; pos->y++)
749  {
750  p->current_interpolated[pos->y - pos->ylow] /= sum;
751  }
752  }
753 
754  cleanup:
755  return;
756 }
757 
758 /*----------------------------------------------------------------------------*/
770 /*----------------------------------------------------------------------------*/
771 double
772 uves_extract_profile_evaluate(const uves_extract_profile *profile,
773  const uves_iterate_position *pos)
774 {
775  double result;
776 
777  if (profile->constant) {
778  result = 1.0 / profile->current_area;
779  }
780  else if (profile->f != NULL)
781  {
782  double a[5];
783 
784  a[0] = profile->current_y0;
785  a[1] = profile->current_sigma;
786  a[2] = 1/profile->current_area; /* This is to get a sum of 1
787  when the profile is summed over
788  all bins. */
789  a[3] = 0.0; /* Sky offset */
790  a[4] = 0.0; /* Sky offset linear term */
791 
792  {
793  /* Don't use gauss-legendre 3-point. It increases execution time,
794  and makes only extremely small (insignificant) difference on output.
795 
796  Also, the profile was measured using an unbinned analytical profile,
797  so such interpolation probably does not even make sense.
798  */
799  if (0)
800  {
801  double xp[3] = {-0.387298334621, 0, 0.387298334621};
802  double weight[3] = {0.2777777777778, 0.444444444444, 0.2777777777778};
803  int i;
804 
805  result = 0;
806  for (i = 0; i < 3; i++)
807  {
808  double val;
809  double y = pos->y;
810 
811  a[0] = profile->current_y0 + xp[i];
812  profile->f(&y, a, &val);
813  result += weight[i] * val;
814  }
815  }
816  else
817  {
818  double y = pos->y;
819 
820  a[0] = profile->current_y0;
821  profile->f(&y, a, &result);
822  }
823  }
824  }
825  else
826  /* Virtual */
827  {
828  result = profile->current_interpolated[pos->y - pos->ylow];
829  }
830 
831  return result;
832 }
833 
void uves_polynomial_delete(polynomial **p)
Delete a polynomial.
#define uves_msg_warning(...)
Print an warning message.
Definition: uves_msg.h:87
double uves_polynomial_evaluate_2d(const polynomial *p, double x1, double x2)
Evaluate a 2d polynomial.
double uves_polynomial_evaluate_1d(const polynomial *p, double x)
Evaluate a 1d polynomial.
double uves_spline_hermite(double xp, const double *x, const double *y, int n, int *istart)
Spline interpolation based on Hermite polynomials.
Definition: uves_utils.c:3721
#define check(CMD,...)
Definition: uves_error.h:198