28#include <cxmessages.h>
29#include <cxstrutils.h>
80static const cxint DW_DEGREE = 3;
81static const cxdouble DW_LOG001 = 2.302585093;
97_giraffe_dydaweight(cxdouble x, cxdouble x0, cxdouble dx)
103 w = exp(-pow(fabs(x - x0), DW_DEGREE) / pow(dx, DW_DEGREE / DW_LOG001));
115_giraffe_model_dtor(GiModel *self)
124 self->arguments.count = 0;
126 if (self->arguments.names) {
127 cpl_propertylist_delete(self->arguments.names);
128 self->arguments.names = NULL;
131 if (self->arguments.values) {
132 cpl_matrix_delete(self->arguments.values);
133 self->arguments.values = NULL;
137 self->parameters.count = 0;
139 if (self->parameters.names) {
140 cpl_propertylist_delete(self->parameters.names);
141 self->parameters.names = NULL;
144 if (self->parameters.values) {
145 cpl_matrix_delete(self->parameters.values);
146 self->parameters.values = NULL;
149 if (self->parameters.limits) {
150 cpl_matrix_delete(self->parameters.limits);
151 self->parameters.limits = NULL;
154 if (self->parameters.flags) {
155 cx_free(self->parameters.flags);
156 self->parameters.flags = NULL;
160 self->fit.iterations = 0;
162 if (self->fit.covariance) {
163 cpl_matrix_delete(self->fit.covariance);
164 self->fit.covariance = NULL;
173_giraffe_xoptmod_ctor(GiModel *self,
const GiModelData *model)
176 cx_assert(self != NULL);
177 cx_assert(model != NULL);
179 self->name = cx_strdup(model->name);
180 self->type = model->type;
182 self->model = model->eval;
189 self->arguments.names = cpl_propertylist_new();
191 cpl_propertylist_append_int(self->arguments.names,
"xf", LMI_XFIB);
192 cpl_propertylist_append_int(self->arguments.names,
"yf", LMI_YFIB);
193 cpl_propertylist_append_int(self->arguments.names,
"lambda", LMI_WLEN);
195 self->arguments.count = cpl_propertylist_get_size(self->arguments.names);
196 self->arguments.values = cpl_matrix_new(self->arguments.count, 1);
203 self->parameters.names = cpl_propertylist_new();
205 cpl_propertylist_append_int(self->parameters.names,
"Orientation",
207 cpl_propertylist_append_int(self->parameters.names,
"Order",
209 cpl_propertylist_append_int(self->parameters.names,
"PixelSize",
211 cpl_propertylist_append_int(self->parameters.names,
"FocalLength",
213 cpl_propertylist_append_int(self->parameters.names,
"Magnification",
215 cpl_propertylist_append_int(self->parameters.names,
"Angle",
217 cpl_propertylist_append_int(self->parameters.names,
"Spacing",
220 self->parameters.count =
221 cpl_propertylist_get_size(self->parameters.names);
222 self->parameters.values = cpl_matrix_new(self->parameters.count, 1);
230_giraffe_xoptmod_eval(cxdouble *y, cxdouble *x, cxdouble *a, cxint na,
231 cxdouble *dyda, cxdouble *r)
234 const cxchar *
const fctid =
"_giraffe_xoptmod_eval";
241 cxdouble pixsize, nx;
242 cxdouble fcoll, cfact;
243 cxdouble gtheta, gorder, gspace;
245 register cxdouble xccd, d, X;
246 register cxdouble yfibre2, tmp, tmp2, d2, X2, gspace2;
247 register cxdouble sqtmp, costheta, sintheta;
252 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
260 dyda[LMP_PXSIZ] = 0.;
261 dyda[LMP_FCOLL] = 0.;
262 dyda[LMP_CFACT] = 0.;
263 dyda[LMP_THETA] = 0.;
264 dyda[LMP_ORDER] = 0.;
265 dyda[LMP_SPACE] = 0.;
268 lambda = x[LMI_WLEN];
269 xfibre = x[LMI_XFIB];
270 yfibre = x[LMI_YFIB];
273 pixsize = a[LMP_PXSIZ];
274 fcoll = a[LMP_FCOLL];
275 cfact = a[LMP_CFACT];
276 gtheta = a[LMP_THETA];
277 gorder = a[LMP_ORDER];
278 gspace = a[LMP_SPACE];
281 lambda *= GI_NM_TO_MM;
283 yfibre2 = yfibre * yfibre;
284 gspace2 = gspace * gspace;
285 costheta = cos(gtheta);
286 sintheta = sin(gtheta);
288 d2 = xfibre * xfibre + yfibre2 + (fcoll * fcoll);
291 X = (-lambda * gorder / gspace) + (xfibre * costheta / d) +
292 (fcoll * sintheta / d);
295 sqtmp = sqrt(1.0 - yfibre2 / d2 - X2);
296 tmp = -sintheta * X + costheta * sqtmp;
298 xccd = (cfact * fcoll * (X * costheta + sintheta * sqtmp)) / tmp;
306 *y = xccd / pixsize - 0.5 * nx;
309 *y = -xccd / pixsize + 0.5 * nx;
321 dyda[LMP_PXSIZ] = 0.0;
323 dyda[LMP_FCOLL] = cfact * (costheta * X + sintheta * sqtmp) / tmp +
324 cfact * fcoll * (costheta * (-X * fcoll / d2 + sintheta / d -
325 gorder * lambda * fcoll /
326 (d2 * gspace)) + 0.5 * sintheta *
327 (-2.0 * X * (-X * fcoll / d2 + sintheta / d -
328 gorder * lambda * fcoll /
330 2.0 * yfibre2 * fcoll / (d2 * d2)) / sqtmp) /
331 tmp - cfact * fcoll * (costheta * X + sintheta * sqtmp) *
332 (-sintheta * (-X * fcoll / d2 + sintheta / d - gorder * lambda *
333 fcoll / (d2 * gspace)) + 0.5 * costheta *
334 (-2.0 * X * (-X * fcoll / d2 + sintheta / d - gorder * lambda *
335 fcoll / (d2 * gspace)) + 2.0 * yfibre2 * fcoll /
336 (d2 * d2)) / sqtmp) / tmp2;
338 dyda[LMP_FCOLL] /= pixsize;
339 dyda[LMP_CFACT] = (xccd / cfact) / pixsize;
341 dyda[LMP_THETA] = cfact * fcoll * ((-xfibre * sintheta / d + fcoll *
342 costheta / d) * costheta -
343 sintheta * X - sintheta * X *
344 (-xfibre * sintheta / d + fcoll *
345 costheta / d) / sqtmp +
346 costheta * sqtmp) / tmp -
347 cfact * fcoll * (costheta * X + sintheta * sqtmp) *
348 (-(-xfibre * sintheta / d + fcoll * costheta / d) * sintheta -
349 costheta * X - costheta * X * (-xfibre * sintheta / d + fcoll *
351 sqtmp - sintheta * sqtmp) / tmp2;
353 dyda[LMP_THETA] /= pixsize;
354 dyda[LMP_ORDER] = 0.0;
356 dyda[LMP_SPACE] = cfact * fcoll * (lambda * gorder * costheta /
357 gspace2 - sintheta * X * lambda *
358 gorder / (sqtmp * gspace2)) /
359 tmp - cfact * fcoll * (X * costheta + sintheta * sqtmp) *
360 (-lambda * gorder * sintheta / gspace2 - costheta * X * lambda *
361 gorder / (sqtmp * gspace2)) / tmp2;
363 dyda[LMP_SPACE] /= pixsize;
366 dyda[LMP_NX] = -dyda[LMP_NX];
367 dyda[LMP_PXSIZ] = -dyda[LMP_PXSIZ];
368 dyda[LMP_FCOLL] = -dyda[LMP_FCOLL];
369 dyda[LMP_CFACT] = -dyda[LMP_CFACT];
370 dyda[LMP_THETA] = -dyda[LMP_THETA];
371 dyda[LMP_ORDER] = -dyda[LMP_ORDER];
372 dyda[LMP_SPACE] = -dyda[LMP_SPACE];
381 dyda[LMP_FCOLL] *= _giraffe_dydaweight(a[LMP_FCOLL], r[k],
387 dyda[LMP_CFACT] *= _giraffe_dydaweight(a[LMP_CFACT], r[k],
393 dyda[LMP_THETA] *= _giraffe_dydaweight(a[LMP_THETA], r[k],
399 dyda[LMP_SPACE] *= _giraffe_dydaweight(a[LMP_SPACE], r[k],
413_giraffe_yoptmod_ctor(GiModel *self,
const GiModelData *model)
416 cx_assert(self != NULL);
417 cx_assert(model != NULL);
419 self->name = cx_strdup(model->name);
420 self->type = model->type;
422 self->model = model->eval;
429 self->arguments.names = cpl_propertylist_new();
431 cpl_propertylist_append_int(self->arguments.names,
"xf", LMI_XFIB);
432 cpl_propertylist_append_int(self->arguments.names,
"yf", LMI_YFIB);
433 cpl_propertylist_append_int(self->arguments.names,
"lambda", LMI_WLEN);
435 self->arguments.count = cpl_propertylist_get_size(self->arguments.names);
436 self->arguments.values = cpl_matrix_new(self->arguments.count, 1);
443 self->parameters.names = cpl_propertylist_new();
445 cpl_propertylist_append_int(self->parameters.names,
"Orientation",
447 cpl_propertylist_append_int(self->parameters.names,
"Order",
449 cpl_propertylist_append_int(self->parameters.names,
"PixelSize",
451 cpl_propertylist_append_int(self->parameters.names,
"FocalLength",
453 cpl_propertylist_append_int(self->parameters.names,
"Magnification",
455 cpl_propertylist_append_int(self->parameters.names,
"Angle",
457 cpl_propertylist_append_int(self->parameters.names,
"Spacing",
460 self->parameters.count =
461 cpl_propertylist_get_size(self->parameters.names);
462 self->parameters.values = cpl_matrix_new(self->parameters.count, 1);
470_giraffe_yoptmod_eval(cxdouble *y, cxdouble *x, cxdouble *a, cxint na,
471 cxdouble *dyda, cxdouble *r)
474 const cxchar *
const fctid =
"_giraffe_yoptmod_eval";
476 cxdouble lambda, xfibre, yfibre;
477 cxdouble pixsize, ny;
478 cxdouble fcoll,cfact;
479 cxdouble gtheta,gorder,gspace;
481 register cxdouble t2, t3, t4, t5, t6, t7, t8, t9;
482 register cxdouble t10, t12, t13, t15, t18;
483 register cxdouble t22, t24, t26, t27, t28, t29;
484 register cxdouble t30, t33;
485 register cxdouble t41, t45, t47;
486 register cxdouble t53, t56, t57;
487 register cxdouble t76;
488 register cxdouble t93, t94;
495 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
503 dyda[LMP_PXSIZ] = 0.;
504 dyda[LMP_FCOLL] = 0.;
505 dyda[LMP_CFACT] = 0.;
506 dyda[LMP_THETA] = 0.;
507 dyda[LMP_ORDER] = 0.;
508 dyda[LMP_SPACE] = 0.;
511 lambda = x[LMI_WLEN];
512 xfibre = x[LMI_XFIB];
513 yfibre = x[LMI_YFIB];
516 pixsize = a[LMP_PXSIZ];
517 fcoll = a[LMP_FCOLL];
518 cfact = a[LMP_CFACT];
519 gtheta = a[LMP_THETA];
520 gorder = a[LMP_ORDER];
521 gspace = a[LMP_SPACE];
523 lambda *= GI_NM_TO_MM;
525 t2 = cfact * fcoll * yfibre;
526 t3 = xfibre * xfibre;
527 t4 = yfibre * yfibre;
532 t9 = lambda * gorder;
537 t18 = -t9 * t10 + t13 * t8 + fcoll * t15 * t8;
539 t24 = sqrt(1.0 - t4 / t6 - t22);
540 t26 = -t18 * t15 + t12 * t24;
545 t33 = pixsize * pixsize;
549 t53 = -t13 * t41 * fcoll + t15 * t8 - t5 * t15 * t41;
552 t76 = -xfibre * t15 * t8 + fcoll * t12 * t8;
553 t93 = gspace * gspace;
556 *y = -t2 * t30 + 0.5 * ny;
567 dyda[LMP_PXSIZ] = t2 * t28 / t33;
568 dyda[LMP_FCOLL] = -cfact * yfibre * t30 + cfact * t5 *
569 yfibre * t41 * t27 * t29 + t2 * t47 * t29 *
570 (-t53 * t15 + t56 * (2.0 * t4 / t57 * fcoll -
571 2.0 * t18 * t53) / 2.0);
572 dyda[LMP_CFACT] = -fcoll * yfibre * t30;
573 dyda[LMP_THETA] = t2 * t47 * t29 * (-t76 * t15 - t18 * t12 -
574 t15 * t24 - t56 * t18 * t76);
575 dyda[LMP_ORDER] = t2 * t47 *t29 *(lambda * t10 * t15 + t56 *
577 dyda[LMP_SPACE] = t2 * t47 * t29 * (-t9 * t94 * t15 -
578 t56 * t18 * t9 * t94);
588_giraffe_xoptmod2_ctor(GiModel *self,
const GiModelData *model)
591 cx_assert(self != NULL);
592 cx_assert(model != NULL);
594 self->name = cx_strdup(model->name);
595 self->type = model->type;
597 self->model = model->eval;
604 self->arguments.names = cpl_propertylist_new();
606 cpl_propertylist_append_int(self->arguments.names,
"xf", LMI_XFIB);
607 cpl_propertylist_append_int(self->arguments.names,
"yf", LMI_YFIB);
608 cpl_propertylist_append_int(self->arguments.names,
"lambda", LMI_WLEN);
610 self->arguments.count = cpl_propertylist_get_size(self->arguments.names);
611 self->arguments.values = cpl_matrix_new(self->arguments.count, 1);
618 self->parameters.names = cpl_propertylist_new();
620 cpl_propertylist_append_int(self->parameters.names,
"Orientation",
622 cpl_propertylist_append_int(self->parameters.names,
"Order",
624 cpl_propertylist_append_int(self->parameters.names,
"PixelSize",
626 cpl_propertylist_append_int(self->parameters.names,
"FocalLength",
628 cpl_propertylist_append_int(self->parameters.names,
"Magnification",
630 cpl_propertylist_append_int(self->parameters.names,
"Angle",
632 cpl_propertylist_append_int(self->parameters.names,
"Spacing",
634 cpl_propertylist_append_int(self->parameters.names,
"Sdx",
636 cpl_propertylist_append_int(self->parameters.names,
"Sdy",
638 cpl_propertylist_append_int(self->parameters.names,
"Sphi",
641 self->parameters.count =
642 cpl_propertylist_get_size(self->parameters.names);
643 self->parameters.values = cpl_matrix_new(self->parameters.count, 1);
651_giraffe_xoptmod2_eval(cxdouble *y, cxdouble *x, cxdouble *a, cxint na,
652 cxdouble *dyda, cxdouble *r)
655 const cxchar *
const fctid =
"_giraffe_xoptmod2_eval";
662 cxdouble pixsize, nx;
663 cxdouble fcoll, cfact;
664 cxdouble gtheta, gorder, gspace;
665 cxdouble slitdx, slitdy, slitphi;
667 register cxdouble t1, t2, t3, t4, t9;
668 register cxdouble t10, t11, t12, t14, t16, t17, t18, t19;
669 register cxdouble t20, t21, t23, t24, t26, t27, t28;
670 register cxdouble t30, t32, t33, t34, t35, t36, t37, t38, t39;
671 register cxdouble t40, t44, t49;
672 register cxdouble t52, t58;
673 register cxdouble t60, t61, t62, t64, t68;
674 register cxdouble t75, t76, t78;
675 register cxdouble t80;
676 register cxdouble t91, t93;
677 register cxdouble t104, t107;
678 register cxdouble t113, t119;
679 register cxdouble t120, t121, t124;
680 register cxdouble t136, t137, t138;
681 register cxdouble t143, t148;
682 register cxdouble t161, t162, t166, t168;
683 register cxdouble t173;
684 register cxdouble t191, t195, t196;
685 register cxdouble t201, t210;
689 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
697 dyda[LMP_PXSIZ] = 0.;
698 dyda[LMP_FCOLL] = 0.;
699 dyda[LMP_CFACT] = 0.;
700 dyda[LMP_THETA] = 0.;
701 dyda[LMP_ORDER] = 0.;
702 dyda[LMP_SPACE] = 0.;
703 dyda[LMP_SOFFX] = 0.;
704 dyda[LMP_SOFFY] = 0.;
708 lambda = x[LMI_WLEN];
709 xfibre = x[LMI_XFIB];
710 yfibre = x[LMI_YFIB];
713 pixsize = a[LMP_PXSIZ];
714 fcoll = a[LMP_FCOLL];
715 cfact = a[LMP_CFACT];
716 gtheta = a[LMP_THETA];
717 gorder = a[LMP_ORDER];
718 gspace = a[LMP_SPACE];
719 slitdx = a[LMP_SOFFX];
720 slitdy = a[LMP_SOFFY];
721 slitphi = a[LMP_SPHI];
723 lambda *= GI_NM_TO_MM;
727 t3 = lambda * gorder;
729 t9 = xfibre * (1.0 + slitphi * yfibre) + slitdx;
732 t12 = slitphi * slitphi;
733 t14 = sqrt(1.0 - t12);
734 t16 = yfibre * t14 + slitdy;
737 t19 = t11 + t17 + t18;
742 t26 = -t3 * t4 + t10 * t21 + t24 * t21;
746 t32 = sqrt(1.0 - t17 * t28 - t30);
755 t44 = pixsize * pixsize;
757 t52 = 1.0 / t20 / t19;
758 t58 = -t10 * t52 * fcoll + t23 * t21 - t18 * t23 * t52;
763 t68 = 2.0 * t64 * fcoll - 2.0 * t26 * t58;
766 t78 = 1.0 / t76 * t40;
768 t91 = -t9 * t23 * t21 + fcoll * t2 * t21;
771 t107 = t26 * lambda * t4;
773 t119 = gspace * gspace;
775 t121 = gorder * t120;
780 t143 = t136 - t10 * t138 / 2.0 - t24 * t138 / 2.0;
781 t148 = t64 * t137 - 2.0 * t26 * t143;
784 t166 = -t10 * t162 / 2.0 - t24 * t162 / 2.0;
786 t173 = -2.0 * t168 + t64 * t161 - 2.0 * t26 * t166;
788 t195 = 2.0 * t9 * xfibre * yfibre - 2.0 * t16 * yfibre * t191 * slitphi;
790 t201 = xfibre * yfibre * t136 - t10 * t196 / 2.0 - t24 * t196 / 2.0;
791 t210 = 2.0 * t168 * yfibre * t191 * slitphi + t64 * t195 -
800 *y = t1 * t39 * t40 - 0.5 * nx;
803 *y = -t1 * t39 * t40 + 0.5 * nx;
815 dyda[LMP_PXSIZ] = -t1 * t39 / t44;
816 dyda[LMP_FCOLL] = cfact * t34 * t49 + t1 *
817 (t2 * t58 + t61 * t68 / 2.0) * t38 * t40 -
818 t75 * t78 * (-t23 * t58 + t80 * t68 / 2.0);
819 dyda[LMP_CFACT] = fcoll * t34 * t49;
820 dyda[LMP_THETA] = t1 * (-t35 + t2 * t91 + t36 - t61 * t93) * t38 *
821 t40 - t75 * t78 * (-t27 - t23 * t91 - t33 - t80 * t93);
822 dyda[LMP_ORDER] = t1 * (-t104 * t4 + t61 * t107) * t38 * t40 - t75 *
823 t78 * (t113 * t4 + t80 * t107);
824 dyda[LMP_SPACE] = t1 * (t104 * t121 - t61 * t26 * t124) * t38 * t40 -
825 t75 * t78 * (-t113 * t121 - t80 * t26 * t124);
826 dyda[LMP_SOFFX] = t1 * (t2 * t143 + t61 * t148 / 2.0) * t38 * t40 -
827 t75 * t78 * (-t23 * t143 + t80 * t148 / 2.0);
828 dyda[LMP_SOFFY] = t1 * (t2 * t166 + t61 * t173 / 2.0) * t38 * t40 -
829 t75 * t78 * (-t23 * t166 + t80 * t173 / 2.0);
830 dyda[LMP_SPHI] = t1 * (t2 * t201 + t61 * t210 / 2.0) * t38 * t40 -
831 t75 * t78 * (-t23 * t201 + t80 * t210 / 2.0);
834 dyda[LMP_NX] = -dyda[LMP_NX];
835 dyda[LMP_PXSIZ] = -dyda[LMP_PXSIZ];
836 dyda[LMP_FCOLL] = -dyda[LMP_FCOLL];
837 dyda[LMP_CFACT] = -dyda[LMP_CFACT];
838 dyda[LMP_THETA] = -dyda[LMP_THETA];
839 dyda[LMP_ORDER] = -dyda[LMP_ORDER];
840 dyda[LMP_SPACE] = -dyda[LMP_SPACE];
841 dyda[LMP_SOFFX] = -dyda[LMP_SOFFX];
842 dyda[LMP_SOFFY] = -dyda[LMP_SOFFY];
843 dyda[LMP_SPHI] = -dyda[LMP_SPHI];
853 dyda[LMP_PXSIZ] *= _giraffe_dydaweight(a[LMP_PXSIZ], r[k],
859 dyda[LMP_FCOLL] *= _giraffe_dydaweight(a[LMP_FCOLL], r[k],
865 dyda[LMP_CFACT] *= _giraffe_dydaweight(a[LMP_CFACT], r[k],
871 dyda[LMP_THETA] *= _giraffe_dydaweight(a[LMP_THETA], r[k],
877 dyda[LMP_ORDER] *= _giraffe_dydaweight(a[LMP_ORDER], r[k],
883 dyda[LMP_SPACE] *= _giraffe_dydaweight(a[LMP_SPACE], r[k],
889 dyda[LMP_SOFFX] *= _giraffe_dydaweight(a[LMP_SOFFX], r[k],
895 dyda[LMP_SOFFY] *= _giraffe_dydaweight(a[LMP_SOFFY], r[k],
901 dyda[LMP_SPHI] *= _giraffe_dydaweight(a[LMP_SPHI], r[k],
915_giraffe_yoptmod2_ctor(GiModel *self,
const GiModelData *model)
918 cx_assert(self != NULL);
919 cx_assert(model != NULL);
921 self->name = cx_strdup(model->name);
922 self->type = model->type;
924 self->model = model->eval;
931 self->arguments.names = cpl_propertylist_new();
933 cpl_propertylist_append_int(self->arguments.names,
"xf", LMI_XFIB);
934 cpl_propertylist_append_int(self->arguments.names,
"yf", LMI_YFIB);
935 cpl_propertylist_append_int(self->arguments.names,
"lambda", LMI_WLEN);
937 self->arguments.count = cpl_propertylist_get_size(self->arguments.names);
938 self->arguments.values = cpl_matrix_new(self->arguments.count, 1);
945 self->parameters.names = cpl_propertylist_new();
947 cpl_propertylist_append_int(self->parameters.names,
"Orientation",
949 cpl_propertylist_append_int(self->parameters.names,
"Order",
951 cpl_propertylist_append_int(self->parameters.names,
"PixelSize",
953 cpl_propertylist_append_int(self->parameters.names,
"FocalLength",
955 cpl_propertylist_append_int(self->parameters.names,
"Magnification",
957 cpl_propertylist_append_int(self->parameters.names,
"Angle",
959 cpl_propertylist_append_int(self->parameters.names,
"Spacing",
961 cpl_propertylist_append_int(self->parameters.names,
"Sdx",
963 cpl_propertylist_append_int(self->parameters.names,
"Sdy",
965 cpl_propertylist_append_int(self->parameters.names,
"Sphi",
968 self->parameters.count =
969 cpl_propertylist_get_size(self->parameters.names);
970 self->parameters.values = cpl_matrix_new(self->parameters.count, 1);
978_giraffe_yoptmod2_eval(cxdouble *y, cxdouble *x, cxdouble *a, cxint na,
979 cxdouble *dyda, cxdouble *r)
982 const cxchar *
const fctid =
"_giraffe_yoptmod2_eval";
985 cxdouble lambda, xfibre, yfibre;
986 cxdouble pixsize, ny;
987 cxdouble fcoll, cfact;
988 cxdouble gtheta, gorder, gspace;
989 cxdouble slitdx, slitdy, slitphi;
991 register cxdouble t1, t2, t4, t6, t7;
992 register cxdouble t11, t12, t13, t14, t15, t16, t17, t18, t19;
993 register cxdouble t21, t22, t24, t25, t27, t29;
994 register cxdouble t31, t33, t35, t36, t37, t38, t39;
995 register cxdouble t42, t50, t51, t54, t56;
996 register cxdouble t62, t65, t66, t68;
997 register cxdouble t85;
998 register cxdouble t102, t103;
999 register cxdouble t112, t117, t118;
1000 register cxdouble t123;
1001 register cxdouble t136;
1002 register cxdouble t141, t145, t147;
1003 register cxdouble t159;
1004 register cxdouble t160;
1005 register cxdouble t172, t179;
1006 register cxdouble t184;
1013 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
1021 dyda[LMP_PXSIZ] = 0.;
1022 dyda[LMP_FCOLL] = 0.;
1023 dyda[LMP_CFACT] = 0.;
1024 dyda[LMP_THETA] = 0.;
1025 dyda[LMP_ORDER] = 0.;
1026 dyda[LMP_SPACE] = 0.;
1027 dyda[LMP_SOFFX] = 0.;
1028 dyda[LMP_SOFFY] = 0.;
1029 dyda[LMP_SPHI] = 0.;
1032 lambda = x[LMI_WLEN];
1033 xfibre = x[LMI_XFIB];
1034 yfibre = x[LMI_YFIB];
1037 pixsize = a[LMP_PXSIZ];
1038 fcoll = a[LMP_FCOLL];
1039 cfact = a[LMP_CFACT];
1040 gtheta = a[LMP_THETA];
1041 gorder = a[LMP_ORDER];
1042 gspace = a[LMP_SPACE];
1043 slitdx = a[LMP_SOFFX];
1044 slitdy = a[LMP_SOFFY];
1045 slitphi = a[LMP_SPHI];
1047 lambda *= GI_NM_TO_MM;
1050 t2 = slitphi * slitphi;
1051 t4 = sqrt(1.0 - t2);
1052 t6 = yfibre * t4 + slitdy;
1054 t11 = xfibre * (1.0 + slitphi * yfibre) + slitdx;
1057 t14 = fcoll * fcoll;
1058 t15 = t12 + t13 + t14;
1061 t18 = lambda * gorder;
1067 t27 = -t18 * t19 + t22 * t17 + t25 * t17;
1070 t33 = sqrt(1.0 - t13 * t29 - t31);
1071 t35 = -t27 * t24 + t21 * t33;
1076 t42 = pixsize * pixsize;
1077 t50 = 1 / t16 / t15;
1081 t62 = -t22 * t50 * fcoll + t24 * t17 - t14 * t24 * t50;
1085 t85 = -t11 * t24 * t17 + fcoll * t21 * t17;
1086 t102 = gspace * gspace;
1091 t123 = t117 - t22 * t118 / 2.0 - t25 * t118 / 2.0;
1094 t145 = -t22 * t141 / 2.0 - t25 * t141 / 2.0;
1097 t160 = yfibre * t159;
1098 t172 = 2.0 * t11 * xfibre * yfibre - 2.0 * t6 * yfibre * t159 * slitphi;
1100 t184 = xfibre * yfibre * t117 - t22 * t179 / 2.0 - t25 * t179 / 2.0;
1102 *y = -t7 * t39 + 0.5 * ny;
1107 dyda[LMP_PXSIZ] = t7 * t37 / t42;
1108 dyda[LMP_FCOLL] = -cfact * t6 * t39 + cfact * t14 * t6 * t51 * t38 +
1109 t7 * t56 * t38 * (-t62 * t24 + t65 * (2.0 * t68 * fcoll -
1110 2.0 * t27 * t62) / 2.0);
1111 dyda[LMP_CFACT] = -fcoll * t6 * t39;
1112 dyda[LMP_THETA] = t7 * t56 * t38 * (-t85 * t24 - t27 * t21 - t24 *
1113 t33 - t65 * t27 * t85);
1114 dyda[LMP_ORDER] = t7 * t56 * t38 * (lambda * t19 * t24 + t65 * t27 *
1116 dyda[LMP_SPACE] = t7 * t56 * t38 * (-t18 * t103 * t24 - t65 * t27 *
1118 dyda[LMP_SOFFX] = t7 * t51 * t38 * t112 / 2.0 + t7 * t56 * t38 *
1119 (-t123 * t24 + t65 * (t68 * t112 - 2.0 * t27 * t123) / 2.0);
1120 dyda[LMP_SOFFY] = -t1 * t39 + t7 * t51 * t38 * t136 / 2.0 + t7 *
1121 t56 * t38 * (-t145 * t24 + t65 * (-2.0 * t147 + t68 * t136 -
1122 2.0 * t27 * t145) / 2.0);
1123 dyda[LMP_SPHI] = t1 * t160 * slitphi * t17 * t36 * t38 + t7 * t51 *
1124 t38 * t172 / 2.0 + t7 * t56 * t38 *
1125 (-t184 * t24 + t65 * (2.0 * t147 * t160 * slitphi + t68 * t172 -
1126 2.0 * t27 * t184) / 2.0);
1136_giraffe_gaussian_ctor(GiModel *self,
const GiModelData *model)
1139 cx_assert(self != NULL);
1140 cx_assert(model != NULL);
1142 self->name = cx_strdup(model->name);
1143 self->type = model->type;
1145 self->model = model->eval;
1152 self->arguments.names = cpl_propertylist_new();
1154 cpl_propertylist_append_int(self->arguments.names,
"x", 0);
1156 self->arguments.count = cpl_propertylist_get_size(self->arguments.names);
1157 self->arguments.values = cpl_matrix_new(self->arguments.count, 1);
1164 self->parameters.names = cpl_propertylist_new();
1166 cpl_propertylist_append_int(self->parameters.names,
"Amplitude",
1168 cpl_propertylist_append_int(self->parameters.names,
"Center",
1170 cpl_propertylist_append_int(self->parameters.names,
"Background",
1172 cpl_propertylist_append_int(self->parameters.names,
"Width1",
1175 self->parameters.count =
1176 cpl_propertylist_get_size(self->parameters.names);
1177 self->parameters.values = cpl_matrix_new(self->parameters.count, 1);
1185_giraffe_gaussian_eval(cxdouble *y, cxdouble *x, cxdouble *a, cxint na,
1186 cxdouble *dyda, cxdouble *r)
1189 const cxchar *
const fctid =
"_giraffe_gaussian_eval";
1205 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
1212 dyda[LMP_AMPL] = 0.;
1213 dyda[LMP_CENT] = 0.;
1214 dyda[LMP_BACK] = 0.;
1215 dyda[LMP_WID1] = 0.;
1219 amplitude = a[LMP_AMPL];
1220 center = a[LMP_CENT];
1221 backg = a[LMP_BACK];
1222 width = a[LMP_WID1];
1224 xred = (x[0] - center) / width;
1226 ex = exp(-xred * xred / 2.);
1227 fac = amplitude * xred * ex;
1229 *y = amplitude * ex + backg;
1239 dyda[LMP_AMPL] = ex;
1240 dyda[LMP_CENT] = fac / width;
1241 dyda[LMP_BACK] = 1.;
1242 dyda[LMP_WID1] = (fac * xred) / width;
1252_giraffe_psfcos_ctor(GiModel *self,
const GiModelData *model)
1255 cx_assert(self != NULL);
1256 cx_assert(model != NULL);
1258 self->name = cx_strdup(model->name);
1259 self->type = model->type;
1261 self->model = model->eval;
1268 self->arguments.names = cpl_propertylist_new();
1270 cpl_propertylist_append_int(self->arguments.names,
"x", 0);
1272 self->arguments.count = cpl_propertylist_get_size(self->arguments.names);
1273 self->arguments.values = cpl_matrix_new(self->arguments.count, 1);
1280 self->parameters.names = cpl_propertylist_new();
1282 cpl_propertylist_append_int(self->parameters.names,
"Amplitude",
1284 cpl_propertylist_append_int(self->parameters.names,
"Center",
1286 cpl_propertylist_append_int(self->parameters.names,
"Background",
1288 cpl_propertylist_append_int(self->parameters.names,
"Width1",
1290 cpl_propertylist_append_int(self->parameters.names,
"Width2",
1293 self->parameters.count =
1294 cpl_propertylist_get_size(self->parameters.names);
1295 self->parameters.values = cpl_matrix_new(self->parameters.count, 1);
1303_giraffe_psfcos_eval(cxdouble *y, cxdouble *x, cxdouble *a, cxint na,
1304 cxdouble *dyda, cxdouble *r)
1307 const cxchar *
const fctid =
"_giraffe_psfcos_eval";
1312 cxdouble background;
1316 cxdouble t1, t2, t3, t4, t5, t6, t7, t8, t9;
1317 cxdouble t10, t13, t14, t15, t16;
1325 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
1332 dyda[LMP_AMPL] = 0.;
1333 dyda[LMP_CENT] = 0.;
1334 dyda[LMP_BACK] = 0.;
1335 dyda[LMP_WID1] = 0.;
1336 dyda[LMP_WID2] = 0.;
1339 amplitude = a[LMP_AMPL];
1340 center = a[LMP_CENT];
1341 background = a[LMP_BACK];
1342 width1 = a[LMP_WID1];
1343 width2 = a[LMP_WID2];
1349 t5 = pow(t4, width1);
1355 t13 = amplitude * t9;
1359 t26 = t1 > 0.0 ? 1.0 : -1.0;
1365 dyda[LMP_WID2] = 1.0;
1369 *y = amplitude * t10 / 8.0 + background;
1373 dyda[LMP_AMPL] = t10 / 8.0;
1374 dyda[LMP_CENT] = 3.0 / 8.0 * t13 * t14 * CX_PI * t5 *
1376 dyda[LMP_BACK] = 1.0;
1377 dyda[LMP_WID1] = -3.0 / 8.0 * t15 * t6 * t16;
1378 dyda[LMP_WID2] = 3.0 / 8.0 * t15 * t6 * width1 * t3;
1389_giraffe_psfexp_ctor(GiModel *self,
const GiModelData *model)
1392 cx_assert(self != NULL);
1393 cx_assert(model != NULL);
1395 self->name = cx_strdup(model->name);
1396 self->type = model->type;
1398 self->model = model->eval;
1405 self->arguments.names = cpl_propertylist_new();
1407 cpl_propertylist_append_int(self->arguments.names,
"x", 0);
1409 self->arguments.count = cpl_propertylist_get_size(self->arguments.names);
1410 self->arguments.values = cpl_matrix_new(self->arguments.count, 1);
1417 self->parameters.names = cpl_propertylist_new();
1419 cpl_propertylist_append_int(self->parameters.names,
"Amplitude",
1421 cpl_propertylist_append_int(self->parameters.names,
"Center",
1423 cpl_propertylist_append_int(self->parameters.names,
"Background",
1425 cpl_propertylist_append_int(self->parameters.names,
"Width1",
1427 cpl_propertylist_append_int(self->parameters.names,
"Width2",
1430 self->parameters.count =
1431 cpl_propertylist_get_size(self->parameters.names);
1432 self->parameters.values = cpl_matrix_new(self->parameters.count, 1);
1440_giraffe_psfexp_eval(cxdouble *y, cxdouble *x, cxdouble *a, cxint na,
1441 cxdouble *dyda, cxdouble *r)
1444 const cxchar *
const fctid =
"_giraffe_psfexp_eval";
1448 cxdouble background;
1452 cxdouble t1, t2, t3, t4, t6, t8;
1453 cxdouble t10, t15, t18;
1459 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
1466 dyda[LMP_AMPL] = 0.;
1467 dyda[LMP_CENT] = 0.;
1468 dyda[LMP_BACK] = 0.;
1469 dyda[LMP_WID1] = 0.;
1470 dyda[LMP_WID2] = 0.;
1473 amplitude = a[LMP_AMPL];
1474 center = a[LMP_CENT];
1475 background = a[LMP_BACK];
1476 width1 = a[LMP_WID1];
1477 width2 = a[LMP_WID2];
1490 t3 = pow(t2, width2);
1493 t8 = amplitude * t3;
1494 t15 = width1 * width1;
1497 *y = amplitude * t6 + background;
1500 dyda[LMP_AMPL] = t6;
1501 dyda[LMP_BACK] = 1.0;
1503 dyda[LMP_CENT] = t8 * width2 * t10 / t2 * t4 * t6;
1505 if (isnan(dyda[LMP_CENT])) {
1506 dyda[LMP_CENT] = 0.;
1509 dyda[LMP_WID1] = t8 / t15 * t6;
1511 if (isnan(dyda[LMP_WID1])) {
1512 dyda[LMP_WID1] = 0.;
1515 dyda[LMP_WID2] = -t8 * t18 * t4 * t6;
1517 if (isnan(dyda[LMP_WID2])) {
1518 dyda[LMP_WID2] = 0.;
1527 dyda[LMP_AMPL] *= _giraffe_dydaweight(a[LMP_AMPL], r[k],
1533 dyda[LMP_CENT] *= _giraffe_dydaweight(a[LMP_CENT], r[k],
1539 dyda[LMP_WID1] *= _giraffe_dydaweight(a[LMP_WID1], r[k],
1545 dyda[LMP_WID2] *= _giraffe_dydaweight(a[LMP_WID2], r[k],
1559_giraffe_psfexp2_ctor(GiModel *self,
const GiModelData *model)
1562 cx_assert(self != NULL);
1563 cx_assert(model != NULL);
1565 self->name = cx_strdup(model->name);
1566 self->type = model->type;
1568 self->model = model->eval;
1575 self->arguments.names = cpl_propertylist_new();
1577 cpl_propertylist_append_int(self->arguments.names,
"x", 0);
1579 self->arguments.count = cpl_propertylist_get_size(self->arguments.names);
1580 self->arguments.values = cpl_matrix_new(self->arguments.count, 1);
1587 self->parameters.names = cpl_propertylist_new();
1589 cpl_propertylist_append_int(self->parameters.names,
"Amplitude",
1591 cpl_propertylist_append_int(self->parameters.names,
"Center",
1593 cpl_propertylist_append_int(self->parameters.names,
"Background",
1595 cpl_propertylist_append_int(self->parameters.names,
"Width1",
1597 cpl_propertylist_append_int(self->parameters.names,
"Width2",
1600 self->parameters.count =
1601 cpl_propertylist_get_size(self->parameters.names);
1602 self->parameters.values = cpl_matrix_new(self->parameters.count, 1);
1610_giraffe_psfexp2_eval(cxdouble *y, cxdouble *x, cxdouble *a, cxint na,
1611 cxdouble *dyda, cxdouble *r)
1614 const cxchar *
const fctid =
"_giraffe_psfexp2_eval";
1618 cxdouble background;
1622 cxdouble t1, t2, t3, t4, t5, t6, t8;
1629 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
1636 dyda[LMP_AMPL] = 0.;
1637 dyda[LMP_CENT] = 0.;
1638 dyda[LMP_BACK] = 0.;
1639 dyda[LMP_WID1] = 0.;
1640 dyda[LMP_WID2] = 0.;
1643 amplitude = a[LMP_AMPL];
1644 center = a[LMP_CENT];
1645 background = a[LMP_BACK];
1646 width1 = a[LMP_WID1];
1647 width2 = a[LMP_WID2];
1662 t5 = pow(t4, width2);
1664 t8 = amplitude * t5;
1667 *y = amplitude * t6 + background;
1671 dyda[LMP_AMPL] = t6;
1673 dyda[LMP_CENT] = t8 * width2 * t10 / t2 * t6;
1675 if (isnan(dyda[LMP_CENT])) {
1676 dyda[LMP_CENT] = 0.0;
1679 dyda[LMP_BACK] = 1.0;
1680 dyda[LMP_WID1] = t8 * width2 * t3 * t6;
1682 dyda[LMP_WID2] = -t8 * t16 * t6;
1684 if (isnan(dyda[LMP_WID2])) {
1685 dyda[LMP_WID2] = 0.0;
1694 dyda[LMP_AMPL] *= _giraffe_dydaweight(a[LMP_AMPL], r[k],
1700 dyda[LMP_CENT] *= _giraffe_dydaweight(a[LMP_CENT], r[k],
1706 dyda[LMP_WID1] *= _giraffe_dydaweight(a[LMP_WID1], r[k],
1712 dyda[LMP_WID2] *= _giraffe_dydaweight(a[LMP_WID2], r[k],
1726_giraffe_test_ctor(GiModel *self,
const GiModelData *model)
1729 cx_assert(self != NULL);
1730 cx_assert(model != NULL);
1732 self->name = cx_strdup(model->name);
1733 self->type = model->type;
1735 self->model = model->eval;
1742 self->arguments.names = cpl_propertylist_new();
1744 cpl_propertylist_append_int(self->arguments.names,
"x", 0);
1746 self->arguments.count = cpl_propertylist_get_size(self->arguments.names);
1747 self->arguments.values = cpl_matrix_new(self->arguments.count, 1);
1754 self->parameters.names = cpl_propertylist_new();
1756 cpl_propertylist_append_int(self->parameters.names,
"Slope", 0);
1757 cpl_propertylist_append_int(self->parameters.names,
"Intercept", 1);
1759 self->parameters.count =
1760 cpl_propertylist_get_size(self->parameters.names);
1761 self->parameters.values = cpl_matrix_new(self->parameters.count, 1);
1769_giraffe_test_eval(cxdouble *y, cxdouble *x, cxdouble *a, cxint na,
1770 cxdouble *dyda, cxdouble *r)
1773 const cxchar *
const fctid =
"_giraffe_test_eval";
1784 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
1798 *y = a1 * x[0] + b1;
1816static GiModelData _gimodels[] = {
1817 {
"xoptmod", GI_MODEL_XOPT,
1818 _giraffe_xoptmod_ctor, _giraffe_model_dtor, _giraffe_xoptmod_eval},
1819 {
"yoptmod", GI_MODEL_YOPT,
1820 _giraffe_yoptmod_ctor, _giraffe_model_dtor, _giraffe_yoptmod_eval},
1821 {
"xoptmod2", GI_MODEL_XOPT,
1822 _giraffe_xoptmod2_ctor, _giraffe_model_dtor, _giraffe_xoptmod2_eval},
1823 {
"yoptmod2", GI_MODEL_XOPT,
1824 _giraffe_yoptmod2_ctor, _giraffe_model_dtor, _giraffe_yoptmod2_eval},
1825 {
"gaussian", GI_MODEL_LINE,
1826 _giraffe_gaussian_ctor, _giraffe_model_dtor, _giraffe_gaussian_eval},
1827 {
"psfcos", GI_MODEL_LINE,
1828 _giraffe_psfcos_ctor, _giraffe_model_dtor, _giraffe_psfcos_eval},
1829 {
"psfexp", GI_MODEL_LINE,
1830 _giraffe_psfexp_ctor, _giraffe_model_dtor, _giraffe_psfexp_eval},
1831 {
"psfexp2", GI_MODEL_LINE,
1832 _giraffe_psfexp2_ctor, _giraffe_model_dtor, _giraffe_psfexp2_eval},
1833 {
"test", GI_MODEL_LINE,
1834 _giraffe_test_ctor, _giraffe_model_dtor, _giraffe_test_eval},
1835 {NULL, 0, NULL, NULL, NULL}
1838const GiModelData *
const giraffe_models = _gimodels;