! Module   : goettingen_to_specint
! Purpose  : create specint files from Goettingen spectra files
!
! Copyright 2022 Rich Townsend & The MSG Team
!
! This file is part of MSG. MSG 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, version 3.
!
! MSG 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 <http://www.gnu.org/licenses/>.

#:include 'forum.inc'

program goettingen_to_specint

   ! Uses

   use forum_m
   use msg_m

   use tools_utils_m

   use ISO_FORTRAN_ENV

   ! No implicit typing

   implicit none

   ! Variables

   character(:), allocatable :: fits_file_name
   character(:), allocatable :: wave_type
   character(:), allocatable :: specint_file_name

   character(LABEL_LEN)        :: head_labels(4)
   real(RD)                    :: head_values(4)
   real(RD), allocatable       :: F(:)
   character(LABEL_LEN)        :: axis_labels(4)
   real(RD)                    :: axis_values(4)
   integer                     :: n_lam
   real(RD), allocatable       :: I(:,:)
   class(range_t), allocatable :: range
   type(limb_specint_t)        :: specint
   type(hdf5io_t)              :: hdf5io
   type(hdf5io_t)              :: hdf5io_labels
   integer                     :: j

   ! Read command-line arguments

   @:ASSERT(n_arg() == 3, 'Syntax: goettingen_to_specint fits_file_name wave_type specint_file_name')

   call get_arg(1, fits_file_name)
   call get_arg(2, wave_type)
   call get_arg(3, specint_file_name)

   ! Read data from the input file
 
   head_labels = ['PHXTEFF ', 'PHXLOGG ', 'PHXM_H  ', 'PHXALPHA']

   call read_fits_file(fits_file_name, F, head_labels, head_values)

   axis_labels =  ['Teff      ', 'log(g)    ', '[Fe/H]    ',  '[alpha/Fe]']
   axis_values = head_values

   ! Set up the bin-averaged intensity (also converting from
   ! erg/cm2/s/cm2 to erg/cm2/s/A)

   n_lam = SIZE(F)

   allocate(I(1,n_lam-1))

   I(1,:) = 0.5_RD*(F(:n_lam-1) + F(2:))/PI*1E-8_RD

   ! Set up the range

   select case(wave_type)
   case('HiRes')
      call create_range_hires(range)
   case('MedRes-A1')
      call create_range_medres_a1(range)
   case('MedRes-R10000')
      call create_range_medres_r10000(range)
   case default
      @:ABORT('invalid wave_type')
   end select

   ! Create specint

   specint = limb_specint_t(I, [1._RD], range, limb_t('CONST'), precise=.FALSE.)

   ! Write it

   hdf5io = hdf5io_t(specint_file_name, CREATE_FILE)

   call specint%write(hdf5io)

   hdf5io_labels = hdf5io_t(hdf5io, 'labels')

   do j = 1, SIZE(axis_labels)
      call hdf5io_labels%write_attr(axis_labels(j), axis_values(j))
   end do

   call hdf5io_labels%final()
      
   call hdf5io%final()

   ! Finish

contains

   subroutine create_range_medres_a1(range)

      class(range_t), allocatable, intent(out) :: range

      ! Set up range (this may need updating if the Goettingen grids
      ! evolve)

      range = lin_range_t(3000._RD, 0.1_RD, 70000)

      ! Finish

      return

   end subroutine create_range_medres_a1

   !****

   subroutine create_range_medres_r10000(range)

      class(range_t), allocatable, intent(out) :: range

      ! Set up range (this may need updating if the Goettingen grids
      ! evolve)

      range = log_range_t(LOG(3000._RD), 1E-5_RD, 212027)

      ! Finish

      return

   end subroutine create_range_medres_r10000

   !****

   subroutine create_range_hires(range)

      class(range_t), allocatable, intent(out) :: range

      ! Set up range (this may need updating if the Goettingen grids
      ! evolve)

      range = comp_range_t([                        &
           lin_range_t(500._RD, 0.1_RD, 25000),     &
           lin_range_t(3000._RD, 0.006_RD, 333332), &
           lin_range_t(5000._RD, 0.01_RD, 500000),  &
           lin_range_t(10000._RD, 0.02_RD, 250000), &
           lin_range_t(15000._RD, 0.03_RD, 166667), &
           lin_range_t(20000._RD, 0.04_RD, 125000), &
           lin_range_t(25000._RD, 0.125_RD, 40000), &
           lin_range_t(30000._RD, 0.15_RD, 33334),  &
           lin_range_t(35000._RD, 0.175_RD, 28572), &
           lin_range_t(40000._RD, 0.2_RD, 25000),   &
           lin_range_t(45000._RD, 0.225_RD, 22223), &
           lin_range_t(50000._RD, 0.25_RD, 20000)])

      ! Finish

      return

   end subroutine create_range_hires

end program goettingen_to_specint

