KAHIBARO
Discord Login Register

25.3 Creating Detector Crystals

Crystal geometry and its role in PET

In a PET scanner, the detector ring is built from many small scintillator crystals. Each crystal acts as an individual detection element. In Geant4 you must model these crystals as repeated geometric volumes arranged around the ring, with unique identifiers so you can later tell which crystal recorded a hit and reconstruct lines of response.

The goal in this chapter is to focus on the crystal geometry itself, not on the full ring layout or physics. You define the shape and size of a single crystal, create a logical volume for it, and prepare it so that many identical copies can be placed in the ring in the next step.

Choosing crystal shape and size

Most PET scanners use long, narrow rectangular crystals. A simple and useful approximation is a box with cross section a few millimeters and length a few centimeters pointing toward the center of the ring. You can also model other cross sections, but the box is the easiest starting point and matches many commercial designs.

In Geant4 a box is created with G4Box, which takes half lengths as arguments. If the crystal is, for example, 4 mm wide, 4 mm thick, and 20 mm long, you define:

cpp
G4double crystalSizeX = 4.0*mm;   // transverse width
G4double crystalSizeY = 4.0*mm;   // transverse thickness
G4double crystalSizeZ = 20.0*mm;  // length along radial direction

The detector ring geometry, which you will define elsewhere, will usually place the long axis of the crystal to point radially inward. For now, you only need to fix a consistent convention. A common choice is to make the crystal long axis align with the local Z axis of the crystal volume.

In G4Box("name", xHalf, yHalf, zHalf) the arguments are half lengths. A 4 mm wide crystal must be created with 2.0mm as the half length, not 4.0mm.

Defining the crystal solid

Once you have chosen the crystal dimensions, you define a solid that represents the geometric shape. For a simple rectangular crystal:

cpp
G4double halfX = crystalSizeX/2.;
G4double halfY = crystalSizeY/2.;
G4double halfZ = crystalSizeZ/2.;
G4Box* crystalSolid =
  new G4Box("CrystalSolid", halfX, halfY, halfZ);

This solid has no material yet. It is a purely geometrical volume. Using a box keeps the geometry simple and efficient in the simulation. For more advanced PET designs, you could use other solids, for example trapezoids for tapered crystals or volumes with cuts for light guides, but for a beginner level example a single G4Box is sufficient.

If you expect to vary the crystal dimensions later, consider storing these sizes as member variables in your detector construction class so they can be changed in one place, and reused for placement, ring radius, and indexing.

Assigning the crystal material

The crystal must be made from a scintillator material. You will usually define this material in the materials chapter or in a dedicated materials section of your DetectorConstruction. In PET you often use materials such as LYSO or BGO. If you already defined a material, for example:

cpp
G4Material* lyso = G4Material::GetMaterial("LYSO");

you can use it for the crystal logical volume. If you have not defined it yet, you can temporarily use a placeholder like G4_NaI or another dense scintillator from the NIST manager, as long as you remember that the physics of light production and attenuation will depend on the final material choice.

The logical volume combines the solid shape with the material:

cpp
G4LogicalVolume* crystalLogic =
  new G4LogicalVolume(crystalSolid, lyso, "CrystalLogical");

At this point the crystal still does not exist in space. It is a template that you will later place many times in the PET ring. The same logical volume will be reused for all crystal instances, which is very efficient and fits the idea that all crystals in the ring are identical.

Every detector crystal instance should reuse the same logical volume. Do not create a new G4LogicalVolume per crystal copy, otherwise you waste memory and complicate sensitive detector assignment and visualization.

Preparing crystals for replication

In the PET detector ring, you will have many crystals. They can be arranged in one ring layer or in multiple rings axially. The standard Geant4 approach is:

  1. Create a single crystal logical volume.
  2. Create a higher level volume that holds an array of crystals, for example a module or a ring segment.
  3. Place many physical crystals inside that higher level volume using repeated placement.

The repeated placement can be done in several ways, which are covered more in the chapter about detector arrays and repeated geometry. Here, you only need to set up the crystal logical volume so that it is compatible with those methods.

A typical structure is:

cpp
// 1. Define crystalSolid and crystalLogic (already done above).
// 2. Later: define a "module" logical volume to host an array
// of crystals, or directly place crystals into the PET ring volume.
// 3. Use replicas, a parameterisation, or multiple placements
// to build the array.

If you already know you will use a parameterised placement for crystals around the ring, you do not have to change anything in the crystal definition. Parameterisation operates at the placement step, not at the solid or logical volume step.

Visual and identification attributes

To debug and interpret your PET geometry, it is useful to give the crystal logical volume a distinctive appearance in the visualisation and prepare it to be uniquely identifiable.

You can set visual attributes so crystals can be seen clearly:

cpp
auto crystalVis = new G4VisAttributes(G4Colour(0.0, 0.8, 0.8));
crystalVis->SetForceSolid(true);
crystalLogic->SetVisAttributes(crystalVis);

This makes each crystal appear as a solid cyan block when you draw the geometry.

For identification at the data level, each physical crystal placement will later receive a unique copy number, usually used as a detector ID. You do not set this in the crystal logical volume itself. Instead, you will assign copy numbers when placing the crystals or in a parameterisation class. The crystal logical volume simply must exist and be reused consistently so that all hits can be associated with this detector type and then distinguished by copy number.

A copy number is assigned to each physical placement, not to the logical volume. The same crystalLogic is used for all crystals, and their copy numbers let you distinguish individual detector elements.

Integration with the detector ring

Although the construction of the full PET detector ring is handled in the next chapter, it is useful to keep in mind how the crystal definition will be used. The key points are:

You define a single crystal solid and logical volume.

You choose a length that matches your desired radial thickness and a cross section that fits your ring radius and number of crystals.

You reuse this logical volume in many placements, arranged around the ring circumference and possibly along the scanner axis.

Because of this, the design of the crystal dimensions affects ring layout, spatial resolution, and the total number of channels. For a beginner example, pick dimensions that give a small but manageable number of crystals, for example 32 or 64 per ring, to keep later analysis simple.

With a well defined crystal logical volume in place, you can now proceed to construct the PET detector ring, assign detector IDs to the crystals, and connect them to sensitive detectors to record hits for coincidence detection.

Views: 9

Comments

Please login to add a comment.

Don't have an account? Register now!