class Argos::Diag
Argos
DIAG file parser
Usage
diag = Argos::Diag.new puts diag.parse(filename).to_json
@author Espen Egeland @author Conrad Helgeland
Constants
- LOCATION_CLASS
- START_REGEX
Attributes
bundle[RW]
errors[R]
filename[RW]
filesize[R]
filter[R]
filtername[R]
log[RW]
multiplicates[R]
programs[RW]
sha1[R]
updated[R]
valid[R]
Public Class Methods
new()
click to toggle source
# File lib/argos/diag.rb, line 53 def initialize @errors = [] @programs = [] @log = Logger.new(STDERR) end
Public Instance Methods
check_format(contact, line_num)
click to toggle source
# File lib/argos/diag.rb, line 158 def check_format(contact, line_num) if contact =~ /#{$FORMAT_1}/ or contact =~ /#{$FORMAT_2}/ or contact =~ /#{$FORMAT_2}/ self << create_diag_hash(contact) true elsif contact =~ /Prog\s\d{5,}$/ true else error = "#{filename}:#{line_num} sha1:#{@sha1} Invalid format:\n" + contact @errors << error log.error error false end end
convert_date(date)
click to toggle source
# File lib/argos/diag.rb, line 268 def convert_date(date) timestamp = DateTime.strptime(date, '%d.%m.%y %H:%M:%S').iso8601.to_s timestamp['+00:00'] = "Z" timestamp end
coordinate_conv(co)
click to toggle source
# File lib/argos/diag.rb, line 256 def coordinate_conv (co) if co =~ /\?+/ co = nil elsif co =~/N$/ || co =~/E$/ co=co.chop.to_f elsif co =~/S$/ || co =~/W$/ co = co.chop.to_f co = co * -1 end end
create_diag_hash(contact="")
click to toggle source
www.argos-system.org/files/pmedia/public/r363_9_argos_users_manual-v1.5.pdf p. 48 Nb mes : 025 Number of messages received Nb mes>-120 dB: 015 Number of messages received by the satellite at a signal strength greater than -120 decibels Best level : -113 dB Best signal strength, units are dB Pass duration : 900s Time elapsed between the first and last message received by the satellite NOPC = 4 Number Of Plausibility Checks successful (from 0-4) Calcul Freq : 401 650000.3 Calculated frequency Altitude : 213 m Altitude used for location calculation
# File lib/argos/diag.rb, line 183 def create_diag_hash(contact="") platform = contact[/^(\d{5,})/,1] location_data = contact[/Date : (\d{2}.\d{2}.\d{2} \d{2}:\d{2}:\d{2})/,1] contact_time = convert_date(location_data) unless location_data ==nil lc = contact[/LC : (3|2|1|0|A|B|Z)/,1] li = contact[/LI : *(\-?\d+)/,1] iq= contact[/IQ : *(\d{2})/,1] lat1= contact[/Lat1 : +(\d+\.\d{3}[NS]|\?+)/,1] lat1 = coordinate_conv(lat1) lon1= contact[/Lon1 : +(\d+\.\d{3}[EW]|\?+)/,1] lon1 = coordinate_conv(lon1) lat2= contact[/Lat2 : +(\d+\.\d{3}[NS]|\?+)/,1] lat2 = coordinate_conv(lat2) lon2= contact[/Lon2 : +(\d+\.\d{3}[EW]|\?+)/,1] lon2 = coordinate_conv(lon2) nb= contact[/Nb mes : (\d{3})/,1] nb120= contact[/Nb mes>-120(Db|dB) : (\d{3})/,2] best_level= contact[/Best level : (-\d{3})/,1] pass_duration= contact[/Pass duration : +(\d+|\?)/,1] dist_track= contact[/Dist track : +(\d+)/,1] nopc= contact[/NOPC : +([0-4]|\?)/,1] nopc = nopc =~/\?+/ ? nil : nopc nopc.to_i unless nopc == nil frequency = contact[/Calcul freq : +(\d{3} \d+\.\d+)/,1] if frequency =~ /[ ]/ frequency = frequency.split(" ").join("").to_f end altitude= contact[/Altitude : +(\d+)? m/,1] altitude = altitude.to_i unless altitude == nil data_start = contact.index(" m ") sensor_data = contact[data_start+2,contact.length].split(" ") unless data_start == nil diag = { platform: platform.to_i, measured: contact_time, lc: lc, iq: iq, li: li, latitude: lat1, longitude: lon1, latitude2: lat2, longitude2: lon2, messages: nb.to_i, messages_120dB: nb120.to_i, best_level: best_level.to_i, pass_duration: pass_duration.to_i, dist_track: dist_track, nopc: nopc.to_i, frequency: frequency, altitude: altitude, sensor_data: sensor_data, technology: "argos", type: type, file: "file://"+filename, source: "#{sha1}", } idbase = diag.clone idbase.delete :file id = Digest::SHA1.hexdigest(idbase.to_json) diag[:parser] = Argos.library_version diag[:id] = id diag[:bundle] = bundle if @program diag[:program] = @program end diag end
filter=(filter)
click to toggle source
# File lib/argos/diag.rb, line 63 def filter=filter if filter.respond_to? :call @filter = filter elsif filter =~ /lambda|Proc/ @filtername = filter @filter = eval(filter) end end
filter?()
click to toggle source
# File lib/argos/diag.rb, line 59 def filter? not @filter.nil? end
messages()
click to toggle source
# File lib/argos/diag.rb, line 278 def messages self end
parse(filename=nil)
click to toggle source
@return []
# File lib/argos/diag.rb, line 73 def parse(filename=nil) if filename.nil? filename = @filename end self.clear # Needed if you parse multiple times @total = linecount = 0 @valid = false filename = File.realpath(filename) @filename = filename if filename.nil? or not File.exists? filename raise ArgumentError, "Missing ARGOS DS file: \"#{filename}\"" end @sha1 = Digest::SHA1.file(filename).hexdigest valid_file = false contact = [] file = File.open(filename) @filesize = file.size @updated = file.mtime.utc log.debug "Parsing Argos DIAG file #{filename} sha1:#{sha1} (#{filesize} bytes)" if filter? log.info "Using filter: #{filter}" end linecount = 0 match =0 startline = 0 contact ="" File.open(filename, :encoding => "iso-8859-1").each do |line| line = line.to_s.strip linecount+=1 if line =~ /Prog\s(\d{4,})$/ @program = line.split(" ").last log.info "Program: #{@program}" @programs << @program end if line =~ START_REGEX match+=1 if contact !="" check_format(contact.strip, startline) end contact = line startline = linecount else contact = contact + " " +line end end check_format(contact.strip, startline) @programs = @programs.uniq if filter? total = self.size filtered = self.select{|diag| filter.call(diag)} log.info "Selected #{filtered.size}/#{total} Argos DIAG segments sha1:#{sha1} #{filename}" self.clear # programs may be wrong now! filtered.each do |filtered| self << filtered end else log.info "Parsed #{self.size} Argos DIAG segments sha1:#{sha1} #{filename}" end @multiplicates = group_by { |e| e }.select { |k, v| v.size > 1 }.map(&:first) if multiplicates.any? #log.warn "#{multiplicates.size} multiplicates in source sha1 #{sha1} #{filename}): #{multiplicates.map {|a|a[:id]} }" self.uniq! log.info "Unique DIAG messages: #{self.size} sha1: #{sha1} #{filename}" end self.sort_by! {|diag| diag[:measured]} self end
source()
click to toggle source
# File lib/argos/diag.rb, line 295 def source sha1 end
start()
click to toggle source
# File lib/argos/diag.rb, line 286 def start first[:measured] end
stop()
click to toggle source
# File lib/argos/diag.rb, line 290 def stop last[:measured] end
type()
click to toggle source
# File lib/argos/diag.rb, line 274 def type "diag" end