!******************************************************************************
!
!    mdoptomog.f95 (part of doptomog package v2.0)
!    Copyright (C) 2015  Enrico J. Kotze ejk@saao.ac.za
!
!    This program is free software: you can redistribute it and/or modify
!    it under the terms of the GNU General Public License as published by
!    the Free Software Foundation, either version 3 of the License, or
!    (at your option) any later version.
!
!    This program is distributed in the hope that it will be useful,
!    but WITHOUT ANY WARRANTY; without even the implied warranty of
!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!    GNU General Public License for more details.
!
!    You should have received a copy of the GNU General Public License
!    along with this program.  If not, see <http://www.gnu.org/licenses/>.
!
!******************************************************************************
module mdoptomog
!******************************************************************************

!******************************************************************************
	implicit none
!******************************************************************************

!******************************************************************************
	! general data:
	! cwd = current working directory
	character(len=255)								::	cwd = ''
	! proj = projection (0 = std, 1 = inside-out), default = 0
	integer											::	proj = 0
	character(len=1)								::	cproj = ''
	! srcpath = path to source folder
	character(len=255)								::	srcpath = ''
	! inpath = input path
	character(len=255)								::	inpath = ''
	! outpath = output path
	character(len=255)								::	outpath = ''
	! debug indicator
	logical											::	debug
	
	! parameter data:
	integer, parameter				::	mc = 1
	! gaussian smearing parameters
	integer, parameter				::	ms = 100
	real, parameter					::	sw = 1.5
	! flim = max limit for acceleration parameter amu
	real(kind(1d0)), parameter		::	flim = 1e+5
	real(kind(1d0)), parameter		::	fmin = 1e-6
	! parameters for acceleration calculation
	integer, parameter	::	dl = 0, dm = 1, dl2 = 2, dm2 = 3, dldm = 4
	! parameters for stages at which output log is written
	integer, parameter				::	l0 = 0, l1 = 1, l2 = 2, l3 = 3
	! parameters for sine and cosine tables
	integer, parameter				::	lower = 1, centre = 2, upper = 3
	
	! input data: 'doptomog.in'
	! iH = type of likelihood function (0 = log, 1 = rms)
	! nrm = 1 for normalisation to flat light curve
	! nsw = smearing width in default map
	integer											::	iH, nrm, nsw
	! nmi = max number of iterations
	! pri = print control (0 = log and screen, 1 = log only)
	integer											::	nmi, pri
	! acc = accuracy of convergence
	! bfa = baseline flux factor (fraction of average spectrum)
	! bfm = minimum overall base level added before normalisation
	real(kind(1d0))									::	acc, bfa, bfm
	! alf = model alfa value
	! amp, wid = amplitude and width of central absorption fudge
	real(kind(1d0))									::	alf, amp, wid
	! np = nr of pixels (in one direction)
	! nhp = nr of half-phase maps
	integer											::	np, nhp = 0
	
	! input data: specFile
	! pmod = period fold indicator (0 = orbital, 1 = spin)
	! npb = nr of phase bins
	! nvp = nr of velocity points
	integer											::	pmod, npb, nvp
	! vs = velocity scale (factor to convert velocity points to m/s)
	! gam = gamma velocity (m/s)
	! w0 = line rest wavelength
	real(kind(1d0))									::	vs, gam, w0
	! if abl=1, invert line (for absorption lines)
	integer											::	abl
	! if atm=1, take out atmospheric absorption
	integer											::	atm
	! src (specList)
	character(len=20)								::	src = ''

	! array data:
	! vp = velocity points
	! phase = centres of phase bins
	! dphase = width of phase bins
	! phii = input spectra flux values
	real(kind(1d0)), dimension(:), allocatable		::	vp, phase, dphase, phii
	real(kind(1d0)), dimension(:,:), allocatable	::	spec

	! calculated data:
	! suffix = suffix to output files
	character(len=4)								::	chp = ''
	! phasep = centres of phase bins used
	! dphasep = width of phase bins used
	! phip = input spectra flux values used
	real(kind(1d0)), dimension(:), allocatable		::	phasep, dphasep, phip
	real(kind(1d0)), dimension(:), allocatable		::	pIndexM
	real(kind(1d0)), dimension(:,:), allocatable	::	specp
	! nvt = total nr of velocity entries
	! nmt = total nr of map points
	! nm = length of map solution
	! npm = nr of phase bins used
	! nvm = nr of velocity points used
	integer											::	nvt, nmt, nm, npm, nvm
	! vmax = maximum absolute velocity
	! fv = half of np
	! dv = velocity bin width
	! dvi = velocity point width
	real(kind(1d0))									::	vmax, fv, dv, dvi
	! H = calculated likelihood value
	! S = calculated entropy value
	! Q = calculated quality function
	! Q0 = previous quality function value
	! del = convergence measure
	real(kind(1d0))									::	H, S, Q, Q0, del
	! fla = lambda acceleration factor
	! fmu = mu acceleration factor
	! amu = additional acceleration factor
	real(kind(1d0))									::	fla, fmu, amu
	real(kind(1d0)), dimension(30)					::	amus
	! ns0, ns1 = interim values of ns
	integer											::	ns0 = 0, ns1 = 0
	! mi = number of modulation iterations
	! ni = number of fme iterations counter
	integer											::	mi, ni
	! idnr = identification number
	real(kind(1d0))									::	idnr
	
	! smp = smearing matrix
	real(kind(1d0)), dimension(-ms:ms)				::	smp

	! forward and backward projection matrices
	real(kind(1d0)), dimension(:,:), allocatable	::	P, indP
	real(kind(1d0)), dimension(:,:), allocatable	::	Pt, indPt
	! array for storage of sums of projection matrix
	real(kind(1d0)), dimension(:), allocatable		::	Psum
	! index arrays - projection matrices
	integer, dimension(:), allocatable				::	ninP
	integer, dimension(:), allocatable				::	ninPt
	! index arrays - image
	integer, dimension(:), allocatable				::	indx, indy
	! lower, centre and upper edges of phase bins
	real(kind(1d0)), dimension(:,:), allocatable	::	phasebins
	! sin and cos tables for centre, lower and upper edges of phase bins
	real(kind(1d0)), dimension(:,:), allocatable	::	sin2piphi, cos2piphi
	! lower edges of velocity bins
	real(kind(1d0)), dimension(:), allocatable		::	vplower

	! phib = baseline spectra flux values
	! phiu = unitising spectra flux values
	real(kind(1d0)), dimension(:), allocatable		::	phib, phiu
	! phi0 = starting spectra flux values
	! phi = "working" spectra flux values
	real(kind(1d0)), dimension(:), allocatable		::	phi0, phi
	! dphi0 = previous delta spectra flux values
	! dphi = current delta spectra flux values
	real(kind(1d0)), dimension(:), allocatable		::	dphi0, dphi
	! psib = flat dopmap corresponding to phib
	real(kind(1d0)), dimension(:), allocatable		::	psib
	! psi0 = starting dopmap
	! psi = "working" dopmap
	real(kind(1d0)), dimension(:), allocatable		::	psi0, psi
	! dpsi0 = previous delta dopmap
	! dpsi = current delta dopmap
	real(kind(1d0)), dimension(:), allocatable		::	dpsi0, dpsi
	! dHdpsi = likelihood derivative dopmap (dH/dpsi)
	! dSdpsi = entropy derivative dopmap (dS/dpsi)
	real(kind(1d0)), dimension(:), allocatable		::	dHdpsi, dSdpsi
	! psic = change dopmaps
	real(kind(1d0)), dimension(:,:), allocatable	::	psic
	! chi = default dopmap
	real(kind(1d0)), dimension(:), allocatable		::	chi

	real(kind(1d0)), dimension(:), allocatable		::	gs, fs
	real(kind(1d0)), dimension(:), allocatable		::	tphii, tphi0, tphase
	real(kind(1d0)), dimension(:), allocatable		::	tpsi, mavg, mamp
	real(kind(1d0)), dimension(:), allocatable		::	mpha, mpham, mphap
	real(kind(1d0)), dimension(:,:), allocatable	::	tpsic
	real(kind(1d0)), dimension(:,:), allocatable	::	mpix

	! ierr = return code (alfa_processed, fme_scheme)
	! 	ierr = 0: not converged
	! 	ierr = 1: not converged
	! 	ierr = 2: not monotonic
	! 	ierr = 3: not converged, not monotonic
	! 	ierr = 4: stuck at vanishing updates
	integer											::	ierr

!******************************************************************************

!******************************************************************************
contains
!******************************************************************************

!******************************************************************************


!******************************************************************************

!******************************************************************************
end module mdoptomog
!******************************************************************************

!******************************************************************************
