rtp-connect 1.1 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://www.rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rtp-connect (1.1)
5
+
6
+ GEM
7
+ remote: http://www.rubygems.org/
8
+ specs:
9
+ dicom (0.9.3)
10
+ diff-lcs (1.1.3)
11
+ metaclass (0.0.1)
12
+ mocha (0.12.0)
13
+ metaclass (~> 0.0.1)
14
+ rake (0.9.2.2)
15
+ rspec (2.11.0)
16
+ rspec-core (~> 2.11.0)
17
+ rspec-expectations (~> 2.11.0)
18
+ rspec-mocks (~> 2.11.0)
19
+ rspec-core (2.11.0)
20
+ rspec-expectations (2.11.1)
21
+ diff-lcs (~> 1.1.3)
22
+ rspec-mocks (2.11.1)
23
+ yard (0.8.2.1)
24
+
25
+ PLATFORMS
26
+ x86-mingw32
27
+
28
+ DEPENDENCIES
29
+ bundler (>= 1.0.0)
30
+ dicom (>= 0.9.3)
31
+ mocha (>= 0.10.5)
32
+ rake (>= 0.9.2.2)
33
+ rspec (>= 2.9.0)
34
+ rtp-connect!
35
+ yard (>= 0.8.2)
data/README.rdoc CHANGED
@@ -26,23 +26,29 @@ external dependencies.
26
26
  === Read, modify and write
27
27
 
28
28
  # Read file:
29
- rtp = Plan.read("some_file.rtp")
29
+ rtp = Plan.read('some_file.rtp')
30
30
  # Extract the Patient's Name:
31
31
  name = rtp.patient_last_name
32
32
  # Modify the Patient's Name:
33
- rtp.patient_last_name = "Anonymous"
33
+ rtp.patient_last_name = 'Anonymous'
34
34
  # Write to file:
35
- rtp.write("new_file.rtp")
35
+ rtp.write('new_file.rtp')
36
36
 
37
37
  === Create a new Plan Definition Record from scratch
38
38
 
39
39
  # Create the instance:
40
40
  rtp = Plan.new
41
41
  # Set the Patient's ID attribute:
42
- rtp.patient_id = "12345"
42
+ rtp.patient_id = '12345'
43
43
  # Export the instance to an RTP string (with CRC):
44
44
  output = rtp.to_s
45
45
 
46
+ === Convert an RTP file to DICOM:
47
+
48
+ p = Plan.read('some_file.rtp')
49
+ dcm = p.to_dcm
50
+ dcm.write('rtplan.dcm')
51
+
46
52
  === Log settings
47
53
 
48
54
  # Change the log level so that only error messages are displayed:
@@ -69,7 +75,7 @@ automatically printed to the screen. A useful hack to avoid this effect is
69
75
  to append ";0" after a command.
70
76
 
71
77
  Example:
72
- rtp = Plan.read("some_file.rtp") ;0
78
+ rtp = Plan.read('some_file.rtp') ;0
73
79
 
74
80
 
75
81
  == RESOURCES
@@ -89,6 +95,7 @@ Example:
89
95
  * Treatment field [FIELD_DEF]
90
96
  * Extended treatment field [EXTENDED_FIELD_DEF]
91
97
  * Control point record [CONTROL_PT_DEF]
98
+ * Dose tracking record [DOSE_DEF]
92
99
 
93
100
  === Unsupported records
94
101
 
@@ -96,7 +103,6 @@ Example:
96
103
  * Document based treatment field [PDF_FIELD_DEF]
97
104
  * Multileaf collimator [MLC_DEF]
98
105
  * MLC shape [MLC_SHAPE_DEF]
99
- * Dose tracking record [DOSE_DEF]
100
106
  * Dose action points [DOSE_ACTION]
101
107
 
102
108
  If you encounter an RTP file with an unsupported record type, please contact me.
data/lib/rtp-connect.rb CHANGED
@@ -1,23 +1,25 @@
1
- # Loads the files that are used by the RTPConnect library.
2
-
3
- # Logging:
4
- require_relative 'rtp-connect/logging'
5
- # Super classes:
6
- require_relative 'rtp-connect/record'
7
- # Core library:
8
- require_relative 'rtp-connect/plan'
9
- require_relative 'rtp-connect/prescription'
10
- require_relative 'rtp-connect/site_setup'
11
- require_relative 'rtp-connect/field'
12
- require_relative 'rtp-connect/extended_field'
13
- require_relative 'rtp-connect/control_point'
14
- # Extensions to the Ruby library:
15
- require_relative 'rtp-connect/ruby_extensions'
16
- # Module settings:
17
- require_relative 'rtp-connect/version'
18
- require_relative 'rtp-connect/constants'
19
- require_relative 'rtp-connect/methods'
20
- require_relative 'rtp-connect/variables'
21
-
22
- # Load the CSV library:
1
+ # Loads the files that are used by the RTPConnect library.
2
+
3
+ # Logging:
4
+ require_relative 'rtp-connect/logging'
5
+ # Super classes:
6
+ require_relative 'rtp-connect/record'
7
+ # Core library:
8
+ require_relative 'rtp-connect/plan'
9
+ require_relative 'rtp-connect/plan_to_dcm'
10
+ require_relative 'rtp-connect/prescription'
11
+ require_relative 'rtp-connect/site_setup'
12
+ require_relative 'rtp-connect/field'
13
+ require_relative 'rtp-connect/extended_field'
14
+ require_relative 'rtp-connect/control_point'
15
+ require_relative 'rtp-connect/dose_tracking'
16
+ # Extensions to the Ruby library:
17
+ require_relative 'rtp-connect/ruby_extensions'
18
+ # Module settings:
19
+ require_relative 'rtp-connect/version'
20
+ require_relative 'rtp-connect/constants'
21
+ require_relative 'rtp-connect/methods'
22
+ require_relative 'rtp-connect/variables'
23
+
24
+ # Load the CSV library:
23
25
  require 'csv'
@@ -1,58 +1,58 @@
1
- module RTP
2
-
3
- # The seed value used in the RTPConnect implementation of the CCITT algorithm.
4
- CRC_SEED = 0x0521
5
-
6
- # The table & values used in the RTPConnect implementation of the CCITT algorithm.
7
- CRC_TABLE = [
8
- 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
9
- 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
10
- 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
11
- 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
12
- 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
13
- 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
14
- 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
15
- 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
16
- 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
17
- 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
18
- 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
19
- 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
20
- 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
21
- 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
22
- 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
23
- 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
24
- 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
25
- 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
26
- 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
27
- 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
28
- 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
29
- 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
30
- 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
31
- 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
32
- 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
33
- 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
34
- 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
35
- 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
36
- 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
37
- 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
38
- 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
39
- 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
40
- ]
41
-
42
- # Pairs of RTPConnect keywords and parse method names.
43
- PARSE_METHOD = {
44
- "PLAN_DEF" => :plan_definition,
45
- "RX_DEF" => :prescription_site,
46
- "SITE_SETUP_DEF" => :site_setup,
47
- "SIM_DEF" => :simulation_field,
48
- "FIELD_DEF" => :treatment_field,
49
- "EXTENDED_FIELD_DEF" => :extended_treatment_field,
50
- "PDF_FIELD_DEF" => :document_based_treatment_field,
51
- "MLC_DEF" => :multileaf_collimator,
52
- "CONTROL_PT_DEF" => :control_point,
53
- "MLC_SHAPE_DEF" => :mlc_shape,
54
- "DOSE_DEF" => :dose_tracking,
55
- "DOSE_ACTION" => :dose_action,
56
- }
57
-
1
+ module RTP
2
+
3
+ # The seed value used in the RTPConnect implementation of the CCITT algorithm.
4
+ CRC_SEED = 0x0521
5
+
6
+ # The table & values used in the RTPConnect implementation of the CCITT algorithm.
7
+ CRC_TABLE = [
8
+ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
9
+ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
10
+ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
11
+ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
12
+ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
13
+ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
14
+ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
15
+ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
16
+ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
17
+ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
18
+ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
19
+ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
20
+ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
21
+ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
22
+ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
23
+ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
24
+ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
25
+ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
26
+ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
27
+ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
28
+ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
29
+ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
30
+ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
31
+ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
32
+ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
33
+ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
34
+ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
35
+ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
36
+ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
37
+ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
38
+ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
39
+ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
40
+ ]
41
+
42
+ # Pairs of RTPConnect keywords and parse method names.
43
+ PARSE_METHOD = {
44
+ "PLAN_DEF" => :plan_definition,
45
+ "RX_DEF" => :prescription_site,
46
+ "SITE_SETUP_DEF" => :site_setup,
47
+ "SIM_DEF" => :simulation_field,
48
+ "FIELD_DEF" => :treatment_field,
49
+ "EXTENDED_FIELD_DEF" => :extended_treatment_field,
50
+ "PDF_FIELD_DEF" => :document_based_treatment_field,
51
+ "MLC_DEF" => :multileaf_collimator,
52
+ "CONTROL_PT_DEF" => :control_point,
53
+ "MLC_SHAPE_DEF" => :mlc_shape,
54
+ "DOSE_DEF" => :dose_tracking,
55
+ "DOSE_ACTION" => :dose_action,
56
+ }
57
+
58
58
  end
@@ -2,10 +2,9 @@ module RTP
2
2
 
3
3
  # The ControlPoint class.
4
4
  #
5
- # === Relations
6
- #
7
- # * Parent: Field
8
- # * Children: MLCShape
5
+ # @note Relations:
6
+ # * Parent: Field
7
+ # * Children: none
9
8
  #
10
9
  class ControlPoint < Record
11
10
 
@@ -51,60 +50,58 @@ module RTP
51
50
 
52
51
  # Creates a new ControlPoint by parsing a RTPConnect string line.
53
52
  #
54
- # === Parameters
55
- #
56
- # * <tt>string</tt> -- A string containing a control point record.
57
- # * <tt>parent</tt> -- A Record which is used to determine the proper parent of this instance.
53
+ # @param [#to_s] string the control point definition record string line
54
+ # @param [Record] parent a record which is used to determine the proper parent of this instance
55
+ # @return [ControlPoint] the created ControlPoint instance
56
+ # @raise [ArgumentError] if given a string containing an invalid number of elements
58
57
  #
59
58
  def self.load(string, parent)
60
59
  # Get the quote-less values:
61
60
  values = string.to_s.values
62
61
  raise ArgumentError, "Invalid argument 'string': Expected exactly 233 elements, got #{values.length}." unless values.length == 233
63
- f = self.new(parent)
62
+ cp = self.new(parent)
64
63
  # Assign the values to attributes:
65
- f.keyword = values[0]
66
- f.field_id = values[1]
67
- f.mlc_type = values[2]
68
- f.mlc_leaves = values[3]
69
- f.total_control_points = values[4]
70
- f.control_pt_number = values[5]
71
- f.mu_convention = values[6]
72
- f.monitor_units = values[7]
73
- f.wedge_position = values[8]
74
- f.energy = values[9]
75
- f.doserate = values[10]
76
- f.ssd = values[11]
77
- f.scale_convention = values[12]
78
- f.gantry_angle = values[13]
79
- f.gantry_dir = values[14]
80
- f.collimator_angle = values[15]
81
- f.collimator_dir = values[16]
82
- f.field_x_mode = values[17]
83
- f.field_x = values[18]
84
- f.collimator_x1 = values[19]
85
- f.collimator_x2 = values[20]
86
- f.field_y_mode = values[21]
87
- f.field_y = values[22]
88
- f.collimator_y1 = values[23]
89
- f.collimator_y2 = values[24]
90
- f.couch_vertical = values[25]
91
- f.couch_lateral = values[26]
92
- f.couch_longitudinal = values[27]
93
- f.couch_angle = values[28]
94
- f.couch_dir = values[29]
95
- f.couch_pedestal = values[30]
96
- f.couch_ped_dir = values[31]
97
- f.mlc_lp_a = [*values[32..131]]
98
- f.mlc_lp_b = [*values[132..231]]
99
- f.crc = values[232]
100
- return f
64
+ cp.keyword = values[0]
65
+ cp.field_id = values[1]
66
+ cp.mlc_type = values[2]
67
+ cp.mlc_leaves = values[3]
68
+ cp.total_control_points = values[4]
69
+ cp.control_pt_number = values[5]
70
+ cp.mu_convention = values[6]
71
+ cp.monitor_units = values[7]
72
+ cp.wedge_position = values[8]
73
+ cp.energy = values[9]
74
+ cp.doserate = values[10]
75
+ cp.ssd = values[11]
76
+ cp.scale_convention = values[12]
77
+ cp.gantry_angle = values[13]
78
+ cp.gantry_dir = values[14]
79
+ cp.collimator_angle = values[15]
80
+ cp.collimator_dir = values[16]
81
+ cp.field_x_mode = values[17]
82
+ cp.field_x = values[18]
83
+ cp.collimator_x1 = values[19]
84
+ cp.collimator_x2 = values[20]
85
+ cp.field_y_mode = values[21]
86
+ cp.field_y = values[22]
87
+ cp.collimator_y1 = values[23]
88
+ cp.collimator_y2 = values[24]
89
+ cp.couch_vertical = values[25]
90
+ cp.couch_lateral = values[26]
91
+ cp.couch_longitudinal = values[27]
92
+ cp.couch_angle = values[28]
93
+ cp.couch_dir = values[29]
94
+ cp.couch_pedestal = values[30]
95
+ cp.couch_ped_dir = values[31]
96
+ cp.mlc_lp_a = [*values[32..131]]
97
+ cp.mlc_lp_b = [*values[132..231]]
98
+ cp.crc = values[232]
99
+ return cp
101
100
  end
102
101
 
103
102
  # Creates a new ControlPoint.
104
103
  #
105
- # === Parameters
106
- #
107
- # * <tt>parent</tt> -- A Record which is used to determine the proper parent of this instance.
104
+ # @param [Record] parent a record which is used to determine the proper parent of this instance
108
105
  #
109
106
  def initialize(parent)
110
107
  # Child:
@@ -117,7 +114,13 @@ module RTP
117
114
  @mlc_lp_b = Array.new(100)
118
115
  end
119
116
 
120
- # Returns true if the argument is an instance with attributes equal to self.
117
+ # Checks for equality.
118
+ #
119
+ # Other and self are considered equivalent if they are
120
+ # of compatible types and their attributes are equivalent.
121
+ #
122
+ # @param other an object to be compared with self.
123
+ # @return [Boolean] true if self and other are considered equivalent
121
124
  #
122
125
  def ==(other)
123
126
  if other.respond_to?(:to_control_point)
@@ -127,23 +130,39 @@ module RTP
127
130
 
128
131
  alias_method :eql?, :==
129
132
 
130
- # As of now, returns an empty array.
131
- # However, by definition, this record may have an mlc shape record as child,
132
- # but this is not implemented yet.
133
+ # As of now, gives an empty array. However, by definition, this record may
134
+ # have an mlc shape record as child, but this is not implemented yet.
135
+ #
136
+ # @return [Array] an emtpy array
133
137
  #
134
138
  def children
135
139
  #return [@mlc_shape]
136
140
  return Array.new
137
141
  end
138
142
 
139
- # Generates a Fixnum hash value for this instance.
143
+ # Computes a hash code for this object.
144
+ #
145
+ # @note Two objects with the same attributes will have the same hash code.
146
+ #
147
+ # @return [Fixnum] the object's hash code
140
148
  #
141
149
  def hash
142
150
  state.hash
143
151
  end
144
152
 
145
- # Returns the values of this instance in an array.
146
- # The values does not include the CRC.
153
+ # Gives the index of this ControlPoint
154
+ # (i.e. its index among the control points belonging to the parent Field).
155
+ #
156
+ # @return [Fixnum] the control point's index
157
+ #
158
+ def index
159
+ @parent.control_points.index(self)
160
+ end
161
+
162
+ # Collects the values (attributes) of this instance.
163
+ #
164
+ # @note The CRC is not considered part of the actual values and is excluded.
165
+ # @return [Array<String>] an array of attributes (in the same order as they appear in the RTP string)
147
166
  #
148
167
  def values
149
168
  return [
@@ -186,13 +205,17 @@ module RTP
186
205
 
187
206
  # Returns self.
188
207
  #
208
+ # @return [ControlPoint] self
209
+ #
189
210
  def to_control_point
190
211
  self
191
212
  end
192
213
 
193
- # Writes the ControlPoint object + any hiearchy of child objects,
214
+ # Encodes the ControlPoint object + any hiearchy of child objects,
194
215
  # to a properly formatted RTPConnect ascii string.
195
216
  #
217
+ # @return [String] an RTP string with a single or multiple lines/records
218
+ #
196
219
  def to_s
197
220
  str = encode
198
221
  if children
@@ -205,34 +228,36 @@ module RTP
205
228
 
206
229
  alias :to_str :to_s
207
230
 
208
- # Sets the mlc_a attribute.
209
- #
210
- # === Notes
231
+ # Sets the mlc_lp_a attribute.
211
232
  #
212
- # As opposed to the ordinary (string) attributes, this attribute
213
- # contains an array holding all 100 MLC leaf 'A' string values.
233
+ # @note As opposed to the ordinary (string) attributes, this attribute
234
+ # contains an array holding all 100 MLC leaf 'A' string values.
235
+ # @param [Array<nil, #to_s>] array the new attribute values
214
236
  #
215
237
  def mlc_lp_a=(array)
216
238
  array = array.to_a
217
239
  raise ArgumentError, "Invalid argument 'array'. Expected length 100, got #{array.length}." unless array.length == 100
218
- @mlc_lp_a = array.collect! {|e| e && e.to_s}
240
+ @mlc_lp_a = array.collect! {|e| e && e.to_s.strip}
219
241
  end
220
242
 
221
- # Sets the mlc_b attribute.
243
+ # Sets the mlc_lp_b attribute.
222
244
  #
223
- # === Notes
224
- #
225
- # As opposed to the ordinary (string) attributes, this attribute
226
- # contains an array holding all 100 MLC leaf 'A' string values.
245
+ # @note As opposed to the ordinary (string) attributes, this attribute
246
+ # contains an array holding all 100 MLC leaf 'B' string values.
247
+ # @param [Array<nil, #to_s>] array the new attribute values
227
248
  #
228
249
  def mlc_lp_b=(array)
229
250
  array = array.to_a
230
251
  raise ArgumentError, "Invalid argument 'array'. Expected length 100, got #{array.length}." unless array.length == 100
231
- @mlc_lp_b = array.collect! {|e| e && e.to_s}
252
+ @mlc_lp_b = array.collect! {|e| e && e.to_s.strip}
232
253
  end
233
254
 
234
255
  # Sets the keyword attribute.
235
256
  #
257
+ # @note Since only a specific string is accepted, this is more of an argument check than a traditional setter method
258
+ # @param [#to_s] value the new attribute value
259
+ # @raise [ArgumentError] if given an unexpected keyword
260
+ #
236
261
  def keyword=(value)
237
262
  value = value.to_s.upcase
238
263
  raise ArgumentError, "Invalid keyword. Expected 'CONTROL_PT_DEF', got #{value}." unless value == "CONTROL_PT_DEF"
@@ -241,186 +266,248 @@ module RTP
241
266
 
242
267
  # Sets the field_id attribute.
243
268
  #
269
+ # @param [nil, #to_s] value the new attribute value
270
+ #
244
271
  def field_id=(value)
245
272
  @field_id = value && value.to_s
246
273
  end
247
274
 
248
275
  # Sets the mlc_type attribute.
249
276
  #
277
+ # @param [nil, #to_s] value the new attribute value
278
+ #
250
279
  def mlc_type=(value)
251
280
  @mlc_type = value && value.to_s
252
281
  end
253
282
 
254
283
  # Sets the mlc_leaves attribute.
255
284
  #
285
+ # @param [nil, #to_s] value the new attribute value
286
+ #
256
287
  def mlc_leaves=(value)
257
- @mlc_leaves = value && value.to_s
288
+ @mlc_leaves = value && value.to_s.strip
258
289
  end
259
290
 
260
291
  # Sets the total_control_points attribute.
261
292
  #
293
+ # @param [nil, #to_s] value the new attribute value
294
+ #
262
295
  def total_control_points=(value)
263
- @total_control_points = value && value.to_s
296
+ @total_control_points = value && value.to_s.strip
264
297
  end
265
298
 
266
299
  # Sets the control_pt_number attribute.
267
300
  #
301
+ # @param [nil, #to_s] value the new attribute value
302
+ #
268
303
  def control_pt_number=(value)
269
- @control_pt_number = value && value.to_s
304
+ @control_pt_number = value && value.to_s.strip
270
305
  end
271
306
 
272
307
  # Sets the mu_convention attribute.
273
308
  #
309
+ # @param [nil, #to_s] value the new attribute value
310
+ #
274
311
  def mu_convention=(value)
275
312
  @mu_convention = value && value.to_s
276
313
  end
277
314
 
278
315
  # Sets the monitor_units attribute.
279
316
  #
317
+ # @param [nil, #to_s] value the new attribute value
318
+ #
280
319
  def monitor_units=(value)
281
320
  @monitor_units = value && value.to_s
282
321
  end
283
322
 
284
323
  # Sets the wedge_position attribute.
285
324
  #
325
+ # @param [nil, #to_s] value the new attribute value
326
+ #
286
327
  def wedge_position=(value)
287
328
  @wedge_position = value && value.to_s
288
329
  end
289
330
 
290
331
  # Sets the energy attribute.
291
332
  #
333
+ # @param [nil, #to_s] value the new attribute value
334
+ #
292
335
  def energy=(value)
293
336
  @energy = value && value.to_s
294
337
  end
295
338
 
296
339
  # Sets the doserate attribute.
297
340
  #
341
+ # @param [nil, #to_s] value the new attribute value
342
+ #
298
343
  def doserate=(value)
299
- @doserate = value && value.to_s
344
+ @doserate = value && value.to_s.strip
300
345
  end
301
346
 
302
347
  # Sets the ssd attribute.
303
348
  #
349
+ # @param [nil, #to_s] value the new attribute value
350
+ #
304
351
  def ssd=(value)
305
352
  @ssd = value && value.to_s
306
353
  end
307
354
 
308
355
  # Sets the scale_convention attribute.
309
356
  #
357
+ # @param [nil, #to_s] value the new attribute value
358
+ #
310
359
  def scale_convention=(value)
311
360
  @scale_convention = value && value.to_s
312
361
  end
313
362
 
314
363
  # Sets the gantry_angle attribute.
315
364
  #
365
+ # @param [nil, #to_s] value the new attribute value
366
+ #
316
367
  def gantry_angle=(value)
317
- @gantry_angle = value && value.to_s
368
+ @gantry_angle = value && value.to_s.strip
318
369
  end
319
370
 
320
371
  # Sets the gantry_dir attribute.
321
372
  #
373
+ # @param [nil, #to_s] value the new attribute value
374
+ #
322
375
  def gantry_dir=(value)
323
376
  @gantry_dir = value && value.to_s
324
377
  end
325
378
 
326
379
  # Sets the collimator_angle attribute.
327
380
  #
381
+ # @param [nil, #to_s] value the new attribute value
382
+ #
328
383
  def collimator_angle=(value)
329
- @collimator_angle = value && value.to_s
384
+ @collimator_angle = value && value.to_s.strip
330
385
  end
331
386
 
332
387
  # Sets the collimator_dir attribute.
333
388
  #
389
+ # @param [nil, #to_s] value the new attribute value
390
+ #
334
391
  def collimator_dir=(value)
335
392
  @collimator_dir = value && value.to_s
336
393
  end
337
394
 
338
395
  # Sets the field_x_mode attribute.
339
396
  #
397
+ # @param [nil, #to_s] value the new attribute value
398
+ #
340
399
  def field_x_mode=(value)
341
400
  @field_x_mode = value && value.to_s
342
401
  end
343
402
 
344
403
  # Sets the field_x attribute.
345
404
  #
405
+ # @param [nil, #to_s] value the new attribute value
406
+ #
346
407
  def field_x=(value)
347
- @field_x = value && value.to_s
408
+ @field_x = value && value.to_s.strip
348
409
  end
349
410
 
350
411
  # Sets the collimator_x1 attribute.
351
412
  #
413
+ # @param [nil, #to_s] value the new attribute value
414
+ #
352
415
  def collimator_x1=(value)
353
- @collimator_x1 = value && value.to_s
416
+ @collimator_x1 = value && value.to_s.strip
354
417
  end
355
418
 
356
419
  # Sets the collimator_x2 attribute.
357
420
  #
421
+ # @param [nil, #to_s] value the new attribute value
422
+ #
358
423
  def collimator_x2=(value)
359
- @collimator_x2 = value && value.to_s
424
+ @collimator_x2 = value && value.to_s.strip
360
425
  end
361
426
 
362
427
  # Sets the field_y_mode attribute.
363
428
  #
429
+ # @param [nil, #to_s] value the new attribute value
430
+ #
364
431
  def field_y_mode=(value)
365
432
  @field_y_mode = value && value.to_s
366
433
  end
367
434
 
368
435
  # Sets the field_y attribute.
369
436
  #
437
+ # @param [nil, #to_s] value the new attribute value
438
+ #
370
439
  def field_y=(value)
371
- @field_y = value && value.to_s
440
+ @field_y = value && value.to_s.strip
372
441
  end
373
442
 
374
443
  # Sets the collimator_y1 attribute.
375
444
  #
445
+ # @param [nil, #to_s] value the new attribute value
446
+ #
376
447
  def collimator_y1=(value)
377
- @collimator_y1 = value && value.to_s
448
+ @collimator_y1 = value && value.to_s.strip
378
449
  end
379
450
 
380
451
  # Sets the collimator_y2 attribute.
381
452
  #
453
+ # @param [nil, #to_s] value the new attribute value
454
+ #
382
455
  def collimator_y2=(value)
383
- @collimator_y2 = value && value.to_s
456
+ @collimator_y2 = value && value.to_s.strip
384
457
  end
385
458
 
386
459
  # Sets the couch_vertical attribute.
387
460
  #
461
+ # @param [nil, #to_s] value the new attribute value
462
+ #
388
463
  def couch_vertical=(value)
389
- @couch_vertical = value && value.to_s
464
+ @couch_vertical = value && value.to_s.strip
390
465
  end
391
466
 
392
467
  # Sets the couch_lateral attribute.
393
468
  #
469
+ # @param [nil, #to_s] value the new attribute value
470
+ #
394
471
  def couch_lateral=(value)
395
- @couch_lateral = value && value.to_s
472
+ @couch_lateral = value && value.to_s.strip
396
473
  end
397
474
 
398
475
  # Sets the couch_longitudinal attribute.
399
476
  #
477
+ # @param [nil, #to_s] value the new attribute value
478
+ #
400
479
  def couch_longitudinal=(value)
401
- @couch_longitudinal = value && value.to_s
480
+ @couch_longitudinal = value && value.to_s.strip
402
481
  end
403
482
 
404
483
  # Sets the couch_angle attribute.
405
484
  #
485
+ # @param [nil, #to_s] value the new attribute value
486
+ #
406
487
  def couch_angle=(value)
407
- @couch_angle = value && value.to_s
488
+ @couch_angle = value && value.to_s.strip
408
489
  end
409
490
 
410
491
  # Sets the couch_dir attribute.
411
492
  #
493
+ # @param [nil, #to_s] value the new attribute value
494
+ #
412
495
  def couch_dir=(value)
413
496
  @couch_dir = value && value.to_s
414
497
  end
415
498
 
416
499
  # Sets the couch_pedestal attribute.
417
500
  #
501
+ # @param [nil, #to_s] value the new attribute value
502
+ #
418
503
  def couch_pedestal=(value)
419
- @couch_pedestal = value && value.to_s
504
+ @couch_pedestal = value && value.to_s.strip
420
505
  end
421
506
 
422
507
  # Sets the couch_ped_dir attribute.
423
508
  #
509
+ # @param [nil, #to_s] value the new attribute value
510
+ #
424
511
  def couch_ped_dir=(value)
425
512
  @couch_ped_dir = value && value.to_s
426
513
  end
@@ -429,7 +516,10 @@ module RTP
429
516
  private
430
517
 
431
518
 
432
- # Returns the attributes of this instance in an array (for comparison purposes).
519
+ # Collects the attributes of this instance.
520
+ #
521
+ # @note The CRC is not considered part of the attributes of interest and is excluded
522
+ # @return [Array<String>] an array of attributes
433
523
  #
434
524
  alias_method :state, :values
435
525