SUBROUTINE RDKAKS(IUNIT,FN,IYS,MHS,IDS,IHS,MINS,MIND, +H,D,Z,F,ICON) C *** Read 1-sec value geomagnetic data in KAKIOKA BINARY FORMAT *** C ** MADE ON 1998/11/20 C ** REVISED ON 1998/11/25 C * INPUT: C IUNIT: Unit number used in this subroutine C FN: input file name, character*(*) C IYS,MHS,IDS,IHS,MINS: Start year, month, day, hour and min. C MIND: Duration in minite. C * OUTPUT: C H,D,Z,F: 1-Sec. values (UNIT: nT for H,Z,F, minite for D), C Double Precision array of size MIND*60. C !!! Accuracy of the single precision array is not enough !!! C !!! in most systems. !!! C !!! DATA MISSING=> 999999.D0 !!! C ICON: Condition code of is this subroutine. C 0 : Normal C 20000: File open error. C 21000: File Read error. C 22000: Illegal data. C !!! Note that for systems using x86 CPU (Most Windows, Linux, !!! C !!! FreeBSD and etc) byte sequence is reversed. The systems !!! C !!! are judged by usng month data. !!! C CHARACTER FN*(*) INTEGER*2 IYR,MHR,IDR,IHR,MINR,NDAY,NMIN,N,FO,DO,HO,ZO INTEGER*2 FR(60),HR(60),DR(60),ZR(60),I2DMY(4) DOUBLE PRECISION H(MIND*60),D(MIND*60),Z(MIND*60),F(MIND*60),DMISS C * Sign of D should be revised for KAKIOKA FORMAT DATA IDSN/-1/ C * LREC is 512 for most systems where unit of LREC is byte, C but may be 256 or 128 for some systems. DATA LREC/512/ C DATA LREC/128/ C * Value for mising data. DATA DMISS/999999.D0/ INTMIN(ID,IH,MIN,IDB,IHB,MINB)=(ID-IDB)*1440+(IH-IHB)*60+MIN-MINB ICON=0 IF(MIND.LE.0) RETURN C * Missing data padding DO 10 I=1,MIND*60 H(I)=DMISS D(I)=DMISS Z(I)=DMISS F(I)=DMISS 10 CONTINUE OPEN(IUNIT,FILE=FN,STATUS='OLD',ACCESS='DIRECT',RECL=LREC, +FORM='UNFORMATTED',IOSTAT=IOS) IF(IOS.NE.0) THEN ICON=20000 RETURN ENDIF IP=MAX(1,(IDS-1)*1440+1) ISMIN=INTMIN(IDS,IHS,MINS,1,0,0) IEMIN=ISMIN+MIND-1 IPS=IP IRDS=0 IREW=0 1 CONTINUE READ(IUNIT,REC=IP,IOSTAT=IOS) IYR,MHR,IDR,IHR,MINR,NDAY,NMIN,N, +FO,HO,ZO,DO,I2DMY,(FR(I),HR(I),ZR(I),DR(I),I=1,60) IF(IOS.LT.0) THEN C * EOF IF(IRDS.EQ.1) GO TO 99 IF(IREW.EQ.1) GO TO 99 IP=1 IREW=1 GO TO 1 ELSE IF(IOS.NE.0) THEN C * Read error ICON=21000 GO TO 99 ENDIF C * Use Month data for check sequence of bytes. MHW=MHR/256 IBREV=0 IF(MHW.GE.1.AND.MHW.LE.12) THEN C * Reverse byte sequence IBREV=1 CALL REVI2(IYR,1) CALL REVI2(MHR,1) CALL REVI2(IDR,1) CALL REVI2(IHR,1) CALL REVI2(MINR,1) ENDIF IF(MOD(IYR,100).NE.MOD(IYS,100).OR.MHR.NE.MHS) THEN C * Illegal data ICON=22000 GO TO 99 ENDIF ID4=IDR IH4=IHR IM4=MINR IRMIN=INTMIN(ID4,IH4,IM4,1,0,0) IMP=IRMIN-ISMIN IF(IMP.LT.0) THEN C * Previous time IP=MAX(1,IP-IMP) GO TO 1 C * After time ELSE IF(IMP.GE.MIND) THEN IF(IRDS.EQ.1) THEN GO TO 99 ELSE IF(IREW.EQ.1) GO TO 99 IP=MAX(1,IP-IMP) IREW=1 GO TO 1 ENDIF ELSE IF(IMP.EQ.0) THEN C * Just start time IRDS=1 ELSE C * Intermediate time IF(IRDS.NE.1) THEN IF(IREW.EQ.0) THEN IP=IP-IMP IREW=1 GO TO 1 ENDIF ENDIF ENDIF IF(IBREV.EQ.1) THEN C * Reverse byte sequence for data CALL REVI2(HO,1) CALL REVI2(DO,1) CALL REVI2(ZO,1) CALL REVI2(FO,1) CALL REVI2(HR,60) CALL REVI2(DR,60) CALL REVI2(ZR,60) CALL REVI2(FR,60) ENDIF IF(HO.NE.-1.AND.HO.NE.32767) THEN DO 30 I=1,60 IPW=IMP*60+I IF(HR(I).NE.-1.AND.HR(I).NE.32767) H(IPW)=(HR(I)+HO*1000)/100.D0 30 CONTINUE ENDIF IF(DO.NE.-1.AND.DO.NE.32767) THEN DO 40 I=1,60 IPW=IMP*60+I IF(DR(I).NE.-1.AND.DR(I).NE.32767) + D(IPW)=(IDSN*(DR(I)+DO*10000))/1000.D0 40 CONTINUE ENDIF IF(ZO.NE.-1.AND.ZO.NE.32767) THEN DO 50 I=1,60 IPW=IMP*60+I IF(ZR(I).NE.-1.AND.ZR(I).NE.32767) Z(IPW)=(ZR(I)+ZO*1000)/100.D0 50 CONTINUE ENDIF IF(FO.NE.-1.AND.FO.NE.32767) THEN DO 60 I=1,60 IPW=IMP*60+I IF(FR(I).NE.-1.AND.FR(I).NE.32767) F(IPW)=(FR(I)+FO*1000)/100.D0 60 CONTINUE ENDIF IP=IP+1 GO TO 1 C * File close and return 99 CONTINUE CLOSE(IUNIT,IOSTAT=IOS) RETURN END SUBROUTINE REVI2(DATA,NDATA) C *** REVERSE BYTE SEQUENCE FOR 2-BYTE DATA *** C * UPDATE: C DATA, DATA, I*2(NDATA) C * INPUT: C NDATA DATA LENGTH C INTEGER*2 DATA(NDATA) INTEGER*4 ID,IL,IH,IR DO 10 I=1,NDATA ID=DATA(I) IF(ID.LT.0) ID=65536+ID IH=ID/256 IL=ID-IH*256 IR=IL*256+IH IF(IR.GE.32768) IR=IR-65536 DATA(I)=IR 10 CONTINUE RETURN END