see the source code below …
TGeoMedium *med = (TGeoMedium *)gGeoManager->GetListOfMedia()->FindObject("Stink");
TGeoMaterial *mat = (TGeoMaterial *)gGeoManager->GetListOfMaterials()->FindObject("Odour");
if (!mat) mat = new TGeoMaterial("Odour", 0.0, 0.0, 0.0);
// FIXME! How can I find a NEW unique Id for my "med"?
// Two cases are possible:
// 1. I created a NEW material "mat" above
// 2. I am reusing an OLD material "mat", which can,
// in principle, be also already used by another medium
// Hence, I cannot rely on the "mat->GetIndex()" value,
// as this value is possibly already used by some medium.
// Should I "scan" all "med->GetId()" and set "max_Id + 1"?
Int_t medUniqueId = 0;
med = new TGeoMedium("Stink", medUniqueId, mat);
A pitiful case, am I not?
Pepe Le Pew.
Is there something fishy about it?
Well, there are many ways to go about it. If you don’t need to keep track of which media gets which id but you only want to give them consecutive different id’s, you could:
Int_t idmed = 0;
// Whenever creating a new media:
med = new TGeoMedium("perfume", idmed++, mat);
// If defining media in many different methods
Int_t lastmed = gGeoManager->GetListOfMedia()->GetSize();
med = new TGeoMedium("bouquet", lastmed, mat);
You can pick the one that smells best
many thanks for your reply.
My problem is more complex, I’m afraid.
I need to modify an existing “disk-resident” geometry, which creation I do not control.
So, in principle I cannot assume anything about already existing “TGeoMedium unique Ids”.
There is no guarantee that the “lastmed” value is not already used (and in fact I know it is).
Moreover, I cannot assume that the highest “unique Id” is assigned to the last existing TGeoMedium, as ROOT does not seem to set any constraints on this value. There doesn’t seem to exist any constraint that they must differ by 1 or keep an ascending order of values. Can they be negative and/or 0, or do they need to be positive values?
This is supposed to be a “general purpose” routine, which is not my-current-geometry specific.
I really need to make sure that I set a completely new “unique Id”, which is not already used by any of the already existing media.
Is there any “canonical” way to do this?
A pitiful case, am I not?
Pepe Le Pew.
OK, I see. The medium id is unfortunately (for you) completely under user control, so even 2 identical numbers are allowed. I am afraid that to complete this task you will have to some massage to the id’s (e.g. loop them and find the max). Then you assign new id’s starting from the max. No canonical approach.
Could you, please, tell me what’s the purpose of the “unique Id”?
How is it used (or can potentially be used) in ROOT and/or GEANT?
What happens (or can potentially happen) if there are 2 media with identical numbers?
The id is indeed unique when creating the geometry via the VMC interface. If the geometry is defined in root but used with GEANT (via TGeant3TGeo or TGeant4), the media ID’s are OVERWRITTEN via SetId() so they stay consecutive. So with GEANT this data member is just a placeholder for the MC to store its ID’s.
Let me get it right.
You are saying that ROOT (including it’s geometry package) does not bother about the “unique Id” at all.
It’s the VMC which will use it, but it will anyhow automatically re-numerate all existing media in advance.
That means that I can set anything, nothing bad will ever happen due to any “non-unique Id”.
I was wondering, is there any function/method (in ROOT itself) which the user can call on demand in order to perform the re-numeration manually (which would mimic the VMC behavior)?
BTW. I think it might be a good idea to add all these notes to the TGeoMedium class description.
Sure, you can just iterate on the defined media and call TGeoMedium::SetId(crt++) starting from 0. This is not documented as people never hit any problem due to the media ID. I will add a note in the class.
That means that the “unique Id” is supposed to be exactly equal to the position number in the list returned by “gGeoManager->GetListOfMedia()” (i.e. from 0 to “gGeoManager->GetListOfMedia()->GetSize() - 1”).
One more question, if I do not use VMC, will ROOT modify my non-unique setting at any occasion, or will it stay no matter what I do in ROOT?
What I’m thinking about is that it may be that the user sets his own private unique numbers which he wants to keep (for any reasons). Can one guarantee that ROOT will not modify them (outside of VMC)?
Yes, these numbers are not touched outside VMC, so one can rely on them.
Thanks for the discussion.
Added the comments to TGeoMedium in trunk.
How about one more change …
In the TGeoMedium.h … change “// unique Id” into “// a user defined value will be overwritten with a unique Id by the VMC”.
Then it will be clear that the user does NOT need to care about this value at all, but if he does he should remember that it may get overwritten.