function progauss (obs,x0,m,dobase)
  use class_types
  !----------------------------------------------------------------------
  ! @ public (for libclass only)
  ! FIT\ Internal routine
  ! M.eq.0:  Computes the composite profile from sum of all gaussians.
  ! M.ne.0:  Computes the profile from gaussian number M
  !----------------------------------------------------------------------
  real(kind=4) :: progauss  ! Function value on return
  type(observation), intent(in)  :: obs     ! Input observation
  real(kind=4),      intent(in)  :: x0      ! Abscissa
  integer(kind=4),   intent(in)  :: m       ! Sum of components or component num.
  logical,           intent(out) :: dobase  ! Dummy argument for compatibility with PROPOI
  ! Local
  integer(kind=4) :: ifi,ila,i,k
  real(kind=4) :: arg
  !
  progauss=0.
  arg=0.
  dobase = .false.
  !
  if (m.eq.0) then
     ifi = 1
     ila = max(obs%head%gau%nline,1)
  else
     ifi = m
     ila = m
  endif
  !
  do i = ifi,ila
     k = 3*(i-1)+1
     arg = abs((x0-obs%head%gau%nfit(k+1)) / obs%head%gau%nfit(k+2)*1.665109)
     if (arg.lt.4.) then
        progauss = progauss + exp(-arg**2)*obs%head%gau%nfit(k)/obs%head%gau%nfit(k+2)/1.064467
     endif
  enddo
  !
end function progauss
!
function pronh3(obs,vi,m,dobase)
  use class_types
  use hyperfine_structure
  !----------------------------------------------------------------------
  ! @ public (for libclass only)
  ! FIT\ Internal routine
  ! M.eq.0:  Computes the composite profile from sum of all NH3 profiles
  ! M.ne.0:  Computes the profile from gaussian number M
  !----------------------------------------------------------------------
  real(kind=4) :: pronh3  ! Function value on return
  type(observation), intent(in)  :: obs     ! Input observation
  real(kind=4),      intent(in)  :: vi      ! Velocity
  integer(kind=4),   intent(in)  :: m       ! Line number
  logical,           intent(out) :: dobase  ! Dummy argument for compatibility with PROPOI
  ! Local
  real(kind=4) :: t1,o1,toi,arg,v1,d1
  integer(kind=4) :: j
  integer(kind=4) :: ifi,ila,i,ki
  !
  if (m.eq.0) then
    ifi = 1
    ila = max(obs%head%hfs%nline,1)
  else
    ifi = m
    ila = m
  endif
  !
  pronh3=0.
  dobase = .false.
  !
  do i = ifi,ila
    ki = 4*(i-1)
    t1=obs%head%hfs%nfit(1+ki)              ! Tant*Tau
    v1=obs%head%hfs%nfit(2+ki)              ! Velocity
    d1=obs%head%hfs%nfit(3+ki)/1.665109     ! Line width
    o1=obs%head%hfs%nfit(4+ki)              ! Opacity
    toi = 0.
    if (t1.ne.0 .and. d1.ne.0) then
      do j=1,nhyp
        arg = abs ((vi-vhfs(j)-v1)/d1)
        if (arg.lt.4.) then
          toi = toi + o1*rhfs(j)*exp(-(arg**2))
        endif
      enddo
      pronh3 = pronh3 + t1 * (1.-exp(-toi)) / o1
    endif
  enddo
end function pronh3
!
function proabs(obs,vi,m,dobase)
  use classfit_interfaces, except_this=>proabs
  use class_types
  !----------------------------------------------------------------------
  ! @ public (for libclass only)
  ! FIT\ Internal routine
  ! M.eq.0:  Computes the composite profile from sum of all ABS profiles
  ! M.ne.0:  Computes the profile from gaussian number M
  !----------------------------------------------------------------------
  real(kind=4) :: proabs  ! Function value on return
  type(observation), intent(in)  :: obs    ! Input observation
  real(kind=4),      intent(in)  :: vi     ! Velocity
  integer,           intent(in)  :: m      ! Line number
  logical,           intent(out) :: dobase ! Dummy argument for compatibility with PROPOI
  ! Local
  integer :: i
  !
  proabs=0.
  dobase = .false.
  if (m.eq.0) then
     do i=1,obs%head%abs%nline
        proabs = proabs+proabs1(obs,vi,i)
     enddo
     proabs = exp(-proabs)
  else
     proabs = exp(-proabs1(obs,vi,m))
  endif
  ! multiply by continuum level
  proabs = proabs*obs%head%abs%nfit(1)
end function proabs
!
function proabs1(obs,vi,m)
  use class_types
  use hyperfine_structure
  !----------------------------------------------------------------------
  ! @ private
  ! FIT\ internal routine
  !----------------------------------------------------------------------
  real(kind=4) :: proabs1  ! Function value on return
  type(observation), intent(in) :: obs  ! Input observation
  real(kind=4),      intent(in) :: vi   ! abscissa
  integer(kind=4),   intent(in) :: m    ! which component
  ! Local
  real(kind=4) :: t1, v1, d1, arg
  integer(kind=4) :: j
  !
  t1=obs%head%abs%nfit((m-1)*3+2)
  v1=obs%head%abs%nfit((m-1)*3+3)
  d1=obs%head%abs%nfit((m-1)*3+4)/1.665109
  proabs1 = 0.
  if (t1.ne.0 .and. d1.ne.0) then
     do j=1,nhyp
        arg = abs ((vi-vhfs(j)-v1)/d1)
        if (arg.lt.4.) then
           proabs1 = proabs1 + rhfs(j)*exp(-(arg**2))
        endif
     enddo
  endif
  proabs1 = proabs1*t1
end function proabs1
!
function proshell(obs,a,m,error)
  use classfit_interfaces, except_this=>proshell
  use class_types
  !----------------------------------------------------------------------
  ! @ public (for libclass only)
  ! FIT\ Internal routine
  ! M.eq.0:  Computes the composite profile from sum of all NH3 profiles
  ! M.ne.0:  Computes the profile from gaussian number M
  !
  ! Note: X unit is FREQUENCY
  !----------------------------------------------------------------------
  real(kind=4) :: proshell  ! Function value on return
  type(observation), intent(in) :: obs      ! Input observation
  real(kind=4),      intent(in)  :: a       ! Velocity
  integer(kind=4),   intent(in)  :: m       ! Line number
  logical,           intent(out) :: error   ! Logical error flag
  ! Local
  integer(kind=4) :: ifi,ila,i,k,l
  !
  proshell=0.
  !
  if (m.eq.0) then
     ifi = 1
     ila = max(obs%head%she%nline,1)
  else
     ifi = m
     ila = m
  endif
  !
  do i = ifi,ila
     k = 4*(i-1)+1
     l = k+2
     if (obs%head%she%nfit(k).ne.0 .and.obs%head%she%nfit(l).ne.0) then
        call kshell(a,abs(obs%head%spe%fres),obs%head%she%nfit(k),proshell,error)
     endif
  enddo
  !
contains
  subroutine kshell(x0,dx,xp,ff,error)
    use gbl_message
    real(kind=4), intent(in)    :: x0     ! Absissa
    real(kind=8), intent(in)    :: dx     ! Channel width
    real(kind=4), intent(in)    :: xp(4)  ! Profile parameters
    real(kind=4), intent(inout) :: ff     ! Output composite value
    logical,      intent(out)   :: error  ! Logical error flag
    ! Local
    real(kind=4) :: arg,arg0,arg1,f
    character(len=message_length) :: chain
    !
    error = .false.
    if (xp(3).eq.0 .or. xp(1).eq.0) then
      write(chain,*) 'Wrong Arguments :',xp
      call class_message(seve%e,'KSHELL',chain)
      error = .true.
      return
    endif
    !
    ! Define 3 regimes:
    ! 1) Central regime (in the shell model itself),
    ! 2) intermediate regime (1-channel wide) to avoid discontinuity
    !    with the 0-regime,
    ! 3) outer regime (zero-valued) out of the shell.
    !
    ! Say the X axis is normalized with center (0 value) on nu0 and the
    ! horns are found at +-1. The intermediate regime (right side) expands
    ! from 1-halfchannel to 1+halfchannel:
    arg  = abs((xp(2)-x0)/xp(3))  ! Normalized distance from center
    arg0 =      1.-0.5*dx/xp(3)   ! Start of intermediate regime
    arg1 =      1.+0.5*dx/xp(3)   ! End of intermediate regime
    !
    ! xp(1) Area
    ! xp(2) Central frequency
    ! xp(3) Half-width at zero level
    ! xp(4) H parameter
    if (arg.lt.arg0) then      ! Central regime
      f = xp(1)*0.5/xp(3)/(1.+xp(4)/3.) * (1.+xp(4)*arg**2)
    elseif (arg.lt.arg1) then  ! Intermediate regime: continuity between the 2 regimes
      f = xp(1)*0.5/xp(3)/(1.+xp(4)/3.) * (1.+xp(4)*arg0**2) * (arg-arg1)/(arg0-arg1)
    else                       ! Outer regime
      f = 0.
    endif
    ff = ff + f
  end subroutine kshell
end function proshell
!
function propoi(obs,x0,m,dobase)
  use class_types
  !----------------------------------------------------------------------
  ! @ private
  ! FIT\ Internal routine
  ! M.eq.0:  Computes the composite profile from sum of all ABS profiles
  ! M.ne.0:  Computes the profile from gaussian number M
  ! Computes the profile from gaussian number M
  ! Modified version with a linear baseline. Note that it is called
  ! by GAUSSFIT with a dummy argument DOBASE after M.
  !----------------------------------------------------------------------
  real(kind=4) :: propoi  ! Function value on return
  type(observation), intent(in)  :: obs     ! Input observation
  real(kind=4),      intent(in)  :: x0      ! Value at which the profile should be computed
  integer(kind=4),   intent(in)  :: m       ! Component number (0 = all)
  logical,           intent(out) :: dobase  ! Is A on the line or on the baseline ?
  ! Local
  real(kind=4) :: arg
  integer(kind=4) :: ifi,ila,i,k
  !
  ! Initialization
  ! - linear baseline
  propoi = obs%head%poi%nfit(1) + x0*obs%head%poi%nfit(2)
  arg=0.
  dobase = .true.
  !
  if (m.eq.0) then
     ifi = 1
     ila = max(obs%head%poi%nline,1)
  else
     ifi = m
     ila = m
  endif
  !
  do i = ifi,ila
     k = 3*(i-1)+3
     arg = abs((x0-obs%head%poi%nfit(k+1)) / obs%head%poi%nfit(k+2)*1.665109)
     if (arg.lt.4.) then
        propoi = propoi + exp(-arg**2)*obs%head%poi%nfit(k)/obs%head%poi%nfit(k+2)/1.064467
     endif
     if (arg.lt.2) dobase = .false.
  enddo
end function propoi
!
function propoibased(obs,x0,m,dobase)
  use class_types
  !----------------------------------------------------------------------
  ! @ private
  ! Same as PROPOI but does not fit the baseline, i.e. ignore poi%nfit(1)
  ! and poi%nfit(2).
  !----------------------------------------------------------------------
  real(kind=4) :: propoibased  ! Function value on return
  type(observation), intent(in)  :: obs     ! Input observation
  real(kind=4),      intent(in)  :: x0      ! Value at which the profile should be computed
  integer(kind=4),   intent(in)  :: m       ! Component number (0 = all)
  logical,           intent(out) :: dobase  ! Is A on the line or on the baseline ?
  ! Local
  real(kind=4) :: arg
  integer(kind=4) :: ifi,ila,i,k
  !
  ! Initialization
  propoibased = 0.
  arg=0.
  dobase = .true.
  !
  if (m.eq.0) then
     ifi = 1
     ila = max(obs%head%poi%nline,1)
  else
     ifi = m
     ila = m
  endif
  !
  do i = ifi,ila
     k = 3*(i-1)+3
     arg = abs((x0-obs%head%poi%nfit(k+1)) / obs%head%poi%nfit(k+2)*1.665109)
     if (arg.lt.4.) then
        propoibased = propoibased + exp(-arg**2)*obs%head%poi%nfit(k)/obs%head%poi%nfit(k+2)/1.064467
     endif
     if (arg.lt.2) dobase = .false.
  enddo
end function propoibased
