! ScalePattern.f90 ! written by Tim Mitchell on 07.11.01 ! last modified on 07.11.01 ! program to scale response pattern from grip file ! designed using the linked list concept ! f90 -o ./../grim/scalepattern sortmod.f90 filenames.f90 initialmod.f90 time.f90 grimfiles.f90 annfiles.f90 ! glofiles.f90 aggfiles.f90 perfiles.f90 regress.f90 ./../grim/scalepattern.f90 program ScalePattern use FileNames use InitialMod use Time use GrimFiles use AnnFiles use GloFiles use AggFiles use PerFiles use Regress implicit none type Exec character (len=20) :: Name ! execution name type (Exec), pointer :: Prev ! prev execution defined: recursion type (Exec), pointer :: Next ! next execution defined: recursion character (len=80) :: Kay1File, Kay2File ! pattern grip files character (len=80) :: GloTFile, EquTFile ! .ann for target character (len=80) :: TargFile, BaseFile ! target grim files end type Exec type (Exec), pointer :: OneExec, CurrentExec, StackExec character (len=80), parameter :: SpecFile = "/cru/mikeh1/f709762/f90/grim/_ref/ops/scalepattern.21.ops.X" real, pointer, dimension (:,:,:) :: Est,Mod real, pointer, dimension (:,:,:) :: Array3D real, pointer, dimension (:,:) :: Array2D,ArrayUM,ArrayWM,ArrayUA,ArrayWA real, pointer, dimension (:,:) :: Kay1,Kay2 ! the arrays of k: SeasonN, BoxN real, pointer, dimension (:,:) :: GloWeights real, pointer, dimension (:) :: GloT,EquT,CurrentTS ! ts: global T, equilibrium T real, pointer, dimension (:) :: Array1D,TSLowVec,TSHighVec,Extract real, pointer, dimension (:) :: Weight1D,RegWeights integer, pointer, dimension (:,:) :: Grid, LoadGrid, MapIDLReg integer, pointer, dimension (:) :: YearAD, LoadYearAD, RegSizes integer, pointer, dimension (:) :: DumpYear ! periods to dump character (len=80), pointer, dimension (:) :: DumpRegSet,TextRegSet,RegNamesUniq80,SaveRegFile character (len=20), pointer, dimension (:) :: RegNames,RegNamesUniq20 character (len= 9), pointer, dimension(:) :: ColTitles real, dimension (4) :: Bounds, LoadBounds integer, dimension (3) :: DumpStat integer, dimension (17) :: DumpCal character (len=3), dimension (17), parameter :: SeasonNames = ['jan','feb','mar','apr','may','jun','jul',& 'aug','sep','oct','nov','dec','MAM','JJA','SON','DJF','ann'] character (len=3), dimension (3), parameter :: StatsText = ['est','mod','dif'] real, parameter :: MissVal = -999.0 integer, parameter :: SeasonN=17, MonthN=12, BoundN=4, StatN=3 character (len=80), parameter :: Blank = "" real :: MissAccept, MissThresh, OpTot, OpEn, OpMiss, VariFactor real :: OpTotUM,OpTotUA,OpTotWM,OpTotWA,OpEnWei,OpMissWei integer :: ReadStatus, AllocStat integer :: ExecN, BoxN, ExeN, WyeN, YearN, LoadYearN, DumpYearN, DumpRegSetN, RegN integer :: XExec, XBox, XExe, XWye, XYear, XLoadYear, XDumpYear, XDumpRegSet, XReg integer :: XSeason, XMonth, XBound, XStat integer :: PerLen, GapLen, YearAD0, YearAD1, YearLimit, CheckBoxN, ThisYear, ThisMonth integer :: QMethod,QCompare,QMeanSum,QDumpGrip,QDumpGlo,QDumpAgg,QDumpGrim,QDumpPer,QDumpGlobe integer :: QGloAgg,QPerGlobe integer :: Year0,Year1,LoadYear0,LoadYear1,CallVariCode character (len=80) :: LoadInfo,LoadFile,SaveInfo,SaveFile,GridRef,VariName character (len=80) :: TextDir,TextInfo,TextTarg,TextPatt,SaveSTem,SaveTip character (len=20) :: TextYear character (len= 4) :: LoadSuffix,SaveSuffix,Variable !******************************************************************************* call Intro call GetOpsFile call SetSpecifics call ResetCurrentExec ! points CurrentExec back to the first exec do print*, " > Execution: ", CurrentExec%Name Variable = trim(CurrentExec%Name) if (Variable.EQ.".wet".OR.Variable.EQ.".pre".OR.Variable.EQ.".frs") then QMeanSum = 2 else QMeanSum = 1 end if print*, " > Loading patterns..." call LoadPatterns print*, " > Loading scalers..." call LoadScalers print*, " > Making estimate..." call MakeEstimate if (QCompare.EQ.1) then print*, " > Making comparison..." call LoadModelled ! call CompareEstMod ! has to be omitted because of lack of memory - workarounds used end if print*, " > Dumping to file..." if (QDumpGrip .EQ.1) call DumpGrip if (QDumpGlo .EQ.1) then QGloAgg = 1 ; call DumpGloAgg end if if (QDumpAgg .EQ.1) then QGloAgg = 2 ; call DumpGloAgg end if if (QDumpGrim .EQ.1) call DumpGrim if (QDumpPer .EQ.1) call DumpPer if (QDumpGlobe.EQ.1) call DumpGlobe call RemoveEstMod if (.not.associated(CurrentExec%Next)) exit ! last exec, so exit loop if (associated(CurrentExec%Next)) CurrentExec => CurrentExec%Next ! not 1st exec, so next exec end do call Finish contains !******************************************************************************* subroutine Intro open (99,file="/cru/mikeh1/f709762/scratch/log/log-scalepattern.dat",status="replace",action="write") print* print*, " > ***** ScalePattern: scales response patterns *****" print* print*, " > Spec file: ", trim(SpecFile) print* end subroutine Intro !******************************************************************************* subroutine GetOpsFile open (1,file=SpecFile,status="old",access="sequential",form="unformatted",action="read") read (1), ExecN, BoxN, ExeN, WyeN read (1), PerLen, MissAccept, QMethod, QCompare, YearAD0, YearAD1 read (1), (Bounds(XBound),XBound=1,4) read (1), (DumpStat(XStat),XStat=1,3) read (1), (DumpCal(XSeason),XSeason=1,17) read (1), DumpYearN,DumpRegSetN read (1), QDumpGrip,QDumpGlo,QDumpAgg,QDumpGrim,QDumpPer,QDumpGlobe read (1), TextInfo,TextDir,TextTarg,TextPatt if (DumpYearN.GT.0) then allocate (DumpYear (DumpYearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Intro: Allocation failure: DumpYear #####" read (1), (DumpYear(XDumpYear),XDumpYear=1,DumpYearN) end if if (DumpRegSetN.GT.0) then allocate (DumpRegSet (DumpRegSetN), & TextRegSet (DumpRegSetN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Intro: Allocation failure: DumpRegSet #####" read (1), (DumpRegSet(XDumpRegSet),XDumpRegSet=1,DumpRegSetN) read (1), (TextRegSet(XDumpRegSet),XDumpRegSet=1,DumpRegSetN) end if allocate (Grid (ExeN,WyeN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Intro: Allocation failure: Grid #####" do XExe = 1, ExeN read (1), (Grid(XExe,XWye), XWye=1,WyeN) end do do XExec = 1, ExecN allocate (OneExec, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Intro: Allocation failure: OneExec #####" read (1), OneExec%Name read (1), OneExec%Kay1File, OneExec%Kay2File, OneExec%GloTFile, OneExec%EquTFile read (1), OneExec%BaseFile, OneExec%TargFile if (XExec.EQ.1) then nullify(OneExec%Prev) nullify(OneExec%Next) else OneExec%Prev => CurrentExec CurrentExec%Next => OneExec nullify(OneExec%Next) end if CurrentExec => OneExec end do close (1) end subroutine GetOpsFile !******************************************************************************* subroutine SetSpecifics YearN = YearAD1 - YearAD0 + 1 allocate (YearAD (YearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: SetTime: Allocation failure: YearAD #####" do XYear = 1, YearN YearAD (XYear) = YearAD0 + XYear - 1 end do GridRef = GetGloRef (ExeN,WyeN) end subroutine SetSpecifics !******************************************************************************* ! kay1 (and kay2 if required) is in a grip file ! it is expressed in per degC subroutine LoadPatterns if (CurrentExec%Kay1File.NE."") then allocate (Kay1(SeasonN,BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadPatterns: Allocation failure: Kay1 #####" Kay1 = MissVal LoadFile = CurrentExec%Kay1File Array2D => Kay1 call GrabGrip end if if (CurrentExec%Kay2File.NE."") then allocate (Kay2(SeasonN,BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadPatterns: Allocation failure: Kay2 #####" Kay2 = MissVal LoadFile = CurrentExec%Kay2File Array2D => Kay2 call GrabGrip end if nullify (Array2D) end subroutine LoadPatterns !******************************************************************************* subroutine GrabGrip call LoadGrip (Array2D,LoadGrid,LoadBounds,LoadInfo,LoadFile,CurrentExec%Name,LoadSuffix) call CheckGridAB (Grid,LoadGrid,CheckBoxN) if (CheckBoxN.EQ.MissVal) then print*, " > ##### ERROR: GrabGrip: grids do not match #####" deallocate (Array2D,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GrabGrip: Deallocation failure #####" end if deallocate (LoadGrid,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GrabGrip: Deallocation failure #####" end subroutine GrabGrip !******************************************************************************* ! GloT (and EquT if required) should be in a single-column .ann file ! both should already be anomalised relative to the same base period as in the BaseFile ! both should already be smoothed at the periodicity PerLen subroutine LoadScalers if (CurrentExec%GloTFile.NE."") then allocate (GloT(YearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadScalers: Allocation failure: GloT #####" GloT = MissVal call LoadAnn (CurrentExec%GloTFile, LoadYearAD, ColTitles, Array2D) CurrentTS => GloT call GrabAnn end if if (CurrentExec%EquTFile.NE."") then allocate (EquT(YearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadScalers: Allocation failure: EquT #####" EquT = MissVal call LoadAnn (CurrentExec%EquTFile, LoadYearAD, ColTitles, Array2D) CurrentTS => EquT call GrabAnn end if nullify (CurrentTS) end subroutine LoadScalers !******************************************************************************* subroutine GrabAnn call CommonVecPer (YearAD,LoadYearAD,Year0,Year1,LoadYear0,LoadYear1) if (size(Array2D,2).EQ.1) then if (Year0.NE.MissVal) then XYear = Year0 - 1 ; XLoadYear = LoadYear0 - 1 do XYear = XYear + 1 ; XLoadYear = XLoadYear + 1 CurrentTS (XYear) = Array2D (XLoadYear,1) if (XYear.EQ.Year1) exit end do else print*, " > ##### ERROR: GrabAnn: no period in common #####" end if else print*, " > ##### ERROR: GrabAnn: multiple columns in .ann #####" end if deallocate (LoadYearAD,Array2D,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GrabAnn: Deallocation failure #####" end subroutine GrabAnn !******************************************************************************* subroutine MakeEstimate allocate (Est(YearN,SeasonN,BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: MakeEstimate: Allocation failure: Est #####" Est = MissVal if (QMethod.EQ. 1) then do XYear = 1, YearN do XSeason = 1, SeasonN do XBox = 1, BoxN Est(XYear,XSeason,XBox) = Kay1(XSeason,XBox) * GloT(XYear) end do end do end do deallocate (Kay1,GloT, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: MakeEstimate: Deallocation failure: 01 #####" else if (QMethod.EQ.11) then do XYear = 1, YearN do XSeason = 1, SeasonN do XBox = 1, BoxN Est(XYear,XSeason,XBox) = (Kay1(XSeason,XBox) * GloT(XYear)) + & (Kay2(XSeason,XBox) * (EquT(XYear) - GloT(XYear))) end do end do end do deallocate (Kay1,Kay2,GloT,EquT, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: MakeEstimate: Deallocation failure: 11 #####" else print*, " > ##### ERROR: MakeEstimate: QMethod unrecognised #####" end if end subroutine MakeEstimate !******************************************************************************* ! we take the unanomalised, unsmoothed, target that we are aiming at, as a grim file ! we anomalise the target versus the base file (which must be a single year) ! we fill in the seasonal (cols 13-16) and annual (17) means ! we smooth the time series at each box and period (1...17) at periodicity PerLen subroutine LoadModelled allocate (Mod(YearN,SeasonN,BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadModelled: Allocation failure: Mod #####" Mod = MissVal call LoadTarg call LoadBase call GetMod1317 call SmooMod end subroutine LoadModelled !******************************************************************************* subroutine LoadTarg call LoadGrim (Array3D,LoadGrid,LoadYearAD,LoadBounds,LoadInfo,CurrentExec%TargFile,& CurrentExec%Name,LoadSuffix) call CommonVecPer (YearAD,LoadYearAD,Year0,Year1,LoadYear0,LoadYear1) call CheckGridAB (Grid,LoadGrid,CheckBoxN) if (Year0.EQ.MissVal) then print*, " > ##### ERROR: LoadTarg: no period in target file that matches YearAD #####" else if (CheckBoxN.EQ.MissVal) then print*, " > ##### ERROR: LoadTarg: grids do not match #####" else do XMonth = 1, MonthN do XBox = 1, BoxN do XYear = Year0, Year1 XLoadYear = LoadYear0 + XYear - Year0 if (Array3D(XLoadYear,XMonth,XBox).NE.MissVal) Mod (XYear,XMonth,XBox) = Array3D (XLoadYear,XMonth,XBox) end do end do end do end if end if deallocate (LoadGrid,LoadYearAD,Array3D,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadTarg: : Deallocation failure #####" end subroutine LoadTarg !******************************************************************************* subroutine LoadBase call LoadGrim (Array3D,LoadGrid,LoadYearAD,LoadBounds,LoadInfo,CurrentExec%BaseFile,& CurrentExec%Name,LoadSuffix) call CheckGridAB (Grid,LoadGrid,CheckBoxN) if (size(LoadYearAD).NE.1) then print*, " > ##### ERROR: LoadBase: grim not a single year #####" else if (CheckBoxN.EQ.MissVal) then print*, " > ##### ERROR: LoadBase: grids do not match #####" else do XMonth = 1, MonthN do XBox = 1, BoxN if (Array3D(1,XMonth,XBox).NE.MissVal) then do XYear = 1, YearN if (Mod(XYear,XMonth,XBox).NE.MissVal) Mod (XYear,XMonth,XBox) = & Mod (XYear,XMonth,XBox) - Array3D (1,XMonth,XBox) end do else do XYear = 1, YearN Mod (XYear,XMonth,XBox) = MissVal end do end if end do end do end if end if deallocate (LoadGrid,LoadYearAD,Array3D,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadBase: : Deallocation failure #####" end subroutine LoadBase !******************************************************************************* subroutine GetMod1317 do XYear = 1, YearN ! get annual data do XBox = 1, BoxN OpTot = 0.0 ; OpEn = 0.0 do XMonth = 1, MonthN if (Mod(XYear,XMonth,XBox).NE.MissVal) then OpTot = OpTot + Mod(XYear,XMonth,XBox) OpEn = OpEn + 1.0 end if end do if (OpEn.EQ.12) then if (QMeanSum.EQ.1) Mod(XYear,17,XBox) = OpTot / OpEn if (QMeanSum.EQ.2) Mod(XYear,17,XBox) = OpTot end if end do end do do XYear = 1, YearN ! get seasonal data do XBox = 1, BoxN do XSeason = 13, 16 OpTot = 0.0 ; OpEn = 0.0 do XMonth = (((XSeason-13)*3)+3), (((XSeason-13)*3)+5) ThisYear = XYear ; ThisMonth = XMonth if (XMonth.GT.12) then ThisYear = XYear + 1 ; ThisMonth = XMonth - 12 end if if (ThisYear.LE.YearN) then if (Mod(ThisYear,ThisMonth,XBox).NE.MissVal) then OpTot = OpTot + Mod(ThisYear,ThisMonth,XBox) OpEn = OpEn + 1.0 end if end if end do if (OpEn.EQ.3) then if (QMeanSum.EQ.1) Mod(XYear,XSeason,XBox) = OpTot / OpEn if (QMeanSum.EQ.2) Mod(XYear,XSeason,XBox) = OpTot end if end do end do end do end subroutine GetMod1317 !******************************************************************************* subroutine SmooMod allocate (Array1D (YearN), & TSLowVec (YearN), & TSHighVec(YearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: SmooMod: Allocation failure #####" do XSeason = 1, SeasonN do XBox = 1, BoxN TSLowVec = MissVal ; TSHighVec = MissVal do XYear = 1, YearN Array1D (XYear) = Mod (XYear,XSeason,XBox) end do call GaussSmooth (YearN,PerLen,1,Array1D,TSLowVec,TSHighVec) do XYear = 1, YearN Mod (XYear,XSeason,XBox) = TSLowVec (XYear) end do end do end do deallocate (Array1D,TSLowVec,TSHighVec, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: SmooMod: Deallocation failure: Array1D #####" end subroutine SmooMod !******************************************************************************* ! Dif = Est -- Mod ! has to be omitted and worked around because of lack of memory ! !subroutine CompareEstMod ! !allocate (Dif(YearN,SeasonN,BoxN), stat=AllocStat) !if (AllocStat.NE.0) print*, " > ##### ERROR: CompareEstMod: Allocation failure: Dif #####" !Dif = MissVal ! !do XYear = 1, YearN ! do XSeason = 1, SeasonN ! do XBox = 1, BoxN ! if (Mod(XYear,XSeason,XBox).NE.MissVal.AND.Est(XYear,XSeason,XBox).NE.MissVal) then ! Dif(XYear,XSeason,XBox) = Est(XYear,XSeason,XBox) - Mod(XYear,XSeason,XBox) ! end if ! end do ! end do !end do ! !end subroutine CompareEstMod ! !******************************************************************************* subroutine DumpGrip write (99,*), "Dumping to grip..." allocate (Array2D(SeasonN,BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGrip: Allocation failure: Array2D #####" do XDumpYear = 1, DumpYearN TextYear = GetTextFromInt (YearAD(DumpYear(XDumpYear))) do XStat = 1, StatN if (DumpStat(XStat).EQ.1) then if (XStat.EQ.1) then do XSeason = 1, SeasonN do XBox = 1, BoxN Array2D (XSeason,XBox) = Est (DumpYear(XDumpYear),XSeason,XBox) end do end do else if (XStat.EQ.2) then do XSeason = 1, SeasonN do XBox = 1, BoxN Array2D (XSeason,XBox) = Mod (DumpYear(XDumpYear),XSeason,XBox) end do end do else if (XStat.EQ.3) then do XSeason = 1, SeasonN do XBox = 1, BoxN if (Est(DumpYear(XDumpYear),XSeason,XBox).NE.MissVal.AND.Mod(DumpYear(XDumpYear),XSeason,XBox) & .NE.MissVal) then Array2D (XSeason,XBox) = Est(DumpYear(XDumpYear),XSeason,XBox)-Mod(DumpYear(XDumpYear),XSeason,XBox) else Array2D (XSeason,XBox) = MissVal end if end do end do end if SaveInfo = trim(TextInfo) // " " // trim(TextTarg) // "@" // trim(TextYear) // & " stat=" // StatsText(XStat) if (XStat.NE.2) SaveInfo = trim(SaveInfo) // " patt=" // trim(TextPatt) if (QMeanSum.EQ.1) SaveInfo = trim(SaveInfo) // " time=mean" if (QMeanSum.EQ.2) SaveInfo = trim(SaveInfo) // " time=sum" SaveFile = trim(TextDir) // StatsText(XStat) // "-" // trim(TextTarg) // "-" // trim(TextYear) if (XStat.NE.2) SaveFile = trim(SaveFile) // "." // trim(TextPatt) SaveFile = trim(SaveFile) // CurrentExec%Name call SaveGrip (Array2D,Grid,Bounds,SaveInfo,SaveFile,CurrentExec%Name,SaveSuffix) end if end do end do deallocate (Array2D, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGrip: Deallocation failure: Array2D #####" end subroutine DumpGrip !******************************************************************************* subroutine DumpGloAgg if (QGloAgg.EQ.1) write (99,*), "Dumping to .glo..." if (QGloAgg.EQ.2) write (99,*), "Dumping to .agg..." allocate (Extract(BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGloAgg: Allocation failure: Extract #####" do XDumpRegSet = 1, DumpRegSetN call PrepareRegions allocate (Array1D (RegN), & Weight1D (RegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGloAgg: Allocation failure: Array1D #####" if (QGloAgg.EQ.2) then allocate (Array2D (RegN,SeasonN), & RegNamesUniq20 (RegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGloAgg: Allocation failure: Array2D #####" call MakeBatch (Blank,Blank,RegNames,RegNamesUniq80) RegNamesUniq20 = RegNamesUniq80 end if do XStat = 1, StatN if (DumpStat(XStat).EQ.1) then do XDumpYear = 1, DumpYearN if (QGloAgg.EQ.2) Array2D = 0.0 do XSeason = 1, SeasonN if (DumpCal(XSeason).EQ.1.OR.QGloAgg.EQ.2) then ! checks whether this dump is required XYear = DumpYear(XDumpYear) call MakeBoxVector call MakeRegVector if (QGloAgg.EQ.1) then TextYear = GetTextFromInt (YearAD(DumpYear(XDumpYear))) SaveInfo = trim(TextInfo) // " " // trim(TextTarg) // "@" // trim(TextYear) // " stat=" // & StatsText(XStat) if (XStat.NE.2) SaveInfo = trim(SaveInfo) // " patt=" // trim(TextPatt) SaveInfo = trim(SaveInfo) // " wei-regs=" // trim(TextRegSet(XDumpRegSet)) // " " // & SeasonNames(XSeason) // "-" if (QMeanSum.EQ.1) SaveInfo = trim(SaveInfo) // "mean" if (QMeanSum.EQ.2) SaveInfo = trim(SaveInfo) // "sum" SaveFile = trim(TextDir) // StatsText(XStat) // "-" // trim(TextTarg) // "-" // trim(TextYear) if (XStat.NE.2) SaveFile = trim(SaveFile) // "." // trim(TextPatt) SaveFile = trim(SaveFile) // "." // trim(TextRegSet(XDumpRegSet)) // "." // SeasonNames(XSeason) //& trim(CurrentExec%Name) // ".glo" call SaveGlo (ExeN,WyeN,RegN,GridRef,SaveFile,SaveInfo,Array1D,MapIDLReg) else if (QGloAgg.EQ.2) then do XReg = 1, RegN Array2D (XReg,XSeason) = Array1D(XReg) end do end if end if end do if (QGloAgg.EQ.2) then TextYear = GetTextFromInt (YearAD(DumpYear(XDumpYear))) SaveInfo = trim(TextInfo) // " " // trim(TextTarg) // "@" // trim(TextYear) // " stat=" // & StatsText(XStat) if (XStat.NE.2) SaveInfo = trim(SaveInfo) // " patt=" // trim(TextPatt) SaveInfo = trim(SaveInfo) // " wei-regs=" // trim(TextRegSet(XDumpRegSet)) // " " if (QMeanSum.EQ.1) SaveInfo = trim(SaveInfo) // "mean" if (QMeanSum.EQ.2) SaveInfo = trim(SaveInfo) // "sum" SaveFile = trim(TextDir) // StatsText(XStat) // "-" // trim(TextTarg) // "-" // trim(TextYear) if (XStat.NE.2) SaveFile = trim(SaveFile) // "." // trim(TextPatt) SaveFile = trim(SaveFile) // "." // trim(TextRegSet(XDumpRegSet)) // trim(CurrentExec%Name) // ".agg" call SaveAgg(SaveFile,RegNamesUniq20,AllData=Array2D,NoResponse=1) end if end do end if end do if (QGloAgg.EQ.2) then deallocate (Array2D,RegNamesUniq20,RegNamesUniq80, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGloAgg: Deallocation failure: Array2D #####" end if deallocate (Array1D,Weight1D,GloWeights,RegWeights,MapIDLReg,RegSizes,RegNames, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGloAgg: Deallocation failure: Array1D #####" end do deallocate (Extract, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGloAgg: Deallocation failure: Extract #####" end subroutine DumpGloAgg !******************************************************************************* subroutine DumpGrim write (99,*), "Dumping ts at every box to grim..." do XStat = 1, StatN if (DumpStat(XStat).EQ.1) then SaveInfo = trim(TextInfo) // " " // trim(TextTarg) // "@" // trim(TextYear) // " stat=" // & StatsText(XStat) if (XStat.NE.2) SaveInfo = trim(SaveInfo) // " patt=" // trim(TextPatt) // " " if (QMeanSum.EQ.1) SaveInfo = trim(SaveInfo) // "mean" if (QMeanSum.EQ.2) SaveInfo = trim(SaveInfo) // "sum" SaveFile = trim(TextDir) // StatsText(XStat) // "-" // trim(TextTarg) if (XStat.NE.2) SaveFile = trim(SaveFile) // "." // trim(TextPatt) // "." // trim(CurrentExec%Name) if (XStat.EQ.1) call SaveGrim (Est,Grid,YearAD,Bounds,SaveInfo,SaveFile,trim(CurrentExec%Name),SaveSuffix) if (XStat.EQ.2) call SaveGrim (Mod,Grid,YearAD,Bounds,SaveInfo,SaveFile,trim(CurrentExec%Name),SaveSuffix) if (XStat.EQ.3) then allocate (Array3D(YearN,SeasonN,BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGrim: Allocation failure: Array3D #####" Array3D = MissVal do XYear = 1, YearN do XSeason = 1, SeasonN do XBox= 1, BoxN if (Est(XYear,XSeason,XBox).NE.MissVal.AND.Mod(XYear,XSeason,XBox).NE.MissVal) & Array3D(XYear,XSeason,XBox) = Est(XYear,XSeason,XBox) - Mod(XYear,XSeason,XBox) end do end do end do call SaveGrim (Array3D,Grid,YearAD,Bounds,SaveInfo,SaveFile,trim(CurrentExec%Name),SaveSuffix) deallocate (Array3D, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGrim: Deallocation failure: Array3D #####" end if end if end do end subroutine DumpGrim !******************************************************************************* ! each seasonal and annual mean is calc as a mean (QMeanSum=1) or sum (=2) ! each regional value is calculated as the weighted mean of its constiuent boxes ! each region has its yearly/17 values dumped to .per ! this option should not be chosen except where the number of regions is relatively small subroutine DumpPer if (QMeanSum.EQ.1) CallVariCode = 0 if (QMeanSum.EQ.2) CallVariCode = 2 do XDumpRegSet = 1, DumpRegSetN call PrepareRegions allocate (Array2D (RegN,SeasonN), & RegNamesUniq20 (RegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGloAgg: Allocation failure: Array2D #####" call MakeBatch (Blank,Blank,RegNames,RegNamesUniq80) RegNamesUniq20 = RegNamesUniq80 allocate (Array3D (RegN,YearN,SeasonN), & Array2D (YearN,SeasonN), & Weight1D (RegN), & Array1D (RegN), & Extract (BoxN), & SaveRegFile (RegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpPer: Allocation failure: Array3D #####" SaveStem = trim(TextDir) // StatsText(XStat) // "-" // trim(TextTarg) // "." if (XStat.NE.2) SaveStem = trim(SaveStem) // trim(TextPatt) // "." SaveTip = "." // trim(CurrentExec%Name) // ".per" call MakeBatch (SaveStem,SaveTip,RegNames,SaveRegFile) do XStat = 1, StatN if (DumpStat(XStat).EQ.1) then do XYear = 1, YearN do XSeason = 1, SeasonN call MakeBoxVector call MakeRegVector do XReg = 1, RegN Array3D (XReg,XYear,XSeason) = Array1D (XReg) end do end do end do do XReg = 1, RegN do XYear = 1, YearN do XSeason = 1, SeasonN Array2D(XYear,XSeason) = Array3D(XReg,XYear,XSeason) end do end do call SavePer (SaveRegFile(XReg), YearAD, CallVariCode, AllData=Array2D, NoResponse=1) end do end if end do deallocate (MapIDLReg,RegSizes,RegNames,GloWeights,RegWeights,& Array3D,Array2D,Array1D,Weight1D,Extract, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpPer: Deallocation failure: Reg* #####" end do end subroutine DumpPer !******************************************************************************* ! each seasonal and annual mean is calc as a mean (QMeanSum=1) or sum (=2) ! each regional value is calculated as the weighted mean of its constiuent boxes ! um: the global mean of all regions is unweighted ! ua: the global average absolute value of all regions is unweighted ! wm: the global mean of all regions is weighted ! wa: the global average absolute value of all regions is weighted subroutine DumpGlobe if (QMeanSum.EQ.1) CallVariCode = 0 if (QMeanSum.EQ.2) CallVariCode = 2 do XDumpRegSet = 1, DumpRegSetN call PrepareRegions allocate (ArrayUM (YearN,SeasonN), & ArrayUA (YearN,SeasonN), & ArrayWM (YearN,SeasonN), & ArrayWA (YearN,SeasonN), & Weight1D (RegN), & Array1D (RegN), & Extract (BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGlobe: Allocation failure: Array2D #####" do XStat = 1, StatN if (DumpStat(XStat).EQ.1) then ArrayUM = MissVal ; ArrayUA = MissVal ; ArrayWM = MissVal ; ArrayWA = MissVal do XYear = 1, YearN do XSeason = 1, SeasonN call MakeBoxVector call MakeRegVector OpTotUM = 0.0 ; OpTotUA = 0 ; OpTotWM = 0.0 ; OpTotWA = 0 OpEn = 0.0 ; OpEnWei = 0.0 ; OpMiss = 0.0 ; OpMissWei = 0.0 do XReg = 1, RegN if (Array1D(XReg).NE.MissVal) then OpTotUM = OpTotUM + Array1D(XReg) OpTotUA = OpTotUA + abs(Array1D(XReg)) OpEn = OpEn + 1.0 if (Weight1D(XReg).NE.MissVal) then OpTotWM = OpTotWM + (Array1D(XReg)*Weight1D(XReg)) OpTotWA = OpTotWA + (abs(Array1D(XReg))*Weight1D(XReg)) OpEnWei = OpEnWei + Weight1D(XReg) else OpMissWei = OpMissWei + 1.0 end if else OpMiss = OpMiss + 1.0 if (Weight1D(XReg).NE.MissVal) then OpMissWei = OpMissWei + Weight1D(XReg) else OpMissWei = OpMissWei + 1.0 end if end if end do if (OpEn.GT.0) then if ((OpMiss/(OpEn+OpMiss)).LT.(MissAccept/100.0)) then ArrayUM (XYear,XSeason) = OpTotUM / OpEn ArrayUA (XYear,XSeason) = OpTotUA / OpEn end if end if if (OpEnWei.GT.0) then if ((OpMissWei/(OpEnWei+OpMissWei)).LT.(MissAccept/100.0)) then ArrayWM (XYear,XSeason) = OpTotWM / OpEnWei ArrayWA (XYear,XSeason) = OpTotWA / OpEnWei end if end if end do end do SaveStem = trim(TextDir) // StatsText(XStat) // "-" // trim(TextTarg) if (XStat.NE.2) SaveStem = trim(SaveStem) // "." // trim(TextPatt) SaveStem = trim(SaveStem) // "." // trim(TextRegSet(XDumpRegSet)) SaveTip = trim(CurrentExec%Name) // ".per" SaveFile = trim(SaveStem) // "-UM" // trim(SaveTip) call SavePer (SaveFile, YearAD, CallVariCode, AllData=ArrayUM, NoResponse=1) SaveFile = trim(SaveStem) // "-UA" // trim(SaveTip) call SavePer (SaveFile, YearAD, CallVariCode, AllData=ArrayUA, NoResponse=1) SaveFile = trim(SaveStem) // "-WM" // trim(SaveTip) call SavePer (SaveFile, YearAD, CallVariCode, AllData=ArrayWM, NoResponse=1) SaveFile = trim(SaveStem) // "-WA" // trim(SaveTip) call SavePer (SaveFile, YearAD, CallVariCode, AllData=ArrayWA, NoResponse=1) end if end do deallocate (MapIDLReg,RegSizes,RegNames,GloWeights,RegWeights,& ArrayUM,ArrayUA,ArrayWM,ArrayWA,Array1D,Weight1D,Extract, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpGlobe: Deallocation failure: Reg* #####" end do end subroutine DumpGlobe !******************************************************************************* subroutine PrepareRegions call LoadRefReg (DumpRegSet(XDumpRegSet),MapIDLReg,RegSizes,RegNames,ExeN=ExeN,WyeN=WyeN) RegN = size (RegNames) call GetGloWeights (ExeN,WyeN,GloWeights) allocate (RegWeights(RegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: PrepareRegions: Allocation failure: RegWeights #####" RegWeights = 0.0 do XExe = 1, ExeN do XWye = 1, WyeN if (MapIDLReg(XExe,XWye).NE.MissVal) then if (RegWeights(MapIDLReg(XExe,XWye)).NE.MissVal.AND.GloWeights(XExe,XWye).NE.MissVal) then RegWeights(MapIDLReg(XExe,XWye)) = RegWeights(MapIDLReg(XExe,XWye)) + GloWeights(XExe,XWye) else RegWeights(MapIDLReg(XExe,XWye)) = MissVal end if end if end do end do end subroutine PrepareRegions !******************************************************************************* subroutine MakeBoxVector Extract = MissVal if (XStat.EQ.1) then do XBox = 1, BoxN Extract (XBox) = Est (XYear,XSeason,XBox) end do else if (XStat.EQ.2) then do XBox = 1, BoxN Extract (XBox) = Mod (XYear,XSeason,XBox) end do else if (XStat.EQ.3) then do XBox = 1, BoxN if (Est(XYear,XSeason,XBox).NE.MissVal.AND.Mod(XYear,XSeason,XBox).NE.MissVal) & Extract (XBox) = Est(XYear,XSeason,XBox) - Mod(XYear,XSeason,XBox) end do end if end subroutine MakeBoxVector !******************************************************************************* subroutine MakeRegVector Array1D = 0.0 ; Weight1D = 0.0 do XExe = 1, ExeN do XWye = 1, WyeN if (MapIDLReg(XExe,XWye).NE.MissVal) then if (Grid(XExe,XWye).NE.MissVal.AND.GloWeights(XExe,XWye).NE.MissVal) then if (Extract(Grid(XExe,XWye)).NE.MissVal) then Array1D(MapIDLReg(XExe,XWye)) = Array1D(MapIDLReg(XExe,XWye)) + & (GloWeights(XExe,XWye)*Extract(Grid(XExe,XWye))) Weight1D(MapIDLReg(XExe,XWye)) = Weight1D(MapIDLReg(XExe,XWye)) + GloWeights(XExe,XWye) end if end if end if end do end do do XReg = 1, RegN if (Array1D(XReg).NE.MissVal) then if (Weight1D(XReg).GT.(RegWeights(XReg)*((100.0-MissAccept)/100.0))) then Array1D(XReg) = Array1D(XReg) / Weight1D(XReg) else Array1D(XReg) = MissVal end if end if end do end subroutine MakeRegVector !******************************************************************************* subroutine ResetCurrentExec do ! resets CurrentExec so that it points at first Exec if (associated(CurrentExec%Prev)) CurrentExec => CurrentExec%Prev if (.not.associated(CurrentExec%Prev)) exit end do end subroutine ResetCurrentExec !******************************************************************************* subroutine RemoveEstMod deallocate (Est, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: RemoveEstMod: Deallocation failure: Est #####" if (QCompare.EQ.1) then deallocate (Mod, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: RemoveEstMod: Deallocation failure: Mod #####" end if end subroutine RemoveEstMod !******************************************************************************* subroutine RemoveExecs call ResetCurrentExec do if (associated(CurrentExec%Next)) then ! set stack to next Exec... StackExec => CurrentExec%Next else ! ...or if no next Exec, nullify nullify (StackExec) end if deallocate (CurrentExec, stat=AllocStat) ! deallocate current Exec if (AllocStat.NE.0) print*, " > ##### ERROR: RemoveExecs: Deallocation failure: CurrentExec #####" if ( associated(StackExec)) CurrentExec => StackExec ! set current to next Exec... if (.not.associated(StackExec)) exit ! ....or exit end do end subroutine RemoveExecs !******************************************************************************* subroutine Finish deallocate (YearAD,DumpYear,DumpRegSet,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Finish: Deallocation failure #####" call RemoveExecs print* close (99) end subroutine Finish !******************************************************************************* end program ScalePattern