! signoi.f90 ! f90 main program written on 03.05.00 by Tim Mitchell ! last modification on 03.05.00 ! f90 -o signoi initialmod.f90 loadmod.f90 savemod.f90 transformmod.f90 signoi.f90 program SigNoi use InitialMod use LoadMod use SaveMod use TransformMod implicit none real, pointer, dimension (:,:,:) :: TimLoaded real, pointer, dimension (:,:) :: TimProc, LinToSave, FileSeries real, pointer, dimension (:) :: NoiseLoaded, Vectorised, GloToSave integer, pointer, dimension (:) :: WorkMapRawReg, WorkRegSizes integer, pointer, dimension (:) :: WorkADYear integer, pointer, dimension (:,:) :: WorkMapIDLRaw, WorkMapIDLReg character (len=80), pointer, dimension (:) :: FileRegNames, WorkRegNames real, parameter :: MissVal = -999.0 real :: YearThresh, RegThresh real :: WorkMissAccept real :: CalcEn, CalcTot real :: PerCentMiss, TotalMiss integer :: WorkGrid, WorkLongN, WorkLatN, WorkDataN, WorkRegN integer :: WorkMonth0, WorkMonth1, WorkMonthN, WorkYearN, WorkDecN integer :: WorkTimN, FileRegN, RegValidN integer :: AllocStat, ReadStatus integer :: XFile, XLin, XYear, XFind, XTim, XReg integer :: QMain, QMissAccept, QSliceify, QSave integer :: ExitCheck integer :: YearMissN integer :: SelectFile, SelectADYear, ChosenADYear, ChosenFileN character (len=10) :: WorkGridTitle character (len=80) :: WorkGridFilePath, WorkLinTitle, WorkRegTitle, WorkGloFilePath, Blank !******************************************************************************* ! main program Blank = "" call Initialise call GrabTim print*, " > We load the noise (RMSE sampling error) from .glo file." call LoadGlo (WorkLongN, WorkLatN, WorkRegN, WorkMapIDLReg, NoiseLoaded) open (99,file='/cru/u2/f709762/data/scratch/logsignoi.dat',access='sequential',status='replace',action='write') print*, " > Alter % acceptable missing (1=no,2=yes), currently: ", WorkMissAccept do read (*,*,iostat=ReadStatus), QMissAccept if (ReadStatus.LE.0.AND.QMissAccept.GE.1.AND.QMissAccept.LE.2) exit end do if (QMissAccept.EQ.2) call SetMissAccept (WorkMissAccept) print*, " > Transform regional series into 30-year slices ? (1=no,2=yes)" do read (*,*,iostat=ReadStatus), QSliceify if (ReadStatus.LE.0.AND.QSliceify.GE.1.AND.QSliceify.LE.2) exit end do if (QSliceify.EQ.2) call IntoSlices call CalcSignal print*, " > Save signals as .tim ? (1=no,2=yes)" do read (*,*,iostat=ReadStatus), QSave if (ReadStatus.LE.0.AND.QSave.GE.1.AND.QSave.LE.2) exit end do if (QSave.EQ.2) call SaveTimProc call CalcSignalNoise print*, " > Save signal-to-noise ratios as .tim ? (1=no,2=yes)" do read (*,*,iostat=ReadStatus), QSave if (ReadStatus.LE.0.AND.QSave.GE.1.AND.QSave.LE.2) exit end do if (QSave.EQ.2) call SaveTimProc print*, " > Save global av signal-to-noise ratios as .lin ? (1=no,2=yes)" do read (*,*,iostat=ReadStatus), QSave if (ReadStatus.LE.0.AND.QSave.GE.1.AND.QSave.LE.2) exit end do if (QSave.EQ.2) call SaveGlobalAv print*, " > Save single year signal-to-noise ratios as .glo ? (1=no,2=yes)" do read (*,*,iostat=ReadStatus), QSave if (ReadStatus.LE.0.AND.QSave.GE.1.AND.QSave.LE.2) exit end do if (QSave.EQ.2) call SaveOneYear deallocate (TimProc,WorkRegNames) print* close (99) contains !******************************************************************************* ! initialise subroutine Initialise print*, " > ***** Signal-to-Noise *****" print*, " > operates on .tim's provided noise is already in .glo" print* WorkMissAccept = 10.0 print*, " > Select parameters that will govern operations." call GridSelect (WorkGrid,WorkGridTitle,WorkLongN,WorkLatN,WorkDataN,WorkGridFilePath) call PeriodSelect (WorkYearN,WorkDecN,WorkADYear) call RegSelect (WorkGrid,WorkLongN,WorkLatN,WorkDataN,WorkMapIDLReg,WorkRegSizes,WorkRegNames,& WorkRegTitle,WorkRegN) end subroutine Initialise !******************************************************************************* ! load .tim subroutine GrabTim print*, " > Select the number of .tim files to load." do read (*,*,iostat=ReadStatus), WorkTimN if (ReadStatus.LE.0.AND.WorkTimN.GE.1) exit end do allocate (TimLoaded (WorkTimN,WorkRegN,WorkYearN), & WorkRegNames (WorkRegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GrabTim: Allocation failure #####" TimLoaded = MissVal WorkRegNames = "blank" do XTim = 1, WorkTimN print*, " > File number : ", XTim do call LoadTim (WorkYearN,WorkADYear,FileRegN,FileRegNames,FileSeries) if (FileRegN.NE.WorkRegN) then print*, " > ##### Incorrect no. of regions in file. Try again #####" ExitCheck = 1 deallocate (FileRegNames,FileSeries,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Deallocation failure #####" else ExitCheck = 0 end if if (ExitCheck.EQ.0) exit end do do XReg = 1, WorkRegN WorkRegNames (XReg) = FileRegNames (XReg) do XYear = 1, WorkYearN TimLoaded (XTim,XReg,XYear) = FileSeries (XReg,XYear) end do end do deallocate (FileRegNames,FileSeries,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GrabTim: Deallocation failure #####" end do TotalMiss = 0.0 do XTim = 1, WorkTimN do XReg = 1, WorkRegN do XYear = 1, WorkYearN if (TimLoaded(XTim,XReg,XYear).EQ.MissVal) TotalMiss = TotalMiss + 1.0 end do end do end do PerCentMiss = 100.0 * TotalMiss / (WorkTimN*WorkRegN*WorkYearN) print "(a38,f8.2)", " > After loading: percentage missing: ", PerCentMiss end subroutine GrabTim !******************************************************************************* ! sliceifying into 30y slices subroutine IntoSlices print*, " > Sliceifying each file and region individually..." allocate (Vectorised (WorkYearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: IntoSlices: Allocation failure #####" do XTim = 1, WorkTimN do XReg = 1, WorkRegN do XYear = 1, WorkYearN Vectorised (XYear) = TimLoaded (XTim,XReg,XYear) end do call SimpleSlice (WorkYearN,30,WorkMissAccept,Vectorised) do XYear = 1, WorkYearN TimLoaded (XTim,XReg,XYear) = Vectorised (XYear) end do end do if (WorkTimN.GT.1) print*, " > Have slicified file: ", XTim end do deallocate (Vectorised, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: IntoSlices: Deallocation failure #####" TotalMiss = 0.0 do XTim = 1, WorkTimN do XReg = 1, WorkRegN do XYear = 1, WorkYearN if (TimLoaded(XTim,XReg,XYear).EQ.MissVal) TotalMiss = TotalMiss + 1.0 end do end do end do PerCentMiss = 100.0 * TotalMiss / (WorkTimN*WorkRegN*WorkYearN) print "(a42,f8.2)", " > After sliceifying: percentage missing: ", PerCentMiss end subroutine IntoSlices !******************************************************************************* ! calcs signal RMSE subroutine CalcSignal print*, " > Calculating signals..." allocate (TimProc (WorkRegN,WorkYearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CalcSignal: Allocation failure #####" TimProc = MissVal RegThresh = real(WorkTimN)*(100.0-WorkMissAccept)/100.0 do XYear = 1, WorkYearN do XReg = 1, WorkRegN CalcEn = 0.0 CalcTot = 0.0 do XTim = 1, WorkTimN if (TimLoaded(XTim,XReg,XYear).NE.MissVal) then CalcEn = CalcEn + 1.0 CalcTot = CalcTot + (TimLoaded (XTim,XReg,XYear) ** 2) endif end do if (CalcEn.GE.RegThresh) then TimProc(XReg,XYear) = CalcTot / CalcEn TimProc(XReg,XYear) = sqrt (TimProc(XReg,XYear)) end if end do end do deallocate (TimLoaded, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CalcSignal: Deallocation failure #####" TotalMiss = 0.0 do XReg = 1, WorkRegN do XYear = 1, WorkYearN if (TimProc(XReg,XYear).EQ.MissVal) TotalMiss = TotalMiss + 1.0 end do end do PerCentMiss = 100.0 * TotalMiss / (WorkRegN*WorkYearN) print "(a41,f8.2)", " > After signalling: percentage missing: ", PerCentMiss end subroutine CalcSignal !******************************************************************************* ! calcs signal-to-noise ratios subroutine CalcSignalNoise print*, " > Dividing signals by noise..." do XReg = 1, WorkRegN do XYear = 1, WorkYearN if (TimProc(XReg,XYear).NE.MissVal) then if (NoiseLoaded(XReg).NE.MissVal) then TimProc(XReg,XYear) = TimProc(XReg,XYear) / NoiseLoaded(XReg) else TimProc(XReg,XYear) = MissVal end if end if end do end do TotalMiss = 0.0 do XReg = 1, WorkRegN do XYear = 1, WorkYearN if (TimProc(XReg,XYear).EQ.MissVal) TotalMiss = TotalMiss + 1.0 end do end do PerCentMiss = 100.0 * TotalMiss / (WorkRegN*WorkYearN) print "(a38,f8.2)", " > After noising: percentage missing: ", PerCentMiss end subroutine CalcSignalNoise !******************************************************************************* ! save TimProc to .tim subroutine SaveTimProc print*, " > Enter the .tim file title: " do read (*,*,iostat=ReadStatus), WorkLinTitle if (ReadStatus.LE.0.AND.WorkLinTitle.NE."") exit end do call SaveTim (WorkRegN, WorkYearN, Blank, Blank, WorkRegNames, WorkADYear, TimProc) end subroutine SaveTimProc !******************************************************************************* ! save global average to .lin subroutine SaveGlobalAv print*, " > Globally averaging..." allocate (LinToSave (1,WorkYearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: SaveGlobalAv: Allocation failure #####" LinToSave = MissVal YearThresh = real(WorkYearN)*(100.0-WorkMissAccept)/100.0 do XYear = 1, WorkYearN CalcEn = 0.0 CalcTot = 0.0 do XReg = 1, WorkRegN if (TimProc(XReg,XYear).NE.MissVal) then CalcEn = CalcEn + 1.0 CalcTot = CalcTot + TimProc(XReg,XYear) end if if (CalcEn.GE.YearThresh) LinToSave (1,XYear) = CalcTot / CalcEn end do end do TotalMiss = 0.0 do XYear = 1, WorkYearN if (LinToSave(1,XYear).EQ.MissVal) TotalMiss = TotalMiss + 1.0 end do PerCentMiss = 100.0 * TotalMiss / WorkYearN print "(a41,f8.2)", " > After globalling: percentage missing: ", PerCentMiss call SaveLin (1,WorkYearN,WorkRegNames,WorkADYear,LinToSave) deallocate (LinToSave,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: SaveGlobalAv: Deallocation failure #####" end subroutine SaveGlobalAv !******************************************************************************* ! save global slice for single year subroutine SaveOneYear allocate (GloToSave (WorkRegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: SaveOneYear: Allocation failure #####" GloToSave = 0 ChosenADYear = 0 do do print*, " > Enter the year AD (-99=end): " do read (*,*,iostat=ReadStatus), SelectADYear if (ReadStatus.LE.0) exit end do if (SelectADYear.NE.-99) then do XYear = 1, WorkYearN if (WorkADYear(XYear).EQ.SelectADYear) ChosenADYear = XYear end do else ChosenADYear = 1 end if if (ChosenADYear.EQ.0) print*, " > Year out of range. Try again." if (ChosenADYear.GE.1) exit end do if (SelectADYear.NE.-99) then do XReg = 1, WorkRegN GloToSave(XReg) = TimProc(XReg,ChosenADYear) end do print*, " > Enter the .glo file title: " do read (*,*,iostat=ReadStatus), WorkLinTitle if (ReadStatus.LE.0.AND.WorkLinTitle.NE."") exit end do call SaveGlo (WorkLongN,WorkLatN,WorkRegN,WorkGridFilePath,Blank,Blank,GloToSave,WorkMapIDLReg) end if if (SelectADYear.EQ.-99) exit end do deallocate (GloToSave,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: SaveOneYear: Deallocation failure #####" end subroutine SaveOneYear !******************************************************************************* end program SigNoi