las2witsml 0.1.4 → 0.1.5

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.
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