! program written by Tim Mitchell on 21.8.00 ! last modified on 4.9.00 ! compares various region sets in .glo form ! f90 -o comparereg initialmod.f90 loadmod.f90 savemod.f90 comparereg.f90 program CompareReg use InitialMod use LoadMod use SaveMod implicit none real, pointer, dimension (:,:,:) :: GloData real, pointer, dimension (:) :: ThisGlo, BoxValid, BoxMiss integer, pointer, dimension (:,:,:) :: GloMap integer, pointer, dimension (:,:) :: MapIDLRaw, MapIDLReg, ThisMap integer, pointer, dimension (:) :: MapRawReg, RegSizes, ADYear character (len=20), dimension (:), pointer :: RegNames,LineNames real, allocatable, dimension (:) :: ScoreExp, ScoreAct, RegTot, RegSqTot integer, allocatable, dimension (:,:,:,:) :: Ring integer, allocatable, dimension (:) :: GloRegN real, parameter :: MissVal = -999.0 real :: MissAccept real :: RegThresh real :: OpTot, OpMiss, OpEn, OpSqTot, OpMagTot, OpMean, OpStDev, OpMagAv, OpMin, OpDiff, OpAdjMin integer :: LatN, LongN, GridChosen, GridDataN, RegN integer :: Month0, Month1, MonthN, YearN, DecN integer :: AllocStat, ReadStatus, MenuChoice integer :: XReg, XYear, XGlo, XLat, XLong, XAdjacent integer :: YLat, YLong integer :: FirstFree, SelectA, SelectB, GotThisReg integer :: AllGloN, LoadGloN, ThisRegN integer :: NearLong, NearLat character (len=80) :: GridFilePath, RegTitle, Blank character (len=10) :: GridTitle ! ****************************************************************************** open (99,file="/cru/u2/f709762/data/scratch/log-compreg.dat",status="replace",action="write") print* print*, " > ***** CompareReg: compares various region sets in .glo form *****" print* call Initialise call MainMenu call Finalise close (99) contains ! ****************************************************************************** subroutine MainMenu MenuChoice = -1 do if (MenuChoice.EQ.0) then call SetMissAccept (MissAccept) else if (MenuChoice.EQ.1) then call IdentifyTwo call CalcRMSE else if (MenuChoice.EQ.2) then call IdentifyTwo call CompareAB else if (MenuChoice.EQ.3) then call IdentifyTwo call ClosestNeighbour else if (MenuChoice.EQ.4) then call IdentifyTwo call HypABEqual else if (MenuChoice.EQ.5) then call IdentifyTwo call CalcCoeffVar else if (MenuChoice.EQ.6) then call IdentifyOne else if (MenuChoice.EQ.30) then call PrintBoxStats else if (MenuChoice.EQ.31) then call PrintRegStats else print* print*, " > 0. Change MissAccept, currently: ", MissAccept print*, " > 1. RMSE in estimate of A boxes from B, saving using A regions" print*, " > 2. A-B, box by box, printing stats" print*, " > 3. Closest neighbour analysis: boxes=A, regions=B" print*, " > 4. Examine A=B hypothesis by box" print*, " > 5. Coeff of var in est of A boxes from B, saving with A reg" print*, " > 30. Print box stats" print*, " > 31. Print reg stats" print*, " > 99. Exit" end if print* print*, " > Main menu. Select your choice." do read (*,*,iostat=ReadStatus), MenuChoice if (ReadStatus.LE.0.AND.MenuChoice.GE.1.AND.MenuChoice.LE.99) exit end do if (MenuChoice.EQ.99) exit end do end subroutine MainMenu ! ****************************************************************************** subroutine Initialise call GridSelect (GridChosen,GridTitle,LongN,LatN,GridDataN,GridFilePath) print*, " > Select the number of .glo to load." do read (*,*,iostat=ReadStatus), LoadGloN if (ReadStatus.LE.0.AND.LoadGloN.GE.1) exit end do MissAccept = 10.0 Blank = "" FirstFree = 1 AllGloN = LoadGloN + 30 allocate (GloData (AllGloN,LongN,LatN), & GloMap (AllGloN,LongN,LatN), & GloRegN (AllGloN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Initialise: Allocation failure #####" GloData = MissVal GloMap = MissVal GloRegN = MissVal do XGlo = 1, LoadGloN call GrabGlo end do end subroutine Initialise ! ****************************************************************************** subroutine Finalise deallocate (GloData,GloMap,GloRegN,MapIDLRaw,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Finalise: Deallocation failure #####" print* end subroutine Finalise ! ****************************************************************************** subroutine GrabGlo print*, " > Load .glo file into column: ", FirstFree call RegSelect (GridChosen, LongN, LatN, GridDataN, MapIDLReg, RegSizes, RegNames, RegTitle, RegN) call LoadGlo (LongN, LatN, RegN, MapIDLReg, ThisGlo) GloRegN (FirstFree) = RegN do XLong = 1, LongN do XLat = 1, LatN GloMap (FirstFree,XLong,XLat) = MapIDLReg (XLong,XLat) if (MapIDLReg (XLong,XLat).NE.MissVal) & GloData (FirstFree,XLong,XLat) = ThisGlo (MapIDLReg (XLong,XLat)) end do end do FirstFree = FirstFree + 1 deallocate (MapRawReg,MapIDLReg,RegSizes,RegNames,ThisGlo, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GrabGlo: Deallocation failure #####" end subroutine GrabGlo ! ****************************************************************************** subroutine IdentifyOne print*, " > Select a column:" do read (*,*,iostat=ReadStatus), SelectA if (ReadStatus.LE.0.AND.SelectA.GE.1.AND.SelectA.LT.FirstFree) exit end do end subroutine IdentifyOne ! ****************************************************************************** subroutine IdentifyTwo print*, " > Select column A:" do read (*,*,iostat=ReadStatus), SelectA if (ReadStatus.LE.0.AND.SelectA.GE.1.AND.SelectA.LT.FirstFree) exit end do print*, " > Select column B:" do read (*,*,iostat=ReadStatus), SelectB if (ReadStatus.LE.0.AND.SelectB.GE.1.AND.SelectB.LT.FirstFree) exit end do end subroutine IdentifyTwo ! ****************************************************************************** subroutine CalcRMSE allocate (ThisMap (LongN,LatN), & ThisGlo (GloRegN(SelectA)), & BoxValid (GloRegN(SelectA)), & BoxMiss (GloRegN(SelectA)), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CalcRMSE: Allocation failure #####" ThisGlo = 0.0 BoxValid = 0.0 BoxMiss = 0.0 do XLong = 1, LongN do XLat = 1, LatN ThisMap (XLong,XLat) = GloMap (SelectA,XLong,XLat) if (GloMap(SelectA,XLong,XLat).NE.MissVal) then if (GloData(SelectA,XLong,XLat).NE.MissVal.AND.GloData(SelectB,XLong,XLat).NE.MissVal) then ThisGlo (GloMap(SelectA,XLong,XLat)) = ThisGlo (GloMap(SelectA,XLong,XLat)) + & ((GloData(SelectB,XLong,XLat)-GloData(SelectA,XLong,XLat))**2) BoxValid (GloMap(SelectA,XLong,XLat)) = BoxValid (GloMap(SelectA,XLong,XLat)) + 1.0 else BoxMiss (GloMap(SelectA,XLong,XLat)) = BoxMiss (GloMap(SelectA,XLong,XLat)) + 1.0 end if end if end do end do do XReg = 1, GloRegN(SelectA) RegThresh = (100.0 - MissAccept) * (BoxValid(XReg) + BoxMiss(XReg)) / 100.0 if (BoxValid(XReg).GE.RegThresh) then ThisGlo (XReg) = ThisGlo (XReg) / BoxValid(XReg) ThisGlo (XReg) = sqrt (ThisGlo (XReg)) else ThisGlo (XReg) = MissVal end if end do call SaveGlo (LongN,LatN,GloRegN(SelectA),GridFilePath,Blank,Blank,ThisGlo,ThisMap) deallocate (ThisGlo,ThisMap,BoxValid,BoxMiss, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CalcRMSE: Deallocation failure #####" end subroutine CalcRMSE ! ****************************************************************************** subroutine CalcCoeffVar allocate (ThisMap (LongN,LatN), & ThisGlo (GloRegN(SelectA)), & BoxValid (GloRegN(SelectA)), & BoxMiss (GloRegN(SelectA)), & RegTot (GloRegN(SelectA)), & RegSqTot (GloRegN(SelectA)), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CalcCoeffVar: Allocation failure #####" ThisGlo = 0.0 BoxValid = 0.0 BoxMiss = 0.0 RegTot = 0.0 RegSqTot = 0.0 do XLong = 1, LongN do XLat = 1, LatN ThisMap (XLong,XLat) = GloMap (SelectA,XLong,XLat) if (GloMap(SelectA,XLong,XLat).NE.MissVal) then if (GloData(SelectB,XLong,XLat).NE.MissVal) then RegSqTot (GloMap(SelectA,XLong,XLat)) = RegSqTot (GloMap(SelectA,XLong,XLat)) + & (GloData(SelectB,XLong,XLat)**2) RegTot (GloMap(SelectA,XLong,XLat)) = RegTot (GloMap(SelectA,XLong,XLat)) + & GloData(SelectB,XLong,XLat) BoxValid (GloMap(SelectA,XLong,XLat)) = BoxValid (GloMap(SelectA,XLong,XLat)) + 1.0 else BoxMiss (GloMap(SelectA,XLong,XLat)) = BoxMiss (GloMap(SelectA,XLong,XLat)) + 1.0 end if end if end do end do do XReg = 1, GloRegN(SelectA) RegThresh = (100.0 - MissAccept) * (BoxValid(XReg) + BoxMiss(XReg)) / 100.0 if (BoxValid(XReg).GE.RegThresh.AND.BoxValid(XReg).GT.0) then OpMean = RegTot(XReg)/BoxValid(XReg) ThisGlo (XReg) = (RegSqTot(XReg)/BoxValid(XReg)) - (OpMean*OpMean) ThisGlo (XReg) = sqrt (ThisGlo (XReg)) if (OpMean.GT.0) then ThisGlo (XReg) = ThisGlo (XReg) / OpMean else ThisGlo (XReg) = MissVal end if else ThisGlo (XReg) = MissVal end if write (99,"(i4,f12.4)"), XReg, ThisGlo (XReg) ! ######################### end do call SaveGlo (LongN,LatN,GloRegN(SelectA),GridFilePath,Blank,Blank,ThisGlo,ThisMap) deallocate (ThisGlo,ThisMap,BoxValid,BoxMiss,RegTot,RegSqTot, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CalcCoeffVar: Deallocation failure #####" end subroutine CalcCoeffVar ! ****************************************************************************** subroutine CompareAB OpMiss = 0.0 OpTot = 0.0 OpEn = 0.0 OpSqTot = 0.0 do XLong = 1, LongN do XLat = 1, LatN if (GloData(SelectA,XLong,XLat).NE.MissVal.AND.GloData(SelectB,XLong,XLat).NE.MissVal) then OpTot = OpTot + (GloData(SelectA,XLong,XLat)-GloData(SelectB,XLong,XLat)) OpSqTot = OpSqTot + ((GloData(SelectA,XLong,XLat)-GloData(SelectB,XLong,XLat)) ** 2) OpEn = OpEn + 1.0 else OpMiss = OpMiss + 1.0 end if end do end do print "(4e12.5)", OpMiss, OpEn, OpTot, OpSqTot end subroutine CompareAB ! ****************************************************************************** ! measures straight line distance from box value to A=B and prints global results subroutine HypABEqual OpMiss = 0.0 OpTot = 0.0 OpEn = 0.0 OpMean = MissVal do XLong = 1, LongN do XLat = 1, LatN if (GloData(SelectA,XLong,XLat).NE.MissVal.AND.GloData(SelectB,XLong,XLat).NE.MissVal) then OpTot = OpTot + (sqrt(0.5) * abs(GloData(SelectA,XLong,XLat)-GloData(SelectB,XLong,XLat))) OpEn = OpEn + 1.0 else OpMiss = OpMiss + 1.0 end if end do end do if (OpEn.GE.1) OpMean = OpTot / OpEn print "(4e12.5)", OpMiss, OpEn, OpTot, OpMean end subroutine HypABEqual ! ****************************************************************************** subroutine MakeRing allocate (Ring (LongN,LatN,8,2), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: MakeRing: Allocation failure #####" Ring = MissVal do XLong = 1, LongN ! identify the 8 grid boxes adjacent to each do XLat = 1, LatN XAdjacent = 0 do YLong = (XLong-1), (XLong+1) if (YLong.LT.1) then NearLong = LongN else if (YLong.GT.LongN) then NearLong = 1 else NearLong = YLong end if do YLat = (XLat-1), (XLat+1) if (YLat.LT.1.OR.YLat.GT.LatN) then NearLat = MissVal else NearLat = YLat end if if (NearLong.NE.XLong.OR.NearLat.NE.XLat) then if (NearLong.NE.MissVal.AND.NearLat.NE.MissVal) then XAdjacent = XAdjacent + 1 Ring (XLong,XLat,XAdjacent,1) = NearLong Ring (XLong,XLat,XAdjacent,2) = NearLat end if end if end do end do end do end do end subroutine MakeRing ! ****************************************************************************** subroutine ClosestNeighbour call MakeRing allocate (ThisMap (LongN,LatN), & ThisGlo (GloRegN(SelectB)), & ScoreExp (GloRegN(SelectB)), & ScoreAct (GloRegN(SelectB)), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: ClosestNeighbour: Allocation failure #####" ScoreExp = 0.0 ScoreAct = 0.0 ! calc actual score for each region do XLong = 1, LongN ! calc a priori E(score) for each region do XLat = 1, LatN if (GloMap(SelectB,XLong,XLat).NE.MissVal) then ! grid box of interest is part of a region if (GloData(SelectA,XLong,XLat).NE.MissVal) then ! grid box of interest has data OpTot = 0.0 ! no. of ring in same reg as box, + with data OpEn = 0.0 ! no. in ring with data OpMin = 100000.0 ! min diff between box and adjacent OpAdjMin = MissVal ! adjacent box with min diff do XAdjacent = 1, 8 if (Ring(XLong,XLat,XAdjacent,1).NE.MissVal) then ! adjacent box identified ! adjacent box has data if (GloData(SelectA,Ring(XLong,XLat,XAdjacent,1),Ring(XLong,XLat,XAdjacent,2)).NE.MissVal) then OpEn = OpEn + 1.0 ! increment no. in ring with data if (GloMap(SelectB,XLong,XLat).EQ.& ! adjacent box is in same region GloMap(SelectB,Ring(XLong,XLat,XAdjacent,1),Ring(XLong,XLat,XAdjacent,2))) & OpTot = OpTot + 1.0 ! increment no. of ring in same reg OpDiff = abs (GloData(SelectA,XLong,XLat) - & ! diff between box and adjacent GloData(SelectA,Ring(XLong,XLat,XAdjacent,1),Ring(XLong,XLat,XAdjacent,2)) ) if (OpDiff.LT.OpMin) then ! diff is min so far OpMin = OpDiff ! make min diff the current diff OpAdjMin = XAdjacent ! make min adjacent the current adjacent end if end if end if end do if (OpEn.GT.0) then ! box(es) in ring have data if ((OpTot/OpEn).NE.1) then ! ignore box if all adjacent are in region ! increment a priori E(score) ScoreExp(GloMap(SelectB,XLong,XLat)) = ScoreExp(GloMap(SelectB,XLong,XLat)) + (OpTot/OpEn) if (GloMap(SelectB,XLong,XLat).EQ.& ! min adjacent is of same region GloMap(SelectB,Ring(XLong,XLat,OpAdjMin,1),Ring(XLong,XLat,OpAdjMin,2))) & ScoreAct(GloMap(SelectB,XLong,XLat)) = ScoreAct(GloMap(SelectB,XLong,XLat)) + 1.0 ! increment actual score end if end if end if end if end do end do do XLong = 1, LongN ! load ThisMap do XLat = 1, LatN ThisMap (XLong,XLat) = GloMap (SelectB,XLong,XLat) end do end do do XReg = 1, GloRegN(SelectB) ! load ThisReg if (ScoreExp(XReg).GT.0) then ThisGlo (XReg) = ScoreAct (XReg) / ScoreExp (XReg) end if end do call SaveGlo (LongN,LatN,GloRegN(SelectB),GridFilePath,Blank,Blank,ThisGlo,ThisMap) deallocate (ScoreExp,ScoreAct,Ring,ThisMap,ThisGlo, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: ClosestNeighbour: Deallocation failure #####" end subroutine ClosestNeighbour ! ****************************************************************************** subroutine PrintBoxStats print "(a4,5a12)", " Col", " Sum", " Sum Squares", " Mean", " StDev", " AvMag" do XGlo = 1, (FirstFree-1) OpMiss = 0.0 OpTot = 0.0 OpMagTot = 0.0 OpEn = 0.0 OpSqTot = 0.0 OpMean = MissVal OpStDev = MissVal do XLong = 1, LongN do XLat = 1, LatN if (GloData(XGlo,XLong,XLat).NE.MissVal) then OpTot = OpTot + GloData(XGlo,XLong,XLat) OpSqTot = OpSqTot + (GloData(XGlo,XLong,XLat) ** 2) OpMagTot = OpMagTot + abs (GloData(XGlo,XLong,XLat)) OpEn = OpEn + 1.0 else OpMiss = OpMiss + 1.0 end if end do end do if (OpEn.GE.1) then OpMean = OpTot/OpEn OpStDev = (OpSqTot/OpEn) - ((OpTot/OpEn) ** 2) OpStDev = sqrt (OpStDev) OpMagAv = OpMagTot/OpEn end if print "(i4,5e12.5)", XGlo, OpTot, OpSqTot, OpMean, OpStDev, OpMagAv end do end subroutine PrintBoxStats ! ****************************************************************************** subroutine PrintRegStats print "(a4,5a12)", " Col", " Sum", " Sum Squares", " Mean", " StDev", " AvMag" do XGlo = 1, (FirstFree-1) OpMiss = 0.0 OpTot = 0.0 OpMagTot = 0.0 OpEn = 0.0 OpSqTot = 0.0 OpMean = MissVal OpStDev = MissVal do XReg = 1, GloRegN (XGlo) GotThisReg = 0 do XLong = 1, LongN do XLat = 1, LatN if (GotThisReg.EQ.0) then if (GloMap(XGlo,XLong,XLat).EQ.XReg.AND.GloData(XGlo,XLong,XLat).NE.MissVal) then OpTot = OpTot + GloData(XGlo,XLong,XLat) OpSqTot = OpSqTot + (GloData(XGlo,XLong,XLat) ** 2) OpMagTot = OpMagTot + abs (GloData(XGlo,XLong,XLat)) OpEn = OpEn + 1.0 GotThisReg = 1 end if end if end do end do end do if (OpEn.GE.1) then OpMean = OpTot/OpEn OpStDev = (OpSqTot/OpEn) - ((OpTot/OpEn) ** 2) OpStDev = sqrt (OpStDev) OpMagAv = OpMagTot/OpEn end if print "(i4,5e12.5)", XGlo, OpTot, OpSqTot, OpMean, OpStDev, OpMagAv end do end subroutine PrintRegStats ! ****************************************************************************** end program CompareReg