-
Notifications
You must be signed in to change notification settings - Fork 23
Iss1847 -- Track objects use global coordinates and MeV #1855
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 Thank You
Two general comments:
- What about the TrackStates? Did I miss something or were those already in detector coordinates?
- Can you increment the version in the
ClassDefofTrack? Since this changes the meaning of the member variables, I want to signal to ROOT that things have changed. (We could also look at doing this conversion ourselves with schema evolution)
|
This does not put all of the parameters into detector coordinates. Really, the only thing that changes is the 3-momentum. The helix parameters don't really make any sense to rotate (the B-field sets the coordinate system) plus we use these parameters/covariances later on for GSF tracking and vertexing. So I'd like for those to stay as they are (even q/p, in GeV). We use the The TrackStates only contain the 5 helix parameters, covariance, and the reference point used. I've incremented the classdef.
|
|
All of that makes sense, can you add doxygen comments to the fields of About the TrackStates - this shows my own misunderstanding, so I'm going to ask for what I want. How would I get a track's projected position at the ECal? I had mistakenly assumed that was stored in the TrackState, but do I need to call some function to calculate it for me? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The QoP is also in MeV now right?
| self.build1DHistogram("theta_err", | ||
| "#sigma_{#theta} [rad]",nbins,0,0.06) | ||
| self.build1DHistogram("qop_err", | ||
| "#sigma_{qOp} [GeV^{-1}]",nbins,0,1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| "#sigma_{qOp} [GeV^{-1}]",nbins,0,1) | |
| "#sigma_{qOp} [MeV^{-1}]",nbins,0,1) |
| self.build1DHistogram("match_theta", | ||
| "reco match #theta", nbins, thetamin,thetamax) | ||
| self.build1DHistogram("match_qop", | ||
| "truth q/p [GeV^{-1}]",nbins,qopmin,qopmax) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| "truth q/p [GeV^{-1}]",nbins,qopmin,qopmax) | |
| "truth q/p [MeV^{-1}]",nbins,qopmin,qopmax) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm keeping q/p (which is a track fit parameter) in GeV so that it aligns with ACTs.
I think the track states paramaters are phi, theta, QoP so X vs Y vs Z is not there, on the other hand the GeV to MeV should be important, Matt please edit away the 1000 in ldmx-sw/Ecal/src/Ecal/EcalHelper.cxx Line 31 in 25e45c0
in case the tracks state QoP is in MeV now |
|
You bring up a good point that I've been going back-and-forth with...ACTs (and every other tracking code I've seen) parameterizes the helix using the perigee of the helix wrt a reference point. The perigee of the helix is the POCA to the tracking-z axis (global y). We actually don't save the perigee state but instead project the track to a surface...the target surface for the default track parameters, but also e.g. the ecal surface, sensor surfaces, etc for different track states. The parameters we save are then not strictly perigee parameters but the parameters at that planar surface. ACTs knows all about this; the parameters always have a corresponding surface associated with them (PerigeeSurface, PlanarSurface etc.) so you can easily move from one to another without screwing things up. Anyway, we want to hide this stuff from the end user since 99% of them want to know things like you suggested: where is the track position and at the target or ECal. These are actually stored in the d0/z0 (or perigee_pars_[0]/[1]) of the Track object where d0-->global X, z0-->global Y. Same with the track state. I think we probably want to make this more explicit and add getPositionAtTarget() and getPositionAtEcal() methods that just return the global positions. Do we add these to the Track object? As a utility function? |
|
That line is still correct. I think we should move away from using q/p and just use getMomentum() and get the magnitude from that vector. Or we could add a getPMag() method to Track.
|
That's fine, but in ECAL we should have the momentum as measured (well propagated) at the ECAL face. The |
|
I think the real solution to this confusion is just to have two different event objects.
I'm not committed to these names, but I don't like the idea of mixing purposes or having live conversions done in the event object itself. The data stored on disk should be directly interpret-able by users of the data. |
|
Since this has come up, why don't we do something like this... The Track object itself has only stuff that is universal to the track: The TrackState objects contain: We can write a converter to/from this ldmx::Track/State to an ACTS::Track so that we can store the ldmx::Track and still get back to the ACTS::Track if we want do something like Vertexing or track re-fitting later on.
|
|
That sounds good to me, would Track still own TrackState or would we keep TrackState's separate? If Track still owns TrackState, then maybe we just have different member variables for the different states? A vector feels like overkill when we have to change the C++ to add a new TrackState anyways... |
0b6af26 to
5648b64
Compare
|
@tomeichlersmith I'm not sure I know enough to have an opinion about TrackState being owned by Track or not. As far as just having Track just having members for the different track states, this feels a bit inflexible (though I may not be fully understanding). Right now, for the Tagger I just have the atTarget state while for recoil it's atTarget and atECal. In the future we may want to add more (atTS or atHCal?). And I know there will be studies we'll want to do where we keep the track state at each sensor. To add those, I figure we can just add those track states to the vector from whatever processor is making the tracks for whatever study we are doing. Is using a vector for this not efficient? |
|
Your extra context about different track states for future studies answers my confusion - let's leave it as a vector of TrackStates. We could avoid having the TrackStates owned by the Track if the TrackStates can function without knowing which Track they came from. Upon further reflection, I also retract this comment since I don't think this is possible. I like your idea of having the data-on-disk be in global/detector coordinates and having utilities that convert to/from ACTS objects (that also convert into Tracking coordinates). |
|
Ok, I will code this new Track object up as described (keeping TrackState in Track). This may take some time to change and test everything. |
|
That's okay, lets move slow and fix things. I've made broken enough things trying to move fast. Edit: I converted this PR to a draft. Mark it as "Ready for Review" and Tamas and I will get notifications and we'll come back and review it again. |
This resolves issue #1847
Added a rotation from tracking-->global coordinates, plus conversion of momentum to MeV, into TrackingUtils. This is done for CKF and GSF tracking. Also fixed up the plot limits in DQM to accommodate.