!******************************************************************************!
!  Purpose: test WAVEFORM command
!
!  Version :  $Id: test_waveform.mm,v 1.26 2013/05/01 17:26:30 jwb Exp $
!******************************************************************************!
startmacro S:wform["ALL"]
  switch BASELINE    baseline GET DEF=FALSE SDEF=TRUE  ! for defects or more obscure test case(s)
  if wform EQS ALL then
    invoke wavelist nxm.sys.prim.waveform.shapeList
    foreach wform INLIST wavelist
      sedit wform wform "LOCASE"
      call test_^wform
    endfor
    call test_formats
  else
    sedit wform wform "LOCASE"
    call test_^wform
  endif

  !!!  TODO: Change the test below so it does not bomb out on Windows for Heap space !!!
  if env.ostype eqs "DOS" then
    INFO "Skipping VRF tests in Windows due to excessive RAM usage"
  else
    call test_vrf     ! Tests VRF= BW= RF= and DURATION=
  endif

endmacro


!******************************************************************************!
procedure processException m:emsg
  assert/text="^reg.main.name: Unexpected exception: ^{emsg}" false
  if "Trace" SUBS ENV.DEBUG invoke ,, emsg.data.printStackTrace()
return

!******************************************************************************!
!  Purpose: To test use of VRF= BW= RF= and DURATION=
procedure test_vrf
  WAVEFORM ram:myfile_sf FORM=SF ELEM=16M SHAPE=SINE &
                         RF=300.1e6 VRF=300e6 BW=1e6 &
                         DURATION=0.1
  WAVEFORM ram:myfile_cf FORM=CF ELEM=16M SHAPE=SINE &
                         RF=300.1e6 VRF=300e6 BW=1e6 &
                         DURATION=0.1

  FFT/PSD    ram:myfile_sf ram:myspec_sf NFFT=64k OVER=0.5 NAVG=16
  STATUS     ram:myspec_sf FS=size
  HEADERMOD  ram:myspec_sf type=1000 size=size
  STATISTICS ram:myspec_sf AMAX=FREQ_SF

  FFT/PSD    ram:myfile_cf ram:myspec_cf NFFT=64k OVER=0.5 NAVG=16
  STATUS     ram:myspec_cf FS=size
  HEADERMOD  ram:myspec_cf type=1000 size=size
  STATISTICS ram:myspec_cf AMAX=FREQ_CF

  key ram:myfile_sf get "VRF" VRF_SF
  key ram:myfile_cf get "VRF" VRF_CF

  assert/text="Using VRF/BW/RF with SF data: xstart" 0.0    EQ   FILE(ram:myfile_sf).xstart
  assert/text="Using VRF/BW/RF with CF data: xstart" 0.0    EQ   FILE(ram:myfile_cf).xstart
  assert/text="Using VRF/BW/RF with SF data: xdelta" 0.5e-6 EQ   FILE(ram:myfile_sf).xdelta
  assert/text="Using VRF/BW/RF with CF data: xdelta" 1.0e-6 EQ   FILE(ram:myfile_cf).xdelta
  assert/text="Using VRF/BW/RF with SF data: VRF"    300e6  EQ   VRF_SF
  assert/text="Using VRF/BW/RF with CF data: VRF"    300e6  EQ   VRF_CF
  assert/text="Using VRF/BW/RF with SF data: FREQ"   400e3  EQ/T FREQ_SF /TOL=1e3
  assert/text="Using VRF/BW/RF with CF data: FREQ"   100e3  EQ/T FREQ_CF /TOL=1e3
  assert/text="Using DURATION  with SF data: size"   200001.0   EQ FILE(ram:myfile_sf).size
  assert/text="Using DURATION  with CF data: size"   100001.0    EQ FILE(ram:myfile_cf).size

  erase ram:myfile_cf ram:myfile_sf
return

!******************************************************************************!
!  Purpose: To test for inconsistent file lengths
procedure test_constant
  set nelems 4k
  waveform short sf 10 const 1
  waveform long sf 20 const 2
  fcalc test1 short long -
  status test1 size=out1
  fcalc test2 long short -
  status test2 size=out2

  res expected 10.0
  ASSERT/TEXT="^reg.main.name: CONSTANT File length (test #1)" out1 EQ out2 AND out2 EQ expected

  waveform short sf 5 const 1
  waveform long sf 10 const 2
  fcalc test1 short long +
  status test1 size=out1
  fcalc test2 long short +
  status test2 size=out2

  res expected 5.0
  ASSERT/TEXT="^reg.main.name: CONSTANT File length (test #2)" out1 EQ expected AND out2 EQ expected

  waveform short sf 15 const 1
  waveform long sf 20 const 2
  fcalc test1 short long /
  status test1 size=out1
  fcalc test2 long short /
  status test2 size=out2

  res expected 15.0
  ASSERT/TEXT="^reg.main.name: CONSTANT File length (test #3)" out1 EQ expected AND out2 EQ expected

  waveform short sf 5 const 1
  waveform long sf 10 const 2
  fcalc test1 short long *
  status test1 size=out1
  fcalc test2 long short *
  status test2 size=out2

  res expected 5.0
  ASSERT/TEXT="^reg.main.name: CONSTANT File length (test #4)" out1 EQ expected AND out2 EQ expected

  waveform short sf 5 const 1
  waveform long sf 5 const 2
  fcalc test1 short long max
  status test1 size=out1
  fcalc test2 long short maximum
  status test2 size=out2

  res expected 5.0
  ASSERT/TEXT="^reg.main.name: CONSTANT File length (test #5)" out1 EQ expected AND out2 EQ expected

  waveform short sf 10 const 1
  waveform long sf 25 const 2
  fcalc test1 short long min
  status test1 size=out1
  fcalc test2 long short minimum
  status test2 size=out2

  res expected 10.0
  ASSERT/TEXT="^reg.main.name: CONSTANT File length (test #6)" out1 EQ expected AND out2 EQ expected

  if test1 fexists erase/verbose=false test1
  if test2 fexists erase/verbose=false test2
  if long fexists erase/verbose=false long
  if short fexists erase/verbose=false short
return

!******************************************************************************!
procedure test_sine
  !
  ! SCALAR BYTE
  !
  set nelems 202
  result tolerance 1e-7
  result formatList "SB,SF"
  foreach format INLIST formatList
    result expTab {}
    result D:expTab.max   1.0
    result D:expTab.min  -1.0
! JPH -- commented out 26JUN03 -- pending a better test
!    if "^format" EQS "SB" then
!      result D:expTab.mean -4.768371582031E-07
!      result D:expTab.sdev  0.812404040025
!    else
!      result D:expTab.mean -4.781190917491E-07
!      result D:expTab.sdev  0.707107359678
!    endif

!WARNING:TEST WILL FAIL IF SIN IS NOT DEFAULT
    result testname "SIN_^format"
    result testfile "temp_waveform"
    WAVEFORM,OUT=^testfile,FORM=^format,ELEM=^nelems, &
             AMP=1,FREQ=.01,PHASE=0,START=0,DELTA=1

    foreach offset INSIZE FILE(^testfile).size
     if "^format" EQS "SB"
      if ^offset eq 0
       assert/text="%TEST_WAVEFORM: SINE at 0  SB" ^{FILE(^testfile).data(offset)} eq 0
      endif
       if ^offset eq 41
       assert/text="%TEST_WAVEFORM: SINE at 41 SB"  ^{FILE(^testfile).data(offset)} eqt 1
      endif
      if ^offset eq 58
       assert/text="%TEST_WAVEFORM: SINE at 58 SB"  ^{FILE(^testfile).data(offset)} eq 0
      endif
      if ^offset eq 91
       assert/text="%TEST_WAVEFORM: SINE at 91 SB"  ^{FILE(^testfile).data(offset)} eqt -1
      endif
     else
      if ^offset eq 0
       assert/text="%TEST_WAVEFORM: SINE at 0  SF" ^{FILE(^testfile).data(offset)} eq 0
      endif
      if ^offset eq 25
       assert/text="%TEST_WAVEFORM: SINE at 25 SF"  ^{FILE(^testfile).data(offset)} eqt 1
      endif
      if ^offset eq 50
       assert/text="%TEST_WAVEFORM: SINE at 50 SF"   ^{FILE(^testfile).data(offset)} GE 0 AND ^{FILE(^testfile).data(offset)} LE 1E-6
      endif
      if ^offset eq 75
       assert/text="%TEST_WAVEFORM: SINE at 75 SF"  ^{FILE(^testfile).data(offset)} eqt -1
      endif
     endif
    endfor
    erase ^testfile
  endfor
return

!******************************************************************************!
procedure test_cosine
  !
  ! SCALAR BYTE
  !
  set nelems 202
  result tolerance 1e-8
  result formatList "SB,SF"
  foreach format INLIST formatList
    result expTab {}
    result D:expTab.max   1.0
    result D:expTab.min  -1.0
    result testname "COS_^format"
    result testfile "temp_waveform"

    WAVEFORM,OUT=^testfile,FORM=^format,ELEM=^nelems,SHAPE=COS,&
             AMP=1,FREQ=.01,PHASE=0,START=1,DELTA=1

    foreach offset INSIZE FILE(^testfile).size
     if "^format" EQS "SB"
      if ^offset eq 0
       assert/text="%TEST_WAVEFORM: COSINE at 0  SB" ^{FILE(^testfile).data(offset)} eqt 1
      endif
       if ^offset eq 33
       assert/text="%TEST_WAVEFORM: COSINE at 33 SB"  ^{FILE(^testfile).data(offset)} eqt 0
      endif
      if ^offset eq 66
       assert/text="%TEST_WAVEFORM: COSINE at 66 SB"  ^{FILE(^testfile).data(offset)} eqt -1
      endif
      if ^offset eq 83
       assert/text="%TEST_WAVEFORM: COSINE at 83 SB"  ^{FILE(^testfile).data(offset)} eqt 0
      endif
     else
      if ^offset eq 0
       assert/text="%TEST_WAVEFORM: COSINE at 0  SF" ^{FILE(^testfile).data(offset)} eqt 1
      endif
      if ^offset eq 25
       assert/text="%TEST_WAVEFORM: COSINE at 25 SF"  ^{FILE(^testfile).data(offset)} GE 0 AND ^{FILE(^testfile).data(offset)} LE 1e-6
      endif
      if ^offset eq 50
       assert/text="%TEST_WAVEFORM: COSINE at 50 SF"  ^{FILE(^testfile).data(offset)} eqt -1
      endif
      if ^offset eq 75
       assert/text="%TEST_WAVEFORM: COSINE at 75 SF"  ^{FILE(^testfile).data(offset)} GE 0 AND ^{FILE(^testfile).data(offset)} LE 1e-6
      endif
     endif
    endfor
    erase ^testfile
  endfor
return

!******************************************************************************!
procedure test_Square
  set nelems 4k
  set formatList "sf,sd"
  foreach form INLIST formatList
    set testfile "test_waveform_^{wform}_^{form}"
    waveform out=testfile form=^form elem=nelems shape=^wform

    ASSERT/TEXT="^reg.main.name: ^wform NELS" FILE(^testfile).getSize EQ nelems

  endfor
  fcalc test_waveform_^{wform}_diff test_waveform_^{wform}_sd test_waveform_^{wform}_sf -
  statistics test_waveform_^{wform}_diff TABLE=stats
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MIN ^stats.min"   stats.min  EQT 0.0
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MAX ^stats.max"   stats.max  EQT 0.0
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MEAN ^stats.mean" stats.mean EQT 0.0

  erase "test_waveform_^{wform}_sf"
  erase "test_waveform_^{wform}_sd"
  erase "test_waveform_^{wform}_diff"
return

!******************************************************************************!
procedure test_Triangle
  set nelems 4k
  set formatList "sf,sd"
  foreach form INLIST formatList
    set testfile "test_waveform_^{wform}_^{form}"
    waveform out=testfile form=^form elem=nelems shape=^wform

    ASSERT/TEXT="^reg.main.name: ^wform NELS" FILE(^testfile).getSize EQ nelems

  endfor
  fcalc test_waveform_^{wform}_diff test_waveform_^{wform}_sd test_waveform_^{wform}_sf -
  statistics test_waveform_^{wform}_diff TABLE=stats

  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MIN ^stats.min"   stats.min  EQT 0.0
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MAX ^stats.max"   stats.max  EQT 0.0
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MEAN ^stats.mean" stats.mean EQT 0.0

  erase "test_waveform_^{wform}_sf"
  erase "test_waveform_^{wform}_sd"
  erase "test_waveform_^{wform}_diff"
return

!******************************************************************************!
procedure test_SawTooth
  set nelems 4k
  set formatList "sf,sd"
  foreach form INLIST formatList
    set testfile "test_waveform_^{wform}_^{form}"
    waveform out=testfile form=^form elem=nelems shape=^wform

    ASSERT/TEXT="^reg.main.name: ^wform NELS" FILE(^testfile).getSize EQ nelems

  endfor
  fcalc test_waveform_^{wform}_diff test_waveform_^{wform}_sd test_waveform_^{wform}_sf -
  statistics test_waveform_^{wform}_diff TABLE=stats
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MIN ^stats.min"   stats.min  EQT 0.0
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MAX ^stats.max"   stats.max  EQT 0.0
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MEAN ^stats.mean" stats.mean EQT 0.0

  erase "test_waveform_^{wform}_sf"
  erase "test_waveform_^{wform}_sd"
  erase "test_waveform_^{wform}_diff"
return

!******************************************************************************!
procedure test_Pulse
  set nelems 4k
  set formatList "sf,sd"
  foreach form INLIST formatList
    set testfile "test_waveform_^{wform}_^{form}"
    waveform out=testfile form=^form elem=nelems shape=^wform

    ASSERT/TEXT="^reg.main.name: ^wform NELS" FILE(^testfile).getSize EQ nelems

  endfor
  fcalc test_waveform_^{wform}_diff test_waveform_^{wform}_sd test_waveform_^{wform}_sf -
  statistics test_waveform_^{wform}_diff TABLE=stats
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MIN ^stats.min"   stats.min  EQT 0.0
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MAX ^stats.max"   stats.max  EQT 0.0
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MEAN ^stats.mean" stats.mean EQT 0.0

  erase "test_waveform_^{wform}_sf"
  erase "test_waveform_^{wform}_sd"
  erase "test_waveform_^{wform}_diff"
return

!******************************************************************************!
procedure test_Zero
  set nelems 4k
  set testfile "test_waveform_^wform"
  waveform out=testfile elem=nelems shape=^wform

  ASSERT/TEXT="^reg.main.name: ^wform NELS" FILE(^testfile).getSize EQ nelems

  statistics testfile TABLE=stats
  ASSERT/TEXT="^reg.main.name: ^wform MIN ^stats.min"   stats.min  EQ 0.0
  ASSERT/TEXT="^reg.main.name: ^wform MAX ^stats.max"   stats.max  EQ 0.0
  ASSERT/TEXT="^reg.main.name: ^wform MEAN ^stats.mean" stats.mean EQ 0.0

  erase testfile

  set formatList "sf,sd"
  foreach form INLIST formatList
    set testfile "test_waveform_^{wform}_^{form}"
    waveform out=testfile form=^form elem=nelems shape=^wform

    ASSERT/TEXT="^reg.main.name: ^wform NELS" FILE(^testfile).getSize EQ nelems

  endfor
  fcalc test_waveform_^{wform}_diff test_waveform_^{wform}_sd test_waveform_^{wform}_sf -
  statistics test_waveform_^{wform}_diff TABLE=stats
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MIN ^stats.min"   stats.min  EQT 0.0
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MAX ^stats.max"   stats.max  EQT 0.0
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MEAN ^stats.mean" stats.mean EQT 0.0

  erase "test_waveform_^{wform}_sf"
  erase "test_waveform_^{wform}_sd"
  erase "test_waveform_^{wform}_diff"
return

!******************************************************************************!
! BUG_2507 - WHITE now uses tests developed for NOISE
procedure test_White
  set formatList "SB,SI,SL,SX,SF,SD,CB,CI,CL,CX,CF,CD"
  set mean 5.0
  set sdev 10.0

  ! first, test for a known size
  set L:nelems 32K
  foreach form INLIST formatList
    set testfile "test_waveform_^{wform}_^{form}_^{nelems}"
    call test_White_helper testfile nelems form mean sdev
  endfor

  set mean -15.0
  set sdev 30.0

  ! next test for a random size
  foreach form INLIST formatList
    calc L:nelems RANDOM 104k * FLOOR 4k +
    set testfile "test_waveform_^{wform}_^{form}_^{nelems}"
    call test_White_helper testfile nelems form mean sdev
  endfor

return

procedure test_White_helper S:testfile L:nelems S:form D:mean D:sdev

  WAVEFORM/seed=123 OUT=testfile FORM=form ELEM=nelems SHAPE=wform MEAN=mean SDEV=sdev

  statistics ^testfile TABLE=stats
  set tolerance 0.1

  ASSERT/TEXT="^reg.main.name: ^wform format ^form NELS ^stats.ELEM == ^nelems" stats.ELEM EQ nelems

  if form.startsWith("C") then
    set  expMean (mean,mean)
    calc expSDev (sdev,sdev) mag  ! since statistics does a magnitude for sdev calcutation
    ASSERT/TEXT="^reg.main.name: ^wform format ^form MEAN ^stats.MEAN =~ ^mean" stats.MEAN EQ/V/T expMean /TOL=tolerance
    ASSERT/TEXT="^reg.main.name: ^wform format ^form SDEV ^stats.SDEV =~ ^expSDev" stats.SDEV EQ/T expSDev /TOL=tolerance
  else
    ASSERT/TEXT="^reg.main.name: ^wform format ^form MEAN ^stats.MEAN =~ ^mean" stats.MEAN EQ/T mean /TOL=tolerance
    ASSERT/TEXT="^reg.main.name: ^wform format ^form SDEV ^stats.SDEV =~ ^sdev" stats.SDEV EQ/T sdev /TOL=tolerance
  endif

  erase testfile
return

!*******************************************************************************
procedure test_LRS
  set nelems 32k
  set formatList "sf,sd"
  foreach form INLIST formatList
    set testfile "test_waveform_^{wform}_^{form}"
    waveform out=testfile form=^form elem=nelems shape=^wform
    statistics testfile TABLE=stats
    ASSERT/TEXT="^reg.main.name: ^wform format ^form NELS" FILE(^testfile).getSize EQ nelems
    calc temp stats.mean ABS
    ASSERT/TEXT="^reg.main.name: ^wform format ^form ABS(MEAN)=^temp" stats.mean LE 1e-3

!jph -- Not sure what other statistical checks I should do here

    erase testfile
  endfor

return

!******************************************************************************!
procedure test_Ramp
  set nelems 4k
  set formatList "sf,sd"
  set amp 10
  foreach form INLIST formatList
    set testfile "test_waveform_^{wform}_^{form}"
    waveform out=testfile form=^form elem=nelems shape=^wform amp=amp
    ASSERT/TEXT="^reg.main.name: ^wform NELS" FILE(^testfile).getSize EQ nelems
    ! test case for Bug 1780 (max is now amp-1 and min is -amp)
    statistics testfile TABLE=stats
    ASSERT/TEXT="^reg.main.name: ^wform MAX" stats.max EQ amp-1
    ASSERT/TEXT="^reg.main.name: ^wform MIN" stats.min EQ -amp
  endfor

  fcalc test_waveform_^{wform}_diff test_waveform_^{wform}_sd test_waveform_^{wform}_sf -
  statistics test_waveform_^{wform}_diff TABLE=stats
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MIN ^stats.min"   stats.min  EQT 0.0
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MAX ^stats.max"   stats.max  EQT 0.0
  ASSERT/TEXT="^reg.main.name: ^wform SF/SD diff MEAN ^stats.mean" stats.mean EQT 0.0

  erase "test_waveform_^{wform}_sf"
  erase "test_waveform_^{wform}_sd"
  erase "test_waveform_^{wform}_diff"
return

!******************************************************************************!
procedure test_formats
!
! The purpose of this test is to make sure waveforms can be created with
! different formats but still have the same values
!
  set nels 100
  set formatList "SB,SI,SL,SF"

  ! Generate the master one in SD
  set masterFile "test_waveform_format_SD"
  waveform out=masterFile form=SD elem=nels amp=127
  foreach form INLIST formatList
    set testfile "test_waveform_format_^{form}"
    set noopFile "^{testFile}_noop"
    set fcalcFile "^{testFile}_fcalc"

    waveform out=testfile form=form elem=nels amp=127
    noop masterFile noopFile{format=^form}
    fcalc fcalcFile noopFile testFile -
    statistics fcalcFile TABLE=stats
    if form EQS "SF" then
!jph -- not sure why this does not work for SF ???
    else
      assert/text="^reg.main.name: FORMAT = ^form" stats.min  EQ 0
      assert/text="^reg.main.name: FORMAT = ^form" stats.max  EQ 0
      assert/text="^reg.main.name: FORMAT = ^form" stats.mean EQ 0
    endif
    erase fcalcFile noopFile testfile

  endfor

  erase masterfile
return
