' ----------------------------------------------------------------------
' DiskFile   : accuracy.ave | Assess Accuracy
' Programmer : Brian Biggs
' Created    : 06-Feb-96
' Revisions  : 
'
' Function   : Calculates the accuracy of a coverage based on ground data.
'            : Requests a theme and field to accuracy assess and a theme 
'            : and field to ground truth with. Both fields must have the
'            : same classification labeling to work properly.  View must 
'            : be active to run.
' Called By  : Project GUI - Menu
' ----------------------------------------------------------------------

'get themes to select
theVw = av.GetActiveDoc 
If (theVw.Is(View)) then
  theThms = theVw.GetThemes
Else
  MsgBox.Error("The View needs to be the active document","Error")
  Exit
End

'select assessment layer and item
theAss = MsgBox.ListAsString(theThms,"Please select the coverage to assess:","Cover Layer")
If (theAss = NIL) then
  Exit
End
theAFtab = theAss.GetFtab
theItems = theAFtab.GetFields
theAssFld = MsgBox.ListAsString(theItems,"Please select the item to compare with:","Item Name")
If (theAssFld = NIL) then
  Exit
End

'select ground truthing layer and item
theTrth = MsgBox.ListAsString(theThms,"Please select the ground truth coverage:","Cover Layer")
If (theTrth = NIL) then
  Exit
End
theTFtab = theTrth.GetFtab
theItems = theTFtab.GetFields
theTrthFld = MsgBox.ListAsString(theItems,"Please select the item to compare with:","Item Name")
If (theTrthFld = NIL) then
  Exit
End
shpFld = theTFtab.FindField("Shape")

'create accuracy table
flName = FileDialog.Put("$ROBWORK/AccTab.dbf".AsFileName,"*.dbf","Filename")
If (flName = NIL) then
  Exit
End
AccVTab = VTab.MakeNew(flName,dBASE)

'get unique item entries for comparison
FldList = {}

'get unique item entries from assess coverage
For Each rec in theAFtab
  theRec = theAFtab.ReturnValueString(theAssFld,rec)
  FldList.Add(theRec)
  FldList.RemoveDuplicates
End

'clone assessment fields for future use
AssList = FldList.Clone
AssList.Sort(TRUE)

'get unique item entries from ground truth table
For Each rec in theTFtab
  theRec = theTFtab.ReturnValueString(theTrthFld,rec)
  FldList.Add(theRec)
  FldList.RemoveDuplicates
End

'clone all fields for future use
FldList.Sort(TRUE)
sumList = FldList.Clone

' - Populate table with fields and records of cover names - 
'add table fields cover_type and items to final field list
FrstFld = Field.Make("Cover_Type",#FIELD_CHAR,16,0)
FnlList = {FrstFld}
For Each li in FldList
  aFld = Field.Make(li,#FIELD_DECIMAL,16,2)
  FnlList.Add(aFld)
End
'add total_commission field
totCFld = Field.Make("Total_Com",#FIELD_DECIMAL,16,2)
FnlList.Add(totCFld)
'add commission accuracy field
cAccFld = Field.Make("Com_Acc",#FIELD_DECIMAL,16,2)
FnlList.Add(cAccFld)
'add total accuracy field
tAccFld = Field.Make("Total_Acc",#FIELD_DECIMAL,16,2)
FnlList.Add(tAccFld)
'add kappa accuracy field
kappaFld = Field.Make("Kappa_Acc",#FIELD_DECIMAL,16,2)
FnlList.Add(kappaFld)

'add all fields to table
AccVTab.AddFields(FnlList)

'add table records - cover types
totOFld = Field.Make("Total_Om",#FIELD_DECIMAL,16,2)
FldList.Add(totOFld.AsString)
oAccFld = Field.Make("Om_Acc",#FIELD_DECIMAL,16,2)
FldList.Add(oAccFld.AsString)
recNum = 0
For Each li in FldList
  AccVtab.AddRecord
  AccVtab.SetValueString(FrstFld,recNum,li)
  recNum = recNum + 1
End

'total all correct and error polygons per class add cell entries to table
For Each fld in AssList
  'select by theme ground truth polygons with center in selected cover type
  'select cover type in assessment theme
  theAFTab.GetSelection.ClearAll
  theAFTab.UpdateSelection
  theBitMap = theAFtab.GetSelection
  theQuery = "(["+theAssFld.AsString+"] = "+fld.AsString.Quote+")"
  theAFtab.Query(theQuery,theBitMap,#VTAB_SELTYPE_NEW)
  theAFtab.SetSelection(theBitMap)
  theAFtab.UpdateSelection
  'select ground truth polygons that fall within cover type
  theTFtab.GetSelection.ClearAll
  theTFtab.UpdateSelection
  theTrth.SelectByTheme(theAss,#FTAB_RELTYPE_HASCENTERWITHIN,0,#VTAB_SELTYPE_NEW)
  'theCheck fixes a bug in the summarize routine where if no polygons
  '  fall within a cover type, summarize says all of the polygons fall into it
  theCheck = theTFtab.GetSelection.Count
  If ((theCheck = 0).Not) then
    'summarize ground truth polygons
    sumFtab = theTFtab.Summarize(FileName.Make("$ROBWORK/zz"+fld.AsString+".dbf"),dBASE,theTrthFld,{shpFld},{#VTAB_SUMMARY_AVG})
    'set summary fields to grab cell values
    covFld = sumFtab.FindField(theTrthFld.AsString)
    cntFld = sumFtab.FindField("Count")
    'get row number of cover type in AccTab.dbf
    row = av.Run("GetRowNumber",{AccVtab,FrstFld,fld})
    'enter cell values into AccTab.dbf
    For Each r in sumFtab
      theCov = sumFtab.ReturnValueString(covFld,r)
      theCnt = sumFtab.ReturnValueNumber(cntFld,r)
      theCovFld = AccVtab.FindField(theCov)
      AccVtab.SetValueNumber(theCovFld,row,theCnt)
    End
  End
End

'calculate ommission totals
rowCnt = sumList.Count
For Each f in sumList
  theFld = AccVtab.FindField(f.asString)
  sum = 0
  For Each r in (0..(rowCnt -1))
    sum = sum + AccVtab.ReturnValueNumber(theFld,r)
  End
  AccVtab.SetValueNumber(theFld,rowCnt,sum)
  'calculate omission percent
  row = av.Run("GetRowNumber",{AccVtab,FrstFld,theFld})
  tCorrect = AccVtab.ReturnValueNumber(theFld,row)
  percent = (tCorrect / sum)
  If (percent.IsNull) then
    percent = 0
  End
  AccVtab.SetValueNumber(theFld,(rowCnt + 1),percent)
End

'calculate commission totals and gather total and kappa accuracy info
totCom = AccVtab.FindField("Total_Com")
accCom = AccVtab.FindField("Com_Acc")
allCorrect = 0
tSamps = 0
kSideTot = 0
For Each r in (0..(rowCnt -1))
  sum = 0
  For Each f in sumList 
    theFld = AccVtab.FindField(f.asString) 
    sum = sum + AccVtab.ReturnValueNumber(theFld,r)
  End
  AccVtab.SetValueNumber(totCom,r,sum)
  'calculate omission percent
  corFld = AccVtab.GetFields.Get((r+1))
  tCorrect = AccVtab.ReturnValueNumber(corFld,r)
  percent = (tCorrect / sum)
  If (percent.IsNull) then
    percent = 0
  End
  AccVtab.SetValueNumber(accCom,r,percent)
  'get total info
  allCorrect = allCorrect + tCorrect
  tSamps = tSamps + sum
  'get kappa info
  kSideNum = AccVtab.ReturnValueNumber(corFld,rowCnt)
  kSideTot = kSideTot + (kSideNum * sum)
End

'calculate total accuracy
tAcc = AccVtab.FindField("Total_Acc")
totAcc = (allCorrect / tSamps)
For Each r in AccVtab
  If (r = 0) then
    AccVtab.SetValueNumber(tAcc,r,totAcc)
  Else
    AccVtab.SetValueNumber(tAcc,r,Number.MakeNull)
  End
End

'calculate kappa accuracy
kAcc = AccVtab.FindField("Kappa_Acc")
lEq = (allCorrect * tSamps) - kSideTot
rEq = (tSamps * tSamps) - kSideTot
kappa = lEq / rEq
For Each r in AccVtab
  If (r = 0) then
    AccVtab.SetValueNumber(kAcc,r,kappa)
  Else
    AccVtab.SetValueNumber(kAcc,r,Number.MakeNull)
  End
End


'delete temp files
delList = "$ROBWORK".AsFileName.Read("zz*")
For Each f in delList
  If (f.IsFile) then
    File.Delete(f)
  End
End

'reset themes to nothing selected
theAFTab.GetSelection.ClearAll
theAFTab.UpdateSelection
theTFtab.GetSelection.ClearAll
theTFtab.UpdateSelection

'open accuracy table
AccTab = Table.Make(AccVTab)
AccTab.GetWin.Open
AccTab.SetName(theAss.GetName++"Accuracy Table")

' ----------------------------------------------------------------------
' End of file