# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "<stdin>"
!<
!tomo_oper_build_mod
!
!Usage:
!call tomo_oper_build_mod (arg1, arg2 arg3)
!
!Input Parameters:
!
!
!Output Parameters:
!
!
!
!Description:
!
!
!
!>
!-------------------------------------------------
!
!Author: Robert Clapp, ESMB 463, 7230253
!
!Date Created:Mon Jan 15 19:12:30 PST 2001
! Thu Jan 9 21:06:08 PST 2003
!
!Purpose:
!
!
module tomo_oper_mod
  use tomo_normal_mod
  use tomo_full_mod
  use tomo_bulk_mod
  implicit none
  character(len=50), private, save :: oper_method
  logical, private, save :: files_ok,verb
  type(sep3d),private,save :: vel_s
  integer, private, save :: ndat
  contains
  logical function init_tomo_oper()
    real :: junk
    init_tomo_oper=.false.
    if (.not. files_ok) then
      call to_history("n1",1,"tomo_oper")
      call srite("tomo_oper",junk,4)
      if (.not. write_current("tomo_oper")) then
        write(0,*) "          ERROR: writing parameters to file"
        return
      end if
      if (oper_method(1:4).eq."full") then
        if (.not. calc_full_tomo()) then
          write(0,*) "          ERROR: calculating full tomo oper"
          return
        end if
      else if (oper_method(1:4).eq."bulk") then
        if (.not. calc_bulk_tomo()) then
          write(0,*) "          ERROR: calculating full tomo oper"
          return
        end if
      else if (oper_method(1:6).eq."normal") then
        if (.not. calc_normal_tomo()) then
          write(0,*) "          ERROR: calculating normal tomo oper"
          return
        end if
      else
        write(0,*) "don't understand oper_method",trim(oper_method)
        return
      end if
    else
      if (verb) then
        write(0,*) "   reading in tomo_oper"
      end if
      if (oper_method(1:4).eq."full" .or. oper_method(1:6).eq."normal"&
        & .or. oper_method(1:4).eq."bulk") then
        if (.not. add_traceback()) then
          write(0,*) "          ERROR: adding traceback"
          return
        end if
      end if
    end if
    init_tomo_oper=.true.
  end function
  logical function load_tomo_oper(dat)
    real, pointer :: dat(:)
    load_tomo_oper=.false.
    if (oper_method(1:4).eq."full") then
      if (.not. load_full_tomo_oper(dat)) then
        write(0,*) "          ERROR: loading full tomo operator"
        return
      end if
    else if (oper_method(1:4).eq."bulk") then
      if (.not. load_full_tomo_oper(dat)) then
        write(0,*) "          ERROR: loading bulk tomo operator"
        return
      end if
    else if (oper_method(1:6).eq."normal") then
      if (.not. load_normal_tomo_oper(dat)) then
        write(0,*) "          ERROR: loading normal tomo operator"
        return
      end if
    else
      write(0,*) "undefined oper method",trim(oper_method)
      return
    end if
    ndat=size(dat)
    load_tomo_oper=.true.
  end function
  integer function tomo_oper_size()
    tomo_oper_size=ndat
  end function
  integer function tomo_op(adj,add,model,data)
    logical, intent(in) :: adj,add
    real :: model(:),data(:)
    tomo_op=0
    if (oper_method(1:4).eq."full") then
      tomo_op=tomo_full_op(adj,add,model,data)
    else if (oper_method(1:4).eq."bulk") then
      tomo_op=tomo_bulk_op(adj,add,model,data)
    else if (oper_method(1:6).eq."normal") then
      tomo_op=tomo_normal_op(adj,add,model,data)
    else
      write(0,*) "tomo_oper_method",trim(oper_method)
      call seperr("undefined tomo_oper_method")
    end if
  end function
  logical function check_tomo_oper_params()
    character(len=128) :: tag
    logical :: stat_ok(20),stat_rerun(20)
    integer, external :: auxin
    stat_rerun=.true.
    stat_ok=.true.
    check_tomo_oper_params=.false.
    if (.not. vel_structure(vel_s)) then
      write(0,*) "          ERROR: grabbing velocity structure"
      return
    end if
!if(.not. new_par_check()) {
! write(0,*) "          ERROR: initializing new param check"
! return
!}
    if (-1.eq.auxin("tomo_oper")) then
      tag="NONE"
    else
      tag="tomo_oper"
    end if
    call from_param("verb",verb,.false.)
    stat_rerun(1)= check_par_file("tomo_oper_method" ,oper_method&
      & ,tag,"full")
    if (oper_method(1:4).eq."full") then
      stat_ok(2)=check_par_tomo_full(vel_s,tag,stat_rerun(2))
    else if (oper_method(1:4).eq."bulk") then
      stat_ok(2)=check_par_tomo_bulk(vel_s,tag,stat_rerun(2))
    else if (oper_method(1:6).eq."normal") then
      stat_ok(2)=check_par_tomo_normal(vel_s,tag,stat_rerun(2))
    else
      write(0,*) "Unknown tomo_oper_method=",trim(oper_method)
      return
    end if
    call from_param("rerun_tomo_oper",stat_rerun(9),.false.)
    call from_param("rerun_all",stat_rerun(8),.false.)
    stat_rerun(8:9)=.not.stat_rerun(8:9)
    call auxclose("tomo_oper")
    if (all(stat_rerun)) then
      files_ok=.true.
    else
      files_ok=.false.
    end if
    if (all(stat_ok)) then
      check_tomo_oper_params=.true.
    end if
  end function
end module
