Creating a spherical-shell detector

Hi William,

Let me know if these code snippets are too limited, I can provide more. I had implemented a class SphericalParameterisation which is derived from G4VPVParameterisation. Here is the header File:

class SphericalParameterisation : public G4VPVParameterisation {
public:
// Constructor
SphericalParameterisation(const G4double startRadius, const G4double incRadius, const G4double stepRad, const G4double thetaSpread);
// Destructor
virtual ~SphericalParameterisation();
// Methods
virtual void ComputeDimensions(G4Sphere& sphere, const G4int copyNo, const G4VPhysicalVolume*) const;
private:
void ComputeTransformation(const G4int, G4VPhysicalVolume*) const {};
//Private variables of your choice below
}

Actual implementation (the only non trivial bit is the ComputeDimensions). Which takes CopyNo that iterates through zero to a number of your choosing and then uniquely determines the radius, theta, and phi. The various undefined variables you see below are internal to the class and passed in through the constructor:

void SphericalParameterisation::ComputeDimensions(G4Sphere& sphere, const G4int copyNo, const G4VPhysicalVolume*) const
{
radno = (G4int)(copyNo/steptheta);
thetano = (G4int)(copyNo-radno * steptheta);

sphere.SetInnerRadius((radno) * incradius+startradius);
sphere.SetOuterRadius(((radno+1) * incradius+startradius-0.01 * mm));
sphere.SetStartPhiAngle(0*deg);
sphere.SetDeltaPhiAngle(360 * deg);
sphere.SetStartThetaAngle(thetano * thetaspread);
sphere.SetDeltaThetaAngle((thetaspread * 0.90));
}

Then in a Parallel or Physical world you will define a logical volume sphere and pass it to G4PVParameterised.

SphericalParameterisation* param = new SphericalParameterisation(input arguments here…);

G4PVParameterised* sphericalscoring_shell = new G4PVParameterised(“sphericalscoring_shell”, SphericalScoring_log, worldLogicalS, kZAxis, numberofvoxels, param);

After this you create a sensitive detector using standard methods and associate the logical volume with the scoring sphere:

SphericalScoring_log->SetSensitiveDetector(Sphere_MultiFunctionalDetector);

Lastly you need to implement your own scorer. The scorer can get the copy number by finding the “RepilicaNumber” of your sphere. You can then add the dose to an array of your choice, and you will know which part of the sphere the energy was deposited in based on the copy number.

G4int index = ((G4TouchableHistory*)(aStep->GetPreStepPoint()->GetTouchable()))->GetReplicaNumber(0);

I know what I’ve described here is fairly long and involved, and you also expressed a desire not to create your own scorer. Still I hope this is helpful.

Joseph