Documentation of the BYU-MERS "SIR" file header contents (c) 2022 BYU MERS A BYU-MERS "SIR" file consists of one or more 512 byte headers containing all the information required read the remainder of the file and the map projection information required to map pixels to lat/lon on the Earth surface and visa-versa, followed by a list of pixels values. The end of the file is padded with zeros to make its length an integer multiple of 512 bytes. Pixel values are stored as 2-byte (high order byte first) integers though the values can optionally be stored as bytes or IEEE floating point. The latter is not portable to all machines. Scale factors to convert the integer or byte pixel values to native floating point units are stored in the file header. The origin of the image is in the lower left corner. Pixel indexes run from 1 to N. Pixel (1,1) is in the lower left of the image. The Lat,Lon of a pixel corresponds to the lower left corner of the pixel The size of image is stored as the first two 2-byte integers in the header (NSX,NSY). The 1-based address of the Nth pixel is X=1+mod(N,NSX) Y=1+floor(N/NSX) where N=Y+(X-1)*NSX. The header record consists of 256 2-byte integers (high order byte first). The meaning of each integer is defined below. When "<=" is used, the integer represents a scalled floating point value whose scaling is defined in the SIR file read/write file code that is part of the file definition. Note that character strings are fixed length and do not have to be null terminated. Longitudes are -180:180. nint=nearest integer. *depends on projection type ** character strings stored as sequence of 2-byte integers as c(n)+c(n+1)*256, where c(n) is the nth byte of string. (recall that the integers are stored in big-endian form in the SIR file) word(1) = nsx ! number of pixels in x direction word(2) = nsy ! number of pixels in y direction word(3) <= xdeg ! span of x* (generally km) word(4) <= ydeg ! span of y* (generally km) word(5) = nhtype ! header type (old<15,20,30) word(6) <= ascale ! x scaling* word(7) <= bscale ! y scaling* word(8) <= a0 ! x origin* word(9) <= b0 ! y origin* word(3) = nint((xdeg + float(ixdeg_off)) * float(ideg_sc)) word(4) = nint((ydeg + float(iydeg_off)) * float(ideg_sc)) if (iopt==1 or iopt==2) then ! lambert word(6) = nint(float(iscale_sc)/ascale) word(7) = nint(float(iscale_sc)/bscale) else if (iopt==11 or iopt==12 or iopt==13) then ! EASE1 grid word(6) = nint(float(iscale_sc)*anint(10.*ascale*25.067525/6371.228)*0.05) word(7) = nint(float(iscale_sc)*anint(10.*bscale/25.067525)*0.05) else ! everything else word(6) = nint(ascale * float(iscale_sc)) word(7) = nint(bscale * float(iscale_sc)) word(8) = nint((a0 + float(ia0_off)) * float(i0_sc)) word(9) = nint((b0 + float(ib0_off)) * float(i0_sc)) word(10) = ioff ! offset to be added to scale val word(11) = iscale ! scale factor ival=(val-ioff)/iscale word(12) = iyear ! year for data used word(13) = isday ! starting JD word(14) = ismin ! time of day for first data (in min) word(15) = ieday ! ending JD word(16) = iemin ! time of day for last data (in min) word(17) = iopt ! map projection type -1 = no projection, image only 0 = rectalinear lat/lon 1 = lambert equal area 2 = lambert equal area (local Earth radius) 5 = polar stereographic 8 = EASE2 north equal area grid 9 = EASE2 south equal area grid 10 = EASE2 cylindrical grid 11 = EASE1 north equal area grid 12 = EASE1 south equal area grid 13 = EASE1 cylindrical grid word(18) = iregion ! region id code word(19) = itype ! image type code word(20) thru word(39) ! 40 chars of "sensor" string** word(40) = iscale_sc ! ascale/bscale scale factor word(41) = nhead ! number of 512 byte header blocks (normally 1) word(42) = ndes ! number of 512 byte blocks description (normally 0) word(43) = ldes ! number of bytes of description (normally 0) word(44) = nia ! number of optional integers (normally 0) word(45) = ipol ! polarization (0=n/a,1=HH,2=VV,3=HV,4=VH) word(46) = ifreqhm ! frequency in 100's MHz (0 if n/a) word(47) = ispare1 ! spare word(48) = idatatype ! data type code 0,2=i*2,1=i*1,4=float Note: the value of idatatype determines how image data is stored and how anodata (the "no data" flag value), vmin, and vmax are stored. vmin and vmax are values that indicate to viewer programs a 'nice' range of values to show when visualization. They are not the the true minimum and maximum of the possible values. if idatatype = 1 data is stored as bytes (minv=128) if idatatype = 2 data is stored as 2 byte integers (minv=32766) if idatatype = 4 data is stored as IEEE floating point idatatype==2 is considered the SIR standard format when idatatype = 1,2 anodata,vmin,vmax are stored as 2 byte integers in word(49)..word(51) minv, ioff and iscal used to convert integers or bytes into floating point values nodata, vmin, and vmax must be representable with ioff and iscale word(*) = (value-ioff)*iscale-minv float value = float(word(*)+minv)/float(iscale)+ioff when idatatype = 4 anodata,vmin,vmax are stored as (ideally IEEE) floating point values in word(42)..word(57) and the minv, ioff, and iscale are ignored. note: floating point storage may not be standard across all platforms word(49) <= anodata ! value representing "no data" word(50) <= vmin ! minimum visualization value from creator prg word(51) <= vmax ! maximum visualization value from creator prg word(52,53) = anodata ! IEEE floating value of "no data" value word(54,55) = vmin ! IEEE floating minimum visualization value word(56,57) = vmax ! IEEE floating maximum visualization value word(58) thru word(126) ! 150 chars of "type" string** word(127) = ixdeg_off ! xdeg offset value word(128) = iydeg_off ! ydeg offset value word(129) thru word(168) ! 80 chars of "title" string** word(169) = ideg_sc ! xdeg,ydeg scale factor value word(170) thru word(189) ! 40 chars of "tag" string** word(190) = ia0_off ! b0 offset value word(191) thru word(240) ! 100 chars of "crproc" string** word(241) = ib0_off ! b0 offset value word(242) thru word(255) ! 28 chars of "crtime" string** word(256) = i0_sc ! a0,b0 scale factor value The SIR file format supports optional 512 byte header blocks that follow the initial header blocks. These are only present when nhead>0. ndes header blocks of 512 bytes: chars of description nhead-ndes-1 header blocks of 512 bytes: values of iaopt by convention, first value iaopt is a code telling how to interpret the rest of the array if nia>0. Usage of additional blocks is user-dependent and non-standard. Remainder of file is image data in a multiple of 512 byte blocks Scaling of image values: For one or two-byte storage (idatatype==1,2) the scaling is stored integer value = int( fvalue-ioff)*iscale-minv ) converted float value = float(intval+minv)/float(iscale)+float(ioff) For float storage (idatatype==4) the stored values are NOT scaled.