las2witsml 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa4fc245989bfce59ebfbd113ae2d834e5770823
4
- data.tar.gz: e5f278bba13a39d059bd3fffff47b64b8b8f86cf
3
+ metadata.gz: 14c9e773b85635719360a9154e63d2d9aacd7422
4
+ data.tar.gz: 4bb54334c6d22e09314bb79fd5943337c7229cc7
5
5
  SHA512:
6
- metadata.gz: 7b3ee9d49069145a5da173ba8853f7813e6f3f34946973ec060d743f799c92e4ecd0b6cdeaf51f047423f09372dbb43dc2cd936a2486926db003ad73a662f171
7
- data.tar.gz: abea5c4ebc9eb65f006fbe4f47998e68fdd56c8fd211af35d4543582c45eeabeef3c7701b406026c27f3133cbc4596921fd0ffcdd63086d202284ef3534c3a20
6
+ metadata.gz: 57254ea3787533afd554409b84af521649f466d37e0aa88b45595e582e2878821f9e2f5cd321592438ad8d88c14612f58f331fa6933a4a2ce120c13814f2e4cb
7
+ data.tar.gz: 4711d47f0e9657677421a4c00815bc7819eead4aefbfbcfe83ba6656280121fb56de13aea36fb15152a2bbb7e3093e34c3b15a28830b04de08b91d94048cc0e8
data/README CHANGED
@@ -1,14 +1,16 @@
1
- las2witsml -- Convert Log ASCII Stanfard (LAS) files to WITSML <log> objects.
1
+ las2witsml -- Convert Log ASCII Standard (LAS) files to WITSML <log> objects.
2
2
 
3
3
  Use this script to convert LAS files to WITSML logs. The script attempts to be forgiving
4
4
  of some commonly encountered variations. It can process most LAS v2 and v3 files.
5
5
 
6
- Usage: las2witsml [-n name] [-u uid] [-b uid] [-l uid] [-x version] [-h] [-v] lasfile
6
+ Usage: las2witsml [-n name] [-u uid] [-b uid] [-l uid] [-x version] [-m uomfile] [-h] [-v] lasfile
7
7
  -n, --namelog name Name to give the WITSML log; default 'Untitled'
8
8
  -u, --uidwell uid WITSML uid of the containing well
9
9
  -b, --uidwellbore uid WITSML uid of the containing wellbore
10
10
  -l, --uidlog uid WITSML uid to assign the log
11
11
  -x, --version version WITSML version to emit, either 1.3.1 or 1.4.1; default 1.4.1
12
+ -m, --uomfile path Path to a units of measure JSON file, mapping foreign
13
+ to WITSML units of measure e.g. https://github.com/wellstorm/las2witsml/blob/master/lib/uom.json
12
14
  -v, --verbose Emit diagnostic output on stderr
13
15
  -h, --help Show this message
14
16
 
@@ -22,4 +24,6 @@ History:
22
24
 
23
25
  12 Jun 2012 -- gemified existing code and initial commit. (0.1.1)
24
26
  14 Jun 2012 -- proper return values to shell: 0 success, 1 failure. (0.1.2)
25
-
27
+ 30 Sep 2013 -- extended list of units of measure; throw exception if unrecognized uom. (0.1.3)
28
+ 1 Oct 2013 -- support for external uom file (0.1.4)
29
+ 4 Oct 2013 -- report all the uom conversion errors if there are any. (0.1.5)
data/bin/las2witsml CHANGED
@@ -65,7 +65,7 @@ if ( !options[:url] )
65
65
  #exit 1
66
66
  end
67
67
 
68
-
68
+ succeed = false
69
69
  ARGV.each do|a|
70
70
  l2w = Las2Witsml.new
71
71
  infile = File.new a, 'r'
@@ -79,12 +79,17 @@ ARGV.each do|a|
79
79
  end
80
80
  begin
81
81
  succeed = l2w.run infile, outfile, options[:uw] || "", options[:uwb] || "", options[:ul] || "", options[:name] || 'Untitled', version, options[:v] != false, options[:uom_file]
82
- succeed ? 0 : 1
83
82
  rescue => e
84
- $stderr.puts e.backtrace
85
- 1
83
+ $stderr.puts e
84
+ exit 1
86
85
  end
87
86
  end
88
87
 
88
+ if succeed
89
+ exit 0
90
+ else
91
+ exit 1
92
+ end
93
+
89
94
 
90
95
 
data/lib/las2witsml.rb CHANGED
@@ -18,6 +18,9 @@ class Las2Witsml
18
18
  rescue => e
19
19
  $stderr.puts e.backtrace.join("\n")
20
20
  false
21
+ rescue WitsmlFile::ConversionError => e
22
+ $stderr.puts e.message
23
+ false
21
24
  end
22
25
  end
23
26
  end
data/lib/las_file.rb CHANGED
@@ -16,13 +16,30 @@ class LasFile
16
16
  :start_measured_depth_index, :stop_measured_depth_index,
17
17
  :start_date_time_index, :stop_date_time_index,
18
18
  :null_value, :service_company, :curve_values,
19
- :elevation_kelly_bushing, :log_measured_from, :permanent_datum, :above_permanent_datum
19
+ :elevation_kelly_bushing, :log_measured_from, :permanent_datum, :above_permanent_datum,
20
+ :elevation_permanent_datum
20
21
 
21
22
  def initialize(io)
22
23
  @log_curve_infos = []
23
24
  @curve_values = []
24
25
  @in = io
25
26
  @next_line=nil
27
+
28
+ @measured_depth_unit =nil
29
+ @start_measured_depth_index=nil
30
+ @stop_measured_depth_index=nil
31
+ @start_date_time_index=nil
32
+ @stop_date_time_index=nil
33
+ @null_value=nil
34
+ @service_company=nil
35
+ @curve_values=nil
36
+ @elevation_kelly_bushing=nil
37
+ @log_measured_from=nil
38
+ @permanent_datum=nil
39
+ @above_permanent_datum=nil
40
+ @elevation_permanent_datum = nil
41
+
42
+
26
43
  end
27
44
 
28
45
  def process verbose=false
data/lib/witsml_file.rb CHANGED
@@ -6,7 +6,15 @@ require 'uom'
6
6
  class WitsmlFile
7
7
  class UnrecognizedUnitException < Exception
8
8
  end
9
-
9
+
10
+ class ConversionError < Exception
11
+ attr_accessor :bad_units
12
+ def initialize bad_units
13
+ super "Units conversion problems: #{bad_units}"
14
+ @bad_units = bad_units
15
+ end
16
+ end
17
+
10
18
  def initialize(out, witsml_version = 1410, uom_file = nil)
11
19
  @indent = 0
12
20
  @out = out
@@ -51,7 +59,7 @@ class WitsmlFile
51
59
  get_index = lambda do |values|
52
60
  date = values[date_index]
53
61
  #$stderr.puts "date #{date} fmt = #{date_fmt}"
54
-
62
+
55
63
  if date_fmt == '1' then
56
64
  #$stderr.puts "date = #{date}"
57
65
  offset = las_file.start_date_time_index
@@ -74,15 +82,19 @@ class WitsmlFile
74
82
  end
75
83
  [new_lcis, index_lci, is_index_index, get_index]
76
84
  end
77
-
78
-
85
+
86
+
79
87
  def not_empty s
80
88
  s && s.length > 0
81
89
  end
82
90
 
91
+ # Populate the WITSML log from a LAS file.
92
+ # Return nil on success.
93
+ # Raise a ConversionError exception containing a problem description on failure.
94
+
83
95
  def from_las_file(las_file, uid_well='$UIDWELL', uid_wellbore='$UIDWELLBORE', uid='$UID', name='$NAME', verbose=false)
84
96
  new_lcis, _, is_index_index, get_index = digest_las(las_file) #unused index_lci
85
-
97
+
86
98
  if @witsml_version >= 1410
87
99
  ns = 'http://www.witsml.org/schemas/1series'
88
100
  vers = '1.4.1.0'
@@ -91,6 +103,9 @@ class WitsmlFile
91
103
  vers = '1.3.1.1'
92
104
  end
93
105
 
106
+ # Accumulate bad unit references in an array
107
+ bad_units = []
108
+
94
109
  index_curve = new_lcis[0].mnemonic # assume first column is index
95
110
  add_element('logs',{'xmlns'=>ns, 'version'=>vers}) do
96
111
  add_element('log', {'uidWell' => uid_well, 'uidWellbore'=>uid_wellbore, 'uid' => uid}) do
@@ -101,16 +116,20 @@ class WitsmlFile
101
116
  add_text_element 'serviceCompany', las_file.service_company if not_empty(las_file.service_company)
102
117
  add_text_element 'description', 'Created by Wellstorm LAS Import'
103
118
 
104
- measured_depth_unit = normalize_unit(las_file.measured_depth_unit);
105
-
119
+ begin
120
+ measured_depth_unit = normalize_unit(las_file.measured_depth_unit);
121
+ rescue UnrecognizedUnitException => e
122
+ # record the error, set a default value for unit, and continue
123
+ bad_units.push( {:name => 'measured depth', :unit => e.message})
124
+ measured_depth_unit = 'unitless'
125
+ end
126
+
106
127
  if measured_depth_unit then
107
128
  add_text_element 'indexType', 'measured depth'
108
129
  add_text_element 'startIndex', las_file.start_measured_depth_index, {'uom' => measured_depth_unit} if las_file.start_measured_depth_index
109
130
  add_text_element 'endIndex', las_file.stop_measured_depth_index, {'uom' => measured_depth_unit} if las_file.stop_measured_depth_index
110
131
  else
111
132
  add_text_element 'indexType', 'date time'
112
-
113
-
114
133
  #puts ("start index in LAS is #{las_file.start_date_time_index}")
115
134
 
116
135
  add_text_element 'startDateTimeIndex', las_file.start_date_time_index.iso8601 if las_file.start_date_time_index
@@ -118,14 +137,14 @@ class WitsmlFile
118
137
  end
119
138
  #add_text_element 'direction'
120
139
 
121
- if @witsml_version >= 1410
140
+ if @witsml_version >= 1410 then
122
141
  add_text_element 'indexCurve', index_curve
123
142
  else
124
143
  add_text_element 'indexCurve', index_curve, {'columnIndex'=>1}
125
144
  end
126
145
  add_text_element 'nullValue', las_file.null_value
127
146
 
128
-
147
+
129
148
  begin
130
149
  # use this new array of curve values we build
131
150
  tempfile = Tempfile.new 'las2witsml'
@@ -140,53 +159,65 @@ class WitsmlFile
140
159
  tempfile << idx
141
160
  #$stderr.puts "idx #{idx}"
142
161
  values.each_with_index do |v, i|
143
-
162
+
144
163
  start[i] = idx if start[i].nil? and v != las_file.null_value
145
164
  stop[i] = idx if v != las_file.null_value
146
165
  tempfile << ",#{v}" if !is_index_index.call(i)
147
166
 
148
- # $stderr.puts "put #{v} on tempfile"
167
+ # $stderr.puts "put #{v} on tempfile"
149
168
  end
150
169
  tempfile << $/
151
170
  nil
152
171
  end
153
172
  $stderr.puts "done adding lines to tempfile" if verbose
154
-
173
+
155
174
  tempfile.rewind
156
175
 
157
176
  $stderr.puts "rewound #{tempfile}" if verbose
158
-
177
+
159
178
  # Now we can build the lcis, surveying each curve for its min/max indexes
160
179
  new_lcis.each_with_index do |lci, index|
161
- add_log_curve_info lci, (index + 1), start[index+1], stop[index+1], measured_depth_unit
180
+ begin
181
+ add_log_curve_info lci, (index + 1), start[index+1], stop[index+1], measured_depth_unit
182
+ rescue UnrecognizedUnitException => e
183
+ bad_units.push( {:name => lci.mnemonic, :unit => e.message})
184
+ end
162
185
  end
163
186
 
164
187
  $stderr.puts "added #{new_lcis.length} LCIs" if verbose
165
-
188
+
166
189
 
167
190
  # Now add the curve data
168
- add_element 'logData' do
169
- if @witsml_version >= 1410
170
- add_text_element 'mnemonicList', new_lcis.map{|lci| lci.mnemonic}.join(',')
171
- add_text_element 'unitList', new_lcis.map{|lci| lci.unit}.join(',')
172
- end
191
+ if bad_units.length == 0 then
192
+ add_element 'logData' do
193
+ if @witsml_version >= 1410
194
+ add_text_element 'mnemonicList', new_lcis.map{|lci| lci.mnemonic}.join(',')
195
+ add_text_element 'unitList', new_lcis.map{|lci| lci.unit}.join(',')
196
+ end
173
197
 
174
- n = 0
175
- tempfile.each_line do |values|
176
- add_text_element 'data', values
177
- n = n + 1
178
- $stderr.puts "converted #{n} lines to WITSML" if (verbose && n % 1000 == 0 )
198
+ n = 0
199
+ tempfile.each_line do |values|
200
+ add_text_element 'data', values
201
+ n = n + 1
202
+ $stderr.puts "converted #{n} lines to WITSML" if (verbose && n % 1000 == 0 )
203
+ end
204
+ $stderr.puts "converted a total of #{n} lines to WITSML" if verbose
179
205
  end
180
- $stderr.puts "converted a total of #{n} lines to WITSML" if verbose
181
206
  end
182
- rescue
207
+ ensure
183
208
  tempfile.close true
184
209
  end
185
-
186
210
  end
187
211
  end
212
+ #return nil if all succeeded, or a problem hash if not
213
+ if bad_units.length == 0
214
+ return nil
215
+ else
216
+ e = ConversionError.new bad_units
217
+ raise e
218
+ end
188
219
  end
189
-
220
+
190
221
  private
191
222
  def add_element name, attrs = {}, one_liner = false
192
223
  @indent.times {@out.write " "}
@@ -244,7 +275,7 @@ class WitsmlFile
244
275
 
245
276
 
246
277
  def make_time_indexes(lcis)
247
-
278
+
248
279
  # Typically we see DATE and TIME
249
280
  # We can also see only TIME in which case we expect long integer seconds since 1970
250
281
  # (There's no spec that says that; but this data comes from SLB's IDEAL which uses Unix epoch)
@@ -256,7 +287,7 @@ class WitsmlFile
256
287
 
257
288
  $stderr.puts("date_index #{date_index}, time_index #{time_index}")
258
289
 
259
-
290
+
260
291
  if !time_index then
261
292
  #assume time will be in the next column
262
293
  time_index = (date_index + 1) if date_index
@@ -277,7 +308,7 @@ class WitsmlFile
277
308
  raise "No TIME or DATE" if (!time_index && !date_index)
278
309
 
279
310
  [date_index, time_index, date_fmt]
280
-
311
+
281
312
  end
282
313
 
283
314
  def normalize_unit(las_unit)
@@ -287,15 +318,15 @@ class WitsmlFile
287
318
 
288
319
  return las_unit if !las_unit
289
320
 
290
- # just a few random ones from CWLS web site:
291
- # RHOB .K/M3 45 350 02 00 : 2 BULK DENSITY
292
- #NPHI .VOL/VO 42 890 00 00 : 3 NEUTRON POROSITY - SANDSTONE
293
- #MSFL .OHMM 20 270 01 00 : 4 Rxo RESISTIVITY
294
- # SP .MV 07 010 01 00 : 8 SPONTANEOUS POTENTIAL
295
- #GR .GAPI 45 310 01 00 : 9 GAMMA RAY
296
- #CALI .MM 45 280 01 00 : 10 CALIPER
297
- #DRHO .K/M3 45 356 01 00 : 11 DENSITY CORRECTION
298
-
321
+ # just a few random ones from CWLS web site:
322
+ # RHOB .K/M3 45 350 02 00 : 2 BULK DENSITY
323
+ #NPHI .VOL/VO 42 890 00 00 : 3 NEUTRON POROSITY - SANDSTONE
324
+ #MSFL .OHMM 20 270 01 00 : 4 Rxo RESISTIVITY
325
+ # SP .MV 07 010 01 00 : 8 SPONTANEOUS POTENTIAL
326
+ #GR .GAPI 45 310 01 00 : 9 GAMMA RAY
327
+ #CALI .MM 45 280 01 00 : 10 CALIPER
328
+ #DRHO .K/M3 45 356 01 00 : 11 DENSITY CORRECTION
329
+
299
330
  retval = @uom.translate las_unit
300
331
  if !retval
301
332
  raise UnrecognizedUnitException, las_unit
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: las2witsml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hugh Winkler