fcsparse 0.1.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.
@@ -0,0 +1,93 @@
1
+ #--
2
+ # /* ***** BEGIN LICENSE BLOCK *****
3
+ # *
4
+ # * Copyright (c) 2012 Colin J. Fuller
5
+ # *
6
+ # * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # * of this software and associated documentation files (the Software), to deal
8
+ # * in the Software without restriction, including without limitation the rights
9
+ # * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # * copies of the Software, and to permit persons to whom the Software is
11
+ # * furnished to do so, subject to the following conditions:
12
+ # *
13
+ # * The above copyright notice and this permission notice shall be included in
14
+ # * all copies or substantial portions of the Software.
15
+ # *
16
+ # * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # * SOFTWARE.
23
+ # *
24
+ # * ***** END LICENSE BLOCK ***** */
25
+ #++
26
+
27
+ ##
28
+ # Contains all classes and constants for parsing FCS v3.x formatted files.
29
+ #
30
+ module FCSParse
31
+
32
+ #
33
+ # Contains constants associated with the fcs file format, such as byte offsets
34
+ # and parameter names.
35
+ #
36
+ # The first character of each constant name specifies the section of the fcs file
37
+ # to which it is relevant. (H = header, T = text, etc.)
38
+ #
39
+ # @author Colin J. Fuller
40
+ #
41
+
42
+ #byte offsets to the start and end of the version string
43
+ H_VersionStart = 0
44
+ H_VersionEnd = 5
45
+
46
+ #length of the block specifying the offsets of text, data, analysis sections
47
+ H_OffsetBlockLength = 8
48
+
49
+ #offsets to the start and end of the text section offset
50
+ H_TextBlockOffsetStart = 10
51
+ H_TextBlockOffsetEnd = 18
52
+
53
+ #offsets to the start and end of the data section offset
54
+ H_DataBlockOffsetStart = 26
55
+ H_DataBlockOffsetEnd = 34
56
+
57
+ #offsets to the start and end of the analysis section offset
58
+ H_AnalysisBlockOffsetStart = 42
59
+ H_AnalysisBlockOffsetEnd = 50
60
+
61
+ #keyword specifying offset to supplementary text section
62
+ T_SupplTextStartKeyword = :$BEGINSTEXT
63
+ T_SupplTextEndKeyword = :$ENDSTEXT
64
+
65
+ #keyword specifying offset to analysis section
66
+ T_AnalysisStartKeyword = :$BEGINANALYSIS
67
+ T_AnalysisEndKeyword = :$BEGINANALYSIS
68
+
69
+ #keyword specifying offset to data section
70
+ T_DataStartKeyword = :$BEGINDATA
71
+ T_DataEndKeyword = :$ENDDATA
72
+
73
+ #keyword specifying the data mode
74
+ T_ModeKeyword = :$MODE
75
+
76
+ #keyword specifying the data type (e.g. integer, float, etc)
77
+ T_DatatypeKeyword = :$DATATYPE
78
+
79
+ #keyword specifying byte order and value when little endian
80
+ T_ByteorderKeyword = :$BYTEORD
81
+ T_LittleEndianByteorder = "1,2,3,4"
82
+
83
+ #keyword specifying the number of parameters measured per event
84
+ T_ParameterCountKeyword = :$PAR
85
+
86
+ #keyword specifying total number of events
87
+ T_EventCountKeyword = :$TOT
88
+
89
+ #regular expressions matching names and ranges of all parameters
90
+ T_ParameterNameKeywordRegex = /P(\d+)N/
91
+ T_ParameterRangeKeywordRegex = /P(\d+)R/
92
+
93
+ end
@@ -0,0 +1,215 @@
1
+ #--
2
+ # /* ***** BEGIN LICENSE BLOCK *****
3
+ # *
4
+ # * Copyright (c) 2012 Colin J. Fuller
5
+ # *
6
+ # * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # * of this software and associated documentation files (the Software), to deal
8
+ # * in the Software without restriction, including without limitation the rights
9
+ # * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # * copies of the Software, and to permit persons to whom the Software is
11
+ # * furnished to do so, subject to the following conditions:
12
+ # *
13
+ # * The above copyright notice and this permission notice shall be included in
14
+ # * all copies or substantial portions of the Software.
15
+ # *
16
+ # * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # * SOFTWARE.
23
+ # *
24
+ # * ***** END LICENSE BLOCK ***** */
25
+ #++
26
+
27
+ require 'fcsparse/fcsconst'
28
+
29
+ ##
30
+ # Contains all classes and constants for parsing FCS v3.x formatted files.
31
+ #
32
+ module FCSParse
33
+
34
+ ##
35
+ # Class representing a single parameter and its value in a single event.
36
+ #
37
+ # @author Colin J. Fuller
38
+ #
39
+ class FCSParam
40
+
41
+ ##
42
+ # Create a new parameter with specified information
43
+ #
44
+ # @param name the name of the parameter
45
+ # @param description a longer description of the parameter
46
+ # @param value the value of the parameter
47
+ # @param limit the maximum value that the parameter can take
48
+ #
49
+ def initialize(name, description, value, limit)
50
+
51
+ @name = name
52
+ @description = description
53
+ @value = value
54
+ @limit = limit
55
+
56
+ end
57
+
58
+ attr_accessor :name, :description, :value, :limit
59
+
60
+ end
61
+
62
+
63
+ ##
64
+ # Class representing a single FCS-encoded event.
65
+ #
66
+ # @author Colin J. Fuller
67
+ #
68
+ class FCSEvent
69
+
70
+ #default delimiter for printing output
71
+ DefaultDelimiter = ","
72
+
73
+ private_class_method :new
74
+
75
+ def initialize
76
+
77
+ @values = Hash.new
78
+
79
+ end
80
+
81
+
82
+ ##
83
+ # Creates a new FCSEvent from the specified information.
84
+ #
85
+ # @param [String] event_data_string the raw data corresponding to the
86
+ # entire event from the fcs file
87
+ # @param [String] event_format_string a string suitable for use with String#unpack
88
+ # that can decode the raw data.
89
+ # @param [Hash] parameter_info_hash a hash containing at minimum the parameters
90
+ # from the text section specifying the names and ranges of the parameters
91
+ # keys should be the parameter names from the fcs file format converted
92
+ # to symbols ($ included), and values should be a string corresponding
93
+ # to the value of the parameter from the fcs file.
94
+ # @return [FCSEvent] an FCSEvent that has been created by parsing the raw data.
95
+ #
96
+ def self.new_with_data_and_format(event_data_string, event_format_string, parameter_info_hash)
97
+
98
+ data_points = event_data_string.unpack(event_format_string)
99
+
100
+ parameter_names = Hash.new
101
+ parameter_limits = Hash.new
102
+
103
+ parameter_info_hash.each_key do |k|
104
+
105
+ matchobj = k.to_s.match(T_ParameterNameKeywordRegex)
106
+
107
+
108
+ if matchobj then
109
+
110
+ parameter_names[matchobj[1].to_i] = parameter_info_hash[k]
111
+
112
+ end
113
+
114
+
115
+ matchobj = k.to_s.match(T_ParameterRangeKeywordRegex)
116
+
117
+ if matchobj then
118
+
119
+ parameter_limits[matchobj[1].to_i] = parameter_info_hash[k]
120
+
121
+ end
122
+
123
+ end
124
+
125
+ ordered_indices = parameter_names.keys.sort
126
+
127
+ event = new
128
+
129
+ data_points.each_with_index do |e, i|
130
+
131
+ param = FCSParam.new(parameter_names[ordered_indices[i]], nil, e, parameter_limits[ordered_indices[i]])
132
+
133
+ event[param.name] = param
134
+
135
+ end
136
+
137
+ event
138
+
139
+ end
140
+
141
+ ##
142
+ # Gets a named parameter associated with the event.
143
+ #
144
+ # @param [String] parameter_name the name of the parameter to retrieve; this should be
145
+ # exactly the name specified for the parameter in the text
146
+ # section of the fcs file
147
+ # @return [FCSParam] an FCSParam object that holds the information about the named parameter.
148
+ #
149
+ def [](parameter_name)
150
+
151
+ @values[parameter_name]
152
+
153
+ end
154
+
155
+ ##
156
+ # Sets a named parameter associated with the event.
157
+ # @param [String] parameter_name the name of the parameter to retrieve; this should be
158
+ # exactly the name specified for the parameter in the text
159
+ # section of the fcs file
160
+ # @param [FCSParam] value an FCSParam object that holds the information about the named parameter.
161
+ #
162
+ def []=(parameter_name, value)
163
+
164
+ @values[parameter_name]= value
165
+
166
+ end
167
+
168
+ ##
169
+ # Gets the names of the parameters associated with this event in alphabetical
170
+ # order as a string, delimited by the supplied delimiter.
171
+ #
172
+ # @param [String] delimiter a String containing the desired delimiter.
173
+ # @return [String] a String containing delimited alphabetized parameter names.
174
+ #
175
+ def names_to_s_delim(delimiter)
176
+
177
+ all_param_names = @values.keys.sort
178
+
179
+ all_param_names.join(delimiter)
180
+
181
+ end
182
+
183
+ ##
184
+ # Gets the values of the parameters associated with this event ordered
185
+ # alphabetically by the parameter names (i.e. in the same order as when calling
186
+ # {#names_to_s_delim}), delimited by the supplied delimiter.
187
+ #
188
+ # @param [String]delimiter a String containing the desired delimiter.
189
+ # @return [String] a String containing delimited ordered parameter values.
190
+ #
191
+ def to_s_delim(delimiter)
192
+
193
+ all_param_names = @values.keys.sort
194
+
195
+ all_param_values = all_param_names.map{|e| @values[e].value}
196
+
197
+ all_param_values.join(delimiter)
198
+
199
+ end
200
+
201
+ ##
202
+ # Converts the event to a string representation. This is the same as calling
203
+ # {#to_s_delim} with the delimiter set to {FCSEvent::DefaultDelimiter}.
204
+ #
205
+ # @return [String] a String containing delimited ordered parameter values.
206
+ #
207
+ def to_s
208
+
209
+ to_s_delim(DefaultDelimiter)
210
+
211
+ end
212
+
213
+ end
214
+
215
+ end
data/lib/fcsparse.rb ADDED
@@ -0,0 +1,363 @@
1
+ #--
2
+ # /* ***** BEGIN LICENSE BLOCK *****
3
+ # *
4
+ # * Copyright (c) 2012 Colin J. Fuller
5
+ # *
6
+ # * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # * of this software and associated documentation files (the Software), to deal
8
+ # * in the Software without restriction, including without limitation the rights
9
+ # * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # * copies of the Software, and to permit persons to whom the Software is
11
+ # * furnished to do so, subject to the following conditions:
12
+ # *
13
+ # * The above copyright notice and this permission notice shall be included in
14
+ # * all copies or substantial portions of the Software.
15
+ # *
16
+ # * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # * SOFTWARE.
23
+ # *
24
+ # * ***** END LICENSE BLOCK ***** */
25
+ #++
26
+
27
+ require 'fcsparse/fcsconst'
28
+ require 'fcsparse/fcsevent'
29
+
30
+ ##
31
+ # Contains all classes and constants for parsing FCS v3.x formatted files.
32
+ #
33
+ module FCSParse
34
+
35
+ ##
36
+ # A class representing an FCS-encoded file. Has methods to parse the data,
37
+ # manage it, and convert it to human-readable format.
38
+ #
39
+ # Currently reads FCS v3.x files. Files must have data encoded in list mode,
40
+ # and data points must be in float or double format (this will change eventually to support
41
+ # all formats in the specification).
42
+ #
43
+ # Analysis sections of the file are ignored.
44
+ #
45
+ # Data can be written to delimited text files, and metadata to plain text files,
46
+ # or the objects containing the data can be used by other code to process
47
+ # the data further.
48
+ #
49
+ # @author Colin J. Fuller
50
+ #
51
+ class FCSFile
52
+
53
+ MetadataExtension = ".meta.txt"
54
+ DataExtension = ".data.csv"
55
+ DataDelimiter = FCSEvent::DefaultDelimiter
56
+ SupportedVersions = ["FCS3.0", "FCS3.1"]
57
+
58
+ attr_accessor :filename, :events
59
+
60
+
61
+ ##
62
+ # Generates a new FCSFile object from the specified file.
63
+ #
64
+ # Calling this will read the entire file into memory but will not parse it.
65
+ #
66
+ # @param [String] filename the filename of the FCS-encoded file (with path as required to locate it)
67
+ # @return [FCSFile] a new FCSFile object initialized with the contents of the file.
68
+ #
69
+ def self.new_from_file(filename)
70
+
71
+ fcsfile = nil
72
+
73
+ File.open(filename) do |f|
74
+ fcsfile = self.new(f.read)
75
+ end
76
+
77
+ fcsfile.filename = filename
78
+
79
+ fcsfile
80
+
81
+ end
82
+
83
+ ##
84
+ # Generates a new FCSFile from the specified FCS-encoded data string.
85
+ #
86
+ # @param [String] file_string a String containing an FCS-encoded dataset.
87
+ def initialize(file_string)
88
+ @data = file_string
89
+ @keywords = Hash.new
90
+ end
91
+
92
+ def read_header
93
+
94
+ version_string= @data[H_VersionStart..H_VersionEnd]
95
+
96
+ unless SupportedVersions.include?(version_string) then
97
+ raise "Unable to read this FCS format: " + version_string
98
+ end
99
+
100
+
101
+ @version = version_string[3..5].to_f
102
+
103
+ @text_offsets = Array.new
104
+ @data_offsets = Array.new
105
+ @analysis_offsets = Array.new
106
+
107
+ @text_offsets << @data[H_TextBlockOffsetStart, H_OffsetBlockLength].to_i
108
+ @text_offsets << @data[H_TextBlockOffsetEnd, H_OffsetBlockLength].to_i
109
+
110
+ @data_offsets << @data[H_DataBlockOffsetStart, H_OffsetBlockLength].to_i
111
+ @data_offsets << @data[H_DataBlockOffsetEnd, H_OffsetBlockLength].to_i
112
+
113
+ @analysis_offsets << @data[H_AnalysisBlockOffsetStart, H_OffsetBlockLength].to_i
114
+ @analysis_offsets << @data[H_AnalysisBlockOffsetEnd, H_OffsetBlockLength].to_i
115
+
116
+ end
117
+
118
+ def parse_text_segment_with_bounds(lower_bound, upper_bound)
119
+
120
+ token_queue = Array.new
121
+
122
+ delimiter = @data[lower_bound]
123
+
124
+ token_start = lower_bound + 1
125
+
126
+ (lower_bound+1).upto(upper_bound) do |i|
127
+
128
+ if @data[i] == delimiter and not @data[i-1] == delimiter and not @data[i+1] == delimiter then
129
+
130
+ token_queue << @data[token_start...i]
131
+ token_start = i+1
132
+
133
+ end
134
+
135
+ end
136
+
137
+ token_queue.each_slice(2) do |kv|
138
+
139
+ @keywords[kv[0].upcase.to_sym]= kv[1]
140
+
141
+ end
142
+
143
+
144
+
145
+ end
146
+
147
+ def parse_text_segment
148
+
149
+ parse_text_segment_with_bounds(@text_offsets[0].to_i, @text_offsets[1].to_i)
150
+
151
+ suppl_text_start = @keywords[T_SupplTextStartKeyword].to_i
152
+ suppl_text_end = @keywords[T_SupplTextEndKeyword].to_i
153
+
154
+ unless suppl_text_start == 0 and suppl_text_end == 0 then
155
+ parse_text_segment_with_bounds(suppl_text_start, suppl_text_end)
156
+ end
157
+
158
+ @data_offsets[0] = @keywords[T_DataStartKeyword].to_i
159
+ @data_offsets[1] = @keywords[T_DataEndKeyword].to_i
160
+
161
+ @analysis_offsets[0] = @keywords[T_AnalysisStartKeyword].to_i
162
+ @analysis_offsets[1] = @keywords[T_AnalysisEndKeyword].to_i
163
+
164
+ unless @keywords[T_ModeKeyword] == "L" then
165
+ raise "Only list mode is supported for the data block."
166
+ end
167
+
168
+ end
169
+
170
+ def parse_data_segment
171
+
172
+ event_format = construct_event_format_string
173
+
174
+ event_count = @keywords[T_EventCountKeyword].to_i
175
+
176
+ bytes_per_event = ((@data_offsets[1] - @data_offsets[0] + 1)*1.0/event_count).to_i
177
+
178
+ @events = Array.new
179
+
180
+ 0.upto(event_count -1) do |e|
181
+
182
+ offset = @data_offsets[0] + bytes_per_event*e
183
+
184
+ event_string = @data[offset, bytes_per_event]
185
+
186
+ event = FCSEvent.new_with_data_and_format(event_string, event_format, @keywords)
187
+
188
+ @events << event
189
+
190
+ end
191
+
192
+ end
193
+
194
+ def construct_event_format_string
195
+
196
+ datatype = @keywords[T_DatatypeKeyword]
197
+
198
+ is_little_endian = (@keywords[T_ByteorderKeyword] == T_LittleEndianByteorder)
199
+
200
+ formatchar = case datatype
201
+
202
+ when 'I'
203
+
204
+ nil
205
+
206
+ when 'F'
207
+
208
+ if is_little_endian then
209
+
210
+ 'e'
211
+
212
+ else
213
+
214
+ 'g'
215
+
216
+ end
217
+
218
+ when 'D'
219
+
220
+ if is_little_endian then
221
+
222
+ 'E'
223
+
224
+ else
225
+
226
+ 'G'
227
+
228
+ end
229
+
230
+ when 'A'
231
+
232
+ nil
233
+
234
+ end
235
+
236
+ unless formatchar then
237
+ raise "Integer and string data not yet supported."
238
+ end
239
+
240
+ parameter_count = @keywords[T_ParameterCountKeyword].to_i
241
+
242
+ formatchar*parameter_count
243
+
244
+ end
245
+
246
+ ##
247
+ # Gets the metadata (that is all the information in the text block of the
248
+ # fcs file) as a string, where there is one key, value pair per line, separated
249
+ # by the characters " => "
250
+ #
251
+ # @return [String] a String containing all the metadata
252
+ def get_metadata_string
253
+ str = ""
254
+ @keywords.keys.map{|e| e.to_s}.sort.each do |k|
255
+ str << k.to_s + " => " + @keywords[k.to_sym].to_s + "\n"
256
+ end
257
+ str
258
+ end
259
+
260
+ ##
261
+ # Prints the metadata string returned by {#get_metadata_string}.
262
+ #
263
+ def print_metadata
264
+
265
+ puts get_metadata_string
266
+
267
+ nil
268
+
269
+ end
270
+
271
+ ##
272
+ # Writes the metadata and data from the FCS-formatted file to disk in human
273
+ # readable format.
274
+ #
275
+ # The metadata is written as a text file (formatted by
276
+ # {#get_metadata_string}), in the same location as the input FCS file and
277
+ # with the same name except for an extra extension specified in
278
+ # {FCSFile::MetadataExtension}.
279
+ #
280
+ # The data, delimited by the data delimiter specified
281
+ # as {FCSFile::DataDelimiter}, one row per event, is written to a text file
282
+ # in the same location as the input FCS file and with the same name except
283
+ # for an extra extension specified in {FCSFile::DataExtension}.
284
+ #
285
+ # @param [Boolean] write_header_row an optional parameter specifying whether
286
+ # the data file should have a header row with the name of each column's
287
+ # parameter. Defaults to true.
288
+ #
289
+ def write_metadata_and_data(write_header_row = true)
290
+
291
+ meta_filename = @filename + MetadataExtension
292
+
293
+ data_filename = @filename + DataExtension
294
+
295
+ File.open(meta_filename, "w") do |f|
296
+
297
+ f.write(get_metadata_string)
298
+
299
+ end
300
+
301
+ File.open(data_filename, "w") do |f|
302
+
303
+ if write_header_row then
304
+ f.puts(@events[0].names_to_s_delim(DataDelimiter))
305
+ end
306
+
307
+ @events.each do |e|
308
+
309
+ f.puts(e.to_s_delim(DataDelimiter))
310
+
311
+ end
312
+
313
+ end
314
+
315
+ nil
316
+
317
+ end
318
+
319
+ ##
320
+ # Parses the raw data loaded in the FCSFile to metadata, events, and parameters.
321
+ #
322
+ # Erases the raw data from the FCSFile object after parsing is complete.
323
+ #
324
+ def parse
325
+ read_header
326
+ parse_text_segment
327
+ parse_data_segment
328
+ @data = nil
329
+ end
330
+
331
+ private :read_header, :parse_text_segment_with_bounds, :parse_text_segment, :parse_data_segment, :construct_event_format_string
332
+
333
+ end
334
+
335
+
336
+ ##
337
+ # Processes a specified FCS-formatted file, and writes human-readable output
338
+ # to disk in the format specified by {FCSFile#write_metadata_and_data}.
339
+ #
340
+ # @param [String] filename the filename of the FCS-encoded file (with path as required to locate it)
341
+ # @param [Boolean] data_header_row an optional parameter specifying whether
342
+ # the data file should have a header row with the name of each column's
343
+ # parameter. Defaults to true.
344
+ #
345
+ def self.process_file(filename, data_header_row = true)
346
+
347
+ fcsfile = FCSFile.new_from_file(filename)
348
+ fcsfile.parse
349
+ fcsfile.write_metadata_and_data(data_header_row)
350
+
351
+ nil
352
+
353
+ end
354
+
355
+
356
+
357
+ end
358
+
359
+ if __FILE__ == $0 then
360
+
361
+ FCSParse.process_file(ARGV[0], false)
362
+
363
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fcsparse
3
+ version: !ruby/object:Gem::Version
4
+ hash: 1322991910812937300
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Colin J. Fuller
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-06-18 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description: Parses flow cytometry FCS v3.x files and allows output to plain (delimited) text.
22
+ email: cjfuller@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - lib/fcsparse.rb
31
+ - lib/fcsparse/fcsconst.rb
32
+ - lib/fcsparse/fcsevent.rb
33
+ homepage: http://code.google.com/p/fcsparse/
34
+ licenses:
35
+ - MIT
36
+ post_install_message:
37
+ rdoc_options: []
38
+
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ hash: 2002549777813010636
47
+ segments:
48
+ - 0
49
+ version: "0"
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ hash: 2002549777813010636
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.8.12
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Parser for FCS v3.x file format
66
+ test_files: []
67
+
68
+ has_rdoc: