subroutine minshell(npar,g,f,x,iflag,obs)
  use classfit_interfaces, except_this=>minshell
  use class_types
  use gauss_parameter
  !----------------------------------------------------------------------
  ! @ private-mandatory (because symbol is used elsewhere)
  ! Function to be minimized in the Shell line fit.
  ! Basic parameters are Area, Width, Position, and Horn/Center ratio.
  ! Allows dependent lines to be fitted.
  !----------------------------------------------------------------------
  integer(kind=4),   intent(in)  :: npar     ! Number of parameters
  real(kind=8),      intent(out) :: g(npar)  ! Array of derivatives
  real(kind=8),      intent(out) :: f        ! Function value
  real(kind=8),      intent(in)  :: x(npar)  ! Input parameter values
  integer(kind=4),   intent(in)  :: iflag    ! Code operation
  type(observation), intent(in)  :: obs      !
  ! Local
  real(kind=4) :: gg(nshellpar*mshelllin),xx(nshellpar*mshelllin),gu(nshellpar*mshelllin)
  real(kind=4) :: g1,g2,g3,g4,aa,nn,vv,hh,ff,xvel,eps
  real(kind=4) :: dff,ybas,yrai,seuil,ta
  integer(kind=4) :: i,j,kbas,krai
  logical :: dograd,error
  !
  if (iflag.eq.3) goto 20
  !
  ! The profile is written as the sum
  ! 	f(Ai,Ni,Vi,Hi)
  ! where Vi = VV.vi, Ai = AA.ai, Ni = NN+ni and Hi = HH*hi
  !
  aa = x(1)
  nn = x(2)
  vv = x(3)
  hh = x(4)
  g1 = 0.0
  g2 = 0.0
  g3 = 0.0
  g4 = 0.0
  do i=4,4*nline,4
     xx(i-3) = x(i+1)*aa
     gg(i-3) = 0.0
     xx(i-2) = x(i+2)+nn
     gg(i-2) = 0.0
     xx(i-1) = x(i+3)*vv
     gg(i-1) = 0.0
     xx(i)   = x(i+4)*hh
     gg(i)   = 0.0
  enddo
  dograd = iflag.eq.2
  !
  f = 0.0
  eps = abs(obs%datax(obs%cimin+1) - obs%datax(obs%cimin))
  do i=obs%cimin, obs%cimax
     if (wfit(i).ne.0) then
        xvel = obs%datax(i)
        ff = 0.0
        do j=1,4*nline,4
           call fshell (xvel,eps,xx(j),ff,gu(j),dograd,error)
           if (error) return
        enddo
        dff = ff - obs%spectre(i)
        f = f + dff**2
        dff = 2.0*dff
        do j = 1, 4*nline
           gu(j) = dff*gu(j)
           gg(j) = gg(j) + gu(j)
        enddo
        do j = 1, 4*nline, 4
           g1 = g1 + gu(j)*xx(j)
           g2 = g2 + gu(j+1)
           g3 = g3 + gu(j+2)*xx(j+2)
           g4 = g4 + gu(j+3)*xx(j+3)
        enddo
     endif
  enddo
  !
  g(1) = g1
  g(2) = g2
  g(3) = g3
  g(4) = g4
  !
  do j=1,4*nline,4
     g(j+4) = gg(j)*aa
     g(j+5) = gg(j+1)
     g(j+6) = gg(j+2)*vv
     g(j+7) = gg(j+3)*hh
  enddo
  return
  !
  ! Compute the new sigma after minimisation
20 kbas=0
  ybas=0.
  krai=0
  yrai=0.
  seuil= sigbas/100.
  !
  do i=obs%cimin,obs%cimax
     if (wfit(i).ne.0) then
        ta = proshell(obs,real(obs%datax(i),4),0,error)
        if (error) return
        if (abs(ta).le.seuil) then
           kbas=kbas+1
           ybas=ybas+obs%spectre(i)**2
        else
           krai=krai+1
           yrai=yrai+(ta-obs%spectre(i))**2
        endif
     endif
  enddo
  if (kbas.ne.0) then
     sigbas=sqrt(ybas/kbas)
  else
     sigbas=0.d0
  endif
  if (krai.ne.0) then
     sigrai=sqrt(yrai/krai)
  else
     sigrai=0.d0
  endif
  !
end subroutine minshell
!
subroutine fshell(x0,dx,xp,fout,gg,dograd,error)
  use gbl_message
  !----------------------------------------------------------------------
  ! @ private
  ! Computes the contribution of a Shell-like profile in the current
  ! channel to the square sum, and to the gradients relative to the
  ! parameters also if DOGRAD is .true.. Highly optimised ?
  !----------------------------------------------------------------------
  real(kind=4), intent(in)  :: x0      ! Abscissa
  real(kind=4), intent(in)  :: dx      ! Freq resolution
  real(kind=4), intent(in)  :: xp(4)   ! Input parameters
  real(kind=4), intent(out) :: fout    ! Output value of Shell function
  real(kind=4), intent(out) :: gg(4)   ! Gradients
  logical,      intent(in)  :: dograd  ! Compute contribution to gradients
  logical,      intent(out) :: error   ! Logical error flag
  ! Local
  real(kind=4) :: ff,tt,vv,dd,hh,arg,aarg,arg0,arg1,arg2,arg3,arg4
  integer(kind=4) :: i
  character(len=80) :: chain
  !
  error = .false.
  tt = xp(1)
  vv = xp(2)-x0
  dd = xp(3)
  hh = xp(4)
  if (dd.eq.0.or.tt.eq.0) then
     write(chain,*) 'Wrong Arguments :',xp
     call class_message(seve%e,'FSHELL',chain)
     error = .true.
     return
  endif
  arg = vv/dd
  arg0 = 1.-0.5*dx/dd
  arg1 = 1.+0.5*dx/dd
  aarg = abs(arg)
  if (aarg .lt. arg0) then
     arg2 = arg**2
     ff = tt*1.5/dd/(3.+hh)*(1.+hh*arg2)
     if (dograd) then
        arg3  = 1./(1.+hh*arg2)
        arg4  = arg2*arg3
        gg(1) =  ff/tt
        gg(2) = -ff*arg3*2.*hh*arg/dd
        gg(3) = -ff/dd*(1.+2.*hh*arg4)
        gg(4) =  ff*(-1./(3.+hh)+arg4)
     endif
  elseif (aarg .lt. arg1) then
     arg2 = arg0**2
     ff   = tt*1.5/dd/(3.+hh)*(1.+hh*arg2)*(aarg-arg1)/(arg0-arg1)
     if (dograd) then
        gg(1) = ff/tt
        gg(2) = - ff/(aarg-arg1)/dd
        if (arg.le.0) gg(2) = -gg(2)
        gg(3) = -ff/dd*(1.-1./(arg1-aarg)-2.*hh*arg0*(1.-arg0)/(1.+hh*arg2))
        gg(4) = ff*(-1./(3.+hh)+arg2/(1.+hh*arg2))
     endif
  else
     ff = 0.
     if (dograd) then
        do i=1,4
           gg(i) = 0.
        enddo
     endif
  endif
  fout = fout + ff
end subroutine fshell
