!******************************************************************************!
! This tests the functionality of correlate.
!
! @author  Scott Fernandez
! @version $Id: test_correlate.mm,v 1.3 2011/10/14 21:16:10 ntn Exp $
! @since   NeXtMidas 3.1.0
!******************************************************************************!
startmacro s:func[""]
  switch INTERACTIVE interAct GET DEF=TRUE  SDEF=TRUE  ! for normal interactive test(s)
  switch BASELINE    baseline GET DEF=FALSE SDEF=TRUE  ! for defects or more obscure test case(s)
  switch KEEP        keep     GET DEF=FALSE SDEF=TRUE  ! to keep generated / output files

  switch "FRAMESIZE"    frame_size    GET 64k
  switch "THROTTLERATE" throttle_rate GET 3E4

  if func NEQS "" and func NEQS "ALL" then
    call test_^{func}
    stop
  endif

  call test_basic
  call test_advanced
  call test_xferLength

  if interAct then
    set instructions "You should see white noise in the top panel with maximum &
        amplitude usually being between 20 and 30, as well as different white &
        noise in the bottom panel with maximum amplitude usually being between &
        1000 and 2000.  It should update every few seconds with new data."

    WAVEFORM OUT=temp_correlate_feature  FORM=SF ELEM=128 SHAPE=SQUARE AMP=5
    headermod temp_correlate_feature xdelta=1/throttle_rate

    set frame_size 64k

    pipe on
      panel/msgid=MAIN/setup/controls=gc
      gcontrol label macro "Test MACRO"
      gcontrol menu  main "Exit with Status =" "PASS,FAIL" TABLE={ItemColors={PASS="GREEN",FAIL="RED"}} /tleft

      WAVEFORM/THROTTLE=REALTIME OUT=_input FORM=SF ELEM=100M FREQ=throttle_rate/10 SHAPE=WHITE AMP=10 DELTA=1/throttle_rate

      correlate/quiet _input temp_correlate_feature _output

      plot/id=input   _input{fs=frame_size} type=line ! Y1=-20 Y2=20
      plot/id=feature temp_correlate_feature
      plot/id=output  _output{fs=frame_size} type=line ! Y1=-1E3 Y2=1E3

      gcontrol text  idtext "Instructions" instructions 24 15 /title
      gcontrol label  debug "Debug" Closed
      gcontrol choice shape "Shape " reg.waveform.shapeList reg.waveform.shape
    pipe off

  endif

  if keep isFalse then
    erase temp_correlate_feature
  endif
endmacro

!******************************************************************************!
! Main process message for this macro. Should be right after the ENDMACRO.
procedure processMessage m:msg
  if msg.name eqs "MAIN" then
    assert/text="^reg.main.name: User indicated tests" msg.data eqss "PASS"
    pipe stop

  elseif msg.name eqs "SHAPE"
    set reg.waveform.shape msg.data

  else
    say "Unhandled message name: ^msg.name from fid: ^msg.fid data: ^msg.data"
  endif
return

!******************************************************************************!
! Process unhandled exceptions
procedure processException m:emsg
  assert/text="^reg.main.name: Unexpected exception: ^{emsg}" false
  if this.verbose then invoke ,, emsg.data.printStacktrace()
return

!******************************************************************************!
! Basic test
procedure test_basic
  WAVEFORM temp_correlate_sin FORM=SF ELEM=128k SHAPE=SIN      AMP=1 FREQ=.01
  WAVEFORM temp_correlate_c   FORM=SF ELEM=1    SHAPE=CONSTANT AMP=1
  correlate/quiet temp_correlate_sin temp_correlate_c temp_correlate_out
  fcalc temp_correlate_diff temp_correlate_sin temp_correlate_out -
  maxmin/quiet temp_correlate_diff temp_max temp_min

  assert/text="^reg.main.name: Compare output to known values" temp_max eq 0 and temp_min eq 0

  remove temp_max temp_min
  if keep isFalse then
    erase temp_correlate_sin temp_correlate_c temp_correlate_out temp_correlate_diff
  endif
return

!******************************************************************************!
! Advanced tests
procedure test_advanced
  set expected1 "nxm.dsp.test.test_correlate_expected1.prm"
  set expected2 "nxm.dsp.test.test_correlate_expected2.prm"
  WAVEFORM OUT=temp_correlate_in    FORM=SF ELEM=25 SHAPE=CONSTANT AMP=0
  WAVEFORM OUT=temp_correlate_merge FORM=SF ELEM=15 SHAPE=CONSTANT AMP=10
  MERGEFILE IN=temp_correlate_in OUT=temp_correlate_merge

  correlate/quiet temp_correlate_merge temp_correlate_merge temp_correlate_out1
  COMPARE IN1=expected1 IN2=temp_correlate_out1 MAX_OUT=junk1 MIN_OUT=junk2  RESULT=same
  assert/text="^reg.main.name: Comparing output to known values" same eq 1

  correlate/quiet temp_correlate_out1 temp_correlate_out1 temp_correlate_out2
  COMPARE IN1=expected2 IN2=temp_correlate_out2 MAX_OUT=junk1 MIN_OUT=junk2 RESULT=same
  assert/text="^reg.main.name: Comparing output to known values" same eq 1

  if keep isFalse then
    erase temp_correlate_in temp_correlate_merge temp_correlate_out1 temp_correlate_out2
  endif
return

!******************************************************************************!
! Test transfer length.
procedure test_xferLength
  ! Randomize impulse and input sizes, make sure at least 1
  CALCULATOR/QUIET impLength RANDOM 401 * FLOOR 1 +
  CALCULATOR/QUIET inpLength RANDOM 2k * FLOOR 1 +
  WAVEFORM OUT=temp_correlate_imp FORM=SF ELEM=impLength SHAPE=CONSTANT AMP=10
  WAVEFORM OUT=temp_correlate_in  FORM=SF ELEM=inpLength SHAPE=SIN AMP=5

  ! Compare tl=inpLength and tl=impLength
  correlate/quiet temp_correlate_in temp_correlate_imp temp_correlate_out1 /tl=impLength
  correlate/quiet temp_correlate_in temp_correlate_imp temp_correlate_out2 /tl=inpLength
  COMPARE IN1=temp_correlate_out1 IN2=temp_correlate_out2 MAX_OUT=junk1 MIN_OUT=junk2 RESULT=same
  assert/text="^reg.main.name: Comparing output with tl at input sizes" same eq 1

  ! Compare probably tl < impLength

  ! 1 + floor( (impLength-1)*random ), less than or equal to impLength
  CALCULATOR/QUIET rand 1 impLength 1 - RANDOM * FLOOR +
  correlate/quiet temp_correlate_in temp_correlate_imp temp_correlate_out2 /tl=rand
  COMPARE IN1=temp_correlate_out1 IN2=temp_correlate_out2 MAX_OUT=junk1 MIN_OUT=junk2 RESULT=same
  assert/text="^reg.main.name: Comparing to output with small transfer length" same eq 1

  ! Compare probably impLength < tl < inpLength

  ! floor( |inpLength-impLength|*random) ) + impLength, greater than or
  ! equal to impLength, probably less than inpLength, probably in between
  CALCULATOR/QUIET rand impLength inpLength impLength - ABS RANDOM * FLOOR +
  correlate/quiet temp_correlate_in temp_correlate_imp temp_correlate_out2 /tl=rand
  COMPARE IN1=temp_correlate_out1 IN2=temp_correlate_out2 MAX_OUT=junk1 MIN_OUT=junk2 RESULT=same
  assert/text="^reg.main.name: Comparing to output with transfer length in between" same eq 1

  ! Compare tl = inpLength + ceil(1M*random) > inpLength
  CALCULATOR/QUIET rand inpLength 1M RANDOM * CEIL +
  correlate/quiet temp_correlate_in temp_correlate_imp temp_correlate_out2 /tl=rand
  COMPARE/QUIET IN1=temp_correlate_out1 IN2=temp_correlate_out2 MAX_OUT=junk1 MIN_OUT=junk2 RESULT=same
  assert/text="^reg.main.name: Comparing to output with very large transfer length" same eq 1

  if keep isFalse then
    erase temp_correlate_in temp_correlate_imp temp_correlate_out1 temp_correlate_out2
  endif
return
