!******************************************************************************!
! Test CONVERT Keyword conversions PLAT2BLUE and KWCONV
!
! Test added for Bug 2918 PLATINUM to BLUE keyword conversion
!
! Author:  Jeanette McCall
!******************************************************************************!
startmacro

  res expectedException ""

  ! Name of PLATINUM file in test area
  res  plat_file nxm.sys.test.testplat4plat2blue_cov.cdif
  ! Name of temporary BLUE file generated by PLAT2BLUE conversion
  res  blue_file ram:testbluefromplat_cov_^{env.pid}.tmp

  ! Convert PLATINUM to BLUE: convert keywords and do not keep original Platinum keywords
  convert ^plat_file PLAT2BLUE ^blue_file options={TOA_SIGMA={VALUE=0.0},FOA_SIGMA={VALUE=0.0}}

  !
  call checkOneToOneKeywordsNumericalValues
  call checkOneToOneKeywordsStringValues
  call checkOneToManyKeywords

  call checkWithAlternateKeywords
  
  call convPlat2blueWarnMissing

  erase/quiet ^blue_file
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
  else
    say "Unhandled message name: ^msg.name from fid: ^msg.fid data: ^msg.data"
  endif
return

!******************************************************************************!
! If an unexpected exception is caught, mark test as failed, unless it is expected
!******************************************************************************!
procedure processException m:emsg
res expectedException
res emsg.data.message
  if expectedException REXISTS then
    assert/text="^reg.main.name: Expected ERROR starts with: ^{expectedException}" expectedException EQSS emsg.data.message
    remove expectedException
  else
    assert/text="^reg.main.name: Caught unexpected exception ^{emsg.data}" "FALSE" isTrue
    if "Trace" SUBS ENV.DEBUG then invoke ,, emsg.data.printStackTrace()
  endif
return

!******************************************************************************!
! Check that Platinum keywords that have a 1-to-1 matching BLUE Keyword
! were successfully converted (Numeric Values)
!******************************************************************************!
procedure checkOneToOneKeywordsNumericalValues

  !Note: There would be some advantages to switching this to a foreach, but it
  ! would have to be blue_key="plat_key" format because dots are not allowed in
  ! key names. The advantage of keeping it this way it makes test development
  ! nice as only a range can be tested at a time.

  res one_to_one_eqt {PLAT1="TERMINAL.LAT",       BLUE1="ANT_LAT", &
                      PLAT2="TERMINAL.LON",       BLUE2="ANT_LON", &
                      PLAT3="TERMINAL.ALT",       BLUE3="ANT_ALT", &
                      PLAT4="AOI.LAT",            BLUE4="FEED_LAT", &
                      PLAT5="AOI.LON",            BLUE5="FEED_LON", &
                      PLAT6="AOI.ALT",            BLUE6="FEED_ALT", &
                      PLAT7="SAMPLE_RATE",        BLUE7="FS", &
                      PLAT8="COL_RF",             BLUE8="VRF", &
                      PLAT9="COL_IF_CENTER",      BLUE9="FNOM", &
                      PLAT10="ACQETF",            BLUE10="SBT" &
                      }

  ! Ten entries in table
  res num_one_to_one_eqt 10

  ! For each PLATINUM/BLUE key pair, check that their values match
  DO index 1 ^num_one_to_one_eqt 1

     ! Get Platinum key and value
     res platkey ^{one_to_one_eqt.PLAT^{index}}
     key ^plat_file GET ^platkey platvalue

     ! Get BLUE key and value
     res bluekey ^{one_to_one_eqt.BLUE^{index}}
     key ^blue_file GET ^bluekey bluevalue

     assert/text="^reg.main.name: Platinum ^platkey=^platvalue equals Blue ^{bluekey}=^{bluevalue}" platvalue EQT bluevalue

  ENDDO
  
return

!******************************************************************************!
! Check that Platinum keywords that have a 1-to-1 matching BLUE Keyword
! were successfully converted (String Values)
!******************************************************************************!
procedure checkOneToOneKeywordsStringValues

  !Note: There would be some advantages to switching this to a foreach, but it
  ! would have to be blue_key="plat_key" format because dots are not allowed in
  ! key names. The advantage of keeping it this way it makes test development
  ! nice as only a range can be tested at a time.


  res one_to_one_eqs {PLAT1="TPS_ANTENNA",         BLUE1="ANTENNA", &
                      PLAT2="TPS_ANTENNA_UPLINK",  BLUE2="UPLINK_ANT", &
                      PLAT3="MISSION",             BLUE3="MISSION", &
                      PLAT4="FEED",                BLUE4="FEED", &
                      PLAT5="RECEIVER",            BLUE5="RECEIVER", &
                      PLAT6="CLASSIFICATION",      BLUE6="CLASSIFICATION" &
                      }

  ! Six entries in table
  res num_one_to_one_eqs 6

  ! For each PLATINUM/BLUE key pair, check that their values match
  DO index 1 ^num_one_to_one_eqs 1

     ! Get Platinum key and value
     res platkey ^{one_to_one_eqs.PLAT^{index}}
     key ^plat_file GET ^platkey platvalue

     ! Get BLUE key and value
     res bluekey ^{one_to_one_eqs.BLUE^{index}}
     key ^blue_file GET ^bluekey bluevalue

     assert/text="^reg.main.name: Platinum ^platkey=^platvalue equals Blue ^{bluekey}=^{bluevalue}" platvalue EQS bluevalue

  ENDDO

return

!******************************************************************************!
! Check that Platinum keywords that have a vector to separate individual BLUE
! keywords were successfully converted
!******************************************************************************!
procedure checkOneToManyKeywords

  !Note: There would be some advantages to switching this to a foreach, but it
  ! would have to be blue_key="plat_key" format because dots are not allowed in
  ! key names. The advantage of keeping it this way it makes test development
  ! nice as only a range can be tested at a time.

  !********** State Vector Keywords *************************************
  res one_to_many_eph {PLAT1="EPH.TIME",        BLUE1="ETIM", &
                       PLAT2="EPH_POS.X",       BLUE2="POSX", &
                       PLAT3="EPH_POS.Y",       BLUE3="POSY", &
                       PLAT4="EPH_POS.Z",       BLUE4="POSZ", &
                       PLAT5="EPH_VEL.X",       BLUE5="VELX", &
                       PLAT6="EPH_VEL.Y",       BLUE6="VELY", &
                       PLAT7="EPH_VEL.Z",       BLUE7="VELZ", &
                       PLAT8="EPH_ACC.X",       BLUE8="ACCX", &
                       PLAT9="EPH_ACC.Y",       BLUE9="ACCY", &
                       PLAT10="EPH_ACC.Z",      BLUE10="ACCZ" &
                      }

  ! Number of entries in table
  res num_one_to_many_eph 10
  ! 6 values per platinum entry (index 0 through 5)
  res last_index 5

  ! Since ETIM values equal Platinum EPH.TIME * TIME_DELTA, get TIME_DELTA to check conversion
  key ^plat_file GET TIME_DELTA time_delta

  ! For each PLATINUM keyword
  DO index 1 ^num_one_to_many_eph 1

    res add_msg "" ! Used in assert: need extra message for TIME/ETIM

    ! For each value in Platinum vector
    DO plat_index 0 ^last_index 1

      ! Blue keyword names consist of root name plus numbers starting at 1
      calc L:blue_num plat_index 1 +

      ! Get Platinum keyword name from table
      res platkey ^{one_to_many_eph.PLAT^{index}}
      ! Get Platinum values (vector of values) from file
      key ^plat_file GET ^platkey plat_values
      ! Get the value for this index
      res platvalue ^{plat_values.^plat_index}

      ! Get the root BLUE keyword name
      res bluekey ^{one_to_many_eph.BLUE^{index}}
      ! Get the full name that matches the given platinum index
      invoke bluekey bluekey.concat(^blue_num)
      ! Get the value in the BLUE file
      key ^blue_file GET ^bluekey bluevalue

      ! ETIM is EPH.TIME * TIME_DELTA
      if ^platkey EQSS "EPH.TIME" then
        calc platvalue platvalue time_delta *
        res add_msg "* ^time_delta "
      endif

      assert/text="^reg.main.name: Platinum ^{platkey}.^{blue_num}=^platvalue ^{add_msg}equals Blue ^{bluekey}=^{bluevalue}" platvalue EQT bluevalue

    ENDDO
  ENDDO

  !********** Covariance Keywords *************************************
  res cov_blue_kwds {POS_COVAR_MTX11=0,  POS_COVAR_MTX12=1,  POS_COVAR_MTX13=2, &
                     POS_COVAR_MTX14=3,  POS_COVAR_MTX15=4,  POS_COVAR_MTX16=5, &
                                         POS_COVAR_MTX22=6,  POS_COVAR_MTX23=7, &
                     POS_COVAR_MTX24=8,  POS_COVAR_MTX25=9,  POS_COVAR_MTX26=10, &
                                                             POS_COVAR_MTX33=11, &
                     POS_COVAR_MTX34=12, POS_COVAR_MTX35=13, POS_COVAR_MTX36=14, &
                     VEL_COVAR_MTX11=15, VEL_COVAR_MTX12=16, VEL_COVAR_MTX13=17, &
                                         VEL_COVAR_MTX22=18, VEL_COVAR_MTX23=19,  &
                                                             VEL_COVAR_MTX33=20 &
                    }

  
  foreach bluekey INTABLE cov_blue_kwds

    ! Get vector of covariance values from Platinum file
    key ^plat_file GET "COV" plat_values
    ! Get index into vector from table (value of BLUE key in table)
    res plat_index ^{cov_blue_kwds.^bluekey}
    ! Get Platinum value using index
    res platvalue ^plat_values.^plat_index
    ! Get value from BLUE file
    key ^blue_file GET ^bluekey bluevalue

    assert/text="^reg.main.name: Platinum COV.^{plat_index}=^platvalue equals Blue ^{bluekey}=^{bluevalue}" platvalue EQT bluevalue

  endfor

return

!******************************************************************************!
! Check that Platinum keywords alternates for SBT, VRF, and FNOM were
! successfully converted
!
! 1st) SBT = ACQETF
! 2nd) SBT = COL_RF + Id * SBT_OFFSET                                (equation 4)
! 3rd) SBT = COL_LOCKED_LO + GND_LOCKED_LO + Id * OUTPUT_IF          (equation 3)
!
! 1st) VRF = COL_RF
! 2nd) VRF = COL_LOCKED_LO + GND_LOCKED_LO + Id * COL_IF_CENTER      (equation 3)
!
! 1st) FNOM = COL_IF_CENTER
! 2nd) FNOM = OUTPUT_IF - SBT_OFFSET                                 (equation 4)
! 3rd) FNOM = (ACQETF - (COL_LOCKED_LO + GND_LOCKED_LO)) * Id        (equation 3)
!
! Note: Equations are from the Platinum ICD Vol 2 Revision 4 Tuning Keywords section
! <..> Keywords are ones that do not need modification (either already exist or already are missing)
!         D:COL_RF           == 1252.5
!         D:COL_IF_CENTER    == 2.5
!         D:ACQETF           == 1251.2
!         L:DATA_INVERSION_FLAG == 1
!
! Note: test case matches the example in nxm.sys.docs.PlatinumTuningKeywordsToBlue
!******************************************************************************!
procedure checkWithAlternateKeywords

  res blue_copy_name "ram:blue_with_platinum_keywords^{env.pid}_"
  res converted_name "ram:converted_blue^{env.pid}_"
  file COPY/F ^plat_file ^{blue_copy_name}1.tmp
  file COPY/F ^plat_file ^{blue_copy_name}2.tmp
  file COPY/F ^plat_file ^{blue_copy_name}3.tmp

  ! Copy 1) missing ACQETF and COL_IF_CENTER but having <COL_RF>, OUTPUT_IF and SBT_OFFSET (2,1,2)
  KEY ^{blue_copy_name}1.tmp DEL NAME="ACQETF"
  KEY ^{blue_copy_name}1.tmp DEL NAME="COL_IF_CENTER"
  KEY ^{blue_copy_name}1.tmp PUT D:OUTPUT_IF          3.8  ! OUTPUT_IF- / FTIF-
  KEY ^{blue_copy_name}1.tmp PUT D:SBT_OFFSET         1.3  ! SBT_OFFSET-
  KEY ^{blue_copy_name}1.tmp PUT L:SBT_OFFSET_CORRECT 1
  info "6 Warnings below saying 'StateVector._toKeywords CURRENTTIME was not set...' are expected until NXM-3142 is addressed"
  convert ^{blue_copy_name}1.tmp PLAT2BLUE ^{converted_name}1.tmp options={TOA_SIGMA={VALUE=0.0},FOA_SIGMA={VALUE=0.0}}
  assert/text="^reg.main.name: Alternate Keywords for SBT, VRF, and FNOM set 1" ^{converted_name}1.tmp FEQ/K ^blue_file

  ! Copy 2) missing COL_RF and <OUTPUT_IF> but having <ACQETF>, <COL_IF_CENTER>, COL_LOCKED_LO, and GND_LOCKED_LO (1,2,3)
  KEY ^{blue_copy_name}2.tmp DEL NAME="COL_RF"
  KEY ^{blue_copy_name}2.tmp PUT D:COL_LOCKED_LO 1250.00  ! Lc + Lg total inverted value
  KEY ^{blue_copy_name}2.tmp PUT D:GND_LOCKED_LO 5.0      !
  info "6 Warnings below saying 'StateVector._toKeywords CURRENTTIME was not set...' are expected until NXM-3142 is addressed"
  convert ^{blue_copy_name}2.tmp PLAT2BLUE ^{converted_name}2.tmp options={TOA_SIGMA={VALUE=0.0},FOA_SIGMA={VALUE=0.0}}
  assert/text="^reg.main.name: Alternate Keywords for SBT, VRF, and FNOM set 2" ^{converted_name}2.tmp FEQ/K ^blue_file

   ! Copy 3) missing ACQETF and COL_RF but having OUTPUT_IF, <COL_IF_CENTER>, COL_LOCKED_LO, and GND_LOCKED_LO  (3,2,1)
   KEY ^{blue_copy_name}3.tmp DEL NAME="ACQETF"
   KEY ^{blue_copy_name}3.tmp DEL NAME="COL_RF"
   KEY ^{blue_copy_name}3.tmp PUT D:OUTPUT_IF     3.8
   KEY ^{blue_copy_name}3.tmp PUT D:COL_LOCKED_LO 1250.00
   KEY ^{blue_copy_name}3.tmp PUT D:GND_LOCKED_LO 5.0
   ! Use KWCONV instead of PLAT2BLUE
   table converttable LOAD kwconv_plat2blue.tbl
   res converttable ^{converttable}{TOA_SIGMA={VALUE=0.0},FOA_SIGMA={VALUE=0.0}}
   info "6 Warnings below saying 'StateVector._toKeywords CURRENTTIME was not set...' are expected until NXM-3142 is addressed"
   convert ^{blue_copy_name}3.tmp KWCONV ^{converted_name}3.tmp options=converttable
   ! This KWCONV equivalent to: convert ^{blue_copy_name}3.tmp  PLAT2BLUE ^{converted_name}3.tmp options={TOA_SIGMA={VALUE=0.0},FOA_SIGMA={VALUE=0.0}}
   assert/text="^reg.main.name: Alternate Keywords for SBT, VRF, and FNOM set 3" ^{converted_name}3.tmp FEQ/K ^blue_file

   erase/quiet ^{blue_copy_name}1.tmp
   erase/quiet ^{blue_copy_name}2.tmp
   erase/quiet ^{blue_copy_name}3.tmp
   erase/quiet ^{converted_name}1.tmp
   erase/quiet ^{converted_name}2.tmp
   erase/quiet ^{converted_name}3.tmp

return

!******************************************************************************!
! Convert Platinum file with missing Platinum keywords to Blue file
! with and without an ERROR message about missing Platinum keywords
!******************************************************************************!
procedure convPlat2blueWarnMissing

  res platConvInfo "You should see INFOs about PLATINUM 1) Does not have full support 2) auto-conversion."
  res platConvErrorInfo "You should see an INFO about PLATINUM not having full support and an EXPECTEDEXCEPTION"
  res platForceInfo "You should see 2 INFOs about unsupported BLUE version VER=2.0."
  res platUnsupportWarn "You should see 1 WARNing about unsupported BLUE version VER=2.0."
  res warnFixTC "Currently there is a WARNing about fixing BLUE TimeCode."
  res warnMissIntro "Expect WARNings about missing these source keys: "
  res warnMiss "^{warnMissIntro} AOI.LAT, AOI.LON, AOI.ALT, SITE_DELAY, COL_RFF, COL_IF_CENTER, ACQETF, MISSION , and StateVector data"

  ! PLAT2BLUE error for missing keywords
  say ""
  info "^{platConvErrorInfo} \n      ^{warnFixTC}      \n      ^{platUnsupportWarn}"
  set outMisskwdsException "ram:test_plat2blue_miss_kwds_exception"
  res expectedException "Could not open ^{outMisskwdsException}: DataFile: Can not set VER=2.0"
  CONVERT nxm.sys.test.testplat1001.cdif PLAT2BLUE outMisskwdsException
  say ""

  ! PLAT2BLUE warnings only
  info "^{platConvInfo} \n      ^{warnFixTC}      \n      ^{warnMiss}"
  set outMisskwdsWarnOnly "ram:test_plat2blue_miss_kwds_warn"
  CONVERT nxm.sys.test.testplat1001.cdif PLAT2BLUE outMisskwdsWarnOnly options={_WARN_MISSING_=true}
  keyword outMisskwdsWarnOnly GET PLAT2BLUE_COMMENT convcomment
  assert/text="^reg.main.name: PLAT2BLUE conversion of file missing keys only gives warnings" convcomment EQS "INFO: Conversion Successful"
  say ""

return
