las_reader 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ *.swp
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in las_reader.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Gilberto P. Carmo Jr.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,36 @@
1
+ # LasReader
2
+
3
+ cwls-las-reader
4
+ Ruby gem for reading CWLS LAS files
5
+
6
+ The Canadian Well Logging Society's Floppy Disk Committee has designed a standard format for log data on floppy disks. It is known as the LAS format (Log ASCII Standard). LAS consists of files written in ASCII containing minimal header information and is intended for optical curves only.
7
+
8
+ Details of the LAS format are described in this paper (http://www.cwls.org/docs/LAS12_Standards.txt).
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'las_reader'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install las_reader
23
+
24
+ ## Quick irb Usage
25
+
26
+ irb> require 'rubygems'
27
+ irb> require 'las_reader'
28
+ irb> my_las = CWLSLas.new('my_well.las')
29
+
30
+ ## Contributing
31
+
32
+ 1. Fork it
33
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
34
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
35
+ 4. Push to the branch (`git push origin my-new-feature`)
36
+ 5. Create new Pull Request
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new('spec')
6
+
7
+ task :default => :spec
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'las_reader/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "las_reader"
8
+ gem.version = LasReader::VERSION
9
+ gem.authors = ["Gilberto P. Carmo Jr."]
10
+ gem.email = ["gpcarmo@gmail.com"]
11
+ gem.description = %q{A simple gem to read CWLS-LAS file format. File in this format will contain well log data in ASCII format}
12
+
13
+ gem.add_development_dependency "rspec"
14
+
15
+ gem.summary = %q{Read CWLS LAS files}
16
+ gem.homepage = "https://github.com/gpcarmo/cwls-las-reader"
17
+
18
+ gem.files = `git ls-files`.split($/)
19
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
20
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
21
+ gem.require_paths = ["lib"]
22
+ end
@@ -0,0 +1,286 @@
1
+ require "las_reader/version"
2
+ require "las_reader/curve_info"
3
+ require "las_reader/curve"
4
+ require "las_reader/mnemonic"
5
+ require "las_reader/well_info"
6
+
7
+ module LasReader
8
+
9
+ attr_reader :version
10
+ attr_reader :wrap
11
+ attr_reader :curves
12
+ attr_reader :parameters
13
+ attr_reader :well_info
14
+
15
+ def set_version(info)
16
+ version = info.match(/(VERS\.).+([1-3]\.[0-9]).*:\s*(.*)/)
17
+ if version.nil?
18
+ wrap_mode = info.match(/(WRAP\.).+(YES|NO).*:\s*(.*)/)
19
+ if not wrap_mode.nil?
20
+ @wrap = (wrap_mode[2] == "YES") ? true : false
21
+ end
22
+ else
23
+ @version = version[2]
24
+ raise "LAS version not supported" if @version.to_f > 2.0
25
+ end
26
+ end
27
+
28
+ def set_curve_info(info)
29
+ mnemonic = info.match(/(\w+)\s*\.(\S*)\s+(.*):\s*(.*)/)
30
+ unless mnemonic.nil?
31
+ @curves["#{mnemonic[1]}"] = Curve.new(mnemonic[1],mnemonic[2],mnemonic[3],mnemonic[4])
32
+ @acurves << mnemonic[1]
33
+ end
34
+ end
35
+
36
+ def set_parameters(info)
37
+ mnemonic = info.match(/(\w+)\s*\.(\S+)\s+(.*):\s*(.*)/)
38
+ unless mnemonic.nil?
39
+ @parameters["#{mnemonic[1]}"] = Mnemonic.new(mnemonic[1],mnemonic[2],mnemonic[3],mnemonic[4])
40
+ end
41
+ end
42
+
43
+ def set_well_info(info)
44
+
45
+ strt = info.match(/(STRT)\.(\w).+\s([0-9]+\.[0-9]+).*:\s*(.*)/)
46
+ unless strt.nil?
47
+ @well_info.start_depth = strt[3].to_f
48
+ @well_info.depth_unit = strt[2]
49
+ return
50
+ end
51
+
52
+ stop = info.match(/(STOP)\.(\w).+\s([0-9]+\.[0-9]+).*:\s*(.*)/)
53
+ unless stop.nil?
54
+ @well_info.stop_depth = stop[3].to_f
55
+ return
56
+ end
57
+
58
+ step = info.match(/(STEP)\.(\w).+\s(-?[0-9]+\.[0-9]+).*:\s*(.*)/)
59
+ unless step.nil?
60
+ @well_info.step = step[3].to_f
61
+ return
62
+ end
63
+
64
+ null = info.match(/(NULL)\..+\s(-?[0-9]+\.[0-9]+).*:\s*(.*)/)
65
+ unless null.nil?
66
+ @well_info.null_value = null[2].to_f
67
+ return
68
+ end
69
+
70
+ comp = info.match(/(COMP\..+COMPANY:\s*(.*))|(COMP\s*\.\s*(.*)\s+:COMPANY)/)
71
+ unless comp.nil?
72
+ @well_info.company_name = (comp[2] or comp[4]).strip
73
+ return
74
+ end
75
+
76
+ well = info.match(/(WELL\..+WELL:\s*(.*))|(WELL\s*\.\s*(.*)\s+:WELL)/)
77
+ unless well.nil?
78
+ @well_info.well_name = (well[2] or well[4]).strip
79
+ return
80
+ end
81
+
82
+ fld = info.match(/(FLD \..+FIELD:\s*(.*))|(FLD\s*\.\s*(.*)\s+:FIELD)/)
83
+ unless fld.nil?
84
+ @well_info.field_name = (fld[2] or fld[4]).strip
85
+ return
86
+ end
87
+
88
+ loc = info.match(/(LOC \..+LOCATION:\s*(.*))|(LOC\s*\.\s*(.*)\s+:LOCATION)/)
89
+ unless loc.nil?
90
+ @well_info.location = (loc[2] or loc[4]).strip
91
+ return
92
+ end
93
+
94
+ prov = info.match(/(PROV\..+PROVINCE:\s*(.*))|(PROV\s*\.\s*(.*)\s+:PROVINCE)/)
95
+ unless prov.nil?
96
+ @well_info.province = (prov[2] or prov[4]).strip
97
+ return
98
+ end
99
+
100
+ cnty = info.match(/(CNTY\..+COUNTY:\s*(.*))|(CNTY\s*\.\s*(.*)\s+:COUNTY)/)
101
+ unless cnty.nil?
102
+ @well_info.county = (cnty[2] or cnty[4]).strip
103
+ return
104
+ end
105
+
106
+ stat = info.match(/(STAT\..+STATE:\s*(.*))|(STAT\s*\.\s*(.*)\s+:STATE)/)
107
+ unless stat.nil?
108
+ @well_info.state = (stat[2] or stat[4]).strip
109
+ return
110
+ end
111
+
112
+ ctry = info.match(/(CTRY\..+COUNTRY:\s*(.*))|(CTRY\s*\.\s*(.*)\s+:COUNTRY)/)
113
+ unless ctry.nil?
114
+ @well_info.country = (ctry[2] or ctry[4]).strip
115
+ return
116
+ end
117
+
118
+ srvc = info.match(/(SRVC\..+SERVICE COMPANY:\s*(.*))|(SRVC\s*\.\s*(.*)\s+:SERVICE COMPANY)/)
119
+ unless srvc.nil?
120
+ @well_info.service_company = (srvc[2] or srvc[4]).strip
121
+ return
122
+ end
123
+
124
+ data = info.match(/(DATE\..+LOG DATE:\s*(.*))|(DATE\s*\.\s*(.*)\s+:LOG DATE)/)
125
+ unless data.nil?
126
+ @well_info.date_logged = (data[2] or data[4]).strip
127
+ return
128
+ end
129
+
130
+ uwi = info.match(/(UWI \..+UNIQUE WELL ID:\s*(.*))|(UWI\s*\.\s*(.*)\s+:UNIQUE WELL ID)/)
131
+ unless uwi.nil?
132
+ @well_info.uwi = (uwi[2] or uwi[4]).strip
133
+ return
134
+ end
135
+
136
+ end
137
+
138
+ def set_other_info(info)
139
+ end
140
+
141
+ def log_wrap_data(info,temp_array)
142
+ d=info.scan(/[-]?[0-9]+.[0-9]+/)
143
+ a = temp_array + d if not d.nil?
144
+ if a.size == self.curves.size
145
+ self.curves.each do |k,v|
146
+ value = a[@acurves.index(k)].to_f
147
+ v.log_data << ((value == @well_info.null_value) ? nil : value)
148
+ end
149
+ a = []
150
+ end
151
+ return a
152
+ end
153
+
154
+ def log_nowrap_data(info)
155
+ d=info.scan(/[-]?[0-9]+.[0-9]+/)
156
+ unless d.nil?
157
+ self.curves.each do |k,v|
158
+ value = d[@acurves.index(k)].to_f
159
+ v.log_data << ((value == @well_info.null_value) ? nil : value)
160
+ end
161
+ end
162
+ end
163
+
164
+ def load_file(file_name)
165
+
166
+ temp_array = []
167
+ @curves = {}
168
+ @parameters = {}
169
+ @acurves = []
170
+
171
+ read_state = 0
172
+
173
+ #section_definition = {
174
+ # 'V' => "Version and wrap mode information",
175
+ # 'W' => "well identification",
176
+ # 'C' => "curve information",
177
+ # 'P' => "parameters or constants",
178
+ # 'O' => "other information such as comments",
179
+ # 'A' => "ASCII log data"
180
+ #}
181
+
182
+ unless File.exist?(file_name)
183
+ raise "No such file or directory"
184
+ end
185
+
186
+ File.open(file_name).each do |line|
187
+ # ignore comments
188
+ next if line[0].chr == '#'
189
+ # The '~' is used to inform the beginning of a section
190
+ if line[0].chr == '~'
191
+ # unless section_definition.keys.include? line[1].chr
192
+ # raise "unsupported_file_format for #{line}"
193
+ # end
194
+ case line[1].chr
195
+ when 'V' # Version information section
196
+ read_state = 1
197
+ when 'W' # Well identification section
198
+ @well_info = WellInfo.new
199
+ read_state = 2
200
+ when 'C' # Curve information section
201
+ read_state = 3
202
+ when 'P' # Parameters information section
203
+ #set_log_pattern(curves.size)
204
+ read_state = 4
205
+ when 'O' # Other information section
206
+ read_state = 5
207
+ when 'A' # ASCII Log data section
208
+ read_state = 6
209
+ else
210
+ raise "unsupported file format for #{line}"
211
+ read_state = 0 # Unknow file format
212
+ end
213
+ else
214
+ case read_state
215
+ when 1
216
+ set_version(line.lstrip)
217
+ when 2
218
+ set_well_info(line.lstrip)
219
+ when 3
220
+ set_curve_info(line.lstrip)
221
+ when 4
222
+ set_parameters(line.lstrip)
223
+ when 5
224
+ set_other_info(line)
225
+ when 6
226
+ if self.wrap
227
+ temp_array = log_wrap_data(line,temp_array)
228
+ else
229
+ log_nowrap_data(line)
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end
235
+
236
+ end
237
+
238
+ class CWLSLas
239
+
240
+ include LasReader
241
+
242
+ def initialize(filename=nil)
243
+ load_file(filename) if not filename.nil?
244
+ end
245
+
246
+ def curve_names
247
+ self.curves.keys
248
+ end
249
+
250
+ def curve(curve_name)
251
+ self.curves[curve_name]
252
+ end
253
+
254
+ def well_name
255
+ self.well_info.well_name
256
+ end
257
+
258
+ def company_name
259
+ self.well_info.company_name
260
+ end
261
+
262
+ def field_name
263
+ self.well_info.field_name
264
+ end
265
+
266
+ def location
267
+ self.well_info.location
268
+ end
269
+
270
+ def province
271
+ self.well_info.province
272
+ end
273
+
274
+ def service_company
275
+ self.well_info.service_company
276
+ end
277
+
278
+ def log_date
279
+ self.well_info.date_logged
280
+ end
281
+
282
+ def uwi
283
+ self.well_info.uwi
284
+ end
285
+
286
+ end
@@ -0,0 +1,21 @@
1
+ class LasReader::Curve
2
+ attr_reader :name, :unit, :api, :description
3
+ attr_accessor :log_data
4
+ def initialize(name,unit,api,info)
5
+ @name = name
6
+ @unit = unit
7
+ @api = api
8
+ @description = info
9
+ @log_data = []
10
+ end
11
+ def add(*p)
12
+ p.each do |point|
13
+ if point.respond_to?(:each)
14
+ @log_data += point
15
+ else
16
+ @log_data << point
17
+ end
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,9 @@
1
+ class LasReader::CurveInfo
2
+ attr_reader :name, :unit, :api, :description
3
+ def initialize(name,unit,api,info)
4
+ @name = name
5
+ @unit = unit
6
+ @api = api
7
+ @description = info
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class LasReader::Mnemonic
2
+ attr_reader :name, :unit, :value, :description
3
+ def initialize(name,unit,value,info)
4
+ @name = name
5
+ @unit = unit
6
+ @value = value
7
+ @description = info
8
+ end
9
+ end