@@ -104,7 +104,7 @@ def __init__(self, name):
104104 # optional fields
105105 self .mother = DEFAULTMOTHER
106106 self .position = '0*mm, 0*mm, 0*mm'
107- self .rotations = ['0*deg, 0*deg, 0*deg' ]
107+ self .rotations = [] # list of "x, y, z" triples; empty means identity
108108 self .g4placement_type = 'active'
109109 self .mfield = None
110110
@@ -132,9 +132,9 @@ def set_rotation(self, x, y, z, lunit='deg', order=''):
132132 ]
133133 string_with_units = ", " .join (with_units )
134134 if order :
135- self .rotations = f"ordered: { order } , { string_with_units } "
135+ self .rotations = [ f"ordered: { order } , { string_with_units } " ]
136136 else :
137- self .rotations = string_with_units
137+ self .rotations = [ string_with_units ]
138138
139139 def set_position (self , x , y , z , lunit = 'mm' ):
140140 myposition = str (x ) + '*' + lunit + ', '
@@ -146,13 +146,26 @@ def add_rotation(self, x, y, z, lunit='deg'):
146146 myrotation = str (x ) + '*' + lunit + ', '
147147 myrotation += str (y ) + '*' + lunit + ', '
148148 myrotation += str (z ) + '*' + lunit
149- self .rotations .append (' + ' + myrotation )
149+ self .rotations .append (myrotation )
150150
151151 def get_rotation_string (self ):
152- rotation_string = ''
153- for r in self .rotations :
154- rotation_string = rotation_string + r
155- return rotation_string
152+ # self.rotations is a list of clean "x, y, z" triples. Emit a form that
153+ # gemc's parser (G4ObjectsFactory::getRotation) actually understands:
154+ # the identity when empty, the single triple for one rotation, and the
155+ # doubleRotation: form for two. gemc has no syntax for three or more, so
156+ # fail loudly instead of silently producing an unrotated volume.
157+ # Tolerate an already-flattened string (publish flattens in place).
158+ if isinstance (self .rotations , str ):
159+ return self .rotations
160+ if not self .rotations :
161+ return '0*deg, 0*deg, 0*deg'
162+ if len (self .rotations ) == 1 :
163+ return self .rotations [0 ]
164+ if len (self .rotations ) == 2 :
165+ return f"doubleRotation: { self .rotations [0 ]} , { self .rotations [1 ]} "
166+ sys .exit (
167+ f" Error: GVolume '{ self .name } ' has { len (self .rotations )} rotations; "
168+ "gemc supports at most two (doubleRotation:)." )
156169
157170 def check_validity (self ):
158171 # need to add checking if it's operation instead
@@ -226,7 +239,7 @@ def publish(self, configuration):
226239
227240 elif configuration .factory == 'sqlite' :
228241 configuration .nvolumes += 1
229- self .rotations = rotation_string
242+ # populate_sqlite_geometry flattens self.rotations to a string before insert
230243 orig_color = self .color
231244 self .color = self .gcolor # publish hex into DB 'color' column
232245 populate_sqlite_geometry (self , configuration )
@@ -769,7 +782,8 @@ def distribute_on_circle(self, n, radius, phistart=0, phispan=360,
769782 if any (existing .startswith (kw ) for kw in ("ordered:" , "doubleRotation:" )):
770783 v .set_rotation (* align_xyz , lunit = aunit )
771784 else :
772- v .rotations = f"doubleRotation: { existing } , { align_str } "
785+ # Keep the list invariant: two triples render as doubleRotation:.
786+ v .rotations = [existing , align_str ]
773787
774788 copies .append (v )
775789
0 commit comments