Viewing contents of file '../idllib/iuedac/iuelib/pro/con_sav.pro'
;******************************************************************************
;+
;*NAME:
;
; CON_SAV
;
;*CLASS:
;
;*CATEGORY:
;
; IUESIPS
;
;*PURPOSE:
;
; Converts RDAF *.sav files to a format compatible with the host
; operating system. CON_SAV can convert files created with IUESAVE
; under VMS IDL version 1 or version 2, and files created under DEC
; or SunOS IDL version 2 to the appropriate format for the host
; operating system. Output files are written using IDL FORTRAN
; compatible unformatted write statements of the form
; WRITEU,UNIT,H,W,F,E.
;
;*CALLING SEQUENCE:
;
; CON_SAV,IMAGET,cpupar
;
;*PARAMETERS:
;
; IMAGET (REQ) (I) (0) (S)
; File name of .sav file (without .sav extension).
; Corrected data is written over original file on
; UNIX systems. Wildcards are accepted.
;
; CPUPAR (OPT) (I) (I) (0)
; Parameter to identify data translation mode.
;
; no conversion 0
;
; VAX to MIPSEL 1
; MIPSEL to VAX 2
;
; VAX to SPARC 3
; SPARC to VAX 4
;
; MIPSEL to SPARC 5
; SPARC to MIPSEL 6
;
; Supported Data Types:
;
; VAX - VAXstations, MicroVAX
; MIPSEL - DECstations, IBM 386
; SPARC - SparcStations, Sun 4##
;
; Note: No Conversion is required between like data types,
; such as DECstations and IBM 386s.
;
; If CPUPAR is not given in the call, the user will be
; prompted for it.
;
; Note that only two modes are allowed for a given machine.
; The allowed modes are those in which the final data format
; is compatible with the host operating system.
;
;*EXAMPLES:
;
; to convert swp1234cii.sav:
; con_sav,'swp1234cii'
;
; to convert all .sav files in users account:
; con_sav,'*'
;
;*SYSTEM VARIABLES USED:
;
; !err_string
;
;*INTERACTIVE INPUT:
;
; If CPUPAR is not given in the call, the user will be prompted for it.
;
;*SUBROUTINES CALLED:
;
; TRANS_BYTES
; PARCHECK
; DECOMPOSE
; CHKFITS
; CONMENU
; PLATFORM
;
;*FILES USED:
;
; imaget given in calling sequence.
;
;*SIDE EFFECTS:
;
;*RESTRICTIONS:
;
; Program requires that the .SAV files be transferred to the host
; CPU verbatim (e.g., using the -v option in DNICP or binary mode
; in FTP). Files transferred as ascii files (e.g., without the -v
; option in DNICP) appear to be corrupted in that the 1st 2 bytes
; are removed(?) and end-of-record bytes are added.
;
; SAV files created using the IDL routine SAVLIST are not properly
; converted by this program.
;
; Not for use with fit formatted files.
;
;*NOTES:
;
;*PROCEDURE:
;
; CON_SAV uses the procedure PLATFORM to determine the host operating
; system and cpu architecture. The allowed conversion options are then
; defined based on the operating system and cpu type. The user is asked
; to select from the allowed conversion options and may also be asked if
; the input file was created on a VMS system. Findfile is used to expand
; wildcard filename inputs to a string array. Each input file is checked
; to determine if it is in fits format. If it is, the file is not
; converted. Then each input file is opened, and read into a byte array
; of length determined by the FSAT command.
;
; The IUESAVE files consist of a record containing a four integer
; vector which gives the number of elements in the H, W, F, & E
; vectors, followed by a record containing the H, W, F, & E vectors.
; Under VMS IDL version 1, the second record usually consists of
; several blocks. Under VMS IDL version 2, the H, W, F, & E vectors
; are contained in a single block unless the number of bytes in the
; second record exceeds 32767 bytes. Under Unix or Ultrix IDL, the
; second record always consists of a single block. In addition to
; the bytes which contain the data, extra bytes are included at the
; beginning and end of each block. VMS FORWRT and WRITEU commands
; add a 4 byte longword at the beginning of each record, and a 2
; byte integer (the block size) at the beginning and end of each
; block. If the number of bytes in the second record of a VMS
; IDL Version 2 file exceeds 32767 bytes, the 4 inter-block bytes
; are preceeded by one "garbage" byte, which must also be removed.
; Unix or Ultrix WRITEU commands add a 4 byte longword
; (the blocksize) at the beginning and end of each block.
;
; Varible-length record files transferred from vms using the binary
; mode of Multinet FTP are slightly different in format. Multinet
; removes the dcl-added bytes during the file transfer. If the vms
; file had carriage-return, carriage-control file attributes however,
; Multinet adds a byte 10 (i.e., a cntl-J or line feed) at the end
; of each block or record. VMS users are therefore prompted for
; whether Multinet was used. Note that a new version of Multinet is
; expected in the fall of 93 which will offer other modes for binary
; file tranfer.
;
; The number of elements in the H, W, F, and E arrays, and the
; blocksize of the second record containing the H, W, F, and E
; arrays are determine from the first 12 to 20 bytes in the input
; file. The block size is determined from the 2 byte integer
; (files created on the VAX) or 4 byte longword (files created on
; a UNIX machine) present at the start of the second record. The
; non-data bytes are removed, and the data portion of the second
; record is concatenated into a single array. The bytes
; representing the H, W, F & E vectors are extracted from this
; array and converted to a format compatible with the host
; operating system by TRANS_BYTES. The byte vectors are converted
; to the proper type, and written out to disk using WRITEU. If
; the host cpu is a VMS system, a new version of the output file
; is opened using the /SEGMENTED keyword. On a UNIX machine, the
; output file is opened with the /F77_UNFORMATTED keyword and
; written over the old input file.
;
;*MODIFICATION HISTORY:
;
; 8/21/89 RWT version 1
; 9/14/89 RWT uses FINDFILE to allow use of wildcards
; 6/07/90 RWT modify to be compatible with both UNIX and ULTRIX
; 2/27/91 GRA modify to allow conversions between VMS version 1
; or version 2 *.sav files, ULTRIX, and SunOS *.sav
; files. Input is accomplished by associating the
; entire input file with a single byte array of length
; status.size. Added ERROR keyword to OPENR statments.
; 4/1/91 PJL added PARCHECK; updated prolog
; 5/1/91 RWT add support for DOS
; 6/13/91 GRA merged vms and sun versions, changed "dos" to "DOS"
; 7/25/91 PJL cleaned up; tested VAX to SUN and SUN to VAX options;
; updated prolog
; 10/25/91 GRA globally changed all references to "syspar" to
; "cpupar", changed cpupar to reference data formats as
; specified by the !version.arch system variable; used
; /block keyword when opening the input file on a VMS
; machine so that the rms information can be bypassed;
; corrected error in blocksize byte removal from large
; data records for files created under VMS IDL version
; 2; condensed VMS and Unix branches; updated prolog;
; tested on ultrix/vax, ultrix/mipsel, vms/vax,
; sunos/sparc.
; 10/29/91 GRA changed blocksize byte removal for large VMS IDL V2
; files so that "extra" byte is removed before blocksize
; bytes rather than after; cleaned up print statements;
; tested on ultrix/vax, ultrix/mipsel, vms/vax,
; sunos/sparc; updated prolog.
; 4/27/93 RWT add option for vms files transferred via Multinet FTP
; and replace trans_bytes calls for integer conversion
; with intrinsic byteorder commands.
; 15 Nov 93 PJL added CHKFITS
; 9 Jun 94 PJL replaced !version with CONMENU and PLATFORM
; 28 Sep 94 RWT add support for Multinet block mode
;-
;******************************************************************************
pro con_sav,imaget,cpupar
;
npar = n_params(0)
if (npar eq 0) then begin
print,'CON_SAV,IMAGET,cpupar'
retall
endif ; npar eq 0
parcheck,npar,[1,2],'CON_SAV'
;
platform,dummy,sysos=sys
conmenu,cpupar,cpustr,from_vms_system=from_vms_system
;
; ask user if file originated on VMS system if it was possible
;
test_from_vms = cpupar ne 0
if test_from_vms then begin
vms_possible = where([1,2,3,5] eq cpupar,ask_vms)
;
if (ask_vms gt 0) then begin
from_vms_system = ''
print,' '
read,'Were the input files formatted for a VMS system? ',from_vms_system
yesno,from_vms_system
if (from_vms_system) then begin
mn = ''
print,' '
print,'Were Files transferred with MultiNet FTP (y (def) or n)?'
read,'(note: type n if using MultiNet block mode) ',mn
yesno,mn
endif
endif else begin
from_vms_system = 0
endelse ; sys ne vms or ultrix
endif ; test_from_vms
;
; form string array of files to convert
;
decompose,imaget,d,p,n,ext,vers
imaget = d + p + n + '.sav'
str = findfile(imaget,count=savn)
;
print,' '
print,'Found ' + strtrim(savn,2) + ' *.sav files.'
;
if (savn eq 0) then begin
print,' '
print,'Returning from CON_SAV'
print,' '
return
endif ; savn
;
for i=0,savn-1 do begin
;
print,' '
print,'Converting ' + str(i) + ' from ' + cpustr + ' format.'
;
; make sure not a fits file
;
chkfits,str(i),newsips,/silent
if (newsips) then begin
print,str(i) + ' is a fits file. File will not be converted.'
goto,nextfile
endif ; newsips
;
; open file and read all records into a single byte array
;
openr,/get_lun,un,str(i),error = err,/block
;
if (err ne 0) then begin
print,' '
print,'Error accessing file '+str(i)
print,' '+!err_string
print,' Proceeding to next file...'
goto,nextfile
endif ; err
;
stat = fstat(un)
siz = stat.size
;
rec = assoc(un,bytarr(siz))
brec = rec(0)
free_lun,un
;
if from_vms_system then begin
;
; BEGIN CONVERSION FOR DATA FROM A VMS SYSTEM
;
; define byte representation of beginning longword (if not multinet)
; and byte representation of the 4 element integer
; vector (n_elements of H, W, F, & E) in first record
;
mnc = 2 * (mn) ; mnc=2 for multinet, 0 for woll.
if (not mn) then begin
bl = brec(0:3)
if (cpupar gt 2) then byteorder,bl,/lswap
l = long(bl,0,1)
l = l(0)
if (l le 0) then begin
print,' '
print,'Error converting '+str(i)
print,' File may be corrupted, or already converted.'
print,' Proceeding to next file...'
goto,nextfile
endif ; l le 0
endif ; not mn
;
; convert byte representations to final type
;
bnum = brec(4-mnc:11-mnc)
if (cpupar gt 2) then byteorder,bnum,/sswap
num = long(fix(bnum,0,4))
snum = strtrim(num,2)
snum = snum(0)+' '+snum(1)+' '+snum(2)+' '+snum(3)
;
; print n_elements H, W, F, & E
;
print,' '
print,'Number of entries in H, W, F, & E = ' + snum
;
; define byte representation of second record blocksize
; convert to host cpu internal format
;
if (mn) then begin ; if multinet
remove = 3L
blksize = 32768L
endif else begin ; if not multinet
bblksize = brec(12:13)
if (cpupar gt 2) then byteorder,bblksize,/sswap
blksize = fix(bblksize,0,1)
blksize = long(blksize(0))
;
; make corrections to blocksize and number of bytes to remove at
; beginning of blocks if the number of bytes written to the
; H, W, F, & E block exceeds 32767 under VMS IDL Version 2
;
if (blksize eq 32767L) then begin
blksize = 32768L
remove = 5L
endif else begin
remove = 4L
endelse ; blksize eq 32767L
;
; check for error and print blksize
;
if (blksize le 0) then begin
print,' '
print,'Error converting '+str(i)
print,' File may be corrupted, or already converted.'
print,' Proceeding to next file...'
goto,nextfile
print,' '
endif else begin
print,' '
print,'Data record blocksize = ' + strtrim(blksize,2)
print,' '
endelse ; blksize le 0
blksize = blksize + 2L ; spacing between bytes to be removed
endelse
;
; define tot vector to include blocksize bytes to eof
; define tbyt to be n_elements tot (siz-12)
;
tot = brec(12-mnc:siz-1L)
tbyt = n_elements(tot)
;
neob = tbyt / blksize ; # of end-of-block words
;
; remove integers from start & end of each block in byte array
; remove 4 bytes at a time unless file ends on a block boundary
; (then remove just 2 bytes)
;
tmp = tot
;
for n=1,neob do begin
ind = (blksize*n) + remove - 1L*(remove eq 5L)
if (ind le (tbyt-1L)) then tmp(ind-remove*n) = tot(ind:*)
endfor ; n
;
if (mn) then tmp = tmp(3L:*) else tmp = tmp(4L:*) ; remove header
;
endif else begin
;
; BEGIN CONVERSION FOR DATA FROM A UNIX OR DOS SYSTEM
;
; define byte representations of beginning and ending blocksize
; longwords, and byte representation of the 4 element integer
; vector (n_elements of H, W, F, E) in first record
;
bl = brec(0:3)
bl2 = brec(12:15)
bnum = brec(4:11)
;
; convert byte representations to host cpu internal format
;
if (cpupar gt 2) then byteorder,bl,/lswap
if (cpupar gt 2) then byteorder,bl2,/lswap
if (cpupar gt 2) then byteorder,bnum,/sswap
; trans_bytes,bl,3,cpupar
; trans_bytes,bl2,3,cpupar
; trans_bytes,bnum,2,cpupar
;
; convert byte representations to final type
;
l = long(bl,0,1)
l2 = long(bl2,0,1)
l = l(0)
l2 = l2(0)
num = long(fix(bnum,0,4))
snum = strtrim(num,2)
snum = snum(0)+' '+snum(1)+' '+snum(2)+' '+snum(3)
;
; check for error and print n_elements H, W, F, E
;
if (l ne l2) then begin
print,' '
print,'Error converting '+str(i)
print,' File may be corrupted, or already converted.'
print,' Proceeding to next file...'
goto,nextfile
endif else begin
print,' '
print,'Number of entries in H, W, F, & E = '+snum
endelse ; l
;
; define byte representations of beginning and ending blocksize
; longwords for second data record.
;
bblksize = brec(16:19)
bblksize2 = brec(siz-4L:siz-1L)
;
; convert byte representations to host cpu internal format
;
if (cpupar gt 2) then byteorder,bblksize,/lswap
if (cpupar gt 2) then byteorder,bblksize2,/lswap
; trans_bytes,bblksize,3,cpupar
; trans_bytes,bblksize2,3,cpupar
;
; convert byte representations to final type
;
blksize = long(bblksize,0,1)
blksize2 = long(bblksize,0,1)
blksize = blksize(0)
blksize2 = blksize2(0)
;
; check for error and print blocksize
;
if (blksize ne blksize2) then begin
print,' '
print,'Error converting '+str(i)
print,' File may be corrupted, or already converted.'
print,' Proceeding to next file...'
print,' '
goto,nextfile
endif else begin
print,' '
print,'Data record blocksize = ' + strtrim(blksize,2)
print,' '
endelse ; blksize
;
; form temporary byte array containing H, W, F, & E
;
tmp = bytarr(blksize)
tmp(0) = brec(20L:blksize+20L-1L)
;
endelse ; from_vms_system
;
; check tmp vector against the number of bytes needed for H, W, F, & E
;
rnum = n_elements(tmp)
fnum = num(0)*2L + (num(1) + num(2) + num(3))*4L
;
if (fnum gt rnum) then begin
print,' '
print,'Fewer bytes remaining than expected.'
print,' Proceeding to next file...'
goto,nextfile
endif ; fnum gt rnum
;
; form index based on num values
;
hind = (num(0) * 2L) - 1L
wind = hind + (num(1) * 4L)
find = wind + (num(2) * 4L)
eind = find + (num(3) * 4L)
;
; extract byte representations of H, W, F, & E
;
bh = tmp(0:hind)
bw = tmp(hind+1L:wind)
bf = tmp(wind+1L:find)
be = tmp(find+1L:eind)
;
; convert byte representations to host cpu internal format
;
if (cpupar gt 2) then byteorder,bh,/sswap
; trans_bytes,bh,2,cpupar
trans_bytes,bw,4,cpupar
trans_bytes,bf,4,cpupar
trans_bytes,be,4,cpupar
;
; convert byte representations to final type
;
h = fix(bh,0,num(0))
w = float(bw,0,num(1))
f = float(bf,0,num(2))
e = float(be,0,num(3))
;
; strip version number from final output name
;
decompose,str(i),d,p,n,ext,ver
name = d+p+n+ext
;
; write vectors to file using segmented keyword if cpu is vms
; and f77_unformatted keyword if cpu is a unix machine with
; unformatted write statments
;
if (sys eq 'vms') then openw,/get_lun,un,name,/segmented else $
openw,/get_lun,un,name,/f77_unformatted
;
num = fix(num)
writeu,un,num
writeu,un,h,w,f,e
;
free_lun,un
;
nextfile:
;
endfor ; i
;
return
end ; con_sav