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

Refactoring coreas to include interpolation #688

Open
wants to merge 27 commits into
base: develop
Choose a base branch
from

Conversation

cg-laser
Copy link
Collaborator

@cg-laser cg-laser commented Jun 5, 2024

Major refactoring of the coreas interface to read the electric field from coreas hdf5 files.
A new class readCoREASDetector.py can be used to read an array and get the interpolated position.

This is largely a copy of #685 which is an undefined state because of an accidental force push. Please never force-push unless you know what you are doing.

@cg-laser
Copy link
Collaborator Author

cg-laser commented Jun 5, 2024

@MijnheerD @lpyras I'm getting these warning from the interpolator module all the time:

Trace arrival times were not set during init, only relative timings are returned!
warning: negative values in abs_spectrum found: 6 times. Setting to zero.

are we not using the interpolator correctly?

@cg-laser
Copy link
Collaborator Author

@MijnheerD @lpyras I added an example of a "LOFAR"-style Xmax reco. The example is using a vertical shower. It would probably be good to also test with an inclined shower as some potential bugs might only appear then.

Before merging this PR, it would be good if the module would be tested a bit more. Is my understanding correct, that this module has not been used by anyone and is essentially untested?

@cg-laser
Copy link
Collaborator Author

The output of the reconstruction looks like this.
A remaining ToDo is a correct uncertainty estimation of the energy fluence. This should be implemented into the efieldSignalReconstructor

Xmax_fit_0
footprint_0_core0 000000_0 000000

@lpyras
Copy link
Collaborator

lpyras commented Aug 5, 2024

@MijnheerD @lpyras I'm getting these warning from the interpolator module all the time:

Trace arrival times were not set during init, only relative timings are returned!
warning: negative values in abs_spectrum found: 6 times. Setting to zero.

are we not using the interpolator correctly?

@MijnheerD I dont really know what that means. I always thought we are anyway only interested in the relative timing. I implemented access now the timing information provided by the cr-pulse-interpolator. Is there something else to do?

@lpyras
Copy link
Collaborator

lpyras commented Aug 5, 2024

@MijnheerD @lpyras I added an example of a "LOFAR"-style Xmax reco. The example is using a vertical shower. It would probably be good to also test with an inclined shower as some potential bugs might only appear then.

Before merging this PR, it would be good if the module would be tested a bit more. Is my understanding correct, that this module has not been used by anyone and is essentially untested?

I tested it before the coreas refactoring for effective area calculation. That yielded reasonable results.

@lpyras
Copy link
Collaborator

lpyras commented Aug 6, 2024

I changed everything we discussed so far e.g. change the coreas readers in a way that they only rely on the readCorsika7() function. Unfortunately I didn't have time to test everything. Any volunteers? Otherwise I try to do it in the next weeks. :)

@MijnheerD
Copy link
Collaborator

Sorry for coming in late on this, I thought I already answered some the questions but apparently I didn't.

@MijnheerD @lpyras I'm getting these warning from the interpolator module all the time:

Trace arrival times were not set during init, only relative timings are returned!
warning: negative values in abs_spectrum found: 6 times. Setting to zero.

are we not using the interpolator correctly?

@MijnheerD I dont really know what that means. I always thought we are anyway only interested in the relative timing. I implemented access now the timing information provided by the cr-pulse-interpolator. Is there something else to do?

This is important, because usually the relative timing is not enough. The problem is that for larger starshapes, the CoREAS time traces start at different times. We added the option to pass the start times to the interpolator, which it can then interpolate for you as well. The warning tells you that the start times were not provided to the constructor. On the lofar/interpolator branch we added this on line 65 of "readCoREASInterpolator.py". Then on line 191 we retrieve the start times, which are used in the make_sim_station function give the traces the correct start time.

@MijnheerD @lpyras I added an example of a "LOFAR"-style Xmax reco. The example is using a vertical shower. It would probably be good to also test with an inclined shower as some potential bugs might only appear then.

Before merging this PR, it would be good if the module would be tested a bit more. Is my understanding correct, that this module has not been used by anyone and is essentially untested?

I agree we should test it more, and I think once the LOFAR pipeline is done we will have an excellent playground for that. Although we can also already start testing on simulations, like the Xmax example (thanks @cg-laser for the script!). I am not sure when we will be able to get to it, but in September we should have a master student who will need to work with the interpolator so he might be able to test it more thoroughly.

@anelles
Copy link
Collaborator

anelles commented Aug 7, 2024

I just tested the branch and it actually fails with a pip installed cr_interpolator on:
File "/usr/local/lib/python3.12/site-packages/cr_pulse_interpolator/signal_interpolation_fourier.py", line 9, in
import interpolation_fourier as interpF
ModuleNotFoundError: No module named 'interpolation_fourier
I feel like I have seen this error discussed. Do we need a new cr_interpolator release?

@anelles
Copy link
Collaborator

anelles commented Aug 7, 2024

So the automatic build fails on the cr_interpolator not being installed, but even if you pip install it, it doesn't work.

@anelles
Copy link
Collaborator

anelles commented Aug 7, 2024

Ah, @lpyras just reminded me that this is known and a new release is being worked on. Then I can do the homework as assigned by @MijnheerD to me check whether the reconstruction is indeed what we have done for LOFAR.

Copy link
Collaborator

@MijnheerD MijnheerD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The readCoREASDetector module looks good, but there is still some more cleanup to do in the coreas.py file. Specifically there are several points where explicit units are used, instead of the internal unit system. On some occasions the z-coordinates are fixed to some value, which I also think is very dangerous because the user does not see this and it might lead to unintended bugs. Lastly I don't see the purpose of the several getter-function that are there. If we think these attributes should be hidden from the user in such a way that they cannot alter them, then we should make proper properties of them. But right now they serve little purpose.

NuRadioReco/modules/io/coreas/coreas.py Show resolved Hide resolved
Parameters
----------
zenith : float
zenith angle in radians
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is better to make use of the internal units here and everywhere else in the file

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

radiants is the default units. You mean I should add a /units.rad?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, in case the internal system would change at some point :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realised that I am not being very clear here, sorry. What I was specifically pointing to is that fact that you assume the zenith angle is given in radians (according to the docstring). But I would not do that/write it like that, ie what we really expect is the angle given in internal units. And then later, when calling the radiotools functions, we should indeed add / units.rad to explicitly convert to radians (in case the internal units would ever change)

NuRadioReco/modules/io/coreas/coreas.py Show resolved Hide resolved
NuRadioReco/modules/io/coreas/coreas.py Show resolved Hide resolved
efield_on_sky = cs.transform_from_ground_to_onsky(efield_geo)

if prepend_zeros:
# prepend trace with zeros to not have the pulse directly at the start
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if this is the best way of achieving this goal. Adding more timesamples will alter the frequency spectra. Why not just roll the pulse to the center?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, is this really necessary? At least for the interpolator I think we solved the issue with pulses not being centered.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is old heritage... @cg-laser what should we do here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just my two cents: What we have found in Auger is that the trace length by CoREAS can be to small resulting in a to large frequency resolution. However, what we would do is padding in the frequency domain.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

somebody wants to implement that?

NuRadioReco/modules/io/coreas/coreas.py Show resolved Hide resolved
NuRadioReco/modules/io/coreas/coreas.py Outdated Show resolved Hide resolved
NuRadioReco/modules/io/coreas/readCoREASDetector.py Outdated Show resolved Hide resolved
observer_position = np.zeros(3)
observer_position[0], observer_position[1], observer_position[2] = -position[1] * units.cm, position[0] * units.cm, position[2] * units.cm
observer_position = cs.transform_from_magnetic_to_geographic(observer_position)
observer_position = convert_obs_positions_to_nuradio_on_ground(position, zenith, azimuth, magnetic_field_vector)
core_position = (-observer_position + station_position)
core_position[2] = 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shower core is fixed to z=0, is that desired?

@lpyras
Copy link
Collaborator

lpyras commented Sep 2, 2024

I try to address @MijnheerD suggestions.

One question still open is the z coordinate of the shower. What should we do in sim_station? The height of the coreas shower? Where do we want the core position? In the same plane as the antenna?

Should we remove make_sim_station() and make_sim_shower() as Mitja suggested?

Any opinions? @cg-laser @fschlueter

Comment on lines +132 to +143
def set_position_onsky(self, position):
"""
set position of the electric field in the on sky (vxB, vxvxB) coordinate system
"""
self._position_onsky = position

def get_position_onsky(self):
"""
get position of the electric field in the on sky (vxB, vxvxB) coordinate system
"""
return self._position_onsky

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to store these coordinates? Aren't they just a transformation of position?

@@ -105,6 +105,8 @@ class showerParameters(Enum):
distance_shower_maximum_geometric = 10 #: distance to xmax in meter
distance_shower_maximum_grammage = 11 #: distance to xmax in g / cm^2
parent_id = 12 #: id of parent in sim particles
core_coordinate_vertical = 13 #: vertical coordinate of the shower core used in corsika
coreas_GPSSecs = 14 #: Event time in GPS time of the shower in coreas
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is anyone using this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think so, but it was stored in the previous implementation, that's why I added it.


def read_CORSIKA7(input_file, declination=None):
"""
this function reads the corsika hdf5 file and returns a sim_station with all relevent information from the file
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc-string could be improved

warning_printed_coreas_py = True
sim_station.set_is_cosmic_ray()
sim_station.set_simulation_weight(weight)
return sim_station


def create_sim_station(station_id, evt, weight=None):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this function also copy over traces?

@lpyras lpyras marked this pull request as ready for review October 14, 2024 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants