Differentiating Events in Physical Volumes

I must be missing something fundamental about using sensitive detectors and EventAction with the GDML detector definition because I seem to have to work really hard for to accomplish something that seems perfectly natural.

I have a modular detector structure defined with several levels of nested volumes. each module has many sensors. And, for example, I want to record the energies of x-rays deposited in one sensor in one module of the detector. So I define SensorSolid, SensorVolume and then place multiple SensorPhysicalVolumes in the into the ModuleVolume.

I am identifying the sensitive detector as in the GDML example like this:

<volume name="Sensor_Large_vol">
     <materialref ref="Sensor_Material"/>
      <solidref ref="Sensor_Large_sol"/>
      <auxiliary auxtype="SensDet" auxvalue="Tracker"/>
      <auxiliary auxtype="Color" auxvalue="red"/>
</volume>

Since the <auxilliary> info is attached to the volume I cannot figure out how to designate that only one of the physical volumes should produce hit events. All the examples I can find show designating a Volume for monitoring, so I end up getting events for all the physical volumes of the same volume type.

My horrible work-around is to define a duplicate volume type with the dose monitoring enabled (SensorVolumeMonitored) and use that to create the unique PhysicalVolume. The problem is that I then need to make a unique version of the module that contains the sensor. And given that the actual design has several levels of modularity, I end up needing a whole cascade of duplicated Volume definitions.

This seems like it must be a very common use case. So I am wondering if there is a better way to handle this.

Help is appreciated!
Brian

SDs are attached to logical volumes, not physical volumes. That’s probably the source of your confusion. In your SD code, you can distinguish the different physical volumes by copy number, making whichever one(s) you want to be the one(s) recording hits. Or you can record all hits in your output, including the copy number, and filter in your analysis after the job.

Yes, I understand that SD’s are connected to logical volumes, and I suppose it is easier that way for the baseline case when you want all placements of the logical volume to be sensitive. I wish there was an analogous method to designate individual PhysicalVolumes as SD’s. I’ll try the method of identifying them by copy number.

By the way, is the copy number attribute is mentioned in the GDML format documentation? I did not see it mentioned anywhere.

You wrote, “is the copy number attribute is mentioned in the GDML format documentation? I did not see it mentioned anywhere.”

It should be. It’s an attribute of physical (placement) volumes, not LVs. I don’t use GDML; in the code, you can specify the copy number explicitly as an argument to G4PVPlacement(), or you get it automatically if you’re using a replicated volume.

If I have 2 copies of Sensor inside each Module, and I have 2 copies of Module, then I have a total of 4 Sensors. Does each Sensor have a distinct instance ID?

For example:

G4int instanceId = touchable_handle->GetVolume()->GetInstanceID();
G4int copyNum = touchable_handle->GetCopyNumber()

Do I need to keep track of the copyNum to differentiate different Sensor PVs? Or is the instanceId of all 4 copies different?

I found this exchange from a month ago that describes my problem and a suggested solution:

I was hoping that the instanceID was a unique way to identify a PV. My approach was check the chain of copy numbers the first time each PV is encountered in my UserSteppingAction() and to store the instanceID as the key in a map for easy checking of future events.

Unfortunately, it seems each PV does not get a unique ID. In fact it seems the PV instances are not stored individually by GEANT4. So it is necessary to follow the stack of nested volumes by using (for example) touchable_handle->GetVolume(stack_level) and checking the copy number of all the parent volumes

I will shift any further discussion over to the previous thread.