FUNCTION gethd,headbytes,length=length ; ; DPS, CNSR, July 1992 ; ; Modified, DPS, November 1992 and January 1993, to handle revised KI ; header format. ; Modified by DPS, July 1994, to handle bytes added to image headers ; in processing. ; ; This function accepts a 512-byte header from an image acquired ; by PoCa under KI, and returns a structure containing the header ; information. The structure field names parallel those used in KI ; as closely as possible. ; ; KI version 1.0 ; nb=N_ELEMENTS(headbytes) IF nb LT 512 THEN BEGIN MESSAGE,'Header too short - '+STRTRIM(nb,2)+' bytes',/INFORMATIONAL RETURN,-1 ENDIF ; ; Start by defining needed structures. ; ti={ t_struct, last:0, min:0, max:0, mean:0, num:0 } dosdate={ dosdate_t, day:0B, month:0B, year:0, dayofweek:0B } dostime={ dostime_t, hour:0B, minute:0B, second:0B, csecond:0B } te={ temp_t, tei:ti, tee:ti, td:ti, tcc:ti, tcf:ti, tfw:ti } ccdd={ ccd_descript, cols:0, rows:0, prescan:0, postscan:0, $ parallel_delay:0, parallel_states:0, $ frame_transfer:0, mpp_expose:0, mpp_clock:0, $ high_hwell:0, id:'CCD_designation#' } cm={ cam_misc, cam:0B, fw:0B, id:0B, port:0B, temp:te, heater:0, fan:0, $ acpower:0, plus5:0, plus15:0, minus15:0, preamp:0, $ exp_scale:0, sequence:0, ems_handle:0, imgsize:0L, $ version:0, dt:dosdate, tm:dostime, exposure_type:0B, $ pixel_max:0, pixel_min:0, opmode:0, lens:'', $ filter:'', loc:'', az:'', oper:'', jpegq:'', compfact:'', $ os_vers:'' } cs={ cam_sys, ccd:ccdd, at200_id:0, frame:0, open_delay:0, $ close_delay:0, preamp_delay:0, speed:0, data_bits:0 } ce={ cam_exp, ram:0L, exposure:0L, gain:0, mpp_mode:0, corg:0, rorg:0, $ cols:0, rows:0, sbin:0, pbin:0, clr_cnt:0, row_shift:0 } ; ; The following structure is needed to describe image processing ; applied to the raw images acquired by the Polar Camera. It has ; no counterpart in the header generated by KI. See the file ; ~cnsr3/bkgrd/header.mods for more information. ; pd={ proc_data, scale_factor:0B, base2:0B, bkgd_camera:0B $ , bkgd_filter:0B, bkgd_hstart:0B, bkgd_mstart:0B $ , bkgd_sstart:0B, bkgd_mlength:0B, bkgd_source:0B } KIh={ KI_header, misc:cm, sys:cs, exp:ce, proc:pd } ; ; Fill structures from headbytes array. ; NOTE: byte reversal done in rdkimg.pro is appropriate for INTEGER- ; type variables, but not for BYTE- or LONGWORD-type variables. Make a ; copy of headbytes and unreverse it for the latter cases. ; ptr=0 ; pointer to current position in input BYTE array urhb=headbytes & BYTEORDER,urhb ; ; First fill 'misc' structure. ; nfields=N_TAGS(KIh.misc) ftype=[0,0,0,0,1,2,2,2,2,2,2,2,2,2,2,3,2,4,5,0,2,2,2,6,6,7,8,9,9,9,9] FOR i=0,nfields-1 DO BEGIN CASE ftype(i) OF 0: BEGIN ; BYTE-valued field KIh.misc.(i)=BYTE(urhb,ptr) ptr=ptr+1 END 1: BEGIN ; temperature structure ntemps=N_TAGS(KIh.misc.(i)) FOR j=0,ntemps-1 DO BEGIN ndata=N_TAGS(KIh.misc.(i).(j)) FOR k=0,ndata-1 DO BEGIN KIh.misc.(i).(j).(k)=FIX(headbytes,ptr) ptr=ptr+2 ENDFOR ENDFOR END 2: BEGIN ; INTEGER-valued field IF ptr MOD 2 EQ 1 THEN ptr=ptr+1 ; even pointer for INTEGER KIh.misc.(i)=FIX(headbytes,ptr) & ptr=ptr+2 END 3: BEGIN ; LONGWORD-valued field tmp=BYTE(urhb,ptr,4) & ptr=ptr+4 BYTEORDER,tmp,/LSWAP ; mirror-reverse all four bytes KIh.misc.(i)=LONG(tmp,0) END 4: BEGIN ; DOS date structure KIh.misc.dt.day=BYTE(urhb,ptr) & ptr=ptr+1 KIh.misc.dt.month=BYTE(urhb,ptr) & ptr=ptr+1 KIh.misc.dt.year=FIX(headbytes,ptr) & ptr=ptr+2 KIh.misc.dt.dayofweek=BYTE(urhb,ptr) & ptr=ptr+2 END 5: BEGIN ; DOS time structure FOR j=0,3 DO BEGIN KIh.misc.(i).(j)=BYTE(urhb,ptr) & ptr=ptr+1 ENDFOR END 6: BEGIN ; BYTARR(6)-valued field KIh.misc.(i)=STRING(BYTE(urhb,ptr,6)) & ptr=ptr+6 END 7: BEGIN ; BYTARR(81)-valued field KIh.misc.(i)=STRING(BYTE(urhb,ptr,81)) & ptr=ptr+81 END 8: BEGIN ; BYTARR(11)-valued field KIh.misc.(i)=STRING(BYTE(urhb,ptr,11)) & ptr=ptr+11 END 9: BEGIN ; BYTARR(4)-valued field KIh.misc.(i)=STRING(BYTE(urhb,ptr,4)) & ptr=ptr+4 END ENDCASE ENDFOR ; ; Next fill 'sys' structure. This one is messy, and can't be dealt ; with as "elegantly" as the 'misc' structure. ; nccdparms=N_TAGS(KIh.sys.ccd) FOR i=0,nccdparms-6 DO BEGIN ; these are ordinary short integers KIh.sys.ccd.(i)=FIX(headbytes,ptr) & ptr=ptr+2 ENDFOR mask=1 FOR i=nccdparms-5,nccdparms-2 DO BEGIN ; single-bit flags KIh.sys.ccd.(i)=(mask AND BYTE(urhb,ptr))/mask mask=2*mask ENDFOR ptr=ptr+2 KIh.sys.ccd.id=STRING(BYTE(urhb,ptr,16)) & ptr=ptr+16 ; ; Finished with 'sys.ccd', so go on to the rest of 'sys'. ; syslong=LONG(urhb,ptr) & ptr=ptr+4 BYTEORDER,syslong,/LSWAP ; mirror-reverse all four bytes fwidth=[0,5,1,5,5,7,3,5] ; define bit widths of fields FOR i=1,N_TAGS(KIh.sys)-1 DO BEGIN ; skip the 'ccd' structure field mask=2^fwidth(i)-1 ; define mask for i'th field KIh.sys.(i)=syslong AND mask ; mask appropriate bits syslong=ISHFT(syslong,-fwidth(i)) ; remove bits once read ENDFOR ; ; That should do it for 'sys'; now do 'exp'. ; KIh.exp.ram=LONG(headbytes,ptr) & ptr=ptr+4 exptime=LONG(urhb,ptr) & ptr=ptr+4 BYTEORDER,exptime,/LSWAP KIh.exp.exposure=exptime FOR i=2,N_TAGS(KIh.exp)-1 DO BEGIN KIh.exp.(i)=FIX(headbytes,ptr) & ptr=ptr+2 ENDFOR ; ; Finally, read the bytes describing any processing done on the image. ; FOR i=0,N_TAGS(KIh.proc)-1 DO BEGIN KIh.proc.(i)=BYTE(headbytes,ptr) & ptr=ptr+1 ENDFOR ; ; Th-th-th-that's all, folks! ; IF KEYWORD_SET(length) THEN PRINT,'First unused byte is ',ptr RETURN,KIh END