!
! This module contains subroutines that estimate uncertains
! in the stellar parameters and chemical abundances.
!
! It is part of the program SP_Ace, which derives stellar parameters,
! such as gravity, temperature, and element abundances from optical
! stellar spectra, assuming Local Thermodynamic Equilibrium (LTE)
! and 1D stellar atmosphere models.
!
! Copyright (C) 2016 Corrado Boeche
!
! 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 3 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, see .
MODULE uncertains2
USE num_type
USE share, ONLY: up_ABD,lo_ABD
USE utils, ONLY: ABD_mask,write_ABD_mask
IMPLICIT NONE
INTEGER (I1B) :: pos
REAL (DP), DIMENSION(3) :: up_TGM,lo_TGM
REAL (DP), DIMENSION(3), PARAMETER :: prob=(/3.53,6.25,8.02/)!for 3 deg of freedom, correspond to %68.3,%90,%95.4
REAL(DP),DIMENSION(5) :: temp_gridS,logg_gridS,met_gridS
LOGICAL :: flag_lim,flag_limS,flag_move,flag_TGM
CONTAINS
!############################
REAL(DP) FUNCTION chisq_tgm_e(x)
USE make_model, ONLY: make_model_TGM
USE share, ONLY: dimsp,TGM,f_sp_norm,sig_noise,TGM_prox
USE utils, ONLY: find_proxS
IMPLICIT NONE
REAL (DP), DIMENSION(3), INTENT(IN) :: x
REAL (DP), DIMENSION(dimsp) :: model
REAL (DP), DIMENSION(5) :: xTGM
xTGM(1:3)=x(1:3)
xTGM(4:5)=TGM(4:5)
!find the closest point in the sub-grid and verify if TGM is inside the grid
CALL find_proxS(xTGM,temp_gridS,logg_gridS,met_gridS,TGM_prox,&
&flag_lim,flag_limS,flag_move)
IF(flag_limS) THEN
CALL update_grid(xTGM)
END IF
CALL make_model_TGM(model,xTGM)
chisq_tgm_e=SUM(((f_sp_norm-model)/sig_noise)**2)
END FUNCTION chisq_tgm_e
!############################
REAL(DP) FUNCTION chisq_abd_e(x)
USE make_model, ONLY: make_model_ABDerr
USE share, ONLY: dimsp,dim_ele,TGM,ABD,f_sp_norm,sig_noise
USE share, ONLY: dimsp,TGM,f_sp_norm,sig_noise,TGM_prox
USE utils, ONLY: find_proxS
IMPLICIT NONE
REAL (DP), DIMENSION(3), INTENT(IN) :: x
REAL (DP), DIMENSION(dimsp) :: model
REAL (DP), DIMENSION(5) :: parTGM
REAL (DP), DIMENSION(dim_ele) :: parABD
parTGM(1:2)=x(1:2)
parTGM(3:5)=TGM(3:5)
!find the closest point in the sub-grid and verify if TGM is inside the grid
CALL find_proxS(parTGM,temp_gridS,logg_gridS,met_gridS,TGM_prox,&
&flag_lim,flag_limS,flag_move)
IF(flag_limS) THEN
CALL update_grid(parTGM)
END IF
parABD=ABD
parABD(pos)=x(3)
CALL make_model_ABDerr(model,parTGM,parABD)
chisq_abd_e=SUM(((f_sp_norm-model)/sig_noise)**2)
END FUNCTION chisq_abd_e
!############################
SUBROUTINE update_grid(TGM_in)
USE read_GCOG, ONLY: load_GCOG_lin
USE share, ONLY: TGM_prox,sigma,coeff_ew_lin
USE func_poly, ONLY: ew_lin_interp
USE utils, ONLY: find_prox,find_proxS,make_gridS,select_lines
IMPLICIT NONE
REAL (DP), DIMENSION(:), INTENT(IN) :: TGM_in
REAL(DP), DIMENSION(4) :: pars
!make a new subgrids
CALL find_prox(TGM_in,TGM_prox)
CALL make_gridS(TGM_prox,temp_gridS,logg_gridS,met_gridS)
!find the closest point in the sub-grid and verify if TGM is inside the grid
CALL find_proxS(TGM_in,temp_gridS,logg_gridS,met_gridS,TGM_prox,&
&flag_lim,flag_limS,flag_move)
IF(flag_limS) THEN
! allocate and upload the table coeff_4deg which contains the coefficient
! to construct the polynomial GCOG
CALL load_GCOG_lin(TGM_prox(1),TGM_prox(2),TGM_prox(3))
pars=(/TGM_in(1),TGM_in(2),TGM_in(3),0._dp/)
CALL select_lines(ew_lin_interp,coeff_ew_lin,pars,sigma,.FALSE.)
END IF
END SUBROUTINE update_grid
!############################
SUBROUTINE TGM_e(chisq_best)
USE share, ONLY: TGM
USE data_lib, ONLY: temp_gridL,logg_gridL,met_gridL
IMPLICIT NONE
REAL(DP), INTENT(IN) :: chisq_best
REAL(DP), DIMENSION(3) :: TGM_best,TGM_test,step,max_step
REAL(DP), DIMENSION(9,3) :: grid
REAL(DP) :: chisq
INTEGER (I2B) :: i,j
REAL(DP) :: chisq_lim,zoom_par
LOGICAL :: flag,flag_one
chisq_lim=chisq_best+prob(1)
CALL make_grid(pos,grid)
!estimate the upper Teff, logg, [M/H] uncertains
zoom_par=1.
max_step=(/100.,0.2,0.1/);
TGM_best=TGM(1:3)
flag_one=.FALSE.
DO j=1,200
IF(zoom_par<0.05) EXIT
flag=.FALSE.
DO i=1,9
step=grid(i,:)*max_step*zoom_par
TGM_test=TGM_best(1:3)+step
!do it only for the points inside the parameter grid
IF(TGM_test(1)MINVAL(temp_gridL)&
&.AND.TGM_test(2)MINVAL(logg_gridL)&
&.AND.TGM_test(3)MINVAL(met_gridL)) THEN
chisq=chisq_tgm_e(TGM_test)
IF(chisqTGM_best(pos)) THEN
TGM_best=TGM_test
flag=.TRUE.
flag_one=.TRUE.
EXIT
ELSE
END IF
END IF
END DO
IF(.not.flag) zoom_par=zoom_par*0.5
END DO
IF(.NOT.flag_one) THEN
up_TGM(pos)=100000
ELSE
up_TGM(pos)=TGM_best(pos)
END IF
CALL update_grid(TGM)
!estimate the lower Teff, logg, [M/H] uncertains
zoom_par=1.
TGM_best=TGM(1:3)
flag_one=.FALSE.
DO j=1,200
IF(zoom_par<0.01) EXIT
flag=.FALSE.
DO i=1,9
step=grid(i,:)*max_step*zoom_par
TGM_test=TGM_best(1:3)-step
!do it only for the points inside the parameter grid
IF(TGM_test(1)MINVAL(temp_gridL)&
&.AND.TGM_test(2)MINVAL(logg_gridL)&
&.AND.TGM_test(3)MINVAL(met_gridL)) THEN
chisq=chisq_tgm_e(TGM_test)
IF(chisqMINVAL(temp_gridL)&
&.AND.TGM_test(2)MINVAL(logg_gridL)) THEN
chisq=chisq_abd_e(TGM_test)
IF(chisqTGM_best(3)) THEN
TGM_best=TGM_test
flag=.TRUE.
flag_one=.TRUE.
EXIT
END IF
END IF
END DO
IF(.not.flag) zoom_par=zoom_par*0.5
IF(TGM_best(3)>0.8) THEN
TGM_best(3)=10.
EXIT
END IF
END DO
IF(.NOT.flag_one) THEN
up_ABD(pos)=9.
ELSE
up_ABD(pos)=TGM_best(3)
END IF
CALL update_grid(TGM)
!estimate the lower [El/m] uncertains
zoom_par=1.
TGM_best=TGM(1:3)
TGM_best(3)=ABD(pos)
flag_one=.FALSE.
DO j=1,200
IF(zoom_par<0.01) EXIT
flag=.FALSE.
DO i=1,9
step=grid(i,:)*max_step*zoom_par
TGM_test=TGM_best(1:3)-step
IF(TGM_test(1)MINVAL(temp_gridL)&
&.AND.TGM_test(2)MINVAL(logg_gridL)) THEN
chisq=chisq_abd_e(TGM_test)
IF(chisq