Nesting calorimeters not working

Please fill out the following information to help in answering your question, and also see tips for posting code snippets. If you don’t provide this information it will take more time to help with your problem!

Geant4 Version: geant4-11-02-patch-01 [MT]
Operating System: Debian11
Compiler/Version:
CMake Version:


Hello Geant4 experts,
I have a probably rather simple question regarding my geometry set up. In my simulation I want to have a combination of a hadronic and electromagnetic calorimeter. It is a fixed target experiment and thus the HCal and ECal are placed downstream of the target as two rectangles. The HCal is supposed to wrap around the ECal. Meaning in the center of the HCal the ECal is placed. Additionally a slit for the beam is cut into both detectors. Now if I define my detectors in the following way:

// hcal parameters
  G4double thickSi = 0.5*cm;
  G4double thickAbHCal = 2*cm;
  G4double numlayersHCal = 145;  
  G4double lengthXhcal = 250*cm;
  G4double lengthYhcal = 270*cm;
  G4Material* absorberHCal = nist->FindOrBuildMaterial("G4_Fe");
  G4double thickhcal = numlayersHCal*(thickSi+thickAbHCal);
  G4ThreeVector calorimeterPos = G4ThreeVector(0., 0., 350*cm+thickhcal/2);

// ecal parameters
  G4double thickAb = 2*cm;
  G4double numlayers = 30; 
  G4double lengthX = 47*cm;
  G4double lengthY = 47*cm;
  G4Material* absorber = nist->FindOrBuildMaterial("G4_W");
  G4double thickecal = numlayers*(thickSi+thickAb);
  G4ThreeVector calorimeterPos2 = G4ThreeVector(0., 0., 350*cm+thickecal/2);//387.5*cm);
 
  G4ThreeVector holePosition(0., 0., 0.);
  // HCal detector Box
  G4Box* hcalDetectorBox = new G4Box("HcalDetectorBox", lengthXhcal/2, lengthYhcal/2, thickhcal/2);
  G4Box* ecalDetectorBox = new G4Box("EcalDetectorBox", lengthX/2, lengthY/2, thickecal/2);
  G4VSolid* hcalDetectorBoxWithHole = new G4SubtractionSolid("hcalDetectorBoxWithHole", hcalDetectorBox, ecalDetectorBox, 0, holePosition);

  G4LogicalVolume* hcalDetectorLogical = new G4LogicalVolume(hcalDetectorBoxWithHole, air, "hcalDetectorLogical");
  new G4PVPlacement(nullptr, calorimeterPos, hcalDetectorLogical, "hcalDetectorPhysical", worldLogical, false, 0, false);

//   Layers inside HCal
  G4Box* layers = new G4Box("Layer", lengthXhcal/2, lengthYhcal/2, thickSi+thickAbHCal);
  G4LogicalVolume* layerLogical = new G4LogicalVolume(layers, air, "Layer");
  
  G4double holeX = 48*cm;
  G4double holeY = 48*cm;
  G4double slitX = 125*cm; // needs to be half of the width of the hcal, as it only covers one side
  G4double slitY = 10*cm;
  G4ThreeVector hole2Position(lengthXhcal/4, 0., 0.);

//   Absorber per layer  
  G4Box* AbsorberBoxHCal = new G4Box("AbsorberBoxHCal", lengthXhcal/2, lengthYhcal/2 , thickAbHCal/2);
  G4Box* HoleBoxAbsorber = new G4Box("HoleBoxAbsorber", holeX/2, holeY/2, thickAbHCal/2);
  G4Box* Hole2BoxAbsorber = new G4Box("Hole2BoxAbsorber", slitX/2, slitY/2, thickAbHCal/2);
  G4VSolid* AbsorberBoxHCalWithHole = new G4SubtractionSolid("AbsorberBoxHCalWithHole", AbsorberBoxHCal, HoleBoxAbsorber, 0, holePosition);
  G4VSolid* AbsorberBoxHCalWithHoles = new G4SubtractionSolid("AbsorberBoxHCalWithHoles", AbsorberBoxHCalWithHole, Hole2BoxAbsorber, 0, hole2Position);
  G4LogicalVolume* AbsorberLogicalHCal = new G4LogicalVolume(AbsorberBoxHCalWithHoles, absorberHCal, "AbsorberLogicalHCal");
  new G4PVPlacement(nullptr, G4ThreeVector(0., 0., -thickAbHCal/2), AbsorberLogicalHCal, "AbsorberHCalPhysical", layerLogical, false, 0, false); 
//   Si per layer
  G4Box* SiBoxHCal = new G4Box("SiBoxHCal", lengthXhcal/2, lengthYhcal/2 , thickSi/2);
  G4Box* HoleBoxSi = new G4Box("HoleBoxSi", holeX/2, holeY/2, thickSi/2);
  G4Box* Hole2BoxSi = new G4Box("Hole2BoxSi", slitX/2, slitY/2, thickSi/2);
  G4VSolid* SiBoxHCalWithHole = new G4SubtractionSolid("SiBoxHCalWithHole", SiBoxHCal, HoleBoxSi, 0, holePosition);
  G4VSolid* SiBoxHCalWithHoles = new G4SubtractionSolid("SiBoxHCalWithHoles", SiBoxHCalWithHole, Hole2BoxSi, 0, hole2Position);
  G4LogicalVolume* SiLogicalHCal = new G4LogicalVolume(SiBoxHCalWithHoles, silicon, "SiLogicalHCal");
  new G4PVPlacement(nullptr, G4ThreeVector(0., thickSi/2), SiLogicalHCal, "SiHCalPhysical", layerLogical, false, 0, false); 

  new G4PVReplica("Layer", layerLogical, hcalDetectorLogical, kZAxis, numlayersHCal, thickSi+thickAbHCal);

  // ECal detector box
  //G4Box* ecalDetectorBox = new G4Box("EcalDetectorBox", lengthX/2, lengthY/2, thickecal/2); // defined this above for creating hole in hcal
  G4LogicalVolume* ecalDetectorLogical = new G4LogicalVolume(ecalDetectorBox, air, "ecalDetectorLogical");
  G4PVPlacement* ecalDetectorBoxPhysical = new G4PVPlacement(nullptr, calorimeterPos2, ecalDetectorLogical, "ecalDetectorPhysical", worldLogical, false, 0, true);

  // Layers
  G4Box* layersECal = new G4Box("LayerECal", lengthX/2, lengthY/2, thickSi+thickAb);
  G4LogicalVolume* layerECalLogical = new G4LogicalVolume(layersECal, air, "LayerECal");
  
  // Definition position hole
  G4ThreeVector holeEcalPosition(lengthX/4, 0., 0.);
  G4double slitecalX = 47*cm/2;
  // Absorber per layer
  G4Box* AbsorberBox = new G4Box("AbsorberBox", lengthX/2, lengthY/2 , thickAb/2);
  G4Box* HoleEcalBoxAbsorber = new G4Box("Hole2BoxAbsorber", slitecalX/2, slitY/2, thickAb/2);
  G4VSolid* AbsorberBoxECalWithHole = new G4SubtractionSolid("AbsorberBoxECalWithHole", AbsorberBox, HoleEcalBoxAbsorber, 0, holeEcalPosition);
  G4LogicalVolume* AbsorberLogical = new G4LogicalVolume(AbsorberBox, absorber, "AbsorberLogical");
  G4PVPlacement* AbsorberPhysical = new G4PVPlacement(nullptr, G4ThreeVector(0., 0., -thickAb/2), AbsorberLogical, "AbsorberPhysical", layerECalLogical, false, 0, false);

  // Si per layer
  G4Box* SiBox = new G4Box("SiBox", lengthX/2, lengthY/2 , thickSi/2);
  G4Box* HoleEcalBoxSi = new G4Box("Hole2BoxSi", slitecalX/2, slitY/2, thickSi/2);
  G4VSolid* SiBoxECalWithHole = new G4SubtractionSolid("SiBoxECalWithHole", SiBox, HoleEcalBoxSi, 0, holeEcalPosition);
  G4LogicalVolume* SiLogical = new G4LogicalVolume(SiBox, silicon, "SiLogical");
  G4PVPlacement* SiPhysical = new G4PVPlacement(nullptr, G4ThreeVector(0., 0., thickSi/2), SiLogical, "SiPhysical", layerECalLogical, false, 0, false);

  new G4PVReplica("LayerECal", layerECalLogical, ecalDetectorLogical, kZAxis, numlayers, thickSi+thickAb);

I get a error message that the ECal and HCal physical volumes are overlapping. Up to now I have not been able to find, why it is that they overlap. One idea is that the boolean SubtractionSolid operation creates the holes, but they are still seen as part of the detector volume and thus overlap with the ECal once I place it. The detector set up works fine, if I move the ECal in the z-direction further upstream for example.

So I wonder if I need to do something different when defining the detectors. One option would be to create the HCal out of 4 rectangles such that the hole for the ECal and the slit are taken into account.
I would be very happy for any kind of help with this issue!
Kind regards,
Laney Klipphahn

ECal is placed in the middle of HCal. Thus, the positions of ECal an HCal in the worldLogical should be exactly the same.

Try to comment the lines with G4PVReplica and draw your setup, you will see the problem.

Thank you for your quick answer! I just want to make sure I understand the geometry here. Since I want the front of the ECal and HCal to be at the same spot, I thought I would have to place them in the world volume such that their different lengths would be taken into account. So if I place an object that is 5m long and an object that is 1m long, for them to start at 0m both, I would place the 5m long object at -2.5m and it would extend from -5m to 0m. And the 1m long object I would place at -0.5m such that it extends from -1m to 0m.

In the case of my two detectors I thought I would have to do the same. However with your suggestion (placing them both at the exact same position in the world volume) the overlapping issue is gone, hence the ECal is placed in the dedicated hole in the HCal.
Why do I now have to not take the different lengths of the ECal and HCal into account when placing it in the world volume? I bet I am missing something very obvious…

Thanks again!
Cheers Laney Klipphahn

When we speak about transformation of an object, we mean the position of its local coordinate system (origin and axes) in another coordinate system. The object can have any shape and dimensions, but we only care about its origin and axes.

Second parameter in G4PVPlacement is the position of the volume’s origin in the mother volume.

In your case, the origins of HCal and ECal are placed in the same point in the world volume.

Thanks for the answer, I think I get it now.:slight_smile: