! qcclimatt.f90 ! program to Quality Control the CLIMAT extra Temperature data supplied directly from Hadley ! written by Dr. Tim Mitchell (Tyndall Centre) on 21.01.02 ! last modified on 22.02.02 ! f90 -o ./../obs/qcclimatt filenames.f90 crutsfiles.f90 wmokey.f90 ./../obs/qcclimatt.f90 program QCClimatT use FileNames use CRUtsFiles use WMOkey implicit none real, pointer, dimension (:,:,:) :: Raw real, pointer, dimension (:,:) :: PhilMeans,PhilSigma real, pointer, dimension (:) :: Lat,Long,Elev real, dimension (7) :: ClassBounds = [0.005,0.105,0.305,0.505,0.805,0.995,1.005] integer, pointer, dimension (:,:,:) :: DTR integer, pointer, dimension (:,:,:) :: CtyRaw,CtyQC,RawQC,RegQC,BitQC integer, pointer, dimension (:,:) :: Station,RegInfo,CheckRaw,SumQC,StnQC,StnInfo,RawTime,PreQCTime integer, pointer, dimension (:) :: CheckStn,CtyBound0,CtyBound1,CtyReg integer, pointer, dimension (:) :: PhilMeansStn,PhilMeansYr0,PhilMeansYr1 integer, pointer, dimension (:) :: PhilSigmaStn,PhilSigmaYr0,PhilSigmaYr1 integer, pointer, dimension (:) :: FileLines,YearAD,Code integer, dimension (16) :: LineInfo,LastInfo integer, dimension (12) :: PhilInfo character (len=80), pointer, dimension (:) :: ClimatTFiles,StepText,BitText character (len=20), pointer, dimension (:) :: NameStn character (len=13), pointer, dimension (:) :: NameCty,CtyName character (len=02), pointer, dimension (:) :: CtyAcro real, parameter :: FileMissVal = -32768.0 real, parameter :: DataMissVal = -9999.0 real, parameter :: MissVal = -999.0 character (len=80), parameter :: Blank = " " real :: AvMinMax,OpFraction real :: KSigmas,KPJThresh integer :: ReadStatus, AllocStat integer :: RawFileN, LineN, StationN, CheckStnN, CtyN, InfoN, MonthN, YearN, RegN, StepN, BitN integer :: XRawFile, XLine, XStation, XCheckStn, XCty, XInfo, XMonth, XYear, XReg, XStep, XBit integer :: PhilMeansN,PhilSigmaN, ClassN integer :: XPhilMeans,XPhilSigma, XClass integer :: ThisCty, OpTot, OpMiss integer :: WMOStation, WMOBlock, WMOCode integer :: QRepeatEntry,QRepeatMonth,QRepeatReport,QOneMissVal character (len=80) :: ClimatTFilter = "/cru/mikeh1/f709762/obs/climat/_raw/????.dat" character (len=80) :: PhilMeansFile = "/cru/mikeh1/f709762/obs/philj/pjones-stn-tmean-norms.dat" character (len=80) :: PhilSigmaFile = "/cru/mikeh1/f709762/obs/philj/pjones-stn-tmean-sigma.dat" character (len=80) :: Trash !******************************************************************************* call Intro call GetCtyBounds call GetPhilJones call GetFileSpecs call AllocArrays print*, " > Loading and QC'ing data..." do XRawFile = 1, RawFileN LineN = FileLines(XRawFile) call LoadRaw call QualityControl call SummStn call EndRawFile end do print*, " > Summarising results..." call DumpRawInfo call DumpQCInfo call DumpData call Conclude contains !******************************************************************************* subroutine Intro open (99,file="/cru/mikeh1/f709762/scratch/log/log-qcclimatt.dat",status="replace",action="write") print* print*, " > ***** QCClimatT: QC on extra CLIMAT Temperature data *****" print* KSigmas = 5.0 ; KPJThresh = 1.0 * 10.0 ! KPJThresh is *10 to allow for degC*10 QOneMissVal = 1 ! 0=allow -8000series missing values, 1=-9999 only call GetBatch (ClimatTFilter,ClimatTFiles) ! locate raw extra CLIMAT T data files RawFileN = size (ClimatTFiles,1) allocate (YearAD(RawFileN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Intro: Allocation failure #####" do XRawFile = 1, RawFileN YearAD(XRawFile) = 1995 + XRawFile - 1 end do MonthN = 12 ; RegN = 12 ; StepN = 11 ; BitN = 16 ; ClassN = 7 end subroutine Intro !******************************************************************************* subroutine GetCtyBounds print*, " > Getting country information..." call LoadWMOCty (CtyBound0,CtyBound1,CtyAcro,CtyReg,CtyName,ExtraCty=1) CtyN = size(CtyBound0) - 1 CtyName(CtyN+1) = "unidentified" ; CtyReg(CtyN+1) = 12 allocate (CtyRaw (RawFileN,MonthN,CtyN+1), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GetCtyBounds: Allocation failure: CtyRaw #####" CtyRaw=0 end subroutine GetCtyBounds !******************************************************************************* subroutine GetPhilJones print*, " > Getting Phil Jones' information..." call system ('wc -l ' // trim(PhilMeansFile) // ' > trashme-pj.txt') open (3,file='trashme-pj.txt',status="old",access="sequential",form="formatted",action="read") read (3,"(i10)"), PhilMeansN ! get number of lines close (3) call system ('rm trashme-pj.txt') allocate (PhilMeansYr0 (PhilMeansN), & PhilMeansYr1 (PhilMeansN), & PhilMeansStn (PhilMeansN), & PhilMeans (PhilMeansN,12),stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GetPhilJones: Allocation failure: PhilMeans* #####" open (3,file=PhilMeansFile,status="old",access="sequential",form="formatted",action="read") do XPhilMeans = 1, PhilMeansN read (3,"(i6,a10,2i5,12i5)"),PhilMeansStn(XPhilMeans),Trash,PhilMeansYr0(XPhilMeans), & PhilMeansYr1(XPhilMeans), (PhilInfo(XInfo),XInfo=1,MonthN) do XMonth = 1, MonthN PhilMeans(XPhilMeans,XMonth) = real(PhilInfo(XMonth)) end do end do close (3) call system ('wc -l ' // trim(PhilSigmaFile) // ' > trashme-pj.txt') open (3,file='trashme-pj.txt',status="old",access="sequential",form="formatted",action="read") read (3,"(i10)"), PhilSigmaN ! get number of lines close (3) call system ('rm trashme-pj.txt') allocate (PhilSigmaYr0 (PhilSigmaN), & PhilSigmaYr1 (PhilSigmaN), & PhilSigmaStn (PhilSigmaN), & PhilSigma (PhilSigmaN,12),stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GetPhilJones: Allocation failure: PhilSigma* #####" open (3,file=PhilSigmaFile,status="old",access="sequential",form="formatted",action="read") do XPhilSigma = 1, PhilSigmaN read (3,"(i6,a10,2i5,12i5)"),PhilSigmaStn(XPhilSigma),Trash,PhilSigmaYr0(XPhilSigma), & PhilSigmaYr1(XPhilSigma), (PhilInfo(XInfo),XInfo=1,MonthN) do XMonth = 1, MonthN PhilSigma(XPhilSigma,XMonth) = real(PhilInfo(XMonth)) end do end do close (3) end subroutine GetPhilJones !******************************************************************************* subroutine GetFileSpecs print*, " > Identifying file specifications..." CheckStnN = 1000000 allocate (CheckStn (CheckStnN), & FileLines (RawFileN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GetFileSpecs: Allocation failure: CheckStn #####" CheckStn = 0 ; FileLines = 0 ; StationN = 0 do XRawFile = 1, RawFileN call system ('wc -l ' // trim(ClimatTFiles(XRawFile)) // ' > trashme-gfs.txt') open (3,file='trashme-gfs.txt',status="old",access="sequential",form="formatted",action="read") read (3,"(i10)"), FileLines(XRawFile) ! get number of lines close (3) call system ('rm trashme-gfs.txt') open (3,file=ClimatTFiles(XRawFile),status="old",access="sequential",form="formatted",action="read") do XLine = 1, FileLines(XRawFile) read (3,"(a12,2i6)"), Trash, WMOBlock, WMOStation WMOCode = (WMOBlock * 10000) + WMOStation CheckStn(WMOCode) = CheckStn(WMOCode) + 1 ! store existence of station/month if (CheckStn(WMOCode).EQ.1) StationN = StationN + 1 end do close (3) end do print*, " > WMO stations in files total: ", StationN allocate (Station (StationN,4), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GetFileSpecs: Allocation failure: Station #####" Station = MissVal ! 1=WMO-stn,2=cty-index,3=PhilJ-mean-index,4=PhilJ-sigma-index XStation = 0 do XCheckStn = 1, CheckStnN if (CheckStn(XCheckStn).GT.0) then XStation = XStation + 1 Station(XStation,1) = XCheckStn call LocateStn Station(XStation,2) = ThisCty XPhilMeans = 0 do XPhilMeans = XPhilMeans + 1 if (PhilMeansStn(XPhilMeans).EQ.XCheckStn) Station(XStation,3) = XPhilMeans if (PhilMeansStn(XPhilMeans).GT.XCheckStn) exit if (XPhilMeans.EQ.PhilMeansN) exit end do XPhilSigma = 0 do XPhilSigma = XPhilSigma + 1 if (PhilSigmaStn(XPhilSigma).EQ.XCheckStn) Station(XStation,4) = XPhilSigma if (PhilSigmaStn(XPhilSigma).GT.XCheckStn) exit if (XPhilSigma.EQ.PhilSigmaN) exit end do end if end do deallocate (CheckStn,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GetFileSpecs: Deallocation failure: CheckStn #####" end subroutine GetFileSpecs !******************************************************************************* subroutine AllocArrays print*, " > Allocating arrays..." allocate (RegQC (RawFileN,RegN,StepN), & BitQC (RawFileN,StepN,0:BitN-1),& StepText (StepN), & BitText (StepN), & CheckRaw (RawFileN,5), & StnQC (RawFileN+1,ClassN+1), & RawTime (RawFileN,MonthN), & PreQCTime (RawFileN,MonthN+1), & DTR (RawFileN,MonthN,StationN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: AllocArrays: Allocation failure #####" RegQC=0 ; BitQC=0 ; CheckRaw=0 ; StepText=Blank ; BitText=Blank ; StnQC = 0 ; DTR = DataMissVal RawTime=0 ; PreQCTime=0 end subroutine AllocArrays !******************************************************************************* subroutine LoadRaw allocate (Raw (MonthN,StationN,16), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadRaw: Allocation failure: Raw #####" Raw = MissVal open (3,file=ClimatTFiles(XRawFile),status="old",access="sequential",form="formatted",action="read") XStation = 1 do XLine = 1, LineN read (3,"(20i6)"), XYear,XMonth,WMOBlock,WMOStation,(LineInfo(XInfo),XInfo=1,16) CheckRaw (XRawFile,1) = CheckRaw (XRawFile,1) + 1 if (XMonth.GE.1.AND.XMonth.LE.12) then PreQCTime (XRawFile,XMonth) = PreQCTime (XRawFile,XMonth) + 1 WMOCode = (WMOBlock * 10000) + WMOStation ! identify WMO code do ! identify XStation if (WMOCode.EQ.Station(XStation,1)) exit if (WMOCode.NE.Station(XStation,1)) XStation = XStation + 1 if (XStation.GT.StationN) XStation = 1 end do if (Raw(XMonth,XStation,1).NE.MissVal) then CheckRaw (XRawFile,3) = CheckRaw (XRawFile,3) + 1 QRepeatEntry = 0 QRepeatReport = 1 else QRepeatEntry = 1 ; QRepeatReport = 0 ; XInfo = 0 do XInfo = XInfo + 1 if (LineInfo(XInfo).NE.LastInfo(XInfo)) QRepeatEntry = 0 if (XInfo.EQ.16.OR.QRepeatEntry.EQ.0) exit end do end if if (XMonth.GT.1) then QRepeatMonth = 1 ; XInfo = 0 do XInfo = XInfo + 1 if (real(LineInfo(XInfo)).NE.Raw((XMonth-1),XStation,XInfo)) QRepeatMonth = 0 if (XInfo.EQ.16.OR.QRepeatMonth.EQ.0) exit end do else QRepeatMonth = 0 end if if (QRepeatEntry.EQ.0.AND.QRepeatMonth.EQ.0) then do XInfo = 1, 16 ! store data for station-month Raw (XMonth,XStation,XInfo) = real(LineInfo(XInfo)) end do ! register station-month if (QRepeatReport.EQ.0) then RawTime(XRawFile,XMonth) = RawTime(XRawFile,XMonth) + 1 CtyRaw (XRawFile,XMonth,Station(XStation,2)) = CtyRaw (XRawFile,XMonth,Station(XStation,2)) + 1 CheckRaw (XRawFile,5) = CheckRaw (XRawFile,5) + 1 end if else if (QRepeatReport.EQ.0) CheckRaw (XRawFile,4) = CheckRaw (XRawFile,4) + 1 end if else PreQCTime (XRawFile,13) = PreQCTime (XRawFile,13) + 1 CheckRaw (XRawFile,2) = CheckRaw (XRawFile,2) + 1 end if LastInfo = LineInfo end do close (3) allocate (RawQC (MonthN,StationN,StepN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadRaw: Allocation failure: RawQC #####" RawQC = MissVal end subroutine LoadRaw !******************************************************************************* subroutine SummStn do XStation = 1, StationN OpTot = 0 ; OpMiss = 0 do XMonth = 1, MonthN if (RawQC(XMonth,XStation,1).NE.MissVal) then OpTot = OpTot + 1 ! if (RawQC(XMonth,XStation,1).GT.0.OR.RawQC(XMonth,XStation,3).GT.0.OR.RawQC(XMonth,XStation,4).GT.0.OR.& ! RawQC(XMonth,XStation,7).GT.0.OR.RawQC(XMonth,XStation,9).GT.0.OR.RawQC(XMonth,XStation,11).GT.0) then ! OpMiss = OpMiss + 1 ! else ! DTR (XRawFile,XMonth,XStation) = nint((Raw(XMonth,XStation,9)-Raw(XMonth,XStation,13))) ! end if if (RawQC(XMonth,XStation, 1).GT.0) then DTR (XRawFile,XMonth,XStation) = -8100 - RawQC(XMonth,XStation, 1) else if (RawQC(XMonth,XStation, 3).GT.0) then DTR (XRawFile,XMonth,XStation) = -8200 - RawQC(XMonth,XStation, 3) else if (RawQC(XMonth,XStation, 4).GT.0) then DTR (XRawFile,XMonth,XStation) = -8300 - RawQC(XMonth,XStation, 4) else if (RawQC(XMonth,XStation, 7).GT.0) then DTR (XRawFile,XMonth,XStation) = -8400 - RawQC(XMonth,XStation, 7) else if (RawQC(XMonth,XStation, 9).GT.0) then DTR (XRawFile,XMonth,XStation) = -8500 - RawQC(XMonth,XStation, 9) else if (RawQC(XMonth,XStation,11).GT.0) then DTR (XRawFile,XMonth,XStation) = -8600 - RawQC(XMonth,XStation,11) else DTR (XRawFile,XMonth,XStation) = nint((Raw(XMonth,XStation,9)-Raw(XMonth,XStation,13))) end if if (QOneMissVal.EQ.1.AND.DTR(XRawFile,XMonth,XStation).LT.-8000) DTR(XRawFile,XMonth,XStation)=DataMissVal end if end do if (OpTot.GT.0) then if (OpMiss.GT.0) then OpFraction = real(OpMiss) / real(OpTot) else OpFraction = 0.0 end if XClass = 0 do XClass = XClass + 1 if (OpFraction.LT.ClassBounds(XClass)) StnQC(XRawFile,XClass) = StnQC(XRawFile,XClass) + 1 if (OpFraction.LT.ClassBounds(XClass)) exit if (XClass.EQ.ClassN) exit end do end if end do end subroutine SummStn !******************************************************************************* subroutine EndRawFile deallocate (Raw,RawQC, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: EndRawFile: Deallocation failure #####" end subroutine EndRawFile !******************************************************************************* subroutine QualityControl do XMonth = 1, MonthN do XStation = 1, StationN if (Raw(XMonth,XStation,1).NE.MissVal) then call Step1 StepText(1) = "rejected if any of Tmean,Tmin,Tmax are missing" BitQC(XRawFile,1,RawQC(XMonth,XStation,1)) = BitQC(XRawFile,1,RawQC(XMonth,XStation,1)) + 1 BitText(1) = "missing obs: 1=mean,2=min,4=max [fatal]" if (RawQC(XMonth,XStation,1).GT.0) then RegQC(XRawFile,CtyReg(Station(XStation,2)),1) = RegQC(XRawFile,CtyReg(Station(XStation,2)),1) + 1 else call Step2 StepText(2) = "no rejections" BitQC(XRawFile,2,RawQC(XMonth,XStation,2)) = BitQC(XRawFile,2,RawQC(XMonth,XStation,2)) + 1 BitText(2) = "missing days: 1=mean,2=min,4=max [not fatal]" if (RawQC(XMonth,XStation,2).LT.7) then call Step3 StepText(3) = "rejected if any 'days count' for Tmean,Tmin,Tmax is present and <15" BitQC(XRawFile,3,RawQC(XMonth,XStation,3)) = BitQC(XRawFile,3,RawQC(XMonth,XStation,3)) + 1 BitText(3) = "days<15: 1=mean,2=min,4=max [>0 is fatal]" if (RawQC(XMonth,XStation,3).GT.0) then RegQC(XRawFile,CtyReg(Station(XStation,2)),3) = RegQC(XRawFile,CtyReg(Station(XStation,2)),3) + 1 end if end if if (RawQC(XMonth,XStation,3).LE.0) then call Step4 StepText(4) = "rejected unless min step8..." ! ################################# RawQC(XMonth,XStation,8) = 0 if (Raw(XMonth,XStation,1).NE.FileMissVal.AND.Raw(XMonth,XStation,2).NE.FileMissVal.AND. & (Raw(XMonth,XStation,2)-Raw(XMonth,XStation,1)).GE.14) then if (Station(XStation,3).NE.MissVal) then if (PhilMeans(Station(XStation,3),XMonth).EQ.MissVal.OR. & PhilMeansYr0(Station(XStation,3)).EQ.MissVal.OR.PhilMeansYr1(Station(XStation,3)).EQ.MissVal) then RawQC(XMonth,XStation,8) = RawQC(XMonth,XStation,8) + 1 else if ((PhilMeansYr1(Station(XStation,3))-PhilMeansYr0(Station(XStation,3))).LT.14) then RawQC(XMonth,XStation,8) = RawQC(XMonth,XStation,8) + 1 else if (Raw(XMonth,XStation,7).NE.FileMissVal) then if (Raw(XMonth,XStation,8).EQ.FileMissVal.OR.Raw(XMonth,XStation,8).GE.15) then if ((Raw(XMonth,XStation,1)+1900.0).NE.PhilMeansYr0(Station(XStation,3)).OR. & (Raw(XMonth,XStation,2)+1900.0).NE.PhilMeansYr1(Station(XStation,3))) then RawQC(XMonth,XStation,8) = RawQC(XMonth,XStation,8) + 1 end if else RawQC(XMonth,XStation,8) = RawQC(XMonth,XStation,8) + 1 end if else RawQC(XMonth,XStation,8) = RawQC(XMonth,XStation,8) + 1 end if end if end if else RawQC(XMonth,XStation,8) = RawQC(XMonth,XStation,8) + 1 end if if (Station(XStation,4).NE.MissVal) then if (PhilSigma(Station(XStation,4),XMonth).EQ.MissVal.OR. & PhilSigmaYr0(Station(XStation,4)).EQ.MissVal.OR.PhilSigmaYr1(Station(XStation,4)).EQ.MissVal) then RawQC(XMonth,XStation,8) = RawQC(XMonth,XStation,8) + 2 else if ((PhilSigmaYr1(Station(XStation,4))-PhilSigmaYr0(Station(XStation,4))).LT.14) then RawQC(XMonth,XStation,8) = RawQC(XMonth,XStation,8) + 2 else if (Raw(XMonth,XStation,6).NE.FileMissVal) then if (Raw(XMonth,XStation,8).EQ.FileMissVal.OR.Raw(XMonth,XStation,8).GE.15) then if ((Raw(XMonth,XStation,1)+1900.0).NE.PhilSigmaYr0(Station(XStation,4)).OR. & (Raw(XMonth,XStation,2)+1900.0).NE.PhilSigmaYr1(Station(XStation,4))) then RawQC(XMonth,XStation,8) = RawQC(XMonth,XStation,8) + 2 end if else RawQC(XMonth,XStation,8) = RawQC(XMonth,XStation,8) + 2 end if else RawQC(XMonth,XStation,8) = RawQC(XMonth,XStation,8) + 2 end if end if end if else RawQC(XMonth,XStation,8) = RawQC(XMonth,XStation,8) + 2 end if else RawQC(XMonth,XStation,8) = RawQC(XMonth,XStation,8) + 3 end if !print*, " > end" ! ################################# end subroutine Step8 !******************************************************************************* ! make the comparison between between PhilJ and CLIMAT+ normal or sigma subroutine Step9 !print*, " > step9..." ! ################################# RawQC(XMonth,XStation,9) = 0 if (RawQC(XMonth,XStation,8).NE.1.AND. & abs(Raw(XMonth,XStation,7)-PhilMeans(Station(XStation,3),XMonth)).GT.KPJThresh) & RawQC(XMonth,XStation,9) = RawQC(XMonth,XStation,9) + 1 if (RawQC(XMonth,XStation,8).NE.2.AND. & abs(Raw(XMonth,XStation,6)-PhilSigma(Station(XStation,4),XMonth)).GT.KPJThresh) & RawQC(XMonth,XStation,9) = RawQC(XMonth,XStation,9) + 2 !print*, " > end" ! ################################# end subroutine Step9 !******************************************************************************* ! can we use PhilJ sigma to compare CLIMAT+ values with normals ? subroutine Step10 !print*, " > step10..." ! ################################# !print*, XMonth,XStation !print*, Station(XStation,4),PhilSigma(Station(XStation,4),XMonth) !print*, PhilSigmaYr1(Station(XStation,4)),PhilSigmaYr0(Station(XStation,4)) RawQC(XMonth,XStation,10) = 0 if (Station(XStation,4).EQ.MissVal) then RawQC(XMonth,XStation,10) = RawQC(XMonth,XStation,10) + 7 else if (PhilSigma(Station(XStation,4),XMonth).EQ.MissVal.OR. & (PhilSigmaYr1(Station(XStation,4))-PhilSigmaYr0(Station(XStation,4))).LT.14) then RawQC(XMonth,XStation,10) = RawQC(XMonth,XStation,10) + 7 else if (Station(XStation,3).EQ.MissVal) then RawQC(XMonth,XStation,10) = RawQC(XMonth,XStation,10) + 1 else if (PhilMeans(Station(XStation,3),XMonth).EQ.MissVal.OR. & (PhilMeansYr1(Station(XStation,3))-PhilMeansYr0(Station(XStation,3))).LT.14) then RawQC(XMonth,XStation,10) = RawQC(XMonth,XStation,10) + 1 end if end if if (Raw(XMonth,XStation,1).EQ.FileMissVal.OR.Raw(XMonth,XStation,2).EQ.FileMissVal.OR. & (Raw(XMonth,XStation,2)-Raw(XMonth,XStation,1)).GE.14) then if (Raw(XMonth,XStation,14).NE.FileMissVal) then if (Raw(XMonth,XStation,12).NE.FileMissVal.AND.Raw(XMonth,XStation,12).LT.15) & RawQC(XMonth,XStation,10) = RawQC(XMonth,XStation,10) + 2 else RawQC(XMonth,XStation,10) = RawQC(XMonth,XStation,10) + 2 end if if (Raw(XMonth,XStation,11).NE.FileMissVal) then if (Raw(XMonth,XStation,12).NE.FileMissVal.AND.Raw(XMonth,XStation,12).LT.15) & RawQC(XMonth,XStation,10) = RawQC(XMonth,XStation,10) + 4 else RawQC(XMonth,XStation,10) = RawQC(XMonth,XStation,10) + 4 end if else RawQC(XMonth,XStation,10) = RawQC(XMonth,XStation,10) + 6 end if end if end if !print*, " > end" ! ################################# end subroutine Step10 !******************************************************************************* ! we use PhilJ sigma to compare CLIMAT+ values with normals subroutine Step11 !print*, " > step11..." ! ################################# RawQC(XMonth,XStation,11) = 0 if (RawQC(XMonth,XStation,10).NE.1.AND.RawQC(XMonth,XStation,10).NE.3.AND.RawQC(XMonth,XStation,10).NE.5) then if (Raw(XMonth,XStation, 4).LT.(PhilMeans(Station(XStation,3),XMonth)-(PhilSigma(Station(XStation,4),XMonth)*KSigmas)) .OR. & Raw(XMonth,XStation, 4).GT.(PhilMeans(Station(XStation,3),XMonth)+(PhilSigma(Station(XStation,4),XMonth)*KSigmas))) & RawQC(XMonth,XStation,11) = RawQC(XMonth,XStation,11) + 1 end if if (RawQC(XMonth,XStation,10).NE.2.AND.RawQC(XMonth,XStation,10).NE.3.AND.RawQC(XMonth,XStation,10).NE.6) then if (Raw(XMonth,XStation,13).LT.(Raw(XMonth,XStation,14)-(PhilSigma(Station(XStation,4),XMonth)*KSigmas)) .OR. & Raw(XMonth,XStation,13).GT.(Raw(XMonth,XStation,14)+(PhilSigma(Station(XStation,4),XMonth)*KSigmas))) & RawQC(XMonth,XStation,11) = RawQC(XMonth,XStation,11) + 2 end if if (RawQC(XMonth,XStation,10).NE.4.AND.RawQC(XMonth,XStation,10).NE.5.AND.RawQC(XMonth,XStation,10).NE.6) then if (Raw(XMonth,XStation, 9).LT.(Raw(XMonth,XStation,11)-(PhilSigma(Station(XStation,4),XMonth)*KSigmas)) .OR. & Raw(XMonth,XStation, 9).GT.(Raw(XMonth,XStation,11)+(PhilSigma(Station(XStation,4),XMonth)*KSigmas))) & RawQC(XMonth,XStation,11) = RawQC(XMonth,XStation,11) + 4 end if !print*, " > end" ! ################################# end subroutine Step11 !******************************************************************************* subroutine DumpRawInfo write (99,*), "Summary table of raw data in file, by year/month: " write (99,"(a)"), " Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ???" do XRawFile = 1, RawFileN write (99,"(i5,13i5)"), XRawFile, (PreQCTime(XRawFile,XMonth),XMonth=1,13) end do write (99,*) write (99,*), "Summary table of raw data in file, by pre-QC category: " write (99,"(a)"), " Year Lines NoMon n*Mon n*Inf Valid" do XRawFile = 1, RawFileN write (99,"(i5,5i6)"), XRawFile, (CheckRaw(XRawFile,XInfo),XInfo=1,5) end do write (99,*) write (99,*), "Summary table of valid data in file, by year/month: " write (99,"(a)"), " Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec" do XRawFile = 1, RawFileN write (99,"(i5,12i5)"), XRawFile, (RawTime(XRawFile,XMonth),XMonth=1,12) end do write (99,*) allocate (RegInfo (RawFileN,RegN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpRawInfo: Allocation failure: RegInfo #####" RegInfo = 0 write (99,*), "Summary table of raw loaded data: " write (99,*), "Year Euro USSR MidE Asia Afri NAme CAme SAme Anta Ocea Buoy Misc TOT" do XRawFile = 1, RawFileN do XCty = 1, (CtyN+1) do XMonth = 1, MonthN RegInfo(XRawFile,CtyReg(XCty)) = RegInfo(XRawFile,CtyReg(XCty)) + CtyRaw(XRawFile,XMonth,XCty) end do end do OpTot = 0 do XReg = 1, RegN OpTot = OpTot + RegInfo(XRawFile,XReg) end do write (99,"(i5,12i5,i6)"), XRawFile, (RegInfo(XRawFile,XReg),XReg=1,RegN), OpTot end do write (99,*) deallocate (RegInfo,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpRawInfo: Deallocation failure: RegInfo #####" end subroutine DumpRawInfo !******************************************************************************* subroutine DumpQCInfo allocate (SumQC (RegN,StepN+1), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpQCInfo: Allocation failure: SumQC 1 #####" SumQC = 0 write (99,*), "Summary table of all data rejected." write (99,"(a)"), " Step Euro USSR MidE Asia Afri NAme CAme SAme Anta Ocea Buoy Misc TOT" do XStep = 1, StepN OpTot = 0 do XReg = 1, RegN do XRawFile = 1, RawFileN SumQC(XReg,XStep) = SumQC(XReg,XStep) + RegQC(XRawFile,XReg,XStep) end do OpTot = OpTot + SumQC(XReg,XStep) end do write (99,"(i5,13i6)"), XStep, (SumQC(XReg,XStep),XReg=1,RegN), OpTot end do OpTot = 0 do XReg = 1, RegN do XStep = 1, StepN SumQC(XReg,StepN+1) = SumQC(XReg,StepN+1) + SumQC(XReg,XStep) end do OpTot = OpTot + SumQC(XReg,StepN+1) end do write (99,"(a5,13i6)"), "TOTAL", (SumQC(XReg,StepN+1),XReg=1,RegN), OpTot write (99,*) deallocate (SumQC, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpQCInfo: Deallocation failure: SumQC 1 #####" allocate (SumQC (StepN,BitN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpQCInfo: Allocation failure: SumQC 2 #####" SumQC = 0 write (99,*), "Summary table of all data processing." write (99,"(a)"), " 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 SUM" do XStep = 1, StepN OpTot = 0 do XBit = 0, BitN-1 do XRawFile = 1, RawFileN SumQC(XStep,XBit) = SumQC(XStep,XBit) + BitQC(XRawFile,XStep,XBit) end do OpTot = OpTot + SumQC(XStep,XBit) end do write (99,"(i2,17i6)"), XStep, (SumQC(XStep,XBit),XBit=0,BitN-1), OpTot end do write (99,*) deallocate (SumQC, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpQCInfo: Deallocation failure: SumQC 2 #####" write (99,*), "Summary table of all stations, classed by % of months rejected." write (99,"(a)"), " Year 0 1-10 11-30 31-50 51-80 81-99 100 TOT" do XRawFile = 1, RawFileN do XClass = 1, ClassN StnQC(XRawFile,ClassN+1) = StnQC(XRawFile,ClassN+1) + StnQC(XRawFile,XClass) end do write (99,"(i5,8i6)"), XRawFile, (StnQC(XRawFile,XClass),XClass=1,ClassN+1) end do do XClass = 1, ClassN+1 do XRawFile = 1, RawFileN StnQC(RawFileN+1,XClass) = StnQC(RawFileN+1,XClass) + StnQC(XRawFile,XClass) end do end do write (99,"(a5,8i6)"), " TOT", (StnQC(RawFileN+1,XClass),XClass=1,ClassN+1) write (99,*) do XStep = 1, StepN if (trim(StepText(XStep)).NE."no rejections") then write (99,*), "Summary table of data rejected at step: ", XStep write (99,*), trim(StepText(XStep)) write (99,*), "Year Euro USSR MidE Asia Afri NAme CAme SAme Anta Ocea Buoy Misc TOT" do XRawFile = 1, RawFileN OpTot = 0 do XReg = 1, RegN OpTot = OpTot + RegQC(XRawFile,XReg,XStep) end do write (99,"(i5,12i5,i6)"), XRawFile, (RegQC(XRawFile,XReg,XStep),XReg=1,RegN), OpTot end do write (99,*) end if end do write (99,*), "Key to bits in data processing tables: " do XStep = 1, StepN write (99,"(i2,a1,a)"), XStep, " ", trim(BitText(XStep)) end do write (99,*) do XRawFile = 1, RawFileN write (99,*), "Summary table of data processing for year: ", XRawFile write (99,"(a)"), " 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 SUM" do XStep = 1, StepN OpTot = 0 do XBit = 0, BitN-1 OpTot = OpTot + BitQC(XRawFile,XStep,XBit) end do write (99,"(i2,17i5)"), XStep, (BitQC(XRawFile,XStep,XBit),XBit=0,BitN-1), OpTot end do write (99,*) end do end subroutine DumpQCInfo !******************************************************************************* ! this is the subroutine that will finally dump the QC'd data into CRU ts files ! when I have got it working, temporarily reverse the process above in which DTR is filled ! so that it fills with rejected data instead, so that I can eyeball the rejected data subroutine DumpData print*, " > Saving the data as a CRU ts file..." allocate (Code(StationN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpData: Allocation failure #####" do XStation = 1, StationN Code(XStation)=Station(XStation,1) end do call GetCRUtsInfo (Code,Lat,Long,Elev,NameStn,NameCty,6) call MakeStnInfo (StnInfo,Code,Lat,Long,Elev,1,YearAD=YearAD,Data=DTR,DataMissVal=DataMissVal) call SaveCTS (StnInfo,NameStn,NameCty,Data=DTR,YearAD=YearAD,Silent=1) deallocate (Code,Lat,Long,Elev,NameStn,NameCty,StnInfo, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: DumpData: Deallocation failure #####" end subroutine DumpData !******************************************************************************* subroutine LocateStn XCty = 0 ; ThisCty = 0 do XCty = XCty + 1 if (XCheckStn.GE.CtyBound0(XCty).AND.XCheckStn.LE.CtyBound1(XCty)) ThisCty = XCty if (XCty.EQ.CtyN.AND.ThisCty.EQ.0) ThisCty = CtyN + 1 if (XCty.EQ.CtyN) exit end do end subroutine LocateStn !******************************************************************************* subroutine Conclude print* close (99) end subroutine Conclude !******************************************************************************* end program QCClimatT