! seqgrim.f90 ! pgf90 -Mstandard -Minfo -fast -Mscalarsse -Mvect=sse -Mflushz ! -o ./../grim/seqgrim time.f90 filenames.f90 grimfiles.f90 annfiles.f90 ! initialmod.f90 sortmod.f90 plainperm.f90 regress.f90 linfiles.f90 ! glofiles.f90 saveperfiles.f90 aggfiles.f90 basicfun.f90 koeppen.f90 ! ./../grim/seqgrim.f90 2> /tyn1/tim/scratch/stderr.txt ! written by Tim Mitchell on 30.03.01 ! last modified on 10.01.02 ! it is designed to be run using Comms defined using a specification file, ! written in SetUpSeqGrim program SeqGrim use Time use FileNames use GrimFiles use AnnFiles use InitialMod use SortMod use PlainPerm use Regress use LinFiles use GloFiles use SavePerFiles use AggFiles use BasicFun use Koeppen implicit none ! ####################### character (len=80), parameter :: SpecFile="./../../../code/f90/grim/_ref/130.ops" real, pointer, dimension (:,:,:) :: OperA, OperB, OperC, OperD, OperK real, pointer, dimension (:,:,:) :: Grim1, Grim2, Grim3, Grim4, Grim5, Grim6 real, pointer, dimension (:,:,:) :: GrimXtra real, pointer, dimension (:,:) :: GridWeights, WeightsXtra, LinData real, pointer, dimension (:,:) :: MonthData,SeasonData,MonthStDev,SeasonStDev real, pointer, dimension (:,:) :: MonthTemp,MonthPrec real, pointer, dimension (:) :: CommKay, VecA, VecB, VecC, VecD, GloSlice real, pointer, dimension (:) :: RegBoreal,RegWeights,GloWeights,AnnualData,AnnualStDev real, dimension (12) :: BoxTemp,BoxPrec real, dimension (4) :: Bounds, FileBounds integer, pointer, dimension (:,:) :: MapIDLReg ! shape of IDL mapping arrays integer, pointer, dimension (:) :: RegSizes ! region sizes + reg-->raw integer, pointer, dimension (:,:) :: CommOp, Grid, FileGrid, MonLen integer, pointer, dimension (:) :: YearAD, FileYearAD character (len=80), pointer, dimension (:,:) :: CommFile, CommInfo character (len=80), pointer, dimension (:) :: FileLineNames,RegFilePaths character (len=20), pointer, dimension (:) :: RegNames !names of individual regions character (len=09), pointer, dimension (:) :: ColTitles character (len= 2), dimension (12) :: MonthName = (/'01','02','03','04','05','06',& '07','08','09','10','11','12'/) character (len= 3), dimension (4) :: SeasonName = (/'MAM','JJA','SON','DJF'/) real, parameter :: MissVal = -999.0 real, parameter :: MissAccept = 10.0 integer, parameter :: SeasonN = 4 character (len=80), parameter :: Blank = "" logical :: Boreal,QIntercept real :: OpTotSq, OpTot, OpEn, OpMiss, OpMean, OpThresh, OpValid, OpBelow, OpAbove real :: FileFactor, LSRAye,LSRBee,LSRPea,LSRAre,LSREnn, NorthSouth,BoxLat integer :: AllocStat, CheckGrid integer :: YearN, MonthN, BoxN, ExeN, WyeN, ExecN, ArrayN, CommN, FileYearN, RegN integer :: XYear, XMonth, XBox, XExe, XWye, XExec, XArray, XComm, XElement, XPerYear, XBound, XSeason integer :: XFileYear, XMasterYear, XReg, XRegCheck, XLetter, XExeNear,XWyeNear integer :: AStart,AEnd,BStart,BEnd,XAyear,XBYear integer :: SuffixStart, FileSubBeg, InfoSubBeg, RegNameLen, KopNumb, QMeanSum integer :: PerYear0, PerYear1, YearAD0, YearAD1, FileYear0, FileYear1, MasterYear0, MasterYear1 integer :: ThisMonth, ThisYear, NoZip, TotA,TotB,TotC,TotD, Operate, Year0,Year1 character (len=80) :: FileInfo,FilePath,FileVariable,GridFilePath,GloFile,GloInfo,GenericFile,SaveVariName character (len=80) :: Stem,Tip,ExtraStr,GivenFile,InfoLine character (len=20) :: RegName,LineFormat character (len=40) :: RegTitle character (len=30) :: KopName character (len= 4) :: FileSuffix, SaveSuffix character (len= 3) :: KopAcro !******************************************************************************* call Initialise call Main call Finalise contains !******************************************************************************* subroutine Initialise open (99,file="./../../../scratch/log-seqgrim.dat",access="sequential", & form="formatted",status="replace",action="write") nullify (OperA,OperB,OperC,OperD,OperK) nullify (Grim1,Grim2,Grim3,Grim4,Grim5,Grim6) nullify (GrimXtra,LinData,CommKay,VecA,VecB,VecC) nullify (CommOp,Grid,FileGrid,YearAD,FileYearAD) nullify (CommFile,CommInfo,FileLineNames) print* print*, " > ***** SeqGrim: performs pre-determined sequence of grim ops *****" print* print "(2a)", " > ", trim(SpecFile) print* call LoadSpec if (ArrayN.GE.1.AND.AllocStat.EQ.0) then allocate (Grim1 (YearN,MonthN,BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Initialise: Allocation failure: Grim1 #####" if (ArrayN.GE.2.AND.AllocStat.EQ.0) then allocate (Grim2 (YearN,MonthN,BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Initialise: Allocation failure: Grim2 #####" if (ArrayN.GE.3.AND.AllocStat.EQ.0) then allocate (Grim3 (YearN,MonthN,BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Initialise: Allocation failure: Grim3 #####" if (ArrayN.GE.4.AND.AllocStat.EQ.0) then allocate (Grim4 (YearN,MonthN,BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Initialise: Allocation failure: Grim4 #####" if (ArrayN.GE.5.AND.AllocStat.EQ.0) then allocate (Grim5 (YearN,MonthN,BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Initialise: Allocation failure: Grim5 #####" if (ArrayN.GE.6.AND.AllocStat.EQ.0) then allocate (Grim6 (YearN,MonthN,BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Initialise: Allocation failure: Grim6 #####" end if end if end if end if end if end if end subroutine Initialise !******************************************************************************* subroutine LoadSpec write (99,"(a)"), "subroutine LoadSpec" open (1,file=SpecFile,status="old",access="sequential",form="formatted",action="read") read (1,"(5i9)"), YearN, MonthN, BoxN, ExeN, WyeN read (1,"(5i9)"), ExecN, ArrayN, CommN, YearAD0, YearAD1 read (1,"(4f9.2)"), (Bounds(XBound), XBound=1,4) print*, " > Basic specifications: " print "(a13,i4,a11,i2,a11,i6,a10,i4,a9,i4)", " > Years = ", YearN, ", Months = ", MonthN, & ", Domain = ", BoxN, ", Longs = ", ExeN, ", Lats = ", WyeN print "(a18,i2,a11,i1,a13,i2,a11,i4,a1,i4)", " > Executions = ", ExecN, ", Arrays = ", ArrayN, & ", Commands = ", CommN, ", Period = ", YearAD0, "-", YearAD1 allocate (CommOp (CommN,5), & CommKay (CommN), & CommFile (CommN,ExecN), & CommInfo (CommN,ExecN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadSpec: Allocation failure: Comm* #####" write (99,"(f10.2)") MissVal write (99,"(a)") "SeqGrim : data found within comms file." do XComm = 1, CommN read (1,"(5i9,f9.2)"), (CommOp(XComm,XElement), XElement=1,5), CommKay(XComm) do XExec = 1, ExecN read (1,"(a80)"), CommFile(XComm,XExec) read (1,"(a80)"), CommInfo(XComm,XExec) end do end do write (99,"(a)") "SeqGrim : data found within comms file. END." allocate (YearAD (YearN), & Grid (ExeN,WyeN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadSpec: Allocation failure: G+YAD #####" do XExe = 1, ExeN do XWye = 1, WyeN read (1,"(i10)"), Grid(XExe,XWye) end do end do close (1) do XYear = 1, YearN YearAD(XYear) = YearAD0 + XYear - 1 end do end subroutine LoadSpec !******************************************************************************* subroutine Main do XExec = 1, ExecN print* call ResetAll call FindVariable do XComm = 1, CommN if (CommOp(XComm,1).EQ.-1) then print "(a,i1)", " > Resetting: ", CommOp(XComm,2) call ResetGrim else if (CommOp(XComm,1).EQ. 0) then print "(a,i1)", " > Loading into: ", CommOp(XComm,2) call GrabGrim else if (CommOp(XComm,1).EQ. 1) then print "(a,i1)", " > Loading single year into: ", CommOp(XComm,2) call GrabGrimYear else if (CommOp(XComm,1).EQ. 2) then print "(a,i1)", " > Loading .lin into: ", CommOp(XComm,2) call GrabLin else if (CommOp(XComm,1).EQ. 3) then call GrabAnn print "(a,i2,a,i1,a,i3,2(a,i4))", " > Loaded .ann (col ", CommOp(XComm,4), ") into: ", CommOp(XComm,2), & "; VALID:", TotA, "; COMMON: ",YearAD(AStart),"-",YearAD(AEnd) else if (CommOp(XComm,1).EQ. 4) then print "(a,i1,2(a,i4))", " > Loading into: ", CommOp(XComm,2), " period=",CommOp(XComm,4),& "-", CommOp(XComm,5) call GrabGrim else if (CommOp(XComm,1).EQ.10) then call OpClim print "(a,i1,a,i4,a1,i4,a,i1)", " > Climatology: ", CommOp(XComm,2), " = ", CommOp(XComm,4), "-", & CommOp(XComm,5), " mean from ", CommOp(XComm,3) else if (CommOp(XComm,1).EQ.11) then call OpGloAv print "(a,i1,a,i1)", " > Global mean: ", CommOp(XComm,2), " = average at each year,month from ", & CommOp(XComm,3) else if (CommOp(XComm,1).EQ.12) then call OpAnnAv print "(a,i1,a,i1)", " > Annual mean: ", CommOp(XComm,2), " = average at each year,box from ", & CommOp(XComm,3) else if (CommOp(XComm,1).EQ.13) then call OpAnomalise if (CommOp(XComm,3).EQ.0) then print "(2(a,i1),2(a,i4),2(a,i9))", " > Anomalise: ", CommOp(XComm,2), " = ", & CommOp(XComm,2), " minus the mean of ", CommOp(XComm,4), & "-", CommOp(XComm,5), " valid=", TotA, ", miss=", TotB else print "(2(a,i1),2(a,i4),2(a,i9))", " > Anomalise: ", CommOp(XComm,2), " = ", & CommOp(XComm,2), " minus the mean of ", CommOp(XComm,4), & "-", CommOp(XComm,5), " valid=", TotA, ", igno=", TotC end if else if (CommOp(XComm,1).EQ.14) then if (CommOp(XComm,5).EQ.1) ExtraStr=" with missvals replaced" if (CommOp(XComm,5).EQ.2) ExtraStr=" with missvals retained" print "(a,i1,a,i1,a,i3,2a)", " > Smooth: ", CommOp(XComm,2), " = ", CommOp(XComm,3), & " smoothed at ", CommOp(XComm,4), " years", trim(ExtraStr) call OpSmooth print "(a,i10,a,i10)", " > VALID: ", TotA, " = ", TotB else if (CommOp(XComm,1).EQ.15) then call OpConvert print "(a,i1,a,i1,a,i5,a,i5,a,i9)", " > Convert: ", CommOp(XComm,2), " = ", CommOp(XComm,3), & " but ", CommOp(XComm,4), "=>", CommOp(XComm,5), " ; changed: ", TotA else if (CommOp(XComm,1).EQ.16) then call OpMask print "(a,i1,a,i5,a,i1,a,f8.3,a,i9)", " > Where ", CommOp(XComm,2), "=", CommOp(XComm,4), & ", ", CommOp(XComm,3), "=", CommKay(XComm), " ; changed: ", TotA else if (CommOp(XComm,1).EQ.17) then call OpMaskRel print "(a,i1,a,i2,3(a,i1),a,i9)", " > Where ", CommOp(XComm,2), "[rel=", & nint(CommKay(XComm)), "]", CommOp(XComm,5), & ", ", CommOp(XComm,3), "=", CommOp(XComm,4), " ; changed: ", TotA else if (CommOp(XComm,1).EQ.18) then call OpMaskTransfer print "(a,i1,a,f8.3,a,i1,a,i5,a,i9)", " > Where ", CommOp(XComm,2), "=", CommKay(XComm), & ", ", CommOp(XComm,3), "=", CommOp(XComm,4), " ; changed: ", TotA else if (CommOp(XComm,1).EQ.19) then call OpMaskRelConstant print "(a,i1,a,i2,a,f8.3,a,i1,a,f8.3,a,i9)", " > Where ", CommOp(XComm,2), "[rel=", & CommOp(XComm,5), "]", CommKay(XComm), & ", ", CommOp(XComm,3), "=", CommKay(XComm), " ; changed: ", TotA else if (CommOp(XComm,1).EQ.20) then if (CommOp(XComm,3).EQ.MissVal) then if (CommOp(XComm,4).NE.CommOp(XComm,5)) then print "(a,i1,a,i1,a,i1)", " > Regressing (y=ax): x=", CommOp(XComm,5), & ", y=", CommOp(XComm,4), ": a=", CommOp(XComm,2) else print "(a,i1,a,i1)", " > Regressing (y=at): y=", CommOp(XComm,4), ": a=", CommOp(XComm,2) end if else if (CommOp(XComm,4).NE.CommOp(XComm,5)) then print "(a,i1,a,i1,a,i1,a,i1)", " > Regressing (y=ax+b): x=", CommOp(XComm,5), & ", y=", CommOp(XComm,4), ": a=", CommOp(XComm,2), ": b=", CommOp(XComm,3) else print "(a,i1,a,i1,a,i1)", " > Regressing (y=at+b): y=", CommOp(XComm,4), & ": a=", CommOp(XComm,2), ": b=", CommOp(XComm,3) end if end if call OpLSR print "(a,3i10)", " > VALID (x,y,a): ", TotC,TotD,TotA else if (CommOp(XComm,1).EQ.21) then print "(a,i1)", " > Putting month lengths into: ", CommOp(XComm,2) call GrabMonLen else if (CommOp(XComm,1).EQ.22) then print "(a,i1,a,i1,a,i5,a,i5)", " > Placing ", CommOp(XComm,3), " into ", CommOp(XComm,2), & " with range truncated to ", CommOp(XComm,4), " - ", CommOp(XComm,5) call OpTruncate else if (CommOp(XComm,1).EQ.30) then call OpGrimKay print "(3(a,i1),2(a,i10),a)", " > Operating: ", CommOp(XComm,2), " = f(", CommOp(XComm,3), & "): op ", CommOp(XComm,4), "; VALID: ",TotA,"=f(",TotB,")" else if (CommOp(XComm,1).EQ.31) then call OpGrimGrim print "(4(a,i1),3(a,i10),a)", " > Operating: ", CommOp(XComm,2), " = f(", CommOp(XComm,3), & ",", CommOp(XComm,5), "): op ", CommOp(XComm,4), & "; VALID: ",TotA,"=f(",TotB,",",TotC,")" else if (CommOp(XComm,1).EQ.32) then call OpSetToKay print "(a,i1,a,f7.2)", " > Setting: ", CommOp(XComm,2), "=", CommKay(XComm) else if (CommOp(XComm,1).EQ.33) then call OpGrimGrimExt print "(4(a,i1),3(a,i10),a)", " > Operating: ", CommOp(XComm,2), " = f(", CommOp(XComm,3), & ",", 0, "): op ", CommOp(XComm,4), & "; VALID: ",TotA,"=f(",TotB,",",TotC,")" else if (CommOp(XComm,1).EQ.43) then print "(a,i1)", " > Saving from: ", CommOp(XComm,2) call DumpGrim else if (CommOp(XComm,1).EQ.44) then print "(a,i4,a1,i4,a,i1)", " > Saving period (", CommOp(XComm,4), "-", CommOp(XComm,5), & ") from: ", CommOp(XComm,2) call DumpGrimPer else if (CommOp(XComm,1).EQ.45) then if (CommOp(XComm,4).EQ.1) print "(a,i4,a,i1,a)", " > Saving year ", CommOp(XComm,3), & " to .glo from ", CommOp(XComm,2), ": annual moment" if (CommOp(XComm,4).EQ.2) print "(a,i4,a,i1,a)", " > Saving year ", CommOp(XComm,3), & " to .glo from ", CommOp(XComm,2), ": seasonal moments" if (CommOp(XComm,4).EQ.3) print "(a,i4,a,i1,a)", " > Saving year ", CommOp(XComm,3), & " to .glo from ", CommOp(XComm,2), ": monthly values" call DumpGlo else if (CommOp(XComm,1).EQ.46) then RegName = "" ! all this is to get RegName=blank and SaveVariName GenericFile = CommFile(XComm,XExec) SuffixStart = index(GenericFile,".per") GenericFile = GenericFile(1:(SuffixStart-1)) SaveSuffix = GetFileSuffix (GenericFile) call CheckVariSuffix (SaveSuffix,SaveVariName,FileFactor) print "(a,i6,a,i1)", " > Saving box ", CommOp(XComm,3), " to .per from ", CommOp(XComm,2) call PointOperA ! don't alter without first understanding why this is here, from option 7 call DumpDotPer nullify (OperA) ! as above else if (CommOp(XComm,1).EQ.47) then print "(a,i1)", " > Saving each region to .per from ", CommOp(XComm,2) call DumpRegPer else if (CommOp(XComm,1).EQ.48) then print "(a,2(i4,a),i1)", " > Saving ", CommOp(XComm,3), "-", CommOp(XComm,5), & " to .agg from ", CommOp(XComm,2) call DumpAgg else if (CommOp(XComm,1).EQ.49) then print "(a,i1,a,f8.2,a)", " > Counting ", CommOp(XComm,2), "=", CommKay(XComm), " to .glo" call CountOccurrences else if (CommOp(XComm,1).EQ.50) then print "(a,i1)", " > Over-riding auto: setting QMeanSum = ", CommOp(XComm,2) QMeanSum = CommOp(XComm,2) else if (CommOp(XComm,1).EQ.51) then call InterpolateMissing print "(2(a,i1),2(a,i9))", " > Interpol missing ", CommOp(XComm,2), "=", CommOp(XComm,3), & ": done=", TotA, ", fail=", TotB else if (CommOp(XComm,1).EQ.52) then call MakeKoeppen print "(2(a,i1),2(a,i9))", " > Koeppen from ", CommOp(XComm,2), "=temp ", CommOp(XComm,3), & "=prec ; done=", TotA, ", fail=", TotB end if end do end do end subroutine Main !******************************************************************************* subroutine ResetAll if (associated(Grim1)) Grim1=MissVal if (associated(Grim2)) Grim2=MissVal if (associated(Grim3)) Grim3=MissVal if (associated(Grim4)) Grim4=MissVal if (associated(Grim5)) Grim5=MissVal if (associated(Grim6)) Grim6=MissVal end subroutine ResetAll !******************************************************************************* subroutine FindVariable XComm = 0 ; FileSuffix = "" ; FileVariable = "" ; FileFactor = MissVal do XComm = XComm + 1 GivenFile = CommFile(XComm,XExec) if (GivenFile.NE."") then SuffixStart = index(GivenFile,'.',.TRUE.) if (GivenFile(SuffixStart:(SuffixStart+1)).EQ.".Z") then GivenFile(SuffixStart:(SuffixStart+1)) = " " SuffixStart = index(GivenFile,'.',.TRUE.) end if if (GivenFile(SuffixStart:(SuffixStart+3)).EQ.".lin".OR. & GivenFile(SuffixStart:(SuffixStart+3)).EQ.".ann") then GivenFile(SuffixStart:(SuffixStart+3)) = " " SuffixStart = index(GivenFile,'.',.TRUE.) end if if (SuffixStart.GT.0) then FilePath = CommFile(XComm,XExec) FileSuffix = FilePath(SuffixStart:(SuffixStart+3)) call CheckVariSuffix (FileSuffix,FileVariable,FileFactor) end if end if if (XComm.EQ.CommN.OR.FileVariable.NE."") exit end do if (FileVariable.EQ."") FileVariable = "unknown" print "(2a)", " > Variable: ", trim(FileVariable) if (FileSuffix.EQ.".pre".OR.FileSuffix.EQ.".frs".OR.FileSuffix.EQ.".wet") then QMeanSum = 2 else QMeanSum = 0 end if end subroutine FindVariable !******************************************************************************* ! command = -1 subroutine ResetGrim if (CommOp(XComm,2).EQ.1) then Grim1 = MissVal else if (CommOp(XComm,2).EQ.2) then Grim2 = MissVal else if (CommOp(XComm,2).EQ.3) then Grim3 = MissVal else if (CommOp(XComm,2).EQ.4) then Grim4 = MissVal else if (CommOp(XComm,2).EQ.5) then Grim5 = MissVal else if (CommOp(XComm,2).EQ.6) then Grim6 = MissVal end if end subroutine ResetGrim !******************************************************************************* ! command=0 or =4 ! if this fails under =4 at LoadGrim, it may be because the spec period is inappropriate subroutine GrabGrim call PointOperA if (CommOp(XComm,1).EQ.0) then call LoadGrim (OperA,FileGrid,FileYearAD,FileBounds,FileInfo,CommFile(XComm,XExec)," ",FileSuffix,& MasterYearAD=YearAD) else if (CommOp(XComm,1).EQ.4) then call LoadGrim (OperA,FileGrid,FileYearAD,FileBounds,FileInfo,CommFile(XComm,XExec)," ",FileSuffix,& MasterYearAD=YearAD,OverRide=CommOp(XComm,4)) end if call GridMismatch nullify (OperA) deallocate (FileGrid,FileYearAD,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GrabGrim: Deallocation failure: File* #####" end subroutine GrabGrim !******************************************************************************* ! command = 1 subroutine GrabGrimYear call PointOperA call LoadGrim (GrimXtra,FileGrid,FileYearAD,FileBounds,FileInfo,CommFile(XComm,XExec)," ",FileSuffix) call GridMismatch if (size(FileYearAD).NE.1) print*, " > ##### ERROR: file period > 1 year #####" deallocate (FileGrid,FileYearAD,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GrabGrimYear: Deallocation failure: File* #####" do XMonth = 1, MonthN do XBox = 1, BoxN do XYear = 1, YearN OperA(XYear,XMonth,XBox) = GrimXtra(1,XMonth,XBox) end do end do end do nullify (OperA) deallocate (GrimXtra,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GrabGrimYear: Deallocation failure: GrimXtra #####" end subroutine GrabGrimYear !******************************************************************************* ! command = 2 subroutine GrabLin call PointOperA call LoadLin (CommFile(XComm,XExec),FileYearAD,FileLineNames,LinData) if (size(FileYearAD).NE.YearN) print*, " > ##### ERROR: loaded YearAD wrong length" if (CommOp(XComm,3).EQ.1) then if (FileYearAD(1).NE.YearAD(1)) print*, " > ##### ERROR: loaded YearAD wrong years" else if (CommOp(XComm,3).EQ.2) then ! no check, as the period is allowed to be anything - it is just ignored end if if (size(LinData,1).EQ.1) then do XYear = 1, YearN do XMonth = 1, MonthN do XBox = 1, BoxN OperA(XYear,XMonth,XBox) = LinData(1,XYear) end do end do end do else print*, " > ##### ERROR: GrabLin: LinData size =/ 1 #####" end if nullify (OperA) deallocate (FileYearAD,FileLineNames,LinData,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GrabLin: Deallocation failure #####" end subroutine GrabLin !******************************************************************************* ! command = 3 subroutine GrabAnn call PointOperA call LoadANN (CommFile(XComm,XExec),FileYearAD,ColTitles,LinData) call CommonVecPer (YearAD,FileYearAD,AStart,AEnd,BStart,BEnd) TotA = 0 if (AStart.EQ.-999.OR.BStart.EQ.-999) then print*, " > ##### ERROR: loaded YearAD wrong years #####" else if (size(LinData,2).LT.CommOp(XComm,4)) then print*, " > ##### ERROR: loaded array does not contain desired column #####" else do XAYear = AStart,AEnd XBYear = BStart + XAYear - 1 if (LinData(XBYear,CommOp(XComm,4)).NE.MissVal) TotA=TotA+1 do XMonth = 1, MonthN do XBox = 1, BoxN OperA(XAYear,XMonth,XBox) = LinData(XBYear,CommOp(XComm,4)) end do end do end do end if nullify (OperA) deallocate (FileYearAD,ColTitles,LinData,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GrabAnn: Deallocation failure #####" end subroutine GrabAnn !******************************************************************************* ! command = 10 subroutine OpClim call PointOperA call PointOperB PerYear0 = 0 ; PerYear1 = 0 ; XYear = 0 do XYear = XYear + 1 if (YearAD(XYear).EQ.CommOp(XComm,4)) PerYear0 = XYear if (YearAD(XYear).EQ.CommOp(XComm,5)) PerYear1 = XYear if (PerYear1.GT.0.OR.XYear.EQ.YearN) exit end do OpThresh = real(PerYear1-PerYear0+1) * (MissAccept/100.0) if (PerYear1.GE.PerYear0) then do XBox = 1, BoxN do XMonth = 1, MonthN OpTot = 0.0 ; OpMiss = 0.0 ; OpEn = 0.0 do XYear = PerYear0, PerYear1 if (OperB(XYear,XMonth,XBox).NE.MissVal) then OpTot = OpTot + OperB(XYear,XMonth,XBox) OpEn = OpEn + 1.0 else OpMiss = OpMiss + 1.0 end if end do if (OpEn.GT.0) then OpMean = OpTot / OpEn else ! OpMean = 0.0 OpMean = MissVal end if ! if (OpMiss.LE.OpThresh.AND.OpEn.GT.0) then ! OpMean = OpTot / OpEn ! else ! OpMean = MissVal ! end if do XYear = 1, YearN OperA(XYear,XMonth,XBox) = OpMean end do end do end do end if nullify (OperA,OperB) end subroutine OpClim !******************************************************************************* ! command = 11 subroutine OpGloAv call PointOperA call PointOperB do XYear = 1, YearN do XMonth = 1, MonthN OpTot = 0.0 ; OpMiss = 0.0 ; OpEn = 0.0 do XBox = 1, BoxN if (OperB(XYear,XMonth,XBox).NE.MissVal) then OpTot = OpTot + OperB(XYear,XMonth,XBox) OpEn = OpEn + 1.0 else OpMiss = OpMiss + 1.0 end if end do if (OpMiss.EQ.0.AND.OpEn.GT.0) then OpMean = OpTot / OpEn else OpMean = MissVal end if do XBox = 1, BoxN OperA(XYear,XMonth,XBox) = OpMean end do end do end do nullify (OperA,OperB) end subroutine OpGloAv !******************************************************************************* ! command = 12 subroutine OpAnnAv call PointOperA call PointOperB do XYear = 1, YearN do XBox = 1, BoxN OpTot = 0.0 ; OpMiss = 0.0 ; OpEn = 0.0 do XMonth = 1, MonthN if (OperB(XYear,XMonth,XBox).NE.MissVal) then OpTot = OpTot + OperB(XYear,XMonth,XBox) OpEn = OpEn + 1.0 else OpMiss = OpMiss + 1.0 end if end do if (OpMiss.EQ.0.AND.OpEn.GT.0) then OpMean = OpTot / OpEn else OpMean = MissVal end if do XMonth = 1, MonthN OperA(XYear,XMonth,XBox) = OpMean end do end do end do nullify (OperA,OperB) end subroutine OpAnnAv !******************************************************************************* ! command = 13 subroutine OpAnomalise call PointOperA PerYear0 = 0 ; PerYear1 = 0 ; XYear = 0 do XYear = XYear + 1 if (YearAD(XYear).EQ.CommOp(XComm,4)) PerYear0 = XYear if (YearAD(XYear).EQ.CommOp(XComm,5)) PerYear1 = XYear if (PerYear1.GT.0.OR.XYear.EQ.YearN) exit end do OpThresh = real(PerYear1-PerYear0+1) * (MissAccept/100.0) TotA=0 ; TotB=0 ; TotC=0 if (PerYear1.GT.PerYear0) then allocate (MonthData(MonthN,BoxN),stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Allocation failure: OpAnomalise #####" do XBox = 1, BoxN ! calc climatology do XMonth = 1, MonthN OpTot = 0.0 ; OpMiss = 0.0 ; OpEn = 0.0 do XYear = PerYear0, PerYear1 if (OperA(XYear,XMonth,XBox).NE.MissVal) then OpTot = OpTot + OperA(XYear,XMonth,XBox) OpEn = OpEn + 1.0 else OpMiss = OpMiss + 1.0 end if end do if (OpMiss.LE.OpThresh) then OpMean = OpTot / OpEn else OpMean = MissVal end if MonthData(XMonth,XBox) = OpMean end do end do do XMonth = 1, MonthN do XBox = 1, BoxN if (MonthData(XMonth,XBox).NE.MissVal) then do XYear = 1, YearN if (OperA(XYear,XMonth,XBox).NE.MissVal) then OperA(XYear,XMonth,XBox) = OperA(XYear,XMonth,XBox) - MonthData(XMonth,XBox) TotA = TotA + 1 end if end do else if (CommOp(XComm,3).EQ.1) then do XYear = 1, YearN TotC = TotC + 1 end do else do XYear = 1, YearN OperA(XYear,XMonth,XBox) = MissVal TotB = TotB + 1 end do end if end if end do end do deallocate (MonthData,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Deallocation failure: OpAnomalise #####" end if nullify (OperA) end subroutine OpAnomalise !******************************************************************************* ! command = 14 subroutine OpSmooth call PointOperA call PointOperB allocate (VecA(YearN),VecB(YearN),VecC(YearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Allocation failure: OpSmooth: Vec* #####" TotA=0 ; TotB=0 do XMonth = 1, MonthN do XBox = 1, BoxN do XYear = 1, YearN VecB(XYear) = OperB(XYear,XMonth,XBox) if (VecB(XYear).NE.MissVal) TotB=TotB+1 end do VecA=MissVal ; VecC=MissVal call GaussSmooth (YearN,CommOp(XComm,4),CommOp(XComm,5),VecB,VecA,VecC) do XYear = 1, YearN if (VecA(XYear).NE.MissVal) TotA=TotA+1 OperA(XYear,XMonth,XBox) = VecA(XYear) end do end do end do deallocate (VecA,VecB,VecC, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Deallocation failure: OpSmooth: Vec* #####" nullify (OperA,OperB) end subroutine OpSmooth !******************************************************************************* ! command = 15 subroutine OpConvert call PointOperA call PointOperB TotA=0 do XMonth = 1, MonthN do XBox = 1, BoxN do XYear = 1, YearN if (OperB(XYear,XMonth,XBox).EQ.real(CommOp(XComm,4))) then OperA(XYear,XMonth,XBox) = real(CommOp(XComm,5)) TotA=TotA+1 else OperA(XYear,XMonth,XBox) = OperB(XYear,XMonth,XBox) end if end do end do end do nullify (OperA,OperB) end subroutine OpConvert !******************************************************************************* ! command = 16 subroutine OpMask call PointOperA call PointOperB TotA=0 do XMonth = 1, MonthN do XBox = 1, BoxN do XYear = 1, YearN if (OperA(XYear,XMonth,XBox).EQ.real(CommOp(XComm,4))) then OperB(XYear,XMonth,XBox) = CommKay(XComm) TotA=TotA+1 end if end do end do end do nullify (OperA,OperB) end subroutine OpMask !******************************************************************************* ! command = 17 subroutine OpMaskRel call PointOperA call PointOperB call PointOperC call PointOperD TotA=0 ; Operate=nint(CommKay(XComm)) do XMonth = 1, MonthN do XBox = 1, BoxN do XYear = 1, YearN if (OperA(XYear,XMonth,XBox).NE.MissVal.AND.OperC(XYear,XMonth,XBox).NE.MissVal) then if (Operate.EQ.-3.AND.OperA(XYear,XMonth,XBox).NE.OperC(XYear,XMonth,XBox)) then OperB(XYear,XMonth,XBox)=OperD(XYear,XMonth,XBox) ; TotA=TotA+1 else if (Operate.EQ.-2.AND.OperA(XYear,XMonth,XBox).LT.OperC(XYear,XMonth,XBox)) then OperB(XYear,XMonth,XBox)=OperD(XYear,XMonth,XBox) ; TotA=TotA+1 else if (Operate.EQ.-1.AND.OperA(XYear,XMonth,XBox).LE.OperC(XYear,XMonth,XBox)) then OperB(XYear,XMonth,XBox)=OperD(XYear,XMonth,XBox) ; TotA=TotA+1 else if (Operate.EQ. 0.AND.OperA(XYear,XMonth,XBox).EQ.OperC(XYear,XMonth,XBox)) then OperB(XYear,XMonth,XBox)=OperD(XYear,XMonth,XBox) ; TotA=TotA+1 else if (Operate.EQ. 1.AND.OperA(XYear,XMonth,XBox).GE.OperC(XYear,XMonth,XBox)) then OperB(XYear,XMonth,XBox)=OperD(XYear,XMonth,XBox) ; TotA=TotA+1 else if (Operate.EQ. 2.AND.OperA(XYear,XMonth,XBox).GT.OperC(XYear,XMonth,XBox)) then OperB(XYear,XMonth,XBox)=OperD(XYear,XMonth,XBox) ; TotA=TotA+1 end if end if end do end do end do nullify (OperA,OperB,OperC,OperD) end subroutine OpMaskRel !******************************************************************************* ! command = 18 subroutine OpMaskTransfer call PointOperA call PointOperB call PointOperD TotA=0 do XBox=1, BoxN do XMonth = 1, MonthN do XYear = 1, YearN if (OperA(XYear,XMonth,XBox).EQ.CommKay(XComm)) then OperB(XYear,XMonth,XBox) = OperD(XYear,XMonth,XBox) TotA=TotA+1 end if end do end do end do nullify (OperA,OperB,OperD) end subroutine OpMaskTransfer !******************************************************************************* ! command = 19 subroutine OpMaskRelConstant call PointOperA call PointOperB TotA=0 ; Operate=CommOp(XComm,5) do XBox = 1, BoxN do XMonth = 1, MonthN do XYear = 1, YearN if (OperA(XYear,XMonth,XBox).NE.MissVal.OR.CommOp(XComm,4).EQ.1) then if (Operate.EQ.-3.AND.OperA(XYear,XMonth,XBox).NE.CommKay(XComm)) then OperB(XYear,XMonth,XBox)=CommKay(XComm) ; TotA=TotA+1 else if (Operate.EQ.-2.AND.OperA(XYear,XMonth,XBox).LT.CommKay(XComm)) then OperB(XYear,XMonth,XBox)=CommKay(XComm) ; TotA=TotA+1 else if (Operate.EQ.-1.AND.OperA(XYear,XMonth,XBox).LE.CommKay(XComm)) then OperB(XYear,XMonth,XBox)=CommKay(XComm) ; TotA=TotA+1 else if (Operate.EQ. 0.AND.OperA(XYear,XMonth,XBox).EQ.CommKay(XComm)) then OperB(XYear,XMonth,XBox)=CommKay(XComm) ; TotA=TotA+1 else if (Operate.EQ. 1.AND.OperA(XYear,XMonth,XBox).GE.CommKay(XComm)) then OperB(XYear,XMonth,XBox)=CommKay(XComm) ; TotA=TotA+1 else if (Operate.EQ. 2.AND.OperA(XYear,XMonth,XBox).GT.CommKay(XComm)) then OperB(XYear,XMonth,XBox)=CommKay(XComm) ; TotA=TotA+1 end if end if end do end do end do nullify (OperA,OperB) end subroutine OpMaskRelConstant !******************************************************************************* ! command = 20 subroutine OpLSR if (CommOp(XComm,3).EQ.MissVal) then QIntercept=.FALSE. else QIntercept=.TRUE. end if call PointOperA call PointOperC call PointOperD if (QIntercept) call PointOperB if (CommKay(XComm).NE.MissVal) call PointOperK allocate (VecC(YearN),VecD(YearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Allocation failure: OpLSR: Vec* #####" TotA=0 ; TotC=0 ; TotD=0 do XMonth = 1, MonthN do XBox = 1, BoxN do XYear = 1, YearN if (CommOp(XComm,4).EQ.CommOp(XComm,5)) then VecC(XYear) = real (YearAD(XYear)) else VecC(XYear) = OperC(XYear,XMonth,XBox) end if VecD(XYear) = OperD(XYear,XMonth,XBox) if (VecC(XYear).NE.MissVal) TotC=TotC+1 if (VecD(XYear).NE.MissVal) TotD=TotD+1 end do if (QIntercept) then ! y=ax+b ! call LinearLSRVec (VecC,VecD,LSRBee,LSRAye,LSRPea) call RegressVectors (VecC,VecD,LSRBee,LSRAye,LSRAre,LSREnn,5) if (LSRAye.NE.MissVal) TotA=TotA+YearN do XYear = 1, YearN OperA(XYear,XMonth,XBox) = LSRAye OperB(XYear,XMonth,XBox) = LSRBee ! if (CommKay(XComm).NE.MissVal) OperK(XYear,XMonth,XBox) = LSRPea if (CommKay(XComm).NE.MissVal) OperK(XYear,XMonth,XBox) = LSRAre end do else ! y=ax call LinearLSRZeroVec (VecC,VecD,LSRAye) if (LSRAye.NE.MissVal) TotA=TotA+YearN do XYear = 1, YearN OperA(XYear,XMonth,XBox) = LSRAye end do end if end do end do deallocate (VecC,VecD, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Deallocation failure: OpLSR: Vec* #####" nullify (OperA,OperC,OperD) if (CommOp(XComm,3).NE.MissVal) nullify (OperB) end subroutine OpLSR !******************************************************************************* ! command = 21 subroutine GrabMonLen allocate (MonLen(YearN,MonthN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Alloc: GrabMonLen #####" call GetMonthLengths (YearAD,MonLen) call PointOperA do XYear = 1, YearN do XMonth = 1, MonthN do XBox = 1, BoxN OperA(XYear,XMonth,XBox) = real(MonLen(XYear,XMonth)) end do end do end do nullify (OperA) deallocate (MonLen, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GrabMonLen: dealloc #####" end subroutine GrabMonLen !******************************************************************************* ! command = 22 subroutine OpTruncate call PointOperA call PointOperB OpBelow = 0.0 ; OpAbove = 0.0 ; OpMiss = 0.0 do XYear = 1, YearN do XMonth = 1, MonthN do XBox = 1, BoxN if (OperB(XYear,XMonth,XBox).NE.MissVal) then if (CommOp(XComm,4).NE.MissVal) then if (OperB(XYear,XMonth,XBox).GE.CommOp(XComm,4)) then OperA(XYear,XMonth,XBox) = OperB(XYear,XMonth,XBox) else OperA(XYear,XMonth,XBox) = CommOp(XComm,4) OpBelow = OpBelow + 1.0 end if end if if (CommOp(XComm,5).NE.MissVal) then if (OperB(XYear,XMonth,XBox).LE.CommOp(XComm,5)) then OperA(XYear,XMonth,XBox) = OperB(XYear,XMonth,XBox) else OperA(XYear,XMonth,XBox) = CommOp(XComm,5) OpAbove = OpAbove + 1.0 end if end if else OpMiss = OpMiss + 1.0 end if end do end do end do nullify (OperA,OperB) OpTot = YearN * MonthN * BoxN OpValid = OpTot - OpMiss if (OpTot.GT.0.AND.OpValid.GT.0) then OpMiss = 100.0 * OpMiss / OpTot OpBelow = 100.0 * OpBelow / OpValid OpAbove = 100.0 * OpAbove / OpValid else OpMiss = MissVal ; OpBelow = MissVal ; OpAbove = MissVal end if print "(a,f14.1,f8.4)", " > Total data, and % missing: ", OpTot, OpMiss print "(a,2f8.4)", " > Of valid data, % truncated from < and > range: ", OpBelow, OpAbove end subroutine OpTruncate !******************************************************************************* ! command = 30 subroutine OpGrimKay call PointOperA call PointOperB TotA=0 ; TotB=0 ; TotC=0 do XYear = 1, YearN do XMonth = 1, MonthN do XBox = 1, BoxN if (OperB(XYear,XMonth,XBox).NE.MissVal) TotB=TotB+1 OperA(XYear,XMonth,XBox) = OpAwithB (OperB(XYear,XMonth,XBox),CommKay(XComm),CommOp(XComm,4)) if (OperA(XYear,XMonth,XBox).NE.MissVal) TotA=TotA+1 end do end do end do nullify (OperA,OperB) end subroutine OpGrimKay !******************************************************************************* ! command = 31 subroutine OpGrimGrim call PointOperA call PointOperB call PointOperC TotA=0 ; TotB=0 ; TotC=0 do XYear = 1, YearN do XMonth = 1, MonthN do XBox = 1, BoxN if (OperB(XYear,XMonth,XBox).NE.MissVal) TotB=TotB+1 if (OperC(XYear,XMonth,XBox).NE.MissVal) TotC=TotC+1 OperA(XYear,XMonth,XBox) = OpAwithB (OperB(XYear,XMonth,XBox),OperC(XYear,XMonth,XBox),CommOp(XComm,4)) if (OperA(XYear,XMonth,XBox).NE.MissVal) TotA=TotA+1 end do end do end do nullify (OperA,OperB,OperC) end subroutine OpGrimGrim !******************************************************************************* ! command = 32 subroutine OpSetToKay call PointOperA do XYear = 1, YearN do XMonth = 1, MonthN do XBox = 1, BoxN OperA(XYear,XMonth,XBox) = CommKay(XComm) end do end do end do nullify (OperA) end subroutine OpSetToKay !******************************************************************************* ! command = 33 subroutine OpGrimGrimExt call PointOperA call PointOperB call LoadGrim (GrimXtra,FileGrid,FileYearAD,FileBounds,FileInfo,CommFile(XComm,XExec)," ",FileSuffix) call GridMismatch if (size(FileYearAD).NE.1) print*, " > ##### ERROR: file period > 1 year #####" deallocate (FileGrid,FileYearAD,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: OpGrimGrimExt: Deallocation failure: File* #####" TotA=0 ; TotB=0 ; TotC=0 do XYear = 1, YearN do XMonth = 1, MonthN do XBox = 1, BoxN if (OperB(XYear,XMonth,XBox).NE.MissVal) TotB=TotB+1 if (GrimXtra(1,XMonth,XBox).NE.MissVal) TotC=TotC+1 OperA(XYear,XMonth,XBox) = OpAwithB (OperB(XYear,XMonth,XBox),GrimXtra(1,XMonth,XBox),CommOp(XComm,4)) if (OperA(XYear,XMonth,XBox).NE.MissVal) TotA=TotA+1 end do end do end do nullify (OperA,OperB) deallocate (GrimXtra,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: OpGrimGrimExt: Deallocation failure: GrimXtra #####" end subroutine OpGrimGrimExt !******************************************************************************* ! command = 43 subroutine DumpGrim call PointOperA call SaveGrim (OperA,Grid,YearAD,Bounds,CommInfo(XComm,XExec),CommFile(XComm,XExec)," ",FileSuffix,NoZip=1) nullify (OperA) end subroutine DumpGrim !******************************************************************************* ! command = 44 subroutine DumpGrimPer call PointOperA call SaveGrim (OperA,Grid,YearAD,Bounds,CommInfo(XComm,XExec),CommFile(XComm,XExec)," ",& FileSuffix,NoZip=1,SaveYearAD0=CommOp(XComm,4),SaveYearAD1=CommOp(XComm,5)) nullify (OperA) end subroutine DumpGrimPer !******************************************************************************* ! command = 45 subroutine DumpGlo GridFilePath = GetGloRef (ExeN,WyeN) call PointOperA XYear = CommOp(XComm,3) - YearAD(1) + 1 allocate (GloSlice(BoxN),stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGlo: Allocation failure." if (CommOp(XComm,4).EQ.1) then ! save annual mean GloSlice = MissVal do XBox = 1, BoxN OpTot = 0.0 ; OpEn = 0.0 do XMonth = 1, MonthN if (OperA(XYear,XMonth,XBox).NE.MissVal) then OpTot = OpTot + OperA(XYear,XMonth,XBox) OpEn = OpEn + 1.0 end if end do if (OpEn.EQ.MonthN) then if (QMeanSum.EQ.0) GloSlice (XBox) = OpTot / OpEn if (QMeanSum.EQ.2) GloSlice (XBox) = OpTot end if end do call SaveGlo (ExeN,WyeN,BoxN,GridFilePath,CommFile(XComm,XExec),CommInfo(XComm,XExec),GloSlice,Grid) else if (CommOp(XComm,4).EQ.2) then ! save seasonal means do XSeason = 1, 4 ! note that XSeason=1 for MAM FileSubBeg = index(CommFile(XComm,XExec),SeasonName(1)) if (FileSubBeg.GT.0) then GloFile = CommFile(XComm,XExec) GloFile (FileSubBeg:(FileSubBeg+2)) = SeasonName(XSeason) else GloFile = "" end if InfoSubBeg = index(CommInfo(XComm,XExec),SeasonName(1)) if (InfoSubBeg.GT.0) then GloInfo = CommInfo(XComm,XExec) GloInfo (InfoSubBeg:(InfoSubBeg+2)) = SeasonName(XSeason) else GloInfo = "" end if if (GloFile.NE."".AND.GloInfo.NE."") then GloSlice = MissVal do XBox = 1, BoxN OpTot = 0.0 ; OpEn = 0.0 do ThisMonth = (XSeason*3), (2+(XSeason*3)) XMonth = ThisMonth if (XMonth.GT.12) XMonth = XMonth - 12 if (OperA(XYear,XMonth,XBox).NE.MissVal) then OpTot = OpTot + OperA(XYear,XMonth,XBox) OpEn = OpEn + 1.0 end if end do if (OpEn.EQ.3) then if (QMeanSum.EQ.0) GloSlice (XBox) = OpTot / OpEn if (QMeanSum.EQ.2) GloSlice (XBox) = OpTot end if end do call SaveGlo (ExeN,WyeN,BoxN,GridFilePath,GloFile,GloInfo,GloSlice,Grid) end if end do else if (CommOp(XComm,4).EQ.3) then ! save monthly values do XMonth = 1, MonthN FileSubBeg = index(CommFile(XComm,XExec),MonthName(1),.true.) if (FileSubBeg.GT.0) then GloFile = CommFile(XComm,XExec) GloFile (FileSubBeg:(FileSubBeg+1)) = MonthName(XMonth) else GloFile = "" end if InfoSubBeg = index(CommInfo(XComm,XExec),MonthName(1),.true.) if (InfoSubBeg.GT.0) then GloInfo = CommInfo(XComm,XExec) GloInfo (InfoSubBeg:(InfoSubBeg+1)) = MonthName(XMonth) else GloInfo = "" end if if (GloFile.NE."".AND.GloInfo.NE."") then do XBox = 1, BoxN GloSlice (XBox) = OperA(XYear,XMonth,XBox) end do call SaveGlo (ExeN,WyeN,BoxN,GridFilePath,GloFile,GloInfo,GloSlice,Grid) end if end do end if deallocate (GloSlice,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGlo: Deallocation failure." nullify (OperA) end subroutine DumpGlo !******************************************************************************* ! command = 46 ; also called many times from command = 47 subroutine DumpDotPer allocate (MonthData (YearN,MonthN), & SeasonData(YearN,SeasonN), & AnnualData(YearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpDotPer: Allocation failure #####" MonthData = MissVal ; SeasonData = MissVal ; AnnualData = MissVal do XYear = 1, YearN ! fill MonthData do XMonth = 1, MonthN MonthData(XYear,XMonth) = OperA(XYear,XMonth,CommOp(XComm,3)) end do end do do ThisYear = 1, YearN ! fill SeasonData do XSeason = 1, SeasonN ! note that XSeason=1 for MAM OpTot = 0.0 ; OpEn = 0.0 do ThisMonth = (XSeason*3), (2+(XSeason*3)) XMonth = ThisMonth XYear = ThisYear if (XMonth.GT.12) then XMonth = XMonth - 12 ! XYear = XYear + 1 ! command removed to enable single year dump end if if (XYear.LE.YearN) then if (OperA(XYear,XMonth,CommOp(XComm,3)).NE.MissVal) then OpTot = OpTot + OperA(XYear,XMonth,CommOp(XComm,3)) OpEn = OpEn + 1 end if end if end do if (OpEn.EQ.3) then if (QMeanSum.EQ.0) SeasonData(ThisYear,XSeason) = OpTot/OpEn if (QMeanSum.EQ.2) SeasonData(ThisYear,XSeason) = OpTot end if end do end do do XYear = 1, YearN ! fill AnnualData OpTot = 0.0 ; OpEn = 0.0 do XMonth = 1, MonthN if (OperA(XYear,XMonth,CommOp(XComm,3)).NE.MissVal) then OpTot = OpTot + OperA(XYear,XMonth,CommOp(XComm,3)) OpEn = OpEn + 1 end if end do if (OpEn.EQ.MonthN) then if (QMeanSum.EQ.0) AnnualData(XYear) = OpTot/OpEn if (QMeanSum.EQ.2) AnnualData(XYear) = OpTot end if end do LineFormat='(i5,12f8.2,5f8.2)' call SavePER (CommFile(XComm,XExec),YearAD,QMeanSum,Monthly=MonthData,Seasonal=SeasonData,& Annual=AnnualData,CallLineFormat=LineFormat,NoResponse=1) ! ScenHeads=1,CallPoliUnitName=RegName,CallVariableName=SaveVariName) deallocate (MonthData,SeasonData,AnnualData,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpDotPer: Deallocation failure #####" end subroutine DumpDotPer !******************************************************************************* ! command = 47 subroutine DumpRegPer call PointOperA ! before we load up into regions, we point OperA towards the correct grim call RegSelect (nint(MissVal), ExeN, WyeN, (ExeN*WyeN), MapIDLReg, RegSizes, RegNames, & RegTitle, RegN, CommInfo(XComm,1)) call GetWeightArrays allocate (GrimXtra(YearN,MonthN,RegN), & RegFilePaths(RegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpRegPer: Allocation failure #####" GrimXtra = 0.0 ! careful - do not inintialise to MissVal do XExe = 1, ExeN ! iterate around grid do XWye = 1, WyeN ! if the grid cell belongs to a region if (MapIDLReg(XExe,XWye).NE.MissVal) then ! then check if the grid cell is within the grim domain if (Grid(XExe,XWye).NE.MissVal.AND.RegWeights(MapIDLReg(XExe,XWye)).NE.MissVal) then do XYear = 1, YearN ! iterate by year, month do XMonth = 1, MonthN if (OperA(XYear,XMonth,Grid(XExe,XWye)).NE.MissVal) then ! check datum = non-missing if (GrimXtra(XYear,XMonth,MapIDLReg(XExe,XWye)).NE.MissVal) then ! check region = OK thus far GrimXtra(XYear,XMonth,MapIDLReg(XExe,XWye)) = GrimXtra(XYear,XMonth,MapIDLReg(XExe,XWye)) & + (OperA(XYear,XMonth,Grid(XExe,XWye)) & * GridWeights(XExe,XWye)) end if else ! datum=missing, so make region missing GrimXtra(XYear,XMonth,MapIDLReg(XExe,XWye)) = MissVal end if end do end do else do XYear = 1, YearN do XMonth = 1, MonthN GrimXtra(XYear,XMonth,MapIDLReg(XExe,XWye)) = MissVal ! cell=missing, so make region missing end do end do end if end if end do end do do XReg = 1, RegN ! convert from sums to means do XYear = 1, YearN do XMonth = 1, MonthN if (RegWeights(XReg).GT.0.0) then if (GrimXtra(XYear,XMonth,XReg).NE.MissVal) then GrimXtra(XYear,XMonth,XReg) = GrimXtra(XYear,XMonth,XReg) / RegWeights(XReg) else GrimXtra(XYear,XMonth,XReg) = MissVal end if else GrimXtra(XYear,XMonth,XReg) = MissVal end if end do end do end do nullify (OperA) ; OperA => GrimXtra ! we now point OperA towards the region array, ready for call to opt 6 GenericFile = CommFile(XComm,XExec) ! generate region filepaths with correct directory SuffixStart = index(GenericFile,".per") GenericFile = GenericFile(1:(SuffixStart-1)) SaveSuffix = GetFileSuffix (GenericFile) SuffixStart = index(GenericFile,SaveSuffix) call CheckVariSuffix (SaveSuffix,SaveVariName,FileFactor) Stem = GenericFile(1:(SuffixStart-1)) // "." Tip = trim(SaveSuffix) // ".per" call MakeBatch (Stem,Tip,RegNames,RegFilePaths) do XReg = 1, RegN CommOp(XComm,3) = XReg CommFile(XComm,XExec) = RegFilePaths(XReg) RegName = RegNames(XReg) call DumpDotPer end do nullify (OperA) deallocate (MapIDLReg, RegSizes, RegNames, GridWeights, RegWeights, RegBoreal, & GrimXtra, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpRegPer: Deallocation failure #####" end subroutine DumpRegPer !******************************************************************************* ! command = 48 - calcs mean and stdev and dumps separately subroutine DumpAgg call PointOperA ! before we load up into regions, we point OperA towards the correct grim call RegSelect (nint(MissVal), ExeN, WyeN, (ExeN*WyeN), MapIDLReg, RegSizes, RegNames, & RegTitle, RegN, CommInfo(XComm,1)) call GetWeightArrays Year0=CommOp(XComm,3)-YearAD(1)+1 ; Year1=CommOp(XComm,5)-YearAD(1)+1 FileYearN=Year1-Year0+1 ! 3,5 is deliberate allocate (GrimXtra(FileYearN,17,RegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpAgg: Allocation failure: MonthData #####" GrimXtra=0 print*, " > Aggregating into regions..." do XYear = Year0,Year1 XFileYear=XYear-Year0+1 do XMonth = 1, MonthN do XExe=1,ExeN do XWye=1,WyeN XReg=MapIDLReg(XExe,XWye) ! write (99,"(7i6)"), XYear,XFileYear,XMonth,XExe,XWye,XReg,Grid(XExe,XWye) if (XReg.NE.MissVal) then ! write (99,"(2f10.2)"), GrimXtra(XFileYear,XMonth,XReg),OperA(XYear,XMonth,Grid(XExe,XWye)) if (GrimXtra(XFileYear,XMonth,XReg).NE.MissVal) then if (Grid(XExe,XWye).NE.MissVal) then if (OperA(XYear,XMonth,Grid(XExe,XWye)).NE.MissVal) then GrimXtra(XFileYear,XMonth,XReg) = GrimXtra(XFileYear,XMonth,XReg) + & (OperA(XYear,XMonth,Grid(XExe,XWye)) * GridWeights(XExe,XWye)) else GrimXtra(XFileYear,XMonth,XReg) = MissVal end if end if end if end if end do end do end do end do print*, " > Removing aggregated weights..." do XReg=1,RegN if (RegWeights(XReg).GT.0) then do XfileYear=1,FileYearN do XMonth=1,MonthN if (GrimXtra(XFileYear,XMonth,XReg).NE.MissVal) & GrimXtra(XFileYear,XMonth,XReg) = GrimXtra(XFileYear,XMonth,XReg) / & RegWeights(XReg) end do end do end if end do print*, " > Seasonalising regions..." do XReg=1,RegN ! fill GrimXtra with regional values for seasons/ years do XFileYear=1,FileYearN OpTot=0 ; OpEn=0 do XMonth = 1, MonthN if (GrimXtra(XFileYear,XMonth,XReg).NE.MissVal) then OpTot=OpTot+GrimXtra(XFileYear,XMonth,XReg) ; opEn=OpEn+1 end if end do if (OpEn.Eq.12) then if (QMeanSum.EQ.0) GrimXtra(XFileYear,17,XReg)=OpTot/OpEn if (QMeanSum.EQ.2) GrimXtra(XFileYear,17,XReg)=OpTot end if do XSeason = 1, SeasonN ! note that XSeason=1 for MAM OpTot = 0.0 ; OpEn = 0.0 do ThisMonth = (XSeason*3), (2+(XSeason*3)) XMonth = ThisMonth ; XYear = XFileYear if (XMonth.GT.12) then XMonth = XMonth - 12 ! XYear = XYear + 1 ! command removed to enable single year dump end if if (XYear.LE.FileYearN) then if (GrimXtra(XYear,XMonth,XReg).NE.MissVal) then OpTot = OpTot + GrimXtra(XYear,XMonth,XReg) OpEn = OpEn + 1 end if end if end do if (OpEn.Eq.3) then if (QMeanSum.EQ.0) GrimXtra(XFileYear,(12+XSeason),XReg)=OpTot/OpEn if (QMeanSum.EQ.2) GrimXtra(XFileYear,(12+XSeason),XReg)=OpTot end if end do end do end do nullify (OperA) deallocate (MapIDLReg, RegSizes, GridWeights, RegWeights, RegBoreal, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpAgg: Deallocation failure: v1 #####" allocate (SeasonData(RegN,SeasonN),MonthData(RegN,MonthN), & AnnualData(RegN),SeasonStDev(RegN,SeasonN),MonthStDev(RegN,MonthN), & AnnualStDev(RegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: NewDumpAgg: Allocation failure: SeaAnnStDev #####" SeasonData=MissVal ; MonthData=MissVal ; AnnualData=MissVal SeasonStDev=MissVal ; MonthStDev=MissVal ; AnnualStDev=MissVal print*, " > Calculating mean and stdev..." do XReg = 1, RegN ! calc mean and stdev do XMonth = 1, 17 OpTot=0 ; OpTotSq=0 ; OpEn=0 do XFileYear=1,FileYearN if (GrimXtra(XFileYear,XMonth,XReg).NE.MissVal) then OpTot=OpTot+GrimXtra(XFileYear,XMonth,XReg) OpTotSq=OpTotSq+(GrimXtra(XFileYear,XMonth,XReg)**2) OpEn=OpEn+1 end if end do if (OpEn.GT.0) then if (XMonth.LE.12) then MonthData(XReg,XMonth)=OpTot/OpEn MonthStDev(XReg,XMonth)=(OpTotSq/OpEn)-(MonthData(XReg,XMonth)**2) if (MonthStDev(XReg,XMonth).GT.0) then MonthStDev(XReg,XMonth)=sqrt(MonthStDev(XReg,XMonth)) else MonthStDev(XReg,XMonth)=0 end if else if (XMonth.LE.16) then SeasonData(XReg,(XMonth-12))=OpTot/OpEn SeasonStDev(XReg,(XMonth-12))=(OpTotSq/OpEn)-(SeasonData(XReg,(XMonth-12))**2) if (SeasonStDev(XReg,(XMonth-12)).GT.0) then SeasonStDev(XReg,(XMonth-12))=sqrt(SeasonStDev(XReg,(XMonth-12))) else SeasonStDev(XReg,(XMonth-12))=0 end if else AnnualData(XReg)=OpTot/OpEn AnnualStDev(XReg)=(OpTotSq/OpEn)-(AnnualData(XReg)**2) if (AnnualStDev(XReg).GT.0) then AnnualStDev(XReg)=sqrt(AnnualStDev(XReg)) else AnnualStDev(XReg)=0 end if end if end if end do end do print*, " > Dumping to twin .agg files..." deallocate (GrimXtra, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpAgg: Deallocation failure: v2 #####" GenericFile = CommFile(XComm,XExec) ! generate region filepaths with correct directory SuffixStart = index(GenericFile,".agg") GenericFile = GenericFile(1:(SuffixStart-1)) SaveSuffix = GetFileSuffix (GenericFile) SuffixStart = index(GenericFile,SaveSuffix) call CheckVariSuffix (SaveSuffix,SaveVariName,FileFactor) GenericFile=CommFile(XComm,XExec) ; LineFormat='(a20,12f8.1,5f8.1)' GivenFile = GenericFile(1:(SuffixStart-1)) // ".av" // GenericFile(SuffixStart:80) call SaveAgg (GivenFile,RegNames,Monthly=MonthData,Seasonal=SeasonData,Annual=AnnualData,& CallLineFormat=LineFormat,NoResponse=1,ExtraHeads=1, & CallVariName=SaveVariName,CallTimeName="mean ") GivenFile = GenericFile(1:(SuffixStart-1)) // ".sd" // GenericFile(SuffixStart:80) LineFormat='(a20,12f8.1,5f8.1)' call SaveAgg (GivenFile,RegNames,Monthly=MonthStDev,Seasonal=SeasonStDev,Annual=AnnualStDev,& CallLineFormat=LineFormat,NoResponse=1,ExtraHeads=1, & CallVariName=SaveVariName,CallTimeName="stdev ") deallocate (MonthData,SeasonData,AnnualData,RegNames, & MonthStDev,SeasonStDev,AnnualStDev, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpAgg: Deallocation failure: v2 #####" end subroutine DumpAgg !******************************************************************************* ! command = 49 subroutine CountOccurrences call PointOperA ! before we load up into regions, we point OperA towards the correct grim call RegSelect (nint(MissVal), ExeN, WyeN, (ExeN*WyeN), MapIDLReg, RegSizes, RegNames, & RegTitle, RegN, CommInfo(XComm,1)) call GetWeightArrays allocate (GloSlice(RegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CountOccurrences: Allocation failure: Gloslice #####" GloSlice = 0.0 ! careful - do not inintialise to MissVal do XExe = 1, ExeN ! iterate around grid do XWye = 1, WyeN ! if the grid cell belongs to a region if (MapIDLReg(XExe,XWye).NE.MissVal) then ! then check if the grid cell is within the grim domain if (Grid(XExe,XWye).NE.MissVal.AND.RegWeights(MapIDLReg(XExe,XWye)).NE.MissVal) then if (GloSlice(MapIDLReg(XExe,XWye)).NE.MissVal) then do XYear = 1, YearN do XMonth = 1, MonthN if (OperA(XYear,XMonth,Grid(XExe,XWye)).EQ.MissVal.OR. & OperA(XYear,XMonth,Grid(XExe,XWye)).EQ.CommKay(XComm)) & GloSlice(MapIDLReg(XExe,XWye)) = GloSlice(MapIDLReg(XExe,XWye)) + GridWeights(XExe,XWye) end do end do end if else GloSlice(MapIDLReg(XExe,XWye)) = MissVal end if end if end do end do do XReg = 1, RegN if (GloSlice(XReg).NE.MissVal.AND.RegWeights(XReg).NE.MissVal.AND.RegWeights(XReg).GT.0) then GloSlice(XReg) = GloSlice(XReg) / (RegWeights(XReg)*12.0) else GloSlice(XReg) = MissVal end if end do nullify (OperA) deallocate (MapIDLReg, RegSizes, GridWeights, RegWeights, RegBoreal, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CountOccurrences: Deallocation failure: v1 #####" call SaveGlo (ExeN,WyeN,BoxN,GridFilePath,CommFile(XComm,XExec),CommInfo(XComm,XExec),GloSlice,Grid) deallocate (GloSlice,RegNames,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CountOccurrences: Deallocation failure: v2 #####" end subroutine CountOccurrences !******************************************************************************* ! command = 51 subroutine InterpolateMissing call PointOperA call PointOperB OperA = OperB TotA=0 ; TotB=0 do XYear = 1, YearN do XMonth = 1, MonthN do XExe = 1, ExeN do XWye = 1, WyeN if (Grid(XExe,XWye).NE.MissVal) then if (OperB(XYear,XMonth,Grid(XExe,XWye)).EQ.MissVal) then OpTot = 0.0 ; OpEn = 0.0 do XExeNear = XExe-1,XExe+1 do XWyeNear = XWye-1,XWye+1 if (XExeNear.GE.1.AND.XExeNear.LE.ExeN.AND.XWyeNear.GE.1.AND.XWyeNear.LE.WyeN) then if (Grid(XExeNear,XWyeNear).NE.MissVal) then if (OperB(XYear,XMonth,Grid(XExeNear,XWyeNear)).NE.MissVal) then OpTot = OpTot + OperB(XYear,XMonth,Grid(XExeNear,XWyeNear)) OpEn = OpEn + 1.0 end if end if end if end do end do if (OpEn.GE.1) then OperA(XYear,XMonth,Grid(XExe,XWye)) = OpTot / OpEn TotA = TotA + 1 else TotB = TotB + 1 end if end if end if end do end do end do end do nullify (OperA,OperB) end subroutine InterpolateMissing !******************************************************************************* ! command = 52 subroutine MakeKoeppen write (99,*), "@@@ point to arrays" ! @@@@@@@@@@@@@@@@@@@@@@@@ call PointOperA call PointOperB write (99,*), "@@@ call RegSelect" ! @@@@@@@@@@@@@@@@@@@@@@@@ call RegSelect (nint(MissVal), ExeN, WyeN, (ExeN*WyeN), MapIDLReg, RegSizes, RegNames, & RegTitle, RegN, CommInfo(XComm,1)) write (99,*), "@@@ call GetWeightArrays" ! @@@@@@@@@@@@@@@@@@@@@@@@ call GetWeightArrays write (99,*), "@@@ make allocations" ! @@@@@@@@@@@@@@@@@@@@@@@@ allocate (MonthTemp(RegN,MonthN),MonthPrec(RegN,MonthN), & GloSlice(RegN),stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: MakeKoeppen: Allocation failure." MonthTemp=0.0 ; MonthPrec=0.0 ; GloSlice=MissVal ; TotA=0 ; TotB=0 XYear = CommOp(XComm,5) - YearAD(1) + 1 write (99,*), "@@@ fill MonthData with area means" ! @@@@@@@@@@@@@@@@@@@@@@@@ do XMonth=1,MonthN do XExe = 1, ExeN ! fill MonthData with totals do XWye = 1, WyeN ! iterate around grid XReg=MapIDLReg(XExe,XWye) ! if the grid cell belongs to a region if (XReg.NE.MissVal) then ! then check if the grid cell is within the grim domain if (Grid(XExe,XWye).NE.MissVal.AND.RegWeights(XReg).NE.MissVal) then if (OperA(XYear,XMonth,Grid(XExe,XWye)).NE.MissVal.AND. & OperB(XYear,XMonth,Grid(XExe,XWye)).NE.MissVal) then ! check T/P = non-missing ! check region = OK thus far if (MonthTemp(XReg,XMonth).NE.MissVal.AND.MonthPrec(XReg,XMonth).NE.MissVal) then MonthTemp(XReg,XMonth) = MonthTemp(XReg,XMonth) + & (OperA(XYear,XMonth,Grid(XExe,XWye)) * GridWeights(XExe,XWye)) MonthPrec(XReg,XMonth) = MonthPrec(XReg,XMonth) + & (OperB(XYear,XMonth,Grid(XExe,XWye)) * GridWeights(XExe,XWye)) end if else ! datum=missing, so make region missing MonthTemp(XReg,XMonth)=MissVal ; MonthPrec(XReg,XMonth)=MissVal end if else ! cell=missing, so make region missing MonthTemp(XReg,XMonth)=MissVal ; MonthPrec(XReg,XMonth)=MissVal end if end if end do end do do XReg=1,RegN ! convert area totals to area means if (RegWeights(XReg).GT.0.0) then if (MonthTemp(XReg,XMonth).NE.MissVal.AND.MonthPrec(XReg,XMonth).NE.MissVal) then MonthTemp(XReg,XMonth) = MonthTemp(XReg,XMonth) / RegWeights(XReg) MonthPrec(XReg,XMonth) = MonthPrec(XReg,XMonth) / RegWeights(XReg) end if else MonthTemp(XReg,XMonth)=MissVal ; MonthPrec(XReg,XMonth)=MissVal end if end do end do write (99,*), "@@@ calculate Koeppen class" ! @@@@@@@@@@@@@@@@@@@@@@@@ do XReg=1,RegN ! calculate Koeppen class for each region do XMonth=1,MonthN BoxTemp(XMonth)=MonthTemp(XReg,XMonth) ; BoxPrec(XMonth)=MonthPrec(XReg,XMonth) end do Boreal=.TRUE. ; if (RegBoreal(XReg).LT.0.0) Boreal=.FALSE. call GetKoeppen (BoxTemp,BoxPrec,Boreal,KopNumb,KopAcro,KopName) if (KopNumb.NE.MissVal) then TotA=TotA+1 else TotB=TotB+1 end if GloSlice(XReg)=KopNumb end do InfoLine="Koeppen classes" write (99,*), "@@@ call SaveGlo" ! @@@@@@@@@@@@@@@@@@@@@@@@ call SaveGlo (ExeN,WyeN,BoxN,GridFilePath,CommFile(XComm,XExec),InfoLine,GloSlice,Grid) write (99,*), "@@@ done SaveGlo" ! @@@@@@@@@@@@@@@@@@@@@@@@ deallocate (MonthTemp,MonthPrec,GloSlice,MapIDLReg,RegSizes,RegNames, & GridWeights,RegWeights,RegBoreal,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: MakeKoeppen: Deallocation failure." nullify (OperA,OperB) write (99,*), "@@@ done MakeKoeppen" ! @@@@@@@@@@@@@@@@@@@@@@@@ end subroutine MakeKoeppen !******************************************************************************* subroutine GetWeightArrays if (CommOp(XComm,4).EQ.2) then call GetGloWeights (ExeN,WyeN,GridWeights) else allocate (GridWeights(ExeN,WyeN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GetWeightArrays: Allocation failure: GridWeights #####" GridWeights = 1.0 end if allocate (RegWeights(RegN), RegBoreal(RegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GetGridWeights: Allocation failure: RegWeights #####" RegWeights = 0.0 ; RegBoreal = 0.0 ! careful - do not initialise to MissVal BoxLat=(Bounds(4)-Bounds(3))/WyeN do XWye = 1, WyeN NorthSouth=1.0 if (((real(XWye)*BoxLat)+Bounds(3)).LT.0) NorthSouth=-1.0 do XExe = 1, ExeN XReg=MapIDLReg(XExe,XWye) if (XReg.NE.MissVal.AND.Grid(XExe,XWye).NE.MissVal) then if (RegWeights(XReg).NE.MissVal.AND.GridWeights(XExe,XWye).NE.MissVal) then RegWeights(XReg) = RegWeights(XReg) + GridWeights(XExe,XWye) RegBoreal (XReg) = RegBoreal(XReg) + (GridWeights(XExe,XWye) * NorthSouth) else RegWeights(XReg) = MissVal ; RegBoreal(XReg) = MissVal end if end if end do end do end subroutine GetWeightArrays !******************************************************************************* subroutine PointOperA if (CommOp(XComm,2).EQ.1) OperA => Grim1 if (CommOp(XComm,2).EQ.2) OperA => Grim2 if (CommOp(XComm,2).EQ.3) OperA => Grim3 if (CommOp(XComm,2).EQ.4) OperA => Grim4 if (CommOp(XComm,2).EQ.5) OperA => Grim5 if (CommOp(XComm,2).EQ.6) OperA => Grim6 end subroutine PointOperA !******************************************************************************* subroutine PointOperB if (CommOp(XComm,3).EQ.1) OperB => Grim1 if (CommOp(XComm,3).EQ.2) OperB => Grim2 if (CommOp(XComm,3).EQ.3) OperB => Grim3 if (CommOp(XComm,3).EQ.4) OperB => Grim4 if (CommOp(XComm,3).EQ.5) OperB => Grim5 if (CommOp(XComm,3).EQ.6) OperB => Grim6 end subroutine PointOperB !******************************************************************************* subroutine PointOperC if (CommOp(XComm,5).EQ.1) OperC => Grim1 if (CommOp(XComm,5).EQ.2) OperC => Grim2 if (CommOp(XComm,5).EQ.3) OperC => Grim3 if (CommOp(XComm,5).EQ.4) OperC => Grim4 if (CommOp(XComm,5).EQ.5) OperC => Grim5 if (CommOp(XComm,5).EQ.6) OperC => Grim6 end subroutine PointOperC !******************************************************************************* subroutine PointOperD if (CommOp(XComm,4).EQ.1) OperD => Grim1 if (CommOp(XComm,4).EQ.2) OperD => Grim2 if (CommOp(XComm,4).EQ.3) OperD => Grim3 if (CommOp(XComm,4).EQ.4) OperD => Grim4 if (CommOp(XComm,4).EQ.5) OperD => Grim5 if (CommOp(XComm,4).EQ.6) OperD => Grim6 end subroutine PointOperD !******************************************************************************* subroutine PointOperK if (CommKay(XComm).EQ.1) OperK => Grim1 if (CommKay(XComm).EQ.2) OperK => Grim2 if (CommKay(XComm).EQ.3) OperK => Grim3 if (CommKay(XComm).EQ.4) OperK => Grim4 if (CommKay(XComm).EQ.5) OperK => Grim5 if (CommKay(XComm).EQ.6) OperK => Grim6 end subroutine PointOperK !******************************************************************************* subroutine GridMismatch if (size(FileGrid,1).NE.size(Grid,1)) print*, " > ##### ERROR: loaded Grid mismatch: X" if (size(FileGrid,2).NE.size(Grid,2)) print*, " > ##### ERROR: loaded Grid mismatch: Y" CheckGrid = 0 do XExe = 1, ExeN do XWye = 1, WyeN if (FileGrid(XExe,XWye).NE.Grid(XExe,XWye)) then CheckGrid = CheckGrid + 1 write (99,"(4i10)"), XExe,XWye,Grid(XExe,XWye),FileGrid(XExe,XWye) end if end do end do if (CheckGrid.NE.0) print*, " > ##### ERROR: Grid mismatches: ", CheckGrid end subroutine GridMismatch !******************************************************************************* subroutine Finalise deallocate (CommOp,CommKay,CommFile,CommInfo, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Finalise: Deallocation failure: Comm* #####" deallocate (Grid,YearAD,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Finalise: Deallocation failure: Basic #####" if (associated(Grim1)) deallocate (Grim1, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Finalise: Deallocation failure: Grim1 #####" if (associated(Grim2)) deallocate (Grim2, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Finalise: Deallocation failure: Grim2 #####" if (associated(Grim3)) deallocate (Grim3, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Finalise: Deallocation failure: Grim3 #####" if (associated(Grim4)) deallocate (Grim4, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Finalise: Deallocation failure: Grim4 #####" if (associated(Grim5)) deallocate (Grim5, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Finalise: Deallocation failure: Grim5 #####" if (associated(Grim6)) deallocate (Grim6, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Finalise: Deallocation failure: Grim6 #####" print* close (99) end subroutine Finalise !******************************************************************************* end program SeqGrim