! compareglo2.f90 ! f90 main program written on 13.01.00 by Tim Mitchell ! last modification on 25.10.01 ! pgf90 -o ./../goglo/compareglo2 filenames.f90 initialmod.f90 glofiles.f90 sortmod.f90 ! ./../goglo/compareglo2.f90 ! purpose is to permit us to avoid multiple saves to .glo and truncations to zero program CompareGlo2 use FileNames use InitialMod use GloFiles use SortMod implicit none real, pointer, dimension (:,:) :: GloLoaded real, pointer, dimension (:) :: GloSaved, ThisGlo, BaseGlo, NewTot, NewEn, GloMin, GloMax, OpVec real, pointer, dimension (:) :: PertRaw, PertTot, BaseTot integer, pointer, dimension (:) :: WorkRegSizes, Indices, NewRegSizes integer, pointer, dimension (:,:) :: WorkMapIDLReg, NewMapIDLReg character (len=20), pointer, dimension (:) :: WorkRegNames, NewRegNames real, allocatable, dimension (:,:) :: UseClass integer, allocatable, dimension (:) :: UseGlo, FreqClass real, parameter :: MissVal = -999.0 real :: RunTot, RunEn, RunSqTot, RunMin, RunMax real :: Aye, Bee, Are, Num, Den real :: SumX, SumY, SumXX, SumYY, SumXY, En real :: OpTot, OpSqTot, OpAbsTot, OpEn, OpMean, OpStDev, OpDiff real :: RegSqTot, RegTot, RegEn, RegMean, RegStDev, RegRMSE real :: CutOffVal, TestVal, ChosenKay, RealConstant, AvMag, XMedianReal real :: MinVal, MaxVal, Median, Mode real :: ClassValue, ClassBound, LastBound, RangeMin, RangeMax, RangeGap real :: ValueToChange, ValueToLeave integer :: WorkGrid, WorkLongN, WorkLatN, WorkDataN integer :: WorkRegN, WorkGloN, NewRegN integer :: SelectGloN, ChosenGlo integer :: AllocStat, ReadStatus integer :: XReg, XGlo, XGloFree, XGloSave, XSelect, XClass, XBound, XLat, XLong integer :: QAnom, QMain, QSampPop, QConvert, QWhichOp, QOutput, QMinMax, QClassMethod integer :: CutOffSign, CutOffType, RegKept, RegCutOff integer :: ChosenExp, Operator, IntConstant, XMedianInt, OpMissN, ExitNow integer :: ClassN, ValidN character (len=10) :: WorkGridTitle character (len=40) :: WorkRegTitle, NewRegTitle character (len=80) :: WorkGridFilePath, WorkGloTitle, Blank !******************************************************************************* ! initialise open (99,file="./../../../scratch/log-compareglo2.dat",status="replace",action="write") print* print*, " > ***** CompareGlo *****" print* call GridSelect (WorkGrid,WorkGridTitle,WorkLongN,WorkLatN,WorkDataN,WorkGridFilePath) call RegSelect (WorkGrid,WorkLongN,WorkLatN,WorkDataN,WorkMapIDLReg,WorkRegSizes,WorkRegNames,& WorkRegTitle,WorkRegN) call GrabGlo Blank = "" QMain = -1 do if (QMain.EQ.-1) then else if (QMain.EQ.1) then SelectGloN = 2 call SelectGloOp call TwoFromOne else if (QMain.EQ.2) then call WhichOp call GrabGloN call SelectGloOp if (QWhichOp.EQ.1) call CalcMean if (QWhichOp.EQ.2) call CalcMedian if (QWhichOp.EQ.3) print*, " > ##### CompareGlo: Not set up to calc mode. #####" if (QWhichOp.EQ.4) call CalcStDev if (QWhichOp.EQ.5) call CalcRange else if (QMain.EQ.5) then SelectGloN = 2 call SelectGloOp call CalcLSR else if (QMain.EQ.6) then SelectGloN = 3 call SelectGloOp call PosABC else if (QMain.EQ.7) then SelectGloN = 2 call SelectGloOp call MaskAB else if (QMain.EQ.8) then SelectGloN = 1 call SelectGloOp call OperateAConstant else if (QMain.EQ.9) then SelectGloN = 2 call SelectGloOp call OperateAB else if (QMain.EQ.10) then call GrabGloN call SelectGloOp call ClassifyABox else if (QMain.EQ.11) then call GrabGloN call SelectGloOp call ClassifyAGroup else if (QMain.EQ.12) then SelectGloN = 2 call SelectGloOp call CompareAB else if (QMain.EQ.13) then SelectGloN = 1 call SelectGloOp call RegionaliseA else if (QMain.EQ.14) then SelectGloN = 1 call SelectGloOp call RegPerCentA else if (QMain.EQ.15) then SelectGloN = 1 call SelectGloOp call TransformVal else if (QMain.EQ.16) then SelectGloN = 2 call SelectGloOp call CompMasked else if (QMain.EQ.20) then call SaveToGlo else if (QMain.EQ.30) then call PrintToScreen else if (QMain.EQ.31) then call PrintToScreenExtra else if (QMain.EQ.32) then SelectGloN = 1 call SelectGloOp call WriteRegLog else if (QMain.EQ.33) then SelectGloN = 1 call SelectGloOp call WriteRegScreen else print*, " > Select the comparison to make: " print*, " > 1. A minus B" print*, " > 2. Summary operations on A,B,..." print*, " > 5. LSR between A and B" print*, " > 6. Position of A relative to B, C" print*, " > 7. Mask A using B" print*, " > 8. Operate on A with k" print*, " > 9. Operate on A with B" print*, " > 10. Classify A: assign value to each box" print*, " > 11. Classify A: group values and report" print*, " > 12. Compare A and B" print*, " > 13. Convert A to new regions (save/print)" print*, " > 14. As 13. For percentage units" print*, " > 15. Convert one value to another" print*, " > 16. Compare masked columns" print*, " > 20. Save A to .glo" print*, " > 30. Print stats for all to screen" print*, " > 31. Print extra stats" print*, " > 32. Write a column to log" print*, " > 33. Print A's regional values to screen" print*, " > 99. Exit." end if if (allocated(UseGlo)) deallocate (UseGlo, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Main: Deallocation failure #####" print* print*, " > Main menu: select option: " do read (*,*,iostat=ReadStatus), QMain if (ReadStatus.LE.0) exit end do if (QMain.EQ.99) exit end do deallocate (GloLoaded) deallocate (WorkMapIDLReg,WorkRegSizes,WorkRegNames) print* close (99) contains !******************************************************************************* ! choose operation on A,B,... subroutine WhichOp print*, " > Select the operation to perform:" print*, " > 1=mean, 2=median, 3=mode, 4=stdev, 5=range" do read (*,*,iostat=ReadStatus), QWhichOp if (ReadStatus.LE.0.AND.QWhichOp.GE.1.AND.QWhichOp.LE.5) exit end do end subroutine WhichOp !******************************************************************************* ! load .glo subroutine GrabGlo print*, " > Select the number of .glo to load." do read (*,*,iostat=ReadStatus), WorkGloN if (ReadStatus.LE.0.AND.WorkGloN.GE.1) exit end do XGloFree = WorkGloN + 1 WorkGloN = WorkGloN + 30 allocate (GloLoaded(WorkGloN,WorkRegN), & ThisGlo (WorkRegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GrabGlo: Allocation failure #####" GloLoaded = MissVal do XGlo = 1, (WorkGloN-30) print*, " > load .glo number ", XGlo ThisGlo = MissVal call LoadGloVec (Blank, WorkMapIDLReg, ThisGlo) do XReg = 1, WorkRegN GloLoaded (XGlo,XReg) = ThisGlo (XReg) end do end do deallocate (ThisGlo, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GrabGlo: Deallocation failure #####" end subroutine GrabGlo !******************************************************************************* ! select number of .glo subroutine GrabGloN print*, " > Select the number of .glo to use." do read (*,*,iostat=ReadStatus), SelectGloN if (ReadStatus.LE.0.AND.SelectGloN.GE.1) exit end do end subroutine GrabGloN !******************************************************************************* ! select particular .glo to use subroutine SelectGloOp allocate (UseGlo(SelectGloN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: SelectGloOp: Allocation failure #####" UseGlo = 0 print*, " > Select particular .glo to use in op, totalling: ", SelectGloN do XSelect = 1, SelectGloN print*, " > Select .glo number: ", XSelect do read (*,*,iostat=ReadStatus), ChosenGlo if (ReadStatus.LE.0.AND.ChosenGlo.GE.1.AND.ChosenGlo.LE.(XGloFree-1)) exit end do UseGlo (XSelect) = ChosenGlo end do end subroutine SelectGloOp !******************************************************************************* ! subtract Two from One subroutine TwoFromOne print*, " > Calc abs diff (=1), % diff (=2), fraction (=3), reduced mag (=4) ?" do read (*,*,iostat=ReadStatus), QAnom if (ReadStatus.LE.0.AND.QAnom.GE.1.AND.QAnom.LE.4) exit end do if (QAnom.EQ.1) then do XReg = 1, WorkRegN if (GloLoaded(UseGlo(1),XReg).NE.MissVal.AND.GloLoaded(UseGlo(2),XReg).NE.MissVal) then GloLoaded (XGloFree,XReg) = GloLoaded(UseGlo(1),XReg) - GloLoaded(UseGlo(2),XReg) end if end do else if (QAnom.EQ.2) then do XReg = 1, WorkRegN if (GloLoaded(UseGlo(1),XReg).NE.MissVal.AND.GloLoaded(UseGlo(2),XReg).NE.MissVal) then if (GloLoaded(UseGlo(2),XReg).NE.0) then GloLoaded (XGloFree,XReg) = 100.0 * (GloLoaded(UseGlo(1),XReg) - & GloLoaded(UseGlo(2),XReg)) / abs (GloLoaded(UseGlo(2),XReg)) end if end if end do else if (QAnom.EQ.3) then do XReg = 1, WorkRegN if (GloLoaded(UseGlo(1),XReg).NE.MissVal.AND.GloLoaded(UseGlo(2),XReg).NE.MissVal) then if (GloLoaded(UseGlo(2),XReg).NE.0) then GloLoaded (XGloFree,XReg) = GloLoaded(UseGlo(1),XReg) / GloLoaded(UseGlo(2),XReg) end if end if end do else if (QAnom.EQ.4) then print*, " > abs(A)0 else A>0-->A-B else A<0-->A+B" do XReg = 1, WorkRegN if (GloLoaded(UseGlo(1),XReg).NE.MissVal.AND.GloLoaded(UseGlo(2),XReg).NE.MissVal) then if (abs(GloLoaded(UseGlo(1),XReg)).LE.GloLoaded(UseGlo(2),XReg)) then GloLoaded (XGloFree,XReg) = 0.0 else if (GloLoaded(1,XReg).GT.0) then GloLoaded (XGloFree,XReg) = GloLoaded(UseGlo(1),XReg) - GloLoaded(UseGlo(2),XReg) else GloLoaded (XGloFree,XReg) = GloLoaded(UseGlo(1),XReg) + GloLoaded(UseGlo(2),XReg) end if end if end if end do end if print*, " > We have stored the result in column: ", XGloFree if (XGloFree.LT.WorkGloN) XGloFree = XGloFree + 1 end subroutine TwoFromOne !******************************************************************************* ! calc Mean subroutine CalcMean do XReg = 1, WorkRegN RunTot = 0.0 RunEn = 0.0 do XGlo = 1, SelectGloN if (GloLoaded(UseGlo(XGlo),XReg).NE.MissVal) then RunTot = RunTot + GloLoaded(UseGlo(XGlo),XReg) RunEn = RunEn + 1.0 end if end do if (RunEn.GE.1) then GloLoaded (XGloFree,XReg) = RunTot / RunEn end if end do print*, " > We have stored the result in column: ", XGloFree if (XGloFree.LT.WorkGloN) XGloFree = XGloFree + 1 end subroutine CalcMean !******************************************************************************* ! calc Median subroutine CalcMedian allocate (OpVec (SelectGloN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CalcMedian: Allocation failure #####" OpVec = MissVal do XReg = 1, WorkRegN do XGlo = 1, SelectGloN OpVec(XGlo) = GloLoaded(UseGlo(XGlo),XReg) end do GloLoaded (XGloFree,XReg) = MedianValue (SelectGloN,OpVec) end do print*, " > We have stored the result in column: ", XGloFree if (XGloFree.LT.WorkGloN) XGloFree = XGloFree + 1 end subroutine CalcMedian !******************************************************************************* ! calc StDev subroutine CalcStDev if (WorkGloN.GE.2) then print*, " > Calc sample (=1) or population (=2) stdev ?" do read (*,*,iostat=ReadStatus), QSampPop if (ReadStatus.LE.0.AND.QSampPop.GE.1.AND.QSampPop.LE.2) exit end do else print*, " > n=1 therefore calc sample stdev" QSampPop = 1 end if do XReg = 1, WorkRegN RunSqTot = 0.0 RunTot = 0.0 RunEn = 0.0 do XGlo = 1, SelectGloN if (GloLoaded(UseGlo(XGlo),XReg).NE.MissVal) then RunSqTot = RunSqTot + (GloLoaded(UseGlo(XGlo),XReg) * GloLoaded(UseGlo(XGlo),XReg)) RunTot = RunTot + GloLoaded(UseGlo(XGlo),XReg) RunEn = RunEn + 1.0 end if end do if (RunEn.GE.2) then if (QSampPop.EQ.1) then GloLoaded (XGloFree,XReg) = (RunSqTot/RunEn) - ((RunTot/RunEn)*(RunTot/RunEn)) GloLoaded (XGloFree,XReg) = sqrt (GloLoaded (XGloFree,XReg)) else GloLoaded (XGloFree,XReg) = (RunSqTot/RunEn) - ((RunTot/RunEn)*(RunTot/RunEn)) GloLoaded (XGloFree,XReg) = GloLoaded (XGloFree,XReg) * RunEn / (RunEn - 1) GloLoaded (XGloFree,XReg) = sqrt (GloLoaded (XGloFree,XReg)) end if end if end do print*, " > We have stored the result in column: ", XGloFree if (XGloFree.LT.WorkGloN) XGloFree = XGloFree + 1 end subroutine CalcStDev !******************************************************************************* ! calc range subroutine CalcRange allocate (GloMin (WorkRegN), & GloMax (WorkRegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CalcRange: Allocation failure #####" GloMin = MissVal GloMax = MissVal do XReg = 1, WorkRegN RunMin = 1000000.0 RunMax = -1000000.0 do XGlo = 1, SelectGloN if (GloLoaded(UseGlo(XGlo),XReg).NE.MissVal) then if (GloLoaded(UseGlo(XGlo),XReg).LT.RunMin) then GloMin (XReg) = GloLoaded(UseGlo(XGlo),XReg) RunMin = GloLoaded(UseGlo(XGlo),XReg) end if if (GloLoaded(UseGlo(XGlo),XReg).GT.RunMax) then GloMax (XReg) = GloLoaded(UseGlo(XGlo),XReg) RunMax = GloLoaded(UseGlo(XGlo),XReg) end if end if end do end do do XReg = 1, WorkRegN ! store min values GloLoaded (XGloFree,XReg) = GloMin (XReg) end do if (XGloFree.LT.WorkGloN) XGloFree = XGloFree + 1 do XReg = 1, WorkRegN ! store max values GloLoaded (XGloFree,XReg) = GloMax (XReg) end do if (XGloFree.LT.WorkGloN) XGloFree = XGloFree + 1 print*, " > We have stored the min and max in columns: ", (XGloFree-2), (XGloFree-1) deallocate (GloMin,GloMax, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CalcRange: Deallocation failure #####" end subroutine CalcRange !******************************************************************************* ! calc LSR subroutine CalcLSR SumX = 0.0 SumY = 0.0 SumXX = 0.0 SumYY = 0.0 SumXY = 0.0 En = 0.0 Aye = MissVal Bee = MissVal Are = MissVal do XReg = 1, WorkRegN if (GloLoaded(UseGlo(1),XReg).NE.MissVal.AND.GloLoaded(UseGlo(2),XReg).NE.MissVal) then SumX = SumX + GloLoaded(UseGlo(1),XReg) SumY = SumY + GloLoaded(UseGlo(2),XReg) SumXX = SumXX + GloLoaded(UseGlo(1),XReg) ** 2 SumYY = SumYY + GloLoaded(UseGlo(2),XReg) ** 2 SumXY = SumXY + GloLoaded(UseGlo(1),XReg) * GloLoaded(UseGlo(2),XReg) En = En + 1.0 end if end do if (En.GE.2) then Num = (En*SumXY)-(SumX*SumY) Den = (En*SumXX)-(SumX*SumX) if (Den.NE.0) Aye = Num / Den if (Aye.NE.MissVal) Bee = (SumY-(Aye*SumX))/En Num = (SumXY/En)-((SumX/En)*(SumY/En)) Den = sqrt((SumXX/En)-((SumX/En)*(SumX/En)))*sqrt((SumYY/En)-((SumY/En)*(SumY/En))) if (Den.NE.0) Are = Num / Den print*, " > Values of a,b,r for y=ax+b, where x= value in first .glo" print "(3F12.4)", Aye, Bee, Are else print*, " > Too few valid regions." end if end subroutine CalcLSR !******************************************************************************* ! pos of A relative to B and C subroutine PosABC do XReg = 1, WorkRegN if (GloLoaded(UseGlo(1),XReg).NE.MissVal.AND.GloLoaded(UseGlo(2),XReg).NE.MissVal & .AND.GloLoaded(UseGlo(3),XReg).NE.MissVal) then if (GloLoaded(UseGlo(1),XReg).LT.GloLoaded(UseGlo(2),XReg) & .AND.GloLoaded(UseGlo(1),XReg).LT.GloLoaded(UseGlo(3),XReg)) then GloLoaded (XGloFree,XReg) = -1 else if (GloLoaded(1,XReg).GT.GloLoaded(UseGlo(2),XReg) & .AND.GloLoaded(UseGlo(1),XReg).GT.GloLoaded(UseGlo(3),XReg)) then GloLoaded (XGloFree,XReg) = 1 else GloLoaded (XGloFree,XReg) = 0 end if else GloLoaded (XGloFree,XReg) = MissVal end if end do print*, " > We have stored the result in column: ", XGloFree if (XGloFree.LT.WorkGloN) XGloFree = XGloFree + 1 end subroutine PosABC !******************************************************************************* ! mask A using B subroutine MaskAB if ((XGloFree+2).LE.WorkGloN) then print*, " > Is the threshold a real (=1) or a magnitude (=2): " do read (*,*,iostat=ReadStatus), CutOffType if (ReadStatus.LE.0.AND.CutOffType.GE.1.AND.CutOffType.LE.2) exit end do print*, " > Enter the threshold in B by which to separate A: " do read (*,*,iostat=ReadStatus), CutOffVal if (ReadStatus.LE.0) exit end do do XReg = 1, WorkRegN if (GloLoaded(UseGlo(1),XReg).NE.MissVal.AND.GloLoaded(UseGlo(2),XReg).NE.MissVal) then if (CutOffType.EQ.2) then TestVal = abs (GloLoaded(UseGlo(2),XReg)) else TestVal = GloLoaded(UseGlo(2),XReg) end if if (TestVal.EQ.CutOffVal) then GloLoaded ((XGloFree+1),XReg) = GloLoaded(UseGlo(1),XReg) else if (TestVal.LT.CutOffVal) then GloLoaded ((XGloFree+0),XReg) = GloLoaded(UseGlo(1),XReg) else if (TestVal.GT.CutOffVal) then GloLoaded ((XGloFree+2),XReg) = GloLoaded(UseGlo(1),XReg) end if end if end do print "(a56,3i4)", " > We have stored values <, =, > threshold in columns: ", & XGloFree, (XGloFree+1), (XGloFree+2) if (XGloFree.LT.WorkGloN) XGloFree = XGloFree + 3 if (XGloFree.GT.WorkGloN) XGloFree = WorkGloN else print*, " > Insufficient columns remaining to perform operation." end if end subroutine MaskAB !******************************************************************************* ! compare two masked columns subroutine CompMasked if ((XGloFree+1).LE.WorkGloN) then print*, " > Select the min (=1) or max (=2) of A and B:" do read (*,*,iostat=ReadStatus), QMinMax if (ReadStatus.LE.0.AND.QMinMax.GE.1.AND.QMinMax.LE.2) exit end do do XReg = 1, WorkRegN if (GloLoaded(UseGlo(1),XReg).EQ.MissVal) then if (GloLoaded(UseGlo(2),XReg).EQ.MissVal) then GloLoaded ((XGloFree+0),XReg) = MissVal GloLoaded ((XGloFree+1),XReg) = 0 else GloLoaded ((XGloFree+0),XReg) = GloLoaded(UseGlo(2),XReg) GloLoaded ((XGloFree+1),XReg) = 1 end if else if (GloLoaded(UseGlo(2),XReg).EQ.MissVal) then GloLoaded ((XGloFree+0),XReg) = GloLoaded(UseGlo(1),XReg) GloLoaded ((XGloFree+1),XReg) = 2 else OpDiff = GloLoaded(UseGlo(2),XReg) - GloLoaded(UseGlo(1),XReg) ! B minus A if (OpDiff.GE.0) then if (QMinMax.EQ.1) then GloLoaded ((XGloFree+0),XReg) = GloLoaded(UseGlo(1),XReg) GloLoaded ((XGloFree+1),XReg) = 3 else GloLoaded ((XGloFree+0),XReg) = GloLoaded(UseGlo(2),XReg) GloLoaded ((XGloFree+1),XReg) = 4 end if else if (QMinMax.EQ.1) then GloLoaded ((XGloFree+0),XReg) = GloLoaded(UseGlo(2),XReg) GloLoaded ((XGloFree+1),XReg) = 4 else GloLoaded ((XGloFree+0),XReg) = GloLoaded(UseGlo(1),XReg) GloLoaded ((XGloFree+1),XReg) = 3 end if end if end if end if end do print*, " > Selected value and code go in columns:", XGloFree, (XGloFree+1) print*, " > A,B=MissVal value=MissVal code=0" print*, " > A=MissVal value=B code=1" print*, " > B=MissVal value=A code=2" print*, " > A=chosen value=A code=3" print*, " > B=chosen value=B code=4" XGloFree = XGloFree + 2 if (XGloFree.GT.WorkGloN) XGloFree = WorkGloN else print*, " > Insufficient columns remaining to perform operation." end if end subroutine CompMasked !******************************************************************************* ! divide by constant subroutine OperateAConstant print*, " > Divide=1, multiply=2, minus=3, add=4, sqroot=5, exp=6, abs=7" do read (*,*,iostat=ReadStatus), Operator if (ReadStatus.LE.0 .AND. Operator.GE.1 .AND. Operator.LE.7) exit end do if (Operator.LT.5) then print*, " > Enter constant (real):" do read (*,*,iostat=ReadStatus), RealConstant if (ReadStatus.LE.0) exit end do else if (Operator.EQ.6) then print*, " > Enter constant (positive integer):" do read (*,*,iostat=ReadStatus), IntConstant if (ReadStatus.LE.0.AND.IntConstant.GE.0) exit end do end if do XReg = 1, WorkRegN if (GloLoaded(UseGlo(1),XReg).NE.MissVal) then if (Operator.EQ.1.AND.RealConstant.NE.0) & GloLoaded (XGloFree,XReg) = GloLoaded(UseGlo(1),XReg) / RealConstant if (Operator.EQ.2) GloLoaded (XGloFree,XReg) = GloLoaded(UseGlo(1),XReg) * RealConstant if (Operator.EQ.3) GloLoaded (XGloFree,XReg) = GloLoaded(UseGlo(1),XReg) - RealConstant if (Operator.EQ.4) GloLoaded (XGloFree,XReg) = GloLoaded(UseGlo(1),XReg) + RealConstant if (Operator.EQ.5) GloLoaded (XGloFree,XReg) = sqrt (GloLoaded(UseGlo(1),XReg)) if (Operator.EQ.6) GloLoaded (XGloFree,XReg) = GloLoaded(UseGlo(1),XReg) ** IntConstant if (Operator.EQ.7) GloLoaded (XGloFree,XReg) = abs (GloLoaded(UseGlo(1),XReg)) end if end do print*, " > We have stored the result in column: ", XGloFree if (XGloFree.LT.WorkGloN) XGloFree = XGloFree + 1 end subroutine OperateAConstant !******************************************************************************* ! operate on A with B subroutine OperateAB print*, " > A operator B" print*, " > Operator is divide =1, multi =2, minus =3, add =4" do read (*,*,iostat=ReadStatus), Operator if (ReadStatus.LE.0 .AND. Operator.GE.1 .AND. Operator.LE.4) exit end do do XReg = 1, WorkRegN if (GloLoaded(UseGlo(1),XReg).NE.MissVal.AND.GloLoaded(UseGlo(2),XReg).NE.MissVal) then if (Operator.EQ.1.AND.GloLoaded(UseGlo(2),XReg).NE.0) & GloLoaded (XGloFree,XReg) = GloLoaded(UseGlo(1),XReg) / GloLoaded(UseGlo(2),XReg) if (Operator.EQ.2) GloLoaded (XGloFree,XReg) = GloLoaded(UseGlo(1),XReg) * GloLoaded(UseGlo(2),XReg) if (Operator.EQ.3) GloLoaded (XGloFree,XReg) = GloLoaded(UseGlo(1),XReg) - GloLoaded(UseGlo(2),XReg) if (Operator.EQ.4) GloLoaded (XGloFree,XReg) = GloLoaded(UseGlo(1),XReg) + GloLoaded(UseGlo(2),XReg) end if end do print*, " > We have stored the result in column: ", XGloFree if (XGloFree.LT.WorkGloN) XGloFree = XGloFree + 1 end subroutine OperateAB !******************************************************************************* ! get class specifications subroutine GetClassSpec print*, " > Define equal-interval classes (=0) or manually (=1) ?" do read (*,*,iostat=ReadStatus), QClassMethod if (ReadStatus.LE.0.AND.QClassMethod.GE.0.AND.QClassMethod.LE.1) exit end do if (QClassMethod.EQ.0) then call EqualClass else call ManualClass end if end subroutine GetClassSpec !******************************************************************************* ! get class specifications subroutine EqualClass print*, " > Enter the min,max,interval: " do read (*,*,iostat=ReadStatus), RangeMin,RangeMax,RangeGap if (ReadStatus.LE.0 .AND. RangeMax.GT.RangeMin .AND. & mod((RangeMax-RangeMin),RangeGap).EQ.0.0) exit end do ClassN = nint((RangeMax-RangeMin) / RangeGap) allocate (UseClass(ClassN,3), stat=AllocStat) ! lower & upper bounds, class value if (AllocStat.NE.0) print*, " > ##### ERROR: EqualClass: Allocation failure #####" do XClass=1,ClassN UseClass (XClass,1) = RangeMin + ((XClass-1)*RangeGap) UseClass (XClass,2) = RangeMin + ((XClass+0)*RangeGap) UseClass (XClass,3) = (UseClass (XClass,1) + UseClass (XClass,2)) / 2.0 end do end subroutine EqualClass !******************************************************************************* ! get class specifications subroutine ManualClass print*, " > Enter the number of classes:" do read (*,*,iostat=ReadStatus), ClassN if (ReadStatus.LE.0 .AND. ClassN.GE.1) exit end do allocate (UseClass(ClassN,3), stat=AllocStat) ! lower & upper bounds, class value if (AllocStat.NE.0) print*, " > ##### ERROR: ManualClass: Allocation failure #####" UseClass = MissVal print*, " > Enter each class boundary, in ascending order, totalling:", (ClassN-1) LastBound = 10 - huge(ClassBound) do XBound = 1, (ClassN-1) do read (*,*,iostat=ReadStatus), ClassBound if (ReadStatus.NE.0 .OR. ClassBound.LE.LastBound) print*, " > Boundary not accepted. Re-enter it." if (ReadStatus.LE.0 .AND. ClassBound.GT.LastBound) exit end do UseClass (XBound,2) = ClassBound UseClass ((XBound+1),1) = ClassBound end do print*, " > Enter each class value, in class order, totalling:", ClassN do XClass = 1, ClassN do read (*,*,iostat=ReadStatus), ClassValue if (ReadStatus.NE.0) print*, " > Value not accepted. Re-enter it." if (ReadStatus.LE.0) exit end do UseClass (XClass,3) = ClassValue end do end subroutine ManualClass !******************************************************************************* ! classify A and assign a class value to each box subroutine ClassifyABox call GetClassSpec do XGlo = 1, SelectGloN do XReg = 1, WorkRegN if (GloLoaded(UseGlo(XGlo),XReg).NE.MissVal) then XClass = 0 ExitNow = 0 do XClass = XClass + 1 if (GloLoaded(UseGlo(XGlo),XReg).LE.UseClass(XClass,2).OR.XClass.EQ.ClassN) then GloLoaded(XGloFree,XReg) = UseClass(XClass,3) ExitNow = 1 end if if (ExitNow.EQ.1) exit end do end if end do print*, " > Column classified to column: ", UseGlo(XGlo), XGloFree if (XGloFree.LT.WorkGloN) XGloFree = XGloFree + 1 end do deallocate (UseClass,UseGlo, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: ClassifyABox: Deallocation failure #####" end subroutine ClassifyABox !******************************************************************************* ! classify A and count frequency in each group subroutine ClassifyAGroup call GetClassSpec allocate (FreqClass(ClassN), stat=AllocStat) ! no. of values in class if (AllocStat.NE.0) print*, " > ##### ERROR: ClassifyAGroup: Allocation failure #####" print "(a22)", " col class value freq" do XGlo = 1, SelectGloN FreqClass = 0 do XReg = 1, WorkRegN if (GloLoaded(UseGlo(XGlo),XReg).NE.MissVal) then XClass = 0 ExitNow = 0 do XClass = XClass + 1 if (GloLoaded(UseGlo(XGlo),XReg).LE.UseClass(XClass,2).OR.XClass.EQ.ClassN) then FreqClass(XClass) = FreqClass(XClass) + 1 ExitNow = 1 end if if (ExitNow.EQ.1) exit end do end if end do print* do XClass = 1, ClassN print "(i4,f12.4,i6)", UseGlo(XGlo), UseClass(XClass,3), FreqClass(XClass) end do end do deallocate (UseClass,FreqClass, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: ClassifyABox: Deallocation failure #####" end subroutine ClassifyAGroup !******************************************************************************* ! compare A and B subroutine CompareAB ClassN = 3 allocate (UseClass(ClassN,1), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CompareAB: Allocation failure #####" UseClass = MissVal print*, " > We classify by: AB. Enter a value to assign to each." do XClass = 1, ClassN do read (*,*,iostat=ReadStatus), ClassValue if (ReadStatus.NE.0) print*, " > Value not accepted. Re-enter it." if (ReadStatus.LE.0) exit end do UseClass (XClass,1) = ClassValue end do do XReg = 1, WorkRegN if (GloLoaded(UseGlo(1),XReg).NE.MissVal.AND.GloLoaded(UseGlo(2),XReg).NE.MissVal) then if (GloLoaded(UseGlo(1),XReg).LT.GloLoaded(UseGlo(2),XReg)) then GloLoaded(XGloFree,XReg) = UseClass(1,1) else if (GloLoaded(UseGlo(1),XReg).EQ.GloLoaded(UseGlo(2),XReg)) then GloLoaded(XGloFree,XReg) = UseClass(2,1) else GloLoaded(XGloFree,XReg) = UseClass(3,1) end if else GloLoaded(XGloFree,XReg) = MissVal end if end do print*, " > We have stored the result in column: ", XGloFree if (XGloFree.LT.WorkGloN) XGloFree = XGloFree + 1 deallocate (UseClass, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CompareAB: Deallocation failure #####" end subroutine CompareAB !******************************************************************************* ! regionalise A using new .ref ! no missing values are permitted, but this could be altered fairly simply subroutine RegionaliseA call RegSelect (WorkGrid, WorkLongN, WorkLatN, WorkDataN, NewMapIDLReg, & NewRegSizes, NewRegNames, NewRegTitle, NewRegN) print*, " > Convert as totals (=1) or means (=2) ? " do read (*,*,iostat=ReadStatus), QConvert if (ReadStatus.LE.0.AND.QConvert.GE.1.AND.QConvert.LE.2) exit end do print*, " > Save to .glo (=1), print to screen (=2), or both (=3) ? " do read (*,*,iostat=ReadStatus), QOutput if (ReadStatus.LE.0.AND.QOutput.GE.1.AND.QOutput.LE.3) exit end do allocate (NewTot (NewRegN), & NewEn (NewRegN), & ThisGlo(NewRegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: RegionaliseA: Allocation failure #####" NewTot = 0.0 NewEn = 0.0 ThisGlo= MissVal do XLong = 1, WorkLongN do XLat = 1, WorkLatN if (NewMapIDLReg (XLong,XLat).NE.MissVal) then ! grid box is wanted for new region set if (WorkMapIDLReg (XLong,XLat).NE.MissVal) then ! grid box is specified in old region set if (GloLoaded ( UseGlo(1), WorkMapIDLReg (XLong,XLat) ).NE.MissVal) then ! value is valid NewTot ( NewMapIDLReg (XLong,XLat) ) = NewTot ( NewMapIDLReg (XLong,XLat) ) + & GloLoaded ( UseGlo(1), WorkMapIDLReg (XLong,XLat) ) NewEn ( NewMapIDLReg (XLong,XLat) ) = NewEn ( NewMapIDLReg (XLong,XLat) ) + 1.0 end if end if end if end do end do do XReg = 1, NewRegN if (NewEn(XReg).EQ.NewRegSizes(XReg)) then if (QConvert.EQ.1) then ThisGlo (XReg) = NewTot (XReg) else ThisGlo (XReg) = NewTot (XReg) / NewEn (XReg) end if end if end do if (QOutput.NE.2) call SaveGlo (WorkLongN,WorkLatN,NewRegN,WorkGridFilePath,Blank,Blank,ThisGlo,NewMapIDLReg) if (QOutput.NE.1) then print '(a6,a1,a20,a1,a6,a12)', ' Index', ' ', ' Region', ' ', & ' Boxes', ' Value' do XReg = 1, NewRegN print '(i6,a1,a20,a1,i6,f20.4)', XReg, ' ', NewRegNames(XReg), ' ', & NewRegSizes(XReg), ThisGlo (XReg) end do end if write (99,'(a6,a1,a20,a1,a6,a12)'), ' Index', ' ', ' Region', ' ', & ' Boxes', ' Value' do XReg = 1, NewRegN write (99,'(i6,a1,a20,a1,i6,f20.4)'), XReg, ' ', NewRegNames(XReg), ' ', & NewRegSizes(XReg), ThisGlo (XReg) end do deallocate (NewMapIDLReg, NewRegSizes, NewRegNames, NewTot, NewEn, ThisGlo, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: RegionaliseA: Deallocation failure #####" end subroutine RegionaliseA !******************************************************************************* ! regionalise A using new .ref for percentage column ! no missing values are permitted, but this could be altered fairly simply subroutine RegPerCentA print*, " > Load the base values against which percentages were calculated." call LoadGloVec (Blank, WorkMapIDLReg, BaseGlo, Silent=1) call RegSelect (WorkGrid, WorkLongN, WorkLatN, WorkDataN, NewMapIDLReg, & NewRegSizes, NewRegNames, NewRegTitle, NewRegN) print*, " > Save to .glo (=1), print to screen (=2), or both (=3) ? " do read (*,*,iostat=ReadStatus), QOutput if (ReadStatus.LE.0.AND.QOutput.GE.1.AND.QOutput.LE.3) exit end do allocate (PertRaw(WorkRegN),& PertTot(NewRegN), & BaseTot(NewRegN), & NewEn (NewRegN), & ThisGlo(NewRegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: RegPerCentA: Allocation failure #####" PertTot = 0.0 BaseTot = 0.0 NewEn = 0.0 ThisGlo = MissVal PertRaw = MissVal do XReg = 1, WorkRegN if (GloLoaded (UseGlo(1),XReg).NE.MissVal.AND.BaseGlo(XReg).NE.MissVal) & PertRaw(XReg) = ((GloLoaded(UseGlo(1),XReg) * BaseGlo(XReg)) / 100.0) + BaseGlo(XReg) end do do XLong = 1, WorkLongN do XLat = 1, WorkLatN if (NewMapIDLReg (XLong,XLat).NE.MissVal) then ! grid box is wanted for new region set if (WorkMapIDLReg (XLong,XLat).NE.MissVal) then ! grid box is specified in old region set if (PertRaw (WorkMapIDLReg(XLong,XLat)).NE.MissVal) then ! raw is valid if (BaseGlo (WorkMapIDLReg(XLong,XLat)).NE.MissVal) then ! base is valid PertTot (NewMapIDLReg(XLong,XLat)) = PertTot (NewMapIDLReg(XLong,XLat)) + & PertRaw (WorkMapIDLReg(XLong,XLat)) BaseTot (NewMapIDLReg(XLong,XLat)) = BaseTot (NewMapIDLReg(XLong,XLat)) + & BaseGlo (WorkMapIDLReg(XLong,XLat)) NewEn (NewMapIDLReg(XLong,XLat)) = NewEn (NewMapIDLReg(XLong,XLat)) + 1.0 end if end if end if end if end do end do do XReg = 1, NewRegN if (NewEn(XReg).EQ.NewRegSizes(XReg)) then ThisGlo (XReg) = 100.0 * (PertTot(XReg)-BaseTot(XReg)) / BaseTot(XReg) end if end do if (QOutput.NE.2) call SaveGlo (WorkLongN,WorkLatN,NewRegN,WorkGridFilePath,Blank,Blank,ThisGlo,NewMapIDLReg) if (QOutput.NE.1) then print '(a6,a1,a20,a1,a6,a12)', ' Index', ' ', ' Region', ' ', & ' Boxes', ' Value' do XReg = 1, NewRegN print '(i6,a1,a20,a1,i6,f12.4)', XReg, ' ', NewRegNames(XReg), ' ', & NewRegSizes(XReg), ThisGlo (XReg) end do end if deallocate (NewMapIDLReg, NewRegSizes, NewRegNames, NewEn, ThisGlo, BaseGlo, & PertRaw, PertTot, BaseTot, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: RegPerCentA: Deallocation failure #####" end subroutine RegPerCentA !******************************************************************************* ! transform one value into another subroutine TransformVal print*, " > Enter the value to transform wherever it occurs: " do read (*,*,iostat=ReadStatus), ValueToChange if (ReadStatus.LE.0) exit end do print*, " > Enter the new value: " do read (*,*,iostat=ReadStatus), ValueToLeave if (ReadStatus.LE.0) exit end do ValidN = 0 do XReg = 1, WorkRegN if (GloLoaded(UseGlo(1),XReg).EQ.ValueToChange) then GloLoaded(XGloFree,XReg) = ValueToLeave ValidN = ValidN + 1 else GloLoaded(XGloFree,XReg) = GloLoaded(UseGlo(1),XReg) end if end do print*, " > Values changed total: ", ValidN print*, " > We have stored the result in column: ", XGloFree if (XGloFree.LT.WorkGloN) XGloFree = XGloFree + 1 end subroutine TransformVal !******************************************************************************* ! save .glo file subroutine SaveToGlo print*, " > Enter the column to save as a .glo: " do read (*,*,iostat=ReadStatus), XGloSave if (ReadStatus.LE.0.AND.XGloSave.GE.1.AND.XGloSave.LE.WorkGloN) exit end do allocate (GloSaved(WorkRegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: SaveToGlo: Allocation failure #####" GloSaved = MissVal do XReg = 1, WorkRegN GloSaved(XReg) = GloLoaded(XGloSave,XReg) end do call SaveGlo (WorkLongN,WorkLatN,WorkRegN,WorkGridFilePath,Blank,Blank,GloSaved,WorkMapIDLReg) deallocate (GloSaved, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: SaveToGlo: Deallocation failure #####" end subroutine SaveToGlo !******************************************************************************* ! print details to screen subroutine PrintToScreen print "(a4,a6,5a12)", "File", " Reg", " Sum", " Sum Squares", " Mean", " StDev", & " AvMag" do XGlo = 1, (XGloFree-1) OpTot = 0.0 OpSqTot = 0.0 OpAbsTot= 0.0 OpEn = 0.0 OpMean = MissVal OpStDev = MissVal AvMag = MissVal do XReg = 1, WorkRegN if (GloLoaded(XGlo,XReg).NE.MissVal) then OpTot = OpTot + GloLoaded(XGlo,XReg) OpSqTot = OpSqTot + (GloLoaded(XGlo,XReg) ** 2) OpAbsTot = OpAbsTot + abs(GloLoaded(XGlo,XReg)) OpEn = OpEn + 1.0 end if end do RegKept = nint (OpEn) if (OpEn.GE.1) then OpMean = OpTot / OpEn OpStDev = (OpSqTot / OpEn) - (OpMean ** 2) OpStDev = sqrt (OpStDev) AvMag = OpAbsTot / OpEn end if print "(i4,i6,5e12.4)", XGlo, RegKept, OpTot, OpSqTot, OpMean, OpStDev, AvMag end do end subroutine PrintToScreen !******************************************************************************* ! print extra details to screen subroutine PrintToScreenExtra allocate (ThisGlo(WorkRegN), & Indices(WorkRegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: PrintToScreenExtra: Allocation failure #####" print "(a4,a6,4a12)", "File", " Reg", " MinVal", " MaxVal", " Median", " Mode" do XGlo = 1, (XGloFree-1) MinVal = 100000.0 MaxVal = -100000.0 Median = MissVal Mode = MissVal OpEn = 0.0 OpTot = 0.0 do XReg = 1, WorkRegN ThisGlo(XReg) = GloLoaded(XGlo,XReg) if (GloLoaded(XGlo,XReg).NE.MissVal) then if (GloLoaded(XGlo,XReg).GT.MaxVal) MaxVal = GloLoaded(XGlo,XReg) if (GloLoaded(XGlo,XReg).LT.MinVal) MinVal = GloLoaded(XGlo,XReg) OpEn = OpEn + 1.0 OpTot = OpTot + GloLoaded(XGlo,XReg) end if end do Median = MedianValue (WorkRegN,ThisGlo) Mode = (OpTot / OpEn) - (3 * ( (OpTot / OpEn) - Median ) ) RegKept = nint (OpEn) print "(i4,i6,4e12.4)", XGlo, RegKept, MinVal, MaxVal, Median, Mode end do deallocate (ThisGlo,Indices, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: PrintToScreenExtra: Deallocation failure #####" end subroutine PrintToScreenExtra !******************************************************************************* ! write region details to log file subroutine WriteRegLog do XReg = 1, WorkRegN write (99,'(i6,a1,a20,a1,i6,e12.5)'), XReg, ' ', WorkRegNames(XReg), ' ', & WorkRegSizes(XReg), GloLoaded (UseGlo(1),XReg) end do end subroutine WriteRegLog !******************************************************************************* ! write region details to the screen subroutine WriteRegScreen print '(a6,a1,a20,a1,a6,a12)', ' Index', ' ', ' Region', ' ', & ' Boxes', ' Value' do XReg = 1, WorkRegN print '(i6,a1,a20,a1,i6,f12.4)', XReg, ' ', WorkRegNames(XReg), ' ', & WorkRegSizes(XReg), GloLoaded (UseGlo(1),XReg) end do end subroutine WriteRegScreen !******************************************************************************* end program CompareGlo2