| Summary: | G4BestUnit in HepRepXML output makes cuts on kinetic energy impossible | ||
|---|---|---|---|
| Product: | Geant4 | Reporter: | Sven Menke <menke> |
| Component: | visualization/HepRep | Assignee: | perl |
| Status: | RESOLVED WONTFIX | ||
| Severity: | minor | CC: | John.Allison, laurent.garnier |
| Priority: | P4 | ||
| Version: | 10.4 | ||
| Hardware: | All | ||
| OS: | All | ||
Hi Sven
I thought you would appreciate a quick response. I have by no means fully understood the issues.
We have a problem. The author of HepRepXML is no longer a member of the Collaboration and apart from fixing a few compilation warnings the code has not been touched for years. As a jas3 user, would you be interested in bringing it up to date?
As I see it, the problem is not in G4BestUnit but in G4HepRepSceneHandler::addAttVals. If you add a couple of lines to print the "value" of the attribute:
for (vector<G4AttValue>::iterator attValIterator = attValues->begin(); attValIterator != attValues->end(); attValIterator++) {
G4String name = attValIterator->GetName();
G4String value = attValIterator->GetValue();
G4cout << "name,\"value\": " << name << ",\"" << value << "\"" << G4endl;
you will see that when appropriate it contains the unit (see list for a single trajectory below). For example, for IKE the value is "100 GeV". G4HepRepSceneHandler::addAttVals does not take advantage of this, except to attempt to code up units for the "Pos" (position) attribute. So (a) it should use the "value" in its entirety and pass it on to Jas3 and (b) it should avoid the special case for "Pos". I think the author did not fully understand how units were incorporated into "value". (It's curious that IMom slipped through.)
The author seems have programmed special cases. It is meant to be generic as far as the scene handler is concerned; it's job is to pass attributes - whatever the attribute (the user may add some) - via the output file to the browser, where they can be interpreted.
Hope this helps. I will dig around a little and try to find where
<attvalue name="IKE" type="double" value="926.12"/>
is written. It should be
<attvalue name="IKE" type="double" value="926.12 MeV"/>
or whatever. The information is there.
John
G4VIS > name,"value": ID,"1"
G4VIS > name,"value": PID,"0"
G4VIS > name,"value": PN,"geantino"
G4VIS > name,"value": Ch,"0"
G4VIS > name,"value": PDG,"0"
G4VIS > name,"value": IKE,"100 GeV"
G4VIS > name,"value": IMom,"0 100 0 GeV"
G4VIS > name,"value": IMag,"100 GeV"
G4VIS > name,"value": NTP,"2"
G4VIS > name,"value": IVPath,"universe_P:0"
G4VIS > name,"value": INVPath,"universe_P:0"
G4VIS > name,"value": CPN,"None"
G4VIS > name,"value": CPTN,"None"
G4VIS > name,"value": CMID,"None"
G4VIS > name,"value": CMN,"None"
G4VIS > name,"value": FVPath,"universe_P:0"
G4VIS > name,"value": FNVPath,"None"
G4VIS > name,"value": EPN,"Transportation"
G4VIS > name,"value": EPTN,"Transportation"
G4VIS > name,"value": FKE,"100 GeV"
G4VIS > name,"value": ID,"1"
G4VIS > name,"value": PID,"0"
G4VIS > name,"value": PN,"geantino"
G4VIS > name,"value": Ch,"0"
G4VIS > name,"value": PDG,"0"
G4VIS > name,"value": IKE,"100 GeV"
G4VIS > name,"value": IMom,"0 100 0 GeV"
G4VIS > name,"value": IMag,"100 GeV"
G4VIS > name,"value": NTP,"2"
G4VIS > name,"value": IVPath,"universe_P:0"
G4VIS > name,"value": INVPath,"universe_P:0"
G4VIS > name,"value": CPN,"None"
G4VIS > name,"value": CPTN,"None"
G4VIS > name,"value": CMID,"None"
G4VIS > name,"value": CMN,"None"
G4VIS > name,"value": FVPath,"universe_P:0"
G4VIS > name,"value": FNVPath,"None"
G4VIS > name,"value": EPN,"Transportation"
G4VIS > name,"value": EPTN,"Transportation"
G4VIS > name,"value": FKE,"100 GeV"
Hi John, yes, the issue is not in G4BestUnit itself but in the way it is converted to the HepRepXML output in G4HepRepSceneHandler.cc. The IMom case is working because for the type G4ThreeVector the value is rendered as string. For the scalars the output is rendered as a double and this does not allow to be replaced by a string ... There are two obvious solutions that unfortunately have both a caveat and that's why I did not offer a patch: a) in G4HepRepSceneHandler::addAttributes IKE is added explicitly as having type G4String and then in G4HepRepSceneHandler::addAttVals one adds a special case for G4BestUnit and type G4double to just write out the value string. This is why IMom is working already because G4ThreeVector is just treated as string ... b) add an attribute in Trajectory that is G4double and uses "MeV" instead of G4BestUnit I've actually implemented both and here come the caveats: a) now you can pick IKE in the viewer and see the unit - but you can not cut on it. It is for jas3 now a string (like IMom) and you can look at it but there is no way to cut ... b) this allows now to cut on IKE in jas3 and always has a fixed unit - but it is ugly since we have to change the original attributes in the Trajectory and it is certainly nice if those come with a best unit (for picking, printing, etc.) So I don't really like b) but can offer a) as a patch - but it would not solve my original problem of wanting to cut on IKE ... Unfortunately I don't have time to also dig into the jas3/Wired code in order to make that happen, but from the Geant4 HepRepXML side I guess a) is o.k. and I can live with patching my Geant4 installation such that I also have IKE with a fixed unit ... Cheers, --Sven Hi Sven
Apologies for taking so long to respond. I have been thinking about it. And as I see you have a workaround, I did not give it top priority.
I am reluctant to change the behaviour of the HepRepXML driver, for which we have no real resources to maintain. Much lees to add more "special cases". I am also reluctant to patch G4Trajectory. But what you can do is write your own trajectory and add a new attribute, IKEMeV, say, that is a "G4double". Then instantiate it in YourTrackingAction::PreUserTrackingAction(). This is described in the Application Developers Guide (Book for Application Developers as it now seems have become), Tracking and Physics/Tracking/Trajectory and Trajectory Point/Customizing trajectory and trajectory point. See examples/extended//runAndEvent/RE01.
YourTrajectory could be derived from G4Trajectory and inherit most methods. In
const std::map<G4String,G4AttDef>* YourTrajectory::GetAttDefs() const
{
G4bool isNew;
std::map<G4String,G4AttDef>* store
= G4AttDefStore::GetInstance("G4RichTrajectory",isNew);
if (isNew) {
// Get att defs from base class...
*store = *(G4Trajectory::GetAttDefs());
// Then add IKEMeV
...
Similarly in
std::vector<G4AttValue>* G4RichTrajectory::CreateAttValues() const
{
// Create base class att values...
std::vector<G4AttValue>* values = G4Trajectory::CreateAttValues();
// Then add IKEMeV
...
You could look at G4RichTrajectory to see how a class inherits G4Trajectory but yours would be much simpler because you are not adding any new data member.
Let me know if you think this is feasible. If so I will broadcast this solution for Jas3 users.
You have also given me the idea that the unused field in G4AttDef, which is always "Physics" (I think), could be used for unit category, such as "Energy". I will talk that idea around.
Finally, I recommend the HepRepFile driver and its associated browser, HepRApp, which are maintained, and deal with attributes in a generic manner, I believe.
Dear John, thanks much for looking into this! It's a pity that HepRepXML will not get fixed. The alternative HepRepFile driver and HepRApp are not quite on the same level as jas3/Wired with the HepRepXML input ... Also the two workarounds that worked for HepRepXML did not work with HepRepFile. I don't think that adding another trajectory class is a satisfactory solution either. This class would just exist to avoid a shortcoming in the treatment of G4BestUnit and thus is not qualitatively better than the 2 workarounds ... What I like though is the idea to add the nature of the G4BestUnit to the G4AttDef such that a proper implementation in HepRepXML can be coded to interpret these units. It would be great if you could encourage someone to work on HepRepXML ... Thanks & Best Regards, --Sven Hi Sven Just to say (although I think you realise this), my proposal was not to add another class to Geant4 but for you, the user, to code it up in your user space. Just at the moment it does not look feasible or safe to make changes to the Geant4 code itself. Sorry. Do keep in touch. I recommend the assignee close this bug report. Best wishes. Keep in touch. John |
Dear all, I am using geant4-10-04-patch-02 with the HepRepXML driver and get for trajectories output like this: <instance type="Event/Trajectory"> <attvalue name="ID" type="int" value="108"/> <attvalue name="PID" type="int" value="83"/> <attvalue name="PN" value="e-"/> <attvalue name="Color" type="Color" value="0.00, 0.00, 0.80, 1.00"/> <attvalue name="Ch" type="double" value="-1"/> <attvalue name="PDG" type="int" value="11"/> <attvalue name="IKE" type="double" value="926.12"/> <attvalue name="IMom" value="1.14699 0.257548 -0.649825 MeV"/> <attvalue name="IMag" type="double" value="1.3432"/> <point x="7.17229" y="6.95543" z="225.673"/> <point x="7.21584" y="6.96521" z="225.648"/> <point x="7.21584" y="6.96521" z="225.648"/> </instance> The problem is the units of the kinetic energy (IKE) and the magnitude of the momentum vector (IMag). Apparently G4BestUnit is used in the output but the viewer I am using (jas3 with Wired plugin) does not know that IKE in this instance is in keV and IMag is in MeV ... the unit in both cases is actually called "G4BestUnit" ... So when you try to apply a cut on the kinetic energy in the viewer you just cut on the numerical value between 1 and 999 but the actual unit (eV, keV, MeV, GeV, ...) is lost. A cut of >11 will thus cut all trajectories from 1-11 GeV, from 1-11 MeV, from 1-11 keV and so on. This is clearly not the desired functionality. The potential solutions I see are: Either each instance has to report the actual best unit for the current value (like IMom where the value string ends with the unit) and then Wired needs to be told how to incorporate units in cuts - or G4BestUnit has to be translated to a fixed unit for each category (Energy, Length, ...) in the first trajectory and used with that unit for all trajectories ... Maybe there are other ways to fix this ... Thanks much for looking into this. Cheers, --Sven