@@ -44,49 +44,50 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s
4444
4545 double sensitive_thickness = 0.1 * mm;
4646 Solid sensitive_solid;
47- Position disk_position;
47+ Transform3D disk_transform; // Full placement transform
4848
4949 // Check if we should use plane-based cross section (default: false, use cone)
5050 bool use_plane_xs = getAttrOrDefault<bool >(slice_coll, _Unicode (use_cross_section), false );
5151
5252 if (use_plane_xs) {
5353 // Use plane-based cross section
5454
55- // Get plane definition from XML (normal vector and distance from origin )
56- double plane_nx = getAttrOrDefault<double >(slice_coll, _Unicode (plane_nx ), 0.0 );
57- double plane_ny = getAttrOrDefault<double >(slice_coll, _Unicode (plane_ny ), 0.0 );
58- double plane_nz = getAttrOrDefault<double >(slice_coll, _Unicode (plane_nz ), 1 .0 );
59- double plane_d = getAttrOrDefault<double >(slice_coll, _Unicode (plane_d ), 0.0 );
55+ // Get plane definition from XML (in world frame )
56+ double plane_x = getAttrOrDefault<double >(slice_coll, _Unicode (plane_x ), 0.0 );
57+ double plane_y = getAttrOrDefault<double >(slice_coll, _Unicode (plane_y ), 0.0 );
58+ double plane_z = getAttrOrDefault<double >(slice_coll, _Unicode (plane_z ), 0 .0 );
59+ double plane_yrot = getAttrOrDefault<double >(slice_coll, _Unicode (plane_yrot ), 0.0 );
6060
61- // Normalize the plane normal vector
62- double norm = sqrt (plane_nx*plane_nx + plane_ny*plane_ny + plane_nz*plane_nz);
63- plane_nx /= norm;
64- plane_ny /= norm;
65- plane_nz /= norm;
61+ // Get the mother volume's transformation to world frame
62+ const auto & mother_matrix = mother.nominal ().worldTransformation ();
63+ const Double_t* translation = mother_matrix.GetTranslation ();
64+ const Double_t* rotation = mother_matrix.GetRotationMatrix ();
65+
66+ // Build Transform3D from TGeoMatrix
67+ Transform3D mother_to_world (
68+ rotation[0 ], rotation[1 ], rotation[2 ], translation[0 ],
69+ rotation[3 ], rotation[4 ], rotation[5 ], translation[1 ],
70+ rotation[6 ], rotation[7 ], rotation[8 ], translation[2 ]
71+ );
72+
73+ // Transform the plane position and rotation from world frame to mother's local frame
74+ Position plane_pos_world (plane_x, plane_y, plane_z);
75+ RotationY plane_rot_world (plane_yrot);
76+ Transform3D plane_transform_world (plane_rot_world, plane_pos_world);
77+
78+ // Apply inverse transformation to get plane in mother's local coordinates
79+ disk_transform = mother_to_world.Inverse () * plane_transform_world;
6680
6781 // Get maximum dimension for cutting box
6882 double max_dim = getAttrOrDefault<double >(slice_coll, _Unicode (max_dimension), 1.0 * m);
6983
7084 // Create a thin box perpendicular to the plane normal
7185 Box cutting_box (max_dim, max_dim, sensitive_thickness / 2 );
72-
73- // Calculate rotation to align box with plane normal
74- // Default box normal is along Z, rotate to align with plane normal
75- RotationZYX rotation;
76- if (fabs (plane_nz - 1.0 ) > 1e-6 || fabs (plane_nx) > 1e-6 || fabs (plane_ny) > 1e-6 ) {
77- // Calculate rotation angles to align Z-axis with plane normal
78- double theta = acos (plane_nz); // angle from Z axis
79- double phi = atan2 (plane_ny, plane_nx); // angle in XY plane
80- rotation = RotationZYX (0.0 , theta, phi);
81- }
82-
83- // Position the cutting plane at distance plane_d along the normal
84- Position plane_pos (plane_nx * plane_d, plane_ny * plane_d, plane_nz * plane_d);
85-
86- // Create intersection of mother volume with the cutting box
87- sensitive_solid = IntersectionSolid (mother_vol.solid (), cutting_box,
88- Transform3D (rotation, plane_pos));
89- disk_position = Position (0.0 , 0.0 , 0.0 );
86+
87+ // Create intersection of cutting box with mother volume (reversed order to preserve rotation)
88+ // Apply the inverse transform to the second operand (mother) to express it in the box frame
89+ sensitive_solid = IntersectionSolid (cutting_box, mother_vol.solid (), disk_transform.Inverse ());
90+
9091
9192 } else {
9293 // Use cone segment (default behavior)
@@ -106,24 +107,23 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s
106107 }
107108
108109 sensitive_solid = ConeSegment (sensitive_thickness / 2 , 0.0 , rOuter2, 0.0 , rEnd);
109- disk_position = Position (0.0 , 0.0 , zPos);
110+ disk_transform = Transform3D ( Rotation3D (), Position (0.0 , 0.0 , zPos) );
110111 }
111112
112113 Volume v_start_disk (" v_start_disk_" + motherName, sensitive_solid, m_Vacuum);
113114 v_start_disk.setSensitiveDetector (sens);
114115
115- auto disk_placement = mother_vol.placeVolume (v_start_disk, disk_position );
116+ auto disk_placement = mother_vol.placeVolume (v_start_disk, disk_transform );
116117 disk_placement.addPhysVolID (" end" , detStart);
117118 disk_placement.addPhysVolID (" pipe" , pipe_id);
118119 disk_placement.addPhysVolID (" system" , det_id);
119120
120- DetElement slice_element (sdet , slice_name, pipe_id);
121+ DetElement slice_element (mother , slice_name, pipe_id);
121122
122123 slice_element.setPlacement (disk_placement);
123- description.declareParent (slice_name, mother);
124124 }
125125
126- auto pv_assembly = description.worldVolume ().placeVolume (assembly, Position ( 0.0 , 0.0 , 0.0 ) );
126+ auto pv_assembly = description.worldVolume ().placeVolume (assembly);
127127 pv_assembly.addPhysVolID (" system" , det_id);
128128 sdet.setPlacement (pv_assembly);
129129
0 commit comments