/* $Id: xsh_model_metric.c,v 1.36 2012-12-18 16:09:26 amodigli Exp $
 *
 * This file is part of the ESO X-shooter Pipeline                          
 * Copyright (C) 2006 European Southern Observatory   
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 * $Author: amodigli $
 * $Date: 2012-12-18 16:09:26 $
 * $Revision: 1.36 $
 * $Name: not supported by cvs2svn $
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/*---------------------------------------------------------------------------*/
/**
 * @addtogroup xsh_model    xsh_model_metric
 *
 * Physical model metric computation
 * See man-page for details.
 */
/*---------------------------------------------------------------------------*/
/**@{*/
/*-----------------------------------------------------------------------------
                                                                   Includes
 -----------------------------------------------------------------------------*/

#include <cpl.h>

#include "xsh_model_kernel.h"
#include "xsh_model_io.h"
#include "xsh_model_metric.h"

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
#include "xsh_model_sa.h"
#include "xsh_model_r250.h"
#include "xsh_model_cputime.h"
#include "xsh_model_randlcg.h"

#include <xsh_utils.h>
#include <xsh_error.h>
#include <xsh_msg.h>
#include "xsh_pfits.h"
#include "xsh_dfs.h"

#ifdef _R250_H_
#define uniform(a,b)    ( a + (b - a) * xsh_dr250() )
#endif

/* #define MELT_ONLY  */
/* #define EQUIL_ONLY        */

#define BIG_VAL 400000.0

/* for conversion from degree to radians */
/* static const DOUBLE DEG2RAD=M_PI/180.0; */
  
int n = 0;
int* chip;
int* x;
int* y;
struct xs_3* local_p_xs;
int local_nparam;
double* local_p_abest;
double* local_p_amin;
double* local_p_amax;
int* local_p_aname;
ann_all_par*local_p_all_par;

DOUBLE p_obsx[10000],p_obsy[10000],p_obsf[10000];
DOUBLE *p_wl; 
DOUBLE** ref;
int p_obsarm[10000], p_obsorder[10000], sp_array[10000];
int* p_chipmod;
int size, mm;

/* the cost function */
void xsh_3_assign(int loc, double val);
void xsh_3_output_data(double*);
 
/*----------------------------------------------------------------------------*/
/**
  @brief    Use the simulated annealing algorithm to adjust the model
            parameters so that the metric (mean Euclidean residual) is
	    minimised
  @param    p_all_par  Pointer to structure of parameters to be optimised
  @param    nparam     Number of parameters to be optimised
  @param    abest      Array of initial guess values
  @param    amin       Array of lower limit values
  @param    amax       Array of upper limit values
  @param    aname      Array of parameter names
  @param    p_xs_3     Model parameter structure
  @param    DS_size    Number of wavelengths
  @param    msp_coord  Structure containing measured positions
  @param    p_wlarray  pointer to the array containing the list of
                       wavelengths
  @param    ref_ind    Refractive index
  @param    maxit      Maximum number of iterations
  @return   conf_tab   Table of optimised parameters
 */
/*----------------------------------------------------------------------------*/

cpl_table* xsh_model_anneal_comp(ann_all_par* p_all_par,
				 int nparam,double* abest,
				 double* amin,
				 double* amax,
				 int* aname,
				 struct xs_3* p_xs_3,
				 int DS_size,
				 coord* msp_coord,
				 DOUBLE* p_wlarray,
				 DOUBLE** ref_ind,
				 int maxit)
{
  int ii;
  float z, t0, t;
  cpl_table* conf_tab=NULL ;
  double* a;
  a=(DOUBLE*)cpl_malloc(nparam*sizeof(DOUBLE));

#ifdef DEBUG 
  fprintf(stderr,"%d points read for analysis\n", DS_size);

  xsh_report_cpu( stderr, NULL );
  printf("%d nparam \n",nparam);
#endif 

  if ( xsh_SAInit(xsh_3_energy,nparam) == 0 ) {
    fprintf(stderr,"trouble initializing in xsh_SAInit\n");
    abort();
  }

  local_p_abest=abest;
  local_p_amax=amax;
  local_p_amin=amin;
  local_p_aname=aname;
  local_nparam=nparam;
  local_p_all_par=p_all_par;
  local_p_xs=p_xs_3;
  for (ii=0;ii<DS_size;ii++) {
    p_obsx[ii]=msp_coord[ii].x;
    p_obsy[ii]=msp_coord[ii].y;
    p_obsarm[ii]=msp_coord[ii].arm;
    p_obsf[ii]=msp_coord[ii].flux;
    sp_array[ii]=msp_coord[ii].slit_pos;
    p_obsorder[ii]=msp_coord[ii].order;
#ifdef DEBUG 
    printf("%d obsx: %lf obsy:%lf, obsarm: %d sp: %d\n",
           ii, p_obsx[ii],p_obsy[ii],p_obsarm[ii],
           sp_array[ii]);
#endif
  }

  p_wl=p_wlarray;        
  size = DS_size; 
  ref=ref_ind;

  for (ii=0; ii<local_nparam ; ii++) {
    a[ii]=local_p_abest[ii];
  }
#ifdef DEBUG 
  printf("bef ener %lf %lf %lf %lf %lf \n",a[0], a[1],a[2], a[3],a[4]);
#endif

  check(z = xsh_3_energy(a));

#ifdef DEBUG 
  printf("bef init %lf %lf %lf %lf %lf \n",a[0], a[1],a[2], a[3],a[4]);
#endif
  xsh_SAinitial( a );
  xsh_SABoltzmann( 0.5 );
#ifdef DEBUG 
  printf("aft boltz %lf %lf %lf %lf %lf \n",a[0], a[1],a[2], a[3],a[4]);

/*        xsh_SAjump( 150.0 ); */
        
  fprintf(stderr,"Boltzman constant: %f\tlearning rate:%f\n",
          xsh_SABoltzmann( NO_VALUE ), xsh_SAlearning_rate( NO_VALUE ) );

  fprintf(stderr,"Initial values: ");
  for (ii = 0; ii < local_nparam; ii++)
    fprintf(stderr,"%g\t", a[ii]);
  fprintf(stderr,"\t(energy = %g)\n", z);
#endif

  xsh_SAmelt( NO_VALUE );                /* melt the system */
#ifdef DEBUG 
  printf("aft melt %lf %lf %lf %lf %lf \n",a[0], a[1],a[2], a[3],a[4]);
#endif

  xsh_SAcurrent( a );
#ifdef DEBUG 
  printf("aft current %lf %lf %lf %lf %lf \n",a[0], a[1],a[2], a[3],a[4]);
#endif

  z = xsh_3_energy(a);

#ifdef DEBUG 
  printf("aft energy %lf %lf %lf %lf %lf \n",a[0], a[1],a[2], a[3],a[4]);


  fprintf(stderr,"melt values: ");
  int i=0;
  for (i = 0; i < local_nparam; i++)
    fprintf(stderr,"%g\t", a[i]);
  fprintf(stderr,"\t(energy = %g)\n", z);
#endif

  t0 = xsh_SAtemperature( NO_VALUE );

#ifdef DEBUG 
  printf("aft temp %lf %lf %lf %lf %lf\n",a[0], a[1],a[2], a[3],a[4]);
#endif

  /* make it a bit warmer than melting temperature */
  t0 = 1.2 * xsh_SAtemperature( NO_VALUE );

  xsh_SAtemperature( t0 );
#ifdef DEBUG 
  printf("aft temp t0 %lf %lf %lf %lf %lf \n",a[0], a[1],a[2], a[3],a[4]);
#endif

  t = xsh_SAanneal( maxit );
#ifdef DEBUG 
  printf("aft anneal %lf %lf %lf %lf %lf \n",a[0], a[1],a[2], a[3],a[4]);
#endif
  xsh_SAcurrent( a );
#ifdef DEBUG 
  printf("aft current %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf \n",
         a[0], a[1],a[2], a[3],a[4],a[5], a[6],a[7], a[8],a[9]);
#endif
  z = xsh_3_energy(a);
#ifdef DEBUG 
  printf("aft energy %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf \n",
         a[0], a[1],a[2], a[3],a[4],a[5], a[6],a[7], a[8],a[9]);

  fprintf(stderr,"Initial temperature: %f\tfinal temperature: %f\n", t0, t);
  fprintf(stderr,"Estimated minimum at: ");
  for (i = 0; i < local_nparam; i++)
    fprintf(stderr,"%g\t", a[i]);
  fprintf(stderr,"\t(energy = %g)\n", z);
#endif

  /* Below is commented out. To be honest its not clear to me what xsh_SAoptimum was ever supposed to do, however it is clear that it changes a[ii] from the values that gave the best solution during the anneal, so that the output solution is then different (and usually worse). Better to leave it out then */
  /*xsh_SAoptimum( a );
  printf("aft opt %lf %lf %lf %lf %lf \n",a[0], a[1],a[2], a[3],a[4]);
  z = xsh_3_energy(a);
  printf("aft energy %lf %lf %lf %lf %lf \n",a[0], a[1],a[2], a[3],a[4]);

  fprintf(stderr,"Best minimum at: ");
  for (i = 0; i < local_nparam; i++)
    fprintf(stderr,"%g\t", a[i]);
    fprintf(stderr,"\t(energy = %g)\n", z);*/

  conf_tab = xsh_model_io_output_cfg(local_p_xs);
  xsh_3_output_data(a); 

  for (ii = 0; ii < nparam; ii++)
  {
    abest[ii]=local_p_abest[ii];
  }
  cpl_free(a);
  xsh_report_cpu( stderr, NULL );
  
 cleanup:
  if(cpl_error_get_code() != CPL_ERROR_NONE) {
     cpl_free(a);
     xsh_SAfree();
    return NULL;
  } else {
     xsh_SAfree();
    return conf_tab ;
  }
}

void xsh_3_output_data(double *a)
{
  static int counter;
  //vec detvec;
  int ii;

  double quad_diff; 
 
  /*for (ii=0; ii<local_nparam; ii++) {
    xsh_3_assign(local_p_aname[ii],local_p_abest[ii]+((local_p_amax[ii]-local_p_amin[ii])/2.0)*a[ii]);
    printf("%lf ",a[ii]);
    }*/

  a[0]=a[0]+0.0;
  xsh_3_init(local_p_xs);

  quad_diff=0;
  for (ii = 0; ii < size; ii++) {
    local_p_xs->es_y_tot=local_p_xs->es_y+local_p_xs->slit_scale*local_p_xs->slit[sp_array[ii]];
    mm=p_obsorder[ii];
    xsh_3_init(local_p_xs);
    xsh_3_eval(p_wl[ii],mm,ref,local_p_xs);
    xsh_3_detpix(local_p_xs);
    quad_diff+=
      ((p_obsx[ii]-local_p_xs->xpospix)*
       (p_obsx[ii]-local_p_xs->xpospix)+
       (p_obsy[ii]-local_p_xs->ypospix)*
       (p_obsy[ii]-local_p_xs->ypospix));

#ifdef DEBUG 
    printf("%d  %lf %lf  %lf %lf  %lf %lf  %d %d %d  %lf  %lf\n",
	   ii,p_obsx[ii]-local_p_xs->xpospix,
	   p_obsy[ii]-local_p_xs->ypospix,p_obsx[ii],
	   local_p_xs->xpospix,p_obsy[ii],local_p_xs->ypospix,
	   p_obsarm[ii],p_obsorder[ii], sp_array[ii], p_obsf[ii], p_wl[ii]*1000.0);
#endif

    //    printf("%lf\n",quad_diff);
    counter++;
  }
#ifdef DEBUG 
  printf("%lf\n",quad_diff);
#endif
  return;
}

/* evaluate the sum squared error, the "energy" */
float xsh_3_energy(double *a) {
  static int flux_wt;
  //FILE * tempc; 
  static int counter;
  static int first_time;
  static float bestyet;
  static int first_ann_flag;
  double newval[100];
  double size_use=0;
  double blaze_wav=0.;
  double blaze_ref=0.;
  double blaze_off=0.;
  double val_max=0.;
  double x_max=0.;
  double y_max=0.;
  double fw_max=0.;
  //float ** plotout=xsh_alloc2Darray_f(size,6);
 
  int ii=0;
  float sum_nw = 0.0, val = 0.0;
  float sum_fw = 0.0, val_fw = 0.0;
  float sum_x = 0.0, val_x = 0.0;
  float sum_y = 0.0, val_y = 0.0;
  float sum = 0.0;

  if (first_ann_flag==0) {
    if (size>33) {
      first_ann_flag=1;
      first_time=0;
      counter=0;
    }
  }
  //  plot=fopen("plot.dat","a+");    
  double sin_min_nug_div_sg=(sin(-local_p_xs->nug))/local_p_xs->sg;
  for (ii=0; ii<local_nparam; ii++) {
    if(first_time >0) {
      newval[ii]=local_p_abest[ii]+((local_p_amax[ii]-local_p_amin[ii])/2.0)*a[ii];
    }
    else {
      newval[ii]=local_p_abest[ii];
    }
    if (newval[ii]>local_p_amax[ii] || newval[ii]<local_p_amin[ii]) {
      sum_nw=HUGE_VAL;
      sum_fw=HUGE_VAL;
    }
    xsh_3_assign(local_p_aname[ii],newval[ii]);
  }

  blaze_off=0.0;
  for (mm=local_p_xs->morder_min;mm<=local_p_xs->morder_max;mm+=1) {
    blaze_wav=2.0*sin_min_nug_div_sg/mm;
    if (local_p_xs->arm==1) {
      //blaze_ref=1.6180339887498949/(mm*99.4);
      blaze_ref = 0.0162780076852276/mm;
    }
    else if (local_p_xs->arm==0) {
      //blaze_ref=1.3322840971595746/(mm*180.0);
      blaze_ref=0.0074015783175532/mm;
    }
    else if (local_p_xs->arm==2) {
      //blaze_ref=1.44030324281136/(mm*55.0);
      blaze_ref = 0.0261873316874793/mm;
    }
    if (fabs(blaze_wav-blaze_ref)>blaze_wav/200.0) {
      //printf("out %lf %d %lf %lf %lf \n",blaze_wav,mm,(blaze_wav-blaze_ref)*500,local_p_xs->nug, local_p_xs->sg);
      sum_nw=HUGE_VAL;
      sum_fw=HUGE_VAL;
    }
    else {
      double tmpval = fabs(blaze_wav-blaze_ref);
      if (tmpval>blaze_off) {
	blaze_off=tmpval;
      }
    }
  }
  xsh_3_init(local_p_xs);

  val_max=0.0;
  fw_max=0.0;
  for (ii = 0; ii < size; ii++) {
    if (sum_nw<HUGE_VAL) {
      local_p_xs->es_y_tot=local_p_xs->es_y+local_p_xs->slit_scale*local_p_xs->slit[sp_array[ii]];
      mm=p_obsorder[ii];

      if (local_p_xs->arm==1) {
	blaze_wav=2.0*sin_min_nug_div_sg/mm;
	//blaze_ref=1.6180339887498949/(mm*99.4);
  blaze_ref = 0.0162780076852276/mm;
      }
      else if (local_p_xs->arm==0) {
	blaze_wav=2.0*sin_min_nug_div_sg/mm;
	//blaze_ref=1.3322840971595746/(mm*180.0);
	blaze_ref=0.0074015783175532/mm;
      }

      xsh_3_init(local_p_xs);

      xsh_3_eval(p_wl[ii],mm,ref,local_p_xs);
      xsh_3_detpix(local_p_xs);
      if (local_p_xs->chippix[0]==1) {
        val_x=p_obsx[ii]-local_p_xs->xpospix;
        if (val_x<0.0) val_x=-val_x;

        val_y=p_obsy[ii]-local_p_xs->ypospix;
        if (val_y<0.0) val_y=-val_y;

	      val=(val_x*val_x+val_y*val_y);
	      val_fw=val*p_obsf[ii];

        //printf("%d  %lf %f    obsx %lf   modx %lf  obsy %lf   mody %lf %lf  \n",ii,1000.0*p_wl[ii],val,p_obsx[ii],local_p_xs->xpospix,p_obsy[ii],local_p_xs->ypospix,local_p_xs->es_y);
        //printf("%4.4lf   %4.4lf\n", local_p_xs->xpospix, local_p_xs->ypospix);
        /*plotout[ii][0]=(float)(local_p_xs->chippix[0]);
        plotout[ii][1]=sqrt(val);
        plotout[ii][2]=p_obsx[ii]-local_p_xs->xpospix;
        plotout[ii][3]=p_obsy[ii]-local_p_xs->ypospix;
        plotout[ii][4]=local_p_xs->ypospix;
        plotout[ii][5]=local_p_xs->xpospix+local_p_xs->chipx[local_p_xs->chippix[0]]/local_p_xs->pix;*/
      }
      else {
	val=BIG_VAL;
	val_fw=BIG_VAL;
      }
      if (val>val_max && val<BIG_VAL) {
	val_max=val;
	fw_max=val_fw;
	x_max=val_x;
	y_max=val_y;
      }
      sum_nw += val;
      sum_fw += val_fw;
      sum_x +=val_x;
      sum_y +=val_y;
      //printf("%d   %f    %lf    %f    %lf    %lf %d %d\n",ii,val,p_obsy[ii],local_p_xs->xdet,p_obsx[ii],local_p_xs->ydet,p_obsarm[ii],local_p_xs->chippix[0]);
      /*if(first_time==0)
        printf("%4.4lf   %4.4lf   %4.4lf   %4.4lf \n",p_obsx[i],x,p_obsy[i],y);*/
      //printf("%f \n",val);
    }
  }
  if (size>4 && val_max>0.5) {
    sum_nw-=val_max;
    sum_fw-=fw_max;
    sum_x-=x_max;
    sum_y-=y_max;
    size_use=(float)(size-1);
  }
  else {
    size_use=(float)(size);
  }
  if (flux_wt==2) {
    sum=val_max;
    size_use=1.0;
  }
  else if (flux_wt==1) {
    sum=sum_fw;
  }
  else {
    sum=sum_nw;
  }

  if (sqrt(sum/size_use)<bestyet && sum>0.0) {
#ifdef DEBUG
    xsh_msg("it: %d blaze off %lf nw %lf fw %lf",counter,blaze_off*1000000.0, sqrt(sum_nw/size_use), sqrt(sum_fw/size_use));
    xsh_msg("x %lf y %lf max %lf T %lf last %lf", sum_x/size_use, sum_y/size_use, sqrt(val_max), local_p_xs->temper, bestyet);
    for (ii=0; ii<local_nparam; ii++) {
      xsh_msg("%s  %f  %f %f  %f", (local_p_all_par+local_p_aname[ii])->name, newval[ii],local_p_amax[ii],local_p_amin[ii],2.0*((newval[ii]-local_p_amin[ii])/(local_p_amax[ii]-local_p_amin[ii]))-1.0);
    }
    //xsh_model_io_output_cfg_txt(local_p_xs);
#endif 
    xsh_msg("Iteration No./10: %d; Mean x residual: %f; Mean y residual: %f", counter/10, sum_x/size_use, sum_y/size_use);

    //printf("%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf \n",a[0],a[1],a[2],a[3],a[4],a[5], a[6],a[7], a[8],a[9]);
    bestyet=sqrt(sum/size_use);
    if (bestyet<80.0) {
      xsh_SAiterations(400);
      //printf("%d %lf %lf %lf\n",mm, p_wl[ii]*1000.0,local_p_xs->xdet,local_p_xs->ydet);

      /*      for (ii = 0; ii < size; ii++) {
        fprintf(plot,"%d %d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf \n",counter, ii,  p_wl[ii], plotout[ii][0], plotout[ii][1], plotout[ii][2], plotout[ii][3], plotout[ii][4], plotout[ii][5], local_p_xs->es_x ,local_p_xs->es_y,local_p_xs->fcp,local_p_xs->mup1/DEG2RAD,local_p_xs->nup1/DEG2RAD,local_p_xs->taup1/DEG2RAD,local_p_xs->mup2/DEG2RAD,local_p_xs->nup2/DEG2RAD,local_p_xs->taup2/DEG2RAD, local_p_xs->mug/DEG2RAD, local_p_xs->nug/DEG2RAD, local_p_xs->taug/DEG2RAD,local_p_xs->fk,local_p_xs->mud/DEG2RAD, local_p_xs->nud/DEG2RAD,local_p_xs->taud/DEG2RAD,local_p_xs->offx,local_p_xs->offy);
        //fprintf(plot,"%d %d %lf %lf %lf %lf %lf %lf %lf \n", counter, ii,  p_wl[ii],plotout[ii][0], plotout[ii][1], plotout[ii][2], plotout[ii][3], plotout[ii][4], plotout[ii][5]);
        }*/
    }
    /*if (bestyet<60.0 && flux_wt==3) {
      bestyet=sqrt(val_max);
      flux_wt=2;
      }*/
  }
  counter++;
  if(first_time==0) {
    first_time++;
    bestyet=1000000;
    flux_wt=0;
  }
  //fclose(plot); 
  return sum;
  //  xsh_free2Darray_f(plotout,size);
        /*}*/
}

void xsh_3_assign(int loc, double val)
{
  int compa,kk,indlen;
  char tempstr[10];
  compa=strncmp((local_p_all_par+loc)->name,"temper",6);
  if (compa==0) local_p_xs->temper=val;
  compa=strncmp((local_p_all_par+loc)->name,"t_ir_p2",7);
  if (compa==0) local_p_xs->t_ir_p2=val;
  compa=strncmp((local_p_all_par+loc)->name,"t_ir_p3",7);
  if (compa==0) local_p_xs->t_ir_p3=val;
  compa=strncmp((local_p_all_par+loc)->name,"es_x",4);
  if (compa==0) local_p_xs->es_x=val;
  compa=strncmp((local_p_all_par+loc)->name,"es_y",4);
  if (compa==0) local_p_xs->es_y=val;
  compa=strncmp((local_p_all_par+loc)->name,"mues",4);
  if (compa==0) local_p_xs->mues=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"nues",4);
  if (compa==0) local_p_xs->nues=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"taues",5);
  if (compa==0) local_p_xs->taues=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"slit_scale",10);
  if (compa==0) local_p_xs->slit_scale=val;
  compa=strncmp((local_p_all_par+loc)->name,"es_s",4);
  if (compa==0) local_p_xs->es_s=val;
  compa=strncmp((local_p_all_par+loc)->name,"es_w",4);
  if (compa==0) local_p_xs->es_w=val;
  compa=strncmp((local_p_all_par+loc)->name,"fcol",4);
  if (compa==0) local_p_xs->fcol=val;
  compa=strncmp((local_p_all_par+loc)->name,"cmup1",5);
  if (compa==0) local_p_xs->cmup1=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"mup1",4);
  if (compa==0) local_p_xs->mup1=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"nup1",4);
  if (compa==0) local_p_xs->nup1=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"taup1",5);
  if (compa==0) local_p_xs->taup1=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"mup2",4);
  if (compa==0) local_p_xs->mup2=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"nup2",4);
  if (compa==0) local_p_xs->nup2=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"taup2",5);
  if (compa==0) local_p_xs->taup2=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"mup3",4);
  if (compa==0) local_p_xs->mup3=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"nup3",4);
  if (compa==0) local_p_xs->nup3=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"taup3",5);
  if (compa==0) local_p_xs->taup3=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"mup4",4);
  if (compa==0) local_p_xs->mup4=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"nup4",4);
  if (compa==0) local_p_xs->nup4=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"taup4",5);
  if (compa==0) local_p_xs->taup4=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"mup5",4);
  if (compa==0) local_p_xs->mup5=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"nup5",4);
  if (compa==0) local_p_xs->nup5=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"taup5",5);
  if (compa==0) local_p_xs->taup5=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"mup6",4);
  if (compa==0) local_p_xs->mup6=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"nup6",4);
  if (compa==0) local_p_xs->nup6=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"taup6",5);
  if (compa==0) local_p_xs->taup6=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"mug",3);
  if (compa==0) local_p_xs->mug=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"nug",3);
  if (compa==0) local_p_xs->nug=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"taug",4);
  if (compa==0) local_p_xs->taug=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"sg",2);
  if (compa==0) local_p_xs->sg=val;
  compa=strncmp((local_p_all_par+loc)->name,"fdet",4);
  if (compa==0) local_p_xs->fdet=val;
  compa=strncmp((local_p_all_par+loc)->name,"mud",3);
  if (compa==0) local_p_xs->mud=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"nud",3);
  if (compa==0) local_p_xs->nud=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"taud",4);
  if (compa==0) local_p_xs->taud=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"pix",3);
  if (compa==0) {
    local_p_xs->pix=val;
    local_p_xs->pix_X=local_p_xs->pix;
    local_p_xs->pix_Y=local_p_xs->pix;
  }
  compa=strncmp((local_p_all_par+loc)->name,"chipx",5);
  if (compa==0) local_p_xs->chipx=val;
  compa=strncmp((local_p_all_par+loc)->name,"chipy",5);
  if (compa==0) local_p_xs->chipy=val;
  compa=strncmp((local_p_all_par+loc)->name,"chiprot",7);
  if (compa==0) local_p_xs->chiprot=val*DEG2RAD;
  compa=strncmp((local_p_all_par+loc)->name,"pc_x_xx",7);
  if (compa==0) local_p_xs->pc_x_xx=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_x_x1",7);
  if (compa==0) local_p_xs->pc_x_x1=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_x_yy",7);
  if (compa==0) local_p_xs->pc_x_yy=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_x_y1",7);
  if (compa==0) local_p_xs->pc_x_y1=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_x_xy",7);
  if (compa==0) local_p_xs->pc_x_xy=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_x_x3",7);
  if (compa==0) local_p_xs->pc_x_x3=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_x_x2y",8);
  if (compa==0) local_p_xs->pc_x_x2y=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_x_y2x",8);
  if (compa==0) local_p_xs->pc_x_y2x=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_x_y3",7);
  if (compa==0) local_p_xs->pc_x_y3=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_y_xx",7);
  if (compa==0) local_p_xs->pc_y_xx=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_y_x1",7);
  if (compa==0) local_p_xs->pc_y_x1=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_y_yy",7);
  if (compa==0) local_p_xs->pc_y_yy=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_y_y1",7);
  if (compa==0) local_p_xs->pc_y_y1=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_y_xy",7);
  if (compa==0) local_p_xs->pc_y_xy=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_y_x3",7);
  if (compa==0) local_p_xs->pc_y_x3=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_y_x2y",8);
  if (compa==0) local_p_xs->pc_y_x2y=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_y_y2x",8);
  if (compa==0) local_p_xs->pc_y_y2x=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc_y_y3",7);
  if (compa==0) local_p_xs->pc_y_y3=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc4_x_xy3",9);
  if (compa==0) local_p_xs->pc4_x_xy3=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc4_x_x3y",9);
  if (compa==0) local_p_xs->pc4_x_x3y=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc4_x_x2y2",10);
  if (compa==0) local_p_xs->pc4_x_x2y2=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc4_x_x4",8);
  if (compa==0) local_p_xs->pc4_x_x4=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc4_x_y4",8);
  if (compa==0) local_p_xs->pc4_x_y4=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc4_y_xy3",9);
  if (compa==0) local_p_xs->pc4_y_xy3=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc4_y_x3y",9);
  if (compa==0) local_p_xs->pc4_y_x3y=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc4_y_x2y2",10);
  if (compa==0) local_p_xs->pc4_y_x2y2=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc4_y_x4",8);
  if (compa==0) local_p_xs->pc4_y_x4=val;
  compa=strncmp((local_p_all_par+loc)->name,"pc4_y_y4",8);
  if (compa==0) local_p_xs->pc4_y_y4=val;
  compa=strncmp((local_p_all_par+loc)->name,"ca_x0",5);
  if (compa==0) local_p_xs->ca_x0=val;
  compa=strncmp((local_p_all_par+loc)->name,"ca_x1",5);
  if (compa==0) local_p_xs->ca_x1=val;
  compa=strncmp((local_p_all_par+loc)->name,"ca_y0",5);
  if (compa==0) local_p_xs->ca_y0=val;
  compa=strncmp((local_p_all_par+loc)->name,"ca_y1",5);
  if (compa==0) local_p_xs->ca_y1=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_x1",5);
  if (compa==0) local_p_xs->d2_x1=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_x2",5);
  if (compa==0) local_p_xs->d2_x2=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_x3",5);
  if (compa==0) local_p_xs->d2_x3=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_y1x0",7);
  if (compa==0) local_p_xs->d2_y1x0=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_y1x1",7);
  if (compa==0) local_p_xs->d2_y1x1=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_y1x2",7);
  if (compa==0) local_p_xs->d2_y1x2=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_y1x3",7);
  if (compa==0) local_p_xs->d2_y1x3=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_y2x0",7);
  if (compa==0) local_p_xs->d2_y2x0=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_y2x1",7);
  if (compa==0) local_p_xs->d2_y2x1=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_y2x2",7);
  if (compa==0) local_p_xs->d2_y2x2=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_y2x3",7);
  if (compa==0) local_p_xs->d2_y2x3=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_y3x0",7);
  if (compa==0) local_p_xs->d2_y3x0=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_y3x1",7);
  if (compa==0) local_p_xs->d2_y3x1=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_y3x2",7);
  if (compa==0) local_p_xs->d2_y3x2=val;
  compa=strncmp((local_p_all_par+loc)->name,"d2_y3x3",7);
  if (compa==0) local_p_xs->d2_y3x3=val;
  for (kk=0;kk<9;kk++) {
    sprintf(tempstr,"slit[%d]",kk);
    indlen=strlen(tempstr);
    compa=strncmp((local_p_all_par+loc)->name,tempstr,indlen);
    if (compa==0) local_p_xs->slit[kk]=val;
  }
  compa=strncmp((local_p_all_par+loc)->name,"offx",4);
  if (compa==0) local_p_xs->offx=val;
  compa=strncmp((local_p_all_par+loc)->name,"offy",4);
  if (compa==0) local_p_xs->offy=val;
  compa=strncmp((local_p_all_par+loc)->name,"flipx",5);
  if (compa==0) local_p_xs->flipx=val;
  compa=strncmp((local_p_all_par+loc)->name,"flipy",5);
  if (compa==0) local_p_xs->flipy=val;
}
/**@}*/
