pro read_sotsp, files, index,data, _extra=_extra, scan_info=scan_info, phead=phead ; ;+ ; Name: read_sotsp ; ; Purpose: ssw style api for SOT-SP level2 and level 2.1 ; ; Input Parameters: ; files - SOT-SP Level 2 (merlin/binary extended fits) ; ; Output Parameters: ; index,data - ssw compatible "index,data", 1:1 sp maps ; ; Keyword Parameters: ; _extra - keywords -> sotsp_l2struct2data via inheritance & -> mrdfits for "non-merlin" ; scan_info (outpu) -> structure containg 1D vectors ; (TIMES, SLITPOS, and SCATT) ; phead (output) -> primary FITS header(structure) ; silent (switch) -> inherit via mrdfits ; ; Calling Sequence: ; IDL> read_sotsp, l2file, index, data , scan_info=scan_info ; ; Calling Example: ; IDL> read_sotsp,l2,index,data,scan_info=si ; IDL> help,data,si,index,/str ; DATA FLOAT = Array[4156, 256, 36] <<, 3 tags, length=66944, data length=66944, refs=1: ; TIMES STRING Array[4156] <<< times per slit position ; SLITPOS FLOAT Array[4156] <<< slit pos ; SCATTPRO FLOAT Array[112] <<< scattered light profile ; ** Structure <2930804>, 54 tags, length=624, data length=620, refs=1: ; SIMPLE INT 1 <<< index.simple ; BITPIX LONG 8 <<< index... etc ; (...etc; more tags here...) ; FITSTAGS STRING 'SFLD' <<< ssw/info added info ; CUNIT1 STRING 'kG' ; CUNIT2 STRING 'kG' ; FTYPE STRING 'Magnetic Field' ; INSTRUME STRING 'SOT/SP Magnetic Field' <<< ssw superset added ; TELESCOP STRING 'HINODE' ; CDELT1 FLOAT 0.148565 ; CDELT2 FLOAT 0.159991 ; DATE_OBS STRING ' 1-Dec-2006 11:00:47.000' ; DATE_END STRING ' 1-Dec-2006 16:59:52.000' ; ; ; History: ; 1-Jun-2008 - S.L.Freeland - ssw interface to merlin/bin extended FITS ; 25-aug-2016 - S.L.Freeland - train to read Ted/Phil style SP "movie" cubes, add PHEAFD output ; 26-Apr-2018 - PGShirts - added two if/then catches to reform 'dat' if n_dimensions(dat) eq 1 (this is the sit-and-stare case). ; NOTE: as each column is read in a for-loop, the read for a sit-and-stare observation can take a long time. ; --perhaps this could be vectorized in the future to improve the sit-and-stare obs ingest speed. ; 14-Jul-2020 - M.DeRosa - added capability to read in level 2.1 ; (disambiguated and reprojected) data if it ; happened to be retrieved by sotsp_getdata.pro. ;- if not file_exist(files(0)) then begin box_message,'Require existing & local SOTSP Level2 filename' return endif mreadfits,files[0],phead next=get_fits_nextend(files[0]) ; get #nextesions if required_tags(phead,'invcode') then begin ; read lev2 header/images into the standard SSWIDL index/data arrays l2s=merlin_read_fits2(files(0),_extra=_extra) sotsp_l2struct2data, l2s, index, data , _extra=_extra, scan_info=scan_info ; read in lev2.1 (disambiguated data) if available lev21file=str_replace(files(0),'level2hao','level2.1hao') lev21file=str_replace(lev21file,'.fits','_L2.1.fits') if file_test(lev21file) then begin lev21s=ssw_binfits2struct(lev21file,_extra=_extra) lev21s=join_struct({header:headfits(lev21file)},temporary(lev21s)) sotsp_l21struct2data,lev21s,index21,data21,_extra=_extra,scan_info=scan_info ; are all lev2 header (=index) keywords in the lev2.1 headers? ;box_message,'merging lev2 and lev2.1 into a single index,data pair' lev2tags=tag_names(index[0]) flag=0 for ii=0,n_elements(lev2tags)-1 do begin if ~tag_exist(index21[0],lev2tags[ii]) then begin print,' tag '+lev2tags[ii]+' not in lev2.1 header' flag++ endif endfor if flag gt 0 then begin box_message,'Found '+strtrim(flag,2)+' tags from lev2 header that are not in lev2.1 header, returning only lev2 data' return endif ; next, extend lev2 headers to include new lev2.1 keywords lev21tags=tag_names(index21[0]) for ii=0,n_elements(lev21tags)-1 do $ if ~tag_exist(index,lev21tags[ii]) then $ index=add_tag(temporary(index),index21[0].(ii),lev21tags[ii]) ; now should be able to concatenate index structures and data arrays index=merge_struct(index,index21) data=[[[temporary(data)]],[[temporary(data21)]]] endif endif else begin ; TODO? - additional sanity check for non-Merlin? dat=mrdfits(files[0],1,head,_extra=_extra) index=replicate(fitshead2struct(head),next) ; in case of single slit position (where extension is a 1-d array) if n_dimensions(dat) eq 1 then dat=reform(dat,[1,n_elements(dat)],/overwr) data=make_array(data_chk(dat,/nx),data_chk(dat,/ny),type=data_chk(dat,/type),next) for e=0,next-1 do begin ; extension loop delvarx,dat,head dat=mrdfits(files[0],e+1,head,_extra=_extra) ; in case of single slit position (where extension is a 1-d array) if n_dimensions(dat) eq 1 then dat=reform(dat,[1,n_elements(dat)],/overwr) data[0,0,e]=dat index[e]=fitshead2struct(head) endfor endelse return end