startmacro
!
! Author : Jay Hallam
!
! DEPENDENCIES: WAVEFORM
!
switch INTERACTIVE interAct GET DEF=FALSE  SDEF=TRUE
  result macroName "test_statistics"


  call setDatDir

  call test_1000
  call test_2000
  call test_negative_numbers
  call test_table
  call test_one_based
  call test_xm_keys
  call test_realminmax_imagminmax ! NXM-4056

  invoke newVer nxm.sys.lib.StringUtil.compareVersions("^env.nmversion","2.3.0")
  if newver GE 0 then
    call test_sum
  endif

  if interAct then
    %test_statistics_pipe
  endif
endmacro

!******************************************************************************!
! Set the dat directory
!******************************************************************************!
procedure setDatDir
  invoke nxmMajor env.nmversion.subString(0,1)
  invoke major java.lang.Integer.valueOf(nxmMajor)
  if major GE 4 then
    invoke s:datDir           nxm.sys.test.DatLocator.getDatDirLocation()
    invoke s:datDirSlash      nxm.sys.test.DatLocator.getDatDirSlashLocation()
    invoke z:sysDatFull       nxm.sys.test.DatLocator.sysDatFull()
    invoke z:sysTestDatExists nxm.sys.test.DatLocator.sysTestDatExists()
  else
    set s:datDir           "nxm.sys.dat"
    set s:datDirSlash      "nxm/sys/dat"
    set z:sysDatFull       true
    set z:sysTestDatExists false
  endif
return

!******************************************************************************!
procedure test_1000

result s:testfile "temp_statistics"
result numElements 10000
waveform "^testfile" FORM=SD SHAPE=SIN ELEM=numElements
statistics ^testfile MEAN=mean,SDEV=sdev,ELEM=elem,MAX=max,&
                     MIN=min,AMIN=amin,AMAX=amax,OMIN=omin,OMAX=omax
calc absmean mean ABS
assert/text="^macroName: SIN stats, MEAN = ^mean" absmean LE 1e-6
!! Before version 2.1, WAVEFORM generated waveforms with SF precision 
!! even if SD was requested
!!assert/text="^macroName: SIN stats, SDEV = ^sdev" sdev EQT 0.70710446
assert/text="^macroName: SIN stats, SDEV = ^sdev" sdev EQT 0.7071067
                                                           
assert/text="^macroName: SIN stats, ELEM = ^elem" elem EQT numElements
assert/text="^macroName: SIN stats, MAX = ^max" max EQT 1.0
assert/text="^macroName: SIN stats, MIN = ^min" min EQT -1.0
!! Before version 2.1, WAVEFORM generated waveforms with SF precision 
!! even if SD was requested
!! The indexing/abscissas for MIN/MAX changed, but this is not really
!! a good or necessary test anyway.
!!assert/text="^macroName: SIN stats, Absc MAX = ^amax" amax EQT 0.0
!!assert/text="^macroName: SIN stats, Absc MIN = ^amin" amin EQT 50.0
!!assert/text="^macroName: SIN stats, Offset of MAX = ^omax" omax EQT 0.0
!!assert/text="^macroName: SIN stats, Offset of MIN = ^omin" omin EQT 50.0

waveform "^testfile" FORM=CD SHAPE=SIN ELEM=numElements
statistics ^testfile MEAN=mean
calc absImean mean.i ABS
assert/text="^macroName: SIN stats, IMEAN = ^absImean" absImean LT 1e-6

statistics ^{datDir}.fftdemo.prm MEAN=mean
calc diff mean.r 0.865967 -
assert/text="^macroName: FFTDEMO stats, MEAN" diff LT 1e-6
calc diff mean.i 0.499770 -
assert/text="^macroName: FFTDEMO stats, MEAN" diff LT 1e-6

erase testfile

return
!******************************************************************************!
procedure test_2000

status "^{datDir}.apenny.prm" fs=frameSize size=size
calc L:numElements size frameSize *
statistics "^{datDir}.apenny.prm" MEAN=mean,SDEV=sdev,ELEM=elem,MAX=max,&
                                  MIN=min,AMIN=amin,AMAX=amax,OMIN=omin,OMAX=omax
assert/text="^macroName: Type2000 stats, MEAN = ^mean" mean EQT -26.1732177734
assert/text="^macroName: Type2000 stats, SDEV = ^sdev" sdev EQT 67.8482743374
assert/text="^macroName: Type2000 stats, ELEM = ^elem" elem EQT numElements
assert/text="^macroName: Type2000 stats, MAX = ^max" max EQT 127.0
assert/text="^macroName: Type2000 stats, MIN = ^min" min EQT -127.0
assert/text="^macroName: Type2000 stats, Absc MAX = ^amax" amax EQT 0.0
assert/text="^macroName: Type2000 stats, Absc MIN = ^amin" amin EQT 0.0
assert/text="^macroName: Type2000 stats, Offset of MAX = ^omax" omax EQT 10880
assert/text="^macroName: Type2000 stats, Offset of MIN = ^omin" omin EQT 0

return
!******************************************************************************!
procedure test_xm_keys
  debug/save=saveDebug
  debug off deprecate

  status "^{datDir}.apenny.prm" fs=frameSize size=size
  calc L:numElements size frameSize *
  statistics "^{datDir}.apenny.prm" MEAN=mean,SDEV=sdev,ELEM=elem,MAX=max,&
                                    MIN=min,AMIN=amin,AMAX=amax,OMIN=omin,OMAX=omax
  info "Expecting warnings about MAXI= and MINI= being zero-based"
  statistics "^{datDir}.apenny.prm" STDV=stdv MAXV=maxv MINV=minv MAXA=maxa MINA=mina MAXI=maxi MINI=mini

  assert/text="^macroName: X-Midas STDV= matches NeXtMidas SDEV=" stdv EQ sdev
  assert/text="^macroName: X-Midas MAXV= matches NeXtMidas MAX="  maxv EQ max
  assert/text="^macroName: X-Midas MINV= matches NeXtMidas MIN="  minv EQ min
  assert/text="^macroName: X-Midas MAXI= matches NeXtMidas OMAX=" maxi EQ omax
  assert/text="^macroName: X-Midas MINI= matches NeXtMidas OMIN=" mini EQ omin
  assert/text="^macroName: X-Midas MAXA= matches NeXtMidas AMAX=" maxa EQ amax
  assert/text="^macroName: X-Midas MINA= matches NeXtMidas AMIN=" mina EQ amin

  debug/load=saveDebug
return

!******************************************************************************!
! Bug 159: STATISTICS computes wrong results when all values in the file are
!          negative.
procedure test_negative_numbers
  res tempFileName "temp_test_statistics"

  waveform ^tempFileName SD 121 CONST -73.0

  statistics ^tempFileName MEAN=mean,SDEV=sdev,ELEM=elem,MAX=max,&
                           MIN=min,AMIN=amin,AMAX=amax,OMIN=omin,OMAX=omax
  assert/text="^macroName: negative value stats, MEAN = ^mean" mean EQT -73.0
  assert/text="^macroName: negative value stats, SDEV = ^sdev" sdev EQT 0.0
  assert/text="^macroName: negative value stats, ELEM = ^elem" elem EQT 121
  assert/text="^macroName: negative value stats, MAX = ^max" max EQT -73.0
  assert/text="^macroName: negative value stats, MIN = ^min" min EQT -73.0
  assert/text="^macroName: negative value stats, Absc MAX = ^amax" amax EQT 0
  assert/text="^macroName: negative value stats, Absc MIN = ^amin" amin EQT 0
  assert/text="^macroName: negative value stats, Offset of MAX = ^omax" omax EQT 0
  assert/text="^macroName: negative value stats, Offset of MIN = ^omin" omin EQT 0

  
  ! Also test 0.0 values
  waveform ^tempFileName SD 121 CONST 0.0

  statistics ^tempFileName MEAN=mean,SDEV=sdev,ELEM=elem,MAX=max,&
                           MIN=min,AMIN=amin,AMAX=amax,OMIN=omin,OMAX=omax
  assert/text="^macroName: zero value stats, MEAN = ^mean" mean EQT 0.0
  assert/text="^macroName: zero value stats, SDEV = ^sdev" sdev EQT 0.0
  assert/text="^macroName: zero value stats, ELEM = ^elem" elem EQT 121
  assert/text="^macroName: zero value stats, MAX = ^max" max EQT 0.0
  assert/text="^macroName: zero value stats, MIN = ^min" min EQT 0.0
  assert/text="^macroName: zero value stats, Absc MAX = ^amax" amax EQT 0
  assert/text="^macroName: zero value stats, Absc MIN = ^amin" amin EQT 0
  assert/text="^macroName: zero value stats, Offset of MAX = ^omax" omax EQT 0
  assert/text="^macroName: zero value stats, Offset of MIN = ^omin" omin EQT 0

  erase tempFileName
return

!******************************************************************************!
! Bug 161 Added ability to output a TABLE
procedure test_table
  statistics "^{datDir}.apenny.prm" MEAN=mean,SDEV=sdev,ELEM=elem,MAX=max,&
                                    MIN=min,AMIN=amin,AMAX=amax,OMIN=omin,OMAX=omax,&
                                    TABLE=MYTABLE

  assert/text="^macroName: TABLE= stats, MEAN = ^MYTABLE.mean"          MYTABLE.mean EQT mean
  assert/text="^macroName: TABLE= stats, SDEV = ^MYTABLE.sdev"          MYTABLE.sdev EQT sdev
  assert/text="^macroName: TABLE= stats, ELEM = ^MYTABLE.elem"          MYTABLE.elem EQT elem
  assert/text="^macroName: TABLE= stats, MAX  = ^MYTABLE.max"           MYTABLE.max  EQT max
  assert/text="^macroName: TABLE= stats, MIN  = ^MYTABLE.min"           MYTABLE.min  EQT min
  assert/text="^macroName: TABLE= stats, Absc MAX = ^MYTABLE.amax"      MYTABLE.amax EQT amax
  assert/text="^macroName: TABLE= stats, Absc MIN = ^MYTABLE.amin"      MYTABLE.amin EQT amin
  assert/text="^macroName: TABLE= stats, Offset of MAX = ^MYTABLE.omax" MYTABLE.omax EQT omax
  assert/text="^macroName: TABLE= stats, Offset of MIN = ^MYTABLE.omin" MYTABLE.omin EQT omin
return

!******************************************************************************!
! Bug 161 Added ability to comput offsets one-based
procedure test_one_based
  statistics/ONEBASE "^{datDir}.apenny.prm" TABLE=MYTABLE
  statistics         "^{datDir}.apenny.prm" TABLE=ZEROBASED
  
  assert/text="^macroName: /ONEBASE stats, MEAN = ^MYTABLE.mean"          MYTABLE.mean EQT ZEROBASED.mean
  assert/text="^macroName: /ONEBASE stats, SDEV = ^MYTABLE.sdev"          MYTABLE.sdev EQT ZEROBASED.sdev
  assert/text="^macroName: /ONEBASE stats, ELEM = ^MYTABLE.elem"          MYTABLE.elem EQT ZEROBASED.elem
  assert/text="^macroName: /ONEBASE stats, MAX  = ^MYTABLE.max"           MYTABLE.max  EQT ZEROBASED.max
  assert/text="^macroName: /ONEBASE stats, MIN  = ^MYTABLE.min"           MYTABLE.min  EQT ZEROBASED.min
  assert/text="^macroName: /ONEBASE stats, Absc MAX = ^MYTABLE.amax"      MYTABLE.amax EQT ZEROBASED.amax
  assert/text="^macroName: /ONEBASE stats, Absc MIN = ^MYTABLE.amin"      MYTABLE.amin EQT ZEROBASED.amin
  assert/text="^macroName: /ONEBASE stats, Offset of MAX = ^MYTABLE.omax" MYTABLE.omax EQT ZEROBASED.omax+1
  assert/text="^macroName: /ONEBASE stats, Offset of MIN = ^MYTABLE.omin" MYTABLE.omin EQT ZEROBASED.omin+1
return

!******************************************************************************!
procedure test_sum
  statistics ^{datDir}.fftdemo.prm MEAN=mean SUM=sumC
  file open tag ^{datDir}.fftdemo.prm
  set sumReal 0.0
  set sumIMAG 0.0
  set L:offset 0
  foreach elem INFILE ^{datDir}.fftdemo.prm
    res cmplx tag.data(offset)
    calc sumReal sumReal cmplx.r +
    calc sumIMAG sumIMAG cmplx.i +
    calc offset offset+1
  endfor
  file close tag
  assert/text="^macroName: FFTDEMO file, complex SUM" sumReal EQT sumC.r AND &
                                                      sumIMAG EQT sumC.i
return

!******************************************************************************!
procedure test_realminmax_imagminmax

  res s:testfile "temp_statistics_realminmax_imagminmax"
  res numElements 100
  res minReal  2
  res minImag  4
  res modval      10
  calc highExtra 10 1 -
  calc averExtra highExtra 2 /
  calc expRealMean minReal averExtra +
  calc expImagMean minImag averExtra +
  res  eMean (^expRealMean,^expImagMean)
  calc maxReal minReal highExtra +
  calc maxImag minImag highExtra +
  calc maxRealSq maxReal 2 **
  calc maxImagSq maxImag 2 **
  calc emax maxRealSq maxImagSq + SQRT
  calc minRealSq minReal 2 **
  calc minImagSq minImag 2 **
  calc emin minRealSq minImagSq + SQRT


  HEADERMOD/CREATE testfile type=1000 FORM=CD
  file open/d/w tag testfile
  LOOP numElements i
    calc offset i 1 -
    calc extra offset modval MOD
    calc real minReal extra +
    calc imag minImag extra +
    res tag.setdata(offset) (^real,^imag)
  ENDLOOP
  file close tag

  statistics ^testfile MEAN=mean,MAX=max,MIN=min,&
                     REALMIN=rmin,REALMAX=rmax,IMAGMIN=imin,IMAGMAX=imax

  assert/text="^reg.main.name: CD 1000 mean" mean EQ emean
  assert/text="^reg.main.name: CD 1000 max"  max  EQ emax
  assert/text="^reg.main.name: CD 1000 min"  min  EQ emin
  assert/text="^reg.main.name: CD 1000 realmax"  rmax  EQ maxReal
  assert/text="^reg.main.name: CD 1000 realmin"  rmin  EQ minReal
  assert/text="^reg.main.name: CD 1000 imagmax"  imax  EQ maxImag
  assert/text="^reg.main.name: CD 1000 imagmin"  imin  EQ minImag

  erase testfile

return
