subroutine mingauss(npar,g,f,x,iflag,obs)
  use classfit_interfaces, except_this=>mingauss
  use class_types
  use gauss_parameter
  !----------------------------------------------------------------------
  ! @ private-mandatory (because symbol is used elsewhere)
  ! Function to be minimized in the gaussian fit. By using 3 hidden
  ! parameters, the method allows dependent and independent gaussians to
  ! be fitted.
  ! The computation is highly optimised, but take care of R*4 and
  ! R*8 values !... Basic parameters are Area, Position and Width.
  !----------------------------------------------------------------------
  integer(kind=4),   intent(in)  :: npar     ! Number of parameters
  real(kind=8),      intent(out) :: g(npar)  ! Array of derivatives, size 3+3*Nline (see below)
  real(kind=8),      intent(out) :: f        ! Function values
  real(kind=8),      intent(in)  :: x(npar)  ! Input parameter values, size 3+3*Nline (see midgauss)
  integer(kind=4),   intent(in)  :: iflag    ! Code operation
  type(observation), intent(in)  :: obs      !
  ! Local
  logical :: dograd, dobase
  integer(kind=4) :: i,k,kbas,krai,kline
  real(kind=4) :: tt,vv,dd,gt,gv,gd,ff
  real(kind=4) :: arg,seuil,ta,ybas,yrai,xvel
  real(kind=4), dimension(15) :: xg
  real(kind=4), dimension(5)  :: argexp,xf,xt,xv,xd
  !
  ! Final computations
  if (iflag.eq.3) then
     ! Compute Sigma after Minimisation
     kbas=0
     ybas=0.
     krai=0
     yrai=0.
     seuil= sigbas/3.
     !
     do i=obs%cimin,obs%cimax
        if (wfit(i).ne.0) then 
           xvel = real(obs%datax(i),4)
           ta = progauss(obs,xvel,0,dobase)
           if (abs(ta).lt.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.gt.5) then
        sigbas=sqrt(ybas/kbas)
     else
        sigbas=0.d0
     endif
     if (krai.ne.0) then
        sigrai=sqrt(yrai/krai)
     else
        sigrai=sigbas
     endif
     if (sigbas.eq.0) sigbas = sigrai
     return
  endif
  !
  dograd = iflag.eq.2
  !
  !	g1 derivee / aire
  !	g2 derivee / vlsr
  !	g3 derivee / delt
  !
  ! Compute gaussians
  f = 0.
  xg = 0.
  gt = 0.
  gv = 0.
  gd = 0.
  xt = 0.
  xv = 0.
  xd = 0.
  tt = x(1)
  vv = x(2)
  dd = x(3)     
  kline = max(nline,1)
  do i=1,kline
     xt(i) = x(3*i+1) * tt
     xv(i) = x(3*i+2) + vv
     xd(i) = x(3*i+3) * dd
  enddo
  !
  do i=obs%cimin,obs%cimax
     if (wfit(i).gt.0) then 
        xvel = obs%datax(i)
        xf     = 0.
        argexp = 0.
        argexp(1:kline) = (xvel - xv(1:kline)) / xd(1:kline)
        where(argexp(1:kline).le.4.)
           xf(1:kline) = exp(-argexp(1:kline)**2)
        end where
        ff = sum(xf(1:kline)*xt(1:kline)/xd(1:kline))
        !
        ! Compute chi^2 (No ponderation, WFIT is ignored)
        ff =  (ff - obs%spectre(i))
        f = f + ff**2
        !
        ! Compute Gradients
        if (dograd) then
           ff = 2. * ff
           do k=1,kline
              if (xf(k).ne.0.) then
                 arg            = xf(k) * ff / xd(k)
                 xg(1+3*(k-1))  = xg(1+3*(k-1)) + arg
                 gt             = gt + arg*xt(k)
                 !
                 arg            = xt(k)*arg/xd(k)
                 xg(3+3*(k-1))  = xg(3+3*(k-1)) - arg
                 gd             = gd - arg*xd(k)
                 !
                 arg            = arg*argexp(k)*2.
                 xg(2+3*(k-1))  = xg(2+3*(k-1)) + arg
                 xg(3+3*(k-1))  = xg(3+3*(k-1)) + arg*argexp(k)
                 gv             = gv + arg
                 gd             = gd + arg*argexp(k)*xd(k)
              endif
           enddo
        endif
     endif
  enddo
  !
  ! Setup values and return
  g(1)=gt/tt
  g(2)=gv
  g(3)=gd/dd
  !
  do i=1,kline
     g(3*i+1) = xg(1+3*(i-1)) *tt
     g(3*i+2) = xg(2+3*(i-1))
     g(3*i+3) = xg(3+3*(i-1)) *dd
  enddo
  !
end subroutine mingauss
