main_rohsa Subroutine

public subroutine main_rohsa(data, std_cube, fileout, n_gauss, n_gauss_add, lambda_amp, lambda_mu, lambda_sig, lambda_var_amp, lambda_var_mu, lambda_var_sig, amp_fact_init, sig_init, maxiter_init, maxiter, m, noise, regul, descent, lstd, ustd, init_option, iprint, iprint_init)

Arguments

Type IntentOptional AttributesName
real(kind=xp), intent(in), dimension(:,:,:), allocatable:: data

initial fits data

real(kind=xp), intent(in), dimension(:,:), allocatable:: std_cube

standard deviation map fo the cube is given by the user

character(len=512), intent(in) :: fileout

name of the output result

integer :: n_gauss

number of gaussian to fit

integer, intent(in) :: n_gauss_add

number of gaussian to add at each step

real(kind=xp), intent(in) :: lambda_amp

lambda for amplitude parameter

real(kind=xp), intent(in) :: lambda_mu

lamnda for mean position parameter

real(kind=xp), intent(in) :: lambda_sig

lambda for dispersion parameter

real(kind=xp), intent(in) :: lambda_var_amp

lambda for amp dispersion parameter

real(kind=xp), intent(in) :: lambda_var_mu

lambda for mean position dispersion parameter

real(kind=xp), intent(in) :: lambda_var_sig

lambda for variance dispersion parameter

real(kind=xp), intent(in) :: amp_fact_init

times max amplitude of additional Gaussian

real(kind=xp), intent(in) :: sig_init

dispersion of additional Gaussian

integer, intent(in) :: maxiter_init

max iteration for L-BFGS-B alogorithm (init mean spectrum)

integer, intent(in) :: maxiter

max iteration for L-BFGS-B alogorithm

integer, intent(in) :: m

number of corrections used in the limited memory matrix by LBFGS-B

logical, intent(in) :: noise

if false --> STD map computed by ROHSA with lstd and ustd (if true given by the user)

logical, intent(in) :: regul

if true --> activate regulation

logical, intent(in) :: descent

if true --> activate hierarchical descent to initiate the optimization

integer, intent(in) :: lstd

lower bound to compute the standard deviation map of the cube (if noise .eq. false)

integer, intent(in) :: ustd

upper bound to compute the standrad deviation map of the cube (if noise .eq. false)

character(len=8), intent(in) :: init_option

Init ROHSA with the mean or the std spectrum

integer, intent(in) :: iprint

print option

integer, intent(in) :: iprint_init

print option init


Calls

proc~~main_rohsa~~CallsGraph proc~main_rohsa main_rohsa proc~mean_array mean_array proc~main_rohsa->proc~mean_array proc~dim2nside dim2nside proc~main_rohsa->proc~dim2nside proc~go_up_level go_up_level proc~main_rohsa->proc~go_up_level proc~set_stdmap set_stdmap proc~main_rohsa->proc~set_stdmap proc~header header proc~main_rohsa->proc~header proc~dim_data2dim_cube dim_data2dim_cube proc~main_rohsa->proc~dim_data2dim_cube proc~ender ender proc~main_rohsa->proc~ender proc~reshape_up reshape_up proc~main_rohsa->proc~reshape_up proc~mean_map mean_map proc~main_rohsa->proc~mean_map proc~std std proc~set_stdmap->proc~std proc~timestamp timestamp proc~header->proc~timestamp proc~ender->proc~timestamp

Called by

proc~~main_rohsa~~CalledByGraph proc~main_rohsa main_rohsa program~rohsa ROHSA program~rohsa->proc~main_rohsa

Contents

Source Code


Source Code

  subroutine main_rohsa(data, std_cube, fileout, n_gauss, n_gauss_add, lambda_amp, &
       lambda_mu, lambda_sig, lambda_var_amp, lambda_var_mu, lambda_var_sig, amp_fact_init, sig_init, &
       maxiter_init, maxiter, m, noise, regul, descent, lstd, ustd, init_option, iprint, iprint_init)
    
    implicit none
    
    logical, intent(in) :: noise           !! if false --> STD map computed by ROHSA with lstd and ustd (if true given by the user)
    logical, intent(in) :: regul           !! if true --> activate regulation
    logical, intent(in) :: descent         !! if true --> activate hierarchical descent to initiate the optimization
    integer, intent(in) :: n_gauss_add     !! number of gaussian to add at each step
    integer, intent(in) :: m               !! number of corrections used in the limited memory matrix by LBFGS-B
    integer, intent(in) :: lstd            !! lower bound to compute the standard deviation map of the cube (if noise .eq. false)
    integer, intent(in) :: ustd            !! upper bound to compute the standrad deviation map of the cube (if noise .eq. false)
    integer, intent(in) :: iprint          !! print option 
    integer, intent(in) :: iprint_init     !! print option init
    integer, intent(in) :: maxiter         !! max iteration for L-BFGS-B alogorithm
    integer, intent(in) :: maxiter_init    !! max iteration for L-BFGS-B alogorithm (init mean spectrum)
    real(xp), intent(in) :: lambda_amp     !! lambda for amplitude parameter
    real(xp), intent(in) :: lambda_mu      !! lamnda for mean position parameter
    real(xp), intent(in) :: lambda_sig     !! lambda for dispersion parameter
    real(xp), intent(in) :: lambda_var_amp !! lambda for amp dispersion parameter
    real(xp), intent(in) :: lambda_var_mu  !! lambda for mean position dispersion parameter
    real(xp), intent(in) :: lambda_var_sig !! lambda for variance dispersion parameter
    real(xp), intent(in) :: amp_fact_init  !! times max amplitude of additional Gaussian
    real(xp), intent(in) :: sig_init       !! dispersion of additional Gaussian

    character(len=8), intent(in)   :: init_option !!Init ROHSA with the mean or the std spectrum    
    character(len=512), intent(in) :: fileout   !! name of the output result

    integer :: n_gauss         !! number of gaussian to fit
    integer :: nside        !! size of the reshaped data \(2^{nside}\)
    integer :: n            !! loop index
    integer :: power        !! loop index

    real(xp), intent(in), dimension(:,:,:), allocatable :: data        !! initial fits data
    real(xp), intent(in), dimension(:,:), allocatable   :: std_cube    !! standard deviation map fo the cube is given by the user 

    real(xp), dimension(:,:,:), allocatable :: cube        !! reshape data with nside --> cube
    real(xp), dimension(:,:,:), allocatable :: cube_mean   !! mean cube over spatial axis
    real(xp), dimension(:,:,:), allocatable :: fit_params  !! parameters to optimize with cube mean at each iteration
    real(xp), dimension(:,:,:), allocatable :: grid_params !! parameters to optimize at final step (dim of initial cube)
    real(xp), dimension(:,:), allocatable :: std_map       !! standard deviation map fo the cube computed by ROHSA with lb and ub
    real(xp), dimension(:), allocatable :: std_spect       !! std spectrum of the observation
    real(xp), dimension(:), allocatable :: max_spect       !! max spectrum of the observation
    real(xp), dimension(:), allocatable :: max_spect_norm  !! max spectrum of the observation normalized by the max of the mean spectrum
    real(xp), dimension(:), allocatable :: mean_spect      !! mean spectrum of the observation
    real(xp), dimension(:), allocatable :: guess_spect !! params obtain fi the optimization of the std spectrum of the observation
    
    integer, dimension(3) :: dim_data !! dimension of original data
    integer, dimension(3) :: dim_cube !! dimension of reshape cube
    
    real(xp), dimension(:,:), allocatable :: kernel !! convolution kernel 
    
    integer :: ios=0 !! ios integer
    integer :: i     !! loop index
    integer :: j     !! loop index
    integer :: k     !! loop index
    integer :: l     !! loop index

    call header()
    
    print*, "fileout = '",trim(fileout),"'"
    
    print*,
    print*, "______Parameters_____"
    print*,
    print*, "n_gauss = ", n_gauss
    print*, "n_gauss_add = ", n_gauss_add
    print*, "lambda_amp = ", lambda_amp
    print*, "lambda_mu = ", lambda_mu
    print*, "lambda_sig = ", lambda_sig
    print*, "lambda_var_amp = ", lambda_var_amp
    print*, "lambda_var_mu = ", lambda_var_mu
    print*, "lambda_var_sig = ", lambda_var_sig
    print*, "amp_fact_init = ", amp_fact_init
    print*, "sig_init = ", sig_init
    print*, "init_option = ", init_option
    print*, "maxiter_init = ", maxiter_init
    print*, "maxiter = ", maxiter
    print*, "lstd = ", lstd
    print*, "ustd = ", ustd
    print*, "noise = ", noise
    print*, "regul = ", regul
    print*, "descent = ", descent
    print*,
    
    allocate(kernel(3, 3))
    
    kernel(1,1) = 0._xp
    kernel(1,2) = -0.25_xp
    kernel(1,3) = 0._xp
    kernel(2,1) = -0.25_xp
    kernel(2,2) = 1._xp
    kernel(2,3) = -0.25_xp
    kernel(3,1) = 0._xp
    kernel(3,2) = -0.25_xp
    kernel(3,3) = 0._xp
        
    dim_data = shape(data)
    
    write(*,*) "dim_v, dim_y, dim_x = ", dim_data
    write(*,*) ""
    write(*,*) "number of los = ", dim_data(2)*dim_data(3)
    
    nside = dim2nside(dim_data)
    
    write(*,*) "nside = ", nside
    
    call dim_data2dim_cube(nside, dim_data, dim_cube)
    
    !Allocate moemory for cube
    allocate(cube(dim_cube(1), dim_cube(2), dim_cube(3)))
    
    !Reshape the data (new cube of size nside)
    print*,
    write(*,*) "Reshape cube, new dimensions :"
    write(*,*) "dim_v, dim_y, dim_x = ", dim_cube
    print*, 
    
    print*, "Compute mean and std spectrum"
    allocate(std_spect(dim_data(1)))
    allocate(max_spect(dim_data(1)), max_spect_norm(dim_data(1)))
    allocate(mean_spect(dim_data(1)))

    call std_spectrum(data, std_spect, dim_data(1), dim_data(2), dim_data(3))
    call mean_spectrum(data, mean_spect, dim_data(1), dim_data(2), dim_data(3))
    call max_spectrum(data, max_spect, dim_data(1), dim_data(2), dim_data(3))
    call max_spectrum(data, max_spect_norm, dim_data(1), dim_data(2), dim_data(3), maxval(mean_spect))
    
    call reshape_up(data, cube, dim_data, dim_cube)
    
    !Allocate memory for parameters grids
    if (descent .eqv. .true.) then
       allocate(grid_params(3*(n_gauss+(nside*n_gauss_add)), dim_data(2), dim_data(3)))
       allocate(fit_params(3*(n_gauss+(nside*n_gauss_add)), 1, 1))
    else 
       allocate(grid_params(3*(n_gauss+n_gauss_add), dim_data(2), dim_data(3)))
    end if
    
    print*, "                    Start iteration"
    print*,
    
    if (descent .eqv. .true.) then
       print*, "Start hierarchical descent"
       !Start iteration
       do n=0,nside
          power = 2**n
          
          allocate(cube_mean(dim_cube(1), power, power))
          
          call mean_array(power, cube, cube_mean)
          
          if (n == 0) then
             if (init_option .eq. "mean") then
                print*, "Init mean spectrum"        
                call init_spectrum(n_gauss, fit_params(:,1,1), dim_cube(1), cube_mean(:,1,1), amp_fact_init, sig_init, &
                     maxiter_init, m, iprint_init)
             elseif (init_option .eq. "std") then
                call init_spectrum(n_gauss, fit_params(:,1,1), dim_cube(1), std_spect, amp_fact_init, sig_init, &
                     maxiter_init, m, iprint_init)
             elseif (init_option .eq. "max") then
                call init_spectrum(n_gauss, fit_params(:,1,1), dim_cube(1), max_spect, amp_fact_init, sig_init, &
                     maxiter_init, m, iprint_init)
             elseif (init_option .eq. "maxnorm") then
                call init_spectrum(n_gauss, fit_params(:,1,1), dim_cube(1), max_spect_norm, amp_fact_init, sig_init, &
                     maxiter_init, m, iprint_init)
             else 
                print*, "init_option keyword should be 'mean' or 'std' or 'max' or 'maxnorm'"
                stop
             end if
          end if
          
          ! Propagate solution on new grid (higher resolution)
          call go_up_level(fit_params)
          write(*,*) ""
          write(*,*) "Update parameters level ", n, ">", power
          
          if (regul .eqv. .false.) then
             call upgrade(cube_mean, fit_params, power, n_gauss, dim_cube(1), maxiter, m, iprint)
          end if
          
          if (regul .eqv. .true.) then
             if (n == 0) then
                call upgrade(cube_mean, fit_params, power, n_gauss, dim_cube(1), maxiter, m, iprint)
             end if
             
             if (n > 0 .and. n < nside) then
                allocate(std_map(power, power))
                
                if (noise .eqv. .true.) then
                   call mean_map(power, std_cube, std_map)           
                else
                   call set_stdmap(std_map, cube_mean, lstd, ustd)
                end if

                ! Update parameters 
                call update(cube_mean, fit_params, n_gauss, dim_cube(1), power, power, lambda_amp, lambda_mu, &
                     lambda_sig, lambda_var_amp, lambda_var_mu, lambda_var_sig, maxiter, m, kernel, iprint, std_map)        

                if (n_gauss_add .ne. 0) then !FIXME
                   ! Add new Gaussian if one reduced chi square > 1 
                   call init_new_gauss(cube_mean, fit_params, std_map, n_gauss, dim_cube(1), power, power, amp_fact_init, &
                        sig_init)
                end if

                deallocate(std_map)
             end if
          end if
          
          deallocate(cube_mean)
       enddo
       
       print*,
       write(*,*) "Reshape cube, restore initial dimensions :"
       write(*,*) "dim_v, dim_y, dim_x = ", dim_data
              
       call reshape_down(fit_params, grid_params,  (/ 3*n_gauss, dim_cube(2), dim_cube(3)/), &
            (/ 3*n_gauss, dim_data(2), dim_data(3)/))       

       else
          allocate(guess_spect(3*(n_gauss+n_gauss_add)))
          if (init_option .eq. "mean") then
             print*, "Use of the mean spectrum to initialize each los"
             call init_spectrum(n_gauss, guess_spect, dim_cube(1), mean_spect, amp_fact_init, sig_init, &
                  maxiter_init, m, iprint_init)
          else if (init_option .eq. "std") then
             print*, "Use of the std spectrum to initialize each los"
             call init_spectrum(n_gauss, guess_spect, dim_cube(1), std_spect, amp_fact_init, sig_init, &
                  maxiter_init, m, iprint_init)
          else if (init_option .eq. "max") then
             print*, "Use of the max spectrum to initialize each los"
             call init_spectrum(n_gauss, guess_spect, dim_cube(1), max_spect, amp_fact_init, sig_init, &
                  maxiter_init, m, iprint_init)
          else if (init_option .eq. "maxnorm") then
             print*, "Use of the std spectrum to initialize each los"
             call init_spectrum(n_gauss, guess_spect, dim_cube(1), max_spect_norm, amp_fact_init, sig_init, &
                  maxiter_init, m, iprint_init)
          else
             print*, "init_option keyword should be 'mean' or 'std' or 'max'"
             stop
          end if
          call init_grid_params(grid_params, guess_spect, dim_data(2), dim_data(3))

          deallocate(guess_spect)      
    end if
    
    !Update last level
    print*,
    print*, "Update last level ..."
    print*,
    
    allocate(std_map(dim_data(2), dim_data(3)))
    
    if (noise .eqv. .true.) then
       std_map = std_cube
    else   
       call set_stdmap(std_map, data, lstd, ustd)
    end if
    
    if (regul .eqv. .true.) then
       call update(data, grid_params, n_gauss, dim_data(1), dim_data(2), dim_data(3), lambda_amp, lambda_mu, &
            lambda_sig, lambda_var_amp, lambda_var_mu, lambda_var_sig, maxiter, m, kernel, iprint, std_map)
       
       if (n_gauss_add .ne. 0) then !FIXME KEYWORD
          do l=1,n_gauss_add
             ! Add new Gaussian if at least one reduced chi square of the field is > 1 
             call init_new_gauss(data, grid_params, std_map, n_gauss, dim_data(1), dim_data(2), dim_data(3), amp_fact_init, &
                  sig_init)
             call update(data, grid_params, n_gauss, dim_data(1), dim_data(2), dim_data(3), lambda_amp, lambda_mu, &
                  lambda_sig, lambda_var_amp, lambda_var_mu, lambda_var_sig, maxiter, m, kernel, iprint, std_map)
          end do
       end if

    end if
    
    print*,
    print*, "_____ Write output file _____"
    print*,
    
    ! Open file
    open(unit=12, file=fileout, action="write", iostat=ios)
    if (ios /= 0) stop "opening file error"
    
    write(12,fmt=*) "# "
    write(12,fmt=*) "# ______Parameters_____"
    write(12,fmt=*) "# "
    write(12,fmt=*) "# n_gauss = ", n_gauss
    write(12,fmt=*) "# n_gauss_add = ", n_gauss_add
    write(12,fmt=*) "# lambda_amp = ", lambda_amp
    write(12,fmt=*) "# lambda_mu = ", lambda_mu
    write(12,fmt=*) "# lambda_sig = ", lambda_sig
    write(12,fmt=*) "# lambda_var_amp = ", lambda_var_amp
    write(12,fmt=*) "# lambda_var_mu = ", lambda_var_mu
    write(12,fmt=*) "# lambda_var_sig = ", lambda_var_sig
    write(12,fmt=*) "# amp_fact_init = ", amp_fact_init
    write(12,fmt=*) "# sig_init = ", sig_init
    write(12,fmt=*) "# init_option = ", init_option
    write(12,fmt=*) "# maxiter_itit = ", maxiter_init
    write(12,fmt=*) "# maxiter = ", maxiter
    write(12,fmt=*) "# lstd = ", lstd
    write(12,fmt=*) "# ustd = ", ustd
    write(12,fmt=*) "# noise = ", noise
    write(12,fmt=*) "# regul = ", regul
    write(12,fmt=*) "# descent = ", descent
    write(12,fmt=*) "# "
    
    write(12,fmt=*) "# i, j, A, mean, sigma"

    do i=1, dim_data(2)
       do j=1, dim_data(3)
          do k=1, n_gauss
             write(12,fmt=*) i-1, j-1, grid_params(1+((k-1)*3),i,j), grid_params(2+((k-1)*3),i,j), grid_params(3+((k-1)*3),i,j)
          enddo
       enddo
    enddo
    close(12)
    
    call ender()
    
  end subroutine main_rohsa