argos-ruby 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # argos-ruby
2
+
3
+ A Ruby library for parsing Argos tracking data
4
+
5
+ ```argos-ruby``` has been developed to parse [Argos](http://www.argos-system.org)
6
+ satellite tracking data collected at the [Norwegian Polar Institute]
7
+ (http://npolar.no/en) over a 25-year period (!) from 1989 to 2013.
8
+
9
+ Be warned, the Argos file formats have changed over time. No promises are
10
+ made that the library will work outside of Norway :).
11
+
12
+ Currently, the library parses Argos DS/DIAG files dating from 1991
13
+ and onwards.
14
+
15
+ ## Install
16
+ Now
17
+ $ git clone https://github.com/npolar/argos-ruby.git
18
+
19
+ Soon
20
+ $ gem install argos-ruby
21
+
22
+ ## Command-line usage
23
+ ```sh
24
+ $ curl "https://raw.github.com/npolar/argos-ruby/master/spec/argos/_ds/990660_A.DAT" > /tmp/990660_A.DAT
25
+ $ ./bin/argos-ruby /tmp/990660_A.DAT --filter "lambda {|a| a[:program] == 660 }"
26
+ ```
27
+ This will output (the lambda filter is of course optional):
28
+
29
+ ```json
30
+ [{"program":660,"platform":14747,"lines":2,"sensors":32,"satellite":"K","lc":null,"positioned":null,"latitude":null,"longitude":null,"altitude":null,"headers":5,"measured":"1999-12-16T00:46:49Z","identical":1,"sensor_data":["92","128","130","132"],"technology":"argos","type":"ds","filename":"/tmp/990660_A.DAT","source":"3a39e0bd0b944dca4f4fbf17bc0680704cde2994","warn":["missing-position","sensors-count-mismatch"],"parser":"argos-ruby-1.0.0","id":"f2c82a5ca1330b312925949a15ac300d07452a12"}]
31
+
32
+ ```
33
+ Links
34
+ * [http://api.npolar.no/tracking/?q=&filter-technology=argos](http://api.npolar.no/tracking/?q=&filter-technology=argos)
35
+ * [Argos users manual v1.5](http://www.argos-system.org/files/pmedia/public/r363_9_argos_users_manual-v1.5.pdf) (PDF)
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+ # https://github.com/radar/guides/blob/master/gem-development.md
3
+ require File.expand_path(File.dirname(__FILE__)+"/lib/argos")
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "argos-ruby"
7
+ s.version = Argos::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Espen Egeland", "Conrad Helgeland"]
10
+ s.email = ["data*npolar.no"]
11
+ s.homepage = "http://github.com/npolar/argos-ruby"
12
+ s.summary = %q{Argos satellite tracking data parsers}
13
+ s.description = %q{Parses Argos (http://www.argos-system.org/) DS/DAT and DIAG/DIA files.}
14
+ s.license = "GPL-3.0"
15
+ s.add_development_dependency "rspec"
16
+ s.files = `git ls-files`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
data/bin/argos-ruby ADDED
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ # argos-ruby /path/argos/ --dest=/path/dest --level=info 2>> /path/argos-json.log
5
+ require_relative "../lib/argos"
6
+ require "optparse"
7
+ require "yaml"
8
+
9
+ param = { format: "json",
10
+ action: "parse",
11
+ level: Logger::WARN,
12
+ dest: nil,
13
+ filter: nil,
14
+ }
15
+
16
+ optparser = OptionParser.new(ARGV) do |opts|
17
+ #opts.banner ""
18
+
19
+ opts.on_tail("--version", "-v", "Library version") do
20
+ puts Argos.library_version
21
+ exit
22
+ end
23
+
24
+ opts.on("--action={parse|source}", "-a", "Action") do |action|
25
+ param[:action] = action
26
+ end
27
+
28
+ opts.on("--dest=destination", "-a", "Destination directory") do |dest|
29
+ param[:dest] = dest
30
+ end
31
+
32
+ opts.on("--format=FORMAT", "-f", "Format") do |format|
33
+ param[:format] = format
34
+ end
35
+
36
+ opts.on("--filter=FILTER", "Filter lambda") do |filter|
37
+ param[:filter] = filter
38
+ end
39
+
40
+ opts.on("--level=LEVEL", "-l=LEVEL", "Log level: debug|info|warn|error|fatal") do |level|
41
+
42
+ param[:level] = case level
43
+ when /debug|0/i
44
+ Logger::DEBUG
45
+ when /info|1/i
46
+ Logger::INFO
47
+ when /warn|2/i
48
+ Logger::WARN
49
+ when /error|3/i
50
+ Logger::ERROR
51
+ when /fatal|4/i
52
+ Logger::FATAL
53
+ else
54
+ param[:level]
55
+ end
56
+ end
57
+
58
+ end
59
+ optparser.parse!
60
+ glob = ARGV[0]||Dir.pwd
61
+
62
+ begin
63
+
64
+ log = Logger.new(STDERR)
65
+ log.level = param[:level]
66
+
67
+
68
+ if not Argos.argos? glob
69
+ glob = glob.gsub(/\/$/, "")
70
+ if glob != /\*/
71
+ glob += "/**/*"
72
+ end
73
+ end
74
+
75
+ log.debug "#{File.realpath(__FILE__)} #{param}"
76
+ bundle = Digest::SHA1.hexdigest(glob+param[:filter].to_s)
77
+ result = []
78
+
79
+ Dir[glob].select {|f|
80
+ Argos.argos? f
81
+ }.map {|filename|
82
+
83
+ argos = Argos.factory(Argos.type(filename))
84
+ argos.filename = filename
85
+ argos.filter = param[:filter]
86
+ argos.log = log
87
+
88
+ case param[:action]
89
+ when "source"
90
+ result << Argos.source(argos).merge(glob: glob, bundle: bundle)
91
+ when "parse"
92
+ arr = argos.parse(filename)
93
+ unless param[:dest].nil?
94
+ jsonfile = "#{param[:dest].gsub(/\$/, "")}/#{argos.source}.json"
95
+ File.open(jsonfile, "w") { |file| file.write(arr.to_json) }
96
+ end
97
+ result += arr
98
+ when "messages"
99
+ argos.parse(filename)
100
+ result += argos.messages
101
+ end
102
+ }
103
+
104
+ ds_count = result.select {|argos| argos[:type] == "ds"}.size
105
+ diag_count = result.select {|argos| argos[:type] == "diag"}.size
106
+ # err count
107
+ # warn count
108
+
109
+ if ["parse", "messages"].include? param[:action]
110
+ log.info "Documents: #{result.size}, ds: #{ds_count}, diag: #{diag_count}, bundle: #{bundle}, glob: #{glob}"
111
+ elsif "source" == param[:action]
112
+ result = result.select {|s| s[:size] > 0 }
113
+ sum_count = result.map {|s| s[:size]}.inject { |sum, c| sum + c }
114
+ result = result.map {|s|
115
+ s[:total] = sum_count
116
+ s
117
+ }
118
+ log.info "Documents (Σcount): #{sum_count}, sources: #{result.size} (ds: #{ds_count}, diag: #{diag_count}), bundle: #{bundle}, glob: #{glob}"
119
+ end
120
+
121
+ if param[:dest].nil?
122
+ case param[:format]
123
+ when "json"
124
+ puts result.to_json
125
+ when /y(a)?ml/
126
+ puts result.to_yaml
127
+ when /(ruby|rb)/
128
+ puts result
129
+ end
130
+ end
131
+
132
+ exit(0)
133
+
134
+ rescue => e
135
+ Logger.new(STDERR).fatal e
136
+ exit(1)
137
+ end
@@ -0,0 +1,58 @@
1
+ require "optparse"
2
+
3
+ module Argos
4
+ class Command
5
+
6
+ attr_accessor :param
7
+
8
+ PARAM_DEFAULT = { format: "json",
9
+ action: "parse",
10
+ level: Logger::WARN,
11
+ dest: nil,
12
+ filter: nil,
13
+ }
14
+
15
+ def initialize
16
+ @param = PARAM_DEFAULT
17
+ end
18
+
19
+ def param(argv=ARGV)
20
+ optparser = OptionParser.new(ARGV) do |opts|
21
+
22
+ opts.on_tail("--version", "-v", "Library version") do
23
+ puts Argos.library_version
24
+ exit
25
+ end
26
+
27
+ opts.on("--action=ACTION", "-a", "Action") do |action|
28
+ param[:action] = action
29
+ end
30
+
31
+ opts.on("--filter=FILTER", "-f", "Filter") do |filter|
32
+ param[:filter] = filter
33
+ end
34
+
35
+ opts.on("--level=LEVEL", "-l=LEVEL", "Log level") do |level|
36
+
37
+ param[:level] = case level
38
+ when /debug|0/i
39
+ Logger::DEBUG
40
+ when /info|1/i
41
+ Logger::INFO
42
+ when /warn|2/i
43
+ Logger::WARN
44
+ when /error|3/i
45
+ Logger::ERROR
46
+ when /fatal|4/i
47
+ Logger::FATAL
48
+ else
49
+ param[:level]
50
+ end
51
+ end
52
+
53
+ end
54
+ optparser.parse!
55
+ end
56
+
57
+ end
58
+ end
data/lib/argos/diag.rb ADDED
@@ -0,0 +1,316 @@
1
+ module Argos
2
+
3
+ # Argos DIAG file parser
4
+ #
5
+ # Usage
6
+ #
7
+ # diag = Argos::Diag.new
8
+ # diag.log = Logger.new(STDERR)
9
+ # puts diag.parse(filename).to_json
10
+ #
11
+ # For information about Argos, see: http://www.argos-system.org
12
+ #
13
+ # @author Espen Egeland
14
+ # @author Conrad Helgeland
15
+ class Diag < Array
16
+ include Argos
17
+
18
+ LOCATION_CLASS = ["3", "2", "1", "0", "A", "B", "Z"]
19
+
20
+ attr_accessor :log, :filename, :programs
21
+
22
+ attr_reader :filename, :filter, :filtername, :sha1, :valid, :filesize
23
+
24
+ START_REGEX = /^\s*\d{5,6}\s+Date : \d{2}.\d{2}.\d{2} \d{2}:\d{2}:\d{2}/
25
+ $start_diag ='^\s*\d{5,6}\s+Date : \d{2}.\d{2}.\d{2} \d{2}:\d{2}:\d{2}'
26
+
27
+ # Diag format 1
28
+ # 02168 Date : 21.06.94 08:43:16 LC : Z IQ : 00
29
+ # Lat1 : ??????? Lon1 : ???????? Lat2 : ??????? Lon2 : ????????
30
+ # Nb mes : 002 Nb mes>-120dB : 000 Best level : -125 dB
31
+ # Pass duration : 113s NOPC : 0
32
+ # Calcul freq : 401 650000.0 Hz Altitude : 0 m
33
+ # 24551 00 137
34
+ #$FORMAT_1 = '\s*\d{5,6} +Date : (0[1-9]|[12][0-9]|3[01])\.(0[1-9]|1[012])\.\d{2} ([0-1][0-9]|2[0-3]):([0-5][0-9]:[0-5][0-9]) +LC : (3|2|1|0|A|B|Z) +IQ : *\d{2} *Lat1 : +((\d+\.\d{3}[NS])|\?)+ +Lon1 : +((\d+\.\d{3}[EW])|\?+) +Lat2 : +((\d+\.\d{3}[NS])|\?+) +Lon2 : +((\d+\.\d{3}[EW])|\?+) +Nb mes : (\d{3})? +Nb mes>-120dB : (\d{3})? +Best level : (-\d{3})? *dB +Pass duration : *(\d+|\?+) *s? +NOPC : +([0-4]|\?) +Calcul freq : +\d{3} (\d+\.\d+)? *Hz +Altitude : +(\d+)? m( +(\d{2,5}|\w{2}))*$'
35
+ $FORMAT_1 =' *\d{5,6} +Date : (0[1-9]|[12][0-9]|3[01])\.(0[1-9]|1[012])\.\d{2} ([0-1][0-9]|2[0-3]):([0-5][0-9]:[0-5][0-9]) +LC : (3|2|1|0|A|B|Z) +IQ : *\d{2} *Lat1 : +((\d+\.\d{3}[NS])|\?+) +Lon1 : +((\d+\.\d{3}[EW])|\?+) +Lat2 : +((\d+\.\d{3}[NS])|\?)+ +Lon2 : +((\d+\.\d{3}[EW])|\?+) +Nb mes : (\d{3})? +Nb mes>-120dB : (\d{3})? +Best level : (-\d{3})? *dB +Pass duration : *(\d+|\?+) *s? +NOPC : *([0-4]|\?)? +Calcul freq : +\d{3} (\d+\.\d+)? *Hz +Altitude : +(\d+)? m( +.+E[+-]\d+)?( +(\d{2,5}|\w{2}))*'
36
+
37
+
38
+ # 09689 Date : 01.02.90 08:35:35 LC : 0 LI : -7
39
+ # Lat1 : 76.304N Lon1 : 18.925E Lat2 : 75.769N Lon2 : 21.554E
40
+ # Nb mes : 004 Nb mes>-120Db : 000 Best level : -130 Db
41
+ # Pass duration : 426s Dist track : 0
42
+ # Calcul freq : 401 649507.6Khz Altitude : 0 m
43
+ # -.81408E+1 03 70
44
+ $FORMAT_2 = '\s*\d{5,6} +Date : (0[1-9]|[12][0-9]|3[01])\.(0[1-9]|1[012])\.\d{2} ([0-1][0-9]|2[0-3]):([0-5][0-9]:[0-5][0-9]) +LC : (3|2|1|0|A|B|Z) +(LI : *\-?\d+)? *Lat1 : +\d+\.\d{3}[NS] +Lon1 : +\d+\.\d{3}[EW] +Lat2 : +\d+\.\d{3}[NS] +Lon2 : +\d+\.\d{3}[EW] +Nb mes : \d{3} +Nb mes>-120(Db|dB) : \d{3} +Best level : -\d{3}? *(Db|dB) +Pass duration : +\d+s +Dist track : +\d+ +Calcul freq : +\d{3} \d+\.\d+ *(Khz|Hz) +Altitude : +\d+ m+(.+E[+-]\d+)*( +(\d{2,5}|\w{2}))*$'
45
+
46
+
47
+ # 09689 Date : 01.02.90 08:35:35 LC : 0 IQ : 00
48
+ # Lat1 : 76.304N Lon1 : 18.925E Lat2 : 75.769N Lon2 : 21.554E
49
+ # Nb mes : 004 Nb mes>-120Db : 000 Best level : -130 Db
50
+ # Pass duration : 426s NOPC :
51
+ # Calcul freq : 401 649507.6Khz Altitude : 0 m
52
+ # 03 70
53
+ $FORMAT_3 =' *\d{5,6} +Date : (0[1-9]|[12][0-9]|3[01])\.(0[1-9]|1[012])\.\d{2} ([0-1][0-9]|2[0-3]):([0-5][0-9]:[0-5][0-9]) +LC : (3|2|1|0|A|B|Z) +IQ : *\d{2} *Lat1 : +((\d+\.\d{3}[NS])|\?+) +Lon1 : +((\d+\.\d{3}[EW])|\?+) +Lat2 : +((\d+\.\d{3}[NS])|\?)+ +Lon2 : +((\d+\.\d{3}[EW])|\?+) +Nb mes : (\d{3})? +Nb mes>-120dB : (\d{3})? +Best level : (-\d{3})? *dB +Pass duration : *(\d+|\?+) *s? +NOPC : +([0-4]|\?) +Calcul freq : +\d{3} (\d+\.\d+)? *Hz +Altitude : +(\d+)? m +.+E[+-]\d+( +(\d{2,5}|\w{2}))*$'
54
+
55
+
56
+ def initialize (filename = nil)
57
+ @index = 0
58
+ @error_num = 0
59
+ @errors_num =0
60
+ @argos_contacts = Array.new
61
+ @filename = filename
62
+ read_file (filename) unless filename == nil
63
+
64
+ end
65
+
66
+ def filter?
67
+ not @filter.nil?
68
+ end
69
+
70
+ def filter=filter
71
+ if filter.respond_to? :call
72
+ @filter = filter
73
+ elsif filter =~ /lambda|Proc/
74
+ @filtername = filter
75
+ @filter = eval(filter)
76
+ end
77
+ end
78
+
79
+ def get_hash
80
+ @argos_contacts
81
+ end
82
+
83
+ def parse(filename=nil)
84
+ if filename.nil?
85
+ filename = @filename
86
+ end
87
+
88
+ self.clear # Needed if you parse multiple times
89
+ @total = linecount = 0
90
+ @valid = false
91
+
92
+ #filename = File.realpath(filename)
93
+ @filename = filename
94
+ if filename.nil? or not File.exists? filename
95
+ raise ArgumentError, "Missing ARGOS DS file: \"#{filename}\""
96
+ end
97
+ @sha1 = Digest::SHA1.file(filename).hexdigest
98
+
99
+
100
+ valid_file = false
101
+
102
+ contact = []
103
+ file = File.open(filename)
104
+ @filesize = file.size
105
+
106
+ log.debug "Parsing Argos DIAG file #{filename} sha1:#{sha1} (#{filesize} bytes)"
107
+ if filter?
108
+ log.info "Using filter: #{filter}"
109
+ end
110
+
111
+
112
+ linecount = 0
113
+ match =0
114
+ startline = 0
115
+ contact =""
116
+
117
+ File.open(filename, :encoding => "iso-8859-1").each do |line|
118
+ line = line.to_s.strip
119
+ linecount+=1
120
+ if line =~ /#{$start_diag}/
121
+ match+=1
122
+ if contact !=""
123
+ check_format(contact.strip, startline)
124
+ end
125
+ contact = line
126
+ startline = linecount
127
+ else
128
+ contact = contact + " " +line
129
+ end
130
+ end
131
+ check_format(contact.strip, startline)
132
+
133
+ if filter?
134
+ total = self.size
135
+ filtered = self.select{|diag| filter.call(diag)}
136
+ log.info "Selected #{filtered.size}/#{total} Argos DIAG segments sha1:#{sha1} #{filename}"
137
+ self.clear
138
+
139
+ filtered.each do |filtered|
140
+ self << filtered
141
+ end
142
+ else
143
+ log.info "Parsed #{self.size} Argos DIAG segments sha1:#{sha1} #{filename}"
144
+ end
145
+
146
+ self
147
+ end
148
+
149
+
150
+ def check_format(contact, line_num)
151
+
152
+ if contact =~ /#{$FORMAT_1}/ or contact =~ /#{$FORMAT_2}/ or contact =~ /#{$FORMAT_2}/
153
+ self << create_diag_hash(contact)
154
+ true
155
+ else
156
+ error = "#{__FILE__}#check_format #{filename}:#{line_num} source:#{@sha1} Invalid format:\n" + contact
157
+ log.error error
158
+ false
159
+ end
160
+
161
+ end
162
+
163
+ #http://www.argos-system.org/files/pmedia/public/r363_9_argos_users_manual-v1.5.pdf p. 48
164
+ #Nb mes : 025 Number of messages received
165
+ #Nb mes>-120 dB: 015 Number of messages received by the satellite at a signal strength greater than -120 decibels
166
+ #Best level : -113 dB Best signal strength, units are dB
167
+ #Pass duration : 900s Time elapsed between the first and last message received by the
168
+ #satellite
169
+ #NOPC = 4 Number Of Plausibility Checks successful (from 0-4)
170
+ #Calcul Freq : 401 650000.3 Calculated frequency
171
+ #Altitude : 213 m Altitude used for location calculation
172
+ def create_diag_hash(contact="")
173
+ platform = contact[/^(\d{5,})/,1]
174
+ location_data = contact[/Date : (\d{2}.\d{2}.\d{2} \d{2}:\d{2}:\d{2})/,1]
175
+ contact_time = convert_date(location_data) unless location_data ==nil
176
+ lc = contact[/LC : (3|2|1|0|A|B|Z)/,1]
177
+ li = contact[/LI : *(\-?\d+)/,1]
178
+ iq= contact[/IQ : *(\d{2})/,1]
179
+ lat1= contact[/Lat1 : +(\d+\.\d{3}[NS]|\?+)/,1]
180
+ lat1 = coordinate_conv(lat1)
181
+ lon1= contact[/Lon1 : +(\d+\.\d{3}[EW]|\?+)/,1]
182
+ lon1 = coordinate_conv(lon1)
183
+ lat2= contact[/Lat2 : +(\d+\.\d{3}[NS]|\?+)/,1]
184
+ lat2 = coordinate_conv(lat2)
185
+ lon2= contact[/Lon2 : +(\d+\.\d{3}[EW]|\?+)/,1]
186
+ lon2 = coordinate_conv(lon2)
187
+ nb= contact[/Nb mes : (\d{3})/,1]
188
+ nb120= contact[/Nb mes>-120(Db|dB) : (\d{3})/,2]
189
+ best_level= contact[/Best level : (-\d{3})/,1]
190
+ pass_duration= contact[/Pass duration : +(\d+|\?)/,1]
191
+ dist_track= contact[/Dist track : +(\d+)/,1]
192
+ nopc= contact[/NOPC : +([0-4]|\?)/,1]
193
+ nopc = nopc =~/\?+/ ? nil : nopc
194
+ nopc.to_i unless nopc == nil
195
+ frequency = contact[/Calcul freq : +(\d{3} \d+\.\d+)/,1]
196
+ if frequency =~ /[ ]/
197
+ frequency = frequency.split(" ").join("").to_f
198
+ end
199
+ altitude= contact[/Altitude : +(\d+)? m/,1]
200
+ altitude = altitude.to_i unless altitude == nil
201
+
202
+ data_start = contact.index(" m ")
203
+ sensor_data = contact[data_start+2,contact.length].split(" ") unless data_start == nil
204
+
205
+ diag = { platform: platform.to_i,
206
+ measured: contact_time,
207
+ lc: lc,
208
+ iq: iq,
209
+ li: li,
210
+ latitude: lat1,
211
+ longitude: lon1,
212
+ latitude2: lat2,
213
+ longitude2: lon2,
214
+ messages: nb.to_i,
215
+ messages_120dB: nb120.to_i,
216
+ best_level: best_level.to_i,
217
+ pass_duration: pass_duration.to_i,
218
+ dist_track: dist_track,
219
+ nopc: nopc.to_i,
220
+ frequency: frequency,
221
+ altitude: altitude,
222
+ sensor_data: sensor_data,
223
+ technology: "argos",
224
+ type: type,
225
+ filename: filename,
226
+ source: "#{sha1}"
227
+ }
228
+
229
+ idbase = diag.clone
230
+ idbase.delete :filename
231
+ id = Digest::SHA1.hexdigest(idbase.to_json)
232
+
233
+ diag[:parser] = Argos.library_version
234
+ diag[:id] = id
235
+ diag
236
+ end
237
+
238
+
239
+ def coordinate_conv (co)
240
+ if co =~ /\?+/
241
+ co = nil
242
+ elsif co =~/N$/ || co =~/E$/
243
+ co=co.chop.to_f
244
+ elsif co =~/S$/ || co =~/W$/
245
+ co = co.chop.to_f
246
+ co = co * -1
247
+ end
248
+ end
249
+
250
+
251
+ def convert_date(date)
252
+ timestamp = DateTime.strptime(date, '%d.%m.%y %H:%M:%S').iso8601.to_s
253
+ timestamp['+00:00'] = "Z"
254
+ timestamp
255
+ end
256
+
257
+ def type
258
+ "diag"
259
+ end
260
+
261
+ def messages
262
+ self
263
+ end
264
+
265
+ def programs
266
+ @programs ||= []
267
+ end
268
+
269
+ def start
270
+ first[:measured]
271
+ end
272
+
273
+ def stop
274
+ last[:measured]
275
+ end
276
+
277
+
278
+ def source
279
+ sha1
280
+ end
281
+
282
+ end
283
+ end
284
+
285
+
286
+ #52061 Date : 03.10.09 08:41:12 LC : 0 IQ : 58
287
+ # Lat1 : 76.651N Lon1 : 20.930W Lat2 : 76.168N Lon2 : 18.539W
288
+ # Nb mes : 006 Nb mes>-120dB : 000 Best level : -123 dB
289
+ # Pass duration : 441s NOPC : 2
290
+ # Calcul freq : 401 677543.2 Hz Altitude : 0 m
291
+ # 40 47 00 00
292
+ # 00 00 00 240
293
+ # 00 00 00 00
294
+ # 00 00 185
295
+ #52061 Date : 03.10.09 09:47:05 LC : Z IQ : 38
296
+ # Lat1 : 76.998N Lon1 : 22.398W Lat2 : 74.370N Lon2 : 10.000
297
+ # Nb mes : 003 Nb mes>-120dB : 000 Best level : -129 dB
298
+ # Pass duration : 100s NOPC : 0
299
+ # Calcul freq : 401 677501.2 Hz Altitude : 0 m
300
+ # 40 35 00 00
301
+ # 00 00 00 240
302
+ # 00 00 00 00
303
+ # 64 00 197
304
+ #52061 Date : 03.10.09 10:23:35 LC : Z IQ : 00
305
+ # Lat1 : ??????? Lon1 : ???????? Lat2 : ??????? Lon2 : ????????
306
+ # Nb mes : 001 Nb mes>-120dB : 000 Best level : -125 dB
307
+ # Pass duration : ???s NOPC : ?
308
+ # Calcul freq : 401 677531.1 Hz Altitude : 0 m
309
+ # 168 64 30
310
+
311
+
312
+
313
+
314
+ #200910Oct.DIA
315
+ #: Line: 26132 Invalid format:
316
+ #52061 Date : 03.10.09 09:47:05 LC : Z IQ : 38 Lat1 : 76.998N Lon1 : 22.398W Lat2 : 74.370N Lon2 : 10.000 Nb mes : 003 Nb mes>-120dB : 000 Best level : -129 dB Pass duration : 100s NOPC : 0 Calcul freq : 401 677501.2 Hz Altitude : 0 m 40 35 00 00 00 00 00 240 00 00 00 00 64 00 197