pro El_Read @compile_opt.pro ; On error, return to caller ;+ ; NAME: ; El_Read ; PURPOSE: ; Read electron (I2) data from optical disk ; CATEGORY: ; I/O ; CALLING SEQUENCE: ; El_Read ; OUTPUTS: ; All output returned in common block I2 ; CHANSeV center energychannels in eV ; AzNoShift unshifted azimuth sector centers (deg) ; AzShift shifted azimuth sector centers (deg ; I2_data structure array for electron data (see PROCEDURE) ; in_YR, in_DOY time origin for the spectrum time (see PROCEDURE) ; CALLS: ; ECHO, E1_define ; COMMON BLOCKS: ; common E1_setup, gen, ndm, hdm1, hdm2 ; Plasma structures ; common I2, CHANSeV,AzNoShift,AzShift,I2_data, ; in_SC,in_YR,in_DOY ; SIDE EFFECTS: ; Data files are accessed readonly. ; RESTRICTIONS: ; Reading becomes slow after the first CntMax (=2000) spectrum (see ; PROCEDURE) ; PROCEDURE: ; > Prompts for: ; - Data directory (current default DUA2:[HOS]) ; - Start time (day of year, hours and minutes) ; - Stop time (day of year, hours and minutes) ; > After the directory is specified it is search for plasma data files ; > The electron data are read into the array of structures I2_data. ; An array of size CntMax (currently set to 2000) is created before ; reading starts (using the REPLICATE command) ; - If the number of spectra read is less than CntMax the data array is ; reduced in size before returning to caller ; - If the number of spectra read is more then CntMax the spectra after ; CntMax are appended to the data array one by one (!!! this is ; sooooo sloooooow). ; The data array I2_data can be accessed by other procedures through ; common block I2 ; > The electron data currently extracted from each spectrum are ; - Electron counts ; - Magnetic field ; - Indicator for azimuth shift (0 for no shift, 1 for shift) ; - Spectrum time (mSec relative to (in_YR, in_DOY) (see common block I2) ; The data for spectrum I are stored in in the form of a structure ; I2_data(I) = {E_struct, TIME: 0L, ELEC: lonarr(8,32), ; AZSHIFT: 0., B: fltarr(3)} ; MODIFICATION HISTORY: ; 1992, Tom Davidson (UCSD), adapted from the F77 version ; AUG-1992, Paul Hick (UCSD), added capability to read data spans ; spanning more than one file ;- common E1_setup, gen, ndm, hdm1, hdm2 ; Plasma structures common I2, CHANSeV,AzNoShift,AzShift,I2_data,in_SC,in_YR,in_DOY common DatDir, DATADIR, iout_HOUR, iout_MIN twin, 2 ; Swithch to alpha-numeric screen ; Define structures necessary to read from optical disk if n_elements(GEN) eq 0 then E1_define ; Define structures if necessary ; Define structure for the electron data e = {E_struct, TIME: 0L, AZshift: 0B, ELEC: lonarr(8,32), B: fltarr(3)} ; Centers of energy channels in eV: 0-15 low energies (program A), 16-31 high ; energies (program B) CHANSeV = [0.,.5,1.,1.5,2.,2.7,3.4,4.1,4.8,5.8,6.8,7.8,8.8,10.3,11.8,13.3, $ 9.28,13.0,18.2,25.48,35.67,49.94,69.92,97.89,137.1,191.9,268.6, $ 376.1,526.5,737.1,1032.,1445.] if n_elements(DATADIR) eq 0 then DATADIR = 'DUA2:[HOS]' echo, 'Enter the data directory ?',DATADIR INFILE = 'H%Y%%.D%%%' Slo = file_search(DATADIR+INFILE) if Slo(0) eq "" then message, DATADIR+' contains no Helios plasma data' Shi = Slo(n_elements(Slo)-1) Slo = Slo(0) POS = strpos(Slo,']H')+1 DATADIR = strupcase( strmid(Slo,0,Pos) ) POS = POS+1 in_SC = fix( strmid (Slo,POS,1) ) POS = POS+2 YR_beg = fix( strmid (Slo,POS,2) ) ; 1st and last year YR_end = fix( strmid (Shi,POS,2) ) POS = POS+4 DOY_beg = fix( strmid (Slo,POS,3) ) ; 1st and last day of year DOY_end = fix( strmid (Shi,POS,3) ) date_doy, 1, [YR_beg,YR_end], CMON, MON, DAY, [DOY_beg,DOY_end] print, ' ' print, 'Helios data in directory '+DATADIR print, ' Spacecraft : Helios ',strcompress(in_SC,/rem) print, ' First day : Year 19',strcompress(YR_beg,/rem),' DOY ', $ string(format='(I3.3)',DOY_beg)+ $ ' ( 19'+strcompress(YR_beg,/rem)+'/'+ $ string(format='(I2.2)',MON(0))+'/'+string(format='(I2.2)',DAY(0))+' )' print, ' Last day : Year 19',strcompress(YR_end,/rem),' DOY ', $ string(format='(I3.3)',DOY_end)+ $ ' ( 19'+strcompress(YR_end,/rem)+'/'+ $ string(format='(I2.2)',MON(1))+'/'+string(format='(I2.2)',DAY(1))+' )' print, '' ; Define two sets for the centers of the azimuth sectors (shifted and ; unshifted). The two arrays can be be accessed by other procedures through ; common block I2 if in_SC eq 1 then begin AzNoShift = [-191.39,-146.28,-101.32,-56.36,-11.40,33.72,78.68,123.64,168.61] AzShift = [-188.58,-143.47,- 98.51,-53.55,- 8.51,36.53,81.49,126.45,171.42] endif else begin AzNoShift = -167.35+45.*findgen(9) AzShift = -22.5+AzNoShift endelse strput, INFILE, string(format='(I1)',in_SC),1 message, 'Specify start time (year,doy,hour,min)', /info if n_elements(in_YR) eq 0 then in_YR = YR_beg ; Saved in common block if YR_beg ne YR_end then echo, 'Year', in_YR, YR_beg,YR_end DOY_lo = 1 ; Set selection limits in_DOY if in_YR eq YR_beg then DOY_lo = DOY_beg DOY_hi = 365 if in_YR mod 4 eq 0 then DOY_hi = 366 if in_YR eq YR_end then DOY_hi = DOY_end if n_elements(in_DOY) eq 0 then in_DOY = DOY_lo; Saved in common block echo, 'Day of year', in_DOY, DOY_lo, DOY_hi if n_elements(iout_HOUR) ne 0 then in_HOUR = iout_HOUR else in_HOUR = 0 echo,'Hour', in_HOUR, 0, 24 if n_elements(iout_MIN) ne 0 then in_MIN = iout_MIN else in_MIN = 0 echo,'Min' , in_MIN , 0, 60 in_mSec = (in_HOUR*60L+in_MIN)*60000L message, 'Specify stop time (year,doy,hour,min)', /info iout_YR = in_YR if iout_YR ne YR_end then echo, 'Year', iout_YR, in_YR, YR_end if iout_YR eq in_YR then DOY_beg = in_DOY else DOY_beg = 1 if iout_YR mod 4 eq 0 then DOY_end = 366 DOY_lo = 1 ; Set selection limits iout_DOY if iout_YR eq in_YR then DOY_lo = in_DOY DOY_hi = 365 if iout_YR mod 4 eq 0 then DOY_hi = 366 if iout_YR eq YR_end then DOY_hi = DOY_end iout_DOY = DOY_lo echo,'Day of year',iout_DOY, DOY_lo, DOY_hi IHOUR_beg = 0 if iout_YR eq in_YR and iout_DOY eq in_DOY then IHOUR_beg = in_HOUR iout_HOUR = IHOUR_beg & echo, 'Hour', iout_HOUR, IHOUR_beg,24 IMIN_beg = 0 if iout_YR eq in_YR and iout_DOY eq in_DOY and iout_HOUR eq in_HOUR then IMIN_beg = in_MIN iout_MIN = IMIN_beg & echo, 'Min', iout_MIN, IMIN_beg, 60 ; l_YR and l_DOY define the current data file (they will be used to construct ; the name of the data file). c_mSec is the index value used to acces the ; proper record l_YR = in_YR & l_DOY = in_DOY c_mSec = string(format='(I8.8)',in_mSec) start = 1 & Cnt = -1 & CntMax = 2000 I2_data = 0B & I2_data = replicate({E_struct},CntMax) ; The value of offset_mSec is a multiple of 86 400 000 (i.e. one day) and is ; added to the spectrum time (necessary to make sure that the time array is ; increases monotically if the requested data span more than one data file ; (i.e. more than one day) offset_mSec = 0L while 1 do begin ; Infinite loop if not start then begin ; Switch to data file for next day l_DOY = l_DOY+1 & offset_mSec = offset_mSec+86400000L DOY_end = 365 if l_YR mod 4 eq 0 then DOY_end = 366 if l_DOY gt DOY_end then begin l_YR = l_YR+1 & l_DOY = 1 & endif ; Check whether all data are read. If so, exit ; !!!! This is the only valid exit point from this procedure if (l_YR gt iout_YR or l_DOY gt iout_DOY or $ ; All data read (l_DOY eq iout_DOY and iout_HOUR eq 0 and iout_MIN eq 0)) then begin if Cnt eq -1 then message, 'No data read from '+DATADIR if Cnt lt Cntmax-1 then I2_data = I2_data(0:Cnt) message, /info, 'Done! '+strcompress(Cnt+1,/remove_all)+' spectra processed.' Tdum = I2_data(0).TIME print, ' Start time : ', StrmSec(in_YR,in_DOY,Tdum) Tdum = I2_data(n_elements(I2_data.TIME)-1).TIME print, ' Stop time : ', StrmSec(in_YR,in_DOY,Tdum) print return endif c_mSec = '00000000' ; Reset index value to 0 endif ; Set of file name for date file; try to locate it start = 0 strput, INFILE, string(format ='(I2.2)',l_YR),3 strput, INFILE, string(format ='(I3.3)',l_DOY),7 csearch = (file_search(DATADIR+INFILE))[0] ; If file not found, move on to next day; if found, open file and start reading if csearch eq '' then message, 'Target file '+datadir+infile+' not found.', /info $ else begin ; File found; start reading message, 'Reading... '+csearch, /info openr, IU, csearch, /get_lun, /key ; Open for keyed access key_MSEC = c_MSEC+'A' ; 'A' : get GEN record ; Set up the index value indicating 'all data found' if l_YR eq iout_YR and l_DOY eq iout_DOY then iend_MSEC = $ (iout_HOUR*60+iout_MIN)*60000 else iend_MSEC = 86410000 ; In case of i/o error move on to next day (ideally the only i/o error is an ; end of file condition) on_ioerror, READ_ERROR ; Enable error handler for I/O errors ; Read the GEN record for the next spectrum readu, IU, gen,key_value=key_MSEC,key_id=0,key_match=1 mSec = gen.mSec while mSec le iend_MSEC do begin ; Until iend_MSEC is reached if gen.MODE lt 10 then begin ; If data record (NDM,HDM1 or HDM2) present e.TIME = -1L e.B(0) = gen.Bx ; Pick up magnetic field e.B(1) = gen.By e.B(2) = gen.Bz e.AZshift = gen.AZshift ; Azimuth shift ???? ; Read the `raw data' record. Test the electron spectra: reject if too bad. ; The rejection criteria may still be too conservative. We'll see. ; Every spectrum with at least positive count (not equal 32768) is accepted. if gen.MODE eq 0 then begin ; NDM record readu, IU, ndm ; Read raw data test = where( ndm.I2ab gt 0 and ndm.I2ab ne 32768 ) if test(0) ne -1 then begin if gen.I2a_b eq 0 then e.ELEC(*,0:15) = ndm.I2ab $ else e.ELEC(*,16:31) = ndm.I2ab e.TIME = offset_mSec+ndm.mSec endif ; HDM1 record endif else if gen.FORMAT eq 2 or gen.FORMAT eq 3 then begin readu, IU, hdm2 ; Read raw data test = where( hdm2.I2ab gt 0 and hdm2.I2ab ne 32768 ) if test(0) ne -1 then begin e.ELEC = hdm2.I2ab(*,*) e.TIME = offset_mSec+hdm2.mSec endif endif else begin ; HDM2 record readu, IU, hdm1 ; Read raw data test = where( hdm1.I2ab gt 0 and hdm1.I2ab ne 32768 ) if test(0) ne -1 then begin e.ELEC = hdm1.I2ab(*,0:15) e.TIME = offset_mSec+hdm1.mSec endif endelse if e.TIME ne -1 then begin ; If electron counts in e-struct Cnt = Cnt+1 ; Store electron data in I2_data if Cnt lt CntMax then I2_data(Cnt) = e else I2_data = [I2_data,e] if Cnt eq CntMax then message, /info, $ 'If you get this message a lot, increase the value of CntMax' endif else $ print, StrMsec(in_YR,in_DOY,gen.mSec)+ ' : spectrum rejected' endif readu, IU, GEN & mSec = gen.mSec ; Read next record endwhile ; In case of i/o error (end-of-file) close file and move on to next day READ_ERROR: free_lun, IU on_ioerror, NULL ; Cancel error handler for i/o errors endelse endwhile return & end