rtp-connect 1.1 → 1.2

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