How to use FITLINES
===================

FITLINES is an interactive widget-based function to fit 1-dimensional
profiles to features in 1-D spectral data, Y[X].  In principle, it
only works with 3-parameter curve families (Gaussians, Lorentzians),
but in practice curves with extra parameters may be fit (Modified
Lorentzians, Rotationally Broadened Line) provided that the extra
parameters are held fixed.

Currently, the following functions are encoded via MK_3MODEL():

Function               TYPE definitions for MK_3MODEL()

Gaussian               G; GAUSSIAN; etc.
Lorentzian             L; LORENTZIAN; etc.
Beta-profile           B; BETA; BETA=<index>; BETA:<index>; BETA <index>; etc.
Asymmetric Slanted     SL; SLANT; SLANT=<angle>; SLANT=<angle>,<beta>; etc.
  Beta-profile
Rotation Broadened     R; ROT; ROT=<velocity>; etc.
  Gaussian
Broken Power-Law       PW; PW@<break>; PW=<break>; etc.
Identity               I; Ident; etc.
Sinusoid               SI; Sin=<phase>; etc.

FITLINES must be called as a function, and returns a structure containing
the best-fit positions, fluxes, widths, associated errors, etc.

To see the complete calling sequence, type
	help,fitlines()
at the "IDL>" prompt.  The output lists all the parameters and keywords
accepted by FITLINES.  Do not panic: in the majority of the cases, only
a few of them have to be specified.  For a description on what each of
the variables mean, see
	http://hea-www.harvard.edu/PINTofALE/PoA.html#FITLINES

An example walk-through for using FITLINES is given below.
This is by no means to be considered comprehensive, but
does exercise some of the major features of the GUI.

-- Start IDL 

-- initialize the PINTofALE environment

    .run initale

-- restore a spectrum for fitting line profiles to (we will
    fit beta-profiles to the Si XIII triplet at 6.7 AA):

    restore,!ARDB+'/demo_v711Tau.save',/verbose

    plot,LAM_M1P_V711TAU,SPC_M1P_V711TAU,psym=10,xr=[6.5,7.0],/xs,$
      xtitle='Wavelength ['+string(byte(197))+']',ytitle='Counts/bin',$
      title='HR 1099: HETG/MEG +1',yr=[0,400],/ys

-- initialize the input to FITLINES

    ;Specify that 3 model components are needed by declaring a 3-element
    ;array for the locations.  the locations need only be approximate.
    pos=fltarr(3)+6.5

    NOTE: it is possible to start off with fewer components; new ones
    may be added to the mix using the GUI.

    type='beta 1.8'   ;to fit beta-profiles of index 1.8
    wdt=0.05          ;set the initial values of the widths to 0.05

-- start up the GUI

    fstr=fitlines(LAM_M1P_V711TAU,SPC_M1P_V711TAU,ysig=SPE_M1P_V711TAU,$
    pos=pos,perrp=perrp,perrm=perrm,perrc=perrc,$
    flx=flx,ferrp=ferrp,ferrm=ferrm,ferrc=ferrc,$
    wdt=wdt,werrp=werrp,werrm=werrm,werrc=werrc,$
    thaw=thaw,type=type,epithet=epithet,ties=ties,$
    conlev=conlev,consig=consig,/dumb,verbose=!verbose)

    NOTE: the /DUMB keyword ensures that FIT_LEVMAR does not stop every
    so often to ask for directions.  For those of you raised on XSPEC,
    that is like setting query to yes while fitting.

-- display the full spectrum
   
   [PULL DOWN] VIEW -> SHOW

-- restrict X-axis range

   [PULL DOWN] XRANGE -> Keyboard
   [TYPE @ PROMPT] 6.5 7 <CR>
   [PULL DOWN] VIEW -> SHOW

   where "<CR>" represents a carriage-return.

   To also set the Y-axis range to something more useful,

   [PULL DOWN] YRANGE -> Current
   [PULL DOWN] VIEW -> SHOW

-- the initial guesses for the line locations are clearly very bad.
   reset them to more reasonable values at the parameter editing
   interface at center-left of the GUI.

   [TYPE IN BOX "Component"] 0
   [TYPE IN BOX "Position"] 6.65 <CR>
   [TYPE IN BOX "Label"] Si13 r <CR>
   [TYPE IN BOX "Component"] 1
   [TYPE IN BOX "Position"] 6.70 <CR>
   [TYPE IN BOX "Label"] Si13 i <CR>
   [TYPE IN BOX "Component"] 2
   [TYPE IN BOX "Position"] 6.75 <CR>
   [TYPE IN BOX "Label"] Si13 f <CR>

-- it is better to let the program figure out the best guesses
   for the initial values of the fluxes, so click on the buttons
   corresponding to the fluxes (parameters A2, A5, and A8) at the
   left of the center-right descriptor window, and then renormalize
   the fluxes

   [LEFT CLICK ON BUTTON FOR A2]
   [LEFT CLICK ON BUTTON FOR A5]
   [LEFT CLICK ON BUTTON FOR A8]
   [LEFT CLICK] RENORM

   the model profiles at this point look thus:

   [PULL DOWN] VIEW -> SHOW

-- there is also a fairly large continuum at this wavelength range.
   the continuum is best set "by hand".

   [PULL DOWN] CONTINUUM -> Piecewise
   [LEFT CLICK ON PLOT, AT APPROX (6.9,95)] 
   (multiple clicks will allow a more complex definition)
   [LEFT CLICK IN PLOT WINDOW, BELOW X-AXIS]
   (get rid of default Poisson error on continuum estimation)
   [RIGHT CLICK WITHIN PLOT]
   (exit)
   [PULL DOWN] CONTINUUM -> ACCEPT
   (to adopt the newly defined continuum)   (VERY IMPORTANT!!!)

   [PULL DOWN] VIEW -> SHOW
   [LEFT CLICK] RENORM
   [PULL DOWN] VIEW -> SHOW

-- set up constraints on the parameters (these are essentially
   any legal IDL statement that modify the parameter values)
   
   these ensure that the widths of all the fitted lines are identical:
   [TYPE IN BOX "ADD"] A4 = A1 <CR>
   [TYPE IN BOX "ADD"] A7 = A1 <CR>
 
   these ensure that all fluxes are +ve:
   [TYPE IN BOX "ADD"] A2 = A2 > 0 <CR>
   [TYPE IN BOX "ADD"] A5 = A5 > 0 <CR>
   [TYPE IN BOX "ADD"] A8 = A8 > 0 <CR>

   far more complicated constraints may also be set.  for example,
   the following ensures that the flux of the intercombination line
   lies between a fifth to half that of the forbidden line
   [TYPE IN BOX "ADD"] A5 = (A5 < (A8/2.) > (0.2*A8))

   as another example, the following forces the location of the
   intercombination line to lie between that of the resonance and
   the forbidden lines
   [TYPE IN BOX "ADD"] A3 = (A3 > A0) < A6

-- Now thaw all the relevant parameters

   [LEFT CLICK ON BUTTON FOR A0]
   [LEFT CLICK ON BUTTON FOR A1]
   [LEFT CLICK ON BUTTON FOR A3]
   [LEFT CLICK ON BUTTON FOR A6]

   Note that A4 and A7 must be left frozen, because they are
   to have values identical to A1.  However, A3, A5, A6, and
   A7 are thawed, because even if strongly constrained, they
   must still be fit.

-- Fit

   [LEFT CLICK] FIT
   [PULL DOWN] VIEW -> SHOW

   which results in a reasonable fit (reduced chisq ~ 1.1)

   the widths may be -ve, which actually does not matter except for
   aesthetic reasons.  if -ve, reset them to +ve values using the
   parameter editing interface.

-- reduce the range over which the fit is carried out.  let the
   program guess at an appropriate range, which it does by looking
   at the values of all the thawed positions and widths.

   [PULL DOWN] XRANGE -> Guess

-- and fit again

   [PULL DOWN] VIEW -> SHOW
   [LEFT CLICK] FIT
   [PULL DOWN] VIEW -> SHOW

-- save the fit parameters internally

   [LEFT CLICK] SAVE

-- dump the current state to disk, for leisurely access via FITLINES_UNDUMP

   [LEFT CLICK] DUMP
   [TYPE @ PROMPT] /tmp/fitlines.save

-- Obtain 1-sigma chisq-surface-projected errors

   [LEFT CLICK] ERRORS

   NOTE: the error finding subroutine is very robust, but it may still
   crash (or go into a catatonic loop) when confronted with pathological
   error surfaces.  it is always possible to get back to the GUI in such
   cases by typing RETURN at the ERORS subroutine level.

-- fit to a new line, say the one at 6.2 AA

   [PULL DOWN] XRANGE -> RESET
   [PULL DOWN] XRANGE -> Keyboard
   [TYPE @ PROMPT] 5.5 7.0 <CR>
   [PULL DOWN] YRANGE -> Current

   Note the sharp drop at 6.5 AA, which is due to the fact that the
   continuum was defined only in the range 6.5-7.0 AA.  Choose a small
   interval in which to fit the new line:

   [PULL DOWN] XRANGE -> Cursor
   this will put you in PICKRANGE(), which is described elsewhere.
   All that matters here is to hold down the left button and drag
   it over the x-interval of interest.
   [LEFT DRAG, say from (6.1,100) to (6.3,100)]
   [RIGHT CLICK to exit PICKRANGE()]

   define a new model component
   [PULL DOWN] MODEL -> ADD Component
   hold down the left button and drag from the peak of the line
   to a point that denotes the width
   [DRAG, say from (6.19,350) to (6.2,150)]
   [CLICK to exit model definition]

   in order to fit only the new component to the selected line feature,
   all the other model components must be frozen
   [PULL DOWN] MODEL -> Freeze Unimportant
   [LEFT CLICK] RENORM

   the continuum must be redefined
   [PULL DOWN] CONTINUUM -> Piecewise
   to avoid using Poisson errors on the defined continuum,
   [LEFT CLICK BELOW X-AXIS]
   to adjust the continuum level, hold down the left button and drag
   to new level
   [LEFT DRAG, from say (6.2,95) to (6.2,90)]
   [RIGHT CLICK to exit]
   [PULL DOWN] CONTINUUM -> ACCEPT
   [LEFT CLICK] RENORM
   [PULL DOWN] VIEW -> SHOW

   [LEFT CLICK] FIT
   [PULL DOWN] VIEW -> SHOW

   which is again a reasonable fit, with a reduced chisq ~ 1.4

   [LEFT CLICK] ERRORS

-- to quit
  
   [LEFT CLICK] QUIT

-- all the useful quantities are in the output,
    IDL> help,fstr,/str
    ** Structure <39a2d0>, 21 tags, length=196952, refs=1:
       POS             FLOAT     Array[4]
       PERRP           FLOAT     Array[4]
       PERRM           FLOAT     Array[4]
       PERRC           FLOAT     Array[4]
       FLX             FLOAT     Array[4]
       FERRP           FLOAT     Array[4]
       FERRM           FLOAT     Array[4]
       FERRC           FLOAT     Array[4]
       WDT             FLOAT     Array[4]
       WERRP           FLOAT     Array[4]
       WERRM           FLOAT     Array[4]
       WERRC           FLOAT     Array[4]
       THAW            INT       Array[12]
       TYPE            STRING    Array[4]
       TIES            STRING    Array[7]
       EPITHET         STRING    Array[4]
       CONLEVX         DOUBLE    Array[8192]
       CONLEV          FLOAT     Array[8192]
       CONSIGX         DOUBLE    Array[8192]
       CONSIG          FLOAT     Array[8192]
       COMMENT         STRING    '<chisq=42.778772> <DUMB=1> <VERBOSE=10> {a4 ='...
    IDL> for i=0,3 do print,(fstr.pos)[i]+[-(fstr.perrm)[i],0,(fstr.perrp)[i]]
          6.65619      6.65661      6.65703
          6.69431      6.69571      6.69710
          6.74903      6.74935      6.74967
          6.18996      6.19036      6.19075
    IDL> for i=0,3 do print,(fstr.wdt)[i]+[-(fstr.werrm)[i],0,(fstr.werrp)[i]]
        0.0111397    0.0116787    0.0122177
        0.0111397    0.0116787    0.0122177
        0.0111397    0.0116787    0.0122177
        0.0115940    0.0122118    0.0128578
    IDL> for i=0,3 do print,(fstr.flx)[i]+[-(fstr.ferrm)[i],0,(fstr.ferrp)[i]]
          1063.90      1109.42      1154.95
          152.692      184.313      215.934
          612.465      651.284      690.103
          1155.23      1205.77      1256.64