pro rd_bda, infil, dset_arr, index, data, roadmap, dp_sync, nodata=nodata, filidx=filidx, dset_str=dset_arr0
;	---------------------------------------------------------------
;+
;NAME:
;	RD_BDA
;PURPOSE:
;	Read and extract BCS images specified in the 'dset_arr'
;	parameter from the BCS Solar-A reformatted data base.
;CALLING SEQUENCE:
;	Rd_BDA, infil, dset_arr, index, data, roadmap
;       Rd_BDA, infil, dset_arr, index, data
;       rd_bda, infil, dset_arr, index, data, roadmap, dset_str=dset_arr
;       Rd_BDA, infil, dset_arr, index, /nodata
;INPUT:
;	infil   : input file specification
;		  "infil" can be a vector of filenames 
;INPUT:
;       infil   : input file specification "infil" can be a vector of filenames 
;       dset_arr: vector of dataset numbers to extract (indices vector)
;               * "dset_arr" can be
;                     1. An indicie vector ("SS") from a search of the roadmap
;                        of ALL of the files in "infil".
;                     2. a structure with fields ".dset" and ".ifil".
;                        ".dset" is the dataset number WITHIN THE FILE, and
;                        ".ifil" is the index of the filename within the
;                        infil array.  The structure is "N" elements long
;                        where "N" is the total number of datasets to extract.
;               * The order that the images are placed in the output
;                 variable "data" is the same order that they
;                 appear in "dset_arr"
;               * If "-1" is passed, the whole file is read
;                 and the dset_arr returned is the "indgen(ndset)"
;OPTIONAL INPUT:
;	nodata  : If present, only the index is read
;OUTPUT:
;	index	: data-index logical record (one for each 
;		  image requested)
;	data	: 2D array
;	roadmap	: summary of data-index logical record, note
;		  all roadmaps records in the file are returned.
;		  In the case where "infil" is an array, roadmap
;                 is the concatenated roadmap for all files that
;                 are being read for the particular extraction.
;	dp_sync :  dp sync section of infil
;                               If the parameter is included
;                               in the call, then it is read
;       filidx  : a vector the same length as the roadmap
;                 with the index of the file associated with that entry
;                 (ie: 0,0,0,0,1,1,1,1,2,2,2,2,...)
;                 This is output from RD_ROADMAP ONLY ON THE FILES FOR
;                 WHICH DATA HAS BEEN SELECTED TO BE READ!
;       dset_str: the structure form of the requested datasets
;                 passed in with "dset_arr".  If user passes in
;                 a simple vector ("SS"), "dset_str" is the structure
;                 form of the output.
;Examples:
;	rd_bda, filename, indgen(10), index, data, roadmap
;	returns 1st 10 images in file=filename
;RESTRICION:
;       CAUTION: If the filename list is long and RD_BDA is going to
;       be called many times getting only a small number of data sets,
;       then it is recommended to use the structure option for "dset_arr"
;       (call MK_DSET_STR externally) because RD_FHEADER is called for
;       all files each time RD_BDA is called when not using the
;       structure option for "dset_arr".
;HISTORY:
;	written by Mons Morrison, Fall 90.
;	 7-Dec-91 MDM - added option to pass a vector of filenames
;			as well as the "filidx" parameter
;	 2-Mar-92 MDM - Changed "data" array output size to look at the
;			"roadmap.length" values for the datasets to be
;			extracted instead of the "file_header.maxsamps"
;			value.  Saves memory.
;        6-Mar-92 MDM - Changed calling sequence to allow "dset_arr"
;                       to be a simple integer array ("SS") or a structure
;                       with .DSET and .IFIL.  "SS" option can be used
;                       even if infil is an array (previously restricted
;                       to turn it into a structure in external routine)
;                       Uses MK_DSET_STR internally.
;                       Also added "dset_str" optional output capability
;	19-Mar-92 MDM - Changed not to use the "roadmap2" method of getting
;			the byte offset.  Instead, uses the full roadmap.
;			This is to speed up the reading if reading the same
;			file multiple times.
;			Also, changed call to RD_INDEX to pass the byte offset
;			so it does not have to read RD_ROADMAP
;       20-Mar-92 MDM - Changed so output structure version is not updated if
;                       the different structure is switching to an OLDER version
;-
;
bcs_struct
bcs_old_struct
;
get_lun, lun
nfiles = n_elements(infil)
;
dset_arr0 = mk_dset_str(infil, dset_arr)        ;turn the input into a structure
nout = n_elements(dset_arr0)
;
ss = 0
if (n_elements(dset_arr0) gt 1) then ss = uniq(dset_arr0.ifil)
ifil0 = dset_arr0(ss).ifil
infil0 = infil( ifil0 )                         ;list only of the files that will be read
;
rd_roadmap, infil0, roadmap, ndset, recsize, filidx=filidx               ;get roadmap for all files that are to be read
if (total(ndset) eq 0) then begin
    print, 'RD_BDA: # of datasets in the file is zero'
    print, 'Returning
    return
end
;
dset_arr3 = dset_arr0.dset      ;indicie in roadmap (of only "infil0" files) - figures how many dataset in total in each file.
offset = 0
for i=0,n_elements(infil0)-2 do begin           ;only relevant if more than one file is being read
    offset = offset + ndset(i)
    ss = where(dset_arr0.ifil eq ifil0(i+1))
    if (ss(0) ne -1) then dset_arr3(ss) = dset_arr3(ss) + offset
end
;
maxsamps = 0
quse_length = 1
ii = tag_index(roadmap, 'length')
if (ii ne -1) then maxsamps = max(roadmap(dset_arr3).length)
if (maxsamps eq 0) then begin		;handles case where tag "index" is not defined at all (OR) case where length = 0
    rd_fheader, infil, file_header, ndset0
    maxsamps = max(file_header.maxSamps)
    quse_length = 0
end
;
rd_index, infil(dset_arr0(0).ifil), roadmap(dset_arr3(0)).byteSkip, index0	;;calling seq changed 19-Mar-92
index_version = [index0.gen.index_version, index0.bcs.index_version]
index = replicate(index0, nout)
data = 0	;free up previously defined memory
;
idset = 0	;dset in the output matrix
for ifil=0,nfiles-1 do begin
    ss = where(dset_arr0.ifil eq ifil)
    ndset_arr2 = 0
    if (ss(0) ne -1) then begin
	dset_arr2 = dset_arr0(ss).dset			;dataset vector for a single file
	ndset_arr2 = n_elements(dset_arr2)
    end

    if (ndset_arr2 ne 0) then begin
	openr, lun, infil(ifil), /block
	;
	;;rd_roadmap, lun, roadmap2
	;;rd_fheader, lun, fheader, ndset
	;;if (dset_arr2(0) eq -1) then dset_arr2 = indgen(ndset)		;should have already been converted to
										;an actual list of dataset #s above
	;
	for idset2=0,ndset_arr2-1 do begin
	    dset = dset_arr2(idset2)
	    dset3 = dset_arr3(idset)	;;added 19-Mar-92
	    ;
;;	    if ((dset gt ndset-1) or (dset lt 0)) then begin
;;		print, 'Data set number must be greater than 0 and less than ', ndset-1
;;		print, 'Action: Returning 
;;		return
;;	    end
	    ;
;;	    ibyt = roadmap2(dset).byteSkip
	    ibyt = roadmap(dset3).byteSkip
	    rdwrt, 'R', lun, ibyt, 0, index0, 1
	    index(idset) = index0
            ;
            ;read the index assuming that the index version was the same.  If it is different, then read it
            ;again using "rd_index" which makes the structure the proper new structure.  Replicate the new structure
            ;and then copy all of the old fields into the new structure.

	    ;
	    chk_index_version = [index0.gen.index_version, index0.bcs.index_version]
	    if (total(chk_index_version-index_version) gt 0) then begin
;;		rd_index, lun, roadmap2(dset).byteSkip, index0
		rd_index, lun, roadmap(dset3).byteSkip, index0
		index_tmp = replicate(index0, nout)		;make output structure the data type of the latest structure
		for i=0,idset-1 do index_tmp(i) = str_copy(index0, index(i))
		index = index_tmp
		index_version = [index0.gen.index_version, index0.bcs.index_version]
	    end
		
	    qread_data = 1
	    if (keyword_set(nodata)) then qread_data = 0
	    if (index(idset).gen.ndatabyte eq 0) then qread_data = 0
	    if (qread_data) then begin
		dtyp = index(idset).gen.data_word_type mod 16
		if (idset eq 0) then begin
		    case dtyp of
			1: data = bytarr(maxsamps, nout)
			2: data = intarr(maxsamps, nout)
			4: data = fltarr(maxsamps, nout)
		    endcase
		    ref_dtyp = dtyp
		end

		if (quse_length) then nbyte = index(idset).bcs.length $
				else nbyte = index(idset).gen.ndatabyte	
				;"ndatabyte" is the actual number of bytes on the disk, including padding
		case dtyp of
		    1: data0 = bytarr(nbyte)
		    2: data0 = intarr(nbyte)
		    4: data0 = fltarr(nbyte)
		endcase
;;		ibyt = roadmap(dset).byteSkip + index(idset).gen.nIndexByte
		ibyt = roadmap(dset3).byteSkip + index(idset).gen.nIndexByte
		rdwrt, 'R', lun, ibyt, 0, data0, 1
		;
		if (dtyp gt ref_dtyp) then case dtyp of	;new data type which requires
							;more space
		    2: data = fix(data)		;convert to integer*2
		    4: data = float(data)	;convert to real*4
		endcase
		;
		data(0,idset) = data0

	    end		;if read data
	    idset = idset + 1

	end		;loop for each dataset in one file
    close, lun
    end			;finished one file
end
;
if (n_params(0) eq 6) then rd_bda_dp, infil, dp_sync
;
free_lun, lun
end
