subroutine midgauss(obs,fit,ifatal,liter)
  use gildas_def
  use gbl_message
  use fit_minuit
  use classfit_dependencies_interfaces
  use classfit_interfaces, except_this=>midgauss
  use class_types
  use gauss_parameter
  !----------------------------------------------------------------------
  ! @ private
  !  Start a gaussian fit by building the PAR array and internal variable
  ! used by Minuit
  !----------------------------------------------------------------------
  type(observation),  intent(in)    :: obs    !
  type(fit_minuit_t), intent(inout) :: fit    ! Fitting variables
  integer(kind=4),    intent(out)   :: ifatal ! Number of fatal errors
  logical,            intent(in)    :: liter  ! Iterate a fit
  ! Local
  character(len=*), parameter :: rname='MIDGAUSS'
  integer(kind=4) :: i,ninte,k,j
  real(kind=4) :: ymax,ymin,aire,vsup,vinf,yy
  real(kind=8) :: sav,sav2,vplu,vminu
  character(len=80) :: mess
  !
  fit%isw(1:7) = 0
  fit%sigma  = 0.d0
  fit%npfix  = 0
  ninte  = 0
  fit%nu     = 0
  fit%npar   = 0
  ifatal = 0
  fit%u(1:fit%maxext)      = 0.0d0
  fit%lcode(1:fit%maxext)  = 0
  fit%lcorsp(1:fit%maxext) = 0
  fit%isw(5) = 1
  fit%data = locwrd(obs)
  !
  ! Starting values
  !
  if (nline.eq.0) then
     !
     ! Automatic guess if NLINE = 0
     ymax=0.
     ymin=0.
     aire=0.
     do i=obs%cimin+1,obs%cimax-1
        if (wfit(i).ne.0) then
           yy = ( obs%spectre(i) + wfit(i-1)*obs%spectre(i-1) +   &
                wfit(i+1)*obs%spectre(i+1) ) / (1+wfit(i-1)+wfit(i+1))
           if (yy.ge.ymax) then
              ymax = yy
              vsup = obs%datax(i)
           endif
           if (yy.le.ymin) then
              ymin = yy
              vinf = obs%datax(i)
           endif
           aire=aire+yy*abs((obs%datax(i+1)-obs%datax(i-1)))
        endif
     enddo
     aire = aire*0.5
     if (abs(ymin).lt.abs(ymax)) then
        par(2)=vsup
        par(1)=ymax
     else
        par(2)=vinf
        par(1)=ymin
     endif
     par(3)=abs(aire/par(1)/1.064467)
     par(1)=aire
     fit%nu=3
  else
     !
     ! Take initial guesses in SPAR
     fit%nu=3*nline
     j=1
     do i=1,nline
        !
        ! That is quite tricky, since the area is the product of the original
        ! intensity by the width. But for dependant gaussian, it is more subtle
        if (kt(i).eq.3) then
           par(j) = spar(j)
        elseif (kd(i).eq.3) then
           par(j) = spar(j)*spar(j+2)*1.064467    ! Area
           par(j) = par(j)*spar(3*kd0)    !
        else
           par(j) = spar(j)*spar(j+2)*1.064467    ! Area=amp*fwhm*sqrt(2pi/8log2)
        endif
        par(j+1) = spar(j+1)     ! Position
        par(j+2) = spar(j+2)     ! FWHM
        j=j+3
     enddo
  endif
  !
  ! Type initial guesses
  fit%nu=fit%nu+3
  call class_message(seve%i,rname,'Input Parameters:  Area Position Fwhm')
  k = 1
  do i=1,max(nline,1)
     write (mess,1002) par(k),par(k+1),par(k+2)
     call class_message(seve%i,rname,mess)
     k=k+3
  enddo
  !
  ! Set up Parameters for Major Variables
  !
  ! Velocities
  if (kv0.eq.0) then
     ! No reference velocity
     fit%u(2)=0.     ! Velocity offset set to 0
     fit%werr(2)=0.  ! Velocity offset not minimized
  else
     ! There is a reference velocity
     fit%u(2)=par(3*kv0-1)  ! Fetch its value
     if (kv(kv0).eq.4) then
        fit%werr(2)=0.  ! The reference velocity is fixed
     else
        fit%werr(2)=deltav  ! This reference velocity is variable
        if (liter.and.err(3*kv0-1).ne.0) fit%werr(2)=err(3*kv0-1)
        fit%alim(2)=fit%u(2)-0.15*obs%cnchan*deltav
        fit%blim(2)=fit%u(2)+0.15*obs%cnchan*deltav
     endif
  endif
  !
  ! Line Widths
  if (kd0.eq.0) then
     ! No reference line width
     fit%u(3)=1./1.665109  ! Line width set to 1/(2*SQRT(LN(2))) (factorize this factor out of the minimization)
     fit%werr(3)=0.        ! This factor is a parameter (i.e. not minimized)
  else
     ! There is a reference line width
     fit%u(3)=abs(par(3*kd0))/1.665109  ! Fetch its value (with factor)
     if (kd(kd0).eq.4) then
        fit%werr(3)=0.  ! The reference line width is fixed
     else
        fit%werr(3)=deltav  ! The reference line width is variable
        if (liter.and.err(3*kd0).ne.0) fit%werr(3)=err(3*kd0)
        fit%alim(3)=0.25*deltav
        fit%blim(3)=0.75*obs%cnchan*deltav
     endif
  endif
  !
  ! Areas
  if (kt0.eq.0) then
     ! No reference area
     fit%u(1)=0.564189584 ! Area set to 1/SQRT(PI) (factorize this factor out of the minimization
     fit%werr(1)=0.       ! This factor is a parameter (i.e. not minimized)
  else
     ! There is a reference area
     fit%u(1)=par(3*kt0-2)  ! Fetch its value
     if (kt(kt0).eq.4) then
        fit%werr(1)=0.  ! The reference area is fixed
     else
        fit%werr(1)=sigbas*deltav  ! The reference area is variable
        if (liter.and.err(3*kt0-2).ne.0) fit%werr(1)=err(3*kt0-2)
        if (fit%u(1).ne.0.) then
           fit%alim(1)=dmin1(0.d0,10*fit%u(1))
           fit%blim(1)=dmax1(0.d0,10*fit%u(1))
        else
           fit%lcode(1)=1
        endif
     endif
  endif
  !
  ! Set up parameters for Secondary Variables
  !
  k=4
  do i=1,max(nline,1)
     ! Area
     fit%u(k)=par(k-3)
     if (kt(i).eq.0 .or. nline.eq.0) then
        fit%werr(k)  =  max(sigbas,sigrai)*deltav
        if (liter.and.err(k-3).ne.0) fit%werr(k)=err(k-3)
        if (fit%u(k).ne.0.) then
           fit%alim(k)=dmin1(0.d0,10*fit%u(k))
           fit%blim(k)=dmax1(0.d0,10*fit%u(k))
        else
           fit%lcode(k)=1             ! No Boundaries if fit%u(k)=0.
        endif
     else
        fit%werr(k)=0.
        if (i.eq.kt0) then
           fit%u(k)=0.564189584
        else
           fit%u(k)=fit%u(k)*0.564189584
        endif
     endif
     k=k+1
     !
     ! Velocity
     fit%u(k)=par(k-3)
     if (kv(i).eq.0 .or. nline.eq.0) then
        fit%werr(k)=deltav
        if (liter.and.err(k-3).ne.0) fit%werr(k)=err(k-3)
        fit%alim(k)=fit%u(k)-0.15*obs%cnchan*deltav
        fit%blim(k)=fit%u(k)+0.15*obs%cnchan*deltav
     else
        fit%werr(k)=0.
        if (i.eq.kv0) fit%u(k)=0.
     endif
     k=k+1
     !
     ! Line Width
     fit%u(k)=abs(par(k-3))
     if (kd(i).eq.0 .or. nline.eq.0) then
        fit%werr(k)=deltav
        if (liter.and.err(k-3).ne.0) fit%werr(k)=err(k-3)
        fit%alim(k)=deltav
        fit%blim(k)=0.75*obs%cnchan*deltav
     else
        fit%werr(k)=0.
        if (i.eq.kd0) fit%u(k)=1.
     endif
     k=k+1
  enddo
  !
  ! Various checks
  do k= 1, fit%nu
     if (k .gt. fit%maxext) then
        ifatal = ifatal+1
     else if (fit%werr(k).le.0.d0) then
        ! Fixed parameter
        fit%lcode(k) = 0
        if (k.gt.3) then
           write(mess,'(a,i3,a)') "Parameter",k-3," is fixed"
           call class_message(seve%w,rname,mess)
        endif
     else
        ! Variable parameter
        ninte = ninte + 1
        ! Parameter with limits
        if (fit%lcode(k).ne.1) then
           fit%lcode(k) = 4
           sav = (fit%blim(k)-fit%u(k))*(fit%u(k)-fit%alim(k))
           if (sav.lt.0d0) then
              ifatal = ifatal + 1
              write(mess,'(a,i0,3(a,f0.3))')  &
                'Parameter #',k-3,' (',fit%u(k),') outside limits ',fit%alim(k),' to ',fit%blim(k)
              call class_message(seve%e,rname,mess)
           else if (sav.eq.0d0) then
              if (k.gt.3) then
                 write(mess,'(a,i3,a)') "Parameter",k-3," is at limit"
                 call class_message(seve%w,rname,mess)
              endif
           endif
        endif
     endif
  enddo
  !
  ! End parameter cards
  ! Stop if fatal error
  if (ninte .gt. fit%maxint)  then
     write(mess,1008) ninte,fit%maxint
     call class_message(seve%e,rname,mess)
     ifatal = ifatal + 1
  endif
  if (ninte .eq. 0) then
     call class_message(seve%i,rname,'All input parameters are fixed')
     ifatal = ifatal + 1
  endif
  if (ifatal.gt.0)  then
    write(mess,'(I0,A)')  ifatal,' errors on input parameters, abort.'
    call class_message(seve%e,rname,mess)
    return
  endif
  !
  ! O.K. Start
  ! Calculate step sizes DIRIN
  fit%npar = 0
  do k= 1, fit%nu
     if (fit%lcode(k) .gt. 0)  then
        fit%npar = fit%npar + 1
        fit%lcorsp(k) = fit%npar
        sav = fit%u(k)
        fit%x(fit%npar) = pintf(fit,sav,k)
        fit%xt(fit%npar) = fit%x(fit%npar)
        sav2 = sav + fit%werr(k)
        vplu = pintf(fit,sav2,k) - fit%x(fit%npar)
        sav2 = sav - fit%werr(k)
        vminu = pintf(fit,sav2,k) - fit%x(fit%npar)
        fit%dirin(fit%npar) = 0.5d0 * (dabs(vplu) +dabs(vminu))
     endif
  enddo
  return
  !
1002 format((3(1pg10.3)))
1008 format (' Too many variable parameters.  You request ',i5/,   &
       &    ' This version of MINUIT is only dimensioned for ',i4)
end subroutine midgauss
