Skip to content
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

Allow adding of parent ID, event ID, and flags from TOPAS PHSP #144

Open
cvelten opened this issue May 1, 2023 · 6 comments
Open

Allow adding of parent ID, event ID, and flags from TOPAS PHSP #144

cvelten opened this issue May 1, 2023 · 6 comments
Labels
enhancement New feature or request

Comments

@cvelten
Copy link

cvelten commented May 1, 2023

A non-exhaustive list of parameters in the PHSP contains the following

              'Position X [cm]': (dtype('float32'), 0),
              'Position Y [cm]': (dtype('float32'), 4),
              'Position Z [cm]': (dtype('float32'), 8),
              'Direction Cosine X': (dtype('float32'), 12),
              'Direction Cosine Y': (dtype('float32'), 16),
              'Energy [MeV]': (dtype('float32'), 20),
              'Weight': (dtype('float32'), 24),
              'Particle Type (in PDG Format)': (dtype('int32'), 28),
              'Flag to tell if Third Direction Cosine is Negative (1 means true)': (dtype('bool'),
               32),
              'Flag to tell if this is the First Scored Particle from this History (1 means true)': (dtype('bool'),
               33),
              'Time of Flight [ns]': (dtype('float32'), 34),
              'Run ID': (dtype('int32'), 38),
              'Event ID': (dtype('int32'), 42),
              'Track ID': (dtype('int32'), 46),
              'Parent ID': (dtype('int32'), 50),
              'Initial Kinetic Energy [MeV]': (dtype('float32'), 54),
              'Vertex Position X [cm]': (dtype('float32'), 58),
              'Vertex Position Y [cm]': (dtype('float32'), 62),
              'Vertex Position Z [cm]': (dtype('float32'), 66),
              'Initial Direction Cosine X': (dtype('float32'), 70),
              'Initial Direction Cosine Y': (dtype('float32'), 74),
              'Initial Direction Cosine Z': (dtype('float32'), 78)

While some of them are used in calculating momentum and similar, others, like RunID and EventID are not easily added. Copying the TOPAS data loader and adding the column does not work as it is not a required column but has to be added as well. This feels somewhat "hacky".

@bwheelz36
Copy link
Owner

Hey @cvelten

I agree that I haven't really thought of a good way to handle all these additional data.

I have thought about how I would do this should someone ask, and I think the answer is:

  • create additional quantities as allowed columns
  • add methods to add quantities under fill, where the topas phase space is re-passed

so the code would look something like:

from ParticlePhaseSpace import DataLoaders
from ParticlePhaseSpace import PhaseSpace

test_data_loc = Path('to/phase_space.phsp')
ps_data = DataLoaders.Load_TopasData(test_data_loc)
PS = PhaseSpace(ps_data)
PS.fill.event_ID(test_data_loc)  # the fill method re-reads the data.
# (we could also not put this in fill but do something like):
PS.read_additional_data.event_ID(test_data_loc)

This is still a bit hacky, but one of the rules I was trying to adhere to was that a DataReader should enable a very consistent data quantities. Allowing all these quantities to maybe/maybe not get read in at the data load stage sends us in a direction I don't like where gets hard to write consistent code downstream. Also I consider most of the quantities above to be pretty niche in most situations.

What do you think? Could this solution work?

@bwheelz36
Copy link
Owner

Or, I could maybe enable passing an optional class which could contain additional methods. this could be a more general solution for these situations where the basic data format is not sufficient?

from ParticlePhaseSpace import DataLoaders
from ParticlePhaseSpace import PhaseSpace

class ClassForMyData:
    def read_vertice_info(self, data_loc):
        pass
    
    def operate_on_new_data(self):
        pass


test_data_loc = Path('to/phase_space.phsp')
ps_data = DataLoaders.Load_TopasData(test_data_loc)
PS = PhaseSpace(ps_data, user_methods = ClassForMyData())
PS.user_methods.read_vertice_info()

@cvelten
Copy link
Author

cvelten commented May 3, 2023

Using those fill methods might work. But to add multiple columns it seems more cumbersome to re-read and fill every time you add a column? What about, in addition, adding a method with a signature like

PhaseSpace.fill(data: Path, fill_methods: List[method signature])

It could either add all the columns at once or call the methods sequentially (which would just be encapsulating multiple method calls.

Alternatively, at least for the TOPAS PhaseSpace, couldn't you just add all the columns that come out of the phase space into the allowed columns list? I could see a method on your data loader or the PhaseSpace that lists all allowed (and available) columns .available_columns(), which one could then pass to a PhaseSpace.fill.columns(List[str]).

@bwheelz36
Copy link
Owner

bwheelz36 commented May 15, 2023

  • include additional columns in allowed data
  • make sure tests pass
  • add a user defined method
  • draft read topas example

bwheelz36 added a commit that referenced this issue May 15, 2023
@bwheelz36
Copy link
Owner

Hi @cvelten

I have drafted an example of how I think this can work. A demonstration is here.

What do you think of this? would this fulfill your needs? Note that you would still have to write a new data exporter to make sure these quantites get written to a new topas phase space file.

@bwheelz36 bwheelz36 added the enhancement New feature or request label May 16, 2023
@cvelten
Copy link
Author

cvelten commented May 27, 2023

I think this looks good and versatile. I'll give it a try, soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants