/*===========================================================================
  Copyright (C) 1995-2009 European Southern Observatory (ESO)
 
  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., 675 Massachusetss Ave, Cambridge, 
  MA 02139, USA.
 
  Corresponding concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY

.VERSION
 090826         last modif

===========================================================================*/


#include <math.h>
#include <stdio.h>
#include <UxLib.h>
#include <globaldef.h>
#include <model.h>


extern void c_minmax(), plot_xy(), end_graphic1();
extern void set_range(), conv_photon();





void	do_convo()
{
extern	struct s_trans	T;
extern	struct s_mod	M;
extern  float   XWmin,XWmax;
extern  int	Nsky;
extern  float   Xsky[],Ysky[];
extern  int	Nspec;
extern  float   Xspec[],Yspec[];
extern  int	Natmos;
extern  float   Xatmos[],Yatmos[];
extern  int	Ngrism;
extern  float   Xgrism[],Ygrism[];
extern  int	Nmir;
extern  float   Xmir[],Ymir[];
extern  int	Noptics;
extern  float   Xoptics[],Yoptics[];
extern  int	Nfilter;
extern  float   Xfilt[],Yfilt[];
extern  int	Nccd;
extern  float   Xccd[],Yccd[];
extern  float	Oxmi,Oxma,Oymi,Oyma;

register int	i;
int	idum=-5;
float	ysky[SPECMAX],yspec[SPECMAX];
float	xr[4000],yr[4000],yf,ys,sums,sumf,sumsf;
char	str[150], str1[40];
float	interpol(),poisson(),gauss();
float	xmi,xma,ymi,yma,ydiff;
float	snr;
char	am[10];


/* set the range of the calculation */
set_range();

if (T.resolution!=0.)
	M.nmax=(int)((XWmax-XWmin)/T.resolution);
else
	M.nmax=200.;

if (M.nmax>4000)
	{
	M.nmax=4000;
	fprintf(stderr,"WARNING: array too small, resolution reduced\r\n");
	};
for(i=0;i<M.nmax;i++)
        {
        xr[i]=XWmin+((float)i)/((float) (M.nmax-1))*(XWmax-XWmin);
        yr[i]=1.;
        };

if (T.iatmos !=0)
	{
        for(i=0;i<M.nmax;i++)
              yr[i]*=interpol(xr[i],Xatmos,Yatmos,Natmos);

	fprintf(stderr,"* atmosphere\r\n");
	};

if (T.imirror !=0)
    {
    for(i=0;i<M.nmax;i++)
        yr[i]*=interpol(xr[i],Xmir,Ymir,Nmir);
    fprintf(stderr,"* mirror\r\n");
    };

if (T.igrism !=0)
	{
	for(i=0;i<M.nmax;i++)
              yr[i]*=interpol(xr[i],Xgrism,Ygrism,Ngrism);
	fprintf(stderr,"* grism\r\n");
	};

if (T.ifilter !=0)
	{
	for(i=0;i<M.nmax;i++)
              yr[i]*=interpol(xr[i],Xfilt,Yfilt,Nfilter);
	fprintf(stderr,"* filter\r\n");
	};

if (T.ioptics !=0)
	{
	for(i=0;i<M.nmax;i++)
              yr[i]*=interpol(xr[i],Xoptics,Yoptics,Noptics);
	fprintf(stderr,"* optics\r\n");
	};

if (T.iccd !=0)
	{
	for(i=0;i<M.nmax;i++)
              yr[i]*=interpol(xr[i],Xccd,Yccd,Nccd);
	fprintf(stderr,"* ccd\r\n");
	};

if (T.ispectra !=0)
        conv_photon(Xspec,Yspec,yspec,Nspec);
if (T.isky !=0)
        conv_photon(Xsky,Ysky,ysky,Nsky);

if ((T.ispectra !=0)||(T.isky==1))
	{
	  if ((T.itimeSN==1)&&(T.resolution!=0.))
		{
		sums=0.; sumf=0.;

	      	if (T.isky==1)
			for(i=0;i<M.nmax;i++)
			   sums+=yr[i]*10.*T.resolution*T.surface
	                        *interpol(xr[i],Xsky,ysky,Nsky);

		if (T.ispectra !=0)
			for(i=0;i<M.nmax;i++)
			   sumf+=yr[i]*10.*T.resolution*T.surface
                                *interpol(xr[i],Xspec,yspec,Nspec);

		sums=sums/M.nmax;
		sumf=sumf/M.nmax;
		sumsf=sums+sumf;

		if (T.ispectra !=0)
		 T.etime=T.SN*T.SN*sumsf/2./sumf/sumf
		  *(1.+sqrt(1.+4*sumf*sumf/sumsf/sumsf*T.ron*T.ron/T.SN/T.SN));
		else
		 T.etime=T.SN*T.SN/2./sumsf
		  *(1.+sqrt(1.+4*T.ron*T.ron/T.SN/T.SN));

	  	sprintf(am,"%1.2f",T.etime);
	  	UxPutText(UxFindSwidget("tf_time"),am);
		}
	
	sumf=0.;
	sumsf=0;
	for(i=0;i<M.nmax;i++)
	  {
	  if (T.resolution!=0.)
/* pour avoir des ADU/pixel */	
	      {
	      ys=0.;yf=0.;
	      if (T.isky==1)
                      ys=yr[i]*10.*T.resolution*T.etime*T.surface
			*interpol(xr[i],Xsky,ysky,Nsky);
	      if (T.ispectra !=0)
	              yf=yr[i]*10.*T.resolution*T.etime*T.surface
			*interpol(xr[i],Xspec,yspec,Nspec);


	      sumf+=yf;
	      sumsf+=yf+ys;

	      yr[i]=(poisson((yf+ys),&idum)+gauss(T.ron,&idum))/T.einadu;

	      if (!strcmp(UxGetSet(UxFindSwidget("tg_extsky")),"true"))
		yr[i]-=ys/T.einadu;
	      }
          else
/* pour avoir des e-/A */	
	      {
	      ys=0.;yf=0.;
              if (T.isky==1)
                   ys=yr[i]*T.etime*T.surface*interpol(xr[i],Xsky,ysky,Nsky);
	      if (T.ispectra !=0)
              	   yf=yr[i]*T.etime*T.surface*interpol(xr[i],Xspec,yspec,Nspec);
	      yr[i]=ys+yf;
	      };
	  }

	  sumsf=sumsf/M.nmax;
	  sumf=sumf/M.nmax;
	  if (T.ispectra !=0)
		snr=sumf/sqrt(sumsf+T.ron*T.ron);
	  else
		snr=sumsf/sqrt(sumsf+T.ron*T.ron);


	if (T.resolution!=0.)
	{
	T.SN=snr;
	sprintf(am,"%1.2f",T.SN);
	UxPutText(UxFindSwidget("tf_SN"),am);
	}

	if (T.isky==1)
		fprintf(stderr,"* sky\r\n");

	if (T.ispectra!=0)
		fprintf(stderr,"* spectrum\r\n");
	};

c_minmax(xr,yr,M.nmax,&xmi,&xma,&ymi,&yma);

if ((T.ispectra ==0)&&(T.isky==0))
        {
sprintf(str1,"\1 Total Transmission");
sprintf(str,
  "TITLE=%20s;DTITL=%4.1f;LABX=%12s;LABY=%12s;DLABL=%4.1f;NGEOM;USER;BOLD;GRID;TIME;XSPACE=%1d;",
     str1, 2.0, "\1Wave [nm]", "\1 Transmission",1.0,0);

	ydiff=.05*(yma-ymi);
	yma+=ydiff;
	ymi-=ydiff;
	}
else
	{
	sprintf(str1,"\1 Received Flux");

if (T.resolution!=0.)
sprintf(str,
  "TITLE=%20s;DTITL=%4.1f;LABX=%12s;LABY=%12s;DLABL=%4.1f;NGEOM;USER;BOLD;GRID;TIME;XSPACE=%1d;",
     str1, 2.0, "\1Wave [nm]", "\1 Flux [ADU/pixel]",1.0,0);
else
sprintf(str,
  "TITLE=%20s;DTITL=%4.1f;LABX=%12s;LABY=%12s;DLABL=%4.1f;NGEOM;USER;BOLD;GRID;TIME;XSPACE=%1d;",
     str1, 2.0, "\1Wave [nm]", "\1 Flux [e-/A]",1.0,0);


/*	ymi=Min(0.,ymi);*/
	yma*=1.1;
	};

plot_xy(str,0,xr,yr,M.nmax,XWmin,XWmax,0.,yma);
end_graphic1();
Oxmi=xmi;
Oxma=xma;
Oymi=ymi;
Oyma=yma;

}
