;+ ;PROCEDURE: mvn_swe_load ;PURPOSE: ; Reads in binary telemetry packet files generated by the MAVEN PFDPU, ; possibly wrapped in spacecraft packets. SWEA packets are identified, ; decompressed if necessary, and decomuted. SWEA housekeeping and data ; are stored in a common block (mvn_swe_com). ; ; The packets can be any combination of: ; ; Housekeeping: normal rate (APID 28) ; fast rate (APID A6) ; ; 3D Distributions: survey mode (APID A0) ; archive mode (APID A1) ; ; PAD Distributions: survey mode (APID A2) ; archive mode (APID A3) ; ; ENGY Spectra: survey mode (APID A4) ; archive mode (APID A5) ; ; Sampling and averaging of 3D, PAD, and ENGY data are controlled by group ; and cycle parameters. The group parameter (G = 0,1,2) sets the summing of ; adjacent energy bins. The cycle parameter (N = 0,1,2,3,4,5) sets sampling ; of 2-second measurement cycles. Data products are sampled every 2^N cycles. ; ENGY spectra can also be summed over 2^N cycles, if the sum mode bit is set. ; ; 3D distributions are stored in 1, 2 or 4 packets, depending on the group ; parameter. Multiple packets must be stitched together (see swe_plot_dpu). ; ; PAD packets have one of 3 possible lengths, depending on the group parameter. ; The PAD data array is sized to accomodate the largest packet (G = 0). When ; energies are summed, only 1/2 or 1/4 of this data array is used. ; ; ENGY spectra always have 64 energy channels (G = 0). ; ;USAGE: ; mvn_swe_load, filename, telemetry=tlm, data=data ; ;INPUTS: ; filename: The full filename (including path) of a binary file containing ; zero or more SWEA APID's. This file can contain compressed ; packets. ; ;KEYWORDS: ; TELEMETRY: A named variable to hold the telemetry bytes, as read ; from filename. This variable is a 1-D byte array. ; ; CBLOCK: If set, then input file is the common block. Default format is ; split/decompressed packets. ; ; MAXBYTES: Maximum number of bytes to process. Default is entire file. ; ; BADPKT: An array of structures providing details of bad packets. ; ; RESET: Clear the data common block before loading new data. ; ; $LastChangedBy: dmitchell $ ; $LastChangedDate: 2014-01-29 10:04:15 -0800 (Wed, 29 Jan 2014) $ ; $LastChangedRevision: 14054 $ ; $URL: svn+ssh://thmsvn@ambrosia.ssl.berkeley.edu/repos/idl_socware/trunk/projects/maven/swea/mvn_swe_load.pro $ ; ;CREATED BY: David L. Mitchell 06-26-11 ;FILE: mvn_swe_load.pro ;- pro mvn_swe_load, filename, cblock=cblock, badpkt=badpkt, maxbytes=maxbytes, reset=reset, $ telemetry=tlm @mvn_swe_com if (data_type(swe_duty) ne 5) then mvn_swe_calib ; swe_3d = 0 ; swe_pad = 0 ; swe_engy = 0 order = n_elements(swe_t) - 1 ; Read in the telemetry file and store the packets in a byte array openr, lun, filename, /get_lun, error=err if (err ne 0) then begin print, !error_state.msg return endif tlm = read_binary(lun, data_type=1, endian='big') ; array of bytes free_lun,lun nbytes = n_elements(tlm) print,nbytes," bytes" if keyword_set(reset) then mvn_swe_clear if keyword_set(maxbytes) then begin print,"Processing only the first ",string(maxbytes)," bytes tlm = temporary(tlm[0L:(maxbytes-1L)]) nbytes = maxbytes endif if keyword_set(cblock) then cbflg = 1 else cbflg = 0 ; Counters for each SWEA packet type. n_28 = 0L ; SWEA Housekeeping n_A0 = 0L ; 3D survey n_A1 = 0L ; 3D archive n_A2 = 0L ; PAD survey n_A3 = 0L ; PAD archive n_A4 = 0L ; ENGY survey n_A5 = 0L ; ENGY archive n_A6 = 0L ; Fast Housekeeping n_XX = 0L ; Unrecognized bytes ; Fixed sync bytes used to identify packets in telemetry stream ; byte 0 --> version (0), secondary header (8) ; byte 1 --> APID (for SWEA: 28, A0, A1, A2, A3, A4, A5, or A6) ; byte 2 --> packet control sequence (11______) ; byte 3 --> packet counter (00-FF) ; byte 4 --> MSB of packet length (variable for compressed and uncompressed SWEA packets) ; byte 5 --> LSB of packet length (09 for uncompressed SWEA packets, variable otherwise) s_28 = '082803'X s_A0 = '08A003'X s_A1 = '08A103'X s_A2 = '08A203'X s_A3 = '08A303'X s_A4 = '08A403'X s_A5 = '08A503'X s_A6 = '08A603'X s_cb = 'EB92'X ; Make one pass through the telemetry and count the number of packets of each type. n = 0L while (n lt (nbytes-6)) do begin head = long(tlm[lindgen(6) + n]) sync = head[2]/64L + 256L*(head[1] + 256L*head[0]) pklen = 7L + head[5] + 256L*head[4] m = n + pklen - 1L if (m ge nbytes) then break ; not enough bytes left to make a packet if (cbflg) then begin ; look for start of next common block packet i = m + 1L if ((i+1L) lt nbytes) then begin scsync = 256L*tlm[i] + tlm[i+1L] if ((scsync) ne s_cb) then sync = 0L endif endif case sync of s_28 : n_28++ s_A0 : n_A0++ s_A1 : n_A1++ s_A2 : n_A2++ s_A3 : n_A3++ s_A4 : n_A4++ s_A5 : n_A5++ s_A6 : n_A6++ else : begin n_XX++ pklen = 1L end endcase n = n + pklen endwhile print,n_28," Housekeeping packets (APID 28)" print,n_A0," 3D Survey packets (APID A0)" print,n_A1," 3D Archive packets (APID A1)" print,n_A2," PAD Survey packets (APID A2)" print,n_A3," PAD Archive packets (APID A3)" print,n_A4," ENGY Survey packets (APID A4)" print,n_A5," ENGY Archive packets (APID A5)" print,n_A6," Fast Hsk packets (APID A6)" print,n_XX," unrecognized bytes" if ((n_28 + n_A0 + n_A1 + n_A2 + n_A3 + n_A4 + n_A5 + n_A6) eq 0L) then begin print,"No SWEA packets!",format='(/,a,/)' return endif ; Define the data types, then make and array for each type hsk_str = {time : 0D , $ ; packet time addr : 0L , $ ; packet address ver : 0B , $ ; CCSDS Version type : 0B , $ ; CCSDS Type hflg : 0B , $ ; CCSDS Secondary header flag APID : 0U , $ ; CCSDS APID gflg : 0B , $ ; CCSDS Group flags npkt : 0B , $ ; packet counter plen : 0U , $ ; packet length LVPST : 0. , $ ; LVPS temperature (C) MCPHV : 0. , $ ; MCP HV (V) NRV : 0. , $ ; NR HV readback (V) ANALV : 0. , $ ; Analyzer voltage (V) DEF1V : 0. , $ ; Deflector 1 voltage (V) DEF2V : 0. , $ ; Deflector 2 voltage (V) V0V : 0. , $ ; V0 voltage (V) ANALT : 0. , $ ; Analyzer temperature (C) P12V : 0. , $ ; +12 V N12V : 0. , $ ; -12 V MCP28V : 0. , $ ; +28-V MCP supply (V) NR28V : 0. , $ ; +28-V NR supply (V) DIGT : 0. , $ ; Digital temperature (C) P2P5DV : 0. , $ ; +2.5 V Digital (V) P5DV : 0. , $ ; +5 V Digital (V) P3P3DV : 0. , $ ; +3.3 V Digital (V) P5AV : 0. , $ ; +5 V Analog (V) N5AV : 0. , $ ; -5 V Analog (V) P28V : 0. , $ ; +28 V Primary (V) modeID : 0B , $ ; Parameter Table Mode ID opts : 0B , $ ; Options DistSvy : 0B , $ ; 3D Survey Options (CCGGxNNN) DistArc : 0B , $ ; 3D Archive Options (CCGGxNNN) PadSvy : 0B , $ ; PAD Survey Options (CCGGxNNN) PadArc : 0B , $ ; PAD Archive Options (CCGGxNNN) SpecSvy : 0B , $ ; ENGY Survey Options (CCxxxNNN) SpecArc : 0B , $ ; ENGY Archive Options (CCxxxNNN) LUTADR0 : 0B , $ ; LUT Address 0 LUTADR1 : 0B , $ ; LUT Address 1 LUTADR2 : 0B , $ ; LUT Address 2 LUTADR3 : 0B , $ ; LUT Address 3 CSMLMT : 0B , $ ; CSM Failure Limit CSMCTR : 0B , $ ; CSM Failure Count RSTLMT : 0B , $ ; Reset if no message in seconds RSTSEC : 0B , $ ; Reset seconds since last message MUX0 : 0B , $ ; Fast Housekeeping MUX 0 MUX1 : 0B , $ ; Fast Housekeeping MUX 1 MUX2 : 0B , $ ; Fast Housekeeping MUX 2 MUX3 : 0B , $ ; Fast Housekeeping MUX 3 DSF1 : 0U , $ ; Deflection scale factor 1 DSF2 : 0U , $ ; Deflection scale factor 2 DSF3 : 0U , $ ; Deflection scale factor 3 DSF4 : 0U , $ ; Deflection scale factor 4 DSF5 : 0U , $ ; Deflection scale factor 5 DSF6 : 0U , $ ; Deflection scale factor 6 ChkSum0 : 0B , $ ; Checksum LUT 0 ChkSum1 : 0B , $ ; Checksum LUT 1 ChkSum2 : 0B , $ ; Checksum LUT 2 ChkSum3 : 0B , $ ; Checksum LUT 3 CmdCnt : 0U , $ ; Command counter HSKREG : bytarr(16) } ; Digital housekeeping register ddd_str = {time : 0D , $ ; packet time addr : 0L , $ ; packet address npkt : 0B , $ ; packet counter cflg : 0B , $ ; compression flag modeID : 0B , $ ; mode ID ctype : 0B , $ ; compression type group : 0B , $ ; grouping (2^N adjacent bins) period : 0B , $ ; sampling interval (2*2^period sec) lut : 0B , $ ; LUT in use (0-7) e0 : 0B , $ ; starting energy frame (0, 1, 2, 3) data : fltarr(80,16) } ; data array (80A x 16E) pad_str = {time : 0D , $ ; packet time addr : 0L , $ ; packet address npkt : 0B , $ ; packet counter cflg : 0B , $ ; compression flag modeID : 0B , $ ; mode ID ctype : 0B , $ ; compression type group : 0B , $ ; grouping (2^N adjacent bins) period : 0B , $ ; sampling interval (2*2^period sec) Baz : 0. , $ ; magnetic field azimuth (0-255) Bel : 0. , $ ; magnetic field elevation (0-40) data : fltarr(16,64) } ; data array (16A x 64E) engy_str = {time : 0D , $ ; packet time addr : 0L , $ ; packet address npkt : 0B , $ ; packet counter cflg : 0B , $ ; compression flag modeID : 0B , $ ; mode ID ctype : 0B , $ ; compression type smode : 0B , $ ; summing mode (0 = off, 1 = on) period : 0B , $ ; sampling interval (2*2^period sec) lut : 0B , $ ; LUT in use (0-7) data : fltarr(64,16) } ; data array (64E x 16T) fhsk_str = {time : 0D , $ ; packet time addr : 0L , $ ; packet address npkt : 0B , $ ; packet counter cflg : 0B , $ ; compression flag mux0 : 0B , $ ; Mux 0 mux1 : 0B , $ ; Mux 1 mux2 : 0B , $ ; Mux 2 mux3 : 0B , $ ; Mux 3 analv : fltarr(224) , $ ; Analyzer voltage def1v : fltarr(224) , $ ; Deflector 1 voltage def2v : fltarr(224) , $ ; Deflector 2 voltage v0v : fltarr(224) } ; V0 voltage maxlen = 2048 bad_str = {time : 0D , $ ; packet time addr : 0L , $ ; packet address npkt : 0B , $ ; packet counter plen : 0 , $ ; packet length apid : 0B , $ ; packet APID dump : bytarr(maxlen) } ; raw packet bytes ; Initialize the data arrays ; If no packets of a certain type exist, then don't overwrite whatever is in the common block. ; This allows sequential loading from multiple files containing subsets of the data (i.e. from ; the splitter). if (n_28 gt 0L) then swe_hsk = replicate(hsk_str, n_28) if (n_A0 gt 0L) then a0 = replicate(ddd_str, n_A0) if (n_A1 gt 0L) then a1 = replicate(ddd_str, n_A1) if (n_A2 gt 0L) then a2 = replicate(pad_str, n_A2) if (n_A3 gt 0L) then a3 = replicate(pad_str, n_A3) if (n_A4 gt 0L) then a4 = replicate(engy_str, n_A4) if (n_A5 gt 0L) then a5 = replicate(engy_str, n_A5) if (n_A6 gt 0L) then a6 = replicate(fhsk_str, n_A6) ; Pass through the telemetry and decommute n = 0L i_28 = 0L i_A0 = 0L i_A1 = 0L i_A2 = 0L i_A3 = 0L i_A4 = 0L i_A5 = 0L i_A6 = 0L badpkt = replicate(bad_str,1) while (n lt (nbytes-6)) do begin head = long(tlm[lindgen(6) + n]) sync = head[2]/64L + 256L*(head[1] + 256L*head[0]) pklen = 7L + head[5] + 256L*head[4] m = n + pklen - 1L if (m ge nbytes) then break ; not enough bytes left to make a packet if (cbflg) then begin ; look for start of next common block packet i = m + 1L if ((i+1L) lt nbytes) then if ((256L*tlm[i] + tlm[i+1L]) ne s_cb) then sync = 0L endif case sync of s_28 : begin pkt = tlm[n:m] ; housekeeping packets are never compressed plen = n_elements(pkt) if (plen ne 112) then begin print,"Bad HSK packet: ",n,format='(a,Z)' bad_str.addr = n m = (plen < maxlen) - 1L bad_str.dump[0L:m] = pkt[0L:m] msb = 2*indgen(5) lsb = msb + 1 ccsds = uint(pkt[msb])*256 + uint(pkt[lsb]) bad_str.apid = '28'X bad_str.npkt = mvn_swe_getbits(ccsds[1],[13,0]) bad_str.plen = plen clock = double(ccsds[3])*65536D + double(ccsds[4]) bad_str.time = mvn_spc_met_to_unixtime(clock) badpkt = [temporary(badpkt), bad_str] endif else begin swe_hsk[i_28].addr = n ; Header (bytes 0-9) msb = 2*indgen(5) lsb = msb + 1 ccsds = uint(pkt[msb])*256 + uint(pkt[lsb]) swe_hsk[i_28].ver = mvn_swe_getbits(ccsds[0],[15,13]) swe_hsk[i_28].type = mvn_swe_getbits(ccsds[0],12) swe_hsk[i_28].hflg = mvn_swe_getbits(ccsds[0],11) swe_hsk[i_28].APID = mvn_swe_getbits(ccsds[0],[10,0]) swe_hsk[i_28].gflg = mvn_swe_getbits(ccsds[1],[15,14]) swe_hsk[i_28].npkt = mvn_swe_getbits(ccsds[1],[13,0]) swe_hsk[i_28].plen = ccsds[2] clock = double(ccsds[3])*65536D + double(ccsds[4]) swe_hsk[i_28].time = mvn_spc_met_to_unixtime(clock) ; SWEA Analog Housekeeping (bytes 10-57) msb = 2L*lindgen(24) + 10L lsb = msb + 1L ahsk = float(fix(pkt[msb])*256 + fix(pkt[lsb])) T = swe_t[order] & for i=(order-1),0,-1 do T = swe_t[i] + T*ahsk[0] swe_hsk[i_28].LVPST = T swe_hsk[i_28].MCPHV = ahsk[1]*swe_v[1] swe_hsk[i_28].NRV = ahsk[2]*swe_v[2] swe_hsk[i_28].ANALV = ahsk[3]*swe_v[3] swe_hsk[i_28].DEF1V = ahsk[4]*swe_v[4] swe_hsk[i_28].DEF2V = ahsk[5]*swe_v[5] swe_hsk[i_28].V0V = ahsk[8]*swe_v[8] T = swe_t[order] & for i=(order-1),0,-1 do T = swe_t[i] + T*ahsk[9] swe_hsk[i_28].ANALT = T swe_hsk[i_28].P12V = ahsk[10]*swe_v[10] swe_hsk[i_28].N12V = ahsk[11]*swe_v[11] swe_hsk[i_28].MCP28V = ahsk[12]*swe_v[12] swe_hsk[i_28].NR28V = ahsk[13]*swe_v[13] T = swe_t[order] & for i=(order-1),0,-1 do T = swe_t[i] + T*ahsk[16] swe_hsk[i_28].DIGT = T swe_hsk[i_28].P2P5DV = ahsk[17]*swe_v[17] swe_hsk[i_28].P5DV = ahsk[18]*swe_v[18] swe_hsk[i_28].P3P3DV = ahsk[19]*swe_v[19] swe_hsk[i_28].P5AV = ahsk[20]*swe_v[20] swe_hsk[i_28].N5AV = ahsk[21]*swe_v[21] swe_hsk[i_28].P28V = ahsk[22]*swe_v[22] ; Flight Software Housekeeping (bytes 58-89) swe_hsk[i_28].modeID = pkt[58] swe_hsk[i_28].opts = pkt[59] swe_hsk[i_28].DistSvy = pkt[60] swe_hsk[i_28].DistArc = pkt[61] swe_hsk[i_28].PadSvy = pkt[62] swe_hsk[i_28].PadArc = pkt[63] swe_hsk[i_28].SpecSvy = pkt[64] swe_hsk[i_28].SpecArc = pkt[65] swe_hsk[i_28].LUTADR0 = pkt[66] swe_hsk[i_28].LUTADR1 = pkt[67] swe_hsk[i_28].LUTADR2 = pkt[68] swe_hsk[i_28].LUTADR3 = pkt[69] swe_hsk[i_28].CSMLMT = pkt[70] swe_hsk[i_28].CSMCTR = pkt[71] swe_hsk[i_28].RSTLMT = pkt[72] swe_hsk[i_28].RSTSEC = pkt[73] swe_hsk[i_28].MUX0 = pkt[74] swe_hsk[i_28].MUX1 = pkt[75] swe_hsk[i_28].MUX2 = pkt[76] swe_hsk[i_28].MUX3 = pkt[77] swe_hsk[i_28].DSF1 = uint(pkt[78])*256 + uint(pkt[79]) swe_hsk[i_28].DSF2 = uint(pkt[80])*256 + uint(pkt[81]) swe_hsk[i_28].DSF3 = uint(pkt[82])*256 + uint(pkt[83]) swe_hsk[i_28].DSF4 = uint(pkt[84])*256 + uint(pkt[85]) swe_hsk[i_28].DSF5 = uint(pkt[85])*256 + uint(pkt[87]) swe_hsk[i_28].DSF6 = uint(pkt[88])*256 + uint(pkt[89]) ; LUT Checksums, Command Counter, and Digital Housekeeping (bytes 92-109) swe_hsk[i_28].Chksum0 = pkt[96] swe_hsk[i_28].Chksum1 = pkt[97] swe_hsk[i_28].Chksum2 = pkt[98] swe_hsk[i_28].Chksum3 = pkt[99] swe_hsk[i_28].CmdCnt = uint(pkt[100])*256 + uint(pkt[101]) swe_hsk[i_28].HSKREG = nibble_word(uint(pkt[108])*256 + uint(pkt[109])) ; 2 spare bytes (110-111) i_28++ endelse end s_A0 : begin pkt = mav_pfdpu_part_decompress_data2(tlm[n:m]) plen = n_elements(pkt) if (plen ne 1296) then begin print,"Bad A0 packet: ",n,format='(a,Z)' bad_str.addr = n m = (plen < maxlen) - 1L bad_str.dump[0L:m] = pkt[0L:m] bad_str.apid = 'A0'X bad_str.npkt = pkt[3] bad_str.plen = plen tb = long(pkt[6:11]) clock = double(tb[3] + 256L*(tb[2] + 256L*(tb[1] + 256L*tb[0]))) subsecs = double(tb[5] + 256L*tb[4])/65536D bad_str.time = mvn_spc_met_to_unixtime(clock + subsecs) badpkt = [temporary(badpkt), bad_str] endif else begin a0[i_A0].addr = n a0[i_A0].npkt = pkt[3] tb = long(pkt[6:11]) clock = double(tb[3] + 256L*(tb[2] + 256L*(tb[1] + 256L*tb[0]))) subsecs = double(tb[5] + 256L*tb[4])/65536D a0[i_A0].time = mvn_spc_met_to_unixtime(clock + subsecs) a0[i_A0].cflg = mvn_swe_getbits(pkt[12],7) ; first bit a0[i_A0].modeID = mvn_swe_getbits(pkt[12],[6,0]) ; last 7 bits a0[i_A0].ctype = mvn_swe_getbits(pkt[13],[7,6]) ; first 2 bits a0[i_A0].group = mvn_swe_getbits(pkt[13],[5,4]) ; next 2 bits a0[i_A0].period = mvn_swe_getbits(pkt[13],[3,0]) ; last 4 bits a0[i_A0].lut = mvn_swe_getbits(pkt[14],[2,0]) ; last 3 bits a0[i_A0].e0 = mvn_swe_getbits(pkt[15],[1,0]) ; last 2 bits counters = decom[pkt[16:1295]/16B, pkt[16:1295] mod 16B] a0[i_A0].data = reform(counters,80,16) i_A0++ endelse end s_A1 : begin pkt = mav_pfdpu_part_decompress_data2(tlm[n:m]) plen = n_elements(pkt) if (plen ne 1296) then begin print,"Bad A1 packet: ",n,format='(a,Z)' bad_str.addr = n m = (plen < maxlen) - 1L bad_str.dump[0L:m] = pkt[0L:m] bad_str.apid = 'A1'X bad_str.npkt = pkt[3] bad_str.plen = plen tb = long(pkt[6:11]) clock = double(tb[3] + 256L*(tb[2] + 256L*(tb[1] + 256L*tb[0]))) subsecs = double(tb[5] + 256L*tb[4])/65536D bad_str.time = mvn_spc_met_to_unixtime(clock + subsecs) badpkt = [temporary(badpkt), bad_str] endif else begin a1[i_A1].addr = n a1[i_A1].npkt = pkt[3] tb = long(pkt[6:11]) clock = double(tb[3] + 256L*(tb[2] + 256L*(tb[1] + 256L*tb[0]))) subsecs = double(tb[5] + 256L*tb[4])/65536D a1[i_A1].time = mvn_spc_met_to_unixtime(clock + subsecs) a1[i_A1].cflg = mvn_swe_getbits(pkt[12],7) ; first bit a1[i_A1].modeID = mvn_swe_getbits(pkt[12],[6,0]) ; last 7 bits a1[i_A1].ctype = mvn_swe_getbits(pkt[13],[7,6]) ; first 2 bits a1[i_A1].group = mvn_swe_getbits(pkt[13],[5,4]) ; next 2 bits a1[i_A1].period = mvn_swe_getbits(pkt[13],[3,0]) ; last 4 bits a1[i_A1].lut = mvn_swe_getbits(pkt[14],[2,0]) ; last 3 bits a1[i_A1].e0 = mvn_swe_getbits(pkt[15],[1,0]) ; last 2 bits counters = decom[pkt[16:1295]/16B, pkt[16:1295] mod 16B] a1[i_A1].data = reform(counters,80,16) i_A1++ endelse end s_A2 : begin pkt = mav_pfdpu_part_decompress_data2(tlm[n:m]) plen = n_elements(pkt) if (plen lt 272) then begin print,"Bad A2 packet: ",n,format='(a,Z)' bad_str.addr = n m = (plen < maxlen) - 1L bad_str.dump[0L:m] = pkt[0L:m] bad_str.apid = 'A2'X bad_str.npkt = pkt[3] bad_str.plen = plen tb = long(pkt[6:11]) clock = double(tb[3] + 256L*(tb[2] + 256L*(tb[1] + 256L*tb[0]))) subsecs = double(tb[5] + 256L*tb[4])/65536D bad_str.time = mvn_spc_met_to_unixtime(clock + subsecs) badpkt = [temporary(badpkt), bad_str] endif else begin a2[i_A2].addr = n a2[i_A2].npkt = pkt[3] tb = long(pkt[6:11]) clock = double(tb[3] + 256L*(tb[2] + 256L*(tb[1] + 256L*tb[0]))) subsecs = double(tb[5] + 256L*tb[4])/65536D a2[i_A2].time = mvn_spc_met_to_unixtime(clock + subsecs) a2[i_A2].cflg = mvn_swe_getbits(pkt[12],7) ; first bit a2[i_A2].modeID = mvn_swe_getbits(pkt[12],[6,0]) ; last 7 bits a2[i_A2].ctype = mvn_swe_getbits(pkt[13],[7,6]) ; first 2 bits a2[i_A2].group = mvn_swe_getbits(pkt[13],[5,4]) ; next 2 bits a2[i_A2].period = mvn_swe_getbits(pkt[13],[3,0]) ; last 4 bits a2[i_A2].Baz = float(pkt[14]) a2[i_A2].Bel = float(mvn_swe_getbits(pkt[15],[5,0])) ; last 6 bits n_e = swe_ne[a2[i_A2].group] bmax = 16*n_e + 15 if ((bmax+1) eq n_elements(pkt)) then begin counters = decom[pkt[16:bmax]/16B, pkt[16:bmax] mod 16B] a2[i_A2].data[*,0:(n_e-1)] = reform(counters,16,n_e) i_A2++ endif else print, "Bad A2 packet: ",n,format='(a,Z)' endelse end s_A3 : begin pkt = mav_pfdpu_part_decompress_data2(tlm[n:m]) plen = n_elements(pkt) if (plen lt 272) then begin print,"Bad A3 packet: ",n,format='(a,Z)' bad_str.addr = n m = (plen < maxlen) - 1L bad_str.dump[0L:m] = pkt[0L:m] bad_str.apid = 'A3'X bad_str.npkt = pkt[3] bad_str.plen = plen tb = long(pkt[6:11]) clock = double(tb[3] + 256L*(tb[2] + 256L*(tb[1] + 256L*tb[0]))) subsecs = double(tb[5] + 256L*tb[4])/65536D bad_str.time = mvn_spc_met_to_unixtime(clock + subsecs) badpkt = [temporary(badpkt), bad_str] endif else begin a3[i_A3].addr = n a3[i_A3].npkt = pkt[3] tb = long(pkt[6:11]) clock = double(tb[3] + 256L*(tb[2] + 256L*(tb[1] + 256L*tb[0]))) subsecs = double(tb[5] + 256L*tb[4])/65536D a3[i_A3].time = mvn_spc_met_to_unixtime(clock + subsecs) a3[i_A3].cflg = mvn_swe_getbits(pkt[12],7) ; first bit a3[i_A3].modeID = mvn_swe_getbits(pkt[12],[6,0]) ; last 7 bits a3[i_A3].ctype = mvn_swe_getbits(pkt[13],[7,6]) ; first 2 bits a3[i_A3].group = mvn_swe_getbits(pkt[13],[5,4]) ; next 2 bits a3[i_A3].period = mvn_swe_getbits(pkt[13],[3,0]) ; last 4 bits a3[i_A3].Baz = float(pkt[14]) a3[i_A3].Bel = float(mvn_swe_getbits(pkt[15],[5,0])) ; last 6 bits n_e = swe_ne[a3[i_A3].group] bmax = 16*n_e + 15 if ((bmax+1) eq n_elements(pkt)) then begin counters = decom[pkt[16:bmax]/16B, pkt[16:bmax] mod 16B] a3[i_A3].data[*,0:(n_e-1)] = reform(counters,16,n_e) i_A3++ endif else print, "Bad A3 packet: ",n,format='(a,Z)' endelse end s_A4 : begin pkt = mav_pfdpu_part_decompress_data2(tlm[n:m]) plen = n_elements(pkt) if (plen ne 1040) then begin print,"Bad A4 packet: ",n,format='(a,Z)' bad_str.addr = n m = (plen < maxlen) - 1L bad_str.dump[0L:m] = pkt[0L:m] bad_str.apid = 'A4'X bad_str.npkt = pkt[3] bad_str.plen = plen tb = long(pkt[6:11]) clock = double(tb[3] + 256L*(tb[2] + 256L*(tb[1] + 256L*tb[0]))) subsecs = double(tb[5] + 256L*tb[4])/65536D bad_str.time = mvn_spc_met_to_unixtime(clock + subsecs) badpkt = [temporary(badpkt), bad_str] endif else begin a4[i_A4].addr = n a4[i_A4].npkt = pkt[3] tb = long(pkt[6:11]) clock = double(tb[3] + 256L*(tb[2] + 256L*(tb[1] + 256L*tb[0]))) subsecs = double(tb[5] + 256L*tb[4])/65536D a4[i_A4].time = mvn_spc_met_to_unixtime(clock + subsecs) a4[i_A4].cflg = mvn_swe_getbits(pkt[12],7) ; first bit a4[i_A4].modeID = mvn_swe_getbits(pkt[12],[6,0]) ; last 7 bits a4[i_A4].ctype = mvn_swe_getbits(pkt[13],[7,6]) ; first 2 bits a4[i_A4].smode = mvn_swe_getbits(pkt[13],3) ; fifth bit a4[i_A4].period = mvn_swe_getbits(pkt[13],[2,0]) ; last 3 bits a4[i_A4].lut = mvn_swe_getbits(pkt[14],[2,0]) ; last 3 bits counters = decom[pkt[16:1039]/16B, pkt[16:1039] mod 16B] a4[i_A4].data = reform(counters,64,16) i_A4++ endelse end s_A5 : begin pkt = mav_pfdpu_part_decompress_data2(tlm[n:m]) plen = n_elements(pkt) if (plen ne 1040) then begin print,"Bad A5 packet: ",n,format='(a,Z)' bad_str.addr = n m = (plen < maxlen) - 1L bad_str.dump[0L:m] = pkt[0L:m] bad_str.apid = 'A5'X bad_str.npkt = pkt[3] bad_str.plen = plen tb = long(pkt[6:11]) clock = double(tb[3] + 256L*(tb[2] + 256L*(tb[1] + 256L*tb[0]))) subsecs = double(tb[5] + 256L*tb[4])/65536D bad_str.time = mvn_spc_met_to_unixtime(clock + subsecs) badpkt = [temporary(badpkt), bad_str] endif else begin a5[i_A5].addr = n a5[i_A5].npkt = pkt[3] tb = long(pkt[6:11]) clock = double(tb[3] + 256L*(tb[2] + 256L*(tb[1] + 256L*tb[0]))) subsecs = double(tb[5] + 256L*tb[4])/65536D a5[i_A5].time = mvn_spc_met_to_unixtime(clock + subsecs) a5[i_A5].cflg = mvn_swe_getbits(pkt[12],7) ; first bit a5[i_A5].modeID = mvn_swe_getbits(pkt[12],[6,0]) ; last 7 bits a5[i_A5].ctype = mvn_swe_getbits(pkt[13],[7,6]) ; first 2 bits a5[i_A5].smode = mvn_swe_getbits(pkt[13],3) ; fifth bit a5[i_A5].period = mvn_swe_getbits(pkt[13],[2,0]) ; last 3 bits a5[i_A5].lut = mvn_swe_getbits(pkt[14],[2,0]) ; last 3 bits counters = decom[pkt[16:1039]/16B, pkt[16:1039] mod 16B] a5[i_A5].data = reform(counters,64,16) i_A5++ endelse end s_A6 : begin pkt = mav_pfdpu_part_decompress_data2(tlm[n:m]) ; is fhsk ever compressed? plen = n_elements(pkt) if (plen ne 1808) then begin print,"Bad A6 packet: ",n,format='(a,Z)' bad_str.addr = n m = (plen < maxlen) - 1L bad_str.dump[0L:m] = pkt[0L:m] bad_str.apid = 'A6'X bad_str.npkt = pkt[3] bad_str.plen = plen tb = long(pkt[6:11]) clock = double(tb[3] + 256L*(tb[2] + 256L*(tb[1] + 256L*tb[0]))) subsecs = double(tb[5] + 256L*tb[4])/65536D bad_str.time = mvn_spc_met_to_unixtime(clock + subsecs) badpkt = [temporary(badpkt), bad_str] endif else begin a6[i_A6].addr = n a6[i_A6].npkt = pkt[3] tb = long(pkt[6:11]) clock = double(tb[3] + 256L*(tb[2] + 256L*(tb[1] + 256L*tb[0]))) subsecs = double(tb[5] + 256L*tb[4])/65536D a6[i_A6].time = mvn_spc_met_to_unixtime(clock + subsecs) a6[i_A6].cflg = mvn_swe_getbits(pkt[12],7) ; first bit a6[i_A6].mux0 = mvn_swe_getbits(pkt[12],[4,0]) ; last 5 bits a6[i_A6].mux1 = mvn_swe_getbits(pkt[13],[4,0]) ; last 5 bits a6[i_A6].mux2 = mvn_swe_getbits(pkt[14],[4,0]) ; last 5 bits a6[i_A6].mux3 = mvn_swe_getbits(pkt[15],[4,0]) ; last 5 bits msb = 2L*lindgen(224*4) + 16L lsb = msb + 1L ahsk = float(fix(pkt[msb])*256 + fix(pkt[lsb])) a6[i_A6].analv = ahsk[0:223]*swe_v[3] a6[i_A6].def1v = ahsk[224:447]*swe_v[4] a6[i_A6].def2v = ahsk[448:671]*swe_v[5] a6[i_A6].v0v = ahsk[672:895]*swe_v[8] i_A6++ endelse end else : pklen = 1L endcase n = n + pklen endwhile ; Check for bogus HSK packets (usually first packet after turnon). ; A raw value of '00'X for temperature corresponds to 165 C, which is bogus. if (n_28 gt 0L) then begin indx = where(swe_hsk.LVPST lt 100., count) if (count gt 0L) then swe_hsk = swe_hsk[indx] endif ; Check for packets with zero MET - discard them t0 = mvn_spc_met_to_unixtime(10D) if (n_28 gt 0L) then begin indx = where(swe_hsk.time lt t0, count, complement=jndx, ncomp=n_28) if (count gt 0L) then begin for i=0,(count-1) do begin n = swe_hsk[indx[i]].addr print,"Zero MET in HSK: ",n,format='(a,Z)' endfor if (n_28 eq 0L) then begin print,"No valid HSK packets!" swe_hsk = 0 endif else swe_hsk = swe_hsk[jndx] endif endif if (n_A0 gt 0L) then begin indx = where(a0.time lt t0, count, complement=jndx, ncomp=n_A0) if (count gt 0L) then begin for i=0,(count-1) do begin n = a0[indx[i]].addr print,"Zero MET in A0: ",n,format='(a,Z)' endfor if (n_A0 eq 0L) then begin print,"No valid A0 packets!" a0 = 0 endif else a0 = a0[jndx] endif endif if (n_A1 gt 0L) then begin indx = where(a1.time lt t0, count, complement=jndx, ncomp=n_A1) if (count gt 0L) then begin for i=0,(count-1) do begin n = a1[indx[i]].addr print,"Zero MET in A1: ",n,format='(a,Z)' endfor if (n_A1 eq 0L) then begin print,"No valid A1 packets!" a1 = 0 endif else a1 = a1[jndx] endif endif if (n_A2 gt 0L) then begin indx = where(a2.time lt t0, count, complement=jndx, ncomp=n_A2) if (count gt 0L) then begin for i=0,(count-1) do begin n = a2[indx[i]].addr print,"Zero MET in A2: ",n,format='(a,Z)' endfor if (n_A2 eq 0L) then begin print,"No valid A2 packets!" a2 = 0 endif else a2 = a2[jndx] endif endif if (n_A3 gt 0L) then begin indx = where(a3.time lt t0, count, complement=jndx, ncomp=n_A3) if (count gt 0L) then begin for i=0,(count-1) do begin n = a3[indx[i]].addr print,"Zero MET in A3: ",n,format='(a,Z)' endfor if (n_A3 eq 0L) then begin print,"No valid A3 packets!" a3 = 0 endif else a3 = a3[jndx] endif endif if (n_A4 gt 0L) then begin indx = where(a4.time lt t0, count, complement=jndx, ncomp=n_A4) if (count gt 0L) then begin for i=0,(count-1) do begin n = a4[indx[i]].addr print,"Zero MET in A4: ",n,format='(a,Z)' endfor if (n_A4 eq 0L) then begin print,"No valid A4 packets!" a4 = 0 endif else a4 = a4[jndx] endif endif if (n_A5 gt 0L) then begin indx = where(a5.time lt t0, count, complement=jndx, ncomp=n_A5) if (count gt 0L) then begin for i=0,(count-1) do begin n = a5[indx[i]].addr print,"Zero MET in A5: ",n,format='(a,Z)' endfor if (n_A5 eq 0L) then begin print,"No valid A5 packets!" a5 = 0 endif else a5 = a5[jndx] endif endif if (n_A6 gt 0L) then begin indx = where(a6.time lt t0, count, complement=jndx, ncomp=n_A6) if (count gt 0L) then begin for i=0,(count-1) do begin n = a6[indx[i]].addr print,"Zero MET in A6: ",n,format='(a,Z)' endfor if (n_A6 eq 0L) then begin print,"No valid A6 packets!" a6 = 0 endif else a6 = a6[jndx] endif endif ; Change definition of frame counter (e0) in 3D packets for group ; parameter of 1. I want e0 to always increment by 1. ; ; Group E0 (FSW) E0 (IDL) ; ----------------------------------- ; 0 0,1,2,3 0,1,2,3 ; 1 0,2 0,1 <-- new definition ; 2 0 0 ; ----------------------------------- if (n_A0 gt 0L) then begin indx = where(a0.group eq 1, count) if (count gt 0L) then a0[indx].e0 = a0[indx].e0/2B endif if (n_A1 gt 0L) then begin indx = where(a1.group eq 1, count) if (count gt 0L) then a1[indx].e0 = a1[indx].e0/2B endif ; Trim bad packets if (n_elements(badpkt) gt 1L) then badpkt = badpkt[1L:*] else badpkt = 0 ; Stitch together 3D packets swe_3d_stitch return end