-
Notifications
You must be signed in to change notification settings - Fork 16
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
Phasespace generation from decay chains #86
Comments
Would this not rather be a thing for a decay chain rather than a particle? Could you give an example of what and how the info would be used down the line in |
OK, down to one example. Imagine we look at B0 -> K*0 gamma:
A simple way to provide you info would be via a new dedicated
Shall we go in this direction at least as a first attempt? |
Let me know, @mayou36, when you want to further discuss this. |
Hi @eduardo-rodrigues, sorry for the long silence! I tried around with some implementation. Just to be sure, the field after the particle name (the list, e.g. after 'B0') is for different possible decays? Or why is that exactly a list? One question, technical: how to best parse it? in https://github.com/scikit-hep/decaylanguage/blob/master/decaylanguage/decay/decay.py#L564 it's a for loop and searching whether the decay happens. So there is no direct way to traverse the decay in a tree-like structure using the wrappers ( It's all surely doable somehow, but I wonder about the most elegant (and "future-proof") way |
So I've got a student who would be interested actually to work on this (maybe, we're still figuring out), this would still be a desired feature I assume? Or did plans somehow change? |
Absolutely, still in planning. Thanks a lot for the ping. That's great to hear. As you know I can't just now but let me then get back to you next week on this "thread". (In fact the comments you made above had forced me to look into some machinery a while back and I then got side tracked by a feature/bug-ish I had found. I then forgot about the starting point :D. In short, talk to you really soon.) |
Hello! I am the student @mayou36 mentioned in a previous message. Currently, I have implemented a small prototype function that converts a dict in the decaylanguage format into a gen_particle = recursively_replace(decaychain.to_dict()) I can also implement a function that directly converts a I was wondering, is the plan to convert dicts, which can contain many ways for a particle to decay, or |
Hello @simonthor. Excellent to see work on this! I'm away on holidays. Let me get back to you upon my return ... |
Ok, enjoy your holidays! I will post some more questions/problems here in the meantime: Currently, I am using the p = Particle.from_string(name)
p.mass # get the mass
p.width # get the width If there is a non-zero width, I create a mass distribution function (currently a normal distribution but this can be changed later). However, the top particle of a decay chain in phasespace must have a fixed mass, and cannot in other words have a width. This is a problem, since all particles except 6 in Do you have any suggestions for how this should be solved? Here are some of my potential solutions:
I also opened an issue about this in my repo with the same information. |
After some discussions with @mayou36, the two questions mentioned earlier have been cleared up. Regarding the first question, I will implement a new object containing all possible decays as For the second question, I will implement a tolerance for the mass width that can be changed by the user. Any width smaller than the tolerance will be seen as constant. I might post some more questions here later, once I encounter some other problems! |
That method is legacy and the much better way is via |
Sure, feel totally free! Apologies that I'm slow as I will have the 2nd part of my holidays but after that I'm sure we can converge. |
Ok, I will use |
Currently, when a particle has a mass width, I assume that the mass distribution is a normal distribution. Is there a way find out what the mass distribution is, i.e., if it is a normal distribution, BreitWigner, etc.? |
There is no "unique solution" though amplitude analysis experts will tell you that for some popular particles it is customary to use shape "X" or Y". Most are of course motivated physically. As a default a Breit-Wigner is not a bad choice.
No since that's not a particle property per say. Such info would go beyond what
I don't really see how since different things. Just take the example
where the models are different per decay mode (spins of particles are not the same). I think the mass shape (model) is something the user will have to specify as guesses are more dangerous than anything here in the end. That's my 2 cents. But check with amplitude analysis experts if there is some way to build a "map" of best guesses that you can make available, if you really want to ... |
Hi @simonthor, @mayou36, I realise that this thread is already long and I may have missed to clarify certain points. Do let me know what you need from me at this stage, and how the API is getting along for this link between our 2 packages. On
I don't quite understand the issue here. can you explain? Maybe sorted in the meantime. |
You should only provide the minimal (though comprehensive for the specific goals) API.
Correct. The |
Old question from @mayou36:
That's right. I tried various ways to represent the most general set of decay chains one may want and the present format seems to bo the job :-).
There is, actually, and in fact https://github.com/scikit-hep/decaylanguage/blob/master/src/decaylanguage/decay/decay.py#L564 shows how to do it. Unless I'm misunderstanding you ... BTW, if some of the internal functions need to be more easily exposed, such as
This I do for the viewer, see https://github.com/scikit-hep/decaylanguage/blob/master/src/decaylanguage/decay/viewer.py. It certainly looks a but cryptic at first but it does the navigation correctly :-). This makes me realise that for searching functionality (not that much available so far) I might reuse quite a bit of these helpers I'm referring you to! Let's iterate as needed. Is there a little notebook you could share to see how your work is shaping up? |
Ok, I might replace the normal distribution with a Breit-Wigner as a default.
This was something that @mayou36 also agreed with, so I will use the suggested zfit parameter that can be added to a decaylanguage dict. I will post another comment in this issue once I have implemented the support for the |
This has been solved. The top particle in a phasespace GenParticle must have a constant mass, so what I do right now is to always use |
Sounds good. Looking forward to it. (Anything like the zfit parameter I suggested at the top of this discussion?) |
Yes, almost the exact way you suggested it to be implemented. |
Ok, the previous comment turned out to be wrong, as the implementation barely resembles the dec_dict = {'D+': [{'bf': 1,
'fs': ['K-', 'pi+', 'pi+',
{'pi0': [{'bf': 1, 'fs': ['gamma', 'gamma']}]},
],
'model': 'PHSP', 'model_params': ''}]
}
FullDecay.from_dict(dec_dict, {'K-': 'rel-BW', 'pi+': 'BW', 'pi0': 'gauss'}) In other words, the user passes a second dict which specifies which particle should have what type of mass function. |
Hi @simonthor and @mayou36, thanks for the example of where you're heading. That will work. You have, though, taken a different approach, as above I incorporate zfit specific metadata at decay mode level inside my decay decay whereas you take the approach of "composition". You loose generality - same shape for a given particle - but same space; the latter is most probably not relevant since you are not going to deal with very deeply nested chains. I confess that I'm more convinced by my suggestion, biased of course. Can you dwell on your motivations? |
@eduardo-rodrigues your suggested implementation seems better, since it allows for more customization, as the same particle can have different mass functions for different decay modes.
To be honest, the main reason I implemented it this way was because I did not fully understand your example with the zfit parameter. More specifically, which particle does the zfit parameter correspond to? I now realize that it probably refers to the particle that decays into that decay mode, i.e., K*0 in the example at the beginning of the thread?
If I have understood it correctly, your suggestion will probably be easier to implement than my current implementation, so I should be able to switch it quite quickly. Though I am also currently wrapping up my Google Summer of Code project, so unfortunately I cannot guarantee any time frame.
|
Morning. Cool. But let's hear anyway from @jonas-eschle to make sure that we converge on the "best" solution to the problem for the benefit of all :-).
Correct - the zfit parameter is added to
and then becomes a "property metadata" of the particle that decays via that decay mode. This make sense. It also indeed mean that, for whatever reason, you wanted to give another K0 another mass shape, that would be possible because either the K0 would decay to a different decay mode or you would have flagged as "MyOtherK*0.
Good luck there! |
Ok, I will leave my implementation as it is for now then. I will discuss with Jonas on Friday, so we will probably come to a conclusion then. I noticed one issue with your suggested implementation: how should particles withut any decays have a specified mass function? {'D+': [{'bf': 1,
'fs': ['K-', 'pi+', 'pi+',
{'pi0': [{'bf': 1, 'fs': ['gamma', 'gamma']}]},
],
'model': 'PHSP', 'model_params': ''}]
} and want K- to have a gaussian mass distribution. How should this be specified? Should it e.g., be specified like this: {'D+': [{'bf': 1,
'fs': [
{'K-': [{'zfit': 'gauss'}]},
'pi+', 'pi+',
{'pi0': [{'bf': 1, 'fs': ['gamma', 'gamma']}]},
],
'model': 'PHSP', 'model_params': ''}]
} This would introduce particles which are dicts that do not have |
My point is that a particle only needs a mass function if it decays. A proton never has/needs a mass function, for example :-).
Yes in a way, but you can in fact use the As you can see the If what you suggest is really needed then we would have to think harder if the present code fails to parse. If you get stuck I can try and help next week, BTW ... |
I talked with Jonas on Friday (i.e., yesterday) and he agreed with you that only particles that decay need a mass function; all stable particles should have a constant mass. dec_dict = {'D+': [{'bf': 1,
'fs': ['K-', 'pi+', 'pi+',
{'pi0': [{'bf': 1, 'fs': ['gamma', 'gamma']}]},
],
'model': 'PHSP', 'model_params': '',
'zfit': 'rel-BW'}]
}
decay = FullDecay.from_dict(dec_dict) The last line will create a What I have left now is to "only" implement some mass functions, such as the relativistic Breit-Wigner (right now I only have a Gaussian implemented). I plan on using zfit (based on a suggestion from Jonas) to create these mass functions. Do you have any suggestions for which mass functions I should implement? By the way, it is already possible for a user to add additional mass functions, besides the common ones I plan to implement. Are there any more features that you would like to see implemented? Otherwise, implementing some specific mass functions will be the last feature that needs to be added. Then this issue should mostly be solved. |
To find the mass of a particle, I currently use def _find_single_particle(name: str) -> Particle:
particles = Particle.findall(lambda p: p.name == name)
if len(particles) != 1:
raise ValueError(f'The given name "{name}" of the particle was not valid.'
'The input dict probably had an invalid particle name in it.')
return particles[0] Can I simply use |
That seems very reasonable to me so far. I think a relativistic BW, a normal BW and a Gaussian seem to be useful. @eduardo-rodrigues I was wondering a bit on the logistics of this, as it uses multiple packages and therefore does not quite fit into one single package (we could add it directly to phasespace, that is maybe the best bet...) and seems to be nearly a standalone package. Or where would you see this fit? Furthermore, it made me think about a RapidSim version. We have the phasespace, the dec parser, so we need some efficiencies, smearing and we would be able to do rapid sim. Do you think this is another possible project (for Simon or anyone else)? I think it could be quite useful |
Good. Reassuring ;-).
If I understand you correctly the above requires no coding on your side at all. Indeed
which is exactly what you wrote. The benefit is that my construction is trivial to read by anyone, even a reasonably newbie.
Here I cannot judge too well but if this is the way you want to have the link/bridge between the 2 packages, then fine.
Not apart from the ones you mention. I guess your intention is to provide a way for the user to pass a user-defined function where you would map a name
From the above I wonder if you would like |
For sure. This is very handy when dealing with decay files since they use EvtGen names rather than the usual PDG ones (I know, these matters are annoying, but not much one can do at this point in history). The Are EvtGen names always used for particle names in decaylanguage dicts? If not, is there a different method that you suggest me to use, tbat has a cleaner syntax than what I do now? So by default DecayLanguage dicts will deal with EvtGen names. For sure if they are constructed from .dec files. This being said, the dicts can equally deal with PDG names and only some methods need to know about that when called, see e.g. https://github.com/scikit-hep/decaylanguage/blob/master/src/decaylanguage/decay/decay.py#L76. (Dunno how much you want my replies to be verbose.)
Happy to discuss anything else there if better. Till now it seems good to have all the discussion of this bridging between the 2 packages in this one place. |
Having it in
This could be a good project but one would need to think carefully on how to make the thing at least as good as RapidSim: functionality but also installation easiness and package dependencies. Maybe something for a dedicated discussion on the PyHEP channel? |
I hope I have by now replied to all outstanding points. Let me know. Seems we're not far from seeing some code in action 👍! |
Further on design. The present example in the README (BTW, I corrected a trivial typo, see zfit/phasespace#61) goes roughly as follows:
For the functionality exploiting
This suggested class method has the advantage that your package dependency on Following up from here you could then also have a method Still thinking out loud: I have not checked whether one can easily get the used particle masses from |
Yes, exactly. One can pass an additional dict to the constructor like so: FullDecay.from_dict(dec_dict, {'cool func': MyCoolFunction}) which will use MyCoolFunction as the mass function for all decay modes with
If
For particles with constant mass, it is possible to get the mass with |
Two quick questions:
|
I work on this during my free time. I am a student from Sweden (KTH Royal Institute of Technology to be specific) that aspire to become a particle physicist and I am interested in contributing to Scikit-HEP. Sorry, I should have introduced myself much earlier!
I have implemented most of what we have discussed, besides the relativistic Breit-Wigner distribution, which will likely be added to zfit-physics as a separate PR. All code I have written can be found in my repo (thought I sent the link before but it might very well have been lost in all the messages). |
I have now added relativistic Breit-Wigner to zfit-physics and use it as the default mass function for the decaylanguage to phasespace conversion. The only task remaining now should be to merge the code into phasespace. |
Good to hear that it works! So for that, what do you think @eduardo-rodrigues , as it is it greatly extends the capability of phasespace and is a real generator that is also capable of generating from multiple decay branches. So I see it as a very possible future to extend the functionality even further (which is difficult if it is in phasespace). I think I would tend to make it a standalone repo, we can very well add it to the zfit org for the moment (it may not be fitted, yet, for Scikit-HEP, or what do you think?). @simonthor what do you think? We could keep it a standalone repo, which allows to have it extendible beyond what phasespace can do. |
I agree that keeping it as a standgalone repo would make more sense, also since it has many dependencies that phasespace currently does not have. |
Hi folks, great news. See my comments and suggestions above on the |
Hi both, any follow-ups? |
Hello, apologies for the delayed reply. |
OK, fair enoug. Let's then wait. |
Closing since zfit/phasespace#63 provides a first version of the functionality. |
In order to make the package compatible with
phasespace
requires eachParticle
to know the distribution that parametrizes its mass if it is not fixed (e.g. BreitWigner, Gauss).Where should this best be added?
The text was updated successfully, but these errors were encountered: