;+                                                                      
;  Name:
;       READ_SHER
;************************************************************************ 
; Pro	READ_SHER, filename, data, start_time, end_time, width64
;	fdr, audit_trail, error=error, file_type=file_type,
;	fits=fits
;       
;	Read Sher, Sher_cor, Her, Her_cor BATSE data 
;
; Inputs:	Filename - full file descriptor for file in native
;		format.  Corrected data may be used.  If the extension
;		is ".fits", then fits readers are used.
;		Must contain the substrings 'her' or 'sher' and may
;		contain 'cor'.  Otherwise, these strings may be input
;		through FILE_TYPE.
;
; Optional Keywords
;		file_type - string containing the substrings which specify
;		the data structure to be read.
;		fits - if set, then fits reader used.
;
; Outputs:	Data - Count data unpacked as whole numbers into 
;			 fltarr( nch, ndet, npck)
;				nch - number of energy bins
;				ndet - number of detectors		
;				npck - maximum number of packets allowed
;			 
;		Start_time - time in s from 79/1/1 for each time interval
;			  dblarr( nrep, npck)
;		End_time - time in s from 79/1/1 for each time interval
;			  dblarr( nrep, npck)
;		width64 - reported width of linear channel 64
;		FDR - header record
;
;		AUDIT - Audit records
;
; Restrictions:  File name must contain the words Her or Sher and 
;		 the word Cor for corrected data.  Otherwise the
;		 correct data structure must be provided.
;		 File Definition Record
;		 includes NUM_AUDIT_REC tag name specifying the
;		 number of data records.  
;
; ras, 93/10/14
; ras, 31-jan-94, used load_struct and conv_vax_unix to make
;	machine independent
; ras, 3-mar-94, corrected time conversion to include no packet offset
; ras, 19-oct-95, revised record length calculation
;************************************************************************
;-

pro READ_SHER, filename, data, start_time, end_time, width64, $
	fdr, audit_trail, error=error, file_type=file_type

error = 0 ;assume no problems to start

@fdr_msfc_str
@audit_trail_str
@her_str
@sher_str
@her_cor_str
@sher_cor_str
her=1
cor=0
break_file, filename(0), disk, dir, filnam, ext
if keyword_set(fits) or strpos(strlowcase(ext),'fits') ne -1 then itsfits=1 $
	else itsfits=0

if n_elements(file_type) eq 0 then begin
	if strpos(strlowcase(filnam),'sher') ne -1 then her =0
	if strpos(strlowcase(filnam),'cor') ne -1 then cor=1
endif else begin
	if strpos(strlowcase(file_type),'sher') ne -1 then her =0
	if strpos(strlowcase(file_type),'cor') ne -1 then cor=1
endelse
;pick the right data structure and repeat cycle

ndet = 1
if her then begin
	nrep = 1  ;number of spectra in one packet
	nch = 128
	if cor then data_str= her_cor_str else data_str= her_str
endif
if not her then begin
	nrep = .5
	nch = 256
	if cor then data_str= sher_cor_str else data_str= sher_str
	if cor then nrep = 1
endif
	
 
if itsfits then begin
	head1 = headfits( filename(0))
	data_fits = readfits( filename(0), head2, /ext)
	nspec = n_elements( data_fits(0,*) )
	load_struct, data_fits, data_str, data_str_arr   
	if not her then width64  = data_str_arr.width64
endif else begin	

;************************************************************************
;HEADER RECORD
;
;	rec_length = n_tags( data_str,/length) 	;length of data records
	data_length= size_struct( data_str)     ;actual number of bytes in structure
	rec_length = ceil( data_length/4.)*4    ;length of data records, ras, 19-oct-95
	fdr_length = size_struct(fdr_msfc)
	aud_length = size_struct(audit_trail)
	test = bytarr( rec_length-fdr_length)

        files = findfile(filename(0), c=cnt)
        if cnt eq 0 then begin
                print,'Error finding/reading file'
                error = 1
                return
        endif

        print, 'Reading ',filename(0)
        openr,/get,lu,filename(0)

        readu,lu, fdr_msfc, test  ;READ HEADER RECORD
	fdr = conv_vax_unix( fdr_msfc) 
;************************************************************************
;AUDIT RECORDS?
;
        if fdr.num_audit_rec ge 1 then begin
		test  = bytarr( rec_length, fdr.num_audit_rec)
		readu, lu, test
		load_struct, test, audit_trail, audit, /noieee
                npck = audit(fdr.num_audit_rec -1).data_recs_num
        endif else npck= fdr.data_recs_num
        nspec = npck *nrep ;number of spectra in file

endelse

;************************************************************************
;READ DATA
;
if itsfits then begin
	data = float(65535l and data_str_arr.data)
	start_time = sc_seconds_ed( data_str_arr.start_time, /no_offset)	;ras 9-mar-94 /no_offset
	end_time = sc_seconds_ed( data_str_arr.end_time,     /no_offset)
	if not her then width64  = data_str_arr.width64
	if not her and not cor then begin ; its sher so group to 256 from 128
		nspec = n_elements(data(0,*))/2 
		data = reform( data, 256, nspec)
		start_time = start_time(indgen(nspec)*2)
		end_time = end_time(indgen(nspec)*2)
		width64 = width64(indgen(nspec)*2)
	endif
	return
end	

test = bytarr(rec_length)
data_str_arr = replicate( data_str, npck)

for i=0,npck-1 do begin
	ftest=fstat(lu)
	if ftest.cur_ptr+ftest.rec_len le ftest.size then begin
		readu, lu, test
		load_struct, test, data_str, data_str, /noieee
		data_str_arr(i) = data_str
	npck_use=i
	endif
endfor
free_lun, lu
data_str_arr=data_str_arr(0:npck_use)

data = float(65535l and data_str_arr.data)
start_time = sc_seconds_ed( data_str_arr.start_time, /no_offset)	;ras 9-mar-94 /no_offset
end_time = sc_seconds_ed( data_str_arr.end_time,     /no_offset)
;start_time = sc_seconds_ed( data_str_arr.start_time)
;end_time   = sc_seconds_ed( data_str_arr.end_time)
if not her then width64 = data_str_arr.width64

if 1/nrep eq 2 then begin
	;spectra have been read in two packets
	;eliminate unpaired packets
	;regroup by twos
	pairs = where( (start_time(1:*)-start_time) eq 0.0 and (end_time(1:*)-end_time eq 0.0), npairs)
	for i=0,npairs-1 do begin
		data(0,i*2) = data(*,pairs(i):pairs(i)+1)
		start_time(i) = start_time(pairs(i))
		end_time(i)   = end_time(pairs(i))
		if not her then width64(i)      = width64(pairs(i))
	endfor
	data = reform( data(*,0:2*npairs-1), n_elements(data(*,0))*2, npairs)
	start_time = start_time(0:npairs-1)
	end_time   = end_time(0:npairs-1)
	if not her then width64 = width64(0:npairs-1)
endif

end