C********************************************************************** C * C PROGRAM: SAI2CDF VERSION: 93.6 PROJECT: NSSDC C C ENGLISH NAME: SAI to CDF C LANGUAGE: FORTRAN77 for VAX 9104 C C PURPOSE: To put the Scanning Auroral Imager data from DE-1 into C a CDF. C C INPUT: C A skeleton CDF must have been created before running this C program. Its name should have < 20 characters. If variable names C other than those in the sample skeleton are desired, change them C from the hard-coded names below as well as in skeleton table. C A list of SAI MAF files for input should be in a file named C .FILES, in which each successive line has one MAF file C listed, as CHAR*40. (The remainder of the line may hold comments.) C The directory name may be assigned a logical name. E.g. C CDAW9DATA:XCD289.MAF 860401 091536 C CDAW9DATA:XCD290.MAF 092731 C [DE]DE83012030627_C2F.SAI00 From NDADS C Link with the CDF package. C C METHOD: The CDF name is entered interactively. The CDF (which C was created by the CDF Toolkit from a skeleton table) is opened C and the start and stop times obtained. The next input filename is C read from the list in .FILES. For each image, the image C column is the scan line number minus an offset; the offset is 28 C for photometer C, for example, since columns 1-27 (and 149-180) C are never used for photometer C. The row is the pixel number C reduced by the mean pixel offset per scan line; for most images, C the offset is +/- 0-2 pixels for all lines.) The coord files C (GEOgraphic Lat and Long, and Corrected GeoMagnetic Lat and Local C Time) are similarly processed. The final arrays are put in the C CDF. This continues until each image (a CDF record) in the list C has been processed. C Files received after ~9/91 may have ASCII rather than EBCDIC C filter wheel codes; there may be other changes. C C HIERARCHY: C SAI2CDF....CDF package C (CDF_open, CDF-attr_get, CDF_var_put, CDF_close) C ....BREAKDOWN.....Epoch_Breakdown C ....SAI_HEADER....Compute_Epoch C ....FILTERS C ....SAI_DATA......CDF_var_hyper_put C ....ICOUNT (fct) C ....ADJUST C ....ERRORS C ....SAI_COORDS....CDF_var_hyper_put C ....ERRORS C ....ERRORS C C COMMONS: VARIABLES C EVENT_minmax EPOCH_MIN, EPOCH_MAX, IMAGE_TIME C C VARIABLES: C see declarations below C C ERROR HANDLING: C CDF package call errors are interpreted and printed. Severe C errors halt processing. C Images not within the CDF start/stop time period, or those C out of order, are omitted, and a warning printed. C C MODIFICATIONS: C Modified for CDAW-9 from CDAW 8 code by Dan Grogan 5/89 C C Code rewritten. Changes: output array is correctly oriented C right to left (images alternate direction of scan), with each scan C line offset the proper amount. Uncalibrated intensity variables C are omitted in the CDF. Modifications also enhance runtime C efficiency, and printout is reduced. Susan Kayser June, 1991 C C Modified to use 'mlc' to put each scan line in proper place. Each C frame has 120 lines at most, but they have positions between 29-148 C (for photometer C) when scanning forward, and 147-28 when scanning C in reverse. Line 90 is claimed to be the center. Line 148 never has C auroral oval data in it, just earth limb, so this line will be C omitted (and l.28 blank filled) for forward scans. ASCII interpret- C ation of the Filter Wheel Code is allowed for. Version 2.3 CDFs C are created. C The code has been generalized to allow for non-CDAW CDFs. C Susan Kayser August, 1992 C The list of files no longer begins with the file count. C Susan Kayser June, 1993 C********1*********2*********3*********4*********5*********6*********7* PROGRAM SAI2CDF implicit none INCLUDE 'CDF$INC:CDF.INC' COMMON /EVENT_minmax/ epoch_min, epoch_max, Image_time real*8 epoch_min, epoch_max, Image_time character*40 maffile, cgmfile, geofile character*20 CDF_name, Date_Time, filesList*30 real*4 sensit integer*4 record_num, indices(10)/10*0/ integer*4 rcode, nphot, lines integer*4 just(120) ! offsets for each scan line integer*4 klines ! lines of geo cgm coords integer*4 CDF_id, eventNumber, lch1,lch2 byte khead(200) equivalence (khead(37),klines) C..Get CDF name TYPE *, 'Enter CDF name (e.g. SAIYYDDD)' READ (5, '(A)') CDF_name filesList= CDF_name//'.FILES' C..Open the list of image files and the skeleton CDF. OPEN (unit=4, name=filesList, form='formatted', status='old', . readonly) record_num = 1 CALL CDF_open (CDF_name, CDF_id, rcode) if (rcode .ne. CDF_OK) call errors(rcode,'OPEN') print *, ' CDF ',CDF_name C..Get max and min times (SCALEMIN, SCALEMAX from skeleton table) CALL CDF_attr_get (CDF_id,CDF_attr_num(CDF_id,'SCALEMIN'),1, . epoch_min,rcode) if (rcode .ne. CDF_OK) call errors(rcode,'Epoch min') CALL CDF_attr_get (CDF_id,CDF_attr_num(CDF_id,'SCALEMAX'),1, . epoch_max,rcode) if (rcode .ne. CDF_OK) call errors(rcode,'Epoch max') C..*** Image loop begins *** C..Process image data, image by image. Intensity data for each image C is in a file named something like xcn098.MAF. From this file, the C MAFCRD program was used to generate two corresponding coordinate C files, with the same filename, and types .GEO and CGM. C..Unit 4 contains the list of MAF filenames. DO WHILE (record_num .lt. 1000) read (4, '(A40)', end=200) maffile lch1 = index(maffile, ':') + 1 lch2 = index(maffile, ']') + 1 lch1 = max(lch1, lch2) lch2 = index(maffile(lch1:), '.') + lch1 - 1 GEOFILE = maffile(lch1:lch2)//'GEO' CGMFILE = maffile(lch1:lch2)//'CGM' PRINT *, 'Image ',record_num,' from ',MAFFILE(lch1:lch2) OPEN (unit=1, name=MAFFILE, . readonly,form='unformatted',status='old') OPEN (unit=2, name=GEOFILE, . readonly,form='unformatted',status='old') OPEN (unit=3, name=CGMFILE, . readonly,form='unformatted',status='old') C..Process file header. Check for valid time for EPOCH and store it. CALL SAI_HEADER(nphot,sensit,lines) if (image_time .EQ. 0.0d0) go to 90 CALL BREAKDOWN(Image_Time,Date_Time) type *, 'Image Time: ', Date_Time C..Store epoch of this image in CDF indices(1)=1 indices(2)=1 CALL CDF_var_put(CDF_id, CDF_var_num(CDF_id,'EPOCH'), . record_num, indices, image_time, rcode) if (rcode .ne. CDF_OK) call errors(rcode,'PUT-EPOCH') C..Process the data in this record, then do the coordinates. C..The appropriate scan lines are stored in columns 1-120 (E.g., for C photometer C, scan line 29 goes into first column.) if (lines .gt. 120) lines = 120 ! Max # of scan lines in image CALL SAI_DATA(CDF_id,record_num,nphot,sensit,lines,just) C C..Read GEO header, then process GEOgraphic coord data C read (2) khead if (klines .ne. lines) type *, 'klines ', klines,lines CALL SAI_COORDS(CDF_id,record_num,nphot,klines,just, . 2,'SAIGOLT','SAIGOLN') C C..Read CGM header, then process Corrected GeoMagnetic coord data C read (3) khead if (klines .ne. lines) type *, 'klines ',klines,lines CALL SAI_COORDS(CDF_id,record_num,nphot,klines,just, . 3,'SAIMLAT','SAIMLT') record_num = record_num + 1 GO TO 100 ! End of this image C C..If no more data, or a time is "0"... 90 TYPE *, 'EOF or bad time at image', record_num 100 close (1) close (2) close (3) C END DO ! End of image loop C C..Close the CDF C 200 CALL CDF_close(CDF_id, rcode) if (rcode .ne. CDF_OK) call errors(rcode,'CLOSE') STOP END SUBROUTINE SAI_HEADER(nphot,sensit,nline) C..Pick up needed values from header, such as time, filter wheel code, C..Calculate the Epoch and store it. C..Coordinates are present in the header, but are difficult to use. C..The MAFCRD program has been supplied by Rae Dvorsky at Iowa C.. which supplies the location of each pixel. implicit none COMMON /EVENT_minmax/ epoch_min, epoch_max,image_time real*8 epoch_min,epoch_max,image_time,lastime real*4 sensit,alt integer*4 rcode,CDF_id,record_num,var_num,indices(10) integer*4 ifil, nline, nphot character*4 fwc BYTE ihead(404) byte mrsrv(8),mname(8),ebsc(4) integer*2 iwords,iblock,ibytes,ncflag,imsync,idirct(7) integer*4 ntype,nyear,nday,msec,id,nfwv,nfwc,nfwt,mlca,mlcz, & lines,npixm,maxpix,ndin(5),ndingr(2),ndghsk(2),mmc,nansub(4), & norbit,nscgei(3),nspin(3),normal(3),nuipro,nvel(3),nsun(3), & nsprat,msecoa,nspnp,mnspnp,mxspnp equivalence (ihead( 1),iwords ), (ihead( 97), mmc ), & (ihead( 3),iblock ), (ihead(101),nansub(1)), & (ihead( 5),ibytes ), (ihead(117),norbit ), & (ihead( 9), ntype ), (ihead(121),nscgei(1)), & (ihead(13), nyear ), (ihead(133), nspin(1)), & (ihead(17), nday ), (ihead(145),normal(1)), & (ihead(21), msec ), (ihead(157),nuipro ), & (ihead(25), id ), (ihead(161), nvel(1)), & (ihead(29), nfwv ), (ihead(173), nsun(1)), & (ihead(33),nfwc,ebsc), (ihead(185),nsprat ), & (ihead(37), nfwt ), (ihead(189),msecoa ), & (ihead(41), mlca ), (ihead(193), nspnp ), & (ihead(45), mlcz ), (ihead(197),mnspnp ), & (ihead(49), lines ), (ihead(201),mxspnp ), & (ihead(53), npixm ), (ihead(205),ncflag ), & (ihead(57),maxpix ), (ihead(373), mrsrv(1)), & (ihead(61), ndin(1)), (ihead(381), mname(1)), & (ihead(81),ndingr(1)), (ihead(389),imsync ), & (ihead(89),ndghsk(1)), (ihead(391),idirct(1)) READ (1) ihead C..Obtain the filter wheel sensitivity. The calibration needs this. C..There are twelve filters available for each of the 3 photometers. C..The photometer ID is obtained from header bytes 25-28. The filter C..wheel code (bytes 33-36 in header) is a 4-character string (EBCDIC C..before about 9/91, now ASCII) which may be determined from the C..filter wheel voltage (bytes 29-33) as well, to avoid worrying about C..whether to use EBCDIC or ASCII. Subroutine FILTERS was supplied by C..Rae Dvorsky (6/92) to return the ASCII code, the calibration factor C..for that filter, and the assumed altitude (for which that filter was C..chosen in the first place). (The altitude is not used here.) 100 CONTINUE nphot = id ! Photometer ID call FILTERS (nphot,nfwv,fwc,ifil,sensit,alt) C..Pass through the number of scan lines in this image nline = lines C..Obtain and test the Epoch NYEAR = NYEAR + 1900 call compute_epoch (NYEAR,1,nday,0,0,0,msec,image_time) IF (image_time .gt. epoch_max) then image_time = 0.0 ELSEIF (image_time .lt. epoch_min) then image_time = 0.0 END IF IF (image_time .gt. lastime) then lastime = image_time ELSE print*, 'time going backwards' image_time = 0.0 END IF return end SUBROUTINE FILTERS(NPHOT,NCOUNT,NAME,NUMBER,SP,ALT) ! (supplied by Rae Dvorsky, 6/92) ! given the photometer ID and the telemetry filter wheel voltage count, ! returns the filter name, number, sensitivity factor, and default ! altitude, when known ! ! name type description ! ! input arguments: NPHOT INT*4 photometer ID (1, 2, or 3) ! NCOUNT INT*4 filter wheel voltage count ! ! output arguments: NAME CHAR*4 filter name ! NUMBER INT*4 filter number ! SP REAL*4 sensitivity factor ! ATL REAL*4 assumed altitude in kilometers ! ! REAL*4 SPS(12,3),ALTS(12,3),SP,ALT INTEGER*4 NPHOT,NCOUNT,NUMBER,N CHARACTER*4 NAME,NAMES(12,3) ! DATA NAMES/'360Z','317Z','630W','557W','391W','394B','626B', & '630W','557N','391N','630N','557N','629C','630N','557N', & '391N','630N','317Z','482M','554B','557W','390W','630W', & '557W','136W','123W','120W','140N','136W','125N','123W', & '117N','140N','125N','117N','117A'/ DATA SPS/2.3E-4,5.7E-4, 0.88, 2.40, 3.31, 1.96, 1.08, & 0.78, 1.30, 2.33, 0.66, 1.60,3.2E-4, 1.31, 2.40, & 4.49, 1.19,4.5E-4, 7.40, 3.85, 4.85, 5.84, 2.00, & 4.64, 1.65, 3.08, 3.10, 1.27, 2.05, 1.71, 3.08, & 0.84, 1.26, 1.80, 0.91, 10.5/ DATA ALTS/ 0., 0., 0., 120.0, 100.0, 100.0, 300.0, & 300.0, 0., 0., 0., 0., 0., 0., 0., & 0., 0., 0., 0., 120.0, 120.0, 100.0, 300.0, & 0., 100.0, 200.0, 200.0, 0., 0., 0., 0., & 0., 0., 0., 0., 200.0/ ! N = NCOUNT GO TO(1,2,3),NPHOT 1 IF (N.LT.95) N = N + 217 NUMBER = (N-77)/18 GO TO 15 2 IF (N.LT.56) N = N + 240 NUMBER = (N-36)/20 GO TO 15 3 IF (N.LT.85) N = N + 227 NUMBER = (N-66)/19 ! 15 NAME = NAMES(NUMBER,NPHOT) SP = SPS(NUMBER,NPHOT) ALT = ALTS(NUMBER,NPHOT) ! RETURN END SUBROUTINE SAI_DATA(CDF_id,record_num,nphot,sensit,lines,just) C..Stores data for each pixel in all scan lines into the CDF implicit none INCLUDE 'CDF$INC:CDF.INC' COMMON /EVENT_minmax/ epoch_min, epoch_max, image_time real*8 epoch_min, epoch_max, image_time real*4 sensit, rayly(150,120), fill/-1.e9/ integer*4 CDF_id,nscan,lines,lscan,ipx,j,mlcu integer*4 nphot, just(120), mpty/-1000/, joff ,lmsec integer*4 icount ! a function integer*4 record_num,rcode,indices(10),nval(10),interval(10) integer*2 lwords,lbytes,ldcu,loffst,lncorr(3),lorder integer*2 i2_value byte iscan(174) ! 174 for 35 degree MAFs, ! 600 for 120 degree MAFs, ! 1600 for 360 degree MAFs. byte mlc,mlan,lfwp,lsubcm,lpixel(150) ! Minimum LPIXEL dimension: ! 150 for 35 degree MAFs, ! 576 for 120 degree MAFs, ! 1576 for 360 degree MAFs. equivalence (iscan( 1),lwords), (iscan(12),lsubcm ), & (iscan( 3),lbytes), (iscan(13), ldcu ), & (iscan( 5), lmsec), (iscan(15),loffst ), & (iscan( 9), mlc), (iscan(17),lncorr(1)), & (iscan(10), mlan), (iscan(23),lorder ), & (iscan(11), lfwp), (iscan(25),lpixel(1)) data indices/10*1/, nval(1)/150/, nval(2)/120/, interval/10*1/ c do lscan = 1,120 ! Initialize arrays just(lscan) = mpty do ipx = 1,150 rayly(ipx,lscan) = fill end do end do C..Read in full data array, putting scan lines in correct location. C..Store the offset adjustment for each line. c DO 40 nscan = 1,lines read (1,end=200) iscan C..Interpret mlc as an unsigned integer mlcu = mlc if (mlc .lt. 0) mlcu = mlc + 256 C..For each photometer, put leftmost scan line in array column 1. if (nphot .eq. 1) lscan = 141 - mlcu if (nphot .eq. 2) lscan = 133 - mlcu if (nphot .eq. 3) lscan = mlcu - 27 if (lscan .le. 0 .or. lscan .gt. 120) go to 40 just(lscan) = (lncorr(1)+lncorr(2)+lncorr(3)) / 8 do ipx = 1,150 j = lpixel(ipx) I2_value = icount(j) C..Fill image array with calibrated values. Offset not yet in. C..(The raw (packed) or total (unpacked) pixel values are omitted.) rayly(ipx,lscan) = I2_value / sensit end do 40 END DO C C..Establish the offsets CALL ADJUST(JUST) C..Apply offset to each scan line of pixels DO 60 NSCAN = 1,120 JOFF = JUST(NSCAN) IF (JOFF .GT. 0) THEN DO IPX = 150,JOFF+1,-1 RAYLY(IPX,NSCAN) = RAYLY(IPX-JOFF,NSCAN) END DO DO IPX = 1,JOFF RAYLY(IPX,NSCAN) = FILL END DO ELSE IF (JOFF .LT. 0 .AND. JOFF.GT.MPTY) THEN DO IPX = 1,150+JOFF RAYLY(IPX,NSCAN) = RAYLY(IPX-JOFF,NSCAN) END DO DO IPX = 151+JOFF,150 RAYLY(IPX,NSCAN) = FILL END DO END IF 60 END DO C..Store entire array in the CDF record CALL CDF_var_hyper_put(CDF_id,CDF_var_num(CDF_id,'SAIKRAY'), . RECORD_NUM,1,1,INDICES,NVAL,INTERVAL,RAYLY,RCODE) if (rcode .ne. CDF_OK) call errors(rcode,'PUT-DATA') RETURN 200 continue ! End of file comes early! type *, 'Early end of file on scanline', nscan RETURN END SUBROUTINE ADJUST(JUST) C..Each scan line should be offset by an amount supplied in the scan C..header and stored in JUST. A negative value pushes a scan line up. C..When an offset occurs, pixels are lost at one end, and empty spaces C..develop at the other, (which are filled with FILL). To avoid C..excessive pixel loss, the offsets are normalized to the most common C..offset. This SR performs this normalization. PARAMETER (MXC = 120, MPTY = -1000) INTEGER JUST(MXC), NV, L1,L,N INTEGER JFREQ(MXC), JVALUE(MXC), MOSTF, LARGEST C..Initialize DO 10 L1 = 1,120 ! Find first non-empty scan line 10 IF (JUST(L1) .GT. MPTY) GO TO 20 20 JVALUE(1) = JUST(L1) NV = 1 ! NV counts how many offset values occur JFREQ(NV) = 1 C..Find the most frequent offset value. DO 100 L = L1+1,120 IF (JUST(L) .EQ. MPTY) GO TO 100 DO 50 N = 1,NV IF (JUST(L) .EQ. JVALUE(N)) THEN JFREQ(N) = JFREQ(N) + 1 GO TO 100 END IF 50 CONTINUE NV = NV + 1 ! New offset value JVALUE(NV) = JUST(L) JFREQ(NV) = 1 100 CONTINUE C C..We have just made a histogram of offset values. C..Find the one occuring most frequently, MOSTF. MOSTF = 0 LARGEST = 0 DO 150 N = 1,NV IF (JFREQ(N) .GT. LARGEST) THEN MOSTF = JVALUE(N) LARGEST = JFREQ(N) END IF 150 END DO C C..Normalize JUST DO 200 L = 1,120 200 IF (JUST(L) .GT. MPTY) JUST(L) = JUST(L) - MOSTF RETURN END INTEGER*4 FUNCTION ICOUNT(I) c c ICOUNT returns the true uncompressed count for the given c telemetry count. C Values 1-32 are uncompressed. After that, they are "logarithmic" in C clumps of 32, increasing by 2's to 64, by 4's to 128, etc. to 1984 C I.e., the possible values of the uncompressed count are: C 0,1,2,...31,32,34,36,...62,64,68,72,...124,128,136,142,...248,256,... c if (i.lt.128) go to 10 icount = -1 !!!OVERFLOW!!! go to 990 c 10 if (i.gt.32) go to 40 icount = i go to 990 c 40 ix = mod(i,16) iy = i/16 icount = (ix+16) * 2**(iy-1) c 990 return end SUBROUTINE SAI_COORDS(CDF_id,record_num,nphot,klines,just, . iu,mlat,mlon) C..Stores coordinates in CDF implicit none INCLUDE 'CDF$INC:CDF.INC' REAL*4 ALAT(150,120), ALON(150,120), FILL/-1.E9/ integer*4 CDF_id, iu, ipx, nscan, lscan, ipxi, ipxf integer*4 record_num, rcode, indices(10), nval(10), interval(10) integer*4 klines, just(120), mpty/-1000/, joff integer*4 ndutms, ndpgei(3), nphot character*8 mlon,mlat byte kscan(628) integer*2 kwrds,kbyts,kpix,kmlc,koffst integer*2 kpairs(2,150) ! minimum KPAIRS dimensions: ! (2, 150) for 35 degree MAFs, ! (2, 576) for 120 degree MAFs, ! (2,1576) for 360 degree MAFs. equivalence (kscan(1),kwrds), (kscan( 9),koffst ), & (kscan(3),kbyts), (kscan(13),ndutms ), & (kscan(5), kpix), (kscan(17),ndpgei(1) ), & (kscan(7), kmlc), (kscan(29),kpairs(1,1)) data indices/1,1,8*0/, nval(1),nval(2)/150,120/, interval/10*1/ C C..Copy GEOgraphic coordinates or Corrected GeoMagnetic latitude and C..Magnetic Local Time into CDF. Indices are adjusted for the offset C..of each scan line. C DO 10 NSCAN = 1,120 ! Initialize arrays DO 10 IPX = 1,150 ALAT(IPX,NSCAN) = FILL ALON(IPX,NSCAN) = FILL 10 END DO DO 50 NSCAN = 1,KLINES READ (IU) KSCAN IF (NPHOT .EQ. 1) LSCAN = 141 - KMLC IF (NPHOT .EQ. 2) LSCAN = 133 - KMLC IF (NPHOT .EQ. 3) LSCAN = KMLC - 27 IF (LSCAN .LE. 0 .OR. LSCAN .GT. 120) GO TO 50 JOFF = JUST(LSCAN) IF (JOFF .EQ. MPTY) GO TO 50 IPXI = 1 IPXF = 150 IF (JOFF .GT. 0) IPXI = JOFF + 1 IF (JOFF .LT. 0 ) IPXF = 150 + JOFF DO IPX = IPXI,IPXF ALAT(IPX,LSCAN) = KPAIRS(1,IPX-JOFF) / 100. ALON(IPX,LSCAN) = KPAIRS(2,IPX-JOFF) / 100. END DO 50 END DO C..Store arrays in the CDF CALL CDF_var_hyper_put(CDF_id,CDF_var_num(CDF_id,MLAT), . RECORD_NUM,1,1,INDICES,NVAL,INTERVAL,ALAT,RCODE) IF (RCODE .NE. CDF_OK) CALL ERRORS(RCODE,'PUT-LAT') CALL CDF_var_hyper_put(CDF_id,CDF_var_num(CDF_id,MLON), . RECORD_NUM,1,1,INDICES,NVAL,INTERVAL,ALON,RCODE) IF (RCODE .NE. CDF_OK) CALL ERRORS(RCODE,'PUT-LONG') RETURN END SUBROUTINE BREAKDOWN(EPOCH, DATE_TIME) C..Breaks Epoch down into date, time, and outputs result in string. REAL*8 EPOCH CHARACTER*20 DATE_TIME DATE_TIME = '860000 00:00:00.000 ' CALL EPOCH_BREAKDOWN(EPOCH,IY,IM,ID,IH,MIN,IS,MSEC) WRITE(DATE_TIME(1:2), '(I2)') IY-1900 IF (IM .LT. 10) WRITE(DATE_TIME(4:4), '(I1)') IM IF (IM .GE. 10) WRITE(DATE_TIME(3:4), '(I2)') IM IF (ID .LT. 10) WRITE(DATE_TIME(6:6), '(I1)') ID IF (ID .GE. 10) WRITE(DATE_TIME(5:6), '(I2)') ID IF (IH .LT. 10) WRITE(DATE_TIME(9:9), '(I1)') IH IF (IH .GE. 10) WRITE(DATE_TIME(8:9), '(I2)') IH IF (MIN .LT. 10) WRITE(DATE_TIME(12:12), '(I1)') MIN IF (MIN .GE. 10) WRITE(DATE_TIME(11:12), '(I2)') MIN SEC = IS + MSEC/1000. IF (IS. LT. 10) WRITE(DATE_TIME(15:19), '(F5.3)') SEC IF (IS. GE. 10) WRITE(DATE_TIME(14:19), '(F6.3)') SEC RETURN END SUBROUTINE ERRORS(ISTAT,CALLTYPE) C..This SR interprets error codes from the CDF calls INCLUDE 'CDF$INC:CDF.INC' CHARACTER MESSAGE*(CDF_ERRTEXT_LEN), MSG(4)*72 EQUIVALENCE (MESSAGE,MSG) CHARACTER*10 CALLTYPE CALL CDF_ERROR(ISTAT,MESSAGE) WRITE (6, 1100) CALLTYPE, ISTAT, MSG 1100 FORMAT(' CDF ',A10, ' Problem; status=',I6/3X,(A)) IF (ISTAT .LT. CDF_WARN) STOP RETURN END