Assembly Volume Rotation

Howdy,

I am building a detector that is made up of many of the same multipiece detector elements rotated about and stacked along the Z axis. The data that comes back has a periodic frequency to it that has to be related to the way it’s being generated.

The Z-step stacking is working as verified by G4cout of the Z position and the angles are correct in the same readout. However it seems the center of rotation might not be the centerline axis causing the elements to rotate out of then back into the beam. All the assembly elements are G4Box and set with a translate and rotation local to the assembly.

G4RotationMatrix *Ra = new G4RotationMatrix();
Ra->rotateX(0.* deg); Ra->rotateY(0.* deg); Ra->rotateZ(0.* deg);
G4ThreeVector Ta = G4ThreeVector(0., 0., 0.);
G4AssemblyVolume* assembly = new G4AssemblyVolume();
G4VSolid* solidGasGap = new G4Box("Gas Gap", 0.5 * SubstrateX, 0.5 * SubstrateY, 0.5 * GasGapZ);
G4LogicalVolume* logicGasGap = new G4LogicalVolume(solidGasGap, P10, "Gas Gap");
Ta.setZ(ElmS + (0.5 * GasGapZ));
assembly->AddPlacedVolume(logicGasGap, Ta, Ra); 

A new set of global translation and rotations are initialized for the placement.

G4RotationMatrix *Rm = new G4RotationMatrix();
Rm->rotateX(0.* deg); Rm->rotateY(0.* deg); Rm->rotateZ(0.* deg);
G4ThreeVector Tm = G4ThreeVector(0., 0., 0.);

This is what places the imprints of the assembly within the mother volume logicGas. There’s a set of switch statements that determine the angle about Z that is stored as rot. My first version of DetectorConstruction used a linear increase in rot which worked fine. However, that’s tomographically inefficient so I changed to a periodic stagger driven by the switch statement. The angles come back correct in the readback of rot but do not seem to be implemented as I desire.

Rm->rotateZ(rot);
G4int lay = ((r * sym) + e);
Tm.setZ(ElmC + (lay * ElmZ));
G4cout << lay << "-Z: " << Tm.getZ() + GasC << ", Ang: " << rot / deg << G4endl;
assembly->MakeImprint(logicGas, Tm, Rm);

Does anyone see what might cause the assembly volume to not rotate about the Z axis?

Thanks

Geant4 Version: geant4-11-02-patch-02
Operating System: Cluster Linux version 4.18.0-553.33.1.el8_10.x86_64
Compiler/Version: UNK
CMake Version: UNK


I still have no resolution to this issue. What is the default axis of alignment of a G4Tubs? Could I have the holder volume rotated the wrong way as the whole unit? The particle come in from a source on the -z and the detector should have an axis of rotation about z, do I need to define this axis for the logical that the imprint is made in?

// * Gas Volume
		G4Tubs *solidGas = new G4Tubs("Gas",
			GasR0, GasR1, 0.5 * GasZ, 0. * deg, 360.*deg);
		G4LogicalVolume* logicGas = new G4LogicalVolume(solidGas, P10, "Gas");
		new G4PVPlacement(0, G4ThreeVector(0., 0., GasC), logicGas, "Gas",
			logicEnv, false, 0, checkOverlaps);

where GasC is the offset to put the center of the volume properly compared to global (0, 0, 0).

This is hard to follow second hand. If you are curious about your geometry you should just use the UI interface to show it. What does it look like? If there are too many elements then only generate a representative sub set of them.

In case of complex transformations that contain both rotation and translation, I would recommend you to use G4PVPlacement with G4Transform3D instead of G4PVPlacement with G4RotationMatrix and G4ThreeVector. G4Transform3D can be constructed as sequence of simple transformations.

Running all of this on the cluster there is no visualization but I’ll try to get it working on a local copy that will to verify.

EVC:
Does G4Transform3D work with assemblies? All of the repetitive pieces are done via an assembly, just the gas holder volume is a G4PVPlacement.

Yes, G4Transform3D can be used for assemblies.

I did a direct replacement and it did not make a difference, the periodicity is still the interval of the stagger. However I did notice that I am defining the rotation as rotateZ everytime. This makes me suspicious that I’m indexing it by the amount not defining the rotation. I moved the initialization inside the loop so it defaults back to (0., 0., 0.) each time then defines rotateZ from that point based on the stagger. If this works I can make a switch/case structure that does this more elegantly but this was a cut and paste operation vs. a rewrite of the logic. Will update as results run.

Unfortunately that did not resolve the issue, the information is still coming in with the period aligned with the stagger. The angles in the readback continue to be exactly what I want them to be but across >300 active elements the hits are only every 4 which is not a statistical process.

// Rotational Element Placement
G4RotationMatrix Rm = G4RotationMatrix(0., 0., 0.);
G4ThreeVector Tm = G4ThreeVector(0., 0., 0.);
...
Rm.rotateZ(rot);
G4int lay = ((r * sym) + ceil(e / it));
Tm.setZ(ElmC + (lay * ElmZ));
G4cout << lay << "-Z: " << Tm.getZ() + GasC << ", Ang: " << rot/deg << G4endl;
G4Transform3D it_loc = G4Transform3D(Rm, Tm);
assembly->MakeImprint(logicGas, it_loc);

Well… The problem was the with analysis code, not GEANT4 though I did learn a lot about Euler angles and how GEANT4 places objects in the process. Basically I was double rearranging the data unnecessarily so a particle track would end up segmented vs. sequential.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.